@slkiser/opencode-quota 3.0.1 → 3.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 (127) hide show
  1. package/README.md +206 -143
  2. package/dist/lib/anthropic.d.ts +4 -5
  3. package/dist/lib/anthropic.d.ts.map +1 -1
  4. package/dist/lib/anthropic.js +230 -18
  5. package/dist/lib/anthropic.js.map +1 -1
  6. package/dist/lib/api-key-resolver.d.ts +1 -1
  7. package/dist/lib/api-key-resolver.d.ts.map +1 -1
  8. package/dist/lib/api-key-resolver.js +11 -13
  9. package/dist/lib/api-key-resolver.js.map +1 -1
  10. package/dist/lib/atomic-json.d.ts.map +1 -1
  11. package/dist/lib/atomic-json.js +3 -1
  12. package/dist/lib/atomic-json.js.map +1 -1
  13. package/dist/lib/config.d.ts.map +1 -1
  14. package/dist/lib/config.js +6 -0
  15. package/dist/lib/config.js.map +1 -1
  16. package/dist/lib/cursor-detection.d.ts.map +1 -1
  17. package/dist/lib/cursor-detection.js +14 -5
  18. package/dist/lib/cursor-detection.js.map +1 -1
  19. package/dist/lib/cursor-usage.d.ts.map +1 -1
  20. package/dist/lib/cursor-usage.js +18 -14
  21. package/dist/lib/cursor-usage.js.map +1 -1
  22. package/dist/lib/entries.d.ts +1 -1
  23. package/dist/lib/entries.d.ts.map +1 -1
  24. package/dist/lib/entries.js.map +1 -1
  25. package/dist/lib/format-utils.d.ts +8 -0
  26. package/dist/lib/format-utils.d.ts.map +1 -1
  27. package/dist/lib/format-utils.js +13 -0
  28. package/dist/lib/format-utils.js.map +1 -1
  29. package/dist/lib/format.d.ts +2 -0
  30. package/dist/lib/format.d.ts.map +1 -1
  31. package/dist/lib/format.js +14 -9
  32. package/dist/lib/format.js.map +1 -1
  33. package/dist/lib/init-installer.d.ts +1 -0
  34. package/dist/lib/init-installer.d.ts.map +1 -1
  35. package/dist/lib/init-installer.js +23 -5
  36. package/dist/lib/init-installer.js.map +1 -1
  37. package/dist/lib/jsonc.d.ts +5 -22
  38. package/dist/lib/jsonc.d.ts.map +1 -1
  39. package/dist/lib/jsonc.js +38 -55
  40. package/dist/lib/jsonc.js.map +1 -1
  41. package/dist/lib/kimi-auth.d.ts +38 -0
  42. package/dist/lib/kimi-auth.d.ts.map +1 -0
  43. package/dist/lib/kimi-auth.js +104 -0
  44. package/dist/lib/kimi-auth.js.map +1 -0
  45. package/dist/lib/kimi.d.ts +3 -0
  46. package/dist/lib/kimi.d.ts.map +1 -0
  47. package/dist/lib/kimi.js +206 -0
  48. package/dist/lib/kimi.js.map +1 -0
  49. package/dist/lib/opencode-sqlite.d.ts.map +1 -1
  50. package/dist/lib/opencode-sqlite.js +9 -12
  51. package/dist/lib/opencode-sqlite.js.map +1 -1
  52. package/dist/lib/opencode-storage.d.ts.map +1 -1
  53. package/dist/lib/opencode-storage.js +9 -5
  54. package/dist/lib/opencode-storage.js.map +1 -1
  55. package/dist/lib/provider-metadata.d.ts +1 -1
  56. package/dist/lib/provider-metadata.d.ts.map +1 -1
  57. package/dist/lib/provider-metadata.js +17 -4
  58. package/dist/lib/provider-metadata.js.map +1 -1
  59. package/dist/lib/quota-render-data.d.ts.map +1 -1
  60. package/dist/lib/quota-render-data.js +1 -4
  61. package/dist/lib/quota-render-data.js.map +1 -1
  62. package/dist/lib/quota-status.d.ts.map +1 -1
  63. package/dist/lib/quota-status.js +46 -7
  64. package/dist/lib/quota-status.js.map +1 -1
  65. package/dist/lib/synthetic-config.d.ts +41 -0
  66. package/dist/lib/synthetic-config.d.ts.map +1 -0
  67. package/dist/lib/synthetic-config.js +57 -0
  68. package/dist/lib/synthetic-config.js.map +1 -0
  69. package/dist/lib/synthetic.d.ts +17 -0
  70. package/dist/lib/synthetic.d.ts.map +1 -0
  71. package/dist/lib/synthetic.js +85 -0
  72. package/dist/lib/synthetic.js.map +1 -0
  73. package/dist/lib/toast-format-grouped.d.ts +2 -0
  74. package/dist/lib/toast-format-grouped.d.ts.map +1 -1
  75. package/dist/lib/toast-format-grouped.js +9 -6
  76. package/dist/lib/toast-format-grouped.js.map +1 -1
  77. package/dist/lib/tui-config-diagnostics.d.ts.map +1 -1
  78. package/dist/lib/tui-config-diagnostics.js +13 -9
  79. package/dist/lib/tui-config-diagnostics.js.map +1 -1
  80. package/dist/lib/tui-panel-state.d.ts.map +1 -1
  81. package/dist/lib/tui-panel-state.js +10 -5
  82. package/dist/lib/tui-panel-state.js.map +1 -1
  83. package/dist/lib/tui-sidebar-format.d.ts +1 -1
  84. package/dist/lib/tui-sidebar-format.d.ts.map +1 -1
  85. package/dist/lib/tui-sidebar-format.js +1 -0
  86. package/dist/lib/tui-sidebar-format.js.map +1 -1
  87. package/dist/lib/types.d.ts +37 -4
  88. package/dist/lib/types.d.ts.map +1 -1
  89. package/dist/lib/types.js +1 -0
  90. package/dist/lib/types.js.map +1 -1
  91. package/dist/plugin.d.ts.map +1 -1
  92. package/dist/plugin.js +1 -0
  93. package/dist/plugin.js.map +1 -1
  94. package/dist/providers/anthropic.js +1 -1
  95. package/dist/providers/anthropic.js.map +1 -1
  96. package/dist/providers/copilot.d.ts.map +1 -1
  97. package/dist/providers/copilot.js +2 -1
  98. package/dist/providers/copilot.js.map +1 -1
  99. package/dist/providers/cursor.d.ts.map +1 -1
  100. package/dist/providers/cursor.js +2 -1
  101. package/dist/providers/cursor.js.map +1 -1
  102. package/dist/providers/google-antigravity.d.ts.map +1 -1
  103. package/dist/providers/google-antigravity.js +2 -1
  104. package/dist/providers/google-antigravity.js.map +1 -1
  105. package/dist/providers/kimi-code.d.ts +3 -0
  106. package/dist/providers/kimi-code.d.ts.map +1 -0
  107. package/dist/providers/kimi-code.js +71 -0
  108. package/dist/providers/kimi-code.js.map +1 -0
  109. package/dist/providers/registry.d.ts.map +1 -1
  110. package/dist/providers/registry.js +4 -2
  111. package/dist/providers/registry.js.map +1 -1
  112. package/dist/providers/synthetic.d.ts +6 -0
  113. package/dist/providers/synthetic.d.ts.map +1 -0
  114. package/dist/providers/{firmware.js → synthetic.js} +13 -15
  115. package/dist/providers/synthetic.js.map +1 -0
  116. package/package.json +3 -2
  117. package/dist/lib/firmware-config.d.ts +0 -41
  118. package/dist/lib/firmware-config.d.ts.map +0 -1
  119. package/dist/lib/firmware-config.js +0 -60
  120. package/dist/lib/firmware-config.js.map +0 -1
  121. package/dist/lib/firmware.d.ts +0 -22
  122. package/dist/lib/firmware.d.ts.map +0 -1
  123. package/dist/lib/firmware.js +0 -62
  124. package/dist/lib/firmware.js.map +0 -1
  125. package/dist/providers/firmware.d.ts +0 -6
  126. package/dist/providers/firmware.d.ts.map +0 -1
  127. package/dist/providers/firmware.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-code.js","sourceRoot":"","sources":["../../src/providers/kimi-code.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAevD,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAiB9C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAgBvD,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAkB9C"}
