@zhin.js/adapter-github 1.1.0 → 1.1.3

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 (79) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +16 -17
  3. package/adapters/{github.js → github/index.js} +6 -6
  4. package/adapters/{github.ts → github/index.ts} +9 -9
  5. package/agents/github/agent.json +20 -0
  6. package/agents/github/boundaries.md +3 -0
  7. package/agents/github/conventions.md +3 -0
  8. package/agents/github/skills/github-account/SKILL.md +20 -0
  9. package/{lib/github-tool-handlers.js → agents/github/skills/github-account/handlers.js} +2 -100
  10. package/{src/github-tool-handlers.ts → agents/github/skills/github-account/handlers.ts} +2 -118
  11. package/agents/github/skills/github-account/tools/bind/index.js +13 -0
  12. package/{agent/tools/bind.ts → agents/github/skills/github-account/tools/bind/index.ts} +3 -3
  13. package/agents/github/skills/github-account/tools/install/index.js +13 -0
  14. package/{agent/tools/install.ts → agents/github/skills/github-account/tools/install/index.ts} +2 -2
  15. package/agents/github/skills/github-account/tools/unbind/index.js +13 -0
  16. package/{agent/tools/unbind.ts → agents/github/skills/github-account/tools/unbind/index.ts} +3 -3
  17. package/agents/github/skills/github-account/tools/whoami/index.js +13 -0
  18. package/{agent/tools/whoami.ts → agents/github/skills/github-account/tools/whoami/index.ts} +3 -3
  19. package/agents/github/skills/github-cli/SKILL.md +47 -0
  20. package/agents/github/skills/github-repository/SKILL.md +21 -0
  21. package/{lib/github-bot-handlers.js → agents/github/skills/github-repository/handlers.js} +2 -1
  22. package/{src/github-bot-handlers.ts → agents/github/skills/github-repository/handlers.ts} +3 -3
  23. package/agents/github/skills/github-repository/tools/create_pr/index.js +20 -0
  24. package/{agent/tools/create_pr.ts → agents/github/skills/github-repository/tools/create_pr/index.ts} +4 -4
  25. package/agents/github/skills/github-repository/tools/patch_file/index.js +19 -0
  26. package/{agent/tools/patch_file.ts → agents/github/skills/github-repository/tools/patch_file/index.ts} +3 -3
  27. package/agents/github/skills/github-repository/tools/prepare_workspace/index.js +15 -0
  28. package/{agent/tools/prepare_workspace.ts → agents/github/skills/github-repository/tools/prepare_workspace/index.ts} +3 -3
  29. package/agents/github/skills/github-repository/tools/push_branch/index.js +18 -0
  30. package/{agent/tools/push_branch.ts → agents/github/skills/github-repository/tools/push_branch/index.ts} +4 -4
  31. package/agents/github/skills/github-subscriptions/SKILL.md +20 -0
  32. package/agents/github/skills/github-subscriptions/handlers.js +101 -0
  33. package/agents/github/skills/github-subscriptions/handlers.ts +119 -0
  34. package/agents/github/skills/github-subscriptions/tools/star/index.js +16 -0
  35. package/{agent/tools/star.ts → agents/github/skills/github-subscriptions/tools/star/index.ts} +3 -3
  36. package/agents/github/skills/github-subscriptions/tools/subscribe/index.js +16 -0
  37. package/{agent/tools/subscribe.ts → agents/github/skills/github-subscriptions/tools/subscribe/index.ts} +3 -3
  38. package/agents/github/skills/github-subscriptions/tools/subscriptions/index.js +13 -0
  39. package/{agent/tools/subscriptions.ts → agents/github/skills/github-subscriptions/tools/subscriptions/index.ts} +3 -3
  40. package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.js +15 -0
  41. package/{agent/tools/unsubscribe.ts → agents/github/skills/github-subscriptions/tools/unsubscribe/index.ts} +3 -3
  42. package/agents/github/system.md +3 -0
  43. package/commands/{endpoint/add/[id].js → github/endpoint/add/[id]/index.js} +1 -1
  44. package/commands/github/endpoint/add/[id]/index.ts +3 -0
  45. package/{lib/github-endpoint-commands.js → commands/github/endpoint/definition.js} +6 -5
  46. package/{src/github-endpoint-commands.ts → commands/github/endpoint/definition.ts} +5 -5
  47. package/commands/{endpoint/list.js → github/endpoint/list/index.js} +1 -1
  48. package/commands/github/endpoint/list/index.ts +3 -0
  49. package/commands/{endpoint/remove/[id].js → github/endpoint/remove/[id]/index.js} +1 -1
  50. package/commands/github/endpoint/remove/[id]/index.ts +3 -0
  51. package/lib/client.js +1 -4
  52. package/lib/endpoint.js +4 -4
  53. package/lib/github-runtime-state.js +1 -1
  54. package/lib/index.d.ts +1 -1
  55. package/lib/oauth-users.d.ts +1 -1
  56. package/lib/oauth-users.js +1 -1
  57. package/lib/protocol.d.ts +11 -33
  58. package/lib/protocol.js +19 -30
  59. package/lib/types.d.ts +0 -23
  60. package/lib/types.js +2 -3
  61. package/package.json +35 -19
  62. package/plugin.js +3 -3
  63. package/prompt-sections/platform/index.js +16 -0
  64. package/schema.json +33 -26
  65. package/src/client.ts +1 -4
  66. package/src/endpoint.ts +4 -4
  67. package/src/github-runtime-state.ts +1 -1
  68. package/src/index.ts +1 -1
  69. package/src/oauth-users.ts +1 -1
  70. package/src/protocol.ts +26 -79
  71. package/src/types.ts +0 -28
  72. package/agent/skills/github.md +0 -283
  73. package/commands/endpoint/add/[id].ts +0 -3
  74. package/commands/endpoint/list.ts +0 -3
  75. package/commands/endpoint/remove/[id].ts +0 -3
  76. package/lib/github-bot-handlers.d.ts +0 -27
  77. package/lib/github-endpoint-commands.d.ts +0 -1
  78. package/lib/github-tool-handlers.d.ts +0 -18
  79. /package/{agent/prompt-sections/platform.ts → prompt-sections/platform/index.ts} +0 -0
