openclaw-codex-app-server 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,22 @@
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure & Module Organization
4
+ `index.ts` is the plugin entrypoint and registers commands, services, and interactive handlers. Core implementation lives in [`src/`](./src): controller flow in `controller.ts`, API/client integration in `client.ts`, configuration in `config.ts`, state and thread helpers in `state.ts`, `thread-picker.ts`, and `thread-selection.ts`, and user-facing text formatting in `format.ts`. Tests are colocated with source files as `src/*.test.ts`. Plugin metadata lives in `openclaw.plugin.json`; package and TypeScript settings are in `package.json` and `tsconfig.json`.
5
+
6
+ ## Build, Test, and Development Commands
7
+ Use `pnpm` for local work.
8
+
9
+ - `pnpm test`: run the Vitest suite once.
10
+ - `pnpm typecheck`: run strict TypeScript checking with `tsc --noEmit`.
11
+ - `pnpm openclaw plugins install --link /path/to/openclaw-codex-app-server`: link this package into a local OpenClaw checkout for manual integration testing.
12
+
13
+ There is no separate build step in this repository; correctness is gated by tests and typechecking.
14
+
15
+ ## Coding Style & Naming Conventions
16
+ Write TypeScript targeting Node ESM (`"module": "NodeNext"`). Match the existing style: 2-space indentation, double quotes, semicolons, and small focused helpers. Use `PascalCase` for classes and types, `camelCase` for functions and variables, and `SCREAMING_SNAKE_CASE` for shared constants such as command lists or namespace identifiers. Keep command and plugin-facing strings explicit and near the registration code when possible.
17
+
18
+ ## Testing Guidelines
19
+ Tests use Vitest and should stay next to the code they cover, named `*.test.ts`. Prefer narrow unit tests over broad fixtures; most existing tests assert exact payloads and formatting behavior. Run `pnpm test` and `pnpm typecheck` before opening a PR. Add or update tests for any command handling, thread-selection logic, formatting branch, or protocol-shape change.
20
+
21
+ ## Commit & Pull Request Guidelines
22
+ Follow the repository’s existing commit style: short imperative subjects, often with a `Plugin:` prefix, for example `Plugin: restore Codex interactive workflows`. Keep commits scoped to one behavior change. PRs should include a concise summary, linked issue or context, and the exact validation performed (`pnpm test`, `pnpm typecheck`, manual OpenClaw plugin exercise). Include screenshots or message transcripts when changing interactive Telegram or Discord flows.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # OpenClaw Codex App Server Plugin
2
+
3
+ Codex App Server as an OpenClaw plugin for Telegram and Discord conversations. It binds a chat to a Codex thread, forwards plain-text messages into that thread, and exposes command-driven controls for resume, planning, review, model selection, compaction, and more.
4
+
5
+ ## Local Setup Before OpenClaw PR #45318 Lands
6
+
7
+ This plugin targets the plugin interface from [openclaw/openclaw#45318](https://github.com/openclaw/openclaw/pull/45318). Until that work is merged and shipped in the latest OpenClaw release, develop against a local OpenClaw checkout on that PR branch or `main` once merged.
8
+
9
+ ### 0. Clone this repository
10
+
11
+ ```bash
12
+ git clone <this-repo-url>
13
+ cd openclaw-codex-app-server
14
+ ```
15
+
16
+ ### 1. Check out OpenClaw with the plugin interface
17
+
18
+ ```bash
19
+ git clone https://github.com/openclaw/openclaw.git
20
+ cd openclaw
21
+ gh pr checkout 45318
22
+ pnpm install
23
+ ```
24
+
25
+ If you are not using `gh`, fetch the PR directly:
26
+
27
+ ```bash
28
+ git fetch origin pull/45318/head:pr-45318
29
+ git checkout pr-45318
30
+ pnpm install
31
+ ```
32
+
33
+ Once the PR is merged, use `main` instead.
34
+
35
+ ### 2. Point this plugin repo at your local OpenClaw checkout
36
+
37
+ From this repository:
38
+
39
+ ```bash
40
+ pnpm add -D openclaw@file:/absolute/path/to/openclaw
41
+ pnpm install
42
+ ```
43
+
44
+ That makes the local `openclaw` package available to this plugin before a published release includes the new interface.
45
+
46
+ ### 3. Install the plugin from your local checkout
47
+
48
+ From the openclaw repository:
49
+
50
+ ```bash
51
+ pnpm openclaw plugins install --link "/absolute/path/to/openclaw-codex-app-server"
52
+ ```
53
+
54
+ ### 4. Start OpenClaw
55
+
56
+ From your OpenClaw checkout:
57
+
58
+ ```bash
59
+ pnpm gateway:watch
60
+ ```
61
+
62
+ ## Typical Workflow
63
+
64
+ 1. Start in the Telegram or Discord conversation where you want Codex bound.
65
+ 2. Run `/codex_resume`.
66
+ 3. Use the buttons to browse projects and threads, or pass filters in the command.
67
+ 4. Once bound, plain text in that conversation routes to the selected Codex thread.
68
+ 5. Use the control commands below as needed.
69
+
70
+ Buttons are presented for project and thread selection, model switching, and skill shortcuts. If your filter is ambiguous, the plugin sends a picker instead of guessing.
71
+
72
+ ## Command Reference
73
+
74
+ | Command | What it does | Notes / examples |
75
+ | --- | --- | --- |
76
+ | `/codex_resume` | Bind this conversation to a Codex thread. | With no args, opens a picker for recent sessions in the current workspace. |
77
+ | `/codex_resume --projects` | Browse projects first. | Opens a project picker, then a thread picker. |
78
+ | `/codex_resume --all` | Search recent sessions across projects. | Useful when the thread is not in the current workspace. |
79
+ | `/codex_resume --cwd ~/github/openclaw` | Restrict browsing/search to one workspace. | `--cwd` accepts an absolute path or `~/...`. |
80
+ | `/codex_resume --sync` | Resume and try to sync the chat/topic name to the Codex thread. | You can combine this with other flags. |
81
+ | `/codex_resume release-fix` | Resume a matching thread by title or id. | If more than one thread matches, you get buttons to choose. |
82
+ | `/codex_status` | Show the current binding and thread state. | Includes thread id, model, workspace, sandbox, and permissions when available. |
83
+ | `/codex_detach` | Unbind this conversation from Codex. | Stops routing plain text from this conversation into the bound thread. |
84
+ | `/codex_stop` | Interrupt the active Codex run. | Only applies when a turn is currently in progress. |
85
+ | `/codex_steer <message>` | Send follow-up steer text to an active run. | Example: `/codex_steer focus on the failing tests first` |
86
+ | `/codex_plan <goal>` | Ask Codex to plan instead of execute. | The plugin relays plan questions and the final plan back into chat. |
87
+ | `/codex_plan off` | Exit plan mode for this conversation. | Interrupts a lingering plan run so future turns go back to default coding mode. |
88
+ | `/codex_review` | Review the current uncommitted changes in the bound workspace. | Requires an existing binding. |
89
+ | `/codex_review <focus>` | Review with custom instructions. | Example: `/codex_review focus on thread selection regressions` |
90
+ | `/codex_compact` | Compact the bound Codex thread. | The plugin posts progress and final context usage. |
91
+ | `/codex_skills` | List available Codex skills for the workspace. | Adds buttons for up to eight skill shortcuts. |
92
+ | `/codex_skills review` | Filter the skills list. | Matches skill name, description, or cwd. |
93
+ | `/codex_experimental` | List experimental features reported by Codex. | Read-only. |
94
+ | `/codex_mcp` | List configured MCP servers. | Shows auth state and counts for tools/resources/templates. |
95
+ | `/codex_mcp github` | Filter MCP servers. | Matches name and auth status. |
96
+ | `/codex_fast` | Toggle fast mode for the bound thread. | Equivalent to switching the service tier between default and fast. |
97
+ | `/codex_fast on|off|status` | Set or inspect fast mode explicitly. | Example: `/codex_fast status` |
98
+ | `/codex_model` | List models and show model-selection buttons. | If the conversation is not bound yet, it lists models only. |
99
+ | `/codex_model gpt-5.4` | Set the model for the bound thread. | Requires an existing binding. |
100
+ | `/codex_permissions` | Show account, rate-limit, and thread permission information. | Works with or without a current binding. |
101
+ | `/codex_init ...` | Forward `/init` to Codex. | Sends the alias straight through to the App Server. |
102
+ | `/codex_diff ...` | Forward `/diff` to Codex. | Sends the alias straight through to the App Server. |
103
+ | `/codex_rename <new name>` | Rename the bound Codex thread. | Example: `/codex_rename approval flow cleanup` |
104
+ | `/codex_rename --sync <new name>` | Rename the thread and try to sync the conversation/topic name too. | Requires an existing binding. |
105
+
106
+ ## Screenshot Placeholders
107
+
108
+ - `[TODO screenshot] /codex_resume --projects` project picker
109
+ - `[TODO screenshot] /codex_resume` thread picker with buttons
110
+ - `[TODO screenshot] bound conversation after /codex_status`
111
+ - `[TODO screenshot] /codex_model` button list
112
+
113
+ ## Plugin Config Notes
114
+
115
+ The plugin schema in [`openclaw.plugin.json`](./openclaw.plugin.json) supports:
116
+
117
+ - `transport`: `stdio` or `websocket`
118
+ - `command` and `args`: the Codex executable and CLI args for `stdio`
119
+ - `url`, `authToken`, `headers`: connection settings for `websocket`
120
+ - `defaultWorkspaceDir`: fallback workspace for unbound actions
121
+ - `defaultModel`: model used when a new thread starts without an explicit selection
122
+ - `defaultServiceTier`: default service tier for new turns
123
+
124
+ ## Development Checks
125
+
126
+ ```bash
127
+ pnpm test
128
+ pnpm typecheck
129
+ ```
package/index.ts ADDED
@@ -0,0 +1,69 @@
1
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
+ import { CodexPluginController } from "./src/controller.js";
3
+ import { INTERACTIVE_NAMESPACE } from "./src/types.js";
4
+
5
+ const COMMANDS = [
6
+ ["codex_resume", "Resume or bind an existing Codex thread."],
7
+ ["codex_detach", "Detach this conversation from the current Codex thread."],
8
+ ["codex_status", "Show the current Codex binding and thread state."],
9
+ ["codex_stop", "Stop the active Codex turn."],
10
+ ["codex_steer", "Send a steer message to the active Codex turn."],
11
+ ["codex_plan", "Ask Codex to produce a plan, or use 'off' to exit plan mode."],
12
+ ["codex_review", "Run Codex review on the current changes."],
13
+ ["codex_compact", "Compact the current Codex thread."],
14
+ ["codex_skills", "List Codex skills."],
15
+ ["codex_experimental", "List Codex experimental features."],
16
+ ["codex_mcp", "List Codex MCP servers."],
17
+ ["codex_fast", "Toggle Codex fast mode."],
18
+ ["codex_model", "List or switch the Codex model."],
19
+ ["codex_permissions", "Show Codex permissions and account status."],
20
+ ["codex_init", "Forward /init to Codex."],
21
+ ["codex_diff", "Forward /diff to Codex."],
22
+ ["codex_rename", "Rename the Codex thread and sync the channel name when possible."],
23
+ ] as const;
24
+
25
+ const plugin = {
26
+ id: "openclaw-codex-app-server",
27
+ name: "OpenClaw App Server",
28
+ description: "Codex App Server as an OpenClaw plugin.",
29
+ register(api: OpenClawPluginApi) {
30
+ const controller = new CodexPluginController(api);
31
+
32
+ api.registerService(controller.createService());
33
+
34
+ api.on("inbound_claim", async (event) => {
35
+ return await controller.handleInboundClaim(event);
36
+ });
37
+
38
+ api.registerInteractiveHandler({
39
+ channel: "telegram",
40
+ namespace: INTERACTIVE_NAMESPACE,
41
+ handler: async (ctx) => {
42
+ await controller.handleTelegramInteractive(ctx);
43
+ return { handled: true };
44
+ },
45
+ });
46
+
47
+ api.registerInteractiveHandler({
48
+ channel: "discord",
49
+ namespace: INTERACTIVE_NAMESPACE,
50
+ handler: async (ctx) => {
51
+ await controller.handleDiscordInteractive(ctx);
52
+ return { handled: true };
53
+ },
54
+ });
55
+
56
+ for (const [name, description] of COMMANDS) {
57
+ api.registerCommand({
58
+ name,
59
+ description,
60
+ acceptsArgs: true,
61
+ handler: async (ctx) => {
62
+ return await controller.handleCommand(name, ctx);
63
+ },
64
+ });
65
+ }
66
+ },
67
+ };
68
+
69
+ export default plugin;
@@ -0,0 +1,105 @@
1
+ {
2
+ "id": "openclaw-codex-app-server",
3
+ "name": "OpenClaw Codex App Server",
4
+ "description": "Codex App Server as an OpenClaw plugin with bound Telegram and Discord conversations.",
5
+ "configSchema": {
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "enabled": {
10
+ "type": "boolean"
11
+ },
12
+ "transport": {
13
+ "type": "string",
14
+ "enum": [
15
+ "stdio",
16
+ "websocket"
17
+ ]
18
+ },
19
+ "command": {
20
+ "type": "string"
21
+ },
22
+ "args": {
23
+ "type": "array",
24
+ "items": {
25
+ "type": "string"
26
+ }
27
+ },
28
+ "url": {
29
+ "type": "string"
30
+ },
31
+ "authToken": {
32
+ "type": "string"
33
+ },
34
+ "headers": {
35
+ "type": "object",
36
+ "additionalProperties": {
37
+ "type": "string"
38
+ }
39
+ },
40
+ "requestTimeoutMs": {
41
+ "type": "number",
42
+ "minimum": 100
43
+ },
44
+ "inputTimeoutMs": {
45
+ "type": "number",
46
+ "minimum": 1000
47
+ },
48
+ "defaultWorkspaceDir": {
49
+ "type": "string"
50
+ },
51
+ "defaultModel": {
52
+ "type": "string"
53
+ },
54
+ "defaultServiceTier": {
55
+ "type": "string"
56
+ }
57
+ }
58
+ },
59
+ "uiHints": {
60
+ "enabled": {
61
+ "label": "Enabled"
62
+ },
63
+ "transport": {
64
+ "label": "Transport"
65
+ },
66
+ "command": {
67
+ "label": "Codex Command",
68
+ "help": "Used for stdio mode. Defaults to codex."
69
+ },
70
+ "args": {
71
+ "label": "Codex Args",
72
+ "advanced": true
73
+ },
74
+ "url": {
75
+ "label": "WebSocket URL"
76
+ },
77
+ "authToken": {
78
+ "label": "WebSocket Bearer Token",
79
+ "sensitive": true
80
+ },
81
+ "headers": {
82
+ "label": "Extra Headers",
83
+ "advanced": true
84
+ },
85
+ "requestTimeoutMs": {
86
+ "label": "Request Timeout (ms)",
87
+ "advanced": true
88
+ },
89
+ "inputTimeoutMs": {
90
+ "label": "Input Timeout (ms)",
91
+ "advanced": true
92
+ },
93
+ "defaultWorkspaceDir": {
94
+ "label": "Default Workspace Dir"
95
+ },
96
+ "defaultModel": {
97
+ "label": "Default Model",
98
+ "advanced": true
99
+ },
100
+ "defaultServiceTier": {
101
+ "label": "Default Service Tier",
102
+ "advanced": true
103
+ }
104
+ }
105
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "openclaw-codex-app-server",
3
+ "version": "0.0.0",
4
+ "description": "OpenClaw plugin for Codex App Server conversations",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "openclaw": {
8
+ "extensions": [
9
+ "./index.ts"
10
+ ]
11
+ },
12
+ "peerDependencies": {
13
+ "openclaw": "*"
14
+ },
15
+ "dependencies": {
16
+ "ws": "^8.18.3"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^24.6.0",
20
+ "openclaw": "2026.3.13",
21
+ "typescript": "^5.9.2",
22
+ "vitest": "^3.2.4"
23
+ },
24
+ "scripts": {
25
+ "test": "vitest run",
26
+ "typecheck": "tsc --noEmit"
27
+ }
28
+ }