@platless/axom-cli 0.5.9 → 0.6.36
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 +18 -5
- package/dist/axom-patch/cli/README.md +100 -12
- package/dist/axom-patch/cli/account-limits/generate.py +15 -12
- package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +20 -3
- package/dist/axom-patch/cli/claude-account-limits.json +9 -9
- package/dist/axom-patch/cli/codex-account-limits.json +11 -11
- package/dist/axom-patch/cli/codex-terminal-output.json +16 -0
- package/dist/axom-patch/cli/commandcode-account-limits.json +9 -9
- package/dist/axom-patch/cli/kimi-quota.mjs +12 -0
- package/dist/axom-patch/cli/kimi-subagents.mjs +173 -0
- package/dist/axom-patch/cli/nightly-task.md +55 -13
- package/dist/axom-patch/cli/probes/codex-terminal-output.mjs +33 -0
- package/dist/axom-patch/cli/probes/kimi-subagent-subwork.mjs +82 -0
- package/dist/axom-patch/cli/qoder/dist/axom-acp-compat.mjs +1591 -0
- package/dist/axom-patch/cli/qoder/releases/1.1.75.json +360 -0
- package/dist/axom-patch/cli/qoder-background-terminal.md +13 -6
- package/dist/axom-patch/cli/qoder-foreground-output.md +14 -8
- package/dist/axom-patch/cli/qoder-native-acp.json +227 -0
- package/dist/axom-patch/cli/qoder-steering.md +20 -25
- package/dist/axom-patch/cli/qoder-subagent-subwork.md +17 -68
- package/dist/axom-patch/cli/runtime.json +16 -18
- package/dist/axom-patch/cli/zcode-account-limits.json +10 -11
- package/dist/axom-patch/cli/zcode-models.json +1 -2
- package/dist/axom-patch/cli/zcode-subagent-subwork.json +9 -10
- package/dist/cli.js +4 -36
- package/dist/commands/knowledge.js +47 -0
- package/dist/commands/update.js +65 -3
- package/dist/commands/workstation.js +73 -7
- package/dist/install/claude/commands.js +13 -13
- package/dist/mcp.js +1 -1
- package/dist/native/darwin-arm64/axom-quic +0 -0
- package/dist/workstation/acp/acpAgents.js +102 -98
- package/dist/workstation/acp/acpClient.js +26 -0
- package/dist/workstation/acp/builds/install/npm.js +99 -10
- package/dist/workstation/acp/initializeResponse.js +6 -1
- package/dist/workstation/acp/managedPatches.js +189 -25
- package/dist/workstation/acp/managedRuntime.js +314 -0
- package/dist/workstation/acp/patchAssets.js +40 -0
- package/dist/workstation/acp/processor/checkpoint.js +25 -34
- package/dist/workstation/acp/processor/control.js +5 -78
- package/dist/workstation/acp/processor/runtime.js +5 -81
- package/dist/workstation/acp/processor/session.js +51 -80
- package/dist/workstation/acp/processor/state.js +6 -13
- package/dist/workstation/acp/processor/step.js +3 -20
- package/dist/workstation/acp/processor/test/fixtureLog.js +9 -16
- package/dist/workstation/acp/processor/updates.js +131 -105
- package/dist/workstation/acp/processorSession.js +8 -172
- package/dist/workstation/acp/registry/catalog.js +65 -39
- package/dist/workstation/acp/registry/launch.js +16 -1
- package/dist/workstation/acp/switching.js +0 -3
- package/dist/workstation/acp/test/fakeAgent.js +13 -0
- package/dist/workstation/acp/test/keeperWorld.js +28 -0
- package/dist/workstation/acp/test/raw/sources.js +16 -130
- package/dist/workstation/acp/test/realAdapter.js +1 -47
- package/dist/workstation/acp/test/scriptAgent.js +11 -3
- package/dist/workstation/agentFlow.js +1 -1
- package/dist/workstation/agentSessions.js +38 -143
- package/dist/workstation/channels/management.js +95 -11
- package/dist/workstation/channels/url.js +1 -1
- package/dist/workstation/config.js +16 -4
- package/dist/workstation/connection/encryptedChannel.js +4 -1
- package/dist/workstation/control/bindingStore.js +200 -0
- package/dist/workstation/control/commands.js +124 -0
- package/dist/workstation/control/daemonIdentity.js +53 -0
- package/dist/workstation/control/enrollment.js +106 -0
- package/dist/workstation/control/inspect.js +71 -0
- package/dist/workstation/control/locks.js +63 -0
- package/dist/workstation/control/protocol.js +40 -0
- package/dist/workstation/control/restartGuard.js +46 -0
- package/dist/workstation/control/runtimeClient.js +97 -0
- package/dist/workstation/control/runtimeHost.js +148 -0
- package/dist/workstation/control/serverIdentity.js +35 -0
- package/dist/workstation/daemon.js +106 -6
- package/dist/workstation/daemonctl.js +77 -14
- package/dist/workstation/desktopControl/audio.js +99 -0
- package/dist/workstation/desktopControl/capabilities.js +92 -0
- package/dist/workstation/desktopControl/captureModes.js +9 -0
- package/dist/workstation/desktopControl/captureTargetLabel.js +9 -0
- package/dist/workstation/desktopControl/deviceSockets.js +246 -0
- package/dist/workstation/desktopControl/helperProcess.js +353 -0
- package/dist/workstation/desktopControl/lobby.js +129 -0
- package/dist/workstation/desktopControl/macProvider.js +155 -0
- package/dist/workstation/desktopControl/media.js +331 -0
- package/dist/workstation/desktopControl/nativeProvider.js +1018 -0
- package/dist/workstation/desktopControl/networkEvidence.js +43 -0
- package/dist/workstation/desktopControl/overview.js +58 -0
- package/dist/workstation/desktopControl/protocol.js +302 -0
- package/dist/workstation/desktopControl/quicMedia.js +240 -0
- package/dist/workstation/desktopControl/rateController.js +226 -0
- package/dist/workstation/desktopControl/supervisor.js +1681 -0
- package/dist/workstation/desktopControl/transport.js +27 -0
- package/dist/workstation/desktopControl/wallpaper.js +78 -0
- package/dist/workstation/files/credentials.js +142 -0
- package/dist/workstation/files/text.js +42 -8
- package/dist/workstation/keepers/kit/bundle.js +21 -17
- package/dist/workstation/keepers/kit/launcher.js +47 -7
- package/dist/workstation/keepers/kit/paths.js +2 -1
- package/dist/workstation/managedInstall.js +57 -0
- package/dist/workstation/protocol/agent.js +2 -15
- package/dist/workstation/protocol/management.js +93 -4
- package/dist/workstation/protocol/runtimeDiagnostics.js +15 -0
- package/dist/workstation/rd/artifact.js +119 -0
- package/dist/workstation/rd/control.js +119 -0
- package/dist/workstation/rd/display.js +29 -0
- package/dist/workstation/rd/provider.js +222 -0
- package/dist/workstation/rd/sessions.js +391 -0
- package/dist/workstation/rd/state.js +45 -0
- package/dist/workstation/rd/update.js +171 -0
- package/dist/workstation/rd/upkeep.js +38 -0
- package/dist/workstation/register.js +27 -37
- package/dist/workstation/service/installer.js +104 -13
- package/dist/workstation/service/launchd.js +1 -0
- package/dist/workstation/storageMetrics.js +118 -0
- package/dist/workstation/systemMetrics.js +44 -92
- package/dist/workstation/toolchain.js +94 -0
- package/dist/workstation/tools/browser.js +28 -4
- package/dist/workstation/update/artifact.js +2 -1
- package/dist/workstation/update/globalInstall.js +116 -0
- package/dist/workstation/update/npmInstaller.js +49 -23
- package/dist/workstation/update/rdRollback.js +145 -0
- package/dist/workstation/update/runUpdate.js +3 -2
- package/dist/workstation/update/watchdog.js +16790 -334
- package/package.json +5 -5
- package/skills/axom/SKILL.md +11 -11
- package/skills/axom-definition/SKILL.md +3 -3
- package/skills/axom-platform/SKILL.md +3 -3
- package/dist/axom-patch/cli/probes/qoder-steering.mjs +0 -89
- package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +0 -61
- package/dist/axom-patch/cli/qoder-steering.json +0 -52
- package/dist/axom-patch/cli/qoder-subagent-origin.json +0 -73
- package/dist/commands/guide.js +0 -38
- package/dist/runtime-deps/qoder-sdk/package-lock.json +0 -1189
- package/dist/runtime-deps/qoder-sdk/package.json +0 -8
- package/dist/workstation/acp/delegationMcp.js +0 -24
- package/dist/workstation/acp/processor/sideChannel.js +0 -80
- package/dist/workstation/acp/qoderStartup.js +0 -45
- package/dist/workstation/acp/test/raw/qoderCaptures.js +0 -125
- package/dist/workstation/qoderAdapter/backgroundProcess.js +0 -118
- package/dist/workstation/qoderAdapter/backgroundTerminal.js +0 -193
- package/dist/workstation/qoderAdapter/backgroundTerminalFold.js +0 -372
- package/dist/workstation/qoderAdapter/callbackContext.js +0 -76
- package/dist/workstation/qoderAdapter/completedContinuation.js +0 -139
- package/dist/workstation/qoderAdapter/contract.js +0 -78
- package/dist/workstation/qoderAdapter/foregroundOutput.js +0 -36
- package/dist/workstation/qoderAdapter/history.js +0 -85
- package/dist/workstation/qoderAdapter/identityIndex.js +0 -191
- package/dist/workstation/qoderAdapter/inputQueue.js +0 -42
- package/dist/workstation/qoderAdapter/main.js +0 -95
- package/dist/workstation/qoderAdapter/mapper.js +0 -117
- package/dist/workstation/qoderAdapter/observerPlugin.js +0 -245
- package/dist/workstation/qoderAdapter/observerReceiver.js +0 -187
- package/dist/workstation/qoderAdapter/permissions.js +0 -61
- package/dist/workstation/qoderAdapter/profile.js +0 -93
- package/dist/workstation/qoderAdapter/sdkDriver.js +0 -48
- package/dist/workstation/qoderAdapter/sdkRuntime.js +0 -93
- package/dist/workstation/qoderAdapter/sdkRuntimeInstall.js +0 -145
- package/dist/workstation/qoderAdapter/session.js +0 -319
- package/dist/workstation/qoderAdapter/subagentMeta.js +0 -28
- package/dist/workstation/qoderAdapter/subwork.js +0 -85
- package/dist/workstation/qoderAdapter/taskControl.js +0 -38
- package/dist/workstation/qoderAdapter/taskLedger.js +0 -163
- package/dist/workstation/qoderAdapter/usage.js +0 -37
- /package/dist/workstation/{qoderAdapter/types.js → desktopControl/provider.js} +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "qoder-native-acp",
|
|
3
|
+
"package": "@qoder-ai/qodercli",
|
|
4
|
+
"versions": [
|
|
5
|
+
"1.1.75"
|
|
6
|
+
],
|
|
7
|
+
"bin": "qodercli",
|
|
8
|
+
"assets": [
|
|
9
|
+
{
|
|
10
|
+
"source": "qoder/dist/axom-acp-compat.mjs",
|
|
11
|
+
"target": "bundle/axom-acp-compat.mjs",
|
|
12
|
+
"sha256": "68d891676d72ca6fde3d8f1f1a131acfa8df3c5229c7bb02087eba431d784377"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"edits": [
|
|
16
|
+
{
|
|
17
|
+
"file": "bundle/qodercli.js",
|
|
18
|
+
"before_sha256": "1b5b17bb25bcd2e059a97e8bc1d4280e4c16fb4194b004463cd677c434536948",
|
|
19
|
+
"after_sha256": "02e98f249544981806c2244708ab5756c46859177ffdc376bb08f6cc1c9711b7",
|
|
20
|
+
"before": "().catch(()=>{}):Q.preload.headlessSession&&ona().catch(()=>{}),(async()=>{try{let{refreshDispatcher:A}=await Promise.resolve().then(()=>(W$e(),V$e));await A({reason:\"startup\"})}catch(A){C.debug(`[startup] dispatcher refresh failed (best-effort): ${A instanceof Error?A.message:String(A)}`)}})();let h=_Pt(A),w=c.merged.advanced.autoConfigureMemory?Ana(h):[],",
|
|
21
|
+
"after": "().catch(()=>{}):Q.preload.headlessSession&&ona().catch(()=>{}),(!A.acp&&(async()=>{try{let{refreshDispatcher:A}=await Promise.resolve().then(()=>(W$e(),V$e));await A({reason:\"startup\"})}catch(A){C.debug(`[startup] dispatcher refresh failed (best-effort): ${A instanceof Error?A.message:String(A)}`)}})());let h=_Pt(A),w=c.merged.advanced.autoConfigureMemory?Ana(h):[],"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"file": "bundle/qodercli.js",
|
|
25
|
+
"before_sha256": "02e98f249544981806c2244708ab5756c46859177ffdc376bb08f6cc1c9711b7",
|
|
26
|
+
"after_sha256": "98b00256424b6f59099866e3d8da715d9d026e46491b87cfb515db84b699c3be",
|
|
27
|
+
"before": "pdate:\"config_option_update\",configOptions:this.configOptions})}async sendUpdate(A){let e={sessionId:this.id,update:A};await this.connection.sessionUpdate(e)}supportsTerminalOutput(){return!0===this.clientCapabilities?.ter",
|
|
28
|
+
"after": "pdate:\"config_option_update\",configOptions:this.configOptions})}async sendUpdate(update){if(this.axomFailure)throw this.axomFailure;await this.axomSetup();await this.axomBridge.send(update);}async axomSdkUpdate(message,update){await this.axomSetup();await this.axomBridge.send(update,message);}supportsTerminalOutput(){return!0===this.clientCapabilities?.ter"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"file": "bundle/qodercli.js",
|
|
32
|
+
"before_sha256": "98b00256424b6f59099866e3d8da715d9d026e46491b87cfb515db84b699c3be",
|
|
33
|
+
"after_sha256": "8ee6ef6834aebed9c76f4f326a9d54c0e6c5c62ba049f082592cbe9d31195806",
|
|
34
|
+
"before": "ext}}):\"thinking_delta\"===e.delta.type&&e.delta.thinking&&await this.sendUpdate({sessionUpdate:\"agent_thought_chunk\",content:{type:\"text\",text:e.delta.thinking}}));break}case\"assistant\":if(A.message?.content&&Array.isArray(A.m",
|
|
35
|
+
"after": "ext}}):\"thinking_delta\"===e.delta.type&&e.delta.thinking&&await this.axomSdkUpdate(A,{sessionUpdate:\"agent_thought_chunk\",content:{type:\"text\",text:e.delta.thinking}}));break}case\"assistant\":if(A.message?.content&&Array.isArray(A.m"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"file": "bundle/qodercli.js",
|
|
39
|
+
"before_sha256": "8ee6ef6834aebed9c76f4f326a9d54c0e6c5c62ba049f082592cbe9d31195806",
|
|
40
|
+
"after_sha256": "bce94f52529e9717a90ad51d6ecad4de1203ada59febba16fde9869f965e699f",
|
|
41
|
+
"before": "type&&e.delta&&(\"text_delta\"===e.delta.type&&e.delta.text?await this.sendUpdate({sessionUpdate:\"agent_message_chunk\",content:{type:\"text\",text:e.delta.text}}):\"thinking_delta\"===e.delta.type&&e.delta.thinking&&await this.a",
|
|
42
|
+
"after": "type&&e.delta&&(\"text_delta\"===e.delta.type&&e.delta.text?await this.axomSdkUpdate(A,{sessionUpdate:\"agent_message_chunk\",content:{type:\"text\",text:e.delta.text}}):\"thinking_delta\"===e.delta.type&&e.delta.thinking&&await this.a"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"file": "bundle/qodercli.js",
|
|
46
|
+
"before_sha256": "bce94f52529e9717a90ad51d6ecad4de1203ada59febba16fde9869f965e699f",
|
|
47
|
+
"after_sha256": "e5a33bd41d46236e7610df1d185b5ea0ee3e6596f5d06a0a7123d724b59b972e",
|
|
48
|
+
"before": "input,output_tokens:e.output}}))}}}}async dispatchSDKMessage(A){switch(A.type){case\"stream_event\":{let e=A.event;\"content_block_",
|
|
49
|
+
"after": "input,output_tokens:e.output}}))}}}}async dispatchSDKMessage(A){await this.axomSetup();this.axomBridge.observe(A);switch(A.type){case\"stream_event\":{let e=A.event;\"content_block_"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"file": "bundle/qodercli.js",
|
|
53
|
+
"before_sha256": "e5a33bd41d46236e7610df1d185b5ea0ee3e6596f5d06a0a7123d724b59b972e",
|
|
54
|
+
"after_sha256": "207e2e0c98544878100c08bfdf2c909b176a80fc82c590e0cf821d7c054acc3e",
|
|
55
|
+
"before": "this.runNextQueuedPrompt()||this.scheduleTaskNotificationDrain()}}runNextQueuedPrompt(){let A=this.pendingMessages.shift();retur",
|
|
56
|
+
"after": "this.runNextQueuedPrompt()||this.scheduleTaskNotificationDrain()}}}runNextQueuedPrompt(){let A=this.pendingMessages.shift();retur"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"file": "bundle/qodercli.js",
|
|
60
|
+
"before_sha256": "207e2e0c98544878100c08bfdf2c909b176a80fc82c590e0cf821d7c054acc3e",
|
|
61
|
+
"after_sha256": "ac0fbece8d88bab7a73149f330003b03ecd518ce855c582dda0c4960a9cbd52f",
|
|
62
|
+
"before": "e.signal.aborted)return{stopReason:\"cancelled\"};throw A}finally{this.pendingPrompt===e&&(this.pendingPrompt=null),this.promptRun",
|
|
63
|
+
"after": "e.signal.aborted)return{stopReason:\"cancelled\"};throw A}finally{try{await this.axomBridge.endTurn();}finally{this.pendingPrompt===e&&(this.pendingPrompt=null),this.promptRun"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"file": "bundle/qodercli.js",
|
|
67
|
+
"before_sha256": "ac0fbece8d88bab7a73149f330003b03ecd518ce855c582dda0c4960a9cbd52f",
|
|
68
|
+
"after_sha256": "525fd57b0e6f8e90ef05d23d352fbe3515d1db56c51ed8b028d2aa2b59da2db0",
|
|
69
|
+
"before": " AbortController;this.pendingPrompt=e,this.promptRunning=!0;try{this.ensureSessionStartHooks(e.signal),await _mr(this.context.co",
|
|
70
|
+
"after": " AbortController;this.pendingPrompt=e,this.promptRunning=!0;try{this.axomBridge.begin();this.ensureSessionStartHooks(e.signal),await _mr(this.context.co"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"file": "bundle/qodercli.js",
|
|
74
|
+
"before_sha256": "525fd57b0e6f8e90ef05d23d352fbe3515d1db56c51ed8b028d2aa2b59da2db0",
|
|
75
|
+
"after_sha256": "598f10e58788697513f409ad154b5176da5ca626ddaed21b3af468353efdcf2c",
|
|
76
|
+
"before": "inking},messageId:t.uuid});let A=Np(t).join(\"\").trim();A&&await this.sendUpdate({sessionUpdate:\"agent_message_chunk\",content:{type:\"text\",text:A},messageId:t.uuid});for(let A of t.message.content){if(\"tool_use\"!==A.type)continue",
|
|
77
|
+
"after": "inking},messageId:t.uuid});let A=Np(t).join(\"\").trim();A&&await this.axomSdkUpdate(t,{sessionUpdate:\"agent_message_chunk\",content:{type:\"text\",text:A},messageId:t.uuid});for(let A of t.message.content){if(\"tool_use\"!==A.type)continue"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"file": "bundle/qodercli.js",
|
|
81
|
+
"before_sha256": "598f10e58788697513f409ad154b5176da5ca626ddaed21b3af468353efdcf2c",
|
|
82
|
+
"after_sha256": "e27e32fe698e7760a9674edc79bebcec8aefb2bc70c4186e85726166fb987bd0",
|
|
83
|
+
"before": "t.message.content)\"thinking\"===A.type&&A.thinking.trim()&&await this.sendUpdate({sessionUpdate:\"agent_thought_chunk\",content:{type:\"text\",text:A.thinking},messageId:t.uuid});let A=Np(t).join(\"\").trim();A&&await this.axomSdkUpdate(t,{sess",
|
|
84
|
+
"after": "t.message.content)\"thinking\"===A.type&&A.thinking.trim()&&await this.axomSdkUpdate(t,{sessionUpdate:\"agent_thought_chunk\",content:{type:\"text\",text:A.thinking},messageId:t.uuid});let A=Np(t).join(\"\").trim();A&&await this.axomSdkUpdate(t,{sess"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"file": "bundle/qodercli.js",
|
|
88
|
+
"before_sha256": "e27e32fe698e7760a9674edc79bebcec8aefb2bc70c4186e85726166fb987bd0",
|
|
89
|
+
"after_sha256": "017105b0b7da865d4536b8b4d21728b8afdd2bc7dd0dc79888458f4203dca225",
|
|
90
|
+
"before": "A){if(TG(t)){let A=_k(t).join(\"\\n\").trim();if(!A)continue;await this.sendUpdate({sessionUpdate:\"user_message_chunk\",content:{type:\"text\",text:A},messageId:t.uuid});continue}if(\"assistant\"===t.type){for(let A of t.message.conten",
|
|
91
|
+
"after": "A){if(TG(t)){let A=_k(t).join(\"\\n\").trim();if(!A)continue;await this.axomSdkUpdate(t,{sessionUpdate:\"user_message_chunk\",content:{type:\"text\",text:A},messageId:t.uuid});continue}if(\"assistant\"===t.type){for(let A of t.message.conten"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"file": "bundle/qodercli.js",
|
|
95
|
+
"before_sha256": "017105b0b7da865d4536b8b4d21728b8afdd2bc7dd0dc79888458f4203dca225",
|
|
96
|
+
"after_sha256": "cfd20401620f8a2a23b4e7572d4d9cae99798cca6e151ea2da3786c010c1512e",
|
|
97
|
+
"before": "figOptions}}async streamHistory(A){let e=yVd(A);for(let t of A){if(TG(t)){let A=_k(t).join(\"\\n\").trim();if(!A)continue;await thi",
|
|
98
|
+
"after": "figOptions}}async streamHistory(A){let e=yVd(A);for(let t of A){await this.axomBridge.history(t);if(TG(t)){let A=_k(t).join(\"\\n\").trim();if(!A)continue;await thi"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"file": "bundle/qodercli.js",
|
|
102
|
+
"before_sha256": "cfd20401620f8a2a23b4e7572d4d9cae99798cca6e151ea2da3786c010c1512e",
|
|
103
|
+
"after_sha256": "5c0800d97b0c029f395ad0bcce41ed2beb31d8a4e0a4c09a355eae4b3510191d",
|
|
104
|
+
"before": "h&&await vBA(iS(A,this.id),this.id)}async cancelPendingPrompt(){let A=this.pendingMessages.splice(0);A.length>0&&(this.pendingMe",
|
|
105
|
+
"after": "h&&await vBA(iS(A,this.id),this.id)}async cancelPendingPrompt(){this.axomBridge?.cancel();let A=this.pendingMessages.splice(0);A.length>0&&(this.pendingMe"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"file": "bundle/qodercli.js",
|
|
109
|
+
"before_sha256": "5c0800d97b0c029f395ad0bcce41ed2beb31d8a4e0a4c09a355eae4b3510191d",
|
|
110
|
+
"after_sha256": "6747880316425aba0339bb14aaf590b216abda30d50675715d3ec15a55ab56a5",
|
|
111
|
+
"before": "tification\"===A.commandMode&&A.sessionId===this.id),z3e(this.id)}async disposeConfig(){await this.context.config.dispose()}track",
|
|
112
|
+
"after": "tification\"===A.commandMode&&A.sessionId===this.id),z3e(this.id)}finally{await this.axomClosing;}}async disposeConfig(){await this.context.config.dispose()}track"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"file": "bundle/qodercli.js",
|
|
116
|
+
"before_sha256": "6747880316425aba0339bb14aaf590b216abda30d50675715d3ec15a55ab56a5",
|
|
117
|
+
"after_sha256": "b2bd40d1f4815729cdd9786408e94aacc47aedf58211f4c51523e24c7033a751",
|
|
118
|
+
"before": "s.finishDispose(A)}),this.disposePromise}async finishDispose(A){await Promise.allSettled(A),Mj(A=>\"task-notification\"===A.comman",
|
|
119
|
+
"after": "s.finishDispose(A)}),this.disposePromise}async finishDispose(A){try{await Promise.allSettled(A),Mj(A=>\"task-notification\"===A.comman"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"file": "bundle/qodercli.js",
|
|
123
|
+
"before_sha256": "b2bd40d1f4815729cdd9786408e94aacc47aedf58211f4c51523e24c7033a751",
|
|
124
|
+
"after_sha256": "ac43059b117176d775b3a59780795a65f7528cc900a3450548d16318ea60b9f2",
|
|
125
|
+
"before": "),!1)}finally{r&&i&&i.removeEventListener(\"abort\",r)}}dispose(){if(this.disposePromise)return this.disposePromise;this.disposed=",
|
|
126
|
+
"after": "),!1)}finally{r&&i&&i.removeEventListener(\"abort\",r)}}dispose(){this.axomClosing??=this.axomBridge?.close();if(this.disposePromise)return this.disposePromise;this.disposed="
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"file": "bundle/qodercli.js",
|
|
130
|
+
"before_sha256": "ac43059b117176d775b3a59780795a65f7528cc900a3450548d16318ea60b9f2",
|
|
131
|
+
"after_sha256": "93b48d4e4b07835a31a2684c4c4848930f413fd94790db8cb94ff9c1a282a304",
|
|
132
|
+
"before": ",e):void 0,n=await A.getTranscriptStore().acquireSessionWriter({filePath:this.resumeTranscriptPath??Ap(e,this.id),sessionId:this",
|
|
133
|
+
"after": ",e):void 0,n=await A.getTranscriptStore().acquireSessionWriter({version:await _r(),filePath:this.resumeTranscriptPath??Ap(e,this.id),sessionId:this"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"file": "bundle/qodercli.js",
|
|
137
|
+
"before_sha256": "93b48d4e4b07835a31a2684c4c4848930f413fd94790db8cb94ff9c1a282a304",
|
|
138
|
+
"after_sha256": "16a78af5e638e91908d2b3c273b60eb8423cb2a53a21c24617b9381366e0f21d",
|
|
139
|
+
"before": "){return this.disposed}isActive(){return this.active}activate(){if(this.disposed)throw new Error(`${_$d1(\"MVQYOisDalkuHTtPE0ETdC",
|
|
140
|
+
"after": "){return this.disposed}isActive(){return this.active}activate(){await this.axomSetup();await this.axomBridge.activate();if(this.disposed)throw new Error(`${_$d1(\"MVQYOisDalkuHTtPE0ETdC"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"file": "bundle/qodercli.js",
|
|
144
|
+
"before_sha256": "16a78af5e638e91908d2b3c273b60eb8423cb2a53a21c24617b9381366e0f21d",
|
|
145
|
+
"after_sha256": "cad0dfd6cf32b3befe7e8825dd7d3c5d4610b982563bf4b05cb093ea85b06172",
|
|
146
|
+
"before": "isDisposed(){return this.disposed}isActive(){return this.active}activate(){await this.axomSetup();await this.axomBridge.activate",
|
|
147
|
+
"after": "isDisposed(){return this.disposed}isActive(){return this.active}async activate(){await this.axomSetup();await this.axomBridge.activate"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"file": "bundle/qodercli.js",
|
|
151
|
+
"before_sha256": "cad0dfd6cf32b3befe7e8825dd7d3c5d4610b982563bf4b05cb093ea85b06172",
|
|
152
|
+
"after_sha256": "09006fd2299c0d2954e3f4ebe937225816606fdfd28ddb1751e2625369beb6bb",
|
|
153
|
+
"before": "lue}`);return e.setConfigOption(A.configId,A.value)}},MAA=class{constructor(A,e,t,i,r,n=\"startup\"){if(this.id=A,this.context=e,t",
|
|
154
|
+
"after": "lue}`);return e.setConfigOption(A.configId,A.value)}},MAA=class{axomBridge;axomClosing;async axomSetup(mode=\"new\"){if(this.disposed)throw new Error(\"Native ACP session disposed\");if(!this.axomBridge)this.axomBridge=__axomAcp.createBridge({root:this.id,cwd:this.context.config.getWorkingDir(),mode,releaseId:\"qoder-1.1.75-native-acp-v1\",historyVersions:[\"1.1.75\"],bindings:{RequestError:cs,uuid:ose,enqueue:Yw,remove:Mj,select:Ieu,consume:Qeu},send:value=>this.connection.sessionUpdate(value),fail:error=>{this.axomFailure=error;Promise.resolve(this.cancelPendingPrompt()).catch(()=>{});}});await this.axomBridge.ready();}axomFailure;\nconstructor(A,e,t,i,r,n=\"startup\"){if(this.id=A,this.context=e,t"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"file": "bundle/qodercli.js",
|
|
158
|
+
"before_sha256": "09006fd2299c0d2954e3f4ebe937225816606fdfd28ddb1751e2625369beb6bb",
|
|
159
|
+
"after_sha256": "8e522714cba1576db43362402423e98ae31937f9aefb50db733cead69cccc2f3",
|
|
160
|
+
"before": "this.sessions.get(A.sessionId);e&&await e.cancelPendingPrompt()}async prompt(A){await this.ensureAuthenticated();let e=this.sess",
|
|
161
|
+
"after": "this.sessions.get(A.sessionId);e&&await e.cancelPendingPrompt()}async extMethod(method,params){if(method!==\"_session/steering\")throw cs.methodNotFound(method);await this.ensureAuthenticated();if(!params||typeof params.sessionId!==\"string\"||!params.sessionId)throw cs.invalidParams(undefined,\"Missing sessionId\");const session=this.sessions.get(params.sessionId);if(!session)throw cs.invalidParams(undefined,\"Unknown sessionId\");if(!session.axomBridge)throw new cs(409,\"Session setup is not complete\");return session.axomBridge.accept(params);}\nasync prompt(A){await this.ensureAuthenticated();let e=this.sess"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"file": "bundle/qodercli.js",
|
|
165
|
+
"before_sha256": "8e522714cba1576db43362402423e98ae31937f9aefb50db733cead69cccc2f3",
|
|
166
|
+
"after_sha256": "487b48e5ad804e97005a712b8c0f771b16fa38b5731f8f038e68e829384a7847",
|
|
167
|
+
"before": "ait this.applySessionWorktreeStartupRequest(t,e,n),t.activate(),r&&await t.streamHistory(g),this.queueAvailableCommandsUpdate(t),IVd(t.getState())}catch(e)",
|
|
168
|
+
"after": "ait this.applySessionWorktreeStartupRequest(t,e,n),t.activate(),(r&&await t.streamHistory(g),await t.activate()),this.queueAvailableCommandsUpdate(t),IVd(t.getState())}catch(e)"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"file": "bundle/qodercli.js",
|
|
172
|
+
"before_sha256": "487b48e5ad804e97005a712b8c0f771b16fa38b5731f8f038e68e829384a7847",
|
|
173
|
+
"after_sha256": "ba5ae573ba1ec06fb7d2d9f83bf8c235ee29ad9d58263fad8a54f9f70ec18a44",
|
|
174
|
+
"before": "te}}:{}})),await this.applySessionWorktreeStartupRequest(t,e,n),t.activate(),(r&&await t.streamHistory(g),await t.activate()),this.queueAvai",
|
|
175
|
+
"after": "te}}:{}})),await this.applySessionWorktreeStartupRequest(t,e,n),await t.axomSetup(r?\"load\":\"resume\"),(r&&await t.streamHistory(g),await t.activate()),this.queueAvai"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"file": "bundle/qodercli.js",
|
|
179
|
+
"before_sha256": "ba5ae573ba1ec06fb7d2d9f83bf8c235ee29ad9d58263fad8a54f9f70ec18a44",
|
|
180
|
+
"after_sha256": "66e7c1691c61e09a5158a33cf3dec8c222c9d41870f80935033195bdab6a896d",
|
|
181
|
+
"before": "essionWorktreeStartupRequest(n,e,r),await n.persistNewSession(),n.activate(),this.queueAvailableCommandsUpdate(n),n.getState()}catch(e){thro",
|
|
182
|
+
"after": "essionWorktreeStartupRequest(n,e,r),await n.persistNewSession(),await n.activate(),this.queueAvailableCommandsUpdate(n),n.getState()}catch(e){thro"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"file": "bundle/qodercli.js",
|
|
186
|
+
"before_sha256": "66e7c1691c61e09a5158a33cf3dec8c222c9d41870f80935033195bdab6a896d",
|
|
187
|
+
"after_sha256": "b48b312417277f117627db0f98a9289e73968c5920c955f61e4e28ca515d7145",
|
|
188
|
+
"before": "await this.ensureQoderAuthBootstrapped();let t=await _r();return{protocolVersion:nAa,authMethods:e,agentInfo:{name:C0,title:Vn,version:t},agentCapabilities:{_meta:{qoder:{promptQueueing:!0}},loadSession:!0,sessionCapabilities:{additionalDirectories:{},close:{},delete:{},fork:{},list:{},resume:{}},promptCapabilities:{image:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate(A){await this.ensureQoderAuthBootstrapped();",
|
|
189
|
+
"after": "await this.ensureQoderAuthBootstrapped();let t=await _r();return(__axomAcp.initialize({protocolVersion:nAa,authMethods:e,agentInfo:{name:C0,title:Vn,version:t},agentCapabilities:{_meta:{qoder:{promptQueueing:!0}},loadSession:!0,sessionCapabilities:{additionalDirectories:{},close:{},delete:{},fork:{},list:{},resume:{}},promptCapabilities:{image:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}},\"qoder-1.1.75-native-acp-v1\",\"1.1.75\",{RequestError:cs,uuid:ose,enqueue:Yw,remove:Mj,select:Ieu,consume:Qeu}))}async authenticate(A){await this.ensureQoderAuthBootstrapped();"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"file": "bundle/qodercli.js",
|
|
193
|
+
"before_sha256": "b48b312417277f117627db0f98a9289e73968c5920c955f61e4e28ca515d7145",
|
|
194
|
+
"after_sha256": "f91ce7b1cbdd6616eb12223594d9cfefab0c06a74b137196d0e6c87fc7037bbb",
|
|
195
|
+
"before": "reason:\"end_turn\",numTurns:NA,usage:z,durationMs:Date.now()-X});let ve=[];if(S){ve=Ieu({isSubagent:!0===U,subagentAgentId:R,sessionId:a});let e=xho(ve),i=rA??D0A();rA=i;let r=VZ(S),n=[],o=new Set,s=!1;try{let t=await Beu(e,()=>{let e=new Set(UA().map(A=>A.function.name)),t=e.has(ed);return e7(null,S,ve,A.config?bO(A.config,[...e],{isMainSession:!0!==U}):null,{isInitialTurn:!1,isMainThread:!0!==U,isTodoToolEnabled:e.has(il),isTaskUpdateToolEnabled:t,taskStore:t&&A.config?.isTasksEnabled()?A.config.getTaskStore():void 0,skillListingConfig:A.config?vG(A.config,{model:pA,catalog:g,contextWindowTokens:PA}):void 0,uploadImagesToQoder:!dpe(A.config,pA),signal:c,diagnostics:{sessionId:a,turnId:w,loopId:eA,phase:\"inter_turn\"}},Ceu(A.config,{requestId:i,requestSetId:V.requestSetId,promptId:w},A.attachmentToolRegistry),!0===U?void 0:A.config?.planStateManager,Me)});n=t.value;let{dropConsumedBatch:r}=t;if(r){let A=new Set(e.flatMap(A=>A.uuid?[A.uuid]:[]));ve=ve.filter(A=>!e.includes(A)),n=n.filter(e=>{if(\"attachment\"!==e.type)return!0;let t=e.attachment.source_uuid;return\"string\"!=typeof t||!A.has(t)});for(let e of A)yield{type:\"command_lifecycle\",uuid:e,state:\"cancelled\"}}for(let A of n)yield A,o.add(A),Me.push(A);s=!0}finally{s||r(n.filter(e=>o.has(e)||!0===A.isAttachmentCommitted?.(e)))}let l=Qeu(ve);t.recordCommands(l);for(let A of l)A.uuid&&(yield{type:\"command_lifecycle\",uuid:A.uuid,state:\"started\"})}FA=Lj(Qe,{messages:Me,pendingUserMessageUuid:void 0,stopHookActive:Qe.stopHookActive||ve.some(A=>\"task-notification\"===A.commandMode&&A.stopHookActive),maxOutputTokensOverride:void 0,maxOutputTokensRecoveryCount:0},{reason:\"next_turn\"})}}catch(A){let e=A instanceof Error?A:new Error(String(A)),t=eE(",
|
|
196
|
+
"after": "reason:\"end_turn\",numTurns:NA,usage:z,durationMs:Date.now()-X});FA=yield* __axomDrain(Me);}}catch(A){let e=A instanceof Error?A:new Error(String(A)),t=eE("
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"file": "bundle/qodercli.js",
|
|
200
|
+
"before_sha256": "f91ce7b1cbdd6616eb12223594d9cfefab0c06a74b137196d0e6c87fc7037bbb",
|
|
201
|
+
"after_sha256": "06c14ab8138b59e62c410b5415ebb3c0472cd4c4e8387f16e49a2fe6381b0907",
|
|
202
|
+
"before": "ontinuationMessage,FA=e.nextState,bA=\"\",KA(se.length);continue}}return upe({sessionId:a,promptId:w,loopId:eA,requestIndex:AA,rea",
|
|
203
|
+
"after": "ontinuationMessage,FA=e.nextState,bA=\"\",KA(se.length);continue}}if(!__axomAcp.finish(a,!0===U)){if(!(S))throw new Error('Native ACP next attachment drain unavailable');FA=yield* __axomDrain([...Qe.messages]);bA=\"\";KA(se.length);continue;}return upe({sessionId:a,promptId:w,loopId:eA,requestIndex:AA,rea"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"file": "bundle/qodercli.js",
|
|
207
|
+
"before_sha256": "06c14ab8138b59e62c410b5415ebb3c0472cd4c4e8387f16e49a2fe6381b0907",
|
|
208
|
+
"after_sha256": "d6ea4f9bbdc598e94619a2b85e828dc0979c96bc79bacde124d60b40396ab3ed",
|
|
209
|
+
"before": "borted_streaming\",numTurns:NA,usage:z,durationMs:Date.now()-X});if(0===se.length){if(A.requestPreparationTiming?.turn.phase(\"fin",
|
|
210
|
+
"after": "borted_streaming\",numTurns:NA,usage:z,durationMs:Date.now()-X});async function* __axomDrain(Me){let ve=[];if(S){ve=Ieu({isSubagent:!0===U,subagentAgentId:R,sessionId:a});let e=xho(ve),i=rA??D0A();rA=i;let r=VZ(S),n=[],o=new Set,s=!1;try{let t=await Beu(e,()=>{let e=new Set(UA().map(A=>A.function.name)),t=e.has(ed);return e7(null,S,ve,A.config?bO(A.config,[...e],{isMainSession:!0!==U}):null,{isInitialTurn:!1,isMainThread:!0!==U,isTodoToolEnabled:e.has(il),isTaskUpdateToolEnabled:t,taskStore:t&&A.config?.isTasksEnabled()?A.config.getTaskStore():void 0,skillListingConfig:A.config?vG(A.config,{model:pA,catalog:g,contextWindowTokens:PA}):void 0,uploadImagesToQoder:!dpe(A.config,pA),signal:c,diagnostics:{sessionId:a,turnId:w,loopId:eA,phase:\"inter_turn\"}},Ceu(A.config,{requestId:i,requestSetId:V.requestSetId,promptId:w},A.attachmentToolRegistry),!0===U?void 0:A.config?.planStateManager,Me)});n=t.value;let{dropConsumedBatch:r}=t;if(r){let A=new Set(e.flatMap(A=>A.uuid?[A.uuid]:[]));ve=ve.filter(A=>!e.includes(A)),n=n.filter(e=>{if(\"attachment\"!==e.type)return!0;let t=e.attachment.source_uuid;return\"string\"!=typeof t||!A.has(t)});for(let e of A)(__axomAcp.cancelled(a,!0===U,[e]),yield{type:\"command_lifecycle\",uuid:e,state:\"cancelled\"})}for(let A of n)yield A,o.add(A),Me.push(A);s=!0}finally{s||r(n.filter(e=>o.has(e)||!0===A.isAttachmentCommitted?.(e)))}let l=Qeu(ve);t.recordCommands(l);for(let A of l)A.uuid&&((__axomAcp.consumed(a,!0===U,[A.uuid]),yield{type:\"command_lifecycle\",uuid:A.uuid,state:\"started\"}))};return Lj(Qe,{messages:Me,pendingUserMessageUuid:void 0,stopHookActive:Qe.stopHookActive||ve.some(A=>\"task-notification\"===A.commandMode&&A.stopHookActive),maxOutputTokensOverride:void 0,maxOutputTokensRecoveryCount:0},{reason:\"next_turn\"});}\nif(0===se.length){if(A.requestPreparationTiming?.turn.phase(\"fin"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"file": "bundle/qodercli.js",
|
|
214
|
+
"before_sha256": "d6ea4f9bbdc598e94619a2b85e828dc0979c96bc79bacde124d60b40396ab3ed",
|
|
215
|
+
"after_sha256": "3b8dbebe1be6d6b691a8ef8533feff636cad21a6e378576d0f61aa889d624073",
|
|
216
|
+
"before": "ok:!0===A.skipBeforeHook,isSubagent:!0===U});let aA,lA=async n=>(n.requestSetId??=V?.requestSetId,n.firstTtftMs??=t.firstTtftMs,A.requestPreparationTiming?.turn.terminal(n.reason,n.error),await(async e=>{if(!V||nA)return;nA=!0,V.finalize(e.reason,e.error);let t=Promise.all([sA(),...U?[]:[Kmo({sessionId:a,businessInfo:V.businessInfo}).catch(A=>{C.warn(\"[AgentLoop] Failed to report business finish\",A)})]]);!0!==A.config?.isInteractive?.()&&await t})(n),i.reason??=n.reason,e.recordTerminal(n),r&&(r.attributes[XA(\"interaction.reason\")]=n.reason,r.attributes[XA(\"interaction.turns\")]=n.numTurns,r.attributes[XA(\"interaction.duration_ms\")]=n.durationMs,n.modelStopReason&&(r.attributes[XA(\"interaction.model_stop_reason\")]=n.modelStopReason),r.output={reason:n.reason,modelStopReason:n.modelStopReason,numTurns:n.numTurns,durationMs:n.durationMs,usage:n.usage},\"error\"===n.reason&&(r.error=n.error??new Error(\"error_during_agent_loop\"))),K?.(n),kEo({sessionId:a,promptId:w,terminal:n})),gA=new AbortController,cA=AbortSignal.any([c,gA.signal]),BA=new",
|
|
217
|
+
"after": "ok:!0===A.skipBeforeHook,isSubagent:!0===U});let aA,lA=async n=>(__axomAcp.terminal(a,!0===U,n),(n.requestSetId??=V?.requestSetId,n.firstTtftMs??=t.firstTtftMs,A.requestPreparationTiming?.turn.terminal(n.reason,n.error),await(async e=>{if(!V||nA)return;nA=!0,V.finalize(e.reason,e.error);let t=Promise.all([sA(),...U?[]:[Kmo({sessionId:a,businessInfo:V.businessInfo}).catch(A=>{C.warn(\"[AgentLoop] Failed to report business finish\",A)})]]);!0!==A.config?.isInteractive?.()&&await t})(n),i.reason??=n.reason,e.recordTerminal(n),r&&(r.attributes[XA(\"interaction.reason\")]=n.reason,r.attributes[XA(\"interaction.turns\")]=n.numTurns,r.attributes[XA(\"interaction.duration_ms\")]=n.durationMs,n.modelStopReason&&(r.attributes[XA(\"interaction.model_stop_reason\")]=n.modelStopReason),r.output={reason:n.reason,modelStopReason:n.modelStopReason,numTurns:n.numTurns,durationMs:n.durationMs,usage:n.usage},\"error\"===n.reason&&(r.error=n.error??new Error(\"error_during_agent_loop\"))),K?.(n),kEo({sessionId:a,promptId:w,terminal:n}))),gA=new AbortController,cA=AbortSignal.any([c,gA.signal]),BA=new"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"file": "bundle/qodercli.js",
|
|
221
|
+
"before_sha256": "3b8dbebe1be6d6b691a8ef8533feff636cad21a6e378576d0f61aa889d624073",
|
|
222
|
+
"after_sha256": "daa88e7ca85152ddf9cc7f6aee1eff6aceb1dc664375950190fff22fa681d4a0",
|
|
223
|
+
"before": "#!/usr/bin/env node\nconst _$d1=(s,k=\"r5vTDwJ8MiR9\")=>{const b=Buffer.from(s,\"base64\"",
|
|
224
|
+
"after": "#!/usr/bin/env node\nimport * as __axomAcp from \"./axom-acp-compat.mjs\";\nconst _$d1=(s,k=\"r5vTDwJ8MiR9\")=>{const b=Buffer.from(s,\"base64\""
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
> **Current status:** The old steering recipe and standalone adapter are retired.
|
|
2
|
+
> The active runtime is the official `@qoder-ai/qodercli@1.1.75 --acp` process with the
|
|
3
|
+
> `qoder-native-acp` ordinary package patch. Release evidence is optional maintenance
|
|
4
|
+
> material; it is not an install or launch gate.
|
|
2
5
|
|
|
3
|
-
Qoder
|
|
4
|
-
`_session/steering`。只在实验 SDK adapter 中支持插话,不能让普通 `qoder` 入口出现按钮。
|
|
6
|
+
# Qoder native ACP patch
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
The current compatibility boundary is generated from `axom-patch/cli/qoder/scripts/generate.mjs`.
|
|
9
|
+
It applies the single `qoder-native-acp.json` recipe and its hashed
|
|
10
|
+
`qoder/dist/axom-acp-compat.mjs` asset to the exact official 1.1.75 package. Launch metadata
|
|
11
|
+
is authenticated as `bin.qodercli` with static argv `['--acp']`; the dispatcher is never used.
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
The patch declares only the native capabilities represented by the generated boundary,
|
|
14
|
+
including `steering.timings: ['next']`. It does not add an SDK, relay, second agent process,
|
|
15
|
+
JSON-RPC id translation, or provider branch in the generic CLI. Install and launch use the
|
|
16
|
+
same version-scoped recipe path as the other CLI patches: the Catalog pins 1.1.75 and the
|
|
17
|
+
recipe checks the pristine and patched file hashes.
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
To author a new candidate, verify the pristine official package, run the deterministic
|
|
20
|
+
builder/generator, and regenerate the recipe. Optional behavior evidence can be collected
|
|
21
|
+
for an upgrade or retirement decision; it does not promote or block the ordinary package
|
|
22
|
+
patch path.
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
当无补丁的原生 Qoder ACP 自己声明并实现相同插话协议,且普通入口的运行中工具、
|
|
25
|
-
消息落点、Stop、load/resume、模型/权限、子任务与完整基线验收通过时,可移除这份
|
|
26
|
-
配方、runtime 引用和台账项;单独 SDK 探针或版本升级不构成移除依据。
|
|
27
|
-
|
|
28
|
-
验证包括 CLI 的 `nativeSteeringPatch.test.ts`、对官方补丁包执行
|
|
29
|
-
`node axom-patch/cli/probes/qoder-steering.mjs <package>`,以及测试环境普通 `qoder`
|
|
30
|
-
入口的真实模型、REST 和 canvas 界面验收。测试入口名称及具体会话必须写入验收记录。
|
|
24
|
+
The previous steering behavior and probe captures are historical context only. They are
|
|
25
|
+
not active recipes or maintenance commands.
|
|
@@ -1,73 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
> **Current status:** The old subagent-origin recipe and standalone adapter are retired.
|
|
2
|
+
> The active runtime is the official `@qoder-ai/qodercli@1.1.75 --acp` process with the
|
|
3
|
+
> `qoder-native-acp` ordinary package patch. Release evidence is optional maintenance
|
|
4
|
+
> material; it is not an install or launch gate.
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# Qoder native subwork boundary
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
The native patch keeps child tool routing and history handling inside the generated ACP
|
|
9
|
+
boundary. Migrated conversion, background readers, checkpointing, and replay guards live
|
|
10
|
+
under `axom-patch/cli/qoder/src/`; they consume the release's declared history versions and
|
|
11
|
+
never infer compatibility from a newer version string.
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
The package identity is shared by Catalog and `qoder-native-acp.json`. The official process
|
|
14
|
+
owns transport, native session IDs, permissions, and history I/O. Axom preserves addressed
|
|
15
|
+
child updates and bounded recovery state without creating a relay or SDK executor.
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
For a candidate update, use the generator tests and the ordinary pristine/package-patch
|
|
18
|
+
hash checks with final package bytes. Optional behavior evidence may cover parallel
|
|
19
|
+
subagents, background reconnect, explicit load, resume, replay, and platform behavior; it
|
|
20
|
+
does not control whether the pinned package can be installed.
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
`bundle/qodercli.js` 做精确版本、原文件及每一步产物 SHA-256 校验。
|
|
17
|
-
在 Qoder 原生 ACP 转换层保留每个工具的父 ID,在文字/思考及历史事件上写
|
|
18
|
-
`_meta.qoder={version:1,source:"native-acp-patch",parentToolUseId,route:"child"}`。
|
|
19
|
-
根工具保留工具名和补丁版本,但不伪造父 ID。冲突和容量不足不猜归属。
|
|
20
|
-
2. `qoderAdapter/subwork.ts` 消费该元数据,生成已有的 ACP
|
|
21
|
-
`subagent_spawned` / `subagent_state_update`,并给 child item 填确定性地址:
|
|
22
|
-
`qoder-agent:<root native sessionId>:<Agent toolCallId>`。
|
|
23
|
-
解析器仍在根进程;任务正文、执行工具、结果和带身份的文字/思考落在 subwork。
|
|
24
|
-
3. Agent 工具调用被归一为同一个 subwork 派发与结果,不再额外产生委派摘要卡。
|
|
25
|
-
后台 `async_launched` 只是启动回执,不能据此结束子工作;已存在的后台真实终态修补
|
|
26
|
-
走同一归一入口。权限回调保持原生根会话的请求/回答路径,不启用独立子任务控制。
|
|
27
|
-
|
|
28
|
-
服务端、数据库、公共工作模型及 App 不新增 Qoder 判断;此次新增的核心 Qoder
|
|
29
|
-
元数据分支已经撤回。通用 ACP 会话只接线到 Qoder 自己的边界。
|
|
30
|
-
|
|
31
|
-
## 分发和版本门槛
|
|
32
|
-
|
|
33
|
-
`runtime.json` 引用补丁配方。`managedPatches.ts` 在 Install/Update/首次 managed
|
|
34
|
-
launch 时复制完整 npm 包及依赖,校验并写收据,启动不可变副本。npm 原缓存和用户
|
|
35
|
-
原有 Qoder 二进制保持原样。Qoder 包同时发布 `qodercli` 和 dispatcher 两个 bin,
|
|
36
|
-
配方显式选择 `bin:"qodercli"`;通用补丁加载器只增加可信配方的 bin 选择能力。
|
|
37
|
-
没有显式 bin 的其他补丁仍执行原来的单入口检查。
|
|
38
|
-
|
|
39
|
-
- 只认证原生 Qoder CLI 1.1.61 的这份发布包,不把 1.1.64 当作兼容版本。
|
|
40
|
-
- CLI 版本 bump 到 0.3.7,补丁跟随正常 Client release 分发。
|
|
41
|
-
- 显式自定义 command 按用户配置运行,不会偷偷替换用户二进制。要启用原生补丁,
|
|
42
|
-
工作站 Qoder 项使用 catalog 管理的原生 npm ACP 入口(清除旧二进制 command/args)。
|
|
43
|
-
- 继续走 Qoder 原生 ACP 的 new/load/resume、模型和权限模式;不把原生会话切换到
|
|
44
|
-
不支持恢复的 SDK adapter。已有历史不追溯猜分或改写;修复后的新事件才按证据分流。
|
|
45
|
-
- SDK adapter 的既有实验同样可经过本边界,但不是原生入口验收的替代品。
|
|
46
|
-
|
|
47
|
-
## 什么时候可以移除
|
|
48
|
-
|
|
49
|
-
当无补丁的 Qoder ACP 能发送稳定的派生关系、每帧子任务归属、真实终态以及可回放
|
|
50
|
-
的同一关系,并通过并发乱序、失败/取消、后台迟到、load/resume/重连验收后:删除
|
|
51
|
-
配方、runtime 引用、Qoder subwork 归一器和接线,台账标 retired。继续保留通用
|
|
52
|
-
ACP/Claude/Codex 基线。不以升级版本号或主 Agent 返回成功作为移除依据。
|
|
53
|
-
|
|
54
|
-
## 验证
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
cd axom-cli
|
|
58
|
-
npm test
|
|
59
|
-
cd ..
|
|
60
|
-
node axom-patch/cli/probes/qoder-subagent-origin.mjs /path/to/patched/qoder-package
|
|
61
|
-
AXOM_BASELINE_SQLITE_BIN=/path/to/new-sqlite/bin \
|
|
62
|
-
AXOM_BASELINE_PYTHON_BIN=/path/to/new-python/bin scripts/test-acp-baseline.sh
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
运行时探针执行官方 bundle 里实际的 ACP dispatch 方法,验证并发 child 的工具与
|
|
66
|
-
结果、文字、根输出和冲突边界;不启动模型、不读取凭据。真实功能验收必须另经
|
|
67
|
-
测试工作站、服务端、数据库、REST 和页面,记录具体会话。fixture 通过不等于上线验收。
|
|
68
|
-
|
|
69
|
-
## 原生后台过程补齐
|
|
70
|
-
|
|
71
|
-
Qoder 1.1.61 不向主 ACP 流转发后台子任务的 SDK 消息。`backgroundProcess.ts` 只读轮询经过原生启动回执确认的 `agent-<agentId>.jsonl`;每行必须同时匹配 native session、cwd、agentId、parent_tool_use_id、isSidechain 与版本。只发出实际记录的工具调用、结果、思考和回复,经 `_meta.qoder` 进入同一 subwork 边界。父会话空闲后仍可接收这些项;完成状态继续采用原生 task-notification,不从最后一条文本推断完成。
|
|
72
|
-
|
|
73
|
-
解析有单行、单轮字节与行数上限,拒绝符号链接、未知工具结果与不完整行,并按原生 uuid 去重。这一补齐针对本次已观察的后台调用;历史未观察任务不会被猜测迁移。上游转发后台消息后应移除 transcript 轮询,并保留并行归属和晚到事件验收。
|
|
22
|
+
Older adapter and version-specific probe notes are retained only in historical reports.
|
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"overrides": [
|
|
4
|
-
{
|
|
5
|
-
"id": "qoder-registry-catch-up",
|
|
6
|
-
"agent": "qoder",
|
|
7
|
-
"distribution": {
|
|
8
|
-
"version": "1.1.71",
|
|
9
|
-
"npx": {
|
|
10
|
-
"package": "@qoder-ai/qodercli@1.1.71",
|
|
11
|
-
"args": [
|
|
12
|
-
"--acp"
|
|
13
|
-
]
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"until_registry_version": "1.1.71"
|
|
17
|
-
},
|
|
18
4
|
{
|
|
19
5
|
"id": "claude-plan-tools",
|
|
20
6
|
"agent": "claude-acp",
|
|
@@ -30,12 +16,18 @@
|
|
|
30
16
|
}
|
|
31
17
|
}
|
|
32
18
|
],
|
|
19
|
+
"install_policies": [
|
|
20
|
+
{
|
|
21
|
+
"package": "@qoder-ai/qodercli",
|
|
22
|
+
"ignore_scripts": true
|
|
23
|
+
}
|
|
24
|
+
],
|
|
33
25
|
"package_patches": [
|
|
26
|
+
"qoder-native-acp.json",
|
|
34
27
|
"pi-steering.json",
|
|
35
28
|
"pi-subagent-subwork.json",
|
|
36
|
-
"qoder-subagent-origin.json",
|
|
37
|
-
"qoder-steering.json",
|
|
38
29
|
"codex-account-limits.json",
|
|
30
|
+
"codex-terminal-output.json",
|
|
39
31
|
"claude-account-limits.json",
|
|
40
32
|
"commandcode-account-limits.json",
|
|
41
33
|
"zcode-account-limits.json",
|
|
@@ -46,7 +38,11 @@
|
|
|
46
38
|
{
|
|
47
39
|
"agent": "kimi-code",
|
|
48
40
|
"versions": [
|
|
49
|
-
"2.1.1"
|
|
41
|
+
"2.1.1",
|
|
42
|
+
"2.2.0",
|
|
43
|
+
"2.3.0",
|
|
44
|
+
"2.3.2",
|
|
45
|
+
"2.3.3"
|
|
50
46
|
],
|
|
51
47
|
"entry": "account-limits/kimi-proxy.mjs"
|
|
52
48
|
},
|
|
@@ -54,7 +50,9 @@
|
|
|
54
50
|
"agent": "antigravity-acp",
|
|
55
51
|
"versions": [
|
|
56
52
|
"1.3.0",
|
|
57
|
-
"1.4.0"
|
|
53
|
+
"1.4.0",
|
|
54
|
+
"1.4.1",
|
|
55
|
+
"1.4.3"
|
|
58
56
|
],
|
|
59
57
|
"entry": "account-limits/antigravity-proxy.mjs",
|
|
60
58
|
"accountLimitsVersion": 5
|
|
@@ -2,30 +2,29 @@
|
|
|
2
2
|
"id": "zcode-account-limits",
|
|
3
3
|
"package": "zcode-acp-server",
|
|
4
4
|
"versions": [
|
|
5
|
-
"0.
|
|
6
|
-
"0.69.4"
|
|
5
|
+
"0.76.3"
|
|
7
6
|
],
|
|
8
7
|
"edits": [
|
|
9
8
|
{
|
|
10
9
|
"file": "dist/index.js",
|
|
11
|
-
"before_sha256": "
|
|
12
|
-
"after_sha256": "
|
|
13
|
-
"before": " .onRequest(\"account/usage_stats\", z.object({}).passthrough(), () =>
|
|
14
|
-
"after": " .onRequest(axomQuota.READ, z.object({}).passthrough(), async () => {\n const { buildAccountProviderConfig, codingPlanRequestAuthFor } = await import(\"./config/account-provider.js\");\n const { resolveQuotaHost } = await import(\"./quota/client.js\");\n let apiKey = null, family = \"\";\n for (const [providerId, provider] of Object.entries(buildAccountProviderConfig()?.providers ?? {})) {\n if (!provider?.access?.entitled) continue;\n const auth = codingPlanRequestAuthFor(providerId);\n if (auth?.apiKey) { apiKey = auth.apiKey; family = providerId; break; }\n }\n if (!apiKey) throw new Error(\"No entitled GLM coding plan: sign in once in the ZCode desktop app\");\n const resp = await fetch(resolveQuotaHost(family.startsWith(\"account:zai\") ? \"https://api.z.ai\" : \"\") + \"/api/monitor/usage/quota/limit\", { headers: { Accept: \"application/json, text/plain, */*\", Authorization: \"Bearer \" + apiKey }, signal: AbortSignal.timeout(8000) });\n const text = await resp.text();\n let json = null; try { json = text ? JSON.parse(text) : null; } catch {}\n if (resp.status === 429 || !json || json.success !== true) throw new Error(\"GLM quota read failed\" + (json?.msg ? \": \" + json.msg : \" (HTTP \" + resp.status + \")\"));\n const snapshot = axomQuota.zcode({ provider: family, level: json.data?.level, limits: json.data?.limits });\n axomQuotaNotify(snapshot);\n return snapshot;\n })\n .onRequest(\"account/usage_stats\", z.object({}).passthrough(), () =>
|
|
10
|
+
"before_sha256": "646b2203e7f3e950d2da202f6802f211ca70a7ccb67e017e78174106f5fda1ef",
|
|
11
|
+
"after_sha256": "00378165f2bbf9c97534805c0e8373e01d0c06049d976be78a1b387d23dc3adc",
|
|
12
|
+
"before": " .onRequest(\"account/usage_stats\", z.object({}).passthrough(), () => accountUsageStatsViaHub())",
|
|
13
|
+
"after": " .onRequest(axomQuota.READ, z.object({}).passthrough(), async () => {\n const { buildAccountProviderConfig, codingPlanRequestAuthFor } = await import(\"./config/account-provider.js\");\n const { resolveQuotaHost } = await import(\"./quota/client.js\");\n let apiKey = null, family = \"\";\n for (const [providerId, provider] of Object.entries(buildAccountProviderConfig()?.providers ?? {})) {\n if (!provider?.access?.entitled) continue;\n const auth = codingPlanRequestAuthFor(providerId);\n if (auth?.apiKey) { apiKey = auth.apiKey; family = providerId; break; }\n }\n if (!apiKey) throw new Error(\"No entitled GLM coding plan: sign in once in the ZCode desktop app\");\n const resp = await fetch(resolveQuotaHost(family.startsWith(\"account:zai\") ? \"https://api.z.ai\" : \"\") + \"/api/monitor/usage/quota/limit\", { headers: { Accept: \"application/json, text/plain, */*\", Authorization: \"Bearer \" + apiKey }, signal: AbortSignal.timeout(8000) });\n const text = await resp.text();\n let json = null; try { json = text ? JSON.parse(text) : null; } catch {}\n if (resp.status === 429 || !json || json.success !== true) throw new Error(\"GLM quota read failed\" + (json?.msg ? \": \" + json.msg : \" (HTTP \" + resp.status + \")\"));\n const snapshot = axomQuota.zcode({ provider: family, level: json.data?.level, limits: json.data?.limits });\n axomQuotaNotify(snapshot);\n return snapshot;\n })\n .onRequest(\"account/usage_stats\", z.object({}).passthrough(), () => accountUsageStatsViaHub())"
|
|
15
14
|
},
|
|
16
15
|
{
|
|
17
16
|
"file": "dist/index.js",
|
|
18
|
-
"before_sha256": "
|
|
19
|
-
"after_sha256": "
|
|
17
|
+
"before_sha256": "00378165f2bbf9c97534805c0e8373e01d0c06049d976be78a1b387d23dc3adc",
|
|
18
|
+
"after_sha256": "f9b292c102776aa4d125bbedb7c415fce5316cadd48096a438710fa21140d323",
|
|
20
19
|
"before": " .onRequest(\"initialize\", (ctx) => server.initialize(ctx.params, ctx.client))",
|
|
21
20
|
"after": " .onRequest(\"initialize\", async (ctx) => { const result = await server.initialize(ctx.params, ctx.client); const caps = result.agentCapabilities ?? {}; result.agentCapabilities = { ...caps, _meta: { ...caps._meta, \"axom/accountRateLimits\": { ...axomQuota.CAPABILITY, provider: \"zcode\" } } }; return result; })"
|
|
22
21
|
},
|
|
23
22
|
{
|
|
24
23
|
"file": "dist/index.js",
|
|
25
|
-
"before_sha256": "
|
|
26
|
-
"after_sha256": "
|
|
24
|
+
"before_sha256": "f9b292c102776aa4d125bbedb7c415fce5316cadd48096a438710fa21140d323",
|
|
25
|
+
"after_sha256": "fb88f1e5275d100e94c7a95e0bd919489fa4e07932f21cd37faa7e44dc6525fa",
|
|
27
26
|
"before": "#!/usr/bin/env node\n/**\n * Entry point: wire the ZcodeAcpServer to a stdio ACP stream.\n *\n * The ACP",
|
|
28
|
-
"after": "#!/usr/bin/env node\n\nconst axomQuota = (() => {\n/** Account quota normalization. No I/O: passive events must never trigger a query. */\nconst READ = '_axom/account/rateLimits/read';\nconst UPDATED = '_axom/account/rateLimits/updated';\nconst CAPABILITY = { version: 2, read: true, updated: true };\nconst percent = v => typeof v === 'number' && Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : null;\nconst finite = v => { if (v == null || typeof v === 'boolean') return null; const n = typeof v === 'number' ? v : Number(v); return Number.isFinite(n) ? n : null; };\nconst time = (v, milliseconds = false) => {\n if (v == null || v === 0) return null;\n const d = new Date(typeof v === 'number' ? v * (milliseconds ? 1 : 1000) : v);\n return Number.isFinite(d.getTime()) ? d.toISOString() : null;\n};\nconst status = v => ({ allowed: 'allowed', allowed_warning: 'warning', rejected: 'blocked', normal: 'allowed' }[v] ?? 'unknown');\n/** Canonical window key rides the snapshot; the UI owns the key → display-label translation.\n * Windows without a canonical key keep their vendor content untouched. */\nconst windowKey = (seconds, period) => period === 'month' ? 'monthly' : seconds === 18000 ? 'five_hour' : seconds === 604800 ? 'weekly' : null;\nconst base = (provider, mode, raw, observedAt) => ({ schemaVersion: 1, updateMode: 'snapshot', provider, billingMode: mode, availability: mode === 'subscription' ? 'available' : mode === 'unknown' ? 'unknown' : 'not_applicable', observedAt: observedAt ?? new Date().toISOString(), plan: null, limits: [], balances: [], _meta: { ['_' + provider]: structuredClone(raw) } });\nfunction codex(raw, authType = 'chatgpt', observedAt) {\n const out = base('codex', ['chatgpt', 'chatgptAuthTokens'].includes(authType) ? 'subscription' : ['apiKey','apikey','amazonBedrock'].includes(authType) ? 'non_subscription' : 'unknown', raw, observedAt);\n if (out.billingMode !== 'subscription') return out;\n const buckets = Object.entries(raw.rateLimitsByLimitId ?? {});\n if (!buckets.length && raw.rateLimits) buckets.push([raw.rateLimits.limitId ?? 'codex', raw.rateLimits]);\n for (const [id, bucket] of buckets) {\n if (!bucket) continue;\n if (bucket.planType) out.plan = { id: bucket.planType, label: bucket.planType };\n for (const name of ['primary', 'secondary']) {\n const w = bucket[name]; if (!w) continue;\n const seconds = w.windowDurationMins == null ? null : w.windowDurationMins * 60;\n out.limits.push({ id: `${id}.${name}`, label: bucket.limitName ?? id, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.usedPercent), resetsAt: time(w.resetsAt), status: bucket.rateLimitReachedType ? 'blocked' : 'unknown', scope: { bucket: id } });\n }\n if (bucket.credits) out.balances.push({ id: `${id}.credits`, label: 'Credits', remaining: bucket.credits.balance ?? null, unit: 'credits', unlimited: bucket.credits.unlimited === true });\n }\n // Account IDs must not escape via provider extensions.\n delete out._meta._codex.accountId;\n return out;\n}\nfunction claude(raw, observedAt) {\n const mode = raw.billing_mode ?? (raw.subscription_type || raw.rate_limits_available === true ? 'subscription' : 'unknown');\n const out = base('claude', mode, raw, observedAt);\n out.plan = raw.subscription_type ? { id: raw.subscription_type, label: raw.subscription_type } : null;\n if (mode === 'subscription' && !raw.rate_limits_available) out.availability = 'unavailable';\n const limits = raw.rate_limits ?? {};\n const rows = Array.isArray(limits.limits) ? limits.limits : [];\n if (rows.length) {\n rows.forEach((w, i) => {\n const seconds = w.group === 'session' ? 18000 : w.group === 'weekly' ? 604800 : null;\n out.limits.push({ id: `claude.${w.kind}.${i}`, label: w.scope?.model?.display_name ?? w.kind, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.percent), resetsAt: time(w.resets_at), status: status(w.severity), active: w.is_active ?? null, scope: w.scope ?? null });\n });\n } else for (const [id, seconds] of [['five_hour', 18000], ['seven_day', 604800], ['seven_day_opus',604800], ['seven_day_sonnet',604800]]) {\n const w = limits[id]; if (!w) continue;\n out.limits.push({ id: `claude.${id}`, label: id, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.utilization), resetsAt: time(w.resets_at), status: 'unknown', scope: id.endsWith('opus') || id.endsWith('sonnet') ? { model: id.split('_').at(-1) } : null });\n }\n const spend=limits.spend;\n if(spend?.enabled && spend.used && spend.limit) out.limits.push({id:'claude.extra_spend',label:'Extra usage',kind:'spend',windowSeconds:null,usedPercent:percent(spend.percent),resetsAt:null,status:status(spend.severity),used:String(spend.used.amount_minor),limit:String(spend.limit.amount_minor),unit:'money',currency:spend.used.currency,exponent:spend.used.exponent});\n if(spend?.balance?.amount_minor != null) out.balances.push({id:'claude.extra_balance',label:'Extra usage balance',remaining:String(spend.balance.amount_minor),unit:'money',currency:spend.balance.currency,exponent:spend.balance.exponent});\n return out;\n}\nfunction claudeEvent(raw, previous = null, observedAt) {\n const out = previous ? structuredClone(previous) : base('claude',raw.rateLimitType?'subscription':'unknown',{},observedAt);\n out.updateMode = 'delta';\n out.balances = [];\n out.observedAt = observedAt ?? new Date().toISOString();\n out._meta._claude = { ...out._meta._claude, rateLimitEvent: raw };\n const seconds = raw.rateLimitType === 'five_hour' ? 18000 : raw.rateLimitType?.startsWith('seven_day') ? 604800 : null;\n if (seconds !== null) {\n const id = `claude.${raw.rateLimitType}`;\n const scoped = !['five_hour','seven_day'].includes(raw.rateLimitType);\n const prior=out.limits.find(w => w.windowSeconds===seconds && JSON.stringify(w.scope??null)===JSON.stringify(scoped ? {model:raw.rateLimitType.split('_').at(-1)}:null));\n const nextReset=time(raw.resetsAt);\n const rolled=prior?.resetsAt && nextReset && Math.abs(Date.parse(nextReset)-Date.parse(prior.resetsAt))>1000;\n const row = { id, label: raw.rateLimitType, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: raw.utilization == null ? (rolled ? null : prior?.usedPercent ?? null) : percent(raw.utilization * 100), resetsAt: raw.resetsAt == null ? prior?.resetsAt ?? null : time(raw.resetsAt), status: status(raw.status), scope: scoped ? { model: raw.rateLimitType.split('_').at(-1) } : null };\n // Event utilization is a ratio, unlike get_usage's percentage. Match the existing window without duplicating it.\n const i = out.limits.findIndex(w => w.windowSeconds === seconds && JSON.stringify(w.scope ?? null) === JSON.stringify(row.scope));\n out.limits = [i >= 0 ? { ...out.limits[i], ...row, id: out.limits[i].id } : row];\n } else out.limits = [];\n return out;\n}\nfunction kimi(raw, observedAt) {\n const quota = raw.quota ?? raw;\n const out = base('kimi','subscription',quota,observedAt);\n for (const [id, seconds] of [['limit5h',18000],['limit7d',604800],['monthTotal',null]]) {\n const w = quota.usages?.[id]; if (!w) continue;\n out.limits.push({ id: `kimi.${id}`, label: id, kind: 'subscription', windowSeconds: seconds, period: id === 'monthTotal' ? 'month' : null, key: windowKey(seconds, id === 'monthTotal' ? 'month' : null), usedPercent: percent(w.usedRatio * 100), resetsAt: time(w.resetAt), status: 'unknown' });\n }\n const wallet = quota.extraUsage;\n if (wallet) out.balances.push({ id:'kimi.extra',label:'Extra usage',remaining:String(wallet.balanceCents),unit:'money',currency:wallet.currency,exponent:2 });\n return out;\n}\n/** GLM quota `percentage` is the USED share (measured: 5% for 58/1000); counters win when present.\n * Counter-derived shares are rounded to 2 decimals — 100-94.2 keeps fp noise otherwise. */\nconst glmPercent = limit => {\n const used = finite(limit.currentValue), remaining = finite(limit.remaining), total = finite(limit.usage);\n const cap = remaining !== null && used !== null ? remaining + used : total;\n const round2 = v => v == null ? null : Math.round(v * 100) / 100;\n if (cap !== null && cap > 0 && remaining !== null && remaining >= 0 && remaining <= cap) return round2(100 - percent(remaining / cap * 100));\n if (cap !== null && cap > 0 && used !== null && used >= 0 && used <= cap) return round2(percent(used / cap * 100));\n return percent(limit.percentage);\n};\nfunction zcode(raw, observedAt) {\n // Raw: the GLM quota endpoint's data block — { level, limits: [{ type, number, usage,\n // currentValue, remaining, percentage, nextResetTime(epoch ms), usageDetails }] }. Which windows\n // exist is plan-dependent (measured pro plan: 5h prompts + a tool/MCP allowance; no weekly row —\n // a `number: 7` window maps when a plan returns one, and nothing is invented when it doesn't).\n const limits = Array.isArray(raw?.limits) ? raw.limits : [];\n const level = typeof raw?.level === 'string' && raw.level ? raw.level : null;\n const out = base('zcode', limits.length ? 'subscription' : 'unknown', raw, observedAt);\n out.plan = level ? { id: level, label: level } : null;\n let tools = 0;\n limits.forEach((limit, i) => {\n if (!limit || typeof limit !== 'object') return;\n const resetsAt = time(limit.nextResetTime, true);\n if (limit.type === 'TOKENS_LIMIT') {\n // GLM window convention: number 5 → the 5-hour prompt window, 7 → weekly.\n // Ids mirror the adapter's own /quota keys (token_5h / token_week).\n const seconds = limit.number === 5 ? 18000 : limit.number === 7 ? 604800 : null;\n const label = limit.number === 5 ? '5h' : limit.number === 7 ? 'Week' : `token ${limit.number ?? i}`;\n const id = limit.number === 5 ? 'zcode.token_5h' : limit.number === 7 ? 'zcode.token_week' : `zcode.token_${limit.number ?? i}`;\n out.limits.push({ id, label, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: glmPercent(limit), resetsAt, status: 'unknown' });\n } else if (limit.type === 'TIME_LIMIT' || limit.type === 'MCP_LIMIT') {\n // Built-in tool/MCP allowance: absolute counters (unit 'calls'); per-model detail stays in _meta.\n const used = finite(limit.currentValue), total = finite(limit.usage), remaining = finite(limit.remaining);\n out.limits.push({ id: tools ? `zcode.mcp.${i}` : 'zcode.mcp', label: 'MCP', kind: 'subscription', windowSeconds: null, usedPercent: glmPercent(limit), ...(used !== null && total !== null ? { used: String(used), limit: String(total), unit: 'calls' } : {}), resetsAt, status: remaining === 0 ? 'blocked' : used !== null || limit.percentage != null ? 'allowed' : 'unknown' });\n tools++;\n }\n });\n return out;\n}\nfunction commandcode(raw, observedAt) {\n const subscription = raw.subscription?.data ?? raw.subscription;\n const windows = raw.credits?.windowLimits ?? raw.windowLimits;\n const subscribed = ['active','trialing','past_due'].includes(subscription?.status) || windows?.limited === true;\n const mode = subscribed ? 'subscription' : subscription || windows ? 'non_subscription' : 'unknown';\n const out = base('commandcode',mode,raw,observedAt);\n out.plan = subscription?.planId ? { id:subscription.planId,label:subscription.planId } : null;\n for (const [id, seconds] of [['fiveHour',18000],['weekly',604800]]) {\n const w=windows?.[id]; if (!w) continue;\n out.limits.push({ id:`commandcode.${id}`,label:id,kind:'subscription',windowSeconds:seconds,key:windowKey(seconds),usedPercent:w.cap > 0 ? percent(w.used / w.cap * 100) : null,used:String(w.used),limit:String(w.cap),unit:'credits',resetsAt:time(w.resetAt,true),status:w.exceeded === true ? 'blocked' : 'allowed' });\n }\n const credits=raw.credits?.credits ?? raw.credits;\n if (subscribed && credits?.monthlyCredits != null) {\n const cap=raw.monthly?.limit;\n const known=typeof cap==='number' && Number.isFinite(cap) && cap>0;\n const used=known ? Math.max(0,cap-credits.monthlyCredits) : null;\n out.limits.push({id:'commandcode.monthly',label:'Monthly',kind:'subscription',windowSeconds:null,period:'month',key:windowKey(null,'month'),usedPercent:known?percent(used/cap*100):null,resetsAt:time(subscription?.currentPeriodEnd,true),status:'unknown',...(known?{used:String(used),limit:String(cap),unit:'credits'}:{})});\n }\n for (const [id,label] of [['monthlyCredits','Monthly credits'],['purchasedCredits','Purchased credits'],['freeCredits','Free credits']]) if (credits?.[id] != null) out.balances.push({ id:`commandcode.${id}`,label,remaining:String(credits[id]),unit:'credits' });\n return out;\n}\n\nreturn {READ,UPDATED,CAPABILITY,codex,claude,claudeEvent,kimi,commandcode,zcode};\n})();\nconst axomQuotaNotify = snapshot => process.stdout.write(JSON.stringify({jsonrpc:\"2.0\",method:axomQuota.UPDATED,params:snapshot})+\"\\n\");\n/**\n * Entry point: wire the ZcodeAcpServer to a stdio ACP stream.\n *\n * The ACP"
|
|
27
|
+
"after": "#!/usr/bin/env node\n\nconst axomQuota = (() => {\n/** Account quota normalization. No I/O: passive events must never trigger a query. */\nconst READ = '_axom/account/rateLimits/read';\nconst UPDATED = '_axom/account/rateLimits/updated';\nconst CAPABILITY = { version: 2, read: true, updated: true };\nconst percent = v => typeof v === 'number' && Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : null;\nconst finite = v => { if (v == null || typeof v === 'boolean') return null; const n = typeof v === 'number' ? v : Number(v); return Number.isFinite(n) ? n : null; };\nconst time = (v, milliseconds = false) => {\n if (v == null || v === 0) return null;\n const d = new Date(typeof v === 'number' ? v * (milliseconds ? 1 : 1000) : v);\n return Number.isFinite(d.getTime()) ? d.toISOString() : null;\n};\nconst status = v => ({ allowed: 'allowed', allowed_warning: 'warning', rejected: 'blocked', normal: 'allowed' }[v] ?? 'unknown');\n/** Canonical window key rides the snapshot; the UI owns the key → display-label translation.\n * Windows without a canonical key keep their vendor content untouched. */\nconst windowKey = (seconds, period) => period === 'month' ? 'monthly' : seconds === 18000 ? 'five_hour' : seconds === 604800 ? 'weekly' : null;\nconst base = (provider, mode, raw, observedAt) => ({ schemaVersion: 1, updateMode: 'snapshot', provider, billingMode: mode, availability: mode === 'subscription' ? 'available' : mode === 'unknown' ? 'unknown' : 'not_applicable', observedAt: observedAt ?? new Date().toISOString(), plan: null, limits: [], balances: [], _meta: { ['_' + provider]: structuredClone(raw) } });\nfunction codex(raw, authType = 'chatgpt', observedAt) {\n const out = base('codex', ['chatgpt', 'chatgptAuthTokens'].includes(authType) ? 'subscription' : ['apiKey','apikey','amazonBedrock'].includes(authType) ? 'non_subscription' : 'unknown', raw, observedAt);\n if (out.billingMode !== 'subscription') return out;\n const buckets = Object.entries(raw.rateLimitsByLimitId ?? {});\n if (!buckets.length && raw.rateLimits) buckets.push([raw.rateLimits.limitId ?? 'codex', raw.rateLimits]);\n for (const [id, bucket] of buckets) {\n if (!bucket) continue;\n if (bucket.planType) out.plan = { id: bucket.planType, label: bucket.planType };\n for (const name of ['primary', 'secondary']) {\n const w = bucket[name]; if (!w) continue;\n const seconds = w.windowDurationMins == null ? null : w.windowDurationMins * 60;\n out.limits.push({ id: `${id}.${name}`, label: bucket.limitName ?? id, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.usedPercent), resetsAt: time(w.resetsAt), status: bucket.rateLimitReachedType ? 'blocked' : 'unknown', scope: { bucket: id } });\n }\n if (bucket.credits) out.balances.push({ id: `${id}.credits`, label: 'Credits', remaining: bucket.credits.balance ?? null, unit: 'credits', unlimited: bucket.credits.unlimited === true });\n }\n // Account IDs must not escape via provider extensions.\n delete out._meta._codex.accountId;\n return out;\n}\n/** App-server notifications describe changed buckets, not the complete account read. */\nfunction codexEvent(raw, authType, observedAt) {\n return { ...codex(raw, authType, observedAt), updateMode: 'delta' };\n}\nfunction claude(raw, observedAt) {\n const mode = raw.billing_mode ?? (raw.subscription_type || raw.rate_limits_available === true ? 'subscription' : 'unknown');\n const out = base('claude', mode, raw, observedAt);\n out.plan = raw.subscription_type ? { id: raw.subscription_type, label: raw.subscription_type } : null;\n if (mode === 'subscription' && !raw.rate_limits_available) out.availability = 'unavailable';\n const limits = raw.rate_limits ?? {};\n const rows = Array.isArray(limits.limits) ? limits.limits : [];\n if (rows.length) {\n rows.forEach((w, i) => {\n const seconds = w.group === 'session' ? 18000 : w.group === 'weekly' ? 604800 : null;\n out.limits.push({ id: `claude.${w.kind}.${i}`, label: w.scope?.model?.display_name ?? w.kind, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.percent), resetsAt: time(w.resets_at), status: status(w.severity), active: w.is_active ?? null, scope: w.scope ?? null });\n });\n } else for (const [id, seconds] of [['five_hour', 18000], ['seven_day', 604800], ['seven_day_opus',604800], ['seven_day_sonnet',604800]]) {\n const w = limits[id]; if (!w) continue;\n out.limits.push({ id: `claude.${id}`, label: id, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: percent(w.utilization), resetsAt: time(w.resets_at), status: 'unknown', scope: id.endsWith('opus') || id.endsWith('sonnet') ? { model: id.split('_').at(-1) } : null });\n }\n const spend=limits.spend;\n if(spend?.enabled && spend.used && spend.limit) out.limits.push({id:'claude.extra_spend',label:'Extra usage',kind:'spend',windowSeconds:null,usedPercent:percent(spend.percent),resetsAt:null,status:status(spend.severity),used:String(spend.used.amount_minor),limit:String(spend.limit.amount_minor),unit:'money',currency:spend.used.currency,exponent:spend.used.exponent});\n if(spend?.balance?.amount_minor != null) out.balances.push({id:'claude.extra_balance',label:'Extra usage balance',remaining:String(spend.balance.amount_minor),unit:'money',currency:spend.balance.currency,exponent:spend.balance.exponent});\n return out;\n}\nfunction claudeEvent(raw, previous = null, observedAt) {\n const out = previous ? structuredClone(previous) : base('claude',raw.rateLimitType?'subscription':'unknown',{},observedAt);\n out.updateMode = 'delta';\n out.balances = [];\n out.observedAt = observedAt ?? new Date().toISOString();\n // Other sessions may have refreshed the account since this process's cached read.\n // Send only facts from this event; the server owns the merged account observation.\n out.plan = null;\n out._meta = { _claude: { rateLimitEvent: raw } };\n const seconds = raw.rateLimitType === 'five_hour' ? 18000 : raw.rateLimitType?.startsWith('seven_day') ? 604800 : null;\n if (seconds !== null) {\n const id = `claude.${raw.rateLimitType}`;\n const scoped = !['five_hour','seven_day'].includes(raw.rateLimitType);\n const prior=out.limits.find(w => w.windowSeconds===seconds && JSON.stringify(w.scope??null)===JSON.stringify(scoped ? {model:raw.rateLimitType.split('_').at(-1)}:null));\n const row = { id: prior?.id ?? id, label: raw.rateLimitType, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: raw.utilization == null ? null : percent(raw.utilization * 100), resetsAt: time(raw.resetsAt), status: status(raw.status), scope: scoped ? { model: raw.rateLimitType.split('_').at(-1) } : null };\n // Event utilization is a ratio, unlike get_usage's percentage. Match the existing window without duplicating it.\n out.limits = [row];\n } else out.limits = [];\n return out;\n}\nfunction kimi(raw, observedAt) {\n const quota = raw.quota ?? raw;\n const out = base('kimi','subscription',quota,observedAt);\n for (const [id, seconds] of [['limit5h',18000],['limit7d',604800],['monthTotal',null]]) {\n const w = quota.usages?.[id]; if (!w) continue;\n out.limits.push({ id: `kimi.${id}`, label: id, kind: 'subscription', windowSeconds: seconds, period: id === 'monthTotal' ? 'month' : null, key: windowKey(seconds, id === 'monthTotal' ? 'month' : null), usedPercent: percent(w.usedRatio * 100), resetsAt: time(w.resetAt), status: 'unknown' });\n }\n const wallet = quota.extraUsage;\n if (wallet) out.balances.push({ id:'kimi.extra',label:'Extra usage',remaining:String(wallet.balanceCents),unit:'money',currency:wallet.currency,exponent:2 });\n return out;\n}\n/** GLM quota `percentage` is the USED share (measured: 5% for 58/1000); counters win when present.\n * Counter-derived shares are rounded to 2 decimals — 100-94.2 keeps fp noise otherwise. */\nconst glmPercent = limit => {\n const used = finite(limit.currentValue), remaining = finite(limit.remaining), total = finite(limit.usage);\n const cap = remaining !== null && used !== null ? remaining + used : total;\n const round2 = v => v == null ? null : Math.round(v * 100) / 100;\n if (cap !== null && cap > 0 && remaining !== null && remaining >= 0 && remaining <= cap) return round2(100 - percent(remaining / cap * 100));\n if (cap !== null && cap > 0 && used !== null && used >= 0 && used <= cap) return round2(percent(used / cap * 100));\n return percent(limit.percentage);\n};\nfunction zcode(raw, observedAt) {\n // Raw: the GLM quota endpoint's data block — { level, limits: [{ type, number, usage,\n // currentValue, remaining, percentage, nextResetTime(epoch ms), usageDetails }] }. Which windows\n // exist is plan-dependent (measured pro plan: 5h prompts + a tool/MCP allowance; no weekly row —\n // a `number: 7` window maps when a plan returns one, and nothing is invented when it doesn't).\n const limits = Array.isArray(raw?.limits) ? raw.limits : [];\n const level = typeof raw?.level === 'string' && raw.level ? raw.level : null;\n const out = base('zcode', limits.length ? 'subscription' : 'unknown', raw, observedAt);\n out.plan = level ? { id: level, label: level } : null;\n let tools = 0;\n limits.forEach((limit, i) => {\n if (!limit || typeof limit !== 'object') return;\n const resetsAt = time(limit.nextResetTime, true);\n if (limit.type === 'TOKENS_LIMIT') {\n // GLM window convention: number 5 → the 5-hour prompt window, 7 → weekly.\n // Ids mirror the adapter's own /quota keys (token_5h / token_week).\n const seconds = limit.number === 5 ? 18000 : limit.number === 7 ? 604800 : null;\n const label = limit.number === 5 ? '5h' : limit.number === 7 ? 'Week' : `token ${limit.number ?? i}`;\n const id = limit.number === 5 ? 'zcode.token_5h' : limit.number === 7 ? 'zcode.token_week' : `zcode.token_${limit.number ?? i}`;\n out.limits.push({ id, label, kind: 'subscription', windowSeconds: seconds, key: windowKey(seconds), usedPercent: glmPercent(limit), resetsAt, status: 'unknown' });\n } else if (limit.type === 'TIME_LIMIT' || limit.type === 'MCP_LIMIT') {\n // Built-in tool/MCP allowance: absolute counters (unit 'calls'); per-model detail stays in _meta.\n const used = finite(limit.currentValue), total = finite(limit.usage), remaining = finite(limit.remaining);\n out.limits.push({ id: tools ? `zcode.mcp.${i}` : 'zcode.mcp', label: 'MCP', kind: 'subscription', windowSeconds: null, usedPercent: glmPercent(limit), ...(used !== null && total !== null ? { used: String(used), limit: String(total), unit: 'calls' } : {}), resetsAt, status: remaining === 0 ? 'blocked' : used !== null || limit.percentage != null ? 'allowed' : 'unknown' });\n tools++;\n }\n });\n return out;\n}\nfunction commandcode(raw, observedAt) {\n const subscription = raw.subscription?.data ?? raw.subscription;\n const windows = raw.credits?.windowLimits ?? raw.windowLimits;\n const subscribed = ['active','trialing','past_due'].includes(subscription?.status) || windows?.limited === true;\n const mode = subscribed ? 'subscription' : subscription || windows ? 'non_subscription' : 'unknown';\n const out = base('commandcode',mode,raw,observedAt);\n out.plan = subscription?.planId ? { id:subscription.planId,label:subscription.planId } : null;\n for (const [id, seconds] of [['fiveHour',18000],['weekly',604800]]) {\n const w=windows?.[id]; if (!w) continue;\n out.limits.push({ id:`commandcode.${id}`,label:id,kind:'subscription',windowSeconds:seconds,key:windowKey(seconds),usedPercent:w.cap > 0 ? percent(w.used / w.cap * 100) : null,used:String(w.used),limit:String(w.cap),unit:'credits',resetsAt:time(w.resetAt,true),status:w.exceeded === true ? 'blocked' : 'allowed' });\n }\n const credits=raw.credits?.credits ?? raw.credits;\n if (subscribed && credits?.monthlyCredits != null) {\n const cap=raw.monthly?.limit;\n const known=typeof cap==='number' && Number.isFinite(cap) && cap>0;\n const used=known ? Math.max(0,cap-credits.monthlyCredits) : null;\n out.limits.push({id:'commandcode.monthly',label:'Monthly',kind:'subscription',windowSeconds:null,period:'month',key:windowKey(null,'month'),usedPercent:known?percent(used/cap*100):null,resetsAt:time(subscription?.currentPeriodEnd,true),status:'unknown',...(known?{used:String(used),limit:String(cap),unit:'credits'}:{})});\n }\n for (const [id,label] of [['monthlyCredits','Monthly credits'],['purchasedCredits','Purchased credits'],['freeCredits','Free credits']]) if (credits?.[id] != null) out.balances.push({ id:`commandcode.${id}`,label,remaining:String(credits[id]),unit:'credits' });\n return out;\n}\n\nreturn {READ,UPDATED,CAPABILITY,codex,codexEvent,claude,claudeEvent,kimi,commandcode,zcode};\n})();\nconst axomQuotaNotify = snapshot => process.stdout.write(JSON.stringify({jsonrpc:\"2.0\",method:axomQuota.UPDATED,params:snapshot})+\"\\n\");\n/**\n * Entry point: wire the ZcodeAcpServer to a stdio ACP stream.\n *\n * The ACP"
|
|
29
28
|
}
|
|
30
29
|
]
|
|
31
30
|
}
|