@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.
Files changed (44) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +4 -0
  3. package/agents/github/messages.js +72 -0
  4. package/agents/github/messages.ts +72 -0
  5. package/agents/github/skills/github-account/handlers.js +30 -25
  6. package/agents/github/skills/github-account/handlers.ts +30 -25
  7. package/agents/github/skills/github-account/tools/bind/index.js +1 -1
  8. package/agents/github/skills/github-account/tools/bind/index.ts +1 -1
  9. package/agents/github/skills/github-account/tools/install/index.js +1 -1
  10. package/agents/github/skills/github-account/tools/install/index.ts +1 -1
  11. package/agents/github/skills/github-account/tools/unbind/index.js +1 -1
  12. package/agents/github/skills/github-account/tools/unbind/index.ts +1 -1
  13. package/agents/github/skills/github-account/tools/whoami/index.js +1 -1
  14. package/agents/github/skills/github-account/tools/whoami/index.ts +1 -1
  15. package/agents/github/skills/github-repository/handlers.js +82 -35
  16. package/agents/github/skills/github-repository/handlers.ts +83 -31
  17. package/agents/github/skills/github-repository/tools/create_pr/index.js +1 -1
  18. package/agents/github/skills/github-repository/tools/create_pr/index.ts +1 -1
  19. package/agents/github/skills/github-repository/tools/patch_file/index.js +1 -1
  20. package/agents/github/skills/github-repository/tools/patch_file/index.ts +1 -1
  21. package/agents/github/skills/github-repository/tools/prepare_workspace/index.js +1 -1
  22. package/agents/github/skills/github-repository/tools/prepare_workspace/index.ts +1 -1
  23. package/agents/github/skills/github-repository/tools/push_branch/index.js +1 -1
  24. package/agents/github/skills/github-repository/tools/push_branch/index.ts +1 -1
  25. package/agents/github/skills/github-subscriptions/handlers.js +85 -22
  26. package/agents/github/skills/github-subscriptions/handlers.ts +86 -22
  27. package/agents/github/skills/github-subscriptions/tools/star/index.js +1 -1
  28. package/agents/github/skills/github-subscriptions/tools/star/index.ts +1 -1
  29. package/agents/github/skills/github-subscriptions/tools/subscribe/index.js +1 -1
  30. package/agents/github/skills/github-subscriptions/tools/subscribe/index.ts +1 -1
  31. package/agents/github/skills/github-subscriptions/tools/subscriptions/index.js +1 -1
  32. package/agents/github/skills/github-subscriptions/tools/subscriptions/index.ts +1 -1
  33. package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.js +1 -1
  34. package/agents/github/skills/github-subscriptions/tools/unsubscribe/index.ts +1 -1
  35. package/commands/github/endpoint/definition.js +2 -2
  36. package/commands/github/endpoint/definition.ts +2 -2
  37. package/lib/github-channel-context.d.ts +2 -1
  38. package/lib/github-channel-context.js +6 -2
  39. package/lib/workspace-manager.d.ts +8 -7
  40. package/lib/workspace-manager.js +62 -50
  41. package/package.json +19 -19
  42. package/schema.json +41 -6
  43. package/src/github-channel-context.ts +7 -1
  44. 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
@@ -109,3 +109,7 @@ github:
109
109
  ## License
110
110
 
111
111
  MIT
