@zhin.js/adapter-github 1.1.14 → 1.1.16
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 +54 -0
- package/README.md +4 -0
- package/agents/github/messages.js +72 -0
- package/agents/github/messages.ts +72 -0
- package/agents/github/skills/github-account/handlers.js +30 -25
- package/agents/github/skills/github-account/handlers.ts +30 -25
- package/agents/github/skills/github-account/tools/bind/index.js +1 -1
- package/agents/github/skills/github-account/tools/bind/index.ts +1 -1
- package/agents/github/skills/github-account/tools/install/index.js +1 -1
- package/agents/github/skills/github-account/tools/install/index.ts +1 -1
- package/agents/github/skills/github-account/tools/unbind/index.js +1 -1
- package/agents/github/skills/github-account/tools/unbind/index.ts +1 -1
- package/agents/github/skills/github-account/tools/whoami/index.js +1 -1
- package/agents/github/skills/github-account/tools/whoami/index.ts +1 -1
- package/agents/github/skills/github-repository/handlers.js +82 -35
- package/agents/github/skills/github-repository/handlers.ts +83 -31
- package/agents/github/skills/github-repository/tools/create_pr/index.js +1 -1
- package/agents/github/skills/github-repository/tools/create_pr/index.ts +1 -1
- package/agents/github/skills/github-repository/tools/patch_file/index.js +1 -1
- package/agents/github/skills/github-repository/tools/patch_file/index.ts +1 -1
- package/agents/github/skills/github-repository/tools/prepare_workspace/index.js +1 -1
- package/agents/github/skills/github-repository/tools/prepare_workspace/index.ts +1 -1
- package/agents/github/skills/github-repository/tools/push_branch/index.js +1 -1
- package/agents/github/skills/github-repository/tools/push_branch/index.ts +1 -1
- package/agents/github/skills/github-subscriptions/handlers.js +85 -22
- package/agents/github/skills/github-subscriptions/handlers.ts +86 -22
- package/agents/github/skills/github-subscriptions/tools/star/index.js +1 -1
- package/agents/github/skills/github-subscriptions/tools/star/index.ts +1 -1
- package/agents/github/skills/github-subscriptions/tools/subscribe/index.js +1 -1
- package/agents/github/skills/github-subscriptions/tools/subscribe/index.ts +1 -1
- package/agents/github/skills/github-subscriptions/tools/subscriptions/index.js +1 -1
- package/agents/github/skills/github-subscriptions/tools/subscriptions/index.ts +1 -1
- package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.js +1 -1
- package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.ts +1 -1
- package/commands/github/endpoint/definition.js +2 -2
- package/commands/github/endpoint/definition.ts +2 -2
- package/lib/github-channel-context.d.ts +2 -1
- package/lib/github-channel-context.js +6 -2
- package/lib/workspace-manager.d.ts +8 -7
- package/lib/workspace-manager.js +62 -50
- package/package.json +19 -19
- package/schema.json +41 -6
- package/src/github-channel-context.ts +7 -1
- package/src/workspace-manager.ts +62 -50
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# @zhin.js/adapter-github
|
|
2
2
|
|
|
3
|
+
## 1.1.16
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 53bc6a0: 适配器配置标签、端点命令和工具反馈支持中英文;复用当前操作语言,保持协议值、用户内容、身份、权限与发送链路不变。Sandbox 展示使用项目语言,QQ 绑定与交互状态保留完整会话身份。
|
|
8
|
+
- 9cade30: 修复国际化调用链遗漏:Agent 审批、管理命令和错误反馈采用可信语言及实际命令前缀;游戏快捷帮助、工具反馈、平台默认卡片和后台通知贯通语言。协议即时回复复用受运行代约束的个人语言查询,业务验证支持不改变审批身份的双语展示元数据。
|
|
9
|
+
|
|
10
|
+
AI 正文、进度与耗尽摘要统一优先遵从用户明确语言要求,再跟随实际输入;个人/项目语言仅作兜底,固定界面文案继续使用配置语言,不增加翻译调用。
|
|
11
|
+
|
|
12
|
+
GitHub 工作区为 Git clone/pull/fetch/ls-remote 显式分隔选项与位置参数,保留仓库和分支校验;顺序写入 Bot 名称和邮箱,避免竞争同一配置文件锁。
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [334e92d]
|
|
15
|
+
- Updated dependencies [f3b7c9f]
|
|
16
|
+
- Updated dependencies [658a5fb]
|
|
17
|
+
- Updated dependencies [144a17b]
|
|
18
|
+
- Updated dependencies [18296cf]
|
|
19
|
+
- Updated dependencies [08e64de]
|
|
20
|
+
- Updated dependencies [9cade30]
|
|
21
|
+
- Updated dependencies [53bc6a0]
|
|
22
|
+
- Updated dependencies [7595136]
|
|
23
|
+
- Updated dependencies [66b6404]
|
|
24
|
+
- Updated dependencies [adb4af2]
|
|
25
|
+
- Updated dependencies [69f9ef6]
|
|
26
|
+
- Updated dependencies [17d1301]
|
|
27
|
+
- @zhin.js/adapter@1.1.23
|
|
28
|
+
- @zhin.js/host-http@1.1.10
|
|
29
|
+
- @zhin.js/core@1.1.51
|
|
30
|
+
- @zhin.js/tool@1.1.10
|
|
31
|
+
- @zhin.js/skill@1.1.10
|
|
32
|
+
- @zhin.js/im-contract@1.1.7
|
|
33
|
+
- @zhin.js/agent-feature@1.1.10
|
|
34
|
+
- @zhin.js/feature-kit@1.1.9
|
|
35
|
+
|
|
36
|
+
## 1.1.15
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [f98025b]
|
|
41
|
+
- Updated dependencies [66ec1a5]
|
|
42
|
+
- Updated dependencies [7d68df6]
|
|
43
|
+
- Updated dependencies [bf0fa9f]
|
|
44
|
+
- Updated dependencies [3326db3]
|
|
45
|
+
- Updated dependencies [e91235e]
|
|
46
|
+
- Updated dependencies [6da2bad]
|
|
47
|
+
- Updated dependencies [3781f1c]
|
|
48
|
+
- @zhin.js/core@1.1.50
|
|
49
|
+
- @zhin.js/adapter@1.1.22
|
|
50
|
+
- @zhin.js/im-contract@1.1.6
|
|
51
|
+
- @zhin.js/tool@1.1.9
|
|
52
|
+
- @zhin.js/host-http@1.1.9
|
|
53
|
+
- @zhin.js/agent-feature@1.1.9
|
|
54
|
+
- @zhin.js/feature-kit@1.1.8
|
|
55
|
+
- @zhin.js/skill@1.1.9
|
|
56
|
+
|
|
3
57
|
## 1.1.14
|
|
4
58
|
|
|
5
59
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { createMessages } from 'zhin.js/i18n';
|
|
3
|
+
export const messages = createMessages({
|
|
4
|
+
"missingUser": {
|
|
5
|
+
"zh-CN": "❌ 无法获取当前用户信息",
|
|
6
|
+
"en": "❌ Cannot resolve the current user."
|
|
7
|
+
},
|
|
8
|
+
"missingClientId": {
|
|
9
|
+
"zh-CN": "❌ Endpoint 未配置 GitHub App 或 App 无 client_id,无法进行账号绑定",
|
|
10
|
+
"en": "❌ This endpoint has no GitHub App client_id; account linking is unavailable."
|
|
11
|
+
},
|
|
12
|
+
"dbNotReady": {
|
|
13
|
+
"zh-CN": "❌ 数据库未就绪",
|
|
14
|
+
"en": "❌ Database is not ready."
|
|
15
|
+
},
|
|
16
|
+
"alreadyBound": {
|
|
17
|
+
"zh-CN": "⚠️ 你已绑定 GitHub 账号: {login}\n如需重新绑定,请先解除绑定。",
|
|
18
|
+
"en": "⚠️ GitHub account already linked: {login}\nUnlink it before linking another account."
|
|
19
|
+
},
|
|
20
|
+
"openDeviceLink": {
|
|
21
|
+
"zh-CN": "🔗 请在浏览器中打开以下链接进行授权:",
|
|
22
|
+
"en": "🔗 Open this link in a browser to authorize:"
|
|
23
|
+
},
|
|
24
|
+
"deviceCode": {
|
|
25
|
+
"zh-CN": "📋 输入验证码: **{code}**",
|
|
26
|
+
"en": "📋 Enter this code: **{code}**"
|
|
27
|
+
},
|
|
28
|
+
"waiting": {
|
|
29
|
+
"zh-CN": "⏳ 等待授权中…({minutes} 分钟内有效)",
|
|
30
|
+
"en": "⏳ Waiting for authorization… (valid for {minutes} minutes)"
|
|
31
|
+
},
|
|
32
|
+
"bound": {
|
|
33
|
+
"zh-CN": "✅ GitHub 账号绑定成功!\n👤 {login}",
|
|
34
|
+
"en": "✅ GitHub account linked!\n👤 {login}"
|
|
35
|
+
},
|
|
36
|
+
"flowFailed": {
|
|
37
|
+
"zh-CN": "❌ Device Flow 启动失败: {error}",
|
|
38
|
+
"en": "❌ Could not start Device Flow: {error}"
|
|
39
|
+
},
|
|
40
|
+
"notBound": {
|
|
41
|
+
"zh-CN": "📭 你尚未绑定 GitHub 账号",
|
|
42
|
+
"en": "📭 No GitHub account is linked."
|
|
43
|
+
},
|
|
44
|
+
"unbound": {
|
|
45
|
+
"zh-CN": "✅ 已解除 GitHub 账号绑定: {login}",
|
|
46
|
+
"en": "✅ GitHub account unlinked: {login}"
|
|
47
|
+
},
|
|
48
|
+
"bindHint": {
|
|
49
|
+
"zh-CN": "📭 你尚未绑定 GitHub 账号\n🔗 请先发起账号绑定。",
|
|
50
|
+
"en": "📭 No GitHub account is linked.\n🔗 Start account linking first."
|
|
51
|
+
},
|
|
52
|
+
"account": {
|
|
53
|
+
"zh-CN": "👤 已绑定 GitHub 账号: {login}\n📅 绑定时间: {date}",
|
|
54
|
+
"en": "👤 Linked GitHub account: {login}\n📅 Linked at: {date}"
|
|
55
|
+
},
|
|
56
|
+
"expired": {
|
|
57
|
+
"zh-CN": "⚠️ 已绑定账号 {login},但 Token 已失效\n🔗 请先解除绑定,再重新绑定。",
|
|
58
|
+
"en": "⚠️ Account {login} is linked, but its token has expired.\n🔗 Unlink it, then link it again."
|
|
59
|
+
},
|
|
60
|
+
"missingApp": {
|
|
61
|
+
"zh-CN": "❌ Endpoint 未配置 GitHub App",
|
|
62
|
+
"en": "❌ No GitHub App is configured for this endpoint."
|
|
63
|
+
},
|
|
64
|
+
"install": {
|
|
65
|
+
"zh-CN": "🔗 请点击以下链接安装 GitHub App 到你的仓库:\n {url}",
|
|
66
|
+
"en": "🔗 Install the GitHub App in your repository using this link:\n {url}"
|
|
67
|
+
},
|
|
68
|
+
"installed": {
|
|
69
|
+
"zh-CN": "\n\n📋 当前已安装 ({count}):",
|
|
70
|
+
"en": "\n\n📋 Current installations ({count}):"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createMessages } from 'zhin.js/i18n';
|
|
2
|
+
|
|
3
|
+
export const messages = createMessages({
|
|
4
|
+
"missingUser": {
|
|
5
|
+
"zh-CN": "❌ 无法获取当前用户信息",
|
|
6
|
+
"en": "❌ Cannot resolve the current user."
|
|
7
|
+
},
|
|
8
|
+
"missingClientId": {
|
|
9
|
+
"zh-CN": "❌ Endpoint 未配置 GitHub App 或 App 无 client_id,无法进行账号绑定",
|
|
10
|
+
"en": "❌ This endpoint has no GitHub App client_id; account linking is unavailable."
|
|
11
|
+
},
|
|
12
|
+
"dbNotReady": {
|
|
13
|
+
"zh-CN": "❌ 数据库未就绪",
|
|
14
|
+
"en": "❌ Database is not ready."
|
|
15
|
+
},
|
|
16
|
+
"alreadyBound": {
|
|
17
|
+
"zh-CN": "⚠️ 你已绑定 GitHub 账号: {login}\n如需重新绑定,请先解除绑定。",
|
|
18
|
+
"en": "⚠️ GitHub account already linked: {login}\nUnlink it before linking another account."
|
|
19
|
+
},
|
|
20
|
+
"openDeviceLink": {
|
|
21
|
+
"zh-CN": "🔗 请在浏览器中打开以下链接进行授权:",
|
|
22
|
+
"en": "🔗 Open this link in a browser to authorize:"
|
|
23
|
+
},
|
|
24
|
+
"deviceCode": {
|
|
25
|
+
"zh-CN": "📋 输入验证码: **{code}**",
|
|
26
|
+
"en": "📋 Enter this code: **{code}**"
|
|
27
|
+
},
|
|
28
|
+
"waiting": {
|
|
29
|
+
"zh-CN": "⏳ 等待授权中…({minutes} 分钟内有效)",
|
|
30
|
+
"en": "⏳ Waiting for authorization… (valid for {minutes} minutes)"
|
|
31
|
+
},
|
|
32
|
+
"bound": {
|
|
33
|
+
"zh-CN": "✅ GitHub 账号绑定成功!\n👤 {login}",
|
|
34
|
+
"en": "✅ GitHub account linked!\n👤 {login}"
|
|
35
|
+
},
|
|
36
|
+
"flowFailed": {
|
|
37
|
+
"zh-CN": "❌ Device Flow 启动失败: {error}",
|
|
38
|
+
"en": "❌ Could not start Device Flow: {error}"
|
|
39
|
+
},
|
|
40
|
+
"notBound": {
|
|
41
|
+
"zh-CN": "📭 你尚未绑定 GitHub 账号",
|
|
42
|
+
"en": "📭 No GitHub account is linked."
|
|
43
|
+
},
|
|
44
|
+
"unbound": {
|
|
45
|
+
"zh-CN": "✅ 已解除 GitHub 账号绑定: {login}",
|
|
46
|
+
"en": "✅ GitHub account unlinked: {login}"
|
|
47
|
+
},
|
|
48
|
+
"bindHint": {
|
|
49
|
+
"zh-CN": "📭 你尚未绑定 GitHub 账号\n🔗 请先发起账号绑定。",
|
|
50
|
+
"en": "📭 No GitHub account is linked.\n🔗 Start account linking first."
|
|
51
|
+
},
|
|
52
|
+
"account": {
|
|
53
|
+
"zh-CN": "👤 已绑定 GitHub 账号: {login}\n📅 绑定时间: {date}",
|
|
54
|
+
"en": "👤 Linked GitHub account: {login}\n📅 Linked at: {date}"
|
|
55
|
+
},
|
|
56
|
+
"expired": {
|
|
57
|
+
"zh-CN": "⚠️ 已绑定账号 {login},但 Token 已失效\n🔗 请先解除绑定,再重新绑定。",
|
|
58
|
+
"en": "⚠️ Account {login} is linked, but its token has expired.\n🔗 Unlink it, then link it again."
|
|
59
|
+
},
|
|
60
|
+
"missingApp": {
|
|
61
|
+
"zh-CN": "❌ Endpoint 未配置 GitHub App",
|
|
62
|
+
"en": "❌ No GitHub App is configured for this endpoint."
|
|
63
|
+
},
|
|
64
|
+
"install": {
|
|
65
|
+
"zh-CN": "🔗 请点击以下链接安装 GitHub App 到你的仓库:\n {url}",
|
|
66
|
+
"en": "🔗 Install the GitHub App in your repository using this link:\n {url}"
|
|
67
|
+
},
|
|
68
|
+
"installed": {
|
|
69
|
+
"zh-CN": "\n\n📋 当前已安装 ({count}):",
|
|
70
|
+
"en": "\n\n📋 Current installations ({count}):"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { resolveLocale } from 'zhin.js/i18n';
|
|
3
|
+
import { messages as t } from "../../messages.js";
|
|
2
4
|
import { formatCompact } from '@zhin.js/logger';
|
|
3
5
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
4
6
|
import { GhClient } from "../../../../lib/gh-client.js";
|
|
@@ -13,32 +15,33 @@ function depsLogger() {
|
|
|
13
15
|
error: (...args) => console.error(...args),
|
|
14
16
|
};
|
|
15
17
|
}
|
|
16
|
-
export async function executeGithubBind(_args, client, commMessage) {
|
|
18
|
+
export async function executeGithubBind(_args, client, commMessage, preference) {
|
|
17
19
|
const log = depsLogger();
|
|
18
20
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
21
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
19
22
|
if (!msg?.clientAdapter || !msg?.sender?.id)
|
|
20
|
-
return
|
|
23
|
+
return t(locale, 'missingUser');
|
|
21
24
|
const clientId = client.clientId;
|
|
22
25
|
if (!clientId)
|
|
23
|
-
return
|
|
26
|
+
return t(locale, 'missingClientId');
|
|
24
27
|
const model = oauthModel(client);
|
|
25
28
|
if (!model)
|
|
26
|
-
return
|
|
29
|
+
return t(locale, 'dbNotReady');
|
|
27
30
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
28
31
|
if (existing) {
|
|
29
|
-
return
|
|
32
|
+
return t(locale, 'alreadyBound', { login: existing.github_login });
|
|
30
33
|
}
|
|
31
34
|
try {
|
|
32
35
|
const host = client.host;
|
|
33
36
|
const codeResp = await GhClient.deviceFlowRequestCode(clientId, host);
|
|
34
37
|
const tokenPromise = GhClient.deviceFlowPollToken(clientId, codeResp.device_code, codeResp.interval, codeResp.expires_in, host);
|
|
35
38
|
const replyMsg = [
|
|
36
|
-
|
|
39
|
+
t(locale, 'openDeviceLink'),
|
|
37
40
|
` ${codeResp.verification_uri}`,
|
|
38
41
|
'',
|
|
39
|
-
|
|
42
|
+
t(locale, 'deviceCode', { code: codeResp.user_code }),
|
|
40
43
|
'',
|
|
41
|
-
|
|
44
|
+
t(locale, 'waiting', { minutes: Math.floor(codeResp.expires_in / 60) }),
|
|
42
45
|
].join('\n');
|
|
43
46
|
tokenPromise.then(async (tokenData) => {
|
|
44
47
|
if (!tokenData) {
|
|
@@ -58,7 +61,7 @@ export async function executeGithubBind(_args, client, commMessage) {
|
|
|
58
61
|
});
|
|
59
62
|
log.debug(formatCompact({ op: 'bind', platform: msg.clientAdapter, sender: msg.sender.id, login }));
|
|
60
63
|
if (msg?.$reply) {
|
|
61
|
-
await msg.$reply(
|
|
64
|
+
await msg.$reply(t(locale, 'bound', { login }));
|
|
62
65
|
}
|
|
63
66
|
}).catch((err) => {
|
|
64
67
|
log.error('GitHub Device Flow 错误:', err);
|
|
@@ -66,48 +69,50 @@ export async function executeGithubBind(_args, client, commMessage) {
|
|
|
66
69
|
return replyMsg;
|
|
67
70
|
}
|
|
68
71
|
catch (e) {
|
|
69
|
-
return
|
|
72
|
+
return t(locale, 'flowFailed', { error: e instanceof Error ? e.message : String(e) });
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
|
-
export async function executeGithubUnbind(_args, client, commMessage) {
|
|
75
|
+
export async function executeGithubUnbind(_args, client, commMessage, preference) {
|
|
73
76
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
77
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
74
78
|
if (!msg?.clientAdapter || !msg?.sender?.id)
|
|
75
|
-
return
|
|
79
|
+
return t(locale, 'missingUser');
|
|
76
80
|
const model = oauthModel(client);
|
|
77
81
|
if (!model)
|
|
78
|
-
return
|
|
82
|
+
return t(locale, 'dbNotReady');
|
|
79
83
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
80
84
|
if (!existing)
|
|
81
|
-
return
|
|
85
|
+
return t(locale, 'notBound');
|
|
82
86
|
await model.delete().where({ id: existing.id });
|
|
83
|
-
return
|
|
87
|
+
return t(locale, 'unbound', { login: existing.github_login });
|
|
84
88
|
}
|
|
85
|
-
export async function executeGithubWhoami(_args, client, commMessage) {
|
|
89
|
+
export async function executeGithubWhoami(_args, client, commMessage, preference) {
|
|
86
90
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
91
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
87
92
|
if (!msg?.clientAdapter || !msg?.sender?.id)
|
|
88
|
-
return
|
|
93
|
+
return t(locale, 'missingUser');
|
|
89
94
|
const model = oauthModel(client);
|
|
90
95
|
if (!model)
|
|
91
|
-
return
|
|
96
|
+
return t(locale, 'dbNotReady');
|
|
92
97
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
93
98
|
if (!existing)
|
|
94
|
-
return
|
|
99
|
+
return t(locale, 'bindHint');
|
|
95
100
|
const userGh = new GhClient({ host: client.host, token: existing.access_token });
|
|
96
101
|
const auth = await userGh.verifyAuth();
|
|
97
102
|
if (auth.ok) {
|
|
98
|
-
return
|
|
103
|
+
return t(locale, 'account', { login: auth.user, date: new Date(existing.created_at).toLocaleString(locale === 'en' ? 'en-US' : 'zh-CN') });
|
|
99
104
|
}
|
|
100
|
-
return
|
|
105
|
+
return t(locale, 'expired', { login: existing.github_login });
|
|
101
106
|
}
|
|
102
|
-
export async function executeGithubInstall(client) {
|
|
107
|
+
export async function executeGithubInstall(client, locale) {
|
|
103
108
|
const slug = client.appSlug;
|
|
104
109
|
if (!slug)
|
|
105
|
-
return
|
|
110
|
+
return t(locale, 'missingApp');
|
|
106
111
|
const host = client.host || 'github.com';
|
|
107
112
|
const installations = client.installations;
|
|
108
|
-
let msg =
|
|
113
|
+
let msg = t(locale, 'install', { url: `https://${host}/apps/${slug}/installations/new` });
|
|
109
114
|
if (installations.length) {
|
|
110
|
-
msg +=
|
|
115
|
+
msg += t(locale, 'installed', { count: installations.length });
|
|
111
116
|
for (const inst of installations) {
|
|
112
117
|
msg += `\n • ${inst.account.login} (${inst.account.type})`;
|
|
113
118
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { resolveLocale, type Locale } from 'zhin.js/i18n';
|
|
2
|
+
import { messages as t } from "../../messages.js";
|
|
1
3
|
import { formatCompact } from '@zhin.js/logger';
|
|
2
4
|
import type { Message } from 'zhin.js';
|
|
3
5
|
import { getCurrentCommMessage } from '@zhin.js/agent/security';
|
|
@@ -23,20 +25,21 @@ function depsLogger() {
|
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
export async function executeGithubBind(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
|
|
28
|
+
export async function executeGithubBind(_args: Record<string, never>, client: GithubClient, commMessage?: Message, preference?: Locale) {
|
|
27
29
|
const log = depsLogger();
|
|
28
30
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
29
|
-
|
|
31
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
32
|
+
if (!msg?.clientAdapter || !msg?.sender?.id) return t(locale, 'missingUser');
|
|
30
33
|
|
|
31
34
|
const clientId = client.clientId;
|
|
32
|
-
if (!clientId) return
|
|
35
|
+
if (!clientId) return t(locale, 'missingClientId');
|
|
33
36
|
|
|
34
37
|
const model = oauthModel(client);
|
|
35
|
-
if (!model) return
|
|
38
|
+
if (!model) return t(locale, 'dbNotReady');
|
|
36
39
|
|
|
37
40
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
38
41
|
if (existing) {
|
|
39
|
-
return
|
|
42
|
+
return t(locale, 'alreadyBound', { login: existing.github_login });
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
try {
|
|
@@ -47,12 +50,12 @@ export async function executeGithubBind(_args: Record<string, never>, client: Gi
|
|
|
47
50
|
);
|
|
48
51
|
|
|
49
52
|
const replyMsg = [
|
|
50
|
-
|
|
53
|
+
t(locale, 'openDeviceLink'),
|
|
51
54
|
` ${codeResp.verification_uri}`,
|
|
52
55
|
'',
|
|
53
|
-
|
|
56
|
+
t(locale, 'deviceCode', { code: codeResp.user_code }),
|
|
54
57
|
'',
|
|
55
|
-
|
|
58
|
+
t(locale, 'waiting', { minutes: Math.floor(codeResp.expires_in / 60) }),
|
|
56
59
|
].join('\n');
|
|
57
60
|
|
|
58
61
|
tokenPromise.then(async (tokenData) => {
|
|
@@ -76,7 +79,7 @@ export async function executeGithubBind(_args: Record<string, never>, client: Gi
|
|
|
76
79
|
log.debug(formatCompact({ op: 'bind', platform: msg.clientAdapter, sender: msg.sender!.id, login }));
|
|
77
80
|
|
|
78
81
|
if (msg?.$reply) {
|
|
79
|
-
await msg.$reply(
|
|
82
|
+
await msg.$reply(t(locale, 'bound', { login }));
|
|
80
83
|
}
|
|
81
84
|
}).catch((err) => {
|
|
82
85
|
log.error('GitHub Device Flow 错误:', err);
|
|
@@ -84,50 +87,52 @@ export async function executeGithubBind(_args: Record<string, never>, client: Gi
|
|
|
84
87
|
|
|
85
88
|
return replyMsg;
|
|
86
89
|
} catch (e: unknown) {
|
|
87
|
-
return
|
|
90
|
+
return t(locale, 'flowFailed', { error: e instanceof Error ? e.message : String(e) });
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
export async function executeGithubUnbind(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
|
|
94
|
+
export async function executeGithubUnbind(_args: Record<string, never>, client: GithubClient, commMessage?: Message, preference?: Locale) {
|
|
92
95
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
93
|
-
|
|
96
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
97
|
+
if (!msg?.clientAdapter || !msg?.sender?.id) return t(locale, 'missingUser');
|
|
94
98
|
|
|
95
99
|
const model = oauthModel(client);
|
|
96
|
-
if (!model) return
|
|
100
|
+
if (!model) return t(locale, 'dbNotReady');
|
|
97
101
|
|
|
98
102
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
99
|
-
if (!existing) return
|
|
103
|
+
if (!existing) return t(locale, 'notBound');
|
|
100
104
|
|
|
101
105
|
await model.delete().where({ id: existing.id });
|
|
102
|
-
return
|
|
106
|
+
return t(locale, 'unbound', { login: existing.github_login });
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
export async function executeGithubWhoami(_args: Record<string, never>, client: GithubClient, commMessage?: Message) {
|
|
109
|
+
export async function executeGithubWhoami(_args: Record<string, never>, client: GithubClient, commMessage?: Message, preference?: Locale) {
|
|
106
110
|
const msg = commMessage ?? getCurrentCommMessage();
|
|
107
|
-
|
|
111
|
+
const locale = resolveLocale(preference ?? msg?.locale);
|
|
112
|
+
if (!msg?.clientAdapter || !msg?.sender?.id) return t(locale, 'missingUser');
|
|
108
113
|
|
|
109
114
|
const model = oauthModel(client);
|
|
110
|
-
if (!model) return
|
|
115
|
+
if (!model) return t(locale, 'dbNotReady');
|
|
111
116
|
|
|
112
117
|
const [existing] = await model.select().where({ platform: msg.clientAdapter, platform_uid: msg.sender.id });
|
|
113
|
-
if (!existing) return
|
|
118
|
+
if (!existing) return t(locale, 'bindHint');
|
|
114
119
|
|
|
115
120
|
const userGh = new GhClient({ host: client.host, token: existing.access_token });
|
|
116
121
|
const auth = await userGh.verifyAuth();
|
|
117
122
|
if (auth.ok) {
|
|
118
|
-
return
|
|
123
|
+
return t(locale, 'account', { login: auth.user, date: new Date(existing.created_at).toLocaleString(locale === 'en' ? 'en-US' : 'zh-CN') });
|
|
119
124
|
}
|
|
120
|
-
return
|
|
125
|
+
return t(locale, 'expired', { login: existing.github_login });
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
export async function executeGithubInstall(client: GithubClient) {
|
|
128
|
+
export async function executeGithubInstall(client: GithubClient, locale?: Locale) {
|
|
124
129
|
const slug = client.appSlug;
|
|
125
|
-
if (!slug) return
|
|
130
|
+
if (!slug) return t(locale, 'missingApp');
|
|
126
131
|
const host = client.host || 'github.com';
|
|
127
132
|
const installations = client.installations;
|
|
128
|
-
let msg =
|
|
133
|
+
let msg = t(locale, 'install', { url: `https://${host}/apps/${slug}/installations/new` });
|
|
129
134
|
if (installations.length) {
|
|
130
|
-
msg +=
|
|
135
|
+
msg += t(locale, 'installed', { count: installations.length });
|
|
131
136
|
for (const inst of installations) {
|
|
132
137
|
msg += `\n • ${inst.account.login} (${inst.account.type})`;
|
|
133
138
|
}
|