github-issue-tower-defence-management 1.33.0 → 1.34.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.
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.OauthAPIClaudeRepository = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const os = __importStar(require("os"));
30
+ const isCredentialsFile = (value) => {
31
+ if (typeof value !== 'object' || value === null)
32
+ return false;
33
+ return true;
34
+ };
35
+ const isUsageResponse = (value) => {
36
+ if (typeof value !== 'object' || value === null)
37
+ return false;
38
+ return true;
39
+ };
40
+ const findCredentials = (filePathList) => {
41
+ const credentials = [];
42
+ const baseFileName = '.credentials.json';
43
+ for (const filePath of filePathList) {
44
+ const fileName = path.basename(filePath);
45
+ if (fileName === baseFileName) {
46
+ continue;
47
+ }
48
+ const suffix = fileName.slice(baseFileName.length + 1);
49
+ const parts = suffix.split('.');
50
+ if (parts.length !== 2) {
51
+ continue;
52
+ }
53
+ const name = parts[0];
54
+ const priorityStr = parts[1];
55
+ const priority = parseInt(priorityStr, 10);
56
+ if (isNaN(priority)) {
57
+ continue;
58
+ }
59
+ credentials.push({
60
+ name,
61
+ priority,
62
+ filePath,
63
+ });
64
+ }
65
+ return credentials.sort((a, b) => a.priority - b.priority);
66
+ };
67
+ class OauthAPIClaudeRepository {
68
+ constructor() {
69
+ this.claudeDir = path.join(os.homedir(), '.claude');
70
+ this.credentialsPath = path.join(this.claudeDir, '.credentials.json');
71
+ }
72
+ getAccessToken() {
73
+ if (!fs.existsSync(this.credentialsPath)) {
74
+ throw new Error(`Claude credentials file not found at ${this.credentialsPath}. Please login to Claude Code first using: claude login`);
75
+ }
76
+ const fileContent = fs.readFileSync(this.credentialsPath, 'utf-8');
77
+ const credentials = JSON.parse(fileContent);
78
+ if (!isCredentialsFile(credentials)) {
79
+ throw new Error('Invalid credentials file format');
80
+ }
81
+ const accessToken = credentials.claudeAiOauth?.accessToken;
82
+ if (!accessToken) {
83
+ throw new Error('No access token found in credentials file');
84
+ }
85
+ return accessToken;
86
+ }
87
+ async getUsage() {
88
+ const accessToken = this.getAccessToken();
89
+ const response = await fetch('https://api.anthropic.com/api/oauth/usage', {
90
+ method: 'GET',
91
+ headers: {
92
+ Accept: 'application/json, text/plain, */*',
93
+ 'Content-Type': 'application/json',
94
+ 'User-Agent': 'claude-code/2.0.32',
95
+ Authorization: `Bearer ${accessToken}`,
96
+ 'anthropic-beta': 'oauth-2025-04-20',
97
+ },
98
+ });
99
+ if (!response.ok) {
100
+ const errorText = await response.text();
101
+ throw new Error(`Claude API error: ${errorText}`);
102
+ }
103
+ const responseData = await response.json();
104
+ if (!isUsageResponse(responseData)) {
105
+ throw new Error('Invalid API response format');
106
+ }
107
+ if (responseData.error) {
108
+ throw new Error(`API error: ${responseData.error}`);
109
+ }
110
+ const usages = [];
111
+ if (responseData.five_hour?.utilization !== undefined) {
112
+ usages.push({
113
+ hour: 5,
114
+ utilizationPercentage: responseData.five_hour.utilization,
115
+ resetsAt: responseData.five_hour.resets_at
116
+ ? new Date(responseData.five_hour.resets_at)
117
+ : new Date(),
118
+ });
119
+ }
120
+ if (responseData.seven_day?.utilization !== undefined) {
121
+ usages.push({
122
+ hour: 168,
123
+ utilizationPercentage: responseData.seven_day.utilization,
124
+ resetsAt: responseData.seven_day.resets_at
125
+ ? new Date(responseData.seven_day.resets_at)
126
+ : new Date(),
127
+ });
128
+ }
129
+ if (responseData.seven_day_opus?.utilization !== undefined) {
130
+ usages.push({
131
+ hour: 168,
132
+ utilizationPercentage: responseData.seven_day_opus.utilization,
133
+ resetsAt: responseData.seven_day_opus.resets_at
134
+ ? new Date(responseData.seven_day_opus.resets_at)
135
+ : new Date(),
136
+ });
137
+ }
138
+ if (responseData.seven_day_sonnet?.utilization !== undefined) {
139
+ usages.push({
140
+ hour: 168,
141
+ utilizationPercentage: responseData.seven_day_sonnet.utilization,
142
+ resetsAt: responseData.seven_day_sonnet.resets_at
143
+ ? new Date(responseData.seven_day_sonnet.resets_at)
144
+ : new Date(),
145
+ });
146
+ }
147
+ return usages;
148
+ }
149
+ async getUsageWithToken(accessToken) {
150
+ const response = await fetch('https://api.anthropic.com/api/oauth/usage', {
151
+ method: 'GET',
152
+ headers: {
153
+ Accept: 'application/json, text/plain, */*',
154
+ 'Content-Type': 'application/json',
155
+ 'User-Agent': 'claude-code/2.0.32',
156
+ Authorization: `Bearer ${accessToken}`,
157
+ 'anthropic-beta': 'oauth-2025-04-20',
158
+ },
159
+ });
160
+ if (!response.ok) {
161
+ const errorText = await response.text();
162
+ throw new Error(`Claude API error: ${errorText}`);
163
+ }
164
+ const responseData = await response.json();
165
+ if (!isUsageResponse(responseData)) {
166
+ throw new Error('Invalid API response format');
167
+ }
168
+ if (responseData.error) {
169
+ throw new Error(`API error: ${responseData.error}`);
170
+ }
171
+ return responseData;
172
+ }
173
+ isUsageUnderThreshold(usageResponse, threshold) {
174
+ const windows = [
175
+ usageResponse.five_hour,
176
+ usageResponse.seven_day,
177
+ usageResponse.seven_day_opus,
178
+ usageResponse.seven_day_sonnet,
179
+ ];
180
+ for (const window of windows) {
181
+ if (window?.utilization !== undefined &&
182
+ window.utilization >= threshold) {
183
+ return false;
184
+ }
185
+ }
186
+ return true;
187
+ }
188
+ async isClaudeAvailable(threshold) {
189
+ if (!fs.existsSync(this.claudeDir)) {
190
+ return false;
191
+ }
192
+ const files = fs.readdirSync(this.claudeDir);
193
+ const filePathList = files
194
+ .filter((file) => file.startsWith('.credentials.json'))
195
+ .map((file) => path.join(this.claudeDir, file));
196
+ const credentials = findCredentials(filePathList);
197
+ if (credentials.length === 0) {
198
+ return false;
199
+ }
200
+ for (const credential of credentials) {
201
+ const fileContent = fs.readFileSync(credential.filePath, 'utf-8');
202
+ const credentialData = JSON.parse(fileContent);
203
+ if (!isCredentialsFile(credentialData)) {
204
+ continue;
205
+ }
206
+ const accessToken = credentialData.claudeAiOauth?.accessToken;
207
+ if (!accessToken) {
208
+ continue;
209
+ }
210
+ try {
211
+ const usageResponse = await this.getUsageWithToken(accessToken);
212
+ if (this.isUsageUnderThreshold(usageResponse, threshold)) {
213
+ fs.copyFileSync(credential.filePath, this.credentialsPath);
214
+ return true;
215
+ }
216
+ }
217
+ catch {
218
+ continue;
219
+ }
220
+ }
221
+ return false;
222
+ }
223
+ }
224
+ exports.OauthAPIClaudeRepository = OauthAPIClaudeRepository;
225
+ //# sourceMappingURL=OauthAPIClaudeRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OauthAPIClaudeRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/OauthAPIClaudeRepository.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "1.33.0",
3
+ "version": "1.34.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {