@trentapps/manager-protocol 1.1.2 → 1.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.
- package/README.md +29 -1
- package/dist/analyzers/CSSAnalyzer.d.ts +188 -8
- package/dist/analyzers/CSSAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/CSSAnalyzer.js +794 -192
- package/dist/analyzers/CSSAnalyzer.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/config/dashboard.d.ts +55 -0
- package/dist/config/dashboard.d.ts.map +1 -0
- package/dist/config/dashboard.js +103 -0
- package/dist/config/dashboard.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/dashboard/httpDashboard.d.ts +100 -0
- package/dist/dashboard/httpDashboard.d.ts.map +1 -0
- package/dist/dashboard/httpDashboard.js +1276 -0
- package/dist/dashboard/httpDashboard.js.map +1 -0
- package/dist/dashboard/index.d.ts +6 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +7 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/engine/AuditLogger.d.ts +370 -2
- package/dist/engine/AuditLogger.d.ts.map +1 -1
- package/dist/engine/AuditLogger.js +1067 -24
- package/dist/engine/AuditLogger.js.map +1 -1
- package/dist/engine/GitHubApprovalManager.d.ts +13 -0
- package/dist/engine/GitHubApprovalManager.d.ts.map +1 -1
- package/dist/engine/GitHubApprovalManager.js +72 -46
- package/dist/engine/GitHubApprovalManager.js.map +1 -1
- package/dist/engine/GitHubClient.d.ts +183 -0
- package/dist/engine/GitHubClient.d.ts.map +1 -0
- package/dist/engine/GitHubClient.js +411 -0
- package/dist/engine/GitHubClient.js.map +1 -0
- package/dist/engine/RateLimiter.d.ts +5 -3
- package/dist/engine/RateLimiter.d.ts.map +1 -1
- package/dist/engine/RateLimiter.js +53 -70
- package/dist/engine/RateLimiter.js.map +1 -1
- package/dist/engine/RuleDependencyAnalyzer.d.ts +73 -0
- package/dist/engine/RuleDependencyAnalyzer.d.ts.map +1 -0
- package/dist/engine/RuleDependencyAnalyzer.js +475 -0
- package/dist/engine/RuleDependencyAnalyzer.js.map +1 -0
- package/dist/engine/RulesEngine.d.ts +102 -3
- package/dist/engine/RulesEngine.d.ts.map +1 -1
- package/dist/engine/RulesEngine.js +326 -21
- package/dist/engine/RulesEngine.js.map +1 -1
- package/dist/engine/TaskManager.d.ts +11 -10
- package/dist/engine/TaskManager.d.ts.map +1 -1
- package/dist/engine/TaskManager.js +180 -195
- package/dist/engine/TaskManager.js.map +1 -1
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +5 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/rules/azure.d.ts.map +1 -1
- package/dist/rules/azure.js +12 -14
- package/dist/rules/azure.js.map +1 -1
- package/dist/rules/compliance.d.ts.map +1 -1
- package/dist/rules/compliance.js +23 -41
- package/dist/rules/compliance.js.map +1 -1
- package/dist/rules/condition-optimizer.d.ts +151 -0
- package/dist/rules/condition-optimizer.d.ts.map +1 -0
- package/dist/rules/condition-optimizer.js +479 -0
- package/dist/rules/condition-optimizer.js.map +1 -0
- package/dist/rules/css.d.ts.map +1 -1
- package/dist/rules/css.js +538 -0
- package/dist/rules/css.js.map +1 -1
- package/dist/rules/field-standards.d.ts +1172 -0
- package/dist/rules/field-standards.d.ts.map +1 -0
- package/dist/rules/field-standards.js +908 -0
- package/dist/rules/field-standards.js.map +1 -0
- package/dist/rules/flask.d.ts.map +1 -1
- package/dist/rules/flask.js +18 -31
- package/dist/rules/flask.js.map +1 -1
- package/dist/rules/index.d.ts +220 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +155 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/ml-ai.d.ts.map +1 -1
- package/dist/rules/ml-ai.js +11 -13
- package/dist/rules/ml-ai.js.map +1 -1
- package/dist/rules/patterns.d.ts +568 -0
- package/dist/rules/patterns.d.ts.map +1 -0
- package/dist/rules/patterns.js +1359 -0
- package/dist/rules/patterns.js.map +1 -0
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +580 -19
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/shared-patterns.d.ts +268 -0
- package/dist/rules/shared-patterns.d.ts.map +1 -0
- package/dist/rules/shared-patterns.js +556 -0
- package/dist/rules/shared-patterns.js.map +1 -0
- package/dist/rules/storage.d.ts +8 -2
- package/dist/rules/storage.d.ts.map +1 -1
- package/dist/rules/storage.js +541 -3
- package/dist/rules/storage.js.map +1 -1
- package/dist/rules/stripe.d.ts.map +1 -1
- package/dist/rules/stripe.js +19 -26
- package/dist/rules/stripe.js.map +1 -1
- package/dist/rules/websocket.d.ts.map +1 -1
- package/dist/rules/websocket.js +32 -40
- package/dist/rules/websocket.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +96 -17
- package/dist/server.js.map +1 -1
- package/dist/supervisor/AgentSupervisor.d.ts +52 -0
- package/dist/supervisor/AgentSupervisor.d.ts.map +1 -1
- package/dist/supervisor/AgentSupervisor.js +120 -1
- package/dist/supervisor/AgentSupervisor.js.map +1 -1
- package/dist/supervisor/ManagedServerRegistry.d.ts +139 -2
- package/dist/supervisor/ManagedServerRegistry.d.ts.map +1 -1
- package/dist/supervisor/ManagedServerRegistry.js +590 -6
- package/dist/supervisor/ManagedServerRegistry.js.map +1 -1
- package/dist/supervisor/ProjectTracker.d.ts +24 -2
- package/dist/supervisor/ProjectTracker.d.ts.map +1 -1
- package/dist/supervisor/ProjectTracker.js +151 -59
- package/dist/supervisor/ProjectTracker.js.map +1 -1
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/rule-tester.d.ts +217 -0
- package/dist/testing/rule-tester.d.ts.map +1 -0
- package/dist/testing/rule-tester.examples.d.ts +57 -0
- package/dist/testing/rule-tester.examples.d.ts.map +1 -0
- package/dist/testing/rule-tester.examples.js +375 -0
- package/dist/testing/rule-tester.examples.js.map +1 -0
- package/dist/testing/rule-tester.js +381 -0
- package/dist/testing/rule-tester.js.map +1 -0
- package/dist/testing/rule-validator.d.ts +141 -0
- package/dist/testing/rule-validator.d.ts.map +1 -0
- package/dist/testing/rule-validator.js +640 -0
- package/dist/testing/rule-validator.js.map +1 -0
- package/dist/types/index.d.ts +265 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +57 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/rate-limiting.d.ts +268 -0
- package/dist/utils/rate-limiting.d.ts.map +1 -0
- package/dist/utils/rate-limiting.js +403 -0
- package/dist/utils/rate-limiting.js.map +1 -0
- package/dist/utils/shared.d.ts +306 -0
- package/dist/utils/shared.d.ts.map +1 -0
- package/dist/utils/shared.js +464 -0
- package/dist/utils/shared.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Agent Supervisor - GitHub Client
|
|
3
|
+
*
|
|
4
|
+
* Provides a clean wrapper around the GitHub API via Octokit.
|
|
5
|
+
* Used by TaskManager for GitHub Issues operations.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Singleton pattern for connection reuse
|
|
9
|
+
* - Automatic authentication via GITHUB_TOKEN
|
|
10
|
+
* - Repository auto-detection from git remote
|
|
11
|
+
* - Proper TypeScript types
|
|
12
|
+
* - Structured error handling
|
|
13
|
+
*/
|
|
14
|
+
import { Octokit } from '@octokit/rest';
|
|
15
|
+
import { exec } from 'child_process';
|
|
16
|
+
import { promisify } from 'util';
|
|
17
|
+
const execAsync = promisify(exec);
|
|
18
|
+
/**
|
|
19
|
+
* GitHub API client using Octokit
|
|
20
|
+
*/
|
|
21
|
+
export class GitHubClient {
|
|
22
|
+
static instance = null;
|
|
23
|
+
octokit;
|
|
24
|
+
cachedRepo = null;
|
|
25
|
+
authenticated = false;
|
|
26
|
+
constructor() {
|
|
27
|
+
const token = process.env.GITHUB_TOKEN;
|
|
28
|
+
if (!token) {
|
|
29
|
+
console.warn('[GitHubClient] GITHUB_TOKEN not set - some operations may fail');
|
|
30
|
+
}
|
|
31
|
+
this.octokit = new Octokit({
|
|
32
|
+
auth: token,
|
|
33
|
+
userAgent: 'enterprise-agent-supervisor/1.1.3',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get singleton instance
|
|
38
|
+
*/
|
|
39
|
+
static getInstance() {
|
|
40
|
+
if (!GitHubClient.instance) {
|
|
41
|
+
GitHubClient.instance = new GitHubClient();
|
|
42
|
+
}
|
|
43
|
+
return GitHubClient.instance;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reset singleton instance (for testing)
|
|
47
|
+
*/
|
|
48
|
+
static resetInstance() {
|
|
49
|
+
GitHubClient.instance = null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Verify authentication and get current user
|
|
53
|
+
*/
|
|
54
|
+
async verifyAuth() {
|
|
55
|
+
if (this.authenticated) {
|
|
56
|
+
return { ok: true };
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const { data } = await this.octokit.users.getAuthenticated();
|
|
60
|
+
this.authenticated = true;
|
|
61
|
+
return { ok: true, user: data.login };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
const err = error;
|
|
65
|
+
if (err.status === 401) {
|
|
66
|
+
return { ok: false, error: 'GitHub authentication failed. Set GITHUB_TOKEN environment variable.' };
|
|
67
|
+
}
|
|
68
|
+
return { ok: false, error: err.message || 'Unknown authentication error' };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse owner/repo string into components
|
|
73
|
+
*/
|
|
74
|
+
parseRepo(repoString) {
|
|
75
|
+
const parts = repoString.split('/');
|
|
76
|
+
if (parts.length !== 2) {
|
|
77
|
+
throw new Error(`Invalid repository format: ${repoString}. Expected "owner/repo".`);
|
|
78
|
+
}
|
|
79
|
+
return { owner: parts[0], repo: parts[1] };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get current repository from git remote
|
|
83
|
+
*/
|
|
84
|
+
async getCurrentRepo() {
|
|
85
|
+
if (this.cachedRepo) {
|
|
86
|
+
return this.cachedRepo;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Try to get repo from git remote
|
|
90
|
+
const { stdout } = await execAsync('git remote get-url origin 2>/dev/null');
|
|
91
|
+
const url = stdout.trim();
|
|
92
|
+
// Parse various git remote URL formats:
|
|
93
|
+
// https://github.com/owner/repo.git
|
|
94
|
+
// git@github.com:owner/repo.git
|
|
95
|
+
// https://github.com/owner/repo
|
|
96
|
+
let match = url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
|
|
97
|
+
if (match) {
|
|
98
|
+
this.cachedRepo = { owner: match[1], repo: match[2] };
|
|
99
|
+
return this.cachedRepo;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Git command failed
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Handle API errors consistently
|
|
109
|
+
*/
|
|
110
|
+
handleError(error, operation) {
|
|
111
|
+
const err = error;
|
|
112
|
+
if (err.status === 401) {
|
|
113
|
+
throw new Error(`Authentication failed for ${operation}. Check GITHUB_TOKEN.`);
|
|
114
|
+
}
|
|
115
|
+
if (err.status === 403) {
|
|
116
|
+
throw new Error(`Permission denied for ${operation}. Check repository access.`);
|
|
117
|
+
}
|
|
118
|
+
if (err.status === 404) {
|
|
119
|
+
throw new Error(`Not found during ${operation}. Check repository/issue exists.`);
|
|
120
|
+
}
|
|
121
|
+
if (err.status === 422) {
|
|
122
|
+
throw new Error(`Validation failed for ${operation}: ${err.message}`);
|
|
123
|
+
}
|
|
124
|
+
throw new Error(`GitHub API error during ${operation}: ${err.message || 'Unknown error'}`);
|
|
125
|
+
}
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// ISSUE OPERATIONS
|
|
128
|
+
// ============================================================================
|
|
129
|
+
/**
|
|
130
|
+
* Create a new issue
|
|
131
|
+
*/
|
|
132
|
+
async createIssue(params) {
|
|
133
|
+
try {
|
|
134
|
+
const { data } = await this.octokit.issues.create({
|
|
135
|
+
owner: params.owner,
|
|
136
|
+
repo: params.repo,
|
|
137
|
+
title: params.title,
|
|
138
|
+
body: params.body,
|
|
139
|
+
labels: params.labels,
|
|
140
|
+
assignees: params.assignees,
|
|
141
|
+
milestone: params.milestone,
|
|
142
|
+
});
|
|
143
|
+
return this.normalizeIssue(data);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
this.handleError(error, 'createIssue');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get a single issue by number
|
|
151
|
+
*/
|
|
152
|
+
async getIssue(owner, repo, issueNumber) {
|
|
153
|
+
try {
|
|
154
|
+
const { data } = await this.octokit.issues.get({
|
|
155
|
+
owner,
|
|
156
|
+
repo,
|
|
157
|
+
issue_number: issueNumber,
|
|
158
|
+
});
|
|
159
|
+
return this.normalizeIssue(data);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
this.handleError(error, 'getIssue');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* List issues for a repository
|
|
167
|
+
*/
|
|
168
|
+
async listIssues(params) {
|
|
169
|
+
try {
|
|
170
|
+
const { data } = await this.octokit.issues.listForRepo({
|
|
171
|
+
owner: params.owner,
|
|
172
|
+
repo: params.repo,
|
|
173
|
+
state: params.state || 'all',
|
|
174
|
+
labels: params.labels,
|
|
175
|
+
assignee: params.assignee,
|
|
176
|
+
per_page: params.per_page || 100,
|
|
177
|
+
page: params.page || 1,
|
|
178
|
+
});
|
|
179
|
+
// Filter out pull requests (GitHub API returns PRs in issues endpoint)
|
|
180
|
+
return data
|
|
181
|
+
.filter((issue) => !('pull_request' in issue))
|
|
182
|
+
.map((issue) => this.normalizeIssue(issue));
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
this.handleError(error, 'listIssues');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Update an existing issue
|
|
190
|
+
*/
|
|
191
|
+
async updateIssue(params) {
|
|
192
|
+
try {
|
|
193
|
+
const { data } = await this.octokit.issues.update({
|
|
194
|
+
owner: params.owner,
|
|
195
|
+
repo: params.repo,
|
|
196
|
+
issue_number: params.issue_number,
|
|
197
|
+
title: params.title,
|
|
198
|
+
body: params.body,
|
|
199
|
+
state: params.state,
|
|
200
|
+
state_reason: params.state_reason,
|
|
201
|
+
labels: params.labels,
|
|
202
|
+
assignees: params.assignees,
|
|
203
|
+
milestone: params.milestone,
|
|
204
|
+
});
|
|
205
|
+
return this.normalizeIssue(data);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
this.handleError(error, 'updateIssue');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Close an issue
|
|
213
|
+
*/
|
|
214
|
+
async closeIssue(owner, repo, issueNumber, reason = 'completed') {
|
|
215
|
+
return this.updateIssue({
|
|
216
|
+
owner,
|
|
217
|
+
repo,
|
|
218
|
+
issue_number: issueNumber,
|
|
219
|
+
state: 'closed',
|
|
220
|
+
state_reason: reason,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Reopen an issue
|
|
225
|
+
*/
|
|
226
|
+
async reopenIssue(owner, repo, issueNumber) {
|
|
227
|
+
return this.updateIssue({
|
|
228
|
+
owner,
|
|
229
|
+
repo,
|
|
230
|
+
issue_number: issueNumber,
|
|
231
|
+
state: 'open',
|
|
232
|
+
state_reason: 'reopened',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
// ============================================================================
|
|
236
|
+
// COMMENT OPERATIONS
|
|
237
|
+
// ============================================================================
|
|
238
|
+
/**
|
|
239
|
+
* Add a comment to an issue
|
|
240
|
+
*/
|
|
241
|
+
async addComment(owner, repo, issueNumber, body) {
|
|
242
|
+
try {
|
|
243
|
+
await this.octokit.issues.createComment({
|
|
244
|
+
owner,
|
|
245
|
+
repo,
|
|
246
|
+
issue_number: issueNumber,
|
|
247
|
+
body,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
this.handleError(error, 'addComment');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// LABEL OPERATIONS
|
|
256
|
+
// ============================================================================
|
|
257
|
+
/**
|
|
258
|
+
* Get a label
|
|
259
|
+
*/
|
|
260
|
+
async getLabel(owner, repo, labelName) {
|
|
261
|
+
try {
|
|
262
|
+
const { data } = await this.octokit.issues.getLabel({
|
|
263
|
+
owner,
|
|
264
|
+
repo,
|
|
265
|
+
name: labelName,
|
|
266
|
+
});
|
|
267
|
+
return {
|
|
268
|
+
name: data.name,
|
|
269
|
+
color: data.color,
|
|
270
|
+
description: data.description,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
const err = error;
|
|
275
|
+
if (err.status === 404) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
this.handleError(error, 'getLabel');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Create a label
|
|
283
|
+
*/
|
|
284
|
+
async createLabel(owner, repo, name, color, description) {
|
|
285
|
+
try {
|
|
286
|
+
const { data } = await this.octokit.issues.createLabel({
|
|
287
|
+
owner,
|
|
288
|
+
repo,
|
|
289
|
+
name,
|
|
290
|
+
color,
|
|
291
|
+
description,
|
|
292
|
+
});
|
|
293
|
+
return {
|
|
294
|
+
name: data.name,
|
|
295
|
+
color: data.color,
|
|
296
|
+
description: data.description,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
const err = error;
|
|
301
|
+
// If label already exists, ignore the error
|
|
302
|
+
if (err.status === 422) {
|
|
303
|
+
return { name, color, description: description || null };
|
|
304
|
+
}
|
|
305
|
+
this.handleError(error, 'createLabel');
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Add labels to an issue
|
|
310
|
+
*/
|
|
311
|
+
async addLabels(owner, repo, issueNumber, labels) {
|
|
312
|
+
try {
|
|
313
|
+
await this.octokit.issues.addLabels({
|
|
314
|
+
owner,
|
|
315
|
+
repo,
|
|
316
|
+
issue_number: issueNumber,
|
|
317
|
+
labels,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
this.handleError(error, 'addLabels');
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Remove a label from an issue
|
|
326
|
+
*/
|
|
327
|
+
async removeLabel(owner, repo, issueNumber, label) {
|
|
328
|
+
try {
|
|
329
|
+
await this.octokit.issues.removeLabel({
|
|
330
|
+
owner,
|
|
331
|
+
repo,
|
|
332
|
+
issue_number: issueNumber,
|
|
333
|
+
name: label,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
const err = error;
|
|
338
|
+
// Ignore if label doesn't exist on the issue
|
|
339
|
+
if (err.status === 404) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this.handleError(error, 'removeLabel');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// ============================================================================
|
|
346
|
+
// SEARCH OPERATIONS
|
|
347
|
+
// ============================================================================
|
|
348
|
+
/**
|
|
349
|
+
* Search issues
|
|
350
|
+
*/
|
|
351
|
+
async searchIssues(params) {
|
|
352
|
+
try {
|
|
353
|
+
const { data } = await this.octokit.search.issuesAndPullRequests({
|
|
354
|
+
q: params.query + ' is:issue',
|
|
355
|
+
per_page: params.per_page || 50,
|
|
356
|
+
page: params.page || 1,
|
|
357
|
+
});
|
|
358
|
+
return data.items.map((item) => this.normalizeIssue(item));
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
this.handleError(error, 'searchIssues');
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// ============================================================================
|
|
365
|
+
// REPOSITORY OPERATIONS
|
|
366
|
+
// ============================================================================
|
|
367
|
+
/**
|
|
368
|
+
* List repositories for authenticated user
|
|
369
|
+
*/
|
|
370
|
+
async listRepos(limit = 20) {
|
|
371
|
+
try {
|
|
372
|
+
const { data } = await this.octokit.repos.listForAuthenticatedUser({
|
|
373
|
+
per_page: limit,
|
|
374
|
+
sort: 'pushed',
|
|
375
|
+
});
|
|
376
|
+
return data.map((repo) => ({ nameWithOwner: repo.full_name }));
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
this.handleError(error, 'listRepos');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// ============================================================================
|
|
383
|
+
// HELPERS
|
|
384
|
+
// ============================================================================
|
|
385
|
+
/**
|
|
386
|
+
* Normalize issue data to our interface
|
|
387
|
+
*/
|
|
388
|
+
normalizeIssue(data) {
|
|
389
|
+
return {
|
|
390
|
+
number: data.number,
|
|
391
|
+
title: data.title,
|
|
392
|
+
body: data.body,
|
|
393
|
+
state: data.state,
|
|
394
|
+
state_reason: data.state_reason,
|
|
395
|
+
labels: (data.labels || []).map((label) => ({
|
|
396
|
+
name: typeof label === 'string' ? label : label.name,
|
|
397
|
+
color: typeof label === 'string' ? undefined : label.color,
|
|
398
|
+
description: typeof label === 'string' ? null : label.description,
|
|
399
|
+
})),
|
|
400
|
+
assignees: data.assignees || [],
|
|
401
|
+
created_at: data.created_at,
|
|
402
|
+
updated_at: data.updated_at,
|
|
403
|
+
closed_at: data.closed_at,
|
|
404
|
+
html_url: data.html_url,
|
|
405
|
+
milestone: data.milestone ? { title: data.milestone.title } : null,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
// Export singleton getter for convenience
|
|
410
|
+
export const gitHubClient = GitHubClient.getInstance();
|
|
411
|
+
//# sourceMappingURL=GitHubClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitHubClient.js","sourceRoot":"","sources":["../../src/engine/GitHubClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Enterprise Agent Supervisor - Rate Limiter
|
|
3
3
|
*
|
|
4
4
|
* Token bucket rate limiting with multiple scopes and configurations.
|
|
5
|
+
* Uses extracted utilities from src/utils/rate-limiting.ts for
|
|
6
|
+
* bucket key building and sliding window logic.
|
|
5
7
|
*/
|
|
6
8
|
import type { RateLimitConfig, RateLimitState, ActionCategory } from '../types/index.js';
|
|
7
9
|
export declare class RateLimiter {
|
|
@@ -62,11 +64,11 @@ export declare class RateLimiter {
|
|
|
62
64
|
*/
|
|
63
65
|
clearBuckets(): void;
|
|
64
66
|
/**
|
|
65
|
-
*
|
|
67
|
+
* Convert params to BucketIdentifiers for the utility function
|
|
66
68
|
*/
|
|
67
|
-
private
|
|
69
|
+
private toIdentifiers;
|
|
68
70
|
/**
|
|
69
|
-
* Get or create a bucket
|
|
71
|
+
* Get or create a bucket with SlidingWindow
|
|
70
72
|
*/
|
|
71
73
|
private getOrCreateBucket;
|
|
72
74
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/engine/RateLimiter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/engine/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWzF,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,iBAAiB,CAAyB;IAElD;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAI5C;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAMhD;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,cAAc,CAAC;QAChC,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,cAAc,CAAA;KAAE;IAyDlE;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,cAAc,CAAC;QAChC,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI;IAqBR;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,cAAc,GAAG,IAAI;IA8BzB;;OAEG;IACH,UAAU,IAAI,eAAe,EAAE;IAI/B;;OAEG;IACH,YAAY,IAAI,IAAI;IAIpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAmC9B;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Enterprise Agent Supervisor - Rate Limiter
|
|
3
3
|
*
|
|
4
4
|
* Token bucket rate limiting with multiple scopes and configurations.
|
|
5
|
+
* Uses extracted utilities from src/utils/rate-limiting.ts for
|
|
6
|
+
* bucket key building and sliding window logic.
|
|
5
7
|
*/
|
|
8
|
+
import { buildBucketKey, SlidingWindow } from '../utils/rate-limiting.js';
|
|
6
9
|
export class RateLimiter {
|
|
7
10
|
configs = new Map();
|
|
8
11
|
buckets = new Map();
|
|
@@ -44,43 +47,37 @@ export class RateLimiter {
|
|
|
44
47
|
continue;
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
// Build bucket key
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
if
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
bucket.windowStart = now;
|
|
55
|
-
bucket.burstCount = 0;
|
|
56
|
-
}
|
|
57
|
-
// Check limits
|
|
58
|
-
if (bucket.count >= config.maxRequests) {
|
|
59
|
-
const resetAt = new Date(bucket.windowStart + config.windowMs);
|
|
50
|
+
// Build bucket key using extracted utility
|
|
51
|
+
const identifiers = this.toIdentifiers(params);
|
|
52
|
+
const bucketKey = buildBucketKey(config.scope, identifiers, configId);
|
|
53
|
+
const bucket = this.getOrCreateBucket(bucketKey, config);
|
|
54
|
+
// Check if window can accept using SlidingWindow
|
|
55
|
+
if (!bucket.window.canAccept(now)) {
|
|
56
|
+
const stats = bucket.window.getStats(now);
|
|
60
57
|
return {
|
|
61
58
|
allowed: false,
|
|
62
59
|
limitId: configId,
|
|
63
60
|
state: {
|
|
64
61
|
key: bucketKey,
|
|
65
|
-
count:
|
|
66
|
-
windowStart:
|
|
62
|
+
count: stats.count,
|
|
63
|
+
windowStart: stats.windowStart,
|
|
67
64
|
remaining: 0,
|
|
68
|
-
resetAt:
|
|
65
|
+
resetAt: stats.resetAtISO
|
|
69
66
|
}
|
|
70
67
|
};
|
|
71
68
|
}
|
|
72
69
|
// Check burst limit if configured
|
|
73
|
-
if (config.burstLimit && bucket.
|
|
74
|
-
const
|
|
70
|
+
if (config.burstLimit && !bucket.window.canAcceptBurst(now)) {
|
|
71
|
+
const stats = bucket.window.getStats(now);
|
|
75
72
|
return {
|
|
76
73
|
allowed: false,
|
|
77
74
|
limitId: configId,
|
|
78
75
|
state: {
|
|
79
76
|
key: bucketKey,
|
|
80
|
-
count:
|
|
81
|
-
windowStart:
|
|
77
|
+
count: stats.count,
|
|
78
|
+
windowStart: stats.windowStart,
|
|
82
79
|
remaining: 0,
|
|
83
|
-
resetAt:
|
|
80
|
+
resetAt: stats.resetAtISO
|
|
84
81
|
}
|
|
85
82
|
};
|
|
86
83
|
}
|
|
@@ -100,16 +97,11 @@ export class RateLimiter {
|
|
|
100
97
|
continue;
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
bucket.windowStart = now;
|
|
109
|
-
bucket.burstCount = 0;
|
|
110
|
-
}
|
|
111
|
-
bucket.count++;
|
|
112
|
-
bucket.burstCount++;
|
|
100
|
+
const identifiers = this.toIdentifiers(params);
|
|
101
|
+
const bucketKey = buildBucketKey(config.scope, identifiers, configId);
|
|
102
|
+
const bucket = this.getOrCreateBucket(bucketKey, config);
|
|
103
|
+
// Record the request in the sliding window
|
|
104
|
+
bucket.window.record(now);
|
|
113
105
|
}
|
|
114
106
|
}
|
|
115
107
|
/**
|
|
@@ -120,7 +112,8 @@ export class RateLimiter {
|
|
|
120
112
|
if (!config)
|
|
121
113
|
return null;
|
|
122
114
|
const now = Date.now();
|
|
123
|
-
const
|
|
115
|
+
const identifiers = this.toIdentifiers(params);
|
|
116
|
+
const bucketKey = buildBucketKey(config.scope, identifiers, configId);
|
|
124
117
|
const bucket = this.buckets.get(bucketKey);
|
|
125
118
|
if (!bucket) {
|
|
126
119
|
return {
|
|
@@ -131,22 +124,13 @@ export class RateLimiter {
|
|
|
131
124
|
resetAt: new Date(now + config.windowMs).toISOString()
|
|
132
125
|
};
|
|
133
126
|
}
|
|
134
|
-
|
|
135
|
-
if (now - bucket.windowStart >= config.windowMs) {
|
|
136
|
-
return {
|
|
137
|
-
key: bucketKey,
|
|
138
|
-
count: 0,
|
|
139
|
-
windowStart: now,
|
|
140
|
-
remaining: config.maxRequests,
|
|
141
|
-
resetAt: new Date(now + config.windowMs).toISOString()
|
|
142
|
-
};
|
|
143
|
-
}
|
|
127
|
+
const stats = bucket.window.getStats(now);
|
|
144
128
|
return {
|
|
145
129
|
key: bucketKey,
|
|
146
|
-
count:
|
|
147
|
-
windowStart:
|
|
148
|
-
remaining:
|
|
149
|
-
resetAt:
|
|
130
|
+
count: stats.count,
|
|
131
|
+
windowStart: stats.windowStart,
|
|
132
|
+
remaining: stats.remaining,
|
|
133
|
+
resetAt: stats.resetAtISO
|
|
150
134
|
};
|
|
151
135
|
}
|
|
152
136
|
/**
|
|
@@ -162,34 +146,30 @@ export class RateLimiter {
|
|
|
162
146
|
this.buckets.clear();
|
|
163
147
|
}
|
|
164
148
|
/**
|
|
165
|
-
*
|
|
149
|
+
* Convert params to BucketIdentifiers for the utility function
|
|
166
150
|
*/
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return `${configId}:session:${params.sessionId || 'unknown'}`;
|
|
175
|
-
case 'user':
|
|
176
|
-
return `${configId}:user:${params.userId || 'unknown'}`;
|
|
177
|
-
case 'action_type':
|
|
178
|
-
return `${configId}:action:${params.actionType || 'unknown'}`;
|
|
179
|
-
default:
|
|
180
|
-
return `${configId}:unknown`;
|
|
181
|
-
}
|
|
151
|
+
toIdentifiers(params) {
|
|
152
|
+
return {
|
|
153
|
+
agentId: params.agentId,
|
|
154
|
+
sessionId: params.sessionId,
|
|
155
|
+
userId: params.userId,
|
|
156
|
+
actionType: params.actionType
|
|
157
|
+
};
|
|
182
158
|
}
|
|
183
159
|
/**
|
|
184
|
-
* Get or create a bucket
|
|
160
|
+
* Get or create a bucket with SlidingWindow
|
|
185
161
|
*/
|
|
186
|
-
getOrCreateBucket(key,
|
|
162
|
+
getOrCreateBucket(key, config) {
|
|
187
163
|
let bucket = this.buckets.get(key);
|
|
188
164
|
if (!bucket) {
|
|
189
165
|
bucket = {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
166
|
+
key,
|
|
167
|
+
window: new SlidingWindow({
|
|
168
|
+
windowMs: config.windowMs,
|
|
169
|
+
maxRequests: config.maxRequests,
|
|
170
|
+
burstLimit: config.burstLimit,
|
|
171
|
+
algorithm: 'fixed' // Use fixed window for consistent behavior with original implementation
|
|
172
|
+
})
|
|
193
173
|
};
|
|
194
174
|
this.buckets.set(key, bucket);
|
|
195
175
|
}
|
|
@@ -213,11 +193,14 @@ export class RateLimiter {
|
|
|
213
193
|
}
|
|
214
194
|
}
|
|
215
195
|
// Remove buckets that are older than the maximum window
|
|
216
|
-
//
|
|
217
|
-
|
|
196
|
+
// This uses >= for consistency with window expiration checks
|
|
197
|
+
// A bucket is expired when: now - windowStart >= 2*maxWindowMs (2x safety margin)
|
|
218
198
|
let removedCount = 0;
|
|
219
199
|
for (const [key, bucket] of this.buckets.entries()) {
|
|
220
|
-
|
|
200
|
+
const state = bucket.window.getState();
|
|
201
|
+
// Off-by-one fix: use consistent >= comparison for boundary calculation
|
|
202
|
+
// Window boundary semantics: now - windowStart >= threshold means expired
|
|
203
|
+
if (now - state.windowStart >= maxWindowMs * 2) {
|
|
221
204
|
this.buckets.delete(key);
|
|
222
205
|
removedCount++;
|
|
223
206
|
}
|