@@ -8,7 +8,7 @@ import { copilotProvider } from "./copilot.js";
8
8
  import { openaiProvider } from "./openai.js";
9
9
  import { cursorProvider } from "./cursor.js";
10
10
  import { googleAntigravityProvider } from "./google-antigravity.js";
11
- import { firmwareProvider } from "./firmware.js";
11
+ import { syntheticProvider } from "./synthetic.js";
12
12
  import { chutesProvider } from "./chutes.js";
13
13
  import { qwenCodeProvider } from "./qwen-code.js";
14
14
  import { alibabaCodingPlanProvider } from "./alibaba-coding-plan.js";
@@ -16,6 +16,7 @@ import { zaiProvider } from "./zai.js";
16
16
  import { nanoGptProvider } from "./nanogpt.js";
17
17
  import { minimaxCodingPlanProvider } from "./minimax-coding-plan.js";
18
18
  import { opencodeGoProvider } from "./opencode-go.js";
19
+ import { kimiCodeProvider } from "./kimi-code.js";
19
20
  export function getProviders() {
20
21
  // Order here defines display ordering in the toast.
21
22
  return [
@@ -25,12 +26,13 @@ export function getProviders() {
25
26
  cursorProvider,
26
27
  qwenCodeProvider,
27
28
  alibabaCodingPlanProvider,
28
- firmwareProvider,
29
+ syntheticProvider,
29
30
  chutesProvider,
30
31
  googleAntigravityProvider,
31
32
  zaiProvider,
32
33
  nanoGptProvider,
33
34
  minimaxCodingPlanProvider,
35
+ kimiCodeProvider,
34
36
  opencodeGoProvider,
35
37
  ];
36
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,UAAU,YAAY;IAC1B,oDAAoD;IACpD,OAAO;QACL,iBAAiB;QACjB,eAAe;QACf,cAAc;QACd,cAAc;QACd,gBAAgB;QAChB,yBAAyB;QACzB,gBAAgB;QAChB,cAAc;QACd,yBAAyB;QACzB,WAAW;QACX,eAAe;QACf,yBAAyB;QACzB,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,UAAU,YAAY;IAC1B,oDAAoD;IACpD,OAAO;QACL,iBAAiB;QACjB,eAAe;QACf,cAAc;QACd,cAAc;QACd,gBAAgB;QAChB,yBAAyB;QACzB,iBAAiB;QACjB,cAAc;QACd,yBAAyB;QACzB,WAAW;QACX,eAAe;QACf,yBAAyB;QACzB,gBAAgB;QAChB,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Synthetic provider wrapper.
3
+ */
4
+ import type { QuotaProvider } from "../lib/entries.js";
5
+ export declare const syntheticProvider: QuotaProvider;
6
+ //# sourceMappingURL=synthetic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic.d.ts","sourceRoot":"","sources":["../../src/providers/synthetic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA6C,MAAM,mBAAmB,CAAC;AAQlG,eAAO,MAAM,iBAAiB,EAAE,aAwC/B,CAAC"}
@@ -1,45 +1,43 @@
1
1
  /**
2
- * Firmware AI provider wrapper.
2
+ * Synthetic provider wrapper.
3
3
  */
4
- import { fmtUsdAmount } from "../lib/format-utils.js";
5
- import { hasFirmwareApiKeyConfigured, queryFirmwareQuota } from "../lib/firmware.js";
6
4
  import { isCanonicalProviderAvailable } from "../lib/provider-availability.js";
5
+ import { hasSyntheticApiKeyConfigured, querySyntheticQuota, } from "../lib/synthetic.js";
7
6
  import { attemptedErrorResult, attemptedResult, notAttemptedResult } from "./result-helpers.js";
8
- export const firmwareProvider = {
9
- id: "firmware",
7
+ export const syntheticProvider = {
8
+ id: "synthetic",
10
9
  async isAvailable(ctx) {
11
10
  const providerAvailable = await isCanonicalProviderAvailable({
12
11
  ctx,
13
- providerId: "firmware",
12
+ providerId: "synthetic",
14
13
  fallbackOnError: false,
15
14
  });
16
15
  if (providerAvailable)
17
16
  return true;
18
- return await hasFirmwareApiKeyConfigured();
17
+ return await hasSyntheticApiKeyConfigured();
19
18
  },
20
19
  matchesCurrentModel(model) {
21
20
  const provider = model.split("/")[0]?.toLowerCase();
22
21
  if (!provider)
23
22
  return false;
24
- return provider.includes("firmware");
23
+ return provider.includes("synthetic");
25
24
  },
26
25
  async fetch(_ctx) {
27
- const result = await queryFirmwareQuota();
26
+ const result = await querySyntheticQuota();
28
27
  if (!result) {
29
28
  return notAttemptedResult();
30
29
  }
31
30
  if (!result.success) {
32
- return attemptedErrorResult("Firmware", result.error);
31
+ return attemptedErrorResult("Synthetic", result.error);
33
32
  }
34
- const value = fmtUsdAmount(result.creditsUsd);
35
33
  return attemptedResult([
36
34
  {
37
- kind: "value",
38
- name: "Firmware",
39
- value,
35
+ name: "Synthetic",
36
+ percentRemaining: result.percentRemaining,
37
+ right: `${result.usedRequests}/${result.requestLimit}`,
40
38
  resetTimeIso: result.resetTimeIso,
41
39
  },
42
40
  ]);
43
41
  },
44
42
  };
45
- //# sourceMappingURL=firmware.js.map
43
+ //# sourceMappingURL=synthetic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic.js","sourceRoot":"","sources":["../../src/providers/synthetic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhG,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,EAAE,EAAE,WAAW;IAEf,KAAK,CAAC,WAAW,CAAC,GAAyB;QACzC,MAAM,iBAAiB,GAAG,MAAM,4BAA4B,CAAC;YAC3D,GAAG;YACH,UAAU,EAAE,WAAW;YACvB,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;QACH,IAAI,iBAAiB;YAAE,OAAO,IAAI,CAAC;QAEnC,OAAO,MAAM,4BAA4B,EAAE,CAAC;IAC9C,CAAC;IAED,mBAAmB,CAAC,KAAa;QAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACpD,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,OAAO,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAA0B;QACpC,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC;QAE3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,kBAAkB,EAAE,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,eAAe,CAAC;YACrB;gBACE,IAAI,EAAE,WAAW;gBACjB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gBACzC,KAAK,EAAE,GAAG,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,EAAE;gBACtD,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slkiser/opencode-quota",
3
- "version": "3.0.1",
4
- "description": "OpenCode quota & tokens usage with zero context window pollution. Supports GitHub Copilot, OpenAI (Plus/Pro), Qwen Code, Chutes AI, Firmware AI, Google Antigravity, Z.ai coding plan and more.",
3
+ "version": "3.1.0",
4
+ "description": "OpenCode quota & tokens usage with zero context window pollution. Supports GitHub Copilot, OpenAI (Plus/Pro), Qwen Code, Chutes AI, Synthetic, Google Antigravity, Z.ai coding plan and more.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -81,6 +81,7 @@
81
81
  "@clack/prompts": "^1.2.0",
82
82
  "@opentui/core": "^0.1.92",
83
83
  "@opentui/solid": "^0.1.92",
84
+ "comment-json": "^5.0.0",
84
85
  "solid-js": "^1.9.10",
85
86
  "xdg-basedir": "^5.1.0"
86
87
  },
@@ -1,41 +0,0 @@
1
- /**
2
- * Firmware API key configuration resolver
3
- *
4
- * Resolution priority (first wins):
5
- * 1. Environment variable: FIRMWARE_AI_API_KEY or FIRMWARE_API_KEY
6
- * 2. User/global opencode.json/opencode.jsonc: provider.firmware.options.apiKey
7
- * - Supports {env:VAR_NAME} syntax for environment variable references
8
- * 3. auth.json: firmware.key (legacy/fallback)
9
- */
10
- /** Result of firmware API key resolution */
11
- export interface FirmwareApiKeyResult {
12
- key: string;
13
- source: FirmwareKeySource;
14
- }
15
- /** Source of the resolved API key */
16
- export type FirmwareKeySource = "env:FIRMWARE_AI_API_KEY" | "env:FIRMWARE_API_KEY" | "opencode.json" | "opencode.jsonc" | "auth.json";
17
- export { getGlobalOpencodeConfigCandidatePaths as getOpencodeConfigCandidatePaths } from "./api-key-resolver.js";
18
- /**
19
- * Resolve Firmware API key from all available sources.
20
- *
21
- * Priority (first wins):
22
- * 1. Environment variable: FIRMWARE_AI_API_KEY or FIRMWARE_API_KEY
23
- * 2. User/global opencode.json/opencode.jsonc: provider.firmware.options.apiKey
24
- * 3. auth.json: firmware.key
25
- *
26
- * @returns API key and source, or null if not found
27
- */
28
- export declare function resolveFirmwareApiKey(): Promise<FirmwareApiKeyResult | null>;
29
- /**
30
- * Check if a Firmware API key is configured in any source
31
- */
32
- export declare function hasFirmwareApiKey(): Promise<boolean>;
33
- /**
34
- * Get diagnostic info about firmware API key configuration
35
- */
36
- export declare function getFirmwareKeyDiagnostics(): Promise<{
37
- configured: boolean;
38
- source: FirmwareKeySource | null;
39
- checkedPaths: string[];
40
- }>;
41
- //# sourceMappingURL=firmware-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware-config.d.ts","sourceRoot":"","sources":["../../src/lib/firmware-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAKD,qCAAqC;AACrC,MAAM,MAAM,iBAAiB,GACzB,yBAAyB,GACzB,sBAAsB,GACtB,eAAe,GACf,gBAAgB,GAChB,WAAW,CAAC;AAGhB,OAAO,EAAE,qCAAqC,IAAI,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAEjH;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoBlF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG1D;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CAMD"}
@@ -1,60 +0,0 @@
1
- /**
2
- * Firmware API key configuration resolver
3
- *
4
- * Resolution priority (first wins):
5
- * 1. Environment variable: FIRMWARE_AI_API_KEY or FIRMWARE_API_KEY
6
- * 2. User/global opencode.json/opencode.jsonc: provider.firmware.options.apiKey
7
- * - Supports {env:VAR_NAME} syntax for environment variable references
8
- * 3. auth.json: firmware.key (legacy/fallback)
9
- */
10
- import { readAuthFile } from "./opencode-auth.js";
11
- import { extractAuthApiKeyEntry, extractProviderOptionsApiKey, getApiKeyDiagnostics, getGlobalOpencodeConfigCandidatePaths, resolveApiKey, } from "./api-key-resolver.js";
12
- const ALLOWED_FIRMWARE_ENV_VARS = ["FIRMWARE_AI_API_KEY", "FIRMWARE_API_KEY"];
13
- const FIRMWARE_PROVIDER_KEYS = ["firmware"];
14
- // Re-export for consumers that need path info
15
- export { getGlobalOpencodeConfigCandidatePaths as getOpencodeConfigCandidatePaths } from "./api-key-resolver.js";
16
- /**
17
- * Resolve Firmware API key from all available sources.
18
- *
19
- * Priority (first wins):
20
- * 1. Environment variable: FIRMWARE_AI_API_KEY or FIRMWARE_API_KEY
21
- * 2. User/global opencode.json/opencode.jsonc: provider.firmware.options.apiKey
22
- * 3. auth.json: firmware.key
23
- *
24
- * @returns API key and source, or null if not found
25
- */
26
- export async function resolveFirmwareApiKey() {
27
- return resolveApiKey({
28
- envVars: [
29
- { name: "FIRMWARE_AI_API_KEY", source: "env:FIRMWARE_AI_API_KEY" },
30
- { name: "FIRMWARE_API_KEY", source: "env:FIRMWARE_API_KEY" },
31
- ],
32
- extractFromConfig: (config) => extractProviderOptionsApiKey(config, {
33
- providerKeys: FIRMWARE_PROVIDER_KEYS,
34
- allowedEnvVars: ALLOWED_FIRMWARE_ENV_VARS,
35
- }),
36
- configJsonSource: "opencode.json",
37
- configJsoncSource: "opencode.jsonc",
38
- extractFromAuth: (auth) => extractAuthApiKeyEntry(auth, FIRMWARE_PROVIDER_KEYS),
39
- authSource: "auth.json",
40
- getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
41
- }, readAuthFile);
42
- }
43
- /**
44
- * Check if a Firmware API key is configured in any source
45
- */
46
- export async function hasFirmwareApiKey() {
47
- const result = await resolveFirmwareApiKey();
48
- return result !== null;
49
- }
50
- /**
51
- * Get diagnostic info about firmware API key configuration
52
- */
53
- export async function getFirmwareKeyDiagnostics() {
54
- return getApiKeyDiagnostics({
55
- envVarNames: ["FIRMWARE_AI_API_KEY", "FIRMWARE_API_KEY"],
56
- resolve: resolveFirmwareApiKey,
57
- getConfigCandidates: getGlobalOpencodeConfigCandidatePaths,
58
- });
59
- }
60
- //# sourceMappingURL=firmware-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware-config.js","sourceRoot":"","sources":["../../src/lib/firmware-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,oBAAoB,EACpB,qCAAqC,EACrC,aAAa,GACd,MAAM,uBAAuB,CAAC;AAQ/B,MAAM,yBAAyB,GAAG,CAAC,qBAAqB,EAAE,kBAAkB,CAAU,CAAC;AACvF,MAAM,sBAAsB,GAAG,CAAC,UAAU,CAAU,CAAC;AAUrD,8CAA8C;AAC9C,OAAO,EAAE,qCAAqC,IAAI,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAEjH;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,OAAO,aAAa,CAClB;QACE,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,EAAE,yBAAyB,EAAE;YAClE,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,sBAAsB,EAAE;SAC7D;QACD,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC5B,4BAA4B,CAAC,MAAM,EAAE;YACnC,YAAY,EAAE,sBAAsB;YACpC,cAAc,EAAE,yBAAyB;SAC1C,CAAC;QACJ,gBAAgB,EAAE,eAAe;QACjC,iBAAiB,EAAE,gBAAgB;QACnC,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,CAAC;QAC/E,UAAU,EAAE,WAAW;QACvB,mBAAmB,EAAE,qCAAqC;KAC3D,EACD,YAAY,CACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC7C,OAAO,MAAM,KAAK,IAAI,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAK7C,OAAO,oBAAoB,CAAoB;QAC7C,WAAW,EAAE,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;QACxD,OAAO,EAAE,qBAAqB;QAC9B,mBAAmB,EAAE,qCAAqC;KAC3D,CAAC,CAAC;AACL,CAAC"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Firmware AI quota fetcher
3
- *
4
- * Resolves API key from multiple sources (env vars, opencode.json, auth.json)
5
- * and queries: https://app.firmware.ai/api/v1/quota
6
- */
7
- import type { QuotaError } from "./types.js";
8
- export type FirmwareResult = {
9
- success: true;
10
- creditsUsd: number;
11
- resetTimeIso?: string;
12
- } | QuotaError | null;
13
- export type FirmwareResetWindowResult = {
14
- success: true;
15
- } | QuotaError | null;
16
- export { getFirmwareKeyDiagnostics, hasFirmwareApiKey as hasFirmwareApiKeyConfigured, type FirmwareKeySource, } from "./firmware-config.js";
17
- export declare function queryFirmwareQuota(): Promise<FirmwareResult>;
18
- /**
19
- * Deprecated: Firmware no longer documents a reset-window endpoint.
20
- */
21
- export declare function resetFirmwareQuotaWindow(): Promise<FirmwareResetWindowResult>;
22
- //# sourceMappingURL=firmware.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../src/lib/firmware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgB7C,MAAM,MAAM,cAAc,GACtB;IACE,OAAO,EAAE,IAAI,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACD,UAAU,GACV,IAAI,CAAC;AAET,MAAM,MAAM,yBAAyB,GACjC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB,UAAU,GACV,IAAI,CAAC;AAIT,OAAO,EACL,yBAAyB,EACzB,iBAAiB,IAAI,2BAA2B,EAChD,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC,CAyClE;AAED;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAQnF"}
@@ -1,62 +0,0 @@
1
- /**
2
- * Firmware AI quota fetcher
3
- *
4
- * Resolves API key from multiple sources (env vars, opencode.json, auth.json)
5
- * and queries: https://app.firmware.ai/api/v1/quota
6
- */
7
- import { sanitizeDisplaySnippet, sanitizeDisplayText } from "./display-sanitize.js";
8
- import { fetchWithTimeout } from "./http.js";
9
- import { resolveFirmwareApiKey, } from "./firmware-config.js";
10
- const FIRMWARE_QUOTA_URL = "https://app.firmware.ai/api/v1/quota";
11
- export { getFirmwareKeyDiagnostics, hasFirmwareApiKey as hasFirmwareApiKeyConfigured, } from "./firmware-config.js";
12
- export async function queryFirmwareQuota() {
13
- const resolved = await resolveFirmwareApiKey();
14
- if (!resolved)
15
- return null;
16
- try {
17
- const resp = await fetchWithTimeout(FIRMWARE_QUOTA_URL, {
18
- method: "GET",
19
- headers: {
20
- Authorization: `Bearer ${resolved.key}`,
21
- "User-Agent": "OpenCode-Quota-Toast/1.0",
22
- },
23
- });
24
- if (!resp.ok) {
25
- const text = await resp.text();
26
- return {
27
- success: false,
28
- error: `Firmware API error ${resp.status}: ${sanitizeDisplaySnippet(text, 120)}`,
29
- };
30
- }
31
- const data = (await resp.json());
32
- const creditsUsd = typeof data.credits === "number" ? data.credits : NaN;
33
- const resetTimeIso = typeof data.reset === "string" && data.reset.length > 0 ? data.reset : undefined;
34
- if (!Number.isFinite(creditsUsd)) {
35
- return { success: false, error: "Firmware API response missing credits" };
36
- }
37
- return {
38
- success: true,
39
- creditsUsd,
40
- resetTimeIso,
41
- };
42
- }
43
- catch (err) {
44
- return {
45
- success: false,
46
- error: sanitizeDisplayText(err instanceof Error ? err.message : String(err)),
47
- };
48
- }
49
- }
50
- /**
51
- * Deprecated: Firmware no longer documents a reset-window endpoint.
52
- */
53
- export async function resetFirmwareQuotaWindow() {
54
- const resolved = await resolveFirmwareApiKey();
55
- if (!resolved)
56
- return null;
57
- return {
58
- success: false,
59
- error: "Deprecated: Firmware reset-window is no longer supported by the API.",
60
- };
61
- }
62
- //# sourceMappingURL=firmware.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../src/lib/firmware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EACL,qBAAqB,GAItB,MAAM,sBAAsB,CAAC;AAsB9B,MAAM,kBAAkB,GAAG,sCAAsC,CAAC;AAElE,OAAO,EACL,yBAAyB,EACzB,iBAAiB,IAAI,2BAA2B,GAEjD,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC/C,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,kBAAkB,EAAE;YACtD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,QAAQ,CAAC,GAAG,EAAE;gBACvC,YAAY,EAAE,0BAA0B;aACzC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,sBAAsB,IAAI,CAAC,MAAM,KAAK,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;aACjF,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;QAE5D,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACzE,MAAM,YAAY,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;QAC5E,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU;YACV,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,mBAAmB,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SAC7E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,MAAM,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC/C,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,sEAAsE;KAC9E,CAAC;AACJ,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Firmware AI provider wrapper.
3
- */
4
- import type { QuotaProvider } from "../lib/entries.js";
5
- export declare const firmwareProvider: QuotaProvider;
6
- //# sourceMappingURL=firmware.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../src/providers/firmware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA6C,MAAM,mBAAmB,CAAC;AAMlG,eAAO,MAAM,gBAAgB,EAAE,aA0C9B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../src/providers/firmware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhG,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C,EAAE,EAAE,UAAU;IAEd,KAAK,CAAC,WAAW,CAAC,GAAyB;QACzC,MAAM,iBAAiB,GAAG,MAAM,4BAA4B,CAAC;YAC3D,GAAG;YACH,UAAU,EAAE,UAAU;YACtB,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;QACH,IAAI,iBAAiB;YAAE,OAAO,IAAI,CAAC;QAEnC,OAAO,MAAM,2BAA2B,EAAE,CAAC;IAC7C,CAAC;IAED,mBAAmB,CAAC,KAAa;QAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACpD,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAA0B;QACpC,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,kBAAkB,EAAE,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE9C,OAAO,eAAe,CAAC;YACrB;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,UAAU;gBAChB,KAAK;gBACL,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}