@ken-jo/agent-connector 0.1.0

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.
Files changed (203) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +6 -0
  3. package/README.md +348 -0
  4. package/dist/amp-QSFH2V7Y.js +217 -0
  5. package/dist/amp-QSFH2V7Y.js.map +1 -0
  6. package/dist/amp-TULUPXXL.js +237 -0
  7. package/dist/amp-TULUPXXL.js.map +1 -0
  8. package/dist/antigravity-CX2YLSY7.js +17 -0
  9. package/dist/antigravity-CX2YLSY7.js.map +1 -0
  10. package/dist/antigravity-STHZWMP3.js +171 -0
  11. package/dist/antigravity-STHZWMP3.js.map +1 -0
  12. package/dist/antigravity-cli-P6HADOAO.js +121 -0
  13. package/dist/antigravity-cli-P6HADOAO.js.map +1 -0
  14. package/dist/antigravity-cli-YQDFVV4U.js +86 -0
  15. package/dist/antigravity-cli-YQDFVV4U.js.map +1 -0
  16. package/dist/chunk-54EMKTTX.js +191 -0
  17. package/dist/chunk-54EMKTTX.js.map +1 -0
  18. package/dist/chunk-7L6ITC4T.js +54 -0
  19. package/dist/chunk-7L6ITC4T.js.map +1 -0
  20. package/dist/chunk-7MSDGHJW.js +316 -0
  21. package/dist/chunk-7MSDGHJW.js.map +1 -0
  22. package/dist/chunk-BCHWFTV4.js +196 -0
  23. package/dist/chunk-BCHWFTV4.js.map +1 -0
  24. package/dist/chunk-DBQMX75U.js +36 -0
  25. package/dist/chunk-DBQMX75U.js.map +1 -0
  26. package/dist/chunk-EXLS7BSI.js +29 -0
  27. package/dist/chunk-EXLS7BSI.js.map +1 -0
  28. package/dist/chunk-JNM3TPLX.js +593 -0
  29. package/dist/chunk-JNM3TPLX.js.map +1 -0
  30. package/dist/chunk-JWNT5KW7.js +197 -0
  31. package/dist/chunk-JWNT5KW7.js.map +1 -0
  32. package/dist/chunk-KHO5WNTP.js +30 -0
  33. package/dist/chunk-KHO5WNTP.js.map +1 -0
  34. package/dist/chunk-LTT56GI3.js +155 -0
  35. package/dist/chunk-LTT56GI3.js.map +1 -0
  36. package/dist/chunk-MEH7GC7R.js +111 -0
  37. package/dist/chunk-MEH7GC7R.js.map +1 -0
  38. package/dist/chunk-MQPNU2CY.js +64 -0
  39. package/dist/chunk-MQPNU2CY.js.map +1 -0
  40. package/dist/chunk-OPXAP3AC.js +12 -0
  41. package/dist/chunk-OPXAP3AC.js.map +1 -0
  42. package/dist/chunk-RK6VBLXP.js +50 -0
  43. package/dist/chunk-RK6VBLXP.js.map +1 -0
  44. package/dist/chunk-TIIP3RG2.js +420 -0
  45. package/dist/chunk-TIIP3RG2.js.map +1 -0
  46. package/dist/chunk-TRKWUNO4.js +702 -0
  47. package/dist/chunk-TRKWUNO4.js.map +1 -0
  48. package/dist/chunk-TRQKHP7D.js +93 -0
  49. package/dist/chunk-TRQKHP7D.js.map +1 -0
  50. package/dist/chunk-WCETQWWK.js +59 -0
  51. package/dist/chunk-WCETQWWK.js.map +1 -0
  52. package/dist/chunk-WV63X7IK.js +357 -0
  53. package/dist/chunk-WV63X7IK.js.map +1 -0
  54. package/dist/chunk-XD7MY6HB.js +343 -0
  55. package/dist/chunk-XD7MY6HB.js.map +1 -0
  56. package/dist/chunk-XNAM7F35.js +276 -0
  57. package/dist/chunk-XNAM7F35.js.map +1 -0
  58. package/dist/chunk-XUCWLJY5.js +238 -0
  59. package/dist/chunk-XUCWLJY5.js.map +1 -0
  60. package/dist/chunk-YNZU6PAV.js +800 -0
  61. package/dist/chunk-YNZU6PAV.js.map +1 -0
  62. package/dist/chunk-YT43MUSJ.js +146 -0
  63. package/dist/chunk-YT43MUSJ.js.map +1 -0
  64. package/dist/claude-code-HKDV7T32.js +637 -0
  65. package/dist/claude-code-HKDV7T32.js.map +1 -0
  66. package/dist/claude-code-W74MNTAC.js +652 -0
  67. package/dist/claude-code-W74MNTAC.js.map +1 -0
  68. package/dist/cli/sdk.d.ts +54 -0
  69. package/dist/cli/sdk.js +82 -0
  70. package/dist/cli/sdk.js.map +1 -0
  71. package/dist/cli.d.ts +2 -0
  72. package/dist/cli.js +15 -0
  73. package/dist/cli.js.map +1 -0
  74. package/dist/codebuff-3PMZJJHP.js +307 -0
  75. package/dist/codebuff-3PMZJJHP.js.map +1 -0
  76. package/dist/codebuff-QX57FJDN.js +220 -0
  77. package/dist/codebuff-QX57FJDN.js.map +1 -0
  78. package/dist/codex-JFQTS6LU.js +593 -0
  79. package/dist/codex-JFQTS6LU.js.map +1 -0
  80. package/dist/codex-Q3ATRRX3.js +364 -0
  81. package/dist/codex-Q3ATRRX3.js.map +1 -0
  82. package/dist/copilot-cli-MTCGHZ2T.js +622 -0
  83. package/dist/copilot-cli-MTCGHZ2T.js.map +1 -0
  84. package/dist/copilot-cli-SJGIXVSD.js +369 -0
  85. package/dist/copilot-cli-SJGIXVSD.js.map +1 -0
  86. package/dist/crush-I7PK3FGI.js +360 -0
  87. package/dist/crush-I7PK3FGI.js.map +1 -0
  88. package/dist/crush-LN5QFFR2.js +183 -0
  89. package/dist/crush-LN5QFFR2.js.map +1 -0
  90. package/dist/cursor-4TMXKJOZ.js +603 -0
  91. package/dist/cursor-4TMXKJOZ.js.map +1 -0
  92. package/dist/cursor-QZ6MTO74.js +194 -0
  93. package/dist/cursor-QZ6MTO74.js.map +1 -0
  94. package/dist/detect-WIAGVYS4.js +68 -0
  95. package/dist/detect-WIAGVYS4.js.map +1 -0
  96. package/dist/doctor-EZW2K4NI.js +372 -0
  97. package/dist/doctor-EZW2K4NI.js.map +1 -0
  98. package/dist/droid-KN6VRMMT.js +424 -0
  99. package/dist/droid-KN6VRMMT.js.map +1 -0
  100. package/dist/droid-W5WF5XEX.js +224 -0
  101. package/dist/droid-W5WF5XEX.js.map +1 -0
  102. package/dist/gemini-cli-CIRW37TU.js +369 -0
  103. package/dist/gemini-cli-CIRW37TU.js.map +1 -0
  104. package/dist/gemini-cli-Y35FFK4M.js +705 -0
  105. package/dist/gemini-cli-Y35FFK4M.js.map +1 -0
  106. package/dist/goose-A3M5GODH.js +212 -0
  107. package/dist/goose-A3M5GODH.js.map +1 -0
  108. package/dist/goose-ZTGTSUFJ.js +480 -0
  109. package/dist/goose-ZTGTSUFJ.js.map +1 -0
  110. package/dist/hermes-H2KV44GK.js +470 -0
  111. package/dist/hermes-H2KV44GK.js.map +1 -0
  112. package/dist/hermes-ZYLMOFLZ.js +196 -0
  113. package/dist/hermes-ZYLMOFLZ.js.map +1 -0
  114. package/dist/hook-YVDILAMZ.js +75 -0
  115. package/dist/hook-YVDILAMZ.js.map +1 -0
  116. package/dist/index.d.ts +22 -0
  117. package/dist/index.js +10 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/install-HQRYZOQ2.js +60 -0
  120. package/dist/install-HQRYZOQ2.js.map +1 -0
  121. package/dist/jetbrains-copilot-HWA3DMH7.js +633 -0
  122. package/dist/jetbrains-copilot-HWA3DMH7.js.map +1 -0
  123. package/dist/kilo-NSWAVP6P.js +235 -0
  124. package/dist/kilo-NSWAVP6P.js.map +1 -0
  125. package/dist/kilo-QXJRCSLT.js +384 -0
  126. package/dist/kilo-QXJRCSLT.js.map +1 -0
  127. package/dist/kilo-cli-EAQTHXUW.js +587 -0
  128. package/dist/kilo-cli-EAQTHXUW.js.map +1 -0
  129. package/dist/kilo-cli-EVBKUODA.js +160 -0
  130. package/dist/kilo-cli-EVBKUODA.js.map +1 -0
  131. package/dist/kimi-EI3UM3ZV.js +155 -0
  132. package/dist/kimi-EI3UM3ZV.js.map +1 -0
  133. package/dist/kimi-GQ7VXNYT.js +423 -0
  134. package/dist/kimi-GQ7VXNYT.js.map +1 -0
  135. package/dist/kiro-UCLSLBW2.js +217 -0
  136. package/dist/kiro-UCLSLBW2.js.map +1 -0
  137. package/dist/kiro-VQTT6LO2.js +451 -0
  138. package/dist/kiro-VQTT6LO2.js.map +1 -0
  139. package/dist/leaderboard-K6ON3SWW.js +137 -0
  140. package/dist/leaderboard-K6ON3SWW.js.map +1 -0
  141. package/dist/mux-T2TV4CIQ.js +211 -0
  142. package/dist/mux-T2TV4CIQ.js.map +1 -0
  143. package/dist/mux-ZMLVAXOO.js +96 -0
  144. package/dist/mux-ZMLVAXOO.js.map +1 -0
  145. package/dist/omp-PB4VDKS6.js +586 -0
  146. package/dist/omp-PB4VDKS6.js.map +1 -0
  147. package/dist/openclaw-ETN2M63O.js +751 -0
  148. package/dist/openclaw-ETN2M63O.js.map +1 -0
  149. package/dist/openclaw-IYA7ASL6.js +150 -0
  150. package/dist/openclaw-IYA7ASL6.js.map +1 -0
  151. package/dist/opencode-FZ33JKUZ.js +734 -0
  152. package/dist/opencode-FZ33JKUZ.js.map +1 -0
  153. package/dist/opencode-HWT3RSMN.js +216 -0
  154. package/dist/opencode-HWT3RSMN.js.map +1 -0
  155. package/dist/package-DLOVE2E4.js +1132 -0
  156. package/dist/package-DLOVE2E4.js.map +1 -0
  157. package/dist/pi-CIU2QHT4.js +208 -0
  158. package/dist/pi-CIU2QHT4.js.map +1 -0
  159. package/dist/pi-UFX2OYFV.js +139 -0
  160. package/dist/pi-UFX2OYFV.js.map +1 -0
  161. package/dist/qwen-code-5POCNU6P.js +573 -0
  162. package/dist/qwen-code-5POCNU6P.js.map +1 -0
  163. package/dist/qwen-code-W7NUCDEN.js +134 -0
  164. package/dist/qwen-code-W7NUCDEN.js.map +1 -0
  165. package/dist/roo-code-IOIUXRDE.js +242 -0
  166. package/dist/roo-code-IOIUXRDE.js.map +1 -0
  167. package/dist/roo-code-ZLKH4A7N.js +229 -0
  168. package/dist/roo-code-ZLKH4A7N.js.map +1 -0
  169. package/dist/runtime/index.d.ts +157 -0
  170. package/dist/runtime/index.js +20 -0
  171. package/dist/runtime/index.js.map +1 -0
  172. package/dist/serve-HVWWY4B6.js +65 -0
  173. package/dist/serve-HVWWY4B6.js.map +1 -0
  174. package/dist/status-FE7TECZD.js +128 -0
  175. package/dist/status-FE7TECZD.js.map +1 -0
  176. package/dist/synthetic-UKR6SMGS.js +178 -0
  177. package/dist/synthetic-UKR6SMGS.js.map +1 -0
  178. package/dist/telemetry-36GESKQQ.js +349 -0
  179. package/dist/telemetry-36GESKQQ.js.map +1 -0
  180. package/dist/trae-JSNDZFKL.js +204 -0
  181. package/dist/trae-JSNDZFKL.js.map +1 -0
  182. package/dist/trae-PA26DPBW.js +157 -0
  183. package/dist/trae-PA26DPBW.js.map +1 -0
  184. package/dist/types-CYUB1OTr.d.ts +427 -0
  185. package/dist/uninstall-IGCKNOSF.js +72 -0
  186. package/dist/uninstall-IGCKNOSF.js.map +1 -0
  187. package/dist/upgrade-JV2VK242.js +104 -0
  188. package/dist/upgrade-JV2VK242.js.map +1 -0
  189. package/dist/usage-6ER6EMEY.js +324 -0
  190. package/dist/usage-6ER6EMEY.js.map +1 -0
  191. package/dist/usage-event-JKBI6XCF.js +48 -0
  192. package/dist/usage-event-JKBI6XCF.js.map +1 -0
  193. package/dist/vscode-copilot-CK3NO54M.js +715 -0
  194. package/dist/vscode-copilot-CK3NO54M.js.map +1 -0
  195. package/dist/warp-JNQA7PBU.js +126 -0
  196. package/dist/warp-JNQA7PBU.js.map +1 -0
  197. package/dist/warp-QNVDXOG4.js +199 -0
  198. package/dist/warp-QNVDXOG4.js.map +1 -0
  199. package/dist/zed-NNNX5MNT.js +272 -0
  200. package/dist/zed-NNNX5MNT.js.map +1 -0
  201. package/dist/zed-VRJKWYUR.js +209 -0
  202. package/dist/zed-VRJKWYUR.js.map +1 -0
  203. package/package.json +79 -0
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ openSqlite
4
+ } from "./chunk-YT43MUSJ.js";
5
+ import {
6
+ firstExistingRoot
7
+ } from "./chunk-JWNT5KW7.js";
8
+ import {
9
+ emptyTokens,
10
+ inferProvider
11
+ } from "./chunk-XD7MY6HB.js";
12
+
13
+ // src/usage/readers/hermes.ts
14
+ import { join } from "path";
15
+ var PLATFORM_ID = "hermes";
16
+ var DEFAULT_PROVIDER = "hermes";
17
+ var HERMES_AGENT_NAME = "Hermes Agent";
18
+ var QUERY = `
19
+ SELECT
20
+ id,
21
+ model,
22
+ billing_provider,
23
+ started_at,
24
+ message_count,
25
+ input_tokens,
26
+ output_tokens,
27
+ cache_read_tokens,
28
+ cache_write_tokens,
29
+ reasoning_tokens,
30
+ estimated_cost_usd,
31
+ actual_cost_usd
32
+ FROM sessions
33
+ WHERE model IS NOT NULL
34
+ AND TRIM(model) != ''
35
+ AND (
36
+ COALESCE(input_tokens, 0) > 0 OR
37
+ COALESCE(output_tokens, 0) > 0 OR
38
+ COALESCE(cache_read_tokens, 0) > 0 OR
39
+ COALESCE(cache_write_tokens, 0) > 0 OR
40
+ COALESCE(reasoning_tokens, 0) > 0 OR
41
+ COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0
42
+ )
43
+ `;
44
+ function resolveDbPath() {
45
+ const home = process.env.HERMES_HOME;
46
+ if (home != null && home.trim() !== "") {
47
+ const candidate = join(home.trim(), "state.db");
48
+ return candidate;
49
+ }
50
+ return firstExistingRoot(PLATFORM_ID);
51
+ }
52
+ function canonicalizeProviderSegment(segment) {
53
+ const normalized = segment.trim().replace(/\/+$/, "").toLowerCase().replace(/-/g, "_");
54
+ if (normalized.startsWith("<") && normalized.endsWith(">")) return void 0;
55
+ switch (normalized) {
56
+ case "":
57
+ case "unknown":
58
+ return void 0;
59
+ case "x_ai":
60
+ case "xai":
61
+ return "xai";
62
+ case "z_ai":
63
+ case "zai":
64
+ return "zai";
65
+ case "moonshot":
66
+ case "moonshotai":
67
+ return "moonshotai";
68
+ case "meta":
69
+ case "meta_llama":
70
+ return "meta_llama";
71
+ case "azure":
72
+ case "azure_ai":
73
+ return "azure_ai";
74
+ case "anthropic":
75
+ case "vertex":
76
+ case "vertex_ai":
77
+ return "anthropic";
78
+ case "together":
79
+ case "together_ai":
80
+ return "together_ai";
81
+ case "fireworks":
82
+ case "fireworks_ai":
83
+ return "fireworks_ai";
84
+ case "google":
85
+ case "gemini":
86
+ return "google";
87
+ case "openai":
88
+ case "openai_codex":
89
+ return "openai";
90
+ case "minimax":
91
+ case "minimaxai":
92
+ case "minimax_ai":
93
+ return "minimax";
94
+ case "mistral":
95
+ case "mistralai":
96
+ return "mistralai";
97
+ case "ai21":
98
+ return "ai21";
99
+ default:
100
+ if (/[0-9]/.test(normalized)) return void 0;
101
+ return normalized;
102
+ }
103
+ }
104
+ function canonicalProvider(raw) {
105
+ for (const segment of raw.trim().replace(/\/+$/, "").split("/")) {
106
+ const tag = canonicalizeProviderSegment(segment);
107
+ if (tag !== void 0) return tag;
108
+ if (segment.includes(".")) {
109
+ for (const dotted of segment.split(".")) {
110
+ const dottedTag = canonicalizeProviderSegment(dotted);
111
+ if (dottedTag !== void 0) return dottedTag;
112
+ }
113
+ }
114
+ }
115
+ return void 0;
116
+ }
117
+ function resolvedProvider(billingProvider, modelId) {
118
+ if (typeof billingProvider === "string") {
119
+ const trimmed = billingProvider.trim();
120
+ if (trimmed !== "") {
121
+ const canonical = canonicalProvider(trimmed);
122
+ if (canonical !== void 0) return canonical;
123
+ }
124
+ }
125
+ return inferProvider(modelId) ?? DEFAULT_PROVIDER;
126
+ }
127
+ function tokenCell(v) {
128
+ const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
129
+ if (!Number.isFinite(n)) return 0;
130
+ return Math.max(0, Math.trunc(n));
131
+ }
132
+ function floatOrNull(v) {
133
+ const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
134
+ return Number.isFinite(n) ? n : null;
135
+ }
136
+ function timestampSecsToMs(timestamp) {
137
+ return timestamp > 1e12 ? Math.trunc(timestamp) : Math.trunc(timestamp * 1e3);
138
+ }
139
+ var hermesReader = {
140
+ platformId: PLATFORM_ID,
141
+ kind: "local",
142
+ async read({ sinceMs }) {
143
+ const dbPath = resolveDbPath();
144
+ if (dbPath === void 0) return [];
145
+ const db = await openSqlite(dbPath);
146
+ if (db === null) return [];
147
+ try {
148
+ const rows = db.all(QUERY);
149
+ const records = [];
150
+ for (const raw of rows) {
151
+ const row = raw;
152
+ const sessionId = row.id;
153
+ if (typeof sessionId !== "string" || sessionId === "") continue;
154
+ const modelId = row.model;
155
+ if (typeof modelId !== "string" || modelId.trim() === "") continue;
156
+ const startedAt = floatOrNull(row.started_at) ?? 0;
157
+ const ts = timestampSecsToMs(startedAt);
158
+ if (sinceMs !== void 0 && ts < sinceMs) continue;
159
+ const providerId = resolvedProvider(row.billing_provider, modelId);
160
+ const tokens = emptyTokens();
161
+ tokens.input = tokenCell(row.input_tokens);
162
+ tokens.output = tokenCell(row.output_tokens);
163
+ tokens.cacheRead = tokenCell(row.cache_read_tokens);
164
+ tokens.cacheWrite = tokenCell(row.cache_write_tokens);
165
+ tokens.reasoning = tokenCell(row.reasoning_tokens);
166
+ const actual = floatOrNull(row.actual_cost_usd);
167
+ const estimated = floatOrNull(row.estimated_cost_usd);
168
+ const cost = Math.max(0, actual ?? estimated ?? 0);
169
+ const messageCount = tokenCell(row.message_count);
170
+ const record = {
171
+ platformId: PLATFORM_ID,
172
+ modelId,
173
+ providerId,
174
+ sessionId,
175
+ tokens,
176
+ cost,
177
+ ts,
178
+ messageCount,
179
+ dedupKey: sessionId,
180
+ // one row per session → session id is the dedup key
181
+ confidence: "host-reported",
182
+ agent: HERMES_AGENT_NAME
183
+ };
184
+ records.push(record);
185
+ }
186
+ return records;
187
+ } finally {
188
+ db.close();
189
+ }
190
+ }
191
+ };
192
+ var hermes_default = hermesReader;
193
+ export {
194
+ hermes_default as default
195
+ };
196
+ //# sourceMappingURL=hermes-ZYLMOFLZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/readers/hermes.ts"],"sourcesContent":["/**\n * usage/readers/hermes — Hermes Agent usage reader (SQLite, sessions table).\n *\n * Faithful port of tokscale sessions/hermes.rs. Hermes stores one aggregated row\n * per session in a `sessions` table inside a single SQLite database:\n * • ~/.hermes/state.db\n * • $HERMES_HOME/state.db (when HERMES_HOME is set, non-empty)\n * (the AGENT_CONNECTOR_HERMES_DIR override + the ~/.hermes default are resolved by\n * paths.ts hostRoots(\"hermes\"); HERMES_HOME is honored here, ahead of those, to\n * match the Rust storage-path spec which the fixed paths.ts does not encode.)\n *\n * One SELECT pulls every session that carries a model and at least one token/cost\n * signal (port of the Rust query verbatim):\n * SELECT id, model, billing_provider, started_at, message_count,\n * input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,\n * reasoning_tokens, estimated_cost_usd, actual_cost_usd\n * FROM sessions\n * WHERE model IS NOT NULL AND TRIM(model) != ''\n * AND ( COALESCE(input_tokens,0) > 0\n * OR COALESCE(output_tokens,0) > 0\n * OR COALESCE(cache_read_tokens,0) > 0\n * OR COALESCE(cache_write_tokens,0) > 0\n * OR COALESCE(reasoning_tokens,0) > 0\n * OR COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0 )\n *\n * Token extraction (flat columns, no JSON nesting — each NULL → 0, clamped ≥ 0):\n * input = input_tokens\n * output = output_tokens\n * cacheRead = cache_read_tokens\n * cacheWrite = cache_write_tokens\n * reasoning = reasoning_tokens\n * Cost = actual_cost_usd ?? estimated_cost_usd ?? 0 (clamped ≥ 0, prefer actual).\n *\n * Model: the `model` column (the WHERE already drops null/blank). Provider (port of\n * resolved_provider): canonical_provider() of a non-blank `billing_provider`, else\n * inferProvider(model), else \"hermes\". Timestamp: `started_at` (f64) disambiguated\n * seconds-vs-milliseconds (> 1e12 → ms as-is, else × 1000). Session id = the `id`\n * column, which is also the dedup key (one row per session). messageCount =\n * `message_count` (clamped ≥ 0). agent fixed to \"Hermes Agent\". No project/workspace\n * in the schema. Confidence is \"host-reported\".\n *\n * Fail-open: db missing/locked/unreadable → openSqlite returns null → []; a bad row\n * is skipped, never thrown.\n */\n\nimport { join } from \"node:path\";\n\nimport type { UsageReader, UsageRecord } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { inferProvider } from \"../normalize.js\";\nimport { firstExistingRoot } from \"../paths.js\";\nimport { openSqlite } from \"../sqlite.js\";\n\nconst PLATFORM_ID = \"hermes\" as const;\nconst DEFAULT_PROVIDER = \"hermes\";\nconst HERMES_AGENT_NAME = \"Hermes Agent\";\n\n/** The session columns we read (everything optional / unknown off the row). */\ninterface HermesRow {\n id?: unknown;\n model?: unknown;\n billing_provider?: unknown;\n started_at?: unknown;\n message_count?: unknown;\n input_tokens?: unknown;\n output_tokens?: unknown;\n cache_read_tokens?: unknown;\n cache_write_tokens?: unknown;\n reasoning_tokens?: unknown;\n estimated_cost_usd?: unknown;\n actual_cost_usd?: unknown;\n}\n\nconst QUERY = `\n SELECT\n id,\n model,\n billing_provider,\n started_at,\n message_count,\n input_tokens,\n output_tokens,\n cache_read_tokens,\n cache_write_tokens,\n reasoning_tokens,\n estimated_cost_usd,\n actual_cost_usd\n FROM sessions\n WHERE model IS NOT NULL\n AND TRIM(model) != ''\n AND (\n COALESCE(input_tokens, 0) > 0 OR\n COALESCE(output_tokens, 0) > 0 OR\n COALESCE(cache_read_tokens, 0) > 0 OR\n COALESCE(cache_write_tokens, 0) > 0 OR\n COALESCE(reasoning_tokens, 0) > 0 OR\n COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0\n )\n`;\n\n// ─────────────────────────────────────────────────────────────────────────\n// DB path resolution (honor $HERMES_HOME, ahead of paths.ts defaults)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve the Hermes state DB. The Rust spec lists both `~/.hermes/state.db` and\n * `$HERMES_HOME/state.db`; the fixed paths.ts only encodes the former (+ the\n * AGENT_CONNECTOR_HERMES_DIR override), so we honor HERMES_HOME first here.\n * Returns the first existing candidate, or undefined when none is present.\n */\nfunction resolveDbPath(): string | undefined {\n const home = process.env.HERMES_HOME;\n if (home != null && home.trim() !== \"\") {\n const candidate = join(home.trim(), \"state.db\");\n // existsSync is checked by openSqlite (returns null on a missing file), but we\n // still need an explicit candidate; let firstExistingRoot cover the default.\n return candidate;\n }\n return firstExistingRoot(PLATFORM_ID);\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Provider resolution (port of provider_identity.rs canonical_provider)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Canonicalize a single provider segment (port of canonicalize_provider_segment):\n * trim, drop a trailing slash, lowercase, `-`→`_`; reject `<…>` placeholders, the\n * empty/`unknown` segment, and unknown segments that contain a digit (those are\n * model-name fragments). Returns the canonical id or undefined.\n */\nfunction canonicalizeProviderSegment(segment: string): string | undefined {\n const normalized = segment.trim().replace(/\\/+$/, \"\").toLowerCase().replace(/-/g, \"_\");\n if (normalized.startsWith(\"<\") && normalized.endsWith(\">\")) return undefined;\n switch (normalized) {\n case \"\":\n case \"unknown\":\n return undefined;\n case \"x_ai\":\n case \"xai\":\n return \"xai\";\n case \"z_ai\":\n case \"zai\":\n return \"zai\";\n case \"moonshot\":\n case \"moonshotai\":\n return \"moonshotai\";\n case \"meta\":\n case \"meta_llama\":\n return \"meta_llama\";\n case \"azure\":\n case \"azure_ai\":\n return \"azure_ai\";\n case \"anthropic\":\n case \"vertex\":\n case \"vertex_ai\":\n return \"anthropic\";\n case \"together\":\n case \"together_ai\":\n return \"together_ai\";\n case \"fireworks\":\n case \"fireworks_ai\":\n return \"fireworks_ai\";\n case \"google\":\n case \"gemini\":\n return \"google\";\n case \"openai\":\n case \"openai_codex\":\n return \"openai\";\n case \"minimax\":\n case \"minimaxai\":\n case \"minimax_ai\":\n return \"minimax\";\n case \"mistral\":\n case \"mistralai\":\n return \"mistralai\";\n case \"ai21\":\n return \"ai21\";\n default:\n if (/[0-9]/.test(normalized)) return undefined;\n return normalized;\n }\n}\n\n/**\n * Port of canonical_provider: the first canonical tag from `provider_tags(raw)`\n * (split on '/', and for any dotted segment also try its dot-parts), or undefined\n * when no segment canonicalizes — so the resolver can fall through to model\n * inference, matching the Rust `Option<String>` semantics.\n */\nfunction canonicalProvider(raw: string): string | undefined {\n for (const segment of raw.trim().replace(/\\/+$/, \"\").split(\"/\")) {\n const tag = canonicalizeProviderSegment(segment);\n if (tag !== undefined) return tag;\n if (segment.includes(\".\")) {\n for (const dotted of segment.split(\".\")) {\n const dottedTag = canonicalizeProviderSegment(dotted);\n if (dottedTag !== undefined) return dottedTag;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Resolve the provider (port of resolved_provider): canonical_provider of a\n * non-blank `billing_provider`, else inferProvider(model), else \"hermes\".\n */\nfunction resolvedProvider(billingProvider: unknown, modelId: string): string {\n if (typeof billingProvider === \"string\") {\n const trimmed = billingProvider.trim();\n if (trimmed !== \"\") {\n const canonical = canonicalProvider(trimmed);\n if (canonical !== undefined) return canonical;\n }\n }\n return inferProvider(modelId) ?? DEFAULT_PROVIDER;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Numbers & timestamps\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Coerce an unknown SQLite cell to an integer ≥ 0 (port of `Option<i64>?.unwrap_or(0).max(0)`). */\nfunction tokenCell(v: unknown): number {\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\n if (!Number.isFinite(n)) return 0;\n return Math.max(0, Math.trunc(n));\n}\n\n/** Coerce an unknown SQLite cell to a finite float, or null when absent/garbage. */\nfunction floatOrNull(v: unknown): number | null {\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Disambiguate `started_at` (f64) seconds-vs-milliseconds (port of\n * timestamp_secs_to_ms): values already in ms (> 1e12) pass through truncated to\n * an integer; smaller values are treated as seconds and scaled × 1000.\n */\nfunction timestampSecsToMs(timestamp: number): number {\n return timestamp > 1e12 ? Math.trunc(timestamp) : Math.trunc(timestamp * 1000);\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Reader\n// ─────────────────────────────────────────────────────────────────────────\n\n/** The Hermes Agent usage reader singleton. */\nconst hermesReader: UsageReader = {\n platformId: PLATFORM_ID,\n kind: \"local\",\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\n const dbPath = resolveDbPath();\n if (dbPath === undefined) return []; // no state.db → fail-open\n\n const db = await openSqlite(dbPath);\n if (db === null) return []; // missing / locked / unreadable / non-sqlite → fail-open\n\n try {\n const rows = db.all(QUERY); // bad SQL / schema mismatch → [] (fail-open)\n const records: UsageRecord[] = [];\n\n for (const raw of rows) {\n const row = raw as HermesRow;\n\n // id and model are read as non-null strings in the Rust decode; the WHERE\n // clause already enforces a non-blank model, but we mirror the decode by\n // skipping any row whose id/model is not a usable string.\n const sessionId = row.id;\n if (typeof sessionId !== \"string\" || sessionId === \"\") continue;\n\n const modelId = row.model;\n if (typeof modelId !== \"string\" || modelId.trim() === \"\") continue;\n\n const startedAt = floatOrNull(row.started_at) ?? 0;\n const ts = timestampSecsToMs(startedAt);\n if (sinceMs !== undefined && ts < sinceMs) continue;\n\n const providerId = resolvedProvider(row.billing_provider, modelId);\n\n const tokens = emptyTokens();\n tokens.input = tokenCell(row.input_tokens);\n tokens.output = tokenCell(row.output_tokens);\n tokens.cacheRead = tokenCell(row.cache_read_tokens);\n tokens.cacheWrite = tokenCell(row.cache_write_tokens);\n tokens.reasoning = tokenCell(row.reasoning_tokens);\n\n // Cost: prefer actual, fall back to estimated, default 0 — clamped ≥ 0.\n const actual = floatOrNull(row.actual_cost_usd);\n const estimated = floatOrNull(row.estimated_cost_usd);\n const cost = Math.max(0, actual ?? estimated ?? 0);\n\n // message_count: Option<i32>.unwrap_or(0).max(0).\n const messageCount = tokenCell(row.message_count);\n\n const record: UsageRecord = {\n platformId: PLATFORM_ID,\n modelId,\n providerId,\n sessionId,\n tokens,\n cost,\n ts,\n messageCount,\n dedupKey: sessionId, // one row per session → session id is the dedup key\n confidence: \"host-reported\",\n agent: HERMES_AGENT_NAME,\n };\n records.push(record);\n }\n\n return records;\n } finally {\n db.close();\n }\n },\n};\n\nexport default hermesReader;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ fail
4
+ } from "./chunk-54EMKTTX.js";
5
+ import {
6
+ runHook
7
+ } from "./chunk-YNZU6PAV.js";
8
+ import "./chunk-BCHWFTV4.js";
9
+ import "./chunk-KHO5WNTP.js";
10
+ import "./chunk-WCETQWWK.js";
11
+ import "./chunk-XUCWLJY5.js";
12
+ import "./chunk-LTT56GI3.js";
13
+ import "./chunk-XNAM7F35.js";
14
+ import "./chunk-MEH7GC7R.js";
15
+ import "./chunk-TRQKHP7D.js";
16
+
17
+ // src/cli/commands/hook.ts
18
+ import { parseArgs } from "util";
19
+ var HOOK_EVENTS = /* @__PURE__ */ new Set([
20
+ "SessionStart",
21
+ "SessionEnd",
22
+ "UserPromptSubmit",
23
+ "PreToolUse",
24
+ "PostToolUse",
25
+ "PreCompact",
26
+ "Stop",
27
+ "Notification"
28
+ ]);
29
+ async function readAll(stream) {
30
+ const chunks = [];
31
+ for await (const chunk of stream) {
32
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
33
+ }
34
+ return Buffer.concat(chunks).toString("utf8");
35
+ }
36
+ async function run(argv) {
37
+ const { values, positionals } = parseArgs({
38
+ args: argv,
39
+ options: {
40
+ connector: { type: "string" }
41
+ },
42
+ allowPositionals: true
43
+ });
44
+ const platformId = positionals[0];
45
+ const event = positionals[1];
46
+ if (!platformId || !event) {
47
+ return fail("usage: agent-connector hook <platform> <event> --connector <id>");
48
+ }
49
+ if (!HOOK_EVENTS.has(event)) {
50
+ return fail(`unknown hook event "${event}"`);
51
+ }
52
+ const connectorId = values.connector;
53
+ if (!connectorId || connectorId.trim() === "") {
54
+ return fail("hook requires --connector <id>");
55
+ }
56
+ const stdin = await readAll(process.stdin);
57
+ const reply = await runHook({
58
+ platformId,
59
+ event,
60
+ connectorId,
61
+ stdin
62
+ });
63
+ if (reply.stdout !== void 0 && reply.stdout !== "") {
64
+ process.stdout.write(reply.stdout);
65
+ }
66
+ if (reply.stderr !== void 0 && reply.stderr !== "") {
67
+ process.stderr.write(reply.stderr.endsWith("\n") ? reply.stderr : `${reply.stderr}
68
+ `);
69
+ }
70
+ process.exit(reply.exitCode);
71
+ }
72
+ export {
73
+ run
74
+ };
75
+ //# sourceMappingURL=hook-YVDILAMZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/hook.ts"],"sourcesContent":["/**\n * cli/commands/hook — the universal json-stdio hook entrypoint.\n *\n * agent-connector hook <platform> <event> --connector <id>\n *\n * This is the single command every host's hook config points at (via the stable\n * home binary). It reads the ENTIRE host payload from stdin, dispatches through\n * runHook, writes any stdout/stderr the adapter produced, and exits with the\n * adapter's exit code (the host interprets it as allow/deny/etc.).\n *\n * Fail-open is the runtime's contract: runHook never rejects, so a framework or\n * handler bug can't wedge a host's tool call.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport type { HookEventName } from \"../../core/types.js\";\nimport { runHook } from \"../../runtime/index.js\";\nimport { fail } from \"../app.js\";\n\nconst HOOK_EVENTS: ReadonlySet<string> = new Set<HookEventName>([\n \"SessionStart\",\n \"SessionEnd\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"Stop\",\n \"Notification\",\n]);\n\n/** Read all of a readable stream to a UTF-8 string. */\nasync function readAll(stream: NodeJS.ReadStream): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const platformId = positionals[0];\n const event = positionals[1];\n if (!platformId || !event) {\n return fail(\"usage: agent-connector hook <platform> <event> --connector <id>\");\n }\n if (!HOOK_EVENTS.has(event)) {\n return fail(`unknown hook event \"${event}\"`);\n }\n const connectorId = values.connector;\n if (!connectorId || connectorId.trim() === \"\") {\n return fail(\"hook requires --connector <id>\");\n }\n\n // Read the entire host payload before dispatching.\n const stdin = await readAll(process.stdin);\n\n const reply = await runHook({\n platformId,\n event: event as HookEventName,\n connectorId,\n stdin,\n });\n\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\n process.stdout.write(reply.stdout);\n }\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\n }\n\n process.exit(reply.exitCode);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAcA,SAAS,iBAAiB;AAM1B,IAAM,cAAmC,oBAAI,IAAmB;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,eAAe,QAAQ,QAA4C;AACjE,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK;AAAA,EACpE;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAC9C;AAEA,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,QAAQ,YAAY,CAAC;AAC3B,MAAI,CAAC,cAAc,CAAC,OAAO;AACzB,WAAO,KAAK,iEAAiE;AAAA,EAC/E;AACA,MAAI,CAAC,YAAY,IAAI,KAAK,GAAG;AAC3B,WAAO,KAAK,uBAAuB,KAAK,GAAG;AAAA,EAC7C;AACA,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,eAAe,YAAY,KAAK,MAAM,IAAI;AAC7C,WAAO,KAAK,gCAAgC;AAAA,EAC9C;AAGA,QAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK;AAEzC,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,MAAM;AAAA,EACnC;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;AAEA,UAAQ,KAAK,MAAM,QAAQ;AAC7B;","names":[]}
@@ -0,0 +1,22 @@
1
+ import { C as ConnectorConfig, R as ResolvedConnector } from './types-CYUB1OTr.js';
2
+ export { A as AuthSpec, a as ChangeRecord, D as DetectedPlatform, b as DiagnosticResult, E as EventPayloadMap, H as HookDefinition, c as HookEventName, d as HookParadigm, e as HookResponse, f as HooksConfig, I as InstallResult, g as InstallScope, N as NotificationEvent, P as PlatformCapabilities, h as PlatformId, i as PlatformOverride, j as PostToolUseEvent, k as PreCompactEvent, l as PreToolUseEvent, S as ServerDef, m as SessionEndEvent, n as SessionStartEvent, o as StopEvent, T as TelemetryConfig, p as ToolFilter, q as Transport, U as UserPromptSubmitEvent } from './types-CYUB1OTr.js';
3
+
4
+ /**
5
+ * core/define-connector — the public write-once entry point.
6
+ *
7
+ * Validates a ConnectorConfig and normalizes it into a ResolvedConnector with
8
+ * every optional field resolved to a default. Validation is intentionally
9
+ * dependency-free (no zod) to keep the single-binary install lean.
10
+ */
11
+
12
+ /** Thrown on an invalid connector configuration. */
13
+ declare class ConnectorConfigError extends Error {
14
+ constructor(message: string);
15
+ }
16
+ /**
17
+ * Validate + normalize a connector definition.
18
+ * Returns a ResolvedConnector that adapters and the CLI consume directly.
19
+ */
20
+ declare function defineConnector(config: ConnectorConfig): ResolvedConnector;
21
+
22
+ export { ConnectorConfig, ConnectorConfigError, ResolvedConnector, defineConnector };
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ConnectorConfigError,
4
+ defineConnector
5
+ } from "./chunk-XNAM7F35.js";
6
+ export {
7
+ ConnectorConfigError,
8
+ defineConnector
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ installConnector
4
+ } from "./chunk-7MSDGHJW.js";
5
+ import {
6
+ fail,
7
+ parseScope,
8
+ parseTargets,
9
+ print,
10
+ renderInstallResult
11
+ } from "./chunk-54EMKTTX.js";
12
+ import "./chunk-KHO5WNTP.js";
13
+ import "./chunk-XUCWLJY5.js";
14
+ import {
15
+ findConnectorConfig,
16
+ loadConnectorFromPath
17
+ } from "./chunk-LTT56GI3.js";
18
+ import "./chunk-XNAM7F35.js";
19
+ import "./chunk-TRQKHP7D.js";
20
+
21
+ // src/cli/commands/install.ts
22
+ import { parseArgs } from "util";
23
+ async function run(argv) {
24
+ const { values } = parseArgs({
25
+ args: argv,
26
+ options: {
27
+ scope: { type: "string", default: "user" },
28
+ targets: { type: "string" },
29
+ connector: { type: "string" },
30
+ project: { type: "string" },
31
+ "dry-run": { type: "boolean", default: false }
32
+ },
33
+ allowPositionals: false
34
+ });
35
+ const projectDir = values.project ?? process.cwd();
36
+ const configPath = values.connector ?? findConnectorConfig(projectDir);
37
+ if (!configPath) {
38
+ return fail(
39
+ "no connector config found. Pass --connector <path> or add an agent-connector.config.{mjs,js,json} to your project."
40
+ );
41
+ }
42
+ const scope = parseScope(values.scope);
43
+ if (scope == null) return fail(`invalid --scope "${values.scope}" (use user|project)`);
44
+ const { connector, modulePath } = await loadConnectorFromPath(configPath);
45
+ const targets = parseTargets(values.targets);
46
+ const result = await installConnector({
47
+ connector,
48
+ modulePath,
49
+ scope,
50
+ projectDir,
51
+ dryRun: values["dry-run"],
52
+ ...targets ? { targets } : {}
53
+ });
54
+ print(renderInstallResult(result, "install"));
55
+ return result.changes.some((c) => c.action === "warn") ? 1 : 0;
56
+ }
57
+ export {
58
+ run
59
+ };
60
+ //# sourceMappingURL=install-HQRYZOQ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/install.ts"],"sourcesContent":["/**\n * cli/commands/install — deploy a connector across its target platforms.\n *\n * Resolves the connector config (--connector <path>, else findConnectorConfig\n * walking up from the project dir), loads it into a live ResolvedConnector, and\n * hands it to the installer orchestration. The resulting ChangeRecords are\n * rendered as a readable diff; --dry-run renders the plan without writing.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport { installConnector } from \"../../core/installer.js\";\nimport { findConnectorConfig, loadConnectorFromPath } from \"../../core/load-connector.js\";\nimport { fail, parseScope, parseTargets, print, renderInstallResult } from \"../app.js\";\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n scope: { type: \"string\", default: \"user\" },\n targets: { type: \"string\" },\n connector: { type: \"string\" },\n project: { type: \"string\" },\n \"dry-run\": { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n const configPath = values.connector ?? findConnectorConfig(projectDir);\n if (!configPath) {\n return fail(\n \"no connector config found. Pass --connector <path> or add an \" +\n \"agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n\n const scope = parseScope(values.scope);\n if (scope == null) return fail(`invalid --scope \"${values.scope}\" (use user|project)`);\n\n const { connector, modulePath } = await loadConnectorFromPath(configPath);\n const targets = parseTargets(values.targets);\n\n const result = await installConnector({\n connector,\n modulePath,\n scope,\n projectDir,\n dryRun: values[\"dry-run\"],\n ...(targets ? { targets } : {}),\n });\n\n print(renderInstallResult(result, \"install\"));\n return result.changes.some((c) => c.action === \"warn\") ? 1 : 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AASA,SAAS,iBAAiB;AAM1B,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,OAAO,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,OAAO,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,MACzC,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,SAAS;AAAA,MAC5B,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,IAC/C;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AACjD,QAAM,aAAa,OAAO,aAAa,oBAAoB,UAAU;AACrE,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,MAAI,SAAS,KAAM,QAAO,KAAK,oBAAoB,OAAO,KAAK,sBAAsB;AAErF,QAAM,EAAE,WAAW,WAAW,IAAI,MAAM,sBAAsB,UAAU;AACxE,QAAM,UAAU,aAAa,OAAO,OAAO;AAE3C,QAAM,SAAS,MAAM,iBAAiB;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,SAAS;AAAA,IACxB,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC;AAED,QAAM,oBAAoB,QAAQ,SAAS,CAAC;AAC5C,SAAO,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,IAAI;AAC/D;","names":[]}