Skip to content

Commit c11781b

Browse files
feat: Codex sender prefix on Codex→Grok messages; sort/filter/search codex threads (#130)
1 parent 256fb84 commit c11781b

26 files changed

Lines changed: 2516 additions & 498 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"grok-bot-cli": minor
3+
---
4+
5+
Codex → Grok Bot messages now carry a sender prefix, `[from Codex thread <id> @ <machine>, cwd <cwd>; reply: codex_send({threadId:"<id>", message:"..."}) via MCP on <machine> (or CLI: gbot codex send <id> "...")]`, on the managed relay path, the plain `gbot_send` path with a known native thread, and `gbot send` inside a Codex terminal (`$CODEX_THREAD_ID`); unknown fields are omitted. Relay return messages use the same prefix. `codex_threads` / `gbot codex list-threads` now sort by recent activity (`updatedAt`) by default (`sort`: `updated` | `created` | `recency`, `order`), and add `query` (case-insensitive name/title, preview or id prefix, scanning every page), `activeWithin` / `since`, `cwd`, `modelProvider`, `sourceKind` and `archived` filters, so old-but-active threads are no longer hidden past the first 100.

‎README.md‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ All gateway / `EnsureSandBox` fetches use `redirect: "error"` so credentials are
195195
```sh
196196
codex app-server daemon start # once per machine session
197197
gbot codex status # socket, daemon version, reachability
198-
gbot codex list-threads --limit 10 # id, status, cwd, preview
198+
gbot codex list-threads --limit 10 # newest activity first: id, status, cwd, updated, preview
199+
gbot codex list-threads --query zerofs --active-within 7d # find an old-but-active thread
199200
gbot codex send <threadId> "Grok here: the build is green, please continue."
200201
gbot codex send --model gpt-6-astra --effort high <threadId> "Review this change"
201202
gbot codex new --cwd /path/to/project --model gpt-6-astra --effort high "Start here"
@@ -248,7 +249,7 @@ MCP tools: `chatgpt_desktop_status`, `chatgpt_desktop_list_threads`, `chatgpt_de
248249

249250
`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.
250251

251-
**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"`.
252+
**Thread discovery.** `list-threads` is newest-activity-first (`--sort updated`, the default; `--sort created|recency`, `--order asc`) and finds old-but-active threads: `--query zerofs` (case-insensitive name/title, preview or id prefix, scanning every page, not just the first 100), `--active-within 7d` / `--since 2026-09-01`, `--cwd`, `--model-provider`, `--source-kind`, `--archived`; the `codex_threads` MCP tool takes the same fields (`query`, `activeWithin`, `since`, `sort`, `order`, ...). `--limit N` (1–200) is the page size and 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"`. With client-side filters (`--query`, `--since`, `--active-within`) a page can hold more matches than `--limit`; `nextCursor` is then a `gbot1:` cursor that resumes inside that page, so nothing repeats or is skipped.
252253

253254
**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:
254255

@@ -287,6 +288,13 @@ fallback). Claude Code and Cursor bundles also include `/gbot:codex-send`,
287288
The tools bundle this repository's gateway client and worker, so the installed
288289
plugin does not need `gbot` on `PATH`.
289290

291+
**Replying to a Codex sender.** Messages a Codex thread sends to Grok Bot
292+
(`gbot_send` with a native or explicit `codexThreadId`, the managed bridge, its
293+
returned answers, and `gbot send` run inside a Codex terminal via `$CODEX_THREAD_ID`)
294+
start with `[from Codex thread <id> @ <machine>, cwd <cwd>; reply: codex_send({threadId:"<id>", message:"..."}) via MCP on <machine> (or CLI: gbot codex send <id> "...")]`.
295+
`<machine>` is the real hostname (`GROK_BOT_MACHINE_NAME` overrides); unknown fields are left out but the thread id never is.
296+
Find a thread to answer with `codex_threads` (`query`, `activeWithin`, newest activity first).
297+
290298
Install the committed bundle directly from GitHub without cloning or building it:
291299

292300
```sh

‎artifact/agent-bundle.compile-evidence.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎artifact/agent-bundle.manifest.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)