botmux 2.91.1 → 2.93.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/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/bot-registry.d.ts +1 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +14 -11
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/dashboard-endpoint.d.ts +9 -6
- package/dist/cli/dashboard-endpoint.d.ts.map +1 -1
- package/dist/cli/dashboard-endpoint.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -1
- package/dist/config.js.map +1 -1
- package/dist/core/session-manager.js +2 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/daemon.d.ts +5 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +24 -6
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/bot-payload.js +1 -1
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +3 -2
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +6 -4
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard-web/app.js +6 -5
- package/dist/dashboard.js +82 -23
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.js +9 -9
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.js +9 -9
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +12 -7
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
- package/dist/im/lark/relay-target-routing.js +7 -2
- package/dist/im/lark/relay-target-routing.js.map +1 -1
- package/dist/im/lark/reply-mode-command.d.ts.map +1 -1
- package/dist/im/lark/reply-mode-command.js +3 -1
- package/dist/im/lark/reply-mode-command.js.map +1 -1
- package/dist/platform/tunnel-client.d.ts +10 -0
- package/dist/platform/tunnel-client.d.ts.map +1 -1
- package/dist/platform/tunnel-client.js +2 -0
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/card-prefs-store.d.ts +1 -1
- package/dist/services/card-prefs-store.d.ts.map +1 -1
- package/dist/services/card-prefs-store.js +5 -5
- package/dist/services/card-prefs-store.js.map +1 -1
- package/dist/services/chat-reply-mode-store.d.ts +1 -1
- package/dist/services/chat-reply-mode-store.d.ts.map +1 -1
- package/dist/services/chat-reply-mode-store.js +17 -3
- package/dist/services/chat-reply-mode-store.js.map +1 -1
- package/dist/skills/definitions.js +1 -1
- package/dist/utils/listen-with-probe.d.ts +20 -1
- package/dist/utils/listen-with-probe.d.ts.map +1 -1
- package/dist/utils/listen-with-probe.js +48 -6
- package/dist/utils/listen-with-probe.js.map +1 -1
- package/package.json +1 -1
package/dist/daemon.d.ts
CHANGED
|
@@ -6,13 +6,17 @@ import type { WorkflowRuntimeContext } from './workflows/runtime.js';
|
|
|
6
6
|
export declare function noteTurnReceived(ds: DaemonSession, triggerMessageId: string, _prompt?: string, _sender?: {
|
|
7
7
|
name?: string;
|
|
8
8
|
}, _turnId?: string): Promise<void>;
|
|
9
|
+
declare function sessionReply(anchor: string, content: string, msgType?: string, larkAppId?: string, turnId?: string): Promise<string>;
|
|
10
|
+
export declare const __testOnly_sessionReply: typeof sessionReply;
|
|
11
|
+
export declare const __testOnly_activeSessions: Map<string, DaemonSession>;
|
|
9
12
|
export declare function enforceMessageQuotaForCliInput(larkAppId: string, chatId: string, senderOpenId: string | undefined, messageId: string, anchor: string): Promise<boolean>;
|
|
10
13
|
export declare function grantRestrictedCommandText(larkAppId: string, chatId: string | undefined, senderOpenId: string | undefined, cmd: string): string | undefined;
|
|
11
14
|
export declare function grantRestrictedSlashCommandText(larkAppId: string, chatId: string | undefined, senderOpenId: string | undefined, cmd: string): string | undefined;
|
|
12
15
|
export declare function attachWorkflowEventWatcher(runId: string, ctx?: WorkflowRuntimeContext): WorkflowEventWatcher;
|
|
13
16
|
/**
|
|
14
17
|
* Resolve the pinned working dir for a brand-new topic via the layered lookup:
|
|
15
|
-
* 1)
|
|
18
|
+
* 1) this bot's OWN oncall binding (per-bot: another bot's binding never pins
|
|
19
|
+
* this bot — cross-bot dir alignment is handled by layer 3 inherit-peer)
|
|
16
20
|
* 2) this bot's defaultOncall — auto-binds a brand-new chat when the flag is on
|
|
17
21
|
* (this WRITES state, so it must run identically on every spawn path)
|
|
18
22
|
* 3) a sibling session's workingDir (cross-bot / chat-scope inheritance)
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAkBA,OAAO,
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAkF,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkBpI,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiFrD,OAAO,EAAE,oBAAoB,EAA6B,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,sBAAsB,EAAiB,MAAM,wBAAwB,CAAC;AAqPpF,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmClK;AAED,iBAAe,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAe,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8D3I;AAMD,eAAO,MAAM,uBAAuB,qBAAe,CAAC;AACpD,eAAO,MAAM,yBAAyB,4BAAiB,CAAC;AAqCxD,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA6ClB;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAMpB;AAoKD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,CA0C5G;AAgtCD;;;;;;;;;;;GAWG;AACH,iBAAe,uBAAuB,CAAC,GAAG,EAAE;IAC1C,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;;;;GAaA;AAED,eAAO,MAAM,kCAAkC,gCAA0B,CAAC;AA88C1E,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8blE"}
|
package/dist/daemon.js
CHANGED
|
@@ -15,7 +15,7 @@ import { sendRestartReportIfPending } from './core/restart-report.js';
|
|
|
15
15
|
import { statSync } from 'node:fs';
|
|
16
16
|
import { addReaction, getChatMode, listChatMemberOpenIds, replyMessage, resolveAllowedUsersWithMap, sendMessage, sendUserMessage, updateMessage } from './im/lark/client.js';
|
|
17
17
|
import { resolveGroupJoinPrompt, waitForAllowedUserInChat } from './core/auto-start.js';
|
|
18
|
-
import { loadBotConfigs, registerBot, getBot, getAllBots,
|
|
18
|
+
import { loadBotConfigs, registerBot, getBot, getAllBots, findOncallChat } from './bot-registry.js';
|
|
19
19
|
import * as sessionStore from './services/session-store.js';
|
|
20
20
|
import * as chatFirstSeenStore from './services/chat-first-seen-store.js';
|
|
21
21
|
import { ensureDefaultOncallBound } from './services/oncall-store.js';
|
|
@@ -50,7 +50,7 @@ import { isCallbackUrl, handleCallbackUrl } from './utils/user-token.js';
|
|
|
50
50
|
import { consumeQuota, removeChatGrant, removeGlobalGrant } from './services/grant-store.js';
|
|
51
51
|
import { abortCharge, commitCharge, beginCharge } from './services/quota-dedup.js';
|
|
52
52
|
import { getSessionWorkingDir, getProjectScanDirs, expandHome, downloadResources, formatAttachmentsHint, buildNewTopicPrompt, buildFollowUpContent, buildBridgeInputContent, buildReforkPrompt, getAvailableBots, restoreActiveSessions, executeScheduledTask, persistStreamCardState, rememberLastCliInput, ensureTerminalWorkerPort, ensureSessionWhiteboard, } from './core/session-manager.js';
|
|
53
|
-
import { beginReplyTargetTurn, resolveSessionReplyTarget, syncReplyTargetState } from './core/reply-target.js';
|
|
53
|
+
import { beginReplyTargetTurn, fallbackTurnId, resolveSessionReplyTarget, syncReplyTargetState } from './core/reply-target.js';
|
|
54
54
|
import { sweepOrphanSandboxes } from './adapters/backend/sandbox.js';
|
|
55
55
|
import { sweepIdleWorkers, DEFAULT_MAX_LIVE_WORKERS } from './core/idle-worker-sweeper.js';
|
|
56
56
|
import { handleCardAction } from './im/lark/card-handler.js';
|
|
@@ -344,7 +344,18 @@ async function sessionReply(anchor, content, msgType = 'text', larkAppId, turnId
|
|
|
344
344
|
const fresh = readSessionFreshFromDisk(ds.session.sessionId, ds.larkAppId);
|
|
345
345
|
if (fresh)
|
|
346
346
|
syncReplyTargetState(ds, fresh);
|
|
347
|
-
|
|
347
|
+
// Resolve through fallbackTurnId so daemon-side sends that carry no turn of
|
|
348
|
+
// their own (the repo-select card, skip/switch confirmations, crash notices)
|
|
349
|
+
// still anchor into the current shared fold-back topic instead of leaking to
|
|
350
|
+
// the chat top level. Callers that DO pass an explicit turnId are unchanged —
|
|
351
|
+
// fallbackTurnId returns it verbatim, so the stale-turn hijack guard stays
|
|
352
|
+
// authoritative. Baking the fallback in HERE (the single chat-scope send
|
|
353
|
+
// chokepoint) means no individual send site can re-introduce the leak by
|
|
354
|
+
// forgetting to thread — the recurring failure mode behind this and the
|
|
355
|
+
// earlier e619250d fix. Guarded by test/session-reply-thread-anchor.test.ts
|
|
356
|
+
// (drives the real sessionReply) and test/reply-target-fallback.test.ts
|
|
357
|
+
// (the resolveSessionReplyTarget × fallbackTurnId composition it relies on).
|
|
358
|
+
const target = resolveSessionReplyTarget(ds, fallbackTurnId(ds, turnId));
|
|
348
359
|
if (target.mode === 'thread')
|
|
349
360
|
return replyMessage(appId, target.rootMessageId, content, msgType, true, undefined, hookContext);
|
|
350
361
|
if (ds.session.rootMessageId) {
|
|
@@ -360,6 +371,12 @@ async function sessionReply(anchor, content, msgType = 'text', larkAppId, turnId
|
|
|
360
371
|
// Thread-scope (or unknown / legacy): reply in thread.
|
|
361
372
|
return replyMessage(appId, anchor, content, msgType, true, undefined, hookContext);
|
|
362
373
|
}
|
|
374
|
+
// Test seams: drive the real sessionReply (the chat-scope thread/top-level
|
|
375
|
+
// chokepoint) against a seeded session, so the shared fold-back leak is guarded
|
|
376
|
+
// at the function that actually routes — not just the resolveSessionReplyTarget
|
|
377
|
+
// composition it relies on. See test/reply-target-fallback.test.ts.
|
|
378
|
+
export const __testOnly_sessionReply = sessionReply;
|
|
379
|
+
export const __testOnly_activeSessions = activeSessions;
|
|
363
380
|
async function revokeQuotaGrant(larkAppId, chatId, senderOpenId, ev) {
|
|
364
381
|
const result = ev.reason === 'chatGrant'
|
|
365
382
|
? await removeChatGrant(larkAppId, chatId, senderOpenId)
|
|
@@ -1628,7 +1645,7 @@ function parseTriggerChatBinding(raw) {
|
|
|
1628
1645
|
* Default-oncall is a uniform forward-only policy: whenever the toggle is
|
|
1629
1646
|
* on, ANY chat the bot is currently in — old or newly added, doesn't matter —
|
|
1630
1647
|
* gets auto-bound to the configured workingDir on its next observed topic,
|
|
1631
|
-
* unless it's already bound (`
|
|
1648
|
+
* unless it's already bound (`findOncallChat`, per-bot, upstream) or the user
|
|
1632
1649
|
* has opted out via tombstone.
|
|
1633
1650
|
*
|
|
1634
1651
|
* Thin wrapper around the shared `ensureDefaultOncallBound` in oncall-store,
|
|
@@ -1666,7 +1683,8 @@ function resolveBotDefaultWorkingDir(larkAppId) {
|
|
|
1666
1683
|
}
|
|
1667
1684
|
/**
|
|
1668
1685
|
* Resolve the pinned working dir for a brand-new topic via the layered lookup:
|
|
1669
|
-
* 1)
|
|
1686
|
+
* 1) this bot's OWN oncall binding (per-bot: another bot's binding never pins
|
|
1687
|
+
* this bot — cross-bot dir alignment is handled by layer 3 inherit-peer)
|
|
1670
1688
|
* 2) this bot's defaultOncall — auto-binds a brand-new chat when the flag is on
|
|
1671
1689
|
* (this WRITES state, so it must run identically on every spawn path)
|
|
1672
1690
|
* 3) a sibling session's workingDir (cross-bot / chat-scope inheritance)
|
|
@@ -1676,7 +1694,7 @@ function resolveBotDefaultWorkingDir(larkAppId) {
|
|
|
1676
1694
|
* both honor the defaultOncall auto-bind the same way.
|
|
1677
1695
|
*/
|
|
1678
1696
|
async function resolvePinnedWorkingDir(ctx) {
|
|
1679
|
-
let oncallEntry =
|
|
1697
|
+
let oncallEntry = findOncallChat(ctx.larkAppId, ctx.chatId);
|
|
1680
1698
|
if (!oncallEntry) {
|
|
1681
1699
|
oncallEntry = await maybeAutoBindDefaultOncall(ctx.larkAppId, ctx.chatId, ctx.chatType);
|
|
1682
1700
|
}
|