dsh-github-flow 0.4.0 → 0.5.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.
Files changed (62) hide show
  1. package/README.en.md +75 -8
  2. package/README.md +75 -8
  3. package/docs/UPGRADE-NOTES.md +9 -12
  4. package/docs/architecture.md +39 -21
  5. package/lib/api/routes-actions.js +132 -0
  6. package/lib/client.d.ts +4 -3
  7. package/lib/client.js +1436 -80
  8. package/lib/commands/gh.d.ts +6 -1
  9. package/lib/commands/gh.js +144 -71
  10. package/lib/executor/git-parser.d.ts +33 -1
  11. package/lib/executor/git-parser.js +116 -4
  12. package/lib/executor.d.ts +27 -2
  13. package/lib/executor.js +189 -5
  14. package/lib/main.js +28 -4
  15. package/lib/renderers/agent-task.d.ts +16 -0
  16. package/lib/renderers/agent-task.js +107 -0
  17. package/lib/renderers/codespace.d.ts +16 -0
  18. package/lib/renderers/codespace.js +103 -0
  19. package/lib/renderers/discussion.d.ts +16 -0
  20. package/lib/renderers/discussion.js +101 -0
  21. package/lib/renderers/markdown.d.ts +4 -0
  22. package/lib/renderers/markdown.js +4 -0
  23. package/lib/renderers/project.d.ts +20 -0
  24. package/lib/renderers/project.js +128 -0
  25. package/lib/renderers/skill.d.ts +30 -0
  26. package/lib/renderers/skill.js +180 -0
  27. package/lib/renderers/status.d.ts +5 -0
  28. package/lib/renderers/status.js +52 -0
  29. package/lib/telemetry.d.ts +70 -0
  30. package/lib/telemetry.js +161 -0
  31. package/lib/tools/agent-task.d.ts +54 -0
  32. package/lib/tools/agent-task.js +135 -0
  33. package/lib/tools/codespace.d.ts +51 -0
  34. package/lib/tools/codespace.js +154 -0
  35. package/lib/tools/discussion.d.ts +70 -0
  36. package/lib/tools/discussion.js +195 -0
  37. package/lib/tools/help.js +109 -9
  38. package/lib/tools/project.d.ts +80 -0
  39. package/lib/tools/project.js +241 -0
  40. package/lib/tools/repo.js +13 -1
  41. package/lib/tools/skill.d.ts +24 -1
  42. package/lib/tools/skill.js +115 -5
  43. package/lib/tools/status.d.ts +3 -2
  44. package/lib/tools/status.js +9 -4
  45. package/lib/types.d.ts +5 -0
  46. package/lib/ui/commit-modal.js +144 -14
  47. package/lib/ui/help-modal.d.ts +15 -0
  48. package/lib/ui/help-modal.js +202 -0
  49. package/lib/ui/storage.d.ts +9 -0
  50. package/lib/ui/storage.js +24 -0
  51. package/lib/ui/styles.d.ts +1 -1
  52. package/lib/ui/styles.js +259 -0
  53. package/lib/ui/sync-settings-modal.js +1 -1
  54. package/lib/ui/upgrade-card.js +39 -14
  55. package/lib/ui/utils.d.ts +35 -0
  56. package/lib/ui/utils.js +160 -0
  57. package/lib/ui/workspace-panel.js +30 -5
  58. package/lib/upgrade-manager.d.ts +5 -1
  59. package/lib/upgrade-manager.js +24 -1
  60. package/lib/version.d.ts +1 -1
  61. package/lib/version.js +1 -1
  62. package/package.json +2 -2
