axusage 3.1.0 → 3.2.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 (84) hide show
  1. package/README.md +78 -194
  2. package/dist/adapters/claude.js +9 -8
  3. package/dist/adapters/coalesce-claude-usage-response.js +5 -7
  4. package/dist/adapters/{chatgpt.d.ts → codex.d.ts} +1 -1
  5. package/dist/adapters/{chatgpt.js → codex.js} +5 -5
  6. package/dist/adapters/copilot.d.ts +7 -0
  7. package/dist/adapters/copilot.js +58 -0
  8. package/dist/adapters/{parse-chatgpt-usage.d.ts → parse-codex-usage.d.ts} +3 -3
  9. package/dist/adapters/parse-copilot-usage.d.ts +15 -0
  10. package/dist/adapters/parse-copilot-usage.js +61 -0
  11. package/dist/cli.js +3 -21
  12. package/dist/commands/auth-setup-command.d.ts +1 -2
  13. package/dist/commands/auth-setup-command.js +44 -67
  14. package/dist/commands/auth-status-command.js +18 -38
  15. package/dist/commands/fetch-service-usage.d.ts +0 -1
  16. package/dist/commands/fetch-service-usage.js +1 -2
  17. package/dist/commands/run-auth-setup.d.ts +0 -10
  18. package/dist/commands/run-auth-setup.js +3 -80
  19. package/dist/commands/usage-command.d.ts +2 -7
  20. package/dist/commands/usage-command.js +7 -39
  21. package/dist/config/credential-sources.d.ts +3 -11
  22. package/dist/config/credential-sources.js +1 -1
  23. package/dist/services/get-service-access-token.d.ts +3 -3
  24. package/dist/services/get-service-access-token.js +11 -11
  25. package/dist/services/service-adapter-registry.d.ts +2 -2
  26. package/dist/services/service-adapter-registry.js +4 -4
  27. package/dist/services/supported-service.d.ts +6 -2
  28. package/dist/services/supported-service.js +2 -6
  29. package/dist/types/{chatgpt.d.ts → codex.d.ts} +4 -4
  30. package/dist/types/{chatgpt.js → codex.js} +6 -6
  31. package/dist/types/copilot.d.ts +14 -0
  32. package/dist/types/copilot.js +21 -0
  33. package/dist/utils/check-cli-dependency.d.ts +2 -4
  34. package/dist/utils/check-cli-dependency.js +7 -4
  35. package/dist/utils/copilot-gh-token.d.ts +1 -0
  36. package/dist/utils/copilot-gh-token.js +38 -0
  37. package/dist/utils/validate-root-options.d.ts +0 -3
  38. package/dist/utils/validate-root-options.js +2 -6
  39. package/package.json +15 -19
  40. package/dist/adapters/github-copilot.d.ts +0 -6
  41. package/dist/adapters/github-copilot.js +0 -57
  42. package/dist/adapters/parse-github-copilot-usage.d.ts +0 -23
  43. package/dist/adapters/parse-github-copilot-usage.js +0 -78
  44. package/dist/commands/auth-clear-command.d.ts +0 -7
  45. package/dist/commands/auth-clear-command.js +0 -84
  46. package/dist/commands/fetch-service-usage-with-reauth.d.ts +0 -7
  47. package/dist/commands/fetch-service-usage-with-reauth.js +0 -45
  48. package/dist/services/app-paths.d.ts +0 -9
  49. package/dist/services/app-paths.js +0 -39
  50. package/dist/services/auth-storage-path.d.ts +0 -3
  51. package/dist/services/auth-storage-path.js +0 -7
  52. package/dist/services/auth-timeouts.d.ts +0 -4
  53. package/dist/services/auth-timeouts.js +0 -4
  54. package/dist/services/browser-auth-manager.d.ts +0 -49
  55. package/dist/services/browser-auth-manager.js +0 -113
  56. package/dist/services/create-auth-context.d.ts +0 -8
  57. package/dist/services/create-auth-context.js +0 -35
  58. package/dist/services/do-setup-auth.d.ts +0 -3
  59. package/dist/services/do-setup-auth.js +0 -19
  60. package/dist/services/fetch-json-with-context.d.ts +0 -5
  61. package/dist/services/fetch-json-with-context.js +0 -37
  62. package/dist/services/launch-chromium.d.ts +0 -6
  63. package/dist/services/launch-chromium.js +0 -20
  64. package/dist/services/persist-storage-state.d.ts +0 -6
  65. package/dist/services/persist-storage-state.js +0 -16
  66. package/dist/services/request-service.d.ts +0 -3
  67. package/dist/services/request-service.js +0 -4
  68. package/dist/services/service-auth-configs.d.ts +0 -15
  69. package/dist/services/service-auth-configs.js +0 -26
  70. package/dist/services/setup-auth-flow.d.ts +0 -3
  71. package/dist/services/setup-auth-flow.js +0 -67
  72. package/dist/services/shared-browser-auth-manager.d.ts +0 -4
  73. package/dist/services/shared-browser-auth-manager.js +0 -87
  74. package/dist/services/verify-session.d.ts +0 -2
  75. package/dist/services/verify-session.js +0 -27
  76. package/dist/services/wait-for-login.d.ts +0 -6
  77. package/dist/services/wait-for-login.js +0 -115
  78. package/dist/types/github-copilot.d.ts +0 -21
  79. package/dist/types/github-copilot.js +0 -27
  80. package/dist/utils/resolve-prompt-capability.d.ts +0 -1
  81. package/dist/utils/resolve-prompt-capability.js +0 -3
  82. package/dist/utils/write-atomic-json.d.ts +0 -1
  83. package/dist/utils/write-atomic-json.js +0 -56
  84. /package/dist/adapters/{parse-chatgpt-usage.js → parse-codex-usage.js} +0 -0
