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,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-time autostart integration for the botmux daemon.
|
|
3
|
+
*
|
|
4
|
+
* macOS — installs a LaunchAgent at ~/Library/LaunchAgents/com.botmux.daemon.plist
|
|
5
|
+
* and bootstraps it into the GUI domain (no sudo).
|
|
6
|
+
* Linux — installs a user systemd unit at ~/.config/systemd/user/botmux.service
|
|
7
|
+
* and enables it (no sudo). Reminds the user to run
|
|
8
|
+
* `loginctl enable-linger` if the unit needs to survive logout.
|
|
9
|
+
*
|
|
10
|
+
* The unit invokes `node <PKG_ROOT>/dist/cli.js start`, which goes through
|
|
11
|
+
* the same pm2 path as `botmux start`. PATH from the install-time shell is
|
|
12
|
+
* captured into the unit so node-pty / claude / codex resolve correctly when
|
|
13
|
+
* launchd or systemd starts us with a minimal environment.
|
|
14
|
+
*/
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { existsSync, mkdirSync, writeFileSync, unlinkSync, readFileSync } from 'node:fs';
|
|
17
|
+
import { homedir, userInfo } from 'node:os';
|
|
18
|
+
import { join, dirname } from 'node:path';
|
|
19
|
+
const LABEL = 'com.botmux.daemon';
|
|
20
|
+
const SERVICE_NAME = 'botmux.service';
|
|
21
|
+
function platform() {
|
|
22
|
+
if (process.platform === 'darwin')
|
|
23
|
+
return 'macos';
|
|
24
|
+
if (process.platform === 'linux')
|
|
25
|
+
return 'linux';
|
|
26
|
+
return 'unsupported';
|
|
27
|
+
}
|
|
28
|
+
function escapeXml(s) {
|
|
29
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
30
|
+
}
|
|
31
|
+
function plistPath() {
|
|
32
|
+
return join(homedir(), 'Library', 'LaunchAgents', `${LABEL}.plist`);
|
|
33
|
+
}
|
|
34
|
+
function unitPath() {
|
|
35
|
+
return join(homedir(), '.config', 'systemd', 'user', SERVICE_NAME);
|
|
36
|
+
}
|
|
37
|
+
function nodeBin() {
|
|
38
|
+
// process.execPath is the Node binary that's currently running cli.js.
|
|
39
|
+
// Using its absolute path means launchd/systemd doesn't have to resolve
|
|
40
|
+
// `node` from a stripped PATH (and we keep the same Node version the
|
|
41
|
+
// user installed botmux under, which matters for native modules like
|
|
42
|
+
// node-pty).
|
|
43
|
+
return process.execPath;
|
|
44
|
+
}
|
|
45
|
+
function cliJs(opts) {
|
|
46
|
+
return join(opts.pkgRoot, 'dist', 'cli.js');
|
|
47
|
+
}
|
|
48
|
+
function currentPath() {
|
|
49
|
+
// Capture PATH from the install-time shell so the unit can find any
|
|
50
|
+
// binaries the user expects (node-pty's `node`, the AI CLI binaries,
|
|
51
|
+
// tmux, etc.). Falls back to a sane default if PATH is empty.
|
|
52
|
+
const p = process.env.PATH || '';
|
|
53
|
+
if (p)
|
|
54
|
+
return p;
|
|
55
|
+
return process.platform === 'darwin'
|
|
56
|
+
? '/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin'
|
|
57
|
+
: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
|
|
58
|
+
}
|
|
59
|
+
// ─── macOS (launchd) ─────────────────────────────────────────────────────────
|
|
60
|
+
function plistContent(opts) {
|
|
61
|
+
const node = escapeXml(nodeBin());
|
|
62
|
+
const cli = escapeXml(cliJs(opts));
|
|
63
|
+
const cwd = escapeXml(opts.configDir);
|
|
64
|
+
const path = escapeXml(currentPath());
|
|
65
|
+
const outLog = escapeXml(join(opts.logDir, 'autostart-out.log'));
|
|
66
|
+
const errLog = escapeXml(join(opts.logDir, 'autostart-err.log'));
|
|
67
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
68
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
69
|
+
<plist version="1.0">
|
|
70
|
+
<dict>
|
|
71
|
+
<key>Label</key>
|
|
72
|
+
<string>${LABEL}</string>
|
|
73
|
+
<key>ProgramArguments</key>
|
|
74
|
+
<array>
|
|
75
|
+
<string>${node}</string>
|
|
76
|
+
<string>${cli}</string>
|
|
77
|
+
<string>start</string>
|
|
78
|
+
</array>
|
|
79
|
+
<key>RunAtLoad</key>
|
|
80
|
+
<true/>
|
|
81
|
+
<key>KeepAlive</key>
|
|
82
|
+
<false/>
|
|
83
|
+
<key>WorkingDirectory</key>
|
|
84
|
+
<string>${cwd}</string>
|
|
85
|
+
<key>EnvironmentVariables</key>
|
|
86
|
+
<dict>
|
|
87
|
+
<key>PATH</key>
|
|
88
|
+
<string>${path}</string>
|
|
89
|
+
</dict>
|
|
90
|
+
<key>StandardOutPath</key>
|
|
91
|
+
<string>${outLog}</string>
|
|
92
|
+
<key>StandardErrorPath</key>
|
|
93
|
+
<string>${errLog}</string>
|
|
94
|
+
</dict>
|
|
95
|
+
</plist>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
function launchctlBootstrap(plist) {
|
|
99
|
+
// `launchctl bootstrap` is the modern replacement for `launchctl load -w`.
|
|
100
|
+
// Falls back to the legacy form on older macOS where bootstrap is missing.
|
|
101
|
+
const uid = userInfo().uid;
|
|
102
|
+
const r = spawnSync('launchctl', ['bootstrap', `gui/${uid}`, plist], { stdio: 'pipe' });
|
|
103
|
+
if (r.status === 0)
|
|
104
|
+
return true;
|
|
105
|
+
const r2 = spawnSync('launchctl', ['load', '-w', plist], { stdio: 'pipe' });
|
|
106
|
+
return r2.status === 0;
|
|
107
|
+
}
|
|
108
|
+
function launchctlBootout() {
|
|
109
|
+
const uid = userInfo().uid;
|
|
110
|
+
const r = spawnSync('launchctl', ['bootout', `gui/${uid}/${LABEL}`], { stdio: 'pipe' });
|
|
111
|
+
if (r.status === 0)
|
|
112
|
+
return true;
|
|
113
|
+
const r2 = spawnSync('launchctl', ['unload', '-w', plistPath()], { stdio: 'pipe' });
|
|
114
|
+
return r2.status === 0;
|
|
115
|
+
}
|
|
116
|
+
function launchctlIsLoaded() {
|
|
117
|
+
const uid = userInfo().uid;
|
|
118
|
+
const r = spawnSync('launchctl', ['print', `gui/${uid}/${LABEL}`], { stdio: 'pipe' });
|
|
119
|
+
return r.status === 0;
|
|
120
|
+
}
|
|
121
|
+
function enableMac(opts) {
|
|
122
|
+
const path = plistPath();
|
|
123
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
124
|
+
mkdirSync(opts.logDir, { recursive: true });
|
|
125
|
+
writeFileSync(path, plistContent(opts));
|
|
126
|
+
console.log(`✅ 已写入 LaunchAgent: ${path}`);
|
|
127
|
+
// We deliberately do NOT bootstrap here — bootstrap on a RunAtLoad=true plist
|
|
128
|
+
// would immediately fire `botmux start`, which surprises users who just
|
|
129
|
+
// wanted to register autostart. launchd reads ~/Library/LaunchAgents/*.plist
|
|
130
|
+
// at the next login and starts the agent then.
|
|
131
|
+
if (launchctlIsLoaded()) {
|
|
132
|
+
// If a previous version was already loaded, reload it so the freshly
|
|
133
|
+
// written plist (with possibly updated paths) takes effect immediately.
|
|
134
|
+
launchctlBootout();
|
|
135
|
+
if (launchctlBootstrap(path)) {
|
|
136
|
+
console.log(`✅ 已重新加载到 launchd (路径已更新)`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log(` 下次登录时自动启动。立即启动: botmux start`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function disableMac() {
|
|
144
|
+
const path = plistPath();
|
|
145
|
+
// bootout removes the agent from launchd's registry. Because the LaunchAgent's
|
|
146
|
+
// ExecStart (`botmux start`) is fire-and-forget — pm2 forks away and the
|
|
147
|
+
// launched process exits immediately — there is no live process for bootout
|
|
148
|
+
// to kill. The pm2 daemon keeps running. To stop the daemon, the user runs
|
|
149
|
+
// `botmux stop` explicitly.
|
|
150
|
+
if (launchctlIsLoaded()) {
|
|
151
|
+
if (launchctlBootout())
|
|
152
|
+
console.log(`✅ 已从 launchd 卸载 ${LABEL}`);
|
|
153
|
+
else
|
|
154
|
+
console.warn(`⚠️ launchctl 卸载失败,继续删除 plist`);
|
|
155
|
+
}
|
|
156
|
+
if (existsSync(path)) {
|
|
157
|
+
unlinkSync(path);
|
|
158
|
+
console.log(`✅ 已删除 ${path}`);
|
|
159
|
+
console.log(` pm2 daemon 仍在运行;要停止请跑 botmux stop`);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
console.log(`ℹ️ ${path} 不存在,无需删除`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function statusMac() {
|
|
166
|
+
const path = plistPath();
|
|
167
|
+
const loaded = launchctlIsLoaded();
|
|
168
|
+
console.log(`平台: macOS (launchd)`);
|
|
169
|
+
console.log(`Plist 路径: ${path}`);
|
|
170
|
+
console.log(`Plist 存在: ${existsSync(path) ? 'yes' : 'no'}`);
|
|
171
|
+
console.log(`launchd 已加载: ${loaded ? 'yes' : 'no'}`);
|
|
172
|
+
if (existsSync(path) && !loaded) {
|
|
173
|
+
console.log(`提示: plist 存在但未加载,运行 botmux autostart enable 重新激活`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// ─── Linux (user systemd) ────────────────────────────────────────────────────
|
|
177
|
+
function unitContent(opts) {
|
|
178
|
+
// Type=oneshot + RemainAfterExit=yes because `botmux start` calls pm2
|
|
179
|
+
// start which forks and returns immediately; without RemainAfterExit
|
|
180
|
+
// systemd would consider the unit "inactive (dead)" right after launch.
|
|
181
|
+
return `[Unit]
|
|
182
|
+
Description=botmux daemon (IM <-> AI coding CLI bridge)
|
|
183
|
+
After=network-online.target
|
|
184
|
+
Wants=network-online.target
|
|
185
|
+
|
|
186
|
+
[Service]
|
|
187
|
+
Type=oneshot
|
|
188
|
+
RemainAfterExit=yes
|
|
189
|
+
WorkingDirectory=${opts.configDir}
|
|
190
|
+
Environment=PATH=${currentPath()}
|
|
191
|
+
ExecStart=${nodeBin()} ${cliJs(opts)} start
|
|
192
|
+
ExecStop=${nodeBin()} ${cliJs(opts)} stop
|
|
193
|
+
|
|
194
|
+
[Install]
|
|
195
|
+
WantedBy=default.target
|
|
196
|
+
`;
|
|
197
|
+
}
|
|
198
|
+
function userSystemdAvailable() {
|
|
199
|
+
// Check the user manager is reachable. In containers / sshd-without-DBus
|
|
200
|
+
// sessions `systemctl --user` will fail with "Failed to connect to bus".
|
|
201
|
+
const r = spawnSync('systemctl', ['--user', 'show-environment'], { stdio: 'pipe' });
|
|
202
|
+
return r.status === 0;
|
|
203
|
+
}
|
|
204
|
+
function lingerEnabled() {
|
|
205
|
+
const username = userInfo().username;
|
|
206
|
+
const r = spawnSync('loginctl', ['show-user', username, '--property=Linger'], { stdio: 'pipe' });
|
|
207
|
+
if (r.status !== 0)
|
|
208
|
+
return false;
|
|
209
|
+
return r.stdout.toString().trim().endsWith('=yes');
|
|
210
|
+
}
|
|
211
|
+
function enableLinux(opts) {
|
|
212
|
+
if (!userSystemdAvailable()) {
|
|
213
|
+
console.error(`❌ 当前会话连不上 user systemd(缺少 DBus / 容器环境)。`);
|
|
214
|
+
console.error(``);
|
|
215
|
+
console.error(` 回退方案:把下面这条写入系统级 cron / rc.local / 你常用的 init:`);
|
|
216
|
+
console.error(` ${nodeBin()} ${cliJs(opts)} start`);
|
|
217
|
+
console.error(``);
|
|
218
|
+
console.error(` 或在有 systemd --user 的桌面环境里再次运行 botmux autostart enable。`);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
const path = unitPath();
|
|
222
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
223
|
+
writeFileSync(path, unitContent(opts));
|
|
224
|
+
console.log(`✅ 已写入 systemd unit: ${path}`);
|
|
225
|
+
const reload = spawnSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });
|
|
226
|
+
if (reload.status !== 0) {
|
|
227
|
+
console.error(`❌ systemctl --user daemon-reload 失败:`);
|
|
228
|
+
console.error(reload.stderr.toString());
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
// No `--now` here on purpose: enable should only register the autostart hook,
|
|
232
|
+
// not interfere with whatever daemon state the user already has. Daemon
|
|
233
|
+
// lifecycle stays under `botmux start`/`stop`. The unit will trigger on next
|
|
234
|
+
// boot via WantedBy=default.target.
|
|
235
|
+
const en = spawnSync('systemctl', ['--user', 'enable', SERVICE_NAME], { stdio: 'pipe' });
|
|
236
|
+
if (en.status !== 0) {
|
|
237
|
+
console.error(`❌ systemctl --user enable 失败:`);
|
|
238
|
+
console.error(en.stderr.toString());
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
console.log(`✅ 已启用 ${SERVICE_NAME}`);
|
|
242
|
+
console.log(` 下次开机自动启动。立即启动: botmux start`);
|
|
243
|
+
if (!lingerEnabled()) {
|
|
244
|
+
const username = userInfo().username;
|
|
245
|
+
console.log(``);
|
|
246
|
+
console.log(`⚠️ Linger 未启用:登出当前会话后服务会停止。`);
|
|
247
|
+
console.log(` 要让服务跨登出/重启常驻,运行(需要 sudo):`);
|
|
248
|
+
console.log(` sudo loginctl enable-linger ${username}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function disableLinux() {
|
|
252
|
+
if (!userSystemdAvailable()) {
|
|
253
|
+
console.error(`❌ 当前会话连不上 user systemd。`);
|
|
254
|
+
console.error(` 如曾手工创建过 unit,请手动 rm: ${unitPath()}`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
const path = unitPath();
|
|
258
|
+
// No `--now`: only undo the boot hook. Without --now systemd skips ExecStop,
|
|
259
|
+
// so the running pm2 daemon is left untouched. To stop it, the user runs
|
|
260
|
+
// `botmux stop` (or `systemctl --user stop botmux.service` for a clean
|
|
261
|
+
// ExecStop-mediated shutdown) explicitly.
|
|
262
|
+
const dis = spawnSync('systemctl', ['--user', 'disable', SERVICE_NAME], { stdio: 'pipe' });
|
|
263
|
+
if (dis.status === 0)
|
|
264
|
+
console.log(`✅ 已禁用 ${SERVICE_NAME}`);
|
|
265
|
+
else
|
|
266
|
+
console.warn(`⚠️ disable 返回非零(可能本来就未启用)`);
|
|
267
|
+
if (existsSync(path)) {
|
|
268
|
+
unlinkSync(path);
|
|
269
|
+
console.log(`✅ 已删除 ${path}`);
|
|
270
|
+
spawnSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
console.log(`ℹ️ ${path} 不存在`);
|
|
274
|
+
}
|
|
275
|
+
console.log(` pm2 daemon 仍在运行;要停止请跑 botmux stop`);
|
|
276
|
+
}
|
|
277
|
+
function statusLinux() {
|
|
278
|
+
const path = unitPath();
|
|
279
|
+
console.log(`平台: Linux (user systemd)`);
|
|
280
|
+
console.log(`Unit 路径: ${path}`);
|
|
281
|
+
console.log(`Unit 存在: ${existsSync(path) ? 'yes' : 'no'}`);
|
|
282
|
+
if (!userSystemdAvailable()) {
|
|
283
|
+
console.log(`user systemd: 不可用(缺少 DBus / 容器环境)`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const isEnabled = spawnSync('systemctl', ['--user', 'is-enabled', SERVICE_NAME], { stdio: 'pipe' });
|
|
287
|
+
const isActive = spawnSync('systemctl', ['--user', 'is-active', SERVICE_NAME], { stdio: 'pipe' });
|
|
288
|
+
console.log(`enabled: ${isEnabled.stdout.toString().trim() || isEnabled.stderr.toString().trim()}`);
|
|
289
|
+
console.log(`active: ${isActive.stdout.toString().trim() || isActive.stderr.toString().trim()}`);
|
|
290
|
+
console.log(`Linger: ${lingerEnabled() ? 'yes' : 'no(登出后服务会停)'}`);
|
|
291
|
+
}
|
|
292
|
+
// ─── Public dispatch ─────────────────────────────────────────────────────────
|
|
293
|
+
export function enableAutostart(opts) {
|
|
294
|
+
switch (platform()) {
|
|
295
|
+
case 'macos': return enableMac(opts);
|
|
296
|
+
case 'linux': return enableLinux(opts);
|
|
297
|
+
default:
|
|
298
|
+
console.error(`❌ 当前平台 ${process.platform} 暂不支持 botmux autostart。`);
|
|
299
|
+
console.error(` Windows 用户可用任务计划程序 (Task Scheduler) 调用:`);
|
|
300
|
+
console.error(` ${nodeBin()} ${cliJs(opts)} start`);
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
export function disableAutostart(_opts) {
|
|
305
|
+
switch (platform()) {
|
|
306
|
+
case 'macos': return disableMac();
|
|
307
|
+
case 'linux': return disableLinux();
|
|
308
|
+
default:
|
|
309
|
+
console.error(`❌ 当前平台 ${process.platform} 暂不支持 botmux autostart。`);
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
export function autostartStatus(_opts) {
|
|
314
|
+
switch (platform()) {
|
|
315
|
+
case 'macos': return statusMac();
|
|
316
|
+
case 'linux': return statusLinux();
|
|
317
|
+
default:
|
|
318
|
+
console.log(`平台: ${process.platform} (不支持)`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/** Re-render the unit/plist file from the current paths without touching enable/disable state. */
|
|
322
|
+
export function refreshAutostart(opts) {
|
|
323
|
+
switch (platform()) {
|
|
324
|
+
case 'macos': {
|
|
325
|
+
const path = plistPath();
|
|
326
|
+
if (!existsSync(path))
|
|
327
|
+
return false;
|
|
328
|
+
// Only rewrite if content changed, to avoid unnecessary launchctl reload.
|
|
329
|
+
const next = plistContent(opts);
|
|
330
|
+
const prev = readFileSync(path, 'utf-8');
|
|
331
|
+
if (prev === next)
|
|
332
|
+
return false;
|
|
333
|
+
writeFileSync(path, next);
|
|
334
|
+
if (launchctlIsLoaded()) {
|
|
335
|
+
launchctlBootout();
|
|
336
|
+
launchctlBootstrap(path);
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
case 'linux': {
|
|
341
|
+
const path = unitPath();
|
|
342
|
+
if (!existsSync(path))
|
|
343
|
+
return false;
|
|
344
|
+
const next = unitContent(opts);
|
|
345
|
+
const prev = readFileSync(path, 'utf-8');
|
|
346
|
+
if (prev === next)
|
|
347
|
+
return false;
|
|
348
|
+
writeFileSync(path, next);
|
|
349
|
+
if (userSystemdAvailable()) {
|
|
350
|
+
spawnSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
default: return false;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
//# sourceMappingURL=autostart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"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"}
|
package/dist/bot-registry.d.ts
CHANGED
|
@@ -5,8 +5,22 @@ export interface OncallChat {
|
|
|
5
5
|
chatId: string;
|
|
6
6
|
/** Default working directory used for every new topic spawned in this chat. */
|
|
7
7
|
workingDir: string;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Per-bot default for new group chats:
|
|
11
|
+
* - `enabled` — when true, group chats first observed after `since` are
|
|
12
|
+
* auto-bound to oncall on their first new-topic.
|
|
13
|
+
* - `workingDir` — the working directory used for the auto-bind. Required
|
|
14
|
+
* when enabled (oncall semantics: chatId ↔ workingDir).
|
|
15
|
+
* - `since` — epoch ms when the flag was switched on. Used to gate
|
|
16
|
+
* "new vs old" against chat-first-seen-store. Chats that
|
|
17
|
+
* existed before `since` are left untouched, matching
|
|
18
|
+
* "新群聊生效,老群聊不变".
|
|
19
|
+
*/
|
|
20
|
+
export interface BotDefaultOncall {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
workingDir: string;
|
|
23
|
+
since: number;
|
|
10
24
|
}
|
|
11
25
|
export interface BotConfig {
|
|
12
26
|
larkAppId: string;
|
|
@@ -18,8 +32,18 @@ export interface BotConfig {
|
|
|
18
32
|
workingDirs?: string[];
|
|
19
33
|
allowedUsers?: string[];
|
|
20
34
|
projectScanDir?: string;
|
|
21
|
-
/** Oncall bindings: chat_id → default workingDir
|
|
35
|
+
/** Oncall bindings: chat_id → default workingDir. Any group member can talk; allowedUsers still gates card buttons / daemon commands. */
|
|
22
36
|
oncallChats?: OncallChat[];
|
|
37
|
+
/** Per-bot default: auto-bind every new group chat to oncall on first new-topic. */
|
|
38
|
+
defaultOncall?: BotDefaultOncall;
|
|
39
|
+
/**
|
|
40
|
+
* Chat IDs that have ever been auto-bound by `defaultOncall`. Append-only.
|
|
41
|
+
* Once a chat appears here, the default is permanently "spent" for it — even
|
|
42
|
+
* if the user later unbinds via Groups & Bots / `/oncall unbind`, the
|
|
43
|
+
* default will not re-bind it. This preserves the manual-override semantics
|
|
44
|
+
* Codex flagged in review.
|
|
45
|
+
*/
|
|
46
|
+
defaultOncallAutoboundChats?: string[];
|
|
23
47
|
}
|
|
24
48
|
export interface BotState {
|
|
25
49
|
config: BotConfig;
|
|
@@ -35,6 +59,8 @@ export declare function getBotClient(larkAppId: string): Lark.Client;
|
|
|
35
59
|
export declare function getAllBots(): BotState[];
|
|
36
60
|
/** Lookup the oncall binding for a given bot+chat, if any. */
|
|
37
61
|
export declare function findOncallChat(larkAppId: string, chatId: string): OncallChat | undefined;
|
|
62
|
+
export declare function findOncallChatForAnyBot(chatId: string): OncallChat | undefined;
|
|
63
|
+
export declare function isChatOncallBoundForAnyBot(chatId: string): boolean;
|
|
38
64
|
/**
|
|
39
65
|
* Load bot configurations from one of (in priority order):
|
|
40
66
|
* 1. BOTS_CONFIG env var — path to a JSON file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot-registry.d.ts","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAIhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"bot-registry.d.ts","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAIhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yIAAyI;IACzI,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,oFAAoF;IACpF,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAMD,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExD;AAwBD,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,GAAG,QAAQ,CAapD;AAED,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAMlD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAE3D;AAED,wBAAgB,UAAU,IAAI,QAAQ,EAAE,CAEvC;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAGxF;AAeD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CA+B9E;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAsB5C"}
|
package/dist/bot-registry.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import * as Lark from '@larksuiteoapi/node-sdk';
|
|
2
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
+
import { logger } from './utils/logger.js';
|
|
5
6
|
const bots = new Map();
|
|
6
7
|
/** Path of the bot config file we loaded (so `/oncall` can persist bindings back). */
|
|
7
8
|
let loadedConfigPath;
|
|
8
9
|
export function getLoadedConfigPath() {
|
|
9
10
|
return loadedConfigPath;
|
|
10
11
|
}
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
12
|
+
// Route Lark SDK output through our logger so it inherits the same sink
|
|
13
|
+
// rules (info/debug → daemon.log in daemon mode, → stderr in CLI mode,
|
|
14
|
+
// dropped when CLI is silent). The default SDK logger calls console.log,
|
|
15
|
+
// which would corrupt CLI stdout consumers.
|
|
16
|
+
//
|
|
17
|
+
// Volume control: the SDK is chatty at info/debug ("client ready", request
|
|
18
|
+
// traces, etc.); without DEBUG=1 those become no-ops in the CLI path and
|
|
19
|
+
// stay in daemon.log on the daemon path — pm2's error.log no longer sees
|
|
20
|
+
// "[lark:info] client ready" floods.
|
|
14
21
|
function safeStringify(v) {
|
|
15
22
|
if (typeof v === 'string')
|
|
16
23
|
return v;
|
|
@@ -21,18 +28,19 @@ function safeStringify(v) {
|
|
|
21
28
|
return String(v);
|
|
22
29
|
}
|
|
23
30
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const fmtLark = (msg) => msg.map(safeStringify).join(' ');
|
|
32
|
+
const larkLogger = {
|
|
33
|
+
error: (...msg) => logger.error(`[lark] ${fmtLark(msg)}`),
|
|
34
|
+
warn: (...msg) => logger.warn(`[lark] ${fmtLark(msg)}`),
|
|
35
|
+
info: (...msg) => logger.info(`[lark] ${fmtLark(msg)}`),
|
|
36
|
+
debug: (...msg) => logger.debug(`[lark] ${fmtLark(msg)}`),
|
|
37
|
+
trace: (..._msg) => { },
|
|
30
38
|
};
|
|
31
39
|
export function registerBot(cfg) {
|
|
32
40
|
const client = new Lark.Client({
|
|
33
41
|
appId: cfg.larkAppId,
|
|
34
42
|
appSecret: cfg.larkAppSecret,
|
|
35
|
-
logger:
|
|
43
|
+
logger: larkLogger,
|
|
36
44
|
});
|
|
37
45
|
const state = {
|
|
38
46
|
config: cfg,
|
|
@@ -60,6 +68,57 @@ export function findOncallChat(larkAppId, chatId) {
|
|
|
60
68
|
const bot = bots.get(larkAppId);
|
|
61
69
|
return bot?.config.oncallChats?.find(c => c.chatId === chatId);
|
|
62
70
|
}
|
|
71
|
+
// Cross-bot oncall chat check — cached by config-file mtime.
|
|
72
|
+
//
|
|
73
|
+
// /oncall bind is per-bot, but oncall is meant to be a chat-level property:
|
|
74
|
+
// once any bot in a multi-bot deployment binds the chat, every sibling bot
|
|
75
|
+
// should treat that chat as an oncall workspace too (otherwise unbound bots
|
|
76
|
+
// fall back to allowedUsers and reply "⚠️ 无操作权限" when @-mentioned).
|
|
77
|
+
//
|
|
78
|
+
// Multi-daemon deployments run one bot per process, so the in-memory `bots`
|
|
79
|
+
// map only sees this daemon's own bot — sibling bots' bindings live only on
|
|
80
|
+
// disk in the shared bots.json. Re-read that file lazily, keyed by mtime,
|
|
81
|
+
// so the hot path is a single stat() once the cache is warm.
|
|
82
|
+
let oncallChatCache = null;
|
|
83
|
+
export function findOncallChatForAnyBot(chatId) {
|
|
84
|
+
// Fast path: this daemon's own bot(s). Covers single-daemon setups and any
|
|
85
|
+
// case where the receiving bot itself is bound.
|
|
86
|
+
for (const bot of bots.values()) {
|
|
87
|
+
const entry = bot.config.oncallChats?.find(c => c.chatId === chatId);
|
|
88
|
+
if (entry)
|
|
89
|
+
return entry;
|
|
90
|
+
}
|
|
91
|
+
// Slow path: scan the shared bots.json for sibling bots' bindings.
|
|
92
|
+
const path = loadedConfigPath;
|
|
93
|
+
if (!path)
|
|
94
|
+
return undefined;
|
|
95
|
+
try {
|
|
96
|
+
const stat = statSync(path);
|
|
97
|
+
if (!oncallChatCache || oncallChatCache.mtimeMs !== stat.mtimeMs) {
|
|
98
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
99
|
+
const chats = new Map();
|
|
100
|
+
if (Array.isArray(raw)) {
|
|
101
|
+
for (const entry of raw) {
|
|
102
|
+
if (!Array.isArray(entry?.oncallChats))
|
|
103
|
+
continue;
|
|
104
|
+
for (const c of entry.oncallChats) {
|
|
105
|
+
if (c && typeof c.chatId === 'string' && typeof c.workingDir === 'string') {
|
|
106
|
+
chats.set(c.chatId, { chatId: c.chatId, workingDir: c.workingDir });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
oncallChatCache = { mtimeMs: stat.mtimeMs, chats };
|
|
112
|
+
}
|
|
113
|
+
return oncallChatCache.chats.get(chatId);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function isChatOncallBoundForAnyBot(chatId) {
|
|
120
|
+
return !!findOncallChatForAnyBot(chatId);
|
|
121
|
+
}
|
|
63
122
|
/**
|
|
64
123
|
* Load bot configurations from one of (in priority order):
|
|
65
124
|
* 1. BOTS_CONFIG env var — path to a JSON file
|
|
@@ -117,9 +176,27 @@ function parseBotConfigFile(filePath) {
|
|
|
117
176
|
.map((c) => ({
|
|
118
177
|
chatId: c.chatId,
|
|
119
178
|
workingDir: c.workingDir,
|
|
120
|
-
owners: Array.isArray(c.owners) ? c.owners.filter((o) => typeof o === 'string') : [],
|
|
121
179
|
}));
|
|
122
180
|
}
|
|
181
|
+
// defaultOncall: per-bot default for auto-binding new group chats.
|
|
182
|
+
// Tolerate missing fields: an entry with `enabled:true` but no workingDir
|
|
183
|
+
// is treated as disabled (dashboard PUT enforces workingDir on save, but
|
|
184
|
+
// hand-edited bots.json could be inconsistent — never crash on parse).
|
|
185
|
+
let defaultOncall;
|
|
186
|
+
const rawDefault = entry.defaultOncall;
|
|
187
|
+
if (rawDefault && typeof rawDefault === 'object') {
|
|
188
|
+
const enabled = rawDefault.enabled === true;
|
|
189
|
+
const workingDir = typeof rawDefault.workingDir === 'string' ? rawDefault.workingDir : '';
|
|
190
|
+
const since = typeof rawDefault.since === 'number' && Number.isFinite(rawDefault.since)
|
|
191
|
+
? rawDefault.since
|
|
192
|
+
: 0;
|
|
193
|
+
defaultOncall = { enabled: enabled && !!workingDir, workingDir, since };
|
|
194
|
+
}
|
|
195
|
+
let defaultOncallAutoboundChats;
|
|
196
|
+
if (Array.isArray(entry.defaultOncallAutoboundChats)) {
|
|
197
|
+
defaultOncallAutoboundChats = entry.defaultOncallAutoboundChats
|
|
198
|
+
.filter((x) => typeof x === 'string');
|
|
199
|
+
}
|
|
123
200
|
configs.push({
|
|
124
201
|
larkAppId: entry.larkAppId,
|
|
125
202
|
larkAppSecret: entry.larkAppSecret,
|
|
@@ -131,6 +208,8 @@ function parseBotConfigFile(filePath) {
|
|
|
131
208
|
allowedUsers: entry.allowedUsers,
|
|
132
209
|
projectScanDir: entry.projectScanDir,
|
|
133
210
|
oncallChats,
|
|
211
|
+
defaultOncall,
|
|
212
|
+
defaultOncallAutoboundChats,
|
|
134
213
|
});
|
|
135
214
|
}
|
|
136
215
|
return configs;
|
package/dist/bot-registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot-registry.js","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bot-registry.js","sourceRoot":"","sources":["../src/bot-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small argv helpers used by botmux subcommands. Lives in a side-effect-free
|
|
3
|
+
* module so tests can import them without triggering cli.ts's top-level
|
|
4
|
+
* dispatcher switch.
|
|
5
|
+
*/
|
|
6
|
+
/** Pick the first positional (non-flag, non-flag-value) token from `args`.
|
|
7
|
+
* Skips both `--name` flags AND their following value tokens, so
|
|
8
|
+
* `cmd --session-id <uuid> om_xxx` correctly returns `om_xxx`. Flags that
|
|
9
|
+
* take values must be passed in `flagsWithValue` to avoid eating their args. */
|
|
10
|
+
export declare function firstPositional(args: string[], flagsWithValue: string[]): string | undefined;
|
|
11
|
+
//# sourceMappingURL=arg-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arg-utils.d.ts","sourceRoot":"","sources":["../../src/cli/arg-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;iFAGiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAS5F"}
|