@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/src/bot.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  /**
2
- * GitHub Bot 实现
2
+ * GitHub Bot 实现(基于 gh CLI)
3
3
  */
4
- import path from 'node:path';
5
- import fs from 'node:fs';
6
4
  import {
7
5
  Bot,
8
6
  Message,
@@ -19,14 +17,7 @@ import type {
19
17
  } from './types.js';
20
18
  import { buildChannelId, parseChannelId } from './types.js';
21
19
  import type { GitHubAdapter } from './adapter.js';
22
- import { GitHubAPI } from './api.js';
23
-
24
- function resolvePrivateKey(raw: string): string {
25
- if (raw.includes('-----BEGIN')) return raw;
26
- const resolved = path.resolve(raw);
27
- if (fs.existsSync(resolved)) return fs.readFileSync(resolved, 'utf-8');
28
- throw new Error(`private_key 既不是 PEM 内容也不是有效的文件路径: ${raw}`);
29
- }
20
+ import { GhClient } from './gh-client.js';
30
21
 
31
22
  export function parseMarkdown(md: string): MessageSegment[] {
32
23
  const segments: MessageSegment[] = [];
@@ -58,7 +49,7 @@ export function toMarkdown(content: SendContent): string {
58
49
 
59
50
  export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
60
51
  $connected = false;
61
- api: GitHubAPI;
52
+ gh: GhClient;
62
53
 
63
54
  get $id() { return this.$config.name; }
64
55
 
@@ -67,12 +58,15 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
67
58
  }
68
59
 
69
60
  constructor(public adapter: GitHubAdapter, public $config: GitHubBotConfig) {
70
- const privateKey = resolvePrivateKey($config.private_key);
71
- this.api = new GitHubAPI($config.app_id, privateKey, $config.installation_id);
61
+ const { host, app_id, private_key } = $config;
62
+ const appAuth = app_id && private_key
63
+ ? { appId: app_id, privateKey: private_key }
64
+ : undefined;
65
+ this.gh = new GhClient({ host, appAuth });
72
66
  }
73
67
 
74
68
  async $connect(): Promise<void> {
75
- const result = await this.api.verifyAuth();
69
+ const result = await this.gh.verifyAuth();
76
70
  if (!result.ok) throw new Error(`GitHub 认证失败: ${result.message}`);
77
71
  this.$connected = true;
78
72
  this.logger.info(`GitHub bot ${this.$id} 已连接 — ${result.message}`);
@@ -88,7 +82,7 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
88
82
  const number = payload.issue.number;
89
83
  const isPR = 'pull_request' in (payload.issue as any);
90
84
  const channelId = buildChannelId(repo, isPR ? 'pr' : 'issue', number);
91
- const api = this.api;
85
+ const gh = this.gh;
92
86
 
93
87
  const result = Message.from(payload, {
94
88
  $id: payload.comment.id.toString(),
@@ -99,11 +93,11 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
99
93
  $content: parseMarkdown(payload.comment.body),
100
94
  $raw: payload.comment.body,
101
95
  $timestamp: new Date(payload.comment.created_at).getTime(),
102
- $recall: async () => { await api.deleteIssueComment(repo, payload.comment.id); },
96
+ $recall: async () => { await gh.deleteIssueComment(repo, payload.comment.id); },
103
97
  $reply: async (content: SendContent, quote?: boolean | string): Promise<string> => {
104
98
  const text = toMarkdown(content);
105
99
  const finalBody = quote ? `> ${payload.comment.body.split('\n')[0]}\n\n${text}` : text;
106
- const r = await api.createIssueComment(repo, number, finalBody);
100
+ const r = await gh.createIssueComment(repo, number, finalBody);
107
101
  return r.ok ? r.data.id.toString() : '';
108
102
  },
109
103
  });
@@ -114,7 +108,7 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
114
108
  const repo = payload.repository.full_name;
115
109
  const number = payload.pull_request.number;
116
110
  const channelId = buildChannelId(repo, 'pr', number);
117
- const api = this.api;
111
+ const gh = this.gh;
118
112
 
119
113
  const body = payload.comment.path
120
114
  ? `**${payload.comment.path}**\n${payload.comment.diff_hunk ? '```diff\n' + payload.comment.diff_hunk + '\n```\n' : ''}${payload.comment.body}`
@@ -129,9 +123,9 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
129
123
  $content: parseMarkdown(body),
130
124
  $raw: body,
131
125
  $timestamp: new Date(payload.comment.created_at).getTime(),
132
- $recall: async () => { await api.deletePRReviewComment(repo, payload.comment.id); },
126
+ $recall: async () => { await gh.deletePRReviewComment(repo, payload.comment.id); },
133
127
  $reply: async (content: SendContent): Promise<string> => {
134
- const r = await api.createPRComment(repo, number, toMarkdown(content));
128
+ const r = await gh.createPRComment(repo, number, toMarkdown(content));
135
129
  return r.ok ? r.data.id.toString() : '';
136
130
  },
137
131
  });
@@ -142,7 +136,7 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
142
136
  const repo = payload.repository.full_name;
143
137
  const number = payload.pull_request.number;
144
138
  const channelId = buildChannelId(repo, 'pr', number);
145
- const api = this.api;
139
+ const gh = this.gh;
146
140
 
147
141
  const stateLabel: Record<string, string> = {
148
142
  approved: '✅ APPROVED', changes_requested: '🔄 CHANGES REQUESTED',
@@ -161,7 +155,7 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
161
155
  $timestamp: new Date(payload.review.submitted_at).getTime(),
162
156
  $recall: async () => {},
163
157
  $reply: async (content: SendContent): Promise<string> => {
164
- const r = await api.createPRComment(repo, number, toMarkdown(content));
158
+ const r = await gh.createPRComment(repo, number, toMarkdown(content));
165
159
  return r.ok ? r.data.id.toString() : '';
166
160
  },
167
161
  });
@@ -173,8 +167,8 @@ export class GitHubBot implements Bot<GitHubBotConfig, IssueCommentPayload> {
173
167
 
174
168
  const text = toMarkdown(options.content);
175
169
  const r = parsed.type === 'issue'
176
- ? await this.api.createIssueComment(parsed.repo, parsed.number, text)
177
- : await this.api.createPRComment(parsed.repo, parsed.number, text);
170
+ ? await this.gh.createIssueComment(parsed.repo, parsed.number, text)
171
+ : await this.gh.createPRComment(parsed.repo, parsed.number, text);
178
172
  if (!r.ok) throw new Error(`发送失败: ${JSON.stringify(r.data)}`);
179
173
 
180
174
  this.logger.debug(`${this.$id} send → ${options.id}: ${text.slice(0, 80)}...`);