@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.4

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 (384) hide show
  1. package/LICENSE +0 -0
  2. package/native-manifest.json +1088 -134
  3. package/package.json +160 -1
  4. package/plugins/UPSTREAM-LICENSES.md +113 -0
  5. package/plugins/_provider-icons/LICENSE +21 -0
  6. package/plugins/_provider-icons/NOTICE +12 -0
  7. package/plugins/_provider-icons/licenses/CodexBar-MIT.txt +21 -0
  8. package/plugins/_provider-icons/licenses/LobeHub-MIT.txt +21 -0
  9. package/plugins/_provider-icons/licenses/UsageStat-Bar-MIT.txt +21 -0
  10. package/plugins/_provider-icons/manifest.json +1219 -0
  11. package/plugins/_provider-icons/provenance.json +269 -0
  12. package/plugins/_provider-icons/source.json +4 -0
  13. package/plugins/abacus-ai/icon-color.svg +18 -0
  14. package/plugins/abacus-ai/icon.svg +0 -0
  15. package/plugins/abacus-ai/plugin.js +0 -0
  16. package/plugins/abacus-ai/plugin.json +0 -0
  17. package/plugins/aiand/icon.svg +6 -0
  18. package/plugins/aiand/plugin.js +108 -0
  19. package/plugins/aiand/plugin.json +22 -0
  20. package/plugins/aixy/LICENSE +21 -0
  21. package/plugins/aixy/plugin.js +261 -0
  22. package/plugins/aixy/plugin.json +24 -0
  23. package/plugins/alibaba/icon-color.svg +0 -0
  24. package/plugins/alibaba/icon.svg +0 -0
  25. package/plugins/alibaba/plugin.js +0 -0
  26. package/plugins/alibaba/plugin.json +0 -0
  27. package/plugins/alibaba-token-plan/icon-color.svg +0 -0
  28. package/plugins/alibaba-token-plan/icon.svg +0 -0
  29. package/plugins/alibaba-token-plan/plugin.js +0 -0
  30. package/plugins/alibaba-token-plan/plugin.json +0 -0
  31. package/plugins/amp/icon-color.svg +0 -0
  32. package/plugins/amp/icon-conflict.svg +0 -0
  33. package/plugins/amp/icon.svg +0 -0
  34. package/plugins/amp/plugin.js +0 -0
  35. package/plugins/amp/plugin.json +0 -0
  36. package/plugins/antigravity/icon-color.svg +0 -0
  37. package/plugins/antigravity/icon-conflict.svg +0 -0
  38. package/plugins/antigravity/icon.svg +0 -0
  39. package/plugins/antigravity/plugin.js +136 -46
  40. package/plugins/antigravity/plugin.json +0 -0
  41. package/plugins/antigravity-cli/icon-color.svg +1 -0
  42. package/plugins/antigravity-cli/icon.svg +1 -3
  43. package/plugins/antigravity-cli/plugin.js +11 -15
  44. package/plugins/antigravity-cli/plugin.json +0 -0
  45. package/plugins/antigravity-ide/icon-color.svg +1 -0
  46. package/plugins/antigravity-ide/icon.svg +1 -3
  47. package/plugins/antigravity-ide/plugin.js +0 -0
  48. package/plugins/antigravity-ide/plugin.json +0 -0
  49. package/plugins/atlascloud/LICENSE +21 -0
  50. package/plugins/atlascloud/icon-color.svg +1 -0
  51. package/plugins/atlascloud/icon.svg +1 -0
  52. package/plugins/atlascloud/plugin.js +49 -0
  53. package/plugins/atlascloud/plugin.json +23 -0
  54. package/plugins/augment/icon-color.svg +14 -0
  55. package/plugins/augment/icon.svg +0 -0
  56. package/plugins/augment/plugin.js +0 -0
  57. package/plugins/augment/plugin.json +0 -0
  58. package/plugins/aws-bedrock/icon-color.svg +0 -0
  59. package/plugins/aws-bedrock/icon.svg +0 -0
  60. package/plugins/aws-bedrock/plugin.js +0 -0
  61. package/plugins/aws-bedrock/plugin.json +0 -0
  62. package/plugins/azure-openai/icon-color.svg +0 -0
  63. package/plugins/azure-openai/icon.svg +0 -0
  64. package/plugins/azure-openai/plugin.js +0 -0
  65. package/plugins/azure-openai/plugin.json +0 -0
  66. package/plugins/bifrost/LICENSE +21 -0
  67. package/plugins/bifrost/plugin.js +361 -0
  68. package/plugins/bifrost/plugin.json +23 -0
  69. package/plugins/chutes/icon.svg +0 -0
  70. package/plugins/chutes/plugin.js +0 -0
  71. package/plugins/chutes/plugin.json +0 -0
  72. package/plugins/claude/icon-color.svg +0 -0
  73. package/plugins/claude/icon.svg +0 -0
  74. package/plugins/claude/plugin.js +358 -161
  75. package/plugins/claude/plugin.json +1 -1
  76. package/plugins/clawrouter/icon.svg +7 -0
  77. package/plugins/clawrouter/plugin.js +45 -0
  78. package/plugins/clawrouter/plugin.json +22 -0
  79. package/plugins/clinepass/icon.svg +4 -0
  80. package/plugins/clinepass/plugin.js +87 -0
  81. package/plugins/clinepass/plugin.json +23 -0
  82. package/plugins/codebuddy/plugin.js +331 -0
  83. package/plugins/codebuddy/plugin.json +30 -0
  84. package/plugins/codebuff/icon-color.svg +92 -0
  85. package/plugins/codebuff/icon.svg +0 -0
  86. package/plugins/codebuff/plugin.js +0 -0
  87. package/plugins/codebuff/plugin.json +0 -0
  88. package/plugins/coderabbit/plugin.js +25 -0
  89. package/plugins/coderabbit/plugin.json +12 -0
  90. package/plugins/codex/icon-color.svg +0 -0
  91. package/plugins/codex/icon.svg +0 -0
  92. package/plugins/codex/plugin.js +8 -2
  93. package/plugins/codex/plugin.json +0 -0
  94. package/plugins/command-code/icon-color.svg +3 -0
  95. package/plugins/command-code/icon.svg +0 -0
  96. package/plugins/command-code/plugin.js +14 -3
  97. package/plugins/command-code/plugin.json +0 -0
  98. package/plugins/copilot/icon-color.svg +0 -0
  99. package/plugins/copilot/icon.svg +1 -1
  100. package/plugins/copilot/plugin.js +61 -9
  101. package/plugins/copilot/plugin.json +4 -1
  102. package/plugins/crof/icon-color.svg +3 -0
  103. package/plugins/crof/icon.svg +0 -0
  104. package/plugins/crof/plugin.js +0 -0
  105. package/plugins/crof/plugin.json +0 -0
  106. package/plugins/crofai/icon-color.svg +3 -0
  107. package/plugins/crofai/icon.svg +2 -15
  108. package/plugins/crofai/plugin.js +0 -0
  109. package/plugins/crofai/plugin.json +0 -0
  110. package/plugins/cursor/icon-color.svg +1 -0
  111. package/plugins/cursor/icon-conflict.svg +0 -0
  112. package/plugins/cursor/icon.svg +0 -0
  113. package/plugins/cursor/plugin.js +46 -9
  114. package/plugins/cursor/plugin.json +3 -2
  115. package/plugins/cursor-nightly/icon.png +0 -0
  116. package/plugins/cursor-nightly/plugin.js +45 -8
  117. package/plugins/cursor-nightly/plugin.json +3 -2
  118. package/plugins/deepgram/icon.svg +0 -0
  119. package/plugins/deepgram/plugin.js +0 -0
  120. package/plugins/deepgram/plugin.json +0 -0
  121. package/plugins/deepinfra/icon-color.svg +1 -0
  122. package/plugins/deepinfra/icon.svg +1 -0
  123. package/plugins/deepinfra/plugin.js +97 -0
  124. package/plugins/deepinfra/plugin.json +28 -0
  125. package/plugins/deepseek/icon-color.svg +0 -0
  126. package/plugins/deepseek/icon.svg +0 -0
  127. package/plugins/deepseek/plugin.js +150 -59
  128. package/plugins/deepseek/plugin.json +3 -1
  129. package/plugins/devin/icon.svg +0 -0
  130. package/plugins/devin/plugin.js +114 -0
  131. package/plugins/devin/plugin.json +2 -1
  132. package/plugins/devpass/LICENSE +21 -0
  133. package/plugins/devpass/plugin.js +115 -0
  134. package/plugins/devpass/plugin.json +23 -0
  135. package/plugins/doubao/icon-color.svg +0 -0
  136. package/plugins/doubao/icon.svg +0 -0
  137. package/plugins/doubao/plugin.js +0 -0
  138. package/plugins/doubao/plugin.json +0 -0
  139. package/plugins/droid/icon.svg +0 -0
  140. package/plugins/droid/plugin.json +2 -1
  141. package/plugins/elevenlabs/icon-color.svg +4 -0
  142. package/plugins/elevenlabs/icon.svg +0 -0
  143. package/plugins/elevenlabs/plugin.js +17 -2
  144. package/plugins/elevenlabs/plugin.json +0 -0
  145. package/plugins/factory/icon-color.svg +1 -0
  146. package/plugins/factory/icon-conflict.svg +0 -0
  147. package/plugins/factory/icon.svg +0 -0
  148. package/plugins/factory/plugin.js +38 -14
  149. package/plugins/factory/plugin.json +2 -1
  150. package/plugins/fireworks-ai/icon-color.svg +1 -0
  151. package/plugins/fireworks-ai/icon.svg +1 -6
  152. package/plugins/fireworks-ai/plugin.js +0 -0
  153. package/plugins/fireworks-ai/plugin.json +0 -0
  154. package/plugins/gemini/icon-color.svg +0 -0
  155. package/plugins/gemini/icon.svg +0 -0
  156. package/plugins/gemini/plugin.js +0 -0
  157. package/plugins/gemini/plugin.json +0 -0
  158. package/plugins/gemini-apps/LICENSE +22 -0
  159. package/plugins/gemini-apps/icon-color.svg +1 -0
  160. package/plugins/gemini-apps/icon.svg +1 -0
  161. package/plugins/gemini-apps/plugin.js +470 -0
  162. package/plugins/gemini-apps/plugin.json +19 -0
  163. package/plugins/gitkraken/LICENSE +21 -0
  164. package/plugins/gitkraken/plugin.js +153 -0
  165. package/plugins/gitkraken/plugin.json +24 -0
  166. package/plugins/grok/icon-color.svg +1 -0
  167. package/plugins/grok/icon.svg +0 -0
  168. package/plugins/grok/plugin.js +30 -5
  169. package/plugins/grok/plugin.json +3 -1
  170. package/plugins/groqcloud/icon-color.svg +1 -0
  171. package/plugins/groqcloud/icon.svg +0 -0
  172. package/plugins/groqcloud/plugin.js +0 -0
  173. package/plugins/groqcloud/plugin.json +0 -0
  174. package/plugins/helmcode/LICENSE +21 -0
  175. package/plugins/helmcode/plugin.js +188 -0
  176. package/plugins/helmcode/plugin.json +24 -0
  177. package/plugins/huggingface/LICENSE +21 -0
  178. package/plugins/huggingface/icon-color.svg +1 -0
  179. package/plugins/huggingface/icon.svg +1 -0
  180. package/plugins/huggingface/plugin.js +293 -0
  181. package/plugins/huggingface/plugin.json +25 -0
  182. package/plugins/hyper/LICENSE +21 -0
  183. package/plugins/hyper/plugin.js +131 -0
  184. package/plugins/hyper/plugin.json +26 -0
  185. package/plugins/ibmbob/icon.svg +23 -0
  186. package/plugins/ibmbob/plugin.js +61 -0
  187. package/plugins/ibmbob/plugin.json +22 -0
  188. package/plugins/jetbrains-ai-assistant/icon-color.svg +0 -0
  189. package/plugins/jetbrains-ai-assistant/icon-conflict.svg +0 -0
  190. package/plugins/jetbrains-ai-assistant/icon.svg +0 -0
  191. package/plugins/jetbrains-ai-assistant/plugin.js +0 -0
  192. package/plugins/jetbrains-ai-assistant/plugin.json +0 -0
  193. package/plugins/kilo/icon-color.svg +1 -0
  194. package/plugins/kilo/icon.svg +0 -0
  195. package/plugins/kilo/plugin.js +0 -0
  196. package/plugins/kilo/plugin.json +0 -0
  197. package/plugins/kimi/icon-color.svg +0 -0
  198. package/plugins/kimi/icon-conflict.svg +0 -0
  199. package/plugins/kimi/icon.svg +0 -0
  200. package/plugins/kimi/plugin.js +122 -141
  201. package/plugins/kimi/plugin.json +5 -2
  202. package/plugins/kimi-k2/icon-color.svg +0 -0
  203. package/plugins/kimi-k2/icon.svg +0 -0
  204. package/plugins/kimi-k2/plugin.js +0 -0
  205. package/plugins/kimi-k2/plugin.json +0 -0
  206. package/plugins/kiro/icon-color.svg +0 -0
  207. package/plugins/kiro/icon-conflict.svg +0 -0
  208. package/plugins/kiro/icon.svg +0 -0
  209. package/plugins/kiro/plugin.js +49 -10
  210. package/plugins/kiro/plugin.json +3 -1
  211. package/plugins/litellm/icon.svg +0 -0
  212. package/plugins/litellm/plugin.js +54 -3
  213. package/plugins/litellm/plugin.json +0 -0
  214. package/plugins/llm-proxy/icon.svg +0 -0
  215. package/plugins/llm-proxy/plugin.js +0 -0
  216. package/plugins/llm-proxy/plugin.json +0 -0
  217. package/plugins/llmman/LICENSE +21 -0
  218. package/plugins/llmman/plugin.js +133 -0
  219. package/plugins/llmman/plugin.json +23 -0
  220. package/plugins/longcat/icon-color.svg +1 -0
  221. package/plugins/longcat/icon.svg +1 -0
  222. package/plugins/longcat/plugin.js +182 -0
  223. package/plugins/longcat/plugin.json +23 -0
  224. package/plugins/manus/icon-color.svg +6 -0
  225. package/plugins/manus/icon.svg +0 -0
  226. package/plugins/manus/plugin.js +0 -0
  227. package/plugins/manus/plugin.json +0 -0
  228. package/plugins/mimo/icon-color.svg +4 -0
  229. package/plugins/mimo/icon.svg +4 -1
  230. package/plugins/mimo/plugin.js +0 -0
  231. package/plugins/mimo/plugin.json +0 -0
  232. package/plugins/minimax/icon-color.svg +0 -0
  233. package/plugins/minimax/icon-conflict.svg +0 -0
  234. package/plugins/minimax/icon.svg +0 -0
  235. package/plugins/minimax/plugin.js +25 -31
  236. package/plugins/minimax/plugin.json +0 -0
  237. package/plugins/mistral/icon-color.svg +0 -0
  238. package/plugins/mistral/icon.svg +0 -0
  239. package/plugins/mistral/plugin.js +110 -5
  240. package/plugins/mistral/plugin.json +0 -0
  241. package/plugins/moonshot/icon-color.svg +1 -0
  242. package/plugins/moonshot/icon.svg +0 -0
  243. package/plugins/moonshot/plugin.js +8 -6
  244. package/plugins/moonshot/plugin.json +0 -0
  245. package/plugins/muse/LICENSE +21 -0
  246. package/plugins/muse/plugin.js +319 -0
  247. package/plugins/muse/plugin.json +26 -0
  248. package/plugins/nanogpt/icon-color.svg +0 -0
  249. package/plugins/nanogpt/icon.svg +0 -0
  250. package/plugins/nanogpt/plugin.js +0 -0
  251. package/plugins/nanogpt/plugin.json +0 -0
  252. package/plugins/neuralwatt/icon.svg +0 -0
  253. package/plugins/neuralwatt/plugin.js +0 -0
  254. package/plugins/neuralwatt/plugin.json +0 -0
  255. package/plugins/notion/icon.svg +1 -0
  256. package/plugins/notion/plugin.js +282 -0
  257. package/plugins/notion/plugin.json +29 -0
  258. package/plugins/nous/LICENSE +21 -0
  259. package/plugins/nous/icon-color.svg +1 -0
  260. package/plugins/nous/icon.svg +1 -0
  261. package/plugins/nous/plugin.js +124 -0
  262. package/plugins/nous/plugin.json +24 -0
  263. package/plugins/ollama/icon-color.svg +1 -0
  264. package/plugins/ollama/icon.svg +0 -0
  265. package/plugins/ollama/plugin.js +257 -56
  266. package/plugins/ollama/plugin.json +6 -3
  267. package/plugins/openai-api/icon-color.svg +1 -0
  268. package/plugins/openai-api/icon.svg +0 -0
  269. package/plugins/openai-api/plugin.js +0 -0
  270. package/plugins/openai-api/plugin.json +0 -0
  271. package/plugins/opencode/icon-color.svg +1 -0
  272. package/plugins/opencode/icon.svg +0 -0
  273. package/plugins/opencode/plugin.js +0 -0
  274. package/plugins/opencode/plugin.json +0 -0
  275. package/plugins/opencode-go/icon-color.svg +1 -0
  276. package/plugins/opencode-go/icon-conflict.svg +0 -0
  277. package/plugins/opencode-go/icon.svg +0 -0
  278. package/plugins/opencode-go/plugin.js +103 -17
  279. package/plugins/opencode-go/plugin.json +5 -2
  280. package/plugins/openrouter/icon-color.svg +1 -0
  281. package/plugins/openrouter/icon.svg +0 -0
  282. package/plugins/openrouter/plugin.js +371 -114
  283. package/plugins/openrouter/plugin.json +6 -0
  284. package/plugins/perplexity/icon-color.svg +0 -0
  285. package/plugins/perplexity/icon-conflict.svg +0 -0
  286. package/plugins/perplexity/icon.svg +0 -0
  287. package/plugins/perplexity/plugin.js +0 -0
  288. package/plugins/perplexity/plugin.json +0 -0
  289. package/plugins/pi/plugin.js +113 -0
  290. package/plugins/pi/plugin.json +11 -0
  291. package/plugins/poe/icon.svg +0 -0
  292. package/plugins/poe/plugin.js +24 -18
  293. package/plugins/poe/plugin.json +2 -0
  294. package/plugins/qoder/icon.svg +3 -0
  295. package/plugins/qoder/plugin.js +227 -0
  296. package/plugins/qoder/plugin.json +23 -0
  297. package/plugins/qwencloud/icon-color.svg +1 -0
  298. package/plugins/qwencloud/icon.svg +1 -0
  299. package/plugins/qwencloud/plugin.js +677 -0
  300. package/plugins/qwencloud/plugin.json +29 -0
  301. package/plugins/raycast/LICENSE +21 -0
  302. package/plugins/raycast/plugin.js +174 -0
  303. package/plugins/raycast/plugin.json +24 -0
  304. package/plugins/replicate/LICENSE +21 -0
  305. package/plugins/replicate/icon-color.svg +1 -0
  306. package/plugins/replicate/icon.svg +1 -0
  307. package/plugins/replicate/plugin.js +165 -0
  308. package/plugins/replicate/plugin.json +24 -0
  309. package/plugins/sakana/icon.svg +5 -0
  310. package/plugins/sakana/plugin.js +156 -0
  311. package/plugins/sakana/plugin.json +23 -0
  312. package/plugins/stepfun/icon-color.svg +0 -0
  313. package/plugins/stepfun/icon.svg +0 -0
  314. package/plugins/stepfun/plugin.js +0 -0
  315. package/plugins/stepfun/plugin.json +0 -0
  316. package/plugins/sub2api/icon.svg +4 -0
  317. package/plugins/sub2api/plugin.js +191 -0
  318. package/plugins/sub2api/plugin.json +16 -0
  319. package/plugins/synthetic/icon-color.svg +14 -0
  320. package/plugins/synthetic/icon-conflict.svg +0 -0
  321. package/plugins/synthetic/icon.svg +0 -0
  322. package/plugins/synthetic/plugin.js +0 -0
  323. package/plugins/synthetic/plugin.json +0 -0
  324. package/plugins/t3chat/icon-color.svg +0 -0
  325. package/plugins/t3chat/icon.svg +0 -0
  326. package/plugins/t3chat/plugin.js +0 -0
  327. package/plugins/t3chat/plugin.json +0 -0
  328. package/plugins/typesafe/LICENSE +21 -0
  329. package/plugins/typesafe/plugin.js +225 -0
  330. package/plugins/typesafe/plugin.json +24 -0
  331. package/plugins/v0/LICENSE +21 -0
  332. package/plugins/v0/icon-color.svg +1 -0
  333. package/plugins/v0/icon.svg +1 -0
  334. package/plugins/v0/plugin.js +214 -0
  335. package/plugins/v0/plugin.json +24 -0
  336. package/plugins/venice/icon-color.svg +0 -0
  337. package/plugins/venice/icon.svg +0 -0
  338. package/plugins/venice/plugin.js +50 -1
  339. package/plugins/venice/plugin.json +2 -1
  340. package/plugins/vercel/LICENSE +21 -0
  341. package/plugins/vercel/icon-color.svg +1 -0
  342. package/plugins/vercel/icon.svg +1 -0
  343. package/plugins/vercel/plugin.js +55 -0
  344. package/plugins/vercel/plugin.json +23 -0
  345. package/plugins/vertex-ai/icon-color.svg +0 -0
  346. package/plugins/vertex-ai/icon.svg +0 -0
  347. package/plugins/vertex-ai/plugin.js +0 -0
  348. package/plugins/vertex-ai/plugin.json +0 -0
  349. package/plugins/warp/icon-color.svg +0 -0
  350. package/plugins/warp/icon.svg +0 -0
  351. package/plugins/warp/plugin.js +0 -0
  352. package/plugins/warp/plugin.json +0 -0
  353. package/plugins/wayfinder/icon.svg +5 -0
  354. package/plugins/wayfinder/plugin.js +47 -0
  355. package/plugins/wayfinder/plugin.json +16 -0
  356. package/plugins/windsurf/icon-color.svg +1 -0
  357. package/plugins/windsurf/icon-conflict.svg +0 -0
  358. package/plugins/windsurf/icon.svg +0 -0
  359. package/plugins/windsurf/plugin.js +0 -0
  360. package/plugins/windsurf/plugin.json +0 -0
  361. package/plugins/xai/icon-color.svg +1 -0
  362. package/plugins/xai/icon.svg +1 -0
  363. package/plugins/xai/plugin.js +162 -0
  364. package/plugins/xai/plugin.json +28 -0
  365. package/plugins/xkiro/LICENSE +21 -0
  366. package/plugins/xkiro/plugin.js +99 -0
  367. package/plugins/xkiro/plugin.json +23 -0
  368. package/plugins/zai/icon-color.svg +1 -0
  369. package/plugins/zai/icon-conflict.svg +0 -0
  370. package/plugins/zai/icon.svg +0 -0
  371. package/plugins/zai/plugin.js +111 -161
  372. package/plugins/zai/plugin.json +4 -1
  373. package/plugins/zed/icon.svg +0 -0
  374. package/plugins/zed/plugin.js +0 -0
  375. package/plugins/zed/plugin.json +0 -0
  376. package/plugins/zenmux/icon-color.svg +1 -0
  377. package/plugins/zenmux/icon.svg +1 -0
  378. package/plugins/zenmux/plugin.js +102 -0
  379. package/plugins/zenmux/plugin.json +23 -0
  380. package/plugins/zoommate/icon.svg +1 -0
  381. package/plugins/zoommate/plugin.js +244 -0
  382. package/plugins/zoommate/plugin.json +29 -0
  383. package/usagestat +0 -0
  384. package/usagestatd +0 -0
