opencode-channels 0.1.0

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 (121) hide show
  1. package/README.md +187 -0
  2. package/bin/cli.js +24 -0
  3. package/bin/cli.ts +62 -0
  4. package/dist/bot/auto-binding.d.ts +6 -0
  5. package/dist/bot/auto-binding.d.ts.map +1 -0
  6. package/dist/bot/auto-binding.js +81 -0
  7. package/dist/bot/auto-binding.js.map +1 -0
  8. package/dist/bot/commands/agents.d.ts +9 -0
  9. package/dist/bot/commands/agents.d.ts.map +1 -0
  10. package/dist/bot/commands/agents.js +53 -0
  11. package/dist/bot/commands/agents.js.map +1 -0
  12. package/dist/bot/commands/base.d.ts +4 -0
  13. package/dist/bot/commands/base.d.ts.map +1 -0
  14. package/dist/bot/commands/base.js +241 -0
  15. package/dist/bot/commands/base.js.map +1 -0
  16. package/dist/bot/commands/dynamic.d.ts +8 -0
  17. package/dist/bot/commands/dynamic.d.ts.map +1 -0
  18. package/dist/bot/commands/dynamic.js +82 -0
  19. package/dist/bot/commands/dynamic.js.map +1 -0
  20. package/dist/bot/commands/index.d.ts +15 -0
  21. package/dist/bot/commands/index.d.ts.map +1 -0
  22. package/dist/bot/commands/index.js +25 -0
  23. package/dist/bot/commands/index.js.map +1 -0
  24. package/dist/bot/commands/models.d.ts +7 -0
  25. package/dist/bot/commands/models.d.ts.map +1 -0
  26. package/dist/bot/commands/models.js +60 -0
  27. package/dist/bot/commands/models.js.map +1 -0
  28. package/dist/bot/commands/sdk-commands.d.ts +5 -0
  29. package/dist/bot/commands/sdk-commands.d.ts.map +1 -0
  30. package/dist/bot/commands/sdk-commands.js +135 -0
  31. package/dist/bot/commands/sdk-commands.js.map +1 -0
  32. package/dist/bot/handlers/callback.d.ts +3 -0
  33. package/dist/bot/handlers/callback.d.ts.map +1 -0
  34. package/dist/bot/handlers/callback.js +52 -0
  35. package/dist/bot/handlers/callback.js.map +1 -0
  36. package/dist/bot/handlers/file.d.ts +3 -0
  37. package/dist/bot/handlers/file.d.ts.map +1 -0
  38. package/dist/bot/handlers/file.js +121 -0
  39. package/dist/bot/handlers/file.js.map +1 -0
  40. package/dist/bot/handlers/group.d.ts +3 -0
  41. package/dist/bot/handlers/group.d.ts.map +1 -0
  42. package/dist/bot/handlers/group.js +41 -0
  43. package/dist/bot/handlers/group.js.map +1 -0
  44. package/dist/bot/handlers/index.d.ts +4 -0
  45. package/dist/bot/handlers/index.d.ts.map +1 -0
  46. package/dist/bot/handlers/index.js +13 -0
  47. package/dist/bot/handlers/index.js.map +1 -0
  48. package/dist/bot/handlers/message.d.ts +15 -0
  49. package/dist/bot/handlers/message.d.ts.map +1 -0
  50. package/dist/bot/handlers/message.js +183 -0
  51. package/dist/bot/handlers/message.js.map +1 -0
  52. package/dist/bot/handlers/topic.d.ts +3 -0
  53. package/dist/bot/handlers/topic.d.ts.map +1 -0
  54. package/dist/bot/handlers/topic.js +43 -0
  55. package/dist/bot/handlers/topic.js.map +1 -0
  56. package/dist/bot/index.d.ts +5 -0
  57. package/dist/bot/index.d.ts.map +1 -0
  58. package/dist/bot/index.js +66 -0
  59. package/dist/bot/index.js.map +1 -0
  60. package/dist/cli/daemon.d.ts +6 -0
  61. package/dist/cli/daemon.d.ts.map +1 -0
  62. package/dist/cli/daemon.js +255 -0
  63. package/dist/cli/daemon.js.map +1 -0
  64. package/dist/cli/init.d.ts +19 -0
  65. package/dist/cli/init.d.ts.map +1 -0
  66. package/dist/cli/init.js +235 -0
  67. package/dist/cli/init.js.map +1 -0
  68. package/dist/cli/logs.d.ts +6 -0
  69. package/dist/cli/logs.d.ts.map +1 -0
  70. package/dist/cli/logs.js +42 -0
  71. package/dist/cli/logs.js.map +1 -0
  72. package/dist/cli/start.d.ts +4 -0
  73. package/dist/cli/start.d.ts.map +1 -0
  74. package/dist/cli/start.js +254 -0
  75. package/dist/cli/start.js.map +1 -0
  76. package/dist/plugin/index.d.ts +4 -0
  77. package/dist/plugin/index.d.ts.map +1 -0
  78. package/dist/plugin/index.js +73 -0
  79. package/dist/plugin/index.js.map +1 -0
  80. package/dist/server/api.d.ts +3 -0
  81. package/dist/server/api.d.ts.map +1 -0
  82. package/dist/server/api.js +30 -0
  83. package/dist/server/api.js.map +1 -0
  84. package/dist/server/events.d.ts +18 -0
  85. package/dist/server/events.d.ts.map +1 -0
  86. package/dist/server/events.js +131 -0
  87. package/dist/server/events.js.map +1 -0
  88. package/dist/server/filters.d.ts +19 -0
  89. package/dist/server/filters.d.ts.map +1 -0
  90. package/dist/server/filters.js +149 -0
  91. package/dist/server/filters.js.map +1 -0
  92. package/dist/server/index.d.ts +4 -0
  93. package/dist/server/index.d.ts.map +1 -0
  94. package/dist/server/index.js +10 -0
  95. package/dist/server/index.js.map +1 -0
  96. package/dist/server/sdk.d.ts +36 -0
  97. package/dist/server/sdk.d.ts.map +1 -0
  98. package/dist/server/sdk.js +485 -0
  99. package/dist/server/sdk.js.map +1 -0
  100. package/dist/shared/config.d.ts +34 -0
  101. package/dist/shared/config.d.ts.map +1 -0
  102. package/dist/shared/config.js +163 -0
  103. package/dist/shared/config.js.map +1 -0
  104. package/dist/shared/logger.d.ts +5 -0
  105. package/dist/shared/logger.d.ts.map +1 -0
  106. package/dist/shared/logger.js +114 -0
  107. package/dist/shared/logger.js.map +1 -0
  108. package/dist/shared/mapping.d.ts +90 -0
  109. package/dist/shared/mapping.d.ts.map +1 -0
  110. package/dist/shared/mapping.js +234 -0
  111. package/dist/shared/mapping.js.map +1 -0
  112. package/dist/shared/message-queue.d.ts +64 -0
  113. package/dist/shared/message-queue.d.ts.map +1 -0
  114. package/dist/shared/message-queue.js +138 -0
  115. package/dist/shared/message-queue.js.map +1 -0
  116. package/dist/shared/types.d.ts +284 -0
  117. package/dist/shared/types.d.ts.map +1 -0
  118. package/dist/shared/types.js +7 -0
  119. package/dist/shared/types.js.map +1 -0
  120. package/index.js +1 -0
  121. package/package.json +71 -0
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # OpenCode Channels
2
+
3
+ > 将 OpenCode AI 编程助手的通知和交互扩展到 Telegram 等即时通讯平台
4
+
5
+ [![npm version](https://img.shields.io/npm/v/opencode-channels.svg)](https://www.npmjs.com/package/opencode-channels)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## 特性
9
+
10
+ - 📱 **移动端通知** - 在手机上接收任务完成、错误警告等通知
11
+ - 🔄 **远程交互** - 无需在电脑前也能响应 AI 的权限请求和问题
12
+ - 🏢 **项目隔离** - 通过 Telegram 群组和主题实现多项目、多会话管理
13
+ - ⚡ **自动化工作流** - 创建主题自动创建 OpenCode 会话
14
+
15
+ ## 快速开始
16
+
17
+ ### 安装
18
+
19
+ ```bash
20
+ npm install -g opencode-channels
21
+ ```
22
+
23
+ ### 初始化配置
24
+
25
+ ```bash
26
+ npx opencode-channels init
27
+ ```
28
+
29
+ 交互式配置向导会引导你完成:
30
+ 1. 设置工作空间目录
31
+ 2. 选择 IM 平台 (Telegram)
32
+ 3. 输入 Bot Token
33
+ 4. 配置通知选项
34
+ 5. 选择启动方式(后台服务/前台服务)
35
+
36
+ ### 启动服务
37
+
38
+ **后台服务(推荐)**:
39
+
40
+ ```bash
41
+ # 启动后台服务
42
+ npx opencode-channels daemon
43
+
44
+ # 查看服务状态
45
+ npx opencode-channels status
46
+
47
+ # 查看日志
48
+ npx opencode-channels logs
49
+
50
+ # 停止服务
51
+ npx opencode-channels stop
52
+ ```
53
+
54
+ **前台服务**:
55
+
56
+ ```bash
57
+ npx opencode-channels start
58
+ ```
59
+
60
+ ### 绑定项目
61
+
62
+ 1. 创建 Telegram 群组
63
+ 2. 添加你的 Bot 到群组
64
+ 3. Bot 会自动扫描工作空间并提示选择要绑定的项目
65
+ 4. 创建主题(Topic)会自动创建对应的 OpenCode 会话
66
+
67
+ ## 使用场景
68
+
69
+ ### 场景 1:接收任务完成通知
70
+
71
+ 当 OpenCode AI 完成任务时,你会在 Telegram 收到通知:
72
+
73
+ ```
74
+ ✅ 任务完成
75
+
76
+ 会话 ID: ses_abc123
77
+ 项目: /path/to/project
78
+ ```
79
+
80
+ ### 场景 2:远程响应权限请求
81
+
82
+ 当 AI 需要权限时,你可以在手机上直接回复:
83
+
84
+ ```
85
+ 🔐 权限请求
86
+
87
+ AI 请求执行: npm install express
88
+
89
+ 回复 'yes' 或 'no'
90
+ ```
91
+
92
+ ### 场景 3:多项目管理
93
+
94
+ - 每个 Telegram 群组绑定一个项目
95
+ - 每个主题(Topic)对应一个 OpenCode 会话
96
+ - 清晰的项目和会话隔离
97
+
98
+ ## 配置
99
+
100
+ 配置文件位于:
101
+ - Windows: `%APPDATA%\opencode\channels.json`
102
+ - macOS/Linux: `~/.config/opencode/channels.json`
103
+
104
+ 示例配置:
105
+
106
+ ```json
107
+ {
108
+ "workspace": "/Users/yang/.workspace",
109
+ "channels": {
110
+ "telegram": {
111
+ "enabled": true,
112
+ "token": "YOUR_BOT_TOKEN"
113
+ }
114
+ },
115
+ "server": {
116
+ "port": 3737,
117
+ "host": "localhost"
118
+ },
119
+ "notifications": {
120
+ "onPermission": true,
121
+ "onComplete": true,
122
+ "onError": true,
123
+ "onIdle": false
124
+ }
125
+ }
126
+ ```
127
+
128
+ ## 命令
129
+
130
+ | 命令 | 说明 |
131
+ |------|------|
132
+ | `init` | 初始化配置 |
133
+ | `start` | 启动前台服务 |
134
+ | `daemon` | 启动后台服务 |
135
+ | `status` | 查看服务状态 |
136
+ | `logs` | 查看 PM2 日志 |
137
+ | `log` | 查看本地日志文件 |
138
+ | `restart` | 重启服务 |
139
+ | `stop` | 停止服务 |
140
+
141
+ ## 架构
142
+
143
+ ```
144
+ OpenCode 项目 → 触发事件 → 全局插件 → HTTP POST → Server → Telegram Bot → 用户
145
+
146
+ 用户回复 ← Telegram ← Bot 接收 ← 解析回复 ← 调用 SDK ←────────┘
147
+ ```
148
+
149
+ ## 文档
150
+
151
+ - [快速开始指南](./QUICK-START.md)
152
+ - [Telegram 插件文档](./README-telegram.md)
153
+ - [架构设计](./docs/ARCHITECTURE.md)
154
+
155
+ ## 技术栈
156
+
157
+ - **运行时**: Bun / Node.js
158
+ - **CLI**: Commander.js + Inquirer
159
+ - **HTTP Server**: Hono
160
+ - **Telegram Bot**: grammY
161
+ - **SDK**: @opencode-ai/sdk
162
+
163
+ ## 开发
164
+
165
+ ```bash
166
+ # 安装依赖
167
+ bun install
168
+
169
+ # 开发模式
170
+ bun run dev
171
+
172
+ # 运行测试
173
+ bun test
174
+
175
+ # 构建
176
+ npm run build
177
+ ```
178
+
179
+ ## 许可证
180
+
181
+ MIT
182
+
183
+ ## 相关链接
184
+
185
+ - [OpenCode AI](https://opencode.ai)
186
+ - [GitHub Repository](https://github.com/your-username/opencode-channels)
187
+ - [问题反馈](https://github.com/your-username/opencode-channels/issues)
package/bin/cli.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { initCommand } from '../src/cli/init.js';
4
+ import { startCommand } from '../src/cli/start.js';
5
+
6
+ const program = new Command();
7
+
8
+ program
9
+ .name('opencode-channels')
10
+ .description('OpenCode Channels - Multi-channel integration for OpenCode AI')
11
+ .version('0.1.0');
12
+
13
+ program
14
+ .command('init')
15
+ .description('Initialize OpenCode Channels configuration')
16
+ .action(initCommand);
17
+
18
+ program
19
+ .command('start')
20
+ .description('Start OpenCode Channels server')
21
+ .option('-d, --daemon', 'Run as daemon')
22
+ .action(startCommand);
23
+
24
+ program.parse();
package/bin/cli.ts ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from 'commander'
3
+ import { initCommand } from '../src/cli/init.js'
4
+ import { startCommand } from '../src/cli/start.js'
5
+ import { startDaemon, stopDaemon, restartDaemon, showStatus, showLogs } from '../src/cli/daemon.js'
6
+ import { showLocalLogs } from '../src/cli/logs.js'
7
+
8
+ const program = new Command()
9
+
10
+ program
11
+ .name('opencode-channels')
12
+ .description('OpenCode Channels - Multi-channel integration for OpenCode AI')
13
+ .version('0.1.0')
14
+
15
+ program
16
+ .command('init')
17
+ .description('Initialize OpenCode Channels configuration')
18
+ .action(initCommand)
19
+
20
+ program
21
+ .command('start')
22
+ .description('Start OpenCode Channels server (foreground)')
23
+ .option('--no-daemon', 'Disable daemon mode (used internally by PM2)')
24
+ .action((options) => startCommand(options))
25
+
26
+ program
27
+ .command('daemon')
28
+ .description('Start OpenCode Channels as background service')
29
+ .action(startDaemon)
30
+
31
+ program
32
+ .command('stop')
33
+ .description('Stop background service')
34
+ .action(stopDaemon)
35
+
36
+ program
37
+ .command('restart')
38
+ .description('Restart background service')
39
+ .action(restartDaemon)
40
+
41
+ program
42
+ .command('status')
43
+ .description('Show service status')
44
+ .action(showStatus)
45
+
46
+ program
47
+ .command('logs')
48
+ .description('Show service logs (PM2 managed)')
49
+ .action(showLogs)
50
+
51
+ program
52
+ .command('log')
53
+ .description('Show local log file')
54
+ .option('-n, --lines <number>', 'Number of lines to show', '50')
55
+ .option('-f, --follow', 'Follow log output in real-time')
56
+ .option('-c, --clear', 'Clear log file')
57
+ .action((options) => {
58
+ const lines = parseInt(options.lines);
59
+ showLocalLogs({ lines, follow: options.follow, clear: options.clear });
60
+ })
61
+
62
+ program.parse()
@@ -0,0 +1,6 @@
1
+ import type { SessionInfo } from '../shared/types.js';
2
+ export declare function scanOpenCodeProjects(workspace: string): string[];
3
+ export declare function createOpenCodeSession(projectPath: string, title: string): Promise<string>;
4
+ export declare function createOpenCodeSessionWithInfo(projectPath: string, title: string): Promise<SessionInfo>;
5
+ export declare function validateProjectPath(projectPath: string): boolean;
6
+ //# sourceMappingURL=auto-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-binding.d.ts","sourceRoot":"","sources":["../../src/bot/auto-binding.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BhE;AAED,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/F;AAED,wBAAsB,6BAA6B,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAW5G;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA0BhE"}
@@ -0,0 +1,81 @@
1
+ import { createSession, createSessionWithInfo } from '../server/sdk.js';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ export function scanOpenCodeProjects(workspace) {
5
+ const projects = [];
6
+ try {
7
+ if (!fs.existsSync(workspace)) {
8
+ console.warn(`[AutoBinding] 工作空间不存在: ${workspace}`);
9
+ return projects;
10
+ }
11
+ const entries = fs.readdirSync(workspace, { withFileTypes: true });
12
+ for (const entry of entries) {
13
+ if (entry.isDirectory()) {
14
+ const projectPath = path.join(workspace, entry.name);
15
+ const gitPath = path.join(projectPath, '.git');
16
+ if (fs.existsSync(gitPath)) {
17
+ projects.push(projectPath);
18
+ console.log(`[AutoBinding] 发现项目: ${projectPath}`);
19
+ }
20
+ }
21
+ }
22
+ console.log(`[AutoBinding] 扫描完成,共发现 ${projects.length} 个项目`);
23
+ }
24
+ catch (error) {
25
+ const errorMessage = error instanceof Error ? error.message : String(error);
26
+ console.error(`[AutoBinding] 扫描项目失败: ${errorMessage}`);
27
+ }
28
+ return projects;
29
+ }
30
+ export async function createOpenCodeSession(projectPath, title) {
31
+ try {
32
+ console.log(`[AutoBinding] 为项目创建会话: ${projectPath}`);
33
+ const sessionId = await createSession(projectPath, title);
34
+ console.log(`[AutoBinding] 会话创建成功: ${sessionId}`);
35
+ return sessionId;
36
+ }
37
+ catch (error) {
38
+ const errorMessage = error instanceof Error ? error.message : String(error);
39
+ console.error(`[AutoBinding] 创建会话失败: ${errorMessage}`);
40
+ throw error;
41
+ }
42
+ }
43
+ export async function createOpenCodeSessionWithInfo(projectPath, title) {
44
+ try {
45
+ console.log(`[AutoBinding] 为项目创建会话(含配置信息): ${projectPath}`);
46
+ const sessionInfo = await createSessionWithInfo(projectPath, title);
47
+ console.log(`[AutoBinding] 会话创建成功: ${sessionInfo.sessionId}, agent: ${sessionInfo.agent}, model: ${sessionInfo.modelId}`);
48
+ return sessionInfo;
49
+ }
50
+ catch (error) {
51
+ const errorMessage = error instanceof Error ? error.message : String(error);
52
+ console.error(`[AutoBinding] 创建会话失败: ${errorMessage}`);
53
+ throw error;
54
+ }
55
+ }
56
+ export function validateProjectPath(projectPath) {
57
+ try {
58
+ if (!fs.existsSync(projectPath)) {
59
+ console.warn(`[AutoBinding] 路径不存在: ${projectPath}`);
60
+ return false;
61
+ }
62
+ const stats = fs.statSync(projectPath);
63
+ if (!stats.isDirectory()) {
64
+ console.warn(`[AutoBinding] 路径不是目录: ${projectPath}`);
65
+ return false;
66
+ }
67
+ const gitPath = path.join(projectPath, '.git');
68
+ if (!fs.existsSync(gitPath)) {
69
+ console.warn(`[AutoBinding] 项目不包含 .git 目录: ${projectPath}`);
70
+ return false;
71
+ }
72
+ console.log(`[AutoBinding] 项目路径有效: ${projectPath}`);
73
+ return true;
74
+ }
75
+ catch (error) {
76
+ const errorMessage = error instanceof Error ? error.message : String(error);
77
+ console.error(`[AutoBinding] 验证路径失败: ${errorMessage}`);
78
+ return false;
79
+ }
80
+ }
81
+ //# sourceMappingURL=auto-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-binding.js","sourceRoot":"","sources":["../../src/bot/auto-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CommandGroup } from '@grammyjs/commands';
2
+ import type { BotContext } from '../../shared/types.js';
3
+ export declare function createAgentCommands(): CommandGroup<BotContext>;
4
+ export declare function buildAgentCommandGroup(group: CommandGroup<BotContext>, projectPath: string, baseCommands: CommandGroup<BotContext>): Promise<void>;
5
+ export declare function getAgentCommandsList(agents: {
6
+ name: string;
7
+ description?: string;
8
+ }[]): string;
9
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAQxD,wBAAgB,mBAAmB,IAAI,YAAY,CAAC,UAAU,CAAC,CAE9D;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,YAAY,CAAC,UAAU,CAAC,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAS7F"}
@@ -0,0 +1,53 @@
1
+ import { CommandGroup } from '@grammyjs/commands';
2
+ import { getProjectByChat, setGroupSettings } from '../../shared/mapping.js';
3
+ import { getAgents, updateConfig } from '../../server/sdk.js';
4
+ function sanitizeCommandName(name) {
5
+ return name.toLowerCase().replace(/[^a-z0-9_]/g, '_').substring(0, 28);
6
+ }
7
+ export function createAgentCommands() {
8
+ return new CommandGroup();
9
+ }
10
+ export async function buildAgentCommandGroup(group, projectPath, baseCommands) {
11
+ const agents = await getAgents(projectPath);
12
+ if (agents.length === 0) {
13
+ return;
14
+ }
15
+ for (const agent of agents) {
16
+ const cmdName = `agent_${sanitizeCommandName(agent.name)}`;
17
+ const description = agent.description || `切换到 ${agent.name}`;
18
+ group.command(cmdName, description, async (ctx) => {
19
+ const chatId = ctx.chat?.id;
20
+ if (!chatId)
21
+ return;
22
+ const currentProject = getProjectByChat(chatId);
23
+ if (!currentProject) {
24
+ await ctx.reply('❌ 当前群组未绑定项目');
25
+ return;
26
+ }
27
+ const success = await updateConfig(currentProject, { agent: agent.name });
28
+ if (success) {
29
+ setGroupSettings(chatId, { agent: agent.name });
30
+ await ctx.setMyCommands?.(baseCommands);
31
+ await ctx.reply(`✅ 已切换到 Agent: *${agent.name}*\n\n` +
32
+ `${agent.description || ''}`, { parse_mode: 'Markdown' });
33
+ }
34
+ else {
35
+ await ctx.reply(`❌ 切换 Agent 失败`);
36
+ }
37
+ });
38
+ }
39
+ group.command('back', '返回主菜单', async (ctx) => {
40
+ await ctx.setMyCommands?.(baseCommands);
41
+ await ctx.reply('✅ 已返回主菜单');
42
+ });
43
+ }
44
+ export function getAgentCommandsList(agents) {
45
+ if (agents.length === 0) {
46
+ return '暂无可用 Agent';
47
+ }
48
+ return agents.map(a => {
49
+ const cmdName = `agent_${sanitizeCommandName(a.name)}`;
50
+ return `/${cmdName} - ${a.description || a.name}`;
51
+ }).join('\n');
52
+ }
53
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/bot/commands/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { CommandGroup } from '@grammyjs/commands';
2
+ import type { BotContext } from '../../shared/types.js';
3
+ export declare function createBaseCommands(): CommandGroup<BotContext>;
4
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA+CxD,wBAAgB,kBAAkB,IAAI,YAAY,CAAC,UAAU,CAAC,CA2P7D"}