@gakr-gakr/codex 0.1.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.
Files changed (86) hide show
  1. package/autobot.plugin.json +374 -0
  2. package/doctor-contract-api.ts +68 -0
  3. package/harness.ts +72 -0
  4. package/index.ts +124 -0
  5. package/media-understanding-provider.ts +521 -0
  6. package/package.json +40 -0
  7. package/prompt-overlay.ts +21 -0
  8. package/provider-catalog.ts +83 -0
  9. package/provider-discovery.ts +45 -0
  10. package/provider.ts +243 -0
  11. package/src/app-server/app-inventory-cache.ts +324 -0
  12. package/src/app-server/approval-bridge.ts +1211 -0
  13. package/src/app-server/auth-bridge.ts +614 -0
  14. package/src/app-server/capabilities.ts +27 -0
  15. package/src/app-server/client-factory.ts +24 -0
  16. package/src/app-server/client.ts +715 -0
  17. package/src/app-server/compact.ts +512 -0
  18. package/src/app-server/computer-use.ts +683 -0
  19. package/src/app-server/config.ts +1038 -0
  20. package/src/app-server/context-engine-projection.ts +403 -0
  21. package/src/app-server/dynamic-tool-diagnostics.ts +73 -0
  22. package/src/app-server/dynamic-tool-profile.ts +70 -0
  23. package/src/app-server/dynamic-tools.ts +623 -0
  24. package/src/app-server/elicitation-bridge.ts +783 -0
  25. package/src/app-server/event-projector.ts +2065 -0
  26. package/src/app-server/image-payload-sanitizer.ts +167 -0
  27. package/src/app-server/local-runtime-attribution.ts +39 -0
  28. package/src/app-server/managed-binary.ts +193 -0
  29. package/src/app-server/models.ts +172 -0
  30. package/src/app-server/native-hook-relay.ts +150 -0
  31. package/src/app-server/native-subagent-task-mirror.ts +497 -0
  32. package/src/app-server/plugin-activation.ts +283 -0
  33. package/src/app-server/plugin-app-cache-key.ts +74 -0
  34. package/src/app-server/plugin-approval-roundtrip.ts +122 -0
  35. package/src/app-server/plugin-inventory.ts +357 -0
  36. package/src/app-server/plugin-thread-config.ts +455 -0
  37. package/src/app-server/protocol-generated/json/DynamicToolCallParams.json +33 -0
  38. package/src/app-server/protocol-generated/json/v2/ErrorNotification.json +199 -0
  39. package/src/app-server/protocol-generated/json/v2/GetAccountResponse.json +102 -0
  40. package/src/app-server/protocol-generated/json/v2/ModelListResponse.json +227 -0
  41. package/src/app-server/protocol-generated/json/v2/ThreadResumeResponse.json +2630 -0
  42. package/src/app-server/protocol-generated/json/v2/ThreadStartResponse.json +2630 -0
  43. package/src/app-server/protocol-generated/json/v2/TurnCompletedNotification.json +1659 -0
  44. package/src/app-server/protocol-generated/json/v2/TurnStartResponse.json +1655 -0
  45. package/src/app-server/protocol-validators.ts +203 -0
  46. package/src/app-server/protocol.ts +520 -0
  47. package/src/app-server/rate-limit-cache.ts +48 -0
  48. package/src/app-server/rate-limits.ts +583 -0
  49. package/src/app-server/request.ts +73 -0
  50. package/src/app-server/run-attempt.ts +4862 -0
  51. package/src/app-server/session-binding.ts +398 -0
  52. package/src/app-server/session-history.ts +44 -0
  53. package/src/app-server/shared-client.ts +289 -0
  54. package/src/app-server/side-question.ts +1009 -0
  55. package/src/app-server/test-support.ts +48 -0
  56. package/src/app-server/thread-lifecycle.ts +959 -0
  57. package/src/app-server/timeout.ts +9 -0
  58. package/src/app-server/tool-progress-normalization.ts +77 -0
  59. package/src/app-server/trajectory.ts +368 -0
  60. package/src/app-server/transcript-mirror.ts +208 -0
  61. package/src/app-server/transport-stdio.ts +107 -0
  62. package/src/app-server/transport-websocket.ts +90 -0
  63. package/src/app-server/transport.ts +117 -0
  64. package/src/app-server/user-input-bridge.ts +316 -0
  65. package/src/app-server/version.ts +4 -0
  66. package/src/app-server/vision-tools.ts +12 -0
  67. package/src/command-account.ts +544 -0
  68. package/src/command-formatters.ts +426 -0
  69. package/src/command-handlers.ts +2021 -0
  70. package/src/command-plugins-management.ts +137 -0
  71. package/src/command-rpc.ts +142 -0
  72. package/src/commands.ts +65 -0
  73. package/src/conversation-binding-data.ts +124 -0
  74. package/src/conversation-binding.ts +561 -0
  75. package/src/conversation-control.ts +303 -0
  76. package/src/conversation-turn-collector.ts +186 -0
  77. package/src/conversation-turn-input.ts +106 -0
  78. package/src/migration/apply.ts +501 -0
  79. package/src/migration/helpers.ts +55 -0
  80. package/src/migration/plan.ts +461 -0
  81. package/src/migration/provider.ts +41 -0
  82. package/src/migration/source.ts +643 -0
  83. package/src/migration/targets.ts +25 -0
  84. package/src/node-cli-sessions.ts +711 -0
  85. package/test-api.ts +95 -0
  86. package/tsconfig.json +16 -0