@@ -0,0 +1,113 @@
1
+ (function () {
2
+ const own = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
3
+ const validCount = n => Number.isSafeInteger(n) && n >= 0;
4
+ const clean = s => typeof s === 'string' && s.trim() ? s.trim() : null;
5
+ const DAY = 86400000;
6
+ function roots(ctx) {
7
+ const settings = ctx.provider?.settings || {};
8
+ if (own(settings, 'sessionRoots')) {
9
+ if (!Array.isArray(settings.sessionRoots) || settings.sessionRoots.some(p => !clean(p))) throw new Error('Invalid Pi sessionRoots.');
10
+ return [...new Set(settings.sessionRoots)];
11
+ }
12
+ if (ctx.provider?.instanceId && ctx.provider.instanceId !== 'pi') throw new Error('Set sessionRoots for this Pi account.');
13
+ const env = k => clean(ctx.host.env.get(k));
14
+ const sessionDir = env('PI_CODING_AGENT_SESSION_DIR');
15
+ if (sessionDir) return [sessionDir];
16
+ const agentDir = env('PI_CODING_AGENT_DIR');
17
+ if (agentDir) return [agentDir.replace(/[\\/]+$/, '') + '/sessions'];
18
+ const home = ctx.host.fs.homeDir;
19
+ const config = env('PI_CONFIG_DIR') || '.omp';
20
+ if (/^(?:[\\/]|[A-Za-z]:)/.test(config) || config.split(/[\\/]/).includes('..')) throw new Error('PI_CONFIG_DIR must be inside the home directory.');
21
+ const xdg = env('XDG_DATA_HOME') || home + '/.local/share';
22
+ const profile = env('OMP_PROFILE') || env('PI_PROFILE');
23
+ if (profile && profile !== 'default') {
24
+ if (!/^[A-Za-z0-9_-]+$/.test(profile)) throw new Error('Invalid OMP profile.');
25
+ return [home + '/' + config, xdg + '/omp'].flatMap(root =>
26
+ [root + '/profiles/' + profile + '/sessions', root + '/profiles/' + profile + '/agent/sessions']);
27
+ }
28
+ return [home + '/.pi/agent/sessions', home + '/' + config + '/agent/sessions', xdg + '/omp/sessions'];
29
+ }
30
+ // API-equivalent USD estimates, reviewed against CodexBar 78ba5a1 (not subscription charges).
31
+ function cost(message, counts, date) {
32
+ const model = String(message.model || '').replace(/^(openai|anthropic)\//, '');
33
+ const [input, output, read, write] = counts;
34
+ let rate;
35
+ if (message.provider === 'openai-codex') {
36
+ if (model === 'gpt-5.4') rate = input + read > 272000 ? [5,22.5,.5,5] : [2.5,15,.25,2.5];
37
+ else if (model === 'gpt-5.4-mini') rate = [.75,4.5,.075,.75];
38
+ else if (model === 'gpt-5.4-nano') rate = [.2,1.25,.02,.2];
39
+ } else if (message.provider === 'anthropic') {
40
+ if (/^claude-sonnet-4-6(?:-\d{8})?$/.test(model)) rate = [3,15,.3,3.75];
41
+ if (/^claude-opus-4-[67](?:-\d{8})?$/.test(model)) rate = [5,25,.5,6.25];
42
+ // Earlier long-context pricing differs; keep it unpriced until its historical rate is available.
43
+ if (date < '2026-03-13' && input + read + write > 200000) return null;
44
+ }
45
+ if (!rate) return null;
46
+ const value = counts.reduce((sum, n, i) => sum + n * rate[i] / 1e6, 0);
47
+ return Number.isFinite(value) ? value : null;
48
+ }
49
+ function probe(ctx) {
50
+ const daily = new Map(), seen = new Set(), paths = new Set();
51
+ const now = Date.parse(ctx.nowIso), start = Date.now();
52
+ let bytes = 0, files = 0, complete = true;
53
+ function visit(root, depth) {
54
+ if (paths.has(root)) return;
55
+ paths.add(root);
56
+ if (depth > 6 || paths.size > 20000 || bytes > 128 * 1024 * 1024 || Date.now() - start > 10000) { complete = false; return; }
57
+ if (!root.endsWith('.jsonl')) {
58
+ let entries;
59
+ try { entries = ctx.host.fs.listDir(root); } catch (_) { if (depth || ctx.host.fs.exists(root)) complete = false; return; }
60
+ for (const name of entries) if (name !== '.' && name !== '..' && !/[\\/]/.test(name)) visit(root + '/' + name, depth + 1);
61
+ return;
62
+ }
63
+ let content;
64
+ try { content = ctx.host.fs.readTextLimited(root, 8 * 1024 * 1024); } catch (_) { complete = false; return; }
65
+ bytes += content.length; files++;
66
+ let session = root;
67
+ for (const line of content.split('\n')) {
68
+ if (!line.trim()) continue;
69
+ let entry;
70
+ try { entry = JSON.parse(line); } catch (_) { complete = false; continue; }
71
+ if (entry.type === 'session' && clean(entry.id)) session = entry.id;
72
+ const m = entry.message;
73
+ if (entry.type !== 'message' || m?.role !== 'assistant') continue;
74
+ const stamp = typeof m.timestamp === 'number' ? m.timestamp : Date.parse(entry.timestamp);
75
+ if (!Number.isFinite(stamp)) { complete = false; continue; }
76
+ if (stamp > now) continue;
77
+ const id = session + ':' + (entry.id || ctx.host.crypto.sha256(line));
78
+ if (seen.has(id)) continue;
79
+ seen.add(id);
80
+ const date = new Date(stamp).toISOString().slice(0, 10);
81
+ if (!daily.has(date)) daily.set(date, {date, inputTokens:0, outputTokens:0, cacheReadTokens:0,
82
+ cacheCreationTokens:0, totalTokens:0, costUsd:0, tokensKnown:true, costKnown:true, requests:0});
83
+ const row = daily.get(date), u = m.usage;
84
+ row.requests++;
85
+ const counts = [u?.input, u?.output, u?.cacheRead ?? 0, u?.cacheWrite ?? 0];
86
+ if (!u || !counts.every(validCount)) { row.tokensKnown = false; row.costKnown = false; continue; }
87
+ const total = counts.reduce((a, b) => a + b, 0);
88
+ if (!validCount(row.totalTokens + total)) { row.tokensKnown = false; row.costKnown = false; continue; }
89
+ ['inputTokens','outputTokens','cacheReadTokens','cacheCreationTokens'].forEach((key, i) => row[key] += counts[i]);
90
+ row.totalTokens += total;
91
+ const amount = cost(m, counts, date);
92
+ if (amount === null) row.costKnown = false; else row.costUsd += amount;
93
+ }
94
+ }
95
+ for (const root of roots(ctx)) visit(root.replace(/[\\/]+$/, ''), 0);
96
+ const rows = [...daily.values()].sort((a,b)=>a.date.localeCompare(b.date));
97
+ if (!complete) rows.forEach(row=>{row.tokensKnown=false;row.costKnown=false;});
98
+ if (rows.length) ctx.host.usageDaily.ingest({displayName:'Pi / OMP', source:'pi_transcript_estimated', daily:rows});
99
+ const lines = [];
100
+ for (const [label, days] of [['Today',1],['Last 30 Days',30]]) {
101
+ const since = new Date(Date.parse(ctx.nowIso.slice(0,10)) - (days-1)*DAY).toISOString().slice(0,10);
102
+ const selected = rows.filter(row=>row.date >= since);
103
+ if (!selected.length) continue;
104
+ const tokens = selected.reduce((sum,r)=>sum+r.totalTokens,0), usd=selected.reduce((sum,r)=>sum+r.costUsd,0);
105
+ const priced = selected.every(r=>r.costKnown), counted = selected.every(r=>r.tokensKnown);
106
+ lines.push(ctx.line.text({label, value:`${tokens}${counted?'':'+'} tokens`,
107
+ subtitle:priced ? '$'+usd.toFixed(2)+' estimated API cost' : usd>0 ? '$'+usd.toFixed(2)+'+ partial estimated API cost' : 'Pricing unavailable'}));
108
+ }
109
+ if (!complete) lines.push(ctx.line.text({label:'History',value:'Partial scan'}));
110
+ return {displayName:'Pi / OMP',source:'local',state:rows.length?'ready':'no-data',lines};
111
+ }
112
+ globalThis.__usagestat_plugin = {id:'pi',probe};
113
+ })();
@@ -0,0 +1,11 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "pi",
4
+ "name": "Pi / OMP",
5
+ "version": "0.1.0",
6
+ "entry": "plugin.js",
7
+ "enabledByDefault": false,
8
+ "supportedModes": ["local"],
9
+ "autoMode": "local",
10
+ "envVars": ["PI_CODING_AGENT_DIR", "PI_CODING_AGENT_SESSION_DIR", "PI_CONFIG_DIR", "OMP_PROFILE", "PI_PROFILE"]
11
+ }
File without changes
@@ -49,16 +49,12 @@
49
49
  }
