@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
@@ -1,77 +1,124 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { createMessages, resolveLocale } from 'zhin.js/i18n';
2
3
  import { getCurrentCommMessage } from '@zhin.js/agent/security';
3
4
  import { formatChannelContext, parseMessageChannel, resolveWorkspaceBranch, } from "../../../../lib/github-channel-context.js";
4
- function requireBotGh(client) {
5
+ function requireBotGh(client, locale) {
5
6
  const gh = client.api;
6
7
  if (!gh?.isAppAuth) {
7
- throw new Error('需要 GitHub App 认证(app_id + private_key),Bot 写操作不可用');
8
+ throw new Error(t(locale, 'appRequired'));
8
9
  }
9
10
  return gh;
10
11
  }
11
- function resolveCommMessage(commMessage) {
12
+ function resolveCommMessage(commMessage, locale) {
12
13
  const msg = commMessage ?? getCurrentCommMessage();
13
14
  if (!msg)
14
- throw new Error('无 IM 上下文,请在 Issue/PR 评论线程内调用');
15
+ throw new Error(t(locale, 'contextRequired'));
15
16
  return msg;
16
17
  }
17
- function resolveChannel(msg, repo) {
18
+ function resolveChannel(msg, repo, locale) {
18
19
  const ctx = parseMessageChannel(msg);
19
20
  if (ctx)
20
21
  return ctx;
21
22
  if (repo) {
22
- throw new Error(`请从 GitHub Issue/PR 频道调用,或提供完整 channel(当前仅 repo=${repo})`);
23
+ throw new Error(t(locale, 'channelRequiredForRepo', { repo }));
23
24
  }
24
- throw new Error('无法解析 GitHub 频道(需要 Issue/PR 评论上下文)');
25
+ throw new Error(t(locale, 'channelRequired'));
25
26
  }
26
- export async function executeGithubPrepareWorkspace(args, client, commMessage) {
27
- const msg = resolveCommMessage(commMessage);
28
- const ctx = resolveChannel(msg, args.repo);
29
- const gh = requireBotGh(client);
27
+ export async function executeGithubPrepareWorkspace(args, client, commMessage, preference) {
28
+ const msg = resolveCommMessage(commMessage, preference);
29
+ const locale = resolveLocale(preference ?? msg.locale);
30
+ const ctx = resolveChannel(msg, args.repo, locale);
31
+ const gh = requireBotGh(client, locale);
30
32
  const wm = client.workspaceManager;
31
- const { branch, base } = await resolveWorkspaceBranch(gh, ctx);
32
- const repoPath = await wm.checkoutBranch(ctx.repo, branch, base);
33
+ const { branch, base } = await resolveWorkspaceBranch(gh, ctx, locale);
34
+ const repoPath = await wm.checkoutBranch(ctx.repo, branch, base, locale);
33
35
  return [
34
- `✅ 工作区就绪`,
36
+ t(locale, 'workspaceReady'),
35
37
  `📁 ${repoPath}`,
36
- `🌿 分支 \`${branch}\`(base: \`${base}\`)`,
38
+ t(locale, 'branch', { branch, base }),
37
39
  `📍 ${formatChannelContext(ctx)}`,
38
40
  ].join('\n');
39
41
  }
40
- export async function executeGithubPatchFile(args, client, commMessage) {
41
- const msg = resolveCommMessage(commMessage);
42
- const ctx = resolveChannel(msg, args.repo);
43
- const gh = requireBotGh(client);
42
+ export async function executeGithubPatchFile(args, client, commMessage, preference) {
43
+ const msg = resolveCommMessage(commMessage, preference);
44
+ const locale = resolveLocale(preference ?? msg.locale);
45
+ const ctx = resolveChannel(msg, args.repo, locale);
46
+ const gh = requireBotGh(client, locale);
44
47
  const { branch } = args.branch
45
48
  ? { branch: args.branch }
46
- : await resolveWorkspaceBranch(gh, ctx);
49
+ : await resolveWorkspaceBranch(gh, ctx, locale);
47
50
  const existing = await gh.getFileContent(ctx.repo, args.path, branch);
48
51
  const sha = existing.ok ? existing.data.sha : undefined;
49
52
  const r = await gh.createOrUpdateFile(ctx.repo, args.path, args.content, args.message, { branch, sha });
50
53
  if (!r.ok) {
51
- return `❌ 更新文件失败: ${JSON.stringify(r.data)}`;
54
+ return t(locale, 'fileFailed', { error: JSON.stringify(r.data) });
52
55
  }
53
56
  const url = r.data.content?.html_url ?? r.data.commit?.html_url ?? '';
54
- return `✅ 已更新 \`${args.path}\` @ \`${branch}\`${url ? `\n🔗 ${url}` : ''}`;
57
+ return t(locale, 'fileUpdated', { path: args.path, branch }) + (url ? `\n🔗 ${url}` : '');
55
58
  }
56
- export async function executeGithubPushBranch(args, client, commMessage) {
57
- const msg = resolveCommMessage(commMessage);
58
- const ctx = resolveChannel(msg, args.repo);
59
- const gh = requireBotGh(client);
59
+ export async function executeGithubPushBranch(args, client, commMessage, preference) {
60
+ const msg = resolveCommMessage(commMessage, preference);
61
+ const locale = resolveLocale(preference ?? msg.locale);
62
+ const ctx = resolveChannel(msg, args.repo, locale);
63
+ const gh = requireBotGh(client, locale);
60
64
  const wm = client.workspaceManager;
61
- const branch = args.branch ?? (await resolveWorkspaceBranch(gh, ctx)).branch;
62
- const result = await wm.commitAndPush(ctx.repo, branch, args.message);
65
+ const branch = args.branch ?? (await resolveWorkspaceBranch(gh, ctx, locale)).branch;
66
+ const result = await wm.commitAndPush(ctx.repo, branch, args.message, locale);
63
67
  return `✅ ${result}\n📍 ${ctx.repo} @ \`${branch}\``;
64
68
  }
65
- export async function executeGithubCreatePr(args, client, commMessage) {
66
- const msg = resolveCommMessage(commMessage);
67
- const ctx = resolveChannel(msg, args.repo);
68
- const gh = requireBotGh(client);
69
- const resolved = await resolveWorkspaceBranch(gh, ctx);
69
+ export async function executeGithubCreatePr(args, client, commMessage, preference) {
70
+ const msg = resolveCommMessage(commMessage, preference);
71
+ const locale = resolveLocale(preference ?? msg.locale);
72
+ const ctx = resolveChannel(msg, args.repo, locale);
73
+ const gh = requireBotGh(client, locale);
74
+ const resolved = await resolveWorkspaceBranch(gh, ctx, locale);
70
75
  const head = args.head ?? resolved.branch;
71
76
  const base = args.base ?? resolved.base;
72
77
  const r = await gh.createPullRequest(ctx.repo, args.title, head, base, args.body);
73
78
  if (!r.ok) {
74
- return `❌ 创建 PR 失败: ${JSON.stringify(r.data)}`;
79
+ return t(locale, 'prFailed', { error: JSON.stringify(r.data) });
75
80
  }
76
- return `✅ PR #${r.data.number} 已创建\n🔗 ${r.data.html_url}`;
81
+ return t(locale, 'prCreated', { number: r.data.number, url: r.data.html_url });
77
82
  }
83
+ const t = createMessages({
84
+ "appRequired": {
85
+ "zh-CN": "需要 GitHub App 认证(app_id + private_key),Bot 写操作不可用",
86
+ "en": "GitHub App authentication (app_id + private_key) is required for bot writes"
87
+ },
88
+ "contextRequired": {
89
+ "zh-CN": "无 IM 上下文,请在 Issue/PR 评论线程内调用",
90
+ "en": "No IM context. Use this tool from an Issue/PR comment thread"
91
+ },
92
+ "channelRequiredForRepo": {
93
+ "zh-CN": "请从 GitHub Issue/PR 频道调用,或提供完整 channel(当前仅 repo={repo})",
94
+ "en": "Use a GitHub Issue/PR channel or provide a full channel (only repo={repo} is available)"
95
+ },
96
+ "channelRequired": {
97
+ "zh-CN": "无法解析 GitHub 频道(需要 Issue/PR 评论上下文)",
98
+ "en": "Cannot resolve the GitHub channel (Issue/PR comment context is required)"
99
+ },
100
+ "workspaceReady": {
101
+ "zh-CN": "✅ 工作区就绪",
102
+ "en": "✅ Workspace ready"
103
+ },
104
+ "branch": {
105
+ "zh-CN": "🌿 分支 `{branch}`(base: `{base}`)",
106
+ "en": "🌿 Branch `{branch}` (base: `{base}`)"
107
+ },
108
+ "fileFailed": {
109
+ "zh-CN": "❌ 更新文件失败: {error}",
110
+ "en": "❌ Failed to update the file: {error}"
111
+ },
112
+ "fileUpdated": {
113
+ "zh-CN": "✅ 已更新 `{path}` @ `{branch}`",
114
+ "en": "✅ Updated `{path}` @ `{branch}`"
115
+ },
116
+ "prFailed": {
117
+ "zh-CN": "❌ 创建 PR 失败: {error}",
118
+ "en": "❌ Failed to create the PR: {error}"
119
+ },
120
+ "prCreated": {
121
+ "zh-CN": "✅ PR #{number} 已创建\n🔗 {url}",
122
+ "en": "✅ PR #{number} created\n🔗 {url}"
123
+ }
124
+ });
@@ -1,3 +1,4 @@
1
+ import { createMessages, resolveLocale, type Locale } from 'zhin.js/i18n';
1
2
  /**
2
3
  * GitHub App Bot workflow handlers (Installation Token identity).
3
4
  */
@@ -10,44 +11,46 @@ import {
10
11
  } from '../../../../src/github-channel-context.js';
11
12
  import type { GithubClient } from '../../../../src/client.js';
12
13
 
13
- function requireBotGh(client: GithubClient) {
14
+ function requireBotGh(client: GithubClient, locale?: Locale) {
14
15
  const gh = client.api;
15
16
  if (!gh?.isAppAuth) {
16
- throw new Error('需要 GitHub App 认证(app_id + private_key),Bot 写操作不可用');
17
+ throw new Error(t(locale, 'appRequired'));
17
18
  }
18
19
  return gh;
19
20
  }
20
21
 
21
- function resolveCommMessage(commMessage?: Message): Message {
22
+ function resolveCommMessage(commMessage?: Message, locale?: Locale): Message {
22
23
  const msg = commMessage ?? getCurrentCommMessage();
23
- if (!msg) throw new Error('无 IM 上下文,请在 Issue/PR 评论线程内调用');
24
+ if (!msg) throw new Error(t(locale, 'contextRequired'));
24
25
  return msg;
25
26
  }
26
27
 
27
- function resolveChannel(msg: Message, repo?: string) {
28
+ function resolveChannel(msg: Message, repo?: string, locale?: Locale) {
28
29
  const ctx = parseMessageChannel(msg);
29
30
  if (ctx) return ctx;
30
31
  if (repo) {
31
- throw new Error(`请从 GitHub Issue/PR 频道调用,或提供完整 channel(当前仅 repo=${repo})`);
32
+ throw new Error(t(locale, 'channelRequiredForRepo', { repo }));
32
33
  }
33
- throw new Error('无法解析 GitHub 频道(需要 Issue/PR 评论上下文)');
34
+ throw new Error(t(locale, 'channelRequired'));
34
35
  }
35
36
 
36
37
  export async function executeGithubPrepareWorkspace(
37
38
  args: { repo?: string },
38
39
  client: GithubClient,
39
40
  commMessage?: Message,
41
+ preference?: Locale,
40
42
  ) {
41
- const msg = resolveCommMessage(commMessage);
42
- const ctx = resolveChannel(msg, args.repo);
43
- const gh = requireBotGh(client);
43
+ const msg = resolveCommMessage(commMessage, preference);
44
+ const locale = resolveLocale(preference ?? msg.locale);
45
+ const ctx = resolveChannel(msg, args.repo, locale);
46
+ const gh = requireBotGh(client, locale);
44
47
  const wm = client.workspaceManager;
45
- const { branch, base } = await resolveWorkspaceBranch(gh, ctx);
46
- const repoPath = await wm.checkoutBranch(ctx.repo, branch, base);
48
+ const { branch, base } = await resolveWorkspaceBranch(gh, ctx, locale);
49
+ const repoPath = await wm.checkoutBranch(ctx.repo, branch, base, locale);
47
50
  return [
48
- `✅ 工作区就绪`,
51
+ t(locale, 'workspaceReady'),
49
52
  `📁 ${repoPath}`,
50
- `🌿 分支 \`${branch}\`(base: \`${base}\`)`,
53
+ t(locale, 'branch', { branch, base }),
51
54
  `📍 ${formatChannelContext(ctx)}`,
52
55
  ].join('\n');
53
56
  }
@@ -56,13 +59,15 @@ export async function executeGithubPatchFile(
56
59
  args: { repo?: string; path: string; content: string; message: string; branch?: string },
57
60
  client: GithubClient,
58
61
  commMessage?: Message,
62
+ preference?: Locale,
59
63
  ) {
60
- const msg = resolveCommMessage(commMessage);
61
- const ctx = resolveChannel(msg, args.repo);
62
- const gh = requireBotGh(client);
64
+ const msg = resolveCommMessage(commMessage, preference);
65
+ const locale = resolveLocale(preference ?? msg.locale);
66
+ const ctx = resolveChannel(msg, args.repo, locale);
67
+ const gh = requireBotGh(client, locale);
63
68
  const { branch } = args.branch
64
69
  ? { branch: args.branch }
65
- : await resolveWorkspaceBranch(gh, ctx);
70
+ : await resolveWorkspaceBranch(gh, ctx, locale);
66
71
 
67
72
  const existing = await gh.getFileContent(ctx.repo, args.path, branch);
68
73
  const sha = existing.ok ? existing.data.sha : undefined;
@@ -74,23 +79,25 @@ export async function executeGithubPatchFile(
74
79
  { branch, sha },
75
80
  );
76
81
  if (!r.ok) {
77
- return `❌ 更新文件失败: ${JSON.stringify(r.data)}`;
82
+ return t(locale, 'fileFailed', { error: JSON.stringify(r.data) });
78
83
  }
79
84
  const url = r.data.content?.html_url ?? r.data.commit?.html_url ?? '';
80
- return `✅ 已更新 \`${args.path}\` @ \`${branch}\`${url ? `\n🔗 ${url}` : ''}`;
85
+ return t(locale, 'fileUpdated', { path: args.path, branch }) + (url ? `\n🔗 ${url}` : '');
81
86
  }
82
87
 
83
88
  export async function executeGithubPushBranch(
84
89
  args: { repo?: string; branch?: string; message: string },
85
90
  client: GithubClient,
86
91
  commMessage?: Message,
92
+ preference?: Locale,
87
93
  ) {
88
- const msg = resolveCommMessage(commMessage);
89
- const ctx = resolveChannel(msg, args.repo);
90
- const gh = requireBotGh(client);
94
+ const msg = resolveCommMessage(commMessage, preference);
95
+ const locale = resolveLocale(preference ?? msg.locale);
96
+ const ctx = resolveChannel(msg, args.repo, locale);
97
+ const gh = requireBotGh(client, locale);
91
98
  const wm = client.workspaceManager;
92
- const branch = args.branch ?? (await resolveWorkspaceBranch(gh, ctx)).branch;
93
- const result = await wm.commitAndPush(ctx.repo, branch, args.message);
99
+ const branch = args.branch ?? (await resolveWorkspaceBranch(gh, ctx, locale)).branch;
100
+ const result = await wm.commitAndPush(ctx.repo, branch, args.message, locale);
94
101
  return `✅ ${result}\n📍 ${ctx.repo} @ \`${branch}\``;
95
102
  }
96
103
 
@@ -98,16 +105,61 @@ export async function executeGithubCreatePr(
98
105
  args: { repo?: string; title: string; body?: string; head?: string; base?: string },
99
106
  client: GithubClient,
100
107
  commMessage?: Message,
108
+ preference?: Locale,
101
109
  ) {
102
- const msg = resolveCommMessage(commMessage);
103
- const ctx = resolveChannel(msg, args.repo);
104
- const gh = requireBotGh(client);
105
- const resolved = await resolveWorkspaceBranch(gh, ctx);
110
+ const msg = resolveCommMessage(commMessage, preference);
111
+ const locale = resolveLocale(preference ?? msg.locale);
112
+ const ctx = resolveChannel(msg, args.repo, locale);
113
+ const gh = requireBotGh(client, locale);
114
+ const resolved = await resolveWorkspaceBranch(gh, ctx, locale);
106
115
  const head = args.head ?? resolved.branch;
107
116
  const base = args.base ?? resolved.base;
108
117
  const r = await gh.createPullRequest(ctx.repo, args.title, head, base, args.body);
109
118
  if (!r.ok) {
110
- return `❌ 创建 PR 失败: ${JSON.stringify(r.data)}`;
119
+ return t(locale, 'prFailed', { error: JSON.stringify(r.data) });
111
120
  }
112
- return `✅ PR #${r.data.number} 已创建\n🔗 ${r.data.html_url}`;
121
+ return t(locale, 'prCreated', { number: r.data.number, url: r.data.html_url });
113
122
  }
123
+
124
+ const t = createMessages({
125
+ "appRequired": {
126
+ "zh-CN": "需要 GitHub App 认证(app_id + private_key),Bot 写操作不可用",
127
+ "en": "GitHub App authentication (app_id + private_key) is required for bot writes"
128
+ },
129
+ "contextRequired": {
130
+ "zh-CN": "无 IM 上下文,请在 Issue/PR 评论线程内调用",
131
+ "en": "No IM context. Use this tool from an Issue/PR comment thread"
132
+ },
133
+ "channelRequiredForRepo": {
134
+ "zh-CN": "请从 GitHub Issue/PR 频道调用,或提供完整 channel(当前仅 repo={repo})",
135
+ "en": "Use a GitHub Issue/PR channel or provide a full channel (only repo={repo} is available)"
136
+ },
137
+ "channelRequired": {
138
+ "zh-CN": "无法解析 GitHub 频道(需要 Issue/PR 评论上下文)",
139
+ "en": "Cannot resolve the GitHub channel (Issue/PR comment context is required)"
140
+ },
141
+ "workspaceReady": {
142
+ "zh-CN": "✅ 工作区就绪",
143
+ "en": "✅ Workspace ready"
144
+ },
145
+ "branch": {
146
+ "zh-CN": "🌿 分支 `{branch}`(base: `{base}`)",
147
+ "en": "🌿 Branch `{branch}` (base: `{base}`)"
148
+ },
149
+ "fileFailed": {
150
+ "zh-CN": "❌ 更新文件失败: {error}",
151
+ "en": "❌ Failed to update the file: {error}"
152
+ },
153
+ "fileUpdated": {
154
+ "zh-CN": "✅ 已更新 `{path}` @ `{branch}`",
155
+ "en": "✅ Updated `{path}` @ `{branch}`"
156
+ },
157
+ "prFailed": {
158
+ "zh-CN": "❌ 创建 PR 失败: {error}",
159
+ "en": "❌ Failed to create the PR: {error}"
160
+ },
161
+ "prCreated": {
162
+ "zh-CN": "✅ PR #{number} 已创建\n🔗 {url}",
163
+ "en": "✅ PR #{number} created\n🔗 {url}"
164
+ }
165
+ });
@@ -15,6 +15,6 @@ export default defineAgentTool({
15
15
  tags: ['github'],
16
16
  requiresApproval: 'always',
17
17
  async execute(input, context) {
18
- return executeGithubCreatePr(input, context.$client);
18
+ return executeGithubCreatePr(input, context.$client, undefined, context.locale);
19
19
  },
20
20
  });
@@ -15,6 +15,6 @@ export default defineAgentTool<{ repo?: string; title: string; body?: string; he
15
15
  tags: ['github'],
16
16
  requiresApproval: 'always',
17
17
  async execute(input, context) {
18
- return executeGithubCreatePr(input, context.$client);
18
+ return executeGithubCreatePr(input, context.$client, undefined, context.locale);
19
19
  },
20
20
  });
@@ -14,6 +14,6 @@ export default defineAgentTool({
14
14
  }),
15
15
  tags: ['github'],
16
16
  async execute(input, context) {
17
- return executeGithubPatchFile(input, context.$client);
17
+ return executeGithubPatchFile(input, context.$client, undefined, context.locale);
18
18
  },
19
19
  });
@@ -14,6 +14,6 @@ export default defineAgentTool<{ repo?: string; path: string; content: string; m
14
14
  }),
15
15
  tags: ['github'],
16
16
  async execute(input, context) {
17
- return executeGithubPatchFile(input, context.$client);
17
+ return executeGithubPatchFile(input, context.$client, undefined, context.locale);
18
18
  },
19
19
  });
@@ -10,6 +10,6 @@ export default defineAgentTool({
10
10
  }),
11
11
  tags: ['github'],
12
12
  async execute(input, context) {
13
- return executeGithubPrepareWorkspace(input, context.$client);
13
+ return executeGithubPrepareWorkspace(input, context.$client, undefined, context.locale);
14
14
  },
15
15
  });
@@ -10,6 +10,6 @@ export default defineAgentTool<{ repo?: string }>({
10
10
  }),
11
11
  tags: ['github'],
12
12
  async execute(input, context) {
13
- return executeGithubPrepareWorkspace(input, context.$client);
13
+ return executeGithubPrepareWorkspace(input, context.$client, undefined, context.locale);
14
14
  },
15
15
  });
