@zhin.js/adapter-github 1.1.18 → 1.1.20
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 +45 -0
- package/README.md +5 -7
- package/adapters/github/index.js +3 -36
- package/adapters/github/index.ts +3 -39
- package/agents/github/skills/github-account/handlers.ts +6 -6
- package/agents/github/skills/github-repository/handlers.js +1 -1
- package/agents/github/skills/github-repository/handlers.ts +7 -7
- package/agents/github/skills/github-subscriptions/handlers.ts +6 -6
- package/commands/github/endpoint/definition.js +0 -2
- package/commands/github/endpoint/definition.ts +0 -2
- package/lib/adapter.d.ts +19 -0
- package/lib/adapter.js +30 -0
- package/lib/client.d.ts +0 -35
- package/lib/client.js +1 -44
- package/lib/console.d.ts +1 -1
- package/lib/console.js +2 -5
- package/lib/endpoint.d.ts +9 -12
- package/lib/endpoint.js +56 -31
- package/lib/gh-client.d.ts +27 -6
- package/lib/gh-client.js +74 -49
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -1
- package/lib/webhook.d.ts +1 -1
- package/lib/webhook.js +3 -3
- package/package.json +21 -21
- package/plugin.js +0 -3
- package/src/adapter.ts +32 -0
- package/src/client.ts +0 -61
- package/src/console.ts +2 -5
- package/src/endpoint.ts +52 -33
- package/src/gh-client.ts +90 -57
- package/src/index.ts +2 -1
- package/src/webhook.ts +4 -4
- package/lib/github-runtime-state.d.ts +0 -1
- package/lib/github-runtime-state.js +0 -6
- package/src/github-runtime-state.ts +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @zhin.js/adapter-github
|
|
2
2
|
|
|
3
|
+
## 1.1.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [5e878ba]
|
|
8
|
+
- @zhin.js/page@1.1.12
|
|
9
|
+
|
|
10
|
+
## 1.1.19
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 2c3610a: Move account lifecycle ownership into the generic Adapter base and let native Endpoints retain their SDK Client inheritance. Infer platform-specific operation Sessions from a single adapter registry while preserving command parameter, option, configuration and factory inference.
|
|
15
|
+
|
|
16
|
+
Bind message replies, management ports, login challenges and Agent cancellation to the captured account incarnation. Persist runtime account intent with encrypted, revision-checked Host storage; keep account management independent of Root process restarts. Require explicit operator confirmation before importing existing accounts, and give replacement accounts a new identity without inheriting previous Sessions.
|
|
17
|
+
|
|
18
|
+
Expose account save, start, stop, update and replacement through the existing adapter Console, with exact account ownership, truthful pending/unknown outcomes and no startup configuration or environment-file rewrites.
|
|
19
|
+
|
|
20
|
+
Complete the target migration across every adapter, the public authoring API, generators, examples and Console. This intentionally removes the old create factory, inheritable Endpoint/ClientEndpoint classes, Client descriptors and file-rewrite account management; plugin authors must use createAdapter, native Client inheritance and the single AdapterRegistry. Satori and OneBot12 require explicit platform/userId selection, and WeCom requires a separate agentId.
|
|
21
|
+
|
|
22
|
+
Verify opaque credential changes before the same configuration snapshot is committed. Drain admitted native callbacks across close/rollback, cancel target work on stop, and keep raw transport parsing, platform ACK timing and SDK native methods under their existing owners. Account metadata conceals credentials carried in URLs.
|
|
23
|
+
|
|
24
|
+
- a9f4e48: PATCH COMPATIBILITY CUTOVER: this batch intentionally changes plugin APIs. The maintainer explicitly chose patch releases with declared version boundaries. Upgrade the complete tested dependency set; patch numbering does not promise compatibility with the removed interfaces.
|
|
25
|
+
|
|
26
|
+
The first planned floors are zhin.js 1.1.19, Core 1.1.54, Adapter 1.1.26, FeatureKit 1.1.10, Plugin Runtime 1.1.18, Runtime/Isolate 1.1.16 and Agent 1.1.45. Keep old-interface plugins with the earlier locked stack until they are migrated. Adapter's independent Feature API changes from 1.0.0 to 2.0.0; official consumers declare ^2.0.0. Existing Feature API admission rejects explicitly incompatible ranges; omitted API metadata keeps its existing behavior and does not certify compatibility. Runtime engine and patch-only release gates remain unchanged.
|
|
27
|
+
|
|
28
|
+
Use the native-Client Adapter target contract, canonical FeatureKit AdapterRegistry augmentation and named Endpoint control/management requests. Route message controls from canonical message/conversation refs; retain exact source authority and propagate caller/account/explicit-Root-stop cancellation. Replace removed Agent activity feedback exports with source-bound feedback. HMR pause/resume belongs to concrete plugin instances; plugins choose accepted-work policy without changing Controller commit/rollback authority. Cooperative worker/process control cancellation does not kill an isolate or reopen retired business admission.
|
|
29
|
+
|
|
30
|
+
Provide authenticated historical-data preview, exact selected binding, transactional application, authoritative inspection and explicit resumption, including active games. Preserve before-images and journals; never replay an unconfirmed effect, infer an account from an alias, or reuse historical permission grants. Owner V2 approvals remain inactive legacy data, while new writes use V3. Rollback requires matching software, lockfile and verified data; installing old code alone cannot read a new V3 approval file. Conflicting after-images are never overwritten.
|
|
31
|
+
|
|
32
|
+
See docs/plans/adapter-operation-version-boundaries.md and the Chinese/English upgrade guide for the complete version inventory, custom-plugin changes, acceptance and recovery sequence. These code and metadata changes do not authorize merging, publication, deployment, login, production migration or removal of installed workspace patches.
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [2c3610a]
|
|
35
|
+
- Updated dependencies [a9f4e48]
|
|
36
|
+
- Updated dependencies [f8505b0]
|
|
37
|
+
- Updated dependencies [2c3610a]
|
|
38
|
+
- @zhin.js/adapter@1.1.26
|
|
39
|
+
- @zhin.js/feature-kit@1.1.10
|
|
40
|
+
- @zhin.js/core@1.1.54
|
|
41
|
+
- @zhin.js/host-http@1.1.12
|
|
42
|
+
- @zhin.js/client@1.1.22
|
|
43
|
+
- @zhin.js/page@1.1.11
|
|
44
|
+
- @zhin.js/agent-feature@1.1.11
|
|
45
|
+
- @zhin.js/skill@1.1.11
|
|
46
|
+
- @zhin.js/tool@1.1.13
|
|
47
|
+
|
|
3
48
|
## 1.1.18
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ GitHub Plugin Runtime 适配器 — Issue/PR 评论区即聊天通道,GitHub A
|
|
|
5
5
|
## 功能特性
|
|
6
6
|
|
|
7
7
|
- **聊天通道**:Issue/PR 评论区映射为群聊,支持收发消息
|
|
8
|
-
- **Webhook 入站**:HMAC-SHA256 验签 → `
|
|
8
|
+
- **Webhook 入站**:HMAC-SHA256 验签 → `endpointSpec.events`
|
|
9
9
|
- **出站**:`send({ conversation, payload })` → Issue/PR comment(`conversation.id` 为 channel ID)
|
|
10
10
|
- **GitHub App 认证**:JWT → Installation Token
|
|
11
11
|
- **Agent 工具**:按账号、订阅和仓库操作拆分在 `agents/github/skills/github-*/tools/`,只激活当前任务所需的一组
|
|
@@ -94,18 +94,16 @@ github:
|
|
|
94
94
|
| `src/protocol.ts` | 协议纯函数(channel / payload) |
|
|
95
95
|
| `src/gh-client.ts` | GitHub API 客户端 |
|
|
96
96
|
|
|
97
|
-
- 入站:`httpHostToken` POST → `
|
|
97
|
+
- 入站:`httpHostToken` POST → `endpointSpec.events`
|
|
98
98
|
- 出站:`send({ conversation, payload })`
|
|
99
99
|
|
|
100
100
|
## Console 页面
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
在所属插件的 Console 页面管理账号:查看配置与运行状态,添加、编辑、启动、停止、替换或删除账号。首次修改启动账号前,管理员需确认迁移清单;保留原身份与历史。此后保存到 Host 运行时存储,不改启动配置或 `.env`,无需重启进程。
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
- 增删 `plugins.github.endpoints`(凭据写入 `.env`,配置里只保留 `${ENV}` 引用);
|
|
106
|
-
- 如果适配器要求登录,页面会显示 LoginAssist 的扫码 / 滑块 / 设备确认待办;
|
|
104
|
+
新增仅保存,需手动启动;运行账号的普通配置更新只重连该账号。身份变化走明确替换,新账号不会继承旧 Session 或登录状态。账号凭据变化先按平台实际只读接口核验;平台无法核验时需明确替换。空白或遮蔽的密码不会覆盖既有密码。
|
|
107
105
|
|
|
108
|
-
读取需要 `github:read
|
|
106
|
+
读取需要 `github:read`,写入需要 `github:write`;首次迁移还需管理员身份。无持久化存储时管理操作不可用,提交结果未知时先刷新核实,不重复提交。
|
|
109
107
|
|
|
110
108
|
## 故障排查
|
|
111
109
|
|
package/adapters/github/index.js
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { GithubAdapter } from "../../lib/adapter.js";
|
|
2
3
|
/**
|
|
3
4
|
* Convention entry: discover `adapters/github/index.ts` → defineAdapter.
|
|
4
5
|
* Implementation lives under `src/` (endpoint / webhook / oauth / protocol).
|
|
5
6
|
*/
|
|
6
7
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
7
|
-
import {
|
|
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";
|
|
8
|
+
import {} from "../../lib/protocol.js";
|
|
12
9
|
export { GithubEndpoint } from "../../lib/endpoint.js";
|
|
13
|
-
function optionalDatabase(context) {
|
|
14
|
-
try {
|
|
15
|
-
return context.use(databaseHostToken);
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
10
|
export default defineAdapter({
|
|
22
11
|
capabilities: ['inbound', 'outbound'],
|
|
23
12
|
// Issue/PR 评论以 markdown 图片链接消费远程 URL;无交互面,交互段降级纯文本。
|
|
@@ -25,27 +14,5 @@ export default defineAdapter({
|
|
|
25
14
|
outboundMedia: ['url'],
|
|
26
15
|
interactive: 'text',
|
|
27
16
|
},
|
|
28
|
-
|
|
29
|
-
const config = resolveGithubConfig(context.config);
|
|
30
|
-
const database = optionalDatabase(context);
|
|
31
|
-
// 注册到插件运行时状态(github endpoint list 的"运行中"数据源)
|
|
32
|
-
context.use(githubRuntimeStateToken).endpoints.set(config.id, {
|
|
33
|
-
id: config.id,
|
|
34
|
-
mode: config.webhookSecret ? 'webhook' : 'api',
|
|
35
|
-
});
|
|
36
|
-
if (config.webhookSecret) {
|
|
37
|
-
return new GithubEndpoint({
|
|
38
|
-
id: context.id,
|
|
39
|
-
http: context.use(httpHostToken),
|
|
40
|
-
database,
|
|
41
|
-
config,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
// API-only: Issue/PR send + agent tools without webhook.
|
|
45
|
-
return new GithubEndpoint({
|
|
46
|
-
id: context.id,
|
|
47
|
-
database,
|
|
48
|
-
config,
|
|
49
|
-
});
|
|
50
|
-
},
|
|
17
|
+
createAdapter: context => new GithubAdapter(context),
|
|
51
18
|
});
|
package/adapters/github/index.ts
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
|
+
import { GithubAdapter } from '../../src/adapter.js';
|
|
1
2
|
/**
|
|
2
3
|
* Convention entry: discover `adapters/github/index.ts` → defineAdapter.
|
|
3
4
|
* Implementation lives under `src/` (endpoint / webhook / oauth / protocol).
|
|
4
5
|
*/
|
|
5
|
-
import { defineAdapter
|
|
6
|
-
import { httpHostToken } from '@zhin.js/host-http';
|
|
6
|
+
import { defineAdapter } from 'zhin.js/adapter';
|
|
7
7
|
import {
|
|
8
|
-
databaseHostToken,
|
|
9
|
-
type PluginDatabaseHost,
|
|
10
|
-
} from 'zhin.js';
|
|
11
|
-
import { GithubEndpoint } from '../../src/endpoint.js';
|
|
12
|
-
import { githubRuntimeStateToken } from '../../src/github-runtime-state.js';
|
|
13
|
-
import {
|
|
14
|
-
resolveGithubConfig,
|
|
15
8
|
type GithubEndpointConfig,
|
|
16
9
|
} from '../../src/protocol.js';
|
|
17
10
|
|
|
18
11
|
export { GithubEndpoint } from '../../src/endpoint.js';
|
|
19
12
|
export type { GithubEndpointOptions } from '../../src/endpoint.js';
|
|
20
13
|
|
|
21
|
-
function optionalDatabase(context: AdapterContext): PluginDatabaseHost | undefined {
|
|
22
|
-
try {
|
|
23
|
-
return context.use(databaseHostToken);
|
|
24
|
-
} catch {
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
14
|
|
|
29
15
|
export default defineAdapter<GithubEndpointConfig>({
|
|
30
16
|
capabilities: ['inbound', 'outbound'],
|
|
@@ -33,27 +19,5 @@ export default defineAdapter<GithubEndpointConfig>({
|
|
|
33
19
|
outboundMedia: ['url'],
|
|
34
20
|
interactive: 'text',
|
|
35
21
|
},
|
|
36
|
-
|
|
37
|
-
const config = resolveGithubConfig(context.config);
|
|
38
|
-
const database = optionalDatabase(context);
|
|
39
|
-
// 注册到插件运行时状态(github endpoint list 的"运行中"数据源)
|
|
40
|
-
context.use(githubRuntimeStateToken).endpoints.set(config.id, {
|
|
41
|
-
id: config.id,
|
|
42
|
-
mode: config.webhookSecret ? 'webhook' : 'api',
|
|
43
|
-
});
|
|
44
|
-
if (config.webhookSecret) {
|
|
45
|
-
return new GithubEndpoint({
|
|
46
|
-
id: context.id,
|
|
47
|
-
http: context.use(httpHostToken),
|
|
48
|
-
database,
|
|
49
|
-
config,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// API-only: Issue/PR send + agent tools without webhook.
|
|
53
|
-
return new GithubEndpoint({
|
|
54
|
-
id: context.id,
|
|
55
|
-
database,
|
|
56
|
-
config,
|
|
57
|
-
});
|
|
58
|
-
},
|
|
22
|
+
createAdapter: context => new GithubAdapter(context),
|
|
59
23
|
});
|
|
@@ -4,9 +4,9 @@ import { formatCompact } from '@zhin.js/logger';
|
|
|
4
4
|
import type { Message } from 'zhin.js';
|
|
5
5
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
6
6
|
import { GhClient } from '../../../../src/gh-client.js';
|
|
7
|
-
import type {
|
|
7
|
+
import type { GithubEndpoint } from '../../../../src/endpoint.js';
|
|
8
8
|
|
|
9
|
-
function oauthModel(client:
|
|
9
|
+
function oauthModel(client: GithubEndpoint) {
|
|
10
10
|
const db = client.database as {
|
|
11
11
|
models?: Map<string, unknown>;
|
|
12
12
|
} | null | undefined;
|
|
@@ -25,7 +25,7 @@ function depsLogger() {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export async function executeGithubBind(_args: Record<string, never>, client:
|
|
28
|
+
export async function executeGithubBind(_args: Record<string, never>, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
29
29
|
const log = depsLogger();
|
|
30
30
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
31
31
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
@@ -91,7 +91,7 @@ export async function executeGithubBind(_args: Record<string, never>, client: Gi
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
export async function executeGithubUnbind(_args: Record<string, never>, client:
|
|
94
|
+
export async function executeGithubUnbind(_args: Record<string, never>, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
95
95
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
96
96
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
97
97
|
if (!msg?.clientAdapter || !msg?.sender?.id) return t(locale, 'missingUser');
|
|
@@ -106,7 +106,7 @@ export async function executeGithubUnbind(_args: Record<string, never>, client:
|
|
|
106
106
|
return t(locale, 'unbound', { login: existing.github_login });
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
export async function executeGithubWhoami(_args: Record<string, never>, client:
|
|
109
|
+
export async function executeGithubWhoami(_args: Record<string, never>, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
110
110
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
111
111
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
112
112
|
if (!msg?.clientAdapter || !msg?.sender?.id) return t(locale, 'missingUser');
|
|
@@ -125,7 +125,7 @@ export async function executeGithubWhoami(_args: Record<string, never>, client:
|
|
|
125
125
|
return t(locale, 'expired', { login: existing.github_login });
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
export async function executeGithubInstall(client:
|
|
128
|
+
export async function executeGithubInstall(client: GithubEndpoint, locale?: Locale) {
|
|
129
129
|
const slug = client.appSlug;
|
|
130
130
|
if (!slug) return t(locale, 'missingApp');
|
|
131
131
|
const host = client.host || 'github.com';
|
|
@@ -3,7 +3,7 @@ import { createMessages, resolveLocale } from 'zhin.js/i18n';
|
|
|
3
3
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
4
4
|
import { formatChannelContext, parseMessageChannel, resolveWorkspaceBranch, } from "../../../../lib/github-channel-context.js";
|
|
5
5
|
function requireBotGh(client, locale) {
|
|
6
|
-
const gh = client
|
|
6
|
+
const gh = client;
|
|
7
7
|
if (!gh?.isAppAuth) {
|
|
8
8
|
throw new Error(t(locale, 'appRequired'));
|
|
9
9
|
}
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
parseMessageChannel,
|
|
10
10
|
resolveWorkspaceBranch,
|
|
11
11
|
} from '../../../../src/github-channel-context.js';
|
|
12
|
-
import type {
|
|
12
|
+
import type { GithubEndpoint } from '../../../../src/endpoint.js';
|
|
13
13
|
|
|
14
|
-
function requireBotGh(client:
|
|
15
|
-
const gh = client
|
|
14
|
+
function requireBotGh(client: GithubEndpoint, locale?: Locale) {
|
|
15
|
+
const gh = client;
|
|
16
16
|
if (!gh?.isAppAuth) {
|
|
17
17
|
throw new Error(t(locale, 'appRequired'));
|
|
18
18
|
}
|
|
@@ -36,7 +36,7 @@ function resolveChannel(msg: Message, repo?: string, locale?: Locale) {
|
|
|
36
36
|
|
|
37
37
|
export async function executeGithubPrepareWorkspace(
|
|
38
38
|
args: { repo?: string },
|
|
39
|
-
client:
|
|
39
|
+
client: GithubEndpoint,
|
|
40
40
|
commMessage?: Message,
|
|
41
41
|
preference?: Locale,
|
|
42
42
|
) {
|
|
@@ -57,7 +57,7 @@ export async function executeGithubPrepareWorkspace(
|
|
|
57
57
|
|
|
58
58
|
export async function executeGithubPatchFile(
|
|
59
59
|
args: { repo?: string; path: string; content: string; message: string; branch?: string },
|
|
60
|
-
client:
|
|
60
|
+
client: GithubEndpoint,
|
|
61
61
|
commMessage?: Message,
|
|
62
62
|
preference?: Locale,
|
|
63
63
|
) {
|
|
@@ -87,7 +87,7 @@ export async function executeGithubPatchFile(
|
|
|
87
87
|
|
|
88
88
|
export async function executeGithubPushBranch(
|
|
89
89
|
args: { repo?: string; branch?: string; message: string },
|
|
90
|
-
client:
|
|
90
|
+
client: GithubEndpoint,
|
|
91
91
|
commMessage?: Message,
|
|
92
92
|
preference?: Locale,
|
|
93
93
|
) {
|
|
@@ -103,7 +103,7 @@ export async function executeGithubPushBranch(
|
|
|
103
103
|
|
|
104
104
|
export async function executeGithubCreatePr(
|
|
105
105
|
args: { repo?: string; title: string; body?: string; head?: string; base?: string },
|
|
106
|
-
client:
|
|
106
|
+
client: GithubEndpoint,
|
|
107
107
|
commMessage?: Message,
|
|
108
108
|
preference?: Locale,
|
|
109
109
|
) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createMessages, resolveLocale, type Locale } from 'zhin.js/i18n';
|
|
2
2
|
import type { Message } from 'zhin.js';
|
|
3
3
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
4
|
-
import type {
|
|
4
|
+
import type { GithubEndpoint } from '../../../../src/endpoint.js';
|
|
5
5
|
import type { EventType } from '../../../../src/types.js';
|
|
6
6
|
|
|
7
|
-
function subscriptionsModel(client:
|
|
7
|
+
function subscriptionsModel(client: GithubEndpoint) {
|
|
8
8
|
const db = client.database as {
|
|
9
9
|
models?: Map<string, unknown>;
|
|
10
10
|
} | null | undefined;
|
|
@@ -16,7 +16,7 @@ function subscriptionsModel(client: GithubClient) {
|
|
|
16
16
|
} | undefined;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export async function executeGithubStar(args: { action: 'star' | 'unstar' | 'check'; repo: string }, client:
|
|
19
|
+
export async function executeGithubStar(args: { action: 'star' | 'unstar' | 'check'; repo: string }, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
20
20
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
21
21
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
22
22
|
const gh = await client.getUserOrDefaultApi(msg?.clientAdapter, msg?.sender?.id);
|
|
@@ -38,7 +38,7 @@ export async function executeGithubStar(args: { action: 'star' | 'unstar' | 'che
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export async function executeGithubSubscribe(args: { repo: string; events?: string }, client:
|
|
41
|
+
export async function executeGithubSubscribe(args: { repo: string; events?: string }, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
42
42
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
43
43
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
44
44
|
if (!msg?.clientAdapter || !msg?.sender?.id || !msg?.conversation.id || !msg?.endpointId) {
|
|
@@ -77,7 +77,7 @@ export async function executeGithubSubscribe(args: { repo: string; events?: stri
|
|
|
77
77
|
return t(locale, 'subscribed', { repo: args.repo, events: events.join(', ') });
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export async function executeGithubUnsubscribe(args: { repo: string }, client:
|
|
80
|
+
export async function executeGithubUnsubscribe(args: { repo: string }, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
81
81
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
82
82
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
83
83
|
if (!msg?.clientAdapter || !msg?.conversation.id || !msg?.endpointId) {
|
|
@@ -99,7 +99,7 @@ export async function executeGithubUnsubscribe(args: { repo: string }, client: G
|
|
|
99
99
|
return t(locale, 'unsubscribed', { repo: args.repo });
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
export async function executeGithubSubscriptions(_args: Record<string, never>, client:
|
|
102
|
+
export async function executeGithubSubscriptions(_args: Record<string, never>, client: GithubEndpoint, commMessage?: Message, preference?: Locale) {
|
|
103
103
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
104
104
|
const locale = resolveLocale(preference ?? msg?.locale);
|
|
105
105
|
if (!msg?.clientAdapter || !msg?.conversation.id || !msg?.endpointId) {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { createEndpointCommands } from 'zhin.js/adapter';
|
|
11
11
|
import { defineCommand } from 'zhin.js/command';
|
|
12
|
-
import { githubRuntimeStateToken } from "../../../lib/github-runtime-state.js";
|
|
13
12
|
export const githubEndpointCommands = createEndpointCommands({
|
|
14
13
|
adapterKey: 'github',
|
|
15
14
|
adapterDisplayName: 'GitHub',
|
|
@@ -18,6 +17,5 @@ export const githubEndpointCommands = createEndpointCommands({
|
|
|
18
17
|
{ key: 'private_key', required: true, description: 'PEM 文件路径(推荐,如 ./data/xxx.pem)或 PEM 内容', descriptionI18n: { en: "PEM file path (recommended, such as ./data/app.pem) or PEM content" } },
|
|
19
18
|
{ key: 'webhook_secret', env: true, description: 'webhook 签名密钥(不配则 API-only)', descriptionI18n: { en: "Webhook signing secret (API-only when omitted)" } },
|
|
20
19
|
],
|
|
21
|
-
running: (use) => use(githubRuntimeStateToken).endpoints.values(),
|
|
22
20
|
describeEntry: (entry) => `app_id: ${String(entry.app_id)}`,
|
|
23
21
|
}, defineCommand);
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { createEndpointCommands } from 'zhin.js/adapter';
|
|
10
10
|
import { defineCommand } from 'zhin.js/command';
|
|
11
|
-
import { githubRuntimeStateToken } from '../../../src/github-runtime-state.js';
|
|
12
11
|
|
|
13
12
|
export const githubEndpointCommands = createEndpointCommands({
|
|
14
13
|
adapterKey: 'github',
|
|
@@ -18,6 +17,5 @@ export const githubEndpointCommands = createEndpointCommands({
|
|
|
18
17
|
{ key: 'private_key', required: true, description: 'PEM 文件路径(推荐,如 ./data/xxx.pem)或 PEM 内容', descriptionI18n: { en: "PEM file path (recommended, such as ./data/app.pem) or PEM content" } },
|
|
19
18
|
{ key: 'webhook_secret', env: true, description: 'webhook 签名密钥(不配则 API-only)', descriptionI18n: { en: "Webhook signing secret (API-only when omitted)" } },
|
|
20
19
|
],
|
|
21
|
-
running: (use) => use(githubRuntimeStateToken).endpoints.values(),
|
|
22
20
|
describeEntry: (entry) => `app_id: ${String(entry.app_id)}`,
|
|
23
21
|
}, defineCommand);
|
package/lib/adapter.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
|
|
2
|
+
import { GithubEndpoint } from './endpoint.js';
|
|
3
|
+
import { type GithubEndpointConfig } from './protocol.js';
|
|
4
|
+
import type { GithubClientEventMap } from './client.js';
|
|
5
|
+
export declare class GithubAdapter extends Adapter<GithubEndpoint, GithubEndpointConfig, GithubClientEventMap> {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(context: AdapterContext<GithubEndpointConfig>);
|
|
8
|
+
get configurationIdentityFields(): readonly string[];
|
|
9
|
+
get configurationUpdateFields(): readonly string[];
|
|
10
|
+
get configurationIdentityProbeFields(): readonly string[];
|
|
11
|
+
protected identifyConfiguration(input: GithubEndpointConfig, signal: AbortSignal, _changed: readonly string[]): Promise<string | undefined>;
|
|
12
|
+
protected validateConfiguration(config: GithubEndpointConfig): void;
|
|
13
|
+
protected createEndpoint(input: GithubEndpointConfig, execution: EndpointCreationContext): GithubEndpoint;
|
|
14
|
+
}
|
|
15
|
+
declare module '@zhin.js/feature-kit' {
|
|
16
|
+
interface AdapterRegistry {
|
|
17
|
+
readonly 'github': GithubAdapter;
|
|
18
|
+
}
|
|
19
|
+
}
|
package/lib/adapter.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GhClient } from './gh-client.js';
|
|
2
|
+
import { Adapter } from 'zhin.js/adapter';
|
|
3
|
+
import { GithubEndpoint } from './endpoint.js';
|
|
4
|
+
import { resolveGithubConfig } from './protocol.js';
|
|
5
|
+
import { httpHostToken } from '@zhin.js/host-http';
|
|
6
|
+
import { databaseHostToken } from 'zhin.js';
|
|
7
|
+
export class GithubAdapter extends Adapter {
|
|
8
|
+
#context;
|
|
9
|
+
constructor(context) { super(); this.#context = context; }
|
|
10
|
+
get configurationIdentityFields() { return ['id', 'app_id', 'host']; }
|
|
11
|
+
get configurationUpdateFields() { return ['private_key', 'webhook_secret', 'webhook_path', 'auto_reply_repos', 'bot_login', 'workspace_root']; }
|
|
12
|
+
get configurationIdentityProbeFields() { return ['private_key']; }
|
|
13
|
+
async identifyConfiguration(input, signal, _changed) {
|
|
14
|
+
const config = resolveGithubConfig(input), client = new GhClient({ host: config.host, appAuth: { appId: config.appId, privateKey: config.privateKey }, signal });
|
|
15
|
+
const authenticated = await client.verifyAuth();
|
|
16
|
+
signal.throwIfAborted();
|
|
17
|
+
if (!authenticated.ok)
|
|
18
|
+
throw new Error('GitHub application identity verification failed');
|
|
19
|
+
const identity = await client.getBotIdentity();
|
|
20
|
+
signal.throwIfAborted();
|
|
21
|
+
if (!identity?.userId)
|
|
22
|
+
throw new Error('GitHub identity verification returned no bot userId');
|
|
23
|
+
return JSON.stringify(['github', config.host ?? 'github.com', identity.userId]);
|
|
24
|
+
}
|
|
25
|
+
validateConfiguration(config) { resolveGithubConfig(config); }
|
|
26
|
+
createEndpoint(input, execution) {
|
|
27
|
+
const config = resolveGithubConfig(input);
|
|
28
|
+
return new GithubEndpoint({ id: execution.canonicalId, config, ...(config.webhookSecret ? { http: this.#context.use(httpHostToken) } : {}), ...(this.#context.has?.(databaseHostToken) ? { database: this.#context.use(databaseHostToken) } : {}) });
|
|
29
|
+
}
|
|
30
|
+
}
|
package/lib/client.d.ts
CHANGED
|
@@ -1,36 +1 @@
|
|
|
1
|
-
import type { PluginDatabaseHost } from 'zhin.js';
|
|
2
|
-
import { GhClient } from './gh-client.js';
|
|
3
|
-
import type { ResolvedGithubConfig } from './protocol.js';
|
|
4
|
-
import { WorkspaceManager } from './workspace-manager.js';
|
|
5
|
-
/** GitHub SDK surface exposed to plugin handlers and Agent tools. */
|
|
6
|
-
export declare class GithubClient {
|
|
7
|
-
#private;
|
|
8
|
-
readonly name: string;
|
|
9
|
-
readonly api: GhClient;
|
|
10
|
-
readonly config: ResolvedGithubConfig;
|
|
11
|
-
readonly database?: PluginDatabaseHost | undefined;
|
|
12
|
-
constructor(name: string, api: GhClient, config: ResolvedGithubConfig, database?: PluginDatabaseHost | undefined);
|
|
13
|
-
getUserOrDefaultApi(platform?: string, platformUid?: string): Promise<GhClient>;
|
|
14
|
-
get clientId(): string | null;
|
|
15
|
-
get host(): string | undefined;
|
|
16
|
-
get appSlug(): string | null;
|
|
17
|
-
get installations(): {
|
|
18
|
-
id: number;
|
|
19
|
-
account: {
|
|
20
|
-
login: string;
|
|
21
|
-
type: string;
|
|
22
|
-
};
|
|
23
|
-
target_type: string;
|
|
24
|
-
}[];
|
|
25
|
-
get workspaceManager(): WorkspaceManager;
|
|
26
|
-
}
|
|
27
1
|
export type GithubClientEventMap = Record<string, unknown>;
|
|
28
|
-
declare module '@zhin.js/feature-kit' {
|
|
29
|
-
interface AdapterClientRegistry {
|
|
30
|
-
readonly github: {
|
|
31
|
-
readonly client: GithubClient;
|
|
32
|
-
readonly events: GithubClientEventMap;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export declare const githubClient: import("@zhin.js/adapter").EndpointClientToken<GithubClient, GithubClientEventMap>;
|
package/lib/client.js
CHANGED
|
@@ -1,44 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { lookupGithubOauthAccessToken } from './oauth-users.js';
|
|
3
|
-
import { WorkspaceManager } from './workspace-manager.js';
|
|
4
|
-
/** GitHub SDK surface exposed to plugin handlers and Agent tools. */
|
|
5
|
-
export class GithubClient {
|
|
6
|
-
name;
|
|
7
|
-
api;
|
|
8
|
-
config;
|
|
9
|
-
database;
|
|
10
|
-
#workspaceManager;
|
|
11
|
-
constructor(name, api, config, database) {
|
|
12
|
-
this.name = name;
|
|
13
|
-
this.api = api;
|
|
14
|
-
this.config = config;
|
|
15
|
-
this.database = database;
|
|
16
|
-
}
|
|
17
|
-
async getUserOrDefaultApi(platform, platformUid) {
|
|
18
|
-
if (platform && platformUid) {
|
|
19
|
-
const token = await lookupGithubOauthAccessToken(this.database, platform, platformUid);
|
|
20
|
-
if (token)
|
|
21
|
-
return this.api.withToken(token);
|
|
22
|
-
}
|
|
23
|
-
return this.api;
|
|
24
|
-
}
|
|
25
|
-
get clientId() {
|
|
26
|
-
return this.api.clientId || null;
|
|
27
|
-
}
|
|
28
|
-
get host() {
|
|
29
|
-
return this.config.host;
|
|
30
|
-
}
|
|
31
|
-
get appSlug() {
|
|
32
|
-
return this.api.appSlug || null;
|
|
33
|
-
}
|
|
34
|
-
get installations() {
|
|
35
|
-
return this.api.installations || [];
|
|
36
|
-
}
|
|
37
|
-
get workspaceManager() {
|
|
38
|
-
if (!this.#workspaceManager) {
|
|
39
|
-
this.#workspaceManager = new WorkspaceManager(this.api, this.config.workspaceRoot);
|
|
40
|
-
}
|
|
41
|
-
return this.#workspaceManager;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
export const githubClient = defineEndpointClient('github');
|
|
1
|
+
export {};
|
package/lib/console.d.ts
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { type AdapterConsoleResources } from 'zhin.js/adapter';
|
|
7
7
|
import type { PluginConsoleRpc } from 'zhin.js';
|
|
8
|
-
export declare function createGithubConsoleRpc(
|
|
8
|
+
export declare function createGithubConsoleRpc(_resources: AdapterConsoleResources, getConfig: () => unknown): PluginConsoleRpc;
|
package/lib/console.js
CHANGED
|
@@ -4,13 +4,10 @@
|
|
|
4
4
|
* 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
|
|
5
5
|
*/
|
|
6
6
|
import { createAdapterConsoleRpc } from 'zhin.js/adapter';
|
|
7
|
-
import { githubRuntimeStateToken } from './github-runtime-state.js';
|
|
8
7
|
import { githubConsoleSpec } from './console-spec.js';
|
|
9
|
-
export function createGithubConsoleRpc(
|
|
10
|
-
const state = resources.use(githubRuntimeStateToken);
|
|
8
|
+
export function createGithubConsoleRpc(_resources, getConfig) {
|
|
11
9
|
return createAdapterConsoleRpc({
|
|
12
10
|
...githubConsoleSpec,
|
|
13
|
-
running: () => state.endpoints.values(),
|
|
14
11
|
getConfig,
|
|
15
|
-
}
|
|
12
|
+
});
|
|
16
13
|
}
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,36 +1,33 @@
|
|
|
1
|
-
import { Endpoint } from 'zhin.js/adapter';
|
|
1
|
+
import { endpointSpec, type Endpoint } from 'zhin.js/adapter';
|
|
2
2
|
/**
|
|
3
3
|
* GithubEndpoint — lifecycle, outbound send, inbound admit.
|
|
4
4
|
*/
|
|
5
|
-
import { type EndpointSendRequest } from 'zhin.js/adapter';
|
|
6
5
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
7
6
|
import type { CapabilityId, PluginDatabaseHost } from 'zhin.js';
|
|
8
7
|
import { GhClient } from './gh-client.js';
|
|
9
8
|
import { type GithubInboundComment, type ResolvedGithubConfig } from './protocol.js';
|
|
10
|
-
import {
|
|
9
|
+
import { WorkspaceManager } from './workspace-manager.js';
|
|
11
10
|
export interface GithubEndpointOptions {
|
|
12
11
|
readonly id: CapabilityId;
|
|
13
12
|
readonly http?: HttpHost;
|
|
14
13
|
readonly database?: PluginDatabaseHost;
|
|
15
14
|
readonly config: ResolvedGithubConfig;
|
|
16
|
-
readonly createClient?: (config: ResolvedGithubConfig) => GhClient;
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* GitHub 是代码协作面(issue/PR),无好友/群/频道等 IM 社交概念,
|
|
20
18
|
* 不适用 EndpointManagement 语义端口;本 endpoint 不暴露该端口。
|
|
21
19
|
*/
|
|
22
|
-
export declare class GithubEndpoint extends Endpoint
|
|
20
|
+
export declare class GithubEndpoint extends GhClient implements Endpoint {
|
|
23
21
|
#private;
|
|
24
|
-
readonly
|
|
22
|
+
readonly [endpointSpec]: import("@zhin.js/adapter").EndpointSpecification;
|
|
23
|
+
get database(): PluginDatabaseHost | undefined;
|
|
24
|
+
get host(): string | undefined;
|
|
25
|
+
getUserOrDefaultApi(platform?: string, platformUid?: string): Promise<GhClient>;
|
|
26
|
+
get workspaceManager(): WorkspaceManager;
|
|
25
27
|
constructor(options: GithubEndpointOptions);
|
|
26
28
|
get config(): ResolvedGithubConfig;
|
|
27
|
-
start(): Promise<void>;
|
|
28
|
-
open(): void;
|
|
29
|
-
close(): void;
|
|
30
|
-
stop(): Promise<void>;
|
|
31
|
-
send({ conversation, payload }: EndpointSendRequest): Promise<string>;
|
|
32
29
|
/** Test / internal: admit a parsed comment when open. */
|
|
33
|
-
admit(comment: GithubInboundComment): void;
|
|
30
|
+
admit(comment: GithubInboundComment, nativeEvent?: unknown): void;
|
|
34
31
|
admitPlatform(name: string, event: unknown): void;
|
|
35
32
|
}
|
|
36
33
|
export declare function defaultCreateClient(config: ResolvedGithubConfig): GhClient;
|