botmux 2.73.0 → 2.75.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 +3 -2
- package/README.md +3 -2
- package/dist/adapters/cli/antigravity.d.ts.map +1 -1
- package/dist/adapters/cli/antigravity.js +7 -0
- package/dist/adapters/cli/antigravity.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +30 -19
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +7 -1
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +7 -1
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +35 -0
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-installer.d.ts +4 -0
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +32 -2
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/bot-registry.d.ts +10 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +3 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +29 -9
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts +10 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +78 -7
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +1 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts +2 -0
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +2 -0
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard.js +13 -7
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +7 -2
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +7 -2
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +14 -4
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +59 -18
- 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 +52 -7
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +8 -2
- package/dist/im/lark/grant-command.d.ts.map +1 -1
- package/dist/im/lark/grant-command.js +66 -14
- package/dist/im/lark/grant-command.js.map +1 -1
- package/dist/services/resumable-session-discovery.d.ts +12 -0
- package/dist/services/resumable-session-discovery.d.ts.map +1 -0
- package/dist/services/resumable-session-discovery.js +331 -0
- package/dist/services/resumable-session-discovery.js.map +1 -0
- package/dist/services/session-store.d.ts +13 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +44 -0
- package/dist/services/session-store.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts +9 -0
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +11 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/cli-selection.d.ts +65 -0
- package/dist/setup/cli-selection.d.ts.map +1 -0
- package/dist/setup/cli-selection.js +112 -0
- package/dist/setup/cli-selection.js.map +1 -0
- package/dist/setup/interactive-select.d.ts +30 -0
- package/dist/setup/interactive-select.d.ts.map +1 -0
- package/dist/setup/interactive-select.js +177 -0
- package/dist/setup/interactive-select.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/ready-gate.d.ts +6 -0
- package/dist/utils/ready-gate.d.ts.map +1 -1
- package/dist/utils/ready-gate.js +6 -0
- package/dist/utils/ready-gate.js.map +1 -1
- package/dist/worker.js +82 -4
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +560 -560
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CliId, ResumableSession } from '../adapters/cli/types.js';
|
|
1
2
|
import { validateWorkingDir } from './working-dir.js';
|
|
2
3
|
import { type AdoptableSession } from './session-discovery.js';
|
|
3
4
|
import { type ZellijAdoptableSession } from './zellij-adopt-discovery.js';
|
|
@@ -117,4 +118,13 @@ export declare function handleTermLinkCommand(rootId: string, larkAppId: string,
|
|
|
117
118
|
export declare function handleCommand(cmd: string, rootId: string, message: LarkMessage, deps: CommandHandlerDeps, larkAppId?: string): Promise<void>;
|
|
118
119
|
export declare function startCodexAppThreadSession(thread: CodexAppThreadSummary, ds: DaemonSession, deps: CommandHandlerDeps, larkAppId?: string): Promise<void>;
|
|
119
120
|
export declare function startAdoptSession(target: AdoptableSession | ZellijAdoptableSession, ds: DaemonSession, deps: CommandHandlerDeps, larkAppId?: string): Promise<void>;
|
|
121
|
+
/** Discover the sessions resumable from disk for `cliId`, excluding any whose
|
|
122
|
+
* CLI-native id is already live in a botmux session (so a session botmux
|
|
123
|
+
* already runs isn't offered for re-import). Returns [] when the adapter has
|
|
124
|
+
* no on-disk store. */
|
|
125
|
+
export declare function discoverResumableSessionsForBot(cliId: CliId, cliPathOverride: string | undefined, activeSessions: Map<string, DaemonSession>, limit?: number): Promise<ResumableSession[]>;
|
|
126
|
+
/** Import (resume) a stored session into the current topic: re-spawn the bot's
|
|
127
|
+
* CLI via `--resume <cliSessionId>` in `cwd`. Mirrors the manual resume path —
|
|
128
|
+
* the worker owns the CLI (NOT an observe-adopt), so no `adoptedFrom` is set. */
|
|
129
|
+
export declare function startResumeImportSession(target: ResumableSession, ds: DaemonSession, deps: CommandHandlerDeps, larkAppId?: string): Promise<void>;
|
|
120
130
|
//# sourceMappingURL=command-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../src/core/command-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../src/core/command-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ import { generateAuthUrl, getTokenStatus } from '../utils/user-token.js';
|
|
|
30
30
|
import { bindOncall, unbindOncall, getOncallStatus } from '../services/oncall-store.js';
|
|
31
31
|
import { CONFIG_FIELDS, findConfigField, settableFieldKeys, parseBooleanValue, applyConfigField, setBotAllowedUsers, getConfigSnapshot, getConfigCardData, } from '../services/bot-config-store.js';
|
|
32
32
|
import { resolveCliId, findInvalidAllowedUserEntries } from '../setup/bot-config-editor.js';
|
|
33
|
+
import { decorateResumeForWrapper } from '../setup/cli-selection.js';
|
|
33
34
|
import { publishAttentionPatch, announcePendingRepoSession } from './session-activity.js';
|
|
34
35
|
import { setCardMode } from '../services/card-mode-store.js';
|
|
35
36
|
import { canOperate } from '../im/lark/event-dispatcher.js';
|
|
@@ -879,10 +880,11 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
879
880
|
const cliResumeCommand = (() => {
|
|
880
881
|
try {
|
|
881
882
|
const adapter = createCliAdapterSync(closedCliId, botCfg.cliPathOverride);
|
|
882
|
-
|
|
883
|
+
const raw = adapter.buildResumeCommand?.({
|
|
883
884
|
sessionId: closedSessionId,
|
|
884
885
|
cliSessionId: ds.session.cliSessionId,
|
|
885
886
|
}) ?? null;
|
|
887
|
+
return raw ? decorateResumeForWrapper(raw, botCfg.wrapperCli) : null;
|
|
886
888
|
}
|
|
887
889
|
catch {
|
|
888
890
|
return null;
|
|
@@ -1433,7 +1435,12 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1433
1435
|
...discoverAdoptableSessions(botCliId),
|
|
1434
1436
|
...discoverAdoptableZellijSessions(botCliId),
|
|
1435
1437
|
];
|
|
1436
|
-
|
|
1438
|
+
// Second filter: sessions resumable from disk (paseo-style import).
|
|
1439
|
+
// Only the bot's OWN CLI is offered (resume needs that CLI's binary).
|
|
1440
|
+
const resumable = botCliId
|
|
1441
|
+
? await discoverResumableSessionsForBot(botCliId, botCfgForAdopt?.cliPathOverride, activeSessions)
|
|
1442
|
+
: [];
|
|
1443
|
+
if (sessions.length === 0 && resumable.length === 0) {
|
|
1437
1444
|
await sessionReply(rootId, t('cmd.adopt.no_sessions', undefined, loc));
|
|
1438
1445
|
break;
|
|
1439
1446
|
}
|
|
@@ -1445,15 +1452,22 @@ export async function handleCommand(cmd, rootId, message, deps, larkAppId) {
|
|
|
1445
1452
|
const target = sessions.find(s => 'zellijPaneId' in s
|
|
1446
1453
|
? `${s.zellijSession}:${s.zellijPaneId}` === zellijNorm
|
|
1447
1454
|
: adoptTargetLabel(s) === directTarget || adoptTargetKey(s) === directTarget || s.tmuxTarget === directTarget || s.herdrPaneId === directTarget);
|
|
1448
|
-
if (
|
|
1449
|
-
|
|
1455
|
+
if (target) {
|
|
1456
|
+
if (ds)
|
|
1457
|
+
await startAdoptSession(target, ds, deps, larkAppId);
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
// Fall back to a resumable session matched by its CLI-native id.
|
|
1461
|
+
const resumeTarget = resumable.find(r => r.cliSessionId === directTarget);
|
|
1462
|
+
if (resumeTarget) {
|
|
1463
|
+
if (ds)
|
|
1464
|
+
await startResumeImportSession(resumeTarget, ds, deps, larkAppId);
|
|
1450
1465
|
break;
|
|
1451
1466
|
}
|
|
1452
|
-
|
|
1453
|
-
await startAdoptSession(target, ds, deps, larkAppId);
|
|
1467
|
+
await sessionReply(rootId, t('cmd.adopt.pane_not_found', { pane: directTarget }, loc));
|
|
1454
1468
|
break;
|
|
1455
1469
|
}
|
|
1456
|
-
const cardJson = buildAdoptSelectCard(sessions, rootId, loc);
|
|
1470
|
+
const cardJson = buildAdoptSelectCard(sessions, rootId, loc, resumable);
|
|
1457
1471
|
await sessionReply(rootId, cardJson, 'interactive');
|
|
1458
1472
|
break;
|
|
1459
1473
|
}
|
|
@@ -2388,4 +2402,61 @@ export async function startAdoptSession(target, ds, deps, larkAppId) {
|
|
|
2388
2402
|
const cliName = getCliDisplayName(target.cliId);
|
|
2389
2403
|
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.success', { cliName, project, pane }, loc));
|
|
2390
2404
|
}
|
|
2405
|
+
/** Discover the sessions resumable from disk for `cliId`, excluding any whose
|
|
2406
|
+
* CLI-native id is already live in a botmux session (so a session botmux
|
|
2407
|
+
* already runs isn't offered for re-import). Returns [] when the adapter has
|
|
2408
|
+
* no on-disk store. */
|
|
2409
|
+
export async function discoverResumableSessionsForBot(cliId, cliPathOverride, activeSessions, limit = 20) {
|
|
2410
|
+
let adapter;
|
|
2411
|
+
try {
|
|
2412
|
+
adapter = createCliAdapterSync(cliId, cliPathOverride);
|
|
2413
|
+
}
|
|
2414
|
+
catch {
|
|
2415
|
+
return [];
|
|
2416
|
+
}
|
|
2417
|
+
if (!adapter.listResumableSessions)
|
|
2418
|
+
return [];
|
|
2419
|
+
// Exclude every session botmux already manages — live OR closed — so the
|
|
2420
|
+
// picker surfaces only genuinely external sessions (a CLI the user ran
|
|
2421
|
+
// standalone). botmux's own closed sessions stay resumable via their
|
|
2422
|
+
// session-closed cards, so hiding them here avoids a redundant, confusing
|
|
2423
|
+
// duplicate. The identity set spans all bot stores and includes both the
|
|
2424
|
+
// botmux sessionId (= the claude jsonl filename) and the cliSessionId
|
|
2425
|
+
// (codex/traex rollout id), covering every CLI's id shape. Passed INTO the
|
|
2426
|
+
// adapter so exclusion happens BEFORE the `limit` truncation.
|
|
2427
|
+
const exclude = sessionStore.collectBotmuxSessionIdentities() ?? new Set();
|
|
2428
|
+
// Belt-and-suspenders: also fold in the in-memory active map (freshest).
|
|
2429
|
+
for (const ds of activeSessions.values()) {
|
|
2430
|
+
if (ds.session.sessionId)
|
|
2431
|
+
exclude.add(ds.session.sessionId);
|
|
2432
|
+
if (ds.session.cliSessionId)
|
|
2433
|
+
exclude.add(ds.session.cliSessionId);
|
|
2434
|
+
}
|
|
2435
|
+
try {
|
|
2436
|
+
return await adapter.listResumableSessions({ limit, exclude });
|
|
2437
|
+
}
|
|
2438
|
+
catch {
|
|
2439
|
+
return [];
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
/** Import (resume) a stored session into the current topic: re-spawn the bot's
|
|
2443
|
+
* CLI via `--resume <cliSessionId>` in `cwd`. Mirrors the manual resume path —
|
|
2444
|
+
* the worker owns the CLI (NOT an observe-adopt), so no `adoptedFrom` is set. */
|
|
2445
|
+
export async function startResumeImportSession(target, ds, deps, larkAppId) {
|
|
2446
|
+
const sessionReply = (rid, content, msgType) => deps.sessionReply(rid, content, msgType, larkAppId);
|
|
2447
|
+
const loc = localeForBot(ds.larkAppId ?? larkAppId);
|
|
2448
|
+
const project = target.cwd.split('/').pop() || target.cwd;
|
|
2449
|
+
ds.workingDir = target.cwd;
|
|
2450
|
+
ds.session.workingDir = target.cwd;
|
|
2451
|
+
ds.session.cliSessionId = target.cliSessionId;
|
|
2452
|
+
ds.session.title = target.title || `Import: ${project}`;
|
|
2453
|
+
// Resume sandbox decision is left to forkWorker (resume=true → not sandboxed,
|
|
2454
|
+
// matching restore semantics). Mark history so the session is treated as a
|
|
2455
|
+
// resume, not a fresh spawn.
|
|
2456
|
+
ds.hasHistory = true;
|
|
2457
|
+
sessionStore.updateSession(ds.session);
|
|
2458
|
+
forkWorker(ds, '', true);
|
|
2459
|
+
const cliName = getCliDisplayName(getBot(ds.larkAppId).config.cliId);
|
|
2460
|
+
await sessionReply(sessionAnchorId(ds), t('cmd.adopt.resume_success', { cliName, project, title: target.title || target.cliSessionId.slice(0, 8) }, loc));
|
|
2461
|
+
}
|
|
2391
2462
|
//# sourceMappingURL=command-handler.js.map
|