50
50
 
51
51
  function parseDate(value) {
52
- if (typeof value === "number" && Number.isFinite(value)) {
53
- return new Date(value > 1000000000000 ? value / 1000 : value * 1000);
54
- }
55
- if (typeof value === "string" && value.trim()) {
56
- var numeric = Number(value);
57
- if (Number.isFinite(numeric)) return parseDate(numeric);
58
- var ms = Date.parse(value);
59
- if (Number.isFinite(ms)) return new Date(ms);
60
- }
61
- return null;
52
+ if (typeof value !== "number" && (typeof value !== "string" || !value.trim())) return null;
53
+ var numeric = Number(value);
54
+ var date = Number.isFinite(numeric)
55
+ ? new Date(Math.abs(numeric) > 100000000000000 ? numeric / 1000 : Math.abs(numeric) > 1000000000000 ? numeric : numeric * 1000)
56
+ : new Date(value);
57
+ return Number.isFinite(date.getTime()) && date.getUTCFullYear() >= 1 && date.getUTCFullYear() <= 9999 ? date : null;
62
58
  }
63
59
 
64
60
  function dayKey(date) {
@@ -77,6 +73,7 @@
77
73
  }
78
74
 
79
75
  function parseHistoryEntry(row) {
76
+ if (!row || typeof row !== "object") return null;
80
77
  var createdAt = parseDate(row.creation_time ?? row.timestamp ?? row.created_at);
81
78
  if (!createdAt) return null;
82
79
  var points = numberValue(row.cost_points ?? row.points ?? row.point_cost) || 0;
@@ -90,10 +87,10 @@
90
87
  };
