botmux 3.2.1 → 3.4.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 +47 -0
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +137 -0
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +4 -0
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +72 -3
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +143 -6
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +8 -2
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +8 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli/deferred-topic-send.d.ts +37 -0
- package/dist/cli/deferred-topic-send.d.ts.map +1 -0
- package/dist/cli/deferred-topic-send.js +69 -0
- package/dist/cli/deferred-topic-send.js.map +1 -0
- package/dist/cli/pm2-command.d.ts.map +1 -1
- package/dist/cli/pm2-command.js +6 -0
- package/dist/cli/pm2-command.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +173 -34
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +17 -12
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +4 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +99 -8
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/deferred-schedule-settlement.d.ts +20 -0
- package/dist/core/deferred-schedule-settlement.d.ts.map +1 -0
- package/dist/core/deferred-schedule-settlement.js +18 -0
- package/dist/core/deferred-schedule-settlement.js.map +1 -0
- package/dist/core/deferred-topic-binding.d.ts +19 -0
- package/dist/core/deferred-topic-binding.d.ts.map +1 -0
- package/dist/core/deferred-topic-binding.js +55 -0
- package/dist/core/deferred-topic-binding.js.map +1 -0
- package/dist/core/device-isolation-activation.d.ts +56 -0
- package/dist/core/device-isolation-activation.d.ts.map +1 -0
- package/dist/core/device-isolation-activation.js +110 -0
- package/dist/core/device-isolation-activation.js.map +1 -0
- package/dist/core/device-isolation-daemon.d.ts +84 -0
- package/dist/core/device-isolation-daemon.d.ts.map +1 -0
- package/dist/core/device-isolation-daemon.js +591 -0
- package/dist/core/device-isolation-daemon.js.map +1 -0
- package/dist/core/scheduler.d.ts +26 -20
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +114 -56
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +47 -15
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +178 -84
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +13 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +7 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +86 -1
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +95 -5
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +12 -3
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +32 -8
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/web/dashboard-components.d.ts +7 -0
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-components.js +11 -2
- package/dist/dashboard/web/dashboard-components.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +30 -6
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts +2 -0
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +74 -27
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-O37SAQD5.js → bot-defaults-page-B5AY4B2J.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-6QHMLMIM.js → chunk-CUV65BIQ.js} +3 -3
- package/dist/dashboard-web/chunks/{chunk-O2DPQL7C.js → chunk-JNRSPKLS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FYALHCPG.js → chunk-P6GO5KT4.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-QFMH6ITB.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-B42PCL5P.js → chunk-UBOLHQCK.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-DZBQ42MH.js → connectors-page-KTC2QWNW.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-3IEGRZKQ.js → groups-page-B3EKGOLY.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-X3ADRON3.js → insights-page-X6RXNCWX.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-IV36RGQY.js → monitor-room-LLRA5LQW.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-ADFKVON4.js → monitoring-page-7MT5FEOS.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-CALAOWNS.js → office-page-KD46D5TD.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-SLMGLK3M.js → overview-page-JUWNH32O.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-L7JJ4FFV.js → roles-page-P6F7NLOI.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-page-XIHWZST4.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-page-OKJ5YWUZ.js → sessions-page-2VECQ27T.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-P6MI2ZUE.js → settings-page-HMIUE2JA.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-FT7BVZ6X.js → skills-page-A46KVWBL.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-DEYCPUFB.js → team-federation-page-SDUC56DF.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-4IOWREZG.js → v3-page-J5JOTUSQ.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-2VMBETZH.js → whiteboards-page-U7LSOAWI.js} +1 -1
- package/dist/dashboard-web/style.css +34 -4
- package/dist/dashboard.js +16 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/desktop/main/auto-start.d.ts +2 -0
- package/dist/desktop/main/auto-start.d.ts.map +1 -1
- package/dist/desktop/main/auto-start.js +10 -6
- package/dist/desktop/main/auto-start.js.map +1 -1
- package/dist/desktop/main/bundled-runtime.d.ts +12 -0
- package/dist/desktop/main/bundled-runtime.d.ts.map +1 -0
- package/dist/desktop/main/bundled-runtime.js +30 -0
- package/dist/desktop/main/bundled-runtime.js.map +1 -0
- package/dist/desktop/main/device-status.d.ts +15 -0
- package/dist/desktop/main/device-status.d.ts.map +1 -0
- package/dist/desktop/main/device-status.js +94 -0
- package/dist/desktop/main/device-status.js.map +1 -0
- package/dist/desktop/main/external-runtime.d.ts +9 -0
- package/dist/desktop/main/external-runtime.d.ts.map +1 -1
- package/dist/desktop/main/external-runtime.js +88 -18
- package/dist/desktop/main/external-runtime.js.map +1 -1
- package/dist/desktop/main/ipc.d.ts.map +1 -1
- package/dist/desktop/main/ipc.js +1 -0
- package/dist/desktop/main/ipc.js.map +1 -1
- package/dist/desktop/main/node-command.d.ts +21 -0
- package/dist/desktop/main/node-command.d.ts.map +1 -1
- package/dist/desktop/main/node-command.js +41 -0
- package/dist/desktop/main/node-command.js.map +1 -1
- package/dist/desktop/main/pm2-apps.d.ts +4 -2
- package/dist/desktop/main/pm2-apps.d.ts.map +1 -1
- package/dist/desktop/main/pm2-apps.js +11 -3
- package/dist/desktop/main/pm2-apps.js.map +1 -1
- package/dist/desktop/main/runtime-service.d.ts +21 -5
- package/dist/desktop/main/runtime-service.d.ts.map +1 -1
- package/dist/desktop/main/runtime-service.js +94 -10
- package/dist/desktop/main/runtime-service.js.map +1 -1
- package/dist/desktop/main/runtime-source.d.ts +2 -0
- package/dist/desktop/main/runtime-source.d.ts.map +1 -1
- package/dist/desktop/main/runtime-source.js +12 -6
- package/dist/desktop/main/runtime-source.js.map +1 -1
- package/dist/desktop/main/tray.d.ts +1 -0
- package/dist/desktop/main/tray.d.ts.map +1 -1
- package/dist/desktop/main/tray.js +3 -3
- package/dist/desktop/main/tray.js.map +1 -1
- package/dist/desktop/main.js +28 -8
- package/dist/desktop/main.js.map +1 -1
- package/dist/desktop/preload.js +3 -0
- package/dist/desktop/preload.js.map +1 -1
- package/dist/desktop/renderer/app.d.ts +2 -1
- package/dist/desktop/renderer/app.d.ts.map +1 -1
- package/dist/desktop/renderer/app.js +6 -1
- package/dist/desktop/renderer/app.js.map +1 -1
- package/dist/desktop/renderer/runtime-state.d.ts.map +1 -1
- package/dist/desktop/renderer/runtime-state.js +2 -0
- package/dist/desktop/renderer/runtime-state.js.map +1 -1
- package/dist/desktop/shared/shell-path-probes.d.ts +24 -0
- package/dist/desktop/shared/shell-path-probes.d.ts.map +1 -0
- package/dist/desktop/shared/shell-path-probes.js +38 -0
- package/dist/desktop/shared/shell-path-probes.js.map +1 -0
- package/dist/desktop/shared/types.d.ts +21 -1
- package/dist/desktop/shared/types.d.ts.map +1 -1
- package/dist/desktop/smoke.d.ts +1 -0
- package/dist/desktop/smoke.d.ts.map +1 -1
- package/dist/desktop/smoke.js +20 -5
- package/dist/desktop/smoke.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +16 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +16 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +3 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +1 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +1 -1
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/schedules-card.d.ts +2 -2
- package/dist/im/lark/schedules-card.d.ts.map +1 -1
- package/dist/im/lark/schedules-card.js +50 -34
- package/dist/im/lark/schedules-card.js.map +1 -1
- package/dist/index-daemon.js +13 -1
- package/dist/index-daemon.js.map +1 -1
- package/dist/platform/bind.d.ts +4 -1
- package/dist/platform/bind.d.ts.map +1 -1
- package/dist/platform/bind.js +10 -1
- package/dist/platform/bind.js.map +1 -1
- package/dist/platform/binding.d.ts.map +1 -1
- package/dist/platform/binding.js +15 -9
- package/dist/platform/binding.js.map +1 -1
- package/dist/platform/device-command.d.ts +35 -0
- package/dist/platform/device-command.d.ts.map +1 -0
- package/dist/platform/device-command.js +187 -0
- package/dist/platform/device-command.js.map +1 -0
- package/dist/platform/device-enroll.d.ts +156 -0
- package/dist/platform/device-enroll.d.ts.map +1 -0
- package/dist/platform/device-enroll.js +781 -0
- package/dist/platform/device-enroll.js.map +1 -0
- package/dist/platform/device-isolation-activation-client.d.ts +28 -0
- package/dist/platform/device-isolation-activation-client.d.ts.map +1 -0
- package/dist/platform/device-isolation-activation-client.js +279 -0
- package/dist/platform/device-isolation-activation-client.js.map +1 -0
- package/dist/platform/device-isolation.d.ts +35 -0
- package/dist/platform/device-isolation.d.ts.map +1 -0
- package/dist/platform/device-isolation.js +90 -0
- package/dist/platform/device-isolation.js.map +1 -0
- package/dist/platform/device-paths.d.ts +9 -0
- package/dist/platform/device-paths.d.ts.map +1 -0
- package/dist/platform/device-paths.js +14 -0
- package/dist/platform/device-paths.js.map +1 -0
- package/dist/platform/device.d.ts +77 -0
- package/dist/platform/device.d.ts.map +1 -0
- package/dist/platform/device.js +212 -0
- package/dist/platform/device.js.map +1 -0
- package/dist/platform/host-command-context.d.ts +15 -0
- package/dist/platform/host-command-context.d.ts.map +1 -0
- package/dist/platform/host-command-context.js +26 -0
- package/dist/platform/host-command-context.js.map +1 -0
- package/dist/platform/secure-host-file.d.ts +12 -0
- package/dist/platform/secure-host-file.d.ts.map +1 -0
- package/dist/platform/secure-host-file.js +182 -0
- package/dist/platform/secure-host-file.js.map +1 -0
- package/dist/services/schedule-store.d.ts +6 -2
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +19 -4
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +4 -5
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +45 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/atomic-write.d.ts +13 -0
- package/dist/utils/atomic-write.d.ts.map +1 -1
- package/dist/utils/atomic-write.js +89 -9
- package/dist/utils/atomic-write.js.map +1 -1
- package/dist/utils/child-env.d.ts +40 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +45 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/pending-input-queue.d.ts +10 -0
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +15 -0
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/worker.js +391 -28
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +4 -4
- package/dist/workflows/events/schema.d.ts +16 -16
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +3 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +14 -3
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/dist/workflows/v3/architect.js +1 -1
- package/dist/workflows/v3/architect.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -0
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +2 -0
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +10 -2
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/run-envelope.d.ts +24 -24
- package/dist/workflows/v3/runtime.d.ts +5 -0
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +1 -0
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/package.json +6 -3
- package/dist/dashboard-web/chunks/chunk-I35DXGM4.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-Z3672POL.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* botmux logs [--lines] — view daemon logs
|
|
13
13
|
* botmux status — show daemon status
|
|
14
14
|
* botmux upgrade|update — upgrade to latest version
|
|
15
|
+
* botmux device enroll|status|logout — manage the host desktop device credential
|
|
15
16
|
* botmux list — interactive session picker (TUI), attach to tmux
|
|
16
17
|
* botmux list --plain — plain table output (for piping / scripts)
|
|
17
18
|
* botmux delete <id> — close a session by ID prefix
|
|
@@ -46,11 +47,13 @@ import { buildBotFromAddFlags, editInputFromFlags, isScriptedSetupInvocation, ma
|
|
|
46
47
|
import { interactiveSelect, pickChoice, pickCliSelection } from './setup/interactive-select.js';
|
|
47
48
|
import { buildPreset, serializePreset, presetFilename } from './setup/agent-preset.js';
|
|
48
49
|
import { logger } from './utils/logger.js';
|
|
50
|
+
import { scrubSessionCliHomeEnv } from './utils/child-env.js';
|
|
49
51
|
import { scheduleTimeZone } from './utils/timezone.js';
|
|
50
52
|
import { expandHomePath, invalidWorkingDirs } from './utils/working-dir.js';
|
|
51
53
|
import { firstPositional } from './cli/arg-utils.js';
|
|
52
54
|
import { isColdResumeDormant, sessionListDisposition } from './cli/session-list-liveness.js';
|
|
53
55
|
import { dispatchPrimaryMessage, findStdinAliasAttachment, normalizeInteractiveCardInput, sendFileAttachments, sendVideoAttachments, shouldSendAsPureVideo, validateVideoAttachments } from './cli/send-dispatch.js';
|
|
56
|
+
import { dispatchDeferredTopicSend } from './cli/deferred-topic-send.js';
|
|
54
57
|
import { resolveDaemonExternalHostEnv } from './cli/daemon-lifecycle-env.js';
|
|
55
58
|
import { buildPm2SpawnCommand } from './cli/pm2-command.js';
|
|
56
59
|
import { callDashboard } from './cli/dashboard-endpoint.js';
|
|
@@ -146,7 +149,18 @@ function pm2Bin() {
|
|
|
146
149
|
}
|
|
147
150
|
/** Env for pm2 invocations with an isolated PM2_HOME. */
|
|
148
151
|
function pm2Env(home = PM2_HOME) {
|
|
149
|
-
|
|
152
|
+
const env = { ...process.env, PM2_HOME: home };
|
|
153
|
+
// pm2 persists the caller's env into every managed app (and into dump.pm2
|
|
154
|
+
// for resurrect), so a `botmux start/restart` invoked from ANY process that
|
|
155
|
+
// carries a session-level CLI home pointer — most commonly a bot's own
|
|
156
|
+
// session during self-upgrade, whose env holds its injected
|
|
157
|
+
// CLAUDE_CONFIG_DIR — would poison ALL workers, making every non-isolated
|
|
158
|
+
// bot read/write a sibling bot's home. Strip at this boundary so the daemon
|
|
159
|
+
// stays session-agnostic; daemon/worker boot scrub the same keys against
|
|
160
|
+
// stale dumps (see SESSION_CLI_HOME_ENV_KEYS for the full story, including
|
|
161
|
+
// why GROK_HOME is exempt and why deleting beats pinning a default).
|
|
162
|
+
scrubSessionCliHomeEnv(env);
|
|
163
|
+
return env;
|
|
150
164
|
}
|
|
151
165
|
function listPm2GodDaemonPids(home = PM2_HOME) {
|
|
152
166
|
if (process.platform !== 'linux')
|
|
@@ -325,6 +339,10 @@ function ecosystemConfig() {
|
|
|
325
339
|
const externalHostEnv = resolveDaemonExternalHostEnv(process.env, existsSync(ENV_FILE) ? readFileSync(ENV_FILE, 'utf-8') : undefined);
|
|
326
340
|
const baseApp = {
|
|
327
341
|
script: daemonScript,
|
|
342
|
+
// Pin every managed core process to the Node that invoked this CLI. This
|
|
343
|
+
// keeps GUI/launchd starts independent from PATH and lets Desktop replace
|
|
344
|
+
// an external fleet without also killing unrelated plugin services.
|
|
345
|
+
interpreter: process.execPath,
|
|
328
346
|
cwd: CONFIG_DIR,
|
|
329
347
|
autorestart: true,
|
|
330
348
|
max_restarts: 10,
|
|
@@ -370,6 +388,7 @@ function ecosystemConfig() {
|
|
|
370
388
|
apps.push({
|
|
371
389
|
name: 'botmux-dashboard',
|
|
372
390
|
script: join(PKG_ROOT, 'dist', 'dashboard.js'),
|
|
391
|
+
interpreter: process.execPath,
|
|
373
392
|
cwd: PKG_ROOT,
|
|
374
393
|
autorestart: true,
|
|
375
394
|
max_restarts: 10,
|
|
@@ -4057,6 +4076,9 @@ async function cmdResume() {
|
|
|
4057
4076
|
else if (errCode === 'adopt_unsupported') {
|
|
4058
4077
|
console.error('❌ adopt 接管会话不支持 resume。');
|
|
4059
4078
|
}
|
|
4079
|
+
else if (errCode === 'deferred_unmaterialized') {
|
|
4080
|
+
console.error('❌ 该静默定时轮次未创建话题,隐藏会话只保留审计记录,不能 resume。');
|
|
4081
|
+
}
|
|
4060
4082
|
else {
|
|
4061
4083
|
console.error(`❌ 恢复失败: ${errCode}`);
|
|
4062
4084
|
}
|
|
@@ -4182,6 +4204,8 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
|
|
|
4182
4204
|
status 查看 daemon 状态
|
|
4183
4205
|
upgrade 升级到最新版本(别名:update)
|
|
4184
4206
|
dashboard 打印新的 Web Dashboard 一次性登录 URL(旧 token 同时失效)
|
|
4207
|
+
device enroll|status|logout
|
|
4208
|
+
在宿主终端注册、查看或清除 desktop device 凭证(AI CLI 会话内拒绝)
|
|
4185
4209
|
list 列出活跃会话(交互式选择并连接 tmux)
|
|
4186
4210
|
--plain 纯文本表格输出(管道/脚本场景)
|
|
4187
4211
|
delete <id> 关闭指定会话(支持 ID 前缀匹配)
|
|
@@ -4231,8 +4255,10 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
|
|
|
4231
4255
|
定时任务(可在 CLI 会话内自动推断 chat):
|
|
4232
4256
|
schedule list 列出所有任务
|
|
4233
4257
|
schedule add <schedule> <prompt> 添加任务(ex: "30m" / "every 2h" / "每日9:00" / "0 9 * * *")
|
|
4234
|
-
--
|
|
4235
|
-
--
|
|
4258
|
+
--top-level 在群消息顶层执行(后续会话形态跟随普通群会话模式)
|
|
4259
|
+
--topic --root-msg-id <om_...> 固定在指定话题下执行
|
|
4260
|
+
--new-topic [--topic-title ...] 每次创建新话题和独立会话
|
|
4261
|
+
--silent 静默执行:不发「执行中」提示,模型判断是否 botmux send 报警
|
|
4236
4262
|
schedule remove <id> 删除任务
|
|
4237
4263
|
schedule pause|resume <id> 暂停/恢复
|
|
4238
4264
|
schedule run <id> 标记立即执行
|
|
@@ -4711,9 +4737,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4711
4737
|
return;
|
|
4712
4738
|
}
|
|
4713
4739
|
if (sub === 'add') {
|
|
4714
|
-
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic', '--silent']);
|
|
4740
|
+
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic', '--top-level', '--topic', '--silent']);
|
|
4715
4741
|
if (!rawSchedule) {
|
|
4716
|
-
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--root-msg-id ROOT] [--lark-app-id APP] [--workdir DIR] [--
|
|
4742
|
+
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--top-level | --topic --root-msg-id ROOT | --new-topic [--topic-title TITLE]] [--lark-app-id APP] [--workdir DIR] [--silent]');
|
|
4717
4743
|
process.exit(1);
|
|
4718
4744
|
}
|
|
4719
4745
|
// prompt may come from positional or --prompt flag
|
|
@@ -4724,25 +4750,50 @@ async function cmdSchedule(sub, rest) {
|
|
|
4724
4750
|
}
|
|
4725
4751
|
const cur = detectCurrentSession();
|
|
4726
4752
|
const chatId = argValue(rest, '--chat-id') ?? cur?.chatId;
|
|
4727
|
-
const
|
|
4753
|
+
const explicitRootMessageId = argValue(rest, '--root-msg-id');
|
|
4754
|
+
const rootMessageId = explicitRootMessageId
|
|
4755
|
+
?? (chatId && chatId === cur?.chatId ? cur.rootMessageId : undefined);
|
|
4728
4756
|
const larkAppId = argValue(rest, '--lark-app-id') ?? cur?.larkAppId;
|
|
4729
4757
|
const workingDir = argValue(rest, '--workdir') ?? cur?.workingDir ?? process.cwd();
|
|
4730
4758
|
const name = argValue(rest, '--name') ?? (promptArg.length > 20 ? promptArg.slice(0, 20) + '…' : promptArg);
|
|
4731
|
-
|
|
4732
|
-
const
|
|
4733
|
-
|
|
4734
|
-
|
|
4759
|
+
const legacyDeliver = argValue(rest, '--deliver');
|
|
4760
|
+
const wantsNewTopic = rest.includes('--new-topic') || legacyDeliver === 'new-topic';
|
|
4761
|
+
const wantsTopLevel = rest.includes('--top-level');
|
|
4762
|
+
const wantsTopic = rest.includes('--topic');
|
|
4763
|
+
if ([wantsNewTopic, wantsTopLevel, wantsTopic].filter(Boolean).length > 1) {
|
|
4764
|
+
console.error('--top-level、--topic 与 --new-topic 只能选择一个。');
|
|
4765
|
+
process.exit(1);
|
|
4766
|
+
}
|
|
4767
|
+
const requestedDeliver = legacyDeliver;
|
|
4768
|
+
const deliver = requestedDeliver === 'local' ? 'local' : 'origin';
|
|
4735
4769
|
// --silent: fires post no "执行中" banner; the spawned turn stays quiet and
|
|
4736
4770
|
// the model only `botmux send`s when the alert condition in the prompt is met.
|
|
4737
4771
|
const silent = rest.includes('--silent');
|
|
4738
|
-
if (silent && deliver === 'new-topic') {
|
|
4739
|
-
console.error('--silent 与 --new-topic 不能同时使用:新话题必须由首条消息开启。要「有异常才开新话题」,请在 prompt 里指示模型报警时用 botmux send 顶层发送。');
|
|
4740
|
-
process.exit(1);
|
|
4741
|
-
}
|
|
4742
4772
|
if (!chatId) {
|
|
4743
4773
|
console.error('无法推断 chat-id。请加上 --chat-id <CHAT_ID>,或从 Lark 话题内的 CLI 会话中运行本命令。');
|
|
4744
4774
|
process.exit(1);
|
|
4745
4775
|
}
|
|
4776
|
+
const executionPosition = wantsNewTopic
|
|
4777
|
+
? 'new-topic'
|
|
4778
|
+
: wantsTopLevel
|
|
4779
|
+
? 'top-level'
|
|
4780
|
+
: wantsTopic
|
|
4781
|
+
? 'topic'
|
|
4782
|
+
: cur?.scope === 'chat' ? 'top-level' : rootMessageId ? 'topic' : 'top-level';
|
|
4783
|
+
const scope = executionPosition === 'topic' ? 'thread' : 'chat';
|
|
4784
|
+
if (scope === 'thread' && !rootMessageId) {
|
|
4785
|
+
console.error('话题下执行需要 --root-msg-id <ROOT_MESSAGE_ID>,或从 Lark 话题会话中运行。');
|
|
4786
|
+
process.exit(1);
|
|
4787
|
+
}
|
|
4788
|
+
const topicTitle = argValue(rest, '--topic-title');
|
|
4789
|
+
if (topicTitle && executionPosition !== 'new-topic') {
|
|
4790
|
+
console.error('--topic-title 仅可与 --new-topic 一起使用。');
|
|
4791
|
+
process.exit(1);
|
|
4792
|
+
}
|
|
4793
|
+
if (topicTitle && Array.from(topicTitle.trim()).length > 200) {
|
|
4794
|
+
console.error('--topic-title 最多 200 个字符。');
|
|
4795
|
+
process.exit(1);
|
|
4796
|
+
}
|
|
4746
4797
|
let parsed;
|
|
4747
4798
|
try {
|
|
4748
4799
|
parsed = scheduler.parseSchedule(rawSchedule);
|
|
@@ -4764,7 +4815,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4764
4815
|
creatorRootMessageId: cur?.rootMessageId,
|
|
4765
4816
|
creatorLarkAppId: cur?.larkAppId,
|
|
4766
4817
|
chatType: cur?.chatType === 'p2p' ? 'p2p' : 'topic_group',
|
|
4767
|
-
scope
|
|
4818
|
+
scope,
|
|
4819
|
+
executionPosition,
|
|
4820
|
+
topicTitle,
|
|
4768
4821
|
deliver,
|
|
4769
4822
|
silent,
|
|
4770
4823
|
});
|
|
@@ -4773,7 +4826,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4773
4826
|
console.log(` 规则: ${parsed.display}`);
|
|
4774
4827
|
console.log(` 下次执行: ${next}`);
|
|
4775
4828
|
console.log(` 工作目录: ${workingDir}`);
|
|
4776
|
-
console.log(`
|
|
4829
|
+
console.log(` 执行位置: ${executionPosition === 'new-topic' ? '每次新话题' : executionPosition === 'top-level' ? '群消息顶层' : '话题下'}`);
|
|
4830
|
+
if (executionPosition === 'new-topic' && topicTitle?.trim())
|
|
4831
|
+
console.log(` 新话题标题: ${topicTitle.trim()}`);
|
|
4777
4832
|
if (silent)
|
|
4778
4833
|
console.log(' 静默: 触发时不发「执行中」提示,由模型判断是否需要 botmux send 报警');
|
|
4779
4834
|
return;
|
|
@@ -5417,6 +5472,10 @@ function riffModeSession(opts = {}) {
|
|
|
5417
5472
|
const scopeEnv = process.env.BOTMUX_SESSION_SCOPE;
|
|
5418
5473
|
const scope = scopeEnv === 'chat' || scopeEnv === 'thread' ? scopeEnv : (rootMessageId ? 'thread' : 'chat');
|
|
5419
5474
|
const ownerOpenId = process.env.BOTMUX_OWNER_OPEN_ID;
|
|
5475
|
+
const deferredTaskId = process.env.BOTMUX_DEFERRED_SCHEDULE_TASK_ID;
|
|
5476
|
+
const deferredTurnId = process.env.BOTMUX_DEFERRED_SCHEDULE_TURN_ID;
|
|
5477
|
+
const deferredRoutingAnchor = process.env.BOTMUX_DEFERRED_SCHEDULE_ROUTING_ANCHOR;
|
|
5478
|
+
const deferredCreatedAt = process.env.BOTMUX_DEFERRED_SCHEDULE_CREATED_AT;
|
|
5420
5479
|
const botConfig = {
|
|
5421
5480
|
larkAppId: appId,
|
|
5422
5481
|
larkAppSecret: appSecret,
|
|
@@ -5434,6 +5493,19 @@ function riffModeSession(opts = {}) {
|
|
|
5434
5493
|
larkAppId: appId,
|
|
5435
5494
|
scope,
|
|
5436
5495
|
ownerOpenId,
|
|
5496
|
+
...(deferredTaskId && deferredTurnId && deferredRoutingAnchor && deferredCreatedAt
|
|
5497
|
+
? {
|
|
5498
|
+
deferredScheduleRun: {
|
|
5499
|
+
taskId: deferredTaskId,
|
|
5500
|
+
turnId: deferredTurnId,
|
|
5501
|
+
routingAnchor: deferredRoutingAnchor,
|
|
5502
|
+
...(process.env.BOTMUX_DEFERRED_SCHEDULE_TOPIC_TITLE
|
|
5503
|
+
? { topicTitle: process.env.BOTMUX_DEFERRED_SCHEDULE_TOPIC_TITLE }
|
|
5504
|
+
: {}),
|
|
5505
|
+
createdAt: deferredCreatedAt,
|
|
5506
|
+
},
|
|
5507
|
+
}
|
|
5508
|
+
: {}),
|
|
5437
5509
|
// 刻意不设 quoteTargetSenderOpenId:env 是任务创建时冻结的,follow-up 轮
|
|
5438
5510
|
// 换了触发人后 --mention-back 会错误 @ 最初 owner。riff routing 明确禁用
|
|
5439
5511
|
// mention-back(@ 硬门会拒绝并提示 agent 改用 --mention <本轮 sender>)。
|
|
@@ -5707,6 +5779,8 @@ async function cmdSend(rest) {
|
|
|
5707
5779
|
console.error(`session ${sid} 缺少 larkAppId`);
|
|
5708
5780
|
process.exit(1);
|
|
5709
5781
|
}
|
|
5782
|
+
let deferredMaterializedByThisCommand = false;
|
|
5783
|
+
let deferredTopicRootMessageIdForOutput;
|
|
5710
5784
|
// 本轮的回复锚点:优先按 turnId 精确取 per-turn 落点(排队/并发轮次不再被
|
|
5711
5785
|
// 后到轮次覆盖 currentReplyTarget 而塌成群顶层 plain),无记录再退回单槽。
|
|
5712
5786
|
const turnReplyTarget = pickTurnReplyTarget(s, currentTurnId);
|
|
@@ -5855,23 +5929,45 @@ async function cmdSend(rest) {
|
|
|
5855
5929
|
}
|
|
5856
5930
|
else {
|
|
5857
5931
|
revalidateVcMeetingManagedSend();
|
|
5858
|
-
const canonicalTarget = resolveSendTarget({
|
|
5859
|
-
into: sendInto,
|
|
5860
|
-
topLevel: sendTopLevel,
|
|
5861
|
-
chatScope: s.scope === 'chat',
|
|
5862
|
-
chatId: canonicalOutput.targetChatId,
|
|
5863
|
-
rootMessageId: s.rootMessageId,
|
|
5864
|
-
replyTargetRootId: turnReplyTarget?.rootMessageId,
|
|
5865
|
-
replyTargetTurnId: turnReplyTarget?.turnId,
|
|
5866
|
-
replyTargetQuoteOnly: turnReplyTarget?.quoteOnly,
|
|
5867
|
-
currentTurnId,
|
|
5868
|
-
});
|
|
5869
5932
|
const managedProviderOptions = prepared
|
|
5870
5933
|
? { suppressHook: true }
|
|
5871
5934
|
: undefined;
|
|
5872
|
-
|
|
5873
|
-
? await
|
|
5874
|
-
|
|
5935
|
+
const deferred = !sendInto && (!overrideChatId || overrideChatId === s.chatId)
|
|
5936
|
+
? await dispatchDeferredTopicSend({
|
|
5937
|
+
dataDir: resolveDataDir(),
|
|
5938
|
+
session: s,
|
|
5939
|
+
currentTurnId,
|
|
5940
|
+
explicitTopLevel: sendTopLevel,
|
|
5941
|
+
reuseBoundRootWhenTopLevel: deferredMaterializedByThisCommand,
|
|
5942
|
+
content: canonicalOutput.content,
|
|
5943
|
+
msgType: canonicalOutput.msgType,
|
|
5944
|
+
uuid: prepared?.providerKey,
|
|
5945
|
+
sendRoot: (body, type, uuid) => sendMessage(appId, targetChatId, body, type, uuid, undefined, managedProviderOptions),
|
|
5946
|
+
sendTitleSeed: (title, uuid) => sendMessage(appId, targetChatId, title, 'text', uuid),
|
|
5947
|
+
replyRoot: (root, body, type, uuid) => replyMessage(appId, root, body, type, true, uuid, undefined, managedProviderOptions),
|
|
5948
|
+
})
|
|
5949
|
+
: { handled: false };
|
|
5950
|
+
if (deferred.handled && deferred.messageId) {
|
|
5951
|
+
deferredMaterializedByThisCommand ||= deferred.materializedNow === true;
|
|
5952
|
+
deferredTopicRootMessageIdForOutput = deferred.rootMessageId;
|
|
5953
|
+
messageId = deferred.messageId;
|
|
5954
|
+
}
|
|
5955
|
+
else {
|
|
5956
|
+
const canonicalTarget = resolveSendTarget({
|
|
5957
|
+
into: sendInto,
|
|
5958
|
+
topLevel: sendTopLevel,
|
|
5959
|
+
chatScope: s.scope === 'chat',
|
|
5960
|
+
chatId: canonicalOutput.targetChatId,
|
|
5961
|
+
rootMessageId: s.rootMessageId,
|
|
5962
|
+
replyTargetRootId: turnReplyTarget?.rootMessageId,
|
|
5963
|
+
replyTargetTurnId: turnReplyTarget?.turnId,
|
|
5964
|
+
replyTargetQuoteOnly: turnReplyTarget?.quoteOnly,
|
|
5965
|
+
currentTurnId,
|
|
5966
|
+
});
|
|
5967
|
+
messageId = canonicalTarget.mode === 'plain'
|
|
5968
|
+
? await sendMessage(appId, canonicalTarget.chatId, canonicalOutput.content, canonicalOutput.msgType, prepared?.providerKey, undefined, managedProviderOptions)
|
|
5969
|
+
: await replyMessage(appId, canonicalTarget.rootMessageId, canonicalOutput.content, canonicalOutput.msgType, canonicalTarget.mode === 'thread', prepared?.providerKey, undefined, managedProviderOptions);
|
|
5970
|
+
}
|
|
5875
5971
|
if (prepared?.kind === 'send' || prepared?.kind === 'succeeded') {
|
|
5876
5972
|
finishVcMeetingImReply(resolveDataDir(), prepared.ref, messageId);
|
|
5877
5973
|
}
|
|
@@ -5879,7 +5975,9 @@ async function cmdSend(rest) {
|
|
|
5879
5975
|
recordVcMeetingPrimaryOutput(messageId, canonicalOutput.targetChatId);
|
|
5880
5976
|
// 语音也是一次回复:写 bridge fallback marker,否则本轮会被判为"没发 botmux send"
|
|
5881
5977
|
// 而触发兜底,多补一张文本卡。与文本/卡片路径同口径:仅同话题回复才记。
|
|
5882
|
-
if (!sendTopLevel
|
|
5978
|
+
if ((!sendTopLevel || !!deferredTopicRootMessageIdForOutput)
|
|
5979
|
+
&& (!overrideChatId || overrideChatId === s.chatId)
|
|
5980
|
+
&& !sendInto) {
|
|
5883
5981
|
try {
|
|
5884
5982
|
const markerDir = join(resolveDataDir(), 'turn-sends');
|
|
5885
5983
|
if (!existsSync(markerDir))
|
|
@@ -5889,7 +5987,16 @@ async function cmdSend(rest) {
|
|
|
5889
5987
|
catch { /* best-effort:漏记只多一条兜底,不致命 */ }
|
|
5890
5988
|
}
|
|
5891
5989
|
console.error(`✓ 已发送语音 ${messageId} | ${Math.round(out.durationMs / 1000)}s`);
|
|
5892
|
-
console.log(JSON.stringify({
|
|
5990
|
+
console.log(JSON.stringify({
|
|
5991
|
+
success: true,
|
|
5992
|
+
messageId,
|
|
5993
|
+
sessionId: sid,
|
|
5994
|
+
kind: 'voice',
|
|
5995
|
+
durationMs: out.durationMs,
|
|
5996
|
+
...(deferredTopicRootMessageIdForOutput
|
|
5997
|
+
? { deferredTopicRootMessageId: deferredTopicRootMessageIdForOutput, turnId: currentTurnId }
|
|
5998
|
+
: {}),
|
|
5999
|
+
}));
|
|
5893
6000
|
}
|
|
5894
6001
|
catch (e) {
|
|
5895
6002
|
console.error(`语音发送失败:${e?.message ?? e}`);
|
|
@@ -6108,10 +6215,33 @@ async function cmdSend(rest) {
|
|
|
6108
6215
|
// Dispatch helper: top-level / chat-scope send vs reply-in-thread, single
|
|
6109
6216
|
// decision point. Used for file attachments (always plain in chat scope).
|
|
6110
6217
|
const sendTarget = resolveSendTarget({ into: sendInto, topLevel: sendTopLevel, chatScope: isChatScope, chatId: targetChatId, rootMessageId: s.rootMessageId, replyTargetRootId: turnReplyTarget?.rootMessageId, replyTargetTurnId: turnReplyTarget?.turnId, replyTargetQuoteOnly: turnReplyTarget?.quoteOnly, currentTurnId });
|
|
6111
|
-
const dispatch = (content, msgType, uuid, suppressHook) => {
|
|
6218
|
+
const dispatch = async (content, msgType, uuid, suppressHook) => {
|
|
6112
6219
|
// This closure also carries attachments, so every Lark call re-checks the
|
|
6113
6220
|
// exact durable attempt/member instead of inheriting the early cmd gate.
|
|
6114
6221
|
revalidateVcMeetingManagedSend();
|
|
6222
|
+
if (!sendInto && (!overrideChatId || overrideChatId === s.chatId)) {
|
|
6223
|
+
const deferred = await dispatchDeferredTopicSend({
|
|
6224
|
+
dataDir: resolveDataDir(),
|
|
6225
|
+
session: s,
|
|
6226
|
+
currentTurnId,
|
|
6227
|
+
explicitTopLevel: sendTopLevel,
|
|
6228
|
+
reuseBoundRootWhenTopLevel: deferredMaterializedByThisCommand,
|
|
6229
|
+
content,
|
|
6230
|
+
msgType,
|
|
6231
|
+
uuid,
|
|
6232
|
+
sendRoot: (body, type, rootUuid) => sendMessage(appId, targetChatId, body, type, rootUuid, hookContext, suppressHook ? { suppressHook: true } : undefined),
|
|
6233
|
+
// The optional title is the root seed and the actual alert follows as
|
|
6234
|
+
// its first reply. Do not emit a user outbound hook for presentation-
|
|
6235
|
+
// only seed text; the alert itself still goes through the hook path.
|
|
6236
|
+
sendTitleSeed: (title, rootUuid) => sendMessage(appId, targetChatId, title, 'text', rootUuid),
|
|
6237
|
+
replyRoot: (root, body, type, replyUuid) => replyMessage(appId, root, body, type, true, replyUuid, hookContext, suppressHook ? { suppressHook: true } : undefined),
|
|
6238
|
+
});
|
|
6239
|
+
if (deferred.handled && deferred.messageId) {
|
|
6240
|
+
deferredMaterializedByThisCommand ||= deferred.materializedNow === true;
|
|
6241
|
+
deferredTopicRootMessageIdForOutput = deferred.rootMessageId;
|
|
6242
|
+
return deferred.messageId;
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6115
6245
|
return sendTarget.mode === 'plain'
|
|
6116
6246
|
? sendMessage(appId, sendTarget.chatId, content, msgType, uuid, hookContext, suppressHook ? { suppressHook: true } : undefined)
|
|
6117
6247
|
: replyMessage(appId, sendTarget.rootMessageId, content, msgType, sendTarget.mode === 'thread', uuid, hookContext, suppressHook ? { suppressHook: true } : undefined);
|
|
@@ -6538,8 +6668,9 @@ async function cmdSend(rest) {
|
|
|
6538
6668
|
// sends can suppress transcript fallback when their content appears to
|
|
6539
6669
|
// cover the same final answer; detoured sends suppress only when they
|
|
6540
6670
|
// closed a pending response card for this turn.
|
|
6541
|
-
if (shouldRecordBridgeMarker)
|
|
6671
|
+
if (shouldRecordBridgeMarker || deferredTopicRootMessageIdForOutput) {
|
|
6542
6672
|
recordBridgeSendMarker(sentAtMs, messageId, text);
|
|
6673
|
+
}
|
|
6543
6674
|
// Send attachments as separate messages — best-effort. The primary message
|
|
6544
6675
|
// is already delivered above; a failing attachment must not throw out to the
|
|
6545
6676
|
// catch below (which would report total failure / exit 1 for an already-sent
|
|
@@ -6619,6 +6750,9 @@ async function cmdSend(rest) {
|
|
|
6619
6750
|
sessionId: sid,
|
|
6620
6751
|
quotedMessageId: primaryQuotedId,
|
|
6621
6752
|
mentioned: mentions.map(m => ({ open_id: m.open_id, name: m.name })),
|
|
6753
|
+
...(deferredTopicRootMessageIdForOutput
|
|
6754
|
+
? { deferredTopicRootMessageId: deferredTopicRootMessageIdForOutput, turnId: currentTurnId }
|
|
6755
|
+
: {}),
|
|
6622
6756
|
...(attention.requested ? { attentionRaised, attentionError } : {}),
|
|
6623
6757
|
...(failedAttachments.length > 0
|
|
6624
6758
|
? { failedAttachments: failedAttachments.map(f => f.path) }
|
|
@@ -8615,6 +8749,11 @@ switch (command) {
|
|
|
8615
8749
|
await cmdBind(process.argv.slice(3));
|
|
8616
8750
|
break;
|
|
8617
8751
|
}
|
|
8752
|
+
case 'device': {
|
|
8753
|
+
const { runDeviceCommand } = await import('./platform/device-command.js');
|
|
8754
|
+
process.exitCode = await runDeviceCommand(process.argv.slice(3));
|
|
8755
|
+
break;
|
|
8756
|
+
}
|
|
8618
8757
|
case 'list':
|
|
8619
8758
|
case 'ls':
|
|
8620
8759
|
await cmdList();
|