@openclaw/codex 2026.5.4-beta.1 → 2026.5.4-beta.3

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.
@@ -1,124 +1,11 @@
1
- import { i as resolveCodexAppServerRuntimeOptions } from "./config-CkkoMeqF.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-B-1qT9nX.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-ByrA30No.js";
2
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-CkowdYbm.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BmhO5h8O.js";
4
+ import { a as formatComputerUseStatus, c as formatThreads, d as CODEX_CONTROL_METHODS, f as describeControlFailure, i as formatCodexStatus, l as readString, n as formatAccount, o as formatList, r as formatCodexDisplayText, s as formatModels, t as buildHelp } from "./command-formatters-PiJcdUbu.js";
5
5
  import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-DuJYTJQy.js";
6
- import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-LXwwffvV.js";
7
- import { i as requestCodexAppServerJson, n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-DtCrnbLb.js";
6
+ import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-CtHkMJfG.js";
7
+ import { a as readCodexComputerUseStatus, i as installCodexComputerUse, n as rememberCodexRateLimits, o as requestCodexAppServerJson } from "./rate-limit-cache-t6ebYmfS.js";
8
8
  import crypto from "node:crypto";
9
- //#region extensions/codex/src/command-formatters.ts
10
- function formatCodexStatus(probes) {
11
- const lines = [`Codex app-server: ${probes.models.ok || probes.account.ok || probes.limits.ok || probes.mcps.ok || probes.skills.ok ? "connected" : "unavailable"}`];
12
- if (probes.models.ok) lines.push(`Models: ${probes.models.value.models.map((model) => model.id).slice(0, 8).join(", ") || "none"}`);
13
- else lines.push(`Models: ${probes.models.error}`);
14
- lines.push(`Account: ${probes.account.ok ? summarizeAccount(probes.account.value) : probes.account.error}`);
15
- lines.push(`Rate limits: ${probes.limits.ok ? summarizeArrayLike(probes.limits.value) : probes.limits.error}`);
16
- lines.push(`MCP servers: ${probes.mcps.ok ? summarizeArrayLike(probes.mcps.value) : probes.mcps.error}`);
17
- lines.push(`Skills: ${probes.skills.ok ? summarizeArrayLike(probes.skills.value) : probes.skills.error}`);
18
- return lines.join("\n");
19
- }
20
- function formatModels(result) {
21
- if (result.models.length === 0) return "No Codex app-server models returned.";
22
- const lines = ["Codex models:", ...result.models.map((model) => `- ${model.id}${model.isDefault ? " (default)" : ""}`)];
23
- if (result.truncated) lines.push("- More models available; output truncated.");
24
- return lines.join("\n");
25
- }
26
- function formatThreads(response) {
27
- const threads = extractArray(response);
28
- if (threads.length === 0) return "No Codex threads returned.";
29
- return ["Codex threads:", ...threads.slice(0, 10).map((thread) => {
30
- const record = isJsonObject(thread) ? thread : {};
31
- const id = readString(record, "threadId") ?? readString(record, "id") ?? "<unknown>";
32
- const title = readString(record, "title") ?? readString(record, "name") ?? readString(record, "summary");
33
- const details = [
34
- readString(record, "model"),
35
- readString(record, "cwd"),
36
- readString(record, "updatedAt") ?? readString(record, "lastUpdatedAt")
37
- ].filter(Boolean);
38
- return `- ${id}${title ? ` - ${title}` : ""}${details.length > 0 ? ` (${details.join(", ")})` : ""}\n Resume: /codex resume ${id}`;
39
- })].join("\n");
40
- }
41
- function formatAccount(account, limits) {
42
- return [`Account: ${account.ok ? summarizeAccount(account.value) : account.error}`, `Rate limits: ${limits.ok ? summarizeArrayLike(limits.value) : limits.error}`].join("\n");
43
- }
44
- function formatComputerUseStatus(status) {
45
- const lines = [`Computer Use: ${status.ready ? "ready" : status.enabled ? "not ready" : "disabled"}`];
46
- lines.push(`Plugin: ${status.pluginName} (${computerUsePluginState(status)})`);
47
- lines.push(`MCP server: ${status.mcpServerName}${status.mcpServerAvailable ? ` (${status.tools.length} tools)` : " (unavailable)"}`);
48
- if (status.marketplaceName) lines.push(`Marketplace: ${status.marketplaceName}`);
49
- if (status.tools.length > 0) lines.push(`Tools: ${status.tools.slice(0, 8).join(", ")}`);
50
- lines.push(status.message);
51
- return lines.join("\n");
52
- }
53
- function computerUsePluginState(status) {
54
- if (!status.installed) return "not installed";
55
- return status.pluginEnabled ? "installed" : "installed, disabled";
56
- }
57
- function formatList(response, label) {
58
- const entries = extractArray(response);
59
- if (entries.length === 0) return `${label}: none returned.`;
60
- return [`${label}:`, ...entries.slice(0, 25).map((entry) => {
61
- const record = isJsonObject(entry) ? entry : {};
62
- return `- ${readString(record, "name") ?? readString(record, "id") ?? JSON.stringify(entry)}`;
63
- })].join("\n");
64
- }
65
- function buildHelp() {
66
- return [
67
- "Codex commands:",
68
- "- /codex status",
69
- "- /codex models",
70
- "- /codex threads [filter]",
71
- "- /codex resume <thread-id>",
72
- "- /codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]",
73
- "- /codex binding",
74
- "- /codex stop",
75
- "- /codex steer <message>",
76
- "- /codex model [model]",
77
- "- /codex fast [on|off|status]",
78
- "- /codex permissions [default|yolo|status]",
79
- "- /codex detach",
80
- "- /codex compact",
81
- "- /codex review",
82
- "- /codex diagnostics [note]",
83
- "- /codex computer-use [status|install]",
84
- "- /codex account",
85
- "- /codex mcp",
86
- "- /codex skills"
87
- ].join("\n");
88
- }
89
- function summarizeAccount(value) {
90
- if (!isJsonObject(value)) return "unavailable";
91
- const account = isJsonObject(value.account) ? value.account : value;
92
- if (readString(account, "type") === "amazonBedrock") return "Amazon Bedrock";
93
- return readString(account, "email") ?? readString(account, "accountEmail") ?? readString(account, "planType") ?? readString(account, "id") ?? "available";
94
- }
95
- function summarizeArrayLike(value) {
96
- const entries = extractArray(value);
97
- if (entries.length === 0) return "none returned";
98
- return `${entries.length}`;
99
- }
100
- function extractArray(value) {
101
- if (Array.isArray(value)) return value;
102
- if (!isJsonObject(value)) return [];
103
- for (const key of [
104
- "data",
105
- "items",
106
- "threads",
107
- "models",
108
- "skills",
109
- "servers",
110
- "rateLimits"
111
- ]) {
112
- const child = value[key];
113
- if (Array.isArray(child)) return child;
114
- }
115
- return [];
116
- }
117
- function readString(record, key) {
118
- const value = record[key];
119
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
120
- }
121
- //#endregion
122
9
  //#region extensions/codex/src/command-rpc.ts
123
10
  function requestOptions(pluginConfig, limit, config) {
124
11
  const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
@@ -219,29 +106,52 @@ async function handleCodexSubcommand(ctx, options) {
219
106
  const [subcommand = "status", ...rest] = splitArgs(ctx.args);
220
107
  const normalized = subcommand.toLowerCase();
221
108
  if (normalized === "help") return { text: buildHelp() };
222
- if (normalized === "status") return { text: formatCodexStatus(await deps.readCodexStatusProbes(options.pluginConfig, ctx.config)) };
223
- if (normalized === "models") return { text: formatModels(await deps.listCodexAppServerModels(deps.requestOptions(options.pluginConfig, 100, ctx.config))) };
109
+ if (normalized === "status") {
110
+ if (rest.length > 0) return { text: "Usage: /codex status" };
111
+ return { text: formatCodexStatus(await deps.readCodexStatusProbes(options.pluginConfig, ctx.config)) };
112
+ }
113
+ if (normalized === "models") {
114
+ if (rest.length > 0) return { text: "Usage: /codex models" };
115
+ return { text: formatModels(await deps.listCodexAppServerModels(deps.requestOptions(options.pluginConfig, 100, ctx.config))) };
116
+ }
224
117
  if (normalized === "threads") return { text: await buildThreads(deps, options.pluginConfig, rest.join(" ")) };
225
- if (normalized === "resume") return { text: await resumeThread(deps, ctx, options.pluginConfig, rest[0]) };
118
+ if (normalized === "resume") return { text: await resumeThread(deps, ctx, options.pluginConfig, rest) };
226
119
  if (normalized === "bind") return await bindConversation(deps, ctx, options.pluginConfig, rest);
227
- if (normalized === "detach" || normalized === "unbind") return { text: await detachConversation(deps, ctx) };
228
- if (normalized === "binding") return { text: await describeConversationBinding(deps, ctx) };
229
- if (normalized === "stop") return { text: await stopConversationTurn(deps, ctx, options.pluginConfig) };
120
+ if (normalized === "detach" || normalized === "unbind") {
121
+ if (rest.length > 0) return { text: "Usage: /codex detach" };
122
+ return { text: await detachConversation(deps, ctx) };
123
+ }
124
+ if (normalized === "binding") {
125
+ if (rest.length > 0) return { text: "Usage: /codex binding" };
126
+ return { text: await describeConversationBinding(deps, ctx) };
127
+ }
128
+ if (normalized === "stop") {
129
+ if (rest.length > 0) return { text: "Usage: /codex stop" };
130
+ return { text: await stopConversationTurn(deps, ctx, options.pluginConfig) };
131
+ }
230
132
  if (normalized === "steer") return { text: await steerConversationTurn(deps, ctx, options.pluginConfig, rest.join(" ")) };
231
- if (normalized === "model") return { text: await setConversationModel(deps, ctx, options.pluginConfig, rest.join(" ")) };
232
- if (normalized === "fast") return { text: await setConversationFastMode(deps, ctx, options.pluginConfig, rest[0]) };
233
- if (normalized === "permissions") return { text: await setConversationPermissions(deps, ctx, options.pluginConfig, rest[0]) };
234
- if (normalized === "compact") return { text: await startThreadAction(deps, ctx, options.pluginConfig, CODEX_CONTROL_METHODS.compact, "compaction") };
235
- if (normalized === "review") return { text: await startThreadAction(deps, ctx, options.pluginConfig, CODEX_CONTROL_METHODS.review, "review") };
133
+ if (normalized === "model") return { text: await setConversationModel(deps, ctx, options.pluginConfig, rest) };
134
+ if (normalized === "fast") return { text: await setConversationFastMode(deps, ctx, options.pluginConfig, rest) };
135
+ if (normalized === "permissions") return { text: await setConversationPermissions(deps, ctx, options.pluginConfig, rest) };
136
+ if (normalized === "compact") return { text: await startThreadAction(deps, ctx, options.pluginConfig, CODEX_CONTROL_METHODS.compact, "compaction", rest) };
137
+ if (normalized === "review") return { text: await startThreadAction(deps, ctx, options.pluginConfig, CODEX_CONTROL_METHODS.review, "review", rest) };
236
138
  if (normalized === "diagnostics") return await handleCodexDiagnosticsFeedback(deps, ctx, options.pluginConfig, rest.join(" "), "/codex diagnostics");
237
139
  if (normalized === "computer-use" || normalized === "computeruse") return { text: await handleComputerUseCommand(deps, options.pluginConfig, rest) };
238
- if (normalized === "mcp") return { text: formatList(await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.listMcpServers, { limit: 100 }), "MCP servers") };
239
- if (normalized === "skills") return { text: formatList(await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.listSkills, {}), "Codex skills") };
140
+ if (normalized === "mcp") {
141
+ if (rest.length > 0) return { text: "Usage: /codex mcp" };
142
+ return { text: formatList(await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.listMcpServers, { limit: 100 }), "MCP servers") };
143
+ }
144
+ if (normalized === "skills") {
145
+ if (rest.length > 0) return { text: "Usage: /codex skills" };
146
+ return { text: formatList(await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.listSkills, {}), "Codex skills") };
147
+ }
240
148
  if (normalized === "account") {
149
+ if (rest.length > 0) return { text: "Usage: /codex account" };
241
150
  const [account, limits] = await Promise.all([deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.account, { refreshToken: false }), deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.rateLimits, void 0)]);
