@slkiser/opencode-quota 3.9.0 → 3.10.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.
- package/README.md +216 -50
- package/dist/bin/opencode-quota.d.ts.map +1 -1
- package/dist/bin/opencode-quota.js +4 -1
- package/dist/bin/opencode-quota.js.map +1 -1
- package/dist/lib/cli-show.d.ts.map +1 -1
- package/dist/lib/cli-show.js +94 -3
- package/dist/lib/cli-show.js.map +1 -1
- package/dist/lib/command-handled.d.ts +2 -2
- package/dist/lib/command-handled.d.ts.map +1 -1
- package/dist/lib/command-handled.js +19 -4
- package/dist/lib/command-handled.js.map +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +60 -5
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cursor-pricing.js +1 -1
- package/dist/lib/cursor-pricing.js.map +1 -1
- package/dist/lib/init-installer.d.ts.map +1 -1
- package/dist/lib/init-installer.js +6 -2
- package/dist/lib/init-installer.js.map +1 -1
- package/dist/lib/ollama-cloud.js +5 -5
- package/dist/lib/ollama-cloud.js.map +1 -1
- package/dist/lib/opencode-go.d.ts +12 -4
- package/dist/lib/opencode-go.d.ts.map +1 -1
- package/dist/lib/opencode-go.js +90 -7
- package/dist/lib/opencode-go.js.map +1 -1
- package/dist/lib/provider-metadata.d.ts +1 -1
- package/dist/lib/provider-metadata.d.ts.map +1 -1
- package/dist/lib/provider-metadata.js +0 -10
- package/dist/lib/provider-metadata.js.map +1 -1
- package/dist/lib/quota-command-format.d.ts +2 -0
- package/dist/lib/quota-command-format.d.ts.map +1 -1
- package/dist/lib/quota-command-format.js +4 -3
- package/dist/lib/quota-command-format.js.map +1 -1
- package/dist/lib/quota-dialog-commands.d.ts +43 -0
- package/dist/lib/quota-dialog-commands.d.ts.map +1 -0
- package/dist/lib/quota-dialog-commands.js +677 -0
- package/dist/lib/quota-dialog-commands.js.map +1 -0
- package/dist/lib/quota-export-types.d.ts +69 -0
- package/dist/lib/quota-export-types.d.ts.map +1 -0
- package/dist/lib/quota-export-types.js +9 -0
- package/dist/lib/quota-export-types.js.map +1 -0
- package/dist/lib/quota-export.d.ts +42 -0
- package/dist/lib/quota-export.d.ts.map +1 -0
- package/dist/lib/quota-export.js +130 -0
- package/dist/lib/quota-export.js.map +1 -0
- package/dist/lib/quota-render-data.d.ts +3 -0
- package/dist/lib/quota-render-data.d.ts.map +1 -1
- package/dist/lib/quota-render-data.js +22 -15
- package/dist/lib/quota-render-data.js.map +1 -1
- package/dist/lib/quota-state.d.ts +12 -0
- package/dist/lib/quota-state.d.ts.map +1 -1
- package/dist/lib/quota-state.js +38 -2
- package/dist/lib/quota-state.js.map +1 -1
- package/dist/lib/quota-stats-format.d.ts +5 -0
- package/dist/lib/quota-stats-format.d.ts.map +1 -1
- package/dist/lib/quota-stats-format.js +48 -13
- package/dist/lib/quota-stats-format.js.map +1 -1
- package/dist/lib/quota-status.d.ts.map +1 -1
- package/dist/lib/quota-status.js +0 -17
- package/dist/lib/quota-status.js.map +1 -1
- package/dist/lib/tui-runtime.d.ts +27 -0
- package/dist/lib/tui-runtime.d.ts.map +1 -1
- package/dist/lib/tui-runtime.js +104 -27
- package/dist/lib/tui-runtime.js.map +1 -1
- package/dist/lib/types.d.ts +16 -7
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +4 -0
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/zai.d.ts.map +1 -1
- package/dist/lib/zai.js +8 -1
- package/dist/lib/zai.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +6 -476
- package/dist/plugin.js.map +1 -1
- package/dist/providers/cursor.js +1 -1
- package/dist/providers/cursor.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +0 -2
- package/dist/providers/registry.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.tsx +252 -1
- package/package.json +2 -2
- package/dist/lib/crof-config.d.ts +0 -15
- package/dist/lib/crof-config.d.ts.map +0 -1
- package/dist/lib/crof-config.js +0 -33
- package/dist/lib/crof-config.js.map +0 -1
- package/dist/lib/crof.d.ts +0 -13
- package/dist/lib/crof.d.ts.map +0 -1
- package/dist/lib/crof.js +0 -70
- package/dist/lib/crof.js.map +0 -1
- package/dist/providers/crof.d.ts +0 -6
- package/dist/providers/crof.d.ts.map +0 -1
- package/dist/providers/crof.js +0 -56
- package/dist/providers/crof.js.map +0 -1
package/dist/lib/crof.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Crof.ai quota fetcher.
|
|
3
|
-
*
|
|
4
|
-
* Resolves API key from multiple sources and queries:
|
|
5
|
-
* https://crof.ai/usage_api/
|
|
6
|
-
*/
|
|
7
|
-
import type { CrofResult } from "./types.js";
|
|
8
|
-
export { getCrofKeyDiagnostics, hasCrofApiKey as hasCrofApiKeyConfigured, type CrofKeySource } from "./crof-config.js";
|
|
9
|
-
export declare function formatCrofCreditsValue(credits: number): string;
|
|
10
|
-
export declare function queryCrofQuota(options?: {
|
|
11
|
-
requestTimeoutMs?: number;
|
|
12
|
-
}): Promise<CrofResult>;
|
|
13
|
-
//# sourceMappingURL=crof.d.ts.map
|
package/dist/lib/crof.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crof.d.ts","sourceRoot":"","sources":["../../src/lib/crof.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoB7C,OAAO,EAAE,qBAAqB,EAAE,aAAa,IAAI,uBAAuB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA6BvH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAgCrG"}
|
package/dist/lib/crof.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Crof.ai quota fetcher.
|
|
3
|
-
*
|
|
4
|
-
* Resolves API key from multiple sources and queries:
|
|
5
|
-
* https://crof.ai/usage_api/
|
|
6
|
-
*/
|
|
7
|
-
import { sanitizeDisplaySnippet, sanitizeDisplayText } from "./display-sanitize.js";
|
|
8
|
-
import { clampPercent } from "./format-utils.js";
|
|
9
|
-
import { fetchWithTimeout } from "./http.js";
|
|
10
|
-
import { resolveCrofApiKey, } from "./crof-config.js";
|
|
11
|
-
const CROF_USAGE_URL = "https://crof.ai/usage_api/";
|
|
12
|
-
const USER_AGENT = "OpenCode-Quota-Toast/1.0";
|
|
13
|
-
export { getCrofKeyDiagnostics, hasCrofApiKey as hasCrofApiKeyConfigured } from "./crof-config.js";
|
|
14
|
-
function getFiniteNumber(value) {
|
|
15
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
16
|
-
}
|
|
17
|
-
function parseCrofUsage(data) {
|
|
18
|
-
if (!data || typeof data !== "object") {
|
|
19
|
-
throw new Error("Crof API returned an unexpected response shape");
|
|
20
|
-
}
|
|
21
|
-
const response = data;
|
|
22
|
-
const credits = getFiniteNumber(response.credits);
|
|
23
|
-
const requestsPlan = getFiniteNumber(response.requests_plan);
|
|
24
|
-
const usableRequests = getFiniteNumber(response.usable_requests);
|
|
25
|
-
if (credits === undefined || requestsPlan === undefined || usableRequests === undefined) {
|
|
26
|
-
throw new Error("Crof API returned an unexpected response shape");
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
success: true,
|
|
30
|
-
credits,
|
|
31
|
-
requestsPlan,
|
|
32
|
-
usableRequests,
|
|
33
|
-
percentRemaining: requestsPlan > 0 ? clampPercent((usableRequests / requestsPlan) * 100) : 0,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
export function formatCrofCreditsValue(credits) {
|
|
37
|
-
if (!Number.isFinite(credits))
|
|
38
|
-
return "0 credits";
|
|
39
|
-
const value = Number.isInteger(credits) ? String(Math.trunc(credits)) : credits.toFixed(4).replace(/\.?0+$/u, "");
|
|
40
|
-
return `${value} credits`;
|
|
41
|
-
}
|
|
42
|
-
export async function queryCrofQuota(options = {}) {
|
|
43
|
-
const resolved = await resolveCrofApiKey();
|
|
44
|
-
if (!resolved)
|
|
45
|
-
return null;
|
|
46
|
-
try {
|
|
47
|
-
const resp = await fetchWithTimeout(CROF_USAGE_URL, {
|
|
48
|
-
method: "GET",
|
|
49
|
-
headers: {
|
|
50
|
-
Authorization: `Bearer ${resolved.key}`,
|
|
51
|
-
"User-Agent": USER_AGENT,
|
|
52
|
-
},
|
|
53
|
-
}, options.requestTimeoutMs);
|
|
54
|
-
if (!resp.ok) {
|
|
55
|
-
const text = await resp.text();
|
|
56
|
-
return {
|
|
57
|
-
success: false,
|
|
58
|
-
error: `Crof API error ${resp.status}: ${sanitizeDisplaySnippet(text, 120)}`,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return parseCrofUsage(await resp.json());
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
return {
|
|
65
|
-
success: false,
|
|
66
|
-
error: sanitizeDisplayText(err instanceof Error ? err.message : String(err)),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=crof.js.map
|
package/dist/lib/crof.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crof.js","sourceRoot":"","sources":["../../src/lib/crof.ts"],"names":[],"mappings":"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"}
|
package/dist/providers/crof.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crof.d.ts","sourceRoot":"","sources":["../../src/providers/crof.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EAId,MAAM,mBAAmB,CAAC;AAY3B,eAAO,MAAM,YAAY,EAAE,aA6C1B,CAAC"}
|
package/dist/providers/crof.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Crof.ai provider wrapper.
|
|
3
|
-
*/
|
|
4
|
-
import { formatCrofCreditsValue, hasCrofApiKeyConfigured, queryCrofQuota } from "../lib/crof.js";
|
|
5
|
-
import { isCanonicalProviderAvailable } from "../lib/provider-availability.js";
|
|
6
|
-
import { modelProviderMatchesRuntimeId } from "../lib/provider-model-matching.js";
|
|
7
|
-
import { attemptedResult, mapNullableProviderResult } from "./result-helpers.js";
|
|
8
|
-
function formatRequestAmount(value) {
|
|
9
|
-
if (!Number.isFinite(value))
|
|
10
|
-
return "0";
|
|
11
|
-
if (Number.isInteger(value))
|
|
12
|
-
return String(Math.trunc(value));
|
|
13
|
-
return value.toFixed(2).replace(/\.?0+$/u, "");
|
|
14
|
-
}
|
|
15
|
-
export const crofProvider = {
|
|
16
|
-
id: "crof",
|
|
17
|
-
async isAvailable(ctx) {
|
|
18
|
-
const providerAvailable = await isCanonicalProviderAvailable({
|
|
19
|
-
ctx,
|
|
20
|
-
providerId: "crof",
|
|
21
|
-
fallbackOnError: false,
|
|
22
|
-
});
|
|
23
|
-
if (providerAvailable)
|
|
24
|
-
return true;
|
|
25
|
-
return await hasCrofApiKeyConfigured();
|
|
26
|
-
},
|
|
27
|
-
matchesCurrentModel(model) {
|
|
28
|
-
return modelProviderMatchesRuntimeId(model, "crof");
|
|
29
|
-
},
|
|
30
|
-
async fetch(ctx) {
|
|
31
|
-
const result = await queryCrofQuota({ requestTimeoutMs: ctx.config?.requestTimeoutMs });
|
|
32
|
-
return mapNullableProviderResult(result, {
|
|
33
|
-
errorLabel: "Crof",
|
|
34
|
-
onSuccess: (result) => {
|
|
35
|
-
const entries = [
|
|
36
|
-
{
|
|
37
|
-
name: "Crof Requests",
|
|
38
|
-
group: "Crof",
|
|
39
|
-
label: "Requests:",
|
|
40
|
-
right: `${formatRequestAmount(result.usableRequests)}/${formatRequestAmount(result.requestsPlan)}`,
|
|
41
|
-
percentRemaining: result.percentRemaining,
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
kind: "value",
|
|
45
|
-
name: "Crof Credits",
|
|
46
|
-
group: "Crof",
|
|
47
|
-
label: "Credits:",
|
|
48
|
-
value: formatCrofCreditsValue(result.credits),
|
|
49
|
-
},
|
|
50
|
-
];
|
|
51
|
-
return attemptedResult(entries);
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
//# sourceMappingURL=crof.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crof.js","sourceRoot":"","sources":["../../src/providers/crof.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,SAAS,mBAAmB,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAkB;IACzC,EAAE,EAAE,MAAM;IAEV,KAAK,CAAC,WAAW,CAAC,GAAyB;QACzC,MAAM,iBAAiB,GAAG,MAAM,4BAA4B,CAAC;YAC3D,GAAG;YACH,UAAU,EAAE,MAAM;YAClB,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;QACH,IAAI,iBAAiB;YAAE,OAAO,IAAI,CAAC;QAEnC,OAAO,MAAM,uBAAuB,EAAE,CAAC;IACzC,CAAC;IAED,mBAAmB,CAAC,KAAa;QAC/B,OAAO,6BAA6B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAyB;QACnC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAExF,OAAO,yBAAyB,CAAC,MAAM,EAAE;YACvC,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;gBACpB,MAAM,OAAO,GAAsB;oBACjC;wBACE,IAAI,EAAE,eAAe;wBACrB,KAAK,EAAE,MAAM;wBACb,KAAK,EAAE,WAAW;wBAClB,KAAK,EAAE,GAAG,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;wBAClG,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;qBAC1C;oBACD;wBACE,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,cAAc;wBACpB,KAAK,EAAE,MAAM;wBACb,KAAK,EAAE,UAAU;wBACjB,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC;qBAC9C;iBACF,CAAC;gBAEF,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|