@@ -0,0 +1,374 @@
1
+ {
2
+ "id": "codex",
3
+ "name": "Codex",
4
+ "description": "Codex app-server harness and Codex-managed GPT model catalog.",
5
+ "providers": ["codex"],
6
+ "contracts": {
7
+ "mediaUnderstandingProviders": ["codex"],
8
+ "migrationProviders": ["codex"]
9
+ },
10
+ "mediaUnderstandingProviderMetadata": {
11
+ "codex": {
12
+ "capabilities": ["image"],
13
+ "defaultModels": {
14
+ "image": "gpt-5.5"
15
+ }
16
+ }
17
+ },
18
+ "providerCatalogEntry": "./provider-discovery.ts",
19
+ "syntheticAuthRefs": ["codex"],
20
+ "nonSecretAuthMarkers": ["codex-app-server"],
21
+ "activation": {
22
+ "onStartup": false,
23
+ "onAgentHarnesses": ["codex"]
24
+ },
25
+ "commandAliases": [
26
+ {
27
+ "name": "codex",
28
+ "kind": "runtime-slash",
29
+ "cliCommand": "plugins"
30
+ }
31
+ ],
32
+ "configSchema": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "properties": {
36
+ "codexDynamicToolsLoading": {
37
+ "type": "string",
38
+ "enum": ["searchable", "direct"],
39
+ "default": "searchable"
40
+ },
41
+ "codexDynamicToolsExclude": {
42
+ "type": "array",
43
+ "items": { "type": "string" },
44
+ "default": []
45
+ },
46
+ "discovery": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "properties": {
50
+ "enabled": { "type": "boolean" },
51
+ "timeoutMs": {
52
+ "type": "number",
53
+ "minimum": 1,
54
+ "default": 2500
55
+ }
56
+ }
57
+ },
58
+ "computerUse": {
59
+ "type": "object",
60
+ "additionalProperties": false,
61
+ "properties": {
62
+ "enabled": {
63
+ "type": "boolean",
64
+ "default": false
65
+ },
66
+ "autoInstall": {
67
+ "type": "boolean",
68
+ "default": false
69
+ },
70
+ "marketplaceDiscoveryTimeoutMs": {
71
+ "type": "number",
72
+ "minimum": 1,
73
+ "default": 60000
74
+ },
75
+ "marketplaceSource": {
76
+ "type": "string"
77
+ },
78
+ "marketplacePath": {
79
+ "type": "string"
80
+ },
81
+ "marketplaceName": {
82
+ "type": "string"
83
+ },
84
+ "pluginName": {
85
+ "type": "string",
86
+ "default": "computer-use"
87
+ },
88
+ "mcpServerName": {
89
+ "type": "string",
90
+ "default": "computer-use"
91
+ }
92
+ }
93
+ },
94
+ "codexPlugins": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "properties": {
98
+ "enabled": {
99
+ "type": "boolean",
100
+ "default": false
101
+ },
102
+ "allow_destructive_actions": {
103
+ "type": "boolean",
104
+ "default": true
105
+ },
106
+ "plugins": {
107
+ "type": "object",
108
+ "additionalProperties": {
109
+ "type": "object",
110
+ "additionalProperties": false,
111
+ "properties": {
112
+ "enabled": {
113
+ "type": "boolean"
114
+ },
115
+ "marketplaceName": {
116
+ "type": "string",
117
+ "enum": ["openai-curated"]
118
+ },
119
+ "pluginName": {
120
+ "type": "string"
121
+ },
122
+ "allow_destructive_actions": {
123
+ "type": "boolean"
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ },
130
+ "appServer": {
131
+ "type": "object",
132
+ "additionalProperties": false,
133
+ "properties": {
134
+ "mode": {
135
+ "type": "string",
136
+ "enum": ["yolo", "guardian"],
137
+ "default": "yolo"
138
+ },
139
+ "transport": {
140
+ "type": "string",
141
+ "enum": ["stdio", "websocket"],
142
+ "default": "stdio"
143
+ },
144
+ "command": { "type": "string" },
145
+ "args": {
146
+ "oneOf": [
147
+ {
148
+ "type": "array",
149
+ "items": { "type": "string" }
150
+ },
151
+ { "type": "string" }
152
+ ]
153
+ },
154
+ "url": { "type": "string" },
155
+ "authToken": { "type": "string" },
156
+ "headers": {
157
+ "type": "object",
158
+ "additionalProperties": { "type": "string" }
159
+ },
160
+ "clearEnv": {
161
+ "type": "array",
162
+ "items": { "type": "string" }
163
+ },
164
+ "codeModeOnly": {
165
+ "type": "boolean",
166
+ "default": false
167
+ },
168
+ "requestTimeoutMs": {
169
+ "type": "number",
170
+ "minimum": 1,
171
+ "default": 60000
172
+ },
173
+ "turnCompletionIdleTimeoutMs": {
174
+ "type": "number",
175
+ "minimum": 1,
176
+ "default": 60000
177
+ },
178
+ "approvalPolicy": {
179
+ "type": "string",
180
+ "enum": ["never", "on-request", "on-failure", "untrusted"]
181
+ },
182
+ "sandbox": {
183
+ "type": "string",
184
+ "enum": ["read-only", "workspace-write", "danger-full-access"]
185
+ },
186
+ "approvalsReviewer": {
187
+ "type": "string",
188
+ "enum": ["user", "auto_review", "guardian_subagent"]
189
+ },
190
+ "serviceTier": { "type": ["string", "null"] },
191
+ "defaultWorkspaceDir": {
192
+ "type": "string"
193
+ }
194
+ }
195
+ }
196
+ }
197
+ },
198
+ "uiHints": {
199
+ "codexDynamicToolsLoading": {
200
+ "label": "Dynamic Tools Loading",
201
+ "help": "Use searchable to defer AutoBot dynamic tools behind Codex tool search, or direct to expose them in the initial context.",
202
+ "advanced": true
203
+ },
204
+ "codexDynamicToolsExclude": {
205
+ "label": "Dynamic Tool Excludes",
206
+ "help": "Additional AutoBot dynamic tool names to omit from Codex app-server turns.",
207
+ "advanced": true
208
+ },
209
+ "discovery": {
210
+ "label": "Model Discovery",
211
+ "help": "Plugin-owned controls for discovering Codex app-server models."
212
+ },
213
+ "discovery.enabled": {
214
+ "label": "Enable Discovery",
215
+ "help": "When false, AutoBot keeps the Codex harness available but uses the bundled fallback model list."
216
+ },
217
+ "discovery.timeoutMs": {
218
+ "label": "Discovery Timeout",
219
+ "help": "Maximum time to wait for Codex app-server model discovery before falling back to the bundled model list.",
220
+ "advanced": true
221
+ },
222
+ "computerUse": {
223
+ "label": "Computer Use",
224
+ "help": "Controls Codex app-server setup for the Computer Use plugin.",
225
+ "advanced": true
226
+ },
227
+ "computerUse.enabled": {
228
+ "label": "Enable Computer Use",
229
+ "help": "When true, Codex-mode turns require the configured Computer Use MCP server to be available.",
230
+ "advanced": true
231
+ },
232
+ "computerUse.autoInstall": {
233
+ "label": "Auto Install",
234
+ "help": "Install the configured Computer Use plugin when Codex-mode turns start.",
235
+ "advanced": true
236
+ },
237
+ "computerUse.marketplaceDiscoveryTimeoutMs": {
238
+ "label": "Marketplace Discovery Timeout",
239
+ "help": "Maximum time to wait for Codex app-server to finish loading marketplaces during Computer Use install.",
240
+ "advanced": true
241
+ },
242
+ "computerUse.marketplaceSource": {
243
+ "label": "Marketplace Source",
244
+ "help": "Optional Codex marketplace source to add before installing Computer Use.",
245
+ "advanced": true
246
+ },
247
+ "computerUse.marketplacePath": {
248
+ "label": "Marketplace Path",
249
+ "help": "Optional local Codex marketplace file path containing the Computer Use plugin.",
250
+ "advanced": true
251
+ },
252
+ "computerUse.marketplaceName": {
253
+ "label": "Marketplace Name",
254
+ "help": "Optional registered Codex marketplace name containing the Computer Use plugin.",
255
+ "advanced": true
256
+ },
257
+ "computerUse.pluginName": {
258
+ "label": "Plugin Name",
259
+ "help": "Codex marketplace plugin name for Computer Use.",
260
+ "advanced": true
261
+ },
262
+ "computerUse.mcpServerName": {
263
+ "label": "MCP Server Name",
264
+ "help": "MCP server name exposed by the Computer Use plugin.",
265
+ "advanced": true
266
+ },
267
+ "codexPlugins": {
268
+ "label": "Native Codex Plugins",
269
+ "help": "Controls native Codex plugin availability for Codex harness turns.",
270
+ "advanced": true
271
+ },
272
+ "codexPlugins.enabled": {
273
+ "label": "Enable Native Plugins",
274
+ "help": "Expose explicit migrated Codex plugin entries to Codex harness turns.",
275
+ "advanced": true
276
+ },
277
+ "codexPlugins.allow_destructive_actions": {
278
+ "label": "Allow Destructive Plugin Actions",
279
+ "help": "Default policy for plugin app write or destructive action elicitations. Defaults to true.",
280
+ "advanced": true
281
+ },
282
+ "codexPlugins.plugins": {
283
+ "label": "Migrated Plugin Entries",
284
+ "help": "Explicit migration-authored plugin entries. The wildcard key * is not supported.",
285
+ "advanced": true
286
+ },
287
+ "appServer": {
288
+ "label": "App Server",
289
+ "help": "Runtime controls for connecting to Codex app-server.",
290
+ "advanced": true
291
+ },
292
+ "appServer.mode": {
293
+ "label": "Execution Mode",
294
+ "help": "Use yolo for unchained local execution or guardian for Codex guardian-reviewed approvals.",
295
+ "advanced": true
296
+ },
297
+ "appServer.transport": {
298
+ "label": "Transport",
299
+ "help": "Use stdio to spawn Codex locally, or websocket to connect to an already-running app-server.",
300
+ "advanced": true
301
+ },
302
+ "appServer.command": {
303
+ "label": "Command",
304
+ "help": "Executable used for stdio transport. Leave unset to use AutoBot's managed Codex binary.",
305
+ "advanced": true
306
+ },
307
+ "appServer.args": {
308
+ "label": "Arguments",
309
+ "help": "Arguments used for stdio transport. Defaults to app-server --listen stdio://.",
310
+ "advanced": true
311
+ },
312
+ "appServer.url": {
313
+ "label": "WebSocket URL",
314
+ "help": "Codex app-server WebSocket URL when transport is websocket.",
315
+ "advanced": true
316
+ },
317
+ "appServer.authToken": {
318
+ "label": "Auth Token",
319
+ "help": "Bearer token sent to the WebSocket app-server.",
320
+ "sensitive": true,
321
+ "advanced": true
322
+ },
323
+ "appServer.headers": {
324
+ "label": "Headers",
325
+ "help": "Additional headers sent to the WebSocket app-server.",
326
+ "advanced": true
327
+ },
328
+ "appServer.clearEnv": {
329
+ "label": "Clear Environment",
330
+ "help": "Environment variable names removed from the spawned stdio app-server process after overrides are applied.",
331
+ "advanced": true
332
+ },
333
+ "appServer.codeModeOnly": {
334
+ "label": "Code Mode Only",
335
+ "help": "Expose Codex's code-mode-only tool surface. AutoBot dynamic tools remain available through Codex nested tool calls.",
336
+ "advanced": true
337
+ },
338
+ "appServer.requestTimeoutMs": {
339
+ "label": "Request Timeout",
340
+ "help": "Maximum time to wait for Codex app-server control-plane requests.",
341
+ "advanced": true
342
+ },
343
+ "appServer.turnCompletionIdleTimeoutMs": {
344
+ "label": "Turn Completion Idle Timeout",
345
+ "help": "Maximum quiet time after Codex accepts a turn or after a turn-scoped app-server request before AutoBot interrupts the turn while waiting for turn/completed.",
346
+ "advanced": true
347
+ },
348
+ "appServer.approvalPolicy": {
349
+ "label": "Approval Policy",
350
+ "help": "Codex native approval policy sent to thread start, resume, and turns.",
351
+ "advanced": true
352
+ },
353
+ "appServer.sandbox": {
354
+ "label": "Sandbox",
355
+ "help": "Codex native sandbox mode sent to thread start and resume.",
356
+ "advanced": true
357
+ },
358
+ "appServer.approvalsReviewer": {
359
+ "label": "Approvals Reviewer",
360
+ "help": "Use user approvals or Codex auto_review for native app-server approvals. guardian_subagent remains accepted for compatibility.",
361
+ "advanced": true
362
+ },
363
+ "appServer.serviceTier": {
364
+ "label": "Service Tier",
365
+ "help": "Optional Codex app-server service tier. Use priority, flex, or null. Legacy fast is accepted as priority.",
366
+ "advanced": true
367
+ },
368
+ "appServer.defaultWorkspaceDir": {
369
+ "label": "Default Workspace",
370
+ "help": "Workspace used by /codex bind when --cwd is omitted.",
371
+ "advanced": true
372
+ }
373
+ }
374
+ }
@@ -0,0 +1,68 @@
1
+ import type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
2
+ import type { DoctorSessionRouteStateOwner } from "autobot/plugin-sdk/runtime-doctor";
3
+
4
+ type LegacyConfigRule = {
5
+ path: string[];
6
+ message: string;
7
+ match: (value: unknown) => boolean;
8
+ };
9
+
10
+ function asRecord(value: unknown): Record<string, unknown> | null {
11
+ return value && typeof value === "object" && !Array.isArray(value)
12
+ ? (value as Record<string, unknown>)
13
+ : null;
14
+ }
15
+
16
+ function hasRetiredDynamicToolsProfile(value: unknown): boolean {
17
+ return Object.prototype.hasOwnProperty.call(asRecord(value) ?? {}, "codexDynamicToolsProfile");
18
+ }
19
+
20
+ export const legacyConfigRules: LegacyConfigRule[] = [
21
+ {
22
+ path: ["plugins", "entries", "codex", "config"],
23
+ message:
24
+ 'plugins.entries.codex.config.codexDynamicToolsProfile is retired; Codex app-server always keeps Codex-native workspace tools native. Run "autobot doctor --fix".',
25
+ match: hasRetiredDynamicToolsProfile,
26
+ },
27
+ ];
28
+
29
+ export function normalizeCompatibilityConfig({ cfg }: { cfg: AutoBotConfig }): {
30
+ config: AutoBotConfig;
31
+ changes: string[];
32
+ } {
33
+ const rawEntry = asRecord(cfg.plugins?.entries?.codex);
34
+ const rawPluginConfig = asRecord(rawEntry?.config);
35
+ if (!rawPluginConfig || !hasRetiredDynamicToolsProfile(rawPluginConfig)) {
36
+ return { config: cfg, changes: [] };
37
+ }
38
+
39
+ const nextConfig = structuredClone(cfg) as AutoBotConfig & {
40
+ plugins?: Record<string, unknown>;
41
+ };
42
+ const nextPlugins = asRecord(nextConfig.plugins);
43
+ const nextEntries = asRecord(nextPlugins?.entries);
44
+ const nextEntry = asRecord(nextEntries?.codex);
45
+ const nextPluginConfig = asRecord(nextEntry?.config);
46
+ if (!nextPluginConfig) {
47
+ return { config: cfg, changes: [] };
48
+ }
49
+
50
+ delete nextPluginConfig.codexDynamicToolsProfile;
51
+ return {
52
+ config: nextConfig,
53
+ changes: [
54
+ "Removed retired plugins.entries.codex.config.codexDynamicToolsProfile; Codex app-server always keeps Codex-native workspace tools native.",
55
+ ],
56
+ };
57
+ }
58
+
59
+ export const sessionRouteStateOwners: DoctorSessionRouteStateOwner[] = [
60
+ {
61
+ id: "codex",
62
+ label: "Codex",
63
+ providerIds: ["codex", "codex-cli", "openai-codex"],
64
+ runtimeIds: ["codex", "codex-cli"],
65
+ cliSessionKeys: ["codex-cli"],
66
+ authProfilePrefixes: ["codex:", "codex-cli:", "openai-codex:"],
67
+ },
68
+ ];
package/harness.ts ADDED
@@ -0,0 +1,72 @@
1
+ import type { AgentHarness } from "autobot/plugin-sdk/agent-harness-runtime";
2
+ import type {
3
+ CodexAppServerListModelsOptions,
4
+ CodexAppServerModel,
5
+ CodexAppServerModelListResult,
6
+ } from "./src/app-server/models.js";
7
+
8
+ const DEFAULT_CODEX_HARNESS_PROVIDER_IDS = new Set(["codex"]);
9
+
10
+ export type { CodexAppServerListModelsOptions, CodexAppServerModel, CodexAppServerModelListResult };
11
+
12
+ export function createCodexAppServerAgentHarness(options?: {
13
+ id?: string;
14
+ label?: string;
15
+ providerIds?: Iterable<string>;
16
+ pluginConfig?: unknown;
17
+ resolvePluginConfig?: () => unknown;
18
+ }): AgentHarness {
19
+ const providerIds = new Set(
20
+ [...(options?.providerIds ?? DEFAULT_CODEX_HARNESS_PROVIDER_IDS)].map((id) =>
21
+ id.trim().toLowerCase(),
22
+ ),
23
+ );
24
+ return {
25
+ id: options?.id ?? "codex",
26
+ label: options?.label ?? "Codex agent harness",
27
+ deliveryDefaults: {
28
+ sourceVisibleReplies: "message_tool",
29
+ },
30
+ supports: (ctx) => {
31
+ const provider = ctx.provider.trim().toLowerCase();
32
+ if (providerIds.has(provider)) {
33
+ return { supported: true, priority: 100 };
34
+ }
35
+ return {
36
+ supported: false,
37
+ reason: `provider is not one of: ${[...providerIds].toSorted().join(", ")}`,
38
+ };
39
+ },
40
+ runAttempt: async (params) => {
41
+ const { runCodexAppServerAttempt } = await import("./src/app-server/run-attempt.js");
42
+ return runCodexAppServerAttempt(params, {
43
+ pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
44
+ nativeHookRelay: { enabled: true },
45
+ });
46
+ },
47
+ runSideQuestion: async (params) => {
48
+ const { runCodexAppServerSideQuestion } = await import("./src/app-server/side-question.js");
49
+ return runCodexAppServerSideQuestion(params, {
50
+ pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
51
+ nativeHookRelay: { enabled: true },
52
+ });
53
+ },
54
+ compact: async (params) => {
55
+ const { maybeCompactCodexAppServerSession } = await import("./src/app-server/compact.js");
56
+ return maybeCompactCodexAppServerSession(params, {
57
+ pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
58
+ });
59
+ },
60
+ reset: async (params) => {
61
+ if (params.sessionFile) {
62
+ const { clearCodexAppServerBinding } = await import("./src/app-server/session-binding.js");
63
+ await clearCodexAppServerBinding(params.sessionFile);
64
+ }
65
+ },
66
+ dispose: async () => {
67
+ const { clearSharedCodexAppServerClientAndWait } =
68
+ await import("./src/app-server/shared-client.js");
69
+ await clearSharedCodexAppServerClientAndWait();
70
+ },
71
+ };
72
+ }
package/index.ts ADDED
@@ -0,0 +1,124 @@
1
+ import type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
2
+ import { mutateConfigFile } from "autobot/plugin-sdk/config-mutation";
3
+ import { resolveLivePluginConfigObject } from "autobot/plugin-sdk/plugin-config-runtime";
4
+ import { definePluginEntry } from "autobot/plugin-sdk/plugin-entry";
5
+ import { createCodexAppServerAgentHarness } from "./harness.js";
6
+ import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
7
+ import { buildCodexProvider } from "./provider.js";
8
+ import type { CodexPluginsConfigBlock } from "./src/command-plugins-management.js";
9
+ import { createCodexCommand } from "./src/commands.js";
10
+ import {
11
+ handleCodexConversationBindingResolved,
12
+ handleCodexConversationInboundClaim,
13
+ } from "./src/conversation-binding.js";
14
+ import { buildCodexMigrationProvider } from "./src/migration/provider.js";
15
+ import {
16
+ createCodexCliSessionNodeHostCommands,
17
+ createCodexCliSessionNodeInvokePolicies,
18
+ listCodexCliSessionsOnNode,
19
+ resumeCodexCliSessionOnNode,
20
+ resolveCodexCliSessionForBindingOnNode,
21
+ } from "./src/node-cli-sessions.js";
22
+
23
+ export default definePluginEntry({
24
+ id: "codex",
25
+ name: "Codex",
26
+ description: "Codex app-server harness and Codex-managed GPT model catalog.",
27
+ register(api) {
28
+ const resolveCurrentPluginConfig = () =>
29
+ resolveLivePluginConfigObject(
30
+ api.runtime.config?.current
31
+ ? () => api.runtime.config.current() as AutoBotConfig
32
+ : undefined,
33
+ "codex",
34
+ api.pluginConfig as Record<string, unknown>,
35
+ ) ?? api.pluginConfig;
36
+ api.registerAgentHarness(
37
+ createCodexAppServerAgentHarness({ resolvePluginConfig: resolveCurrentPluginConfig }),
38
+ );
39
+ api.registerProvider(buildCodexProvider({ pluginConfig: api.pluginConfig }));
40
+ api.registerMediaUnderstandingProvider(
41
+ buildCodexMediaUnderstandingProvider({ pluginConfig: api.pluginConfig }),
42
+ );
43
+ api.registerMigrationProvider(buildCodexMigrationProvider({ runtime: api.runtime }));
44
+ for (const command of createCodexCliSessionNodeHostCommands()) {
45
+ api.registerNodeHostCommand(command);
46
+ }
47
+ for (const policy of createCodexCliSessionNodeInvokePolicies()) {
48
+ api.registerNodeInvokePolicy(policy);
49
+ }
50
+ api.registerCommand(
51
+ createCodexCommand({
52
+ pluginConfig: api.pluginConfig,
53
+ deps: {
54
+ listCodexCliSessionsOnNode: (params) =>
55
+ listCodexCliSessionsOnNode({ runtime: api.runtime, ...params }),
56
+ resolveCodexCliSessionForBindingOnNode: (params) =>
57
+ resolveCodexCliSessionForBindingOnNode({ runtime: api.runtime, ...params }),
58
+ codexPluginsManagementIo: {
59
+ readConfig: () => {
60
+ const current = (api.runtime.config?.current?.() ?? {}) as AutoBotConfig;
61
+ const plugins = (current as Record<string, unknown>).plugins;
62
+ if (!plugins || typeof plugins !== "object") {
63
+ return Promise.resolve({});
64
+ }
65
+ const entries = (plugins as Record<string, unknown>).entries;
66
+ if (!entries || typeof entries !== "object") {
67
+ return Promise.resolve({});
68
+ }
69
+ const codexEntry = (entries as Record<string, unknown>).codex;
70
+ if (!codexEntry || typeof codexEntry !== "object") {
71
+ return Promise.resolve({});
72
+ }
73
+ const config = (codexEntry as Record<string, unknown>).config;
74
+ if (!config || typeof config !== "object") {
75
+ return Promise.resolve({});
76
+ }
77
+ const codexPlugins = (config as Record<string, unknown>).codexPlugins;
78
+ if (!codexPlugins || typeof codexPlugins !== "object") {
79
+ return Promise.resolve({});
80
+ }
81
+ const declared = (codexPlugins as Record<string, unknown>).plugins;
82
+ if (!declared || typeof declared !== "object") {
83
+ return Promise.resolve({
84
+ enabled: (codexPlugins as Record<string, unknown>).enabled === true,
85
+ });
86
+ }
87
+ return Promise.resolve({
88
+ enabled: (codexPlugins as Record<string, unknown>).enabled === true,
89
+ plugins: declared as Record<string, never>,
90
+ });
91
+ },
92
+ mutate: async (update) => {
93
+ await mutateConfigFile({
94
+ mutate: (draft) => {
95
+ const root = draft as Record<string, unknown>;
96
+ root.plugins = (root.plugins ?? {}) as Record<string, unknown>;
97
+ const pluginsBlock = root.plugins as Record<string, unknown>;
98
+ pluginsBlock.entries = (pluginsBlock.entries ?? {}) as Record<string, unknown>;
99
+ const entries = pluginsBlock.entries as Record<string, unknown>;
100
+ entries.codex = (entries.codex ?? {}) as Record<string, unknown>;
101
+ const codexEntry = entries.codex as Record<string, unknown>;
102
+ codexEntry.config = (codexEntry.config ?? {}) as Record<string, unknown>;
103
+ const config = codexEntry.config as Record<string, unknown>;
104
+ config.codexPlugins = (config.codexPlugins ?? {}) as Record<string, unknown>;
105
+ const codexPlugins = config.codexPlugins as Record<string, unknown>;
106
+ codexPlugins.plugins = (codexPlugins.plugins ?? {}) as Record<string, unknown>;
107
+ update(codexPlugins as CodexPluginsConfigBlock);
108
+ },
109
+ });
110
+ },
111
+ },
112
+ },
113
+ }),
114
+ );
115
+ api.on("inbound_claim", (event, ctx) =>
116
+ handleCodexConversationInboundClaim(event, ctx, {
117
+ pluginConfig: resolveCurrentPluginConfig(),
118
+ resumeCodexCliSessionOnNode: (params) =>
119
+ resumeCodexCliSessionOnNode({ runtime: api.runtime, ...params }),
120
+ }),
121
+ );
122
+ api.onConversationBindingResolved?.(handleCodexConversationBindingResolved);
123
+ },
124
+ });