@@ -13,6 +13,6 @@ export default defineAgentTool({
13
13
  tags: ['github'],
14
14
  requiresApproval: 'always',
15
15
  async execute(input, context) {
16
- return executeGithubPushBranch(input, context.$client);
16
+ return executeGithubPushBranch(input, context.$client, undefined, context.locale);
17
17
  },
18
18
  });
@@ -13,6 +13,6 @@ export default defineAgentTool<{ repo?: string; branch?: string; message: string
13
13
  tags: ['github'],
14
14
  requiresApproval: 'always',
15
15
  async execute(input, context) {
16
- return executeGithubPushBranch(input, context.$client);
16
+ return executeGithubPushBranch(input, context.$client, undefined, context.locale);
17
17
  },
18
18
  });
@@ -1,43 +1,46 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { createMessages, resolveLocale } from 'zhin.js/i18n';
2
3
  import { getCurrentCommMessage } from '@zhin.js/agent/security';
3
4
  function subscriptionsModel(client) {
4
5
  const db = client.database;
5
6
  return db?.models?.get('github_subscriptions');
6
7
  }
7
- export async function executeGithubStar(args, client, commMessage) {
8
+ export async function executeGithubStar(args, client, commMessage, preference) {
8
9
  const msg = commMessage ?? getCurrentCommMessage();
10
+ const locale = resolveLocale(preference ?? msg?.locale);
9
11
  const gh = await client.getUserOrDefaultApi(msg?.clientAdapter, msg?.sender?.id);
10
12
  switch (args.action) {
11
13
  case 'star': {
12
14
  const r = await gh.starRepo(args.repo);
13
- return r.ok ? `⭐ 已 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
15
+ return r.ok ? t(locale, 'starred', { repo: args.repo }) : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
14
16
  }
15
17
  case 'unstar': {
16
18
  const r = await gh.unstarRepo(args.repo);
17
- return r.ok ? `💔 已取消 Star ${args.repo}` : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
19
+ return r.ok ? t(locale, 'unstarred', { repo: args.repo }) : `❌ ${r.data?.message || JSON.stringify(r.data)}`;
18
20
  }
19
21
  case 'check': {
20
22
  const starred = await gh.isStarred(args.repo);
21
- return starred ? `⭐ 已 Star ${args.repo}` : `☆ 尚未 Star ${args.repo}`;
23
+ return starred ? t(locale, 'starred', { repo: args.repo }) : t(locale, 'notStarred', { repo: args.repo });
22
24
  }
23
25
  default:
24
- return `❌ 未知操作: ${args.action}`;
26
+ return t(locale, 'unknownAction', { action: args.action });
25
27
  }
26
28
  }
27
- export async function executeGithubSubscribe(args, client, commMessage) {
29
+ export async function executeGithubSubscribe(args, client, commMessage, preference) {
28
30
  const msg = commMessage ?? getCurrentCommMessage();
31
+ const locale = resolveLocale(preference ?? msg?.locale);
29
32
  if (!msg?.clientAdapter || !msg?.sender?.id || !msg?.conversation.id || !msg?.endpointId) {
30
- return '❌ 无法获取当前聊天通道信息';
33
+ return t(locale, 'missingChannel');
31
34
  }
32
35
  const model = subscriptionsModel(client);
33
36
  if (!model)
34
- return '❌ 数据库未就绪';
37
+ return t(locale, 'databaseNotReady');
35
38
  const validEvents = ['push', 'issue', 'star', 'fork', 'unstar', 'pull_request'];
36
39
  const events = args.events
37
40
  ? args.events.split(',').map((s) => s.trim()).filter((e) => validEvents.includes(e))
38
41
  : validEvents;
39
42
  if (!events.length)
40
- return `❌ 无效的事件类型,可选: ${validEvents.join(', ')}`;
43
+ return t(locale, 'invalidEvents', { events: validEvents.join(', ') });
41
44
  const [existing] = await model.select().where({
42
45
  repo: args.repo,
43
46
  target_id: msg.conversation.id,
@@ -46,7 +49,7 @@ export async function executeGithubSubscribe(args, client, commMessage) {
46
49
  });
47
50
  if (existing) {
48
51
  await model.update({ events, target_type: msg.conversation.kind || 'private' }).where({ id: existing.id });
49
- return `✅ 已更新订阅 ${args.repo}\n📡 事件: ${events.join(', ')}`;
52
+ return t(locale, 'updated', { repo: args.repo, events: events.join(', ') });
50
53
  }
51
54
  await model.insert({
52
55
  id: Date.now(),
@@ -57,16 +60,17 @@ export async function executeGithubSubscribe(args, client, commMessage) {
57
60
  adapter: msg.clientAdapter,
58
61
  endpoint: msg.endpointId,
59
62
  });
60
- return `✅ 已订阅 ${args.repo}\n📡 事件: ${events.join(', ')}\n📌 通知将推送到当前通道`;
63
+ return t(locale, 'subscribed', { repo: args.repo, events: events.join(', ') });
61
64
  }
62
- export async function executeGithubUnsubscribe(args, client, commMessage) {
65
+ export async function executeGithubUnsubscribe(args, client, commMessage, preference) {
63
66
  const msg = commMessage ?? getCurrentCommMessage();
67
+ const locale = resolveLocale(preference ?? msg?.locale);
64
68
  if (!msg?.clientAdapter || !msg?.conversation.id || !msg?.endpointId) {
65
- return '❌ 无法获取当前聊天通道信息';
69
+ return t(locale, 'missingChannel');
66
70
  }
67
71
  const model = subscriptionsModel(client);
68
72
  if (!model)
69
- return '❌ 数据库未就绪';
73
+ return t(locale, 'databaseNotReady');
70
74
  const [existing] = await model.select().where({
71
75
  repo: args.repo,
72
76
  target_id: msg.conversation.id,
@@ -74,28 +78,87 @@ export async function executeGithubUnsubscribe(args, client, commMessage) {
74
78
  endpoint: msg.endpointId,
75
79
  });
76
80
  if (!existing)
77
- return `📭 当前通道未订阅 ${args.repo}`;
81
+ return t(locale, 'notSubscribed', { repo: args.repo });
78
82
  await model.delete().where({ id: existing.id });
79
- return `✅ 已取消订阅 ${args.repo}`;
83
+ return t(locale, 'unsubscribed', { repo: args.repo });
80
84
  }
81
- export async function executeGithubSubscriptions(_args, client, commMessage) {
85
+ export async function executeGithubSubscriptions(_args, client, commMessage, preference) {
82
86
  const msg = commMessage ?? getCurrentCommMessage();
87
+ const locale = resolveLocale(preference ?? msg?.locale);
83
88
  if (!msg?.clientAdapter || !msg?.conversation.id || !msg?.endpointId) {
84
- return '❌ 无法获取当前聊天通道信息';
89
+ return t(locale, 'missingChannel');
85
90
  }
86
91
  const model = subscriptionsModel(client);
87
92
  if (!model)
88
- return '❌ 数据库未就绪';
93
+ return t(locale, 'databaseNotReady');
89
94
  const subs = await model.select().where({
90
95
  target_id: msg.conversation.id,
91
96
  adapter: msg.clientAdapter,
92
97
  endpoint: msg.endpointId,
93
98
  });
94
99
  if (!subs?.length)
95
- return '📭 当前通道没有任何 GitHub 订阅';
96
- return `📋 当前通道订阅 (${subs.length}):\n\n` +
100
+ return t(locale, 'empty');
101
+ return t(locale, 'list', { count: subs.length }) +
97
102
  subs.map((s) => {
98
103
  const events = Array.isArray(s.events) ? s.events : [];
99
- return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || '(无事件)'}`;
104
+ return ` 📦 ${s.repo}\n 📡 ${events.join(', ') || t(locale, 'noEvents')}`;
100
105
  }).join('\n\n');
101
106
  }
107
+ const t = createMessages({
108
+ "starred": {
109
+ "zh-CN": "⭐ 已 Star {repo}",
110
+ "en": "⭐ Starred: {repo}"
111
+ },
112
+ "unstarred": {
113
+ "zh-CN": "💔 已取消 Star {repo}",
114
+ "en": "💔 Unstarred: {repo}"
115
+ },
116
+ "notStarred": {
117
+ "zh-CN": "☆ 尚未 Star {repo}",
118
+ "en": "☆ Not starred: {repo}"
119
+ },
120
+ "unknownAction": {
121
+ "zh-CN": "❌ 未知操作: {action}",
122
+ "en": "❌ Unknown action: {action}"
123
+ },
124
+ "missingChannel": {
125
+ "zh-CN": "❌ 无法获取当前聊天通道信息",
126
+ "en": "❌ Current chat channel is unavailable"
127
+ },
128
+ "databaseNotReady": {
129
+ "zh-CN": "❌ 数据库未就绪",
130
+ "en": "❌ Database is not ready"
131
+ },
132
+ "invalidEvents": {
133
+ "zh-CN": "❌ 无效的事件类型,可选: {events}",
134
+ "en": "❌ Invalid event types. Available: {events}"
135
+ },
136
+ "updated": {
137
+ "zh-CN": "✅ 已更新订阅 {repo}\n📡 事件: {events}",
138
+ "en": "✅ Subscription updated: {repo}\n📡 Events: {events}"
139
+ },
140
+ "subscribed": {
141
+ "zh-CN": "✅ 已订阅 {repo}\n📡 事件: {events}\n📌 通知将推送到当前通道",
142
+ "en": "✅ Subscribed to {repo}\n📡 Events: {events}\n📌 Notifications will be sent to this channel"
143
+ },
144
+ "notSubscribed": {
145
+ "zh-CN": "📭 当前通道未订阅 {repo}",
146
+ "en": "📭 This channel is not subscribed to {repo}"
147
+ },
148
+ "unsubscribed": {
149
+ "zh-CN": "✅ 已取消订阅 {repo}",
150
+ "en": "✅ Unsubscribed from {repo}"
151
+ },
152
+ "empty": {
153
+ "zh-CN": "📭 当前通道没有任何 GitHub 订阅",
154
+ "en": "📭 This channel has no GitHub subscriptions"
155
+ },
156
+ "list": {
157
+ "zh-CN": "📋 当前通道订阅 ({count}):\n\n",
158
+ "en": "📋 Channel subscriptions ({count}):\n\n"
159
+ },
160
+ "noEvents": {
161
+ "zh-CN": "(无事件)",
162
+ "en": "(no events)"
163
+ }
164
+ });