@bitkyc08/opencodex 2.37.0 → 2.39.0-preview.20260901
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/bin/ocx.mjs +127 -16
- package/gui/dist/assets/index-6HZDkIpX.js +112 -0
- package/gui/dist/assets/index-uvENYLin.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/aside.svg +3 -0
- package/gui/dist/provider-icons/baseten.svg +13 -0
- package/gui/dist/provider-icons/bizrouter.svg +41 -0
- package/gui/dist/provider-icons/cerebras.svg +26 -0
- package/gui/dist/provider-icons/deepinfra.svg +75 -0
- package/gui/dist/provider-icons/deepseek-harness.svg +3 -0
- package/gui/dist/provider-icons/digitalocean.svg +10 -0
- package/gui/dist/provider-icons/featherless.svg +4 -0
- package/gui/dist/provider-icons/gajae-code.svg +410 -0
- package/gui/dist/provider-icons/hermes-agent.svg +207 -0
- package/gui/dist/provider-icons/hyperbolic.svg +18 -0
- package/gui/dist/provider-icons/kilo.svg +13 -0
- package/gui/dist/provider-icons/litellm.svg +1 -0
- package/gui/dist/provider-icons/minimax.svg +1 -0
- package/gui/dist/provider-icons/nanogpt.svg +74 -0
- package/gui/dist/provider-icons/nebius.svg +1 -0
- package/gui/dist/provider-icons/neuralwatt.svg +27 -0
- package/gui/dist/provider-icons/nous.svg +149 -0
- package/gui/dist/provider-icons/novita.svg +32 -0
- package/gui/dist/provider-icons/oh-my-pi.svg +11 -0
- package/gui/dist/provider-icons/openclaw.svg +54 -0
- package/gui/dist/provider-icons/orcarouter.svg +175 -0
- package/gui/dist/provider-icons/parallel.svg +13 -0
- package/gui/dist/provider-icons/prime-agent.svg +21 -0
- package/gui/dist/provider-icons/sambanova.svg +276 -0
- package/gui/dist/provider-icons/scaleway.svg +11 -0
- package/gui/dist/provider-icons/siliconflow.svg +18 -0
- package/gui/dist/provider-icons/synthetic.svg +12 -0
- package/gui/dist/provider-icons/together.svg +18 -0
- package/gui/dist/provider-icons/umans.svg +30 -0
- package/gui/dist/provider-icons/venice.svg +165 -0
- package/gui/dist/provider-icons/vultr.svg +15 -0
- package/gui/dist/provider-icons/zai.svg +218 -0
- package/gui/dist/provider-icons/zcode.svg +219 -0
- package/gui/dist/provider-icons/zenmux.svg +1 -0
- package/package.json +1 -1
- package/src/adapters/cursor/live-models.ts +1 -0
- package/src/adapters/cursor/protobuf-request.ts +4 -1
- package/src/adapters/cursor/tool-definitions.ts +36 -4
- package/src/adapters/openai-responses.ts +72 -10
- package/src/bridge.ts +15 -15
- package/src/cli/capabilities.ts +14 -0
- package/src/cli/codex-cli-update.ts +96 -0
- package/src/cli/codex-shim-autorestore.ts +3 -0
- package/src/cli/dispatch.ts +54 -18
- package/src/cli/export-command.ts +18 -17
- package/src/cli/help.ts +2 -2
- package/src/cli/index.ts +423 -32
- package/src/cli/integrations.ts +24 -2
- package/src/cli/launcher-context.ts +53 -2
- package/src/cli/opencode.ts +126 -33
- package/src/cli/registry.ts +16 -10
- package/src/cli/system-command.ts +6 -1
- package/src/cli/uninstall-plan.ts +86 -0
- package/src/clients/config-export.ts +293 -28
- package/src/codex/account-store.ts +131 -12
- package/src/codex/auth-api.ts +202 -33
- package/src/codex/autostart-health.ts +3 -3
- package/src/codex/catalog/provider-fetch.ts +96 -10
- package/src/codex/catalog/sync.ts +4 -3
- package/src/codex/cli-install-provenance.ts +795 -0
- package/src/codex/convergence.ts +4 -3
- package/src/codex/credential-mutation-epoch.ts +11 -0
- package/src/codex/history-job.ts +10 -0
- package/src/codex/history-manifest.ts +35 -2
- package/src/codex/history-provider.ts +196 -19
- package/src/codex/history-worker.ts +3 -0
- package/src/codex/main-account.ts +2 -0
- package/src/codex/model-entitlements.ts +430 -27
- package/src/codex/native-profile-manager.ts +4 -0
- package/src/codex/quota-401-recovery.ts +190 -0
- package/src/codex/quota-recovery-timing.ts +28 -0
- package/src/codex/quota.ts +6 -0
- package/src/codex/reset-credit-operation-ledger.ts +1411 -0
- package/src/codex/reset-credit-recovery.ts +20 -2
- package/src/codex/routing.ts +68 -16
- package/src/codex/shim.ts +204 -18
- package/src/codex/subagent-model-fallback.ts +4 -1
- package/src/codex/user-identity.ts +2 -1
- package/src/config/paths.ts +18 -3
- package/src/config/pending-teardown-names.d.mts +8 -0
- package/src/config/pending-teardown-names.mjs +69 -0
- package/src/config/pending-teardown.ts +286 -0
- package/src/config.ts +23 -0
- package/src/generated/compatibility-version.json +155 -67
- package/src/integrations/journal.ts +12 -1
- package/src/integrations/registry.ts +112 -0
- package/src/integrations/state.ts +67 -5
- package/src/integrations/writer.ts +107 -16
- package/src/lib/bounded-subprocess.ts +36 -0
- package/src/lib/process-control.ts +30 -5
- package/src/lib/state-store-registrations.ts +8 -0
- package/src/lib/strict-semver.ts +47 -0
- package/src/lib/windows-elevation.ts +32 -1
- package/src/lib/windows-secret-acl.ts +47 -25
- package/src/lib/windows-service-mutation-lock.ts +133 -0
- package/src/lib/windows-user-principal.ts +15 -17
- package/src/oauth/index.ts +220 -13
- package/src/oauth/store.ts +220 -18
- package/src/responses/spill-store.ts +354 -29
- package/src/responses/state.ts +775 -8
- package/src/server/index.ts +4 -3
- package/src/server/lifecycle.ts +5 -1
- package/src/server/management/integration-routes.ts +36 -5
- package/src/server/management/model-rows.ts +11 -2
- package/src/server/management/provider-routes.ts +4 -0
- package/src/server/management/system-restart.ts +5 -5
- package/src/server/management-api.ts +72 -13
- package/src/server/responses/encrypted-payload.ts +18 -1
- package/src/server/startup-action-control.ts +3 -2
- package/src/server/stop-teardown.ts +84 -0
- package/src/service.ts +749 -53
- package/src/sidecar/candidates.ts +1 -1
- package/src/update/codex-cli-update-launch-policy.d.mts +18 -0
- package/src/update/codex-cli-update-launch-policy.mjs +30 -0
- package/src/update/index.ts +39 -6
- package/src/update/job.ts +10 -11
- package/src/update/proxy-liveness-probe.d.mts +6 -0
- package/src/update/proxy-liveness-probe.mjs +84 -0
- package/src/update/stop-contract.d.mts +2 -0
- package/src/update/stop-contract.mjs +15 -0
- package/src/update/stop-decision.d.mts +10 -0
- package/src/update/stop-decision.mjs +34 -0
- package/src/vision/eligibility.ts +19 -1
- package/src/vision/index.ts +4 -18
- package/gui/dist/assets/index-CowztZdo.js +0 -112
- package/gui/dist/assets/index-jqE_VOKI.css +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
4
|
+
viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
.st0{opacity:0.3;fill:#E2E4E7;}
|
|
7
|
+
.st1{opacity:0.8;fill:#E2E4E7;stroke:#FFFFFF;stroke-width:5;stroke-miterlimit:10;}
|
|
8
|
+
.st2{fill:url(#SVGID_1_);}
|
|
9
|
+
.st3{fill:none;stroke:#E0E4E9;stroke-width:0.25;stroke-miterlimit:10;}
|
|
10
|
+
.st4{fill:none;}
|
|
11
|
+
.st5{fill:#9DA1A5;}
|
|
12
|
+
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:none;}
|
|
13
|
+
.st7{fill-rule:evenodd;clip-rule:evenodd;fill:#DFE2E7;}
|
|
14
|
+
.st8{fill-rule:evenodd;clip-rule:evenodd;fill:#CDD4DA;}
|
|
15
|
+
.st9{fill-rule:evenodd;clip-rule:evenodd;fill:#B3BCC7;}
|
|
16
|
+
.st10{fill-rule:evenodd;clip-rule:evenodd;fill:#9DAAB7;}
|
|
17
|
+
.st11{fill-rule:evenodd;clip-rule:evenodd;fill:#8698A8;}
|
|
18
|
+
.st12{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_2_);}
|
|
19
|
+
.st13{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_3_);}
|
|
20
|
+
.st14{fill:#1F63EC;}
|
|
21
|
+
.st15{fill:#2D2D2D;}
|
|
22
|
+
.st16{fill:none;stroke:#E0E4E9;stroke-width:0.5;stroke-miterlimit:10;}
|
|
23
|
+
.st17{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_4_);}
|
|
24
|
+
.st18{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_5_);}
|
|
25
|
+
.st19{fill:none;stroke:#677380;stroke-width:0.5;stroke-miterlimit:10;}
|
|
26
|
+
.st20{fill:none;stroke:url(#SVGID_6_);stroke-width:2;stroke-miterlimit:10;}
|
|
27
|
+
.st21{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_7_);}
|
|
28
|
+
.st22{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_8_);}
|
|
29
|
+
.st23{fill:#FFFFFF;}
|
|
30
|
+
.st24{fill-rule:evenodd;clip-rule:evenodd;fill:#2D2D2D;}
|
|
31
|
+
.st25{clip-path:url(#SVGID_10_);}
|
|
32
|
+
.st26{clip-path:url(#SVGID_12_);}
|
|
33
|
+
.st27{fill:url(#SVGID_13_);}
|
|
34
|
+
.st28{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_14_);}
|
|
35
|
+
.st29{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_15_);}
|
|
36
|
+
.st30{clip-path:url(#SVGID_17_);}
|
|
37
|
+
.st31{clip-path:url(#SVGID_19_);}
|
|
38
|
+
.st32{fill:url(#SVGID_20_);}
|
|
39
|
+
.st33{fill:none;stroke:url(#SVGID_21_);stroke-width:2;stroke-miterlimit:10;}
|
|
40
|
+
.st34{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_22_);}
|
|
41
|
+
.st35{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_23_);}
|
|
42
|
+
.st36{clip-path:url(#SVGID_25_);}
|
|
43
|
+
.st37{clip-path:url(#SVGID_27_);}
|
|
44
|
+
.st38{fill:url(#SVGID_28_);}
|
|
45
|
+
.st39{clip-path:url(#SVGID_30_);}
|
|
46
|
+
.st40{clip-path:url(#SVGID_32_);}
|
|
47
|
+
.st41{fill:url(#SVGID_33_);}
|
|
48
|
+
.st42{fill-rule:evenodd;clip-rule:evenodd;fill:#126EF6;}
|
|
49
|
+
.st43{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
|
50
|
+
.st44{clip-path:url(#SVGID_35_);}
|
|
51
|
+
.st45{clip-path:url(#SVGID_37_);}
|
|
52
|
+
.st46{fill:url(#SVGID_38_);}
|
|
53
|
+
.st47{fill-rule:evenodd;clip-rule:evenodd;fill:#9DA1A5;}
|
|
54
|
+
.st48{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_39_);}
|
|
55
|
+
.st49{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_40_);}
|
|
56
|
+
.st50{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_41_);}
|
|
57
|
+
.st51{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_42_);}
|
|
58
|
+
.st52{fill:none;stroke:url(#SVGID_43_);stroke-width:2;stroke-miterlimit:10;}
|
|
59
|
+
.st53{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#E0E4E9;stroke-width:0.5;stroke-miterlimit:10;}
|
|
60
|
+
.st54{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_44_);}
|
|
61
|
+
.st55{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_45_);}
|
|
62
|
+
.st56{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_46_);}
|
|
63
|
+
.st57{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_47_);}
|
|
64
|
+
.st58{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_48_);}
|
|
65
|
+
.st59{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_49_);}
|
|
66
|
+
.st60{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_50_);}
|
|
67
|
+
.st61{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_51_);}
|
|
68
|
+
.st62{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_52_);}
|
|
69
|
+
.st63{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_53_);}
|
|
70
|
+
.st64{clip-path:url(#SVGID_55_);}
|
|
71
|
+
.st65{clip-path:url(#SVGID_57_);}
|
|
72
|
+
.st66{fill:url(#SVGID_58_);}
|
|
73
|
+
.st67{clip-path:url(#SVGID_60_);}
|
|
74
|
+
.st68{clip-path:url(#SVGID_62_);}
|
|
75
|
+
.st69{fill:url(#SVGID_63_);}
|
|
76
|
+
.st70{fill:none;stroke:url(#SVGID_64_);stroke-width:2;stroke-miterlimit:10;}
|
|
77
|
+
.st71{clip-path:url(#SVGID_66_);}
|
|
78
|
+
.st72{clip-path:url(#SVGID_68_);}
|
|
79
|
+
.st73{fill:url(#SVGID_69_);}
|
|
80
|
+
.st74{clip-path:url(#SVGID_71_);}
|
|
81
|
+
.st75{clip-path:url(#SVGID_73_);}
|
|
82
|
+
.st76{fill:url(#SVGID_74_);}
|
|
83
|
+
.st77{clip-path:url(#SVGID_76_);}
|
|
84
|
+
.st78{clip-path:url(#SVGID_78_);}
|
|
85
|
+
.st79{fill:url(#SVGID_79_);}
|
|
86
|
+
.st80{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_80_);}
|
|
87
|
+
.st81{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_81_);}
|
|
88
|
+
.st82{clip-path:url(#SVGID_83_);}
|
|
89
|
+
.st83{clip-path:url(#SVGID_85_);}
|
|
90
|
+
.st84{fill:url(#SVGID_86_);}
|
|
91
|
+
.st85{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_87_);}
|
|
92
|
+
.st86{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_88_);}
|
|
93
|
+
.st87{clip-path:url(#SVGID_90_);}
|
|
94
|
+
.st88{clip-path:url(#SVGID_92_);}
|
|
95
|
+
.st89{fill:url(#SVGID_93_);}
|
|
96
|
+
.st90{fill:none;stroke:url(#SVGID_94_);stroke-width:2;stroke-miterlimit:10;}
|
|
97
|
+
.st91{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_95_);}
|
|
98
|
+
.st92{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_96_);}
|
|
99
|
+
.st93{clip-path:url(#SVGID_98_);}
|
|
100
|
+
.st94{clip-path:url(#SVGID_100_);}
|
|
101
|
+
.st95{fill:url(#SVGID_101_);}
|
|
102
|
+
.st96{clip-path:url(#SVGID_103_);}
|
|
103
|
+
.st97{clip-path:url(#SVGID_105_);}
|
|
104
|
+
.st98{fill:url(#SVGID_106_);}
|
|
105
|
+
.st99{clip-path:url(#SVGID_108_);}
|
|
106
|
+
.st100{clip-path:url(#SVGID_110_);}
|
|
107
|
+
.st101{fill:url(#SVGID_111_);}
|
|
108
|
+
.st102{fill:#FFFFFF;stroke:#B3BCC7;stroke-width:0.275;stroke-miterlimit:10;}
|
|
109
|
+
.st103{clip-path:url(#SVGID_113_);}
|
|
110
|
+
.st104{fill:#FDD138;}
|
|
111
|
+
.st105{fill:#FCA62F;}
|
|
112
|
+
.st106{fill:#FB7927;}
|
|
113
|
+
.st107{fill:#F44B22;}
|
|
114
|
+
.st108{fill:#D81915;}
|
|
115
|
+
.st109{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.3354;stroke-miterlimit:10;}
|
|
116
|
+
.st110{fill:none;stroke:#65727F;stroke-width:2;stroke-miterlimit:10;}
|
|
117
|
+
.st111{fill:none;stroke:#65727F;stroke-width:0.75;stroke-miterlimit:10;}
|
|
118
|
+
.st112{fill:url(#SVGID_114_);}
|
|
119
|
+
.st113{fill:#D06C50;}
|
|
120
|
+
.st114{fill:#2D2D2D;stroke:#B3BCC7;stroke-width:0.275;stroke-miterlimit:10;}
|
|
121
|
+
.st115{opacity:0.2;}
|
|
122
|
+
.st116{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;}
|
|
123
|
+
.st117{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0212,1.0212;}
|
|
124
|
+
.st118{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0205,1.0205;}
|
|
125
|
+
.st119{opacity:0.2;fill:none;}
|
|
126
|
+
.st120{fill:none;stroke:#677380;stroke-width:0.3689;stroke-miterlimit:10;}
|
|
127
|
+
.st121{fill:none;stroke:#677380;stroke-width:0.3689;stroke-miterlimit:10;stroke-dasharray:1.0509,1.0509;}
|
|
128
|
+
.st122{opacity:0.3;fill:#1F63EC;}
|
|
129
|
+
.st123{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.3162;stroke-miterlimit:10;}
|
|
130
|
+
.st124{fill:#FFFFFF;stroke:#B3BCC7;stroke-width:0.3162;stroke-miterlimit:10;}
|
|
131
|
+
.st125{clip-path:url(#SVGID_118_);}
|
|
132
|
+
.st126{fill:url(#SVGID_119_);}
|
|
133
|
+
.st127{fill:none;stroke:#DFE2E7;stroke-width:0.75;stroke-miterlimit:10;}
|
|
134
|
+
.st128{fill:#9DA1A5;stroke:#FFFFFF;stroke-miterlimit:10;}
|
|
135
|
+
.st129{fill:url(#SVGID_120_);}
|
|
136
|
+
.st130{fill:none;stroke:#677380;stroke-width:0.75;stroke-miterlimit:10;}
|
|
137
|
+
.st131{opacity:0.4;}
|
|
138
|
+
.st132{clip-path:url(#SVGID_122_);}
|
|
139
|
+
.st133{clip-path:url(#SVGID_124_);}
|
|
140
|
+
.st134{fill:url(#SVGID_125_);}
|
|
141
|
+
.st135{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;}
|
|
142
|
+
.st136{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:0.9951,0.9951;}
|
|
143
|
+
.st137{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:1.004,1.004;}
|
|
144
|
+
.st138{fill:none;stroke:url(#SVGID_126_);stroke-width:1.5;stroke-miterlimit:10;}
|
|
145
|
+
.st139{fill:url(#SVGID_127_);}
|
|
146
|
+
.st140{fill:none;stroke:#DDE0E4;stroke-width:0.35;stroke-miterlimit:10;}
|
|
147
|
+
.st141{fill:#2D2D2D;stroke:#A9B3BE;stroke-width:0.275;stroke-miterlimit:10;}
|
|
148
|
+
.st142{fill-rule:evenodd;clip-rule:evenodd;fill:#126EF4;}
|
|
149
|
+
.st143{fill:#FFFFFF;stroke:#B1BAC4;stroke-width:0.275;stroke-miterlimit:10;}
|
|
150
|
+
.st144{fill:#CE6C50;}
|
|
151
|
+
.st145{fill:#5B5B5B;}
|
|
152
|
+
.st146{fill:#8392A3;}
|
|
153
|
+
.st147{fill:none;stroke:url(#SVGID_128_);stroke-width:1.5;stroke-miterlimit:10;}
|
|
154
|
+
.st148{fill:url(#SVGID_129_);}
|
|
155
|
+
.st149{fill:none;stroke:#B5BDC4;stroke-width:0.7;stroke-miterlimit:10;}
|
|
156
|
+
.st150{opacity:0.6;fill:none;stroke:#78838E;stroke-width:0.35;stroke-miterlimit:10;}
|
|
157
|
+
.st151{opacity:0.2;fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:1,1;}
|
|
158
|
+
.st152{fill:none;stroke:#DDE0E4;stroke-width:0.75;stroke-miterlimit:10;}
|
|
159
|
+
.st153{fill:none;stroke:#8392A3;stroke-width:0.5;stroke-miterlimit:10;}
|
|
160
|
+
.st154{opacity:0.2;fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0182,1.0182;}
|
|
161
|
+
.st155{fill:none;stroke:#DDE0E4;stroke-width:0.765;stroke-miterlimit:10;}
|
|
162
|
+
.st156{fill:url(#SVGID_130_);}
|
|
163
|
+
.st157{fill:url(#SVGID_131_);}
|
|
164
|
+
.st158{fill:#B1BAC4;}
|
|
165
|
+
.st159{fill:#CBD1D8;}
|
|
166
|
+
.st160{fill:#0B1B2B;}
|
|
167
|
+
.st161{fill:#91D119;}
|
|
168
|
+
.st162{opacity:0.7;}
|
|
169
|
+
.st163{fill:#FFFFFF;stroke:#000000;stroke-width:0.4418;stroke-miterlimit:10;}
|
|
170
|
+
.st164{fill:none;stroke:#939CAA;stroke-width:0.2209;stroke-miterlimit:10;}
|
|
171
|
+
.st165{fill:none;stroke:#FFFFFF;stroke-width:3.0924;stroke-miterlimit:10;}
|
|
172
|
+
.st166{fill:url(#SVGID_132_);}
|
|
173
|
+
.st167{fill:none;stroke:url(#SVGID_133_);stroke-width:1.714;stroke-miterlimit:10;}
|
|
174
|
+
.st168{fill:url(#SVGID_134_);}
|
|
175
|
+
.st169{fill:url(#SVGID_135_);}
|
|
176
|
+
.st170{fill:url(#SVGID_136_);}
|
|
177
|
+
.st171{fill:url(#SVGID_137_);}
|
|
178
|
+
.st172{fill:url(#SVGID_138_);}
|
|
179
|
+
.st173{fill:url(#SVGID_139_);}
|
|
180
|
+
.st174{fill:url(#SVGID_140_);}
|
|
181
|
+
.st175{fill:url(#SVGID_141_);}
|
|
182
|
+
.st176{fill:url(#SVGID_142_);}
|
|
183
|
+
.st177{fill:url(#SVGID_143_);}
|
|
184
|
+
.st178{fill:url(#SVGID_144_);}
|
|
185
|
+
.st179{fill:none;stroke:#1F63EC;stroke-width:4;stroke-miterlimit:10;}
|
|
186
|
+
.st180{fill:none;stroke:#0B1B2B;stroke-width:4;stroke-miterlimit:10;}
|
|
187
|
+
.st181{fill:none;stroke:#677380;stroke-width:0.3989;stroke-miterlimit:10;}
|
|
188
|
+
.st182{fill:none;stroke:#677380;stroke-width:0.3989;stroke-miterlimit:10;stroke-dasharray:1.14,1.14;}
|
|
189
|
+
.st183{fill:#257AF1;}
|
|
190
|
+
.st184{opacity:0.3;fill:#FFFFFF;}
|
|
191
|
+
.st185{fill:none;stroke:#98A5B2;stroke-width:4;stroke-miterlimit:10;}
|
|
192
|
+
.st186{fill:none;stroke:#65727F;stroke-width:0.3989;stroke-miterlimit:10;}
|
|
193
|
+
.st187{fill:none;stroke:#65727F;stroke-width:0.3989;stroke-miterlimit:10;stroke-dasharray:1.14,1.14;}
|
|
194
|
+
.st188{fill:none;stroke:#DDDFE4;stroke-width:0.75;stroke-miterlimit:10;}
|
|
195
|
+
.st189{fill:#9A9EA2;}
|
|
196
|
+
.st190{fill-rule:evenodd;clip-rule:evenodd;fill:#3267AC;}
|
|
197
|
+
.st191{fill:#FFFFFF;stroke:#AFB8C3;stroke-width:0.275;stroke-miterlimit:10;}
|
|
198
|
+
.st192{fill:#C5694E;}
|
|
199
|
+
.st193{fill:#8192A2;}
|
|
200
|
+
.st194{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.6317;stroke-miterlimit:10;}
|
|
201
|
+
</style>
|
|
202
|
+
<g id="图层_2">
|
|
203
|
+
</g>
|
|
204
|
+
<g id="图层_1">
|
|
205
|
+
<path class="st194" d="M24.51,28.51H5.49c-2.21,0-4-1.79-4-4V5.49c0-2.21,1.79-4,4-4h19.03c2.21,0,4,1.79,4,4v19.03
|
|
206
|
+
C28.51,26.72,26.72,28.51,24.51,28.51z"/>
|
|
207
|
+
<g>
|
|
208
|
+
<g>
|
|
209
|
+
<g>
|
|
210
|
+
<g>
|
|
211
|
+
<path class="st23" d="M15.47,7.1l-1.3,1.85c-0.2,0.29-0.54,0.47-0.9,0.47h-7.1V7.09C6.16,7.1,15.47,7.1,15.47,7.1z"/>
|
|
212
|
+
<polygon class="st23" points="24.3,7.1 13.14,22.91 5.7,22.91 16.86,7.1 "/>
|
|
213
|
+
<path class="st23" d="M14.53,22.91l1.31-1.86c0.2-0.29,0.54-0.47,0.9-0.47h7.09v2.33H14.53z"/>
|
|
214
|
+
</g>
|
|
215
|
+
</g>
|
|
216
|
+
</g>
|
|
217
|
+
</g>
|
|
218
|
+
</g>
|
|
219
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg" fill="none"><path stroke="null" fill="#000" d="M77.776.421c8.25-.317 24.947.775 38.304 12.768 10.957 9.839 14.733 28.078 12.18 42.221-2.341 12.965-7.858 23.572-5.696 33.394 2.16 9.821 7.658 14.663 12.334 16.696 4.519 1.965 8.886 1.375 8.055 5.108-.832 3.732-6.482 5.107-10.608 5.107-2.262 0-9.103-.59-12.139-2.554-3.587-2.322-4.386-4.402-5.752-6.074-.231-.284-.64-.087-.586.276.622 4.113 2.338 11.094 5.12 15.423 2.252 3.503 3.183 6.058 8.341 10.38 5.16 4.32 7.57 8.249 2.553 11.031-4.456 2.471-14.142-2.585-19.839-8.839-5.127-5.629-8.697-12.572-10.108-17.09-.755-2.415-1.511-6.57-2.266-9.969-.1-.446-.711-.374-.725.084-.25 8.649-1.61 16.909-3.598 25.764-1.43 6.375-4.91 14.143-8.053 18.857-3.833 5.749-9.522 7.543-13.75 5.971-3.382-1.257-.983-5.531 0-9.232.982-3.7 2.947-11.439 4.27-19.918 1.197-7.674 1.514-15.271.981-22.47-.033-.439-.708-.506-.844-.087-1.102 3.376-3.18 8.972-4.696 12.376-3.162 7.099-5.501 10.214-11.983 17.677-5.83 6.714-22.597 16.207-24.75 6.876-.59-2.553 2.498-3.671 5.345-5.893 4.28-3.339 7.857-9.264 11.248-16.5 3.045-6.497 4.592-12.782 4.83-16.794.022-.387-.464-.533-.682-.213-1.41 2.067-3.485 4.865-5.771 7.185-3.819 3.877-8.054 7.867-12.966 9.822-7.897 3.143-15.95.982-15.361-4.714.492-4.758 5.804-3.773 12.416-10.987 6.482-7.072 8.643-12.573 9.035-18.662.314-4.872-4.451-16.434-6.874-21.607-3.863-8.25-6.718-31.665 4.91-46.75C55.188.226 72.67.617 77.777.42zM55.101 33.397c-5.408 0-8.112 4.151-8.112 9.272 0 5.12 3.004 9.271 8.112 9.271 5.108 0 8.113-4.15 8.113-9.271 0-5.12-2.705-9.272-8.113-9.272zm44.04 0c-5.408 0-8.112 4.151-8.113 9.272 0 5.12 3.005 9.271 8.113 9.271s8.113-4.15 8.113-9.271c0-5.12-2.705-9.272-8.113-9.272z" clip-rule="evenodd" fill-rule="evenodd"/></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitkyc08/opencodex",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.39.0-preview.20260901",
|
|
4
4
|
"description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./bin/package-main.mjs",
|
|
@@ -262,6 +262,7 @@ async function fetchCursorUsableModelsHttp2Once(opts: CursorUsableModelsOptions)
|
|
|
262
262
|
req.on("error", () => close({ ok: false, error: "transport", detail: "HTTP/2 request failed" }));
|
|
263
263
|
req.on("end", () => {
|
|
264
264
|
if (bodyRejected) return;
|
|
265
|
+
if (status === 0) return close({ ok: false, error: "transport", detail: "HTTP/2 response ended before headers" });
|
|
265
266
|
if (status === 401 || status === 403) {
|
|
266
267
|
return close({ ok: false, error: "auth", detail: `HTTP ${status}` });
|
|
267
268
|
}
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
cursorToolsForActivePrompt,
|
|
57
57
|
buildCursorToolGuidanceSystemNote,
|
|
58
58
|
buildCursorToolDefinitions,
|
|
59
|
+
cursorToolWireName,
|
|
59
60
|
cursorRequestHasShellAlias,
|
|
60
61
|
CURSOR_SHELL_ALIAS_SYSTEM_NOTE,
|
|
61
62
|
OCX_RESPONSES_TOOL_PROVIDER,
|
|
@@ -1091,7 +1092,9 @@ function toolCallStep(
|
|
|
1091
1092
|
): Uint8Array {
|
|
1092
1093
|
const args: Record<string, Uint8Array> = {};
|
|
1093
1094
|
for (const [key, value] of Object.entries(part.arguments ?? {})) args[key] = argBytes(value);
|
|
1094
|
-
|
|
1095
|
+
// Replay the same provider-isolated identity advertised in this request. Returned calls are
|
|
1096
|
+
// restored to the client name, so transcript parts carry the client name again on the next turn.
|
|
1097
|
+
const toolName = cursorToolWireName(part);
|
|
1095
1098
|
const decodedResult = result ? decodeResultParts(result) : undefined;
|
|
1096
1099
|
const serialize = (maxImages: number): Uint8Array => toBinary(ConversationStepSchema, create(ConversationStepSchema, {
|
|
1097
1100
|
message: {
|
|
@@ -12,6 +12,7 @@ export const CODEX_SHELL_COMMAND_TOOL = "shell_command";
|
|
|
12
12
|
export const CODEX_UNIFIED_EXEC_TOOL = "exec";
|
|
13
13
|
export const CODEX_WAIT_TOOL = "wait";
|
|
14
14
|
export const CODEX_APPLY_PATCH_TOOL = "apply_patch";
|
|
15
|
+
export const CODEX_TOOL_SEARCH_TOOL = "tool_search";
|
|
15
16
|
export const CURSOR_EDIT_FILE_TOOL = "edit_file";
|
|
16
17
|
export const CURSOR_MULTI_EDIT_TOOL = "multi_edit";
|
|
17
18
|
export const CURSOR_STRUCTURED_EDIT_TOOLS = [CURSOR_EDIT_FILE_TOOL, CURSOR_MULTI_EDIT_TOOL] as const;
|
|
@@ -169,8 +170,10 @@ function cursorToolChoiceMatches(
|
|
|
169
170
|
}
|
|
170
171
|
return tool.name === choiceName || cursorToolWireName(tool) === choiceName;
|
|
171
172
|
}
|
|
172
|
-
if (tool.name === choiceName
|
|
173
|
-
|
|
173
|
+
if (tool.name === choiceName) return true;
|
|
174
|
+
if (cursorToolChoiceAliases(tool).includes(choiceName)) return true;
|
|
175
|
+
return cursorToolWireName(tool) === choiceName
|
|
176
|
+
&& !catalog.some(candidate => candidate.name === choiceName);
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
export function isBareCodexShellBridgeTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
@@ -320,10 +323,39 @@ export function cursorRequestAdvertisesStructuredEdits(
|
|
|
320
323
|
return cursorStructuredEditTools(tools, toolChoice).length > 0;
|
|
321
324
|
}
|
|
322
325
|
|
|
326
|
+
const CURSOR_CLIENT_TOOL_WIRE_PREFIX = "ocx_client_";
|
|
327
|
+
const CURSOR_PROXY_OWNED_BARE_TOOL_NAMES = new Set([
|
|
328
|
+
CODEX_UNIFIED_EXEC_TOOL,
|
|
329
|
+
CODEX_WAIT_TOOL,
|
|
330
|
+
CODEX_EXEC_COMMAND_TOOL,
|
|
331
|
+
CODEX_SHELL_COMMAND_TOOL,
|
|
332
|
+
CODEX_APPLY_PATCH_TOOL,
|
|
333
|
+
CURSOR_EDIT_FILE_TOOL,
|
|
334
|
+
CURSOR_MULTI_EDIT_TOOL,
|
|
335
|
+
CODEX_TOOL_SEARCH_TOOL,
|
|
336
|
+
]);
|
|
337
|
+
|
|
338
|
+
/** Avoid collisions with Cursor's private bare-tool namespace. */
|
|
339
|
+
function isCursorBareClientToolWireAliased(
|
|
340
|
+
tool: Pick<OcxTool, "namespace" | "name">,
|
|
341
|
+
): boolean {
|
|
342
|
+
return !tool.namespace
|
|
343
|
+
&& !CURSOR_PROXY_OWNED_BARE_TOOL_NAMES.has(tool.name);
|
|
344
|
+
}
|
|
345
|
+
|
|
323
346
|
export function cursorToolWireName(tool: Pick<OcxTool, "namespace" | "name">): string {
|
|
347
|
+
if (isCursorBareClientToolWireAliased(tool)) {
|
|
348
|
+
return `${CURSOR_CLIENT_TOOL_WIRE_PREFIX}${tool.name}`;
|
|
349
|
+
}
|
|
324
350
|
return namespacedToolName(tool.namespace, tool.name);
|
|
325
351
|
}
|
|
326
352
|
|
|
353
|
+
function clientSemanticToolNameFromCursorWire(name: string): string {
|
|
354
|
+
return name.startsWith(CURSOR_CLIENT_TOOL_WIRE_PREFIX)
|
|
355
|
+
? name.slice(CURSOR_CLIENT_TOOL_WIRE_PREFIX.length)
|
|
356
|
+
: name;
|
|
357
|
+
}
|
|
358
|
+
|
|
327
359
|
/**
|
|
328
360
|
* Cursor's harness shows MCP tools to the model as `mcp_<providerIdentifier>_<toolName>`; models
|
|
329
361
|
* sometimes call that display name verbatim instead of the advertised short name (live 20:41/21:00
|
|
@@ -591,7 +623,7 @@ function quotedNames(names: readonly string[]): string {
|
|
|
591
623
|
}
|
|
592
624
|
|
|
593
625
|
function advertisedCoversNeighbor(wireNames: readonly string[], neighbor: (typeof NEIGHBOR_AGENT_TOOL_NAMES)[number]): boolean {
|
|
594
|
-
const advertised = new Set(wireNames.map(name => name.toLowerCase()));
|
|
626
|
+
const advertised = new Set(wireNames.map(name => clientSemanticToolNameFromCursorWire(name).toLowerCase()));
|
|
595
627
|
if (advertised.has(neighbor.toLowerCase())) return true;
|
|
596
628
|
return NEIGHBOR_AGENT_TOOL_ALIASES[neighbor].some(alias => advertised.has(alias.toLowerCase()));
|
|
597
629
|
}
|
|
@@ -602,7 +634,7 @@ function unavailableNeighborAgentToolNames(wireNames: readonly string[]): string
|
|
|
602
634
|
|
|
603
635
|
function discoveryToolLabel(wireNames: readonly string[]): string | undefined {
|
|
604
636
|
const labels: string[] = [];
|
|
605
|
-
if (wireNames.includes(
|
|
637
|
+
if (wireNames.includes(CODEX_TOOL_SEARCH_TOOL)) labels.push(`\`${CODEX_TOOL_SEARCH_TOOL}\``);
|
|
606
638
|
if (wireNames.some(name => name.startsWith("mcp__"))) labels.push("MCP");
|
|
607
639
|
if (wireNames.some(name => /resource/i.test(name))) labels.push("resource discovery");
|
|
608
640
|
return labels.length > 0 ? labels.join(", ") : undefined;
|
|
@@ -236,6 +236,30 @@ function stripCanonicalOnlyToolFields(body: unknown, includeCapabilityGated: boo
|
|
|
236
236
|
return input ? { ...rewrittenBody, input } : rewrittenBody;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Codex keeps this ChatGPT-internal item metadata when its configured provider name is `openai`.
|
|
241
|
+
* Loopback OpenCodex injection intentionally retains that provider identity for history continuity,
|
|
242
|
+
* even when the proxy ultimately routes the request to a public Responses destination. Those
|
|
243
|
+
* destinations reject the private field as an unknown `input[*]` parameter, so remove it at the
|
|
244
|
+
* noncanonical boundary without mutating the caller-owned raw body.
|
|
245
|
+
*/
|
|
246
|
+
function stripInternalChatMessageMetadataPassthrough(body: unknown): unknown {
|
|
247
|
+
if (!isPlainObject(body) || !Array.isArray(body.input)) return body;
|
|
248
|
+
|
|
249
|
+
let changed = false;
|
|
250
|
+
const input = body.input.map(item => {
|
|
251
|
+
if (!isPlainObject(item) || !Object.hasOwn(item, "internal_chat_message_metadata_passthrough")) {
|
|
252
|
+
return item;
|
|
253
|
+
}
|
|
254
|
+
changed = true;
|
|
255
|
+
const next = { ...item };
|
|
256
|
+
delete next.internal_chat_message_metadata_passthrough;
|
|
257
|
+
return next;
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
return changed ? { ...body, input } : body;
|
|
261
|
+
}
|
|
262
|
+
|
|
239
263
|
/**
|
|
240
264
|
* When `store` is false, the upstream API does not persist response items. Any item ID
|
|
241
265
|
* forwarded in `input` is then interpreted as a reference to a stored item that does not
|
|
@@ -901,13 +925,23 @@ function annotateEmptyResponsesToolOutputs(body: unknown, enabled: boolean): unk
|
|
|
901
925
|
* Runs on every forward request; with intact pairs it returns the original reference.
|
|
902
926
|
*/
|
|
903
927
|
/**
|
|
904
|
-
*
|
|
928
|
+
* Repair a replayed `web_search_call` action that is missing either key.
|
|
905
929
|
*
|
|
906
930
|
* `webSearchAction()` in the bridge now emits both keys, but that only helps items
|
|
907
931
|
* created after the fix. A conversation that already recorded
|
|
908
|
-
* `{type:"search", query:"..."}` replays that stored
|
|
909
|
-
* DeepSeek's native Responses parser requires `queries`
|
|
910
|
-
*
|
|
932
|
+
* `{type:"search", query:"..."}` or `{type:"search", queries:[...]}` replays that stored
|
|
933
|
+
* item on every subsequent turn. DeepSeek's native Responses parser requires `queries`
|
|
934
|
+
* (#930) and Console Go's validator requires `query` (#3071), so upgrading alone leaves
|
|
935
|
+
* those threads permanently 400ing in one direction or the other. The repair runs both
|
|
936
|
+
* ways.
|
|
937
|
+
*
|
|
938
|
+
* Input items carry a loose schema, so a stored `queries` is not necessarily an array of
|
|
939
|
+
* strings. A partly- or wholly-malformed array is left alone rather than used as a source
|
|
940
|
+
* for the singular field: writing `query: 123` would satisfy the presence check and still
|
|
941
|
+
* fail the validator this repair exists to satisfy, and deriving `query` from
|
|
942
|
+
* `["a", 42]` would satisfy Console Go while leaving DeepSeek to reject the same replay.
|
|
943
|
+
* An empty `queries: []` canonicalizes to the shape the bridge emits for an empty search,
|
|
944
|
+
* keeping an existing `query` when the item has one.
|
|
911
945
|
*
|
|
912
946
|
* Runs on every Responses request, on both `input` items and the `action` nested inside
|
|
913
947
|
* them. Returns the original reference when nothing needs repair, so the common path
|
|
@@ -920,9 +954,35 @@ function backfillWebSearchQueries(body: unknown): unknown {
|
|
|
920
954
|
if (!isPlainObject(item) || item.type !== "web_search_call") return item;
|
|
921
955
|
const action = item.action;
|
|
922
956
|
if (!isPlainObject(action) || action.type !== "search") return item;
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
957
|
+
// Repair whichever side is missing so both strict parsers pass:
|
|
958
|
+
// DeepSeek native Responses requires `queries`; Console Go requires `query`.
|
|
959
|
+
const rep: Record<string, unknown> = { ...action };
|
|
960
|
+
let itemChanged = false;
|
|
961
|
+
const hasQuery = typeof action.query === "string";
|
|
962
|
+
const queries = Array.isArray(action.queries) ? action.queries : undefined;
|
|
963
|
+
if (queries !== undefined && queries.length === 0) {
|
|
964
|
+
// An empty array satisfies neither validator. Canonicalize to the empty-search
|
|
965
|
+
// shape the bridge emits, keeping an existing query rather than discarding it.
|
|
966
|
+
const query = hasQuery ? action.query as string : "";
|
|
967
|
+
rep.query = query;
|
|
968
|
+
rep.queries = [query];
|
|
969
|
+
itemChanged = true;
|
|
970
|
+
} else if (!hasQuery && queries !== undefined) {
|
|
971
|
+
// A plural array is only a usable source for the singular field when EVERY member
|
|
972
|
+
// is a string: deriving `query` from a partly-malformed array would satisfy Console
|
|
973
|
+
// Go while leaving DeepSeek to reject the same replay. Wholly malformed arrays are
|
|
974
|
+
// left untouched — coercing or dropping members would invent semantics the stored
|
|
975
|
+
// item never had.
|
|
976
|
+
if (queries.every(entry => typeof entry === "string")) {
|
|
977
|
+
rep.query = queries[0]; // multi-query item recorded before the fix
|
|
978
|
+
itemChanged = true;
|
|
979
|
+
}
|
|
980
|
+
} else if (hasQuery && queries === undefined) {
|
|
981
|
+
rep.queries = [action.query]; // single-query item recorded before the fix
|
|
982
|
+
itemChanged = true;
|
|
983
|
+
}
|
|
984
|
+
if (itemChanged) changed = true;
|
|
985
|
+
return itemChanged ? { ...item, action: rep } : item;
|
|
926
986
|
});
|
|
927
987
|
return changed ? { ...body, input } : body;
|
|
928
988
|
}
|
|
@@ -2097,11 +2157,13 @@ export function createResponsesPassthroughAdapter(provider: OcxProviderConfig):
|
|
|
2097
2157
|
outBody = repairOversizedReplayCallIds(outBody);
|
|
2098
2158
|
}
|
|
2099
2159
|
outBody = stripUnsupportedReasoningSummaryDelivery(outBody, parsed.modelId);
|
|
2100
|
-
// Repair stored history from before the bridge emitted both keys
|
|
2101
|
-
// that already recorded a
|
|
2102
|
-
// a strict parser rejects the whole request over
|
|
2160
|
+
// Repair stored history from before the bridge emitted both keys, in either
|
|
2161
|
+
// direction: a conversation that already recorded a web_search_call replays it
|
|
2162
|
+
// every turn, and a strict parser rejects the whole request over the missing key —
|
|
2163
|
+
// `queries` for DeepSeek (#930), `query` for Console Go (#3071).
|
|
2103
2164
|
outBody = backfillWebSearchQueries(outBody);
|
|
2104
2165
|
if (!isCanonicalOpenAiForwardProvider(provider)) {
|
|
2166
|
+
outBody = stripInternalChatMessageMetadataPassthrough(outBody);
|
|
2105
2167
|
outBody = promoteClientLoadedTools(outBody);
|
|
2106
2168
|
}
|
|
2107
2169
|
if (!isCanonicalOpenAiForwardProvider(provider)) {
|
package/src/bridge.ts
CHANGED
|
@@ -146,27 +146,27 @@ export { adapterFailureFromMessage } from "./lib/errors";
|
|
|
146
146
|
/**
|
|
147
147
|
* Build the native `WebSearchAction::Search` payload from the queries that ran.
|
|
148
148
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
149
|
+
* Every action carries BOTH keys: `{ query, queries }`, where `query` is the first
|
|
150
|
+
* member. Empty → `{ query: "", queries: [""] }`.
|
|
151
151
|
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
152
|
+
* Carrying both is load-bearing in both directions. DeepSeek's native Responses parser
|
|
153
|
+
* makes `queries` a required field, and Console Go's upstream validator makes `query` a
|
|
154
|
+
* required field — so a replayed `web_search_call` carried in the history of every
|
|
155
|
+
* subsequent turn fails deserialization with `missing field 'queries'` (#930) or 400s
|
|
156
|
+
* with `missing required field 'query'` unless both keys are present. Carrying both keys
|
|
157
|
+
* in every case satisfies both strict parsers; the trade-off is that a multi-query batch
|
|
158
|
+
* loses the "<first> ..." ellipsis in codex-rs and shows the first query as the label.
|
|
159
|
+
*
|
|
160
|
+
* That trade is deliberate: a cosmetic label against a conversation that 400s on every
|
|
161
|
+
* subsequent turn. Do not restore the old batch-omits-`query` shape to win the ellipsis
|
|
162
|
+
* back — it reopens #3071.
|
|
160
163
|
*
|
|
161
164
|
* This fixes items created from here on. History recorded before it is repaired at the
|
|
162
165
|
* replay boundary by `backfillWebSearchQueries()` in the Responses adapter.
|
|
163
166
|
*/
|
|
164
167
|
function webSearchAction(queries: string[]): Record<string, unknown> {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return { type: "search", query, queries: [query] };
|
|
168
|
-
}
|
|
169
|
-
return { type: "search", queries };
|
|
168
|
+
const first = queries[0] ?? "";
|
|
169
|
+
return { type: "search", query: first, queries: queries.length > 0 ? queries : [first] };
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
interface OutputItem {
|
package/src/cli/capabilities.ts
CHANGED
|
@@ -418,6 +418,20 @@ export const CAPABILITIES: readonly Capability[] = [
|
|
|
418
418
|
"The GUI reads this state directly; without a verb an agent could not tell whether the Codex app-server was reachable at all.",
|
|
419
419
|
],
|
|
420
420
|
},
|
|
421
|
+
{
|
|
422
|
+
command: ["system", "codex-cli-update", "check"],
|
|
423
|
+
summary: "Inspect a configured Codex CLI candidate and its ownership provenance.",
|
|
424
|
+
routes: [],
|
|
425
|
+
flags: [{ name: "--json", value: "boolean", summary: "Emit the redacted provenance report as JSON." }],
|
|
426
|
+
mutates: false,
|
|
427
|
+
json: "envelope",
|
|
428
|
+
details: [
|
|
429
|
+
"Proof-bound published-launcher context authenticates the configured candidate snapshot, not successful Codex execution; this check does not attest or admit a selected runtime.",
|
|
430
|
+
"On Windows this first slice performs no candidate or configuration filesystem I/O: only a proof-captured absolute environment candidate can receive lexical app-bundle or version-manager labels; every other Windows candidate fails closed.",
|
|
431
|
+
"Makes no package-registry request.",
|
|
432
|
+
"Does not execute Codex or npm, install or repair software, control a process, or write configuration or cache state.",
|
|
433
|
+
],
|
|
434
|
+
},
|
|
421
435
|
{
|
|
422
436
|
command: ["system", "codex-restart"],
|
|
423
437
|
summary: "Restart the Codex app-server.",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
inspectCodexCliInstall,
|
|
3
|
+
type CodexCliInstallProvenanceDeps,
|
|
4
|
+
type CodexCliInstallReport,
|
|
5
|
+
} from "../codex/cli-install-provenance";
|
|
6
|
+
import { CliUsageError, isJsonOption, printData, runCliAction } from "./runtime-api";
|
|
7
|
+
import { trustedNodeLauncherContext } from "./launcher-context";
|
|
8
|
+
|
|
9
|
+
export const CODEX_CLI_UPDATE_USAGE = `Usage:
|
|
10
|
+
ocx system codex-cli-update check [--json]`;
|
|
11
|
+
|
|
12
|
+
export type ParsedCodexCliUpdateArgs = Readonly<{
|
|
13
|
+
json: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
export interface CodexCliUpdateCommandDeps {
|
|
17
|
+
readonly inspectInstall?: (deps: CodexCliInstallProvenanceDeps) => Promise<CodexCliInstallReport>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function installSummary(report: CodexCliInstallReport): string[] {
|
|
21
|
+
return [
|
|
22
|
+
`candidate: ${report.candidateAvailable ? "yes" : "no"}`,
|
|
23
|
+
`candidate-source: ${report.candidateSource ?? "unavailable"}`,
|
|
24
|
+
`selection-attested: ${report.selectionAttested ? "yes" : "no"}`,
|
|
25
|
+
`provenance: ${report.provenance}`,
|
|
26
|
+
`managed: ${report.managed ? "yes" : "no"}`,
|
|
27
|
+
`reason: ${report.reason}`,
|
|
28
|
+
`candidate-version: ${report.candidateVersion ?? "unavailable"}`,
|
|
29
|
+
`package-version: ${report.packageVersion ?? "unavailable"}`,
|
|
30
|
+
`version-evidence: ${report.versionEvidence.kind}`,
|
|
31
|
+
`location: ${report.location ?? "unavailable"}`,
|
|
32
|
+
`shim: ${report.shim.status}${report.shim.backingKind ? `/${report.shim.backingKind}` : ""}`,
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function parseCodexCliUpdateArgs(argv: readonly string[]): ParsedCodexCliUpdateArgs {
|
|
37
|
+
// `--json` is accepted in any argv position CLI-wide, so remove it before positional
|
|
38
|
+
// validation. Requiring `check` at index 0 first would reject `--json check`, which
|
|
39
|
+
// automation that puts output flags ahead of the subcommand legitimately produces.
|
|
40
|
+
let json = false;
|
|
41
|
+
const positional: string[] = [];
|
|
42
|
+
for (const token of argv) {
|
|
43
|
+
if (isJsonOption(token)) {
|
|
44
|
+
if (json) throw new CliUsageError("--json may be specified only once", CODEX_CLI_UPDATE_USAGE);
|
|
45
|
+
json = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
positional.push(token);
|
|
49
|
+
}
|
|
50
|
+
if (positional[0] !== "check") {
|
|
51
|
+
throw new CliUsageError("codex-cli-update action must be check", CODEX_CLI_UPDATE_USAGE);
|
|
52
|
+
}
|
|
53
|
+
if (positional.length > 1) {
|
|
54
|
+
throw new CliUsageError("unsupported codex-cli-update argument", CODEX_CLI_UPDATE_USAGE);
|
|
55
|
+
}
|
|
56
|
+
return Object.freeze({ json });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function handleCodexCliUpdateCommand(
|
|
60
|
+
argv: readonly string[],
|
|
61
|
+
deps: CodexCliUpdateCommandDeps = {},
|
|
62
|
+
): Promise<number> {
|
|
63
|
+
let parsed: ParsedCodexCliUpdateArgs;
|
|
64
|
+
try {
|
|
65
|
+
parsed = parseCodexCliUpdateArgs(argv);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error instanceof CliUsageError) {
|
|
68
|
+
console.error(`Error: ${error.message}`);
|
|
69
|
+
console.error(error.usage ?? CODEX_CLI_UPDATE_USAGE);
|
|
70
|
+
return 2;
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
return runCliAction(async () => {
|
|
75
|
+
const trustedInspectionEnv = trustedNodeLauncherContext()?.codexCliInspectionEnv;
|
|
76
|
+
const inspectionDeps: CodexCliInstallProvenanceDeps = trustedInspectionEnv
|
|
77
|
+
&& trustedInspectionEnv.managerRoots !== null ? {
|
|
78
|
+
env: {
|
|
79
|
+
...trustedInspectionEnv.managerRoots,
|
|
80
|
+
CODEX_CLI_PATH: trustedInspectionEnv.codexCliPath ?? undefined,
|
|
81
|
+
PATH: trustedInspectionEnv.path ?? undefined,
|
|
82
|
+
PATHEXT: trustedInspectionEnv.pathExt ?? undefined,
|
|
83
|
+
},
|
|
84
|
+
configDir: trustedInspectionEnv.configDir,
|
|
85
|
+
// This is a fresh one-shot CLI process. Its proof-bound launcher snapshot
|
|
86
|
+
// supplies configured candidate evidence, not selected-runtime admission.
|
|
87
|
+
} : {
|
|
88
|
+
// Direct Bun/source launches have no pre-dotenv proof. Do not inspect
|
|
89
|
+
// ambient or persisted candidate state at all.
|
|
90
|
+
env: { PATH: "" },
|
|
91
|
+
configDir: ".",
|
|
92
|
+
};
|
|
93
|
+
const report = await (deps.inspectInstall ?? inspectCodexCliInstall)(inspectionDeps);
|
|
94
|
+
printData(report, parsed.json, installSummary(report));
|
|
95
|
+
});
|
|
96
|
+
}
|
|
@@ -19,6 +19,9 @@ export function skipsCodexShimAutoRestore(command: string | undefined, args: str
|
|
|
19
19
|
if (command === "uninstall" || command === "remove") return true;
|
|
20
20
|
// `lab` is read-only inspection; it must not trigger shim side effects.
|
|
21
21
|
if (command === "lab") return true;
|
|
22
|
+
// The entire updater-inspection namespace is zero-effect, including malformed
|
|
23
|
+
// or future actions. A later `apply` implementation must own its preflight.
|
|
24
|
+
if (command === "system" && args[1] === "codex-cli-update") return true;
|
|
22
25
|
return command === "codex-shim" && ["install", "uninstall", "remove"].includes(args[1] ?? "");
|
|
23
26
|
}
|
|
24
27
|
|