@zhin.js/adapter-github 1.1.0 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +16 -17
  3. package/adapters/{github.js → github/index.js} +6 -6
  4. package/adapters/{github.ts → github/index.ts} +9 -9
  5. package/agents/github/agent.json +20 -0
  6. package/agents/github/boundaries.md +3 -0
  7. package/agents/github/conventions.md +3 -0
  8. package/agents/github/skills/github-account/SKILL.md +20 -0
  9. package/{lib/github-tool-handlers.js → agents/github/skills/github-account/handlers.js} +2 -100
  10. package/{src/github-tool-handlers.ts → agents/github/skills/github-account/handlers.ts} +2 -118
  11. package/agents/github/skills/github-account/tools/bind/index.js +13 -0
  12. package/{agent/tools/bind.ts → agents/github/skills/github-account/tools/bind/index.ts} +3 -3
  13. package/agents/github/skills/github-account/tools/install/index.js +13 -0
  14. package/{agent/tools/install.ts → agents/github/skills/github-account/tools/install/index.ts} +2 -2
  15. package/agents/github/skills/github-account/tools/unbind/index.js +13 -0
  16. package/{agent/tools/unbind.ts → agents/github/skills/github-account/tools/unbind/index.ts} +3 -3
  17. package/agents/github/skills/github-account/tools/whoami/index.js +13 -0
  18. package/{agent/tools/whoami.ts → agents/github/skills/github-account/tools/whoami/index.ts} +3 -3
  19. package/agents/github/skills/github-cli/SKILL.md +47 -0
  20. package/agents/github/skills/github-repository/SKILL.md +21 -0
  21. package/{lib/github-bot-handlers.js → agents/github/skills/github-repository/handlers.js} +2 -1
  22. package/{src/github-bot-handlers.ts → agents/github/skills/github-repository/handlers.ts} +3 -3
  23. package/agents/github/skills/github-repository/tools/create_pr/index.js +20 -0
  24. package/{agent/tools/create_pr.ts → agents/github/skills/github-repository/tools/create_pr/index.ts} +4 -4
  25. package/agents/github/skills/github-repository/tools/patch_file/index.js +19 -0
  26. package/{agent/tools/patch_file.ts → agents/github/skills/github-repository/tools/patch_file/index.ts} +3 -3
  27. package/agents/github/skills/github-repository/tools/prepare_workspace/index.js +15 -0
  28. package/{agent/tools/prepare_workspace.ts → agents/github/skills/github-repository/tools/prepare_workspace/index.ts} +3 -3
  29. package/agents/github/skills/github-repository/tools/push_branch/index.js +18 -0
  30. package/{agent/tools/push_branch.ts → agents/github/skills/github-repository/tools/push_branch/index.ts} +4 -4
  31. package/agents/github/skills/github-subscriptions/SKILL.md +20 -0
  32. package/agents/github/skills/github-subscriptions/handlers.js +101 -0
  33. package/agents/github/skills/github-subscriptions/handlers.ts +119 -0
  34. package/agents/github/skills/github-subscriptions/tools/star/index.js +16 -0
  35. package/{agent/tools/star.ts → agents/github/skills/github-subscriptions/tools/star/index.ts} +3 -3
  36. package/agents/github/skills/github-subscriptions/tools/subscribe/index.js +16 -0
  37. package/{agent/tools/subscribe.ts → agents/github/skills/github-subscriptions/tools/subscribe/index.ts} +3 -3
  38. package/agents/github/skills/github-subscriptions/tools/subscriptions/index.js +13 -0
  39. package/{agent/tools/subscriptions.ts → agents/github/skills/github-subscriptions/tools/subscriptions/index.ts} +3 -3
  40. package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.js +15 -0
  41. package/{agent/tools/unsubscribe.ts → agents/github/skills/github-subscriptions/tools/unsubscribe/index.ts} +3 -3
  42. package/agents/github/system.md +3 -0
  43. package/commands/{endpoint/add/[id].js → github/endpoint/add/[id]/index.js} +1 -1
  44. package/commands/github/endpoint/add/[id]/index.ts +3 -0
  45. package/{lib/github-endpoint-commands.js → commands/github/endpoint/definition.js} +6 -5
  46. package/{src/github-endpoint-commands.ts → commands/github/endpoint/definition.ts} +5 -5
  47. package/commands/{endpoint/list.js → github/endpoint/list/index.js} +1 -1
  48. package/commands/github/endpoint/list/index.ts +3 -0
  49. package/commands/{endpoint/remove/[id].js → github/endpoint/remove/[id]/index.js} +1 -1
  50. package/commands/github/endpoint/remove/[id]/index.ts +3 -0
  51. package/lib/client.js +1 -4
  52. package/lib/endpoint.js +4 -4
  53. package/lib/github-runtime-state.js +1 -1
  54. package/lib/index.d.ts +1 -1
  55. package/lib/oauth-users.d.ts +1 -1
  56. package/lib/oauth-users.js +1 -1
  57. package/lib/protocol.d.ts +11 -33
  58. package/lib/protocol.js +19 -30
  59. package/lib/types.d.ts +0 -23
  60. package/lib/types.js +2 -3
  61. package/package.json +35 -19
  62. package/plugin.js +3 -3
  63. package/prompt-sections/platform/index.js +16 -0
  64. package/schema.json +33 -26
  65. package/src/client.ts +1 -4
  66. package/src/endpoint.ts +4 -4
  67. package/src/github-runtime-state.ts +1 -1
  68. package/src/index.ts +1 -1
  69. package/src/oauth-users.ts +1 -1
  70. package/src/protocol.ts +26 -79
  71. package/src/types.ts +0 -28
  72. package/agent/skills/github.md +0 -283
  73. package/commands/endpoint/add/[id].ts +0 -3
  74. package/commands/endpoint/list.ts +0 -3
  75. package/commands/endpoint/remove/[id].ts +0 -3
  76. package/lib/github-bot-handlers.d.ts +0 -27
  77. package/lib/github-endpoint-commands.d.ts +0 -1
  78. package/lib/github-tool-handlers.d.ts +0 -18
  79. /package/{agent/prompt-sections/platform.ts → prompt-sections/platform/index.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,120 @@
1
1
  # @zhin.js/adapter-github
2
2
 
3
+ ## 1.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 36c2eb9: Add schema-driven database setup with explicit live-tested server and driver versions, validate environment-backed connection options before startup, and generate safe database examples for new projects.
8
+
9
+ Make durable timestamp columns portable across SQL dialects, preserve dialect-specific identity syntax, migrate legacy inbox tables before their first millisecond timestamp write, and encode canonical conversation keys at the database boundary so PostgreSQL accepts them.
10
+
11
+ Keep legacy durable conversation rows readable, normalize transaction results consistently, and make production mode select the matching environment overlay by default.
12
+
13
+ - Updated dependencies [5b5d270]
14
+ - Updated dependencies [36c2eb9]
15
+ - @zhin.js/im-contract@1.1.2
16
+ - @zhin.js/core@1.1.38
17
+ - @zhin.js/adapter@1.1.15
18
+ - @zhin.js/host-http@1.1.2
19
+ - @zhin.js/agent-feature@1.1.2
20
+ - @zhin.js/feature-kit@1.1.2
21
+ - @zhin.js/skill@1.1.2
22
+ - @zhin.js/tool@1.1.2
23
+
24
+ ## 1.1.2
25
+
26
+ ### Patch Changes
27
+
28
+ - 62dee52: Rename the Agent Tool policy field from `approval` to `requiresApproval`, so values such as `never` and `always` state when human approval is required. Remove the old field without a compatibility alias and migrate built-in, adapter, feature, and utility Tools to the canonical contract.
29
+ - a9e4a40: Derive Command user routes only from explicit `commands/**/*/index.ts(x)` entry paths instead of prepending the plugin owner. Child plugins can now publish top-level static or dynamic commands, while duplicate routes across owners fail during generation construction. Adapter endpoint commands move to explicit paths such as `commands/qq/endpoint/list/index.ts` and are invoked as `qq endpoint list`.
30
+ - 8740059: Standardize TypeScript capabilities on named module directories such as `commands/foo/index.ts`, `middlewares/audit/index.ts`, `handlers/message-receive/index.ts`, `pages/workroom/index.tsx`, and `mcps/filesystem/index.ts`. Only the fixed `index` entry is discovered; sibling files remain private helpers.
31
+
32
+ Command route segments come from directories, while `[name]`, `[[name]]`, `[...name]`, and `[[...name]]` directories declare dynamic parameters. Plugin owners do not enter the route unless their config explicitly sets `commandNamespace`; Endpoint `commandPrefix` remains platform-owned and defaults to an empty string.
33
+
34
+ Migrate the built-in adapters, plugins, examples, generators, migration tooling, hot reload classification, Agent authoring surfaces, documentation, and release artifacts to the explicit entry convention.
35
+
36
+ Make Tool ownership and progressive disclosure explicit across all four supported locations: plugin-public `tools/`, Agent-private `agents/<name>/tools/`, Skill-private `skills/<name>/tools/`, and Agent-Skill-private `agents/<name>/skills/<name>/tools/`. Move adapter and group-suite operations that require domain instructions into their owning Skills so `load_skill` is the only path that unlocks their schemas.
37
+
38
+ Remove the package-root `agent/` convention. Public capabilities now use named package-root directories, schedules use `schedules/<name>/index.ts` or `plugin.ts` injection, MCP connections use `mcps/<name>/index.ts`, Prompt Sections use `prompt-sections/<name>/index.ts`, Agent definitions use `agents/<name>/`, and permission vocabulary is published as `PERMITS.md`.
39
+
40
+ - 25a845a: Unify Skills on `skills/<name>/SKILL.md`, support Agent-private Skills and nested Skill-private Tools, publish and mount existing plugin Skills, add governed Skill metadata and Turn access filtering, unlock only already-admitted same-owner Tools, and make `on-risk` and `once` approval behavior precise.
41
+ - ddbb92e: Isolate adapter Skills under platform-specific Agents and automatically select the matching platform Agent for IM ingress, preventing unrelated adapter Skills from entering another platform's prompt surface.
42
+ - 40d2c8f: Reduce the default Agent Tool surface by moving process diagnostics into a Skill and splitting broad platform Skills into focused task domains. Restore ICQQ friend and group directory tools with `on-risk` approval and explicit owner, administrator, master, or trusted access.
43
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
44
+ - 46489ee: Require one canonical expanded GitHub endpoint configuration. Remove nested endpoint, environment, camelCase alias, default identity, and inert polling compatibility while making the resolved App credentials and workspace root explicit.
45
+ - 5c3858e: Make `@zhin.js/im-contract` the explicit zero-dependency owner of transport identities, canonical segments, media guards, conversation facts, stores, and delivery contracts. Platform adapters now read media contracts from that foundation instead of reaching through Core.
46
+ - 33ea736: Use `tools/<name>/index.ts` and `defineAgentTool` from `@zhin.js/tool` as the sole Agent Tool authoring model. Remove the duplicate `@zhin.js/tools` definition, context, bridge, export, and discovery path; migrate plugin manifests, examples, scaffolding, HMR, and prepack compilation to the generation-owned Tool Feature.
47
+ - Updated dependencies [c861789]
48
+ - Updated dependencies [1414ccb]
49
+ - Updated dependencies [743d470]
50
+ - Updated dependencies [62dee52]
51
+ - Updated dependencies [cd54131]
52
+ - Updated dependencies [244e475]
53
+ - Updated dependencies [a9e4a40]
54
+ - Updated dependencies [5855db7]
55
+ - Updated dependencies [ec921d2]
56
+ - Updated dependencies [8740059]
57
+ - Updated dependencies [63d1f7a]
58
+ - Updated dependencies [25a845a]
59
+ - Updated dependencies [103f2c3]
60
+ - Updated dependencies [9110ab8]
61
+ - Updated dependencies [cd2a888]
62
+ - Updated dependencies [eb3227a]
63
+ - Updated dependencies [b853dba]
64
+ - Updated dependencies [e561309]
65
+ - Updated dependencies [d4c6175]
66
+ - Updated dependencies [7a0e1ca]
67
+ - Updated dependencies [103b5d3]
68
+ - Updated dependencies [5a7a7f7]
69
+ - Updated dependencies [b076eae]
70
+ - Updated dependencies [535fed1]
71
+ - Updated dependencies [73a24b7]
72
+ - Updated dependencies [2dbbc15]
73
+ - Updated dependencies [1cb1163]
74
+ - Updated dependencies [be3061e]
75
+ - Updated dependencies [75f8332]
76
+ - Updated dependencies [81935e2]
77
+ - Updated dependencies [f9ed01b]
78
+ - Updated dependencies [ac0ab50]
79
+ - Updated dependencies [5140ce1]
80
+ - Updated dependencies [522d75f]
81
+ - Updated dependencies [a7611b3]
82
+ - Updated dependencies [8823044]
83
+ - Updated dependencies [379439b]
84
+ - Updated dependencies [11c9352]
85
+ - Updated dependencies [6b70e46]
86
+ - Updated dependencies [135ac91]
87
+ - Updated dependencies [140cf0f]
88
+ - Updated dependencies [251e4d2]
89
+ - Updated dependencies [203ad34]
90
+ - Updated dependencies [e6c5113]
91
+ - Updated dependencies [e0f6478]
92
+ - Updated dependencies [baef56b]
93
+ - Updated dependencies [698f16f]
94
+ - Updated dependencies [da0a8e3]
95
+ - Updated dependencies [2fd8017]
96
+ - Updated dependencies [5c3858e]
97
+ - Updated dependencies [33ea736]
98
+ - Updated dependencies [507d602]
99
+ - Updated dependencies [df9f76b]
100
+ - @zhin.js/core@1.1.37
101
+ - @zhin.js/tool@1.1.1
102
+ - @zhin.js/host-http@1.1.1
103
+ - @zhin.js/adapter@1.1.14
104
+ - @zhin.js/feature-kit@1.1.1
105
+ - @zhin.js/agent-feature@1.1.1
106
+ - @zhin.js/skill@1.1.1
107
+ - @zhin.js/logger@1.1.1
108
+ - @zhin.js/im-contract@1.1.1
109
+
110
+ ## 1.1.1
111
+
112
+ ### Patch Changes
113
+
114
+ - Updated dependencies [769e67f]
115
+ - @zhin.js/adapter@1.1.13
116
+ - @zhin.js/core@1.1.36
117
+
3
118
  ## 1.1.0
4
119
 
5
120
  ### Minor Changes
package/README.md CHANGED
@@ -8,7 +8,7 @@ GitHub Plugin Runtime 适配器 — Issue/PR 评论区即聊天通道,GitHub A
8
8
  - **Webhook 入站**:HMAC-SHA256 验签 → `Endpoint.emit(...)`
9
9
  - **出站**:`send({ conversation, payload })` → Issue/PR comment(`conversation.id` 为 channel ID)
10
10
  - **GitHub App 认证**:JWT → Installation Token
11
- - **Agent 工具**:`agent/` 下 star/bind/subscribe/workspace 等保留
11
+ - **Agent 工具**:按账号、订阅和仓库操作拆分在 `agents/github/skills/github-*/tools/`,只激活当前任务所需的一组
12
12
 
13
13
  ## 安装
14
14
 
@@ -36,37 +36,36 @@ plugins:
36
36
  - zhinjs/zhin
37
37
  workspace_root: ./data/github-workspaces
38
38
  endpoints:
39
- - name: my-github-bot
40
- app_id: 123456
39
+ - id: my-github-bot
40
+ app_id: "${GITHUB_APP_ID}"
41
41
  private_key: ./data/github-app.pem
42
- webhook_secret: your-secret
43
- ```
44
-
45
- ```env
46
- GITHUB_APP_ID=123456
47
- GITHUB_WEBHOOK_SECRET=your-secret
42
+ webhook_secret: "${GITHUB_WEBHOOK_SECRET}"
48
43
  ```
49
44
 
50
45
  `private_key` 支持文件路径或 PEM 内容。未配置 `webhook_secret` 时仅 API 出站 / agent 工具可用(无入站)。
51
46
 
52
- 多 App:一个插件实例挂多个 endpoint(`endpoints` 数组逐项覆盖顶层字段,`name` 必填):
47
+ `AdapterIndex` 会先合并插件实例默认值与 endpoint 覆盖值,再把一份完整配置交给
48
+ GitHub adapter。协议层只接受这份展开后的 endpoint 配置,不读取环境变量、不解析嵌套
49
+ `endpoints`,也不接受 camelCase 配置别名。`${...}` 由 composition root 在加载配置时展开。
50
+
51
+ 多 App:一个插件实例挂多个 endpoint(`endpoints` 数组逐项覆盖顶层字段;`id`、`app_id`、`private_key` 必填):
53
52
 
54
53
  ```yaml
55
54
  plugins:
56
55
  github:
57
56
  endpoints:
58
- - name: app-a
57
+ - id: app-a
59
58
  app_id: 123456
60
59
  private_key: ./data/app-a.pem
61
- - name: app-b
60
+ - id: app-b
62
61
  app_id: 234567
63
62
  private_key: ./data/app-b.pem
64
63
  ```
65
64
 
66
- ## 已移除的配置
65
+ ## 已移除的能力
67
66
 
68
- - **`ai.githubMcp.enabled` / `ai.githubMcp.token`**:Plugin Runtime 迁移后 `register-github-mcp`(stdio `@modelcontextprotocol/server-github`,PAT 人身份)已移除,该配置不再生效。如需 MCP 工具,请按新运行时 `mcp/<name>.ts`(`@zhin.js/mcp-feature`)约定自行装配。
69
- - **`poll_interval`**:轮询降级已删除,仅 webhook 入站;该字段目前解析但不生效(deferred)。
67
+ - **`ai.githubMcp.enabled` / `ai.githubMcp.token`**:Plugin Runtime 迁移后 `register-github-mcp`(stdio `@modelcontextprotocol/server-github`,PAT 人身份)已移除,该配置不再生效。如需 MCP 工具,请按 `mcps/<name>/index.ts`(`@zhin.js/mcp-feature`)约定自行装配。
68
+ - 轮询降级已删除,入站只通过 Webhook;没有保留无效的轮询配置字段。
70
69
 
71
70
  ## Channel ID
72
71
 
@@ -77,14 +76,14 @@ plugins:
77
76
 
78
77
  ## AI 工具
79
78
 
80
- 见 `agent/tools/`:`github_star`、`github_bind`、`github_subscribe`、`github_prepare_workspace` 等。
79
+ 见 `agents/github/skills/github-*/tools/`:账号绑定、订阅管理和仓库写入分别按需披露。
81
80
 
82
81
  ## 架构
83
82
 
84
83
  | 路径 | 职责 |
85
84
  |------|------|
86
85
  | `plugin.ts` | 插件元数据;有 DatabaseHost 时定义 `github_oauth_users` |
87
- | `adapters/github.ts` | 薄 `defineAdapter` 入口(发现约定) |
86
+ | `adapters/github/index.ts` | 薄 `defineAdapter` 入口(发现约定) |
88
87
  | `src/endpoint.ts` | Endpoint 生命周期、出站、admit |
89
88
  | `src/webhook.ts` | HMAC 验签与事件分发 |
90
89
  | `src/oauth-users.ts` | OAuth 表 SSOT + token 查找 |
@@ -1,15 +1,15 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/github.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/github/index.ts` → defineAdapter.
4
4
  * Implementation lives under `src/` (endpoint / webhook / oauth / protocol).
5
5
  */
6
6
  import { defineAdapter } from 'zhin.js/adapter';
7
7
  import { httpHostToken } from '@zhin.js/host-http';
8
8
  import { databaseHostToken, } from 'zhin.js';
9
- import { GithubEndpoint } from "../lib/endpoint.js";
10
- import { githubRuntimeStateToken } from "../lib/github-runtime-state.js";
11
- import { resolveGithubConfig, } from "../lib/protocol.js";
12
- export { GithubEndpoint } from "../lib/endpoint.js";
9
+ import { GithubEndpoint } from "../../lib/endpoint.js";
10
+ import { githubRuntimeStateToken } from "../../lib/github-runtime-state.js";
11
+ import { resolveGithubConfig, } from "../../lib/protocol.js";
12
+ export { GithubEndpoint } from "../../lib/endpoint.js";
13
13
  function optionalDatabase(context) {
14
14
  try {
15
15
  return context.use(databaseHostToken);
@@ -28,7 +28,7 @@ export default defineAdapter({
28
28
  create(context) {
29
29
  const config = resolveGithubConfig(context.config);
30
30
  const database = optionalDatabase(context);
31
- // 注册到插件运行时状态(github.endpoint list 的"运行中"数据源)
31
+ // 注册到插件运行时状态(github endpoint list 的"运行中"数据源)
32
32
  context.use(githubRuntimeStateToken).endpoints.set(config.id, {
33
33
  id: config.id,
34
34
  mode: config.webhookSecret ? 'webhook' : 'api',
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Convention entry: discover `adapters/github.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/github/index.ts` → defineAdapter.
3
3
  * Implementation lives under `src/` (endpoint / webhook / oauth / protocol).
4
4
  */
5
5
  import { defineAdapter, type AdapterContext } from 'zhin.js/adapter';
@@ -8,15 +8,15 @@ import {
8
8
  databaseHostToken,
9
9
  type PluginDatabaseHost,
10
10
  } from 'zhin.js';
11
- import { GithubEndpoint } from '../src/endpoint.js';
12
- import { githubRuntimeStateToken } from '../src/github-runtime-state.js';
11
+ import { GithubEndpoint } from '../../src/endpoint.js';
12
+ import { githubRuntimeStateToken } from '../../src/github-runtime-state.js';
13
13
  import {
14
14
  resolveGithubConfig,
15
- type GithubAdapterConfig,
16
- } from '../src/protocol.js';
15
+ type GithubEndpointConfig,
16
+ } from '../../src/protocol.js';
17
17
 
18
- export { GithubEndpoint } from '../src/endpoint.js';
19
- export type { GithubEndpointOptions } from '../src/endpoint.js';
18
+ export { GithubEndpoint } from '../../src/endpoint.js';
19
+ export type { GithubEndpointOptions } from '../../src/endpoint.js';
20
20
 
21
21
  function optionalDatabase(context: AdapterContext): PluginDatabaseHost | undefined {
22
22
  try {
@@ -26,7 +26,7 @@ function optionalDatabase(context: AdapterContext): PluginDatabaseHost | undefin
26
26
  }
27
27
  }
28
28
 
29
- export default defineAdapter<GithubAdapterConfig>({
29
+ export default defineAdapter<GithubEndpointConfig>({
30
30
  capabilities: ['inbound', 'outbound'],
31
31
  // Issue/PR 评论以 markdown 图片链接消费远程 URL;无交互面,交互段降级纯文本。
32
32
  segments: {
@@ -36,7 +36,7 @@ export default defineAdapter<GithubAdapterConfig>({
36
36
  create(context) {
37
37
  const config = resolveGithubConfig(context.config);
38
38
  const database = optionalDatabase(context);
39
- // 注册到插件运行时状态(github.endpoint list 的"运行中"数据源)
39
+ // 注册到插件运行时状态(github endpoint list 的"运行中"数据源)
40
40
  context.use(githubRuntimeStateToken).endpoints.set(config.id, {
41
41
  id: config.id,
42
42
  mode: config.webhookSecret ? 'webhook' : 'api',
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "GITHUB Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles github platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "github",
9
+ "adapter:github"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "github"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active github endpoint and authenticated conversation context. Respect every Tool permission and approval policy. Do not infer identifiers, roles, or authorization from display names.
@@ -0,0 +1,3 @@
1
+ # Conventions
2
+
3
+ Use stable platform identifiers from the current turn or directory queries. Load one task-specific Skill at a time, and use the unified reply and outbound message path.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: github-account
3
+ platforms:
4
+ - github
5
+ description: GitHub 账号绑定、安装状态和身份查询能力。
6
+ keywords:
7
+ - "github"
8
+ - "账号"
9
+ - "绑定"
10
+ - "安装"
11
+ tools:
12
+ - "bind"
13
+ - "install"
14
+ - "unbind"
15
+ - "whoami"
16
+ ---
17
+
18
+ # github-account
19
+
20
+ 处理 GitHub 身份与绑定状态时加载。`bind` 使用 Device Flow 绑定用户 OAuth 身份;`install` 返回 GitHub App 安装入口;`whoami` 用于确认当前绑定。用户想用自己的账号执行操作时先绑定。解绑和安装相关操作遵守 Tool 审批,不回显 Token、Device Code 或其他凭据。
@@ -1,14 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  import { formatCompact } from '@zhin.js/logger';
2
3
  import { getCurrentCommMessage } from '@zhin.js/agent/security';
3
- import { GhClient } from './gh-client.js';
4
+ import { GhClient } from "../../../../lib/gh-client.js";
4
5
  function oauthModel(client) {
5
6
  const db = client.database;
6
7
  return db?.models?.get('github_oauth_users');
7
8
  }
8
- function subscriptionsModel(client) {
9
- const db = client.database;
10
- return db?.models?.get('github_subscriptions');
11
- }
12
9
  function depsLogger() {
13
10
  return {
14
11
  debug: (...args) => console.debug(...args),
@@ -16,26 +13,6 @@ function depsLogger() {
16
13
  error: (...args) => console.error(...args),
17
14
  };
18
15
  }
19
- export async function executeGithubStar(args, client, commMessage) {
20
- const msg = commMessage ?? getCurrentCommMessage();
21
- const gh = await client.getUserOrDefaultApi(msg?.$adapter, msg?.$sender.id);
22
- switch (args.action) {
23
- case 'star': {
24
- const r = await gh.starRepo(args.repo);
25
- return r.ok ? `⭐ 已 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
26
- }
27
- case 'unstar': {
28
- const r = await gh.unstarRepo(args.repo);
29
- return r.ok ? `💔 已取消 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
30
- }
31
- case 'check': {
32
- const starred = await gh.isStarred(args.repo);
33
- return starred ? `⭐ 已 Star ${args.repo}` : `☆ 尚未 Star ${args.repo}`;
34
- }
35
- default:
36
- return `❌ 未知操作: ${args.action}`;
37
- }
38
- }
39
16
  export async function executeGithubBind(_args, client, commMessage) {
40
17
  const log = depsLogger();
41
18
  const msg = commMessage ?? getCurrentCommMessage();
@@ -137,78 +114,3 @@ export async function executeGithubInstall(client) {
137
114
  }
138
115
  return msg;
139
116
  }
140
- export async function executeGithubSubscribe(args, client, commMessage) {
141
- const msg = commMessage ?? getCurrentCommMessage();
142
- if (!msg?.$adapter || !msg?.$sender.id || !msg?.$channel?.id || !msg?.$endpoint) {
143
- return '❌ 无法获取当前聊天通道信息';
144
- }
145
- const model = subscriptionsModel(client);
146
- if (!model)
147
- return '❌ 数据库未就绪';
148
- const validEvents = ['push', 'issue', 'star', 'fork', 'unstar', 'pull_request'];
149
- const events = args.events
150
- ? args.events.split(',').map((s) => s.trim()).filter((e) => validEvents.includes(e))
151
- : validEvents;
152
- if (!events.length)
153
- return `❌ 无效的事件类型,可选: ${validEvents.join(', ')}`;
154
- const [existing] = await model.select().where({
155
- repo: args.repo,
156
- target_id: msg.$channel?.id,
157
- adapter: msg.$adapter,
158
- endpoint: msg.$endpoint,
159
- });
160
- if (existing) {
161
- await model.update({ events, target_type: msg.$channel?.type || 'private' }).where({ id: existing.id });
162
- return `✅ 已更新订阅 ${args.repo}\n📡 事件: ${events.join(', ')}`;
163
- }
164
- await model.insert({
165
- id: Date.now(),
166
- repo: args.repo,
167
- events,
168
- target_id: msg.$channel?.id,
169
- target_type: msg.$channel?.type || 'private',
170
- adapter: msg.$adapter,
171
- endpoint: msg.$endpoint,
172
- });
173
- return `✅ 已订阅 ${args.repo}\n📡 事件: ${events.join(', ')}\n📌 通知将推送到当前通道`;
174
- }
175
- export async function executeGithubUnsubscribe(args, client, commMessage) {
176
- const msg = commMessage ?? getCurrentCommMessage();
177
- if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
178
- return '❌ 无法获取当前聊天通道信息';
179
- }
180
- const model = subscriptionsModel(client);
181
- if (!model)
182
- return '❌ 数据库未就绪';
183
- const [existing] = await model.select().where({
184
- repo: args.repo,
185
- target_id: msg.$channel?.id,
186
- adapter: msg.$adapter,
187
- endpoint: msg.$endpoint,
188
- });
189
- if (!existing)
190
- return `📭 当前通道未订阅 ${args.repo}`;
191
- await model.delete().where({ id: existing.id });
192
- return `✅ 已取消订阅 ${args.repo}`;
193
- }
194
- export async function executeGithubSubscriptions(_args, client, commMessage) {
195
- const msg = commMessage ?? getCurrentCommMessage();
196
- if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
197
- return '❌ 无法获取当前聊天通道信息';
198
- }
199
- const model = subscriptionsModel(client);
200
- if (!model)
201
- return '❌ 数据库未就绪';
202
- const subs = await model.select().where({
203
- target_id: msg.$channel?.id,
204
- adapter: msg.$adapter,
205
- endpoint: msg.$endpoint,
206
- });
207
- if (!subs?.length)
208
- return '📭 当前通道没有任何 GitHub 订阅';
209
- return `📋 当前通道订阅 (${subs.length}):\n\n` +
210
- subs.map((s) => {
211
- const events = Array.isArray(s.events) ? s.events : [];
212
- return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || '(无事件)'}`;
213
- }).join('\n\n');
214
- }
@@ -1,9 +1,8 @@
1
1
  import { formatCompact } from '@zhin.js/logger';
2
2
  import type { Message } from 'zhin.js';
3
3
  import { getCurrentCommMessage } from '@zhin.js/agent/security';
4
- import { GhClient } from './gh-client.js';
5
- import type { EventType } from './types.js';
6
- import type { GithubClient } from './client.js';
4
+ import { GhClient } from '../../../../src/gh-client.js';
5
+ import type { GithubClient } from '../../../../src/client.js';
7
6
 
8
7
  function oauthModel(client: GithubClient) {
9
8
  const db = client.database as {
@@ -16,18 +15,6 @@ function oauthModel(client: GithubClient) {
16
15
  } | undefined;
17
16
  }
18
17
 
19
- function subscriptionsModel(client: GithubClient) {
20
- const db = client.database as {
21
- models?: Map<string, unknown>;
22
- } | null | undefined;
23
- return db?.models?.get('github_subscriptions') as {
24
- select: () => { where: (q: object) => Promise<any[]> };
25
- insert: (row: object) => Promise<void>;
26
- update: (row: object) => { where: (q: object) => Promise<void> };
27
- delete: () => { where: (q: object) => Promise<void> };
28
- } | undefined;
29
- }
30
-
31
18
  function depsLogger() {
32
19
  return {
33
20
  debug: (...args: unknown[]) => console.debug(...args),
@@ -36,27 +23,6 @@ function depsLogger() {
36
23
  };
37
24
  }
38
25
 
39
- export async function executeGithubStar(args: { action: 'star' | 'unstar' | 'check'; repo: string }, client: GithubClient, commMessage?: Message) {
40
- const msg = commMessage ?? getCurrentCommMessage();
41
- const gh = await client.getUserOrDefaultApi(msg?.$adapter, msg?.$sender.id);
42
- switch (args.action) {
43
- case 'star': {
44
- const r = await gh.starRepo(args.repo);
45
- return r.ok ? `⭐ 已 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
46
- }
47
- case 'unstar': {
48
- const r = await gh.unstarRepo(args.repo);
49
- return r.ok ? `💔 已取消 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
50
- }
51
- case 'check': {
52
- const starred = await gh.isStarred(args.repo);
53
- return starred ? `⭐ 已 Star ${args.repo}` : `☆ 尚未 Star ${args.repo}`;
54
- }
55
- default:
56
- return `❌ 未知操作: ${args.action}`;
57
- }
58
- }
59
-
60
26
  export async function executeGithubBind(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
61
27
  const log = depsLogger();
62
28
  const msg = commMessage ?? getCurrentCommMessage();
@@ -168,85 +134,3 @@ export async function executeGithubInstall(client: GithubClient) {
168
134
  }
169
135
  return msg;
170
136
  }
171
-
172
- export async function executeGithubSubscribe(args: { repo: string; events?: string }, client: GithubClient, commMessage?: Message) {
173
- const msg = commMessage ?? getCurrentCommMessage();
174
- if (!msg?.$adapter || !msg?.$sender.id || !msg?.$channel?.id || !msg?.$endpoint) {
175
- return '❌ 无法获取当前聊天通道信息';
176
- }
177
-
178
- const model = subscriptionsModel(client);
179
- if (!model) return '❌ 数据库未就绪';
180
-
181
- const validEvents: EventType[] = ['push', 'issue', 'star', 'fork', 'unstar', 'pull_request'];
182
- const events: EventType[] = args.events
183
- ? args.events.split(',').map((s) => s.trim()).filter((e): e is EventType => validEvents.includes(e as EventType))
184
- : validEvents;
185
- if (!events.length) return `❌ 无效的事件类型,可选: ${validEvents.join(', ')}`;
186
-
187
- const [existing] = await model.select().where({
188
- repo: args.repo,
189
- target_id: msg.$channel?.id,
190
- adapter: msg.$adapter,
191
- endpoint: msg.$endpoint,
192
- });
193
- if (existing) {
194
- await model.update({ events, target_type: msg.$channel?.type || 'private' }).where({ id: existing.id });
195
- return `✅ 已更新订阅 ${args.repo}\n📡 事件: ${events.join(', ')}`;
196
- }
197
-
198
- await model.insert({
199
- id: Date.now(),
200
- repo: args.repo,
201
- events,
202
- target_id: msg.$channel?.id,
203
- target_type: msg.$channel?.type || 'private',
204
- adapter: msg.$adapter,
205
- endpoint: msg.$endpoint,
206
- });
207
- return `✅ 已订阅 ${args.repo}\n📡 事件: ${events.join(', ')}\n📌 通知将推送到当前通道`;
208
- }
209
-
210
- export async function executeGithubUnsubscribe(args: { repo: string }, client: GithubClient, commMessage?: Message) {
211
- const msg = commMessage ?? getCurrentCommMessage();
212
- if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
213
- return '❌ 无法获取当前聊天通道信息';
214
- }
215
-
216
- const model = subscriptionsModel(client);
217
- if (!model) return '❌ 数据库未就绪';
218
-
219
- const [existing] = await model.select().where({
220
- repo: args.repo,
221
- target_id: msg.$channel?.id,
222
- adapter: msg.$adapter,
223
- endpoint: msg.$endpoint,
224
- });
225
- if (!existing) return `📭 当前通道未订阅 ${args.repo}`;
226
-
227
- await model.delete().where({ id: existing.id });
228
- return `✅ 已取消订阅 ${args.repo}`;
229
- }
230
-
231
- export async function executeGithubSubscriptions(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
232
- const msg = commMessage ?? getCurrentCommMessage();
233
- if (!msg?.$adapter || !msg?.$channel?.id || !msg?.$endpoint) {
234
- return '❌ 无法获取当前聊天通道信息';
235
- }
236
-
237
- const model = subscriptionsModel(client);
238
- if (!model) return '❌ 数据库未就绪';
239
-
240
- const subs = await model.select().where({
241
- target_id: msg.$channel?.id,
242
- adapter: msg.$adapter,
243
- endpoint: msg.$endpoint,
244
- });
245
- if (!subs?.length) return '📭 当前通道没有任何 GitHub 订阅';
246
-
247
- return `📋 当前通道订阅 (${subs.length}):\n\n` +
248
- subs.map((s: any) => {
249
- const events = Array.isArray(s.events) ? s.events : [];
250
- return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || '(无事件)'}`;
251
- }).join('\n\n');
252
- }
@@ -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 { executeGithubBind } from '../../handlers.js';
5
+ export default defineAgentTool({
6
+ description: '绑定你的 GitHub 账号 — 使用 Device Flow 授权,无需输入密码',
7
+ adapter: 'github',
8
+ inputSchema: z.object({}),
9
+ tags: ['github'],
10
+ async execute(input, context) {
11
+ return executeGithubBind({}, context.$client);
12
+ },
13
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { executeGithubBind } from '../../src/github-tool-handlers.js';
3
+ import { executeGithubBind } from '../../handlers.js';
4
4
 
5
5
  export default defineAgentTool<{}>({
6
6
  description: '绑定你的 GitHub 账号 — 使用 Device Flow 授权,无需输入密码',
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubBind({}, context.$client, context.message);
11
+ return executeGithubBind({}, 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 { executeGithubInstall } from '../../handlers.js';
5
+ export default defineAgentTool({
6
+ description: '获取安装 GitHub App 的链接 — 安装后 Endpoint 可以访问你的仓库,你也可以使用更多功能',
7
+ adapter: 'github',
8
+ inputSchema: z.object({}),
9
+ tags: ['github'],
10
+ async execute(input, context) {
11
+ return executeGithubInstall(context.$client);
12
+ },
13
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { executeGithubInstall } from '../../src/github-tool-handlers.js';
3
+ import { executeGithubInstall } from '../../handlers.js';
4
4
 
5
5
  export default defineAgentTool<{}>({
6
6
  description: '获取安装 GitHub App 的链接 — 安装后 Endpoint 可以访问你的仓库,你也可以使用更多功能',
@@ -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 { executeGithubUnbind } 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 executeGithubUnbind({}, context.$client);
12
+ },
13
+ });