91
88
  }
92
89
 
93
- function fetchHistory(ctx, key) {
90
+ function fetchHistory(ctx, key, nowMs) {
94
91
  var entries = [];
95
92
  var cursor = null;
96
- var cutoff = Date.now() - 30 * 24 * 3600 * 1000;
93
+ var cutoff = nowMs - 30 * 24 * 3600 * 1000;
97
94
  for (var page = 0; page < 5; page++) {
98
95
  var url = HISTORY_URL + "?limit=100";
99
96
  if (cursor) url += "&starting_after=" + encodeURIComponent(cursor);
@@ -111,7 +108,7 @@
111
108
  var lastEntry = entries[entries.length - 1];
112
109
  if (!cursor || (lastEntry && lastEntry.createdAt.getTime() < cutoff)) break;
113
110
  }
114
- return entries.filter(function (entry) { return entry.createdAt.getTime() >= cutoff; });
111
+ return entries.filter(function (entry) { return entry.createdAt.getTime() >= cutoff && entry.createdAt.getTime() <= nowMs; });
115
112
  }
116
113
 
117
114
  function summarizeHistory(entries) {
@@ -142,12 +139,19 @@
142
139
  return { byDay: byDay, days: days, topModel: topModel, totalPoints: totalPoints, totalCost: hasCost ? totalCost : null, requests: entries.length };
143
140
  }
144
141
 
145
- function appendHistoryLines(lines, ctx, entries) {
146
- if (!entries.length) return;
147
- var summary = summarizeHistory(entries);
142
+ function appendSummary(lines, ctx, label, summary) {
148
143
  var value = fmtNumber(summary.totalPoints) + " points";
149
144
  if (summary.totalCost != null) value += " · $" + summary.totalCost.toFixed(2);
150
- lines.push(ctx.line.text({ label: "Last 30 Days", value: value + " · " + summary.requests + " requests" }));
145
+ lines.push(ctx.line.text({ label: label, value: value + " · " + summary.requests + " requests" }));
146
+ }
147
+
148
+ function appendHistoryLines(lines, ctx, entries, nowMs) {
149
+ if (!entries.length) return;
150
+ var summary = summarizeHistory(entries);
151
+ var today = dayKey(new Date(nowMs));
152
+ appendSummary(lines, ctx, "Today", summarizeHistory(entries.filter(function (entry) { return dayKey(entry.createdAt) === today; })));
153
+ appendSummary(lines, ctx, "Last 7 Days", summarizeHistory(entries.filter(function (entry) { return entry.createdAt.getTime() >= nowMs - 7 * 86400000; })));
154
+ appendSummary(lines, ctx, "Last 30 Days", summary);
151
155
  if (summary.topModel) lines.push(ctx.line.text({ label: "Top Model", value: summary.topModel }));
152
156
 
153
157
  var points = summary.days.map(function (day) {
@@ -178,7 +182,9 @@
178
182
  }
179
183
 
180
184
  try {
181
- appendHistoryLines(lines, ctx, fetchHistory(ctx, key));
185
+ var nowMs = Date.parse(ctx.nowIso);
186
+ if (!Number.isFinite(nowMs)) nowMs = Date.now();
187
+ appendHistoryLines(lines, ctx, fetchHistory(ctx, key, nowMs), nowMs);
182
188
  } catch (e) {
183
189
  ctx.host.log.warn("poe points_history failed: " + String(e));
184
190
  }
@@ -13,6 +13,8 @@
13
13
  "autoMode": "api",
14
14
  "lines": [
15
15
  { "type": "text", "label": "Balance", "scope": "overview", "primaryOrder": 1 },
16
+ { "type": "text", "label": "Today", "scope": "detail" },
17
+ { "type": "text", "label": "Last 7 Days", "scope": "detail" },
16
18
  { "type": "text", "label": "Last 30 Days", "scope": "detail" },
17
19
  { "type": "barChart", "label": "Point History", "scope": "detail" }
18
20
  ]
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <path fill="black" d="M12 2.5c5.25 0 9.5 4.25 9.5 9.5s-4.25 9.5-9.5 9.5S2.5 17.25 2.5 12 6.75 2.5 12 2.5Zm0 3.2A6.3 6.3 0 1 0 12 18.3 6.3 6.3 0 0 0 12 5.7Zm0 2.8a3.5 3.5 0 0 1 3.5 3.5c0 .75-.23 1.44-.62 2.01l1.18 1.18-1.98 1.98-1.18-1.18A3.5 3.5 0 1 1 12 8.5Zm0 2.5a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z"/>
3
+ </svg>
@@ -0,0 +1,227 @@
1
+ (function () {
2
+ var GLOBAL_API = "https://qoder.com/api/v2/me/usages/big_model_credits";
3
+ var CHINA_API = "https://qoder.com.cn/api/v2/me/usages/big_model_credits";
4
+ var USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
5
+
6
+ function trim(value) {
7
+ return typeof value === "string" && value.trim() ? value.trim() : null;
8
+ }
9
+
10
+ function env(ctx, name) {
11
+ try {
12
+ return trim(ctx.host.env.get(name));
13
+ } catch (_) {
14
+ return null;
15
+ }
16
+ }
17
+
18
+ function setting(ctx, names) {
19
+ var settings = ctx.provider && ctx.provider.settings ? ctx.provider.settings : {};
20
+ for (var i = 0; i < names.length; i++) {
21
+ var value = trim(settings[names[i]]);
22
+ if (value) return value;
23
+ }
24
+ return null;
25
+ }
26
+
27
+ function normalizeCookie(raw) {
28
+ var header = trim(raw);
29
+ if (!header) return null;
30
+ if (header.slice(0, 7).toLowerCase() === "cookie:") header = header.slice(7).trim();
31
+ var pairs = [];
32
+ var chunks = header.split(";");
33
+ for (var i = 0; i < chunks.length; i++) {
34
+ var idx = chunks[i].indexOf("=");
35
+ if (idx < 0) continue;
36
+ var name = chunks[i].slice(0, idx).trim();
37
+ var value = chunks[i].slice(idx + 1).trim();
38
+ if (name && value) pairs.push(name + "=" + value);
39
+ }
40
+ return pairs.length ? pairs.join("; ") : null;
41
+ }
42
+
43
+ function cookieHeader(ctx) {
44
+ return normalizeCookie(ctx.provider && ctx.provider.cookieHeader) ||
45
+ normalizeCookie(setting(ctx, ["cookieHeader", "cookie"])) ||
46
+ normalizeCookie(env(ctx, "QODER_COOKIE"));
47
+ }
48
+
49
+ function requestRegion(ctx, url, referer, cookie) {
50
+ var result = ctx.util.requestJson({
51
+ method: "GET",
52
+ url: url,
53
+ headers: {
54
+ Cookie: cookie,
55
+ Accept: "application/json, text/plain, */*",
56
+ Referer: referer,
57
+ "User-Agent": USER_AGENT,
58
+ },
59
+ timeoutMs: 15000,
60
+ });
61
+ if (ctx.util.isAuthStatus(result.resp.status)) throw { auth: true, message: "Qoder session expired." };
62
+ if (result.resp.status < 200 || result.resp.status >= 300) throw "Qoder usage returned HTTP " + result.resp.status + ".";
63
+ if (!result.json || typeof result.json !== "object") throw "Failed to parse Qoder usage.";
64
+ return result.json;
65
+ }
66
+
67
+ function number(value) {
68
+ if (typeof value === "number" && Number.isFinite(value)) return value;
69
+ if (typeof value === "string" && value.trim()) {
70
+ var parsed = Number(value.replace(/,/g, ""));
71
+ if (Number.isFinite(parsed)) return parsed;
72
+ }
73
+ return null;
74
+ }
75
+
76
+ function first(obj, keys) {
77
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) return undefined;
78
+ for (var i = 0; i < keys.length; i++) {
79
+ if (obj[keys[i]] !== undefined && obj[keys[i]] !== null) return obj[keys[i]];
80
+ }
81
+ return undefined;
82
+ }
83
+
84
+ function stringFromKeys(obj, keys) {
85
+ var v = first(obj, keys);
86
+ return typeof v === "string" && v.trim() ? v.trim() : null;
87
+ }
88
+
89
+ function numberFromKeys(obj, keys) {
90
+ return number(first(obj, keys));
91
+ }
92
+
93
+ function parseDate(ctx, value) {
94
+ if (value === null || value === undefined || value === "") return null;
95
+ return ctx.util.toIso(value);
96
+ }
97
+
98
+ function normalizedPercent(value) {
99
+ var n = number(value);
100
+ if (n === null) return null;
101
+ if (n <= 1 && n >= 0) n *= 100;
102
+ return Math.max(0, Math.min(100, n));
103
+ }
104
+
105
+ function usagePercentage(used, total, remaining, provided) {
106
+ if (used < 0 || total < 0 || remaining < 0) throw "Qoder quota values must be nonnegative.";
107
+ if (total === 0) {
108
+ if (used !== 0 || remaining !== 0) throw "Qoder zero total quota has nonzero usage.";
109
+ return provided === null ? 100 : normalizedPercent(provided);
110
+ }
111
+ return provided === null ? used / total * 100 : normalizedPercent(provided);
112
+ }
113
+
114
+ function quotaSummary(root, containerKeys) {
115
+ var container = first(root, containerKeys);
116
+ if (!container || typeof container !== "object" || Array.isArray(container)) return null;
117
+ var summary = container.quotaSummary || container.quota_summary;
118
+ if (!summary || typeof summary !== "object" || Array.isArray(summary)) return null;
119
+ var used = numberFromKeys(summary, ["usedValue", "used_value"]);
120
+ var total = numberFromKeys(summary, ["limitValue", "limit_value"]);
121
+ if (used === null || total === null) throw "Missing Qoder quota summary values.";
122
+ var remaining = numberFromKeys(summary, ["remainingValue", "remaining_value"]);
123
+ if (remaining === null) remaining = Math.max(0, total - used);
124
+ var provided = numberFromKeys(summary, ["usagePercentage", "usage_percentage"]);
125
+ var unitRaw = stringFromKeys(summary, ["unit"]);
126
+ return {
127
+ used: used,
128
+ total: total,
129
+ remaining: remaining,
130
+ percentage: usagePercentage(used, total, remaining, provided),
131
+ unit: unitRaw && /^credits?$/i.test(unitRaw) ? "credits" : "units",
132
+ };
133
+ }
134
+
135
+ function mergeSummaries(a, b) {
136
+ var used = a.used + b.used;
137
+ var total = a.total + b.total;
138
+ var remaining = a.remaining + b.remaining;
139
+ return {
140
+ used: used,
141
+ total: total,
142
+ remaining: remaining,
143
+ percentage: usagePercentage(used, total, remaining, null),
144
+ unit: a.unit || b.unit || "credits",
145
+ };
146
+ }
147
+
148
+ function quotaSummarySnapshot(ctx, root, loginMethod) {
149
+ var base = quotaSummary(root, ["totalQuota", "total_quota"]);
150
+ if (!base) return null;
151
+ var shared = quotaSummary(root, ["sharedQuota", "shared_quota"]);
152
+ var merged = shared ? mergeSummaries(base, shared) : base;
153
+ var reset = parseDate(ctx, first(root, ["nextResetAt", "next_reset_at"]));
154
+ var detail = Math.round(merged.used) + "/" + Math.round(merged.total) + " " + (merged.unit || "credits") +
155
+ " used, " + Math.round(merged.remaining) + " remaining";
156
+ var opts = {
157
+ label: "Credits",
158
+ used: Math.max(0, Math.min(100, merged.percentage)),
159
+ limit: 100,
160
+ format: { kind: "percent" },
161
+ detail: detail,
162
+ };
163
+ if (reset) opts.resetsAt = reset;
164
+ return { displayName: "Qoder", source: "web", plan: loginMethod, lines: [ctx.line.progress(opts)] };
165
+ }
166
+
167
+ function collectCreditWindows(ctx, value, out) {
168
+ if (!value || typeof value !== "object") return;
169
+ if (Array.isArray(value)) {
170
+ for (var i = 0; i < value.length; i++) collectCreditWindows(ctx, value[i], out);
171
+ return;
172
+ }
173
+ var used = numberFromKeys(value, ["used", "usedCredits", "used_credits", "usage", "usedQuota", "used_quota"]);
174
+ var total = numberFromKeys(value, ["total", "totalCredits", "total_credits", "limit", "quota", "quotaLimit", "quota_limit"]);
175
+ var percent = normalizedPercent(first(value, ["usedPercent", "used_percent", "usagePercent", "usage_percent", "percent"]));
176
+ if (percent === null && used !== null && total !== null && total > 0) percent = used / total * 100;
177
+ if (percent !== null) {
178
+ var reset = parseDate(ctx, first(value, ["nextResetAt", "next_reset_at", "resetAt", "reset_at"]));
179
+ var detail = used !== null && total !== null ? Math.round(used) + "/" + Math.round(total) + " credits" : null;
180
+ var line = {
181
+ label: stringFromKeys(value, ["label", "name", "type"]) || "Credits",
182
+ used: Math.max(0, Math.min(100, percent)),
183
+ limit: 100,
184
+ format: { kind: "percent" },
185
+ };
186
+ if (reset) line.resetsAt = reset;
187
+ if (detail) line.detail = detail;
188
+ out.push(ctx.line.progress(line));
189
+ }
190
+ var keys = Object.keys(value);
191
+ for (var j = 0; j < keys.length; j++) collectCreditWindows(ctx, value[keys[j]], out);
192
+ }
193
+
194
+ function snapshotFromPayload(ctx, value, loginMethod) {
195
+ var root = value && value.data && typeof value.data === "object" ? value.data : value;
196
+ var summary = quotaSummarySnapshot(ctx, root, loginMethod);
197
+ if (summary) return summary;
198
+ var lines = [];
199
+ collectCreditWindows(ctx, root, lines);
200
+ lines.sort(function (a, b) { return b.used - a.used; });
201
+ if (!lines.length) throw "Missing Qoder credit usage.";
202
+ return { displayName: "Qoder", source: "web", plan: loginMethod, lines: lines };
203
+ }
204
+
205
+ function probe(ctx) {
206
+ var cookie = cookieHeader(ctx);
207
+ if (!cookie) throw "Qoder session not configured. Set QODER_COOKIE or provider cookieHeader.";
208
+ var authFailed = false;
209
+ var lastError = null;
210
+ var regions = [
211
+ [GLOBAL_API, "https://qoder.com/account/usage", "Qoder"],
212
+ [CHINA_API, "https://qoder.com.cn/account/usage", "Qoder China"],
213
+ ];
214
+ for (var i = 0; i < regions.length; i++) {
215
+ try {
216
+ return snapshotFromPayload(ctx, requestRegion(ctx, regions[i][0], regions[i][1], cookie), regions[i][2]);
217
+ } catch (error) {
218
+ if (error && error.auth) authFailed = true;
219
+ else lastError = error;
220
+ }
221
+ }
222
+ if (authFailed) throw "Qoder session expired.";
223
+ throw lastError || "No Qoder usage payload.";
224
+ }
225
+
226
+ globalThis.__openusage_plugin = { id: "qoder", probe: probe };
227
+ })();
@@ -0,0 +1,23 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "qoder",
4
+ "name": "Qoder",
5
+ "version": "0.1.0",
6
+ "entry": "plugin.js",
7
+ "enabledByDefault": false,
8
+ "supportedModes": [
9
+ "web"
10
+ ],
11
+ "autoMode": "web",
12
+ "webUrl": "https://qoder.com",
13
+ "usageDashboardUrl": "https://qoder.com/account/usage",
14
+ "links": [
15
+ {
16
+ "label": "Dashboard",
17
+ "url": "https://qoder.com/account/usage"
18
+ }
19
+ ],
20
+ "envVars": [
21
+ "QODER_COOKIE"
22
+ ]
23
+ }
@@ -0,0 +1 @@
1
+ <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Qwen</title><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z" fill="url(#lobe-icons-qwen-_R_0_)" fill-rule="nonzero"></path><defs><linearGradient id="lobe-icons-qwen-_R_0_" x1="0%" x2="100%" y1="0%" y2="0%"><stop offset="0%" stop-color="#6336E7" stop-opacity=".84"></stop><stop offset="100%" stop-color="#6F69F7" stop-opacity=".84"></stop></linearGradient></defs></svg>
@@ -0,0 +1 @@
1
+ <svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Qwen</title><path d="M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z"></path></svg>