botmux 3.1.1 → 3.2.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.
- package/dist/adapters/backend/sandbox.d.ts +23 -0
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +68 -1
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +1 -1
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +15 -7
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +117 -25
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +11 -4
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +1 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +132 -0
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/maintenance.d.ts +23 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +63 -25
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/plugins/cli-generation.d.ts.map +1 -1
- package/dist/core/plugins/cli-generation.js +7 -0
- package/dist/core/plugins/cli-generation.js.map +1 -1
- package/dist/core/plugins/convention-scanner.d.ts +3 -3
- package/dist/core/plugins/convention-scanner.d.ts.map +1 -1
- package/dist/core/plugins/convention-scanner.js.map +1 -1
- package/dist/core/plugins/install.d.ts.map +1 -1
- package/dist/core/plugins/install.js +84 -26
- package/dist/core/plugins/install.js.map +1 -1
- package/dist/core/plugins/mcp/environment.d.ts +12 -0
- package/dist/core/plugins/mcp/environment.d.ts.map +1 -0
- package/dist/core/plugins/mcp/environment.js +17 -0
- package/dist/core/plugins/mcp/environment.js.map +1 -0
- package/dist/core/plugins/mcp/gateway-installer.d.ts.map +1 -1
- package/dist/core/plugins/mcp/gateway-installer.js +9 -3
- package/dist/core/plugins/mcp/gateway-installer.js.map +1 -1
- package/dist/core/plugins/mcp/gateway.d.ts +13 -1
- package/dist/core/plugins/mcp/gateway.d.ts.map +1 -1
- package/dist/core/plugins/mcp/gateway.js +143 -23
- package/dist/core/plugins/mcp/gateway.js.map +1 -1
- package/dist/core/plugins/mcp/host.d.ts +18 -0
- package/dist/core/plugins/mcp/host.d.ts.map +1 -0
- package/dist/core/plugins/mcp/host.js +126 -0
- package/dist/core/plugins/mcp/host.js.map +1 -0
- package/dist/core/plugins/mcp/private-store.d.ts +15 -0
- package/dist/core/plugins/mcp/private-store.d.ts.map +1 -0
- package/dist/core/plugins/mcp/private-store.js +162 -0
- package/dist/core/plugins/mcp/private-store.js.map +1 -0
- package/dist/core/plugins/mcp/session-runtime.d.ts +25 -0
- package/dist/core/plugins/mcp/session-runtime.d.ts.map +1 -0
- package/dist/core/plugins/mcp/session-runtime.js +76 -0
- package/dist/core/plugins/mcp/session-runtime.js.map +1 -0
- package/dist/core/plugins/mcp/socket-auth.d.ts +9 -0
- package/dist/core/plugins/mcp/socket-auth.d.ts.map +1 -0
- package/dist/core/plugins/mcp/socket-auth.js +94 -0
- package/dist/core/plugins/mcp/socket-auth.js.map +1 -0
- package/dist/core/plugins/paths.d.ts +3 -0
- package/dist/core/plugins/paths.d.ts.map +1 -1
- package/dist/core/plugins/paths.js +9 -0
- package/dist/core/plugins/paths.js.map +1 -1
- package/dist/core/plugins/pm2.d.ts.map +1 -1
- package/dist/core/plugins/pm2.js +3 -1
- package/dist/core/plugins/pm2.js.map +1 -1
- package/dist/core/plugins/runtime.d.ts +2 -0
- package/dist/core/plugins/runtime.d.ts.map +1 -1
- package/dist/core/plugins/runtime.js.map +1 -1
- package/dist/core/plugins/service-manager.d.ts +22 -0
- package/dist/core/plugins/service-manager.d.ts.map +1 -1
- package/dist/core/plugins/service-manager.js +189 -52
- package/dist/core/plugins/service-manager.js.map +1 -1
- package/dist/core/plugins/types.d.ts +15 -1
- package/dist/core/plugins/types.d.ts.map +1 -1
- package/dist/core/restart-report.d.ts +1 -1
- package/dist/core/restart-report.d.ts.map +1 -1
- package/dist/core/restart-report.js +5 -3
- package/dist/core/restart-report.js.map +1 -1
- package/dist/core/scheduler.d.ts +47 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +117 -0
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-manager.d.ts +7 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +130 -33
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/silent-schedule-turns.d.ts +5 -0
- package/dist/core/silent-schedule-turns.d.ts.map +1 -0
- package/dist/core/silent-schedule-turns.js +47 -0
- package/dist/core/silent-schedule-turns.js.map +1 -0
- package/dist/core/types.d.ts +6 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/update-check.d.ts +16 -0
- package/dist/core/update-check.d.ts.map +1 -1
- package/dist/core/update-check.js +52 -0
- package/dist/core/update-check.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +30 -23
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +3 -0
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +5 -0
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +295 -6
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +92 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/plugin-page.d.ts.map +1 -1
- package/dist/dashboard/web/plugin-page.js +1 -3
- package/dist/dashboard/web/plugin-page.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +111 -4
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +5 -1
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/update-action.d.ts +16 -0
- package/dist/dashboard/web/update-action.d.ts.map +1 -0
- package/dist/dashboard/web/update-action.js +64 -0
- package/dist/dashboard/web/update-action.js.map +1 -0
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-KLDCZNLP.js → bot-defaults-page-4PM4T6QQ.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FMJNOATE.js → chunk-3PMN55Z6.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-MLNI5BKE.js → chunk-AIDN2WZB.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-EZAW2EPM.js → chunk-IKCZ677K.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-KEAOTUL3.js → chunk-RXVA6XW3.js} +7 -7
- package/dist/dashboard-web/chunks/{connectors-page-O32LFAL5.js → connectors-page-2MKF4YTN.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-PSAFIZ6M.js → groups-page-TAU2UIVS.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-V23LLATX.js → insights-page-PJ2XVM6T.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-7X5AKYOF.js → monitor-room-D6445HJO.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-CBA3CQYL.js → monitoring-page-GUHMCKSO.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-RL6QSEM7.js → office-page-6K6U2MS5.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-XQIPO6KH.js → overview-page-USDYU7U5.js} +1 -1
- package/dist/dashboard-web/chunks/plugin-page-JXC5F5YV.js +1 -0
- package/dist/dashboard-web/chunks/{roles-page-ACIWV7QS.js → roles-page-O4OUA7ZH.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-page-LNIBXJSZ.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-page-2WDWHSP4.js → sessions-page-B6U6TCFF.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-6VX4OUGG.js → settings-page-PXLRFF7I.js} +2 -2
- package/dist/dashboard-web/chunks/{skills-page-WXE3UYLT.js → skills-page-M5KYNXBA.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-PYTF4FLM.js → team-federation-page-GT7UFQMN.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-G6CD6O3I.js → v3-page-UYZIRJ2C.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-6SG33GP4.js → whiteboards-page-WAR77DQE.js} +1 -1
- package/dist/dashboard-web/style.css +697 -0
- package/dist/dashboard.js +404 -29
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +4 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +4 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/schedules-card.d.ts.map +1 -1
- package/dist/im/lark/schedules-card.js +2 -0
- package/dist/im/lark/schedules-card.js.map +1 -1
- package/dist/services/plugin-registry-store.d.ts.map +1 -1
- package/dist/services/plugin-registry-store.js +100 -18
- package/dist/services/plugin-registry-store.js.map +1 -1
- package/dist/services/restart-intent-store.d.ts +17 -2
- package/dist/services/restart-intent-store.d.ts.map +1 -1
- package/dist/services/restart-intent-store.js +110 -0
- package/dist/services/restart-intent-store.js.map +1 -1
- package/dist/services/schedule-store.d.ts +3 -1
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +5 -0
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +3 -2
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +1 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +5 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/global-install.d.ts +2 -0
- package/dist/utils/global-install.d.ts.map +1 -1
- package/dist/utils/global-install.js +14 -0
- package/dist/utils/global-install.js.map +1 -1
- package/dist/worker.js +125 -17
- package/dist/worker.js.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +3 -0
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +9 -0
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/plugin-page-7FW2LPJH.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-KJDUKOJV.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -53,7 +53,8 @@ import { isColdResumeDormant, sessionListDisposition } from './cli/session-list-
|
|
|
53
53
|
import { dispatchPrimaryMessage, findStdinAliasAttachment, normalizeInteractiveCardInput, sendFileAttachments, sendVideoAttachments, shouldSendAsPureVideo, validateVideoAttachments } from './cli/send-dispatch.js';
|
|
54
54
|
import { buildPm2SpawnCommand } from './cli/pm2-command.js';
|
|
55
55
|
import { callDashboard } from './cli/dashboard-endpoint.js';
|
|
56
|
-
import { installLatestBotmuxSync } from './core/maintenance.js';
|
|
56
|
+
import { globalInstallUpdateLockTargetIn, installLatestBotmuxSync } from './core/maintenance.js';
|
|
57
|
+
import { withFileLockSync } from './utils/file-lock.js';
|
|
57
58
|
import { formatGlobalInstallCommand, resolveGlobalInstallPlan, UnsupportedGlobalInstallError, } from './utils/global-install.js';
|
|
58
59
|
import { loadDashboardSecret } from './dashboard/auth.js';
|
|
59
60
|
import { postWorkflowDaemonMutation, } from './workflows/v3/daemon-ipc-client.js';
|
|
@@ -68,7 +69,7 @@ import { chatAppLink, larkHosts, normalizeBrand, sdkDomain } from './im/lark/lar
|
|
|
68
69
|
import { mergeDashboardConfig, mergeGlobalConfig, readGlobalConfig, setGlobalLocale, globalConfigPath } from './global-config.js';
|
|
69
70
|
import { createWhiteboard, ensureDefaultWhiteboard, getWhiteboard, listWhiteboards, readWhiteboard, whiteboardEnabled, whiteboardPath, } from './services/whiteboard-store.js';
|
|
70
71
|
import { buildBridgeSendMarkerContent } from './services/bridge-fallback-gate.js';
|
|
71
|
-
import { writeManualIntentIfAbsentTo } from './services/restart-intent-store.js';
|
|
72
|
+
import { bindRestartLeaseTo, writeManualIntentIfAbsentTo } from './services/restart-intent-store.js';
|
|
72
73
|
import { stripLegacyPendingCardFields } from './services/session-store.js';
|
|
73
74
|
import { evaluateVcMeetingManagedSend, isTrustedVcMeetingHostRelayParent, resolveVcMeetingImTurnOrigin, } from './services/vc-meeting-send-policy.js';
|
|
74
75
|
import { finishVcMeetingImReply, prepareVcMeetingDeliveryReply, prepareVcMeetingImReply, } from './services/vc-meeting-im-reply.js';
|
|
@@ -2303,6 +2304,20 @@ async function cmdStop() {
|
|
|
2303
2304
|
console.log('daemon 未在运行。');
|
|
2304
2305
|
}
|
|
2305
2306
|
async function cmdRestart() {
|
|
2307
|
+
const restartLeaseId = process.env.BOTMUX_RESTART_LEASE_ID;
|
|
2308
|
+
const restartLeaseDir = process.env.BOTMUX_RESTART_LEASE_DIR;
|
|
2309
|
+
delete process.env.BOTMUX_RESTART_LEASE_ID;
|
|
2310
|
+
delete process.env.BOTMUX_RESTART_LEASE_DIR;
|
|
2311
|
+
if (restartLeaseId) {
|
|
2312
|
+
if (!restartLeaseDir)
|
|
2313
|
+
throw new Error('restart driver lease directory is missing');
|
|
2314
|
+
let bound = false;
|
|
2315
|
+
withFileLockSync(globalInstallUpdateLockTargetIn(restartLeaseDir), () => {
|
|
2316
|
+
bound = bindRestartLeaseTo(restartLeaseDir, restartLeaseId, process.pid, Date.now());
|
|
2317
|
+
});
|
|
2318
|
+
if (!bound)
|
|
2319
|
+
throw new Error('failed to bind restart driver lease');
|
|
2320
|
+
}
|
|
2306
2321
|
if (!hasConfig()) {
|
|
2307
2322
|
console.error('❌ 未找到配置文件');
|
|
2308
2323
|
console.error(' 请先运行: botmux setup');
|
|
@@ -4210,6 +4225,7 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
|
|
|
4210
4225
|
schedule list 列出所有任务
|
|
4211
4226
|
schedule add <schedule> <prompt> 添加任务(ex: "30m" / "every 2h" / "每日9:00" / "0 9 * * *")
|
|
4212
4227
|
--new-topic 每次触发在同群开一个新话题、起独立会话(不续旧话题)
|
|
4228
|
+
--silent 静默执行:不发「执行中」提示,模型判断是否 botmux send 报警(与 --new-topic 互斥)
|
|
4213
4229
|
schedule remove <id> 删除任务
|
|
4214
4230
|
schedule pause|resume <id> 暂停/恢复
|
|
4215
4231
|
schedule run <id> 标记立即执行
|
|
@@ -4337,6 +4353,7 @@ function detectCurrentSession() {
|
|
|
4337
4353
|
workingDir: s.workingDir,
|
|
4338
4354
|
larkAppId: s.larkAppId,
|
|
4339
4355
|
chatType: s.chatType,
|
|
4356
|
+
scope: s.scope,
|
|
4340
4357
|
};
|
|
4341
4358
|
}
|
|
4342
4359
|
/** Pick a value from --flag <value> or --flag=value style args. */
|
|
@@ -4678,7 +4695,7 @@ async function cmdSchedule(sub, rest) {
|
|
|
4678
4695
|
const prompt = t.prompt ?? '';
|
|
4679
4696
|
const chatId = t.chatId ?? '—';
|
|
4680
4697
|
const rootId = t.rootMessageId ?? '—';
|
|
4681
|
-
console.log(`${status} [${t.id}] ${display} | ${t.name}`);
|
|
4698
|
+
console.log(`${status} [${t.id}] ${display} | ${t.name}${t.silent ? ' 🔇静默' : ''}`);
|
|
4682
4699
|
console.log(` prompt: ${prompt.length > 60 ? prompt.slice(0, 60) + '…' : prompt}`);
|
|
4683
4700
|
console.log(` chat: ${chatId.slice(0, 12)}… thread: ${rootId.slice(0, 16)}…`);
|
|
4684
4701
|
console.log(` next: ${next} last: ${last}${t.lastStatus === 'error' ? ' ❌' : ''}`);
|
|
@@ -4687,9 +4704,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4687
4704
|
return;
|
|
4688
4705
|
}
|
|
4689
4706
|
if (sub === 'add') {
|
|
4690
|
-
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic']);
|
|
4707
|
+
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic', '--silent']);
|
|
4691
4708
|
if (!rawSchedule) {
|
|
4692
|
-
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--root-msg-id ROOT] [--lark-app-id APP] [--workdir DIR] [--new-topic]');
|
|
4709
|
+
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--root-msg-id ROOT] [--lark-app-id APP] [--workdir DIR] [--new-topic] [--silent]');
|
|
4693
4710
|
process.exit(1);
|
|
4694
4711
|
}
|
|
4695
4712
|
// prompt may come from positional or --prompt flag
|
|
@@ -4708,6 +4725,13 @@ async function cmdSchedule(sub, rest) {
|
|
|
4708
4725
|
const deliver = rest.includes('--new-topic')
|
|
4709
4726
|
? 'new-topic'
|
|
4710
4727
|
: (argValue(rest, '--deliver') ?? 'origin');
|
|
4728
|
+
// --silent: fires post no "执行中" banner; the spawned turn stays quiet and
|
|
4729
|
+
// the model only `botmux send`s when the alert condition in the prompt is met.
|
|
4730
|
+
const silent = rest.includes('--silent');
|
|
4731
|
+
if (silent && deliver === 'new-topic') {
|
|
4732
|
+
console.error('--silent 与 --new-topic 不能同时使用:新话题必须由首条消息开启。要「有异常才开新话题」,请在 prompt 里指示模型报警时用 botmux send 顶层发送。');
|
|
4733
|
+
process.exit(1);
|
|
4734
|
+
}
|
|
4711
4735
|
if (!chatId) {
|
|
4712
4736
|
console.error('无法推断 chat-id。请加上 --chat-id <CHAT_ID>,或从 Lark 话题内的 CLI 会话中运行本命令。');
|
|
4713
4737
|
process.exit(1);
|
|
@@ -4733,7 +4757,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4733
4757
|
creatorRootMessageId: cur?.rootMessageId,
|
|
4734
4758
|
creatorLarkAppId: cur?.larkAppId,
|
|
4735
4759
|
chatType: cur?.chatType === 'p2p' ? 'p2p' : 'topic_group',
|
|
4760
|
+
scope: cur?.scope,
|
|
4736
4761
|
deliver,
|
|
4762
|
+
silent,
|
|
4737
4763
|
});
|
|
4738
4764
|
const next = task.nextRunAt ? new Date(task.nextRunAt).toLocaleString('zh-CN', { timeZone: scheduleTimeZone() }) : '—';
|
|
4739
4765
|
console.log(`✅ 已创建定时任务 [${task.id}] ${task.name}`);
|
|
@@ -4741,6 +4767,8 @@ async function cmdSchedule(sub, rest) {
|
|
|
4741
4767
|
console.log(` 下次执行: ${next}`);
|
|
4742
4768
|
console.log(` 工作目录: ${workingDir}`);
|
|
4743
4769
|
console.log(` 话题: ${deliver === 'new-topic' ? '(每次新开话题,独立会话)' : rootMessageId ?? '(将新开)'}`);
|
|
4770
|
+
if (silent)
|
|
4771
|
+
console.log(' 静默: 触发时不发「执行中」提示,由模型判断是否需要 botmux send 报警');
|
|
4744
4772
|
return;
|
|
4745
4773
|
}
|
|
4746
4774
|
const id = positionals(rest)[0];
|
|
@@ -8268,6 +8296,32 @@ function printPluginUsage() {
|
|
|
8268
8296
|
botmux plugin service restart [plugin-id|--all]
|
|
8269
8297
|
`);
|
|
8270
8298
|
}
|
|
8299
|
+
function printPluginServiceRunningError(err) {
|
|
8300
|
+
if (!err || typeof err !== 'object' || err.code !== 'plugin_service_running')
|
|
8301
|
+
return false;
|
|
8302
|
+
const pluginId = String(err.pluginId ?? 'unknown');
|
|
8303
|
+
const operation = String(err.operation ?? 'update');
|
|
8304
|
+
const status = String(err.serviceStatus ?? 'unknown');
|
|
8305
|
+
const pid = typeof err.pid === 'number' ? `, PID ${err.pid}` : '';
|
|
8306
|
+
const operationLabel = operation === 'uninstall' ? '卸载' : operation === 'install' ? '安装' : '更新';
|
|
8307
|
+
console.error(`❌ 无法${operationLabel}插件 ${pluginId}:插件服务仍在运行(${status}${pid})。`);
|
|
8308
|
+
console.error(` 请先运行: botmux plugin service stop ${pluginId}`);
|
|
8309
|
+
console.error(' Botmux 不会在安装、更新或卸载时隐式停止插件服务。');
|
|
8310
|
+
return true;
|
|
8311
|
+
}
|
|
8312
|
+
function printPluginServiceDeleteError(err) {
|
|
8313
|
+
if (!err || typeof err !== 'object' || err.code !== 'plugin_service_delete_failed')
|
|
8314
|
+
return false;
|
|
8315
|
+
const failures = Array.isArray(err.failures) ? err.failures : [];
|
|
8316
|
+
const details = failures
|
|
8317
|
+
.map((failure) => `${String(failure.pluginId ?? 'unknown')}: ${String(failure.warning ?? 'PM2 删除失败')}`)
|
|
8318
|
+
.join('; ');
|
|
8319
|
+
console.error('❌ 插件服务的 PM2 记录删除失败,插件未卸载。');
|
|
8320
|
+
if (details)
|
|
8321
|
+
console.error(` ${details}`);
|
|
8322
|
+
console.error(' 请确认 PM2 可用后重新执行卸载;Botmux 未清理插件文件、配置或绑定。');
|
|
8323
|
+
return true;
|
|
8324
|
+
}
|
|
8271
8325
|
async function cmdPlugin(args) {
|
|
8272
8326
|
const sub = (args[0] ?? 'list').toLowerCase();
|
|
8273
8327
|
if (sub === 'help' || sub === '--help' || sub === '-h') {
|
|
@@ -8283,7 +8337,17 @@ async function cmdPlugin(args) {
|
|
|
8283
8337
|
const { installPlugin } = await import('./core/plugins/install.js');
|
|
8284
8338
|
const { resolveOfficialPluginPackageSpec } = await import('./core/plugins/init.js');
|
|
8285
8339
|
const resolvedSpec = resolveOfficialPluginPackageSpec(spec);
|
|
8286
|
-
|
|
8340
|
+
let result;
|
|
8341
|
+
try {
|
|
8342
|
+
result = installPlugin(resolvedSpec, { link: args.includes('--link') });
|
|
8343
|
+
}
|
|
8344
|
+
catch (err) {
|
|
8345
|
+
if (printPluginServiceRunningError(err)) {
|
|
8346
|
+
process.exitCode = 1;
|
|
8347
|
+
return;
|
|
8348
|
+
}
|
|
8349
|
+
throw err;
|
|
8350
|
+
}
|
|
8287
8351
|
const enabledPlugins = normalizePluginIdList(readGlobalConfig().plugins) ?? [];
|
|
8288
8352
|
if (enabledPlugins.includes(result.record.id)) {
|
|
8289
8353
|
const { materializePlugin } = await import('./core/plugins/materializer.js');
|
|
@@ -8381,27 +8445,54 @@ async function cmdPlugin(args) {
|
|
|
8381
8445
|
if (sub === 'uninstall' || sub === 'remove' || sub === 'rm') {
|
|
8382
8446
|
const pluginId = requirePluginId(args[1]);
|
|
8383
8447
|
assertPluginInstalled(pluginId);
|
|
8384
|
-
const
|
|
8385
|
-
for (const bot of loadBotsJson()) {
|
|
8386
|
-
for (const id of normalizePluginIdList(bot.plugins) ?? [])
|
|
8387
|
-
enabledEverywhere.add(id);
|
|
8388
|
-
}
|
|
8389
|
-
const dependents = enabledPluginDependents(pluginId, [...enabledEverywhere], registry);
|
|
8390
|
-
if (dependents.length > 0) {
|
|
8391
|
-
console.error(`❌ 不能卸载 ${pluginId},以下已启用插件依赖它: ${dependents.join(', ')}`);
|
|
8392
|
-
console.error(' 请先在对应作用域显式禁用这些插件。');
|
|
8393
|
-
process.exit(1);
|
|
8394
|
-
}
|
|
8448
|
+
const { assertPluginServiceStopped, deletePluginServicesOrThrowUnlocked, withPluginServiceLock, } = await import('./core/plugins/service-manager.js');
|
|
8395
8449
|
const { dematerializePlugin } = await import('./core/plugins/materializer.js');
|
|
8396
|
-
const {
|
|
8397
|
-
dematerializePlugin(pluginId);
|
|
8398
|
-
await deletePluginServices([pluginId]);
|
|
8399
|
-
await removePluginSkillRegistryEntries(pluginId);
|
|
8400
|
-
const { removeInstalledPlugin } = await import('./services/plugin-registry-store.js');
|
|
8450
|
+
const { readPluginRegistry, removeInstalledPlugin } = await import('./services/plugin-registry-store.js');
|
|
8401
8451
|
const { pluginHome } = await import('./core/plugins/paths.js');
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8452
|
+
try {
|
|
8453
|
+
await withPluginServiceLock(async () => {
|
|
8454
|
+
const lockedRegistry = readPluginRegistry();
|
|
8455
|
+
const installed = lockedRegistry.plugins[pluginId];
|
|
8456
|
+
if (!installed)
|
|
8457
|
+
throw new Error(`plugin_not_installed:${pluginId}`);
|
|
8458
|
+
const enabledEverywhere = new Set(normalizePluginIdList(readGlobalConfig().plugins) ?? []);
|
|
8459
|
+
for (const bot of loadBotsJson()) {
|
|
8460
|
+
for (const id of normalizePluginIdList(bot.plugins) ?? [])
|
|
8461
|
+
enabledEverywhere.add(id);
|
|
8462
|
+
}
|
|
8463
|
+
const dependents = enabledPluginDependents(pluginId, [...enabledEverywhere], lockedRegistry);
|
|
8464
|
+
if (dependents.length > 0) {
|
|
8465
|
+
throw new Error(`plugin_has_enabled_dependents:${pluginId}:${dependents.join(',')}`);
|
|
8466
|
+
}
|
|
8467
|
+
if (installed.manifest.service) {
|
|
8468
|
+
assertPluginServiceStopped(pluginId, 'uninstall');
|
|
8469
|
+
}
|
|
8470
|
+
await deletePluginServicesOrThrowUnlocked([pluginId]);
|
|
8471
|
+
dematerializePlugin(pluginId);
|
|
8472
|
+
await removePluginSkillRegistryEntries(pluginId);
|
|
8473
|
+
removeInstalledPlugin(pluginId);
|
|
8474
|
+
removePluginBindingsEverywhere(pluginId);
|
|
8475
|
+
rmSync(pluginHome(pluginId), { recursive: true, force: true });
|
|
8476
|
+
});
|
|
8477
|
+
}
|
|
8478
|
+
catch (err) {
|
|
8479
|
+
if (err instanceof Error && err.message.startsWith(`plugin_has_enabled_dependents:${pluginId}:`)) {
|
|
8480
|
+
const dependents = err.message.slice(`plugin_has_enabled_dependents:${pluginId}:`.length).split(',').filter(Boolean);
|
|
8481
|
+
console.error(`❌ 不能卸载 ${pluginId},以下已启用插件依赖它: ${dependents.join(', ')}`);
|
|
8482
|
+
console.error(' 请先在对应作用域显式禁用这些插件。');
|
|
8483
|
+
process.exitCode = 1;
|
|
8484
|
+
return;
|
|
8485
|
+
}
|
|
8486
|
+
if (printPluginServiceRunningError(err)) {
|
|
8487
|
+
process.exitCode = 1;
|
|
8488
|
+
return;
|
|
8489
|
+
}
|
|
8490
|
+
if (printPluginServiceDeleteError(err)) {
|
|
8491
|
+
process.exitCode = 1;
|
|
8492
|
+
return;
|
|
8493
|
+
}
|
|
8494
|
+
throw err;
|
|
8495
|
+
}
|
|
8405
8496
|
console.log(`✅ 已卸载插件: ${pluginId}`);
|
|
8406
8497
|
return;
|
|
8407
8498
|
}
|
|
@@ -8579,6 +8670,7 @@ switch (command) {
|
|
|
8579
8670
|
process.exitCode = 2;
|
|
8580
8671
|
break;
|
|
8581
8672
|
}
|
|
8673
|
+
process.env.SESSION_DATA_DIR ??= resolveDataDir();
|
|
8582
8674
|
const { runMcpGateway } = await import('./core/plugins/mcp/gateway.js');
|
|
8583
8675
|
await runMcpGateway();
|
|
8584
8676
|
break;
|