@@ -1,115 +0,0 @@
1
- import { errors } from "playwright";
2
- import { LOGIN_TIMEOUT_MS } from "./auth-timeouts.js";
3
- import { input } from "@inquirer/prompts";
4
- function isTimeoutError(error) {
5
- return error instanceof errors.TimeoutError;
6
- }
7
- const SELECTOR_CLOSED_MESSAGES = [
8
- "target closed",
9
- "page closed",
10
- "context closed",
11
- "execution context was destroyed",
12
- ];
13
- function isSelectorClosedError(error) {
14
- if (!(error instanceof Error))
15
- return false;
16
- const message = error.message.toLowerCase();
17
- return SELECTOR_CLOSED_MESSAGES.some((snippet) => message.includes(snippet));
18
- }
19
- function classifySelectorFailure(error) {
20
- if (isTimeoutError(error))
21
- return "timeout";
22
- if (isSelectorClosedError(error))
23
- return "closed";
24
- return undefined;
25
- }
26
- function classifySelectorAggregate(error) {
27
- if (error instanceof AggregateError) {
28
- const outcomes = error.errors.map((item) => classifySelectorFailure(item));
29
- if (outcomes.every((item) => item === "timeout"))
30
- return "timeout";
31
- if (outcomes.every((item) => item === "timeout" || item === "closed") &&
32
- outcomes.includes("closed")) {
33
- return "closed";
34
- }
35
- return undefined;
36
- }
37
- return classifySelectorFailure(error);
38
- }
39
- export async function waitForLogin(page, selectors) {
40
- const timeoutMs = LOGIN_TIMEOUT_MS;
41
- const canPrompt = process.stdin.isTTY && process.stdout.isTTY;
42
- // Non-TTY sessions rely solely on selector waits (no manual continuation).
43
- if (!canPrompt && selectors.length === 0) {
44
- return "skipped";
45
- }
46
- const waiters = selectors.map((sel) => page.waitForSelector(sel, { timeout: timeoutMs }));
47
- const shouldShowCountdown = process.stderr.isTTY && waiters.length > 0;
48
- let interval;
49
- const manualController = canPrompt ? new AbortController() : undefined;
50
- const manualPromise = manualController
51
- ? input({
52
- message: "Press Enter after completing login in the browser...",
53
- default: "",
54
- }, { signal: manualController.signal })
55
- .then(() => "manual")
56
- .catch((error) => {
57
- if (error instanceof Error &&
58
- (error.name === "AbortPromptError" || error.name === "AbortError")) {
59
- // Expected when we cancel the prompt after a selector wins.
60
- // Returning "manual" keeps the promise resolved for the race.
61
- return "manual";
62
- }
63
- if (error instanceof Error && error.name === "ExitPromptError") {
64
- return "aborted";
65
- }
66
- throw error;
67
- })
68
- : undefined;
69
- if (shouldShowCountdown) {
70
- const deadline = Date.now() + timeoutMs;
71
- interval = setInterval(() => {
72
- const remaining = deadline - Date.now();
73
- if (remaining <= 0) {
74
- // Stop logging once timeout elapses to avoid confusing "0 minute(s)" spam
75
- if (interval)
76
- clearInterval(interval);
77
- console.error("Login wait timed out; finishing up...");
78
- return;
79
- }
80
- // Round up to the next minute for clearer UX, ensure at least 1
81
- const minutes = Math.max(1, Math.ceil(remaining / 60_000));
82
- console.error(`Still waiting for login... ${String(minutes)} minute(s) remaining`);
83
- }, 60_000);
84
- }
85
- try {
86
- const selectorPromise = waiters.length > 0
87
- ? Promise.any(waiters)
88
- .then(() => "selector")
89
- .catch((error) => {
90
- // Promise.any only rejects once all selectors have settled.
91
- const outcome = classifySelectorAggregate(error);
92
- if (outcome)
93
- return outcome;
94
- throw error;
95
- })
96
- : undefined;
97
- if (selectorPromise) {
98
- // Avoid unhandled rejections if the manual prompt wins the race.
99
- void selectorPromise.catch(() => { });
100
- }
101
- const raceTargets = [];
102
- if (manualPromise)
103
- raceTargets.push(manualPromise);
104
- if (selectorPromise)
105
- raceTargets.push(selectorPromise);
106
- if (raceTargets.length === 0)
107
- return "skipped";
108
- return await Promise.race(raceTargets);
109
- }
110
- finally {
111
- if (interval)
112
- clearInterval(interval);
113
- manualController?.abort();
114
- }
115
- }
@@ -1,21 +0,0 @@
1
- import { z } from "zod";
2
- export declare const GitHubCopilotUsageResponse: z.ZodObject<{
3
- licenseType: z.ZodString;
4
- quotas: z.ZodObject<{
5
- limits: z.ZodObject<{
6
- premiumInteractions: z.ZodNumber;
7
- }, z.core.$strip>;
8
- remaining: z.ZodObject<{
9
- premiumInteractions: z.ZodNumber;
10
- chatPercentage: z.ZodOptional<z.ZodNumber>;
11
- premiumInteractionsPercentage: z.ZodNumber;
12
- }, z.core.$strip>;
13
- resetDate: z.ZodString;
14
- overagesEnabled: z.ZodOptional<z.ZodBoolean>;
15
- }, z.core.$strip>;
16
- plan: z.ZodString;
17
- trial: z.ZodOptional<z.ZodObject<{
18
- eligible: z.ZodBoolean;
19
- }, z.core.$strip>>;
20
- }, z.core.$strip>;
21
- export type GitHubCopilotUsageResponse = z.infer<typeof GitHubCopilotUsageResponse>;
@@ -1,27 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * GitHub Copilot API response schemas
4
- */
5
- const GitHubCopilotQuotaLimits = z.object({
6
- premiumInteractions: z.number(),
7
- });
8
- const GitHubCopilotQuotaRemaining = z.object({
9
- premiumInteractions: z.number(),
10
- chatPercentage: z.number().optional(),
11
- premiumInteractionsPercentage: z.number(),
12
- });
13
- const GitHubCopilotQuotas = z.object({
14
- limits: GitHubCopilotQuotaLimits,
15
- remaining: GitHubCopilotQuotaRemaining,
16
- resetDate: z.string(), // Format: "YYYY-MM-DD"
17
- overagesEnabled: z.boolean().optional(),
18
- });
19
- const GitHubCopilotTrial = z.object({
20
- eligible: z.boolean(),
21
- });
22
- export const GitHubCopilotUsageResponse = z.object({
23
- licenseType: z.string(),
24
- quotas: GitHubCopilotQuotas,
25
- plan: z.string(),
26
- trial: GitHubCopilotTrial.optional(),
27
- });
@@ -1 +0,0 @@
1
- export declare function resolvePromptCapability(): boolean;
@@ -1,3 +0,0 @@
1
- export function resolvePromptCapability() {
2
- return process.stdin.isTTY && process.stdout.isTTY;
3
- }
@@ -1 +0,0 @@
1
- export declare function writeAtomicJson(filePath: string, data: unknown, mode?: number): Promise<void>;
@@ -1,56 +0,0 @@
1
- import { chmod, rename, unlink, writeFile } from "node:fs/promises";
2
- import { randomUUID } from "node:crypto";
3
- function getErrorCode(error) {
4
- if (error instanceof Error && "code" in error) {
5
- return error.code;
6
- }
7
- return undefined;
8
- }
9
- export async function writeAtomicJson(filePath, data, mode) {
10
- const temporaryPath = `${filePath}.${randomUUID()}.tmp`;
11
- const writeOptions = mode === undefined ? "utf8" : { encoding: "utf8", mode };
12
- await writeFile(temporaryPath, JSON.stringify(data), writeOptions);
13
- if (mode !== undefined) {
14
- await chmod(temporaryPath, mode).catch(() => {
15
- // Best-effort: some filesystems ignore chmod, but the mode was set at write.
16
- });
17
- }
18
- try {
19
- await rename(temporaryPath, filePath);
20
- }
21
- catch (error) {
22
- const code = getErrorCode(error);
23
- if (code === "EPERM" || code === "EACCES" || code === "EEXIST") {
24
- // Windows can reject rename over an existing file; fall back to a backup swap.
25
- // Best-effort: not fully atomic and assumes a single writer. Backups are
26
- // cleaned up by auth-clear when possible.
27
- const backupPath = `${filePath}.${randomUUID()}.bak`;
28
- let hasBackup = false;
29
- try {
30
- await rename(filePath, backupPath);
31
- hasBackup = true;
32
- }
33
- catch {
34
- // Best-effort: source file may not exist or be locked.
35
- }
36
- try {
37
- await rename(temporaryPath, filePath);
38
- }
39
- catch (fallbackError) {
40
- if (hasBackup) {
41
- await rename(backupPath, filePath).catch(() => {
42
- console.warn(`Warning: Failed to restore backup from ${backupPath}`);
43
- });
44
- }
45
- await unlink(temporaryPath).catch(() => { });
46
- throw fallbackError;
47
- }
48
- if (hasBackup) {
49
- await unlink(backupPath).catch(() => { });
50
- }
51
- return;
52
- }
53
- await unlink(temporaryPath).catch(() => { });
54
- throw error;
55
- }
56
- }