dsh-github-flow 0.3.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.
- package/README.en.md +287 -143
- package/README.md +270 -125
- package/docs/UPGRADE-NOTES.md +12 -9
- package/docs/architecture.md +126 -126
- package/lib/api/routes-actions.js +249 -0
- package/lib/api/routes-overview.js +94 -2
- package/lib/cache.d.ts +4 -0
- package/lib/cache.js +14 -0
- package/lib/client.d.ts +14 -1
- package/lib/client.js +4287 -2500
- package/lib/commands/gh.d.ts +6 -1
- package/lib/commands/gh.js +144 -71
- package/lib/executor/git-parser.d.ts +57 -0
- package/lib/executor/git-parser.js +255 -0
- package/lib/executor/platform-guide.d.ts +14 -0
- package/lib/executor/platform-guide.js +40 -0
- package/lib/executor/process-utils.d.ts +51 -0
- package/lib/executor/process-utils.js +162 -0
- package/lib/executor/version-utils.d.ts +12 -0
- package/lib/executor/version-utils.js +27 -0
- package/lib/executor.d.ts +70 -48
- package/lib/executor.js +371 -356
- package/lib/git-watcher.d.ts +36 -0
- package/lib/git-watcher.js +91 -0
- package/lib/main.js +37 -3
- package/lib/renderers/agent-task.d.ts +16 -0
- package/lib/renderers/agent-task.js +107 -0
- package/lib/renderers/cache.d.ts +8 -0
- package/lib/renderers/cache.js +66 -0
- package/lib/renderers/codespace.d.ts +16 -0
- package/lib/renderers/codespace.js +103 -0
- package/lib/renderers/common.d.ts +24 -0
- package/lib/renderers/common.js +88 -0
- package/lib/renderers/discussion.d.ts +16 -0
- package/lib/renderers/discussion.js +101 -0
- package/lib/renderers/gist.d.ts +15 -0
- package/lib/renderers/gist.js +99 -0
- package/lib/renderers/issue.d.ts +4 -0
- package/lib/renderers/issue.js +70 -0
- package/lib/renderers/label.d.ts +4 -0
- package/lib/renderers/label.js +48 -0
- package/lib/renderers/markdown.d.ts +19 -32
- package/lib/renderers/markdown.js +19 -624
- package/lib/renderers/pr.d.ts +4 -0
- package/lib/renderers/pr.js +107 -0
- package/lib/renderers/project.d.ts +20 -0
- package/lib/renderers/project.js +128 -0
- package/lib/renderers/release.d.ts +4 -0
- package/lib/renderers/release.js +74 -0
- package/lib/renderers/repo.d.ts +4 -0
- package/lib/renderers/repo.js +149 -0
- package/lib/renderers/ruleset.d.ts +4 -0
- package/lib/renderers/ruleset.js +74 -0
- package/lib/renderers/run.d.ts +4 -0
- package/lib/renderers/run.js +79 -0
- package/lib/renderers/skill.d.ts +34 -0
- package/lib/renderers/skill.js +241 -0
- package/lib/renderers/status.d.ts +28 -0
- package/lib/renderers/status.js +176 -0
- package/lib/telemetry.d.ts +70 -0
- package/lib/telemetry.js +161 -0
- package/lib/tools/agent-task.d.ts +54 -0
- package/lib/tools/agent-task.js +135 -0
- package/lib/tools/cache.d.ts +64 -0
- package/lib/tools/cache.js +186 -0
- package/lib/tools/codespace.d.ts +51 -0
- package/lib/tools/codespace.js +154 -0
- package/lib/tools/discussion.d.ts +70 -0
- package/lib/tools/discussion.js +195 -0
- package/lib/tools/gist.d.ts +155 -0
- package/lib/tools/gist.js +190 -0
- package/lib/tools/help.js +214 -13
- package/lib/tools/image-utils.d.ts +8 -0
- package/lib/tools/image-utils.js +34 -0
- package/lib/tools/issue.d.ts +8 -1
- package/lib/tools/issue.js +26 -4
- package/lib/tools/label.d.ts +80 -0
- package/lib/tools/label.js +237 -0
- package/lib/tools/pr.d.ts +8 -0
- package/lib/tools/pr.js +48 -3
- package/lib/tools/project.d.ts +80 -0
- package/lib/tools/project.js +241 -0
- package/lib/tools/repo.js +13 -1
- package/lib/tools/ruleset.d.ts +80 -0
- package/lib/tools/ruleset.js +177 -0
- package/lib/tools/skill.d.ts +24 -1
- package/lib/tools/skill.js +115 -5
- package/lib/tools/status.d.ts +40 -0
- package/lib/tools/status.js +58 -0
- package/lib/types.d.ts +44 -0
- package/lib/ui/auth-guide-card.d.ts +4 -0
- package/lib/ui/auth-guide-card.js +161 -0
- package/lib/ui/branch-selector.d.ts +10 -0
- package/lib/ui/branch-selector.js +163 -0
- package/lib/ui/commit-modal.d.ts +8 -0
- package/lib/ui/commit-modal.js +219 -0
- package/lib/ui/help-modal.d.ts +15 -0
- package/lib/ui/help-modal.js +202 -0
- package/lib/ui/icons.d.ts +7 -0
- package/lib/ui/icons.js +53 -0
- package/lib/ui/network-banner.d.ts +10 -0
- package/lib/ui/network-banner.js +54 -0
- package/lib/ui/storage.d.ts +35 -0
- package/lib/ui/storage.js +158 -0
- package/lib/ui/styles.d.ts +6 -0
- package/lib/ui/styles.js +1544 -0
- package/lib/ui/sync-settings-modal.d.ts +11 -0
- package/lib/ui/sync-settings-modal.js +350 -0
- package/lib/ui/sync-status-badge.d.ts +8 -0
- package/lib/ui/sync-status-badge.js +64 -0
- package/lib/ui/upgrade-card.d.ts +7 -0
- package/lib/ui/upgrade-card.js +222 -0
- package/lib/ui/utils.d.ts +45 -0
- package/lib/ui/utils.js +226 -0
- package/lib/ui/workspace-panel.d.ts +4 -0
- package/lib/ui/workspace-panel.js +489 -0
- package/lib/upgrade-manager.d.ts +5 -1
- package/lib/upgrade-manager.js +24 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +2 -2
|
@@ -1,627 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DSH GitHub Flow - Native Markdown
|
|
2
|
+
* DSH GitHub Flow - Native Markdown 格式化渲染引擎门面入口
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* 2. 节省 70%+ 的会话上下文 Token,极大加速长对话推理速度;
|
|
7
|
-
* 3. 嵌入可点击超链接与直观的状态药丸 Emoji,提升人类与模型阅读体验;
|
|
8
|
-
* 4. 严谨防御 Markdown 表格竖线破坏、缺失值回退与异常对象降级。
|
|
4
|
+
* 为保持向后兼容性与构建产物一致性,本入口统一 Re-export 全部领域渲染器
|
|
5
|
+
* 与通用徽章工具,各 Agent Tool 与自动化单测可无感引用。
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
return '-';
|
|
27
|
-
const s = state.toUpperCase();
|
|
28
|
-
if (isDraft)
|
|
29
|
-
return '⚪ DRAFT';
|
|
30
|
-
if (s === 'OPEN')
|
|
31
|
-
return '🟢 OPEN';
|
|
32
|
-
if (s === 'MERGED')
|
|
33
|
-
return '🟣 MERGED';
|
|
34
|
-
if (s === 'CLOSED')
|
|
35
|
-
return '🔴 CLOSED';
|
|
36
|
-
return s;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* 格式化 CI 工作流状态徽章。
|
|
40
|
-
* 第二参数按调用域语义不同:run 域传 conclusion(success/failure/cancelled/skipped),
|
|
41
|
-
* pr checks 域传 bucket(pass/fail/pending/skipping/cancel)——取值族不同但映射到
|
|
42
|
-
* 同一组徽章;state 参数兜底(in_progress/queued 等进行中态)。
|
|
43
|
-
*/
|
|
44
|
-
export function formatCiBadge(status, conclusion) {
|
|
45
|
-
const conc = (conclusion || '').toLowerCase();
|
|
46
|
-
const st = (status || '').toLowerCase();
|
|
47
|
-
if (conc === 'success' || conc === 'pass')
|
|
48
|
-
return '✅ ' + conc;
|
|
49
|
-
if (conc === 'failure' || conc === 'fail')
|
|
50
|
-
return '❌ ' + conc;
|
|
51
|
-
if (conc === 'cancelled' || conc === 'cancel')
|
|
52
|
-
return '🚫 ' + conc;
|
|
53
|
-
if (conc === 'skipped' || conc === 'skipping')
|
|
54
|
-
return '⏭️ ' + conc;
|
|
55
|
-
if (conc === 'pending')
|
|
56
|
-
return '⏳ pending';
|
|
57
|
-
if (st === 'in_progress')
|
|
58
|
-
return '⏳ running';
|
|
59
|
-
if (st === 'queued')
|
|
60
|
-
return '⏱️ queued';
|
|
61
|
-
return conc || st || '-';
|
|
62
|
-
}
|
|
63
|
-
/** 格式化合并冲突状态 */
|
|
64
|
-
export function formatConflictBadge(status) {
|
|
65
|
-
if (!status)
|
|
66
|
-
return '-';
|
|
67
|
-
const s = status.toUpperCase();
|
|
68
|
-
if (s === 'CLEAN')
|
|
69
|
-
return '✅ CLEAN';
|
|
70
|
-
if (s === 'DIRTY' || s === 'CONFLICT')
|
|
71
|
-
return '⚠️ CONFLICT';
|
|
72
|
-
if (s === 'BLOCKED')
|
|
73
|
-
return '⛔ BLOCKED';
|
|
74
|
-
return s;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* 降级链路可见标注(runGuarded 契约的渲染兑现)。
|
|
78
|
-
* 为什么必须可见:降级若是静默的,Agent 就无法感知能力边界(同一 action 在
|
|
79
|
-
* 不同 gh 版本上走不同链路);一条 blockquote 注释成本一行,换链路透明。
|
|
80
|
-
*/
|
|
81
|
-
export function appendDegradedNote(value) {
|
|
82
|
-
if (value && value.degraded === true && value.degradedReason) {
|
|
83
|
-
return `\n\n> ⚠️ ${value.degradedReason}`;
|
|
84
|
-
}
|
|
85
|
-
return '';
|
|
86
|
-
}
|
|
87
|
-
// -------------------------------------------------------------
|
|
88
|
-
// 1. PR 渲染器
|
|
89
|
-
// -------------------------------------------------------------
|
|
90
|
-
export function renderPrMarkdown(args, value) {
|
|
91
|
-
if (!value)
|
|
92
|
-
return '无返回内容';
|
|
93
|
-
if (value.status === 'AWAITING_CONFIRMATION') {
|
|
94
|
-
return [
|
|
95
|
-
`> ### ${value.warning || '⚠️ 高危操作拦截警告'}`,
|
|
96
|
-
`> - **影响评估**: ${value.impact || '该操作将改变远端仓库状态。'}`,
|
|
97
|
-
`> - **确认指引**: ${value.requiredAction || '如确认继续,请向用户核实并在参数中附加 `confirm: true` 重新调用。'}`,
|
|
98
|
-
].join('\n');
|
|
99
|
-
}
|
|
100
|
-
if (typeof value.result === 'string')
|
|
101
|
-
return value.result;
|
|
102
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
103
|
-
const extra = value.detail || value.output;
|
|
104
|
-
return `**${value.message}**` + (value.url ? `\n🔗 链接: ${value.url}` : '') + (extra ? `\n\`\`\`\n${extra}\n\`\`\`` : '');
|
|
105
|
-
}
|
|
106
|
-
// 1.1 PR 列表
|
|
107
|
-
if (Array.isArray(value.items) && args?.action === 'list') {
|
|
108
|
-
const list = value.items.filter(Boolean);
|
|
109
|
-
if (list.length === 0)
|
|
110
|
-
return '📭 当前仓库暂无匹配的 Pull Request。';
|
|
111
|
-
const rows = list.map((p) => {
|
|
112
|
-
const numLink = p.url ? `[#${p.number}](${p.url})` : `#${p.number}`;
|
|
113
|
-
const badge = formatStateBadge(p.state, p.isDraft);
|
|
114
|
-
const title = sanitizeCell(p.title, 55);
|
|
115
|
-
const author = p.author?.login ? `@${p.author.login}` : (typeof p.author === 'string' ? `@${p.author}` : '-');
|
|
116
|
-
const date = p.updatedAt ? p.updatedAt.slice(0, 10) : (p.mergedAt ? p.mergedAt.slice(0, 10) : '-');
|
|
117
|
-
return `| ${numLink} | ${badge} | ${title} | ${author} | ${date} |`;
|
|
118
|
-
});
|
|
119
|
-
return [
|
|
120
|
-
`**找到 ${list.length} 个 Pull Request:**\n`,
|
|
121
|
-
'| 编号 | 状态 | 标题 | 作者 | 更新日期 |',
|
|
122
|
-
'| :--- | :--- | :--- | :--- | :--- |',
|
|
123
|
-
...rows,
|
|
124
|
-
].join('\n');
|
|
125
|
-
}
|
|
126
|
-
// 1.2 PR CI Checks
|
|
127
|
-
if (Array.isArray(value.items) && args?.action === 'checks') {
|
|
128
|
-
const list = value.items.filter(Boolean);
|
|
129
|
-
if (list.length === 0)
|
|
130
|
-
return '当前 PR 暂无 CI Checks 运行记录。';
|
|
131
|
-
const rows = list.map((c) => {
|
|
132
|
-
const name = sanitizeCell(c.name, 40);
|
|
133
|
-
// bucket 是 gh pr checks 的分类字段(pass/fail/pending/skipping/cancel),
|
|
134
|
-
// 优先于 state 呈现;state(SUCCESS/FAILURE/...)作为兜底——渲染器同步
|
|
135
|
-
// Issue #3 修复:旧 conclusion/detailsUrl 字段在 gh 中不存在。
|
|
136
|
-
const badge = formatCiBadge(c.state, c.bucket);
|
|
137
|
-
const url = c.link ? `[查看详情](${c.link})` : '-';
|
|
138
|
-
const wf = c.workflow ? sanitizeCell(c.workflow, 24) : '-';
|
|
139
|
-
return `| ${name} | ${badge} | ${wf} | ${url} |`;
|
|
140
|
-
});
|
|
141
|
-
return [
|
|
142
|
-
`**CI 检查结果 (${list.length} 项):**\n`,
|
|
143
|
-
'| 检查项名称 | 结论 / 状态 | 工作流 | 详情链接 |',
|
|
144
|
-
'| :--- | :--- | :--- | :--- |',
|
|
145
|
-
...rows,
|
|
146
|
-
].join('\n');
|
|
147
|
-
}
|
|
148
|
-
// 1.3 PR Status (冲突与相关状态)
|
|
149
|
-
if (args?.action === 'status') {
|
|
150
|
-
const created = Array.isArray(value.createdBy) ? value.createdBy : [];
|
|
151
|
-
const review = Array.isArray(value.needsReview) ? value.needsReview : [];
|
|
152
|
-
const parts = ['### 🔀 当前分支关联 PR 状态\n'];
|
|
153
|
-
if (created.length > 0) {
|
|
154
|
-
parts.push('**由我发起的 PR:**\n| 编号 | 状态 | 冲突检测 | 标题 |', '| :--- | :--- | :--- | :--- |');
|
|
155
|
-
for (const p of created) {
|
|
156
|
-
const link = p.url ? `[#${p.number}](${p.url})` : `#${p.number}`;
|
|
157
|
-
parts.push(`| ${link} | ${formatStateBadge(p.state)} | ${formatConflictBadge(p.mergeStateStatus)} | ${sanitizeCell(p.title, 50)} |`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
parts.push('当前分支未检测到本人发起的活跃 PR。');
|
|
162
|
-
}
|
|
163
|
-
if (review.length > 0) {
|
|
164
|
-
parts.push('\n**待我审查的 PR:**\n| 编号 | 状态 | 标题 |', '| :--- | :--- | :--- |');
|
|
165
|
-
for (const p of review) {
|
|
166
|
-
const link = p.url ? `[#${p.number}](${p.url})` : `#${p.number}`;
|
|
167
|
-
parts.push(`| ${link} | ${formatStateBadge(p.state)} | ${sanitizeCell(p.title, 50)} |`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return parts.join('\n');
|
|
171
|
-
}
|
|
172
|
-
// 1.4 PR View 单卡详情
|
|
173
|
-
if (args?.action === 'view' && value.number) {
|
|
174
|
-
const link = value.url ? `[#${value.number}](${value.url})` : `#${value.number}`;
|
|
175
|
-
const badge = formatStateBadge(value.state, value.isDraft);
|
|
176
|
-
const author = value.author?.login ? `@${value.author.login}` : '-';
|
|
177
|
-
const lines = [
|
|
178
|
-
`### ${badge} ${value.title} (${link})`,
|
|
179
|
-
`- **作者**: ${author} | **分支**: \`${value.headRefName || '-'}\` → \`${value.baseRefName || 'main'}\``,
|
|
180
|
-
`- **合并判定**: ${formatConflictBadge(value.mergeable || value.mergeStateStatus)} | **审查判定**: ${value.reviewDecision || 'NONE'}`,
|
|
181
|
-
];
|
|
182
|
-
if (Array.isArray(value.labels) && value.labels.length > 0) {
|
|
183
|
-
lines.push(`- **标签**: ${value.labels.map((l) => `\`${l.name || l}\``).join(' ')}`);
|
|
184
|
-
}
|
|
185
|
-
if (value.body) {
|
|
186
|
-
lines.push('\n**正文说明:**\n```markdown\n' + sanitizeCell(value.body, 300) + '\n```');
|
|
187
|
-
}
|
|
188
|
-
return lines.join('\n');
|
|
189
|
-
}
|
|
190
|
-
// 兜底降级
|
|
191
|
-
return JSON.stringify(value, null, 2);
|
|
192
|
-
}
|
|
193
|
-
// -------------------------------------------------------------
|
|
194
|
-
// 2. Issue 渲染器
|
|
195
|
-
// -------------------------------------------------------------
|
|
196
|
-
export function renderIssueMarkdown(args, value) {
|
|
197
|
-
if (!value)
|
|
198
|
-
return '无返回内容';
|
|
199
|
-
if (value.status === 'AWAITING_CONFIRMATION') {
|
|
200
|
-
return [
|
|
201
|
-
`> ### ${value.warning || '⚠️ 高危操作拦截警告'}`,
|
|
202
|
-
`> - **影响评估**: ${value.impact || '该操作将改变远端仓库状态。'}`,
|
|
203
|
-
`> - **确认指引**: ${value.requiredAction || '如确认继续,请向用户核实并在参数中附加 `confirm: true` 重新调用。'}`,
|
|
204
|
-
].join('\n');
|
|
205
|
-
}
|
|
206
|
-
if (typeof value.result === 'string')
|
|
207
|
-
return value.result;
|
|
208
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
209
|
-
const extra = value.detail || value.output;
|
|
210
|
-
return `**${value.message}**` + (value.url ? `\n🔗 链接: ${value.url}` : '') + (extra ? `\n\`\`\`\n${extra}\n\`\`\`` : '');
|
|
211
|
-
}
|
|
212
|
-
// 2.1 Issue 列表
|
|
213
|
-
if (Array.isArray(value.items) && args?.action === 'list') {
|
|
214
|
-
const list = value.items.filter(Boolean);
|
|
215
|
-
if (list.length === 0)
|
|
216
|
-
return '📭 当前仓库暂无匹配的 Issue。';
|
|
217
|
-
const rows = list.map((i) => {
|
|
218
|
-
const numLink = i.url ? `[#${i.number}](${i.url})` : `#${i.number}`;
|
|
219
|
-
const badge = formatStateBadge(i.state);
|
|
220
|
-
const title = sanitizeCell(i.title, 60);
|
|
221
|
-
const labels = Array.isArray(i.labels) && i.labels.length > 0
|
|
222
|
-
? i.labels.map((l) => `\`${sanitizeCell(l.name || l, 15)}\``).join(' ')
|
|
223
|
-
: '-';
|
|
224
|
-
const author = i.author?.login ? `@${i.author.login}` : (typeof i.author === 'string' ? `@${i.author}` : '-');
|
|
225
|
-
const date = i.updatedAt ? i.updatedAt.slice(0, 10) : '-';
|
|
226
|
-
return `| ${numLink} | ${badge} | ${title} | ${labels} | ${author} | ${date} |`;
|
|
227
|
-
});
|
|
228
|
-
return [
|
|
229
|
-
`**找到 ${list.length} 个 Issue:**\n`,
|
|
230
|
-
'| 编号 | 状态 | 标题 | 标签 | 作者 | 更新日期 |',
|
|
231
|
-
'| :--- | :--- | :--- | :--- | :--- | :--- |',
|
|
232
|
-
...rows,
|
|
233
|
-
].join('\n');
|
|
234
|
-
}
|
|
235
|
-
// 2.2 Issue View 详情
|
|
236
|
-
if (args?.action === 'view' && value.number) {
|
|
237
|
-
const link = value.url ? `[#${value.number}](${value.url})` : `#${value.number}`;
|
|
238
|
-
const badge = formatStateBadge(value.state);
|
|
239
|
-
const author = value.author?.login ? `@${value.author.login}` : '-';
|
|
240
|
-
const lines = [
|
|
241
|
-
`### ${badge} ${value.title} (${link})`,
|
|
242
|
-
`- **作者**: ${author} | **更新时间**: ${value.updatedAt?.slice(0, 16) || '-'}`,
|
|
243
|
-
];
|
|
244
|
-
if (Array.isArray(value.labels) && value.labels.length > 0) {
|
|
245
|
-
lines.push(`- **标签**: ${value.labels.map((l) => `\`${l.name || l}\``).join(' ')}`);
|
|
246
|
-
}
|
|
247
|
-
if (Array.isArray(value.assignees) && value.assignees.length > 0) {
|
|
248
|
-
lines.push(`- **指派人**: ${value.assignees.map((a) => `@${a.login || a}`).join(' ')}`);
|
|
249
|
-
}
|
|
250
|
-
if (value.body) {
|
|
251
|
-
lines.push('\n**议题正文:**\n```markdown\n' + sanitizeCell(value.body, 300) + '\n```');
|
|
252
|
-
}
|
|
253
|
-
// 图片附件清单(view 附带 URL 清单,view_images 按需下载查看)
|
|
254
|
-
if (Array.isArray(value.images) && value.images.length > 0) {
|
|
255
|
-
lines.push(`- **📎 图片附件 (${value.images.length}):** 调用 \`github_issue(action: 'view_images', issue_number: ${value.number})\` 可下载查看`);
|
|
256
|
-
}
|
|
257
|
-
return lines.join('\n');
|
|
258
|
-
}
|
|
259
|
-
// 兜底降级
|
|
260
|
-
return JSON.stringify(value, null, 2);
|
|
261
|
-
}
|
|
262
|
-
// -------------------------------------------------------------
|
|
263
|
-
// 3. Workflow Run 渲染器
|
|
264
|
-
// -------------------------------------------------------------
|
|
265
|
-
export function renderRunMarkdown(args, value) {
|
|
266
|
-
if (!value)
|
|
267
|
-
return '无返回数据';
|
|
268
|
-
if (typeof value.result === 'string')
|
|
269
|
-
return value.result;
|
|
270
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
271
|
-
return `**${value.message}**` + (value.output ? `\n\`\`\`\n${value.output}\n\`\`\`` : '');
|
|
272
|
-
}
|
|
273
|
-
// 3.1 Run 列表
|
|
274
|
-
if (Array.isArray(value.items) && args?.action === 'list') {
|
|
275
|
-
const list = value.items.filter(Boolean);
|
|
276
|
-
if (list.length === 0)
|
|
277
|
-
return '📭 暂无匹配的工作流运行记录。';
|
|
278
|
-
const rows = list.map((r) => {
|
|
279
|
-
const idLink = r.url ? `[${r.databaseId}](${r.url})` : `\`${r.databaseId}\``;
|
|
280
|
-
const badge = formatCiBadge(r.status, r.conclusion);
|
|
281
|
-
const name = sanitizeCell(r.name, 35);
|
|
282
|
-
const branch = r.headBranch ? `\`${r.headBranch}\`` : '-';
|
|
283
|
-
const event = r.event || '-';
|
|
284
|
-
const time = r.createdAt ? r.createdAt.slice(0, 16).replace('T', ' ') : '-';
|
|
285
|
-
return `| ${idLink} | ${badge} | ${name} | ${branch} | ${event} | ${time} |`;
|
|
286
|
-
});
|
|
287
|
-
return [
|
|
288
|
-
`**最近 ${list.length} 次工作流运行:**\n`,
|
|
289
|
-
'| Run ID | 结论 / 状态 | 工作流名称 | 触发分支 | 触发事件 | 运行时间 |',
|
|
290
|
-
'| :--- | :--- | :--- | :--- | :--- | :--- |',
|
|
291
|
-
...rows,
|
|
292
|
-
].join('\n');
|
|
293
|
-
}
|
|
294
|
-
// 3.2 Workflow 清单(字段集为 gh 2.96 实测合法全集 4 个)
|
|
295
|
-
if (Array.isArray(value.items) && args?.action === 'workflow_list') {
|
|
296
|
-
const list = value.items.filter(Boolean);
|
|
297
|
-
if (list.length === 0)
|
|
298
|
-
return args?.all === true ? '📭 该仓库没有任何工作流。' : '📭 暂无 active 工作流(可能全部 disabled,传 all: true 查看)。';
|
|
299
|
-
const rows = list.map((w) => {
|
|
300
|
-
const badge = w.state === 'active' ? '🟢 active' : (w.state === 'disabled' ? '🔴 disabled' : String(w.state || '-'));
|
|
301
|
-
return `| \`${w.id}\` | ${sanitizeCell(w.name, 40)} | ${badge} | \`${sanitizeCell(w.path, 45)}\` |`;
|
|
302
|
-
});
|
|
303
|
-
return [
|
|
304
|
-
`**工作流清单 (${list.length} 个${args?.all === true ? ',含 disabled' : ''}):**\n`,
|
|
305
|
-
'| ID | 名称 | 状态 | 文件 |',
|
|
306
|
-
'| :--- | :--- | :--- | :--- |',
|
|
307
|
-
...rows,
|
|
308
|
-
].join('\n');
|
|
309
|
-
}
|
|
310
|
-
// 3.3 Workflow 详情(gh 无 --json,头部结构化 + Recent runs 原文引用块——D4 决策)
|
|
311
|
-
if (args?.action === 'workflow_view' && value.workflow) {
|
|
312
|
-
const lines = [
|
|
313
|
-
`### 🔄 ${value.workflow}`,
|
|
314
|
-
`- **ID**: \`${value.id || '-'}\`${value.totalRuns ? ` | **累计运行**: ${value.totalRuns} 次` : ''}`,
|
|
315
|
-
];
|
|
316
|
-
if (value.recentRuns) {
|
|
317
|
-
lines.push('', '**最近运行:**', '```', value.recentRuns, '```');
|
|
318
|
-
}
|
|
319
|
-
return lines.join('\n');
|
|
320
|
-
}
|
|
321
|
-
// 3.4 Run View 详情
|
|
322
|
-
if (args?.action === 'view' && value.databaseId) {
|
|
323
|
-
const idLink = value.url ? `[${value.databaseId}](${value.url})` : `\`${value.databaseId}\``;
|
|
324
|
-
const badge = formatCiBadge(value.status, value.conclusion);
|
|
325
|
-
const lines = [
|
|
326
|
-
`### 工作流: ${value.name} (Run: ${idLink})`,
|
|
327
|
-
`- **状态**: ${badge}`,
|
|
328
|
-
];
|
|
329
|
-
if (Array.isArray(value.jobs) && value.jobs.length > 0) {
|
|
330
|
-
lines.push('\n**Jobs 步骤明细:**\n| Job 名称 | 结论 / 状态 | 详情 |', '| :--- | :--- | :--- |');
|
|
331
|
-
for (const j of value.jobs) {
|
|
332
|
-
lines.push(`| ${sanitizeCell(j.name, 30)} | ${formatCiBadge(j.status, j.conclusion)} | ${j.url ? `[链接](${j.url})` : '-'} |`);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return lines.join('\n');
|
|
336
|
-
}
|
|
337
|
-
// 兜底降级
|
|
338
|
-
return JSON.stringify(value, null, 2);
|
|
339
|
-
}
|
|
340
|
-
// -------------------------------------------------------------
|
|
341
|
-
// 4. Repo 渲染器
|
|
342
|
-
// -------------------------------------------------------------
|
|
343
|
-
export function renderRepoMarkdown(args, value) {
|
|
344
|
-
if (!value)
|
|
345
|
-
return '无返回内容';
|
|
346
|
-
if (typeof value.result === 'string')
|
|
347
|
-
return value.result;
|
|
348
|
-
// 4.0 README 预览(文本截断版 + 图片清单)——必须在 message 早退分支之前:
|
|
349
|
-
// readme 返回同时带 message 与 readme 字段,先判 readme 才能渲染预览而非一行摘要
|
|
350
|
-
if (args?.action === 'readme' && typeof value.readme === 'string') {
|
|
351
|
-
const lines = [`### 📖 README 预览`, '', '```markdown', value.readme, '```'];
|
|
352
|
-
if (Array.isArray(value.images) && value.images.length > 0) {
|
|
353
|
-
lines.push('', `**📎 图片清单 (${value.images.length}):** 可用 \`image_urls\` 参数下载指定图片(留空下载全部)`);
|
|
354
|
-
value.images.slice(0, 8).forEach((u, i) => lines.push(`${i + 1}. ${u}`));
|
|
355
|
-
if (value.images.length > 8)
|
|
356
|
-
lines.push(`…共 ${value.images.length} 个`);
|
|
357
|
-
}
|
|
358
|
-
return lines.join('\n');
|
|
359
|
-
}
|
|
360
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
361
|
-
return `**${value.message}**` + (value.output ? `\n\`\`\`\n${value.output}\n\`\`\`` : '');
|
|
362
|
-
}
|
|
363
|
-
// 4.1 Repo View 概览卡片
|
|
364
|
-
if (args?.action === 'view' && value.nameWithOwner) {
|
|
365
|
-
const link = value.url ? `[${value.nameWithOwner}](${value.url})` : `**${value.nameWithOwner}**`;
|
|
366
|
-
const stars = value.stargazerCount ?? value.stars ?? 0;
|
|
367
|
-
const forks = value.forkCount ?? value.forks ?? 0;
|
|
368
|
-
const branch = value.defaultBranchRef?.name || value.defaultBranch || 'main';
|
|
369
|
-
const lines = [
|
|
370
|
-
`### 📦 ${link}`,
|
|
371
|
-
`> ⭐ **Stars**: ${stars} | 🍴 **Forks**: ${forks} | ⎇ **默认分支**: \`${branch}\``,
|
|
372
|
-
value.description ? `\n${value.description}\n` : '',
|
|
373
|
-
];
|
|
374
|
-
if (value.licenseInfo?.name || value.licenseInfo?.key) {
|
|
375
|
-
lines.push(`- **开源协议**: \`${value.licenseInfo.name || value.licenseInfo.key}\``);
|
|
376
|
-
}
|
|
377
|
-
if (Array.isArray(value.repositoryTopics) && value.repositoryTopics.length > 0) {
|
|
378
|
-
lines.push(`- **仓库标签 (Topics)**: ${value.repositoryTopics.map((t) => `\`${t.name || t}\``).join(' ')}`);
|
|
379
|
-
}
|
|
380
|
-
return lines.filter(Boolean).join('\n');
|
|
381
|
-
}
|
|
382
|
-
// 4.2 Repo Search 仓库搜索列表
|
|
383
|
-
if (Array.isArray(value.items) && args?.action === 'search_repos') {
|
|
384
|
-
if (value.items.length === 0)
|
|
385
|
-
return '未找到匹配的仓库。';
|
|
386
|
-
const rows = value.items.map((r) => {
|
|
387
|
-
const name = r.fullName ? `[${r.fullName}](https://github.com/${r.fullName})` : '-';
|
|
388
|
-
const stars = r.stargazersCount ?? '-';
|
|
389
|
-
const desc = sanitizeCell(r.description, 45);
|
|
390
|
-
const date = r.updatedAt ? r.updatedAt.slice(0, 10) : '-';
|
|
391
|
-
return `| ${name} | ⭐ ${stars} | ${desc} | ${date} |`;
|
|
392
|
-
});
|
|
393
|
-
return [
|
|
394
|
-
`**仓库检索结果 (${value.items.length} 个):**\n`,
|
|
395
|
-
'| 仓库全名 | Stars | 描述 | 更新日期 |',
|
|
396
|
-
'| :--- | :--- | :--- | :--- |',
|
|
397
|
-
...rows,
|
|
398
|
-
].join('\n');
|
|
399
|
-
}
|
|
400
|
-
// 4.3 Code Search 代码搜索列表
|
|
401
|
-
if (Array.isArray(value.items) && args?.action === 'search_code') {
|
|
402
|
-
if (value.items.length === 0)
|
|
403
|
-
return '未找到匹配的代码片段。';
|
|
404
|
-
const rows = value.items.map((c) => {
|
|
405
|
-
const repo = c.repository?.fullName || '-';
|
|
406
|
-
const path = sanitizeCell(c.path, 50);
|
|
407
|
-
return `| \`${path}\` | ${repo} |`;
|
|
408
|
-
});
|
|
409
|
-
return [
|
|
410
|
-
`**代码检索结果 (${value.items.length} 处匹配):**\n`,
|
|
411
|
-
'| 文件路径 | 所属仓库 |',
|
|
412
|
-
'| :--- | :--- |',
|
|
413
|
-
...rows,
|
|
414
|
-
].join('\n');
|
|
415
|
-
}
|
|
416
|
-
// 4.4 Issue/PR 搜索列表(search_issues / search_prs 共用,字段同构)
|
|
417
|
-
if (Array.isArray(value.items) && (args?.action === 'search_issues' || args?.action === 'search_prs')) {
|
|
418
|
-
if (value.items.length === 0)
|
|
419
|
-
return '未找到匹配的结果。';
|
|
420
|
-
const kind = args.action === 'search_prs' ? 'PR' : 'Issue';
|
|
421
|
-
const rows = value.items.map((it) => {
|
|
422
|
-
const num = it.number ?? '-';
|
|
423
|
-
const repo = it.repository?.nameWithOwner || it.repository?.fullName || '-';
|
|
424
|
-
const link = it.url ? `[#${num}](${it.url})` : `#${num}`;
|
|
425
|
-
const badge = formatStateBadge(it.state, it.isDraft);
|
|
426
|
-
const author = it.author?.login || '-';
|
|
427
|
-
const date = it.updatedAt ? String(it.updatedAt).slice(0, 10) : '-';
|
|
428
|
-
return `| ${link} | ${sanitizeCell(it.title, 45)} | ${badge} | ${repo} | ${author} | ${date} |`;
|
|
429
|
-
});
|
|
430
|
-
return [
|
|
431
|
-
`**${kind} 检索结果 (${value.items.length} 条):**\n`,
|
|
432
|
-
'| 编号 | 标题 | 状态 | 仓库 | 作者 | 更新日期 |',
|
|
433
|
-
'| :--- | :--- | :--- | :--- | :--- | :--- |',
|
|
434
|
-
...rows,
|
|
435
|
-
].join('\n');
|
|
436
|
-
}
|
|
437
|
-
// 4.5 Commit 搜索列表(嵌套 commit.commit.message 取首行)
|
|
438
|
-
if (Array.isArray(value.items) && args?.action === 'search_commits') {
|
|
439
|
-
if (value.items.length === 0)
|
|
440
|
-
return '未找到匹配的提交。';
|
|
441
|
-
const rows = value.items.map((c) => {
|
|
442
|
-
const sha = `\`${String(c.sha || '').slice(0, 7)}\``;
|
|
443
|
-
const msg = sanitizeCell(String(c.commit?.message || '').split('\n')[0], 50);
|
|
444
|
-
const author = c.commit?.author?.name || c.author?.login || '-';
|
|
445
|
-
const repo = c.repository?.fullName || '-';
|
|
446
|
-
return `| ${sha} | ${msg} | ${author} | ${repo} |`;
|
|
447
|
-
});
|
|
448
|
-
return [
|
|
449
|
-
`**提交检索结果 (${value.items.length} 条):**\n`,
|
|
450
|
-
'| SHA | 提交信息 | 作者 | 仓库 |',
|
|
451
|
-
'| :--- | :--- | :--- | :--- |',
|
|
452
|
-
...rows,
|
|
453
|
-
].join('\n');
|
|
454
|
-
}
|
|
455
|
-
// 4.6 目录清单(read_dir:dir 置顶 + size 人性化;mode 八进制是 Git 内部语义不展示)
|
|
456
|
-
if (args?.action === 'read_dir' && Array.isArray(value.items)) {
|
|
457
|
-
if (value.items.length === 0)
|
|
458
|
-
return `**${value.path || '/'}** 为空目录。` + appendDegradedNote(value);
|
|
459
|
-
const sorted = [...value.items].sort((a, b) => (a.type === b.type ? String(a.name).localeCompare(String(b.name)) : a.type === 'dir' ? -1 : 1));
|
|
460
|
-
const rows = sorted.map((e) => {
|
|
461
|
-
const icon = e.type === 'dir' ? '📁' : '📄';
|
|
462
|
-
const size = e.type === 'dir' ? '-' : (typeof e.size === 'number' ? (e.size > 1024 ? `${(e.size / 1024).toFixed(1)}KB` : `${e.size}B`) : '-');
|
|
463
|
-
return `| ${icon} \`${sanitizeCell(e.name, 60)}\` | ${size} |`;
|
|
464
|
-
});
|
|
465
|
-
return [
|
|
466
|
-
`**目录 ${value.path || '/'}(${value.items.length} 项):**\n`,
|
|
467
|
-
'| 名称 | 大小 |',
|
|
468
|
-
'| :--- | :--- |',
|
|
469
|
-
...rows,
|
|
470
|
-
appendDegradedNote(value),
|
|
471
|
-
].filter((l) => l !== '').join('\n');
|
|
472
|
-
}
|
|
473
|
-
// 4.7 文件内容(read_file:代码块 + 元信息行)
|
|
474
|
-
if (args?.action === 'read_file' && typeof value.content === 'string') {
|
|
475
|
-
const ext = (value.path || '').split('.').pop() || '';
|
|
476
|
-
const size = typeof value.size === 'number' ? (value.size > 1024 ? `${(value.size / 1024).toFixed(1)}KB` : `${value.size}B`) : '-';
|
|
477
|
-
return [
|
|
478
|
-
`**📄 \`${value.path}\`** (${size}${value.ref ? ` @ ${value.ref}` : ''})\n`,
|
|
479
|
-
'```' + ext,
|
|
480
|
-
value.content,
|
|
481
|
-
'```',
|
|
482
|
-
appendDegradedNote(value),
|
|
483
|
-
].filter((l) => l !== '').join('\n');
|
|
484
|
-
}
|
|
485
|
-
// 兜底降级
|
|
486
|
-
return JSON.stringify(value, null, 2);
|
|
487
|
-
}
|
|
488
|
-
// -------------------------------------------------------------
|
|
489
|
-
// 5. Release 渲染器
|
|
490
|
-
// -------------------------------------------------------------
|
|
491
|
-
export function formatReleaseBadge(isDraft, isPrerelease) {
|
|
492
|
-
if (isDraft)
|
|
493
|
-
return '⚪ DRAFT';
|
|
494
|
-
if (isPrerelease)
|
|
495
|
-
return '🍼 PRE';
|
|
496
|
-
return '✅ STABLE';
|
|
497
|
-
}
|
|
498
|
-
export function renderReleaseMarkdown(args, value) {
|
|
499
|
-
if (!value)
|
|
500
|
-
return '无返回内容';
|
|
501
|
-
if (value.status === 'AWAITING_CONFIRMATION') {
|
|
502
|
-
return [
|
|
503
|
-
`> ### ${value.warning || '⚠️ 高危操作拦截警告'}`,
|
|
504
|
-
`> - **影响评估**: ${value.impact || '该操作将改变远端仓库状态。'}`,
|
|
505
|
-
`> - **确认指引**: ${value.requiredAction || '如确认继续,请向用户核实并在参数中附加 `confirm: true` 重新调用。'}`,
|
|
506
|
-
].join('\n');
|
|
507
|
-
}
|
|
508
|
-
if (typeof value.result === 'string')
|
|
509
|
-
return value.result;
|
|
510
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
511
|
-
const extra = value.detail || value.output;
|
|
512
|
-
return `**${value.message}**` + (value.url ? `\n🔗 链接: ${value.url}` : '') + (extra ? `\n\`\`\`\n${extra}\n\`\`\`` : '');
|
|
513
|
-
}
|
|
514
|
-
// 5.1 Release 列表
|
|
515
|
-
if (Array.isArray(value.items) && args?.action === 'list') {
|
|
516
|
-
const list = value.items.filter(Boolean);
|
|
517
|
-
if (list.length === 0)
|
|
518
|
-
return '📭 当前仓库暂无任何 Release。';
|
|
519
|
-
const rows = list.map((r) => {
|
|
520
|
-
const tag = r.tagName ? `\`${r.tagName}\`` : '-';
|
|
521
|
-
const name = sanitizeCell(r.name || r.tagName, 40);
|
|
522
|
-
const badge = formatReleaseBadge(r.isDraft, r.isPrerelease);
|
|
523
|
-
const date = (r.publishedAt || r.createdAt || '').slice(0, 10) || '-';
|
|
524
|
-
return `| ${tag} | ${badge} | ${name} | ${date} |`;
|
|
525
|
-
});
|
|
526
|
-
return [
|
|
527
|
-
`**最近 ${list.length} 个 Release:**\n`,
|
|
528
|
-
'| Tag | 类型 | 名称 | 发布日期 |',
|
|
529
|
-
'| :--- | :--- | :--- | :--- |',
|
|
530
|
-
...rows,
|
|
531
|
-
].join('\n');
|
|
532
|
-
}
|
|
533
|
-
// 5.2 Release 详情卡片
|
|
534
|
-
if (args?.action === 'view' && value.tagName) {
|
|
535
|
-
const badge = formatReleaseBadge(value.isDraft, value.isPrerelease);
|
|
536
|
-
const lines = [
|
|
537
|
-
`### 🏷️ Release \`${value.tagName}\` ${badge}`,
|
|
538
|
-
];
|
|
539
|
-
// 元信息压缩成一段(硬换行分隔),避免逐行 filter 空串把段落分隔也滤掉。
|
|
540
|
-
// Markdown 的列表/段落渲染依赖空行:若标题、资产列表、正文之间没有空行,
|
|
541
|
-
// 列表语法会失效并连成一段——所以这里改为「分段数组 + 空行 join」。
|
|
542
|
-
const meta = [];
|
|
543
|
-
if (value.name)
|
|
544
|
-
meta.push(`**${value.name}**`);
|
|
545
|
-
if (value.url)
|
|
546
|
-
meta.push(`🔗 ${value.url}`);
|
|
547
|
-
if (value.publishedAt)
|
|
548
|
-
meta.push(`📅 发布于 ${value.publishedAt.slice(0, 10)}`);
|
|
549
|
-
if (meta.length > 0)
|
|
550
|
-
lines.push(meta.join(' \n'));
|
|
551
|
-
if (Array.isArray(value.assets) && value.assets.length > 0) {
|
|
552
|
-
const assetLines = value.assets.map((a) => {
|
|
553
|
-
const size = typeof a.size === 'number' ? ` (${(a.size / 1024).toFixed(1)} KB)` : '';
|
|
554
|
-
return `- \`${a.name || '-'}\`${size}`;
|
|
555
|
-
});
|
|
556
|
-
lines.push(`**📎 附属资产 (${value.assets.length}):**\n${assetLines.join('\n')}`);
|
|
557
|
-
}
|
|
558
|
-
if (value.body) {
|
|
559
|
-
// 发版说明可能非常长,只保留前 600 字符做快速预览,避免单次调用撑爆上下文
|
|
560
|
-
const preview = value.body.length > 600 ? value.body.slice(0, 600) + '\n…(已截断,完整内容见 Release 页面)' : value.body;
|
|
561
|
-
lines.push(`**📝 发版说明摘要:**\n\n${preview}`);
|
|
562
|
-
}
|
|
563
|
-
return lines.join('\n\n');
|
|
564
|
-
}
|
|
565
|
-
// 兜底降级
|
|
566
|
-
return JSON.stringify(value, null, 2);
|
|
567
|
-
}
|
|
568
|
-
// -------------------------------------------------------------
|
|
569
|
-
// 6. Skill 渲染器
|
|
570
|
-
// -------------------------------------------------------------
|
|
571
|
-
export function renderSkillMarkdown(args, value) {
|
|
572
|
-
if (!value)
|
|
573
|
-
return '无返回内容';
|
|
574
|
-
if (value.status === 'AWAITING_CONFIRMATION') {
|
|
575
|
-
return [
|
|
576
|
-
`> ### ${value.warning || '⚠️ 操作确认拦截'}`,
|
|
577
|
-
`> - **影响评估**: ${value.impact || ''}`,
|
|
578
|
-
`> - **确认指引**: ${value.requiredAction || '如确认继续,请在参数中附加 `confirm: true` 重新调用。'}`,
|
|
579
|
-
].join('\n');
|
|
580
|
-
}
|
|
581
|
-
if (typeof value.result === 'string')
|
|
582
|
-
return value.result;
|
|
583
|
-
if (typeof value.message === 'string' && !value.items) {
|
|
584
|
-
const extra = value.detail || value.output;
|
|
585
|
-
return `**${value.message}**` + (extra ? `\n\`\`\`\n${extra}\n\`\`\`` : '');
|
|
586
|
-
}
|
|
587
|
-
// 6.1 Skill 检索列表
|
|
588
|
-
if (Array.isArray(value.items) && args?.action === 'search') {
|
|
589
|
-
const list = value.items.filter(Boolean);
|
|
590
|
-
if (list.length === 0)
|
|
591
|
-
return '📭 未检索到匹配的 Agent Skill。';
|
|
592
|
-
const rows = list.map((s) => {
|
|
593
|
-
const name = s.skillName ? `\`${s.skillName}\`` : '-';
|
|
594
|
-
const repo = s.repo ? `[${s.repo}](https://github.com/${s.repo})` : '-';
|
|
595
|
-
const stars = typeof s.stars === 'number' ? `⭐ ${s.stars}` : '-';
|
|
596
|
-
const desc = sanitizeCell(s.description, 50);
|
|
597
|
-
return `| ${name} | ${repo} | ${stars} | ${desc} |`;
|
|
598
|
-
});
|
|
599
|
-
return [
|
|
600
|
-
`**Skills 检索结果 (${list.length} 个):**\n`,
|
|
601
|
-
'| Skill | 仓库 | Stars | 描述 |',
|
|
602
|
-
'| :--- | :--- | :--- | :--- |',
|
|
603
|
-
...rows,
|
|
604
|
-
].join('\n');
|
|
605
|
-
}
|
|
606
|
-
// 6.2 已安装 Skills 列表
|
|
607
|
-
if (Array.isArray(value.items) && args?.action === 'list') {
|
|
608
|
-
const list = value.items.filter(Boolean);
|
|
609
|
-
if (list.length === 0)
|
|
610
|
-
return '📭 当前环境尚未安装任何 Agent Skill。';
|
|
611
|
-
const rows = list.map((s) => {
|
|
612
|
-
const name = s.skillName ? `\`${s.skillName}\`` : '-';
|
|
613
|
-
const ver = s.version ? String(s.version) : '-';
|
|
614
|
-
const scope = s.scope ? String(s.scope) : '-';
|
|
615
|
-
const source = s.sourceURL ? `[来源](${s.sourceURL})` : (s.path ? `\`${sanitizeCell(s.path, 40)}\`` : '-');
|
|
616
|
-
return `| ${name} | ${ver} | ${scope} | ${source} |`;
|
|
617
|
-
});
|
|
618
|
-
return [
|
|
619
|
-
`**已安装 ${list.length} 个 Agent Skill:**\n`,
|
|
620
|
-
'| Skill | 版本 | 范围 | 来源 |',
|
|
621
|
-
'| :--- | :--- | :--- | :--- |',
|
|
622
|
-
...rows,
|
|
623
|
-
].join('\n');
|
|
624
|
-
}
|
|
625
|
-
// 兜底降级
|
|
626
|
-
return JSON.stringify(value, null, 2);
|
|
627
|
-
}
|
|
7
|
+
export * from './common.js';
|
|
8
|
+
export * from './pr.js';
|
|
9
|
+
export * from './issue.js';
|
|
10
|
+
export * from './run.js';
|
|
11
|
+
export * from './repo.js';
|
|
12
|
+
export * from './release.js';
|
|
13
|
+
export * from './skill.js';
|
|
14
|
+
export * from './label.js';
|
|
15
|
+
export * from './ruleset.js';
|
|
16
|
+
export * from './cache.js';
|
|
17
|
+
export * from './gist.js';
|
|
18
|
+
export * from './status.js';
|
|
19
|
+
export * from './agent-task.js';
|
|
20
|
+
export * from './discussion.js';
|
|
21
|
+
export * from './project.js';
|
|
22
|
+
export * from './codespace.js';
|