@ken-jo/agent-connector 0.4.97 → 0.4.98
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 +1 -1
- package/dist/{action-IPFDPOZU.js → action-5JM23CFJ.js} +10 -10
- package/dist/action-5JM23CFJ.js.map +1 -0
- package/dist/{amazon-q-IT44LEWV.js → amazon-q-LFZNGN27.js} +3 -3
- package/dist/{amp-P35FRU2Z.js → amp-S22XTPEQ.js} +3 -3
- package/dist/{antigravity-TWIWXTQH.js → antigravity-PZXYAO3X.js} +4 -4
- package/dist/{antigravity-cli-MPE27LPI.js → antigravity-cli-PN474FXM.js} +4 -4
- package/dist/{audit-3E5JAOP2.js → audit-2H7E3Z4N.js} +5 -5
- package/dist/{chunk-L2C5UMKW.js → chunk-6XWORQM6.js} +4 -4
- package/dist/{chunk-FHYR5Q5T.js → chunk-7VSZXOXJ.js} +7 -7
- package/dist/{chunk-FHYR5Q5T.js.map → chunk-7VSZXOXJ.js.map} +1 -1
- package/dist/{chunk-GZZCHJDP.js → chunk-B6PKHS5I.js} +2 -2
- package/dist/{chunk-3EP5V2F4.js → chunk-DOPFBUCX.js} +2 -2
- package/dist/{chunk-GCPEPUD7.js → chunk-DWZ5IWF4.js} +3 -3
- package/dist/{chunk-XVEJAFKW.js → chunk-FJ6F5U3W.js} +3 -3
- package/dist/{chunk-N4ENLZEU.js → chunk-HATCOSQT.js} +19 -19
- package/dist/{chunk-WPTNMYYM.js → chunk-KTBAB556.js} +6 -6
- package/dist/{chunk-WPTNMYYM.js.map → chunk-KTBAB556.js.map} +1 -1
- package/dist/{chunk-7ZFK2WEO.js → chunk-KWC5DQ5Z.js} +2 -2
- package/dist/{chunk-TGZFDXNH.js → chunk-LD5HAN6O.js} +3 -3
- package/dist/{chunk-LQ55E7QI.js → chunk-LZL2YITN.js} +5 -5
- package/dist/{chunk-SLJI5BOM.js → chunk-RNVIK5YJ.js} +2 -2
- package/dist/{chunk-C63AAXK7.js → chunk-RPWD5H6Y.js} +3 -3
- package/dist/{chunk-MLU7NDAZ.js → chunk-S25MVWBP.js} +6 -6
- package/dist/chunk-S25MVWBP.js.map +1 -0
- package/dist/{chunk-NDMNMAKP.js → chunk-TOSNS2BY.js} +43 -43
- package/dist/{chunk-3FINQ2ZF.js → chunk-UNU2KPYJ.js} +9 -7
- package/dist/chunk-UNU2KPYJ.js.map +1 -0
- package/dist/{chunk-Y3K6KJMS.js → chunk-W7AGWAMH.js} +1 -1
- package/dist/chunk-W7AGWAMH.js.map +1 -0
- package/dist/{claude-code-QBWDT5RT.js → claude-code-TA53454O.js} +8 -8
- package/dist/claude-code-TA53454O.js.map +1 -0
- package/dist/cli/sdk.js +4 -4
- package/dist/cli.js +1 -1
- package/dist/{cline-JKEAYWVR.js → cline-GZFN32BM.js} +3 -3
- package/dist/{codebuddy-EB6EYPC3.js → codebuddy-IYS3TQZ3.js} +3 -3
- package/dist/{codebuff-5RSXFU6G.js → codebuff-D3MIKJHC.js} +3 -3
- package/dist/{codex-ART46CDD.js → codex-ZKLP5IXZ.js} +3 -3
- package/dist/{continue-JHZCMSPH.js → continue-I34FNSTJ.js} +3 -3
- package/dist/{copilot-cli-QVAU5CFM.js → copilot-cli-NWPM5GE6.js} +3 -3
- package/dist/{crush-7TORBYUL.js → crush-MDGPZSZU.js} +3 -3
- package/dist/{cursor-W7I4QUFO.js → cursor-JRVK56QA.js} +4 -4
- package/dist/{define-connector-DTWb46UB.d.ts → define-connector-B7tLHVnx.d.ts} +1 -1
- package/dist/{detect-JHSA3G3U.js → detect-FKJC36P4.js} +4 -4
- package/dist/{devin-SSR7S4WX.js → devin-TZMRC57O.js} +3 -3
- package/dist/{doctor-CQJ7TZPA.js → doctor-PGVYUQYG.js} +15 -15
- package/dist/{droid-45PJ7JGF.js → droid-SCFWDJR4.js} +3 -3
- package/dist/{gemini-cli-24PFDK7D.js → gemini-cli-MLDGOR2L.js} +3 -3
- package/dist/{goose-U5D3LCPC.js → goose-5DBHDSJW.js} +3 -3
- package/dist/{grok-cli-L2MHAPBY.js → grok-cli-LX6Q6RUY.js} +3 -3
- package/dist/{hermes-2S5JUTTJ.js → hermes-LJB3SJKB.js} +3 -3
- package/dist/{hook-VHICXHXL.js → hook-PVGBQUQI.js} +10 -10
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{install-WLENR4KF.js → install-HPDIK7F6.js} +12 -12
- package/dist/{introspect-dNekqPDY.d.ts → introspect-DWCu0Krk.d.ts} +1 -1
- package/dist/{jetbrains-copilot-Z4FC3RM3.js → jetbrains-copilot-2DSVAJMJ.js} +3 -3
- package/dist/{junie-ULGJJIHB.js → junie-GUBDRADP.js} +3 -3
- package/dist/{kilo-WWIJOVWD.js → kilo-HRLWMENX.js} +3 -3
- package/dist/{kilo-cli-QKE2EQLS.js → kilo-cli-IQMFMYZF.js} +3 -3
- package/dist/{kimi-JMUFTVSF.js → kimi-EPD46UJK.js} +3 -3
- package/dist/{kiro-UWUCRKR3.js → kiro-A7DL52FX.js} +3 -3
- package/dist/{leaderboard-NJWKGMXP.js → leaderboard-KCT7XPCI.js} +2 -2
- package/dist/{mimo-code-BPNYYIVM.js → mimo-code-NDGLBXNC.js} +3 -3
- package/dist/{mistral-vibe-LT3DAJ3L.js → mistral-vibe-LLWASF5X.js} +3 -3
- package/dist/{mux-AHNUAY5Z.js → mux-ON4QK3OC.js} +3 -3
- package/dist/{nemoclaw-RE5RZASZ.js → nemoclaw-45R5MFBF.js} +4 -4
- package/dist/{omp-D2EXEPH7.js → omp-ROCTFV3A.js} +3 -3
- package/dist/{open-interpreter-SSGBEUKX.js → open-interpreter-V6CN542J.js} +3 -3
- package/dist/{openclaw-IJ33K45M.js → openclaw-AOKFJGRQ.js} +4 -4
- package/dist/{opencode-YKUKZY3J.js → opencode-YYWQ45LF.js} +3 -3
- package/dist/{openhands-SEZMCUC3.js → openhands-OFFMWCQW.js} +3 -3
- package/dist/{package-JECVQEFT.js → package-TALOSRQ4.js} +9 -9
- package/dist/{pi-YPYV2ULH.js → pi-4W74ETTI.js} +3 -3
- package/dist/{qwen-code-ZHCLCYMC.js → qwen-code-JOBFNEVT.js} +10 -10
- package/dist/qwen-code-JOBFNEVT.js.map +1 -0
- package/dist/{roo-code-7F4HYB34.js → roo-code-RHIGJZNY.js} +3 -3
- package/dist/runtime/index.d.ts +9 -8
- package/dist/runtime/index.js +8 -8
- package/dist/sdk/index.d.ts +4 -4
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +6 -6
- package/dist/{serve-LYSBH43G.js → serve-4TEHK726.js} +10 -10
- package/dist/{status-PHKKGEW5.js → status-DVD4EHMX.js} +6 -6
- package/dist/{statusline-ZDD4OZ4F.js → statusline-ZVNH7XBK.js} +9 -9
- package/dist/{telemetry-HDGMI2BK.js → telemetry-NWUJPIK3.js} +5 -5
- package/dist/{trae-Y67HSDOW.js → trae-TLAFSQRQ.js} +3 -3
- package/dist/{types-JyhpJHJa.d.ts → types-C6j18a6R.d.ts} +13 -14
- package/dist/{uninstall-RWO2GM2I.js → uninstall-DZVFV7KE.js} +12 -12
- package/dist/{upgrade-YJCXNUEE.js → upgrade-OUE4ED52.js} +12 -12
- package/dist/{usage-IWO4RQN6.js → usage-NT3ZXALZ.js} +2 -2
- package/dist/{usage-event-AFFKCLHE.js → usage-event-IELZE6WO.js} +9 -9
- package/dist/{vscode-copilot-5CI5B3X6.js → vscode-copilot-VZ5XYSTK.js} +3 -3
- package/dist/{warp-INAKVGBV.js → warp-P2HWXIKT.js} +3 -3
- package/dist/{windsurf-4HM57QAY.js → windsurf-3JC73GZK.js} +3 -3
- package/dist/{zed-YN5X37PQ.js → zed-6CMUKXLI.js} +3 -3
- package/package.json +1 -1
- package/dist/action-IPFDPOZU.js.map +0 -1
- package/dist/chunk-3FINQ2ZF.js.map +0 -1
- package/dist/chunk-MLU7NDAZ.js.map +0 -1
- package/dist/chunk-Y3K6KJMS.js.map +0 -1
- package/dist/claude-code-QBWDT5RT.js.map +0 -1
- package/dist/qwen-code-ZHCLCYMC.js.map +0 -1
- /package/dist/{amazon-q-IT44LEWV.js.map → amazon-q-LFZNGN27.js.map} +0 -0
- /package/dist/{amp-P35FRU2Z.js.map → amp-S22XTPEQ.js.map} +0 -0
- /package/dist/{antigravity-TWIWXTQH.js.map → antigravity-PZXYAO3X.js.map} +0 -0
- /package/dist/{antigravity-cli-MPE27LPI.js.map → antigravity-cli-PN474FXM.js.map} +0 -0
- /package/dist/{audit-3E5JAOP2.js.map → audit-2H7E3Z4N.js.map} +0 -0
- /package/dist/{chunk-L2C5UMKW.js.map → chunk-6XWORQM6.js.map} +0 -0
- /package/dist/{chunk-GZZCHJDP.js.map → chunk-B6PKHS5I.js.map} +0 -0
- /package/dist/{chunk-3EP5V2F4.js.map → chunk-DOPFBUCX.js.map} +0 -0
- /package/dist/{chunk-GCPEPUD7.js.map → chunk-DWZ5IWF4.js.map} +0 -0
- /package/dist/{chunk-XVEJAFKW.js.map → chunk-FJ6F5U3W.js.map} +0 -0
- /package/dist/{chunk-N4ENLZEU.js.map → chunk-HATCOSQT.js.map} +0 -0
- /package/dist/{chunk-7ZFK2WEO.js.map → chunk-KWC5DQ5Z.js.map} +0 -0
- /package/dist/{chunk-TGZFDXNH.js.map → chunk-LD5HAN6O.js.map} +0 -0
- /package/dist/{chunk-LQ55E7QI.js.map → chunk-LZL2YITN.js.map} +0 -0
- /package/dist/{chunk-SLJI5BOM.js.map → chunk-RNVIK5YJ.js.map} +0 -0
- /package/dist/{chunk-C63AAXK7.js.map → chunk-RPWD5H6Y.js.map} +0 -0
- /package/dist/{chunk-NDMNMAKP.js.map → chunk-TOSNS2BY.js.map} +0 -0
- /package/dist/{cline-JKEAYWVR.js.map → cline-GZFN32BM.js.map} +0 -0
- /package/dist/{codebuddy-EB6EYPC3.js.map → codebuddy-IYS3TQZ3.js.map} +0 -0
- /package/dist/{codebuff-5RSXFU6G.js.map → codebuff-D3MIKJHC.js.map} +0 -0
- /package/dist/{codex-ART46CDD.js.map → codex-ZKLP5IXZ.js.map} +0 -0
- /package/dist/{continue-JHZCMSPH.js.map → continue-I34FNSTJ.js.map} +0 -0
- /package/dist/{copilot-cli-QVAU5CFM.js.map → copilot-cli-NWPM5GE6.js.map} +0 -0
- /package/dist/{crush-7TORBYUL.js.map → crush-MDGPZSZU.js.map} +0 -0
- /package/dist/{cursor-W7I4QUFO.js.map → cursor-JRVK56QA.js.map} +0 -0
- /package/dist/{detect-JHSA3G3U.js.map → detect-FKJC36P4.js.map} +0 -0
- /package/dist/{devin-SSR7S4WX.js.map → devin-TZMRC57O.js.map} +0 -0
- /package/dist/{doctor-CQJ7TZPA.js.map → doctor-PGVYUQYG.js.map} +0 -0
- /package/dist/{droid-45PJ7JGF.js.map → droid-SCFWDJR4.js.map} +0 -0
- /package/dist/{gemini-cli-24PFDK7D.js.map → gemini-cli-MLDGOR2L.js.map} +0 -0
- /package/dist/{goose-U5D3LCPC.js.map → goose-5DBHDSJW.js.map} +0 -0
- /package/dist/{grok-cli-L2MHAPBY.js.map → grok-cli-LX6Q6RUY.js.map} +0 -0
- /package/dist/{hermes-2S5JUTTJ.js.map → hermes-LJB3SJKB.js.map} +0 -0
- /package/dist/{hook-VHICXHXL.js.map → hook-PVGBQUQI.js.map} +0 -0
- /package/dist/{install-WLENR4KF.js.map → install-HPDIK7F6.js.map} +0 -0
- /package/dist/{jetbrains-copilot-Z4FC3RM3.js.map → jetbrains-copilot-2DSVAJMJ.js.map} +0 -0
- /package/dist/{junie-ULGJJIHB.js.map → junie-GUBDRADP.js.map} +0 -0
- /package/dist/{kilo-WWIJOVWD.js.map → kilo-HRLWMENX.js.map} +0 -0
- /package/dist/{kilo-cli-QKE2EQLS.js.map → kilo-cli-IQMFMYZF.js.map} +0 -0
- /package/dist/{kimi-JMUFTVSF.js.map → kimi-EPD46UJK.js.map} +0 -0
- /package/dist/{kiro-UWUCRKR3.js.map → kiro-A7DL52FX.js.map} +0 -0
- /package/dist/{leaderboard-NJWKGMXP.js.map → leaderboard-KCT7XPCI.js.map} +0 -0
- /package/dist/{mimo-code-BPNYYIVM.js.map → mimo-code-NDGLBXNC.js.map} +0 -0
- /package/dist/{mistral-vibe-LT3DAJ3L.js.map → mistral-vibe-LLWASF5X.js.map} +0 -0
- /package/dist/{mux-AHNUAY5Z.js.map → mux-ON4QK3OC.js.map} +0 -0
- /package/dist/{nemoclaw-RE5RZASZ.js.map → nemoclaw-45R5MFBF.js.map} +0 -0
- /package/dist/{omp-D2EXEPH7.js.map → omp-ROCTFV3A.js.map} +0 -0
- /package/dist/{open-interpreter-SSGBEUKX.js.map → open-interpreter-V6CN542J.js.map} +0 -0
- /package/dist/{openclaw-IJ33K45M.js.map → openclaw-AOKFJGRQ.js.map} +0 -0
- /package/dist/{opencode-YKUKZY3J.js.map → opencode-YYWQ45LF.js.map} +0 -0
- /package/dist/{openhands-SEZMCUC3.js.map → openhands-OFFMWCQW.js.map} +0 -0
- /package/dist/{package-JECVQEFT.js.map → package-TALOSRQ4.js.map} +0 -0
- /package/dist/{pi-YPYV2ULH.js.map → pi-4W74ETTI.js.map} +0 -0
- /package/dist/{roo-code-7F4HYB34.js.map → roo-code-RHIGJZNY.js.map} +0 -0
- /package/dist/{serve-LYSBH43G.js.map → serve-4TEHK726.js.map} +0 -0
- /package/dist/{status-PHKKGEW5.js.map → status-DVD4EHMX.js.map} +0 -0
- /package/dist/{statusline-ZDD4OZ4F.js.map → statusline-ZVNH7XBK.js.map} +0 -0
- /package/dist/{telemetry-HDGMI2BK.js.map → telemetry-NWUJPIK3.js.map} +0 -0
- /package/dist/{trae-Y67HSDOW.js.map → trae-TLAFSQRQ.js.map} +0 -0
- /package/dist/{uninstall-RWO2GM2I.js.map → uninstall-DZVFV7KE.js.map} +0 -0
- /package/dist/{upgrade-YJCXNUEE.js.map → upgrade-OUE4ED52.js.map} +0 -0
- /package/dist/{usage-IWO4RQN6.js.map → usage-NT3ZXALZ.js.map} +0 -0
- /package/dist/{usage-event-AFFKCLHE.js.map → usage-event-IELZE6WO.js.map} +0 -0
- /package/dist/{vscode-copilot-5CI5B3X6.js.map → vscode-copilot-VZ5XYSTK.js.map} +0 -0
- /package/dist/{warp-INAKVGBV.js.map → warp-P2HWXIKT.js.map} +0 -0
- /package/dist/{windsurf-4HM57QAY.js.map → windsurf-3JC73GZK.js.map} +0 -0
- /package/dist/{zed-YN5X37PQ.js.map → zed-6CMUKXLI.js.map} +0 -0
package/README.md
CHANGED
|
@@ -75,7 +75,7 @@ npm install @ken-jo/agent-connector
|
|
|
75
75
|
"name": "@acme/acme-db-mcp",
|
|
76
76
|
"mcpName": "io.github.acme/acme-db",
|
|
77
77
|
"bin": { "acme-db": "./bin.mjs" },
|
|
78
|
-
"dependencies": { "@ken-jo/agent-connector": "^0.4.
|
|
78
|
+
"dependencies": { "@ken-jo/agent-connector": "^0.4.98" }
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
fail
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HATCOSQT.js";
|
|
5
5
|
import {
|
|
6
6
|
runAction
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7VSZXOXJ.js";
|
|
8
8
|
import "./chunk-LFWYYWLV.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-RNVIK5YJ.js";
|
|
10
|
+
import "./chunk-B6PKHS5I.js";
|
|
11
|
+
import "./chunk-DWZ5IWF4.js";
|
|
12
12
|
import "./chunk-IOJDZJ72.js";
|
|
13
13
|
import "./chunk-4GH2KA7V.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-DOPFBUCX.js";
|
|
15
|
+
import "./chunk-KWC5DQ5Z.js";
|
|
16
|
+
import "./chunk-TOSNS2BY.js";
|
|
17
17
|
import "./chunk-KFPSJRHR.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-W7AGWAMH.js";
|
|
19
19
|
import "./chunk-ILWHLGIC.js";
|
|
20
20
|
import "./chunk-QYOUQCC6.js";
|
|
21
21
|
|
|
@@ -52,4 +52,4 @@ async function run(argv) {
|
|
|
52
52
|
export {
|
|
53
53
|
run
|
|
54
54
|
};
|
|
55
|
-
//# sourceMappingURL=action-
|
|
55
|
+
//# sourceMappingURL=action-5JM23CFJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/action.ts"],"sourcesContent":["/**\r\n * cli/commands/action — the universal user-invokable action entrypoint.\r\n *\r\n * agent-connector action <platform> <actionId> --connector <id>\r\n *\r\n * A host-native affordance or a manual command points at the single stable home\n * binary (via core/spawn.buildHomeBinActionCommand). This command parses the\n * positionals + --connector, dispatches through runAction, writes any\n * stdout/stderr the action produced, and exits with its code. It reads NO stdin\n * (an action takes no host payload, unlike a hook or status line).\n *\r\n * USER-TRIGGERED is the runtime's contract: unlike the fail-open hook command,\r\n * an unknown action id or a throwing run surfaces as exit 1 + a stderr message —\r\n * the user invoked it deliberately, so the failure is shown, never swallowed.\r\n */\r\n\r\nimport { parseArgs } from \"node:util\";\r\n\r\nimport { runAction } from \"../../runtime/index.js\";\r\nimport { fail } from \"../app.js\";\r\n\r\nexport async function run(argv: string[]): Promise<number> {\r\n const { values, positionals } = parseArgs({\r\n args: argv,\r\n options: {\r\n connector: { type: \"string\" },\r\n },\r\n allowPositionals: true,\r\n });\r\n\r\n const platformId = positionals[0];\r\n const actionId = positionals[1];\r\n if (!platformId || !actionId) {\r\n return fail(\"usage: agent-connector action <platform> <actionId> --connector <id>\");\r\n }\r\n const connectorId = values.connector;\r\n if (!connectorId || connectorId.trim() === \"\") {\r\n return fail(\"action requires --connector <id>\");\r\n }\r\n\r\n const reply = await runAction({ platformId, actionId, connectorId });\r\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\r\n process.stdout.write(reply.stdout.endsWith(\"\\n\") ? reply.stdout : `${reply.stdout}\\n`);\r\n }\r\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\r\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\r\n }\r\n process.exit(reply.exitCode);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAS,iBAAiB;AAK1B,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAM;AAAA,IACN,SAAS;AAAA,MACP,WAAW,EAAE,MAAM,SAAS;AAAA,IAC9B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,YAAY,CAAC;AAChC,QAAM,WAAW,YAAY,CAAC;AAC9B,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,WAAO,KAAK,sEAAsE;AAAA,EACpF;AACA,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,eAAe,YAAY,KAAK,MAAM,IAAI;AAC7C,WAAO,KAAK,kCAAkC;AAAA,EAChD;AAEA,QAAM,QAAQ,MAAM,UAAU,EAAE,YAAY,UAAU,YAAY,CAAC;AACnE,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,UAAQ,KAAK,MAAM,QAAQ;AAC7B;","names":[]}
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-XXLCMSD3.js";
|
|
5
5
|
import {
|
|
6
6
|
BaseAdapter
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-UNU2KPYJ.js";
|
|
8
8
|
import {
|
|
9
9
|
buildWrappedStdio,
|
|
10
10
|
isHomeBinHookCommand
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-W7AGWAMH.js";
|
|
12
12
|
import "./chunk-ILWHLGIC.js";
|
|
13
13
|
import "./chunk-QYOUQCC6.js";
|
|
14
14
|
|
|
@@ -563,4 +563,4 @@ export {
|
|
|
563
563
|
adapter,
|
|
564
564
|
amazon_q_default as default
|
|
565
565
|
};
|
|
566
|
-
//# sourceMappingURL=amazon-q-
|
|
566
|
+
//# sourceMappingURL=amazon-q-LFZNGN27.js.map
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
BaseAdapter,
|
|
10
10
|
renderSkillMd
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-UNU2KPYJ.js";
|
|
12
12
|
import {
|
|
13
13
|
buildWrappedStdio
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-W7AGWAMH.js";
|
|
15
15
|
import "./chunk-ILWHLGIC.js";
|
|
16
16
|
import "./chunk-QYOUQCC6.js";
|
|
17
17
|
|
|
@@ -608,4 +608,4 @@ export {
|
|
|
608
608
|
adapter,
|
|
609
609
|
amp_default as default
|
|
610
610
|
};
|
|
611
|
-
//# sourceMappingURL=amp-
|
|
611
|
+
//# sourceMappingURL=amp-S22XTPEQ.js.map
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
AntigravityAdapter,
|
|
4
4
|
adapter,
|
|
5
5
|
antigravity_default
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RPWD5H6Y.js";
|
|
7
7
|
import "./chunk-PSGTHJQU.js";
|
|
8
8
|
import "./chunk-XXLCMSD3.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-UNU2KPYJ.js";
|
|
10
|
+
import "./chunk-W7AGWAMH.js";
|
|
11
11
|
import "./chunk-ILWHLGIC.js";
|
|
12
12
|
import "./chunk-QYOUQCC6.js";
|
|
13
13
|
export {
|
|
@@ -15,4 +15,4 @@ export {
|
|
|
15
15
|
adapter,
|
|
16
16
|
antigravity_default as default
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=antigravity-
|
|
18
|
+
//# sourceMappingURL=antigravity-PZXYAO3X.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AntigravityAdapter,
|
|
4
4
|
adapter
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RPWD5H6Y.js";
|
|
6
6
|
import {
|
|
7
7
|
addLedgerOwner,
|
|
8
8
|
createLedgerEntry,
|
|
@@ -18,11 +18,11 @@ import {
|
|
|
18
18
|
} from "./chunk-KFPSJRHR.js";
|
|
19
19
|
import "./chunk-PSGTHJQU.js";
|
|
20
20
|
import "./chunk-XXLCMSD3.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-UNU2KPYJ.js";
|
|
22
22
|
import {
|
|
23
23
|
buildHomeBinStatuslineCommand,
|
|
24
24
|
isHomeBinStatuslineCommand
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-W7AGWAMH.js";
|
|
26
26
|
import "./chunk-ILWHLGIC.js";
|
|
27
27
|
import "./chunk-QYOUQCC6.js";
|
|
28
28
|
|
|
@@ -464,4 +464,4 @@ export {
|
|
|
464
464
|
adapter2 as adapter,
|
|
465
465
|
antigravity_cli_default as default
|
|
466
466
|
};
|
|
467
|
-
//# sourceMappingURL=antigravity-cli-
|
|
467
|
+
//# sourceMappingURL=antigravity-cli-PN474FXM.js.map
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fail,
|
|
4
4
|
print
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HATCOSQT.js";
|
|
6
6
|
import {
|
|
7
7
|
findConnectorConfig,
|
|
8
8
|
loadConnectorFromPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DOPFBUCX.js";
|
|
10
10
|
import {
|
|
11
11
|
deriveHostAliasFromMcpName,
|
|
12
12
|
deriveHostAliasFromPackageName,
|
|
13
13
|
findNearestPackageJson,
|
|
14
14
|
readConnectorPackageMetadataFromPackageJson
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-KWC5DQ5Z.js";
|
|
16
|
+
import "./chunk-TOSNS2BY.js";
|
|
17
17
|
import "./chunk-KFPSJRHR.js";
|
|
18
18
|
import "./chunk-ILWHLGIC.js";
|
|
19
19
|
import "./chunk-QYOUQCC6.js";
|
|
@@ -308,4 +308,4 @@ async function run(argv) {
|
|
|
308
308
|
export {
|
|
309
309
|
run
|
|
310
310
|
};
|
|
311
|
-
//# sourceMappingURL=audit-
|
|
311
|
+
//# sourceMappingURL=audit-2H7E3Z4N.js.map
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileMatcher,
|
|
4
4
|
eventMatcherSubject
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DWZ5IWF4.js";
|
|
6
6
|
import {
|
|
7
7
|
SURFACE_PREDICATES,
|
|
8
8
|
hostCanFireEvent
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KTBAB556.js";
|
|
10
10
|
import {
|
|
11
11
|
allAdapters,
|
|
12
12
|
loadAdapter
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-TOSNS2BY.js";
|
|
14
14
|
|
|
15
15
|
// src/sdk/test-harness.ts
|
|
16
16
|
function declaredGlobalSurfaces(connector) {
|
|
@@ -383,4 +383,4 @@ export {
|
|
|
383
383
|
simulate,
|
|
384
384
|
explainHooks
|
|
385
385
|
};
|
|
386
|
-
//# sourceMappingURL=chunk-
|
|
386
|
+
//# sourceMappingURL=chunk-6XWORQM6.js.map
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
} from "./chunk-LFWYYWLV.js";
|
|
7
7
|
import {
|
|
8
8
|
spawnChild
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RNVIK5YJ.js";
|
|
10
10
|
import {
|
|
11
11
|
detectRuntimeHost
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-B6PKHS5I.js";
|
|
13
13
|
import {
|
|
14
14
|
attachLazyTelemetryUsage,
|
|
15
15
|
buildTelemetryAccessor,
|
|
16
16
|
measureToolCall,
|
|
17
17
|
measureToolDefs
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-DWZ5IWF4.js";
|
|
19
19
|
import {
|
|
20
20
|
getTokenizer,
|
|
21
21
|
inferModelFamily,
|
|
@@ -28,14 +28,14 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
loadRegisteredConnector,
|
|
30
30
|
readRegisteredMeta
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-DOPFBUCX.js";
|
|
32
32
|
import {
|
|
33
33
|
REGISTERED_PLATFORM_IDS,
|
|
34
34
|
loadAdapter
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TOSNS2BY.js";
|
|
36
36
|
import {
|
|
37
37
|
detectLaunchMethod
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-W7AGWAMH.js";
|
|
39
39
|
import {
|
|
40
40
|
dataRoot,
|
|
41
41
|
ensureDir,
|
|
@@ -706,4 +706,4 @@ export {
|
|
|
706
706
|
runStatusline,
|
|
707
707
|
runAction
|
|
708
708
|
};
|
|
709
|
-
//# sourceMappingURL=chunk-
|
|
709
|
+
//# sourceMappingURL=chunk-7VSZXOXJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/serve.ts","../src/telemetry/calibration.ts","../src/telemetry/proxy.ts","../src/runtime/usage-event.ts","../src/runtime/statusline-entrypoint.ts","../src/runtime/action-entrypoint.ts"],"sourcesContent":["/**\r\n * runtime/serve — the `agent-connector serve` telemetry-wrapping entrypoint.\r\n *\r\n * When a stdio MCP server opts into transparent telemetry, its host config is\r\n * rewritten (by the adapter, via core/spawn.buildServeWrapperCommand) to launch\r\n * <homeBin> serve --connector <id> -- <realCommand> <realArgs...>\r\n * instead of the server directly. The CLI parses those flags and calls\r\n * {@link runServe}, which stands up the per-session telemetry context (store,\r\n * tokenizer, project identity, host detection) and hands off to the proxy.\r\n *\r\n * The proxy (telemetry/proxy.runServeProxy) forwards bytes VERBATIM in both\r\n * directions and measures aggregate per-tool token counts out of band, so this\r\n * wrapper is transparent to both the host and the real server. It resolves with\r\n * the child server's exit code, which the CLI uses as its own.\r\n */\r\n\r\nimport { randomUUID } from \"node:crypto\";\r\n\r\nimport { detectRuntimeHost } from \"../adapters/detect.js\";\r\nimport { REGISTERED_PLATFORM_IDS } from \"../adapters/registry.js\";\r\nimport { readRegisteredMeta } from \"../core/load-connector.js\";\r\nimport { projectIdentity } from \"../core/paths.js\";\r\nimport { detectLaunchMethod } from \"../core/spawn.js\";\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { runServeProxy } from \"../telemetry/proxy.js\";\r\nimport { openStore } from \"../telemetry/store.js\";\r\nimport { getTokenizer } from \"../telemetry/tokenizer.js\";\r\nimport type { TelemetryInstallScope } from \"../telemetry/types.js\";\r\n\r\n/** Flags the CLI hands to {@link runServe}. */\r\nexport interface RunServeOptions {\r\n /** Connector id from `--connector <id>`; selects telemetry config + stamps records. */\r\n connectorId: string;\r\n /** The real MCP server executable to spawn (everything after `--`). */\r\n serverCommand: string;\r\n /** Arguments passed to that executable. */\r\n serverArgs: string[];\r\n /**\r\n * Install scope from `--scope <user|project>`. OPTIONAL: absent for configs\r\n * written before scope plumbing existed — left unstamped so older rows read\r\n * as \"unknown\". Stamped verbatim onto every telemetry record when present.\r\n */\r\n installScope?: TelemetryInstallScope;\r\n /**\r\n * Install TARGET platform id from `--host <platformId>` (baked into the\r\n * wrapper at install time). OPTIONAL: when a recognized platform id, it\r\n * OVERRIDES runtime env detection so headless spawns stamp hostPlatform\r\n * correctly (detectRuntimeHost only knows env markers for a few hosts and\r\n * otherwise mis-attributes). Absent/unrecognized → fall back to detection.\r\n */\r\n hostPlatformOverride?: PlatformId;\r\n /**\r\n * Framework data-root from `--data-dir <path>` (baked into the wrapper at\r\n * install time, only for a NON-DEFAULT root). OPTIONAL: when present, it pins\r\n * the data-root the WHOLE child resolves — connector record lookup AND the\r\n * telemetry store — by populating AGENT_CONNECTOR_DATA_DIR before anything\r\n * reads it. This is the env-independent path for hosts (codex) that strip the\r\n * MCP child's environment and would otherwise drop the override, leaving the\r\n * child to resolve the default `~/.agent-connector` and fail \"not registered\".\r\n * Absent → resolve the data-root the usual way (env or default).\r\n */\r\n dataDir?: string;\r\n}\r\n\r\n/**\r\n * Launch the developer's real MCP server under the telemetry-wrapping proxy.\r\n *\r\n * Resolves with the child server's exit code (propagated as this process's exit\r\n * code by the CLI). The session id comes from AGENT_CONNECTOR_SESSION when the\r\n * host sets it (empty otherwise); the host platform is detected from runtime env\r\n * markers; the project identity partitions telemetry by the stable project key.\r\n */\r\n/**\r\n * Resolve a session id for telemetry attribution. Prefers a host-provided\r\n * session/thread marker (so records from the same host session group together);\r\n * falls back to a per-process UUID — each `serve` invocation is one server\r\n * session, a sensible default granularity — so `--by session` rollups are never\r\n * collapsed into a single empty-keyed group.\r\n */\r\nfunction resolveSessionId(env: NodeJS.ProcessEnv = process.env): string {\r\n return (\r\n env.AGENT_CONNECTOR_SESSION ||\r\n env.CLAUDE_SESSION_ID ||\r\n env.CODEX_THREAD_ID ||\r\n env.CURSOR_TRACE_ID ||\r\n env.MCP_SESSION_ID ||\r\n `proc-${randomUUID()}`\r\n );\r\n}\r\n\r\nexport async function runServe(opts: RunServeOptions): Promise<number> {\r\n const {\r\n connectorId,\r\n serverCommand,\r\n serverArgs,\r\n installScope,\r\n hostPlatformOverride,\r\n dataDir,\r\n } = opts;\r\n\r\n // Pin the data-root BEFORE anything resolves it (the connector record lookup\r\n // below and openStore later both read dataRoot()). The wrapper passes\r\n // --data-dir only for a non-default root on a host that may strip the child\r\n // env (codex) — populating AGENT_CONNECTOR_DATA_DIR here makes the whole child\r\n // resolve that root regardless of whether the host propagated the env var.\r\n if (dataDir !== undefined && dataDir.trim() !== \"\") {\r\n process.env.AGENT_CONNECTOR_DATA_DIR = dataDir;\r\n }\r\n\r\n const connector = readRegisteredMeta(connectorId);\r\n if (!connector) {\r\n throw new Error(\r\n `Connector \"${connectorId}\" is not registered. Run an install/register step first.`,\r\n );\r\n }\r\n\r\n const id = projectIdentity(process.cwd());\r\n // Prefer the install TARGET platform baked into the wrapper (--host), but only\r\n // when it is a KNOWN registered platform id — a bad/unknown value falls back to\r\n // runtime env detection so a config typo can never poison hostPlatform.\r\n const hostPlatform: PlatformId =\r\n hostPlatformOverride !== undefined &&\r\n REGISTERED_PLATFORM_IDS.has(hostPlatformOverride)\r\n ? hostPlatformOverride\r\n : detectRuntimeHost().platform;\r\n const sessionId = resolveSessionId();\r\n\r\n // `serve` only ever wraps a locally-spawned stdio server (a remote/http server\r\n // is never launched through the proxy), so isRemote is always false here.\r\n const launchMethod = detectLaunchMethod(serverCommand, serverArgs);\r\n\r\n const store = openStore({});\r\n const tok = getTokenizer();\r\n\r\n return runServeProxy({\r\n connectorId,\r\n command: serverCommand,\r\n args: serverArgs,\r\n store,\r\n tokenizer: tok,\r\n modelFamilyHint: connector.telemetry.modelFamilyHint,\r\n hostPlatform,\r\n sessionId,\r\n projectKey: id.key,\r\n projectDir: id.dir,\r\n measureToolDefs: connector.telemetry.measureToolDefs,\r\n installScope,\r\n launchMethod,\r\n });\r\n}\r\n","/**\r\n * telemetry/calibration — OPT-IN Anthropic count_tokens calibration.\r\n *\r\n * The default tokenizer counts every family with the OpenAI o200k_base BPE, so\r\n * an Anthropic session's counts are an honest-but-approximate stand-in\r\n * (\"tokenizer-approx\"). This module lets a developer OPT IN to calibrating that\r\n * approximation against Anthropic's real `count_tokens` endpoint: we sample a\r\n * tiny fraction of tool calls off-box, learn a per-family correction factor\r\n * (rolling mean of exact/approx), and apply it to the locally-tokenized counts\r\n * so they land much closer to the host's real numbers — labeled honestly as\r\n * \"tokenizer-calibrated\".\r\n *\r\n * PRIVACY + SAFETY — load-bearing invariants:\r\n * • OPT-IN only. Nothing here runs unless BOTH AGENT_CONNECTOR_CALIBRATE\r\n * contains \"anthropic\" AND ANTHROPIC_API_KEY is set (see isCalibrationEnabled).\r\n * • Sampling only — shouldSample() rate-limits hard so we never hammer the API.\r\n * • Content leaves the box ONLY on a sampled call, ONLY when opted in. We store\r\n * a single scalar factor + sample count — NEVER the sampled text itself.\r\n * • Fail-open everywhere: a network/parse/IO error returns null / passes the\r\n * approximation through unchanged and NEVER throws into a tool call or hook.\r\n *\r\n * No new dependencies: uses Node's global fetch (Node >= 18) and node:fs.\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nimport { dataRoot, ensureDir } from \"../core/paths.js\";\r\nimport type { ConfidenceSource, ModelFamily } from \"./types.js\";\r\n\r\n// ── Env switches ──────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Is opt-in Anthropic calibration enabled for this process?\r\n *\r\n * Requires BOTH:\r\n * • AGENT_CONNECTOR_CALIBRATE — a comma-separated allowlist that INCLUDES\r\n * `anthropic` (so a future `AGENT_CONNECTOR_CALIBRATE=openai,anthropic` can\r\n * opt other families in without touching this gate), and\r\n * • ANTHROPIC_API_KEY — a non-empty key to authenticate the off-box call.\r\n *\r\n * Either missing → disabled (the privacy-safe default).\r\n */\r\nexport function isCalibrationEnabled(): boolean {\r\n const families = (process.env.AGENT_CONNECTOR_CALIBRATE || \"\")\r\n .split(\",\")\r\n .map((s) => s.trim())\r\n .filter((s) => s !== \"\");\r\n const key = (process.env.ANTHROPIC_API_KEY || \"\").trim();\r\n return families.includes(\"anthropic\") && key !== \"\";\r\n}\r\n\r\n// ── Factor store (dataRoot/calibration.json) ────────────────────────────────\r\n\r\n/** One learned correction factor for a model family: factor + sample count. */\r\nexport interface CalibrationFactor {\r\n /** Multiply an approx count by this to estimate the real count. */\r\n factor: number;\r\n /** How many samples have folded into the rolling mean. */\r\n samples: number;\r\n}\r\n\r\n/** The on-disk factor map, keyed by model family. */\r\nexport type CalibrationFactors = Partial<Record<ModelFamily, CalibrationFactor>>;\r\n\r\n/** Path to the learned-factor store: dataRoot()/calibration.json. */\r\nexport function calibrationPath(): string {\r\n return join(dataRoot(), \"calibration.json\");\r\n}\r\n\r\n/**\r\n * Clamp a measured exact/approx ratio into a sane range. A pathological sample\r\n * (e.g. an empty-string approx of 0 → Infinity, or a parse glitch) must never\r\n * poison the rolling mean, so ratios are pinned to [0.2, 5].\r\n */\r\nconst RATIO_MIN = 0.2;\r\nconst RATIO_MAX = 5;\r\n\r\nfunction clampRatio(ratio: number): number | null {\r\n if (!Number.isFinite(ratio) || ratio <= 0) return null;\r\n if (ratio < RATIO_MIN) return RATIO_MIN;\r\n if (ratio > RATIO_MAX) return RATIO_MAX;\r\n return ratio;\r\n}\r\n\r\n/**\r\n * Load the learned factors from disk. Fail-open: a missing/unreadable/malformed\r\n * file returns an empty map rather than throwing.\r\n */\r\nexport function loadFactors(): CalibrationFactors {\r\n const path = calibrationPath();\r\n if (!existsSync(path)) return {};\r\n try {\r\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\r\n if (parsed === null || typeof parsed !== \"object\") return {};\r\n const out: CalibrationFactors = {};\r\n for (const [family, value] of Object.entries(parsed as Record<string, unknown>)) {\r\n if (value === null || typeof value !== \"object\") continue;\r\n const rec = value as Record<string, unknown>;\r\n const factor = rec[\"factor\"];\r\n const samples = rec[\"samples\"];\r\n if (\r\n typeof factor === \"number\" &&\r\n Number.isFinite(factor) &&\r\n factor > 0 &&\r\n typeof samples === \"number\" &&\r\n Number.isFinite(samples) &&\r\n samples >= 0\r\n ) {\r\n (out as Record<string, CalibrationFactor>)[family] = {\r\n factor,\r\n samples,\r\n };\r\n }\r\n }\r\n return out;\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Fold one observed exact/approx `ratio` into the rolling mean for `family` and\r\n * persist it. A running average converges to the true mean while staying cheap\r\n * and stateless across processes (each writer reads the prior count, blends in\r\n * the new sample, writes back). Fail-open: any read/write/clamp problem leaves\r\n * the store untouched and never throws.\r\n */\r\nexport function recordSample(family: ModelFamily, ratio: number): void {\r\n const clamped = clampRatio(ratio);\r\n if (clamped === null) return;\r\n try {\r\n const factors = loadFactors();\r\n const prior = factors[family];\r\n let next: CalibrationFactor;\r\n if (prior === undefined || prior.samples <= 0) {\r\n next = { factor: clamped, samples: 1 };\r\n } else {\r\n const samples = prior.samples + 1;\r\n // Running average: new mean = old mean + (sample - old mean) / n.\r\n const factor = prior.factor + (clamped - prior.factor) / samples;\r\n next = { factor, samples };\r\n }\r\n const updated: CalibrationFactors = { ...factors, [family]: next };\r\n const path = calibrationPath();\r\n ensureDir(dataRoot());\r\n writeFileSync(path, `${JSON.stringify(updated, null, 2)}\\n`, \"utf8\");\r\n } catch {\r\n /* fail-open: a calibration write must never break a tool call */\r\n }\r\n}\r\n\r\n// ── Anthropic count_tokens (off-box, sampled, fail-open) ─────────────────────\r\n\r\n/** Default model used for count_tokens when no family→model map applies. */\r\nconst DEFAULT_ANTHROPIC_MODEL = \"claude-3-5-sonnet-latest\";\r\n\r\n/** Anthropic count_tokens endpoint. */\r\nconst COUNT_TOKENS_URL = \"https://api.anthropic.com/v1/messages/count_tokens\";\r\n\r\n/** The single field we read out of a successful response. */\r\ninterface CountTokensResponse {\r\n input_tokens?: unknown;\r\n}\r\n\r\n/**\r\n * Ask Anthropic's `count_tokens` endpoint for the exact token count of `text`\r\n * under `model`. Returns the integer count, or `null` on ANY failure (no key,\r\n * non-200, network error, unparseable body) — fail-open by contract.\r\n *\r\n * Only ever called on a SAMPLED tool call when calibration is opted in, so the\r\n * sampled text leaves the box only under explicit operator consent.\r\n */\r\nexport async function countTokensAnthropic(\r\n text: string,\r\n model: string = DEFAULT_ANTHROPIC_MODEL,\r\n): Promise<number | null> {\r\n const apiKey = (process.env.ANTHROPIC_API_KEY || \"\").trim();\r\n if (apiKey === \"\") return null;\r\n try {\r\n const res = await fetch(COUNT_TOKENS_URL, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-api-key\": apiKey,\r\n \"anthropic-version\": \"2023-06-01\",\r\n \"content-type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n model,\r\n messages: [{ role: \"user\", content: text }],\r\n }),\r\n });\r\n if (!res.ok) return null;\r\n const body = (await res.json()) as CountTokensResponse;\r\n const n = body.input_tokens;\r\n if (typeof n === \"number\" && Number.isFinite(n) && n >= 0) {\r\n return n;\r\n }\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n// ── Sampling (rate-limit so we never hammer the API) ─────────────────────────\r\n\r\n/**\r\n * Sample roughly 1 in {@link SAMPLE_EVERY} calls, with a hard per-minute cap so\r\n * a burst of tool calls can never fan out into a burst of API calls. Both\r\n * counters are in-memory (per process) — calibration is a best-effort,\r\n * low-volume background signal, not a per-call requirement.\r\n */\r\nconst SAMPLE_EVERY = 20;\r\nconst MAX_SAMPLES_PER_MINUTE = 10;\r\n\r\nlet callCounter = 0;\r\nlet windowStartMs = 0;\r\nlet samplesThisWindow = 0;\r\n\r\n/**\r\n * Should THIS call fire an off-box count_tokens sample? Combines a 1-in-N\r\n * counter with a rolling per-minute cap. Pure in-memory bookkeeping; never\r\n * throws, never blocks.\r\n */\r\nexport function shouldSample(now: number = Date.now()): boolean {\r\n // Roll the per-minute window.\r\n if (now - windowStartMs >= 60_000) {\r\n windowStartMs = now;\r\n samplesThisWindow = 0;\r\n }\r\n callCounter += 1;\r\n if (callCounter % SAMPLE_EVERY !== 0) return false;\r\n if (samplesThisWindow >= MAX_SAMPLES_PER_MINUTE) return false;\r\n samplesThisWindow += 1;\r\n return true;\r\n}\r\n\r\n/** Reset the in-memory sampling counters. Test-only seam; cheap + side-effect-free. */\r\nexport function _resetSamplingForTest(): void {\r\n callCounter = 0;\r\n windowStartMs = 0;\r\n samplesThisWindow = 0;\r\n}\r\n\r\n// ── Apply a learned factor to a local approximation ──────────────────────────\r\n\r\n/** Result of {@link applyCalibration}: the adjusted count + its honest source. */\r\nexport interface CalibratedCount {\r\n tokens: number;\r\n source: Extract<ConfidenceSource, \"tokenizer-approx\" | \"tokenizer-calibrated\">;\r\n}\r\n\r\n/**\r\n * Adjust a locally-tokenized `approxTokens` count by the learned factor for\r\n * `family`. When a stored factor exists for the anthropic family, return the\r\n * scaled count labeled \"tokenizer-calibrated\"; otherwise pass the approximation\r\n * through unchanged as \"tokenizer-approx\". Pure: reads the factor store but\r\n * mutates nothing.\r\n */\r\nexport function applyCalibration(\r\n approxTokens: number,\r\n family: ModelFamily,\r\n factors: CalibrationFactors = loadFactors(),\r\n): CalibratedCount {\r\n if (family === \"anthropic\") {\r\n const f = factors[family];\r\n if (f !== undefined && f.samples > 0 && Number.isFinite(f.factor) && f.factor > 0) {\r\n return {\r\n tokens: Math.max(0, Math.round(approxTokens * f.factor)),\r\n source: \"tokenizer-calibrated\",\r\n };\r\n }\r\n }\r\n return { tokens: approxTokens, source: \"tokenizer-approx\" };\r\n}\r\n\r\n/** The model used for a family's count_tokens sample (anthropic → default model). */\r\nexport function modelForFamily(_family: ModelFamily): string {\r\n return DEFAULT_ANTHROPIC_MODEL;\r\n}\r\n","/**\r\n * telemetry/proxy — the telemetry-wrapping MCP stdio proxy.\r\n *\r\n * `agent-connector serve <command> <args…>` spawns the developer's REAL MCP\r\n * server as a child and sits transparently between the host and that server,\r\n * speaking the MCP stdio wire format: NEWLINE-DELIMITED JSON-RPC (one single-line\r\n * JSON object per message, terminated by `\\n`; stdio has NO Content-Length\r\n * framing). Bytes are forwarded VERBATIM in both directions so the proxy can\r\n * never corrupt the stream; a side line-buffer tees a COPY of each direction,\r\n * parses complete messages, and measures per-tool token usage out of band.\r\n *\r\n * Honesty / safety rules baked in here:\r\n * • Forwarding always happens FIRST. Measurement runs after the bytes are out\r\n * the door and is wrapped so a measurement bug can never break a tool call.\r\n * • Telemetry stores AGGREGATE COUNTS ONLY — the parsed `tools/call` arguments\r\n * and results are tokenized and discarded; raw content is never persisted.\r\n * • AGENT_CONNECTOR_TELEMETRY=0 → still proxy transparently, skip all measure.\r\n *\r\n * The proxy resolves with the child's exit code and propagates SIGINT/SIGTERM.\r\n */\r\n\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { spawnChild } from \"../core/spawn-child.js\";\r\nimport { type JsonRpcMessage, LineBuffer, idKey, isObject } from \"./jsonrpc.js\";\r\nimport {\r\n applyCalibration,\r\n countTokensAnthropic,\r\n isCalibrationEnabled,\r\n modelForFamily,\r\n recordSample,\r\n shouldSample,\r\n} from \"./calibration.js\";\r\nimport { measureToolCall, measureToolDefs } from \"./measure.js\";\r\nimport { newRecordId } from \"./store.js\";\r\nimport { inferModelFamily } from \"./tokenizer.js\";\r\nimport type {\r\n ConfidenceSource,\r\n LaunchMethod,\r\n ModelFamily,\r\n TelemetryInstallScope,\r\n TelemetryStore,\r\n Tokenizer,\r\n ToolEventRecord,\r\n} from \"./types.js\";\r\n\r\n/** Options for {@link runServeProxy}. */\r\nexport interface RunServeProxyOptions {\r\n /** Connector id this server belongs to (stamped on every record). */\r\n connectorId: string;\r\n /** The real MCP server executable to spawn. */\r\n command: string;\r\n /** Arguments passed to that executable. */\r\n args: string[];\r\n /** Where measured records are appended. */\r\n store: TelemetryStore;\r\n /** Tokenizer used for measurement (defaults baked into measure helpers). */\r\n tokenizer: Tokenizer;\r\n /**\r\n * Telemetry model-family hint. \"auto\" infers the family from the MCP client's\r\n * `initialize` clientInfo.name; any explicit family wins outright.\r\n */\r\n modelFamilyHint: \"auto\" | ModelFamily;\r\n /** Host platform executing this proxy (stamped on every record). */\r\n hostPlatform: PlatformId;\r\n /** Host session id (stamped on every record). */\r\n sessionId: string;\r\n /** Hashed stable project identity (stamped on every record). */\r\n projectKey: string;\r\n /** Human-readable project directory (stamped on every record). */\r\n projectDir: string;\r\n /** When true, tokenize the `tools/list` schema once → tool-defs overhead. */\r\n measureToolDefs: boolean;\r\n /**\r\n * Install scope (global user vs project-local) stamped on every record.\r\n * OPTIONAL: omitted for configs written before scope plumbing existed, leaving\r\n * the field off the row so it reads as \"unknown\".\r\n */\r\n installScope?: TelemetryInstallScope;\r\n /**\r\n * How the wrapped server was launched (npx/bunx/uvx/node/binary/http), stamped\r\n * on every record. OPTIONAL for the same backward-compat reason as above.\r\n */\r\n launchMethod?: LaunchMethod;\r\n}\r\n\r\n// ── JSON-RPC shapes we read (kept local + narrow; everything else opaque) ─────\r\n\r\n/** A client→server `tools/call` we remember until its result comes back. */\r\ninterface PendingCall {\r\n toolName: string;\r\n args: unknown;\r\n}\r\n\r\n/**\r\n * Canonical string form of a tool call's arguments for an off-box count_tokens\r\n * sample — mirrors the tokenizer's own serialization so the sampled text equals\r\n * the bytes we approximated locally. A string passes through; anything else is\r\n * JSON-stringified; a value that stringifies to undefined becomes \"\".\r\n */\r\nfunction canonicalArgs(value: unknown): string {\r\n if (typeof value === \"string\") return value;\r\n try {\r\n return JSON.stringify(value) ?? \"\";\r\n } catch {\r\n return \"\";\r\n }\r\n}\r\n\r\n/**\r\n * Run the telemetry-wrapping MCP stdio proxy.\r\n *\r\n * Spawns `command args` with piped stdin/stdout (stderr inherited), forwards\r\n * both directions byte-for-byte, and measures `tools/call` round-trips and the\r\n * one-time `tools/list` tool-defs overhead into `store`. Resolves with the\r\n * child's exit code (or a signal-derived code) once the child closes.\r\n */\r\nexport async function runServeProxy(\r\n opts: RunServeProxyOptions,\r\n): Promise<number> {\r\n const {\r\n connectorId,\r\n command,\r\n args,\r\n store,\r\n tokenizer,\r\n modelFamilyHint,\r\n hostPlatform,\r\n sessionId,\r\n projectKey,\r\n projectDir,\r\n measureToolDefs: shouldMeasureToolDefs,\r\n installScope,\r\n launchMethod,\r\n } = opts;\r\n\r\n // Global kill switch: still proxy transparently, but skip ALL measurement.\r\n const measuringEnabled = process.env.AGENT_CONNECTOR_TELEMETRY !== \"0\";\r\n // OPT-IN Anthropic count_tokens calibration. Resolved once per session — the\r\n // gate (AGENT_CONNECTOR_CALIBRATE + ANTHROPIC_API_KEY) is process-level and\r\n // does not change mid-session. Off by default; privacy-safe.\r\n const calibrationEnabled = isCalibrationEnabled();\r\n\r\n // spawnChild fixes native-Windows package-runner launches: a bare npx/uvx\r\n // resolves to a .cmd shim that raw CreateProcess can't find/launch, so it is\r\n // run via a quoted single command line with a shell. No-op on macOS/Linux.\r\n const child = spawnChild(command, args, {\r\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\r\n env: process.env,\r\n });\r\n\r\n // ── Per-session measurement state ───────────────────────────────────────\r\n // Family resolved from the client's `initialize` (or the hint) and cached.\r\n let family: ModelFamily = inferModelFamily(\"\", modelFamilyHint);\r\n // Outstanding tools/call requests, keyed by JSON-RPC id.\r\n const pending = new Map<string, PendingCall>();\r\n // Monotonic sequence so two records in the same ms still get distinct ids.\r\n let seq = 0;\r\n // tools/list overhead is measured exactly once per session.\r\n let toolDefsMeasured = false;\r\n\r\n /**\r\n * Build a base record stamped with the per-session identity fields plus the\r\n * scope dimensions. `installScope` / `launchMethod` are spread in ONLY when\r\n * defined, so a session without them leaves those fields off the row entirely\r\n * (read as \"unknown\") rather than writing an explicit `undefined`.\r\n */\r\n function baseRecord(): Omit<\r\n ToolEventRecord,\r\n \"toolName\" | \"scope\" | \"inputTokens\" | \"outputTokens\" | \"confidenceSource\" | \"isError\"\r\n > {\r\n return {\r\n id: newRecordId(seq++),\r\n ts: Date.now(),\r\n connectorId,\r\n hostPlatform,\r\n sessionId,\r\n projectKey,\r\n projectDir,\r\n ...(installScope !== undefined ? { installScope } : {}),\r\n ...(launchMethod !== undefined ? { launchMethod } : {}),\r\n };\r\n }\r\n\r\n /**\r\n * Inspect one parsed CLIENT→SERVER message. Caches the model family on\r\n * `initialize` and remembers `tools/call` requests so their results can be\r\n * measured when they come back. Never throws into the data path.\r\n */\r\n function onClientMessage(msg: JsonRpcMessage): void {\r\n const method = msg.method;\r\n if (method === \"initialize\") {\r\n const params = isObject(msg.params) ? msg.params : undefined;\r\n const clientInfo =\r\n params && isObject(params[\"clientInfo\"])\r\n ? (params[\"clientInfo\"] as Record<string, unknown>)\r\n : undefined;\r\n const clientName =\r\n clientInfo && typeof clientInfo[\"name\"] === \"string\"\r\n ? (clientInfo[\"name\"] as string)\r\n : \"\";\r\n family = inferModelFamily(clientName, modelFamilyHint);\r\n return;\r\n }\r\n\r\n if (method === \"tools/call\") {\r\n const key = idKey(msg.id);\r\n if (key === null) return; // a call with no id has no result to match\r\n const params = isObject(msg.params) ? msg.params : undefined;\r\n const toolName =\r\n params && typeof params[\"name\"] === \"string\"\r\n ? (params[\"name\"] as string)\r\n : \"unknown\";\r\n const callArgs = params ? params[\"arguments\"] : undefined;\r\n pending.set(key, { toolName, args: callArgs });\r\n }\r\n }\r\n\r\n /**\r\n * Inspect one parsed SERVER→CLIENT message. Matches `tools/call` results to\r\n * remembered requests and measures them; measures `tools/list` results once.\r\n * Never throws into the data path.\r\n */\r\n function onServerMessage(msg: JsonRpcMessage): void {\r\n const key = idKey(msg.id);\r\n if (key === null) return; // notifications carry no id we can correlate\r\n\r\n const pendingCall = pending.get(key);\r\n if (pendingCall !== undefined) {\r\n pending.delete(key);\r\n recordToolCall(pendingCall, msg);\r\n return;\r\n }\r\n\r\n // Not a tracked tools/call — it may be the tools/list result we measure\r\n // once for the fixed tool-definition overhead.\r\n if (shouldMeasureToolDefs && !toolDefsMeasured) {\r\n const result = isObject(msg.result) ? msg.result : undefined;\r\n const tools = result ? result[\"tools\"] : undefined;\r\n if (Array.isArray(tools)) {\r\n recordToolDefs(tools);\r\n }\r\n }\r\n }\r\n\r\n /** Measure a matched tools/call round-trip and append the record. */\r\n function recordToolCall(call: PendingCall, response: JsonRpcMessage): void {\r\n const hasError = response.error !== undefined;\r\n const result = response.result;\r\n // A JSON-RPC error has no `result`; measure against an empty object so the\r\n // input (args) tokens are still recorded honestly.\r\n const resultForMeasure = hasError ? {} : result;\r\n const measurement = measureToolCall(\r\n call.args,\r\n resultForMeasure,\r\n family,\r\n tokenizer,\r\n );\r\n\r\n // OPT-IN calibration: for an anthropic session, nudge the locally-tokenized\r\n // approx counts toward Anthropic's real numbers via the learned factor, and\r\n // fire a sampled off-box count_tokens to keep that factor fresh. Both steps\r\n // are best-effort and wrapped so they can never break the record path.\r\n let inputTokens = measurement.inputTokens;\r\n let outputTokens = measurement.outputTokens;\r\n let confidenceSource: ConfidenceSource = measurement.source;\r\n if (calibrationEnabled && family === \"anthropic\") {\r\n try {\r\n ({ inputTokens, outputTokens, confidenceSource } = calibrateCounts(\r\n measurement.inputTokens,\r\n measurement.outputTokens,\r\n measurement.source,\r\n ));\r\n maybeSampleCalibration(call.args, measurement.inputTokens);\r\n } catch {\r\n // Calibration is a non-essential enrichment — fall back to the raw\r\n // measurement values already captured above.\r\n }\r\n }\r\n\r\n // MCP signals a tool-level failure via result.isError===true; a JSON-RPC\r\n // protocol error (response.error) is also a failure.\r\n const resultIsError =\r\n isObject(result) && result[\"isError\"] === true;\r\n store.append({\r\n ...baseRecord(),\r\n toolName: call.toolName,\r\n scope: \"call\",\r\n inputTokens,\r\n outputTokens,\r\n confidenceSource,\r\n isError: hasError || resultIsError,\r\n });\r\n }\r\n\r\n /**\r\n * Apply the learned anthropic factor to the approx input/output counts. Only\r\n * a `tokenizer-approx` measurement is calibratable (a heuristic fallback or\r\n * host-native count is left exactly as-is); the combined source becomes\r\n * `tokenizer-calibrated` only when at least one side was actually scaled.\r\n */\r\n function calibrateCounts(\r\n rawIn: number,\r\n rawOut: number,\r\n rawSource: ConfidenceSource,\r\n ): { inputTokens: number; outputTokens: number; confidenceSource: ConfidenceSource } {\r\n if (rawSource !== \"tokenizer-approx\") {\r\n return { inputTokens: rawIn, outputTokens: rawOut, confidenceSource: rawSource };\r\n }\r\n const cin = applyCalibration(rawIn, family);\r\n const cout = applyCalibration(rawOut, family);\r\n const calibrated =\r\n cin.source === \"tokenizer-calibrated\" || cout.source === \"tokenizer-calibrated\";\r\n return {\r\n inputTokens: cin.tokens,\r\n outputTokens: cout.tokens,\r\n confidenceSource: calibrated ? \"tokenizer-calibrated\" : \"tokenizer-approx\",\r\n };\r\n }\r\n\r\n /**\r\n * On a SAMPLED call, fire-and-forget an off-box count_tokens for the call's\r\n * input args and fold the resulting exact/approx ratio into the learned\r\n * factor. Returns immediately — the network round-trip never blocks\r\n * forwarding or measurement. Fail-open: any error is swallowed.\r\n */\r\n function maybeSampleCalibration(args: unknown, approxInputTokens: number): void {\r\n if (approxInputTokens <= 0) return; // nothing to ratio against\r\n if (!shouldSample()) return;\r\n const text = canonicalArgs(args);\r\n if (text === \"\") return;\r\n // Detached promise — intentionally NOT awaited so the proxy never blocks on\r\n // the network. Errors are handled inside countTokensAnthropic (returns null)\r\n // and the .catch is a belt-and-braces guard against an unhandled rejection.\r\n void countTokensAnthropic(text, modelForFamily(family))\r\n .then((exact) => {\r\n if (exact !== null && exact > 0) {\r\n recordSample(family, exact / approxInputTokens);\r\n }\r\n })\r\n .catch(() => {\r\n /* fail-open: a calibration sample must never surface an error */\r\n });\r\n }\r\n\r\n /** Measure the one-time tools/list overhead and append the record. */\r\n function recordToolDefs(tools: readonly unknown[]): void {\r\n toolDefsMeasured = true;\r\n const count = measureToolDefs(tools, family, tokenizer);\r\n store.append({\r\n ...baseRecord(),\r\n toolName: \"*\",\r\n scope: \"tool_defs\",\r\n inputTokens: count.tokens,\r\n outputTokens: 0,\r\n confidenceSource: count.source,\r\n isError: false,\r\n });\r\n }\r\n\r\n /** Parse one NDJSON line and route it, swallowing any measurement error. */\r\n function handleLine(line: string, direction: \"client\" | \"server\"): void {\r\n if (!measuringEnabled) return;\r\n let msg: JsonRpcMessage;\r\n try {\r\n const parsed = JSON.parse(line) as unknown;\r\n if (!isObject(parsed)) return;\r\n msg = parsed as JsonRpcMessage;\r\n } catch {\r\n return; // not a complete/valid JSON message — ignore for telemetry\r\n }\r\n try {\r\n if (direction === \"client\") onClientMessage(msg);\r\n else onServerMessage(msg);\r\n } catch {\r\n // Measurement must NEVER break the proxy. Drop the record silently.\r\n }\r\n }\r\n\r\n const clientLines = new LineBuffer((line) => handleLine(line, \"client\"));\r\n const serverLines = new LineBuffer((line) => handleLine(line, \"server\"));\r\n\r\n // ── Transparent byte forwarding (host stdin → child stdin) ───────────────\r\n // Forward VERBATIM first, then tee a copy into the line buffer to measure.\r\n // Honor backpressure: if the child's stdin buffer is full, pause the host\r\n // stdin and resume on drain so a slow server can't make us buffer unboundedly.\r\n process.stdin.on(\"data\", (chunk: Buffer) => {\r\n if (child.stdin && child.stdin.writable) {\r\n const ok = child.stdin.write(chunk);\r\n if (!ok) {\r\n process.stdin.pause();\r\n child.stdin.once(\"drain\", () => process.stdin.resume());\r\n }\r\n }\r\n if (measuringEnabled) {\r\n try {\r\n clientLines.push(chunk);\r\n } catch {\r\n /* tee side-channel must never affect forwarding */\r\n }\r\n }\r\n });\r\n process.stdin.on(\"end\", () => {\r\n if (child.stdin && !child.stdin.destroyed) child.stdin.end();\r\n });\r\n\r\n // ── Transparent byte forwarding (child stdout → host stdout) ─────────────\r\n if (child.stdout) {\r\n const childStdout = child.stdout;\r\n childStdout.on(\"data\", (chunk: Buffer) => {\r\n const ok = process.stdout.write(chunk);\r\n if (!ok) {\r\n childStdout.pause();\r\n process.stdout.once(\"drain\", () => childStdout.resume());\r\n }\r\n if (measuringEnabled) {\r\n try {\r\n serverLines.push(chunk);\r\n } catch {\r\n /* tee side-channel must never affect forwarding */\r\n }\r\n }\r\n });\r\n }\r\n\r\n // ── Signal propagation: forward SIGINT/SIGTERM to the child ──────────────\r\n const forwardSignal = (signal: NodeJS.Signals): void => {\r\n try {\r\n if (!child.killed) child.kill(signal);\r\n } catch {\r\n /* child may already be gone */\r\n }\r\n };\r\n const onSigint = (): void => forwardSignal(\"SIGINT\");\r\n const onSigterm = (): void => forwardSignal(\"SIGTERM\");\r\n process.on(\"SIGINT\", onSigint);\r\n process.on(\"SIGTERM\", onSigterm);\r\n\r\n // ── Resolve with the child's exit code (or signal-derived code) ──────────\r\n return await new Promise<number>((resolve) => {\r\n const finish = (code: number): void => {\r\n process.removeListener(\"SIGINT\", onSigint);\r\n process.removeListener(\"SIGTERM\", onSigterm);\r\n try {\r\n store.close();\r\n } catch {\r\n /* best-effort flush */\r\n }\r\n resolve(code);\r\n };\r\n\r\n child.on(\"error\", () => {\r\n // The server could not be spawned/launched. Surface a conventional\r\n // \"command not executable\" style failure code.\r\n finish(126);\r\n });\r\n\r\n child.on(\"close\", (code, signal) => {\r\n if (typeof code === \"number\") {\r\n finish(code);\r\n return;\r\n }\r\n // Killed by a signal → conventional 128 + signal number where known.\r\n if (signal) {\r\n const num = signalToNumber(signal);\r\n finish(num === undefined ? 1 : 128 + num);\r\n return;\r\n }\r\n finish(1);\r\n });\r\n });\r\n}\r\n\r\n/** Map the common termination signals to their numbers for exit-code math. */\r\nfunction signalToNumber(signal: NodeJS.Signals): number | undefined {\r\n const table: Partial<Record<NodeJS.Signals, number>> = {\r\n SIGINT: 2,\r\n SIGQUIT: 3,\r\n SIGKILL: 9,\r\n SIGTERM: 15,\r\n };\r\n return table[signal];\r\n}\r\n\r\nexport default runServeProxy;\r\n","/**\r\n * runtime/usage-event — the OPT-IN host-native turn-usage enricher (enricher 4a).\r\n *\r\n * Gemini CLI / Antigravity fire an `AfterModel` (Antigravity CLI: `PostInvocation`)\r\n * hook AFTER each model turn, whose stdin payload carries a `usageMetadata` block\r\n * with the host's OWN exact token accounting for that whole conversation turn:\r\n * { promptTokenCount, candidatesTokenCount, cachedContentTokenCount,\r\n * thoughtsTokenCount, totalTokenCount }\r\n * This is the single point in the whole matrix where a host reports REAL per-turn\r\n * usage to a command we control — so we record it as `confidenceSource:\"host-native\"`\r\n * (the top of CONFIDENCE_RANK), upgrading those rows from the serve-proxy estimate.\r\n *\r\n * DISTINCT, NEVER-SUMMED ORIGIN. Host-native turn usage is WHOLE-CONVERSATION, not\r\n * per-MCP. To avoid double-counting against (a) the per-MCP serve-proxy `call`\r\n * rows and (b) the usage-reader host-scan numbers, every record written here uses\r\n * the DISTINCT scope `\"model_turn\"`. The MCP leaderboard excludes that scope (just\r\n * as it special-cases `tool_defs`); the unified leaderboard surfaces it as its own\r\n * clearly-labeled section that is explicitly never added to the other two origins.\r\n *\r\n * PRIVACY + FAIL-OPEN. This enricher is OPT-IN at install time (see the adapters);\r\n * it stores AGGREGATE COUNTS ONLY (no raw content — the payload's prompt/response\r\n * text is never read). ANY parse / store / IO error degrades to exit 0 and records\r\n * NOTHING: a host-native usage hook must never break a model turn. This function\r\n * never throws.\r\n */\r\n\r\nimport { projectIdentity } from \"../core/paths.js\";\r\nimport { newRecordId, openStore } from \"../telemetry/store.js\";\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport type { ToolEventRecord } from \"../telemetry/types.js\";\r\n\r\n/** Flags + stdin the CLI hands to {@link runUsageEvent}. */\r\nexport interface RunUsageEventOptions {\r\n /** Host platform id from the command (`usage-event <platformId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>` (stamped on the record). */\r\n connectorId: string;\r\n /** Raw stdin payload (host-native JSON). Empty string is tolerated → no record. */\r\n stdin: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into an exit code. */\r\nexport interface RunUsageEventResult {\r\n /** Always 0 — a host-native usage hook must never block a model turn. */\r\n exitCode: number;\r\n /** True when a `model_turn` record was appended (false on any fail-open path). */\r\n recorded: boolean;\r\n}\r\n\r\n/** The never-records, never-throws result. */\r\nconst NOOP: RunUsageEventResult = { exitCode: 0, recorded: false };\r\n\r\nfunction isObject(v: unknown): v is Record<string, unknown> {\r\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\r\n}\r\n\r\n/** Coerce a value to a non-negative safe integer (NaN/negatives/floats → 0). */\r\nfunction toNonNegInt(v: unknown): number {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n if (!Number.isFinite(n) || n < 0) return 0;\r\n return Math.floor(n);\r\n}\r\n\r\n/** First non-empty string among the given keys of an object. */\r\nfunction firstStr(obj: Record<string, unknown>, keys: readonly string[]): string | undefined {\r\n for (const k of keys) {\r\n const v = obj[k];\r\n if (typeof v === \"string\" && v.trim() !== \"\") return v;\r\n }\r\n return undefined;\r\n}\r\n\r\n/** Read a token field tolerant of both camelCase and snake_case spellings. */\r\nfunction tokenField(\r\n meta: Record<string, unknown>,\r\n keys: readonly string[],\r\n): number {\r\n for (const k of keys) {\r\n if (k in meta) return toNonNegInt(meta[k]);\r\n }\r\n return 0;\r\n}\r\n\r\n/** Locate the `usageMetadata` block under either spelling, top-level or nested. */\r\nfunction findUsageMetadata(root: Record<string, unknown>): Record<string, unknown> | undefined {\r\n for (const k of [\"usageMetadata\", \"usage_metadata\"]) {\r\n if (isObject(root[k])) return root[k] as Record<string, unknown>;\r\n }\r\n // Some hosts nest the model response (with its usage) under a `response` /\r\n // `modelResponse` envelope — probe one level down, best-effort.\r\n for (const k of [\"response\", \"modelResponse\", \"model_response\"]) {\r\n const nested = root[k];\r\n if (isObject(nested)) {\r\n for (const mk of [\"usageMetadata\", \"usage_metadata\"]) {\r\n if (isObject(nested[mk])) return nested[mk] as Record<string, unknown>;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n/** A registered PlatformId, or \"unknown\" when the id is not one we know. */\r\nconst KNOWN_PLATFORMS: ReadonlySet<string> = new Set<PlatformId>([\r\n \"claude-code\", \"codex\", \"cursor\", \"vscode-copilot\", \"jetbrains-copilot\",\r\n \"copilot-cli\", \"gemini-cli\", \"opencode\", \"kilo\", \"kilo-cli\", \"warp\", \"hermes\",\r\n \"openclaw\", \"zed\", \"antigravity\", \"antigravity-cli\", \"kiro\", \"qwen-code\",\r\n \"kimi\", \"pi\", \"omp\", \"droid\", \"roo-code\", \"trae\", \"amp\", \"codebuff\", \"mux\",\r\n \"crush\", \"goose\", \"synthetic\", \"unknown\",\r\n]);\r\n\r\nfunction asPlatformId(id: string): PlatformId {\r\n return (KNOWN_PLATFORMS.has(id) ? id : \"unknown\") as PlatformId;\r\n}\r\n\r\n/**\r\n * Record one host-native model turn. Parses the host's `usageMetadata`, maps it to\r\n * a DISTINCT `model_turn` `ToolEventRecord` (confidence `host-native`, toolName\r\n * `\"*\"`), and appends it to the shared telemetry store. NEVER throws and never\r\n * blocks the turn: every failure path resolves to {@link NOOP} (exit 0, nothing\r\n * recorded).\r\n */\r\nexport async function runUsageEvent(\r\n opts: RunUsageEventOptions,\r\n): Promise<RunUsageEventResult> {\r\n try {\r\n // Global telemetry kill switch is honored by the store's append (no-op when\r\n // AGENT_CONNECTOR_TELEMETRY=0); we still parse cheaply and let append drop it.\r\n const trimmed = opts.stdin.trim();\r\n if (trimmed === \"\") return NOOP;\r\n\r\n let raw: unknown;\r\n try {\r\n raw = JSON.parse(trimmed);\r\n } catch {\r\n return NOOP; // malformed payload → fail-open, record nothing\r\n }\r\n if (!isObject(raw)) return NOOP;\r\n\r\n const meta = findUsageMetadata(raw);\r\n if (meta === undefined) return NOOP;\r\n\r\n const promptTokens = tokenField(meta, [\"promptTokenCount\", \"prompt_token_count\"]);\r\n const candidates = tokenField(meta, [\"candidatesTokenCount\", \"candidates_token_count\"]);\r\n const cached = tokenField(meta, [\"cachedContentTokenCount\", \"cached_content_token_count\"]);\r\n const thoughts = tokenField(meta, [\"thoughtsTokenCount\", \"thoughts_token_count\"]);\r\n\r\n // promptTokenCount is cache-INCLUSIVE (Gemini-family semantics, mirrored by\r\n // the antigravity-shared usage reader): net fresh input = prompt - cached.\r\n const inputTokens = Math.max(0, promptTokens - Math.min(cached, promptTokens));\r\n // Output = generated candidates + reasoning (\"thoughts\") tokens.\r\n const outputTokens = candidates + thoughts;\r\n\r\n // A turn with no measurable tokens is not worth a row.\r\n if (inputTokens === 0 && outputTokens === 0) return NOOP;\r\n\r\n // Identity: prefer payload session/cwd; fall back to process.cwd() for the\r\n // project key so a turn always lands in a stable project partition.\r\n const sessionId =\r\n firstStr(raw, [\"session_id\", \"sessionId\", \"conversationId\", \"conversation_id\"]) ?? \"\";\r\n const cwd = firstStr(raw, [\"cwd\", \"workspace\", \"projectDir\", \"project_dir\"]) ?? process.cwd();\r\n const id = projectIdentity(cwd);\r\n\r\n const record: ToolEventRecord = {\r\n id: newRecordId(0),\r\n ts: Date.now(),\r\n connectorId: opts.connectorId,\r\n toolName: \"*\",\r\n scope: \"model_turn\",\r\n hostPlatform: asPlatformId(opts.platformId),\r\n sessionId,\r\n projectKey: id.key,\r\n projectDir: id.dir,\r\n inputTokens,\r\n outputTokens,\r\n confidenceSource: \"host-native\",\r\n isError: false,\r\n };\r\n\r\n const store = openStore({});\r\n try {\r\n store.append(record);\r\n } finally {\r\n try {\r\n store.close();\r\n } catch {\r\n /* best-effort flush */\r\n }\r\n }\r\n return { exitCode: 0, recorded: true };\r\n } catch {\r\n // Fail-open: a host-native usage enricher must never surface an error.\r\n return NOOP;\r\n }\r\n}\r\n\r\nexport default runUsageEvent;\r\n","/**\r\n * runtime/statusline-entrypoint — the universal statusline (HUD) renderer.\r\n *\r\n * A statusline-supporting host points its status line config at the single stable\r\n * home binary (`<homeBin> statusline <platformId> --connector <id>`, built by\r\n * core/spawn.buildHomeBinStatuslineCommand). The CLI reads stdin and calls\r\n * {@link runStatusline} with the parsed flags + the raw stdin string. This module:\r\n *\r\n * 1. Loads the registered connector (live render handler) and the host adapter.\r\n * 2. Parses the host's raw status payload into a normalized StatuslineContext.\r\n * 3. Calls the connector's render(ctx) and coerces the result to a string.\r\n * 4. Formats the line into the host's native status reply (exit code + stdout).\r\n *\r\n * FAIL-SAFE is the contract (NOT fail-open with carve-outs like hooks): a status\r\n * line is decorative — it must NEVER wedge the host or spew an error/stack trace\r\n * into the status bar. So ANY error path — bad payload, missing connector,\r\n * throwing render, adapter without statusline support — returns exit 0 with NO\r\n * stdout (an empty status line), never a non-zero exit and never partial output.\r\n *\r\n * NOTE (follow-up): no telemetry is recorded for statusline renders in v1 (out of\r\n * scope). When added, it MUST stay inside the same fail-safe envelope.\r\n */\r\n\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { log } from \"../core/logger.js\";\r\nimport {\r\n loadRegisteredConnector,\r\n readRegisteredMeta,\r\n} from \"../core/load-connector.js\";\r\nimport { loadAdapter } from \"../adapters/registry.js\";\r\nimport {\r\n attachLazyTelemetryUsage,\r\n buildTelemetryAccessor,\r\n} from \"./telemetry-accessor.js\";\r\n\r\n/** Flags + stdin the CLI hands to {@link runStatusline}. */\r\nexport interface RunStatuslineOptions {\r\n /** Host platform id from the command (`statusline <platformId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>`. */\r\n connectorId: string;\r\n /** Raw stdin payload (host-native status JSON). Empty string is tolerated → `{}`. */\r\n stdin: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into exit code + stdout/stderr. */\r\nexport interface RunStatuslineResult {\r\n exitCode: number;\r\n stdout?: string;\r\n stderr?: string;\r\n}\r\n\r\n/** The fail-safe result: exit 0, no output (an empty status line). */\r\nconst EMPTY: RunStatuslineResult = { exitCode: 0 };\r\n\r\n/**\r\n * Tolerantly parse the host's stdin payload. Empty / whitespace-only input is a\r\n * legitimate \"no payload\" signal and resolves to `{}`. Malformed JSON also\r\n * degrades to `{}` rather than throwing — fail-safe is the contract.\r\n */\r\nfunction parseStdin(stdin: string): unknown {\r\n const trimmed = stdin.trim();\r\n if (trimmed === \"\") return {};\r\n try {\r\n return JSON.parse(trimmed);\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Render one host status-line invocation. Always resolves (never rejects): every\r\n * failure path returns the empty {@link EMPTY} result so the CLI exits cleanly\r\n * with an empty status line. See the module header for the fail-safe contract.\r\n */\r\nexport async function runStatusline(\r\n opts: RunStatuslineOptions,\r\n): Promise<RunStatuslineResult> {\r\n const { platformId, connectorId, stdin } = opts;\r\n\r\n try {\r\n const connector = await loadRegisteredConnector(connectorId);\r\n const adapter = await loadAdapter(platformId);\r\n\r\n // Nothing to render: no statusline declared, or the host adapter has no\r\n // statusline runtime support (parse/format pair). Empty line, exit 0.\r\n if (\r\n !connector.statusline ||\r\n typeof connector.statusline.render !== \"function\" ||\r\n !adapter ||\r\n !adapter.parseStatusInput ||\r\n !adapter.formatStatusOutput\r\n ) {\r\n return EMPTY;\r\n }\r\n\r\n const raw = parseStdin(stdin);\r\n const ctx = adapter.parseStatusInput(raw);\r\n // The command carries the authoritative connector id; stamp it so render()\r\n // sees the connector it was dispatched for.\r\n ctx.connectorId = connectorId;\r\n // capabilities is REQUIRED on StatuslineContext. claude-code's parseStatusInput\r\n // sets it, but a future/third-party adapter could omit it — backfill so the\r\n // runtime guarantee matches the type (mirrors the simulate harness). Never\r\n // let render() see undefined capabilities while the type claims it is present.\r\n if (ctx.capabilities == null) ctx.capabilities = adapter.capabilities;\r\n // Recover the install scope from the registered metadata (sync) and stamp it\r\n // onto the ctx — scope is an install-time property the entrypoint has no\r\n // other access to. Undefined when the meta carries none. Also expose the\r\n // per-connector telemetry usage accessor (lazy, fail-safe to zeros).\r\n ctx.scope = readRegisteredMeta(connectorId)?.scope;\r\n ctx.telemetry = buildTelemetryAccessor(connectorId);\r\n // Keep `ctx.usage` synchronous for render functions, but compute it only if\r\n // the render actually reads the property. Status lines refresh frequently,\r\n // and the NDJSON backend has to scan the store for an all-time summary.\r\n attachLazyTelemetryUsage(ctx, connectorId);\r\n\r\n // Per-host render override: when rendering for host X, `hosts[X].render`\r\n // wins over the top-level render; a host not listed (or a per-host entry\r\n // that is somehow not a function) falls back to the top-level render.\r\n // Selection NEVER throws — fail-safe is preserved.\r\n const perHost = connector.statusline.hosts?.[platformId as PlatformId]?.render;\r\n const render =\r\n typeof perHost === \"function\" ? perHost : connector.statusline.render;\r\n\r\n const rendered = await render(ctx);\r\n // Coerce: a non-string return (number, accidental object) is stringified so\r\n // a misbehaving render never crashes the format step. null/undefined → \"\".\r\n const line = rendered == null ? \"\" : String(rendered);\r\n\r\n const reply = adapter.formatStatusOutput(line);\r\n return {\r\n exitCode: reply.exitCode,\r\n ...(reply.stdout !== undefined ? { stdout: reply.stdout } : {}),\r\n ...(reply.stderr !== undefined ? { stderr: reply.stderr } : {}),\r\n };\r\n } catch (err) {\r\n // FAIL-SAFE: a status line must never wedge the host or surface an error.\r\n // Log for diagnostics (stderr of the home binary — not the status bar) and\r\n // return the empty line.\r\n const message = err instanceof Error ? err.message : String(err);\r\n log.error(`statusline ${platformId} (${connectorId}) failed:`, message);\r\n return EMPTY;\r\n }\r\n}\r\n\r\nexport default runStatusline;\r\n","/**\r\n * runtime/action-entrypoint — the universal user-invokable action dispatcher.\r\n *\r\n * A future host affordance (slash command / keybinding) points at the single\r\n * stable home binary (`<homeBin> action <platformId> <actionId> --connector\r\n * <id>`, built by core/spawn.buildHomeBinActionCommand). The CLI parses the\r\n * flags and calls {@link runAction}. This module:\r\n *\r\n * 1. Loads the registered connector (live run handler) and the host adapter.\r\n * 2. Builds the shared {@link HostCtx} (host + the adapter's capabilities; NO\r\n * stdin — an action takes no host payload, unlike a hook or status line).\r\n * 3. Finds the action by id, resolves the per-host run override, runs it, and\r\n * prints the optional result.message.\r\n *\r\n * USER-TRIGGERED ERROR SEMANTICS (the key difference from hooks/statusline):\r\n * actions are invoked DELIBERATELY by a user, so errors are SURFACED, never\r\n * failed silently. An unknown action id or a throwing run → exit 1 + a stderr\r\n * message. (Hooks fail-open to exit 0; the statusline fail-safes to an empty\r\n * line — both are passive surfaces a host fires automatically. An action is not:\r\n * swallowing its failure would leave the user staring at nothing, unable to\r\n * tell the action ran.)\r\n *\r\n * NOTE (follow-up): no telemetry is recorded for action runs in v1 (out of\r\n * scope), and no adapter EMITS the affordance yet — v1 ships the dispatch\r\n * backbone only.\r\n */\r\n\r\nimport type {\r\n HostCtx,\r\n PlatformCapabilities,\r\n PlatformId,\r\n} from \"../core/types.js\";\r\nimport {\r\n loadRegisteredConnector,\r\n readRegisteredMeta,\r\n} from \"../core/load-connector.js\";\r\nimport { loadAdapter, REGISTERED_PLATFORM_IDS } from \"../adapters/registry.js\";\r\nimport { buildTelemetryAccessor } from \"./telemetry-accessor.js\";\r\n\r\n/** Flags the CLI hands to {@link runAction} (no stdin — actions take no payload). */\r\nexport interface RunActionOptions {\r\n /** Host platform id from the command (`action <platformId> <actionId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>`. */\r\n connectorId: string;\r\n /** The action id positional (`action <platformId> <actionId> …`). */\r\n actionId: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into exit code + stdout/stderr. */\r\nexport interface RunActionResult {\r\n exitCode: number;\r\n stdout?: string;\r\n stderr?: string;\r\n}\r\n\r\n/**\r\n * Minimal all-false capabilities for the fallback ctx when the host adapter is\r\n * unknown/unregistered. The action still runs (it takes no host payload), but\r\n * branching on `ctx.capabilities` reads every flag as off — no affordance is\r\n * advertised for a host we cannot describe.\r\n */\r\nconst EMPTY_CAPABILITIES: PlatformCapabilities = {\r\n preToolUse: false,\r\n postToolUse: false,\r\n preCompact: false,\r\n sessionStart: false,\r\n sessionEnd: false,\r\n userPromptSubmit: false,\r\n stop: false,\r\n notification: false,\r\n canModifyArgs: false,\r\n canModifyOutput: false,\r\n canInjectSessionContext: false,\r\n transports: [],\r\n};\r\n\r\n/**\r\n * Dispatch one user-invokable action. Always resolves (never rejects): every\r\n * path returns a concrete {@link RunActionResult} so the CLI can exit cleanly,\r\n * but UNLIKE the hook/statusline runtimes an error resolves to exit 1 + a stderr\r\n * message (actions are user-triggered — surface the failure). See the module\r\n * header for the user-triggered error contract.\r\n */\r\nexport async function runAction(\r\n opts: RunActionOptions,\r\n): Promise<RunActionResult> {\r\n const { platformId, connectorId, actionId } = opts;\r\n\r\n let connector;\r\n try {\r\n connector = await loadRegisteredConnector(connectorId);\r\n } catch (err) {\r\n // A user asked to run an action on a connector we cannot load — surface it\r\n // (do NOT fail-open: the user would otherwise see nothing and assume it ran).\r\n const message = err instanceof Error ? err.message : String(err);\r\n return { exitCode: 1, stderr: message };\r\n }\r\n\r\n const action = connector.actions.find((a) => a.id === actionId);\r\n if (!action) {\r\n return {\r\n exitCode: 1,\r\n stderr: `no action \"${actionId}\" on connector ${connectorId}`,\r\n };\r\n }\r\n\r\n // Build the shared HostCtx. capabilities come from the adapter; an unknown\r\n // adapter still runs with the minimal ctx (an action takes no host payload).\r\n const adapter = await loadAdapter(platformId).catch(() => undefined);\r\n const host: PlatformId = REGISTERED_PLATFORM_IDS.has(platformId as PlatformId)\r\n ? (platformId as PlatformId)\r\n : \"unknown\";\r\n const ctx: HostCtx = {\r\n host,\r\n capabilities: adapter?.capabilities ?? EMPTY_CAPABILITIES,\r\n // Recover the install scope from the registered metadata (sync) — scope is\r\n // an install-time property the entrypoint otherwise has no access to —\r\n // and expose the per-connector telemetry usage accessor (lazy, fail-safe).\r\n scope: readRegisteredMeta(connectorId)?.scope,\r\n telemetry: buildTelemetryAccessor(connectorId),\r\n };\r\n\r\n // Per-host run override: when running for host X, `hosts[X].run` wins over the\r\n // top-level run; a host not listed (or a per-host entry that is somehow not a\r\n // function) falls back to the top-level run.\r\n const perHost = action.hosts?.[platformId as PlatformId]?.run;\r\n const run = typeof perHost === \"function\" ? perHost : action.run;\r\n\r\n try {\r\n const result = await run(ctx);\r\n const message = result?.message;\r\n if (typeof message === \"string\" && message !== \"\") {\r\n return { exitCode: 0, stdout: message };\r\n }\r\n // void / no message → success with no output.\r\n return { exitCode: 0 };\r\n } catch (err) {\r\n // USER-TRIGGERED: a throwing action surfaces its failure (exit 1 + stderr),\r\n // never a silent fail-open. This is the documented difference from\r\n // hooks/statusline.\r\n const message = err instanceof Error ? err.message : String(err);\r\n return {\r\n exitCode: 1,\r\n stderr: `action \"${actionId}\" failed: ${message}`,\r\n };\r\n }\r\n}\r\n\r\nexport default runAction;\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAS,kBAAkB;;;ACQ3B,SAAS,YAAY,cAAc,qBAAqB;AACxD,SAAS,YAAY;AAkBd,SAAS,uBAAgC;AAC9C,QAAM,YAAY,QAAQ,IAAI,6BAA6B,IACxD,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AACzB,QAAM,OAAO,QAAQ,IAAI,qBAAqB,IAAI,KAAK;AACvD,SAAO,SAAS,SAAS,WAAW,KAAK,QAAQ;AACnD;AAgBO,SAAS,kBAA0B;AACxC,SAAO,KAAK,SAAS,GAAG,kBAAkB;AAC5C;AAOA,IAAM,YAAY;AAClB,IAAM,YAAY;AAElB,SAAS,WAAW,OAA8B;AAChD,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,EAAG,QAAO;AAClD,MAAI,QAAQ,UAAW,QAAO;AAC9B,MAAI,QAAQ,UAAW,QAAO;AAC9B,SAAO;AACT;AAMO,SAAS,cAAkC;AAChD,QAAM,OAAO,gBAAgB;AAC7B,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO,CAAC;AAC/B,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;AACpD,QAAI,WAAW,QAAQ,OAAO,WAAW,SAAU,QAAO,CAAC;AAC3D,UAAM,MAA0B,CAAC;AACjC,eAAW,CAAC,QAAQ,KAAK,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC/E,UAAI,UAAU,QAAQ,OAAO,UAAU,SAAU;AACjD,YAAM,MAAM;AACZ,YAAM,SAAS,IAAI,QAAQ;AAC3B,YAAM,UAAU,IAAI,SAAS;AAC7B,UACE,OAAO,WAAW,YAClB,OAAO,SAAS,MAAM,KACtB,SAAS,KACT,OAAO,YAAY,YACnB,OAAO,SAAS,OAAO,KACvB,WAAW,GACX;AACA,QAAC,IAA0C,MAAM,IAAI;AAAA,UACnD;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AASO,SAAS,aAAa,QAAqB,OAAqB;AACrE,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM;AACtB,MAAI;AACF,UAAM,UAAU,YAAY;AAC5B,UAAM,QAAQ,QAAQ,MAAM;AAC5B,QAAI;AACJ,QAAI,UAAU,UAAa,MAAM,WAAW,GAAG;AAC7C,aAAO,EAAE,QAAQ,SAAS,SAAS,EAAE;AAAA,IACvC,OAAO;AACL,YAAM,UAAU,MAAM,UAAU;AAEhC,YAAM,SAAS,MAAM,UAAU,UAAU,MAAM,UAAU;AACzD,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B;AACA,UAAM,UAA8B,EAAE,GAAG,SAAS,CAAC,MAAM,GAAG,KAAK;AACjE,UAAM,OAAO,gBAAgB;AAC7B,cAAU,SAAS,CAAC;AACpB,kBAAc,MAAM,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AAAA,EACrE,QAAQ;AAAA,EAER;AACF;AAKA,IAAM,0BAA0B;AAGhC,IAAM,mBAAmB;AAezB,eAAsB,qBACpB,MACA,QAAgB,yBACQ;AACxB,QAAM,UAAU,QAAQ,IAAI,qBAAqB,IAAI,KAAK;AAC1D,MAAI,WAAW,GAAI,QAAO;AAC1B,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,kBAAkB;AAAA,MACxC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,aAAa;AAAA,QACb,qBAAqB;AAAA,QACrB,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,IAAI,KAAK;AACf,QAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,KAAK,KAAK,GAAG;AACzD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAUA,IAAM,eAAe;AACrB,IAAM,yBAAyB;AAE/B,IAAI,cAAc;AAClB,IAAI,gBAAgB;AACpB,IAAI,oBAAoB;AAOjB,SAAS,aAAa,MAAc,KAAK,IAAI,GAAY;AAE9D,MAAI,MAAM,iBAAiB,KAAQ;AACjC,oBAAgB;AAChB,wBAAoB;AAAA,EACtB;AACA,iBAAe;AACf,MAAI,cAAc,iBAAiB,EAAG,QAAO;AAC7C,MAAI,qBAAqB,uBAAwB,QAAO;AACxD,uBAAqB;AACrB,SAAO;AACT;AAwBO,SAAS,iBACd,cACA,QACA,UAA8B,YAAY,GACzB;AACjB,MAAI,WAAW,aAAa;AAC1B,UAAM,IAAI,QAAQ,MAAM;AACxB,QAAI,MAAM,UAAa,EAAE,UAAU,KAAK,OAAO,SAAS,EAAE,MAAM,KAAK,EAAE,SAAS,GAAG;AACjF,aAAO;AAAA,QACL,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,EAAE,MAAM,CAAC;AAAA,QACvD,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,cAAc,QAAQ,mBAAmB;AAC5D;AAGO,SAAS,eAAe,SAA8B;AAC3D,SAAO;AACT;;;ACpLA,SAAS,cAAc,OAAwB;AAC7C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,WAAO,KAAK,UAAU,KAAK,KAAK;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAUA,eAAsB,cACpB,MACiB;AACjB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM,mBAAmB,QAAQ,IAAI,8BAA8B;AAInE,QAAM,qBAAqB,qBAAqB;AAKhD,QAAM,QAAQ,WAAW,SAAS,MAAM;AAAA,IACtC,OAAO,CAAC,QAAQ,QAAQ,SAAS;AAAA,IACjC,KAAK,QAAQ;AAAA,EACf,CAAC;AAID,MAAI,SAAsB,iBAAiB,IAAI,eAAe;AAE9D,QAAM,UAAU,oBAAI,IAAyB;AAE7C,MAAI,MAAM;AAEV,MAAI,mBAAmB;AAQvB,WAAS,aAGP;AACA,WAAO;AAAA,MACL,IAAI,YAAY,KAAK;AAAA,MACrB,IAAI,KAAK,IAAI;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IACvD;AAAA,EACF;AAOA,WAAS,gBAAgB,KAA2B;AAClD,UAAM,SAAS,IAAI;AACnB,QAAI,WAAW,cAAc;AAC3B,YAAM,SAAS,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS;AACnD,YAAM,aACJ,UAAU,SAAS,OAAO,YAAY,CAAC,IAClC,OAAO,YAAY,IACpB;AACN,YAAM,aACJ,cAAc,OAAO,WAAW,MAAM,MAAM,WACvC,WAAW,MAAM,IAClB;AACN,eAAS,iBAAiB,YAAY,eAAe;AACrD;AAAA,IACF;AAEA,QAAI,WAAW,cAAc;AAC3B,YAAM,MAAM,MAAM,IAAI,EAAE;AACxB,UAAI,QAAQ,KAAM;AAClB,YAAM,SAAS,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS;AACnD,YAAM,WACJ,UAAU,OAAO,OAAO,MAAM,MAAM,WAC/B,OAAO,MAAM,IACd;AACN,YAAM,WAAW,SAAS,OAAO,WAAW,IAAI;AAChD,cAAQ,IAAI,KAAK,EAAE,UAAU,MAAM,SAAS,CAAC;AAAA,IAC/C;AAAA,EACF;AAOA,WAAS,gBAAgB,KAA2B;AAClD,UAAM,MAAM,MAAM,IAAI,EAAE;AACxB,QAAI,QAAQ,KAAM;AAElB,UAAM,cAAc,QAAQ,IAAI,GAAG;AACnC,QAAI,gBAAgB,QAAW;AAC7B,cAAQ,OAAO,GAAG;AAClB,qBAAe,aAAa,GAAG;AAC/B;AAAA,IACF;AAIA,QAAI,yBAAyB,CAAC,kBAAkB;AAC9C,YAAM,SAAS,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS;AACnD,YAAM,QAAQ,SAAS,OAAO,OAAO,IAAI;AACzC,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,uBAAe,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAGA,WAAS,eAAe,MAAmB,UAAgC;AACzE,UAAM,WAAW,SAAS,UAAU;AACpC,UAAM,SAAS,SAAS;AAGxB,UAAM,mBAAmB,WAAW,CAAC,IAAI;AACzC,UAAM,cAAc;AAAA,MAClB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAMA,QAAI,cAAc,YAAY;AAC9B,QAAI,eAAe,YAAY;AAC/B,QAAI,mBAAqC,YAAY;AACrD,QAAI,sBAAsB,WAAW,aAAa;AAChD,UAAI;AACF,SAAC,EAAE,aAAa,cAAc,iBAAiB,IAAI;AAAA,UACjD,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,YAAY;AAAA,QACd;AACA,+BAAuB,KAAK,MAAM,YAAY,WAAW;AAAA,MAC3D,QAAQ;AAAA,MAGR;AAAA,IACF;AAIA,UAAM,gBACJ,SAAS,MAAM,KAAK,OAAO,SAAS,MAAM;AAC5C,UAAM,OAAO;AAAA,MACX,GAAG,WAAW;AAAA,MACd,UAAU,KAAK;AAAA,MACf,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,YAAY;AAAA,IACvB,CAAC;AAAA,EACH;AAQA,WAAS,gBACP,OACA,QACA,WACmF;AACnF,QAAI,cAAc,oBAAoB;AACpC,aAAO,EAAE,aAAa,OAAO,cAAc,QAAQ,kBAAkB,UAAU;AAAA,IACjF;AACA,UAAM,MAAM,iBAAiB,OAAO,MAAM;AAC1C,UAAM,OAAO,iBAAiB,QAAQ,MAAM;AAC5C,UAAM,aACJ,IAAI,WAAW,0BAA0B,KAAK,WAAW;AAC3D,WAAO;AAAA,MACL,aAAa,IAAI;AAAA,MACjB,cAAc,KAAK;AAAA,MACnB,kBAAkB,aAAa,yBAAyB;AAAA,IAC1D;AAAA,EACF;AAQA,WAAS,uBAAuBA,OAAe,mBAAiC;AAC9E,QAAI,qBAAqB,EAAG;AAC5B,QAAI,CAAC,aAAa,EAAG;AACrB,UAAM,OAAO,cAAcA,KAAI;AAC/B,QAAI,SAAS,GAAI;AAIjB,SAAK,qBAAqB,MAAM,eAAe,MAAM,CAAC,EACnD,KAAK,CAAC,UAAU;AACf,UAAI,UAAU,QAAQ,QAAQ,GAAG;AAC/B,qBAAa,QAAQ,QAAQ,iBAAiB;AAAA,MAChD;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EACL;AAGA,WAAS,eAAe,OAAiC;AACvD,uBAAmB;AACnB,UAAM,QAAQ,gBAAgB,OAAO,QAAQ,SAAS;AACtD,UAAM,OAAO;AAAA,MACX,GAAG,WAAW;AAAA,MACd,UAAU;AAAA,MACV,OAAO;AAAA,MACP,aAAa,MAAM;AAAA,MACnB,cAAc;AAAA,MACd,kBAAkB,MAAM;AAAA,MACxB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAGA,WAAS,WAAW,MAAc,WAAsC;AACtE,QAAI,CAAC,iBAAkB;AACvB,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,UAAI,CAAC,SAAS,MAAM,EAAG;AACvB,YAAM;AAAA,IACR,QAAQ;AACN;AAAA,IACF;AACA,QAAI;AACF,UAAI,cAAc,SAAU,iBAAgB,GAAG;AAAA,UAC1C,iBAAgB,GAAG;AAAA,IAC1B,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,cAAc,IAAI,WAAW,CAAC,SAAS,WAAW,MAAM,QAAQ,CAAC;AACvE,QAAM,cAAc,IAAI,WAAW,CAAC,SAAS,WAAW,MAAM,QAAQ,CAAC;AAMvE,UAAQ,MAAM,GAAG,QAAQ,CAAC,UAAkB;AAC1C,QAAI,MAAM,SAAS,MAAM,MAAM,UAAU;AACvC,YAAM,KAAK,MAAM,MAAM,MAAM,KAAK;AAClC,UAAI,CAAC,IAAI;AACP,gBAAQ,MAAM,MAAM;AACpB,cAAM,MAAM,KAAK,SAAS,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,MACxD;AAAA,IACF;AACA,QAAI,kBAAkB;AACpB,UAAI;AACF,oBAAY,KAAK,KAAK;AAAA,MACxB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC;AACD,UAAQ,MAAM,GAAG,OAAO,MAAM;AAC5B,QAAI,MAAM,SAAS,CAAC,MAAM,MAAM,UAAW,OAAM,MAAM,IAAI;AAAA,EAC7D,CAAC;AAGD,MAAI,MAAM,QAAQ;AAChB,UAAM,cAAc,MAAM;AAC1B,gBAAY,GAAG,QAAQ,CAAC,UAAkB;AACxC,YAAM,KAAK,QAAQ,OAAO,MAAM,KAAK;AACrC,UAAI,CAAC,IAAI;AACP,oBAAY,MAAM;AAClB,gBAAQ,OAAO,KAAK,SAAS,MAAM,YAAY,OAAO,CAAC;AAAA,MACzD;AACA,UAAI,kBAAkB;AACpB,YAAI;AACF,sBAAY,KAAK,KAAK;AAAA,QACxB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,gBAAgB,CAAC,WAAiC;AACtD,QAAI;AACF,UAAI,CAAC,MAAM,OAAQ,OAAM,KAAK,MAAM;AAAA,IACtC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,WAAW,MAAY,cAAc,QAAQ;AACnD,QAAM,YAAY,MAAY,cAAc,SAAS;AACrD,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,SAAS;AAG/B,SAAO,MAAM,IAAI,QAAgB,CAAC,YAAY;AAC5C,UAAM,SAAS,CAAC,SAAuB;AACrC,cAAQ,eAAe,UAAU,QAAQ;AACzC,cAAQ,eAAe,WAAW,SAAS;AAC3C,UAAI;AACF,cAAM,MAAM;AAAA,MACd,QAAQ;AAAA,MAER;AACA,cAAQ,IAAI;AAAA,IACd;AAEA,UAAM,GAAG,SAAS,MAAM;AAGtB,aAAO,GAAG;AAAA,IACZ,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,MAAM,WAAW;AAClC,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,IAAI;AACX;AAAA,MACF;AAEA,UAAI,QAAQ;AACV,cAAM,MAAM,eAAe,MAAM;AACjC,eAAO,QAAQ,SAAY,IAAI,MAAM,GAAG;AACxC;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAGA,SAAS,eAAe,QAA4C;AAClE,QAAM,QAAiD;AAAA,IACrD,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACA,SAAO,MAAM,MAAM;AACrB;;;AFlZA,SAAS,iBAAiB,MAAyB,QAAQ,KAAa;AACtE,SACE,IAAI,2BACJ,IAAI,qBACJ,IAAI,mBACJ,IAAI,mBACJ,IAAI,kBACJ,QAAQ,WAAW,CAAC;AAExB;AAEA,eAAsB,SAAS,MAAwC;AACrE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAOJ,MAAI,YAAY,UAAa,QAAQ,KAAK,MAAM,IAAI;AAClD,YAAQ,IAAI,2BAA2B;AAAA,EACzC;AAEA,QAAM,YAAY,mBAAmB,WAAW;AAChD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR,cAAc,WAAW;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,KAAK,gBAAgB,QAAQ,IAAI,CAAC;AAIxC,QAAM,eACJ,yBAAyB,UACzB,wBAAwB,IAAI,oBAAoB,IAC5C,uBACA,kBAAkB,EAAE;AAC1B,QAAM,YAAY,iBAAiB;AAInC,QAAM,eAAe,mBAAmB,eAAe,UAAU;AAEjE,QAAM,QAAQ,UAAU,CAAC,CAAC;AAC1B,QAAM,MAAM,aAAa;AAEzB,SAAO,cAAc;AAAA,IACnB;AAAA,IACA,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA,WAAW;AAAA,IACX,iBAAiB,UAAU,UAAU;AAAA,IACrC;AAAA,IACA;AAAA,IACA,YAAY,GAAG;AAAA,IACf,YAAY,GAAG;AAAA,IACf,iBAAiB,UAAU,UAAU;AAAA,IACrC;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;AGnGA,IAAM,OAA4B,EAAE,UAAU,GAAG,UAAU,MAAM;AAEjE,SAASC,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAGA,SAAS,YAAY,GAAoB;AACvC,QAAM,IAAI,OAAO,MAAM,WAAW,IAAI,OAAO,MAAM,WAAW,OAAO,CAAC,IAAI;AAC1E,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,EAAG,QAAO;AACzC,SAAO,KAAK,MAAM,CAAC;AACrB;AAGA,SAAS,SAAS,KAA8B,MAA6C;AAC3F,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,GAAI,QAAO;AAAA,EACvD;AACA,SAAO;AACT;AAGA,SAAS,WACP,MACA,MACQ;AACR,aAAW,KAAK,MAAM;AACpB,QAAI,KAAK,KAAM,QAAO,YAAY,KAAK,CAAC,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAGA,SAAS,kBAAkB,MAAoE;AAC7F,aAAW,KAAK,CAAC,iBAAiB,gBAAgB,GAAG;AACnD,QAAIA,UAAS,KAAK,CAAC,CAAC,EAAG,QAAO,KAAK,CAAC;AAAA,EACtC;AAGA,aAAW,KAAK,CAAC,YAAY,iBAAiB,gBAAgB,GAAG;AAC/D,UAAM,SAAS,KAAK,CAAC;AACrB,QAAIA,UAAS,MAAM,GAAG;AACpB,iBAAW,MAAM,CAAC,iBAAiB,gBAAgB,GAAG;AACpD,YAAIA,UAAS,OAAO,EAAE,CAAC,EAAG,QAAO,OAAO,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAM,kBAAuC,oBAAI,IAAgB;AAAA,EAC/D;AAAA,EAAe;AAAA,EAAS;AAAA,EAAU;AAAA,EAAkB;AAAA,EACpD;AAAA,EAAe;AAAA,EAAc;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAQ;AAAA,EACrE;AAAA,EAAY;AAAA,EAAO;AAAA,EAAe;AAAA,EAAmB;AAAA,EAAQ;AAAA,EAC7D;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAO;AAAA,EAAS;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAY;AAAA,EACrE;AAAA,EAAS;AAAA,EAAS;AAAA,EAAa;AACjC,CAAC;AAED,SAAS,aAAa,IAAwB;AAC5C,SAAQ,gBAAgB,IAAI,EAAE,IAAI,KAAK;AACzC;AASA,eAAsB,cACpB,MAC8B;AAC9B,MAAI;AAGF,UAAM,UAAU,KAAK,MAAM,KAAK;AAChC,QAAI,YAAY,GAAI,QAAO;AAE3B,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,MAAM,OAAO;AAAA,IAC1B,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,CAACA,UAAS,GAAG,EAAG,QAAO;AAE3B,UAAM,OAAO,kBAAkB,GAAG;AAClC,QAAI,SAAS,OAAW,QAAO;AAE/B,UAAM,eAAe,WAAW,MAAM,CAAC,oBAAoB,oBAAoB,CAAC;AAChF,UAAM,aAAa,WAAW,MAAM,CAAC,wBAAwB,wBAAwB,CAAC;AACtF,UAAM,SAAS,WAAW,MAAM,CAAC,2BAA2B,4BAA4B,CAAC;AACzF,UAAM,WAAW,WAAW,MAAM,CAAC,sBAAsB,sBAAsB,CAAC;AAIhF,UAAM,cAAc,KAAK,IAAI,GAAG,eAAe,KAAK,IAAI,QAAQ,YAAY,CAAC;AAE7E,UAAM,eAAe,aAAa;AAGlC,QAAI,gBAAgB,KAAK,iBAAiB,EAAG,QAAO;AAIpD,UAAM,YACJ,SAAS,KAAK,CAAC,cAAc,aAAa,kBAAkB,iBAAiB,CAAC,KAAK;AACrF,UAAM,MAAM,SAAS,KAAK,CAAC,OAAO,aAAa,cAAc,aAAa,CAAC,KAAK,QAAQ,IAAI;AAC5F,UAAM,KAAK,gBAAgB,GAAG;AAE9B,UAAM,SAA0B;AAAA,MAC9B,IAAI,YAAY,CAAC;AAAA,MACjB,IAAI,KAAK,IAAI;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,cAAc,aAAa,KAAK,UAAU;AAAA,MAC1C;AAAA,MACA,YAAY,GAAG;AAAA,MACf,YAAY,GAAG;AAAA,MACf;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,MAClB,SAAS;AAAA,IACX;AAEA,UAAM,QAAQ,UAAU,CAAC,CAAC;AAC1B,QAAI;AACF,YAAM,OAAO,MAAM;AAAA,IACrB,UAAE;AACA,UAAI;AACF,cAAM,MAAM;AAAA,MACd,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO,EAAE,UAAU,GAAG,UAAU,KAAK;AAAA,EACvC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;AC5IA,IAAM,QAA6B,EAAE,UAAU,EAAE;AAOjD,SAAS,WAAW,OAAwB;AAC1C,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,YAAY,GAAI,QAAO,CAAC;AAC5B,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAOA,eAAsB,cACpB,MAC8B;AAC9B,QAAM,EAAE,YAAY,aAAa,MAAM,IAAI;AAE3C,MAAI;AACF,UAAM,YAAY,MAAM,wBAAwB,WAAW;AAC3D,UAAM,UAAU,MAAM,YAAY,UAAU;AAI5C,QACE,CAAC,UAAU,cACX,OAAO,UAAU,WAAW,WAAW,cACvC,CAAC,WACD,CAAC,QAAQ,oBACT,CAAC,QAAQ,oBACT;AACA,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,WAAW,KAAK;AAC5B,UAAM,MAAM,QAAQ,iBAAiB,GAAG;AAGxC,QAAI,cAAc;AAKlB,QAAI,IAAI,gBAAgB,KAAM,KAAI,eAAe,QAAQ;AAKzD,QAAI,QAAQ,mBAAmB,WAAW,GAAG;AAC7C,QAAI,YAAY,uBAAuB,WAAW;AAIlD,6BAAyB,KAAK,WAAW;AAMzC,UAAM,UAAU,UAAU,WAAW,QAAQ,UAAwB,GAAG;AACxE,UAAM,SACJ,OAAO,YAAY,aAAa,UAAU,UAAU,WAAW;AAEjE,UAAM,WAAW,MAAM,OAAO,GAAG;AAGjC,UAAM,OAAO,YAAY,OAAO,KAAK,OAAO,QAAQ;AAEpD,UAAM,QAAQ,QAAQ,mBAAmB,IAAI;AAC7C,WAAO;AAAA,MACL,UAAU,MAAM;AAAA,MAChB,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC7D,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/D;AAAA,EACF,SAAS,KAAK;AAIZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,QAAI,MAAM,cAAc,UAAU,KAAK,WAAW,aAAa,OAAO;AACtE,WAAO;AAAA,EACT;AACF;;;AClFA,IAAM,qBAA2C;AAAA,EAC/C,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,YAAY,CAAC;AACf;AASA,eAAsB,UACpB,MAC0B;AAC1B,QAAM,EAAE,YAAY,aAAa,SAAS,IAAI;AAE9C,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,wBAAwB,WAAW;AAAA,EACvD,SAAS,KAAK;AAGZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO,EAAE,UAAU,GAAG,QAAQ,QAAQ;AAAA,EACxC;AAEA,QAAM,SAAS,UAAU,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAC9D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,cAAc,QAAQ,kBAAkB,WAAW;AAAA,IAC7D;AAAA,EACF;AAIA,QAAM,UAAU,MAAM,YAAY,UAAU,EAAE,MAAM,MAAM,MAAS;AACnE,QAAM,OAAmB,wBAAwB,IAAI,UAAwB,IACxE,aACD;AACJ,QAAM,MAAe;AAAA,IACnB;AAAA,IACA,cAAc,SAAS,gBAAgB;AAAA;AAAA;AAAA;AAAA,IAIvC,OAAO,mBAAmB,WAAW,GAAG;AAAA,IACxC,WAAW,uBAAuB,WAAW;AAAA,EAC/C;AAKA,QAAM,UAAU,OAAO,QAAQ,UAAwB,GAAG;AAC1D,QAAM,MAAM,OAAO,YAAY,aAAa,UAAU,OAAO;AAE7D,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAM,UAAU,QAAQ;AACxB,QAAI,OAAO,YAAY,YAAY,YAAY,IAAI;AACjD,aAAO,EAAE,UAAU,GAAG,QAAQ,QAAQ;AAAA,IACxC;AAEA,WAAO,EAAE,UAAU,EAAE;AAAA,EACvB,SAAS,KAAK;AAIZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,WAAW,QAAQ,aAAa,OAAO;AAAA,IACjD;AAAA,EACF;AACF;","names":["args","isObject"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime/serve.ts","../src/telemetry/calibration.ts","../src/telemetry/proxy.ts","../src/runtime/usage-event.ts","../src/runtime/statusline-entrypoint.ts","../src/runtime/action-entrypoint.ts"],"sourcesContent":["/**\r\n * runtime/serve — the `agent-connector serve` telemetry-wrapping entrypoint.\r\n *\r\n * When a stdio MCP server opts into transparent telemetry, its host config is\r\n * rewritten (by the adapter, via core/spawn.buildServeWrapperCommand) to launch\r\n * <homeBin> serve --connector <id> -- <realCommand> <realArgs...>\r\n * instead of the server directly. The CLI parses those flags and calls\r\n * {@link runServe}, which stands up the per-session telemetry context (store,\r\n * tokenizer, project identity, host detection) and hands off to the proxy.\r\n *\r\n * The proxy (telemetry/proxy.runServeProxy) forwards bytes VERBATIM in both\r\n * directions and measures aggregate per-tool token counts out of band, so this\r\n * wrapper is transparent to both the host and the real server. It resolves with\r\n * the child server's exit code, which the CLI uses as its own.\r\n */\r\n\r\nimport { randomUUID } from \"node:crypto\";\r\n\r\nimport { detectRuntimeHost } from \"../adapters/detect.js\";\r\nimport { REGISTERED_PLATFORM_IDS } from \"../adapters/registry.js\";\r\nimport { readRegisteredMeta } from \"../core/load-connector.js\";\r\nimport { projectIdentity } from \"../core/paths.js\";\r\nimport { detectLaunchMethod } from \"../core/spawn.js\";\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { runServeProxy } from \"../telemetry/proxy.js\";\r\nimport { openStore } from \"../telemetry/store.js\";\r\nimport { getTokenizer } from \"../telemetry/tokenizer.js\";\r\nimport type { TelemetryInstallScope } from \"../telemetry/types.js\";\r\n\r\n/** Flags the CLI hands to {@link runServe}. */\r\nexport interface RunServeOptions {\r\n /** Connector id from `--connector <id>`; selects telemetry config + stamps records. */\r\n connectorId: string;\r\n /** The real MCP server executable to spawn (everything after `--`). */\r\n serverCommand: string;\r\n /** Arguments passed to that executable. */\r\n serverArgs: string[];\r\n /**\r\n * Install scope from `--scope <user|project>`. OPTIONAL: absent for configs\r\n * written before scope plumbing existed — left unstamped so older rows read\r\n * as \"unknown\". Stamped verbatim onto every telemetry record when present.\r\n */\r\n installScope?: TelemetryInstallScope;\r\n /**\r\n * Install TARGET platform id from `--host <platformId>` (baked into the\r\n * wrapper at install time). OPTIONAL: when a recognized platform id, it\r\n * OVERRIDES runtime env detection so headless spawns stamp hostPlatform\r\n * correctly (detectRuntimeHost only knows env markers for a few hosts and\r\n * otherwise mis-attributes). Absent/unrecognized → fall back to detection.\r\n */\r\n hostPlatformOverride?: PlatformId;\r\n /**\r\n * Framework data-root from `--data-dir <path>` (baked into the wrapper at\r\n * install time, only for a NON-DEFAULT root). OPTIONAL: when present, it pins\r\n * the data-root the WHOLE child resolves — connector record lookup AND the\r\n * telemetry store — by populating AGENT_CONNECTOR_DATA_DIR before anything\r\n * reads it. This is the env-independent path for hosts (codex) that strip the\r\n * MCP child's environment and would otherwise drop the override, leaving the\r\n * child to resolve the default `~/.agent-connector` and fail \"not registered\".\r\n * Absent → resolve the data-root the usual way (env or default).\r\n */\r\n dataDir?: string;\r\n}\r\n\r\n/**\r\n * Launch the developer's real MCP server under the telemetry-wrapping proxy.\r\n *\r\n * Resolves with the child server's exit code (propagated as this process's exit\r\n * code by the CLI). The session id comes from AGENT_CONNECTOR_SESSION when the\r\n * host sets it (empty otherwise); the host platform is detected from runtime env\r\n * markers; the project identity partitions telemetry by the stable project key.\r\n */\r\n/**\r\n * Resolve a session id for telemetry attribution. Prefers a host-provided\r\n * session/thread marker (so records from the same host session group together);\r\n * falls back to a per-process UUID — each `serve` invocation is one server\r\n * session, a sensible default granularity — so `--by session` rollups are never\r\n * collapsed into a single empty-keyed group.\r\n */\r\nfunction resolveSessionId(env: NodeJS.ProcessEnv = process.env): string {\r\n return (\r\n env.AGENT_CONNECTOR_SESSION ||\r\n env.CLAUDE_SESSION_ID ||\r\n env.CODEX_THREAD_ID ||\r\n env.CURSOR_TRACE_ID ||\r\n env.MCP_SESSION_ID ||\r\n `proc-${randomUUID()}`\r\n );\r\n}\r\n\r\nexport async function runServe(opts: RunServeOptions): Promise<number> {\r\n const {\r\n connectorId,\r\n serverCommand,\r\n serverArgs,\r\n installScope,\r\n hostPlatformOverride,\r\n dataDir,\r\n } = opts;\r\n\r\n // Pin the data-root BEFORE anything resolves it (the connector record lookup\r\n // below and openStore later both read dataRoot()). The wrapper passes\r\n // --data-dir only for a non-default root on a host that may strip the child\r\n // env (codex) — populating AGENT_CONNECTOR_DATA_DIR here makes the whole child\r\n // resolve that root regardless of whether the host propagated the env var.\r\n if (dataDir !== undefined && dataDir.trim() !== \"\") {\r\n process.env.AGENT_CONNECTOR_DATA_DIR = dataDir;\r\n }\r\n\r\n const connector = readRegisteredMeta(connectorId);\r\n if (!connector) {\r\n throw new Error(\r\n `Connector \"${connectorId}\" is not registered. Run an install/register step first.`,\r\n );\r\n }\r\n\r\n const id = projectIdentity(process.cwd());\r\n // Prefer the install TARGET platform baked into the wrapper (--host), but only\r\n // when it is a KNOWN registered platform id — a bad/unknown value falls back to\r\n // runtime env detection so a config typo can never poison hostPlatform.\r\n const hostPlatform: PlatformId =\r\n hostPlatformOverride !== undefined &&\r\n REGISTERED_PLATFORM_IDS.has(hostPlatformOverride)\r\n ? hostPlatformOverride\r\n : detectRuntimeHost().platform;\r\n const sessionId = resolveSessionId();\r\n\r\n // `serve` only ever wraps a locally-spawned stdio server (a remote/http server\r\n // is never launched through the proxy), so isRemote is always false here.\r\n const launchMethod = detectLaunchMethod(serverCommand, serverArgs);\r\n\r\n const store = openStore({});\r\n const tok = getTokenizer();\r\n\r\n return runServeProxy({\r\n connectorId,\r\n command: serverCommand,\r\n args: serverArgs,\r\n store,\r\n tokenizer: tok,\r\n modelFamilyHint: connector.telemetry.modelFamilyHint,\r\n hostPlatform,\r\n sessionId,\r\n projectKey: id.key,\r\n projectDir: id.dir,\r\n measureToolDefs: connector.telemetry.measureToolDefs,\r\n installScope,\r\n launchMethod,\r\n });\r\n}\r\n","/**\r\n * telemetry/calibration — OPT-IN Anthropic count_tokens calibration.\r\n *\r\n * The default tokenizer counts every family with the OpenAI o200k_base BPE, so\r\n * an Anthropic session's counts are an honest-but-approximate stand-in\r\n * (\"tokenizer-approx\"). This module lets a developer OPT IN to calibrating that\r\n * approximation against Anthropic's real `count_tokens` endpoint: we sample a\r\n * tiny fraction of tool calls off-box, learn a per-family correction factor\r\n * (rolling mean of exact/approx), and apply it to the locally-tokenized counts\r\n * so they land much closer to the host's real numbers — labeled honestly as\r\n * \"tokenizer-calibrated\".\r\n *\r\n * PRIVACY + SAFETY — load-bearing invariants:\r\n * • OPT-IN only. Nothing here runs unless BOTH AGENT_CONNECTOR_CALIBRATE\r\n * contains \"anthropic\" AND ANTHROPIC_API_KEY is set (see isCalibrationEnabled).\r\n * • Sampling only — shouldSample() rate-limits hard so we never hammer the API.\r\n * • Content leaves the box ONLY on a sampled call, ONLY when opted in. We store\r\n * a single scalar factor + sample count — NEVER the sampled text itself.\r\n * • Fail-open everywhere: a network/parse/IO error returns null / passes the\r\n * approximation through unchanged and NEVER throws into a tool call or hook.\r\n *\r\n * No new dependencies: uses Node's global fetch (Node >= 18) and node:fs.\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nimport { dataRoot, ensureDir } from \"../core/paths.js\";\r\nimport type { ConfidenceSource, ModelFamily } from \"./types.js\";\r\n\r\n// ── Env switches ──────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Is opt-in Anthropic calibration enabled for this process?\r\n *\r\n * Requires BOTH:\r\n * • AGENT_CONNECTOR_CALIBRATE — a comma-separated allowlist that INCLUDES\r\n * `anthropic` (so a future `AGENT_CONNECTOR_CALIBRATE=openai,anthropic` can\r\n * opt other families in without touching this gate), and\r\n * • ANTHROPIC_API_KEY — a non-empty key to authenticate the off-box call.\r\n *\r\n * Either missing → disabled (the privacy-safe default).\r\n */\r\nexport function isCalibrationEnabled(): boolean {\r\n const families = (process.env.AGENT_CONNECTOR_CALIBRATE || \"\")\r\n .split(\",\")\r\n .map((s) => s.trim())\r\n .filter((s) => s !== \"\");\r\n const key = (process.env.ANTHROPIC_API_KEY || \"\").trim();\r\n return families.includes(\"anthropic\") && key !== \"\";\r\n}\r\n\r\n// ── Factor store (dataRoot/calibration.json) ────────────────────────────────\r\n\r\n/** One learned correction factor for a model family: factor + sample count. */\r\nexport interface CalibrationFactor {\r\n /** Multiply an approx count by this to estimate the real count. */\r\n factor: number;\r\n /** How many samples have folded into the rolling mean. */\r\n samples: number;\r\n}\r\n\r\n/** The on-disk factor map, keyed by model family. */\r\nexport type CalibrationFactors = Partial<Record<ModelFamily, CalibrationFactor>>;\r\n\r\n/** Path to the learned-factor store: dataRoot()/calibration.json. */\r\nexport function calibrationPath(): string {\r\n return join(dataRoot(), \"calibration.json\");\r\n}\r\n\r\n/**\r\n * Clamp a measured exact/approx ratio into a sane range. A pathological sample\r\n * (e.g. an empty-string approx of 0 → Infinity, or a parse glitch) must never\r\n * poison the rolling mean, so ratios are pinned to [0.2, 5].\r\n */\r\nconst RATIO_MIN = 0.2;\r\nconst RATIO_MAX = 5;\r\n\r\nfunction clampRatio(ratio: number): number | null {\r\n if (!Number.isFinite(ratio) || ratio <= 0) return null;\r\n if (ratio < RATIO_MIN) return RATIO_MIN;\r\n if (ratio > RATIO_MAX) return RATIO_MAX;\r\n return ratio;\r\n}\r\n\r\n/**\r\n * Load the learned factors from disk. Fail-open: a missing/unreadable/malformed\r\n * file returns an empty map rather than throwing.\r\n */\r\nexport function loadFactors(): CalibrationFactors {\r\n const path = calibrationPath();\r\n if (!existsSync(path)) return {};\r\n try {\r\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\r\n if (parsed === null || typeof parsed !== \"object\") return {};\r\n const out: CalibrationFactors = {};\r\n for (const [family, value] of Object.entries(parsed as Record<string, unknown>)) {\r\n if (value === null || typeof value !== \"object\") continue;\r\n const rec = value as Record<string, unknown>;\r\n const factor = rec[\"factor\"];\r\n const samples = rec[\"samples\"];\r\n if (\r\n typeof factor === \"number\" &&\r\n Number.isFinite(factor) &&\r\n factor > 0 &&\r\n typeof samples === \"number\" &&\r\n Number.isFinite(samples) &&\r\n samples >= 0\r\n ) {\r\n (out as Record<string, CalibrationFactor>)[family] = {\r\n factor,\r\n samples,\r\n };\r\n }\r\n }\r\n return out;\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Fold one observed exact/approx `ratio` into the rolling mean for `family` and\r\n * persist it. A running average converges to the true mean while staying cheap\r\n * and stateless across processes (each writer reads the prior count, blends in\r\n * the new sample, writes back). Fail-open: any read/write/clamp problem leaves\r\n * the store untouched and never throws.\r\n */\r\nexport function recordSample(family: ModelFamily, ratio: number): void {\r\n const clamped = clampRatio(ratio);\r\n if (clamped === null) return;\r\n try {\r\n const factors = loadFactors();\r\n const prior = factors[family];\r\n let next: CalibrationFactor;\r\n if (prior === undefined || prior.samples <= 0) {\r\n next = { factor: clamped, samples: 1 };\r\n } else {\r\n const samples = prior.samples + 1;\r\n // Running average: new mean = old mean + (sample - old mean) / n.\r\n const factor = prior.factor + (clamped - prior.factor) / samples;\r\n next = { factor, samples };\r\n }\r\n const updated: CalibrationFactors = { ...factors, [family]: next };\r\n const path = calibrationPath();\r\n ensureDir(dataRoot());\r\n writeFileSync(path, `${JSON.stringify(updated, null, 2)}\\n`, \"utf8\");\r\n } catch {\r\n /* fail-open: a calibration write must never break a tool call */\r\n }\r\n}\r\n\r\n// ── Anthropic count_tokens (off-box, sampled, fail-open) ─────────────────────\r\n\r\n/** Default model used for count_tokens when no family→model map applies. */\r\nconst DEFAULT_ANTHROPIC_MODEL = \"claude-3-5-sonnet-latest\";\r\n\r\n/** Anthropic count_tokens endpoint. */\r\nconst COUNT_TOKENS_URL = \"https://api.anthropic.com/v1/messages/count_tokens\";\r\n\r\n/** The single field we read out of a successful response. */\r\ninterface CountTokensResponse {\r\n input_tokens?: unknown;\r\n}\r\n\r\n/**\r\n * Ask Anthropic's `count_tokens` endpoint for the exact token count of `text`\r\n * under `model`. Returns the integer count, or `null` on ANY failure (no key,\r\n * non-200, network error, unparseable body) — fail-open by contract.\r\n *\r\n * Only ever called on a SAMPLED tool call when calibration is opted in, so the\r\n * sampled text leaves the box only under explicit operator consent.\r\n */\r\nexport async function countTokensAnthropic(\r\n text: string,\r\n model: string = DEFAULT_ANTHROPIC_MODEL,\r\n): Promise<number | null> {\r\n const apiKey = (process.env.ANTHROPIC_API_KEY || \"\").trim();\r\n if (apiKey === \"\") return null;\r\n try {\r\n const res = await fetch(COUNT_TOKENS_URL, {\r\n method: \"POST\",\r\n headers: {\r\n \"x-api-key\": apiKey,\r\n \"anthropic-version\": \"2023-06-01\",\r\n \"content-type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n model,\r\n messages: [{ role: \"user\", content: text }],\r\n }),\r\n });\r\n if (!res.ok) return null;\r\n const body = (await res.json()) as CountTokensResponse;\r\n const n = body.input_tokens;\r\n if (typeof n === \"number\" && Number.isFinite(n) && n >= 0) {\r\n return n;\r\n }\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n// ── Sampling (rate-limit so we never hammer the API) ─────────────────────────\r\n\r\n/**\r\n * Sample roughly 1 in {@link SAMPLE_EVERY} calls, with a hard per-minute cap so\r\n * a burst of tool calls can never fan out into a burst of API calls. Both\r\n * counters are in-memory (per process) — calibration is a best-effort,\r\n * low-volume background signal, not a per-call requirement.\r\n */\r\nconst SAMPLE_EVERY = 20;\r\nconst MAX_SAMPLES_PER_MINUTE = 10;\r\n\r\nlet callCounter = 0;\r\nlet windowStartMs = 0;\r\nlet samplesThisWindow = 0;\r\n\r\n/**\r\n * Should THIS call fire an off-box count_tokens sample? Combines a 1-in-N\r\n * counter with a rolling per-minute cap. Pure in-memory bookkeeping; never\r\n * throws, never blocks.\r\n */\r\nexport function shouldSample(now: number = Date.now()): boolean {\r\n // Roll the per-minute window.\r\n if (now - windowStartMs >= 60_000) {\r\n windowStartMs = now;\r\n samplesThisWindow = 0;\r\n }\r\n callCounter += 1;\r\n if (callCounter % SAMPLE_EVERY !== 0) return false;\r\n if (samplesThisWindow >= MAX_SAMPLES_PER_MINUTE) return false;\r\n samplesThisWindow += 1;\r\n return true;\r\n}\r\n\r\n/** Reset the in-memory sampling counters. Test-only seam; cheap + side-effect-free. */\r\nexport function _resetSamplingForTest(): void {\r\n callCounter = 0;\r\n windowStartMs = 0;\r\n samplesThisWindow = 0;\r\n}\r\n\r\n// ── Apply a learned factor to a local approximation ──────────────────────────\r\n\r\n/** Result of {@link applyCalibration}: the adjusted count + its honest source. */\r\nexport interface CalibratedCount {\r\n tokens: number;\r\n source: Extract<ConfidenceSource, \"tokenizer-approx\" | \"tokenizer-calibrated\">;\r\n}\r\n\r\n/**\r\n * Adjust a locally-tokenized `approxTokens` count by the learned factor for\r\n * `family`. When a stored factor exists for the anthropic family, return the\r\n * scaled count labeled \"tokenizer-calibrated\"; otherwise pass the approximation\r\n * through unchanged as \"tokenizer-approx\". Pure: reads the factor store but\r\n * mutates nothing.\r\n */\r\nexport function applyCalibration(\r\n approxTokens: number,\r\n family: ModelFamily,\r\n factors: CalibrationFactors = loadFactors(),\r\n): CalibratedCount {\r\n if (family === \"anthropic\") {\r\n const f = factors[family];\r\n if (f !== undefined && f.samples > 0 && Number.isFinite(f.factor) && f.factor > 0) {\r\n return {\r\n tokens: Math.max(0, Math.round(approxTokens * f.factor)),\r\n source: \"tokenizer-calibrated\",\r\n };\r\n }\r\n }\r\n return { tokens: approxTokens, source: \"tokenizer-approx\" };\r\n}\r\n\r\n/** The model used for a family's count_tokens sample (anthropic → default model). */\r\nexport function modelForFamily(_family: ModelFamily): string {\r\n return DEFAULT_ANTHROPIC_MODEL;\r\n}\r\n","/**\r\n * telemetry/proxy — the telemetry-wrapping MCP stdio proxy.\r\n *\r\n * `agent-connector serve <command> <args…>` spawns the developer's REAL MCP\r\n * server as a child and sits transparently between the host and that server,\r\n * speaking the MCP stdio wire format: NEWLINE-DELIMITED JSON-RPC (one single-line\r\n * JSON object per message, terminated by `\\n`; stdio has NO Content-Length\r\n * framing). Bytes are forwarded VERBATIM in both directions so the proxy can\r\n * never corrupt the stream; a side line-buffer tees a COPY of each direction,\r\n * parses complete messages, and measures per-tool token usage out of band.\r\n *\r\n * Honesty / safety rules baked in here:\r\n * • Forwarding always happens FIRST. Measurement runs after the bytes are out\r\n * the door and is wrapped so a measurement bug can never break a tool call.\r\n * • Telemetry stores AGGREGATE COUNTS ONLY — the parsed `tools/call` arguments\r\n * and results are tokenized and discarded; raw content is never persisted.\r\n * • AGENT_CONNECTOR_TELEMETRY=0 → still proxy transparently, skip all measure.\r\n *\r\n * The proxy resolves with the child's exit code and propagates SIGINT/SIGTERM.\r\n */\r\n\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { spawnChild } from \"../core/spawn-child.js\";\r\nimport { type JsonRpcMessage, LineBuffer, idKey, isObject } from \"./jsonrpc.js\";\r\nimport {\r\n applyCalibration,\r\n countTokensAnthropic,\r\n isCalibrationEnabled,\r\n modelForFamily,\r\n recordSample,\r\n shouldSample,\r\n} from \"./calibration.js\";\r\nimport { measureToolCall, measureToolDefs } from \"./measure.js\";\r\nimport { newRecordId } from \"./store.js\";\r\nimport { inferModelFamily } from \"./tokenizer.js\";\r\nimport type {\r\n ConfidenceSource,\r\n LaunchMethod,\r\n ModelFamily,\r\n TelemetryInstallScope,\r\n TelemetryStore,\r\n Tokenizer,\r\n ToolEventRecord,\r\n} from \"./types.js\";\r\n\r\n/** Options for {@link runServeProxy}. */\r\nexport interface RunServeProxyOptions {\r\n /** Connector id this server belongs to (stamped on every record). */\r\n connectorId: string;\r\n /** The real MCP server executable to spawn. */\r\n command: string;\r\n /** Arguments passed to that executable. */\r\n args: string[];\r\n /** Where measured records are appended. */\r\n store: TelemetryStore;\r\n /** Tokenizer used for measurement (defaults baked into measure helpers). */\r\n tokenizer: Tokenizer;\r\n /**\r\n * Telemetry model-family hint. \"auto\" infers the family from the MCP client's\r\n * `initialize` clientInfo.name; any explicit family wins outright.\r\n */\r\n modelFamilyHint: \"auto\" | ModelFamily;\r\n /** Host platform executing this proxy (stamped on every record). */\r\n hostPlatform: PlatformId;\r\n /** Host session id (stamped on every record). */\r\n sessionId: string;\r\n /** Hashed stable project identity (stamped on every record). */\r\n projectKey: string;\r\n /** Human-readable project directory (stamped on every record). */\r\n projectDir: string;\r\n /** When true, tokenize the `tools/list` schema once → tool-defs overhead. */\r\n measureToolDefs: boolean;\r\n /**\r\n * Install scope (global user vs project-local) stamped on every record.\r\n * OPTIONAL: omitted for configs written before scope plumbing existed, leaving\r\n * the field off the row so it reads as \"unknown\".\r\n */\r\n installScope?: TelemetryInstallScope;\r\n /**\r\n * How the wrapped server was launched (npx/bunx/uvx/node/binary/http), stamped\r\n * on every record. OPTIONAL for the same backward-compat reason as above.\r\n */\r\n launchMethod?: LaunchMethod;\r\n}\r\n\r\n// ── JSON-RPC shapes we read (kept local + narrow; everything else opaque) ─────\r\n\r\n/** A client→server `tools/call` we remember until its result comes back. */\r\ninterface PendingCall {\r\n toolName: string;\r\n args: unknown;\r\n}\r\n\r\n/**\r\n * Canonical string form of a tool call's arguments for an off-box count_tokens\r\n * sample — mirrors the tokenizer's own serialization so the sampled text equals\r\n * the bytes we approximated locally. A string passes through; anything else is\r\n * JSON-stringified; a value that stringifies to undefined becomes \"\".\r\n */\r\nfunction canonicalArgs(value: unknown): string {\r\n if (typeof value === \"string\") return value;\r\n try {\r\n return JSON.stringify(value) ?? \"\";\r\n } catch {\r\n return \"\";\r\n }\r\n}\r\n\r\n/**\r\n * Run the telemetry-wrapping MCP stdio proxy.\r\n *\r\n * Spawns `command args` with piped stdin/stdout (stderr inherited), forwards\r\n * both directions byte-for-byte, and measures `tools/call` round-trips and the\r\n * one-time `tools/list` tool-defs overhead into `store`. Resolves with the\r\n * child's exit code (or a signal-derived code) once the child closes.\r\n */\r\nexport async function runServeProxy(\r\n opts: RunServeProxyOptions,\r\n): Promise<number> {\r\n const {\r\n connectorId,\r\n command,\r\n args,\r\n store,\r\n tokenizer,\r\n modelFamilyHint,\r\n hostPlatform,\r\n sessionId,\r\n projectKey,\r\n projectDir,\r\n measureToolDefs: shouldMeasureToolDefs,\r\n installScope,\r\n launchMethod,\r\n } = opts;\r\n\r\n // Global kill switch: still proxy transparently, but skip ALL measurement.\r\n const measuringEnabled = process.env.AGENT_CONNECTOR_TELEMETRY !== \"0\";\r\n // OPT-IN Anthropic count_tokens calibration. Resolved once per session — the\r\n // gate (AGENT_CONNECTOR_CALIBRATE + ANTHROPIC_API_KEY) is process-level and\r\n // does not change mid-session. Off by default; privacy-safe.\r\n const calibrationEnabled = isCalibrationEnabled();\r\n\r\n // spawnChild fixes native-Windows package-runner launches: a bare npx/uvx\r\n // resolves to a .cmd shim that raw CreateProcess can't find/launch, so it is\r\n // run via a quoted single command line with a shell. No-op on macOS/Linux.\r\n const child = spawnChild(command, args, {\r\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\r\n env: process.env,\r\n });\r\n\r\n // ── Per-session measurement state ───────────────────────────────────────\r\n // Family resolved from the client's `initialize` (or the hint) and cached.\r\n let family: ModelFamily = inferModelFamily(\"\", modelFamilyHint);\r\n // Outstanding tools/call requests, keyed by JSON-RPC id.\r\n const pending = new Map<string, PendingCall>();\r\n // Monotonic sequence so two records in the same ms still get distinct ids.\r\n let seq = 0;\r\n // tools/list overhead is measured exactly once per session.\r\n let toolDefsMeasured = false;\r\n\r\n /**\r\n * Build a base record stamped with the per-session identity fields plus the\r\n * scope dimensions. `installScope` / `launchMethod` are spread in ONLY when\r\n * defined, so a session without them leaves those fields off the row entirely\r\n * (read as \"unknown\") rather than writing an explicit `undefined`.\r\n */\r\n function baseRecord(): Omit<\r\n ToolEventRecord,\r\n \"toolName\" | \"scope\" | \"inputTokens\" | \"outputTokens\" | \"confidenceSource\" | \"isError\"\r\n > {\r\n return {\r\n id: newRecordId(seq++),\r\n ts: Date.now(),\r\n connectorId,\r\n hostPlatform,\r\n sessionId,\r\n projectKey,\r\n projectDir,\r\n ...(installScope !== undefined ? { installScope } : {}),\r\n ...(launchMethod !== undefined ? { launchMethod } : {}),\r\n };\r\n }\r\n\r\n /**\r\n * Inspect one parsed CLIENT→SERVER message. Caches the model family on\r\n * `initialize` and remembers `tools/call` requests so their results can be\r\n * measured when they come back. Never throws into the data path.\r\n */\r\n function onClientMessage(msg: JsonRpcMessage): void {\r\n const method = msg.method;\r\n if (method === \"initialize\") {\r\n const params = isObject(msg.params) ? msg.params : undefined;\r\n const clientInfo =\r\n params && isObject(params[\"clientInfo\"])\r\n ? (params[\"clientInfo\"] as Record<string, unknown>)\r\n : undefined;\r\n const clientName =\r\n clientInfo && typeof clientInfo[\"name\"] === \"string\"\r\n ? (clientInfo[\"name\"] as string)\r\n : \"\";\r\n family = inferModelFamily(clientName, modelFamilyHint);\r\n return;\r\n }\r\n\r\n if (method === \"tools/call\") {\r\n const key = idKey(msg.id);\r\n if (key === null) return; // a call with no id has no result to match\r\n const params = isObject(msg.params) ? msg.params : undefined;\r\n const toolName =\r\n params && typeof params[\"name\"] === \"string\"\r\n ? (params[\"name\"] as string)\r\n : \"unknown\";\r\n const callArgs = params ? params[\"arguments\"] : undefined;\r\n pending.set(key, { toolName, args: callArgs });\r\n }\r\n }\r\n\r\n /**\r\n * Inspect one parsed SERVER→CLIENT message. Matches `tools/call` results to\r\n * remembered requests and measures them; measures `tools/list` results once.\r\n * Never throws into the data path.\r\n */\r\n function onServerMessage(msg: JsonRpcMessage): void {\r\n const key = idKey(msg.id);\r\n if (key === null) return; // notifications carry no id we can correlate\r\n\r\n const pendingCall = pending.get(key);\r\n if (pendingCall !== undefined) {\r\n pending.delete(key);\r\n recordToolCall(pendingCall, msg);\r\n return;\r\n }\r\n\r\n // Not a tracked tools/call — it may be the tools/list result we measure\r\n // once for the fixed tool-definition overhead.\r\n if (shouldMeasureToolDefs && !toolDefsMeasured) {\r\n const result = isObject(msg.result) ? msg.result : undefined;\r\n const tools = result ? result[\"tools\"] : undefined;\r\n if (Array.isArray(tools)) {\r\n recordToolDefs(tools);\r\n }\r\n }\r\n }\r\n\r\n /** Measure a matched tools/call round-trip and append the record. */\r\n function recordToolCall(call: PendingCall, response: JsonRpcMessage): void {\r\n const hasError = response.error !== undefined;\r\n const result = response.result;\r\n // A JSON-RPC error has no `result`; measure against an empty object so the\r\n // input (args) tokens are still recorded honestly.\r\n const resultForMeasure = hasError ? {} : result;\r\n const measurement = measureToolCall(\r\n call.args,\r\n resultForMeasure,\r\n family,\r\n tokenizer,\r\n );\r\n\r\n // OPT-IN calibration: for an anthropic session, nudge the locally-tokenized\r\n // approx counts toward Anthropic's real numbers via the learned factor, and\r\n // fire a sampled off-box count_tokens to keep that factor fresh. Both steps\r\n // are best-effort and wrapped so they can never break the record path.\r\n let inputTokens = measurement.inputTokens;\r\n let outputTokens = measurement.outputTokens;\r\n let confidenceSource: ConfidenceSource = measurement.source;\r\n if (calibrationEnabled && family === \"anthropic\") {\r\n try {\r\n ({ inputTokens, outputTokens, confidenceSource } = calibrateCounts(\r\n measurement.inputTokens,\r\n measurement.outputTokens,\r\n measurement.source,\r\n ));\r\n maybeSampleCalibration(call.args, measurement.inputTokens);\r\n } catch {\r\n // Calibration is a non-essential enrichment — fall back to the raw\r\n // measurement values already captured above.\r\n }\r\n }\r\n\r\n // MCP signals a tool-level failure via result.isError===true; a JSON-RPC\r\n // protocol error (response.error) is also a failure.\r\n const resultIsError =\r\n isObject(result) && result[\"isError\"] === true;\r\n store.append({\r\n ...baseRecord(),\r\n toolName: call.toolName,\r\n scope: \"call\",\r\n inputTokens,\r\n outputTokens,\r\n confidenceSource,\r\n isError: hasError || resultIsError,\r\n });\r\n }\r\n\r\n /**\r\n * Apply the learned anthropic factor to the approx input/output counts. Only\r\n * a `tokenizer-approx` measurement is calibratable (a heuristic fallback or\r\n * host-native count is left exactly as-is); the combined source becomes\r\n * `tokenizer-calibrated` only when at least one side was actually scaled.\r\n */\r\n function calibrateCounts(\r\n rawIn: number,\r\n rawOut: number,\r\n rawSource: ConfidenceSource,\r\n ): { inputTokens: number; outputTokens: number; confidenceSource: ConfidenceSource } {\r\n if (rawSource !== \"tokenizer-approx\") {\r\n return { inputTokens: rawIn, outputTokens: rawOut, confidenceSource: rawSource };\r\n }\r\n const cin = applyCalibration(rawIn, family);\r\n const cout = applyCalibration(rawOut, family);\r\n const calibrated =\r\n cin.source === \"tokenizer-calibrated\" || cout.source === \"tokenizer-calibrated\";\r\n return {\r\n inputTokens: cin.tokens,\r\n outputTokens: cout.tokens,\r\n confidenceSource: calibrated ? \"tokenizer-calibrated\" : \"tokenizer-approx\",\r\n };\r\n }\r\n\r\n /**\r\n * On a SAMPLED call, fire-and-forget an off-box count_tokens for the call's\r\n * input args and fold the resulting exact/approx ratio into the learned\r\n * factor. Returns immediately — the network round-trip never blocks\r\n * forwarding or measurement. Fail-open: any error is swallowed.\r\n */\r\n function maybeSampleCalibration(args: unknown, approxInputTokens: number): void {\r\n if (approxInputTokens <= 0) return; // nothing to ratio against\r\n if (!shouldSample()) return;\r\n const text = canonicalArgs(args);\r\n if (text === \"\") return;\r\n // Detached promise — intentionally NOT awaited so the proxy never blocks on\r\n // the network. Errors are handled inside countTokensAnthropic (returns null)\r\n // and the .catch is a belt-and-braces guard against an unhandled rejection.\r\n void countTokensAnthropic(text, modelForFamily(family))\r\n .then((exact) => {\r\n if (exact !== null && exact > 0) {\r\n recordSample(family, exact / approxInputTokens);\r\n }\r\n })\r\n .catch(() => {\r\n /* fail-open: a calibration sample must never surface an error */\r\n });\r\n }\r\n\r\n /** Measure the one-time tools/list overhead and append the record. */\r\n function recordToolDefs(tools: readonly unknown[]): void {\r\n toolDefsMeasured = true;\r\n const count = measureToolDefs(tools, family, tokenizer);\r\n store.append({\r\n ...baseRecord(),\r\n toolName: \"*\",\r\n scope: \"tool_defs\",\r\n inputTokens: count.tokens,\r\n outputTokens: 0,\r\n confidenceSource: count.source,\r\n isError: false,\r\n });\r\n }\r\n\r\n /** Parse one NDJSON line and route it, swallowing any measurement error. */\r\n function handleLine(line: string, direction: \"client\" | \"server\"): void {\r\n if (!measuringEnabled) return;\r\n let msg: JsonRpcMessage;\r\n try {\r\n const parsed = JSON.parse(line) as unknown;\r\n if (!isObject(parsed)) return;\r\n msg = parsed as JsonRpcMessage;\r\n } catch {\r\n return; // not a complete/valid JSON message — ignore for telemetry\r\n }\r\n try {\r\n if (direction === \"client\") onClientMessage(msg);\r\n else onServerMessage(msg);\r\n } catch {\r\n // Measurement must NEVER break the proxy. Drop the record silently.\r\n }\r\n }\r\n\r\n const clientLines = new LineBuffer((line) => handleLine(line, \"client\"));\r\n const serverLines = new LineBuffer((line) => handleLine(line, \"server\"));\r\n\r\n // ── Transparent byte forwarding (host stdin → child stdin) ───────────────\r\n // Forward VERBATIM first, then tee a copy into the line buffer to measure.\r\n // Honor backpressure: if the child's stdin buffer is full, pause the host\r\n // stdin and resume on drain so a slow server can't make us buffer unboundedly.\r\n process.stdin.on(\"data\", (chunk: Buffer) => {\r\n if (child.stdin && child.stdin.writable) {\r\n const ok = child.stdin.write(chunk);\r\n if (!ok) {\r\n process.stdin.pause();\r\n child.stdin.once(\"drain\", () => process.stdin.resume());\r\n }\r\n }\r\n if (measuringEnabled) {\r\n try {\r\n clientLines.push(chunk);\r\n } catch {\r\n /* tee side-channel must never affect forwarding */\r\n }\r\n }\r\n });\r\n process.stdin.on(\"end\", () => {\r\n if (child.stdin && !child.stdin.destroyed) child.stdin.end();\r\n });\r\n\r\n // ── Transparent byte forwarding (child stdout → host stdout) ─────────────\r\n if (child.stdout) {\r\n const childStdout = child.stdout;\r\n childStdout.on(\"data\", (chunk: Buffer) => {\r\n const ok = process.stdout.write(chunk);\r\n if (!ok) {\r\n childStdout.pause();\r\n process.stdout.once(\"drain\", () => childStdout.resume());\r\n }\r\n if (measuringEnabled) {\r\n try {\r\n serverLines.push(chunk);\r\n } catch {\r\n /* tee side-channel must never affect forwarding */\r\n }\r\n }\r\n });\r\n }\r\n\r\n // ── Signal propagation: forward SIGINT/SIGTERM to the child ──────────────\r\n const forwardSignal = (signal: NodeJS.Signals): void => {\r\n try {\r\n if (!child.killed) child.kill(signal);\r\n } catch {\r\n /* child may already be gone */\r\n }\r\n };\r\n const onSigint = (): void => forwardSignal(\"SIGINT\");\r\n const onSigterm = (): void => forwardSignal(\"SIGTERM\");\r\n process.on(\"SIGINT\", onSigint);\r\n process.on(\"SIGTERM\", onSigterm);\r\n\r\n // ── Resolve with the child's exit code (or signal-derived code) ──────────\r\n return await new Promise<number>((resolve) => {\r\n const finish = (code: number): void => {\r\n process.removeListener(\"SIGINT\", onSigint);\r\n process.removeListener(\"SIGTERM\", onSigterm);\r\n try {\r\n store.close();\r\n } catch {\r\n /* best-effort flush */\r\n }\r\n resolve(code);\r\n };\r\n\r\n child.on(\"error\", () => {\r\n // The server could not be spawned/launched. Surface a conventional\r\n // \"command not executable\" style failure code.\r\n finish(126);\r\n });\r\n\r\n child.on(\"close\", (code, signal) => {\r\n if (typeof code === \"number\") {\r\n finish(code);\r\n return;\r\n }\r\n // Killed by a signal → conventional 128 + signal number where known.\r\n if (signal) {\r\n const num = signalToNumber(signal);\r\n finish(num === undefined ? 1 : 128 + num);\r\n return;\r\n }\r\n finish(1);\r\n });\r\n });\r\n}\r\n\r\n/** Map the common termination signals to their numbers for exit-code math. */\r\nfunction signalToNumber(signal: NodeJS.Signals): number | undefined {\r\n const table: Partial<Record<NodeJS.Signals, number>> = {\r\n SIGINT: 2,\r\n SIGQUIT: 3,\r\n SIGKILL: 9,\r\n SIGTERM: 15,\r\n };\r\n return table[signal];\r\n}\r\n\r\nexport default runServeProxy;\r\n","/**\r\n * runtime/usage-event — the OPT-IN host-native turn-usage enricher (enricher 4a).\r\n *\r\n * Gemini CLI / Antigravity fire an `AfterModel` (Antigravity CLI: `PostInvocation`)\r\n * hook AFTER each model turn, whose stdin payload carries a `usageMetadata` block\r\n * with the host's OWN exact token accounting for that whole conversation turn:\r\n * { promptTokenCount, candidatesTokenCount, cachedContentTokenCount,\r\n * thoughtsTokenCount, totalTokenCount }\r\n * This is the single point in the whole matrix where a host reports REAL per-turn\r\n * usage to a command we control — so we record it as `confidenceSource:\"host-native\"`\r\n * (the top of CONFIDENCE_RANK), upgrading those rows from the serve-proxy estimate.\r\n *\r\n * DISTINCT, NEVER-SUMMED ORIGIN. Host-native turn usage is WHOLE-CONVERSATION, not\r\n * per-MCP. To avoid double-counting against (a) the per-MCP serve-proxy `call`\r\n * rows and (b) the usage-reader host-scan numbers, every record written here uses\r\n * the DISTINCT scope `\"model_turn\"`. The MCP leaderboard excludes that scope (just\r\n * as it special-cases `tool_defs`); the unified leaderboard surfaces it as its own\r\n * clearly-labeled section that is explicitly never added to the other two origins.\r\n *\r\n * PRIVACY + FAIL-OPEN. This enricher is OPT-IN at install time (see the adapters);\r\n * it stores AGGREGATE COUNTS ONLY (no raw content — the payload's prompt/response\r\n * text is never read). ANY parse / store / IO error degrades to exit 0 and records\r\n * NOTHING: a host-native usage hook must never break a model turn. This function\r\n * never throws.\r\n */\r\n\r\nimport { projectIdentity } from \"../core/paths.js\";\r\nimport { newRecordId, openStore } from \"../telemetry/store.js\";\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport type { ToolEventRecord } from \"../telemetry/types.js\";\r\n\r\n/** Flags + stdin the CLI hands to {@link runUsageEvent}. */\r\nexport interface RunUsageEventOptions {\r\n /** Host platform id from the command (`usage-event <platformId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>` (stamped on the record). */\r\n connectorId: string;\r\n /** Raw stdin payload (host-native JSON). Empty string is tolerated → no record. */\r\n stdin: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into an exit code. */\r\nexport interface RunUsageEventResult {\r\n /** Always 0 — a host-native usage hook must never block a model turn. */\r\n exitCode: number;\r\n /** True when a `model_turn` record was appended (false on any fail-open path). */\r\n recorded: boolean;\r\n}\r\n\r\n/** The never-records, never-throws result. */\r\nconst NOOP: RunUsageEventResult = { exitCode: 0, recorded: false };\r\n\r\nfunction isObject(v: unknown): v is Record<string, unknown> {\r\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\r\n}\r\n\r\n/** Coerce a value to a non-negative safe integer (NaN/negatives/floats → 0). */\r\nfunction toNonNegInt(v: unknown): number {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n if (!Number.isFinite(n) || n < 0) return 0;\r\n return Math.floor(n);\r\n}\r\n\r\n/** First non-empty string among the given keys of an object. */\r\nfunction firstStr(obj: Record<string, unknown>, keys: readonly string[]): string | undefined {\r\n for (const k of keys) {\r\n const v = obj[k];\r\n if (typeof v === \"string\" && v.trim() !== \"\") return v;\r\n }\r\n return undefined;\r\n}\r\n\r\n/** Read a token field tolerant of both camelCase and snake_case spellings. */\r\nfunction tokenField(\r\n meta: Record<string, unknown>,\r\n keys: readonly string[],\r\n): number {\r\n for (const k of keys) {\r\n if (k in meta) return toNonNegInt(meta[k]);\r\n }\r\n return 0;\r\n}\r\n\r\n/** Locate the `usageMetadata` block under either spelling, top-level or nested. */\r\nfunction findUsageMetadata(root: Record<string, unknown>): Record<string, unknown> | undefined {\r\n for (const k of [\"usageMetadata\", \"usage_metadata\"]) {\r\n if (isObject(root[k])) return root[k] as Record<string, unknown>;\r\n }\r\n // Some hosts nest the model response (with its usage) under a `response` /\r\n // `modelResponse` envelope — probe one level down, best-effort.\r\n for (const k of [\"response\", \"modelResponse\", \"model_response\"]) {\r\n const nested = root[k];\r\n if (isObject(nested)) {\r\n for (const mk of [\"usageMetadata\", \"usage_metadata\"]) {\r\n if (isObject(nested[mk])) return nested[mk] as Record<string, unknown>;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n/** A registered PlatformId, or \"unknown\" when the id is not one we know. */\r\nconst KNOWN_PLATFORMS: ReadonlySet<string> = new Set<PlatformId>([\r\n \"claude-code\", \"codex\", \"cursor\", \"vscode-copilot\", \"jetbrains-copilot\",\r\n \"copilot-cli\", \"gemini-cli\", \"opencode\", \"kilo\", \"kilo-cli\", \"warp\", \"hermes\",\r\n \"openclaw\", \"zed\", \"antigravity\", \"antigravity-cli\", \"kiro\", \"qwen-code\",\r\n \"kimi\", \"pi\", \"omp\", \"droid\", \"roo-code\", \"trae\", \"amp\", \"codebuff\", \"mux\",\r\n \"crush\", \"goose\", \"synthetic\", \"unknown\",\r\n]);\r\n\r\nfunction asPlatformId(id: string): PlatformId {\r\n return (KNOWN_PLATFORMS.has(id) ? id : \"unknown\") as PlatformId;\r\n}\r\n\r\n/**\r\n * Record one host-native model turn. Parses the host's `usageMetadata`, maps it to\r\n * a DISTINCT `model_turn` `ToolEventRecord` (confidence `host-native`, toolName\r\n * `\"*\"`), and appends it to the shared telemetry store. NEVER throws and never\r\n * blocks the turn: every failure path resolves to {@link NOOP} (exit 0, nothing\r\n * recorded).\r\n */\r\nexport async function runUsageEvent(\r\n opts: RunUsageEventOptions,\r\n): Promise<RunUsageEventResult> {\r\n try {\r\n // Global telemetry kill switch is honored by the store's append (no-op when\r\n // AGENT_CONNECTOR_TELEMETRY=0); we still parse cheaply and let append drop it.\r\n const trimmed = opts.stdin.trim();\r\n if (trimmed === \"\") return NOOP;\r\n\r\n let raw: unknown;\r\n try {\r\n raw = JSON.parse(trimmed);\r\n } catch {\r\n return NOOP; // malformed payload → fail-open, record nothing\r\n }\r\n if (!isObject(raw)) return NOOP;\r\n\r\n const meta = findUsageMetadata(raw);\r\n if (meta === undefined) return NOOP;\r\n\r\n const promptTokens = tokenField(meta, [\"promptTokenCount\", \"prompt_token_count\"]);\r\n const candidates = tokenField(meta, [\"candidatesTokenCount\", \"candidates_token_count\"]);\r\n const cached = tokenField(meta, [\"cachedContentTokenCount\", \"cached_content_token_count\"]);\r\n const thoughts = tokenField(meta, [\"thoughtsTokenCount\", \"thoughts_token_count\"]);\r\n\r\n // promptTokenCount is cache-INCLUSIVE (Gemini-family semantics, mirrored by\r\n // the antigravity-shared usage reader): net fresh input = prompt - cached.\r\n const inputTokens = Math.max(0, promptTokens - Math.min(cached, promptTokens));\r\n // Output = generated candidates + reasoning (\"thoughts\") tokens.\r\n const outputTokens = candidates + thoughts;\r\n\r\n // A turn with no measurable tokens is not worth a row.\r\n if (inputTokens === 0 && outputTokens === 0) return NOOP;\r\n\r\n // Identity: prefer payload session/cwd; fall back to process.cwd() for the\r\n // project key so a turn always lands in a stable project partition.\r\n const sessionId =\r\n firstStr(raw, [\"session_id\", \"sessionId\", \"conversationId\", \"conversation_id\"]) ?? \"\";\r\n const cwd = firstStr(raw, [\"cwd\", \"workspace\", \"projectDir\", \"project_dir\"]) ?? process.cwd();\r\n const id = projectIdentity(cwd);\r\n\r\n const record: ToolEventRecord = {\r\n id: newRecordId(0),\r\n ts: Date.now(),\r\n connectorId: opts.connectorId,\r\n toolName: \"*\",\r\n scope: \"model_turn\",\r\n hostPlatform: asPlatformId(opts.platformId),\r\n sessionId,\r\n projectKey: id.key,\r\n projectDir: id.dir,\r\n inputTokens,\r\n outputTokens,\r\n confidenceSource: \"host-native\",\r\n isError: false,\r\n };\r\n\r\n const store = openStore({});\r\n try {\r\n store.append(record);\r\n } finally {\r\n try {\r\n store.close();\r\n } catch {\r\n /* best-effort flush */\r\n }\r\n }\r\n return { exitCode: 0, recorded: true };\r\n } catch {\r\n // Fail-open: a host-native usage enricher must never surface an error.\r\n return NOOP;\r\n }\r\n}\r\n\r\nexport default runUsageEvent;\r\n","/**\r\n * runtime/statusline-entrypoint — the universal statusline (HUD) renderer.\r\n *\r\n * A statusline-supporting host points its status line config at the single stable\r\n * home binary (`<homeBin> statusline <platformId> --connector <id>`, built by\r\n * core/spawn.buildHomeBinStatuslineCommand). The CLI reads stdin and calls\r\n * {@link runStatusline} with the parsed flags + the raw stdin string. This module:\r\n *\r\n * 1. Loads the registered connector (live render handler) and the host adapter.\r\n * 2. Parses the host's raw status payload into a normalized StatuslineContext.\r\n * 3. Calls the connector's render(ctx) and coerces the result to a string.\r\n * 4. Formats the line into the host's native status reply (exit code + stdout).\r\n *\r\n * FAIL-SAFE is the contract (NOT fail-open with carve-outs like hooks): a status\r\n * line is decorative — it must NEVER wedge the host or spew an error/stack trace\r\n * into the status bar. So ANY error path — bad payload, missing connector,\r\n * throwing render, adapter without statusline support — returns exit 0 with NO\r\n * stdout (an empty status line), never a non-zero exit and never partial output.\r\n *\r\n * NOTE (follow-up): no telemetry is recorded for statusline renders in v1 (out of\r\n * scope). When added, it MUST stay inside the same fail-safe envelope.\r\n */\r\n\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport { log } from \"../core/logger.js\";\r\nimport {\r\n loadRegisteredConnector,\r\n readRegisteredMeta,\r\n} from \"../core/load-connector.js\";\r\nimport { loadAdapter } from \"../adapters/registry.js\";\r\nimport {\r\n attachLazyTelemetryUsage,\r\n buildTelemetryAccessor,\r\n} from \"./telemetry-accessor.js\";\r\n\r\n/** Flags + stdin the CLI hands to {@link runStatusline}. */\r\nexport interface RunStatuslineOptions {\r\n /** Host platform id from the command (`statusline <platformId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>`. */\r\n connectorId: string;\r\n /** Raw stdin payload (host-native status JSON). Empty string is tolerated → `{}`. */\r\n stdin: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into exit code + stdout/stderr. */\r\nexport interface RunStatuslineResult {\r\n exitCode: number;\r\n stdout?: string;\r\n stderr?: string;\r\n}\r\n\r\n/** The fail-safe result: exit 0, no output (an empty status line). */\r\nconst EMPTY: RunStatuslineResult = { exitCode: 0 };\r\n\r\n/**\r\n * Tolerantly parse the host's stdin payload. Empty / whitespace-only input is a\r\n * legitimate \"no payload\" signal and resolves to `{}`. Malformed JSON also\r\n * degrades to `{}` rather than throwing — fail-safe is the contract.\r\n */\r\nfunction parseStdin(stdin: string): unknown {\r\n const trimmed = stdin.trim();\r\n if (trimmed === \"\") return {};\r\n try {\r\n return JSON.parse(trimmed);\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Render one host status-line invocation. Always resolves (never rejects): every\r\n * failure path returns the empty {@link EMPTY} result so the CLI exits cleanly\r\n * with an empty status line. See the module header for the fail-safe contract.\r\n */\r\nexport async function runStatusline(\r\n opts: RunStatuslineOptions,\r\n): Promise<RunStatuslineResult> {\r\n const { platformId, connectorId, stdin } = opts;\r\n\r\n try {\r\n const connector = await loadRegisteredConnector(connectorId);\r\n const adapter = await loadAdapter(platformId);\r\n\r\n // Nothing to render: no statusline declared, or the host adapter has no\r\n // statusline runtime support (parse/format pair). Empty line, exit 0.\r\n if (\r\n !connector.statusline ||\r\n typeof connector.statusline.render !== \"function\" ||\r\n !adapter ||\r\n !adapter.parseStatusInput ||\r\n !adapter.formatStatusOutput\r\n ) {\r\n return EMPTY;\r\n }\r\n\r\n const raw = parseStdin(stdin);\r\n const ctx = adapter.parseStatusInput(raw);\r\n // The command carries the authoritative connector id; stamp it so render()\r\n // sees the connector it was dispatched for.\r\n ctx.connectorId = connectorId;\r\n // capabilities is REQUIRED on StatuslineContext. claude-code's parseStatusInput\r\n // sets it, but a future/third-party adapter could omit it — backfill so the\r\n // runtime guarantee matches the type (mirrors the simulate harness). Never\r\n // let render() see undefined capabilities while the type claims it is present.\r\n if (ctx.capabilities == null) ctx.capabilities = adapter.capabilities;\r\n // Recover the install scope from the registered metadata (sync) and stamp it\r\n // onto the ctx — scope is an install-time property the entrypoint has no\r\n // other access to. Undefined when the meta carries none. Also expose the\r\n // per-connector telemetry usage accessor (lazy, fail-safe to zeros).\r\n ctx.scope = readRegisteredMeta(connectorId)?.scope;\r\n ctx.telemetry = buildTelemetryAccessor(connectorId);\r\n // Keep `ctx.usage` synchronous for render functions, but compute it only if\r\n // the render actually reads the property. Status lines refresh frequently,\r\n // and the NDJSON backend has to scan the store for an all-time summary.\r\n attachLazyTelemetryUsage(ctx, connectorId);\r\n\r\n // Per-host render override: when rendering for host X, `hosts[X].render`\r\n // wins over the top-level render; a host not listed (or a per-host entry\r\n // that is somehow not a function) falls back to the top-level render.\r\n // Selection NEVER throws — fail-safe is preserved.\r\n const perHost = connector.statusline.hosts?.[platformId as PlatformId]?.render;\r\n const render =\r\n typeof perHost === \"function\" ? perHost : connector.statusline.render;\r\n\r\n const rendered = await render(ctx);\r\n // Coerce: a non-string return (number, accidental object) is stringified so\r\n // a misbehaving render never crashes the format step. null/undefined → \"\".\r\n const line = rendered == null ? \"\" : String(rendered);\r\n\r\n const reply = adapter.formatStatusOutput(line);\r\n return {\r\n exitCode: reply.exitCode,\r\n ...(reply.stdout !== undefined ? { stdout: reply.stdout } : {}),\r\n ...(reply.stderr !== undefined ? { stderr: reply.stderr } : {}),\r\n };\r\n } catch (err) {\r\n // FAIL-SAFE: a status line must never wedge the host or surface an error.\r\n // Log for diagnostics (stderr of the home binary — not the status bar) and\r\n // return the empty line.\r\n const message = err instanceof Error ? err.message : String(err);\r\n log.error(`statusline ${platformId} (${connectorId}) failed:`, message);\r\n return EMPTY;\r\n }\r\n}\r\n\r\nexport default runStatusline;\r\n","/**\r\n * runtime/action-entrypoint — the universal user-invokable action dispatcher.\r\n *\r\n * A host-native affordance (workflow, task, slash command, keybinding) or a\n * manual command points at the single stable home binary (`<homeBin> action\n * <platformId> <actionId> --connector <id>`, built by\n * core/spawn.buildHomeBinActionCommand). The CLI parses the flags and calls\n * {@link runAction}. This module:\n *\r\n * 1. Loads the registered connector (live run handler) and the host adapter.\r\n * 2. Builds the shared {@link HostCtx} (host + the adapter's capabilities; NO\r\n * stdin — an action takes no host payload, unlike a hook or status line).\r\n * 3. Finds the action by id, resolves the per-host run override, runs it, and\r\n * prints the optional result.message.\r\n *\r\n * USER-TRIGGERED ERROR SEMANTICS (the key difference from hooks/statusline):\r\n * actions are invoked DELIBERATELY by a user, so errors are SURFACED, never\r\n * failed silently. An unknown action id or a throwing run → exit 1 + a stderr\r\n * message. (Hooks fail-open to exit 0; the statusline fail-safes to an empty\r\n * line — both are passive surfaces a host fires automatically. An action is not:\r\n * swallowing its failure would leave the user staring at nothing, unable to\r\n * tell the action ran.)\r\n *\r\n * NOTE: no telemetry is recorded for action runs in v1 (out of scope). Adapters\n * with a verified native trigger surface emit host affordances; unsupported\n * hosts can still call this stable dispatch verb manually.\n */\n\r\nimport type {\r\n HostCtx,\r\n PlatformCapabilities,\r\n PlatformId,\r\n} from \"../core/types.js\";\r\nimport {\r\n loadRegisteredConnector,\r\n readRegisteredMeta,\r\n} from \"../core/load-connector.js\";\r\nimport { loadAdapter, REGISTERED_PLATFORM_IDS } from \"../adapters/registry.js\";\r\nimport { buildTelemetryAccessor } from \"./telemetry-accessor.js\";\r\n\r\n/** Flags the CLI hands to {@link runAction} (no stdin — actions take no payload). */\r\nexport interface RunActionOptions {\r\n /** Host platform id from the command (`action <platformId> <actionId> …`). */\r\n platformId: string;\r\n /** Connector id from `--connector <id>`. */\r\n connectorId: string;\r\n /** The action id positional (`action <platformId> <actionId> …`). */\r\n actionId: string;\r\n}\r\n\r\n/** Process-level result the CLI translates into exit code + stdout/stderr. */\r\nexport interface RunActionResult {\r\n exitCode: number;\r\n stdout?: string;\r\n stderr?: string;\r\n}\r\n\r\n/**\r\n * Minimal all-false capabilities for the fallback ctx when the host adapter is\r\n * unknown/unregistered. The action still runs (it takes no host payload), but\r\n * branching on `ctx.capabilities` reads every flag as off — no affordance is\r\n * advertised for a host we cannot describe.\r\n */\r\nconst EMPTY_CAPABILITIES: PlatformCapabilities = {\r\n preToolUse: false,\r\n postToolUse: false,\r\n preCompact: false,\r\n sessionStart: false,\r\n sessionEnd: false,\r\n userPromptSubmit: false,\r\n stop: false,\r\n notification: false,\r\n canModifyArgs: false,\r\n canModifyOutput: false,\r\n canInjectSessionContext: false,\r\n transports: [],\r\n};\r\n\r\n/**\r\n * Dispatch one user-invokable action. Always resolves (never rejects): every\r\n * path returns a concrete {@link RunActionResult} so the CLI can exit cleanly,\r\n * but UNLIKE the hook/statusline runtimes an error resolves to exit 1 + a stderr\r\n * message (actions are user-triggered — surface the failure). See the module\r\n * header for the user-triggered error contract.\r\n */\r\nexport async function runAction(\r\n opts: RunActionOptions,\r\n): Promise<RunActionResult> {\r\n const { platformId, connectorId, actionId } = opts;\r\n\r\n let connector;\r\n try {\r\n connector = await loadRegisteredConnector(connectorId);\r\n } catch (err) {\r\n // A user asked to run an action on a connector we cannot load — surface it\r\n // (do NOT fail-open: the user would otherwise see nothing and assume it ran).\r\n const message = err instanceof Error ? err.message : String(err);\r\n return { exitCode: 1, stderr: message };\r\n }\r\n\r\n const action = connector.actions.find((a) => a.id === actionId);\r\n if (!action) {\r\n return {\r\n exitCode: 1,\r\n stderr: `no action \"${actionId}\" on connector ${connectorId}`,\r\n };\r\n }\r\n\r\n // Build the shared HostCtx. capabilities come from the adapter; an unknown\r\n // adapter still runs with the minimal ctx (an action takes no host payload).\r\n const adapter = await loadAdapter(platformId).catch(() => undefined);\r\n const host: PlatformId = REGISTERED_PLATFORM_IDS.has(platformId as PlatformId)\r\n ? (platformId as PlatformId)\r\n : \"unknown\";\r\n const ctx: HostCtx = {\r\n host,\r\n capabilities: adapter?.capabilities ?? EMPTY_CAPABILITIES,\r\n // Recover the install scope from the registered metadata (sync) — scope is\r\n // an install-time property the entrypoint otherwise has no access to —\r\n // and expose the per-connector telemetry usage accessor (lazy, fail-safe).\r\n scope: readRegisteredMeta(connectorId)?.scope,\r\n telemetry: buildTelemetryAccessor(connectorId),\r\n };\r\n\r\n // Per-host run override: when running for host X, `hosts[X].run` wins over the\r\n // top-level run; a host not listed (or a per-host entry that is somehow not a\r\n // function) falls back to the top-level run.\r\n const perHost = action.hosts?.[platformId as PlatformId]?.run;\r\n const run = typeof perHost === \"function\" ? perHost : action.run;\r\n\r\n try {\r\n const result = await run(ctx);\r\n const message = result?.message;\r\n if (typeof message === \"string\" && message !== \"\") {\r\n return { exitCode: 0, stdout: message };\r\n }\r\n // void / no message → success with no output.\r\n return { exitCode: 0 };\r\n } catch (err) {\r\n // USER-TRIGGERED: a throwing action surfaces its failure (exit 1 + stderr),\r\n // never a silent fail-open. This is the documented difference from\r\n // hooks/statusline.\r\n const message = err instanceof Error ? err.message : String(err);\r\n return {\r\n exitCode: 1,\r\n stderr: `action \"${actionId}\" failed: ${message}`,\r\n };\r\n }\r\n}\r\n\r\nexport default runAction;\r\n"],"mappings":"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","names":["args","isObject"]}
|