@openclaw/codex 2026.9.5 → 2026.9.7
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/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
- package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
- package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
- package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
- package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
- package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
- package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
- package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
- package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
- package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
- package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
- package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
- package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
- package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
- package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
- package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
- package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
- package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
- package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
- package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
- package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
- package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
- package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
- package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
- package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
- package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
- package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
- package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
- package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
- package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
- package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
- package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
- package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
- package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
- package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
- package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
- package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
- package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
- package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
- package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
- package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
- package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
- package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
- package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
- package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
- package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
- package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
- package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
- package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
- package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
- package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
- package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
- package/dist/api.js +25 -16
- package/dist/catalog-page-worker-entrypoint.js +12 -0
- package/dist/catalog-page.worker.js +9 -0
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +345 -346
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +16 -33
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +11 -7
- package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
- package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
- package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
- package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
- package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
- package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
- package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
- package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
- package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
- package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
- package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
- package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
- package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
- package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
- package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
- package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
- package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
- package/dist/.setup/version-CoqzXPgK.mjs +0 -12
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { n as projectCodexCatalogNativeResponse, r as projectCodexCatalogNativeThread } from "./session-catalog-native-projection-DjhwGL6x.mjs";
|
|
3
|
+
import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
4
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
|
+
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
6
|
+
//#region extensions/codex/src/app-server/protocol-json.ts
|
|
7
|
+
function isRpcResponse(message) {
|
|
8
|
+
return message !== null && typeof message === "object" && "id" in message && (typeof message.id === "number" || typeof message.id === "string") && !("method" in message);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region extensions/codex/src/app-server/client-line-preview.ts
|
|
12
|
+
const CODEX_APP_SERVER_PARSE_LOG_MAX = 500;
|
|
13
|
+
function redactCodexAppServerLinePreview(value) {
|
|
14
|
+
const redacted = value.replace(/\s+/g, " ").trim().replace(/(Bearer\s+)[A-Za-z0-9._~+/-]+/gi, "$1<redacted>").replace(/("(?:api_?key|authorization|token|access_token|refresh_token)"\s*:\s*")([^"]+)(")/gi, "$1<redacted>$3").replace(/\b([a-z0-9_]*(?:api_?key|authorization|access_token|refresh_token|token))(\s*=\s*)(["']?)[^\s"']+(\3)/gi, "$1$2$3<redacted>$4");
|
|
15
|
+
return redacted.length > CODEX_APP_SERVER_PARSE_LOG_MAX ? `${truncateUtf16Safe(redacted, CODEX_APP_SERVER_PARSE_LOG_MAX)}...` : redacted;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region extensions/codex/src/app-server/client-message-decoder.ts
|
|
19
|
+
const PARSE_BUFFER_MAX = 8388608;
|
|
20
|
+
const PARSE_BUFFER_MAX_LINES = 1e3;
|
|
21
|
+
const UNICODE_ESCAPE_QUAD = /^[\da-fA-F]{4}$/u;
|
|
22
|
+
/** Recovers the raw newlines observed inside native JSON string values. */
|
|
23
|
+
var CodexAppServerMessageDecoder = class {
|
|
24
|
+
constructor(reportError) {
|
|
25
|
+
this.reportError = reportError;
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
this.pending = void 0;
|
|
29
|
+
}
|
|
30
|
+
get hasPending() {
|
|
31
|
+
return this.pending !== void 0;
|
|
32
|
+
}
|
|
33
|
+
parse(line) {
|
|
34
|
+
const rawLine = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
35
|
+
if (this.pending) return this.parseContinuation(rawLine, this.pending);
|
|
36
|
+
const trimmed = rawLine.trim();
|
|
37
|
+
if (!trimmed) return;
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(trimmed);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (isRecoverableParseFailure(trimmed, error)) {
|
|
42
|
+
const text = rawLine.trimStart();
|
|
43
|
+
this.pending = {
|
|
44
|
+
fragments: [text],
|
|
45
|
+
length: text.length,
|
|
46
|
+
inString: endsInsideJsonString(text)
|
|
47
|
+
};
|
|
48
|
+
} else this.reportError(trimmed, error, 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
parseContinuation(line, pending) {
|
|
52
|
+
pending.fragments.push(line);
|
|
53
|
+
pending.length += 2 + line.length;
|
|
54
|
+
const withinBounds = pending.length <= PARSE_BUFFER_MAX && pending.fragments.length <= PARSE_BUFFER_MAX_LINES;
|
|
55
|
+
if (withinBounds && pending.inString && scanJsonString(line, 0) === line.length) return;
|
|
56
|
+
const candidate = pending.fragments.join("\\n");
|
|
57
|
+
this.pending = void 0;
|
|
58
|
+
try {
|
|
59
|
+
return JSON.parse(candidate);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (withinBounds && isRecoverableParseFailure(candidate, error)) {
|
|
62
|
+
pending.inString = endsInsideJsonString(candidate);
|
|
63
|
+
this.pending = pending;
|
|
64
|
+
} else this.reportError(candidate, error, pending.fragments.length);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function isRecoverableParseFailure(value, error) {
|
|
69
|
+
if (!value.startsWith("{") && !value.startsWith("[")) return false;
|
|
70
|
+
const message = coerceErrorMessage(error);
|
|
71
|
+
return message.includes("Unterminated string") || message.includes("Unexpected end of JSON input");
|
|
72
|
+
}
|
|
73
|
+
function endsInsideJsonString(value) {
|
|
74
|
+
for (let index = 0; index < value.length; index++) {
|
|
75
|
+
if (value[index] !== "\"") continue;
|
|
76
|
+
const end = scanJsonString(value, index + 1);
|
|
77
|
+
if (end < 0) return false;
|
|
78
|
+
if (end === value.length) return true;
|
|
79
|
+
index = end;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
/** Finds a closing quote; incomplete or invalid escapes require native parsing. */
|
|
84
|
+
function scanJsonString(value, start) {
|
|
85
|
+
for (let index = start; index < value.length; index++) {
|
|
86
|
+
const character = value[index];
|
|
87
|
+
if (character === "\"") return index;
|
|
88
|
+
if (value.charCodeAt(index) < 32) return -1;
|
|
89
|
+
if (character !== "\\") continue;
|
|
90
|
+
const escape = value[++index];
|
|
91
|
+
if (escape === "u") {
|
|
92
|
+
if (!UNICODE_ESCAPE_QUAD.test(value.slice(index + 1, index + 5))) return -1;
|
|
93
|
+
index += 4;
|
|
94
|
+
} else if (!escape || !"\"\\/bfnrt".includes(escape)) return -1;
|
|
95
|
+
}
|
|
96
|
+
return value.length;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region extensions/codex/src/app-server/client-message-frames.ts
|
|
100
|
+
const UNPAIRED_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
101
|
+
/** One byte reader owns framing and stops at an asynchronous page decode. */
|
|
102
|
+
function listenCodexAppServerLines(input, onLine, onError) {
|
|
103
|
+
let fragments = [];
|
|
104
|
+
let length = 0;
|
|
105
|
+
let remainder;
|
|
106
|
+
let waiting = false;
|
|
107
|
+
let ended = false;
|
|
108
|
+
let closed = false;
|
|
109
|
+
const close = () => {
|
|
110
|
+
closed = true;
|
|
111
|
+
fragments = [];
|
|
112
|
+
remainder = void 0;
|
|
113
|
+
input.off("data", onData);
|
|
114
|
+
input.off("end", onEnd);
|
|
115
|
+
input.pause();
|
|
116
|
+
};
|
|
117
|
+
const deliver = (tail) => {
|
|
118
|
+
const line = fragments.length ? Buffer.concat([...fragments, tail], length + tail.length) : tail;
|
|
119
|
+
fragments = [];
|
|
120
|
+
length = 0;
|
|
121
|
+
const completion = onLine(line);
|
|
122
|
+
if (!completion) return true;
|
|
123
|
+
waiting = true;
|
|
124
|
+
input.pause();
|
|
125
|
+
completion.then(() => {
|
|
126
|
+
waiting = false;
|
|
127
|
+
if (!closed) {
|
|
128
|
+
drain();
|
|
129
|
+
if (!waiting && !ended && !closed) input.resume();
|
|
130
|
+
}
|
|
131
|
+
}).catch((error) => {
|
|
132
|
+
close();
|
|
133
|
+
onError(error);
|
|
134
|
+
});
|
|
135
|
+
return false;
|
|
136
|
+
};
|
|
137
|
+
const drain = () => {
|
|
138
|
+
try {
|
|
139
|
+
const chunk = remainder;
|
|
140
|
+
remainder = void 0;
|
|
141
|
+
if (chunk) {
|
|
142
|
+
let start = 0;
|
|
143
|
+
let end;
|
|
144
|
+
while ((end = chunk.indexOf(10, start)) !== -1) {
|
|
145
|
+
if (closed) return;
|
|
146
|
+
remainder = chunk.subarray(end + 1);
|
|
147
|
+
if (!deliver(chunk.subarray(start, end))) return;
|
|
148
|
+
remainder = void 0;
|
|
149
|
+
start = end + 1;
|
|
150
|
+
}
|
|
151
|
+
if (!closed && start < chunk.length) {
|
|
152
|
+
fragments.push(chunk.subarray(start));
|
|
153
|
+
length += chunk.length - start;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (ended && !closed) {
|
|
157
|
+
if (length && !deliver(Buffer.alloc(0))) return;
|
|
158
|
+
close();
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
close();
|
|
162
|
+
onError(error);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const onData = (chunk) => {
|
|
166
|
+
remainder = chunk;
|
|
167
|
+
drain();
|
|
168
|
+
};
|
|
169
|
+
const onEnd = () => {
|
|
170
|
+
ended = true;
|
|
171
|
+
if (!waiting) drain();
|
|
172
|
+
};
|
|
173
|
+
input.on("data", onData);
|
|
174
|
+
input.once("end", onEnd);
|
|
175
|
+
return close;
|
|
176
|
+
}
|
|
177
|
+
function codexCatalogResponseRoute(id) {
|
|
178
|
+
return typeof id === "number" && Number.isSafeInteger(id) && id >= 2 ** 52 ? {
|
|
179
|
+
id,
|
|
180
|
+
kind: id % 2 === 1 ? "list" : "thread"
|
|
181
|
+
} : void 0;
|
|
182
|
+
}
|
|
183
|
+
/** Read bounded envelope keys and IDs; skip native payload strings as bytes. */
|
|
184
|
+
function readCodexCatalogDecodeRoute(line) {
|
|
185
|
+
let depth = 0;
|
|
186
|
+
let route;
|
|
187
|
+
let response = false;
|
|
188
|
+
for (let index = 0; index < line.length; index++) {
|
|
189
|
+
const byte = line[index];
|
|
190
|
+
if (byte === 123 || byte === 91) depth++;
|
|
191
|
+
else if (byte === 125 || byte === 93) depth--;
|
|
192
|
+
else if (byte === 34) {
|
|
193
|
+
const start = index;
|
|
194
|
+
for (;;) {
|
|
195
|
+
index = line.indexOf(34, index + 1);
|
|
196
|
+
if (index < 0) return "unresolved";
|
|
197
|
+
let slash = index - 1;
|
|
198
|
+
while (line[slash] === 92) slash--;
|
|
199
|
+
if ((index - slash) % 2 === 1) break;
|
|
200
|
+
}
|
|
201
|
+
if (depth !== 1 || index - start > 64) continue;
|
|
202
|
+
let colon = index + 1;
|
|
203
|
+
while (line[colon] === 32 || line[colon] === 9 || line[colon] === 13) colon++;
|
|
204
|
+
if (line[colon] !== 58) continue;
|
|
205
|
+
const token = line.toString("utf8", start, index + 1);
|
|
206
|
+
let key = token.slice(1, -1);
|
|
207
|
+
if (token.includes("\\")) try {
|
|
208
|
+
key = JSON.parse(token);
|
|
209
|
+
} catch {
|
|
210
|
+
return "unresolved";
|
|
211
|
+
}
|
|
212
|
+
if (key === "method") return;
|
|
213
|
+
if (key === "result" || key === "error") {
|
|
214
|
+
response = true;
|
|
215
|
+
if (route) return route;
|
|
216
|
+
}
|
|
217
|
+
if (key !== "id") continue;
|
|
218
|
+
const match = /^\s*:\s*(\d+)(?=\s*[,}])/u.exec(line.toString("utf8", index + 1, Math.min(index + 100, line.length)));
|
|
219
|
+
if (!match) continue;
|
|
220
|
+
route = codexCatalogResponseRoute(Number(match[1]));
|
|
221
|
+
if (!route || response) return route;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return response || route ? "unresolved" : void 0;
|
|
225
|
+
}
|
|
226
|
+
function stringifyCodexAppServerMessage(message) {
|
|
227
|
+
return JSON.stringify(message, (_key, value) => typeof value === "string" ? value.replace(UNPAIRED_SURROGATE_RE, "") : value) ?? "null";
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region extensions/codex/src/app-server/client-catalog-response.ts
|
|
231
|
+
/** The worker retains recovery fragments, but never a completed native page. */
|
|
232
|
+
function createCodexCatalogDecoder() {
|
|
233
|
+
let failures = [];
|
|
234
|
+
const decoder = new CodexAppServerMessageDecoder((value, error, fragmentCount) => {
|
|
235
|
+
failures.push({
|
|
236
|
+
value: redactCodexAppServerLinePreview(value),
|
|
237
|
+
error,
|
|
238
|
+
fragmentCount
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
return (input) => {
|
|
242
|
+
failures = [];
|
|
243
|
+
const result = projectCodexCatalogMessage(decoder.parse(Buffer.from(input.bytes.buffer, input.bytes.byteOffset, input.bytes.byteLength).toString("utf8")), input);
|
|
244
|
+
result.pending = decoder.hasPending;
|
|
245
|
+
result.failures = failures;
|
|
246
|
+
return result;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function projectCodexCatalogMessage(parsed, input, cachedPreview) {
|
|
250
|
+
const result = {
|
|
251
|
+
pending: false,
|
|
252
|
+
failures: []
|
|
253
|
+
};
|
|
254
|
+
if (!isJsonObject(parsed)) return result;
|
|
255
|
+
result.message = parsed;
|
|
256
|
+
if (!isRpcResponse(parsed)) return result;
|
|
257
|
+
const message = parsed;
|
|
258
|
+
const route = codexCatalogResponseRoute(message.id);
|
|
259
|
+
if (message.error || !route) return result;
|
|
260
|
+
const remainingRows = input.route === "unresolved" ? input.catalogRows?.has(route.id) ? input.catalogRows.get(route.id) : 0 : input.remainingRows;
|
|
261
|
+
try {
|
|
262
|
+
if (!isJsonObject(message.result)) throw new Error("Codex catalog response contains an invalid result");
|
|
263
|
+
if (route.kind === "list") {
|
|
264
|
+
const raw = message.result;
|
|
265
|
+
message.result = projectCodexCatalogNativeResponse(raw, sanitizeTerminalText, cachedPreview, remainingRows);
|
|
266
|
+
if (!cachedPreview) result.previewStates = Array.isArray(raw.data) ? raw.data.slice(0, Array.isArray(message.result.data) ? message.result.data.length : 0).map((row) => isJsonObject(row) && typeof row.preview === "string" ? Boolean(row.preview) : void 0) : [];
|
|
267
|
+
} else {
|
|
268
|
+
const thread = message.result.thread;
|
|
269
|
+
message.result = { thread: {
|
|
270
|
+
...projectCodexCatalogNativeThread(thread, sanitizeTerminalText),
|
|
271
|
+
...isJsonObject(thread) && typeof thread.cwd === "string" ? { cwd: thread.cwd } : {},
|
|
272
|
+
...isJsonObject(thread) && (thread.historyMode === "paginated" || thread.historyMode === "legacy") ? { historyMode: thread.historyMode } : {}
|
|
273
|
+
} };
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
delete result.message;
|
|
277
|
+
result.projectionError = {
|
|
278
|
+
id: route.id,
|
|
279
|
+
error: error instanceof Error ? error : new Error("Codex catalog projection failed", { cause: error })
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
//#endregion
|
|
285
|
+
export { stringifyCodexAppServerMessage as a, isRpcResponse as c, readCodexCatalogDecodeRoute as i, projectCodexCatalogMessage as n, CodexAppServerMessageDecoder as o, listenCodexAppServerLines as r, redactCodexAppServerLinePreview as s, createCodexCatalogDecoder as t };
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { o as formatCodexDisplayText } from "./command-formatters-
|
|
2
|
-
import { n as describeControlFailure } from "./capabilities-
|
|
1
|
+
import { o as formatCodexDisplayText } from "./command-formatters-R3ckE3Co.mjs";
|
|
2
|
+
import { n as describeControlFailure } from "./capabilities-B3WEZl4e.mjs";
|
|
3
3
|
//#region extensions/codex/src/command-dispatch.ts
|
|
4
4
|
/** Dispatches a `/codex` command to the lazily loaded handler. */
|
|
5
5
|
async function handleCodexCommand(ctx, options) {
|
|
6
|
-
const
|
|
6
|
+
const commandContext = {
|
|
7
|
+
...ctx,
|
|
8
|
+
gatewayClientScopes: ctx.gatewayClientScopes?.slice()
|
|
9
|
+
};
|
|
10
|
+
const { resolvePluginConfig, ...subcommandOptions } = options;
|
|
7
11
|
try {
|
|
8
|
-
|
|
12
|
+
const { handleCodexSubcommand } = await import("./command-handlers-ylTMS00z.mjs");
|
|
13
|
+
return await handleCodexSubcommand(commandContext, {
|
|
9
14
|
...subcommandOptions,
|
|
10
15
|
pluginConfig: resolvePluginConfig?.() ?? subcommandOptions.pluginConfig
|
|
11
16
|
});
|
|
@@ -13,9 +18,5 @@ async function handleCodexCommand(ctx, options) {
|
|
|
13
18
|
return { text: `Codex command failed: ${formatCodexDisplayText(describeControlFailure(error))}` };
|
|
14
19
|
}
|
|
15
20
|
}
|
|
16
|
-
async function loadDefaultCodexSubcommandHandler() {
|
|
17
|
-
const { handleCodexSubcommand } = await import("./command-handlers-BtAJEW1X.mjs");
|
|
18
|
-
return handleCodexSubcommand;
|
|
19
|
-
}
|
|
20
21
|
//#endregion
|
|
21
22
|
export { handleCodexCommand };
|
|
@@ -1,30 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-B7-X2TgG.mjs";
|
|
3
3
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
//#region extensions/codex/src/command-formatters.ts
|
|
5
5
|
/**
|
|
6
6
|
* Formats Codex command responses for safe chat display, including status,
|
|
7
7
|
* lists, account summaries, and user-facing help text.
|
|
8
8
|
*/
|
|
9
|
-
/** Formats the combined `/codex status` probe result. */
|
|
10
9
|
function formatCodexStatus(probes) {
|
|
11
10
|
const lines = [`Codex app-server: ${probes.models.ok || probes.account.ok || probes.limits.ok || probes.mcps.ok || probes.skills.ok ? "connected" : "unavailable"}`];
|
|
12
11
|
if (probes.models.ok) lines.push(`Models: ${probes.models.value.models.map((model) => formatCodexDisplayText(model.id)).slice(0, 8).join(", ") || "none"}`);
|
|
13
12
|
else lines.push(`Models: ${formatCodexDisplayText(probes.models.error)}`);
|
|
14
|
-
lines.push(`Account: ${probes.account.
|
|
15
|
-
lines.push(`Rate limits: ${probes.limits.ok ? formatCodexRateLimitSummary(probes.limits.value) : formatCodexDisplayText(probes.limits.error)}`);
|
|
16
|
-
lines.push(`MCP servers: ${probes.mcps.ok ? summarizeArrayLike(probes.mcps.value) : formatCodexDisplayText(probes.mcps.error)}`);
|
|
17
|
-
lines.push(`Skills: ${probes.skills.ok ? summarizeCodexSkills(probes.skills.value) : formatCodexDisplayText(probes.skills.error)}`);
|
|
13
|
+
lines.push(`Account: ${formatProbe(probes.account, formatCodexAccountSummary)}`, `Rate limits: ${formatProbe(probes.limits, formatCodexRateLimitSummary)}`, `MCP servers: ${formatProbe(probes.mcps, summarizeArrayLike)}`, `Skills: ${formatProbe(probes.skills, summarizeCodexSkills)}`);
|
|
18
14
|
return lines.join("\n");
|
|
19
15
|
}
|
|
20
|
-
|
|
16
|
+
function formatProbe(probe, format) {
|
|
17
|
+
return probe.ok ? format(probe.value) : formatCodexDisplayText(probe.error);
|
|
18
|
+
}
|
|
21
19
|
function formatModels(result) {
|
|
22
20
|
if (result.models.length === 0) return "No Codex app-server models returned.";
|
|
23
21
|
const lines = ["Codex models:", ...result.models.map((model) => `- ${formatCodexDisplayText(model.id)}${model.isDefault ? " (default)" : ""}`)];
|
|
24
22
|
if (result.truncated) lines.push("- More models available; output truncated.");
|
|
25
23
|
return lines.join("\n");
|
|
26
24
|
}
|
|
27
|
-
/** Formats Codex thread-list responses with safe resume hints. */
|
|
28
25
|
function formatThreads(response) {
|
|
29
26
|
const threads = extractArray(response);
|
|
30
27
|
if (threads.length === 0) return "No Codex threads returned.";
|
|
@@ -40,12 +37,15 @@ function formatThreads(response) {
|
|
|
40
37
|
return `- ${formatCodexDisplayText(id)}${title ? ` - ${formatCodexDisplayText(title)}` : ""}${details.length > 0 ? ` (${details.map(formatCodexDisplayText).join(", ")})` : ""}\n Resume: ${formatCodexResumeHint(id)}`;
|
|
41
38
|
})].join("\n");
|
|
42
39
|
}
|
|
43
|
-
/** Formats account and rate-limit output for `/codex account`. */
|
|
44
40
|
function formatAccount(account, limits, authOverview) {
|
|
45
|
-
if (authOverview) return formatAccountAuthOverview(authOverview);
|
|
41
|
+
if (authOverview?.rows.some((row) => row.active)) return formatAccountAuthOverview(authOverview);
|
|
46
42
|
const formattedLimits = limits.ok ? formatCodexRateLimitDetails(limits.value) : formatCodexDisplayText(limits.error);
|
|
47
43
|
const rateLimitBlock = formattedLimits.startsWith("Codex is ") ? formattedLimits : formattedLimits.includes("\n") ? `Rate limits:\n${formattedLimits}` : `Rate limits: ${formattedLimits}`;
|
|
48
|
-
return [
|
|
44
|
+
return [
|
|
45
|
+
`Account: ${account.ok ? formatCodexAccountSummary(account.value) : formatCodexDisplayText(account.error)}`,
|
|
46
|
+
rateLimitBlock,
|
|
47
|
+
...authOverview ? [formatAccountAuthOverview(authOverview)] : []
|
|
48
|
+
].join("\n\n");
|
|
49
49
|
}
|
|
50
50
|
function formatAccountAuthOverview(overview) {
|
|
51
51
|
const lines = [];
|
|
@@ -57,22 +57,20 @@ function formatAccountAuthOverview(overview) {
|
|
|
57
57
|
}
|
|
58
58
|
if (overview.rows.length > 0) {
|
|
59
59
|
lines.push(overview.orderTitle);
|
|
60
|
-
for (const [index, row] of overview.rows.entries()) lines.push(` ${index + 1}. ${row.label} ${row.kind} — ${
|
|
60
|
+
for (const [index, row] of overview.rows.entries()) lines.push(` ${index + 1}. ${row.label} ${row.kind} — ${row.billingNote ? `${row.status} · ${row.billingNote}` : row.status}`);
|
|
61
61
|
}
|
|
62
62
|
while (lines.at(-1) === "") lines.pop();
|
|
63
63
|
return lines.map(formatCodexAccountLine).join("\n");
|
|
64
64
|
}
|
|
65
|
-
function formatAuthRowStatus(row) {
|
|
66
|
-
return row.billingNote ? `${row.status} · ${row.billingNote}` : row.status;
|
|
67
|
-
}
|
|
68
|
-
/** Formats Codex Computer Use readiness and plugin/MCP availability. */
|
|
69
65
|
function formatComputerUseStatus(status) {
|
|
70
|
-
const lines = [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
const lines = [
|
|
67
|
+
`Computer Use: ${status.ready ? "ready" : status.enabled ? "not ready" : "disabled"}`,
|
|
68
|
+
`Plugin: ${formatCodexDisplayText(status.pluginName)} (${computerUsePluginState(status)})`,
|
|
69
|
+
`Installation: ${formatCodexDisplayText(status.installation.status)} (${status.installation.ok ? "ok" : "not ok"})`,
|
|
70
|
+
`MCP server: ${formatCodexDisplayText(status.mcpServerName)}${status.mcpServerAvailable ? ` (${status.tools.length} tools)` : " (unavailable)"}`,
|
|
71
|
+
`Exposure: ${formatCodexDisplayText(status.exposure.status)} (${status.exposure.ok ? "ok" : "not ok"})`,
|
|
72
|
+
`Live test: ${formatCodexDisplayText(status.liveTest.status)} (${status.liveTest.attempted ? `${status.liveTest.attempts} attempt${status.liveTest.attempts === 1 ? "" : "s"}, ${status.liveTest.timeoutMs}ms` : "not run"})`
|
|
73
|
+
];
|
|
76
74
|
if (status.liveTest.retried || status.liveTest.repaired) lines.push(`Live test recovery: retried=${status.liveTest.retried ? "yes" : "no"}, repaired=${status.liveTest.repaired ? "yes" : "no"}`);
|
|
77
75
|
if (status.marketplaceName) lines.push(`Marketplace: ${formatCodexDisplayText(status.marketplaceName)}`);
|
|
78
76
|
if (status.tools.length > 0) lines.push(`Tools: ${status.tools.slice(0, 8).map(formatCodexDisplayText).join(", ")}`);
|
|
@@ -81,10 +79,10 @@ function formatComputerUseStatus(status) {
|
|
|
81
79
|
return lines.join("\n");
|
|
82
80
|
}
|
|
83
81
|
function computerUsePluginState(status) {
|
|
82
|
+
if (status.installed === null) return "installation unchecked";
|
|
84
83
|
if (!status.installed) return "not installed";
|
|
85
84
|
return status.pluginEnabled ? "installed" : "installed, disabled";
|
|
86
85
|
}
|
|
87
|
-
/** Formats generic array-like Codex app-server responses. */
|
|
88
86
|
function formatList(response, label) {
|
|
89
87
|
const entries = extractArray(response);
|
|
90
88
|
if (entries.length === 0) return `${label}: none returned.`;
|
|
@@ -93,29 +91,9 @@ function formatList(response, label) {
|
|
|
93
91
|
return `- ${formatCodexDisplayText(normalizeOptionalString(record.name) ?? normalizeOptionalString(record.id) ?? JSON.stringify(entry))}`;
|
|
94
92
|
})].join("\n");
|
|
95
93
|
}
|
|
96
|
-
/** Formats Codex skills grouped by scope, omitting disabled entries. */
|
|
97
94
|
function formatSkills(response) {
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
const lines = ["Codex skills:"];
|
|
101
|
-
let renderedSkills = 0;
|
|
102
|
-
let loadErrors = 0;
|
|
103
|
-
for (const group of groups) {
|
|
104
|
-
const record = isJsonObject(group) ? group : {};
|
|
105
|
-
if (Array.isArray(record.errors)) loadErrors += record.errors.length;
|
|
106
|
-
const skills = Array.isArray(record.skills) ? record.skills : [];
|
|
107
|
-
if (skills.length === 0) continue;
|
|
108
|
-
for (const skill of skills) {
|
|
109
|
-
if (isJsonObject(skill) && skill.enabled === false) continue;
|
|
110
|
-
lines.push(`- ${formatCodexSkillEntry(skill)}`);
|
|
111
|
-
renderedSkills += 1;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (renderedSkills === 0) {
|
|
115
|
-
if (loadErrors > 0) return `Codex skills: none returned (${loadErrors} load ${loadErrors === 1 ? "error" : "errors"}).`;
|
|
116
|
-
return "Codex skills: none returned.";
|
|
117
|
-
}
|
|
118
|
-
return lines.join("\n");
|
|
95
|
+
const { skills, emptySummary } = readEnabledCodexSkills(response);
|
|
96
|
+
return skills.length > 0 ? ["Codex skills:", ...skills.map((skill) => `- ${formatCodexSkillEntry(skill)}`)].join("\n") : `Codex skills: ${emptySummary}.`;
|
|
119
97
|
}
|
|
120
98
|
function formatCodexSkillEntry(entry) {
|
|
121
99
|
const record = isJsonObject(entry) ? entry : {};
|
|
@@ -139,12 +117,7 @@ function formatCodexTextForDisplay(value) {
|
|
|
139
117
|
return sanitizeCodexTextForDisplay(value).trim() || "<unknown>";
|
|
140
118
|
}
|
|
141
119
|
function sanitizeCodexTextForDisplay(value) {
|
|
142
|
-
|
|
143
|
-
for (const character of value) {
|
|
144
|
-
const codePoint = character.codePointAt(0);
|
|
145
|
-
safe += codePoint != null && isUnsafeDisplayCodePoint(codePoint) ? "?" : character;
|
|
146
|
-
}
|
|
147
|
-
return safe;
|
|
120
|
+
return value.replace(/[\p{Cc}\u00ad\u061c\u180e\u200b-\u200f\u202a-\u202e\u2060-\u206f\ufeff\ufff9-\ufffb\u{e0000}-\u{e007f}]/gu, "?");
|
|
148
121
|
}
|
|
149
122
|
function escapeCodexChatText(value) {
|
|
150
123
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("@", "@").replaceAll("`", "`").replaceAll("[", "[").replaceAll("]", "]").replaceAll("(", "(").replaceAll(")", ")").replaceAll("*", "∗").replaceAll("_", "_").replaceAll("~", "~").replaceAll("|", "|");
|
|
@@ -171,10 +144,6 @@ function formatCodexAccountLine(value) {
|
|
|
171
144
|
function isLikelyEmailAddress(value) {
|
|
172
145
|
return /^[^\s@<>()[\]`]+@[^\s@<>()[\]`]+\.[^\s@<>()[\]`]+$/.test(value);
|
|
173
146
|
}
|
|
174
|
-
function isUnsafeDisplayCodePoint(codePoint) {
|
|
175
|
-
return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint === 173 || codePoint === 1564 || codePoint === 6158 || codePoint >= 8203 && codePoint <= 8207 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8288 && codePoint <= 8303 || codePoint === 65279 || codePoint >= 65529 && codePoint <= 65531 || codePoint >= 917504 && codePoint <= 917631;
|
|
176
|
-
}
|
|
177
|
-
/** Builds the portable `/codex` command help text. */
|
|
178
147
|
function buildHelp() {
|
|
179
148
|
return [
|
|
180
149
|
"Codex commands:",
|
|
@@ -215,20 +184,23 @@ function summarizeArrayLike(value) {
|
|
|
215
184
|
if (entries.length === 0) return "none returned";
|
|
216
185
|
return `${entries.length}`;
|
|
217
186
|
}
|
|
218
|
-
function
|
|
187
|
+
function readEnabledCodexSkills(value) {
|
|
219
188
|
const groups = isJsonObject(value) && Array.isArray(value.data) ? value.data : [];
|
|
220
|
-
|
|
221
|
-
let enabledSkills = 0;
|
|
189
|
+
const skills = [];
|
|
222
190
|
let loadErrors = 0;
|
|
223
191
|
for (const group of groups) {
|
|
224
192
|
if (!isJsonObject(group)) continue;
|
|
225
193
|
if (Array.isArray(group.errors)) loadErrors += group.errors.length;
|
|
226
|
-
|
|
227
|
-
enabledSkills += group.skills.filter((skill) => !isJsonObject(skill) || skill.enabled !== false).length;
|
|
194
|
+
for (const skill of Array.isArray(group.skills) ? group.skills : []) if (!isJsonObject(skill) || skill.enabled !== false) skills.push(skill);
|
|
228
195
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
196
|
+
return {
|
|
197
|
+
skills,
|
|
198
|
+
emptySummary: loadErrors > 0 ? `none returned (${loadErrors} load ${loadErrors === 1 ? "error" : "errors"})` : "none returned"
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function summarizeCodexSkills(value) {
|
|
202
|
+
const { skills, emptySummary } = readEnabledCodexSkills(value);
|
|
203
|
+
return skills.length > 0 ? `${skills.length}` : emptySummary;
|
|
232
204
|
}
|
|
233
205
|
function formatCodexRateLimitSummary(value) {
|
|
234
206
|
const summary = summarizeCodexRateLimits(value);
|