151
+ if (limits.ok) rememberCodexRateLimits(limits.value);
242
152
  return { text: formatAccount(account, limits) };
243
153
  }
244
- return { text: `Unknown Codex command: ${subcommand}\n\n${buildHelp()}` };
154
+ return { text: `Unknown Codex command: ${formatCodexDisplayText(subcommand)}\n\n${buildHelp()}` };
245
155
  }
246
156
  async function handleComputerUseCommand(deps, pluginConfig, args) {
247
157
  const parsed = parseComputerUseArgs(args);
@@ -255,9 +165,9 @@ async function handleComputerUseCommand(deps, pluginConfig, args) {
255
165
  return formatComputerUseStatus(await deps.readCodexComputerUseStatus(params));
256
166
  }
257
167
  async function bindConversation(deps, ctx, pluginConfig, args) {
258
- if (!ctx.sessionFile) return { text: "Cannot bind Codex because this command did not include an OpenClaw session file." };
259
168
  const parsed = parseBindArgs(args);
260
169
  if (parsed.help) return { text: "Usage: /codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]" };
170
+ if (!ctx.sessionFile) return { text: "Cannot bind Codex because this command did not include an OpenClaw session file." };
261
171
  const workspaceDir = parsed.cwd ?? deps.resolveCodexDefaultWorkspaceDir(pluginConfig);
262
172
  const authProfileId = (await deps.readCodexAppServerBinding(ctx.sessionFile))?.authProfileId;
263
173
  const startParams = {
@@ -272,7 +182,7 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
272
182
  if (authProfileId) startParams.authProfileId = authProfileId;
273
183
  const data = await deps.startCodexConversationThread(startParams);
274
184
  const threadId = (await deps.readCodexAppServerBinding(ctx.sessionFile))?.threadId ?? parsed.threadId ?? "new thread";
275
- const summary = `Codex app-server thread ${threadId} in ${workspaceDir}`;
185
+ const summary = `Codex app-server thread ${formatCodexDisplayText(threadId)} in ${formatCodexDisplayText(workspaceDir)}`;
276
186
  let request;
277
187
  try {
278
188
  request = await ctx.requestConversationBinding({
@@ -284,10 +194,10 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
284
194
  await deps.clearCodexAppServerBinding(ctx.sessionFile);
285
195
  throw error;
286
196
  }
287
- if (request.status === "bound") return { text: `Bound this conversation to Codex thread ${threadId} in ${workspaceDir}.` };
197
+ if (request.status === "bound") return { text: `Bound this conversation to Codex thread ${formatCodexDisplayText(threadId)} in ${formatCodexDisplayText(workspaceDir)}.` };
288
198
  if (request.status === "pending") return request.reply;
289
199
  await deps.clearCodexAppServerBinding(ctx.sessionFile);
290
- return { text: request.message };
200
+ return { text: formatCodexDisplayText(request.message) };
291
201
  }
292
202
  async function detachConversation(deps, ctx) {
293
203
  const data = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
@@ -304,13 +214,13 @@ async function describeConversationBinding(deps, ctx) {
304
214
  const active = deps.readCodexConversationActiveTurn(data.sessionFile);
305
215
  return [
306
216
  "Codex conversation binding:",
307
- `- Thread: ${threadBinding?.threadId ?? "unknown"}`,
308
- `- Workspace: ${data.workspaceDir}`,
309
- `- Model: ${threadBinding?.model ?? "default"}`,
217
+ `- Thread: ${formatCodexDisplayText(threadBinding?.threadId ?? "unknown")}`,
218
+ `- Workspace: ${formatCodexDisplayText(data.workspaceDir)}`,
219
+ `- Model: ${formatCodexDisplayText(threadBinding?.model ?? "default")}`,
310
220
  `- Fast: ${threadBinding?.serviceTier === "fast" ? "on" : "off"}`,
311
221
  `- Permissions: ${threadBinding ? formatPermissionsMode(threadBinding) : "default"}`,
312
- `- Active run: ${active ? active.turnId : "none"}`,
313
- `- Session: ${data.sessionFile}`
222
+ `- Active run: ${formatCodexDisplayText(active ? active.turnId : "none")}`,
223
+ `- Session: ${formatCodexDisplayText(data.sessionFile)}`
314
224
  ].join("\n");
315
225
  }
316
226
  async function buildThreads(deps, pluginConfig, filter) {
@@ -319,9 +229,10 @@ async function buildThreads(deps, pluginConfig, filter) {
319
229
  ...filter.trim() ? { searchTerm: filter.trim() } : {}
320
230
  }));
321
231
  }
322
- async function resumeThread(deps, ctx, pluginConfig, threadId) {
232
+ async function resumeThread(deps, ctx, pluginConfig, args) {
233
+ const [threadId] = args;
323
234
  const normalizedThreadId = threadId?.trim();
324
- if (!normalizedThreadId) return "Usage: /codex resume <thread-id>";
235
+ if (!normalizedThreadId || args.length !== 1) return "Usage: /codex resume <thread-id>";
325
236
  if (!ctx.sessionFile) return "Cannot attach a Codex thread because this command did not include an OpenClaw session file.";
326
237
  const response = await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.resumeThread, {
327
238
  threadId: normalizedThreadId,
@@ -335,7 +246,7 @@ async function resumeThread(deps, ctx, pluginConfig, threadId) {
335
246
  model: isJsonObject(response) ? readString(response, "model") : void 0,
336
247
  modelProvider: isJsonObject(response) ? readString(response, "modelProvider") : void 0
337
248
  });
338
- return `Attached this OpenClaw session to Codex thread ${effectiveThreadId}.`;
249
+ return `Attached this OpenClaw session to Codex thread ${formatCodexDisplayText(effectiveThreadId)}.`;
339
250
  }
340
251
  async function stopConversationTurn(deps, ctx, pluginConfig) {
341
252
  const sessionFile = await resolveControlSessionFile(ctx);
@@ -354,13 +265,15 @@ async function steerConversationTurn(deps, ctx, pluginConfig, message) {
354
265
  message
355
266
  })).message;
356
267
  }
357
- async function setConversationModel(deps, ctx, pluginConfig, model) {
268
+ async function setConversationModel(deps, ctx, pluginConfig, args) {
269
+ if (args.length > 1) return "Usage: /codex model <model>";
358
270
  const sessionFile = await resolveControlSessionFile(ctx);
359
271
  if (!sessionFile) return "Cannot set Codex model because this command did not include an OpenClaw session file.";
272
+ const [model = ""] = args;
360
273
  const normalized = model.trim();
361
274
  if (!normalized) {
362
275
  const binding = await deps.readCodexAppServerBinding(sessionFile);
363
- return binding?.model ? `Codex model: ${binding.model}` : "Usage: /codex model <model>";
276
+ return binding?.model ? `Codex model: ${formatCodexDisplayText(binding.model)}` : "Usage: /codex model <model>";
364
277
  }
365
278
  return await deps.setCodexConversationModel({
366
279
  sessionFile,
@@ -368,9 +281,11 @@ async function setConversationModel(deps, ctx, pluginConfig, model) {
368
281
  model: normalized
369
282
  });
370
283
  }
371
- async function setConversationFastMode(deps, ctx, pluginConfig, value) {
284
+ async function setConversationFastMode(deps, ctx, pluginConfig, args) {
285
+ if (args.length > 1) return "Usage: /codex fast [on|off|status]";
372
286
  const sessionFile = await resolveControlSessionFile(ctx);
373
287
  if (!sessionFile) return "Cannot set Codex fast mode because this command did not include an OpenClaw session file.";
288
+ const value = args[0];
374
289
  const parsed = parseCodexFastModeArg(value);
375
290
  if (value && parsed == null && value.trim().toLowerCase() !== "status") return "Usage: /codex fast [on|off|status]";
376
291
  return await deps.setCodexConversationFastMode({
@@ -379,9 +294,11 @@ async function setConversationFastMode(deps, ctx, pluginConfig, value) {
379
294
  enabled: parsed
380
295
  });
381
296
  }
382
- async function setConversationPermissions(deps, ctx, pluginConfig, value) {
297
+ async function setConversationPermissions(deps, ctx, pluginConfig, args) {
298
+ if (args.length > 1) return "Usage: /codex permissions [default|yolo|status]";
383
299
  const sessionFile = await resolveControlSessionFile(ctx);
384
300
  if (!sessionFile) return "Cannot set Codex permissions because this command did not include an OpenClaw session file.";
301
+ const value = args[0];
385
302
  const parsed = parseCodexPermissionsModeArg(value);
386
303
  if (value && !parsed && value.trim().toLowerCase() !== "status") return "Usage: /codex permissions [default|yolo|status]";
387
304
  return await deps.setCodexConversationPermissions({
@@ -396,6 +313,7 @@ async function resolveControlSessionFile(ctx) {
396
313
  async function handleCodexDiagnosticsFeedback(deps, ctx, pluginConfig, args, commandPrefix) {
397
314
  if (ctx.senderIsOwner !== true) return { text: "Only an owner can send Codex diagnostics." };
398
315
  const parsed = parseDiagnosticsArgs(args);
316
+ if (parsed.action === "usage") return { text: formatDiagnosticsUsage(commandPrefix) };
399
317
  if (parsed.action === "confirm") return { text: await confirmCodexDiagnosticsFeedback(deps, ctx, pluginConfig, parsed.token) };
400
318
  if (parsed.action === "cancel") return { text: cancelCodexDiagnosticsFeedback(ctx, parsed.token) };
401
319
  if (ctx.diagnosticsUploadApproved === true) return { text: await sendCodexDiagnosticsFeedbackForContext(deps, ctx, pluginConfig, parsed.note) };
@@ -642,21 +560,29 @@ function normalizeDiagnosticsReason(note) {
642
560
  return normalized ? normalized.slice(0, CODEX_DIAGNOSTICS_REASON_MAX_CHARS) : void 0;
643
561
  }
644
562
  function parseDiagnosticsArgs(args) {
645
- const [action, token] = splitArgs(args);
563
+ const [action, token, ...extra] = splitArgs(args);
646
564
  const normalizedAction = action?.toLowerCase();
647
- if ((normalizedAction === "confirm" || normalizedAction === "--confirm") && token) return {
565
+ if ((normalizedAction === "confirm" || normalizedAction === "--confirm") && token && extra.length === 0) return {
648
566
  action: "confirm",
649
567
  token
650
568
  };
651
- if ((normalizedAction === "cancel" || normalizedAction === "--cancel") && token) return {
569
+ if ((normalizedAction === "cancel" || normalizedAction === "--cancel") && token && extra.length === 0) return {
652
570
  action: "cancel",
653
571
  token
654
572
  };
573
+ if (normalizedAction === "confirm" || normalizedAction === "--confirm" || normalizedAction === "cancel" || normalizedAction === "--cancel") return { action: "usage" };
655
574
  return {
656
575
  action: "request",
657
576
  note: args
658
577
  };
659
578
  }
579
+ function formatDiagnosticsUsage(commandPrefix) {
580
+ return [
581
+ `Usage: ${commandPrefix} [note]`,
582
+ `Usage: ${commandPrefix} confirm <token>`,
583
+ `Usage: ${commandPrefix} cancel <token>`
584
+ ].join("\n");
585
+ }
660
586
  function createCodexDiagnosticsConfirmation(params) {
661
587
  prunePendingCodexDiagnosticsConfirmations(params.now);
662
588
  if (!pendingCodexDiagnosticsConfirmationTokensByScope.has(params.scopeKey) && pendingCodexDiagnosticsConfirmationTokensByScope.size >= CODEX_DIAGNOSTICS_CONFIRMATION_MAX_SCOPES) {
@@ -850,7 +776,8 @@ function normalizeCodexDiagnosticsScopeField(value) {
850
776
  if (normalized.length <= CODEX_DIAGNOSTICS_SCOPE_FIELD_MAX_CHARS) return normalized;
851
777
  return `sha256:${crypto.createHash("sha256").update(normalized).digest("hex")}`;
852
778
  }
853
- async function startThreadAction(deps, ctx, pluginConfig, method, label) {
779
+ async function startThreadAction(deps, ctx, pluginConfig, method, label, args) {
780
+ if (args.length > 0) return `Usage: /codex ${label === "compaction" ? "compact" : label}`;
854
781
  const sessionFile = await resolveControlSessionFile(ctx);
855
782
  if (!sessionFile) return `Cannot start Codex ${label} because this command did not include an OpenClaw session file.`;
856
783
  const binding = await deps.readCodexAppServerBinding(sessionFile);
@@ -860,10 +787,52 @@ async function startThreadAction(deps, ctx, pluginConfig, method, label) {
860
787
  target: { type: "uncommittedChanges" }
861
788
  });
862
789
  else await deps.codexControlRequest(pluginConfig, method, { threadId: binding.threadId });
863
- return `Started Codex ${label} for thread ${binding.threadId}.`;
790
+ return `Started Codex ${label} for thread ${formatCodexDisplayText(binding.threadId)}.`;
864
791
  }
865
792
  function splitArgs(value) {
866
- return (value ?? "").trim().split(/\s+/).filter(Boolean);
793
+ const input = value ?? "";
794
+ const args = [];
795
+ let current = "";
796
+ let quote;
797
+ let escaping = false;
798
+ let tokenStarted = false;
799
+ for (const char of input) {
800
+ if (escaping) {
801
+ current += char;
802
+ escaping = false;
803
+ tokenStarted = true;
804
+ continue;
805
+ }
806
+ if (char === "\\" && quote !== "'") {
807
+ escaping = true;
808
+ tokenStarted = true;
809
+ continue;
810
+ }
811
+ if (quote) {
812
+ if (char === quote) quote = void 0;
813
+ else current += char;
814
+ tokenStarted = true;
815
+ continue;
816
+ }
817
+ if (char === "\"" || char === "'") {
818
+ quote = char;
819
+ tokenStarted = true;
820
+ continue;
821
+ }
822
+ if (/\s/.test(char)) {
823
+ if (tokenStarted) {
824
+ args.push(current);
825
+ current = "";
826
+ tokenStarted = false;
827
+ }
828
+ continue;
829
+ }
830
+ current += char;
831
+ tokenStarted = true;
832
+ }
833
+ if (escaping) current += "\\";
834
+ if (tokenStarted) args.push(current);
835
+ return args;
867
836
  }
868
837
  function parseBindArgs(args) {
869
838
  const parsed = {};
@@ -874,17 +843,32 @@ function parseBindArgs(args) {
874
843
  continue;
875
844
  }
876
845
  if (arg === "--cwd") {
877
- parsed.cwd = args[index + 1];
846
+ const value = readRequiredOptionValue(args, index);
847
+ if (!value || parsed.cwd !== void 0) {
848
+ parsed.help = true;
849
+ continue;
850
+ }
851
+ parsed.cwd = value;
878
852
  index += 1;
879
853
  continue;
880
854
  }
881
855
  if (arg === "--model") {
882
- parsed.model = args[index + 1];
856
+ const value = readRequiredOptionValue(args, index);
857
+ if (!value || parsed.model !== void 0) {
858
+ parsed.help = true;
859
+ continue;
860
+ }
861
+ parsed.model = value;
883
862
  index += 1;
884
863
  continue;
885
864
  }
886
865
  if (arg === "--provider" || arg === "--model-provider") {
887
- parsed.provider = args[index + 1];
866
+ const value = readRequiredOptionValue(args, index);
867
+ if (!value || parsed.provider !== void 0) {
868
+ parsed.help = true;
869
+ continue;
870
+ }
871
+ parsed.provider = value;
888
872
  index += 1;
889
873
  continue;
890
874
  }
@@ -906,6 +890,7 @@ function parseComputerUseArgs(args) {
906
890
  overrides: {},
907
891
  hasOverrides: false
908
892
  };
893
+ let sawAction = false;
909
894
  for (let index = 0; index < args.length; index += 1) {
910
895
  const arg = args[index];
911
896
  if (arg === "--help" || arg === "-h") {
@@ -913,12 +898,17 @@ function parseComputerUseArgs(args) {
913
898
  continue;
914
899
  }
915
900
  if (arg === "status" || arg === "install") {
901
+ if (sawAction) {
902
+ parsed.help = true;
903
+ continue;
904
+ }
905
+ sawAction = true;
916
906
  parsed.action = arg;
917
907
  continue;
918
908
  }
919
909
  if (arg === "--source" || arg === "--marketplace-source") {
920
910
  const value = readRequiredOptionValue(args, index);
921
- if (!value) {
911
+ if (!value || parsed.overrides.marketplaceSource !== void 0) {
922
912
  parsed.help = true;
923
913
  continue;
924
914
  }
@@ -928,7 +918,7 @@ function parseComputerUseArgs(args) {
928
918
  }
929
919
  if (arg === "--marketplace-path" || arg === "--path") {
930
920
  const value = readRequiredOptionValue(args, index);
931
- if (!value) {
921
+ if (!value || parsed.overrides.marketplacePath !== void 0) {
932
922
  parsed.help = true;
933
923
  continue;
934
924
  }
@@ -938,7 +928,7 @@ function parseComputerUseArgs(args) {
938
928
  }
939
929
  if (arg === "--marketplace") {
940
930
  const value = readRequiredOptionValue(args, index);
941
- if (!value) {
931
+ if (!value || parsed.overrides.marketplaceName !== void 0) {
942
932
  parsed.help = true;
943
933
  continue;
944
934
  }
@@ -948,7 +938,7 @@ function parseComputerUseArgs(args) {
948
938
  }
949
939
  if (arg === "--plugin") {
950
940
  const value = readRequiredOptionValue(args, index);
951
- if (!value) {
941
+ if (!value || parsed.overrides.pluginName !== void 0) {
952
942
  parsed.help = true;
953
943
  continue;
954
944
  }
@@ -958,7 +948,7 @@ function parseComputerUseArgs(args) {
958
948
  }
959
949
  if (arg === "--server" || arg === "--mcp-server") {
960
950
  const value = readRequiredOptionValue(args, index);
961
- if (!value) {
951
+ if (!value || parsed.overrides.mcpServerName !== void 0) {
962
952
  parsed.help = true;
963
953
  continue;
964
954
  }
@@ -974,7 +964,8 @@ function parseComputerUseArgs(args) {
974
964
  }
975
965
  function readRequiredOptionValue(args, index) {
976
966
  const value = args[index + 1];
977
- if (!value || value.startsWith("-")) return;
967
+ const normalized = value?.trim();
968
+ if (!normalized || normalized.startsWith("-")) return;
978
969
  return value;
979
970
  }
980
971
  function normalizeComputerUseStringOverrides(overrides) {
@@ -1,7 +1,7 @@
1
- import { i as resolveCodexAppServerRuntimeOptions } from "./config-CkkoMeqF.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-ByrA30No.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
3
  import { i as readCodexAppServerBinding } from "./session-binding-DuJYTJQy.js";
4
- import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-ClSvDfKC.js";
4
+ import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory--cll1Fba.js";
5
5
  import { embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, runHarnessContextEngineMaintenance } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/compact.ts
7
7
  const DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS = 300 * 1e3;
@@ -139,13 +139,11 @@ function codexSandboxPolicyForTurn(mode, cwd) {
139
139
  if (mode === "danger-full-access") return { type: "dangerFullAccess" };
140
140
  if (mode === "read-only") return {
141
141
  type: "readOnly",
142
- access: { type: "fullAccess" },
143
142
  networkAccess: false
144
143
  };
145
144
  return {
146
145
  type: "workspaceWrite",
147
146
  writableRoots: [cwd],
148
- readOnlyAccess: { type: "fullAccess" },
149
147
  networkAccess: false,
150
148
  excludeTmpdirEnvVar: false,
151
149
  excludeSlashTmp: false