@openclaw/codex 2026.10.5-beta.4 → 2026.10.10-beta.1
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 +10 -3
- package/dist/.setup/{account-usage-runtime-CoVpNIlD.mjs → account-usage-runtime-DDCDkvtl.mjs} +15 -9
- package/dist/.setup/{app-server-policy-D_zv8J7V.mjs → app-server-policy-Cog6mm2i.mjs} +1 -1
- package/dist/.setup/{apply-BXDMd05l.mjs → apply-BVSXYkTV.mjs} +11 -11
- package/dist/.setup/{attempt-client-cleanup-zNuNTKVr.mjs → attempt-client-cleanup-6OcbMH46.mjs} +14 -8
- package/dist/.setup/attempt-terminal-sZutF0WY.mjs +1 -0
- package/dist/.setup/{attempt-workspace-context-CcwP3DA3.mjs → attempt-workspace-context-GYPLawX6.mjs} +2 -2
- package/dist/.setup/{auth-binding-BaxlhaNx.mjs → auth-binding-830RLAJW.mjs} +2 -2
- package/dist/.setup/{auth-cache-key-f8ODJ_OX.mjs → auth-cache-key-CVcYw8HD.mjs} +92 -80
- package/dist/.setup/{auth-profile-CgHQ8Vot.mjs → auth-profile-auwzSwwy.mjs} +14 -8
- package/dist/.setup/{auth-profile-health-oHizqgye.mjs → auth-profile-health-BVPZU9I8.mjs} +15 -8
- package/dist/.setup/{auth-profile-selection-hr8ocLtz.mjs → auth-profile-selection-Bp5PDk3W.mjs} +24 -7
- package/dist/.setup/{binding-connection-B7HAAZSI.mjs → binding-connection-GTgUj9pi.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-DAXn7iFl.mjs → binding-connection.runtime-RcWR3vQu.mjs} +4 -3
- package/dist/.setup/{bounded-turn-isolation-BfDAo-qZ.mjs → bounded-turn-isolation-D8CDrAVX.mjs} +3 -3
- package/dist/.setup/{bounded-turn-DfIJtRlv.mjs → bounded-turn-mN_ekXYW.mjs} +18 -22
- package/dist/.setup/{build-state-Ds14X10-.mjs → build-state-VcujMRqP.mjs} +1 -1
- package/dist/.setup/{capabilities-DbOzOglY.mjs → capabilities-DAS-JX1z.mjs} +1 -1
- package/dist/.setup/{client-D93nbdB8.mjs → client-BS8X7HmG.mjs} +47 -317
- package/dist/.setup/{client-catalog-response-CuVLp4I0.mjs → client-catalog-response-jM38o5w1.mjs} +2 -2
- package/dist/.setup/client-initialize-CjgZcX61.mjs +165 -0
- package/dist/.setup/{command-dispatch-DxdH5a9-.mjs → command-dispatch-DzXbHqCn.mjs} +3 -3
- package/dist/.setup/{command-formatters-xW9KpoSZ.mjs → command-formatters-B_7-QZ1c.mjs} +2 -2
- package/dist/.setup/{command-handlers-fiYvYYq0.mjs → command-handlers-tfb5Uq-O.mjs} +539 -406
- package/dist/.setup/command-rpc-SXqLQukR.mjs +296 -0
- package/dist/.setup/compact-M-JxLcbZ.mjs +823 -0
- package/dist/.setup/{computer-use-DL2v3Kxq.mjs → computer-use-FqQ-Flbl.mjs} +21 -68
- package/dist/.setup/{config-C1YVVLEA.mjs → config-BfrAlTMT.mjs} +3 -3
- package/dist/.setup/{config-options-DDzeNQ8m.mjs → config-options-DMFZkd3X.mjs} +1 -1
- package/dist/.setup/{config-runtime-DWzK-k0n.mjs → config-runtime-BZRizyuG.mjs} +2 -2
- package/dist/.setup/{context-engine-projection-ps-yn_ci.mjs → context-engine-projection-PIeLSnR-.mjs} +16 -30
- package/dist/.setup/{conversation-binding-BieJZRRV.mjs → conversation-binding-C7MZy-Cx.mjs} +228 -116
- package/dist/.setup/{conversation-binding-data-UgLuTSQT.mjs → conversation-binding-data-khgW0n-o.mjs} +4 -2
- package/dist/.setup/{conversation-control-GXM3unE4.mjs → conversation-control-B2EpVZEb.mjs} +53 -23
- package/dist/.setup/{cyber-failover-D4dgNfFf.mjs → cyber-failover-CqEZoQsj.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-ljgGGL0s.mjs → cyber-failover-notice-poL3Advd.mjs} +1 -1
- package/dist/.setup/{doctor-start-options-JjTAl-q_.mjs → doctor-start-options-8uIBXIzR.mjs} +8 -5
- package/dist/.setup/{dynamic-tool-build-DcaPmBlE.mjs → dynamic-tool-build-BjFAIG-f.mjs} +208 -218
- package/dist/.setup/{dynamic-tools-CnQFnNKH.mjs → dynamic-tools-XqWsVjcC.mjs} +344 -118
- package/dist/.setup/{effective-mcp-catalog-B5HKFZNK.mjs → effective-mcp-catalog-C3ta5hHc.mjs} +11 -9
- package/dist/.setup/{ephemeral-turn-De3qb8EQ.mjs → ephemeral-turn-1ZF17fUR.mjs} +5 -4
- package/dist/.setup/{event-projector-assistant-message-CLMKN4x-.mjs → event-projector-assistant-message-ChOAY7rW.mjs} +16 -11
- package/dist/.setup/{event-projector-usage-BpKfdoTm.mjs → event-projector-usage-CBY0Hkga.mjs} +2 -2
- package/dist/.setup/{event-projector-values-CLvG1Hil.mjs → event-projector-values-yf4us9Pf.mjs} +1 -1
- package/dist/.setup/experimental-features-uGnVDtp-.mjs +19 -0
- package/dist/.setup/inference-context-mv_dBpAL.mjs +209 -0
- package/dist/.setup/{inference-dispatch-CO6tTs4q.mjs → inference-dispatch-C2zVSnrr.mjs} +2 -2
- package/dist/.setup/{inference-metadata-DCvcG_N_.mjs → inference-metadata-CYFWLHVk.mjs} +3 -1
- package/dist/.setup/{inference-proxy-BDWV0djM.mjs → inference-proxy-yd3hr2dr.mjs} +8 -8
- package/dist/.setup/installed-probe-lVC1X5ve.mjs +185 -0
- package/dist/.setup/{isolated-completion-BPJdvk5F.mjs → isolated-completion-P-r8NRE4.mjs} +7 -7
- package/dist/.setup/managed-binary-DbKvGXKl.mjs +395 -0
- package/dist/.setup/{mcp-app-session-preparation-Dz2GOwyE.mjs → mcp-app-session-preparation-fnsnCovu.mjs} +18 -14
- package/dist/.setup/{model-catalog-ZNwltCKl.mjs → model-catalog-Y_esgRPY.mjs} +28 -17
- package/dist/.setup/{models-BHpbAuz8.mjs → models-BWLEUo2E.mjs} +3 -3
- package/dist/.setup/{native-auth-esN5MdIv.mjs → native-auth-DpZIaY8N.mjs} +7 -4
- package/dist/.setup/native-execution-policy-D09tLP-u.mjs +152 -0
- package/dist/.setup/{native-hook-relay-wq7jrNLk.mjs → native-hook-relay-C7aaLJaP.mjs} +45 -10
- package/dist/.setup/{native-mcp-app-DX3nyTtc.mjs → native-mcp-app-CsWj-v_x.mjs} +5 -5
- package/dist/.setup/{native-skill-isolation-DSBeF-Yy.mjs → native-skill-isolation-CMimsKYy.mjs} +7 -7
- package/dist/.setup/{native-subagent-monitor-DOLEIf9r.mjs → native-subagent-monitor-CFE7b4oC.mjs} +485 -239
- package/dist/.setup/{native-subagent-pending-assignments-DmVhedNs.mjs → native-subagent-pending-assignments-CTinVtjo.mjs} +1 -1
- package/dist/.setup/{native-task-assignments-DimsQ9Qa.mjs → native-task-assignments-YJopbaVO.mjs} +9 -5
- package/dist/.setup/{node-cli-sessions-CzKg2nGq.mjs → node-cli-sessions-BuJnBnEq.mjs} +7 -4
- package/dist/.setup/{node-exec-server.runtime-BWkULhBM.mjs → node-exec-server.runtime-CP7RC1Nd.mjs} +3 -3
- package/dist/.setup/{plan-41-YOBMq.mjs → plan-B4cHgqNv.mjs} +7 -20
- package/dist/.setup/{plugin-activation-D7WkJMvU.mjs → plugin-activation-CXPWe-hl.mjs} +4 -4
- package/dist/.setup/{plugin-app-cache-key-Bg9DbDI6.mjs → plugin-app-cache-key-DRb-niJc.mjs} +17 -55
- package/dist/.setup/{plugin-approval-roundtrip-CD88q3yx.mjs → plugin-approval-roundtrip-DIZHLbAM.mjs} +1 -1
- package/dist/.setup/{plugin-inventory-CYgdo14P.mjs → plugin-inventory-DE9wcaeH.mjs} +2 -2
- package/dist/.setup/{plugin-metadata-cache-Bi8TAPwX.mjs → plugin-metadata-cache-BqC-a6Fb.mjs} +2 -15
- package/dist/.setup/{project-doc-thread-config-BVcvnps8.mjs → project-doc-thread-config-B0UI3f1D.mjs} +6 -6
- package/dist/.setup/protocol-CaPAVwe9.mjs +12 -0
- package/dist/.setup/{provider-capabilities-Dn2WwH4P.mjs → provider-capabilities-DjcKunHS.mjs} +1 -1
- package/dist/.setup/{provider-LWKll6dV.mjs → provider-wj_LFJH3.mjs} +4 -4
- package/dist/.setup/{rate-limits-CI8pTPqL.mjs → rate-limits-BpfURnuy.mjs} +1 -1
- package/dist/.setup/{request-Bo0kKABI.mjs → request-ePeNJrOd.mjs} +132 -136
- package/dist/.setup/{responses-oauth-twnuTaAa.mjs → responses-oauth-CCV7aVYF.mjs} +6 -6
- package/dist/.setup/{rpc-error-C98SHchT.mjs → rpc-error-DemqqaxE.mjs} +7 -3
- package/dist/.setup/{run-attempt-ClU8MxhZ.mjs → run-attempt-BcWArowv.mjs} +595 -426
- package/dist/.setup/{run-attempt-lifecycle-KN4oh-7O.mjs → run-attempt-lifecycle-DN-ATDp9.mjs} +1 -1
- package/dist/.setup/{runtime-artifact-C13pR7tD.mjs → runtime-artifact-CmLWeyJB.mjs} +3 -3
- package/dist/.setup/{runtime-artifact-connection-jS5DeCok.mjs → runtime-artifact-connection-DpWlZ02e.mjs} +3 -3
- package/dist/.setup/{sandbox-guard-DIImwCy1.mjs → sandbox-guard-DneAfNye.mjs} +70 -30
- package/dist/.setup/{session-binding-JEHNMPsr.mjs → session-binding-BgsWcbdY.mjs} +25 -23
- package/dist/.setup/{session-binding-record-DU_0biMD.mjs → session-binding-record-C_THntMe.mjs} +27 -12
- package/dist/.setup/{session-binding-record-codec-BpH8u_G9.mjs → session-binding-record-codec-DvmOI7g_.mjs} +1 -0
- package/dist/.setup/{session-binding-sidecars-DD-enC8w.mjs → session-binding-sidecars-BNSS6WL4.mjs} +55 -63
- package/dist/.setup/session-cancellation-DLBSJO5n.mjs +43 -0
- package/dist/.setup/{session-catalog-adoption-Ca3OYGYM.mjs → session-catalog-adoption-ppsLlVLB.mjs} +24 -38
- package/dist/.setup/{session-catalog-archive-Bv6gV7x9.mjs → session-catalog-archive-CqLRHJ6z.mjs} +11 -13
- package/dist/.setup/{session-catalog-events-kR2Ot6nX.mjs → session-catalog-events-DK0opVp3.mjs} +5 -5
- package/dist/.setup/{session-catalog-index-CrnfVEnT.mjs → session-catalog-index-BfzfdtH7.mjs} +96 -271
- package/dist/.setup/{session-catalog-index-order-CTfoefow.mjs → session-catalog-index-order-0Zqng2u8.mjs} +1 -1
- package/dist/.setup/{session-catalog-limits-BynIoOYm.mjs → session-catalog-limits-Dc6E0BZz.mjs} +1 -1
- package/dist/.setup/{session-catalog-list-request-D4MYNgDB.mjs → session-catalog-list-request-CAjoWjaH.mjs} +3 -4
- package/dist/.setup/{session-catalog-native-projection-CWqCU1I_.mjs → session-catalog-native-projection-G3lSDYYG.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-adoption-BdP9Zjqo.mjs → session-catalog-node-adoption-e9v8mGgx.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-continue-CNJibO4_.mjs → session-catalog-node-continue-H7nrzcUD.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-lookup-BH_DBGa9.mjs → session-catalog-node-lookup-BrZfDkA8.mjs} +2 -2
- package/dist/.setup/{session-catalog-parsing-DkeoVn60.mjs → session-catalog-parsing-V6jyFg9g.mjs} +2 -2
- package/dist/.setup/{session-catalog-projection-BzHiV818.mjs → session-catalog-projection-BjWE414G.mjs} +8 -7
- package/dist/.setup/{session-catalog-provenance-CmsOE5mh.mjs → session-catalog-provenance-Dg9s12z-.mjs} +50 -30
- package/dist/.setup/{session-catalog-source-DGuRdGvM.mjs → session-catalog-source-DqyuNxCe.mjs} +2 -6
- package/dist/.setup/{session-cli-GwU0izn-.mjs → session-cli-CBGKiqdv.mjs} +1 -1
- package/dist/.setup/{session-history-BO6i_pfk.mjs → session-history-7W0cgTXF.mjs} +11 -9
- package/dist/.setup/{session-history-import-CaO8s6ta.mjs → session-history-import-BwPKwcNi.mjs} +4 -4
- package/dist/.setup/{session-initialization-Bi_2DKhc.mjs → session-initialization-Dn3vveGv.mjs} +2 -2
- package/dist/.setup/{session-retirement-B3U5hpGJ.mjs → session-retirement-Ci_JvOfH.mjs} +8 -8
- package/dist/.setup/{session-history.worker-DJQfek5p.mjs → settled-turn-evidence--tRW6fSm.mjs} +2 -18
- package/dist/.setup/{settled-turn-finalizer-CYCVpTv2.mjs → settled-turn-finalizer-D3-KXsbP.mjs} +8 -8
- package/dist/.setup/{shared-client-BCx1wbyA.mjs → shared-client-CE_uY0A1.mjs} +380 -557
- package/dist/.setup/side-question-OM18H9WJ.mjs +998 -0
- package/dist/.setup/{source-DipMO9hL.mjs → source-uGKgKWm8.mjs} +5 -5
- package/dist/.setup/{thread-archive-guard-LKdwQKyr.mjs → thread-archive-guard-BWjSsA92.mjs} +1 -1
- package/dist/.setup/{thread-lifecycle-run-C_aYiYqk.mjs → thread-lifecycle-run-mLueY6pH.mjs} +172 -75
- package/dist/.setup/{thread-model-selection-DcVebr8N.mjs → thread-model-selection-DxposL4X.mjs} +9 -9
- package/dist/.setup/{thread-ownership-BoUd0i6L.mjs → thread-ownership-t6Y9fLQS.mjs} +7 -7
- package/dist/.setup/{thread-policy-B3wBRNph.mjs → thread-policy-Cy301Or8.mjs} +6 -6
- package/dist/.setup/{thread-requests-BgzJwJtS.mjs → thread-requests-BjawdIVV.mjs} +14 -14
- package/dist/.setup/{thread-resume-D-3bsr1j.mjs → thread-resume-BUbsUfgF.mjs} +6 -6
- package/dist/.setup/{transcript-history-projection-DfKcoZCB.mjs → transcript-history-projection-i-FVpyha.mjs} +1 -1
- package/dist/.setup/{transcript-mirror-Bee2o6jj.mjs → transcript-mirror-CEQJZlF3.mjs} +6 -9
- package/dist/.setup/{transport-stdio-CRWTkKOn.mjs → transport-stdio-Bq160Dhv.mjs} +63 -64
- package/dist/.setup/{transport-websocket-DIyPfkHo.mjs → transport-websocket-0YqiI_MH.mjs} +1 -1
- package/dist/.setup/{turn-router-DBVMToGo.mjs → turn-router-Dbw17k3K.mjs} +2 -2
- package/dist/.setup/{upstream-session-fork-p5fwKi7w.mjs → upstream-session-fork-_LYkh0nZ.mjs} +46 -219
- package/dist/.setup/{usage-limit-error-BQX8RHAd.mjs → usage-limit-error-DcOSH3J4.mjs} +4 -4
- package/dist/.setup/{usage-C2Kq7oej.mjs → usage-w_93wnnR.mjs} +4 -4
- package/dist/.setup/{web-search-item-CvokaZOo.mjs → web-search-item-DHVuNSqk.mjs} +1 -1
- package/dist/.setup/{web-search-provider.runtime-D89djc7e.mjs → web-search-provider.runtime-DMHxve5v.mjs} +3 -3
- package/dist/.setup/{workspace-write-sandbox-probe-BDWO2Qkh.mjs → workspace-write-sandbox-probe-DJxOXcF3.mjs} +2 -2
- package/dist/api.js +7 -28
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-version-api.js +25 -0
- package/dist/doctor-contract-api.js +5 -5
- package/dist/harness.js +59 -36
- package/dist/index.js +259 -295
- package/dist/media-understanding-provider.js +2 -2
- package/dist/migration-provider-api.js +1 -2
- package/dist/native-session-binding-api.js +1 -2
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-entrypoint.js +12 -0
- package/dist/session-history-worker-runtime.js +7 -18
- package/dist/session-history.worker.js +18 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +6 -6
- package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +0 -2
- package/dist/.setup/command-rpc-HIvsy3wS.mjs +0 -247
- package/dist/.setup/compact-ClZ7Ar7L.mjs +0 -808
- package/dist/.setup/inference-context-DNlGwzwy.mjs +0 -91
- package/dist/.setup/managed-binary-BtIjV7yN.mjs +0 -175
- package/dist/.setup/native-execution-policy-MXEe7PB3.mjs +0 -75
- package/dist/.setup/protocol-CANUwXJ3.mjs +0 -17
- package/dist/.setup/side-question-Bz2UQW0l.mjs +0 -826
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as isJsonObject } from "./protocol-CaPAVwe9.mjs";
|
|
2
|
+
import { g as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, r as bindingStoreKey } from "./session-binding-record-C_THntMe.mjs";
|
|
3
3
|
import { r as isCodexFastServiceTier } from "./config-utils-DN_YT7dE.mjs";
|
|
4
|
-
import { c as resolveCodexAppServerPreparedApiKeyCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-
|
|
4
|
+
import { c as resolveCodexAppServerPreparedApiKeyCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-CVcYw8HD.mjs";
|
|
5
5
|
import { n as withCodexConversationThreadActivity } from "./thread-ownership-queue-CeyYScUC.mjs";
|
|
6
6
|
import { a as canMutateCodexHost, i as assertCodexHostOwnerCurrent, n as CODEX_HOST_INSPECTION_AUTH_ERROR, o as hasCodexAdminScope, r as CODEX_NATIVE_EXECUTION_AUTH_ERROR, t as CODEX_FULL_PERMISSIONS_AUTH_ERROR } from "./command-authorization-AikPDtcc.mjs";
|
|
7
|
-
import { l as formatRelativeDuration, s as summarizeCodexAccountUsage } from "./rate-limits-
|
|
8
|
-
import { a as formatCodexAccountLine, c as formatCodexTextForDisplay, d as formatModels, f as formatSkills, i as formatAccount, l as formatComputerUseStatus, m as isLikelyEmailAddress, n as buildHelp, o as formatCodexDisplayText, p as formatThreads, r as escapeCodexChatText, s as formatCodexStatus, t as CODEX_RESUME_SAFE_THREAD_ID_PATTERN, u as formatList } from "./command-formatters-
|
|
9
|
-
import { i as readCodexConversationBindingData, n as createCodexCliNodeConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-
|
|
10
|
-
import { r as CodexAppServerRpcError } from "./rpc-error-
|
|
11
|
-
import { t as CODEX_CONTROL_METHODS } from "./capabilities-
|
|
7
|
+
import { l as formatRelativeDuration, s as summarizeCodexAccountUsage } from "./rate-limits-BpfURnuy.mjs";
|
|
8
|
+
import { a as formatCodexAccountLine, c as formatCodexTextForDisplay, d as formatModels, f as formatSkills, i as formatAccount, l as formatComputerUseStatus, m as isLikelyEmailAddress, n as buildHelp, o as formatCodexDisplayText, p as formatThreads, r as escapeCodexChatText, s as formatCodexStatus, t as CODEX_RESUME_SAFE_THREAD_ID_PATTERN, u as formatList } from "./command-formatters-B_7-QZ1c.mjs";
|
|
9
|
+
import { i as readCodexConversationBindingData, n as createCodexCliNodeConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-khgW0n-o.mjs";
|
|
10
|
+
import { r as CodexAppServerRpcError } from "./rpc-error-DemqqaxE.mjs";
|
|
11
|
+
import { t as CODEX_CONTROL_METHODS } from "./capabilities-DAS-JX1z.mjs";
|
|
12
12
|
import { n as filterCodexMarketplacePlugins, r as parseCodexPluginMarketplaceId, t as discoverCodexMarketplacePlugins } from "./plugin-marketplace-discovery-BblHM3DU.mjs";
|
|
13
|
-
import { o as formatCodexCliSessions } from "./node-cli-sessions-
|
|
14
|
-
import { a as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-
|
|
15
|
-
import { i as resolveCodexBindingAppServerConnection } from "./binding-connection-
|
|
16
|
-
import { a as withCodexAppServerJsonClient } from "./request-
|
|
17
|
-
import { n as findCodexMarketplacePluginSummary, o as pluginReadParams, r as isOpenAiCuratedMarketplaceName, u as CODEX_PLUGINS_MARKETPLACE_NAME } from "./plugin-inventory-
|
|
18
|
-
import "./config-
|
|
19
|
-
import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-
|
|
20
|
-
import { a as resolveCodexAppServerAuthProfileStore, i as resolveCodexAppServerAuthProfileIdForAgent, n as normalizeCodexAppServerBindingModelProvider } from "./auth-profile-
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { o as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-
|
|
24
|
-
import { n as fingerprintCodexAppServerAuthBinding } from "./auth-binding-
|
|
25
|
-
import { n as listAllCodexAppServerModels } from "./models-
|
|
26
|
-
import { n as refreshCodexAppRuntimeState, r as refreshCodexPluginRuntimeState } from "./plugin-activation-
|
|
27
|
-
import { i as resolveCodexSessionBinding, n as createCodexSessionGenerationSupersededError } from "./session-binding-
|
|
28
|
-
import { a as rollbackCodexAppServerBindingSubscription, c as withExclusiveCodexAppServerThread, i as retireCodexConversationThreadBinding, n as releaseCodexAppServerBindingSubscription, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-
|
|
29
|
-
import { n as
|
|
30
|
-
import { i as assertCodexSupervisionThreadLineage } from "./thread-policy-
|
|
31
|
-
import { t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-
|
|
32
|
-
import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-
|
|
33
|
-
import {
|
|
34
|
-
import { a as
|
|
13
|
+
import { o as formatCodexCliSessions } from "./node-cli-sessions-BuJnBnEq.mjs";
|
|
14
|
+
import { a as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DRb-niJc.mjs";
|
|
15
|
+
import { i as resolveCodexBindingAppServerConnection } from "./binding-connection-GTgUj9pi.mjs";
|
|
16
|
+
import { a as withCodexAppServerJsonClient } from "./request-ePeNJrOd.mjs";
|
|
17
|
+
import { n as findCodexMarketplacePluginSummary, o as pluginReadParams, r as isOpenAiCuratedMarketplaceName, u as CODEX_PLUGINS_MARKETPLACE_NAME } from "./plugin-inventory-DE9wcaeH.mjs";
|
|
18
|
+
import "./config-BfrAlTMT.mjs";
|
|
19
|
+
import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-BZRizyuG.mjs";
|
|
20
|
+
import { a as resolveCodexAppServerAuthProfileStore, i as resolveCodexAppServerAuthProfileIdForAgent, n as normalizeCodexAppServerBindingModelProvider, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-auwzSwwy.mjs";
|
|
21
|
+
import { A as hasCodexAppServerLiveThread, D as consumeCodexAppServerLiveThread, Z as resolveCodexAppServerAuthAccountCacheKey, f as releaseLeasedSharedCodexAppServerClient, o as getLeasedSharedCodexAppServerClient } from "./shared-client-CE_uY0A1.mjs";
|
|
22
|
+
import { f as assertCodexThreadAcceptsDirectInput, i as isCodexAppServerIndeterminateRequestCancellationError, m as assertCodexThreadResumeResponse, o as isCodexAppServerPrewriteRequestCancellationError } from "./client-BS8X7HmG.mjs";
|
|
23
|
+
import { o as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-6OcbMH46.mjs";
|
|
24
|
+
import { n as fingerprintCodexAppServerAuthBinding } from "./auth-binding-830RLAJW.mjs";
|
|
25
|
+
import { n as listAllCodexAppServerModels } from "./models-BWLEUo2E.mjs";
|
|
26
|
+
import { n as refreshCodexAppRuntimeState, r as refreshCodexPluginRuntimeState } from "./plugin-activation-CXPWe-hl.mjs";
|
|
27
|
+
import { i as resolveCodexSessionBinding, n as createCodexSessionGenerationSupersededError } from "./session-binding-BgsWcbdY.mjs";
|
|
28
|
+
import { a as rollbackCodexAppServerBindingSubscription, c as withExclusiveCodexAppServerThread, i as retireCodexConversationThreadBinding, n as releaseCodexAppServerBindingSubscription, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-t6Y9fLQS.mjs";
|
|
29
|
+
import { n as prepareCodexNativeExecutionBlock, r as prepareCodexNativeSandboxBlock } from "./sandbox-guard-DneAfNye.mjs";
|
|
30
|
+
import { i as assertCodexSupervisionThreadLineage } from "./thread-policy-Cy301Or8.mjs";
|
|
31
|
+
import { t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BqC-a6Fb.mjs";
|
|
32
|
+
import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-FqQ-Flbl.mjs";
|
|
33
|
+
import { t as readCodexExperimentalFeature } from "./experimental-features-uGnVDtp-.mjs";
|
|
34
|
+
import { a as requestOptions, i as readCodexStatusProbes, o as safeCodexControlRequest, r as prepareCodexControlSessionAuth, t as codexControlRequest } from "./command-rpc-SXqLQukR.mjs";
|
|
35
|
+
import { a as readCodexConversationActiveTurn, c as setCodexConversationModel, d as stopCodexConversationTurn, i as parseCodexPermissionsModeArg, l as setCodexConversationPermissions, n as formatPermissionsMode, r as parseCodexFastModeArg, s as setCodexConversationFastMode, u as steerCodexConversationTurn } from "./conversation-control-B2EpVZEb.mjs";
|
|
35
36
|
import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
36
37
|
import crypto from "node:crypto";
|
|
37
38
|
import { isDeepStrictEqual } from "node:util";
|
|
@@ -42,20 +43,20 @@ import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
|
42
43
|
import { isIncognitoSessionKey } from "openclaw/plugin-sdk/session-key-runtime";
|
|
43
44
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
44
45
|
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import { findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
|
|
46
|
+
import { ensureAuthProfileStoreAsync, resolveAgentDir as resolveAgentDir$1, resolveAgentWorkspaceDir, resolveAuthProfileEligibility, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
|
|
47
|
+
import { getSessionEntryAsync, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
48
|
+
import { ensureAuthProfileStore, findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
|
|
48
49
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
50
|
+
import { captureSessionEntryCurrentCheckAsync, composeSessionEntryCommitGuards } from "openclaw/plugin-sdk/session-binding-runtime";
|
|
49
51
|
import { renderMessagePresentationFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
|
|
50
52
|
import { MODEL_SELECTION_LOCKED_MESSAGE, isModelSelectionLocked, resolvePersistedSessionRuntimeId } from "openclaw/plugin-sdk/model-session-runtime";
|
|
51
|
-
import { composeSessionEntryCommitGuards } from "openclaw/plugin-sdk/session-binding-runtime";
|
|
52
53
|
//#region extensions/codex/src/command-account.ts
|
|
53
54
|
const OPENAI_PROVIDER_ID = "openai";
|
|
54
55
|
async function readCodexAccountAuthOverview(params) {
|
|
55
56
|
if (!params.account.ok && !params.limits.ok) return;
|
|
56
57
|
const config = params.ctx.config;
|
|
57
58
|
const agentDir = params.agentDir;
|
|
58
|
-
const store =
|
|
59
|
+
const store = await ensureAuthProfileStoreAsync(agentDir, {
|
|
59
60
|
allowKeychainPrompt: false,
|
|
60
61
|
config
|
|
61
62
|
});
|
|
@@ -394,22 +395,7 @@ function buildCodexCommandPickerPresentation(title, prompt, buttons) {
|
|
|
394
395
|
async function readCodexHostedAppsSupport(context, account) {
|
|
395
396
|
if (account.status !== "known") return "unknown";
|
|
396
397
|
if (!isJsonObject(account.value.account) || account.value.account.type !== "chatgpt") return "sign_in_required";
|
|
397
|
-
const features = await readEvidence(
|
|
398
|
-
let cursor;
|
|
399
|
-
const visited = /* @__PURE__ */ new Set();
|
|
400
|
-
do {
|
|
401
|
-
const response = await context.request("experimentalFeature/list", {
|
|
402
|
-
...context.threadId ? { threadId: context.threadId } : {},
|
|
403
|
-
...cursor ? { cursor } : {},
|
|
404
|
-
limit: 100
|
|
405
|
-
});
|
|
406
|
-
const apps = response.data.find((feature) => feature.name === "apps");
|
|
407
|
-
if (apps) return apps.enabled;
|
|
408
|
-
cursor = response.nextCursor ?? void 0;
|
|
409
|
-
if (cursor && visited.has(cursor)) return;
|
|
410
|
-
if (cursor) visited.add(cursor);
|
|
411
|
-
} while (cursor);
|
|
412
|
-
});
|
|
398
|
+
const features = await readEvidence(() => readCodexExperimentalFeature((params) => context.request("experimentalFeature/list", params), "apps", context.threadId));
|
|
413
399
|
if (features.status !== "known") return features.reason === "unsupported" ? "unsupported" : "unknown";
|
|
414
400
|
return features.value === void 0 ? "unknown" : features.value ? "supported" : "disabled";
|
|
415
401
|
}
|
|
@@ -1230,12 +1216,12 @@ async function resolveControlTarget(ctx) {
|
|
|
1230
1216
|
} : void 0;
|
|
1231
1217
|
}
|
|
1232
1218
|
async function resolvePreparedCodexCommandAuthority(deps, ctx) {
|
|
1233
|
-
const target = await resolveControlTarget(ctx);
|
|
1234
1219
|
const fallback = resolveCodexConversationControlScope(ctx);
|
|
1235
1220
|
const sessionId = ctx.sessionId;
|
|
1236
1221
|
const sessionKey = ctx.sessionKey;
|
|
1237
1222
|
const sessionAgentId = ctx.sessionTarget?.agentId ?? fallback.agentId;
|
|
1238
1223
|
const storePath = ctx.sessionTarget?.storePath ?? (sessionKey ? resolveStorePath(ctx.config.session?.store, { agentId: sessionAgentId }) : void 0);
|
|
1224
|
+
const target = await resolveControlTarget(ctx);
|
|
1239
1225
|
const sessionIdentity = sessionId ? sessionBindingIdentity({
|
|
1240
1226
|
sessionId,
|
|
1241
1227
|
sessionKey,
|
|
@@ -1249,71 +1235,98 @@ async function resolvePreparedCodexCommandAuthority(deps, ctx) {
|
|
|
1249
1235
|
config: ctx.config,
|
|
1250
1236
|
storePath
|
|
1251
1237
|
}) : void 0;
|
|
1252
|
-
|
|
1253
|
-
const
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
binding,
|
|
1269
|
-
currentSessionBinding: currentSession?.binding,
|
|
1270
|
-
sessionId,
|
|
1271
|
-
sessionKey,
|
|
1272
|
-
storePath,
|
|
1273
|
-
assertHostCurrent,
|
|
1274
|
-
assertCurrent,
|
|
1275
|
-
assertMutationCurrent: composeSessionEntryCommitGuards([assertCurrent], (assertSource) => {
|
|
1276
|
-
assertCodexHostOwnerCurrent(ctx);
|
|
1238
|
+
let resolvedTarget = currentSession;
|
|
1239
|
+
const release = () => {
|
|
1240
|
+
if (resolvedTarget !== currentSession) resolvedTarget?.release();
|
|
1241
|
+
currentSession?.release();
|
|
1242
|
+
};
|
|
1243
|
+
try {
|
|
1244
|
+
const assertHostCurrent = currentSession?.authority.assertLegacyCurrent ?? composeSessionEntryCommitGuards([]);
|
|
1245
|
+
resolvedTarget = target && (!sessionIdentity || !isDeepStrictEqual(target.identity, sessionIdentity)) ? await resolveCodexSessionBinding({
|
|
1246
|
+
bindingStore: deps.bindingStore,
|
|
1247
|
+
identity: target.identity,
|
|
1248
|
+
config: ctx.config,
|
|
1249
|
+
storePath,
|
|
1250
|
+
assertCurrent: assertHostCurrent
|
|
1251
|
+
}) : currentSession;
|
|
1252
|
+
const binding = resolvedTarget?.binding;
|
|
1253
|
+
const assertCurrent = composeSessionEntryCommitGuards([assertHostCurrent], (assertSource) => {
|
|
1277
1254
|
assertSource();
|
|
1278
|
-
|
|
1279
|
-
assertHostMutationCurrent: composeSessionEntryCommitGuards([assertHostCurrent], (assertSource) => {
|
|
1280
|
-
assertCodexHostOwnerCurrent(ctx);
|
|
1255
|
+
if (target && !isDeepStrictEqual(deps.bindingStore.read(target.identity), binding)) throw new Error("Codex command binding changed before dispatch");
|
|
1281
1256
|
assertSource();
|
|
1282
|
-
})
|
|
1283
|
-
|
|
1257
|
+
});
|
|
1258
|
+
assertCurrent();
|
|
1259
|
+
const assertCurrentAsync = async () => {
|
|
1260
|
+
await ctx.assertNativePolicyCurrent?.();
|
|
1261
|
+
await resolvedTarget?.authority.withCurrent(assertCurrent);
|
|
1262
|
+
if (!resolvedTarget) assertCurrent();
|
|
1263
|
+
};
|
|
1264
|
+
return {
|
|
1265
|
+
release,
|
|
1266
|
+
target,
|
|
1267
|
+
binding,
|
|
1268
|
+
currentSessionBinding: currentSession?.binding,
|
|
1269
|
+
sessionId,
|
|
1270
|
+
sessionKey,
|
|
1271
|
+
storePath,
|
|
1272
|
+
assertHostCurrent,
|
|
1273
|
+
assertCurrent,
|
|
1274
|
+
assertCurrentAsync,
|
|
1275
|
+
mutationSource: composeSessionEntryCommitGuards([assertCurrent, ctx.nativePolicySource]),
|
|
1276
|
+
assertMutationCurrent: composeSessionEntryCommitGuards([assertCurrent], (assertSource) => {
|
|
1277
|
+
assertCodexHostOwnerCurrent(ctx);
|
|
1278
|
+
assertSource();
|
|
1279
|
+
}),
|
|
1280
|
+
assertHostMutationCurrent: composeSessionEntryCommitGuards([assertHostCurrent], (assertSource) => {
|
|
1281
|
+
assertCodexHostOwnerCurrent(ctx);
|
|
1282
|
+
assertSource();
|
|
1283
|
+
})
|
|
1284
|
+
};
|
|
1285
|
+
} catch (error) {
|
|
1286
|
+
release();
|
|
1287
|
+
throw error;
|
|
1288
|
+
}
|
|
1284
1289
|
}
|
|
1285
1290
|
async function resolveCommandAppServerContext(deps, ctx, pluginConfig) {
|
|
1286
1291
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
authProfileId
|
|
1292
|
-
|
|
1293
|
-
config: ctx.config
|
|
1294
|
-
});
|
|
1295
|
-
const connection = await resolveCodexBindingAppServerConnection({
|
|
1296
|
-
binding,
|
|
1297
|
-
authProfileId,
|
|
1298
|
-
pluginConfig,
|
|
1299
|
-
agentDir,
|
|
1300
|
-
config: ctx.config,
|
|
1301
|
-
assertCurrent: authority.assertCurrent
|
|
1302
|
-
});
|
|
1303
|
-
return {
|
|
1304
|
-
scope: {
|
|
1305
|
-
agentId: target?.agentId ?? fallback.agentId,
|
|
1292
|
+
try {
|
|
1293
|
+
const { target, binding } = authority;
|
|
1294
|
+
const fallback = resolveCodexConversationControlScope(ctx);
|
|
1295
|
+
const agentDir = target?.agentDir ?? fallback.agentDir;
|
|
1296
|
+
const authProfileId = binding?.connectionScope === "supervision" ? void 0 : await resolveCodexAppServerAuthProfileIdForAgent({
|
|
1297
|
+
authProfileId: binding?.authProfileId ?? target?.requestedAuthProfileId,
|
|
1306
1298
|
agentDir,
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1299
|
+
config: ctx.config
|
|
1300
|
+
});
|
|
1301
|
+
const connection = await resolveCodexBindingAppServerConnection({
|
|
1302
|
+
binding,
|
|
1303
|
+
authProfileId,
|
|
1304
|
+
pluginConfig,
|
|
1305
|
+
agentDir,
|
|
1306
|
+
config: ctx.config,
|
|
1307
|
+
assertCurrent: authority.assertCurrent,
|
|
1308
|
+
assertCurrentAsync: authority.assertCurrentAsync
|
|
1309
|
+
});
|
|
1310
|
+
return {
|
|
1311
|
+
scope: {
|
|
1312
|
+
agentId: target?.agentId ?? fallback.agentId,
|
|
1313
|
+
agentDir,
|
|
1314
|
+
...connection.clientAuthProfileId !== void 0 ? { authProfileId: connection.clientAuthProfileId } : {},
|
|
1315
|
+
...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {},
|
|
1316
|
+
...authority.sessionKey ? { sessionKey: authority.sessionKey } : {},
|
|
1317
|
+
...authority.sessionId ? { sessionId: authority.sessionId } : {},
|
|
1318
|
+
...authority.storePath ? { storePath: authority.storePath } : {},
|
|
1319
|
+
assertCurrent: authority.assertCurrent,
|
|
1320
|
+
assertCurrentAsync: authority.assertCurrentAsync,
|
|
1321
|
+
release: authority.release
|
|
1322
|
+
},
|
|
1323
|
+
target,
|
|
1324
|
+
binding
|
|
1325
|
+
};
|
|
1326
|
+
} catch (error) {
|
|
1327
|
+
authority.release();
|
|
1328
|
+
throw error;
|
|
1329
|
+
}
|
|
1317
1330
|
}
|
|
1318
1331
|
async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
|
|
1319
1332
|
return (await resolveCommandAppServerContext(deps, ctx, pluginConfig)).scope;
|
|
@@ -1426,7 +1439,10 @@ async function confirmCodexDiagnosticsFeedback(deps, ctx, pluginConfig, token) {
|
|
|
1426
1439
|
const pending = consumeCodexDiagnosticsConfirmation(ctx, token, "confirm");
|
|
1427
1440
|
if (typeof pending === "string") return pending;
|
|
1428
1441
|
if (!pending.privateRouted && !await hasAnyCodexDiagnosticsIdentity(ctx)) return "Cannot send Codex diagnostics because this command did not include a stable session identity.";
|
|
1429
|
-
const currentTargets = pending.privateRouted ?
|
|
1442
|
+
const currentTargets = pending.privateRouted ? (await Promise.all(pending.targets.map(async (target) => {
|
|
1443
|
+
const binding = await deps.bindingStore.readAsync(target.identity);
|
|
1444
|
+
return binding?.threadId ? [await resolveCodexDiagnosticsTarget(target, binding, ctx.config)] : [];
|
|
1445
|
+
}))).flat() : await resolveCodexDiagnosticsTargets(deps, ctx);
|
|
1430
1446
|
if (!codexDiagnosticsTargetsMatch(pending.targets, currentTargets)) return "The Codex diagnostics sessions changed before confirmation. Run /diagnostics again for the current threads.";
|
|
1431
1447
|
return await sendCodexDiagnosticsFeedbackForTargets(deps, ctx, pluginConfig, pending.note ?? "", currentTargets, pending.scopeKey);
|
|
1432
1448
|
}
|
|
@@ -1558,20 +1574,38 @@ async function resolveCodexDiagnosticsTargets(deps, ctx) {
|
|
|
1558
1574
|
const key = bindingStoreKey(candidate.identity);
|
|
1559
1575
|
if (seenBindingKeys.has(key)) continue;
|
|
1560
1576
|
seenBindingKeys.add(key);
|
|
1561
|
-
const binding = deps.bindingStore.
|
|
1577
|
+
const binding = await deps.bindingStore.readAsync(candidate.identity);
|
|
1562
1578
|
if (!binding?.threadId || seenThreadIds.has(binding.threadId)) continue;
|
|
1563
1579
|
seenThreadIds.add(binding.threadId);
|
|
1564
|
-
targets.push(resolveCodexDiagnosticsTarget(candidate, binding, ctx.config));
|
|
1580
|
+
targets.push(await resolveCodexDiagnosticsTarget(candidate, binding, ctx.config));
|
|
1565
1581
|
}
|
|
1566
1582
|
return targets;
|
|
1567
1583
|
}
|
|
1568
1584
|
function resolvePendingCodexDiagnosticsTargets(deps, targets, config) {
|
|
1569
1585
|
return targets.flatMap((target) => {
|
|
1570
1586
|
const binding = deps.bindingStore.read(target.identity);
|
|
1571
|
-
|
|
1587
|
+
if (!binding?.threadId) return [];
|
|
1588
|
+
return [createCodexDiagnosticsTarget(target, binding, binding.connectionScope === "supervision" ? void 0 : binding.authProfileId?.trim() || resolveCodexAppServerAuthProfileId({
|
|
1589
|
+
authProfileId: binding.authProfileId,
|
|
1590
|
+
config,
|
|
1591
|
+
store: ensureAuthProfileStore(target.agentDir, {
|
|
1592
|
+
profileId: binding.authProfileId,
|
|
1593
|
+
allowKeychainPrompt: false,
|
|
1594
|
+
config,
|
|
1595
|
+
externalCliProviderIds: ["openai"],
|
|
1596
|
+
...binding.authProfileId ? { externalCliProfileIds: [binding.authProfileId] } : {}
|
|
1597
|
+
})
|
|
1598
|
+
}))];
|
|
1572
1599
|
});
|
|
1573
1600
|
}
|
|
1574
|
-
function resolveCodexDiagnosticsTarget(target, binding, config) {
|
|
1601
|
+
async function resolveCodexDiagnosticsTarget(target, binding, config) {
|
|
1602
|
+
return createCodexDiagnosticsTarget(target, binding, binding.connectionScope === "supervision" ? void 0 : await resolveCodexAppServerAuthProfileIdForAgent({
|
|
1603
|
+
authProfileId: binding.authProfileId,
|
|
1604
|
+
agentDir: target.agentDir,
|
|
1605
|
+
config
|
|
1606
|
+
}));
|
|
1607
|
+
}
|
|
1608
|
+
function createCodexDiagnosticsTarget(target, binding, authProfileId) {
|
|
1575
1609
|
const candidate = {
|
|
1576
1610
|
identity: target.identity,
|
|
1577
1611
|
agentDir: target.agentDir,
|
|
@@ -1590,11 +1624,6 @@ function resolveCodexDiagnosticsTarget(target, binding, config) {
|
|
|
1590
1624
|
appServerRuntimeFingerprint: binding.appServerRuntimeFingerprint,
|
|
1591
1625
|
pendingSupervisionBranch: binding.pendingSupervisionBranch
|
|
1592
1626
|
};
|
|
1593
|
-
const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
|
|
1594
|
-
authProfileId: binding.authProfileId,
|
|
1595
|
-
agentDir: target.agentDir,
|
|
1596
|
-
config
|
|
1597
|
-
});
|
|
1598
1627
|
return {
|
|
1599
1628
|
...candidate,
|
|
1600
1629
|
threadId: binding.threadId,
|
|
@@ -1603,12 +1632,12 @@ function resolveCodexDiagnosticsTarget(target, binding, config) {
|
|
|
1603
1632
|
}
|
|
1604
1633
|
//#endregion
|
|
1605
1634
|
//#region extensions/codex/src/command-handler-bindings.ts
|
|
1606
|
-
function isCurrentSessionModelSelectionLocked(ctx) {
|
|
1635
|
+
async function isCurrentSessionModelSelectionLocked(ctx) {
|
|
1607
1636
|
const sessionKey = ctx.sessionKey?.trim();
|
|
1608
1637
|
if (!sessionKey) return false;
|
|
1609
1638
|
const { agentId } = resolveCodexConversationControlScope(ctx);
|
|
1610
1639
|
const storePath = ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId });
|
|
1611
|
-
return isModelSelectionLocked(
|
|
1640
|
+
return isModelSelectionLocked(await getSessionEntryAsync({
|
|
1612
1641
|
storePath,
|
|
1613
1642
|
sessionKey,
|
|
1614
1643
|
hydrateSkillPromptRefs: false,
|
|
@@ -1618,7 +1647,7 @@ function isCurrentSessionModelSelectionLocked(ctx) {
|
|
|
1618
1647
|
async function bindConversation(deps, ctx, pluginConfig, args) {
|
|
1619
1648
|
const parsed = parseBindArgs(args);
|
|
1620
1649
|
if (parsed.help) return { text: "Usage: /codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]" };
|
|
1621
|
-
if (isCurrentSessionModelSelectionLocked(ctx)) return { text: MODEL_SELECTION_LOCKED_MESSAGE };
|
|
1650
|
+
if (await isCurrentSessionModelSelectionLocked(ctx)) return { text: MODEL_SELECTION_LOCKED_MESSAGE };
|
|
1622
1651
|
const scope = resolveCodexConversationControlScope(ctx);
|
|
1623
1652
|
const workspaceDir = parsed.cwd ?? deps.resolveCodexDefaultWorkspaceDir(pluginConfig);
|
|
1624
1653
|
const currentConversation = await ctx.getCurrentConversationBinding();
|
|
@@ -1631,12 +1660,13 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
|
|
|
1631
1660
|
config: ctx.config
|
|
1632
1661
|
}) : void 0;
|
|
1633
1662
|
const currentOwner = currentConversationData?.kind === "codex-app-server-session" ? conversationBindingIdentity(currentConversationData.bindingId) : sessionOwner;
|
|
1634
|
-
const existingBinding = currentOwner ? deps.bindingStore.
|
|
1663
|
+
const existingBinding = currentOwner ? await deps.bindingStore.readAsync(currentOwner) : void 0;
|
|
1635
1664
|
assertCodexBindingMayBeReplaced(existingBinding, "binding this conversation to another thread");
|
|
1636
1665
|
const sessionSource = sessionOwner && existingBinding ? {
|
|
1637
1666
|
agentId: sessionOwner.agentId,
|
|
1638
1667
|
sessionId: sessionOwner.sessionId,
|
|
1639
1668
|
threadId: existingBinding.threadId,
|
|
1669
|
+
storePath: ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId: sessionOwner.agentId }),
|
|
1640
1670
|
...sessionOwner.sessionKey ? { sessionKey: sessionOwner.sessionKey } : {}
|
|
1641
1671
|
} : void 0;
|
|
1642
1672
|
const authProfileId = existingBinding?.authProfileId;
|
|
@@ -1655,6 +1685,7 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
|
|
|
1655
1685
|
}
|
|
1656
1686
|
});
|
|
1657
1687
|
const threadLabel = parsed.threadId ?? "a new thread";
|
|
1688
|
+
await ctx.assertNativePolicyCurrent?.();
|
|
1658
1689
|
assertCodexHostOwnerCurrent(ctx);
|
|
1659
1690
|
const request = await ctx.requestConversationBinding({
|
|
1660
1691
|
summary: `Codex app-server thread ${formatCodexDisplayText(threadLabel)} in ${formatCodexDisplayText(workspaceDir)}`,
|
|
@@ -1666,7 +1697,7 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
|
|
|
1666
1697
|
return { text: `Bound this conversation to ${formatCodexDisplayText(threadLabel)} in ${formatCodexDisplayText(workspaceDir)}. The next message will initialize it.` };
|
|
1667
1698
|
}
|
|
1668
1699
|
async function detachConversation(deps, ctx) {
|
|
1669
|
-
if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1700
|
+
if (await isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1670
1701
|
const current = await ctx.getCurrentConversationBinding();
|
|
1671
1702
|
const data = readCodexConversationBindingData(current);
|
|
1672
1703
|
const identity = data?.kind === "codex-app-server-session" ? conversationBindingIdentity(data.bindingId) : void 0;
|
|
@@ -1674,7 +1705,7 @@ async function detachConversation(deps, ctx) {
|
|
|
1674
1705
|
let expectedThreadId;
|
|
1675
1706
|
let expectedStartId;
|
|
1676
1707
|
if (data?.kind === "codex-app-server-session") {
|
|
1677
|
-
const binding = deps.bindingStore.
|
|
1708
|
+
const binding = await deps.bindingStore.readAsync(identity);
|
|
1678
1709
|
assertCodexBindingMayBeReplaced(binding, "detaching its conversation binding");
|
|
1679
1710
|
if (deps.readCodexConversationActiveTurn(identity)) return "This Codex conversation has an active run; use /codex stop before detaching it.";
|
|
1680
1711
|
expectedThreadId = binding?.threadId;
|
|
@@ -1698,6 +1729,7 @@ async function detachConversation(deps, ctx) {
|
|
|
1698
1729
|
})) return "This Codex conversation binding changed while detaching; try again.";
|
|
1699
1730
|
return detachedPublicConversation;
|
|
1700
1731
|
});
|
|
1732
|
+
await ctx.assertNativePolicyCurrent?.();
|
|
1701
1733
|
assertCodexHostOwnerCurrent(ctx);
|
|
1702
1734
|
return await detachPublicConversation();
|
|
1703
1735
|
}
|
|
@@ -1714,11 +1746,11 @@ async function describeConversationBinding(deps, ctx) {
|
|
|
1714
1746
|
"- Active run: not tracked"
|
|
1715
1747
|
].join("\n");
|
|
1716
1748
|
const identity = conversationBindingIdentity(data.bindingId);
|
|
1717
|
-
const threadBinding = deps.bindingStore.
|
|
1749
|
+
const threadBinding = await deps.bindingStore.readAsync(identity);
|
|
1718
1750
|
const active = deps.readCodexConversationActiveTurn(identity);
|
|
1719
1751
|
const sessionKey = ctx.sessionKey?.trim();
|
|
1720
1752
|
const { agentId } = resolveCodexConversationControlScope(ctx);
|
|
1721
|
-
const sessionEntry = sessionKey ?
|
|
1753
|
+
const sessionEntry = sessionKey ? await getSessionEntryAsync({
|
|
1722
1754
|
agentId,
|
|
1723
1755
|
storePath: ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId }),
|
|
1724
1756
|
sessionKey,
|
|
@@ -1739,6 +1771,7 @@ async function describeConversationBinding(deps, ctx) {
|
|
|
1739
1771
|
}
|
|
1740
1772
|
async function buildThreads(deps, ctx, pluginConfig, filter) {
|
|
1741
1773
|
const scope = await resolveCommandAppServerScope(deps, ctx, pluginConfig);
|
|
1774
|
+
using _ = { [Symbol.dispose]: scope.release };
|
|
1742
1775
|
const response = await deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.listThreads, {
|
|
1743
1776
|
limit: 10,
|
|
1744
1777
|
...filter.trim() ? { searchTerm: filter.trim() } : {}
|
|
@@ -1763,7 +1796,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1763
1796
|
if (parsed.help) return args.includes("--help") || args.includes("-h") || parsed.host ? "Usage: /codex resume <thread-id>\nUsage: /codex resume <session-id> --host <node> --bind here" : "Usage: /codex resume <thread-id>";
|
|
1764
1797
|
if (parsed.host) return await bindCodexCliNodeSession(deps, ctx, parsed);
|
|
1765
1798
|
if (!normalizedThreadId || args.length !== 1) return "Usage: /codex resume <thread-id>";
|
|
1766
|
-
if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1799
|
+
if (await isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1767
1800
|
if (!ctx.sessionId) return "Cannot attach a Codex thread because this command did not include an OpenClaw session id.";
|
|
1768
1801
|
const scope = resolveCodexConversationControlScope(ctx);
|
|
1769
1802
|
const identity = sessionBindingIdentity({
|
|
@@ -1772,13 +1805,14 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1772
1805
|
agentId: scope.agentId,
|
|
1773
1806
|
config: ctx.config
|
|
1774
1807
|
});
|
|
1775
|
-
const { authority } = await resolveCodexSessionBinding({
|
|
1808
|
+
const { authority, release } = await resolveCodexSessionBinding({
|
|
1776
1809
|
reclaimStale: true,
|
|
1777
1810
|
bindingStore: deps.bindingStore,
|
|
1778
1811
|
identity,
|
|
1779
1812
|
config: ctx.config,
|
|
1780
1813
|
storePath: ctx.sessionTarget?.storePath
|
|
1781
1814
|
});
|
|
1815
|
+
using _ = { [Symbol.dispose]: release };
|
|
1782
1816
|
const assertHostGeneration = authority.assertLegacyCurrent;
|
|
1783
1817
|
return await withExclusiveCodexAppServerThread({
|
|
1784
1818
|
bindingStore: deps.bindingStore,
|
|
@@ -1788,16 +1822,16 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1788
1822
|
const generation = await deps.bindingStore.prepareSessionGenerationReclaim(identity);
|
|
1789
1823
|
assertHostGeneration();
|
|
1790
1824
|
if (generation.kind !== "resolved" || !generation.result) throw createCodexSessionGenerationSupersededError(identity.sessionId);
|
|
1791
|
-
const currentBinding = deps.bindingStore.
|
|
1825
|
+
const currentBinding = await deps.bindingStore.readAsync(identity);
|
|
1792
1826
|
assertCodexBindingMayBeReplaced(currentBinding, "attaching a different resumed thread");
|
|
1793
1827
|
let pendingResumeConfiguration = false;
|
|
1794
|
-
const commitResumedThread = async (value, client, { authProfileId, assertCurrent }) => {
|
|
1828
|
+
const commitResumedThread = async (value, client, { authProfileId, assertCurrent, assertCurrentAsync, source }) => {
|
|
1795
1829
|
const response = assertCodexThreadResumeResponse(value);
|
|
1796
1830
|
const effectiveThreadId = response.thread.id;
|
|
1797
1831
|
if (effectiveThreadId !== normalizedThreadId) throw new Error(`Codex thread/resume returned ${effectiveThreadId} for ${normalizedThreadId}`);
|
|
1798
1832
|
const resumedCwd = response.thread.cwd;
|
|
1799
1833
|
if (typeof resumedCwd !== "string") throw new Error(`Codex thread/resume returned no cwd for ${normalizedThreadId}`);
|
|
1800
|
-
const modelProvider = normalizeCodexAppServerBindingModelProvider({
|
|
1834
|
+
const modelProvider = await normalizeCodexAppServerBindingModelProvider({
|
|
1801
1835
|
authProfileId,
|
|
1802
1836
|
modelProvider: response.modelProvider ?? void 0,
|
|
1803
1837
|
agentDir: scope.agentDir,
|
|
@@ -1808,7 +1842,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1808
1842
|
let sameOwner = false;
|
|
1809
1843
|
let knownOwnership;
|
|
1810
1844
|
try {
|
|
1811
|
-
const bindingBeforeCommit = deps.bindingStore.
|
|
1845
|
+
const bindingBeforeCommit = await deps.bindingStore.readAsync(identity);
|
|
1812
1846
|
assertCodexBindingMayBeReplaced(bindingBeforeCommit, "committing a different resumed thread");
|
|
1813
1847
|
sameOwner = isSameCodexAppServerThreadOwner(bindingBeforeCommit, {
|
|
1814
1848
|
threadId: effectiveThreadId,
|
|
@@ -1816,6 +1850,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1816
1850
|
});
|
|
1817
1851
|
const sameThreadBinding = bindingBeforeCommit?.threadId === effectiveThreadId ? bindingBeforeCommit : void 0;
|
|
1818
1852
|
pendingResumeConfiguration = sameThreadBinding?.preserveNativeModel !== true && (!sameThreadBinding?.dynamicToolsFingerprint || !sameThreadBinding.webSearchThreadConfigFingerprint || sameThreadBinding.pendingResumeConfiguration === true);
|
|
1853
|
+
await assertCurrentAsync?.();
|
|
1819
1854
|
assertCurrent();
|
|
1820
1855
|
assertCodexThreadAcceptsDirectInput(response.thread);
|
|
1821
1856
|
knownOwnership = sameOwner ? await consumeCodexAppServerLiveThread(client, effectiveThreadId) : void 0;
|
|
@@ -1825,6 +1860,11 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1825
1860
|
if (!retained) throw new Error("Codex resumed thread lost its native subscription owner.");
|
|
1826
1861
|
if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit, {
|
|
1827
1862
|
assertCurrent,
|
|
1863
|
+
withCurrent: async (write) => {
|
|
1864
|
+
await assertCurrentAsync?.();
|
|
1865
|
+
assertCurrent();
|
|
1866
|
+
write();
|
|
1867
|
+
},
|
|
1828
1868
|
retainedClientId: clientId
|
|
1829
1869
|
});
|
|
1830
1870
|
assertCurrent();
|
|
@@ -1842,7 +1882,11 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1842
1882
|
modelProvider,
|
|
1843
1883
|
historyCoveredThrough: (/* @__PURE__ */ new Date()).toISOString()
|
|
1844
1884
|
}
|
|
1845
|
-
},
|
|
1885
|
+
}, composeSessionEntryCommitGuards([
|
|
1886
|
+
assertCurrent,
|
|
1887
|
+
source,
|
|
1888
|
+
ctx.nativePolicySource
|
|
1889
|
+
]))) throw new Error("Codex thread binding changed while attaching the resumed thread.");
|
|
1846
1890
|
} catch (error) {
|
|
1847
1891
|
if (sameOwner && knownOwnership && !retained) {
|
|
1848
1892
|
if (!await retainCodexAppServerBindingSubscription(client, effectiveThreadId, knownOwnership)) await closeCodexStartupClientBestEffort(client);
|
|
@@ -1862,6 +1906,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1862
1906
|
sessionId: ctx.sessionId,
|
|
1863
1907
|
storePath: ctx.sessionTarget?.storePath,
|
|
1864
1908
|
assertCurrent: assertHostGeneration,
|
|
1909
|
+
assertCurrentAsync: ctx.assertNativePolicyCurrent,
|
|
1865
1910
|
assertOwnerCurrent: () => assertCodexHostOwnerCurrent(ctx),
|
|
1866
1911
|
beforeRequest: async (request) => {
|
|
1867
1912
|
const { thread } = await request({
|
|
@@ -1881,10 +1926,10 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1881
1926
|
}
|
|
1882
1927
|
async function bindCodexCliNodeSession(deps, ctx, parsed) {
|
|
1883
1928
|
if (!parsed.threadId || !parsed.host || parsed.bindHere !== true) return "Usage: /codex resume <session-id> --host <node> --bind here";
|
|
1884
|
-
if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1929
|
+
if (await isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1885
1930
|
if (ctx.sessionId) {
|
|
1886
1931
|
const scope = resolveCodexConversationControlScope(ctx);
|
|
1887
|
-
const binding = deps.bindingStore.
|
|
1932
|
+
const binding = await deps.bindingStore.readAsync(sessionBindingIdentity({
|
|
1888
1933
|
sessionId: ctx.sessionId,
|
|
1889
1934
|
sessionKey: ctx.sessionKey,
|
|
1890
1935
|
agentId: scope.agentId,
|
|
@@ -1907,6 +1952,7 @@ async function bindCodexCliNodeSession(deps, ctx, parsed) {
|
|
|
1907
1952
|
cwd: resolved.session?.cwd
|
|
1908
1953
|
});
|
|
1909
1954
|
const summary = `Codex CLI session ${formatCodexDisplayText(parsed.threadId)} on ${formatCodexDisplayText(nodeId)}`;
|
|
1955
|
+
await ctx.assertNativePolicyCurrent?.();
|
|
1910
1956
|
assertCodexHostOwnerCurrent(ctx);
|
|
1911
1957
|
const request = await ctx.requestConversationBinding({
|
|
1912
1958
|
summary,
|
|
@@ -1936,21 +1982,71 @@ const CODEX_NATIVE_CONTROL_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
1936
1982
|
"unbind",
|
|
1937
1983
|
"stop"
|
|
1938
1984
|
]);
|
|
1939
|
-
function resolveCodexNativeCommandSandboxBlock(ctx, subcommand, args) {
|
|
1940
|
-
if (isReadOnlyCodexGoalCommand(subcommand, args) ||
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1985
|
+
async function resolveCodexNativeCommandSandboxBlock(ctx, subcommand, args) {
|
|
1986
|
+
if (isReadOnlyCodexGoalCommand(subcommand, args) || returnsBeforeNativeCodexExecution(subcommand, args)) return {
|
|
1987
|
+
block: void 0,
|
|
1988
|
+
async assertCurrent() {},
|
|
1989
|
+
release() {}
|
|
1990
|
+
};
|
|
1991
|
+
const sessionKey = ctx.sessionTarget?.sessionKey ?? ctx.sessionKey;
|
|
1992
|
+
const checksModelLock = [
|
|
1993
|
+
"bind",
|
|
1994
|
+
"resume",
|
|
1995
|
+
"detach",
|
|
1996
|
+
"unbind",
|
|
1997
|
+
"model"
|
|
1998
|
+
].includes(subcommand);
|
|
1999
|
+
if (!checksModelLock && !CODEX_NATIVE_EXECUTION_SUBCOMMANDS.has(subcommand)) return {
|
|
2000
|
+
block: void 0,
|
|
2001
|
+
async assertCurrent() {},
|
|
2002
|
+
release() {}
|
|
2003
|
+
};
|
|
2004
|
+
const agentId = ctx.sessionTarget?.agentId ?? resolveCodexConversationControlScope(ctx).agentId;
|
|
2005
|
+
const storePath = ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId });
|
|
2006
|
+
const modelCurrent = checksModelLock && sessionKey ? await captureSessionEntryCurrentCheckAsync({
|
|
2007
|
+
agentId,
|
|
2008
|
+
storePath,
|
|
2009
|
+
sessionKey,
|
|
2010
|
+
fields: ["modelSelectionLocked"]
|
|
2011
|
+
}) : void 0;
|
|
2012
|
+
if (!CODEX_NATIVE_EXECUTION_SUBCOMMANDS.has(subcommand)) return {
|
|
2013
|
+
block: void 0,
|
|
2014
|
+
assertCurrent: modelCurrent?.assertCurrent ?? (async () => {}),
|
|
2015
|
+
source: modelCurrent?.source,
|
|
2016
|
+
release: modelCurrent?.release ?? (() => {})
|
|
2017
|
+
};
|
|
2018
|
+
let execution;
|
|
2019
|
+
try {
|
|
2020
|
+
const surface = `/${["codex", subcommand].join(" ")}`;
|
|
2021
|
+
execution = isCodexCliNodeResumeBind(subcommand, args) ? await prepareCodexNativeSandboxBlock({
|
|
2022
|
+
config: ctx.config,
|
|
2023
|
+
sessionKey: ctx.sessionKey,
|
|
2024
|
+
sessionId: ctx.sessionId,
|
|
2025
|
+
surface
|
|
2026
|
+
}) : await prepareCodexNativeExecutionBlock({
|
|
2027
|
+
config: ctx.config,
|
|
2028
|
+
agentId: ctx.agentId,
|
|
2029
|
+
sessionKey,
|
|
2030
|
+
sessionId: ctx.sessionId,
|
|
2031
|
+
storePath,
|
|
2032
|
+
surface
|
|
2033
|
+
});
|
|
2034
|
+
} catch (error) {
|
|
2035
|
+
modelCurrent?.release();
|
|
2036
|
+
throw error;
|
|
2037
|
+
}
|
|
2038
|
+
return {
|
|
2039
|
+
block: execution.block,
|
|
2040
|
+
source: composeSessionEntryCommitGuards([modelCurrent?.source, execution.source]),
|
|
2041
|
+
assertCurrent: async () => {
|
|
2042
|
+
await modelCurrent?.assertCurrent();
|
|
2043
|
+
await execution.assertCurrent();
|
|
2044
|
+
},
|
|
2045
|
+
release: () => {
|
|
2046
|
+
modelCurrent?.release();
|
|
2047
|
+
execution.release();
|
|
2048
|
+
}
|
|
2049
|
+
};
|
|
1954
2050
|
}
|
|
1955
2051
|
function isReadOnlyCodexGoalCommand(subcommand, args) {
|
|
1956
2052
|
if (subcommand !== "goal" || args.length > 1) return false;
|
|
@@ -2006,6 +2102,7 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
|
|
|
2006
2102
|
const action = (args[0] ?? "status").toLowerCase();
|
|
2007
2103
|
const objective = args.slice(1).join(" ").trim();
|
|
2008
2104
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
2105
|
+
using _ = { [Symbol.dispose]: authority.release };
|
|
2009
2106
|
const { target, binding } = authority;
|
|
2010
2107
|
if (!target) return "Cannot manage the Codex goal because this command has no stable binding identity.";
|
|
2011
2108
|
if (!binding?.threadId) return "No Codex thread is attached to this OpenClaw session yet.";
|
|
@@ -2015,7 +2112,8 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
|
|
|
2015
2112
|
pluginConfig,
|
|
2016
2113
|
agentDir: target.agentDir,
|
|
2017
2114
|
config: ctx.config,
|
|
2018
|
-
assertCurrent: authority.assertCurrent
|
|
2115
|
+
assertCurrent: authority.assertCurrent,
|
|
2116
|
+
assertCurrentAsync: authority.assertCurrentAsync
|
|
2019
2117
|
});
|
|
2020
2118
|
const goalRequestOptions = {
|
|
2021
2119
|
agentDir: target.agentDir,
|
|
@@ -2025,6 +2123,7 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
|
|
|
2025
2123
|
sessionKey: authority.sessionKey,
|
|
2026
2124
|
storePath: authority.storePath,
|
|
2027
2125
|
assertCurrent: authority.assertCurrent,
|
|
2126
|
+
assertCurrentAsync: authority.assertCurrentAsync,
|
|
2028
2127
|
...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {}
|
|
2029
2128
|
};
|
|
2030
2129
|
if (action === "status" || action === "get" || action === "clear") {
|
|
@@ -2066,12 +2165,14 @@ function formatNativeGoal(response) {
|
|
|
2066
2165
|
}
|
|
2067
2166
|
async function controlConversationTurn(deps, ctx, command, message) {
|
|
2068
2167
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
2168
|
+
using _ = { [Symbol.dispose]: authority.release };
|
|
2069
2169
|
const { target, binding } = authority;
|
|
2070
2170
|
if (!target) return `Cannot ${command} Codex because this command did not include a stable binding identity.`;
|
|
2071
2171
|
const params = {
|
|
2072
2172
|
identity: target.identity,
|
|
2073
2173
|
binding,
|
|
2074
|
-
assertCurrent: authority.assertMutationCurrent
|
|
2174
|
+
assertCurrent: authority.assertMutationCurrent,
|
|
2175
|
+
assertCurrentAsync: authority.assertCurrentAsync
|
|
2075
2176
|
};
|
|
2076
2177
|
return (command === "stop" ? await deps.stopCodexConversationTurn(params) : await deps.steerCodexConversationTurn({
|
|
2077
2178
|
...params,
|
|
@@ -2082,12 +2183,13 @@ async function setConversationModel(deps, ctx, args) {
|
|
|
2082
2183
|
if (args.length > 1) return "Usage: /codex model <model>";
|
|
2083
2184
|
const [model = ""] = args;
|
|
2084
2185
|
const normalized = model.trim();
|
|
2085
|
-
if (normalized && isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
2186
|
+
if (normalized && await isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
2086
2187
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
2188
|
+
using _ = { [Symbol.dispose]: authority.release };
|
|
2087
2189
|
const { target, binding } = authority;
|
|
2088
2190
|
if (!target) return "Cannot set Codex model because this command did not include a stable binding identity.";
|
|
2089
2191
|
if (!normalized) {
|
|
2090
|
-
const currentSession = authority.sessionId && authority.sessionKey && authority.storePath ?
|
|
2192
|
+
const currentSession = authority.sessionId && authority.sessionKey && authority.storePath ? await getSessionEntryAsync({
|
|
2091
2193
|
storePath: authority.storePath,
|
|
2092
2194
|
sessionKey: authority.sessionKey,
|
|
2093
2195
|
hydrateSkillPromptRefs: false,
|
|
@@ -2107,13 +2209,15 @@ async function setConversationModel(deps, ctx, args) {
|
|
|
2107
2209
|
binding,
|
|
2108
2210
|
storePath: authority.storePath,
|
|
2109
2211
|
assertCurrent: authority.assertCurrent,
|
|
2110
|
-
|
|
2212
|
+
assertCurrentAsync: authority.assertCurrentAsync,
|
|
2213
|
+
assertCommitAllowed: composeSessionEntryCommitGuards([authority.mutationSource, authority.assertMutationCurrent])
|
|
2111
2214
|
});
|
|
2112
2215
|
}
|
|
2113
2216
|
async function setConversationPreference(deps, ctx, args, kind) {
|
|
2114
2217
|
const usage = `Usage: /codex ${kind} ${kind === "fast" ? "[on|off|status]" : "[default|yolo|status]"}`;
|
|
2115
2218
|
if (args.length > 1) return usage;
|
|
2116
2219
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
2220
|
+
using _ = { [Symbol.dispose]: authority.release };
|
|
2117
2221
|
const { target, binding } = authority;
|
|
2118
2222
|
if (kind === "fast") {
|
|
2119
2223
|
if (!target) return "Cannot set Codex fast mode because this command did not include a stable binding identity.";
|
|
@@ -2125,7 +2229,7 @@ async function setConversationPreference(deps, ctx, args, kind) {
|
|
|
2125
2229
|
bindingStore: deps.bindingStore,
|
|
2126
2230
|
binding,
|
|
2127
2231
|
enabled: parsed,
|
|
2128
|
-
assertCurrent: parsed === void 0 ? authority.assertCurrent : authority.assertMutationCurrent
|
|
2232
|
+
assertCurrent: parsed === void 0 ? authority.assertCurrent : composeSessionEntryCommitGuards([authority.mutationSource, authority.assertMutationCurrent])
|
|
2129
2233
|
});
|
|
2130
2234
|
}
|
|
2131
2235
|
if (!target || !ctx.sessionId || !ctx.sessionKey) return "Cannot set Codex permissions because this command did not include a complete session identity.";
|
|
@@ -2138,6 +2242,7 @@ async function setConversationPreference(deps, ctx, args, kind) {
|
|
|
2138
2242
|
config: ctx.config,
|
|
2139
2243
|
storePath: authority.storePath,
|
|
2140
2244
|
assertCurrent: parsed ? authority.assertHostMutationCurrent : authority.assertHostCurrent,
|
|
2245
|
+
sourceAuthority: parsed ? composeSessionEntryCommitGuards([authority.mutationSource, authority.assertHostMutationCurrent]) : void 0,
|
|
2141
2246
|
session: {
|
|
2142
2247
|
agentId: target.agentId,
|
|
2143
2248
|
sessionId: ctx.sessionId,
|
|
@@ -2148,13 +2253,14 @@ async function setConversationPreference(deps, ctx, args, kind) {
|
|
|
2148
2253
|
async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
2149
2254
|
if (args.length > 0) return `Usage: /codex ${kind}`;
|
|
2150
2255
|
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
2256
|
+
using _ = { [Symbol.dispose]: authority.release };
|
|
2151
2257
|
const { target, binding } = authority;
|
|
2152
2258
|
if (!target) return `Cannot start Codex ${kind === "compact" ? "compaction" : "review"} because this command did not include a stable binding identity.`;
|
|
2153
2259
|
if (!binding?.threadId) return `No Codex thread is attached to this OpenClaw session yet.`;
|
|
2154
2260
|
if (kind === "compact") {
|
|
2155
2261
|
const sessionTarget = ctx.sessionTarget;
|
|
2156
2262
|
if (!ctx.sessionId || !ctx.sessionKey || !sessionTarget || sessionTarget.sessionId !== ctx.sessionId || sessionTarget.sessionKey !== ctx.sessionKey) return "Codex compaction is unavailable because this command is not bound to a complete session identity.";
|
|
2157
|
-
const currentSession =
|
|
2263
|
+
const currentSession = await getSessionEntryAsync({
|
|
2158
2264
|
storePath: authority.storePath ?? sessionTarget.storePath,
|
|
2159
2265
|
sessionKey: ctx.sessionKey,
|
|
2160
2266
|
hydrateSkillPromptRefs: false,
|
|
@@ -2166,6 +2272,7 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
|
2166
2272
|
}
|
|
2167
2273
|
const compactCurrent = ctx.runtimeContext?.compactCurrent;
|
|
2168
2274
|
if (!compactCurrent) return "Codex compaction is unavailable because this command is not bound to a session.";
|
|
2275
|
+
await authority.assertCurrentAsync();
|
|
2169
2276
|
authority.assertMutationCurrent();
|
|
2170
2277
|
const result = await compactCurrent();
|
|
2171
2278
|
return result.compacted ? `Compacted Codex session (${result.tokensAfter ?? "unknown"} tokens after).` : `Codex compaction did not complete: ${formatCodexDisplayText(result.reason ?? "no reason returned")}.`;
|
|
@@ -2176,7 +2283,8 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
|
2176
2283
|
pluginConfig,
|
|
2177
2284
|
agentDir: target.agentDir,
|
|
2178
2285
|
config: ctx.config,
|
|
2179
|
-
assertCurrent: authority.assertCurrent
|
|
2286
|
+
assertCurrent: authority.assertCurrent,
|
|
2287
|
+
assertCurrentAsync: authority.assertCurrentAsync
|
|
2180
2288
|
});
|
|
2181
2289
|
await deps.bindingStore.withLease(target.identity, () => deps.codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.review, {
|
|
2182
2290
|
threadId: binding.threadId,
|
|
@@ -2189,6 +2297,7 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
|
2189
2297
|
sessionKey: authority.sessionKey,
|
|
2190
2298
|
storePath: authority.storePath,
|
|
2191
2299
|
assertCurrent: authority.assertCurrent,
|
|
2300
|
+
assertCurrentAsync: authority.assertCurrentAsync,
|
|
2192
2301
|
assertOwnerCurrent: () => assertCodexHostOwnerCurrent(ctx),
|
|
2193
2302
|
...connection.usesSupervisionConnection ? {
|
|
2194
2303
|
startOptions: connection.appServer.start,
|
|
@@ -2613,8 +2722,8 @@ async function withCodexPluginCommandContext(params, run) {
|
|
|
2613
2722
|
gatewayClientScopes: params.ctx.gatewayClientScopes?.slice()
|
|
2614
2723
|
};
|
|
2615
2724
|
const current = await deps.codexPluginsManagementIo?.readConfig() ?? {};
|
|
2616
|
-
const
|
|
2617
|
-
|
|
2725
|
+
const { scope, binding } = await resolveCommandAppServerContext(deps, ctx, pluginConfig);
|
|
2726
|
+
using _ = { [Symbol.dispose]: scope.release };
|
|
2618
2727
|
const conversation = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
|
|
2619
2728
|
const workspaceDir = binding?.cwd || (conversation?.kind === "codex-app-server-session" ? conversation.workspaceDir : void 0) || resolveAgentWorkspaceDir(ctx.config, scope.agentId);
|
|
2620
2729
|
const configuredRuntime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
@@ -2626,102 +2735,108 @@ async function withCodexPluginCommandContext(params, run) {
|
|
|
2626
2735
|
...scope,
|
|
2627
2736
|
config: ctx.config
|
|
2628
2737
|
}, appServer.start);
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2738
|
+
try {
|
|
2739
|
+
const { assertCurrentAsync } = {
|
|
2740
|
+
assertCurrentAsync: scope.assertCurrentAsync,
|
|
2741
|
+
...auth.clientOptions
|
|
2742
|
+
};
|
|
2743
|
+
const preparedAuth = "preparedAuth" in auth.clientOptions ? auth.clientOptions.preparedAuth : void 0;
|
|
2744
|
+
const usesNativeAuth = scope.authProfileId === null || appServer.start.homeScope === "user";
|
|
2745
|
+
const profileId = usesNativeAuth ? void 0 : auth.authProfileId;
|
|
2746
|
+
const readAuthBinding = async () => profileId ? fingerprintCodexAppServerAuthBinding({
|
|
2747
|
+
authProfileId: profileId,
|
|
2748
|
+
authProfileStore: await resolveCodexAppServerAuthProfileStore({
|
|
2749
|
+
authProfileId: profileId,
|
|
2750
|
+
agentDir: scope.agentDir,
|
|
2751
|
+
config: ctx.config
|
|
2752
|
+
}),
|
|
2753
|
+
agentDir: scope.agentDir,
|
|
2754
|
+
config: ctx.config
|
|
2755
|
+
}) : Promise.resolve(void 0);
|
|
2756
|
+
const authBinding = "authBindingFingerprint" in auth.clientOptions ? auth.clientOptions.authBindingFingerprint : await readAuthBinding();
|
|
2757
|
+
const accountId = usesNativeAuth ? void 0 : preparedAuth?.kind === "api-key" ? resolveCodexAppServerPreparedApiKeyCacheKey(preparedAuth.apiKey) : preparedAuth?.kind === "profile" ? preparedAuth.snapshot.secretFreeCacheKey : await resolveCodexAppServerAuthAccountCacheKey({
|
|
2635
2758
|
authProfileId: profileId,
|
|
2636
2759
|
agentDir: scope.agentDir,
|
|
2637
2760
|
config: ctx.config
|
|
2638
|
-
}),
|
|
2639
|
-
agentDir: scope.agentDir,
|
|
2640
|
-
config: ctx.config
|
|
2641
|
-
}) : Promise.resolve(void 0);
|
|
2642
|
-
const authBinding = "authBindingFingerprint" in auth.clientOptions ? auth.clientOptions.authBindingFingerprint : await readAuthBinding();
|
|
2643
|
-
const accountId = usesNativeAuth ? void 0 : preparedAuth?.kind === "api-key" ? resolveCodexAppServerPreparedApiKeyCacheKey(preparedAuth.apiKey) : preparedAuth?.kind === "profile" ? preparedAuth.snapshot.secretFreeCacheKey : await resolveCodexAppServerAuthAccountCacheKey({
|
|
2644
|
-
authProfileId: profileId,
|
|
2645
|
-
agentDir: scope.agentDir,
|
|
2646
|
-
config: ctx.config
|
|
2647
|
-
});
|
|
2648
|
-
if (await readAuthBinding() !== authBinding) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2649
|
-
return await withCodexAppServerJsonClient({
|
|
2650
|
-
startOptions: appServer.start,
|
|
2651
|
-
pluginConfig,
|
|
2652
|
-
agentDir: scope.agentDir,
|
|
2653
|
-
config: ctx.config,
|
|
2654
|
-
sessionId: ctx.sessionId,
|
|
2655
|
-
sessionKey: ctx.sessionKey,
|
|
2656
|
-
timeoutMs: appServer.requestTimeoutMs,
|
|
2657
|
-
timeoutMessage: "Codex plugin request timed out. Check the Codex connection and retry.",
|
|
2658
|
-
assertCurrent: scope.assertCurrent,
|
|
2659
|
-
...auth.clientOptions
|
|
2660
|
-
}, async (request, client, requestScope) => {
|
|
2661
|
-
const assertCurrent = () => {
|
|
2662
|
-
requestScope.assertCurrent();
|
|
2663
|
-
if (client.getCloseError()) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2664
|
-
};
|
|
2665
|
-
const validateCurrent = async () => {
|
|
2666
|
-
assertCurrent();
|
|
2667
|
-
const currentTarget = await resolveControlTarget(ctx);
|
|
2668
|
-
const currentConversation = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
|
|
2669
|
-
const currentPolicy = JSON.stringify(await deps.codexPluginsManagementIo?.readConfig() ?? {});
|
|
2670
|
-
const currentAuthBinding = await readAuthBinding();
|
|
2671
|
-
assertCurrent();
|
|
2672
|
-
if (!isDeepStrictEqual(currentTarget, target) || !isDeepStrictEqual(currentConversation, conversation) || currentPolicy !== initialPolicy || currentAuthBinding !== authBinding) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2673
|
-
};
|
|
2674
|
-
try {
|
|
2675
|
-
await request({
|
|
2676
|
-
method: "account/read",
|
|
2677
|
-
requestParams: { refreshToken: false },
|
|
2678
|
-
assertCurrent
|
|
2679
|
-
});
|
|
2680
|
-
} catch {
|
|
2681
|
-
requestScope.assertCurrent();
|
|
2682
|
-
throw new Error("Codex account startup could not be confirmed. Check /codex account and retry.");
|
|
2683
|
-
}
|
|
2684
|
-
const unsubscribe = client.addNotificationHandler((notification) => {
|
|
2685
|
-
if (notification.method === "account/updated") requestScope.abort(/* @__PURE__ */ new Error(SCOPE_CHANGED_MESSAGE));
|
|
2686
2761
|
});
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
})
|
|
2717
|
-
|
|
2762
|
+
if (await readAuthBinding() !== authBinding) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2763
|
+
return await withCodexAppServerJsonClient({
|
|
2764
|
+
startOptions: appServer.start,
|
|
2765
|
+
pluginConfig,
|
|
2766
|
+
agentDir: scope.agentDir,
|
|
2767
|
+
config: ctx.config,
|
|
2768
|
+
sessionId: ctx.sessionId,
|
|
2769
|
+
sessionKey: ctx.sessionKey,
|
|
2770
|
+
timeoutMs: appServer.requestTimeoutMs,
|
|
2771
|
+
timeoutMessage: "Codex plugin request timed out. Check the Codex connection and retry.",
|
|
2772
|
+
assertCurrent: scope.assertCurrent,
|
|
2773
|
+
...auth.clientOptions
|
|
2774
|
+
}, async (request, client, requestScope) => {
|
|
2775
|
+
const assertCurrent = () => {
|
|
2776
|
+
requestScope.assertCurrent();
|
|
2777
|
+
if (client.getCloseError()) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2778
|
+
};
|
|
2779
|
+
const validateCurrent = async () => {
|
|
2780
|
+
assertCurrent();
|
|
2781
|
+
const currentAuthBinding = await readAuthBinding();
|
|
2782
|
+
await assertCurrentAsync?.();
|
|
2783
|
+
assertCurrent();
|
|
2784
|
+
if (currentAuthBinding !== authBinding) throw new Error(SCOPE_CHANGED_MESSAGE);
|
|
2785
|
+
};
|
|
2786
|
+
try {
|
|
2787
|
+
await request({
|
|
2788
|
+
method: "account/read",
|
|
2789
|
+
requestParams: { refreshToken: false },
|
|
2790
|
+
assertCurrent
|
|
2791
|
+
});
|
|
2792
|
+
} catch {
|
|
2793
|
+
requestScope.assertCurrent();
|
|
2794
|
+
throw new Error("Codex account startup could not be confirmed. Check /codex account and retry.");
|
|
2795
|
+
}
|
|
2796
|
+
const unsubscribe = client.addNotificationHandler((notification) => {
|
|
2797
|
+
if (notification.method === "account/updated") requestScope.abort(/* @__PURE__ */ new Error(SCOPE_CHANGED_MESSAGE));
|
|
2718
2798
|
});
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2799
|
+
try {
|
|
2800
|
+
await validateCurrent();
|
|
2801
|
+
const result = await run({
|
|
2802
|
+
request: async (method, requestParams) => {
|
|
2803
|
+
await validateCurrent();
|
|
2804
|
+
const response = await request({
|
|
2805
|
+
method,
|
|
2806
|
+
requestParams,
|
|
2807
|
+
assertCurrent: () => {
|
|
2808
|
+
assertCurrent();
|
|
2809
|
+
assertCodexHostOwnerCurrent(ctx);
|
|
2810
|
+
}
|
|
2811
|
+
});
|
|
2812
|
+
await validateCurrent();
|
|
2813
|
+
return response;
|
|
2814
|
+
},
|
|
2815
|
+
workspaceDir,
|
|
2816
|
+
agentId: scope.agentId,
|
|
2817
|
+
current,
|
|
2818
|
+
...profileId ? { profileId } : {},
|
|
2819
|
+
...binding?.clientId === client.getInstanceId() ? { threadId: binding.threadId } : {},
|
|
2820
|
+
appCacheKey: buildCodexPluginAppCacheKey({
|
|
2821
|
+
appServer,
|
|
2822
|
+
agentDir: scope.agentDir,
|
|
2823
|
+
authProfileId: profileId,
|
|
2824
|
+
accountId,
|
|
2825
|
+
envApiKeyFingerprint: usesNativeAuth || preparedAuth || profileId ? void 0 : resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions: appServer.start }),
|
|
2826
|
+
appServerVersion: client.getServerVersion(),
|
|
2827
|
+
runtimeIdentity: client.getRuntimeIdentity()
|
|
2828
|
+
}),
|
|
2829
|
+
validateCurrent
|
|
2830
|
+
});
|
|
2831
|
+
await validateCurrent();
|
|
2832
|
+
return result;
|
|
2833
|
+
} finally {
|
|
2834
|
+
unsubscribe();
|
|
2835
|
+
}
|
|
2836
|
+
});
|
|
2837
|
+
} finally {
|
|
2838
|
+
auth.release();
|
|
2839
|
+
}
|
|
2725
2840
|
}
|
|
2726
2841
|
//#endregion
|
|
2727
2842
|
//#region extensions/codex/src/command-handlers.ts
|
|
@@ -2733,168 +2848,186 @@ const CODEX_HOST_INSPECTION_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
2733
2848
|
"status",
|
|
2734
2849
|
"threads"
|
|
2735
2850
|
]);
|
|
2736
|
-
async function handleCodexSubcommand(
|
|
2851
|
+
async function handleCodexSubcommand(inputCtx, options) {
|
|
2737
2852
|
const deps = resolveCodexCommandDeps(options.deps);
|
|
2738
|
-
const args = splitArgs(
|
|
2853
|
+
const args = splitArgs(inputCtx.args);
|
|
2739
2854
|
if (args.length === 0) return buildCodexSubcommandPickerReply();
|
|
2740
2855
|
const [subcommand = "status", ...rest] = args;
|
|
2741
2856
|
const normalized = subcommand.toLowerCase();
|
|
2742
2857
|
if (normalized === "help") return { text: buildHelp() };
|
|
2743
|
-
if (CODEX_HOST_INSPECTION_SUBCOMMANDS.has(normalized) && !canMutateCodexHost(
|
|
2744
|
-
if (CODEX_NATIVE_CONTROL_SUBCOMMANDS.has(normalized) && !returnsBeforeNativeCodexExecution(normalized, rest) && !isReadOnlyCodexGoalCommand(normalized, rest) && !canMutateCodexHost(
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
}
|
|
2768
|
-
if (
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
}
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
pluginConfig: options.pluginConfig
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
const
|
|
2818
|
-
appServer,
|
|
2819
|
-
agentDir: scope.agentDir,
|
|
2858
|
+
if (CODEX_HOST_INSPECTION_SUBCOMMANDS.has(normalized) && !canMutateCodexHost(inputCtx)) return { text: CODEX_HOST_INSPECTION_AUTH_ERROR };
|
|
2859
|
+
if (CODEX_NATIVE_CONTROL_SUBCOMMANDS.has(normalized) && !returnsBeforeNativeCodexExecution(normalized, rest) && !isReadOnlyCodexGoalCommand(normalized, rest) && !canMutateCodexHost(inputCtx)) return { text: CODEX_NATIVE_EXECUTION_AUTH_ERROR };
|
|
2860
|
+
const nativePolicy = await resolveCodexNativeCommandSandboxBlock(inputCtx, normalized, rest);
|
|
2861
|
+
try {
|
|
2862
|
+
if (nativePolicy.block) return { text: nativePolicy.block };
|
|
2863
|
+
const previousPolicyCheck = inputCtx.assertNativePolicyCurrent;
|
|
2864
|
+
const ctx = {
|
|
2865
|
+
...inputCtx,
|
|
2866
|
+
nativePolicySource: nativePolicy.source,
|
|
2867
|
+
assertNativePolicyCurrent: async () => {
|
|
2868
|
+
await previousPolicyCheck?.();
|
|
2869
|
+
await nativePolicy.assertCurrent();
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
const usageCommand = normalized === "unbind" ? "detach" : normalized;
|
|
2873
|
+
if (rest.length > 0 && [
|
|
2874
|
+
"status",
|
|
2875
|
+
"models",
|
|
2876
|
+
"detach",
|
|
2877
|
+
"binding",
|
|
2878
|
+
"stop",
|
|
2879
|
+
"mcp",
|
|
2880
|
+
"skills",
|
|
2881
|
+
"account"
|
|
2882
|
+
].includes(usageCommand)) return { text: `Usage: /codex ${usageCommand}` };
|
|
2883
|
+
if (normalized === "plugins") {
|
|
2884
|
+
if (rest[0]?.toLowerCase() === "refresh") {
|
|
2885
|
+
if (rest.length !== 1) return { text: "Usage: /codex plugins refresh — refresh hosted app inventory for the current Codex account/runtime." };
|
|
2886
|
+
if (!canMutateCodexHost(ctx)) return { text: "Only an owner or operator.admin gateway client can refresh hosted app inventory." };
|
|
2887
|
+
return await withCodexPluginCommandContext({
|
|
2888
|
+
deps,
|
|
2889
|
+
ctx,
|
|
2890
|
+
pluginConfig: options.pluginConfig
|
|
2891
|
+
}, (context) => refreshCodexHostedApps(context));
|
|
2892
|
+
}
|
|
2893
|
+
if (!deps.codexPluginsManagementIo) return { text: "Codex sub-plugin management is not wired up (codexPluginsManagementIo dep is undefined). Edit ~/.openclaw/openclaw.json or use `openclaw config patch` until the runtime exposes the IO." };
|
|
2894
|
+
let appServerScope;
|
|
2895
|
+
await using _ = { [Symbol.asyncDispose]: async () => {
|
|
2896
|
+
await appServerScope?.then((scope) => scope.release(), () => {});
|
|
2897
|
+
} };
|
|
2898
|
+
const getAppServerScope = () => appServerScope ??= resolveCommandAppServerScope(deps, ctx, options.pluginConfig);
|
|
2899
|
+
return await handleCodexPluginsSubcommand(ctx, rest, deps.codexPluginsManagementIo, {
|
|
2900
|
+
withContext: (run) => withCodexPluginCommandContext({
|
|
2901
|
+
deps,
|
|
2902
|
+
ctx,
|
|
2903
|
+
pluginConfig: options.pluginConfig
|
|
2904
|
+
}, run),
|
|
2905
|
+
workspaceDir: async () => {
|
|
2906
|
+
const data = readCodexConversationBindingData(await ctx.getCurrentConversationBinding());
|
|
2907
|
+
return (data?.kind === "codex-app-server-session" ? data.workspaceDir : void 0)?.trim() || deps.resolveCodexDefaultWorkspaceDir(options.pluginConfig);
|
|
2908
|
+
},
|
|
2909
|
+
list: async (requestParams) => {
|
|
2910
|
+
const scope = await getAppServerScope();
|
|
2911
|
+
return await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.listPlugins, requestParams, {
|
|
2912
|
+
...scope,
|
|
2913
|
+
config: ctx.config
|
|
2914
|
+
});
|
|
2915
|
+
},
|
|
2916
|
+
install: async (requestParams) => {
|
|
2917
|
+
const scope = await getAppServerScope();
|
|
2918
|
+
return await deps.codexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.installPlugin, requestParams, {
|
|
2919
|
+
...scope,
|
|
2920
|
+
config: ctx.config,
|
|
2921
|
+
assertOwnerCurrent: () => assertCodexHostOwnerCurrent(ctx)
|
|
2922
|
+
});
|
|
2923
|
+
},
|
|
2924
|
+
refresh: async (workspaceDir) => {
|
|
2925
|
+
const scope = await getAppServerScope();
|
|
2926
|
+
const configuredAppServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
|
|
2927
|
+
const appServer = scope.startOptions ? {
|
|
2928
|
+
...configuredAppServer,
|
|
2929
|
+
start: scope.startOptions
|
|
2930
|
+
} : configuredAppServer;
|
|
2931
|
+
const authProfileId = scope.authProfileId ?? void 0;
|
|
2932
|
+
const accountId = await resolveCodexAppServerAuthAccountCacheKey({
|
|
2820
2933
|
authProfileId,
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
appServerVersion: client.getServerVersion(),
|
|
2824
|
-
runtimeIdentity: client.getRuntimeIdentity()
|
|
2934
|
+
agentDir: scope.agentDir,
|
|
2935
|
+
config: ctx.config
|
|
2825
2936
|
});
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
const requestMethod = resolvePluginRuntimeRefreshMethod(method);
|
|
2833
|
-
return await deps.codexControlRequest(options.pluginConfig, requestMethod, requestParams, {
|
|
2834
|
-
...scope,
|
|
2835
|
-
config: ctx.config
|
|
2836
|
-
});
|
|
2837
|
-
}
|
|
2937
|
+
const client = await getLeasedSharedCodexAppServerClient({
|
|
2938
|
+
startOptions: appServer.start,
|
|
2939
|
+
pluginConfig: options.pluginConfig,
|
|
2940
|
+
authProfileId: scope.authProfileId,
|
|
2941
|
+
agentDir: scope.agentDir,
|
|
2942
|
+
config: ctx.config
|
|
2838
2943
|
});
|
|
2839
|
-
|
|
2840
|
-
|
|
2944
|
+
try {
|
|
2945
|
+
const appCacheKey = buildCodexPluginAppCacheKey({
|
|
2946
|
+
appServer,
|
|
2947
|
+
agentDir: scope.agentDir,
|
|
2948
|
+
authProfileId,
|
|
2949
|
+
accountId,
|
|
2950
|
+
envApiKeyFingerprint: authProfileId ? void 0 : resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions: appServer.start }),
|
|
2951
|
+
appServerVersion: client.getServerVersion(),
|
|
2952
|
+
runtimeIdentity: client.getRuntimeIdentity()
|
|
2953
|
+
});
|
|
2954
|
+
return await refreshCodexPluginRuntimeState({
|
|
2955
|
+
configCwd: workspaceDir,
|
|
2956
|
+
appCache: defaultCodexAppInventoryCache,
|
|
2957
|
+
appCacheKey,
|
|
2958
|
+
metadataCache: defaultCodexPluginMetadataCache,
|
|
2959
|
+
request: async (method, requestParams) => {
|
|
2960
|
+
const requestMethod = resolvePluginRuntimeRefreshMethod(method);
|
|
2961
|
+
return await deps.codexControlRequest(options.pluginConfig, requestMethod, requestParams, {
|
|
2962
|
+
...scope,
|
|
2963
|
+
config: ctx.config
|
|
2964
|
+
});
|
|
2965
|
+
}
|
|
2966
|
+
});
|
|
2967
|
+
} finally {
|
|
2968
|
+
releaseLeasedSharedCodexAppServerClient(client);
|
|
2969
|
+
}
|
|
2841
2970
|
}
|
|
2842
|
-
}
|
|
2843
|
-
}
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
if (normalized === "status") {
|
|
2974
|
+
const { agentDir } = resolveCodexConversationControlScope(ctx);
|
|
2975
|
+
return { text: formatCodexStatus(await deps.readCodexStatusProbes(options.pluginConfig, ctx.config, agentDir)) };
|
|
2976
|
+
}
|
|
2977
|
+
if (normalized === "models") {
|
|
2978
|
+
const { agentDir } = resolveCodexConversationControlScope(ctx);
|
|
2979
|
+
return { text: formatModels(await deps.listCodexAppServerModels(deps.requestOptions(options.pluginConfig, 100, ctx.config, agentDir))) };
|
|
2980
|
+
}
|
|
2981
|
+
if (normalized === "threads") return { text: await buildThreads(deps, ctx, options.pluginConfig, rest.join(" ")) };
|
|
2982
|
+
if (normalized === "goal") return { text: await handleNativeGoal(deps, ctx, options.pluginConfig, rest) };
|
|
2983
|
+
if (normalized === "sessions") return { text: await buildCodexCliSessions(deps, rest) };
|
|
2984
|
+
if (normalized === "resume") return { text: await resumeThread(deps, ctx, options.pluginConfig, rest) };
|
|
2985
|
+
if (normalized === "bind") return await bindConversation(deps, ctx, options.pluginConfig, rest);
|
|
2986
|
+
if (normalized === "detach" || normalized === "unbind") return { text: await detachConversation(deps, ctx) };
|
|
2987
|
+
if (normalized === "binding") return { text: await describeConversationBinding(deps, ctx) };
|
|
2988
|
+
if (normalized === "stop" || normalized === "steer") return { text: await controlConversationTurn(deps, ctx, normalized, rest.join(" ")) };
|
|
2989
|
+
if (normalized === "model") return { text: await setConversationModel(deps, ctx, rest) };
|
|
2990
|
+
if (normalized === "fast" || normalized === "permissions") {
|
|
2991
|
+
if (isMenuVerb(rest)) return buildCodexChoiceMenuReply(normalized);
|
|
2992
|
+
return { text: await setConversationPreference(deps, ctx, rest, normalized) };
|
|
2993
|
+
}
|
|
2994
|
+
if (normalized === "compact" || normalized === "review") return { text: await startThreadAction(deps, ctx, options.pluginConfig, normalized, rest) };
|
|
2995
|
+
if (normalized === "diagnostics") return await handleCodexDiagnosticsFeedback(deps, ctx, options.pluginConfig, rest.join(" "));
|
|
2996
|
+
if (normalized === "computer-use" || normalized === "computeruse") {
|
|
2997
|
+
if (isMenuVerb(rest)) return buildCodexChoiceMenuReply("computer-use");
|
|
2998
|
+
return { text: await handleComputerUseCommand(deps, ctx, options.pluginConfig, rest) };
|
|
2999
|
+
}
|
|
3000
|
+
if (normalized === "mcp" || normalized === "skills") {
|
|
3001
|
+
const scope = await resolveCommandAppServerScope(deps, ctx, options.pluginConfig);
|
|
3002
|
+
using _ = { [Symbol.dispose]: scope.release };
|
|
3003
|
+
const response = await deps.codexControlRequest(options.pluginConfig, normalized === "mcp" ? CODEX_CONTROL_METHODS.listMcpServers : CODEX_CONTROL_METHODS.listSkills, normalized === "mcp" ? { limit: 100 } : {}, {
|
|
3004
|
+
config: ctx.config,
|
|
3005
|
+
...scope
|
|
3006
|
+
});
|
|
3007
|
+
return { text: normalized === "mcp" ? formatList(response, "MCP servers") : formatSkills(response) };
|
|
3008
|
+
}
|
|
3009
|
+
if (normalized === "account") {
|
|
3010
|
+
const scope = await resolveCommandAppServerScope(deps, ctx, options.pluginConfig);
|
|
3011
|
+
using _ = { [Symbol.dispose]: scope.release };
|
|
3012
|
+
const requestScope = {
|
|
3013
|
+
config: ctx.config,
|
|
3014
|
+
...scope
|
|
3015
|
+
};
|
|
3016
|
+
const [account, limits] = await Promise.all([deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.account, { refreshToken: false }, requestScope), deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.rateLimits, void 0, requestScope)]);
|
|
3017
|
+
return { text: formatAccount(account, limits, await readCodexAccountAuthOverview({
|
|
3018
|
+
ctx,
|
|
3019
|
+
agentDir: scope.agentDir,
|
|
3020
|
+
authProfileId: scope.authProfileId,
|
|
3021
|
+
pluginConfig: options.pluginConfig,
|
|
3022
|
+
safeCodexControlRequest: deps.safeCodexControlRequest,
|
|
3023
|
+
account,
|
|
3024
|
+
limits
|
|
3025
|
+
})) };
|
|
3026
|
+
}
|
|
3027
|
+
return { text: `Unknown Codex command: ${formatCodexDisplayText(subcommand)}\n\n${buildHelp()}` };
|
|
3028
|
+
} finally {
|
|
3029
|
+
nativePolicy.release();
|
|
2896
3030
|
}
|
|
2897
|
-
return { text: `Unknown Codex command: ${formatCodexDisplayText(subcommand)}\n\n${buildHelp()}` };
|
|
2898
3031
|
}
|
|
2899
3032
|
function resolvePluginRuntimeRefreshMethod(method) {
|
|
2900
3033
|
const recognized = [
|