Skip to content

Commit b769964

Browse files
authored
feat(codex): support workspace-directory plugins (#104188)
* feat(codex): support workspace directory plugins * fix(codex): contain workspace catalog failures * chore(config): refresh documentation baseline
1 parent 4271b82 commit b769964

14 files changed

Lines changed: 755 additions & 97 deletions
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
e3ad73cabe4197da73e8bfac98933a647b821d3e876d5547a48ebb26d7d635a7 config-baseline.json
1+
2788a2f397b519b111105ce543db300c1cdc4c3d67993ce31c8e4aa918dc5279 config-baseline.json
22
1b4ea34ca4c7edcbb29173dd7ebed0a35077dda23e95093c4e199606d505d179 config-baseline.core.json
3-
923a34547068a6fb3230c6a5744b430e81cf2a83e0028b3688d27eb6acd54bc0 config-baseline.channel.json
4-
c5e6594d765117bf4d0e060c0189afbcbd12e8eeec806e4bbab08fa53eb48ecf config-baseline.plugin.json
3+
82596aeb4c8d4cd18fefae554ff4d0c9e2cd82895b53d460db8f8ceb819f0ef6 config-baseline.channel.json
4+
168e3c52da484c235fbc451dead71af16c3bee0c0186c460e5b4b4af70a496df config-baseline.plugin.json

docs/gateway/configuration-reference.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ conversation bindings, or any non-Codex harness.
310310
currently accessible app connected to the authenticated Codex account in
311311
each new native Codex thread. Default: `false`.
312312
- `plugins.entries.codex.config.codexPlugins.allow_destructive_actions`:
313-
default destructive-action policy for migrated plugin app elicitations.
313+
default destructive-action policy for configured plugin app elicitations.
314314
Use `true` to accept safe Codex approval schemas without prompting, `false`
315315
to decline them, `"auto"` to route Codex-required approvals through OpenClaw
316316
plugin approvals, or `"ask"` to prompt for every plugin write/destructive
@@ -319,12 +319,17 @@ conversation bindings, or any non-Codex harness.
319319
approvals reviewer for that app before the Codex thread starts.
320320
Default: `true`.
321321
- `plugins.entries.codex.config.codexPlugins.plugins.<key>.enabled`: enables a
322-
migrated plugin entry when global `codexPlugins.enabled` is also true.
322+
configured plugin entry when global `codexPlugins.enabled` is also true.
323323
Default: `true` for explicit entries.
324324
- `plugins.entries.codex.config.codexPlugins.plugins.<key>.marketplaceName`:
325-
stable marketplace identity. V1 only supports `"openai-curated"`.
325+
stable marketplace identity, required with `pluginName` for every resolved
326+
entry. Supports `"openai-curated"` and `"workspace-directory"`. Entries
327+
missing either identity field are ignored.
326328
- `plugins.entries.codex.config.codexPlugins.plugins.<key>.pluginName`: stable
327-
Codex plugin identity from migration, for example `"google-calendar"`.
329+
Codex plugin identity, required with `marketplaceName`. A
330+
`workspace-directory` entry must use the exact marketplace-qualified
331+
`summary.id` returned by `plugin/list`, for example
332+
`"example-plugin@workspace-directory"`.
328333
- `plugins.entries.codex.config.codexPlugins.plugins.<key>.allow_destructive_actions`:
329334
per-plugin destructive-action override. When omitted, the global
330335
`allow_destructive_actions` value is used. The per-plugin value accepts the
@@ -335,10 +340,17 @@ to the human reviewer. Other apps and non-app thread approvals keep their
335340
configured reviewer, so mixed plugin policies do not inherit `"ask"` behavior.
336341

337342
`codexPlugins.enabled` is the global enablement directive. Explicit plugin
338-
entries written by migration are the durable install and repair eligibility set.
339-
`plugins["*"]` is not supported, there is no `install` switch, and local
340-
`marketplacePath` values are intentionally not config fields because they are
341-
host-specific.
343+
entries written by migration are the durable curated install and repair
344+
eligibility set. Manually configured `workspace-directory` entries must already
345+
be installed and enabled, and their owned apps must be accessible; OpenClaw
346+
does not install or authenticate them. If Codex rejects the explicit workspace
347+
catalog request, enabled workspace entries fail closed with
348+
`marketplace_missing` while curated entries from the default catalog remain
349+
available. `plugins["*"]` is not supported, there is no `install` switch, and
350+
local `marketplacePath` values are intentionally not config fields because they
351+
are host-specific. See
352+
[Native Codex plugins](/plugins/codex-native-plugins) for app-server version and
353+
readiness requirements.
342354

343355
`app/list` readiness checks are cached for one hour and refreshed
344356
asynchronously when stale. Codex thread app config is computed at Codex harness

docs/plugins/codex-native-plugins.md

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
2-
summary: "Configure migrated native Codex plugins for Codex-mode OpenClaw agents"
2+
summary: "Configure native Codex plugins for Codex-mode OpenClaw agents"
33
title: "Native Codex plugins"
44
read_when:
55
- You want Codex-mode OpenClaw agents to use native Codex plugins
66
- You are migrating source-installed openai-curated Codex plugins
7+
- You are configuring an existing workspace-directory Codex plugin
78
- You are troubleshooting codexPlugins, app inventory, destructive actions, or plugin app diagnostics
89
---
910

@@ -23,8 +24,12 @@ working.
2324
- `plugins.entries.codex.config.codexPlugins.enabled` is `true`.
2425
- The target Codex app-server can see the expected marketplace, plugin, and
2526
app inventory.
26-
- V1 supports only `openai-curated` plugins that migration observed as
27+
- Migration supports only `openai-curated` plugins that it observed as
2728
source-installed in the source Codex home.
29+
- Manually configured `workspace-directory` plugins require a Codex app-server
30+
whose `plugin/list` accepts `marketplaceKinds` and whose pathless workspace
31+
summaries include `remotePluginId`. The plugin must already be installed and
32+
enabled, and its owned apps must be accessible in `app/list`.
2833

2934
`codexPlugins` has no effect on OpenClaw-provider runs, ACP conversation
3035
bindings, or other harnesses, because those paths never create Codex
@@ -86,6 +91,44 @@ config looks like this:
8691
}
8792
```
8893

94+
Migration remains limited to `openai-curated`. To use an existing
95+
`workspace-directory` plugin, add it manually with the exact
96+
marketplace-qualified `summary.id` returned by `plugin/list`. For example, if
97+
Codex returns `example-plugin@workspace-directory`, configure that complete
98+
value instead of its display name:
99+
100+
```json5
101+
{
102+
plugins: {
103+
entries: {
104+
codex: {
105+
enabled: true,
106+
config: {
107+
codexPlugins: {
108+
enabled: true,
109+
plugins: {
110+
"example-plugin": {
111+
enabled: true,
112+
marketplaceName: "workspace-directory",
113+
pluginName: "example-plugin@workspace-directory",
114+
},
115+
},
116+
},
117+
},
118+
},
119+
},
120+
},
121+
}
122+
```
123+
124+
OpenClaw does not call `plugin/install` or start authentication for a
125+
`workspace-directory` plugin. Install, enable, and authenticate it in Codex
126+
before adding or enabling the OpenClaw policy. OpenClaw keeps apps hidden when
127+
the response omits the exact marketplace, plugin ID, detail ID, or app-readiness
128+
evidence. If Codex rejects the explicit workspace `plugin/list` request,
129+
OpenClaw reports `marketplace_missing` for each enabled workspace plugin and
130+
keeps any independently discovered curated plugins available.
131+
89132
After a `codexPlugins` change, new Codex conversations pick up the updated
90133
app set automatically. Run `/new` or `/reset` to refresh the current
91134
conversation. A gateway restart is not required for plugin enable/disable
@@ -112,20 +155,23 @@ from `plugins.entries.codex.config.codexPlugins.plugins`.
112155
gateway client with the `operator.admin` scope can run them.
113156

114157
Enabling a configured plugin also turns on the global `codexPlugins.enabled`
115-
switch. If the plugin was written disabled because migration returned
158+
switch. If a curated plugin was written disabled because migration returned
116159
`auth_required`, reauthorize the app in Codex before enabling it in OpenClaw.
160+
For a `workspace-directory` entry, enabling it here changes only OpenClaw
161+
policy; the plugin and app must already be active in Codex.
117162

118163
## How native plugin setup works
119164

120165
The integration tracks three states:
121166

122-
| State | Meaning |
123-
| ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
124-
| Installed | Codex has the local plugin bundle in the target app-server runtime. |
125-
| Enabled | OpenClaw config allows the plugin for Codex harness turns. |
126-
| Accessible | Codex app-server confirms the plugin's app entries are available for the active account and map to the migrated plugin identity. |
167+
| State | Meaning |
168+
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
169+
| Installed | Codex has the plugin bundle in the target app-server runtime. |
170+
| Enabled | Codex reports the plugin enabled, and OpenClaw config allows it for Codex harness turns. |
171+
| Accessible | Codex app-server confirms the plugin's app entries are available for the active account and map to the configured plugin identity. |
127172

128-
Migration is the durable install/eligibility step:
173+
For `openai-curated` plugins, migration is the durable install/eligibility
174+
step:
129175

130176
- During planning, OpenClaw reads source Codex `plugin/read` details and
131177
checks that the source Codex app-server account is a ChatGPT subscription
@@ -141,17 +187,33 @@ Migration is the durable install/eligibility step:
141187
failures then fall through to the source app-inventory gate instead of
142188
skipping outright.
143189

144-
Runtime app inventory is the target-session accessibility check that runs
145-
after migration. Codex harness session setup computes a restrictive thread
146-
app config from the enabled and accessible plugin apps; it is not
147-
recomputed on every turn, so `/codex plugins enable`/`disable` only affect
190+
For `workspace-directory` plugins, setup happens outside OpenClaw. OpenClaw
191+
queries that marketplace only when at least one enabled workspace entry is
192+
configured, resolves each plugin by exact `summary.id`, and reuses the existing
193+
`plugin/read` ownership and `app/list` readiness checks. An uninstalled,
194+
disabled, inaccessible, or unauthenticated plugin exposes no apps; OpenClaw
195+
does not attempt installation or authentication.
196+
197+
Runtime app inventory is the target-session accessibility check for both
198+
migrated curated plugins and manually configured workspace plugins. Codex
199+
harness session setup computes a restrictive thread app config from the enabled
200+
and accessible plugin apps; it is not recomputed on every turn, so
201+
`/codex plugins enable`/`disable` only affect
148202
new Codex conversations. Use `/new` or `/reset` to pick up the change in the
149203
current conversation.
150204

151205
## V1 support boundary
152206

153207
- Only `openai-curated` plugins already installed in the source Codex
154208
app-server inventory are migration-eligible.
209+
- Runtime also supports explicit `workspace-directory` entries on app-server
210+
builds whose `plugin/list` implements `marketplaceKinds` and returns
211+
`remotePluginId` for pathless workspace summaries. These entries must use
212+
their exact marketplace-qualified `summary.id` and must already be installed,
213+
enabled, and app-accessible. A rejected workspace list request produces the
214+
existing per-plugin `marketplace_missing` diagnostic; missing marketplace,
215+
plugin, detail, or app evidence exposes no workspace app. Curated inventory
216+
from the default list request remains usable.
155217
- App-backed source plugins must pass the migration-time subscription gate.
156218
`--verify-plugin-apps` adds the source app-inventory gate. Subscription-gated
157219
accounts, and in verification mode inaccessible/disabled/missing source
@@ -163,9 +225,10 @@ current conversation.
163225
- `codexPlugins.enabled` is the only global enablement switch; there is no
164226
`plugins["*"]` wildcard or config key that grants arbitrary install
165227
authority.
166-
- Unsupported marketplaces, cached plugin bundles, hooks, and Codex config
167-
files are preserved in the migration report for manual review, not
168-
activated automatically.
228+
- Non-curated marketplaces, cached plugin bundles, hooks, and Codex config
229+
files are preserved in the migration report for manual review, not activated
230+
automatically. Runtime accepts manually configured `workspace-directory`
231+
entries; other marketplaces remain unsupported.
169232

170233
## App inventory and ownership
171234

@@ -179,11 +242,12 @@ Migration and runtime use separate cache keys:
179242
- Source migration verification uses the source Codex home and start
180243
options. It runs only with `--verify-plugin-apps` and forces a fresh
181244
source `app/list` traversal for that planning run.
182-
- Target runtime setup uses the target agent's Codex app-server identity
183-
when building the thread app config. Plugin activation invalidates that
245+
- Target runtime setup uses the target agent's Codex app-server identity when
246+
building the thread app config. Curated plugin activation invalidates that
184247
target cache key, then force-refreshes it after `plugin/install`.
248+
`workspace-directory` setup never runs this activation path.
185249

186-
A plugin app is exposed only when OpenClaw can map it back to the migrated
250+
A plugin app is exposed only when OpenClaw can map it back to the configured
187251
plugin through stable ownership: an exact app id from plugin detail, a known
188252
MCP server name, or unique stable metadata. Display-name-only or ambiguous
189253
ownership is excluded until the next inventory refresh proves ownership.
@@ -226,7 +290,7 @@ closed instead of falling back to an unrestricted default.
226290
## Thread app config
227291

228292
OpenClaw injects a restrictive `config.apps` patch for the Codex thread:
229-
`_default` is disabled, and only apps owned by enabled migrated plugins or
293+
`_default` is disabled, and only apps owned by enabled configured plugins or
230294
accessible account apps admitted by `allow_all_plugins` are enabled.
231295

232296
`destructive_enabled` on each app comes from the effective global or
@@ -244,7 +308,7 @@ controlled by each app's `destructive_enabled` policy.
244308

245309
## Destructive action policy
246310

247-
Destructive plugin elicitations are allowed by default for migrated Codex
311+
Destructive plugin elicitations are allowed by default for configured Codex
248312
plugins, while unsafe schemas and ambiguous ownership fail closed:
249313

250314
- Global `allow_destructive_actions` defaults to `true`.
@@ -276,10 +340,31 @@ plugins, while unsafe schemas and ambiguous ownership fail closed:
276340
| `app_inventory_unavailable` | Strict source app verification was requested but the source Codex app inventory refresh failed. | Fix source Codex app-server access, or retry without `--verify-plugin-apps` to accept the faster account-gated plan. |
277341
| `codex_subscription_required` | The source Codex app-server account was not a ChatGPT subscription account. | Log in to the Codex app with subscription auth, then rerun migration. |
278342
| `codex_account_unavailable` | The source Codex app-server account could not be read. | Fix source Codex app-server auth, or rerun with `--verify-plugin-apps` to let source app inventory decide eligibility. |
279-
| `marketplace_missing`, `plugin_missing` | The target Codex app-server cannot see the expected `openai-curated` marketplace or plugin. | Rerun migration against the target runtime, or inspect Codex app-server plugin status. |
343+
| `marketplace_missing`, `plugin_missing` | Marketplace or exact plugin unavailable; the explicit workspace catalog request may have been rejected; workspace apps fail closed. | Verify the compatible app-server contract and exact ID described below. |
344+
| `plugin_detail_unavailable` | OpenClaw could not read plugin ownership details. | Inspect the target app-server's `plugin/list` and `plugin/read` responses. |
345+
| `plugin_disabled` | Codex reports the plugin installed but disabled. | Curated activation may repair it; enable a workspace plugin in Codex before retrying. |
346+
| `plugin_activation_failed` | Plugin activation did not complete. | Use the attached diagnostic to distinguish marketplace, auth, refresh, or workspace-readiness failures. |
280347
| `app_inventory_missing`, `app_inventory_stale` | App readiness came from an empty or stale cache. | OpenClaw schedules an async refresh automatically; plugin apps stay excluded until ownership and readiness are known. |
281348
| `app_ownership_ambiguous` | App inventory only matched by display name. | The app stays hidden from the Codex thread until a later refresh proves ownership. |
282349

350+
**Workspace plugin is installed but not visible:** confirm the workspace
351+
`plugin/list` result reports the exact configured ID as installed and enabled,
352+
then confirm `app/list` reports every owned app accessible for the same Codex
353+
account. OpenClaw can enable an accessible app for the thread even when the
354+
account inventory currently reports that app disabled. If you changed that state after the gateway cached app
355+
inventory, wait for the one-hour cache refresh or restart the gateway, then use
356+
`/new` or `/reset`. OpenClaw does not repair or authenticate workspace plugins.
357+
If the explicit workspace list request is rejected, each enabled workspace
358+
entry reports `marketplace_missing`; unrelated curated entries still proceed
359+
from the default list response.
360+
361+
For `plugin_detail_unavailable`, a pathless workspace summary must include
362+
`remotePluginId`; OpenClaw keeps owned apps hidden when that selector or the
363+
subsequent `plugin/read` result is unavailable. For
364+
`plugin_activation_failed`, curated plugins may report a marketplace, auth, or
365+
post-install refresh failure. A workspace plugin reports this code when it is
366+
not already active; install, enable, and authenticate it outside OpenClaw.
367+
283368
**Config changed but the agent cannot see the plugin:** run `/codex plugins
284369
list` to confirm the configured state, then `/new` or `/reset`. Existing
285370
Codex thread bindings keep the app config they started with until OpenClaw

extensions/codex/openclaw.plugin.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@
161161
},
162162
"marketplaceName": {
163163
"type": "string",
164-
"enum": ["openai-curated"]
164+
"enum": ["openai-curated", "workspace-directory"]
165165
},
166166
"pluginName": {
167167
"type": "string"
@@ -464,7 +464,7 @@
464464
},
465465
"codexPlugins.enabled": {
466466
"label": "Enable Native Plugins",
467-
"help": "Expose explicit migrated Codex plugin entries to Codex harness turns.",
467+
"help": "Expose explicit Codex plugin entries to Codex harness turns.",
468468
"advanced": true
469469
},
470470
"codexPlugins.allow_all_plugins": {
@@ -478,8 +478,8 @@
478478
"advanced": true
479479
},
480480
"codexPlugins.plugins": {
481-
"label": "Migrated Plugin Entries",
482-
"help": "Explicit migration-authored plugin entries. The wildcard key * is not supported.",
481+
"label": "Plugin Entries",
482+
"help": "Explicit plugin entries. The wildcard key * is not supported.",
483483
"advanced": true
484484
},
485485
"supervision": {

0 commit comments

Comments
 (0)