@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.
- package/CHANGELOG.md +115 -0
- package/README.md +16 -17
- package/adapters/{github.js → github/index.js} +6 -6
- package/adapters/{github.ts → github/index.ts} +9 -9
- package/agents/github/agent.json +20 -0
- package/agents/github/boundaries.md +3 -0
- package/agents/github/conventions.md +3 -0
- package/agents/github/skills/github-account/SKILL.md +20 -0
- package/{lib/github-tool-handlers.js → agents/github/skills/github-account/handlers.js} +2 -100
- package/{src/github-tool-handlers.ts → agents/github/skills/github-account/handlers.ts} +2 -118
- package/agents/github/skills/github-account/tools/bind/index.js +13 -0
- package/{agent/tools/bind.ts → agents/github/skills/github-account/tools/bind/index.ts} +3 -3
- package/agents/github/skills/github-account/tools/install/index.js +13 -0
- package/{agent/tools/install.ts → agents/github/skills/github-account/tools/install/index.ts} +2 -2
- package/agents/github/skills/github-account/tools/unbind/index.js +13 -0
- package/{agent/tools/unbind.ts → agents/github/skills/github-account/tools/unbind/index.ts} +3 -3
- package/agents/github/skills/github-account/tools/whoami/index.js +13 -0
- package/{agent/tools/whoami.ts → agents/github/skills/github-account/tools/whoami/index.ts} +3 -3
- package/agents/github/skills/github-cli/SKILL.md +47 -0
- package/agents/github/skills/github-repository/SKILL.md +21 -0
- package/{lib/github-bot-handlers.js → agents/github/skills/github-repository/handlers.js} +2 -1
- package/{src/github-bot-handlers.ts → agents/github/skills/github-repository/handlers.ts} +3 -3
- package/agents/github/skills/github-repository/tools/create_pr/index.js +20 -0
- package/{agent/tools/create_pr.ts → agents/github/skills/github-repository/tools/create_pr/index.ts} +4 -4
- package/agents/github/skills/github-repository/tools/patch_file/index.js +19 -0
- package/{agent/tools/patch_file.ts → agents/github/skills/github-repository/tools/patch_file/index.ts} +3 -3
- package/agents/github/skills/github-repository/tools/prepare_workspace/index.js +15 -0
- package/{agent/tools/prepare_workspace.ts → agents/github/skills/github-repository/tools/prepare_workspace/index.ts} +3 -3
- package/agents/github/skills/github-repository/tools/push_branch/index.js +18 -0
- package/{agent/tools/push_branch.ts → agents/github/skills/github-repository/tools/push_branch/index.ts} +4 -4
- package/agents/github/skills/github-subscriptions/SKILL.md +20 -0
- package/agents/github/skills/github-subscriptions/handlers.js +101 -0
- package/agents/github/skills/github-subscriptions/handlers.ts +119 -0
- package/agents/github/skills/github-subscriptions/tools/star/index.js +16 -0
- package/{agent/tools/star.ts → agents/github/skills/github-subscriptions/tools/star/index.ts} +3 -3
- package/agents/github/skills/github-subscriptions/tools/subscribe/index.js +16 -0
- package/{agent/tools/subscribe.ts → agents/github/skills/github-subscriptions/tools/subscribe/index.ts} +3 -3
- package/agents/github/skills/github-subscriptions/tools/subscriptions/index.js +13 -0
- package/{agent/tools/subscriptions.ts → agents/github/skills/github-subscriptions/tools/subscriptions/index.ts} +3 -3
- package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.js +15 -0
- package/{agent/tools/unsubscribe.ts → agents/github/skills/github-subscriptions/tools/unsubscribe/index.ts} +3 -3
- package/agents/github/system.md +3 -0
- package/commands/{endpoint/add/[id].js → github/endpoint/add/[id]/index.js} +1 -1
- package/commands/github/endpoint/add/[id]/index.ts +3 -0
- package/{lib/github-endpoint-commands.js → commands/github/endpoint/definition.js} +6 -5
- package/{src/github-endpoint-commands.ts → commands/github/endpoint/definition.ts} +5 -5
- package/commands/{endpoint/list.js → github/endpoint/list/index.js} +1 -1
- package/commands/github/endpoint/list/index.ts +3 -0
- package/commands/{endpoint/remove/[id].js → github/endpoint/remove/[id]/index.js} +1 -1
- package/commands/github/endpoint/remove/[id]/index.ts +3 -0
- package/lib/client.js +1 -4
- package/lib/endpoint.js +4 -4
- package/lib/github-runtime-state.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/oauth-users.d.ts +1 -1
- package/lib/oauth-users.js +1 -1
- package/lib/protocol.d.ts +11 -33
- package/lib/protocol.js +19 -30
- package/lib/types.d.ts +0 -23
- package/lib/types.js +2 -3
- package/package.json +35 -19
- package/plugin.js +3 -3
- package/prompt-sections/platform/index.js +16 -0
- package/schema.json +33 -26
- package/src/client.ts +1 -4
- package/src/endpoint.ts +4 -4
- package/src/github-runtime-state.ts +1 -1
- package/src/index.ts +1 -1
- package/src/oauth-users.ts +1 -1
- package/src/protocol.ts +26 -79
- package/src/types.ts +0 -28
- package/agent/skills/github.md +0 -283
- package/commands/endpoint/add/[id].ts +0 -3
- package/commands/endpoint/list.ts +0 -3
- package/commands/endpoint/remove/[id].ts +0 -3
- package/lib/github-bot-handlers.d.ts +0 -27
- package/lib/github-endpoint-commands.d.ts +0 -1
- package/lib/github-tool-handlers.d.ts +0 -18
- /package/{agent/prompt-sections/platform.ts → prompt-sections/platform/index.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubUnbind } from '../../
|
|
3
|
+
import { executeGithubUnbind } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{}>({
|
|
6
6
|
description: '解除你绑定的 GitHub 账号',
|
|
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
|
|
|
8
8
|
inputSchema: z.object({}),
|
|
9
9
|
tags: ['github'],
|
|
10
10
|
async execute(input, context) {
|
|
11
|
-
return executeGithubUnbind({}, context.$client
|
|
11
|
+
return executeGithubUnbind({}, context.$client);
|
|
12
12
|
},
|
|
13
13
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubWhoami } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '查看你绑定的 GitHub 账号信息',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({}),
|
|
9
|
+
tags: ['github'],
|
|
10
|
+
async execute(input, context) {
|
|
11
|
+
return executeGithubWhoami({}, context.$client);
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubWhoami } from '../../
|
|
3
|
+
import { executeGithubWhoami } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{}>({
|
|
6
6
|
description: '查看你绑定的 GitHub 账号信息',
|
|
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
|
|
|
8
8
|
inputSchema: z.object({}),
|
|
9
9
|
tags: ['github'],
|
|
10
10
|
async execute(input, context) {
|
|
11
|
-
return executeGithubWhoami({}, context.$client
|
|
11
|
+
return executeGithubWhoami({}, context.$client);
|
|
12
12
|
},
|
|
13
13
|
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-cli
|
|
3
|
+
platforms:
|
|
4
|
+
- github
|
|
5
|
+
description: 使用 gh CLI 处理内置 GitHub Tool 未覆盖的 Issue、PR、Release、Workflow、搜索和 API 操作。
|
|
6
|
+
keywords:
|
|
7
|
+
- "github"
|
|
8
|
+
- "gh"
|
|
9
|
+
- "issue"
|
|
10
|
+
- "pull request"
|
|
11
|
+
- "release"
|
|
12
|
+
- "workflow"
|
|
13
|
+
- "search"
|
|
14
|
+
- "api"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# GitHub CLI
|
|
18
|
+
|
|
19
|
+
只有内置 GitHub Skill 不覆盖任务时才加载本 Skill。当前进程通过 `GH_TOKEN` 提供 gh CLI 身份;先执行 `gh auth status` 核对身份和权限。仓库参数统一使用 `owner/repo`。
|
|
20
|
+
|
|
21
|
+
## 常用命令
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gh issue list -R owner/repo --state open --limit 20 --json number,title,state,labels,assignees
|
|
25
|
+
gh issue view 123 -R owner/repo --json number,title,body,state,labels,assignees
|
|
26
|
+
gh issue create -R owner/repo --title "标题" --body "正文"
|
|
27
|
+
gh pr list -R owner/repo --state open --limit 20 --json number,title,state,author,mergeable
|
|
28
|
+
gh pr view 456 -R owner/repo --json number,title,body,state,author,mergeable,reviewDecision
|
|
29
|
+
gh pr checks 456 -R owner/repo
|
|
30
|
+
gh pr diff 456 -R owner/repo
|
|
31
|
+
gh release list -R owner/repo --limit 10
|
|
32
|
+
gh run list -R owner/repo --limit 10 --json databaseId,displayTitle,status,conclusion
|
|
33
|
+
gh workflow list -R owner/repo
|
|
34
|
+
gh search issues "关键词" --repo owner/repo --limit 10 --json number,title,state
|
|
35
|
+
gh search code "函数名" --repo owner/repo --limit 10 --json path,textMatches
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
需要其他 API 时使用 `gh api` 或 `gh api graphql`。任何创建、修改、合并、关闭、重跑或发布操作都属于外部副作用,必须遵守执行工具的审批策略。
|
|
39
|
+
|
|
40
|
+
## 输出控制
|
|
41
|
+
|
|
42
|
+
- 列表必须使用 `--limit`,默认不超过 20 条。
|
|
43
|
+
- 使用 `--json` 与 `--jq` 只保留任务需要的字段。
|
|
44
|
+
- 正文最多读取 2000 字符,diff 最多读取 200 行。
|
|
45
|
+
- 单次调用输出应小于 15KB。
|
|
46
|
+
|
|
47
|
+
遇到 401 检查身份与 Token;404 同时检查资源存在性和权限;422 检查必填参数。不要把命令失败推断成资源不存在。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-repository
|
|
3
|
+
platforms:
|
|
4
|
+
- github
|
|
5
|
+
description: GitHub 工作区准备、文件补丁、分支推送和 PR 创建能力。
|
|
6
|
+
keywords:
|
|
7
|
+
- "github"
|
|
8
|
+
- "repository"
|
|
9
|
+
- "patch"
|
|
10
|
+
- "branch"
|
|
11
|
+
- "pull request"
|
|
12
|
+
tools:
|
|
13
|
+
- "prepare_workspace"
|
|
14
|
+
- "patch_file"
|
|
15
|
+
- "create_pr"
|
|
16
|
+
- "push_branch"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# github-repository
|
|
20
|
+
|
|
21
|
+
这些 Tool 使用 GitHub App Installation Token,以 Bot 身份写仓库。按 `prepare_workspace`、`patch_file`、`push_branch`、`create_pr` 的顺序操作,每一步使用上一步返回的稳定引用。Issue 线程创建新分支后开 PR;PR 线程推送到现有 head 分支。不要改用人身份 PAT 的 MCP 工具完成 Bot 写入。推送和创建 PR 前复核仓库、base/head 分支与变更内容,并遵守 HITL 审批。
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
1
2
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
2
|
-
import { parseMessageChannel, resolveWorkspaceBranch,
|
|
3
|
+
import { formatChannelContext, parseMessageChannel, resolveWorkspaceBranch, } from "../../../../lib/github-channel-context.js";
|
|
3
4
|
function requireBotGh(client) {
|
|
4
5
|
const gh = client.api;
|
|
5
6
|
if (!gh?.isAppAuth) {
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Message } from 'zhin.js';
|
|
5
5
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
6
|
-
import type { GithubClient } from './client.js';
|
|
7
6
|
import {
|
|
7
|
+
formatChannelContext,
|
|
8
8
|
parseMessageChannel,
|
|
9
9
|
resolveWorkspaceBranch,
|
|
10
|
-
|
|
11
|
-
} from '
|
|
10
|
+
} from '../../../../src/github-channel-context.js';
|
|
11
|
+
import type { GithubClient } from '../../../../src/client.js';
|
|
12
12
|
|
|
13
13
|
function requireBotGh(client: GithubClient) {
|
|
14
14
|
const gh = client.api;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubCreatePr } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '以 GitHub App Bot 身份创建 Pull Request(需 HITL 确认;Issue 场景常用)',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
repo: z.string().optional().describe('owner/repo'),
|
|
10
|
+
title: z.string().describe('PR 标题'),
|
|
11
|
+
body: z.string().optional().describe('PR 正文'),
|
|
12
|
+
head: z.string().optional().describe('head 分支,缺省为工作区分支'),
|
|
13
|
+
base: z.string().optional().describe('base 分支,缺省为仓库默认分支'),
|
|
14
|
+
}),
|
|
15
|
+
tags: ['github'],
|
|
16
|
+
requiresApproval: 'always',
|
|
17
|
+
async execute(input, context) {
|
|
18
|
+
return executeGithubCreatePr(input, context.$client);
|
|
19
|
+
},
|
|
20
|
+
});
|
package/{agent/tools/create_pr.ts → agents/github/skills/github-repository/tools/create_pr/index.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubCreatePr } from '../../
|
|
3
|
+
import { executeGithubCreatePr } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ repo?: string; title: string; body?: string; head?: string; base?: string }>({
|
|
6
6
|
description: '以 GitHub App Bot 身份创建 Pull Request(需 HITL 确认;Issue 场景常用)',
|
|
@@ -13,8 +13,8 @@ export default defineAgentTool<{ repo?: string; title: string; body?: string; he
|
|
|
13
13
|
base: z.string().optional().describe('base 分支,缺省为仓库默认分支'),
|
|
14
14
|
}),
|
|
15
15
|
tags: ['github'],
|
|
16
|
-
|
|
16
|
+
requiresApproval: 'always',
|
|
17
17
|
async execute(input, context) {
|
|
18
|
-
return executeGithubCreatePr(input, context.$client
|
|
18
|
+
return executeGithubCreatePr(input, context.$client);
|
|
19
19
|
},
|
|
20
20
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubPatchFile } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '通过 Contents API 单文件更新(小改;Bot Installation Token 身份)',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
repo: z.string().optional().describe('owner/repo'),
|
|
10
|
+
path: z.string().describe('仓库内文件路径'),
|
|
11
|
+
content: z.string().describe('新文件内容'),
|
|
12
|
+
message: z.string().describe('commit message'),
|
|
13
|
+
branch: z.string().optional().describe('目标分支,缺省从 Issue/PR 上下文推断'),
|
|
14
|
+
}),
|
|
15
|
+
tags: ['github'],
|
|
16
|
+
async execute(input, context) {
|
|
17
|
+
return executeGithubPatchFile(input, context.$client);
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubPatchFile } from '../../
|
|
3
|
+
import { executeGithubPatchFile } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ repo?: string; path: string; content: string; message: string; branch?: string }>({
|
|
6
6
|
description: '通过 Contents API 单文件更新(小改;Bot Installation Token 身份)',
|
|
@@ -14,6 +14,6 @@ export default defineAgentTool<{ repo?: string; path: string; content: string; m
|
|
|
14
14
|
}),
|
|
15
15
|
tags: ['github'],
|
|
16
16
|
async execute(input, context) {
|
|
17
|
-
return executeGithubPatchFile(input, context.$client
|
|
17
|
+
return executeGithubPatchFile(input, context.$client);
|
|
18
18
|
},
|
|
19
19
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubPrepareWorkspace } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: 'Clone/fetch 托管工作区并 checkout 到 Issue/PR 对应分支(GitHub App Bot 身份)',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
repo: z.string().optional().describe('owner/repo,缺省从当前 Issue/PR 频道推断'),
|
|
10
|
+
}),
|
|
11
|
+
tags: ['github'],
|
|
12
|
+
async execute(input, context) {
|
|
13
|
+
return executeGithubPrepareWorkspace(input, context.$client);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubPrepareWorkspace } from '../../
|
|
3
|
+
import { executeGithubPrepareWorkspace } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ repo?: string }>({
|
|
6
6
|
description: 'Clone/fetch 托管工作区并 checkout 到 Issue/PR 对应分支(GitHub App Bot 身份)',
|
|
@@ -10,6 +10,6 @@ export default defineAgentTool<{ repo?: string }>({
|
|
|
10
10
|
}),
|
|
11
11
|
tags: ['github'],
|
|
12
12
|
async execute(input, context) {
|
|
13
|
-
return executeGithubPrepareWorkspace(input, context.$client
|
|
13
|
+
return executeGithubPrepareWorkspace(input, context.$client);
|
|
14
14
|
},
|
|
15
15
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubPushBranch } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '在托管工作区 git commit 并 push 到远程分支(需 HITL 确认;Bot 身份)',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
repo: z.string().optional().describe('owner/repo'),
|
|
10
|
+
branch: z.string().optional().describe('分支名,缺省从上下文推断'),
|
|
11
|
+
message: z.string().describe('commit message'),
|
|
12
|
+
}),
|
|
13
|
+
tags: ['github'],
|
|
14
|
+
requiresApproval: 'always',
|
|
15
|
+
async execute(input, context) {
|
|
16
|
+
return executeGithubPushBranch(input, context.$client);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubPushBranch } from '../../
|
|
3
|
+
import { executeGithubPushBranch } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ repo?: string; branch?: string; message: string }>({
|
|
6
6
|
description: '在托管工作区 git commit 并 push 到远程分支(需 HITL 确认;Bot 身份)',
|
|
@@ -11,8 +11,8 @@ export default defineAgentTool<{ repo?: string; branch?: string; message: string
|
|
|
11
11
|
message: z.string().describe('commit message'),
|
|
12
12
|
}),
|
|
13
13
|
tags: ['github'],
|
|
14
|
-
|
|
14
|
+
requiresApproval: 'always',
|
|
15
15
|
async execute(input, context) {
|
|
16
|
-
return executeGithubPushBranch(input, context.$client
|
|
16
|
+
return executeGithubPushBranch(input, context.$client);
|
|
17
17
|
},
|
|
18
18
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-subscriptions
|
|
3
|
+
platforms:
|
|
4
|
+
- github
|
|
5
|
+
description: GitHub Star 与仓库订阅管理能力。
|
|
6
|
+
keywords:
|
|
7
|
+
- "github"
|
|
8
|
+
- "star"
|
|
9
|
+
- "订阅"
|
|
10
|
+
- "通知"
|
|
11
|
+
tools:
|
|
12
|
+
- "star"
|
|
13
|
+
- "subscribe"
|
|
14
|
+
- "subscriptions"
|
|
15
|
+
- "unsubscribe"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# github-subscriptions
|
|
19
|
+
|
|
20
|
+
先用 `subscriptions` 查询当前聊天通道的已有订阅,再执行订阅或取消。Webhook 订阅绑定当前聊天通道,只会向该通道投递事件。`star` 优先使用用户绑定的 OAuth 身份,未绑定时才使用 Endpoint 默认身份;外部写操作遵守审批策略。
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
3
|
+
function subscriptionsModel(client) {
|
|
4
|
+
const db = client.database;
|
|
5
|
+
return db?.models?.get('github_subscriptions');
|
|
6
|
+
}
|
|
7
|
+
export async function executeGithubStar(args, client, commMessage) {
|
|
8
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
9
|
+
const gh = await client.getUserOrDefaultApi(msg?.$adapter, msg?.$sender.id);
|
|
10
|
+
switch (args.action) {
|
|
11
|
+
case 'star': {
|
|
12
|
+
const r = await gh.starRepo(args.repo);
|
|
13
|
+
return r.ok ? `⭐ 已 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
|
|
14
|
+
}
|
|
15
|
+
case 'unstar': {
|
|
16
|
+
const r = await gh.unstarRepo(args.repo);
|
|
17
|
+
return r.ok ? `💔 已取消 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
|
|
18
|
+
}
|
|
19
|
+
case 'check': {
|
|
20
|
+
const starred = await gh.isStarred(args.repo);
|
|
21
|
+
return starred ? `⭐ 已 Star ${args.repo}` : `☆ 尚未 Star ${args.repo}`;
|
|
22
|
+
}
|
|
23
|
+
default:
|
|
24
|
+
return `❌ 未知操作: ${args.action}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function executeGithubSubscribe(args, client, commMessage) {
|
|
28
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
29
|
+
if (!msg?.$adapter || !msg?.$sender.id || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
30
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
31
|
+
}
|
|
32
|
+
const model = subscriptionsModel(client);
|
|
33
|
+
if (!model)
|
|
34
|
+
return '❌ 数据库未就绪';
|
|
35
|
+
const validEvents = ['push', 'issue', 'star', 'fork', 'unstar', 'pull_request'];
|
|
36
|
+
const events = args.events
|
|
37
|
+
? args.events.split(',').map((s) => s.trim()).filter((e) => validEvents.includes(e))
|
|
38
|
+
: validEvents;
|
|
39
|
+
if (!events.length)
|
|
40
|
+
return `❌ 无效的事件类型,可选: ${validEvents.join(', ')}`;
|
|
41
|
+
const [existing] = await model.select().where({
|
|
42
|
+
repo: args.repo,
|
|
43
|
+
target_id: msg.$channel?.id,
|
|
44
|
+
adapter: msg.$adapter,
|
|
45
|
+
endpoint: msg.$endpoint,
|
|
46
|
+
});
|
|
47
|
+
if (existing) {
|
|
48
|
+
await model.update({ events, target_type: msg.$channel?.type || 'private' }).where({ id: existing.id });
|
|
49
|
+
return `✅ 已更新订阅 ${args.repo}\n📡 事件: ${events.join(', ')}`;
|
|
50
|
+
}
|
|
51
|
+
await model.insert({
|
|
52
|
+
id: Date.now(),
|
|
53
|
+
repo: args.repo,
|
|
54
|
+
events,
|
|
55
|
+
target_id: msg.$channel?.id,
|
|
56
|
+
target_type: msg.$channel?.type || 'private',
|
|
57
|
+
adapter: msg.$adapter,
|
|
58
|
+
endpoint: msg.$endpoint,
|
|
59
|
+
});
|
|
60
|
+
return `✅ 已订阅 ${args.repo}\n📡 事件: ${events.join(', ')}\n📌 通知将推送到当前通道`;
|
|
61
|
+
}
|
|
62
|
+
export async function executeGithubUnsubscribe(args, client, commMessage) {
|
|
63
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
64
|
+
if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
65
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
66
|
+
}
|
|
67
|
+
const model = subscriptionsModel(client);
|
|
68
|
+
if (!model)
|
|
69
|
+
return '❌ 数据库未就绪';
|
|
70
|
+
const [existing] = await model.select().where({
|
|
71
|
+
repo: args.repo,
|
|
72
|
+
target_id: msg.$channel?.id,
|
|
73
|
+
adapter: msg.$adapter,
|
|
74
|
+
endpoint: msg.$endpoint,
|
|
75
|
+
});
|
|
76
|
+
if (!existing)
|
|
77
|
+
return `📭 当前通道未订阅 ${args.repo}`;
|
|
78
|
+
await model.delete().where({ id: existing.id });
|
|
79
|
+
return `✅ 已取消订阅 ${args.repo}`;
|
|
80
|
+
}
|
|
81
|
+
export async function executeGithubSubscriptions(_args, client, commMessage) {
|
|
82
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
83
|
+
if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
84
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
85
|
+
}
|
|
86
|
+
const model = subscriptionsModel(client);
|
|
87
|
+
if (!model)
|
|
88
|
+
return '❌ 数据库未就绪';
|
|
89
|
+
const subs = await model.select().where({
|
|
90
|
+
target_id: msg.$channel?.id,
|
|
91
|
+
adapter: msg.$adapter,
|
|
92
|
+
endpoint: msg.$endpoint,
|
|
93
|
+
});
|
|
94
|
+
if (!subs?.length)
|
|
95
|
+
return '📭 当前通道没有任何 GitHub 订阅';
|
|
96
|
+
return `📋 当前通道订阅 (${subs.length}):\n\n` +
|
|
97
|
+
subs.map((s) => {
|
|
98
|
+
const events = Array.isArray(s.events) ? s.events : [];
|
|
99
|
+
return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || '(无事件)'}`;
|
|
100
|
+
}).join('\n\n');
|
|
101
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { Message } from 'zhin.js';
|
|
2
|
+
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
3
|
+
import type { GithubClient } from '../../../../src/client.js';
|
|
4
|
+
import type { EventType } from '../../../../src/types.js';
|
|
5
|
+
|
|
6
|
+
function subscriptionsModel(client: GithubClient) {
|
|
7
|
+
const db = client.database as {
|
|
8
|
+
models?: Map<string, unknown>;
|
|
9
|
+
} | null | undefined;
|
|
10
|
+
return db?.models?.get('github_subscriptions') as {
|
|
11
|
+
select: () => { where: (q: object) => Promise<any[]> };
|
|
12
|
+
insert: (row: object) => Promise<void>;
|
|
13
|
+
update: (row: object) => { where: (q: object) => Promise<void> };
|
|
14
|
+
delete: () => { where: (q: object) => Promise<void> };
|
|
15
|
+
} | undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function executeGithubStar(args: { action: 'star' | 'unstar' | 'check'; repo: string }, client: GithubClient, commMessage?: Message) {
|
|
19
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
20
|
+
const gh = await client.getUserOrDefaultApi(msg?.$adapter, msg?.$sender.id);
|
|
21
|
+
switch (args.action) {
|
|
22
|
+
case 'star': {
|
|
23
|
+
const r = await gh.starRepo(args.repo);
|
|
24
|
+
return r.ok ? `⭐ 已 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
|
|
25
|
+
}
|
|
26
|
+
case 'unstar': {
|
|
27
|
+
const r = await gh.unstarRepo(args.repo);
|
|
28
|
+
return r.ok ? `💔 已取消 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
|
|
29
|
+
}
|
|
30
|
+
case 'check': {
|
|
31
|
+
const starred = await gh.isStarred(args.repo);
|
|
32
|
+
return starred ? `⭐ 已 Star ${args.repo}` : `☆ 尚未 Star ${args.repo}`;
|
|
33
|
+
}
|
|
34
|
+
default:
|
|
35
|
+
return `❌ 未知操作: ${args.action}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function executeGithubSubscribe(args: { repo: string; events?: string }, client: GithubClient, commMessage?: Message) {
|
|
40
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
41
|
+
if (!msg?.$adapter || !msg?.$sender.id || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
42
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const model = subscriptionsModel(client);
|
|
46
|
+
if (!model) return '❌ 数据库未就绪';
|
|
47
|
+
|
|
48
|
+
const validEvents: EventType[] = ['push', 'issue', 'star', 'fork', 'unstar', 'pull_request'];
|
|
49
|
+
const events: EventType[] = args.events
|
|
50
|
+
? args.events.split(',').map((s) => s.trim()).filter((e): e is EventType => validEvents.includes(e as EventType))
|
|
51
|
+
: validEvents;
|
|
52
|
+
if (!events.length) return `❌ 无效的事件类型,可选: ${validEvents.join(', ')}`;
|
|
53
|
+
|
|
54
|
+
const [existing] = await model.select().where({
|
|
55
|
+
repo: args.repo,
|
|
56
|
+
target_id: msg.$channel?.id,
|
|
57
|
+
adapter: msg.$adapter,
|
|
58
|
+
endpoint: msg.$endpoint,
|
|
59
|
+
});
|
|
60
|
+
if (existing) {
|
|
61
|
+
await model.update({ events, target_type: msg.$channel?.type || 'private' }).where({ id: existing.id });
|
|
62
|
+
return `✅ 已更新订阅 ${args.repo}\n📡 事件: ${events.join(', ')}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await model.insert({
|
|
66
|
+
id: Date.now(),
|
|
67
|
+
repo: args.repo,
|
|
68
|
+
events,
|
|
69
|
+
target_id: msg.$channel?.id,
|
|
70
|
+
target_type: msg.$channel?.type || 'private',
|
|
71
|
+
adapter: msg.$adapter,
|
|
72
|
+
endpoint: msg.$endpoint,
|
|
73
|
+
});
|
|
74
|
+
return `✅ 已订阅 ${args.repo}\n📡 事件: ${events.join(', ')}\n📌 通知将推送到当前通道`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function executeGithubUnsubscribe(args: { repo: string }, client: GithubClient, commMessage?: Message) {
|
|
78
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
79
|
+
if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
80
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const model = subscriptionsModel(client);
|
|
84
|
+
if (!model) return '❌ 数据库未就绪';
|
|
85
|
+
|
|
86
|
+
const [existing] = await model.select().where({
|
|
87
|
+
repo: args.repo,
|
|
88
|
+
target_id: msg.$channel?.id,
|
|
89
|
+
adapter: msg.$adapter,
|
|
90
|
+
endpoint: msg.$endpoint,
|
|
91
|
+
});
|
|
92
|
+
if (!existing) return `📭 当前通道未订阅 ${args.repo}`;
|
|
93
|
+
|
|
94
|
+
await model.delete().where({ id: existing.id });
|
|
95
|
+
return `✅ 已取消订阅 ${args.repo}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function executeGithubSubscriptions(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
|
|
99
|
+
const msg = commMessage ?? getCurrentCommMessage();
|
|
100
|
+
if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
|
|
101
|
+
return '❌ 无法获取当前聊天通道信息';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const model = subscriptionsModel(client);
|
|
105
|
+
if (!model) return '❌ 数据库未就绪';
|
|
106
|
+
|
|
107
|
+
const subs = await model.select().where({
|
|
108
|
+
target_id: msg.$channel?.id,
|
|
109
|
+
adapter: msg.$adapter,
|
|
110
|
+
endpoint: msg.$endpoint,
|
|
111
|
+
});
|
|
112
|
+
if (!subs?.length) return '📭 当前通道没有任何 GitHub 订阅';
|
|
113
|
+
|
|
114
|
+
return `📋 当前通道订阅 (${subs.length}):\n\n` +
|
|
115
|
+
subs.map((s: any) => {
|
|
116
|
+
const events = Array.isArray(s.events) ? s.events : [];
|
|
117
|
+
return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || '(无事件)'}`;
|
|
118
|
+
}).join('\n\n');
|
|
119
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubStar } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: 'Star 或取消 Star 一个 GitHub 仓库(使用你绑定的 GitHub 账号,未绑定则用 Endpoint 默认账号)',
|
|
7
|
+
adapter: 'github',
|
|
8
|
+
inputSchema: z.object({
|
|
9
|
+
action: z.enum(['star', 'unstar', 'check']),
|
|
10
|
+
repo: z.string().min(1),
|
|
11
|
+
}),
|
|
12
|
+
tags: ['github'],
|
|
13
|
+
async execute(input, context) {
|
|
14
|
+
return executeGithubStar(input, context.$client);
|
|
15
|
+
},
|
|
16
|
+
});
|
package/{agent/tools/star.ts → agents/github/skills/github-subscriptions/tools/star/index.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubStar } from '../../
|
|
3
|
+
import { executeGithubStar } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ action: 'star' | 'unstar' | 'check'; repo: string }>({
|
|
6
6
|
description: 'Star 或取消 Star 一个 GitHub 仓库(使用你绑定的 GitHub 账号,未绑定则用 Endpoint 默认账号)',
|
|
@@ -11,6 +11,6 @@ export default defineAgentTool<{ action: 'star' | 'unstar' | 'check'; repo: stri
|
|
|
11
11
|
}),
|
|
12
12
|
tags: ['github'],
|
|
13
13
|
async execute(input, context) {
|
|
14
|
-
return executeGithubStar(input, context.$client
|
|
14
|
+
return executeGithubStar(input, context.$client);
|
|
15
15
|
},
|
|
16
16
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubSubscribe } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '订阅 GitHub 仓库的 Webhook 事件,事件将推送到当前聊天通道',
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
repo: z.string().min(1),
|
|
9
|
+
events: z.string().optional(),
|
|
10
|
+
}),
|
|
11
|
+
adapter: 'github',
|
|
12
|
+
tags: ['github'],
|
|
13
|
+
async execute(input, context) {
|
|
14
|
+
return executeGithubSubscribe(input, context.$client);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubSubscribe } from '../../
|
|
3
|
+
import { executeGithubSubscribe } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{ repo: string; events?: string }>({
|
|
6
6
|
description: '订阅 GitHub 仓库的 Webhook 事件,事件将推送到当前聊天通道',
|
|
@@ -11,6 +11,6 @@ export default defineAgentTool<{ repo: string; events?: string }>({
|
|
|
11
11
|
adapter: 'github',
|
|
12
12
|
tags: ['github'],
|
|
13
13
|
async execute(input, context) {
|
|
14
|
-
return executeGithubSubscribe(input, context.$client
|
|
14
|
+
return executeGithubSubscribe(input, context.$client);
|
|
15
15
|
},
|
|
16
16
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { executeGithubSubscriptions } from '../../handlers.js';
|
|
5
|
+
export default defineAgentTool({
|
|
6
|
+
description: '查看当前聊天通道的 GitHub 仓库订阅列表',
|
|
7
|
+
inputSchema: z.object({}),
|
|
8
|
+
adapter: 'github',
|
|
9
|
+
tags: ['github'],
|
|
10
|
+
async execute(input, context) {
|
|
11
|
+
return executeGithubSubscriptions({}, context.$client);
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineAgentTool } from '@zhin.js/
|
|
1
|
+
import { defineAgentTool } from '@zhin.js/tool';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { executeGithubSubscriptions } from '../../
|
|
3
|
+
import { executeGithubSubscriptions } from '../../handlers.js';
|
|
4
4
|
|
|
5
5
|
export default defineAgentTool<{}>({
|
|
6
6
|
description: '查看当前聊天通道的 GitHub 仓库订阅列表',
|
|
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
|
|
|
8
8
|
adapter: 'github',
|
|
9
9
|
tags: ['github'],
|
|
10
10
|
async execute(input, context) {
|
|
11
|
-
return executeGithubSubscriptions({}, context.$client
|
|
11
|
+
return executeGithubSubscriptions({}, context.$client);
|
|
12
12
|
},
|
|
13
13
|
});
|