botmux 2.9.1 → 2.9.3
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/README.en.md +140 -76
- package/README.md +134 -75
- package/dist/adapters/backend/pty-backend.d.ts +6 -0
- package/dist/adapters/backend/pty-backend.d.ts.map +1 -1
- package/dist/adapters/backend/pty-backend.js +10 -0
- package/dist/adapters/backend/pty-backend.js.map +1 -1
- package/dist/adapters/backend/session-backend-selector.d.ts +11 -0
- package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -0
- package/dist/adapters/backend/session-backend-selector.js +26 -0
- package/dist/adapters/backend/session-backend-selector.js.map +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts +80 -3
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +301 -49
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +100 -0
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -0
- package/dist/adapters/backend/tmux-pipe-backend.js +473 -0
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -0
- package/dist/adapters/cli/aiden.d.ts.map +1 -1
- package/dist/adapters/cli/aiden.js +5 -0
- package/dist/adapters/cli/aiden.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts +40 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +470 -49
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/coco.d.ts.map +1 -1
- package/dist/adapters/cli/coco.js +191 -9
- package/dist/adapters/cli/coco.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +94 -17
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +2 -2
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +7 -5
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +38 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/autostart.d.ts +14 -0
- package/dist/autostart.d.ts.map +1 -0
- package/dist/autostart.js +357 -0
- package/dist/autostart.js.map +1 -0
- package/dist/bot-registry.d.ts +29 -3
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +91 -12
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/arg-utils.d.ts +11 -0
- package/dist/cli/arg-utils.d.ts.map +1 -0
- package/dist/cli/arg-utils.js +25 -0
- package/dist/cli/arg-utils.js.map +1 -0
- package/dist/cli/create-group-resolver.d.ts +32 -0
- package/dist/cli/create-group-resolver.d.ts.map +1 -0
- package/dist/cli/create-group-resolver.js +70 -0
- package/dist/cli/create-group-resolver.js.map +1 -0
- package/dist/cli/quoted-render.d.ts +30 -0
- package/dist/cli/quoted-render.d.ts.map +1 -0
- package/dist/cli/quoted-render.js +29 -0
- package/dist/cli/quoted-render.js.map +1 -0
- package/dist/cli.js +916 -272
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -8
- package/dist/config.js.map +1 -1
- package/dist/core/command-handler.d.ts +43 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +167 -64
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-events.d.ts +57 -0
- package/dist/core/dashboard-events.d.ts.map +1 -0
- package/dist/core/dashboard-events.js +23 -0
- package/dist/core/dashboard-events.js.map +1 -0
- package/dist/core/dashboard-ipc-server.d.ts +43 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -0
- package/dist/core/dashboard-ipc-server.js +481 -0
- package/dist/core/dashboard-ipc-server.js.map +1 -0
- package/dist/core/dashboard-locate.d.ts +20 -0
- package/dist/core/dashboard-locate.d.ts.map +1 -0
- package/dist/core/dashboard-locate.js +26 -0
- package/dist/core/dashboard-locate.js.map +1 -0
- package/dist/core/dashboard-rows.d.ts +31 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -0
- package/dist/core/dashboard-rows.js +65 -0
- package/dist/core/dashboard-rows.js.map +1 -0
- package/dist/core/inherit-peer.d.ts +14 -0
- package/dist/core/inherit-peer.d.ts.map +1 -0
- package/dist/core/inherit-peer.js +32 -0
- package/dist/core/inherit-peer.js.map +1 -0
- package/dist/core/scheduler.d.ts +24 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +93 -2
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-activity.d.ts +3 -0
- package/dist/core/session-activity.d.ts.map +1 -0
- package/dist/core/session-activity.js +20 -0
- package/dist/core/session-activity.js.map +1 -0
- package/dist/core/session-discovery.d.ts +39 -0
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +114 -21
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +72 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +396 -106
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +27 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +14 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +72 -3
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +459 -38
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +645 -314
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/aggregator.d.ts +41 -0
- package/dist/dashboard/aggregator.d.ts.map +1 -0
- package/dist/dashboard/aggregator.js +125 -0
- package/dist/dashboard/aggregator.js.map +1 -0
- package/dist/dashboard/auth.d.ts +23 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +66 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/operator-selector.d.ts +20 -0
- package/dist/dashboard/operator-selector.d.ts.map +1 -0
- package/dist/dashboard/operator-selector.js +39 -0
- package/dist/dashboard/operator-selector.js.map +1 -0
- package/dist/dashboard/registry.d.ts +35 -0
- package/dist/dashboard/registry.d.ts.map +1 -0
- package/dist/dashboard/registry.js +74 -0
- package/dist/dashboard/registry.js.map +1 -0
- package/dist/dashboard/web/app.d.ts +2 -0
- package/dist/dashboard/web/app.d.ts.map +1 -0
- package/dist/dashboard/web/app.js +45 -0
- package/dist/dashboard/web/app.js.map +1 -0
- package/dist/dashboard/web/bot-defaults.d.ts +2 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -0
- package/dist/dashboard/web/bot-defaults.js +201 -0
- package/dist/dashboard/web/bot-defaults.js.map +1 -0
- package/dist/dashboard/web/groups.d.ts +16 -0
- package/dist/dashboard/web/groups.d.ts.map +1 -0
- package/dist/dashboard/web/groups.js +584 -0
- package/dist/dashboard/web/groups.js.map +1 -0
- package/dist/dashboard/web/schedules.d.ts +2 -0
- package/dist/dashboard/web/schedules.d.ts.map +1 -0
- package/dist/dashboard/web/schedules.js +105 -0
- package/dist/dashboard/web/schedules.js.map +1 -0
- package/dist/dashboard/web/sessions.d.ts +2 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -0
- package/dist/dashboard/web/sessions.js +374 -0
- package/dist/dashboard/web/sessions.js.map +1 -0
- package/dist/dashboard/web/store.d.ts +23 -0
- package/dist/dashboard/web/store.d.ts.map +1 -0
- package/dist/dashboard/web/store.js +82 -0
- package/dist/dashboard/web/store.js.map +1 -0
- package/dist/dashboard-web/app.js +263 -0
- package/dist/dashboard-web/index.html +23 -0
- package/dist/dashboard-web/style.css +93 -0
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +639 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +18 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +70 -9
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +123 -109
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +35 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +114 -11
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +88 -6
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +398 -62
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/forwarded-renderer.d.ts +23 -0
- package/dist/im/lark/forwarded-renderer.d.ts.map +1 -0
- package/dist/im/lark/forwarded-renderer.js +105 -0
- package/dist/im/lark/forwarded-renderer.js.map +1 -0
- package/dist/im/lark/md-card.d.ts +73 -0
- package/dist/im/lark/md-card.d.ts.map +1 -0
- package/dist/im/lark/md-card.js +332 -0
- package/dist/im/lark/md-card.js.map +1 -0
- package/dist/im/lark/merge-forward.d.ts +32 -0
- package/dist/im/lark/merge-forward.d.ts.map +1 -0
- package/dist/im/lark/merge-forward.js +110 -0
- package/dist/im/lark/merge-forward.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +9 -3
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +48 -13
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/quote-hint.d.ts +18 -0
- package/dist/im/lark/quote-hint.d.ts.map +1 -0
- package/dist/im/lark/quote-hint.js +23 -0
- package/dist/im/lark/quote-hint.js.map +1 -0
- package/dist/services/bridge-fallback-gate.d.ts +42 -0
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -0
- package/dist/services/bridge-fallback-gate.js +12 -0
- package/dist/services/bridge-fallback-gate.js.map +1 -0
- package/dist/services/bridge-rotation-policy.d.ts +139 -0
- package/dist/services/bridge-rotation-policy.d.ts.map +1 -0
- package/dist/services/bridge-rotation-policy.js +125 -0
- package/dist/services/bridge-rotation-policy.js.map +1 -0
- package/dist/services/bridge-turn-queue.d.ts +154 -0
- package/dist/services/bridge-turn-queue.d.ts.map +1 -0
- package/dist/services/bridge-turn-queue.js +316 -0
- package/dist/services/bridge-turn-queue.js.map +1 -0
- package/dist/services/chat-first-seen-store.d.ts +27 -0
- package/dist/services/chat-first-seen-store.d.ts.map +1 -0
- package/dist/services/chat-first-seen-store.js +114 -0
- package/dist/services/chat-first-seen-store.js.map +1 -0
- package/dist/services/claude-transcript.d.ts +268 -0
- package/dist/services/claude-transcript.d.ts.map +1 -0
- package/dist/services/claude-transcript.js +798 -0
- package/dist/services/claude-transcript.js.map +1 -0
- package/dist/services/coco-transcript.d.ts +35 -0
- package/dist/services/coco-transcript.d.ts.map +1 -0
- package/dist/services/coco-transcript.js +192 -0
- package/dist/services/coco-transcript.js.map +1 -0
- package/dist/services/codex-bridge-queue.d.ts +56 -0
- package/dist/services/codex-bridge-queue.d.ts.map +1 -0
- package/dist/services/codex-bridge-queue.js +150 -0
- package/dist/services/codex-bridge-queue.js.map +1 -0
- package/dist/services/codex-transcript.d.ts +84 -0
- package/dist/services/codex-transcript.d.ts.map +1 -0
- package/dist/services/codex-transcript.js +298 -0
- package/dist/services/codex-transcript.js.map +1 -0
- package/dist/services/group-creator.d.ts +23 -0
- package/dist/services/group-creator.d.ts.map +1 -0
- package/dist/services/group-creator.js +75 -0
- package/dist/services/group-creator.js.map +1 -0
- package/dist/services/groups-store.d.ts +98 -0
- package/dist/services/groups-store.d.ts.map +1 -0
- package/dist/services/groups-store.js +213 -0
- package/dist/services/groups-store.js.map +1 -0
- package/dist/services/oncall-store.d.ts +80 -8
- package/dist/services/oncall-store.d.ts.map +1 -1
- package/dist/services/oncall-store.js +265 -55
- package/dist/services/oncall-store.js.map +1 -1
- package/dist/services/project-scanner.d.ts +1 -2
- package/dist/services/project-scanner.d.ts.map +1 -1
- package/dist/services/project-scanner.js +118 -68
- package/dist/services/project-scanner.js.map +1 -1
- package/dist/services/schedule-store.d.ts +5 -0
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +77 -1
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/services/session-store.d.ts +22 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +62 -4
- package/dist/services/session-store.js.map +1 -1
- package/dist/setup/bots-store.d.ts +3 -0
- package/dist/setup/bots-store.d.ts.map +1 -0
- package/dist/setup/bots-store.js +24 -0
- package/dist/setup/bots-store.js.map +1 -0
- package/dist/setup/detect-platform.d.ts +14 -0
- package/dist/setup/detect-platform.d.ts.map +1 -0
- package/dist/setup/detect-platform.js +139 -0
- package/dist/setup/detect-platform.js.map +1 -0
- package/dist/setup/ensure-fonts.d.ts +13 -0
- package/dist/setup/ensure-fonts.d.ts.map +1 -0
- package/dist/setup/ensure-fonts.js +225 -0
- package/dist/setup/ensure-fonts.js.map +1 -0
- package/dist/setup/ensure-tmux.d.ts +60 -0
- package/dist/setup/ensure-tmux.d.ts.map +1 -0
- package/dist/setup/ensure-tmux.js +236 -0
- package/dist/setup/ensure-tmux.js.map +1 -0
- package/dist/setup/index.d.ts +9 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +46 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/lark-scopes.json +301 -0
- package/dist/setup/register-app.d.ts +52 -0
- package/dist/setup/register-app.d.ts.map +1 -0
- package/dist/setup/register-app.js +91 -0
- package/dist/setup/register-app.js.map +1 -0
- package/dist/setup/verify-permissions.d.ts +115 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -0
- package/dist/setup/verify-permissions.js +207 -0
- package/dist/setup/verify-permissions.js.map +1 -0
- package/dist/skills/definitions.d.ts +4 -0
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +133 -19
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/installer.d.ts +3 -1
- package/dist/skills/installer.d.ts.map +1 -1
- package/dist/skills/installer.js +18 -3
- package/dist/skills/installer.js.map +1 -1
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/bot-routing.d.ts +6 -0
- package/dist/utils/bot-routing.d.ts.map +1 -0
- package/dist/utils/bot-routing.js +50 -0
- package/dist/utils/bot-routing.js.map +1 -0
- package/dist/utils/file-lock.d.ts +2 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +114 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/font-installer.js +1 -1
- package/dist/utils/font-installer.js.map +1 -1
- package/dist/utils/idle-detector.d.ts +6 -0
- package/dist/utils/idle-detector.d.ts.map +1 -1
- package/dist/utils/idle-detector.js +25 -4
- package/dist/utils/idle-detector.js.map +1 -1
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +60 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/render-dimensions.d.ts +48 -0
- package/dist/utils/render-dimensions.d.ts.map +1 -0
- package/dist/utils/render-dimensions.js +55 -0
- package/dist/utils/render-dimensions.js.map +1 -0
- package/dist/utils/screen-analyzer.d.ts.map +1 -1
- package/dist/utils/screen-analyzer.js +24 -0
- package/dist/utils/screen-analyzer.js.map +1 -1
- package/dist/utils/screenshot-renderer.d.ts.map +1 -1
- package/dist/utils/screenshot-renderer.js +67 -23
- package/dist/utils/screenshot-renderer.js.map +1 -1
- package/dist/utils/terminal-renderer.d.ts +16 -0
- package/dist/utils/terminal-renderer.d.ts.map +1 -1
- package/dist/utils/terminal-renderer.js +40 -23
- package/dist/utils/terminal-renderer.js.map +1 -1
- package/dist/utils/transient-snapshot.d.ts +28 -0
- package/dist/utils/transient-snapshot.d.ts.map +1 -0
- package/dist/utils/transient-snapshot.js +96 -0
- package/dist/utils/transient-snapshot.js.map +1 -0
- package/dist/worker.js +2248 -83
- package/dist/worker.js.map +1 -1
- package/package.json +12 -5
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 凭证 + 权限自检. 不阻塞 setup / daemon 启动, 任意失败都降级到"打印剩余步骤".
|
|
3
|
+
*
|
|
4
|
+
* 主路径只用:
|
|
5
|
+
* - {@link validateCredentials} —— 取一次 `tenant_access_token`, 通过才认为
|
|
6
|
+
* AppID/Secret 有效. 没拿到才会让 setup 失败 (拒绝写 bots.json).
|
|
7
|
+
*
|
|
8
|
+
* 仅作为可选 helper, **未启用于 setup / start 主链路**:
|
|
9
|
+
* - {@link checkRequiredScopes} —— 调 `application.v6.scope.list` 比对 botmux
|
|
10
|
+
* 需要的 scope. 待 spike 用真实/可复现 mock 证明 grant_status 闭环后再启用.
|
|
11
|
+
* - {@link applyScopesUnverified} —— 调 `application.v6.scope.apply` 触发管理
|
|
12
|
+
* 员审批. Lark 文档表明它只能提交"已声明但未授权"的 scope, 不能给 manifest
|
|
13
|
+
* 加新 scope, 所以无法绕开"用户去开放平台勾"这步; 同样待 spike 后启用.
|
|
14
|
+
*
|
|
15
|
+
* 安全约束:
|
|
16
|
+
* - Secret 永远不进 console / 日志 / 错误链
|
|
17
|
+
* - 网络/接口错误一律返回结构化结果, 不抛
|
|
18
|
+
*/
|
|
19
|
+
import * as Lark from '@larksuiteoapi/node-sdk';
|
|
20
|
+
/**
|
|
21
|
+
* botmux 运行所需的 scope. 这里**只用于检测/提示**, 不用于自动申请——飞书
|
|
22
|
+
* `scope.apply` 只能提交"已声明但未授权"的, 没法给应用 manifest 加新声明.
|
|
23
|
+
* scope 选择必须用户去开放平台勾.
|
|
24
|
+
*/
|
|
25
|
+
export const BOTMUX_REQUIRED_SCOPES = [
|
|
26
|
+
{ name: 'im:message', desc: '收发消息', critical: true },
|
|
27
|
+
{ name: 'im:message.group_at_msg', desc: '群消息接收', critical: true },
|
|
28
|
+
{ name: 'im:resource', desc: '消息附件下载', critical: true },
|
|
29
|
+
{ name: 'im:chat', desc: '群信息读取', critical: true },
|
|
30
|
+
{ name: 'contact:user.base:readonly', desc: '用户基本信息', critical: true },
|
|
31
|
+
{ name: 'im:message.group_at_msg.include_bot:readonly', desc: '跨 bot @ 事件', critical: false },
|
|
32
|
+
{ name: 'application:application:self_manage', desc: '应用自查 (免审批)', critical: false },
|
|
33
|
+
];
|
|
34
|
+
export function buildScopeDeepLink(appId, scopeName, brand = 'feishu') {
|
|
35
|
+
const host = brand === 'lark' ? 'open.larksuite.com' : 'open.feishu.cn';
|
|
36
|
+
return `https://${host}/app/${appId}/auth?q=${encodeURIComponent(scopeName)}&op_from=openapi&token_type=tenant`;
|
|
37
|
+
}
|
|
38
|
+
export function buildEventSubDeepLink(appId, brand = 'feishu') {
|
|
39
|
+
const host = brand === 'lark' ? 'open.larksuite.com' : 'open.feishu.cn';
|
|
40
|
+
return `https://${host}/app/${appId}/dev-config/event-sub`;
|
|
41
|
+
}
|
|
42
|
+
export function buildAppHomeDeepLink(appId, brand = 'feishu') {
|
|
43
|
+
const host = brand === 'lark' ? 'open.larksuite.com' : 'open.feishu.cn';
|
|
44
|
+
return `https://${host}/app/${appId}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 用 AppID/Secret 取一次 tenant_access_token, 验证凭证可用.
|
|
48
|
+
*
|
|
49
|
+
* Secret 不进 error.message: 错误信息只来自飞书返回的 msg 字段或 axios 错误类型.
|
|
50
|
+
*
|
|
51
|
+
* Codex review #3: 加 AbortController + 总超时. 网络半挂时 `botmux setup` /
|
|
52
|
+
* `botmux start` 不能无限卡住; 超时归类为 network, 这样 setup 走"凭证校验失败
|
|
53
|
+
* 不写盘" 路径, start 走"network 只 WARN 继续"路径.
|
|
54
|
+
*/
|
|
55
|
+
export async function validateCredentials(appId, appSecret, brand = 'feishu', opts = {}) {
|
|
56
|
+
const budgetMs = opts.budgetMs ?? 10_000;
|
|
57
|
+
const host = brand === 'lark' ? 'open.larksuite.com' : 'open.feishu.cn';
|
|
58
|
+
const url = `https://${host}/open-apis/auth/v3/tenant_access_token/internal`;
|
|
59
|
+
// 自家 AbortController 控制总超时; 同时把上层传进来的 signal 也接上.
|
|
60
|
+
const ac = new AbortController();
|
|
61
|
+
const timer = setTimeout(() => ac.abort(), budgetMs);
|
|
62
|
+
if (opts.signal) {
|
|
63
|
+
if (opts.signal.aborted)
|
|
64
|
+
ac.abort();
|
|
65
|
+
else
|
|
66
|
+
opts.signal.addEventListener('abort', () => ac.abort(), { once: true });
|
|
67
|
+
}
|
|
68
|
+
// Codex review v2 follow-up: timer 必须覆盖 res.json() 阶段, 否则飞书极端半挂
|
|
69
|
+
// (body 半 chunk 后服务端不再发) 仍会卡住. clearTimeout 推迟到 JSON 解析之后.
|
|
70
|
+
let res;
|
|
71
|
+
let body;
|
|
72
|
+
try {
|
|
73
|
+
res = await fetch(url, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: { 'Content-Type': 'application/json' },
|
|
76
|
+
// 注意: 这是飞书唯一接受 appSecret 的端点; 其它端点全部用 token. 不要把
|
|
77
|
+
// secret 拼到 query string 或日志里.
|
|
78
|
+
body: JSON.stringify({ app_id: appId, app_secret: appSecret }),
|
|
79
|
+
signal: ac.signal,
|
|
80
|
+
});
|
|
81
|
+
body = await res.json();
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
// AbortError (fetch / json() 内部 / 我们自己 timeout) 全部归到 network
|
|
86
|
+
const isAbort = err?.name === 'AbortError' || ac.signal.aborted;
|
|
87
|
+
// JSON 解析错 (非 abort) 归 unknown, 保留旧行为
|
|
88
|
+
if (!isAbort && err instanceof SyntaxError) {
|
|
89
|
+
return { ok: false, error: 'unknown', message: `HTTP ${res?.status ?? '?'} 响应非 JSON` };
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
error: 'network',
|
|
94
|
+
message: isAbort
|
|
95
|
+
? `请求超时 (> ${budgetMs}ms)`
|
|
96
|
+
: `网络错误: ${err?.code ?? err?.message ?? 'unknown'}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
if (body?.code === 0 && typeof body.tenant_access_token === 'string') {
|
|
101
|
+
return { ok: true, tenantAccessToken: body.tenant_access_token, tokenExpiresIn: body.expire ?? 7200 };
|
|
102
|
+
}
|
|
103
|
+
// 飞书常见错误码:
|
|
104
|
+
// 10003 / 10012: app_id or app_secret invalid
|
|
105
|
+
// 10014: 应用未发布
|
|
106
|
+
// 99991663: app_secret invalid
|
|
107
|
+
if (body?.code === 10003 || body?.code === 10012 || body?.code === 99991663) {
|
|
108
|
+
return { ok: false, error: 'invalid_credentials', message: `凭证无效 (code=${body.code}): ${body.msg ?? ''}` };
|
|
109
|
+
}
|
|
110
|
+
return { ok: false, error: 'unknown', message: `code=${body?.code ?? '?'} msg=${body?.msg ?? ''}` };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 列出应用的 scope grant 状态, 比对 BOTMUX_REQUIRED_SCOPES.
|
|
114
|
+
*
|
|
115
|
+
* **不在主路径使用** — 待 spike 用真实/可复现 mock 证明 grant_status 含义和
|
|
116
|
+
* 状态闭环后再启用. 当前主路径只输出"剩余步骤 + 深链", 不做 grant_status 判定.
|
|
117
|
+
*
|
|
118
|
+
* scope.list 返回 shape (SDK type):
|
|
119
|
+
* `{ data: { scopes: [{ scope_name, grant_status, scope_type }] } }`
|
|
120
|
+
* grant_status 含义未在官方文档明确, 但社区 SDK / 实测一般约定:
|
|
121
|
+
* 1 = 已申请未生效, 2 = 已生效. 启用前 spike 务必确认这个映射.
|
|
122
|
+
*/
|
|
123
|
+
export async function checkRequiredScopes(appId, appSecret, brand = 'feishu') {
|
|
124
|
+
const domain = brand === 'lark' ? Lark.Domain.Lark : Lark.Domain.Feishu;
|
|
125
|
+
const client = new Lark.Client({ appId, appSecret, domain, loggerLevel: Lark.LoggerLevel.error });
|
|
126
|
+
let resp;
|
|
127
|
+
try {
|
|
128
|
+
resp = await client.application.scope.list();
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
return { ok: false, error: 'network', message: `scope.list 调用失败: ${err?.code ?? err?.message ?? 'unknown'}` };
|
|
132
|
+
}
|
|
133
|
+
// SDK 失败时不抛, 返回 { code, msg }
|
|
134
|
+
if (resp?.code === 99991672) {
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
error: 'need_self_manage',
|
|
138
|
+
message: '应用缺少 application:application:self_manage 权限, 无法自查 scope 列表',
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (resp?.code !== 0) {
|
|
142
|
+
return { ok: false, error: 'unknown', message: `code=${resp?.code ?? '?'} msg=${resp?.msg ?? ''}` };
|
|
143
|
+
}
|
|
144
|
+
const scopes = resp?.data?.scopes ?? [];
|
|
145
|
+
// grant_status === 2 → granted (待 spike 确认这是正确映射)
|
|
146
|
+
const grantedNames = scopes
|
|
147
|
+
.filter((s) => s?.grant_status === 2 && typeof s?.scope_name === 'string')
|
|
148
|
+
.map((s) => s.scope_name);
|
|
149
|
+
const missingCritical = BOTMUX_REQUIRED_SCOPES.filter(s => s.critical && !grantedNames.includes(s.name));
|
|
150
|
+
const missingOptional = BOTMUX_REQUIRED_SCOPES.filter(s => !s.critical && !grantedNames.includes(s.name));
|
|
151
|
+
return { ok: true, granted: grantedNames, missingCritical, missingOptional };
|
|
152
|
+
}
|
|
153
|
+
export async function applyScopesUnverified(appId, appSecret, opts = {}) {
|
|
154
|
+
const brand = opts.brand ?? 'feishu';
|
|
155
|
+
const budgetMs = opts.budgetMs ?? 15_000;
|
|
156
|
+
const domain = brand === 'lark' ? Lark.Domain.Lark : Lark.Domain.Feishu;
|
|
157
|
+
const client = new Lark.Client({ appId, appSecret, domain, loggerLevel: Lark.LoggerLevel.error });
|
|
158
|
+
const timeout = new Promise((resolve) => {
|
|
159
|
+
const timer = setTimeout(() => resolve({ status: 'timeout', msg: `> ${budgetMs}ms` }), budgetMs);
|
|
160
|
+
opts.signal?.addEventListener('abort', () => {
|
|
161
|
+
clearTimeout(timer);
|
|
162
|
+
resolve({ status: 'timeout', msg: 'aborted' });
|
|
163
|
+
}, { once: true });
|
|
164
|
+
});
|
|
165
|
+
const call = (async () => {
|
|
166
|
+
try {
|
|
167
|
+
const resp = await client.application.scope.apply();
|
|
168
|
+
const code = resp?.code;
|
|
169
|
+
const msg = resp?.msg;
|
|
170
|
+
if (code === 0)
|
|
171
|
+
return { status: 'submitted', code, msg };
|
|
172
|
+
if (code === 212001)
|
|
173
|
+
return { status: 'super_scope_only', code, msg };
|
|
174
|
+
if (code === 212002)
|
|
175
|
+
return { status: 'nothing_to_apply', code, msg };
|
|
176
|
+
if (code === 212003)
|
|
177
|
+
return { status: 'over_limit', code, msg };
|
|
178
|
+
if (code === 212004)
|
|
179
|
+
return { status: 'already_applied', code, msg };
|
|
180
|
+
return { status: 'error', code, msg };
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
return { status: 'error', msg: err?.code ?? err?.message ?? 'unknown' };
|
|
184
|
+
}
|
|
185
|
+
})();
|
|
186
|
+
return Promise.race([call, timeout]);
|
|
187
|
+
}
|
|
188
|
+
// ─── Remaining-steps printer ──────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* setup 后 "还要手动点的步骤" 结构化数据. 跟 cli.ts 的 printRemainingSteps + README
|
|
191
|
+
* "5 分钟快速接入" 一致: 主线就两步 (权限申请 + 按需重定向 URL); PersonalAgent
|
|
192
|
+
* 应用默认订阅事件 + bot 能力, 不在主线提示, 收不到消息时见 README 的 fallback
|
|
193
|
+
* 自查清单.
|
|
194
|
+
*/
|
|
195
|
+
export function buildRemainingSteps(appId, brand = 'feishu') {
|
|
196
|
+
return [
|
|
197
|
+
{
|
|
198
|
+
title: '申请权限 (一次性导入完整 JSON 提交审批) — 进入「权限管理」→「批量导入/导出权限」, 粘贴 ~/.botmux/lark-scopes.json',
|
|
199
|
+
url: `${buildAppHomeDeepLink(appId, brand)}/auth`,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
title: '添加重定向 URL http://127.0.0.1:9768/callback (按需, 用于 botmux 内 /login 跨用户调 API)',
|
|
203
|
+
url: `${buildAppHomeDeepLink(appId, brand)}/safe`,
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=verify-permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-permissions.js","sourceRoot":"","sources":["../../src/setup/verify-permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,4 +14,8 @@ export interface SkillDef {
|
|
|
14
14
|
content: string;
|
|
15
15
|
}
|
|
16
16
|
export declare const BUILTIN_SKILLS: SkillDef[];
|
|
17
|
+
/** Skills that earlier botmux versions installed but no longer ship. The
|
|
18
|
+
* installer cleans these up so renamed skills don't linger as duplicates
|
|
19
|
+
* in the CLI's skills directory. */
|
|
20
|
+
export declare const RETIRED_SKILL_NAMES: string[];
|
|
17
21
|
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAuXD,eAAO,MAAM,cAAc,EAAE,QAAQ,EAMpC,CAAC;AAEF;;qCAEqC;AACrC,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAEvC,CAAC"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
const SCHEDULE_SKILL = `---
|
|
11
11
|
name: botmux-schedule
|
|
12
|
-
description:
|
|
12
|
+
description: 在当前飞书/Lark 话题里创建、管理定时提醒(用 botmux schedule 命令,支持增删查改暂停恢复)。触发场景:用户说"每天X点"、"每周X"(任意星期,不限周一)、"每月X号"、"N分钟后/N小时后"、"明天X点"、"提醒我"、"定时任务"、"周期任务"、"recurring"、"reminder"、"crontab" 时;或显式提到 botmux schedule。到点后 daemon 会在原话题自动续一条消息并触发新 CLI 会话。注意区分:本 skill 是飞书话题内提醒;要在云端跑 remote agent 用 superpowers:schedule;要在当前会话循环跑 prompt 用 loop。
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# botmux-schedule — 定时任务
|
|
@@ -82,27 +82,43 @@ botmux schedule add "30m" "检查部署状态(调用 kubectl get pods 看看
|
|
|
82
82
|
- botmux daemon 每 30 秒 tick 一次,到点会在**原话题**里自动续一条消息并把 prompt 喂给一个新的 CLI 会话
|
|
83
83
|
- 工作目录与创建任务时一致
|
|
84
84
|
- 如果原话题的会话还活着,prompt 会直接注入现有会话(不会开新会话)
|
|
85
|
+
|
|
86
|
+
## 跨群发布场景(changelog 群、动态频道等)
|
|
87
|
+
|
|
88
|
+
如果定时任务的目的是"把内容发到另一个群作为顶层消息"(而不是回复到当前话题),让 prompt 内部用 \`botmux send --top-level --chat-id <目标群>\` 即可。任务本身仍然创建在当前话题里——这样:
|
|
89
|
+
|
|
90
|
+
- "🕐 task 开始执行" + 流式卡片留在你当前话题,方便监控
|
|
91
|
+
- 实际内容作为顶层消息发到目标群,不绑定话题、不 @ 你
|
|
92
|
+
|
|
93
|
+
\`\`\`bash
|
|
94
|
+
botmux schedule add "每日11:00" "
|
|
95
|
+
1. <做事>
|
|
96
|
+
2. botmux send --top-level --chat-id oc_xxxxxxxxxxxx '推送内容...'
|
|
97
|
+
"
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
详见 \`botmux-send\` 技能的"顶层广播 / 跨群发布"章节。
|
|
85
101
|
`;
|
|
86
|
-
const
|
|
87
|
-
name: botmux-
|
|
88
|
-
description:
|
|
102
|
+
const HISTORY_SKILL = `---
|
|
103
|
+
name: botmux-history
|
|
104
|
+
description: 需要查看当前飞书会话历史消息时触发。话题群拉话题内消息,普通群拉整群最近 N 条(默认 50,用 --limit 调节,最多 50/页)。适合"看看之前聊了什么"、"最近的消息"、"上下文"类请求。在 CLI 会话内自动推断 session-id。
|
|
89
105
|
---
|
|
90
106
|
|
|
91
|
-
# botmux-
|
|
107
|
+
# botmux-history — 读取会话消息历史
|
|
92
108
|
|
|
93
|
-
|
|
109
|
+
想回顾当前飞书会话里用户之前发过什么、别的机器人说了什么时使用。**话题群和普通群都支持**:话题群里只返回当前话题内的消息,普通群里返回整群最近 N 条(默认 50,按时间倒序取尾部、再按时间正序返回)。觉得历史太多就把 \`--limit\` 调小,需要更多上下文就调大。
|
|
94
110
|
|
|
95
111
|
## 用法
|
|
96
112
|
|
|
97
113
|
\`\`\`bash
|
|
98
114
|
# 拉取最近 50 条(默认)
|
|
99
|
-
botmux
|
|
115
|
+
botmux history
|
|
100
116
|
|
|
101
117
|
# 拉取最近 100 条
|
|
102
|
-
botmux
|
|
118
|
+
botmux history --limit 100
|
|
103
119
|
|
|
104
120
|
# 指定 session-id(不在 CLI 会话内时用)
|
|
105
|
-
botmux
|
|
121
|
+
botmux history --session-id <uuid>
|
|
106
122
|
\`\`\`
|
|
107
123
|
|
|
108
124
|
## 输出
|
|
@@ -112,7 +128,9 @@ JSON 格式,字段:
|
|
|
112
128
|
\`\`\`json
|
|
113
129
|
{
|
|
114
130
|
"sessionId": "...",
|
|
115
|
-
"
|
|
131
|
+
"chatId": "...",
|
|
132
|
+
"scope": "thread" | "chat",
|
|
133
|
+
"rootMessageId": "...", // 仅 scope=thread 时存在
|
|
116
134
|
"messages": [
|
|
117
135
|
{ "messageId": "...", "senderId": "...", "senderType": "user|app", "msgType": "text|post|interactive", "content": "...", "createTime": "..." }
|
|
118
136
|
],
|
|
@@ -122,13 +140,62 @@ JSON 格式,字段:
|
|
|
122
140
|
|
|
123
141
|
## 注意
|
|
124
142
|
|
|
125
|
-
-
|
|
126
|
-
-
|
|
143
|
+
- \`scope=thread\`:只返回属于当前话题的消息(按 rootMessageId 过滤)
|
|
144
|
+
- \`scope=chat\`:返回当前群整群最近 N 条消息(不限于 session 创建之后,需要更老的就把 --limit 调大)
|
|
145
|
+
- \`senderType="app"\` 表示机器人发的消息(包括 Claude Code / Codex / 其它 bot),\`"user"\` 表示用户
|
|
146
|
+
- **合并转发**消息会自动展开:\`msgType\` 变为 \`merge_forward_expanded\`,\`content\` 是 \`<forwarded_messages>...</forwarded_messages>\` XML(含 \`<participants>\` 别名表 + 嵌套 \`<msg from="A">\` 节点),与 daemon 实时事件路径一致
|
|
127
147
|
- 需要先把 JSON 读进来再做总结,不要直接把 JSON 扔给用户
|
|
128
148
|
`;
|
|
149
|
+
const QUOTED_SKILL = `---
|
|
150
|
+
name: botmux-quoted
|
|
151
|
+
description: 当 prompt 顶部出现 \`[用户引用了消息 用 botmux quoted om_xxx 查看]\` 提示时,用本技能按需读取被引用的那条消息内容。看到这种提示就该判断引用内容是否对当前任务必要,必要就调用,不必要就跳过。
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
# botmux-quoted — 读取被引用的消息
|
|
155
|
+
|
|
156
|
+
用户在飞书里使用"引用回复" UI @ 机器人时,daemon 会在喂给你的 prompt 头部加一行:
|
|
157
|
+
|
|
158
|
+
\`\`\`
|
|
159
|
+
[用户引用了消息 用 botmux quoted om_xxx 查看]
|
|
160
|
+
<用户的实际文字>
|
|
161
|
+
\`\`\`
|
|
162
|
+
|
|
163
|
+
看到这种提示,先判断引用内容是否对当前任务必要:必要就调用 \`botmux quoted om_xxx\` 拉取,不必要就忽略(不要无脑调用、污染上下文)。
|
|
164
|
+
|
|
165
|
+
## 用法
|
|
166
|
+
|
|
167
|
+
\`\`\`bash
|
|
168
|
+
botmux quoted <message_id>
|
|
169
|
+
\`\`\`
|
|
170
|
+
|
|
171
|
+
\`message_id\` 直接从提示行里复制即可。
|
|
172
|
+
|
|
173
|
+
## 输出
|
|
174
|
+
|
|
175
|
+
JSON 格式,与 \`botmux history\` 的单条消息字段一致,并附带 \`resources\` 列表:
|
|
176
|
+
|
|
177
|
+
\`\`\`json
|
|
178
|
+
{
|
|
179
|
+
"messageId": "om_xxx",
|
|
180
|
+
"senderId": "ou_xxx",
|
|
181
|
+
"senderType": "user|app",
|
|
182
|
+
"msgType": "text|post|interactive|image|file|merge_forward_expanded",
|
|
183
|
+
"content": "...",
|
|
184
|
+
"createTime": "1234567890000",
|
|
185
|
+
"resources": [{"type":"image","key":"img_v3_xxx","name":"img_v3_xxx.jpg"}]
|
|
186
|
+
}
|
|
187
|
+
\`\`\`
|
|
188
|
+
|
|
189
|
+
## 注意
|
|
190
|
+
|
|
191
|
+
- 图片/文件渲染成 \`[图片 N]\` / \`[文件 N: name.pdf]\` 占位符(与 \`botmux history\` 一致),实际附件 key 在 \`resources\` 列表里
|
|
192
|
+
- 卡片消息会被解析成可读文本
|
|
193
|
+
- 合并转发消息会自动展开
|
|
194
|
+
- 当前不支持自动下载附件本地化;要看图片实际内容,目前只能让用户单独转发或 \`botmux send\` 询问
|
|
195
|
+
`;
|
|
129
196
|
const SEND_SKILL = `---
|
|
130
197
|
name: botmux-send
|
|
131
|
-
description: 向飞书话题发送消息。用户在飞书上阅读看不到终端输出,需要用户看到的内容(关键结论、方案、最终结果、进度更新)必须通过 botmux send
|
|
198
|
+
description: 向飞书话题发送消息。用户在飞书上阅读看不到终端输出,需要用户看到的内容(关键结论、方案、最终结果、进度更新)必须通过 botmux send 发送。支持图文混排(图片穿插在 markdown 正文中)、文本、图片/文件附件、@mention。
|
|
132
199
|
---
|
|
133
200
|
|
|
134
201
|
# botmux-send — 向飞书话题发送消息
|
|
@@ -154,6 +221,8 @@ description: 向飞书话题发送消息。用户在飞书上阅读看不到终
|
|
|
154
221
|
|
|
155
222
|
### 纯文本(最常见)
|
|
156
223
|
|
|
224
|
+
多行内容必须用 heredoc;不要写成 \`botmux send "第一行\\n第二行"\`,否则用户会在飞书里看到字面量 \`\\n\`。
|
|
225
|
+
|
|
157
226
|
\`\`\`bash
|
|
158
227
|
# 直接传参
|
|
159
228
|
botmux send "分析完成,核心问题是 X"
|
|
@@ -172,6 +241,10 @@ EOF
|
|
|
172
241
|
echo "构建成功 ✅" | botmux send
|
|
173
242
|
\`\`\`
|
|
174
243
|
|
|
244
|
+
> ⚠️ **重要:single-quoted heredoc \`<<'EOF'\` 内反引号直接写真反引号,不要加反斜杠转义。**
|
|
245
|
+
> 原因:单引号 heredoc 已经禁用所有特殊字符解释(\`$\`、反斜杠、反引号一律按字面量处理)。再加反斜杠反而会把"反斜杠+反引号"作为字面字符混进 markdown,让 markdown-it 按 CommonMark 的 backslash-escape 处理——结果卡片里三反引号变成可见字符、代码块整段废掉。
|
|
246
|
+
> 自检:写完 bash 命令后扫一眼,如果 EOF 块内**任何反引号前面带反斜杠**,删掉那个反斜杠。
|
|
247
|
+
|
|
175
248
|
### 可用的 markdown 语法(自动走卡片)
|
|
176
249
|
|
|
177
250
|
| 语法 | 渲染 |
|
|
@@ -185,18 +258,34 @@ echo "构建成功 ✅" | botmux send
|
|
|
185
258
|
| pipe 表格 | **原生 table 组件**(不是 monospace 伪表格) |
|
|
186
259
|
| \`<at id=open_id></at>\` | @mention(一般用 \`--mention\` 自动注入,无需手写) |
|
|
187
260
|
|
|
188
|
-
**图片混排**:\`--images\` 上传的本地图片默认追加到消息末尾。想在正文中指定位置,用占位符 \`\`(N 是 0-based 索引),会被替换成真正的 img_key。例:\`botmux send --images a.png --images b.png "前情\\n\\n\\n\\n中间文字\\n\\n"\`。
|
|
189
|
-
|
|
190
261
|
**不支持**:外链图片 \`\`(飞书 markdown 元素只认本地上传的 img_key)、setext 标题(\`===\` 下划线式)、HTML 标签。
|
|
191
262
|
|
|
192
|
-
###
|
|
263
|
+
### 图文混排(图片穿插在正文中)
|
|
264
|
+
|
|
265
|
+
\`--images <path>\` 上传本地图片(可重复)。在 markdown 正文中用占位符 \`\` 标记位置(\`N\` 是 0-based 索引,按 \`--images\` 给出的顺序对应);不写占位符的图片自动追加到消息末尾。
|
|
193
266
|
|
|
194
267
|
\`\`\`bash
|
|
195
|
-
|
|
196
|
-
截图如上,红框部分是问题所在。
|
|
268
|
+
# 单图:默认追加到末尾
|
|
269
|
+
botmux send --images /tmp/screenshot.png "截图如上,红框部分是问题所在。"
|
|
270
|
+
|
|
271
|
+
# 图文混排:占位符控制图片位置
|
|
272
|
+
botmux send --images chart.png --images table.png <<'EOF'
|
|
273
|
+
## 销售报告
|
|
274
|
+
|
|
275
|
+
第一张是趋势图:
|
|
276
|
+
|
|
277
|
+

|
|
278
|
+
|
|
279
|
+
明细见下表:
|
|
280
|
+
|
|
281
|
+

|
|
282
|
+
|
|
283
|
+
环比 +12%。
|
|
197
284
|
EOF
|
|
198
285
|
\`\`\`
|
|
199
286
|
|
|
287
|
+
只支持本地路径上传,外链图片 \`\` 不会渲染。
|
|
288
|
+
|
|
200
289
|
### 带文件附件
|
|
201
290
|
|
|
202
291
|
\`\`\`bash
|
|
@@ -216,6 +305,22 @@ botmux send --mention "ou_xxx:Aiden" "请 @Aiden 帮忙 review 这段代码"
|
|
|
216
305
|
botmux send --mention ou_xxx "帮忙看下这段代码"
|
|
217
306
|
\`\`\`
|
|
218
307
|
|
|
308
|
+
### 顶层广播 / 跨群发布
|
|
309
|
+
|
|
310
|
+
默认行为:消息**回复**到当前话题里。如果要把内容发到群里作为新的顶层消息(不绑定到任何已有话题),或要发到**另一个群**,用 \`--top-level\` 和 \`--chat-id\`。
|
|
311
|
+
|
|
312
|
+
适用场景:定时任务把更新推到对外发布频道(changelog 群、动态群);当前会话向另一个群广播通知。
|
|
313
|
+
|
|
314
|
+
\`\`\`bash
|
|
315
|
+
# 在当前群发顶层消息(不回复进当前话题)
|
|
316
|
+
botmux send --top-level "📢 重要更新:xxx"
|
|
317
|
+
|
|
318
|
+
# 跨群顶层发布(任意群,给定 chat_id)
|
|
319
|
+
botmux send --top-level --chat-id oc_xxxxxxxxxxxx "📦 自动推送内容..."
|
|
320
|
+
\`\`\`
|
|
321
|
+
|
|
322
|
+
\`--top-level\` 模式下不会附加"发送给:@xxx / cc:xxx" 那行 footer(顶层广播没有特定收件人)。oncall 寻址也会跳过。
|
|
323
|
+
|
|
219
324
|
## 参数
|
|
220
325
|
|
|
221
326
|
| 参数 | 说明 |
|
|
@@ -226,6 +331,8 @@ botmux send --mention ou_xxx "帮忙看下这段代码"
|
|
|
226
331
|
| \`--files <path>\` | 附件文件,可重复多次,每个单独发送 |
|
|
227
332
|
| \`--mention <open_id[:name]>\` | @mention,可重复。带 \`:name\` 时文本里的 \`@name\` 会被替换成 \<at\> 标签;只传 open_id 则在消息末尾追加 @。用 \`botmux bots list\` 查 open_id |
|
|
228
333
|
| \`--card\` / \`--text\` | 强制卡片或纯文本模式(默认按 md 语法自动判断) |
|
|
334
|
+
| \`--top-level\` | 发顶层消息(不回复进当前话题);自动跳过"发送给/cc" footer |
|
|
335
|
+
| \`--chat-id <oc_xxx>\` | 指定目标群(默认当前会话所在群);常和 \`--top-level\` 一起用做跨群发布 |
|
|
229
336
|
| \`--session-id <id>\` | 手动指定 session(通常自动推断,不需要传) |
|
|
230
337
|
|
|
231
338
|
## 输出
|
|
@@ -270,8 +377,15 @@ botmux send --mention "ou_yyy:Aiden" "请 @Aiden 帮忙处理"
|
|
|
270
377
|
`;
|
|
271
378
|
export const BUILTIN_SKILLS = [
|
|
272
379
|
{ name: 'botmux-schedule', content: SCHEDULE_SKILL },
|
|
273
|
-
{ name: 'botmux-
|
|
380
|
+
{ name: 'botmux-history', content: HISTORY_SKILL },
|
|
381
|
+
{ name: 'botmux-quoted', content: QUOTED_SKILL },
|
|
274
382
|
{ name: 'botmux-send', content: SEND_SKILL },
|
|
275
383
|
{ name: 'botmux-bots', content: BOTS_SKILL },
|
|
276
384
|
];
|
|
385
|
+
/** Skills that earlier botmux versions installed but no longer ship. The
|
|
386
|
+
* installer cleans these up so renamed skills don't linger as duplicates
|
|
387
|
+
* in the CLI's skills directory. */
|
|
388
|
+
export const RETIRED_SKILL_NAMES = [
|
|
389
|
+
'botmux-thread-messages',
|
|
390
|
+
];
|
|
277
391
|
//# sourceMappingURL=definitions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,cAAc,GAAG
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2FtB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CrB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CpB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkJlB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkClB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,EAAE;IACpD,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE;IAClD,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE;IAChD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE;IAC5C,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE;CAC7C,CAAC;AAEF;;qCAEqC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAa;IAC3C,wBAAwB;CACzB,CAAC"}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* directory. Idempotent — only writes when content differs.
|
|
4
4
|
*
|
|
5
5
|
* Each skill becomes {skillsDir}/<name>/SKILL.md. Sub-directory layout
|
|
6
|
-
* matches Claude Code / Gemini / OpenCode convention.
|
|
6
|
+
* matches Claude Code / Gemini / OpenCode convention. Retired skills (renamed
|
|
7
|
+
* or removed in a later version) are deleted from the directory so the CLI
|
|
8
|
+
* doesn't keep surfacing stale entries alongside their replacements.
|
|
7
9
|
*/
|
|
8
10
|
export declare function ensureSkills(cliId: string, skillsDir: string | undefined): void;
|
|
9
11
|
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"AAUA
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAgC/E"}
|
package/dist/skills/installer.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
|
|
1
|
+
import { writeFileSync, mkdirSync, existsSync, readFileSync, rmSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
|
-
import { BUILTIN_SKILLS } from './definitions.js';
|
|
5
|
+
import { BUILTIN_SKILLS, RETIRED_SKILL_NAMES } from './definitions.js';
|
|
6
6
|
function expandHome(p) {
|
|
7
7
|
return p.startsWith('~') ? join(homedir(), p.slice(1)) : p;
|
|
8
8
|
}
|
|
@@ -11,7 +11,9 @@ function expandHome(p) {
|
|
|
11
11
|
* directory. Idempotent — only writes when content differs.
|
|
12
12
|
*
|
|
13
13
|
* Each skill becomes {skillsDir}/<name>/SKILL.md. Sub-directory layout
|
|
14
|
-
* matches Claude Code / Gemini / OpenCode convention.
|
|
14
|
+
* matches Claude Code / Gemini / OpenCode convention. Retired skills (renamed
|
|
15
|
+
* or removed in a later version) are deleted from the directory so the CLI
|
|
16
|
+
* doesn't keep surfacing stale entries alongside their replacements.
|
|
15
17
|
*/
|
|
16
18
|
export function ensureSkills(cliId, skillsDir) {
|
|
17
19
|
if (!skillsDir)
|
|
@@ -38,5 +40,18 @@ export function ensureSkills(cliId, skillsDir) {
|
|
|
38
40
|
logger.warn(`[skills] Failed to install ${skill.name} for ${cliId}: ${err.message}`);
|
|
39
41
|
}
|
|
40
42
|
}
|
|
43
|
+
// Clean up retired skill directories (e.g. botmux-thread-messages → botmux-history).
|
|
44
|
+
for (const retired of RETIRED_SKILL_NAMES) {
|
|
45
|
+
const retiredDir = join(dir, retired);
|
|
46
|
+
if (!existsSync(retiredDir))
|
|
47
|
+
continue;
|
|
48
|
+
try {
|
|
49
|
+
rmSync(retiredDir, { recursive: true, force: true });
|
|
50
|
+
logger.info(`[skills] Removed retired skill ${retired} for ${cliId}`);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
logger.warn(`[skills] Failed to remove retired skill ${retired} for ${cliId}: ${err.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
41
56
|
}
|
|
42
57
|
//# sourceMappingURL=installer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,SAA6B;IACvE,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,CAAC;QAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAEnE,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACjD,IAAI,OAAO,KAAK,KAAK,CAAC,OAAO;oBAAE,SAAS;YAC1C,CAAC;YACD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,IAAI,QAAQ,KAAK,MAAM,SAAS,EAAE,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,IAAI,QAAQ,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,qFAAqF;IACrF,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,kCAAkC,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,2CAA2C,OAAO,QAAQ,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;AACH,CAAC"}
|