@@ -0,0 +1,195 @@
1
+ import { renderDiscussionMarkdown } from '../renderers/markdown.js';
2
+ function normalizeOutput(data) {
3
+ if (data && typeof data === 'object' && !Array.isArray(data)) {
4
+ return data;
5
+ }
6
+ if (Array.isArray(data)) {
7
+ return { items: data, count: data.length };
8
+ }
9
+ return { result: data !== undefined && data !== null ? data : '' };
10
+ }
11
+ const DISCUSSION_LIST_FIELDS = 'number,title,body,category,author,closed,createdAt,updatedAt,url,labels,answered,stateReason';
12
+ const DISCUSSION_VIEW_FIELDS = 'number,title,body,category,author,state,createdAt,updatedAt,url,labels,answered,comments';
13
+ export function createDiscussionTool(executor) {
14
+ return {
15
+ name: 'github_discussion',
16
+ description: '管理 GitHub Discussions 讨论区:浏览社区讨论、检视讨论详情与回复楼层、发起新讨论议题、编辑现有讨论以及追加评论回复。基于 gh CLI preview 特性。',
17
+ parameters: {
18
+ type: 'object',
19
+ properties: {
20
+ action: {
21
+ type: 'string',
22
+ enum: ['list', 'view', 'create', 'edit', 'comment'],
23
+ description: 'Discussion 操作类型。list 查阅讨论列表、view 查看正文与评论、create 发起新讨论、edit 修改讨论、comment 发表评论。',
24
+ },
25
+ repo: {
26
+ type: 'string',
27
+ description: '目标仓库 [owner/repo],留空则识别当前工作区仓库。',
28
+ },
29
+ discussion_number: {
30
+ type: 'number',
31
+ description: '讨论编号(view, edit, comment 动作必需,如 123)。',
32
+ },
33
+ title: {
34
+ type: 'string',
35
+ description: '讨论标题(create 动作必需,edit 动作修改标题时可选)。',
36
+ },
37
+ body: {
38
+ type: 'string',
39
+ description: '讨论正文或评论正文(create, comment 必需,edit 动作修改正文时可选)。',
40
+ },
41
+ category: {
42
+ type: 'string',
43
+ description: '讨论分类名称(create 动作必需,list 动作按分类筛选使用,如 "General"、"Q&A"、"Ideas")。',
44
+ },
45
+ state: {
46
+ type: 'string',
47
+ enum: ['open', 'closed', 'all'],
48
+ description: '讨论状态过滤(list 动作使用,默认 open)。',
49
+ },
50
+ labels: {
51
+ type: 'array',
52
+ items: { type: 'string' },
53
+ description: '按标签筛选(list 动作使用)。',
54
+ },
55
+ search: {
56
+ type: 'string',
57
+ description: '搜索过滤关键词(list 动作使用,映射 -S/--search)。',
58
+ },
59
+ comments: {
60
+ type: 'boolean',
61
+ description: '是否一并拉取评论列表(view 动作使用,默认 true)。',
62
+ },
63
+ limit: {
64
+ type: 'number',
65
+ description: '返回讨论数量上限(list 动作使用,默认 30)。',
66
+ },
67
+ },
68
+ required: ['action'],
69
+ },
70
+ output: {
71
+ schema: { type: 'object' },
72
+ render(args, value) {
73
+ return [{ type: 'text', text: renderDiscussionMarkdown(args, value) }];
74
+ },
75
+ },
76
+ async execute(args, execContext) {
77
+ const cwd = execContext?.cwd || process.cwd();
78
+ const sessionId = execContext?.sessionId || execContext?.session?.id || process.env.DSH_SESSION_ID;
79
+ const repoArgs = args.repo ? ['-R', args.repo] : [];
80
+ const runOpts = { cwd, sessionId };
81
+ switch (args.action) {
82
+ case 'list': {
83
+ const limit = typeof args.limit === 'number' && args.limit > 0 ? Math.min(args.limit, 100) : 30;
84
+ const listCmd = [
85
+ 'discussion', 'list',
86
+ '-L', String(limit),
87
+ '--json', DISCUSSION_LIST_FIELDS,
88
+ ...repoArgs,
89
+ ];
90
+ if (args.category)
91
+ listCmd.push('-c', String(args.category).trim());
92
+ if (args.state)
93
+ listCmd.push('-s', args.state);
94
+ if (args.search)
95
+ listCmd.push('-S', String(args.search).trim());
96
+ if (Array.isArray(args.labels) && args.labels.length > 0) {
97
+ args.labels.forEach((l) => {
98
+ if (l)
99
+ listCmd.push('-l', String(l).trim());
100
+ });
101
+ }
102
+ const res = await executor.run(listCmd, runOpts);
103
+ if (!res.ok)
104
+ throw new Error(res.error);
105
+ return normalizeOutput(res.data || res.rawOutput);
106
+ }
107
+ case 'view': {
108
+ if (!args.discussion_number || typeof args.discussion_number !== 'number') {
109
+ throw new Error('view 操作必须提供 discussion_number(讨论数字编号),以防止进入交互式挂起');
110
+ }
111
+ const numStr = String(args.discussion_number);
112
+ const viewCmd = [
113
+ 'discussion', 'view', numStr,
114
+ '--json', DISCUSSION_VIEW_FIELDS,
115
+ ...repoArgs,
116
+ ];
117
+ if (args.comments !== false) {
118
+ viewCmd.push('-c');
119
+ }
120
+ const res = await executor.run(viewCmd, runOpts);
121
+ if (!res.ok)
122
+ throw new Error(res.error);
123
+ return normalizeOutput(res.data || res.rawOutput);
124
+ }
125
+ case 'create': {
126
+ if (!args.title || typeof args.title !== 'string' || !args.title.trim()) {
127
+ throw new Error('create 操作必须提供 title(讨论标题)');
128
+ }
129
+ if (!args.body || typeof args.body !== 'string' || !args.body.trim()) {
130
+ throw new Error('create 操作必须提供 body(讨论正文)');
131
+ }
132
+ if (!args.category || typeof args.category !== 'string' || !args.category.trim()) {
133
+ throw new Error('create 操作必须提供 category(讨论分类,例如 "General"、"Q&A"、"Ideas")');
134
+ }
135
+ const createCmd = [
136
+ 'discussion', 'create',
137
+ '-t', args.title.trim(),
138
+ '-b', args.body.trim(),
139
+ '-c', args.category.trim(),
140
+ ...repoArgs,
141
+ ];
142
+ const res = await executor.run(createCmd, { ...runOpts, rawText: true, timeoutMs: 60_000 });
143
+ if (!res.ok)
144
+ throw new Error(res.error);
145
+ return {
146
+ message: '讨论已成功发起',
147
+ url: res.rawOutput ? res.rawOutput.trim() : undefined,
148
+ };
149
+ }
150
+ case 'edit': {
151
+ if (!args.discussion_number || typeof args.discussion_number !== 'number') {
152
+ throw new Error('edit 操作必须提供 discussion_number(讨论数字编号)');
153
+ }
154
+ if (!args.title && !args.body) {
155
+ throw new Error('edit 操作至少需提供 title 或 body 中的一项进行修改');
156
+ }
157
+ const editCmd = ['discussion', 'edit', String(args.discussion_number), ...repoArgs];
158
+ if (args.title)
159
+ editCmd.push('-t', String(args.title).trim());
160
+ if (args.body)
161
+ editCmd.push('-b', String(args.body).trim());
162
+ const res = await executor.run(editCmd, { ...runOpts, rawText: true, timeoutMs: 60_000 });
163
+ if (!res.ok)
164
+ throw new Error(res.error);
165
+ return {
166
+ message: `讨论 #${args.discussion_number} 已更新成功`,
167
+ output: res.rawOutput || 'Updated',
168
+ };
169
+ }
170
+ case 'comment': {
171
+ if (!args.discussion_number || typeof args.discussion_number !== 'number') {
172
+ throw new Error('comment 操作必须提供 discussion_number(讨论数字编号)');
173
+ }
174
+ if (!args.body || typeof args.body !== 'string' || !args.body.trim()) {
175
+ throw new Error('comment 操作必须提供 body(评论正文)');
176
+ }
177
+ const commentCmd = [
178
+ 'discussion', 'comment', String(args.discussion_number),
179
+ '-b', args.body.trim(),
180
+ ...repoArgs,
181
+ ];
182
+ const res = await executor.run(commentCmd, { ...runOpts, rawText: true, timeoutMs: 60_000 });
183
+ if (!res.ok)
184
+ throw new Error(res.error);
185
+ return {
186
+ message: `已向讨论 #${args.discussion_number} 成功发表评论`,
187
+ url: res.rawOutput ? res.rawOutput.trim() : undefined,
188
+ };
189
+ }
190
+ default:
191
+ throw new Error(`未知的 Discussion 操作: ${args.action}`);
192
+ }
193
+ },
194
+ };
195
+ }
package/lib/tools/help.js CHANGED
@@ -18,9 +18,14 @@ const KNOWLEDGE_BASE = {
18
18
  | \`github_cache\` | Actions 构建缓存盘点与安全清理 | 查看缓存列表与体积占用、按 ID/Key 删除指定缓存、全量清空缓存(需 confirm) |
19
19
  | \`github_gist\` | 代码片段与调试日志分享治理 | 查看 Gist 列表与代码正文、创建 Secret/Public 代码片段、编辑与物理删除(需 confirm) |
20
20
  | \`github_status\` | 跨仓库待办与动态聚合看板 | 账号维度汇总指派给我的 Issue/PR、等待评审、被 @提及 以及订阅仓库近期动态 |
21
+ | \`github_agent_task\` | 云端智能体编码任务会话治理 | 查阅已分派任务列表、检视任务状态与会话日志、向云端 Agent 发起新编码重构任务 |
22
+ | \`github_discussion\` | 团队技术讨论与开源社区 RFC 闭环 | 浏览讨论列表、检视正文与评论楼层、发起新讨论、编辑正文与追加回复 |
23
+ | \`github_project\` | Projects v2 项目看板与任务规划 | 查阅项目列表/详情、浏览看板条目 (Items)、添加 Issue/PR 到看板、创建草稿任务与删除条目 |
24
+ | \`github_codespace\` | 云端远程开发环境管控 (MVP) | 查阅运行中实例、检视机器规格配置、停机防计费 (stop)、安全销毁环境 (delete,需 confirm) |
21
25
  | \`github_help\` | 路由导航、官方语法速查与故障自愈 | 遇到不确定的操作、搜索语法或接口报错时查询用法与诊断配方 |
22
26
 
23
27
  💡 **使用准则**:优先调用高层语义工具(pr / issue / run / repo / release / secret);当高层工具无法满足特殊接口需求时,再降级使用 \`github_api\`。
28
+ 💬 **人类指令**:聊天框支持 \`/gh status\`(大盘看板)、\`/gh upgrade\`(一键升级插件)、\`/gh help\`(快捷帮助)。
24
29
  🗺️ **命令对照**:不确定某 gh 命令对应哪个工具?\`github_help(topic: 'mapping')\` 查询完整映射表(含未覆盖域的 API 引导)。`,
25
30
  pr: `### 🔀 github_pr 详细操作指南
26
31
 
@@ -155,6 +160,10 @@ const KNOWLEDGE_BASE = {
155
160
  - install 会写本地磁盘,必须 \`confirm: true\`;scope 默认 project(当前 git 仓库)。
156
161
  - 支持的 agent 值:claude-code / cursor / github-copilot / codex / gemini-cli 等。
157
162
  - **查看已安装**: \`github_skill(action: 'list')\`
163
+ - **规范自检与发布**:
164
+ - \`github_skill(action: 'publish')\` —— 默认 \`--dry-run\` 模式,对本地技能目录进行 agentskills.io 合规性检查(命名规范、目录匹配、必需 frontmatter 字段等),零副作用安全自检。
165
+ - \`github_skill(action: 'publish', fix: true)\` —— 自动清洗并剥离残留的安装元数据(\`metadata.github-*\`),修改本地文件但不发布。
166
+ - \`github_skill(action: 'publish', tag: 'v1.0.0', dry_run: false, confirm: true)\` —— 正式发布,强制要求指定 \`tag\` 并附带 \`confirm: true\`(防无头挂起与误发布),自动创建 GitHub Release。
158
167
  - ⚠️ 若报「unknown command」,说明宿主机 gh 版本过低,需升级到 2.9x 以上。`,
159
168
  label: `### 🏷️ github_label 详细操作指南
160
169
 
@@ -210,7 +219,52 @@ const KNOWLEDGE_BASE = {
210
219
  - **限定组织**: \`github_status(org: 'my-org')\`
211
220
  - 仅汇报指定组织内部的待办事项与动态。
212
221
  - **排除噪音仓库**: \`github_status(exclude: ['owner/noisy-repo'])\`
213
- - 过滤高频刷屏但无需关注的仓库活动。`,
222
+ - 过滤高频刷屏但无需关注的仓库活动。
223
+ - **查看工具链运行时健康度**: \`github_status(action: 'health')\`
224
+ - 审计当前会话 18 大工具矩阵的综合健康分、API 降级率、安全防线拦截频次与针对性自愈建议。`,
225
+ agent_task: `### 🤖 github_agent_task 智能体任务指南
226
+
227
+ 管理与调度 GitHub Copilot Coding Agent 云端智能体会话:
228
+ - **查看任务列表**: \`github_agent_task(action: 'list', limit: 30)\`
229
+ - 账号全局任务全景列表(注:上游 gh CLI 原生不接收 -R/--repo 限制,默认列出当前用户所有活跃会话)。
230
+ - **检视任务会话与日志**: \`github_agent_task(action: 'view', task_id: 'e2fa49d2-...', log: true)\`
231
+ - 必须提供 \`task_id\`(支持 Session ID、PR 编号或 URL),支持 \`repo: 'owner/repo'\`,附加 \`log: true\` 可完整拉取任务执行过程日志。
232
+ - **派发新编码任务**: \`github_agent_task(action: 'create', prompt: '为用户模块补全单元测试', base_branch: 'main', repo: 'owner/repo')\`
233
+ - 支持附加 \`custom_agent: 'my-agent'\` 指定仓库预设的智能体定义,支持 \`repo\` 定向派发。`,
234
+ discussion: `### 💬 github_discussion 讨论区操作指南
235
+
236
+ 基于 GitHub CLI 的 \`gh discussion\` preview 特性,支持团队架构探讨、RFC 与社区互动:
237
+ - **查看讨论列表**: \`github_discussion(action: 'list', category: 'General', state: 'open', limit: 30)\`
238
+ - 支持按 \`category\`(分类)、\`state\`(open/closed/all)、\`labels\` 以及 \`search\`(关键词)过滤;状态自动结构化映射为 OPEN / CLOSED / ANSWERED。
239
+ - **检视讨论正文与回复楼层**: \`github_discussion(action: 'view', discussion_number: 123, comments: true)\`
240
+ - **发起新讨论**: \`github_discussion(action: 'create', title: 'RFC: 架构演进方案', category: 'Ideas', body: '详细方案...')\`
241
+ - \`title\`、\`category\` 与 \`body\` 均为必填项。
242
+ - **编辑讨论**: \`github_discussion(action: 'edit', discussion_number: 123, title: '新标题', body: '修正后的正文')\`
243
+ - **发表讨论回复**: \`github_discussion(action: 'comment', discussion_number: 123, body: '赞同该方案!')\`
244
+ - 💡 **提示**:若报错「discussions disabled」,说明目标仓库未在 GitHub 仓库「Settings -> General -> Features」中启用 Discussions 社区功能。`,
245
+ project: `### 📋 github_project 项目看板与规划指南
246
+
247
+ 基于 GitHub Projects v2,支持项目看板与任务全生命周期管理:
248
+ - **查看项目列表**: \`github_project(action: 'list', owner: '@me', closed: false)\`
249
+ - 缺省 owner 为 \`@me\`(当前用户),可指定组织或用户名称。
250
+ - **查看项目详情**: \`github_project(action: 'view', project_number: 1)\`
251
+ - **浏览看板条目 (Items)**: \`github_project(action: 'item-list', project_number: 1, query: 'is:open')\`
252
+ - **添加现有 Issue/PR 到看板**: \`github_project(action: 'item-add', project_number: 1, url: 'https://github.com/owner/repo/issues/10')\`
253
+ - **创建草稿条目**: \`github_project(action: 'item-create', project_number: 1, title: '待调研技术方案', body: '方案说明...')\`
254
+ - **删除看板条目**: \`github_project(action: 'item-delete', item_id: 'PVTI_...', confirm: true)\`
255
+ - 必须附加 \`confirm: true\`;仅解除条目与看板的关联,不删除 Issue/PR 原型。
256
+ - 🔑 若报缺少权限,在终端执行单行自愈授权命令:\`gh auth refresh -s read:project\``,
257
+ codespace: `### ☁️ github_codespace 云端开发环境指南
258
+
259
+ 管理 GitHub Codespaces 云端远程工作区(精选高频实用 MVP):
260
+ - **查看云端环境列表**: \`github_codespace(action: 'list', limit: 30)\`
261
+ - **检视实例配置与状态**: \`github_codespace(action: 'view', codespace: 'fuzzy-spoon-69vj')\`
262
+ - 必须显式提供 \`codespace\` 名称,杜绝交互式挂起。
263
+ - **停止运行环境 (防计费)**: \`github_codespace(action: 'stop', codespace: 'fuzzy-spoon-69vj')\`
264
+ - 立即向云端实例发送停机信号,防止持续扣除计算核时配额。
265
+ - **安全销毁实例**: \`github_codespace(action: 'delete', codespace: 'fuzzy-spoon-69vj', confirm: true)\`
266
+ - 物理销毁不可逆,必须附加 \`confirm: true\`。
267
+ - 🔑 若报缺少权限,在终端执行单行自愈授权命令:\`gh auth refresh -h github.com -s codespace\``,
214
268
  mapping: `### 🗺️ gh 命令 ↔ 插件工具映射总表
215
269
 
216
270
  #### 一、已覆盖域映射(语义化 action 精确对照)
@@ -271,8 +325,8 @@ const KNOWLEDGE_BASE = {
271
325
  | \`gh variable list/set/get/delete\` | \`github_secret(action:…, kind:'variable')\` | CI 明文:-b 直传、get 可回显 |
272
326
  | (gh secret get 不存在) | — | GitHub 侧加密存储,物理不可读取 |
273
327
 
274
- **Skill(github_skill,4 action)**
275
- \`gh skill search/preview/install/list\` → \`github_skill(action:…)\`;install 需 confirm(写磁盘)。
328
+ **Skill(github_skill,5 action)**
329
+ \`gh skill search/preview/install/list/publish\` → \`github_skill(action:…)\`;install 需 confirm(写磁盘);publish 默认 dry-run 安全自检,正式发布需 tag 与 confirm。
276
330
 
277
331
  **Label(github_label,5 action)**
278
332
  | gh 命令 | 插件调用 | 备注 |
@@ -304,10 +358,45 @@ const KNOWLEDGE_BASE = {
304
358
  | \`gh gist edit\` | \`github_gist(action:'edit', gist_id:…)\` | 描述与文件修改 |
305
359
  | \`gh gist delete\` | \`github_gist(action:'delete', gist_id:…, confirm:true)\` | 物理删除,需 confirm |
306
360
 
307
- **Status(github_status,账号维度聚合面板)**
361
+ **Status(github_status,2 action)**
308
362
  | gh 命令 | 插件调用 | 备注 |
309
363
  | :--- | :--- | :--- |
310
364
  | \`gh status\` | \`github_status(action:'view')\` | 跨仓待办大盘与动态 |
365
+ | — | \`github_status(action:'health')\` | 工具链健康度与降级率审计 |
366
+
367
+ **Agent Task(github_agent_task,3 action)**
368
+ | gh 命令 | 插件调用 | 备注 |
369
+ | :--- | :--- | :--- |
370
+ | \`gh agent-task list\` | \`github_agent_task(action:'list')\` | 智能体编码任务列表 |
371
+ | \`gh agent-task view\` | \`github_agent_task(action:'view', task_id:…)\` | 任务状态与日志,ID 必填 |
372
+ | \`gh agent-task create\` | \`github_agent_task(action:'create', prompt:…)\` | 向云端 Agent 派发任务 |
373
+
374
+ **Discussion(github_discussion,5 action)**
375
+ | gh 命令 | 插件调用 | 备注 |
376
+ | :--- | :--- | :--- |
377
+ | \`gh discussion list\` | \`github_discussion(action:'list')\` | 社区与团队讨论列表 |
378
+ | \`gh discussion view\` | \`github_discussion(action:'view', discussion_number:…)\` | 讨论正文与回复楼层 |
379
+ | \`gh discussion create\` | \`github_discussion(action:'create', title:…, category:…, body:…)\` | 发起新讨论,三项必填 |
380
+ | \`gh discussion edit\` | \`github_discussion(action:'edit', discussion_number:…)\` | 修改讨论标题或正文 |
381
+ | \`gh discussion comment\` | \`github_discussion(action:'comment', discussion_number:…, body:…)\` | 追加讨论评论 |
382
+
383
+ **Project(github_project,6 action)**
384
+ | gh 命令 | 插件调用 | 备注 |
385
+ | :--- | :--- | :--- |
386
+ | \`gh project list\` | \`github_project(action:'list')\` | 项目看板列表,默认 @me |
387
+ | \`gh project view\` | \`github_project(action:'view', project_number:…)\` | 项目元数据与描述 |
388
+ | \`gh project item-list\` | \`github_project(action:'item-list', project_number:…)\` | 任务条目看板 |
389
+ | \`gh project item-add\` | \`github_project(action:'item-add', project_number:…, url:…)\` | 关联 Issue/PR 到看板 |
390
+ | \`gh project item-create\` | \`github_project(action:'item-create', project_number:…, title:…)\` | 创建草稿条目 |
391
+ | \`gh project item-delete\` | \`github_project(action:'item-delete', item_id:…, confirm:true)\` | 移除条目,需 confirm |
392
+
393
+ **Codespace(github_codespace,4 action)**
394
+ | gh 命令 | 插件调用 | 备注 |
395
+ | :--- | :--- | :--- |
396
+ | \`gh codespace list\` | \`github_codespace(action:'list')\` | 云端开发环境列表 |
397
+ | \`gh codespace view\` | \`github_codespace(action:'view', codespace:…)\` | 实例详情,名称必填 |
398
+ | \`gh codespace stop\` | \`github_codespace(action:'stop', codespace:…)\` | 关机防计费 |
399
+ | \`gh codespace delete\` | \`github_codespace(action:'delete', codespace:…, confirm:true)\` | 销毁实例,需 confirm |
311
400
 
312
401
  #### 二、归属提示(命令域与工具名不同构)
313
402
 
@@ -320,14 +409,10 @@ const KNOWLEDGE_BASE = {
320
409
 
321
410
  | gh 域 | 用途 | 推荐 REST 端点 |
322
411
  | :--- | :--- | :--- |
323
- | \`gh project\` | Projects v2 | \`graphql\`(Projects API 仅 GraphQL) |
324
- | \`gh discussion\` | 讨论 | \`graphql\`(需仓库开启 discussions) |
325
- | \`gh codespace\` | 云端开发环境 | \`user/codespaces\` |
326
412
  | \`gh org\` | 组织信息 | \`orgs/{org}\` |
327
413
  | \`gh auth/config/extension/alias\` | 本机配置类 | 多数无需 API(本机文件/命令) |
328
414
  | \`gh browse\` | 打开浏览器 | 直接给用户 URL 即可 |
329
415
  | \`gh attestation/gpg-key/ssh-key\` | 签名与密钥 | \`repos/{o}/{r}/attestations\` 等 |
330
- | \`gh agent-task\` | Copilot 会话 | \`graphql\`(需 Copilot 授权) |
331
416
 
332
417
  > 用法示例:\`github_api(endpoint: 'repos/owner/repo/pulls')\`(原有 \`repos/{o}/{r}/labels\` 端点已由原生 \`github_label\` 工具接管)`,
333
418
  search_syntax: `### 🔍 GitHub 官方高级检索语法速查手册
@@ -361,7 +446,18 @@ const KNOWLEDGE_BASE = {
361
446
  - *解法*:宿主机尚未安装 gh。Windows 运行 \`winget install GitHub.cli\`,macOS 运行 \`brew install gh\`,然后执行 \`gh auth login\` 登录。
362
447
  5. **报 \`unknown command "skill" for "gh"\`**:
363
448
  - *原因*:\`gh skill\` 是 GitHub CLI 2.9x 引入的 preview 特性,宿主机版本过低。
364
- - *解法*:升级 gh(Windows: \`winget upgrade GitHub.cli\`;macOS: \`brew upgrade gh\`)后重试;升级前可改用 \`github_api\` 检索 \`SKILL.md\` 文件路径作为替代。`
449
+ - *解法*:升级 gh(Windows: \`winget upgrade GitHub.cli\`;macOS: \`brew upgrade gh\`)后重试;升级前可改用 \`github_api\` 检索 \`SKILL.md\` 文件路径作为替代。
450
+ 6. **报 \`the token ... needs the '<scope>' scope\` (缺少权限)**:
451
+ - *原因*:GitHub Token 缺少对应操作的最小 Scope 权限(如 Codespaces 需要 \`codespace\` 权限,Projects v2 需要 \`read:project\` 权限)。
452
+ - *解法*:在系统终端执行单行自愈命令完成授权刷新(无需重启插件,即刻生效):
453
+ - Codespace: \`gh auth refresh -h github.com -s codespace\`
454
+ - Project: \`gh auth refresh -s read:project\`
455
+ 7. **报 \`the '...' repository has discussions disabled\`**:
456
+ - *原因*:目标 GitHub 仓库未开启 Discussions 社区功能。
457
+ - *解法*:需管理员前往 GitHub 网页端 \`Settings -> General -> Features\` 勾选开启 \`Discussions\`。
458
+ 8. **操作被拦截提示 \`Awaiting confirmation\`**:
459
+ - *原因*:对于高危破坏性操作(如合并 PR、删除分支、物理删除 Issue、清空构建缓存、删除密钥、销毁 Codespace),插件设置了强制安全确认防线,未确认时绝对不触发底层 CLI。
460
+ - *解法*:审阅影响评估报告后,在参数中显式传入 \`confirm: true\` 即可放行。`
365
461
  };
366
462
  export function createHelpTool(executor) {
367
463
  return {
@@ -387,6 +483,10 @@ export function createHelpTool(executor) {
387
483
  'cache',
388
484
  'gist',
389
485
  'status',
486
+ 'agent_task',
487
+ 'discussion',
488
+ 'project',
489
+ 'codespace',
390
490
  'mapping',
391
491
  'search_syntax',
392
492
  'troubleshooting',
@@ -0,0 +1,80 @@
1
+ import type { GhExecutor } from '../executor.js';
2
+ /**
3
+ * 检测错误信息是否属于 Scope 权限不足,并返回标准自愈对象
4
+ */
5
+ export declare function checkScopeRequired(errorMsg: string, scope: string, command: string, tool: string): {
6
+ status: string;
7
+ scope: string;
8
+ command: string;
9
+ tool: string;
10
+ } | null;
11
+ export declare function createProjectTool(executor: GhExecutor): {
12
+ name: string;
13
+ description: string;
14
+ parameters: {
15
+ type: string;
16
+ properties: {
17
+ action: {
18
+ type: string;
19
+ enum: string[];
20
+ description: string;
21
+ };
22
+ owner: {
23
+ type: string;
24
+ description: string;
25
+ };
26
+ project_number: {
27
+ type: string;
28
+ description: string;
29
+ };
30
+ item_id: {
31
+ type: string;
32
+ description: string;
33
+ };
34
+ url: {
35
+ type: string;
36
+ description: string;
37
+ };
38
+ title: {
39
+ type: string;
40
+ description: string;
41
+ };
42
+ body: {
43
+ type: string;
44
+ description: string;
45
+ };
46
+ query: {
47
+ type: string;
48
+ description: string;
49
+ };
50
+ closed: {
51
+ type: string;
52
+ description: string;
53
+ };
54
+ limit: {
55
+ type: string;
56
+ description: string;
57
+ };
58
+ confirm: {
59
+ type: string;
60
+ description: string;
61
+ };
62
+ };
63
+ required: string[];
64
+ };
65
+ output: {
66
+ schema: {
67
+ type: string;
68
+ };
69
+ render(args: any, value: any): {
70
+ type: string;
71
+ text: string;
72
+ }[];
73
+ };
74
+ execute(args: any, execContext: any): Promise<Record<string, any> | {
75
+ status: string;
76
+ scope: string;
77
+ command: string;
78
+ tool: string;
79
+ }>;
80
+ };