112
+
113
+ ## Language / 语言
114
+
115
+ 命令和工具反馈使用当前操作语言,账号绑定等异步流程固定开始时语言。用户名称、第三方内容和结构化协议字段保持原样;语言不改变权限、认证、通知或重试策略。参见[官方插件语言说明](https://github.com/zhinjs/zhin/blob/main/plugins/README.md#语言与内容)。
@@ -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 '❌ Endpoint 未配置 GitHub App 或 App 无 client_id,无法进行账号绑定';
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 `⚠️ 你已绑定 GitHub 账号: ${existing.github_login}\n如需重新绑定,请先执行 github_unbind`;
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
- `📋 输入验证码: **${codeResp.user_code}**`,
42
+ t(locale, 'deviceCode', { code: codeResp.user_code }),
40
43
  '',
41
- `⏳ 等待授权中…(${Math.floor(codeResp.expires_in / 60)} 分钟内有效)`,
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(`✅ GitHub 账号绑定成功!\n👤 ${login}`);
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 `❌ Device Flow 启动失败: ${e instanceof Error ? e.message : String(e)}`;
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 '📭 你尚未绑定 GitHub 账号';
85
+ return t(locale, 'notBound');
82
86
  await model.delete().where({ id: existing.id });
83
- return `✅ 已解除 GitHub 账号绑定: ${existing.github_login}`;
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 '📭 你尚未绑定 GitHub 账号\n🔗 使用 github_bind 绑定你的账号';
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 `👤 已绑定 GitHub 账号: ${auth.user}\n📅 绑定时间: ${new Date(existing.created_at).toLocaleString('zh-CN')}`;
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 `⚠️ 已绑定账号 ${existing.github_login},但 Token 已失效\n🔗 请执行 github_unbind 后重新 github_bind`;
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 '❌ Endpoint 未配置 GitHub App';
110
+ return t(locale, 'missingApp');
106
111
  const host = client.host || 'github.com';
107
112
  const installations = client.installations;
108
- let msg = `🔗 请点击以下链接安装 GitHub App 到你的仓库:\n https://${host}/apps/${slug}/installations/new`;
113
+ let msg = t(locale, 'install', { url: `https://${host}/apps/${slug}/installations/new` });
109
114
  if (installations.length) {
110
- msg += `\n\n📋 当前已安装 (${installations.length}):`;
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
- if (!msg?.clientAdapter || !msg?.sender?.id) return '❌ 无法获取当前用户信息';
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 '❌ Endpoint 未配置 GitHub App 或 App 无 client_id,无法进行账号绑定';
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 `⚠️ 你已绑定 GitHub 账号: ${existing.github_login}\n如需重新绑定,请先执行 github_unbind`;
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
- `📋 输入验证码: **${codeResp.user_code}**`,
56
+ t(locale, 'deviceCode', { code: codeResp.user_code }),
54
57
  '',
55
- `⏳ 等待授权中…(${Math.floor(codeResp.expires_in / 60)} 分钟内有效)`,
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(`✅ GitHub 账号绑定成功!\n👤 ${login}`);
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 `❌ Device Flow 启动失败: ${e instanceof Error ? e.message : String(e)}`;
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
- if (!msg?.clientAdapter || !msg?.sender?.id) return '❌ 无法获取当前用户信息';
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 '📭 你尚未绑定 GitHub 账号';
103
+ if (!existing) return t(locale, 'notBound');
100
104
 
101
105
  await model.delete().where({ id: existing.id });
102
- return `✅ 已解除 GitHub 账号绑定: ${existing.github_login}`;
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
- if (!msg?.clientAdapter || !msg?.sender?.id) return '❌ 无法获取当前用户信息';
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 '📭 你尚未绑定 GitHub 账号\n🔗 使用 github_bind 绑定你的账号';
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 `👤 已绑定 GitHub 账号: ${auth.user}\n📅 绑定时间: ${new Date(existing.created_at).toLocaleString('zh-CN')}`;
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 `⚠️ 已绑定账号 ${existing.github_login},但 Token 已失效\n🔗 请执行 github_unbind 后重新 github_bind`;
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 '❌ Endpoint 未配置 GitHub App';
130
+ if (!slug) return t(locale, 'missingApp');
126
131
  const host = client.host || 'github.com';
127
132
  const installations = client.installations;
128
- let msg = `🔗 请点击以下链接安装 GitHub App 到你的仓库:\n https://${host}/apps/${slug}/installations/new`;
133
+ let msg = t(locale, 'install', { url: `https://${host}/apps/${slug}/installations/new` });
129
134
  if (installations.length) {
130
- msg += `\n\n📋 当前已安装 (${installations.length}):`;
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
  }
@@ -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);
11
+ return executeGithubBind({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });
@@ -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);
11
+ return executeGithubBind({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubInstall(context.$client);
11
+ return executeGithubInstall(context.$client, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubInstall(context.$client);
11
+ return executeGithubInstall(context.$client, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubUnbind({}, context.$client);
11
+ return executeGithubUnbind({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubUnbind({}, context.$client);
11
+ return executeGithubUnbind({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubWhoami({}, context.$client);
11
+ return executeGithubWhoami({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });
@@ -8,6 +8,6 @@ export default defineAgentTool<{}>({
8
8
  inputSchema: z.object({}),
9
9
  tags: ['github'],
10
10
  async execute(input, context) {
11
- return executeGithubWhoami({}, context.$client);
11
+ return executeGithubWhoami({}, context.$client, undefined, context.locale);
12
12
  },
13
13
  });