@zhin.js/adapter-github 1.1.19 → 1.1.21
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 +36 -0
- package/lib/endpoint.js +2 -0
- package/lib/protocol.d.ts +2 -5
- package/lib/self-profile.d.ts +9 -0
- package/lib/self-profile.js +27 -0
- package/package.json +23 -23
- package/schema.json +106 -1
- package/src/endpoint.ts +2 -0
- package/src/protocol.ts +2 -1
- package/src/self-profile.ts +30 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @zhin.js/adapter-github
|
|
2
2
|
|
|
3
|
+
## 1.1.21
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- af8f803: Use the current Endpoint's platform profile for Agent account identity, with per-field configured fallbacks and scoped, identity-approved profile tools. Keep SOUL first-person and independent of account names. Profile ports preserve the source Client, cancellation, truthful update outcomes and private image authority.
|
|
8
|
+
|
|
9
|
+
Adapter Feature API 2.1 and Tool Feature API 1.1 describe the additive profile requirements; new Core, official adapters and generated plugins declare the corresponding floors. Existing compatible API-2.0/API-1.0 plugins remain accepted by the newer providers. npm releases remain patch.
|
|
10
|
+
|
|
11
|
+
Private IM assets now bind to the full canonical conversation and principal. Existing IM asset records that contain only the earlier lossy hash remain on disk until their original expiry, but cannot be safely rebound; recapture them. No automatic file deletion, platform profile mutation or workspace SOUL rewrite occurs during upgrade.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [b88e988]
|
|
14
|
+
- Updated dependencies [f78eb84]
|
|
15
|
+
- Updated dependencies [c15cef9]
|
|
16
|
+
- Updated dependencies [b0c02a2]
|
|
17
|
+
- Updated dependencies [af8f803]
|
|
18
|
+
- Updated dependencies [26fda97]
|
|
19
|
+
- Updated dependencies [976886c]
|
|
20
|
+
- Updated dependencies [032dc96]
|
|
21
|
+
- @zhin.js/adapter@1.1.27
|
|
22
|
+
- @zhin.js/client@1.1.23
|
|
23
|
+
- @zhin.js/im-contract@1.1.10
|
|
24
|
+
- @zhin.js/core@1.1.55
|
|
25
|
+
- @zhin.js/tool@1.1.14
|
|
26
|
+
- @zhin.js/page@1.1.13
|
|
27
|
+
- @zhin.js/host-http@1.1.13
|
|
28
|
+
- @zhin.js/agent-feature@1.1.12
|
|
29
|
+
- @zhin.js/feature-kit@1.1.11
|
|
30
|
+
- @zhin.js/skill@1.1.12
|
|
31
|
+
|
|
32
|
+
## 1.1.20
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [5e878ba]
|
|
37
|
+
- @zhin.js/page@1.1.12
|
|
38
|
+
|
|
3
39
|
## 1.1.19
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/lib/endpoint.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createEndpointSpecification, endpointSpec } from 'zhin.js/adapter';
|
|
2
2
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
3
3
|
import { GhClient } from './gh-client.js';
|
|
4
|
+
import { createGithubSelfProfile } from './self-profile.js';
|
|
4
5
|
import { enrichInboundContent, formatInboundContent, formatOutboundBody, githubInboundConversation, parseChannelId, } from './protocol.js';
|
|
5
6
|
import { registerGithubWebhookRoutes } from './webhook.js';
|
|
6
7
|
import { WorkspaceManager } from './workspace-manager.js';
|
|
@@ -13,6 +14,7 @@ export class GithubEndpoint extends GhClient {
|
|
|
13
14
|
[endpointSpec] = createEndpointSpecification(this, {
|
|
14
15
|
start: signal => this.#startFramework(signal), open: () => this.#openFramework(), close: () => this.#closeFramework(),
|
|
15
16
|
stop: () => this.#stopFramework(), send: request => this.#sendFramework(request),
|
|
17
|
+
profile: createGithubSelfProfile({ client: this, reportAccount: id => this[endpointSpec].reportSelfUserId(id) }),
|
|
16
18
|
});
|
|
17
19
|
#workspaceManager;
|
|
18
20
|
get database() { return this.#options.database; }
|
package/lib/protocol.d.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
* GitHub webhook / comment helpers — no legacy Adapter/Endpoint / segment-mapper.
|
|
3
|
-
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
|
-
*/
|
|
1
|
+
import type { EndpointProfileConfiguration } from 'zhin.js/adapter';
|
|
5
2
|
import type { IncomingMessage } from 'node:http';
|
|
6
3
|
import { type ConversationRef } from '@zhin.js/im-contract';
|
|
7
4
|
import { type GenericWebhookPayload, type IssueCommentPayload, type PRReviewCommentPayload, type PRReviewPayload } from './types.js';
|
|
8
5
|
export type { EventType, GenericWebhookPayload, GitHubComment, GitHubIssue, GitHubOAuthUser, GitHubPR, GitHubRepo, GitHubUser, IssueCommentPayload, ParsedChannel, PRReviewCommentPayload, PRReviewPayload, Subscription, } from './types.js';
|
|
9
6
|
export { buildChannelId, parseChannelId } from './types.js';
|
|
10
7
|
/** One expanded GitHub endpoint configuration produced by AdapterIndex. */
|
|
11
|
-
export interface GithubEndpointConfig {
|
|
8
|
+
export interface GithubEndpointConfig extends EndpointProfileConfiguration {
|
|
12
9
|
readonly id: string;
|
|
13
10
|
readonly host?: string;
|
|
14
11
|
readonly app_id: string | number;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type EndpointProfile } from 'zhin.js/adapter';
|
|
2
|
+
import type { GhClient } from './gh-client.js';
|
|
3
|
+
interface GithubSelfProfileOptions {
|
|
4
|
+
readonly client: Pick<GhClient, 'getBotIdentity' | 'request' | 'isAppAuth'>;
|
|
5
|
+
readonly reportAccount: (id: string) => void;
|
|
6
|
+
}
|
|
7
|
+
/** PAT accounts read /user; GitHub Apps read the verified app bot's public user profile. */
|
|
8
|
+
export declare function createGithubSelfProfile({ client, reportAccount }: GithubSelfProfileOptions): EndpointProfile;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createEndpointOperation } from 'zhin.js/adapter';
|
|
2
|
+
/** PAT accounts read /user; GitHub Apps read the verified app bot's public user profile. */
|
|
3
|
+
export function createGithubSelfProfile({ client, reportAccount }) {
|
|
4
|
+
return Object.freeze({
|
|
5
|
+
writableFields: Object.freeze([]),
|
|
6
|
+
async read({ signal }) {
|
|
7
|
+
const operation = createEndpointOperation({ signal });
|
|
8
|
+
const bot = await operation.prepare(() => client.getBotIdentity());
|
|
9
|
+
if (client.isAppAuth && !bot)
|
|
10
|
+
throw new Error('GitHub App bot identity is unavailable');
|
|
11
|
+
const response = await client.request({
|
|
12
|
+
method: 'GET', path: bot ? `/users/${encodeURIComponent(bot.login)}` : '/user', signal,
|
|
13
|
+
});
|
|
14
|
+
if (!response.ok)
|
|
15
|
+
throw new Error(`GitHub self profile lookup failed (${response.status}): ${response.data?.message ?? 'API request failed'}`);
|
|
16
|
+
if (!response.data?.id || typeof response.data.login !== 'string')
|
|
17
|
+
throw new Error('GitHub returned no account profile');
|
|
18
|
+
if (bot && response.data.id !== bot.userId)
|
|
19
|
+
throw new Error('GitHub returned another account profile');
|
|
20
|
+
const user = response.data;
|
|
21
|
+
reportAccount(String(user.id));
|
|
22
|
+
return { nickname: user.name || user.login,
|
|
23
|
+
...(user.bio === null || typeof user.bio === 'string' ? { bio: user.bio } : {}),
|
|
24
|
+
...(typeof user.avatar_url === 'string' ? { avatar: user.avatar_url } : {}) };
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-github",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.21",
|
|
4
4
|
"description": "Zhin.js GitHub adapter for Plugin Runtime (App auth + webhook)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -39,28 +39,28 @@
|
|
|
39
39
|
"directory": "plugins/adapters/github"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@zhin.js/adapter": "1.1.
|
|
43
|
-
"@zhin.js/agent-feature": "1.1.
|
|
44
|
-
"@zhin.js/client": "1.1.
|
|
42
|
+
"@zhin.js/adapter": "1.1.27",
|
|
43
|
+
"@zhin.js/agent-feature": "1.1.12",
|
|
44
|
+
"@zhin.js/client": "1.1.23",
|
|
45
45
|
"@zhin.js/console-contract": "1.1.3",
|
|
46
|
-
"@zhin.js/core": "1.1.
|
|
47
|
-
"@zhin.js/feature-kit": "1.1.
|
|
48
|
-
"@zhin.js/host-http": "1.1.
|
|
49
|
-
"@zhin.js/im-contract": "1.1.
|
|
46
|
+
"@zhin.js/core": "1.1.55",
|
|
47
|
+
"@zhin.js/feature-kit": "1.1.11",
|
|
48
|
+
"@zhin.js/host-http": "1.1.13",
|
|
49
|
+
"@zhin.js/im-contract": "1.1.10",
|
|
50
50
|
"@zhin.js/logger": "1.1.2",
|
|
51
|
-
"@zhin.js/page": "1.1.
|
|
52
|
-
"@zhin.js/skill": "1.1.
|
|
53
|
-
"@zhin.js/tool": "1.1.
|
|
51
|
+
"@zhin.js/page": "1.1.13",
|
|
52
|
+
"@zhin.js/skill": "1.1.12",
|
|
53
|
+
"@zhin.js/tool": "1.1.14"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"zod": "^4.0.0",
|
|
57
|
-
"@zhin.js/adapter": "^1.1.
|
|
58
|
-
"@zhin.js/agent": "^1.1.
|
|
59
|
-
"@zhin.js/command": "^1.1.
|
|
60
|
-
"@zhin.js/core": "^1.1.
|
|
61
|
-
"@zhin.js/host-http": "^1.1.
|
|
62
|
-
"@zhin.js/prompt-section": "^1.1.
|
|
63
|
-
"zhin.js": "^1.1.
|
|
57
|
+
"@zhin.js/adapter": "^1.1.27",
|
|
58
|
+
"@zhin.js/agent": "^1.1.46",
|
|
59
|
+
"@zhin.js/command": "^1.1.13",
|
|
60
|
+
"@zhin.js/core": "^1.1.55",
|
|
61
|
+
"@zhin.js/host-http": "^1.1.13",
|
|
62
|
+
"@zhin.js/prompt-section": "^1.1.11",
|
|
63
|
+
"zhin.js": "^1.1.20"
|
|
64
64
|
},
|
|
65
65
|
"peerDependenciesMeta": {
|
|
66
66
|
"@zhin.js/agent": {
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"typescript": "^6.0.3",
|
|
85
85
|
"vitest": "^4.1.10",
|
|
86
86
|
"zod": "^4.4.3",
|
|
87
|
-
"@zhin.js/agent": "1.1.
|
|
88
|
-
"@zhin.js/prompt-section": "1.1.
|
|
89
|
-
"zhin.js": "1.1.
|
|
87
|
+
"@zhin.js/agent": "1.1.46",
|
|
88
|
+
"@zhin.js/prompt-section": "1.1.11",
|
|
89
|
+
"zhin.js": "1.1.20"
|
|
90
90
|
},
|
|
91
91
|
"files": [
|
|
92
92
|
"adapters",
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"features": [
|
|
118
118
|
{
|
|
119
119
|
"package": "@zhin.js/adapter",
|
|
120
|
-
"api": "^2.
|
|
120
|
+
"api": "^2.1.0"
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"package": "@zhin.js/command",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"package": "@zhin.js/tool",
|
|
128
|
-
"api": "^1.
|
|
128
|
+
"api": "^1.1.0"
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"package": "@zhin.js/skill",
|
package/schema.json
CHANGED
|
@@ -141,6 +141,27 @@
|
|
|
141
141
|
"description": "Command prefix for this endpoint."
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
+
},
|
|
145
|
+
"nickname": {
|
|
146
|
+
"type": [
|
|
147
|
+
"string",
|
|
148
|
+
"null"
|
|
149
|
+
],
|
|
150
|
+
"description": "账号昵称兜底",
|
|
151
|
+
"x-i18n": {
|
|
152
|
+
"en": {
|
|
153
|
+
"description": "Fallback account nickname"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"profile": {
|
|
158
|
+
"$ref": "#/$defs/selfProfileFallback",
|
|
159
|
+
"description": "账号资料兜底",
|
|
160
|
+
"x-i18n": {
|
|
161
|
+
"en": {
|
|
162
|
+
"description": "Fallback account profile"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
144
165
|
}
|
|
145
166
|
},
|
|
146
167
|
"required": [
|
|
@@ -164,9 +185,93 @@
|
|
|
164
185
|
"description": "Command prefix. The default empty string allows unprefixed commands; '/' requires a leading slash. Each endpoints[i] can override it."
|
|
165
186
|
}
|
|
166
187
|
}
|
|
188
|
+
},
|
|
189
|
+
"nickname": {
|
|
190
|
+
"type": [
|
|
191
|
+
"string",
|
|
192
|
+
"null"
|
|
193
|
+
],
|
|
194
|
+
"description": "账号昵称兜底",
|
|
195
|
+
"x-i18n": {
|
|
196
|
+
"en": {
|
|
197
|
+
"description": "Fallback account nickname"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"profile": {
|
|
202
|
+
"$ref": "#/$defs/selfProfileFallback",
|
|
203
|
+
"description": "账号资料兜底",
|
|
204
|
+
"x-i18n": {
|
|
205
|
+
"en": {
|
|
206
|
+
"description": "Fallback account profile"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
167
209
|
}
|
|
168
210
|
},
|
|
169
211
|
"required": [
|
|
170
212
|
"endpoints"
|
|
171
|
-
]
|
|
213
|
+
],
|
|
214
|
+
"$defs": {
|
|
215
|
+
"selfProfileFallback": {
|
|
216
|
+
"type": "object",
|
|
217
|
+
"additionalProperties": false,
|
|
218
|
+
"properties": {
|
|
219
|
+
"gender": {
|
|
220
|
+
"type": [
|
|
221
|
+
"string",
|
|
222
|
+
"null"
|
|
223
|
+
],
|
|
224
|
+
"enum": [
|
|
225
|
+
"male",
|
|
226
|
+
"female",
|
|
227
|
+
"other",
|
|
228
|
+
"unknown",
|
|
229
|
+
null
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
"age": {
|
|
233
|
+
"type": [
|
|
234
|
+
"integer",
|
|
235
|
+
"null"
|
|
236
|
+
],
|
|
237
|
+
"minimum": 0
|
|
238
|
+
},
|
|
239
|
+
"birthday": {
|
|
240
|
+
"type": [
|
|
241
|
+
"string",
|
|
242
|
+
"null"
|
|
243
|
+
],
|
|
244
|
+
"pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$"
|
|
245
|
+
},
|
|
246
|
+
"signature": {
|
|
247
|
+
"type": [
|
|
248
|
+
"string",
|
|
249
|
+
"null"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
"avatar": {
|
|
253
|
+
"type": [
|
|
254
|
+
"string",
|
|
255
|
+
"null"
|
|
256
|
+
],
|
|
257
|
+
"pattern": "^(https?://[^\\s/?#]+(?:[/?#].*)?|)$"
|
|
258
|
+
},
|
|
259
|
+
"interests": {
|
|
260
|
+
"type": [
|
|
261
|
+
"array",
|
|
262
|
+
"null"
|
|
263
|
+
],
|
|
264
|
+
"items": {
|
|
265
|
+
"type": "string"
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
"bio": {
|
|
269
|
+
"type": [
|
|
270
|
+
"string",
|
|
271
|
+
"null"
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
172
277
|
}
|
package/src/endpoint.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
|
6
6
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
7
7
|
import type { CapabilityId, PluginDatabaseHost } from 'zhin.js';
|
|
8
8
|
import { GhClient } from './gh-client.js';
|
|
9
|
+
import { createGithubSelfProfile } from './self-profile.js';
|
|
9
10
|
import {
|
|
10
11
|
enrichInboundContent,
|
|
11
12
|
formatInboundContent,
|
|
@@ -34,6 +35,7 @@ export class GithubEndpoint extends GhClient implements Endpoint {
|
|
|
34
35
|
readonly [endpointSpec] = createEndpointSpecification(this, {
|
|
35
36
|
start: signal => this.#startFramework(signal), open: () => this.#openFramework(), close: () => this.#closeFramework(),
|
|
36
37
|
stop: () => this.#stopFramework(), send: request => this.#sendFramework(request),
|
|
38
|
+
profile: createGithubSelfProfile({ client: this, reportAccount: id => this[endpointSpec].reportSelfUserId(id) }),
|
|
37
39
|
});
|
|
38
40
|
#workspaceManager?: WorkspaceManager;
|
|
39
41
|
get database() { return this.#options.database; }
|
package/src/protocol.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EndpointProfileConfiguration } from 'zhin.js/adapter';
|
|
1
2
|
/**
|
|
2
3
|
* GitHub webhook / comment helpers — no legacy Adapter/Endpoint / segment-mapper.
|
|
3
4
|
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
@@ -36,7 +37,7 @@ export type {
|
|
|
36
37
|
export { buildChannelId, parseChannelId } from './types.js';
|
|
37
38
|
|
|
38
39
|
/** One expanded GitHub endpoint configuration produced by AdapterIndex. */
|
|
39
|
-
export interface GithubEndpointConfig {
|
|
40
|
+
export interface GithubEndpointConfig extends EndpointProfileConfiguration {
|
|
40
41
|
readonly id: string;
|
|
41
42
|
readonly host?: string;
|
|
42
43
|
readonly app_id: string | number;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createEndpointOperation, type EndpointProfile } from 'zhin.js/adapter';
|
|
2
|
+
import type { GhClient } from './gh-client.js';
|
|
3
|
+
|
|
4
|
+
interface GithubSelfProfileOptions {
|
|
5
|
+
readonly client: Pick<GhClient, 'getBotIdentity' | 'request' | 'isAppAuth'>;
|
|
6
|
+
readonly reportAccount: (id: string) => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** PAT accounts read /user; GitHub Apps read the verified app bot's public user profile. */
|
|
10
|
+
export function createGithubSelfProfile({ client, reportAccount }: GithubSelfProfileOptions): EndpointProfile {
|
|
11
|
+
return Object.freeze<EndpointProfile>({
|
|
12
|
+
writableFields: Object.freeze([]),
|
|
13
|
+
async read({ signal }) {
|
|
14
|
+
const operation = createEndpointOperation({ signal });
|
|
15
|
+
const bot = await operation.prepare(() => client.getBotIdentity());
|
|
16
|
+
if (client.isAppAuth && !bot) throw new Error('GitHub App bot identity is unavailable');
|
|
17
|
+
const response = await client.request<{ id?: number; login?: string; name?: string | null; bio?: string | null; avatar_url?: string; message?: string }>({
|
|
18
|
+
method: 'GET', path: bot ? `/users/${encodeURIComponent(bot.login)}` : '/user', signal,
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) throw new Error(`GitHub self profile lookup failed (${response.status}): ${response.data?.message ?? 'API request failed'}`);
|
|
21
|
+
if (!response.data?.id || typeof response.data.login !== 'string') throw new Error('GitHub returned no account profile');
|
|
22
|
+
if (bot && response.data.id !== bot.userId) throw new Error('GitHub returned another account profile');
|
|
23
|
+
const user = response.data;
|
|
24
|
+
reportAccount(String(user.id));
|
|
25
|
+
return { nickname: user.name || user.login,
|
|
26
|
+
...(user.bio === null || typeof user.bio === 'string' ? { bio: user.bio } : {}),
|
|
27
|
+
...(typeof user.avatar_url === 'string' ? { avatar: user.avatar_url } : {}) };
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|