@zhin.js/adapter-github 0.1.34 → 0.1.36
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/lib/adapter.d.ts +52 -9
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +254 -189
- package/lib/adapter.js.map +1 -1
- package/lib/bot.d.ts +5 -2
- package/lib/bot.d.ts.map +1 -1
- package/lib/bot.js +19 -26
- package/lib/bot.js.map +1 -1
- package/lib/{api.d.ts → gh-client.d.ts} +113 -42
- package/lib/gh-client.d.ts.map +1 -0
- package/lib/gh-client.js +555 -0
- package/lib/gh-client.js.map +1 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +213 -127
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +23 -29
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +2 -2
- package/lib/types.js.map +1 -1
- package/package.json +7 -6
- package/plugin.yml +3 -0
- package/skills/github/SKILL.md +17 -8
- package/src/adapter.ts +265 -188
- package/src/bot.ts +19 -25
- package/src/gh-client.ts +640 -0
- package/src/index.ts +220 -124
- package/src/types.ts +29 -34
- package/lib/api.d.ts.map +0 -1
- package/lib/api.js +0 -300
- package/lib/api.js.map +0 -1
- package/src/api.ts +0 -353
package/lib/gh-client.js
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub CLI (`gh`) 客户端封装
|
|
3
|
+
*
|
|
4
|
+
* 支持三种认证方式:
|
|
5
|
+
* 1. gh CLI 默认凭据(gh auth login)
|
|
6
|
+
* 2. GitHub App — JWT → Installation Token(自动续期)
|
|
7
|
+
* 3. 个人 OAuth Token(用户绑定 / Device Flow)
|
|
8
|
+
*
|
|
9
|
+
* 零外部依赖,使用 Node.js 原生模块。
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from 'node:child_process';
|
|
12
|
+
import crypto from 'node:crypto';
|
|
13
|
+
import fs from 'node:fs';
|
|
14
|
+
export class GhClient {
|
|
15
|
+
host;
|
|
16
|
+
token;
|
|
17
|
+
_appAuth;
|
|
18
|
+
_resolvedKey;
|
|
19
|
+
_user = null;
|
|
20
|
+
/** Installation Token 缓存: installationId → { token, expiresAt } */
|
|
21
|
+
_installationTokens = new Map();
|
|
22
|
+
/** repo(小写) → installationId */
|
|
23
|
+
_repoToInstallation = new Map();
|
|
24
|
+
/** 所有 Installation 信息 */
|
|
25
|
+
_allInstallations = [];
|
|
26
|
+
/** 上次 syncInstallations 时间 (ms) */
|
|
27
|
+
_lastSyncTime = 0;
|
|
28
|
+
constructor(options = {}) {
|
|
29
|
+
this.host = options.host;
|
|
30
|
+
this.token = options.token;
|
|
31
|
+
this._appAuth = options.appAuth;
|
|
32
|
+
}
|
|
33
|
+
/** 创建使用指定 token 的副本(共享 host 配置,不继承 App 认证) */
|
|
34
|
+
withToken(token) {
|
|
35
|
+
return new GhClient({ host: this.host, token });
|
|
36
|
+
}
|
|
37
|
+
get authenticatedUser() { return this._user; }
|
|
38
|
+
// ── 底层执行 ──────────────────────────────────────────────────────
|
|
39
|
+
exec(args, stdin) {
|
|
40
|
+
const fullArgs = this.host ? [...args, '--hostname', this.host] : args;
|
|
41
|
+
const env = this.token
|
|
42
|
+
? { ...process.env, GH_TOKEN: this.token }
|
|
43
|
+
: undefined;
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const proc = spawn('gh', fullArgs, { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
46
|
+
let stdout = '';
|
|
47
|
+
let stderr = '';
|
|
48
|
+
proc.stdout.on('data', (d) => (stdout += d.toString()));
|
|
49
|
+
proc.stderr.on('data', (d) => (stderr += d.toString()));
|
|
50
|
+
proc.on('error', (err) => {
|
|
51
|
+
if (err.code === 'ENOENT')
|
|
52
|
+
reject(new Error('gh CLI 未安装,请先安装: https://cli.github.com/'));
|
|
53
|
+
else
|
|
54
|
+
reject(err);
|
|
55
|
+
});
|
|
56
|
+
proc.on('close', (code) => {
|
|
57
|
+
if (code === 0)
|
|
58
|
+
resolve(stdout);
|
|
59
|
+
else
|
|
60
|
+
reject(Object.assign(new Error(stderr.trim() || `gh exited with code ${code}`), {
|
|
61
|
+
stdout,
|
|
62
|
+
stderr,
|
|
63
|
+
exitCode: code,
|
|
64
|
+
}));
|
|
65
|
+
});
|
|
66
|
+
if (stdin !== undefined)
|
|
67
|
+
proc.stdin.write(stdin);
|
|
68
|
+
proc.stdin.end();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// ── API 调用 ──────────────────────────────────────────────────────
|
|
72
|
+
/**
|
|
73
|
+
* 确保 App 认证的 Installation Token 有效(自动按 repo 查找对应安装)
|
|
74
|
+
* @param repo 仓库全名(owner/repo),用于选择正确的 Installation
|
|
75
|
+
*/
|
|
76
|
+
async ensureTokenForRepo(repo) {
|
|
77
|
+
if (!this._appAuth)
|
|
78
|
+
return;
|
|
79
|
+
let installId;
|
|
80
|
+
if (repo) {
|
|
81
|
+
const key = repo.toLowerCase();
|
|
82
|
+
installId = this._repoToInstallation.get(key);
|
|
83
|
+
if (!installId) {
|
|
84
|
+
// Owner 级别匹配(安装在整个账号/组织上)
|
|
85
|
+
const owner = key.split('/')[0];
|
|
86
|
+
for (const inst of this._allInstallations) {
|
|
87
|
+
if (inst.account.login.toLowerCase() === owner) {
|
|
88
|
+
installId = inst.id;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 懒加载重新发现(5 分钟冷却)
|
|
94
|
+
if (!installId && Date.now() - this._lastSyncTime > 5 * 60_000) {
|
|
95
|
+
await this.syncInstallations();
|
|
96
|
+
installId = this._repoToInstallation.get(key);
|
|
97
|
+
if (!installId) {
|
|
98
|
+
const owner = key.split('/')[0];
|
|
99
|
+
for (const inst of this._allInstallations) {
|
|
100
|
+
if (inst.account.login.toLowerCase() === owner) {
|
|
101
|
+
installId = inst.id;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// 回退到第一个安装
|
|
109
|
+
if (!installId && this._allInstallations.length) {
|
|
110
|
+
installId = this._allInstallations[0].id;
|
|
111
|
+
}
|
|
112
|
+
if (!installId)
|
|
113
|
+
return;
|
|
114
|
+
const cached = this._installationTokens.get(installId);
|
|
115
|
+
if (cached && cached.expiresAt > Date.now() + 60_000) {
|
|
116
|
+
this.token = cached.token;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await this.refreshInstallationToken(installId);
|
|
120
|
+
}
|
|
121
|
+
async request(method, path, body, headers) {
|
|
122
|
+
// 从路径自动检测 repo 以选择正确的 Installation Token
|
|
123
|
+
const repoMatch = path.match(/^\/repos\/([^/?]+\/[^/?]+)/);
|
|
124
|
+
await this.ensureTokenForRepo(repoMatch?.[1]);
|
|
125
|
+
const args = ['api', path, '--method', method];
|
|
126
|
+
if (body)
|
|
127
|
+
args.push('--input', '-');
|
|
128
|
+
if (headers) {
|
|
129
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
130
|
+
args.push('-H', `${k}: ${v}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const raw = await this.exec(args, body ? JSON.stringify(body) : undefined);
|
|
135
|
+
let data;
|
|
136
|
+
try {
|
|
137
|
+
data = raw ? JSON.parse(raw) : null;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
data = raw;
|
|
141
|
+
}
|
|
142
|
+
return { ok: true, status: 200, data };
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
let data;
|
|
146
|
+
try {
|
|
147
|
+
data = err.stdout ? JSON.parse(err.stdout) : { message: err.message };
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
data = { message: err.stderr?.trim() || err.message };
|
|
151
|
+
}
|
|
152
|
+
return { ok: false, status: err.exitCode || 0, data };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
get(path) { return this.request('GET', path); }
|
|
156
|
+
post(path, body) { return this.request('POST', path, body); }
|
|
157
|
+
patch(path, body) { return this.request('PATCH', path, body); }
|
|
158
|
+
put(path, body) { return this.request('PUT', path, body); }
|
|
159
|
+
del(path, body) { return this.request('DELETE', path, body); }
|
|
160
|
+
// ── 认证验证 ──────────────────────────────────────────────────────
|
|
161
|
+
async verifyAuth() {
|
|
162
|
+
// App 认证模式:自动发现所有安装
|
|
163
|
+
if (this._appAuth) {
|
|
164
|
+
try {
|
|
165
|
+
await this.syncInstallations();
|
|
166
|
+
if (!this._allInstallations.length) {
|
|
167
|
+
return { ok: false, user: '', message: 'GitHub App 没有任何安装,请先在 GitHub 上安装 App' };
|
|
168
|
+
}
|
|
169
|
+
// 用 JWT 查询 App 信息(/app 端点只接受 JWT 认证,不能用 Installation Token)
|
|
170
|
+
const key = this.resolvePrivateKey();
|
|
171
|
+
const jwt = GhClient.createJWT(this._appAuth.appId, key);
|
|
172
|
+
const baseUrl = this.host ? `https://${this.host}/api/v3` : 'https://api.github.com';
|
|
173
|
+
const appRes = await fetch(`${baseUrl}/app`, {
|
|
174
|
+
headers: { Authorization: `Bearer ${jwt}`, Accept: 'application/vnd.github+json' },
|
|
175
|
+
});
|
|
176
|
+
if (appRes.ok) {
|
|
177
|
+
const appData = (await appRes.json());
|
|
178
|
+
const name = `${appData.slug || appData.name}[bot]`;
|
|
179
|
+
this._user = name;
|
|
180
|
+
this._appSlug = appData.slug || null;
|
|
181
|
+
if (appData.client_id)
|
|
182
|
+
this._clientId = appData.client_id;
|
|
183
|
+
const repos = this._repoToInstallation.size;
|
|
184
|
+
return { ok: true, user: name, message: `GitHub App: ${name} (${this._allInstallations.length} 安装, ${repos} 仓库)` };
|
|
185
|
+
}
|
|
186
|
+
const errBody = await appRes.text();
|
|
187
|
+
return { ok: false, user: '', message: `App Token 验证失败 (${appRes.status}): ${errBody}` };
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
return { ok: false, user: '', message: e.message || 'App 认证失败' };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Token 模式(用户绑定)或 gh CLI 默认模式
|
|
194
|
+
try {
|
|
195
|
+
if (this.token) {
|
|
196
|
+
// 直接用 token 查 /user
|
|
197
|
+
const r = await this.get('/user');
|
|
198
|
+
if (r.ok) {
|
|
199
|
+
this._user = r.data.login;
|
|
200
|
+
return { ok: true, user: r.data.login, message: `token: ${r.data.login}` };
|
|
201
|
+
}
|
|
202
|
+
return { ok: false, user: '', message: 'Token 无效' };
|
|
203
|
+
}
|
|
204
|
+
await this.exec(['auth', 'status']);
|
|
205
|
+
const raw = await this.exec(['api', '/user', '--jq', '.login']);
|
|
206
|
+
const login = raw.trim();
|
|
207
|
+
this._user = login;
|
|
208
|
+
return { ok: true, user: login, message: `gh CLI: ${login}` };
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
return { ok: false, user: '', message: e.message || 'gh 认证检查失败' };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ── Issue 评论 (聊天核心) ─────────────────────────────────────────
|
|
215
|
+
async createIssueComment(repo, issueNumber, body) {
|
|
216
|
+
return this.post(`/repos/${repo}/issues/${issueNumber}/comments`, { body });
|
|
217
|
+
}
|
|
218
|
+
async deleteIssueComment(repo, commentId) {
|
|
219
|
+
return this.del(`/repos/${repo}/issues/comments/${commentId}`);
|
|
220
|
+
}
|
|
221
|
+
async createPRComment(repo, prNumber, body) {
|
|
222
|
+
return this.createIssueComment(repo, prNumber, body);
|
|
223
|
+
}
|
|
224
|
+
async deletePRReviewComment(repo, commentId) {
|
|
225
|
+
return this.del(`/repos/${repo}/pulls/comments/${commentId}`);
|
|
226
|
+
}
|
|
227
|
+
// ── Pull Requests ─────────────────────────────────────────────────
|
|
228
|
+
async listPRs(repo, state = 'open', limit = 15) {
|
|
229
|
+
return this.get(`/repos/${repo}/pulls?state=${state}&per_page=${limit}`);
|
|
230
|
+
}
|
|
231
|
+
async getPR(repo, number) {
|
|
232
|
+
return this.get(`/repos/${repo}/pulls/${number}`);
|
|
233
|
+
}
|
|
234
|
+
async getPRDiff(repo, number) {
|
|
235
|
+
return this.request('GET', `/repos/${repo}/pulls/${number}`, undefined, {
|
|
236
|
+
Accept: 'application/vnd.github.diff',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
async mergePR(repo, number, method = 'squash') {
|
|
240
|
+
return this.put(`/repos/${repo}/pulls/${number}/merge`, { merge_method: method });
|
|
241
|
+
}
|
|
242
|
+
async createPR(repo, title, body, head, base = 'main') {
|
|
243
|
+
return this.post(`/repos/${repo}/pulls`, { title, body, head, base });
|
|
244
|
+
}
|
|
245
|
+
async createPRReview(repo, number, event, body) {
|
|
246
|
+
return this.post(`/repos/${repo}/pulls/${number}/reviews`, { event, body: body || '' });
|
|
247
|
+
}
|
|
248
|
+
async closePR(repo, number) {
|
|
249
|
+
return this.patch(`/repos/${repo}/pulls/${number}`, { state: 'closed' });
|
|
250
|
+
}
|
|
251
|
+
// ── Issues ────────────────────────────────────────────────────────
|
|
252
|
+
async listIssues(repo, state = 'open', limit = 15) {
|
|
253
|
+
return this.get(`/repos/${repo}/issues?state=${state}&per_page=${limit}&direction=desc`);
|
|
254
|
+
}
|
|
255
|
+
async getIssue(repo, number) {
|
|
256
|
+
return this.get(`/repos/${repo}/issues/${number}`);
|
|
257
|
+
}
|
|
258
|
+
async createIssue(repo, title, body, labels) {
|
|
259
|
+
return this.post(`/repos/${repo}/issues`, { title, body, labels });
|
|
260
|
+
}
|
|
261
|
+
async closeIssue(repo, number) {
|
|
262
|
+
return this.patch(`/repos/${repo}/issues/${number}`, { state: 'closed', state_reason: 'completed' });
|
|
263
|
+
}
|
|
264
|
+
// ── Repository ────────────────────────────────────────────────────
|
|
265
|
+
async getRepo(repo) {
|
|
266
|
+
return this.get(`/repos/${repo}`);
|
|
267
|
+
}
|
|
268
|
+
async listBranches(repo, limit = 30) {
|
|
269
|
+
return this.get(`/repos/${repo}/branches?per_page=${limit}`);
|
|
270
|
+
}
|
|
271
|
+
async listReleases(repo, limit = 10) {
|
|
272
|
+
return this.get(`/repos/${repo}/releases?per_page=${limit}`);
|
|
273
|
+
}
|
|
274
|
+
async listWorkflowRuns(repo, limit = 10) {
|
|
275
|
+
return this.get(`/repos/${repo}/actions/runs?per_page=${limit}`);
|
|
276
|
+
}
|
|
277
|
+
// ── Search ───────────────────────────────────────────────────────
|
|
278
|
+
async searchIssues(query, limit = 15) {
|
|
279
|
+
return this.get(`/search/issues?q=${encodeURIComponent(query)}&per_page=${limit}`);
|
|
280
|
+
}
|
|
281
|
+
async searchRepos(query, limit = 15) {
|
|
282
|
+
return this.get(`/search/repositories?q=${encodeURIComponent(query)}&per_page=${limit}`);
|
|
283
|
+
}
|
|
284
|
+
async searchCode(query, limit = 15) {
|
|
285
|
+
return this.get(`/search/code?q=${encodeURIComponent(query)}&per_page=${limit}`);
|
|
286
|
+
}
|
|
287
|
+
// ── Labels ───────────────────────────────────────────────────────
|
|
288
|
+
async listLabels(repo) {
|
|
289
|
+
return this.get(`/repos/${repo}/labels?per_page=100`);
|
|
290
|
+
}
|
|
291
|
+
async addLabels(repo, issueNumber, labels) {
|
|
292
|
+
return this.post(`/repos/${repo}/issues/${issueNumber}/labels`, { labels });
|
|
293
|
+
}
|
|
294
|
+
async removeLabel(repo, issueNumber, label) {
|
|
295
|
+
return this.del(`/repos/${repo}/issues/${issueNumber}/labels/${encodeURIComponent(label)}`);
|
|
296
|
+
}
|
|
297
|
+
// ── Assignees ────────────────────────────────────────────────────
|
|
298
|
+
async addAssignees(repo, issueNumber, assignees) {
|
|
299
|
+
return this.post(`/repos/${repo}/issues/${issueNumber}/assignees`, { assignees });
|
|
300
|
+
}
|
|
301
|
+
async removeAssignees(repo, issueNumber, assignees) {
|
|
302
|
+
return this.del(`/repos/${repo}/issues/${issueNumber}/assignees`, { assignees });
|
|
303
|
+
}
|
|
304
|
+
// ── File Content ─────────────────────────────────────────────────
|
|
305
|
+
async getFileContent(repo, filePath, ref) {
|
|
306
|
+
const qs = ref ? `?ref=${encodeURIComponent(ref)}` : '';
|
|
307
|
+
return this.get(`/repos/${repo}/contents/${filePath}${qs}`);
|
|
308
|
+
}
|
|
309
|
+
// ── Commits ──────────────────────────────────────────────────────
|
|
310
|
+
async listCommits(repo, sha, filePath, limit = 15) {
|
|
311
|
+
const params = new URLSearchParams({ per_page: String(limit) });
|
|
312
|
+
if (sha)
|
|
313
|
+
params.set('sha', sha);
|
|
314
|
+
if (filePath)
|
|
315
|
+
params.set('path', filePath);
|
|
316
|
+
return this.get(`/repos/${repo}/commits?${params}`);
|
|
317
|
+
}
|
|
318
|
+
async compareCommits(repo, base, head) {
|
|
319
|
+
return this.get(`/repos/${repo}/compare/${encodeURIComponent(base)}...${encodeURIComponent(head)}`);
|
|
320
|
+
}
|
|
321
|
+
// ── Update Issue / PR ────────────────────────────────────────────
|
|
322
|
+
async updateIssue(repo, number, data) {
|
|
323
|
+
return this.patch(`/repos/${repo}/issues/${number}`, data);
|
|
324
|
+
}
|
|
325
|
+
async updatePR(repo, number, data) {
|
|
326
|
+
return this.patch(`/repos/${repo}/pulls/${number}`, data);
|
|
327
|
+
}
|
|
328
|
+
// ── Star ─────────────────────────────────────────────────────────
|
|
329
|
+
async starRepo(repo) {
|
|
330
|
+
return this.put(`/user/starred/${repo}`);
|
|
331
|
+
}
|
|
332
|
+
async unstarRepo(repo) {
|
|
333
|
+
return this.del(`/user/starred/${repo}`);
|
|
334
|
+
}
|
|
335
|
+
async isStarred(repo) {
|
|
336
|
+
const r = await this.request('GET', `/user/starred/${repo}`);
|
|
337
|
+
return r.ok;
|
|
338
|
+
}
|
|
339
|
+
// ── Fork ─────────────────────────────────────────────────────────
|
|
340
|
+
async forkRepo(repo) {
|
|
341
|
+
return this.post(`/repos/${repo}/forks`);
|
|
342
|
+
}
|
|
343
|
+
// ── GitHub App JWT + Installation Token ──────────────────────────
|
|
344
|
+
/** 解析私钥:PEM字符串 或 文件路径 */
|
|
345
|
+
resolvePrivateKey() {
|
|
346
|
+
if (this._resolvedKey)
|
|
347
|
+
return this._resolvedKey;
|
|
348
|
+
if (!this._appAuth)
|
|
349
|
+
throw new Error('未配置 App 认证');
|
|
350
|
+
let key = this._appAuth.privateKey;
|
|
351
|
+
if (!key.includes('-----BEGIN')) {
|
|
352
|
+
// 当作文件路径读取
|
|
353
|
+
key = fs.readFileSync(key, 'utf-8');
|
|
354
|
+
}
|
|
355
|
+
this._resolvedKey = key;
|
|
356
|
+
return key;
|
|
357
|
+
}
|
|
358
|
+
/** 生成 GitHub App JWT(有效期 10 分钟) */
|
|
359
|
+
static createJWT(appId, privateKey) {
|
|
360
|
+
const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');
|
|
361
|
+
const now = Math.floor(Date.now() / 1000);
|
|
362
|
+
const payload = Buffer.from(JSON.stringify({
|
|
363
|
+
iat: now - 60,
|
|
364
|
+
exp: now + 600,
|
|
365
|
+
iss: String(appId),
|
|
366
|
+
})).toString('base64url');
|
|
367
|
+
const signature = crypto
|
|
368
|
+
.sign('sha256', Buffer.from(`${header}.${payload}`), privateKey)
|
|
369
|
+
.toString('base64url');
|
|
370
|
+
return `${header}.${payload}.${signature}`;
|
|
371
|
+
}
|
|
372
|
+
/** 使用 JWT 获取指定 Installation 的 Access Token(有效期 1 小时) */
|
|
373
|
+
async refreshInstallationToken(installationId) {
|
|
374
|
+
if (!this._appAuth)
|
|
375
|
+
throw new Error('未配置 App 认证');
|
|
376
|
+
const key = this.resolvePrivateKey();
|
|
377
|
+
const jwt = GhClient.createJWT(this._appAuth.appId, key);
|
|
378
|
+
const baseUrl = this.host
|
|
379
|
+
? `https://${this.host}/api/v3`
|
|
380
|
+
: 'https://api.github.com';
|
|
381
|
+
const res = await fetch(`${baseUrl}/app/installations/${installationId}/access_tokens`, {
|
|
382
|
+
method: 'POST',
|
|
383
|
+
headers: {
|
|
384
|
+
Authorization: `Bearer ${jwt}`,
|
|
385
|
+
Accept: 'application/vnd.github+json',
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
if (!res.ok) {
|
|
389
|
+
const body = await res.text();
|
|
390
|
+
throw new Error(`Installation Token 获取失败 (${res.status}): ${body}`);
|
|
391
|
+
}
|
|
392
|
+
const data = (await res.json());
|
|
393
|
+
this.token = data.token;
|
|
394
|
+
this._installationTokens.set(installationId, {
|
|
395
|
+
token: data.token,
|
|
396
|
+
expiresAt: new Date(data.expires_at).getTime(),
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
/** 发现所有 App 安装及其可访问的仓库 */
|
|
400
|
+
async syncInstallations() {
|
|
401
|
+
if (!this._appAuth)
|
|
402
|
+
return;
|
|
403
|
+
const key = this.resolvePrivateKey();
|
|
404
|
+
const jwt = GhClient.createJWT(this._appAuth.appId, key);
|
|
405
|
+
const baseUrl = this.host ? `https://${this.host}/api/v3` : 'https://api.github.com';
|
|
406
|
+
const listRes = await fetch(`${baseUrl}/app/installations`, {
|
|
407
|
+
headers: { Authorization: `Bearer ${jwt}`, Accept: 'application/vnd.github+json' },
|
|
408
|
+
});
|
|
409
|
+
if (!listRes.ok) {
|
|
410
|
+
const errBody = await listRes.text();
|
|
411
|
+
throw new Error(`列出安装失败: ${listRes.status} - ${errBody}`);
|
|
412
|
+
}
|
|
413
|
+
const installations = (await listRes.json());
|
|
414
|
+
this._allInstallations = installations;
|
|
415
|
+
this._repoToInstallation.clear();
|
|
416
|
+
for (const inst of installations) {
|
|
417
|
+
try {
|
|
418
|
+
await this.refreshInstallationToken(inst.id);
|
|
419
|
+
const cached = this._installationTokens.get(inst.id);
|
|
420
|
+
if (!cached)
|
|
421
|
+
continue;
|
|
422
|
+
const repoRes = await fetch(`${baseUrl}/installation/repositories?per_page=100`, {
|
|
423
|
+
headers: { Authorization: `Bearer ${cached.token}`, Accept: 'application/vnd.github+json' },
|
|
424
|
+
});
|
|
425
|
+
if (repoRes.ok) {
|
|
426
|
+
const data = (await repoRes.json());
|
|
427
|
+
for (const repo of data.repositories) {
|
|
428
|
+
this._repoToInstallation.set(repo.full_name.toLowerCase(), inst.id);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// 单个安装失败不影响其他
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
this._lastSyncTime = Date.now();
|
|
437
|
+
}
|
|
438
|
+
/** 当前是否使用 App 认证 */
|
|
439
|
+
get isAppAuth() { return !!this._appAuth; }
|
|
440
|
+
/** 所有已发现的安装 */
|
|
441
|
+
get installations() { return this._allInstallations; }
|
|
442
|
+
/** App 的 slug(verifyAuth 后可用) */
|
|
443
|
+
_appSlug = null;
|
|
444
|
+
get appSlug() { return this._appSlug; }
|
|
445
|
+
/** App 的 client_id(verifyAuth 后从 /app 获取,用于 Device Flow) */
|
|
446
|
+
_clientId = null;
|
|
447
|
+
get clientId() { return this._clientId; }
|
|
448
|
+
// ── 事件轮询 ─────────────────────────────────────────────────────
|
|
449
|
+
/**
|
|
450
|
+
* 获取仓库事件(支持 ETag 条件请求)
|
|
451
|
+
* @returns events 数组 + 新 etag;若 304 未修改则 events 为空
|
|
452
|
+
*/
|
|
453
|
+
async listRepoEvents(repo, etag) {
|
|
454
|
+
await this.ensureTokenForRepo(repo);
|
|
455
|
+
const args = ['api', `/repos/${repo}/events?per_page=30`, '--method', 'GET', '--include'];
|
|
456
|
+
if (etag)
|
|
457
|
+
args.push('-H', `If-None-Match: ${etag}`);
|
|
458
|
+
try {
|
|
459
|
+
const raw = await this.exec(args);
|
|
460
|
+
// --include 输出包含 HTTP 头 + 空行 + body
|
|
461
|
+
const sepIdx = raw.indexOf('\r\n\r\n');
|
|
462
|
+
const headerPart = sepIdx >= 0 ? raw.slice(0, sepIdx) : '';
|
|
463
|
+
const bodyPart = sepIdx >= 0 ? raw.slice(sepIdx + 4) : raw;
|
|
464
|
+
const newEtag = headerPart.match(/etag:\s*"?([^"\r\n]+)"?/i)?.[1] || null;
|
|
465
|
+
let events;
|
|
466
|
+
try {
|
|
467
|
+
events = JSON.parse(bodyPart);
|
|
468
|
+
}
|
|
469
|
+
catch {
|
|
470
|
+
events = [];
|
|
471
|
+
}
|
|
472
|
+
return { events: Array.isArray(events) ? events : [], etag: newEtag };
|
|
473
|
+
}
|
|
474
|
+
catch (err) {
|
|
475
|
+
// 304 Not Modified — gh 会以非 0 退出码返回
|
|
476
|
+
if (err.stderr?.includes('304') || err.exitCode === 1) {
|
|
477
|
+
return { events: [], etag: etag || null };
|
|
478
|
+
}
|
|
479
|
+
throw err;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// ── Device Flow OAuth(多用户绑定) ──────────────────────────────
|
|
483
|
+
/**
|
|
484
|
+
* 第一步:请求设备码
|
|
485
|
+
* GitHub App 不需要 scope 参数(权限由 App 设置决定),OAuth App 可传 scope。
|
|
486
|
+
* 注意:Device Flow 端点在 github.com(而非 api.github.com),需确保网络可达。
|
|
487
|
+
* @returns device_code, user_code, verification_uri, expires_in, interval
|
|
488
|
+
*/
|
|
489
|
+
static async deviceFlowRequestCode(clientId, host) {
|
|
490
|
+
const baseUrl = host ? `https://${host}` : 'https://github.com';
|
|
491
|
+
const url = `${baseUrl}/login/device/code`;
|
|
492
|
+
let res;
|
|
493
|
+
try {
|
|
494
|
+
res = await fetch(url, {
|
|
495
|
+
method: 'POST',
|
|
496
|
+
headers: {
|
|
497
|
+
'Content-Type': 'application/json',
|
|
498
|
+
'Accept': 'application/json',
|
|
499
|
+
},
|
|
500
|
+
body: JSON.stringify({ client_id: clientId }),
|
|
501
|
+
signal: AbortSignal.timeout(15_000),
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
catch (e) {
|
|
505
|
+
throw new Error(`Device Flow 请求失败: 无法连接 ${baseUrl} (${e.cause?.code || e.message})。` +
|
|
506
|
+
`Device Flow 需要访问 github.com(非 api.github.com),请检查网络/代理设置。`);
|
|
507
|
+
}
|
|
508
|
+
if (!res.ok) {
|
|
509
|
+
const body = await res.text().catch(() => '');
|
|
510
|
+
const hint = res.status === 400
|
|
511
|
+
? ' (请确认 GitHub App 已启用 Device Flow: Settings → Developer settings → GitHub Apps → General)'
|
|
512
|
+
: '';
|
|
513
|
+
throw new Error(`Device Flow 请求失败: ${res.status}${body ? ' — ' + body : ''}${hint}`);
|
|
514
|
+
}
|
|
515
|
+
return res.json();
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* 第二步:轮询等待用户授权
|
|
519
|
+
* @returns access_token 或 null(超时/拒绝)
|
|
520
|
+
*/
|
|
521
|
+
static async deviceFlowPollToken(clientId, deviceCode, interval = 5, expiresIn = 900, host) {
|
|
522
|
+
const baseUrl = host ? `https://${host}` : 'https://github.com';
|
|
523
|
+
const deadline = Date.now() + expiresIn * 1000;
|
|
524
|
+
let pollInterval = interval * 1000;
|
|
525
|
+
while (Date.now() < deadline) {
|
|
526
|
+
await new Promise(r => setTimeout(r, pollInterval));
|
|
527
|
+
const res = await fetch(`${baseUrl}/login/oauth/access_token`, {
|
|
528
|
+
method: 'POST',
|
|
529
|
+
headers: {
|
|
530
|
+
'Content-Type': 'application/json',
|
|
531
|
+
'Accept': 'application/json',
|
|
532
|
+
},
|
|
533
|
+
body: JSON.stringify({
|
|
534
|
+
client_id: clientId,
|
|
535
|
+
device_code: deviceCode,
|
|
536
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
537
|
+
}),
|
|
538
|
+
});
|
|
539
|
+
const data = await res.json();
|
|
540
|
+
if (data.access_token) {
|
|
541
|
+
return { access_token: data.access_token, token_type: data.token_type, scope: data.scope };
|
|
542
|
+
}
|
|
543
|
+
if (data.error === 'slow_down') {
|
|
544
|
+
pollInterval = (data.interval || interval + 5) * 1000;
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (data.error === 'authorization_pending')
|
|
548
|
+
continue;
|
|
549
|
+
// expired_token / access_denied / 其他错误
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
//# sourceMappingURL=gh-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh-client.js","sourceRoot":"","sources":["../src/gh-client.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { GitHubAdapter } from './adapter.js';
|
|
2
2
|
declare module 'zhin.js' {
|
|
3
|
+
interface Adapters {
|
|
4
|
+
github: GitHubAdapter;
|
|
5
|
+
}
|
|
3
6
|
namespace Plugin {
|
|
4
7
|
interface Contexts {
|
|
5
8
|
router: import('@zhin.js/http').Router;
|
|
6
9
|
}
|
|
7
10
|
}
|
|
8
|
-
interface Adapters {
|
|
9
|
-
github: GitHubAdapter;
|
|
10
|
-
}
|
|
11
11
|
interface Models {
|
|
12
12
|
github_subscriptions: {
|
|
13
13
|
id: number;
|
|
@@ -30,4 +30,5 @@ declare module 'zhin.js' {
|
|
|
30
30
|
export * from './types.js';
|
|
31
31
|
export { GitHubBot, parseMarkdown, toMarkdown } from './bot.js';
|
|
32
32
|
export { GitHubAdapter } from './adapter.js';
|
|
33
|
+
export { GhClient } from './gh-client.js';
|
|
33
34
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7C,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,QAAQ;QAChB,MAAM,EAAE,aAAa,CAAC;KACvB;IACD,UAAU,MAAM,CAAC;QACf,UAAU,QAAQ;YAChB,MAAM,EAAE,OAAO,eAAe,EAAE,MAAM,CAAC;SACxC;KACF;IACD,UAAU,MAAM;QACd,oBAAoB,EAAE;YACpB,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,OAAO,YAAY,EAAE,SAAS,EAAE,CAAC;YACzC,SAAS,EAAE,MAAM,CAAC;YAClB,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;YAC7C,OAAO,EAAE,MAAM,CAAC;YAChB,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;QACF,aAAa,EAAE;YACb,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,GAAG,CAAC;SACd,CAAC;QACF,kBAAkB,EAAE,OAAO,YAAY,EAAE,eAAe,CAAC;KAC1D;CACF;AAED,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
|