package/src/endpoint.ts CHANGED
@@ -162,8 +162,8 @@ export class GithubEndpoint extends Endpoint<GithubClient> {
162
162
  }
163
163
 
164
164
  export function defaultCreateClient(config: ResolvedGithubConfig): GhClient {
165
- const appAuth = config.appId && config.privateKey
166
- ? { appId: config.appId, privateKey: config.privateKey }
167
- : undefined;
168
- return new GhClient({ host: config.host, appAuth });
165
+ return new GhClient({
166
+ host: config.host,
167
+ appAuth: { appId: config.appId, privateKey: config.privateKey },
168
+ });
169
169
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * GitHub 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `github.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `github endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
 
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@ export {
12
12
  resolveGithubConfig,
13
13
  shouldAutoReplyRepo,
14
14
  verifyWebhookSignature,
15
- type GithubAdapterConfig,
15
+ type GithubEndpointConfig,
16
16
  type GithubInboundComment,
17
17
  type GithubWireSegment,
18
18
  type ResolvedGithubConfig,
@@ -14,7 +14,7 @@ export const GITHUB_OAUTH_USERS_SCHEMA = {
14
14
  platform_uid: { type: 'text', nullable: false },
15
15
  github_login: { type: 'text', nullable: false },
16
16
  access_token: { type: 'text', nullable: false },
17
- created_at: { type: 'integer', nullable: false },
17
+ created_at: { type: 'bigint', nullable: false },
18
18
  } as const;
19
19
 
20
20
  export function defineGithubOauthUsersTable(
package/src/protocol.ts CHANGED
@@ -5,9 +5,7 @@
5
5
 
6
6
  import { createHmac, timingSafeEqual } from 'node:crypto';
7
7
  import type { IncomingMessage } from 'node:http';
8
- import { pickCredential } from 'zhin.js/adapter';
9
- import { isMediaRef } from '@zhin.js/core';
10
- import type { ConversationRef } from '@zhin.js/im-contract';
8
+ import { isMediaRef, type ConversationRef } from '@zhin.js/im-contract';
11
9
  import { formatCompact, getLogger } from '@zhin.js/logger';
12
10
 
13
11
  const logger = getLogger('github');
@@ -23,7 +21,6 @@ export type {
23
21
  EventType,
24
22
  GenericWebhookPayload,
25
23
  GitHubComment,
26
- GitHubEndpointConfig,
27
24
  GitHubIssue,
28
25
  GitHubOAuthUser,
29
26
  GitHubPR,
@@ -38,52 +35,30 @@ export type {
38
35
 
39
36
  export { buildChannelId, parseChannelId } from './types.js';
40
37
 
41
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
42
- export interface GithubAdapterConfig {
43
- readonly id?: string;
38
+ /** One expanded GitHub endpoint configuration produced by AdapterIndex. */
39
+ export interface GithubEndpointConfig {
40
+ readonly id: string;
44
41
  readonly host?: string;
45
- readonly app_id?: string | number;
46
- readonly appId?: string | number;
47
- readonly private_key?: string;
48
- readonly privateKey?: string;
42
+ readonly app_id: string | number;
43
+ readonly private_key: string;
49
44
  readonly webhook_secret?: string;
50
- readonly webhookSecret?: string;
51
45
  readonly webhook_path?: string;
52
- readonly webhookPath?: string;
53
- readonly poll_interval?: number;
54
- readonly pollInterval?: number;
55
46
  readonly auto_reply_repos?: readonly string[];
56
- readonly autoReplyRepos?: readonly string[];
57
47
  readonly bot_login?: string;
58
- readonly botLogin?: string;
59
48
  readonly workspace_root?: string;
60
- readonly workspaceRoot?: string;
61
- /** Transitional: legacy root `endpoints[]` with `context: github`. */
62
- readonly endpoints?: ReadonlyArray<Partial<ResolvedGithubConfig> & {
63
- readonly context?: string;
64
- readonly app_id?: string | number;
65
- readonly private_key?: string;
66
- readonly webhook_secret?: string;
67
- readonly webhook_path?: string;
68
- readonly poll_interval?: number;
69
- readonly auto_reply_repos?: readonly string[];
70
- readonly bot_login?: string;
71
- readonly workspace_root?: string;
72
- }>;
73
49
  }
74
50
 
75
51
  export interface ResolvedGithubConfig {
76
52
  readonly context: 'github';
77
53
  readonly id: string;
78
54
  readonly host?: string;
79
- readonly appId?: string | number;
80
- readonly privateKey?: string;
55
+ readonly appId: string | number;
56
+ readonly privateKey: string;
81
57
  readonly webhookSecret?: string;
82
58
  readonly webhookPath: string;
83
- readonly pollInterval: number;
84
59
  readonly autoReplyRepos: readonly string[];
85
60
  readonly botLogin?: string;
86
- readonly workspaceRoot?: string;
61
+ readonly workspaceRoot: string;
87
62
  }
88
63
 
89
64
  export interface GithubWireSegment {
@@ -118,63 +93,35 @@ export function githubInboundConversation(
118
93
  };
119
94
  }
120
95
 
121
- export function resolveGithubConfig(config: GithubAdapterConfig = {}): ResolvedGithubConfig {
122
- const entry = config.endpoints?.find((item) => item.context === 'github');
123
- const appIdRaw = pickCredential(
124
- config.appId != null ? String(config.appId) : undefined,
125
- config.app_id != null ? String(config.app_id) : undefined,
126
- entry?.appId != null ? String(entry.appId) : undefined,
127
- entry?.app_id != null ? String(entry.app_id) : undefined,
128
- process.env.GITHUB_APP_ID,
129
- );
96
+ export function resolveGithubConfig(config: GithubEndpointConfig): ResolvedGithubConfig {
97
+ const id = typeof config.id === 'string' ? config.id.trim() : '';
98
+ if (!id) throw new TypeError('GitHub endpoint requires a non-empty id');
99
+ const appIdRaw = config.app_id != null ? String(config.app_id).trim() : '';
130
100
  const appId = appIdRaw ? (Number(appIdRaw) || appIdRaw) : undefined;
131
- const privateKey = pickCredential(
132
- config.privateKey,
133
- config.private_key,
134
- entry?.privateKey,
135
- entry?.private_key,
136
- ) || undefined;
101
+ const privateKey = typeof config.private_key === 'string'
102
+ ? config.private_key.trim()
103
+ : '';
137
104
  if (!appId || !privateKey) {
138
- throw new TypeError(
139
- 'GitHub adapter requires app_id + private_key (plugins.<key> or GITHUB_APP_ID)',
140
- );
105
+ throw new TypeError('GitHub endpoint requires app_id and private_key');
141
106
  }
142
- const id = (typeof config.id === 'string' && config.id)
143
- || (typeof entry?.id === 'string' && entry.id)
144
- || process.env.GITHUB_BOT_NAME
145
- || 'github-bot';
146
- const webhookSecret = config.webhookSecret ?? config.webhook_secret
147
- ?? entry?.webhookSecret ?? entry?.webhook_secret
148
- ?? process.env.GITHUB_WEBHOOK_SECRET
149
- ?? undefined;
150
- const host = config.host ?? entry?.host;
151
- const webhookPath = normalizeWebhookPath(
152
- config.webhookPath ?? config.webhook_path ?? entry?.webhookPath ?? entry?.webhook_path
153
- ?? '/github/webhook',
154
- );
155
- const pollInterval = Number(
156
- config.pollInterval ?? config.poll_interval ?? entry?.pollInterval ?? entry?.poll_interval ?? 60,
157
- ) || 60;
158
- const autoReplyRepos = [
159
- ...(config.autoReplyRepos ?? config.auto_reply_repos
160
- ?? entry?.autoReplyRepos ?? entry?.auto_reply_repos ?? []),
161
- ];
162
- const botLogin = config.botLogin ?? config.bot_login ?? entry?.botLogin ?? entry?.bot_login;
163
- const workspaceRoot = config.workspaceRoot ?? config.workspace_root
164
- ?? entry?.workspaceRoot ?? entry?.workspace_root;
107
+ const webhookSecret = config.webhook_secret;
108
+ const host = config.host;
109
+ const webhookPath = normalizeWebhookPath(config.webhook_path ?? '/github/webhook');
110
+ const autoReplyRepos = [...(config.auto_reply_repos ?? [])];
111
+ const botLogin = config.bot_login;
112
+ const workspaceRoot = config.workspace_root ?? 'data/github-workspaces';
165
113
 
166
114
  return {
167
115
  context: 'github',
168
116
  id,
169
117
  ...(host ? { host } : {}),
170
- ...(appId != null ? { appId } : {}),
171
- ...(privateKey ? { privateKey } : {}),
118
+ appId,
119
+ privateKey,
172
120
  ...(webhookSecret ? { webhookSecret } : {}),
173
121
  webhookPath,
174
- pollInterval,
175
122
  autoReplyRepos,
176
123
  ...(botLogin ? { botLogin } : {}),
177
- ...(workspaceRoot ? { workspaceRoot } : {}),
124
+ workspaceRoot,
178
125
  };
179
126
  }
180
127
 
package/src/types.ts CHANGED
@@ -1,31 +1,3 @@
1
- // ── Endpoint 配置 ─────────────────────────────────────────────────────────
2
- // 基于 gh CLI 认证:需要系统已安装并认证 gh CLI
3
- // 认证方式:gh auth login
4
-
5
- export interface GitHubEndpointConfig {
6
- context: 'github';
7
- /** Endpoint 标识名称 */
8
- name: string;
9
- /** GitHub Enterprise 主机名(默认 github.com) */
10
- host?: string;
11
- /** GitHub App ID */
12
- app_id?: string | number;
13
- /** GitHub App 私钥(PEM 内容或文件路径) */
14
- private_key?: string;
15
- /** Webhook Secret(配置后启用 Webhook 接收事件,不配置则使用轮询) */
16
- webhook_secret?: string;
17
- /** Webhook 路由路径(默认 /github/webhook) */
18
- webhook_path?: string;
19
- /** 事件轮询间隔(秒,默认 60,Webhook 模式下作为降级备选) */
20
- poll_interval?: number;
21
- /** 这些仓库的人类 Issue/PR 评论自动触发 AI(无需 @bot) */
22
- auto_reply_repos?: string[];
23
- /** 覆盖 App bot 登录名(默认 {slug}[bot]) */
24
- bot_login?: string;
25
- /** 托管 git 工作区根目录(默认 {cwd}/data/github-workspaces) */
26
- workspace_root?: string;
27
- }
28
-
29
1
  // ── Channel ID ───────────────────────────────────────────────────────
30
2
  // 格式: {owner}/{repo}/issues/{number} 或 {owner}/{repo}/pull/{number}
31
3
 
@@ -1,283 +0,0 @@
1
- ---
2
- name: github
3
- platforms:
4
- - github
5
- description: >-
6
- GitHub 全功能适配器技能:内置工具处理 Star/绑定/订阅;MCP server-github 处理 Fork/PR/Issue 等 API;
7
- bash + gh CLI 覆盖其余仓库自动化。
8
- Endpoint 操作使用 GitHub App 身份;Star 等可使用用户 OAuth 绑定。
9
- 每个 Zhin 实例通过 GH_TOKEN 环境变量注入身份,支持多实例协同。
10
- channel ID 格式:owner/repo/issues/N 或 owner/repo/pull/N。
11
- keywords:
12
- - github
13
- - gh
14
- - cli
15
- - adapter:github
16
- - pr
17
- - pull request
18
- - issue
19
- - merge
20
- - review
21
- - star
22
- - fork
23
- - branch
24
- - release
25
- - CI
26
- - workflow
27
- - repo
28
- - 合并
29
- - 仓库
30
- - 拉取请求
31
- - 代码审查
32
- - search
33
- - 搜索
34
- - bind
35
- - unbind
36
- - whoami
37
- - 绑定
38
- - 授权
39
- - label
40
- - assign
41
- - file
42
- - commit
43
- - compare
44
- - edit
45
- - webhook
46
- - subscribe
47
- - discussion
48
- tags:
49
- - github
50
- - development
51
- - git
52
- - ci-cd
53
- tools:
54
- - bash
55
- - github_star
56
- - github_bind
57
- - github_unbind
58
- - github_whoami
59
- - github_install
60
- - github_subscribe
61
- - github_unsubscribe
62
- - github_subscriptions
63
- - github_prepare_workspace
64
- - github_patch_file
65
- - github_push_branch
66
- - github_create_pr
67
- always: false
68
- requires:
69
- bins:
70
- - gh
71
- env:
72
- - GH_TOKEN
73
- ---
74
-
75
- # GitHub 全功能操作指南
76
-
77
- 本技能提供三种操作方式:
78
- - **适配器内置工具**(`github_*`):用户交互类操作,具备账号绑定、Device Flow 授权、频道级订阅等适配器专有逻辑
79
- - **Bot 写仓库工具**(`github_prepare_workspace` / `github_patch_file` / `github_push_branch` / `github_create_pr`):Installation Token,UI 显示 **Bot** 身份;push/开 PR 需 HITL
80
- - **MCP server-github**(`mcp_github_*`,可选):`ai.githubMcp.*` 配置已随 Plugin Runtime 迁移移除;如需 MCP 工具,按 `mcp/<name>.ts` 约定自行装配(PAT 为**人身份**,勿用于 Bot 写仓库)
81
- - **bash + gh CLI**:仓库自动化操作,灵活覆盖 GitHub API 全场景
82
-
83
- ## 一、适配器内置工具
84
-
85
- 以下工具由 GitHub 适配器注册,具有特殊行为(用户 OAuth 绑定、频道绑定等),**不能用 gh CLI 替代**。
86
-
87
- ### 账号与身份
88
-
89
- | 工具 | 说明 |
90
- |------|------|
91
- | `github_bind` | 绑定用户的 GitHub 账号(Device Flow 授权,无需输入密码)。用户想 star/fork 或操作自己的账号时,先引导使用此工具 |
92
- | `github_unbind` | 解除用户绑定的 GitHub 账号 |
93
- | `github_whoami` | 查看用户已绑定的 GitHub 账号信息 |
94
- | `github_install` | 获取安装 GitHub App 的链接,安装后 Endpoint 可访问用户的仓库 |
95
-
96
- ### 用户操作(使用绑定账号)
97
-
98
- | 工具 | 说明 |
99
- |------|------|
100
- | `github_star` | Star 或取消 Star 一个仓库。优先使用用户绑定的 GitHub 账号,未绑定则降级为 Endpoint 默认账号 |
101
-
102
- ### Bot 开发工作流(App 身份)
103
-
104
- | 工具 | 说明 |
105
- |------|------|
106
- | `github_prepare_workspace` | Clone/fetch 托管工作区并 checkout Issue/PR 对应分支 |
107
- | `github_patch_file` | Contents API 单文件更新(小改) |
108
- | `github_push_branch` | git commit + push(**需 HITL**) |
109
- | `github_create_pr` | 创建 PR(**需 HITL**;Issue 线程常用) |
110
-
111
- Issue 线程:新分支 → 开发 → push → 开 PR。PR 线程:push 到现有 head 分支。
112
-
113
- ### MCP(server-github,可选 PAT)
114
-
115
- | 工具 | 说明 |
116
- |------|------|
117
- | `mcp_github_fork_repository` | Fork 仓库(替代已移除的 `github_fork`) |
118
- | `mcp_github_create_issue` 等 | Issue/PR/搜索/文件等,见 MCP 工具列表 |
119
-
120
- ### Webhook 订阅(频道级)
121
-
122
- | 工具 | 说明 |
123
- |------|------|
124
- | `github_subscribe` | 订阅仓库的 Webhook 事件,推送到**当前聊天通道** |
125
- | `github_unsubscribe` | 取消订阅仓库的 Webhook 事件 |
126
- | `github_subscriptions` | 查看当前聊天通道的订阅列表 |
127
-
128
- ### 内置工具执行规则
129
-
130
- 1. `github_star` 优先使用用户绑定的 GitHub 账号,未绑定则降级为 Endpoint 默认账号
131
- 2. Bot 写仓库用 `github_*` 工具,不用 `mcp_github_*` 写操作
132
- 3. MCP(`mcp_github_*`)仅在你按 `mcp/<name>.ts` 约定装配后可用(旧 `ai.githubMcp.enabled` 已移除),PAT 为人身份
133
- 4. 当用户想操作自己的 GitHub 账号进行 Star 时,先引导用户使用 `github_bind` 绑定
134
- 5. Webhook 订阅关联到当前聊天通道,仅在该通道接收事件通知
135
-
136
- ---
137
-
138
- ## 二、gh CLI 全场景速查
139
-
140
- 当适配器内置工具不能满足需求(如 Release 管理、Workflow 触发、Discussion、gh api 万能调用),或需要更灵活的参数控制时,使用 `bash` 工具调用 `gh` CLI。当前进程已通过 `GH_TOKEN` 环境变量注入身份凭据。
141
-
142
- ### 0. 前提检查
143
-
144
- ```bash
145
- gh --version
146
- gh auth status
147
- ```
148
-
149
- ### 1. 仓库(gh repo)
150
-
151
- ```bash
152
- gh repo view owner/repo
153
- gh repo list owner --limit 10 --json name,description
154
- gh repo clone owner/repo
155
- gh repo create owner/new-repo --public --description "描述"
156
- ```
157
-
158
- ### 2. Issue(gh issue)
159
-
160
- ```bash
161
- gh issue list -R owner/repo --state open --limit 20 --json number,title,state,labels,assignees
162
- gh issue view 123 -R owner/repo --json number,title,body,state,labels,assignees --jq '{number,title,state,labels,assignees,body: .body[:2000]}'
163
- gh issue create -R owner/repo --title "标题" --body "正文" --label "bug" --assignee "user1"
164
- gh issue close 123 -R owner/repo
165
- gh issue reopen 123 -R owner/repo
166
- gh issue comment 123 -R owner/repo --body "评论内容"
167
- gh issue edit 123 -R owner/repo --title "新标题"
168
- gh issue edit 123 -R owner/repo --add-label "enhancement" --remove-label "bug"
169
- gh issue edit 123 -R owner/repo --add-assignee "user2" --remove-assignee "user1"
170
- ```
171
-
172
- ### 3. Pull Request(gh pr)
173
-
174
- ```bash
175
- gh pr list -R owner/repo --state open --limit 20 --json number,title,state,author,mergeable
176
- gh pr view 456 -R owner/repo --json number,title,body,state,author,mergeable,reviewDecision --jq '{number,title,state,author,mergeable,reviewDecision,body: .body[:2000]}'
177
- gh pr create -R owner/repo --title "标题" --body "描述" --base main --head feature-branch
178
- gh pr merge 456 -R owner/repo --squash --delete-branch
179
- gh pr close 456 -R owner/repo
180
- gh pr reopen 456 -R owner/repo
181
- gh pr comment 456 -R owner/repo --body "评论内容"
182
- gh pr review 456 -R owner/repo --approve
183
- gh pr review 456 -R owner/repo --request-changes --body "需要修改的内容"
184
- gh pr review 456 -R owner/repo --comment --body "一般性建议"
185
- gh pr checks 456 -R owner/repo
186
- gh pr diff 456 -R owner/repo | head -n 200
187
- ```
188
-
189
- ### 4. Release(gh release)
190
-
191
- ```bash
192
- gh release list -R owner/repo --limit 10
193
- gh release view v1.0.0 -R owner/repo
194
- gh release create v1.0.0 -R owner/repo --title "v1.0.0" --notes "发布说明" --target main
195
- gh release delete v1.0.0 -R owner/repo --yes
196
- ```
197
-
198
- ### 5. Workflow / CI(gh run & gh workflow)
199
-
200
- ```bash
201
- gh run list -R owner/repo --limit 10 --json databaseId,displayTitle,status,conclusion
202
- gh run view 12345 -R owner/repo
203
- gh run rerun 12345 -R owner/repo --failed
204
- gh workflow list -R owner/repo
205
- gh workflow run ci.yml -R owner/repo --ref main
206
- ```
207
-
208
- ### 6. 搜索(gh search)
209
-
210
- ```bash
211
- gh search issues "关键词" --repo owner/repo --limit 10 --json number,title,state
212
- gh search repos "关键词" --limit 10 --json fullName,description,stargazersCount
213
- gh search code "函数名" --repo owner/repo --limit 10 --json path,textMatches
214
- ```
215
-
216
- ### 7. 标签与指派
217
-
218
- ```bash
219
- gh label list -R owner/repo
220
- gh label create "priority:high" -R owner/repo --color FF0000 --description "高优先级"
221
- gh issue edit 123 -R owner/repo --add-label "priority:high"
222
- gh issue edit 123 -R owner/repo --remove-label "priority:low"
223
- gh issue edit 123 -R owner/repo --add-assignee "user1"
224
- gh issue edit 123 -R owner/repo --remove-assignee "user2"
225
- ```
226
-
227
- ### 8. 文件与提交
228
-
229
- ```bash
230
- gh api /repos/owner/repo/contents/path/to/file --jq '.content' | base64 -d
231
- gh api /repos/owner/repo/commits --jq '.[0:10] | .[] | {sha: .sha[:7], message: .commit.message[:80], author: .commit.author.name, date: .commit.author.date}'
232
- gh api /repos/owner/repo/compare/main...feature --jq '{ahead_by, behind_by, files: [.files[:20][] | {filename, status, changes}]}'
233
- ```
234
-
235
- ### 9. Discussion
236
-
237
- ```bash
238
- gh api /repos/owner/repo/discussions --jq '.[0:10] | .[] | {number, title, category: .category.name}'
239
- gh api /repos/owner/repo/discussions/categories --jq '.[] | {id: .node_id, name, slug}'
240
- gh api graphql -f query='mutation {
241
- createDiscussion(input: {
242
- repositoryId: "REPO_NODE_ID",
243
- categoryId: "CATEGORY_NODE_ID",
244
- title: "标题",
245
- body: "正文"
246
- }) { discussion { number url } }
247
- }'
248
- gh api -X POST /repos/owner/repo/discussions/{number}/comments -f body="评论内容"
249
- ```
250
-
251
- ### 10. 万能 fallback:gh api
252
-
253
- ```bash
254
- gh api /repos/owner/repo/xxx
255
- gh api -X POST /repos/owner/repo/xxx -f key=value
256
- gh api -X PATCH /repos/owner/repo/xxx -f key=value
257
- gh api graphql -f query='{ repository(owner:"owner", name:"repo") { ... } }'
258
- ```
259
-
260
- ---
261
-
262
- ## 三、输出控制黄金规则
263
-
264
- **所有 gh CLI 命令都必须控制输出大小**,防止 token 爆炸:
265
-
266
- | 手段 | 示例 |
267
- |------|------|
268
- | `--json` + `--jq` | 精确控制返回字段和条数 |
269
- | `--limit N` | 列表不超过 20 条 |
270
- | `--jq '.body[:2000]'` | 截断长文本字段 |
271
- | `\| head -n 200` | 截断 diff 等大文本 |
272
-
273
- **目标:单次调用输出 < 15KB。**
274
-
275
- ## 四、常见错误与修复
276
-
277
- | 错误 | 原因 | 修复 |
278
- |------|------|------|
279
- | `gh: command not found` | 未安装 gh CLI | 需管理员安装 |
280
- | `HTTP 401` | Token 无效或过期 | 检查 GH_TOKEN 环境变量 |
281
- | `HTTP 404` | 仓库/资源不存在或无权限 | 确认 owner/repo 和 Token scope |
282
- | `HTTP 422` | 参数不合法 | 检查必填字段是否缺失 |
283
- | `GraphQL: ...` | GraphQL 查询语法错误 | 检查 query 拼写与字段名 |
@@ -1,3 +0,0 @@
1
- import { githubEndpointCommands } from '../../../src/github-endpoint-commands.js';
2
-
3
- export default githubEndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { githubEndpointCommands } from '../../src/github-endpoint-commands.js';
2
-
3
- export default githubEndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { githubEndpointCommands } from '../../../src/github-endpoint-commands.js';
2
-
3
- export default githubEndpointCommands.remove;
@@ -1,27 +0,0 @@
1
- /**
2
- * GitHub App Bot workflow handlers (Installation Token identity).
3
- */
4
- import type { Message } from 'zhin.js';
5
- import type { GithubClient } from './client.js';
6
- export declare function executeGithubPrepareWorkspace(args: {
7
- repo?: string;
8
- }, client: GithubClient, commMessage?: Message): Promise<string>;
9
- export declare function executeGithubPatchFile(args: {
10
- repo?: string;
11
- path: string;
12
- content: string;
13
- message: string;
14
- branch?: string;
15
- }, client: GithubClient, commMessage?: Message): Promise<string>;
16
- export declare function executeGithubPushBranch(args: {
17
- repo?: string;
18
- branch?: string;
19
- message: string;
20
- }, client: GithubClient, commMessage?: Message): Promise<string>;
21
- export declare function executeGithubCreatePr(args: {
22
- repo?: string;
23
- title: string;
24
- body?: string;
25
- head?: string;
26
- base?: string;
27
- }, client: GithubClient, commMessage?: Message): Promise<string>;
@@ -1 +0,0 @@
1
- export declare const githubEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
@@ -1,18 +0,0 @@
1
- import type { Message } from 'zhin.js';
2
- import type { GithubClient } from './client.js';
3
- export declare function executeGithubStar(args: {
4
- action: 'star' | 'unstar' | 'check';
5
- repo: string;
6
- }, client: GithubClient, commMessage?: Message): Promise<string>;
7
- export declare function executeGithubBind(_args: Record<string, never>, client: GithubClient, commMessage?: Message): Promise<string>;
8
- export declare function executeGithubUnbind(_args: Record<string, never>, client: GithubClient, commMessage?: Message): Promise<string>;
9
- export declare function executeGithubWhoami(_args: Record<string, never>, client: GithubClient, commMessage?: Message): Promise<string>;
10
- export declare function executeGithubInstall(client: GithubClient): Promise<string>;
11
- export declare function executeGithubSubscribe(args: {
12
- repo: string;
13
- events?: string;
14
- }, client: GithubClient, commMessage?: Message): Promise<string>;
15
- export declare function executeGithubUnsubscribe(args: {
16
- repo: string;
17
- }, client: GithubClient, commMessage?: Message): Promise<string>;
18
- export declare function executeGithubSubscriptions(_args: Record<string, never>, client: GithubClient, commMessage?: Message): Promise<string>;