botmux 2.49.0-canary.0 → 2.49.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 +33 -32
- package/README.md +33 -31
- package/dist/adapters/adopt-route.d.ts +63 -0
- package/dist/adapters/adopt-route.d.ts.map +1 -0
- package/dist/adapters/adopt-route.js +195 -0
- package/dist/adapters/adopt-route.js.map +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts +5 -3
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +48 -12
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +11 -0
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +17 -1
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/cli/aiden.js +2 -3
- package/dist/adapters/cli/aiden.js.map +1 -1
- package/dist/adapters/cli/antigravity.js +2 -2
- 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 +40 -15
- 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 +27 -3
- package/dist/adapters/cli/coco.js.map +1 -1
- package/dist/adapters/cli/codex-app.d.ts +4 -0
- package/dist/adapters/cli/codex-app.d.ts.map +1 -0
- package/dist/adapters/cli/codex-app.js +72 -0
- package/dist/adapters/cli/codex-app.js.map +1 -0
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +50 -18
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/cursor.d.ts.map +1 -1
- package/dist/adapters/cli/cursor.js +59 -13
- package/dist/adapters/cli/cursor.js.map +1 -1
- package/dist/adapters/cli/gemini.d.ts.map +1 -1
- package/dist/adapters/cli/gemini.js +6 -2
- package/dist/adapters/cli/gemini.js.map +1 -1
- package/dist/adapters/cli/hermes.d.ts +4 -0
- package/dist/adapters/cli/hermes.d.ts.map +1 -0
- package/dist/adapters/cli/hermes.js +40 -0
- package/dist/adapters/cli/hermes.js.map +1 -0
- package/dist/adapters/cli/mira.d.ts +4 -0
- package/dist/adapters/cli/mira.d.ts.map +1 -0
- package/dist/adapters/cli/mira.js +67 -0
- package/dist/adapters/cli/mira.js.map +1 -0
- package/dist/adapters/cli/mtr.d.ts +5 -0
- package/dist/adapters/cli/mtr.d.ts.map +1 -0
- package/dist/adapters/cli/mtr.js +62 -0
- package/dist/adapters/cli/mtr.js.map +1 -0
- package/dist/adapters/cli/opencode.d.ts.map +1 -1
- package/dist/adapters/cli/opencode.js +19 -1
- package/dist/adapters/cli/opencode.js.map +1 -1
- package/dist/adapters/cli/registry.d.ts +5 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +22 -2
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +1 -1
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +2 -1
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +36 -8
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-command.d.ts +18 -0
- package/dist/adapters/hook-command.d.ts.map +1 -0
- package/dist/adapters/hook-command.js +38 -0
- package/dist/adapters/hook-command.js.map +1 -0
- package/dist/adapters/hook-installer.d.ts +14 -0
- package/dist/adapters/hook-installer.d.ts.map +1 -0
- package/dist/adapters/hook-installer.js +192 -0
- package/dist/adapters/hook-installer.js.map +1 -0
- package/dist/bot-registry.d.ts +79 -3
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +74 -1
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/bots-list-output.d.ts +8 -0
- package/dist/cli/bots-list-output.d.ts.map +1 -1
- package/dist/cli/bots-list-output.js +9 -0
- package/dist/cli/bots-list-output.js.map +1 -1
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +626 -110
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-runner.d.ts +3 -0
- package/dist/codex-app-runner.d.ts.map +1 -0
- package/dist/codex-app-runner.js +512 -0
- package/dist/codex-app-runner.js.map +1 -0
- package/dist/config.d.ts +12 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -4
- package/dist/config.js.map +1 -1
- package/dist/core/ask-api.d.ts +47 -0
- package/dist/core/ask-api.d.ts.map +1 -0
- package/dist/core/ask-api.js +139 -0
- package/dist/core/ask-api.js.map +1 -0
- package/dist/core/ask-args.d.ts +53 -0
- package/dist/core/ask-args.d.ts.map +1 -0
- package/dist/core/ask-args.js +122 -0
- package/dist/core/ask-args.js.map +1 -0
- package/dist/core/ask-broker.d.ts +98 -0
- package/dist/core/ask-broker.d.ts.map +1 -0
- package/dist/core/ask-broker.js +329 -0
- package/dist/core/ask-broker.js.map +1 -0
- package/dist/core/ask-hook/claude-code.d.ts +50 -0
- package/dist/core/ask-hook/claude-code.d.ts.map +1 -0
- package/dist/core/ask-hook/claude-code.js +145 -0
- package/dist/core/ask-hook/claude-code.js.map +1 -0
- package/dist/core/ask-hook/codex.d.ts +43 -0
- package/dist/core/ask-hook/codex.d.ts.map +1 -0
- package/dist/core/ask-hook/codex.js +69 -0
- package/dist/core/ask-hook/codex.js.map +1 -0
- package/dist/core/ask-hook/opencode.d.ts +41 -0
- package/dist/core/ask-hook/opencode.d.ts.map +1 -0
- package/dist/core/ask-hook/opencode.js +108 -0
- package/dist/core/ask-hook/opencode.js.map +1 -0
- package/dist/core/ask-hook/registry.d.ts +3 -0
- package/dist/core/ask-hook/registry.d.ts.map +1 -0
- package/dist/core/ask-hook/registry.js +12 -0
- package/dist/core/ask-hook/registry.js.map +1 -0
- package/dist/core/ask-hook/types.d.ts +26 -0
- package/dist/core/ask-hook/types.d.ts.map +1 -0
- package/dist/core/ask-hook/types.js +2 -0
- package/dist/core/ask-hook/types.js.map +1 -0
- package/dist/core/ask-types.d.ts +146 -0
- package/dist/core/ask-types.d.ts.map +1 -0
- package/dist/core/ask-types.js +18 -0
- package/dist/core/ask-types.js.map +1 -0
- package/dist/core/auto-start.d.ts +61 -0
- package/dist/core/auto-start.d.ts.map +1 -0
- package/dist/core/auto-start.js +62 -0
- package/dist/core/auto-start.js.map +1 -0
- package/dist/core/command-handler.d.ts +29 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +789 -313
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +2 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +232 -3
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +3 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +2 -0
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/role-resolver.d.ts +17 -1
- package/dist/core/role-resolver.d.ts.map +1 -1
- package/dist/core/role-resolver.js +64 -10
- package/dist/core/role-resolver.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +19 -5
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -3
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +84 -28
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/terminal-proxy.d.ts +32 -0
- package/dist/core/terminal-proxy.d.ts.map +1 -0
- package/dist/core/terminal-proxy.js +139 -0
- package/dist/core/terminal-proxy.js.map +1 -0
- package/dist/core/terminal-url.d.ts +27 -0
- package/dist/core/terminal-url.d.ts.map +1 -0
- package/dist/core/terminal-url.js +26 -0
- package/dist/core/terminal-url.js.map +1 -0
- package/dist/core/trigger-session.d.ts +9 -0
- package/dist/core/trigger-session.d.ts.map +1 -0
- package/dist/core/trigger-session.js +158 -0
- package/dist/core/trigger-session.js.map +1 -0
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +141 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +550 -30
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +459 -68
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +6 -1
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +9 -1
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +24 -2
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts +3 -0
- package/dist/dashboard/connector-api.d.ts.map +1 -0
- package/dist/dashboard/connector-api.js +351 -0
- package/dist/dashboard/connector-api.js.map +1 -0
- package/dist/dashboard/federated-group-core.d.ts +54 -0
- package/dist/dashboard/federated-group-core.d.ts.map +1 -0
- package/dist/dashboard/federated-group-core.js +165 -0
- package/dist/dashboard/federated-group-core.js.map +1 -0
- package/dist/dashboard/federation-api.d.ts +42 -0
- package/dist/dashboard/federation-api.d.ts.map +1 -0
- package/dist/dashboard/federation-api.js +408 -0
- package/dist/dashboard/federation-api.js.map +1 -0
- package/dist/dashboard/federation-spoke-api.d.ts +82 -0
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -0
- package/dist/dashboard/federation-spoke-api.js +645 -0
- package/dist/dashboard/federation-spoke-api.js.map +1 -0
- package/dist/dashboard/team-group.d.ts +18 -0
- package/dist/dashboard/team-group.d.ts.map +1 -0
- package/dist/dashboard/team-group.js +7 -0
- package/dist/dashboard/team-group.js.map +1 -0
- package/dist/dashboard/trigger-api.d.ts +13 -0
- package/dist/dashboard/trigger-api.d.ts.map +1 -0
- package/dist/dashboard/trigger-api.js +77 -0
- package/dist/dashboard/trigger-api.js.map +1 -0
- package/dist/dashboard/web/app.d.ts +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +44 -0
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +397 -20
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/connectors.d.ts +2 -0
- package/dist/dashboard/web/connectors.d.ts.map +1 -0
- package/dist/dashboard/web/connectors.js +187 -0
- package/dist/dashboard/web/connectors.js.map +1 -0
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +75 -5
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +5 -1
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/team-federation.d.ts +3 -0
- package/dist/dashboard/web/team-federation.d.ts.map +1 -0
- package/dist/dashboard/web/team-federation.js +485 -0
- package/dist/dashboard/web/team-federation.js.map +1 -0
- package/dist/dashboard/web/workflows.js +3 -3
- package/dist/dashboard/web/workflows.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts +19 -0
- package/dist/dashboard/webhook-routes.d.ts.map +1 -0
- package/dist/dashboard/webhook-routes.js +321 -0
- package/dist/dashboard/webhook-routes.js.map +1 -0
- package/dist/dashboard/workflow-api.d.ts +8 -1
- package/dist/dashboard/workflow-api.d.ts.map +1 -1
- package/dist/dashboard/workflow-api.js +19 -4
- package/dist/dashboard/workflow-api.js.map +1 -1
- package/dist/dashboard-web/app.js +579 -377
- package/dist/dashboard-web/index.html +3 -1
- package/dist/dashboard-web/style.css +63 -1
- package/dist/dashboard.js +202 -2
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +120 -15
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +120 -15
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/ask-card.d.ts +55 -0
- package/dist/im/lark/ask-card.d.ts.map +1 -0
- package/dist/im/lark/ask-card.js +328 -0
- package/dist/im/lark/ask-card.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +122 -8
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +528 -56
- 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 +337 -36
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +112 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +385 -70
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +9 -2
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +90 -19
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +8 -1
- package/dist/im/lark/grant-command.d.ts.map +1 -1
- package/dist/im/lark/grant-command.js +53 -24
- package/dist/im/lark/grant-command.js.map +1 -1
- package/dist/im/lark/grant-pending.d.ts +3 -0
- package/dist/im/lark/grant-pending.d.ts.map +1 -1
- package/dist/im/lark/grant-pending.js +8 -1
- package/dist/im/lark/grant-pending.js.map +1 -1
- package/dist/im/lark/identity-cache.d.ts.map +1 -1
- package/dist/im/lark/identity-cache.js +3 -3
- package/dist/im/lark/identity-cache.js.map +1 -1
- package/dist/im/lark/md-card.d.ts +20 -2
- package/dist/im/lark/md-card.d.ts.map +1 -1
- package/dist/im/lark/md-card.js +49 -17
- package/dist/im/lark/md-card.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +87 -31
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/workflow-card-handler.d.ts +2 -2
- package/dist/im/lark/workflow-card-handler.d.ts.map +1 -1
- package/dist/im/lark/workflow-card-handler.js +12 -1
- package/dist/im/lark/workflow-card-handler.js.map +1 -1
- package/dist/im/lark/workflow-progress-card.d.ts.map +1 -1
- package/dist/im/lark/workflow-progress-card.js +53 -0
- package/dist/im/lark/workflow-progress-card.js.map +1 -1
- package/dist/mira-output.d.ts +3 -0
- package/dist/mira-output.d.ts.map +1 -0
- package/dist/mira-output.js +136 -0
- package/dist/mira-output.js.map +1 -0
- package/dist/mira-runner.d.ts +3 -0
- package/dist/mira-runner.d.ts.map +1 -0
- package/dist/mira-runner.js +534 -0
- package/dist/mira-runner.js.map +1 -0
- package/dist/services/bot-owner-store.d.ts +28 -0
- package/dist/services/bot-owner-store.d.ts.map +1 -0
- package/dist/services/bot-owner-store.js +82 -0
- package/dist/services/bot-owner-store.js.map +1 -0
- package/dist/services/bot-profile-store.d.ts +16 -0
- package/dist/services/bot-profile-store.d.ts.map +1 -0
- package/dist/services/bot-profile-store.js +98 -0
- package/dist/services/bot-profile-store.js.map +1 -0
- package/dist/services/brand-store.d.ts +15 -0
- package/dist/services/brand-store.d.ts.map +1 -0
- package/dist/services/brand-store.js +47 -0
- package/dist/services/brand-store.js.map +1 -0
- package/dist/services/card-prefs-store.d.ts +26 -0
- package/dist/services/card-prefs-store.d.ts.map +1 -0
- package/dist/services/card-prefs-store.js +119 -0
- package/dist/services/card-prefs-store.js.map +1 -0
- package/dist/services/codex-bridge-queue.d.ts +1 -0
- package/dist/services/codex-bridge-queue.d.ts.map +1 -1
- package/dist/services/codex-bridge-queue.js +72 -19
- package/dist/services/codex-bridge-queue.js.map +1 -1
- package/dist/services/codex-transcript.d.ts +1 -0
- package/dist/services/codex-transcript.d.ts.map +1 -1
- package/dist/services/codex-transcript.js.map +1 -1
- package/dist/services/connector-store.d.ts +58 -0
- package/dist/services/connector-store.d.ts.map +1 -0
- package/dist/services/connector-store.js +79 -0
- package/dist/services/connector-store.js.map +1 -0
- package/dist/services/deployment-identity.d.ts +22 -0
- package/dist/services/deployment-identity.d.ts.map +1 -0
- package/dist/services/deployment-identity.js +67 -0
- package/dist/services/deployment-identity.js.map +1 -0
- package/dist/services/federation-membership-store.d.ts +23 -0
- package/dist/services/federation-membership-store.d.ts.map +1 -0
- package/dist/services/federation-membership-store.js +66 -0
- package/dist/services/federation-membership-store.js.map +1 -0
- package/dist/services/federation-roster.d.ts +54 -0
- package/dist/services/federation-roster.d.ts.map +1 -0
- package/dist/services/federation-roster.js +51 -0
- package/dist/services/federation-roster.js.map +1 -0
- package/dist/services/federation-store.d.ts +76 -0
- package/dist/services/federation-store.d.ts.map +1 -0
- package/dist/services/federation-store.js +133 -0
- package/dist/services/federation-store.js.map +1 -0
- package/dist/services/grant-store.d.ts +12 -2
- package/dist/services/grant-store.d.ts.map +1 -1
- package/dist/services/grant-store.js +51 -4
- package/dist/services/grant-store.js.map +1 -1
- package/dist/services/group-creator.d.ts +10 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +26 -1
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/groups-store.d.ts +30 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +85 -12
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/hermes-transcript.d.ts +7 -0
- package/dist/services/hermes-transcript.d.ts.map +1 -0
- package/dist/services/hermes-transcript.js +117 -0
- package/dist/services/hermes-transcript.js.map +1 -0
- package/dist/services/invite-store.d.ts +28 -0
- package/dist/services/invite-store.d.ts.map +1 -0
- package/dist/services/invite-store.js +85 -0
- package/dist/services/invite-store.js.map +1 -0
- package/dist/services/mtr-transcript.d.ts +14 -0
- package/dist/services/mtr-transcript.d.ts.map +1 -0
- package/dist/services/mtr-transcript.js +291 -0
- package/dist/services/mtr-transcript.js.map +1 -0
- package/dist/services/pairing-store.d.ts +47 -0
- package/dist/services/pairing-store.d.ts.map +1 -0
- package/dist/services/pairing-store.js +132 -0
- package/dist/services/pairing-store.js.map +1 -0
- package/dist/services/project-scanner.d.ts +10 -0
- package/dist/services/project-scanner.d.ts.map +1 -1
- package/dist/services/project-scanner.js +11 -0
- package/dist/services/project-scanner.js.map +1 -1
- package/dist/services/relay-picker.d.ts +22 -0
- package/dist/services/relay-picker.d.ts.map +1 -0
- package/dist/services/relay-picker.js +82 -0
- package/dist/services/relay-picker.js.map +1 -0
- package/dist/services/send-policy.d.ts +55 -0
- package/dist/services/send-policy.d.ts.map +1 -0
- package/dist/services/send-policy.js +47 -0
- package/dist/services/send-policy.js.map +1 -0
- package/dist/services/session-store.js +1 -1
- package/dist/services/session-store.js.map +1 -1
- package/dist/services/team-roster.d.ts +38 -0
- package/dist/services/team-roster.d.ts.map +1 -0
- package/dist/services/team-roster.js +82 -0
- package/dist/services/team-roster.js.map +1 -0
- package/dist/services/team-store.d.ts +54 -0
- package/dist/services/team-store.d.ts.map +1 -0
- package/dist/services/team-store.js +156 -0
- package/dist/services/team-store.js.map +1 -0
- package/dist/services/trigger-log-store.d.ts +46 -0
- package/dist/services/trigger-log-store.d.ts.map +1 -0
- package/dist/services/trigger-log-store.js +132 -0
- package/dist/services/trigger-log-store.js.map +1 -0
- package/dist/services/trigger-types.d.ts +57 -0
- package/dist/services/trigger-types.d.ts.map +1 -0
- package/dist/services/trigger-types.js +28 -0
- package/dist/services/trigger-types.js.map +1 -0
- package/dist/services/webhook-key.d.ts +16 -0
- package/dist/services/webhook-key.d.ts.map +1 -0
- package/dist/services/webhook-key.js +123 -0
- package/dist/services/webhook-key.js.map +1 -0
- package/dist/services/webhook-lifecycle-extractors.d.ts +15 -0
- package/dist/services/webhook-lifecycle-extractors.d.ts.map +1 -0
- package/dist/services/webhook-lifecycle-extractors.js +59 -0
- package/dist/services/webhook-lifecycle-extractors.js.map +1 -0
- package/dist/services/webhook-lifecycle-store.d.ts +45 -0
- package/dist/services/webhook-lifecycle-store.d.ts.map +1 -0
- package/dist/services/webhook-lifecycle-store.js +159 -0
- package/dist/services/webhook-lifecycle-store.js.map +1 -0
- package/dist/setup/bot-config-editor.d.ts +13 -3
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +27 -6
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/ensure-tmux.d.ts +0 -22
- package/dist/setup/ensure-tmux.d.ts.map +1 -1
- package/dist/setup/ensure-tmux.js +25 -1
- package/dist/setup/ensure-tmux.js.map +1 -1
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +19 -2
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/skills/definitions.d.ts +2 -0
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +178 -12
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/installer.d.ts +34 -0
- package/dist/skills/installer.d.ts.map +1 -1
- package/dist/skills/installer.js +119 -2
- package/dist/skills/installer.js.map +1 -1
- package/dist/types.d.ts +29 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/bot-routing.d.ts +50 -0
- package/dist/utils/bot-routing.d.ts.map +1 -1
- package/dist/utils/bot-routing.js +83 -0
- package/dist/utils/bot-routing.js.map +1 -1
- package/dist/utils/child-env.d.ts +35 -0
- package/dist/utils/child-env.d.ts.map +1 -0
- package/dist/utils/child-env.js +40 -0
- package/dist/utils/child-env.js.map +1 -0
- package/dist/utils/daemon-discovery.d.ts +11 -0
- package/dist/utils/daemon-discovery.d.ts.map +1 -0
- package/dist/utils/daemon-discovery.js +59 -0
- package/dist/utils/daemon-discovery.js.map +1 -0
- package/dist/utils/user-token.d.ts.map +1 -1
- package/dist/utils/user-token.js +0 -2
- package/dist/utils/user-token.js.map +1 -1
- package/dist/worker.js +365 -77
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts.map +1 -1
- package/dist/workflows/attempt-resume.js +2 -2
- package/dist/workflows/attempt-resume.js.map +1 -1
- package/dist/workflows/definition.d.ts +412 -9
- package/dist/workflows/definition.d.ts.map +1 -1
- package/dist/workflows/definition.js +238 -3
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +114 -11
- package/dist/workflows/events/payloads.d.ts.map +1 -1
- package/dist/workflows/events/payloads.js +46 -0
- package/dist/workflows/events/payloads.js.map +1 -1
- package/dist/workflows/events/replay.d.ts +21 -0
- package/dist/workflows/events/replay.d.ts.map +1 -1
- package/dist/workflows/events/replay.js +103 -0
- package/dist/workflows/events/replay.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +1301 -606
- package/dist/workflows/events/schema.d.ts.map +1 -1
- package/dist/workflows/events/schema.js +37 -1
- package/dist/workflows/events/schema.js.map +1 -1
- package/dist/workflows/events/types.d.ts +5 -1
- package/dist/workflows/events/types.d.ts.map +1 -1
- package/dist/workflows/loader.d.ts +14 -0
- package/dist/workflows/loader.d.ts.map +1 -1
- package/dist/workflows/loader.js +27 -0
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/loop.js +58 -0
- package/dist/workflows/loop.js.map +1 -1
- package/dist/workflows/ops-projection.d.ts +58 -0
- package/dist/workflows/ops-projection.d.ts.map +1 -1
- package/dist/workflows/ops-projection.js +74 -0
- package/dist/workflows/ops-projection.js.map +1 -1
- package/dist/workflows/orchestrator.d.ts +65 -1
- package/dist/workflows/orchestrator.d.ts.map +1 -1
- package/dist/workflows/orchestrator.js +486 -74
- package/dist/workflows/orchestrator.js.map +1 -1
- package/dist/workflows/output-binding.d.ts +8 -1
- package/dist/workflows/output-binding.d.ts.map +1 -1
- package/dist/workflows/output-binding.js +75 -11
- package/dist/workflows/output-binding.js.map +1 -1
- package/dist/workflows/runtime.d.ts +1 -1
- package/dist/workflows/runtime.d.ts.map +1 -1
- package/dist/workflows/runtime.js +39 -4
- package/dist/workflows/runtime.js.map +1 -1
- package/dist/workflows/trigger-from-envelope.d.ts +13 -0
- package/dist/workflows/trigger-from-envelope.d.ts.map +1 -0
- package/dist/workflows/trigger-from-envelope.js +67 -0
- package/dist/workflows/trigger-from-envelope.js.map +1 -0
- package/dist/workflows/wait.d.ts +23 -2
- package/dist/workflows/wait.d.ts.map +1 -1
- package/dist/workflows/wait.js +39 -17
- package/dist/workflows/wait.js.map +1 -1
- package/package.json +1 -1
- package/dist/services/feishu-task-client.d.ts +0 -28
- package/dist/services/feishu-task-client.d.ts.map +0 -1
- package/dist/services/feishu-task-client.js +0 -123
- package/dist/services/feishu-task-client.js.map +0 -1
- package/dist/services/task-store.d.ts +0 -37
- package/dist/services/task-store.d.ts.map +0 -1
- package/dist/services/task-store.js +0 -115
- package/dist/services/task-store.js.map +0 -1
package/README.en.md
CHANGED
|
@@ -62,7 +62,8 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
|
|
|
62
62
|
## Prerequisites
|
|
63
63
|
|
|
64
64
|
- **Node.js** >= 20
|
|
65
|
-
- **AI coding CLI** installed and authenticated (`claude`, `codex`, `cursor-agent`, `gemini`, `opencode`, or `agy` (Antigravity) in PATH)
|
|
65
|
+
- **AI coding CLI / local agent app** installed and authenticated (`claude`, `codex`, `coco`, `cursor-agent`, `gemini`, `opencode`, `hermes`, or `agy` (Antigravity) in PATH)
|
|
66
|
+
- **CoCo requires `0.120.32+`**: type-ahead (sending a new message while a turn is still running, parked in CoCo's own message queue) relies on 0.120.32+ behavior; earlier versions may drop or serialize input while busy — upgrade before use
|
|
66
67
|
- **tmux** >= 3.x (optional — auto-enabled when installed for persistent CLI sessions)
|
|
67
68
|
- **CJK fonts** (only needed for screenshot rendering of Chinese text / emoji):
|
|
68
69
|
- macOS: ships with PingFang / Hiragino, no action needed
|
|
@@ -71,43 +72,41 @@ Compared to OpenClaw-style approaches built on Agent SDKs:
|
|
|
71
72
|
|
|
72
73
|
## 5-Minute Setup
|
|
73
74
|
|
|
74
|
-
> 💡 **TL;DR**:
|
|
75
|
+
> 💡 **TL;DR**: `npm i -g botmux` → `botmux setup` and pick "scan-to-create" to get the AppID/AppSecret in one shot (Step 2) → `botmux start`. PersonalAgent apps come with event subscriptions and bot capability pre-configured, so only Step 4 (permissions) + Step 5 (optional redirect URL) + Step 6 (publish) require browser clicks; the setup wizard writes a JSON file with a one-line clipboard copy command and prints deep-links to each remaining step.
|
|
75
76
|
|
|
76
|
-
### Step 1:
|
|
77
|
+
### Step 1: Install botmux
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
```bash
|
|
80
|
+
npm install -g botmux
|
|
81
|
+
```
|
|
79
82
|
|
|
80
|
-
>
|
|
83
|
+
> Requires **Node.js ≥ 20**, with at least one AI coding CLI installed and authenticated (`claude` / `codex` / `cursor-agent` / `gemini` / `opencode` / `coco` / `agy` on your PATH). Installing **tmux** too is recommended (enables session persistence automatically).
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
### Step 2: Create the App & Configure (`botmux setup`)
|
|
83
86
|
|
|
84
|
-
|
|
87
|
+
Run `botmux setup` and follow the interactive menu:
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
1. **New config**: type `1` and press Enter (with an existing config, type `2` to add a bot).
|
|
90
|
+
2. **Create the bot**:
|
|
91
|
+
- Type `1` → **Scan-to-create (recommended)**: scan with the Lark mobile app and a PersonalAgent app is created with AppID/AppSecret persisted automatically, **with event subscriptions + bot capability pre-configured** — no manual browser navigation. Uses the official `@larksuiteoapi/node-sdk` device flow.
|
|
92
|
+
- Type `2` → **Manual**: go to the [Lark Open Platform](https://open.larkoffice.com/app), create a "Custom App", copy **App ID / App Secret** from "Credentials & Basic Info", and paste them back.
|
|
93
|
+
3. **Pick the CLI**: choose the CLI to bridge (e.g. type `1` for Claude Code).
|
|
94
|
+
4. **Default working dir**: usually the **parent directory** of your git projects (e.g. `~/projects`); new topics scan **downward** for git repos (up to 3 levels). Avoid `~` (too many folders to traverse).
|
|
87
95
|
|
|
88
|
-
>
|
|
96
|
+
> ⚠️ **Currently only Feishu (feishu.cn) tenants are supported.** If scan detects a Lark international (larksuite.com) tenant, setup aborts — the daemon runtime (Lark Client/WSClient/event-dispatcher) hasn't been wired up for the `larksuite.com` domain yet. A follow-up PR will add full Lark support.
|
|
89
97
|
|
|
90
|
-
|
|
98
|
+
At the end, setup validates credentials with a `tenant_access_token` call (only writing `bots.json` on success), writes the full scope JSON to `~/.botmux/lark-scopes.json`, and prints a one-line clipboard copy command plus deep-links to each remaining step.
|
|
91
99
|
|
|
92
|
-

|
|
93
101
|
|
|
94
|
-
### Step 3:
|
|
102
|
+
### Step 3: Start
|
|
95
103
|
|
|
96
104
|
```bash
|
|
97
|
-
# Install
|
|
98
|
-
npm install -g botmux
|
|
99
|
-
|
|
100
|
-
# Interactive setup — pick "1) Scan-to-create app" or "2) Paste AppID/Secret manually".
|
|
101
|
-
# Credentials are validated with a tenant_access_token call before bots.json is written.
|
|
102
|
-
# At the end of setup the wizard writes the full scope JSON to ~/.botmux/lark-scopes.json
|
|
103
|
-
# and prints a one-line clipboard copy command for your platform.
|
|
104
|
-
botmux setup
|
|
105
|
-
|
|
106
|
-
# Start (if you ever need to verify the event subscription, Lark requires the daemon to be running so it can detect the WebSocket connection)
|
|
107
|
-
# Re-validates credentials before forking workers; missing scopes only WARN, do not block the daemon.
|
|
108
105
|
botmux start
|
|
109
106
|
```
|
|
110
107
|
|
|
108
|
+
> `start` re-validates credentials before forking workers; missing scopes only WARN, they don't block the daemon. If you later need to verify the event subscription, Lark requires the daemon to be running so it can detect the WebSocket connection.
|
|
109
|
+
|
|
111
110
|
### Step 4: Add Permissions
|
|
112
111
|
|
|
113
112
|
Run the copy-to-clipboard command setup printed, then go to "Permissions & Scopes" → "Batch Import/Export" and paste. Submit for review — visibility "only me" auto-approves.
|
|
@@ -306,9 +305,9 @@ Send these straight into a topic — the daemon intercepts them (no clash with t
|
|
|
306
305
|
|
|
307
306
|
| Command | Description |
|
|
308
307
|
|---------|-------------|
|
|
309
|
-
| `/repo` |
|
|
308
|
+
| `/repo` | While a repo is pending selection, launch in the default workingDir; mid-session, show the project selector card (interactive dropdown + text list) |
|
|
310
309
|
| `/repo <N>` | Switch to Nth project from last scan |
|
|
311
|
-
| `/
|
|
310
|
+
| `/repo <path\|name>` | Skip the selector card; pass a path (relative/absolute) or a first-level project name under workingDir |
|
|
312
311
|
| `/cd <path>` | Change working directory and restart the CLI process |
|
|
313
312
|
| `/status` | Show session info (uptime, terminal URL, etc.) |
|
|
314
313
|
| `/restart` | Restart CLI process (keeps the session context) |
|
|
@@ -355,8 +354,8 @@ Send these straight into a topic — the daemon intercepts them (no clash with t
|
|
|
355
354
|
|
|
356
355
|
| Command | Description |
|
|
357
356
|
|---------|-------------|
|
|
358
|
-
| `@bot /grant @someone` | Pop an authorization card to add the user to the "this chat" or "global" allowlist; also auto-pops (and @s the owner) when an unauthorized user @-mentions the bot |
|
|
359
|
-
| `@bot /revoke @someone` | Revoke the user's this-chat + global access |
|
|
357
|
+
| `@bot /grant @someone` | Pop an authorization card to add the user to the "this chat" or "global" allowlist; you can @ several people/bots at once (one card lists every target, one scope click applies to all); if a granted target is a bot, it's auto-registered into the roster on success (an implicit `/introduce`) for cross-bot collaboration; also auto-pops (and @s the owner) when an unauthorized user @-mentions the bot |
|
|
358
|
+
| `@bot /revoke @someone` | Revoke the user's this-chat + global access; you can @ several people/bots at once |
|
|
360
359
|
|
|
361
360
|
**🆕 One-shot session group**
|
|
362
361
|
|
|
@@ -369,7 +368,7 @@ Send these straight into a topic — the daemon intercepts them (no clash with t
|
|
|
369
368
|
| Command | Description |
|
|
370
369
|
|---------|-------------|
|
|
371
370
|
| `@botA @botB /t <prompt>` | With multiple bots, each @-mentioned bot opens its own independent topic from the same message |
|
|
372
|
-
| `@botA @botB /introduce` | Bots register each other's open_id so they can later explicitly @-mention one another across sessions (any @ order, extra text allowed) |
|
|
371
|
+
| `@botA @botB /introduce` | Bots register each other's open_id so they can later explicitly @-mention one another across sessions (any @ order, extra text allowed; roster-only, grants no permission — **anyone in the chat can run it, no authorization needed**) |
|
|
373
372
|
|
|
374
373
|
**❓ Help**
|
|
375
374
|
|
|
@@ -414,7 +413,7 @@ Configure bots via `~/.botmux/bots.json`. Run `botmux setup` to create it intera
|
|
|
414
413
|
botmux setup
|
|
415
414
|
```
|
|
416
415
|
|
|
417
|
-
When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfigure from scratch, edit an existing bot, or delete a bot config. The edit/delete flow accepts the process name shown by `botmux status` (e.g. `botmux-1` or a custom `botmux-claude-main`) or the `larkAppId`; empty input keeps the current value, and `-` clears optional fields such as `name`, `backendType`, `workingDir`, and `allowedUsers`. Changing `larkAppId` asks for confirmation because historical session/chat state under the old app ID is not migrated automatically. Deleting a bot only removes one local `bots.json` entry; it does not delete the Lark app, historical messages, or local session data. Run `botmux restart` for changes to take effect.
|
|
416
|
+
When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfigure from scratch, edit an existing bot, or delete a bot config. The edit/delete flow accepts the process name shown by `botmux status` (e.g. `botmux-1` or a custom `botmux-claude-main`) or the `larkAppId`; empty input keeps the current value, and `-` clears optional fields such as `name`, `model`, `backendType`, `workingDir`, and `allowedUsers`. Changing `larkAppId` asks for confirmation because historical session/chat state under the old app ID is not migrated automatically. Deleting a bot only removes one local `bots.json` entry; it does not delete the Lark app, historical messages, or local session data. Run `botmux restart` for changes to take effect.
|
|
418
417
|
|
|
419
418
|
**bots.json format:**
|
|
420
419
|
|
|
@@ -425,7 +424,7 @@ When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfi
|
|
|
425
424
|
"larkAppSecret": "secret_1",
|
|
426
425
|
"name": "claude-main",
|
|
427
426
|
"cliId": "claude-code",
|
|
428
|
-
"
|
|
427
|
+
"model": "sonnet",
|
|
429
428
|
"workingDir": "~/projects",
|
|
430
429
|
"allowedUsers": ["alice@company.com"],
|
|
431
430
|
"allowedChatGroups": ["oc_xxx_team"]
|
|
@@ -434,6 +433,7 @@ When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfi
|
|
|
434
433
|
"larkAppId": "cli_xxx_bot2",
|
|
435
434
|
"larkAppSecret": "secret_2",
|
|
436
435
|
"cliId": "codex",
|
|
436
|
+
"model": "gpt-5-codex",
|
|
437
437
|
"workingDir": "~/work"
|
|
438
438
|
}
|
|
439
439
|
]
|
|
@@ -444,14 +444,15 @@ When `~/.botmux/bots.json` already exists, `botmux setup` can add a bot, reconfi
|
|
|
444
444
|
| `larkAppId` | Yes | Lark app ID |
|
|
445
445
|
| `larkAppSecret` | Yes | Lark app secret |
|
|
446
446
|
| `name` | No | Process name suffix shown by `botmux status`; e.g. `claude-main` appears as `botmux-claude-main`, defaults to `botmux-<index>` |
|
|
447
|
-
| `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `cursor`, `gemini`, `opencode`, `antigravity`) |
|
|
447
|
+
| `cliId` | No | CLI adapter, defaults to `claude-code` (options: `aiden`, `coco`, `codex`, `codex-app`, `cursor`, `gemini`, `opencode`, `antigravity`, `hermes`) |
|
|
448
|
+
| `model` | No | Model name used when spawning the CLI. Currently honored by: `claude-code`, `codex`, `coco`, `cursor`, `gemini`, `opencode`; other adapters ignore the field. Leave empty to use the CLI default. `botmux setup` proposes per-CLI candidates plus a free-form Other option. |
|
|
448
449
|
| `cliPathOverride` | No | Absolute path to the CLI entry, for wrappers / routers; typical use: `ccr`, `claude-w`, `aiden-x-claude`, etc. |
|
|
449
|
-
| `requireApproval` | No | Whether to require the CLI's own approval/sandbox flow. Missing or `false` keeps the legacy behavior: botmux still adds bypass / weak-sandbox flags such as `--yolo`, `--dangerously-*`, `--force`, or `--permission-mode agentFull`. When `true`, botmux stops adding those flags. If you need a fixed approval/sandbox policy, point `cliPathOverride` at a wrapper script that appends the desired CLI-specific arguments |
|
|
450
450
|
| `backendType` | No | Session backend: `pty` or `tmux` (auto-detected by default) |
|
|
451
451
|
| `workingDir` | No | Default working directory, supports comma-separated. The new-topic repo-select card scans for git repos **from this directory downward** (recursive, up to 3 levels), no longer climbing to the parent: point it at a repos root (e.g. `~/projects`) to list every repo beneath it, or at a single repo to list just that repo (and its linked worktrees) |
|
|
452
452
|
| `defaultWorkingDir` | No | Single-repo default: new topics with no oncall binding and no peer-session inheritance spawn directly here, skipping the repo-select card. `/cd <path>` still switches mid-session; the next new topic falls back to this default. **Difference from `defaultOncall`:** does NOT write `oncallChats` and does NOT change the `canTalk` / `canOperate` permission model |
|
|
453
453
|
| `allowedUsers` | No | Allowed users (**full emails** like `alice@example.com`, or open_ids `ou_xxx`). Email prefixes can't be resolved and are dropped. Required (at least one entry, as owner) when `allowedChatGroups` is set |
|
|
454
454
|
| `allowedChatGroups` | No | Talk-open chats (`chat_id`, for example `oc_xxx`). Any member talking **inside these chats** can use the bot (decided by the message's chat — new members work immediately, removed members lose access, no restart needed); grants `canTalk` only, sensitive ops still require `allowedUsers`. Equivalent to the owner running `/grant` (no target) in that chat. |
|
|
455
|
+
| `globalGrants` | No | Global talk allowlist (`open_id` list, e.g. `ou_xxx`; humans or bots). Listed entries can talk to the bot in **any** chat; grants `canTalk` only, sensitive ops still require `allowedUsers`. Usually written via the owner's `/grant` card (the "grant talk globally" button); can also be set manually here. |
|
|
455
456
|
| `oncallChats` | No | Oncall bindings (written by `/oncall bind`), e.g. `[{ "chatId": "oc_xxx", "workingDir": "~/projects/foo" }]`; any group member can @ the bot |
|
|
456
457
|
|
|
457
458
|
**Config priority:** `BOTS_CONFIG` env var > `~/.botmux/bots.json`
|
package/README.md
CHANGED
|
@@ -169,7 +169,8 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
|
|
|
169
169
|
## 前置要求
|
|
170
170
|
|
|
171
171
|
- **Node.js** >= 20
|
|
172
|
-
- **AI 编程 CLI
|
|
172
|
+
- **AI 编程 CLI / 本地 Agent 应用** 已安装并完成认证(`claude`、`codex`、`coco`、`cursor-agent`、`gemini`、`opencode`、`hermes` 或 `agy`(Antigravity)在 PATH 中)
|
|
173
|
+
- **CoCo 最低版本 `0.120.32`**:type-ahead(会话忙时即可发新消息,由 CoCo 自己的消息队列接住)依赖 0.120.32+ 的行为;更早版本忙时输入可能丢失或串行,请升级后再用
|
|
173
174
|
- **tmux** >= 3.x(可选,安装后自动启用会话常驻)
|
|
174
175
|
- **CJK 字体**(用于截图渲染中文/emoji):
|
|
175
176
|
- macOS 自带 PingFang/Hiragino,无需配置
|
|
@@ -178,42 +179,41 @@ CLI 进入 botmux 会话时自动获得 `~/.botmux/bin` 在 PATH 中,以及一
|
|
|
178
179
|
|
|
179
180
|
## 5 分钟快速接入
|
|
180
181
|
|
|
181
|
-
> 💡 **TL;DR
|
|
182
|
+
> 💡 **TL;DR**:`npm i -g botmux` → `botmux setup` 选「扫码建应用」一步拿到 AppID/AppSecret(Step 2)→ `botmux start`。PersonalAgent 应用建出来时事件订阅和 bot 能力都已默认配好,只剩 Step 4 权限申请 + Step 5(按需)重定向 URL + Step 6 发版三步要在浏览器手动点;setup 完成后会自动写 JSON 文件 + 打印一键复制命令 + 各步骤的深链。
|
|
182
183
|
|
|
183
|
-
### Step 1:
|
|
184
|
+
### Step 1: 安装 botmux
|
|
184
185
|
|
|
185
|
-
|
|
186
|
+
```bash
|
|
187
|
+
npm install -g botmux
|
|
188
|
+
```
|
|
186
189
|
|
|
187
|
-
>
|
|
190
|
+
> 要求 **Node.js ≥ 20**,且本地已装好并登录至少一种 AI 编程 CLI(`claude` / `codex` / `cursor-agent` / `gemini` / `opencode` / `coco` / `agy` 等在 PATH 中)。推荐顺手装 **tmux**(装了自动启用会话常驻)。
|
|
188
191
|
|
|
189
|
-
|
|
192
|
+
### Step 2: 创建应用并配置(`botmux setup`)
|
|
190
193
|
|
|
191
|
-
|
|
194
|
+
跑 `botmux setup`,按交互菜单一步步选:
|
|
192
195
|
|
|
193
|
-
|
|
196
|
+
1. **新建配置**:输入 `1` 回车(已有配置时输入 `2` 添加机器人)。
|
|
197
|
+
2. **创建机器人**:
|
|
198
|
+
- 输入 `1` → **扫码创建(推荐)**:飞书扫码完成后自动建出 PersonalAgent 应用并落盘 AppID/AppSecret,**事件订阅 + bot 能力默认已配好**,无需手动浏览器创建。底层走 `@larksuiteoapi/node-sdk` 官方 device flow。
|
|
199
|
+
- 输入 `2` → **手动创建**:去 [飞书开放平台](https://open.larkoffice.com/app) 建「企业自建应用」,在「凭证与基础信息」复制 **App ID / App Secret** 回来粘贴。
|
|
200
|
+
3. **选择 CLI**:选本次要接入的 CLI(如接 Claude Code 就选 `1`)。
|
|
201
|
+
4. **默认工作目录**:通常填 git 项目的**父级目录**(如 `~/projects`),新话题会从该目录**向下**查找 git 仓库(最多 3 层);尽量别填 `~`(要遍历太多文件夹)。
|
|
194
202
|
|
|
195
|
-
>
|
|
203
|
+
> ⚠️ **目前仅支持飞书 (feishu.cn) 租户**。扫码检测到 Lark 国际版 (larksuite.com) 会中止 setup —— daemon runtime (Lark Client/WSClient/event-dispatcher 等) 需要一并接入 lark 域,会在单独 PR 跟进。
|
|
196
204
|
|
|
197
|
-
|
|
205
|
+
setup 末尾会用 `tenant_access_token` 校验凭证(通过才落盘 `bots.json`),并把完整权限 JSON 写到 `~/.botmux/lark-scopes.json` + 打印一键复制命令 + 各步骤深链。
|
|
198
206
|
|
|
199
|
-

|
|
200
208
|
|
|
201
|
-
### Step 3:
|
|
209
|
+
### Step 3: 启动
|
|
202
210
|
|
|
203
211
|
```bash
|
|
204
|
-
# 安装
|
|
205
|
-
npm install -g botmux
|
|
206
|
-
|
|
207
|
-
# 交互式配置 — 选「1) 扫码建应用」或「2) 手动粘 AppID/Secret」
|
|
208
|
-
# 凭证拿到后自动取一次 tenant_access_token 校验,通过才落盘 bots.json
|
|
209
|
-
# setup 末尾会把完整权限 JSON 写到 ~/.botmux/lark-scopes.json 并打印一键复制命令
|
|
210
|
-
botmux setup
|
|
211
|
-
|
|
212
|
-
# 启动(如果之后需要确认事件订阅,飞书后台会要求 daemon 已在跑才能识别长连接)
|
|
213
|
-
# start 前再校验一次凭证;权限未配齐不会阻塞 daemon,只 WARN
|
|
214
212
|
botmux start
|
|
215
213
|
```
|
|
216
214
|
|
|
215
|
+
> start 前再校验一次凭证;权限未配齐不会阻塞 daemon,只 WARN。如果之后需要确认事件订阅,飞书后台会要求 daemon 已在跑才能识别长连接。
|
|
216
|
+
|
|
217
217
|
### Step 4: 添加权限
|
|
218
218
|
|
|
219
219
|
setup 完成后,按 terminal 提示的一键复制命令把权限 JSON 复制到剪贴板,进入「权限管理」→「批量导入/导出权限」粘贴 → 提交审批。可用性范围选「仅自己可见」会自动通过:
|
|
@@ -300,9 +300,9 @@ botmux autostart enable
|
|
|
300
300
|
|
|
301
301
|
| 命令 | 说明 |
|
|
302
302
|
|------|------|
|
|
303
|
-
| `/repo` |
|
|
303
|
+
| `/repo` | 仓库待选时直接用默认 workingDir 启动会话;会话进行中则弹出项目选择卡片(交互式下拉 + 文本列表) |
|
|
304
304
|
| `/repo <N>` | 切换到上次扫描的第 N 个项目 |
|
|
305
|
-
| `/
|
|
305
|
+
| `/repo <路径\|项目名>` | 跳过选择卡片,直接指定路径(相对/绝对)或 workingDir 下的一级项目名 |
|
|
306
306
|
| `/cd <路径>` | 切换工作目录并重启 CLI 进程 |
|
|
307
307
|
| `/status` | 查看会话信息(运行时间、终端地址等) |
|
|
308
308
|
| `/restart` | 重启 CLI 进程(保留 session 上下文) |
|
|
@@ -349,8 +349,8 @@ botmux autostart enable
|
|
|
349
349
|
|
|
350
350
|
| 命令 | 说明 |
|
|
351
351
|
|------|------|
|
|
352
|
-
| `@机器人 /grant @某人` |
|
|
353
|
-
| `@机器人 /revoke @某人` | 撤销对方的本群 +
|
|
352
|
+
| `@机器人 /grant @某人` | 弹授权卡片,把对方加进「本群使用」或「全局」白名单;可一次 @ 多人/多 bot(一张卡列出全部目标、点一次范围对全部生效);被授权的若是 bot,授权成功后会自动登记进花名册(等于顺带 `/introduce` 一次)便于跨 bot 协作;无权限者 @ 机器人时也会自动弹这张卡并 @owner |
|
|
353
|
+
| `@机器人 /revoke @某人` | 撤销对方的本群 + 全局授权;可一次 @ 多人/多 bot |
|
|
354
354
|
|
|
355
355
|
**🆕 一键新建会话群**
|
|
356
356
|
|
|
@@ -363,7 +363,7 @@ botmux autostart enable
|
|
|
363
363
|
| 命令 | 说明 |
|
|
364
364
|
|------|------|
|
|
365
365
|
| `@botA @botB /t <prompt>` | 多机器人时,让每个被 @ 的机器人在同一条消息上各自独立开新话题 |
|
|
366
|
-
| `@botA @botB /introduce` | 互相登记彼此的 open_id,便于后续跨 bot 显式 @mention 协作(@
|
|
366
|
+
| `@botA @botB /introduce` | 互相登记彼此的 open_id,便于后续跨 bot 显式 @mention 协作(@ 顺序任意,可带额外文本;只记花名册、不授予任何权限,**群内任何人都可用、无需授权**) |
|
|
367
367
|
|
|
368
368
|
**❓ 帮助**
|
|
369
369
|
|
|
@@ -518,7 +518,7 @@ dashboard 走单独 pm2 进程 `botmux-dashboard`,跟着 `pnpm daemon:restart`
|
|
|
518
518
|
botmux setup
|
|
519
519
|
```
|
|
520
520
|
|
|
521
|
-
已有 `~/.botmux/bots.json` 时,`botmux setup` 支持添加新机器人、重新配置、编辑现有机器人,以及删除机器人配置。编辑或删除时用 `botmux status` 里的进程名(如 `botmux-1` 或自定义的 `botmux-claude-main`)或 `larkAppId` 选择目标;字段留空表示保留当前值,`name`、`cliPathOverride`、`backendType`、`workingDir`、`allowedUsers` 等可选字段输入 `-` 表示清空。修改 `larkAppId` 会提示确认,因为旧 appId 下的历史会话和群聊状态数据不会自动迁移。删除机器人只移除本机 `bots.json` 中的一项,不删除飞书开放平台应用、历史消息或本地会话数据;修改完成后运行 `botmux restart` 生效。
|
|
521
|
+
已有 `~/.botmux/bots.json` 时,`botmux setup` 支持添加新机器人、重新配置、编辑现有机器人,以及删除机器人配置。编辑或删除时用 `botmux status` 里的进程名(如 `botmux-1` 或自定义的 `botmux-claude-main`)或 `larkAppId` 选择目标;字段留空表示保留当前值,`name`、`model`、`cliPathOverride`、`backendType`、`workingDir`、`allowedUsers` 等可选字段输入 `-` 表示清空。修改 `larkAppId` 会提示确认,因为旧 appId 下的历史会话和群聊状态数据不会自动迁移。删除机器人只移除本机 `bots.json` 中的一项,不删除飞书开放平台应用、历史消息或本地会话数据;修改完成后运行 `botmux restart` 生效。
|
|
522
522
|
|
|
523
523
|
**bots.json 格式:**
|
|
524
524
|
|
|
@@ -529,7 +529,7 @@ botmux setup
|
|
|
529
529
|
"larkAppSecret": "secret_1",
|
|
530
530
|
"name": "claude-main",
|
|
531
531
|
"cliId": "claude-code",
|
|
532
|
-
"
|
|
532
|
+
"model": "sonnet",
|
|
533
533
|
"workingDir": "~/projects",
|
|
534
534
|
"allowedUsers": ["alice@company.com"],
|
|
535
535
|
"allowedChatGroups": ["oc_xxx_team"]
|
|
@@ -538,6 +538,7 @@ botmux setup
|
|
|
538
538
|
"larkAppId": "cli_xxx_bot2",
|
|
539
539
|
"larkAppSecret": "secret_2",
|
|
540
540
|
"cliId": "codex",
|
|
541
|
+
"model": "gpt-5-codex",
|
|
541
542
|
"workingDir": "~/work"
|
|
542
543
|
}
|
|
543
544
|
]
|
|
@@ -548,14 +549,15 @@ botmux setup
|
|
|
548
549
|
| `larkAppId` | 是 | 飞书应用 App ID |
|
|
549
550
|
| `larkAppSecret` | 是 | 飞书应用 App Secret |
|
|
550
551
|
| `name` | 否 | `botmux status` 中的进程名后缀;例如 `claude-main` 会显示为 `botmux-claude-main`,留空默认 `botmux-<序号>` |
|
|
551
|
-
| `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`cursor`、`gemini`、`opencode`、`antigravity`) |
|
|
552
|
+
| `cliId` | 否 | CLI 适配器,默认 `claude-code`(可选:`aiden`、`coco`、`codex`、`codex-app`、`cursor`、`gemini`、`opencode`、`antigravity`、`hermes`) |
|
|
553
|
+
| `model` | 否 | 启动 CLI 时使用的模型名;留空走 CLI 默认。当前会注入到支持模型参数的适配器:`claude-code` / `codex` / `coco` / `cursor` / `gemini` / `opencode`;其它适配器会忽略该字段 |
|
|
552
554
|
| `cliPathOverride` | 否 | CLI 入口的绝对路径,用于套 wrapper / router;典型场景:ccr、claude-w、aiden-x-claude 等自定义入口 |
|
|
553
|
-
| `requireApproval` | 否 | 是否要求 CLI 自身审批/沙箱机制。未配置或 `false` 时保持兼容旧逻辑,botmux 会继续添加 `--yolo`、`--dangerously-*`、`--force`、`--permission-mode agentFull` 等免审批/弱沙箱参数;设为 `true` 时不再自动添加这些参数。如需固定 approval/sandbox 策略,可通过 `cliPathOverride` 指向自定义 wrapper 脚本自行追加对应 CLI 参数 |
|
|
554
555
|
| `backendType` | 否 | 会话后端:`pty` 或 `tmux`(默认自动检测) |
|
|
555
556
|
| `workingDir` | 否 | 默认工作目录,支持逗号分隔多个目录。新话题的 repo 选择卡片会**从该目录自身向下**递归查找 git 仓库(最多 3 层),不再向上扫父目录:指向仓库集合根目录(如 `~/projects`)即列出其下所有仓库,指向单个仓库则只列该仓库(及其 linked worktrees) |
|
|
556
557
|
| `defaultWorkingDir` | 否 | 单仓库默认目录:新话题在无 oncall 绑定 / 无同群兄弟 session 时直接进入该目录,跳过 repo 选择卡片。`/cd <path>` 仍可临时切换;下一个新话题回到该默认值。**与 `defaultOncall` 的区别**:不写 `oncallChats`、不修改 `canTalk`/`canOperate` 权限模型 |
|
|
557
558
|
| `allowedUsers` | 否 | 允许的用户列表(**完整邮箱**如 `alice@example.com`,或 open_id `ou_xxx`)。邮箱前缀无法解析、会被丢弃。配置了 `allowedChatGroups` 时此项必须至少有一个条目作为 owner |
|
|
558
559
|
| `allowedChatGroups` | 否 | 可对话群列表(飞书 `chat_id`,如 `oc_xxx`)。**在这些群里**任何成员都能与机器人对话(按消息所在群判断,新人进群即生效、退群即失权,无需重启);仅授对话权(`canTalk`),敏感操作仍由 `allowedUsers` 控制。等价于 owner 在该群发 `/grant`(不带 @)。 |
|
|
560
|
+
| `globalGrants` | 否 | 全局可对话名单(`open_id` 列表,如 `ou_xxx`;人或 bot 均可)。名单内的对象可在**任意群**与机器人对话;仅授对话权(`canTalk`),敏感操作仍由 `allowedUsers` 控制。通常由 owner 在授权卡上点「全局授权对话」写入,也可在此手动配置。 |
|
|
559
561
|
| `oncallChats` | 否 | oncall 绑定(`/oncall bind` 写入),形如 `[{ "chatId": "oc_xxx", "workingDir": "~/projects/foo" }]`,群内任何成员可 @ 提问 |
|
|
560
562
|
|
|
561
563
|
**配置优先级:** `BOTS_CONFIG` 环境变量 → `~/.botmux/bots.json`
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adopt-route.ts
|
|
3
|
+
*
|
|
4
|
+
* 为没有 BOTMUX_* 环境变量的"孤立" Claude 进程(即通过 /adopt 接管的外部 CLI)
|
|
5
|
+
* 提供 askUserQuestion hook 的路由解析逻辑。
|
|
6
|
+
*
|
|
7
|
+
* 通过以下步骤确定目标 Lark 会话:
|
|
8
|
+
* 1. 收集 hook 进程的祖先 PID 链
|
|
9
|
+
* 2. 遍历在线 daemon,查询每个 daemon 是否有以某祖先 PID 启动的 adopt 会话
|
|
10
|
+
* 3. 首个命中即返回路由信息
|
|
11
|
+
*/
|
|
12
|
+
/** 从 daemon 取回的 adopt 会话路由信息 */
|
|
13
|
+
export interface AdoptRoute {
|
|
14
|
+
sessionId: string;
|
|
15
|
+
chatId: string;
|
|
16
|
+
larkAppId: string;
|
|
17
|
+
rootMessageId: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 沿进程祖先链向上收集 PID(不含 startPid 自己)。
|
|
21
|
+
*
|
|
22
|
+
* @param startPid 起始进程 PID(自身不包含在结果中)
|
|
23
|
+
* @param readParent 注入式父 PID 读取函数(默认使用 /proc 或 ps)
|
|
24
|
+
* @param maxDepth 最大深度,防止意外无限循环(默认 40)
|
|
25
|
+
* @returns 祖先 PID 数组,从最近父进程到最远祖先
|
|
26
|
+
*/
|
|
27
|
+
export declare function getAncestorPids(startPid: number, readParent?: (pid: number) => number | null, maxDepth?: number): number[];
|
|
28
|
+
/**
|
|
29
|
+
* 查询某个 daemon 是否有以指定 PID 启动的活跃 adopt 会话。
|
|
30
|
+
*
|
|
31
|
+
* GET http://127.0.0.1:<ipcPort>/api/adopt-session/<pid>
|
|
32
|
+
* 200 → 解析 AdoptRoute;其它状态码或异常 → null(不抛)。
|
|
33
|
+
* 超时:2 秒(AbortController)。
|
|
34
|
+
*/
|
|
35
|
+
export declare function queryAdoptSession(ipcPort: number, pid: number): Promise<AdoptRoute | null>;
|
|
36
|
+
/**
|
|
37
|
+
* 通过祖先 PID 匹配在线 adopt 会话。
|
|
38
|
+
*
|
|
39
|
+
* **并发 + 全局 budget 封顶**:候选 = daemon 列表序 × 祖先链序(由近及远)逐个编号;
|
|
40
|
+
* 全部并发查询(每请求各自带 2s 超时),整体不超过 `budgetMs`。命中按候选 index 取
|
|
41
|
+
* 最小,保持确定性。
|
|
42
|
+
*
|
|
43
|
+
* 为何要全局 budget:runHook 在缺 BOTMUX_* 时同步 await 本函数,而全局 hook 会覆盖
|
|
44
|
+
* 非 botmux 的 Claude 会话;若某 daemon still-online 但 IPC 不响应,顺序 await 会
|
|
45
|
+
* `祖先数 × 2s × daemon 数` 线性叠加(可达几十秒),把真·非 botmux 的 ask 卡死。
|
|
46
|
+
* 并发让总耗时收敛到单请求量级,budget 再封顶,保证快速 passthrough。
|
|
47
|
+
*
|
|
48
|
+
* @param deps.startPid hook 进程自身的 PID
|
|
49
|
+
* @param deps.listDaemons 列出在线 daemon(ipcPort)
|
|
50
|
+
* @param deps.queryDaemon 查询某 daemon 是否有该 pid 的活跃 adopt 会话
|
|
51
|
+
* @param deps.getAncestors 取祖先 PID(默认使用 getAncestorPids)
|
|
52
|
+
* @param deps.budgetMs 整体耗时上限(默认 1500ms;可注入便于测试)
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveAdoptRoute(deps: {
|
|
55
|
+
startPid: number;
|
|
56
|
+
listDaemons: () => Array<{
|
|
57
|
+
ipcPort: number;
|
|
58
|
+
}>;
|
|
59
|
+
queryDaemon: (ipcPort: number, pid: number) => Promise<AdoptRoute | null>;
|
|
60
|
+
getAncestors?: (startPid: number) => number[];
|
|
61
|
+
budgetMs?: number;
|
|
62
|
+
}): Promise<AdoptRoute | null>;
|
|
63
|
+
//# sourceMappingURL=adopt-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-route.d.ts","sourceRoot":"","sources":["../../src/adapters/adopt-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA8CD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAC3C,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,EAAE,CAiBV;AAID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgC5B;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC1E,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA+C7B"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adopt-route.ts
|
|
3
|
+
*
|
|
4
|
+
* 为没有 BOTMUX_* 环境变量的"孤立" Claude 进程(即通过 /adopt 接管的外部 CLI)
|
|
5
|
+
* 提供 askUserQuestion hook 的路由解析逻辑。
|
|
6
|
+
*
|
|
7
|
+
* 通过以下步骤确定目标 Lark 会话:
|
|
8
|
+
* 1. 收集 hook 进程的祖先 PID 链
|
|
9
|
+
* 2. 遍历在线 daemon,查询每个 daemon 是否有以某祖先 PID 启动的 adopt 会话
|
|
10
|
+
* 3. 首个命中即返回路由信息
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync } from 'node:child_process';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
// ── 祖先 PID 收集 ──────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* 读取某进程的父 PID。
|
|
17
|
+
*
|
|
18
|
+
* 默认实现:
|
|
19
|
+
* 1. 优先从 /proc/<pid>/stat 读取(Linux),第 4 字段(0-based)是 ppid。
|
|
20
|
+
* 注意 stat 第 2 字段 comm 可以含括号和空格,所以从最后一个 `)` 之后的子串解析。
|
|
21
|
+
* 2. 失败时回退到 `ps -o ppid= -p <pid>`(macOS/Linux 通用)。
|
|
22
|
+
*
|
|
23
|
+
* 失败/进程不存在 → 返回 null。
|
|
24
|
+
*/
|
|
25
|
+
function defaultReadParent(pid) {
|
|
26
|
+
// 先尝试 /proc(Linux 最快)
|
|
27
|
+
try {
|
|
28
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf-8');
|
|
29
|
+
// stat 格式: "<pid> (<comm>) <state> <ppid> ..."
|
|
30
|
+
// comm 字段可能含空格和括号,取最后一个 ')' 之后的部分
|
|
31
|
+
const lastParen = stat.lastIndexOf(')');
|
|
32
|
+
if (lastParen === -1)
|
|
33
|
+
throw new Error('unexpected /proc stat format');
|
|
34
|
+
const tail = stat.slice(lastParen + 1).trim();
|
|
35
|
+
// tail: "<state> <ppid> ..."
|
|
36
|
+
const parts = tail.split(' ');
|
|
37
|
+
// parts[0] = state, parts[1] = ppid
|
|
38
|
+
const ppid = parseInt(parts[1], 10);
|
|
39
|
+
if (Number.isInteger(ppid) && ppid > 0)
|
|
40
|
+
return ppid;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// /proc 不可用或解析失败,回退到 ps
|
|
44
|
+
}
|
|
45
|
+
// 回退到 ps(macOS / 无 /proc 的 Linux)
|
|
46
|
+
try {
|
|
47
|
+
const out = execFileSync('ps', ['-o', 'ppid=', '-p', String(pid)], {
|
|
48
|
+
encoding: 'utf-8',
|
|
49
|
+
});
|
|
50
|
+
const ppid = parseInt(out.trim(), 10);
|
|
51
|
+
if (Number.isInteger(ppid) && ppid > 0)
|
|
52
|
+
return ppid;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// 进程不存在或 ps 调用失败
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 沿进程祖先链向上收集 PID(不含 startPid 自己)。
|
|
61
|
+
*
|
|
62
|
+
* @param startPid 起始进程 PID(自身不包含在结果中)
|
|
63
|
+
* @param readParent 注入式父 PID 读取函数(默认使用 /proc 或 ps)
|
|
64
|
+
* @param maxDepth 最大深度,防止意外无限循环(默认 40)
|
|
65
|
+
* @returns 祖先 PID 数组,从最近父进程到最远祖先
|
|
66
|
+
*/
|
|
67
|
+
export function getAncestorPids(startPid, readParent, maxDepth) {
|
|
68
|
+
const reader = readParent ?? defaultReadParent;
|
|
69
|
+
const depth = maxDepth ?? 40;
|
|
70
|
+
const ancestors = [];
|
|
71
|
+
const visited = new Set([startPid]);
|
|
72
|
+
let current = startPid;
|
|
73
|
+
for (let i = 0; i < depth; i++) {
|
|
74
|
+
const parent = reader(current);
|
|
75
|
+
if (parent === null || parent <= 1)
|
|
76
|
+
break; // 到 init 或读不到,停止
|
|
77
|
+
if (visited.has(parent))
|
|
78
|
+
break; // 防环
|
|
79
|
+
visited.add(parent);
|
|
80
|
+
ancestors.push(parent);
|
|
81
|
+
current = parent;
|
|
82
|
+
}
|
|
83
|
+
return ancestors;
|
|
84
|
+
}
|
|
85
|
+
// ── Daemon 查询辅助 ─────────────────────────────────────────────────────────────
|
|
86
|
+
/**
|
|
87
|
+
* 查询某个 daemon 是否有以指定 PID 启动的活跃 adopt 会话。
|
|
88
|
+
*
|
|
89
|
+
* GET http://127.0.0.1:<ipcPort>/api/adopt-session/<pid>
|
|
90
|
+
* 200 → 解析 AdoptRoute;其它状态码或异常 → null(不抛)。
|
|
91
|
+
* 超时:2 秒(AbortController)。
|
|
92
|
+
*/
|
|
93
|
+
export async function queryAdoptSession(ipcPort, pid) {
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timer = setTimeout(() => controller.abort(), 2000);
|
|
96
|
+
try {
|
|
97
|
+
const res = await fetch(`http://127.0.0.1:${ipcPort}/api/adopt-session/${pid}`, { signal: controller.signal });
|
|
98
|
+
if (!res.ok)
|
|
99
|
+
return null;
|
|
100
|
+
const body = (await res.json());
|
|
101
|
+
if (!body || typeof body !== 'object')
|
|
102
|
+
return null;
|
|
103
|
+
const b = body;
|
|
104
|
+
if (typeof b.sessionId !== 'string' ||
|
|
105
|
+
typeof b.chatId !== 'string' ||
|
|
106
|
+
typeof b.larkAppId !== 'string' ||
|
|
107
|
+
typeof b.rootMessageId !== 'string') {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
sessionId: b.sessionId,
|
|
112
|
+
chatId: b.chatId,
|
|
113
|
+
larkAppId: b.larkAppId,
|
|
114
|
+
rootMessageId: b.rootMessageId,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// 超时、网络错误、JSON 解析失败等 → null
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ── 主逻辑 ─────────────────────────────────────────────────────────────────────
|
|
126
|
+
/**
|
|
127
|
+
* 通过祖先 PID 匹配在线 adopt 会话。
|
|
128
|
+
*
|
|
129
|
+
* **并发 + 全局 budget 封顶**:候选 = daemon 列表序 × 祖先链序(由近及远)逐个编号;
|
|
130
|
+
* 全部并发查询(每请求各自带 2s 超时),整体不超过 `budgetMs`。命中按候选 index 取
|
|
131
|
+
* 最小,保持确定性。
|
|
132
|
+
*
|
|
133
|
+
* 为何要全局 budget:runHook 在缺 BOTMUX_* 时同步 await 本函数,而全局 hook 会覆盖
|
|
134
|
+
* 非 botmux 的 Claude 会话;若某 daemon still-online 但 IPC 不响应,顺序 await 会
|
|
135
|
+
* `祖先数 × 2s × daemon 数` 线性叠加(可达几十秒),把真·非 botmux 的 ask 卡死。
|
|
136
|
+
* 并发让总耗时收敛到单请求量级,budget 再封顶,保证快速 passthrough。
|
|
137
|
+
*
|
|
138
|
+
* @param deps.startPid hook 进程自身的 PID
|
|
139
|
+
* @param deps.listDaemons 列出在线 daemon(ipcPort)
|
|
140
|
+
* @param deps.queryDaemon 查询某 daemon 是否有该 pid 的活跃 adopt 会话
|
|
141
|
+
* @param deps.getAncestors 取祖先 PID(默认使用 getAncestorPids)
|
|
142
|
+
* @param deps.budgetMs 整体耗时上限(默认 1500ms;可注入便于测试)
|
|
143
|
+
*/
|
|
144
|
+
export async function resolveAdoptRoute(deps) {
|
|
145
|
+
const { startPid, listDaemons, queryDaemon } = deps;
|
|
146
|
+
const getAncestors = deps.getAncestors ?? ((pid) => getAncestorPids(pid));
|
|
147
|
+
const budgetMs = deps.budgetMs ?? 1500;
|
|
148
|
+
const ancestors = getAncestors(startPid);
|
|
149
|
+
if (ancestors.length === 0)
|
|
150
|
+
return null;
|
|
151
|
+
const daemons = listDaemons();
|
|
152
|
+
if (daemons.length === 0)
|
|
153
|
+
return null;
|
|
154
|
+
// 候选编号:daemon 列表序 × 祖先链序(由近及远),index 决定确定性优先级。
|
|
155
|
+
const candidates = [];
|
|
156
|
+
let idx = 0;
|
|
157
|
+
for (const daemon of daemons) {
|
|
158
|
+
for (const pid of ancestors) {
|
|
159
|
+
candidates.push({ index: idx++, ipcPort: daemon.ipcPort, pid });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// 并发发起全部查询,命中按 index 记入 hits;整体被 budget 封顶。
|
|
163
|
+
const hits = new Map();
|
|
164
|
+
const queries = candidates.map(async (c) => {
|
|
165
|
+
const route = await queryDaemon(c.ipcPort, c.pid);
|
|
166
|
+
if (route)
|
|
167
|
+
hits.set(c.index, route);
|
|
168
|
+
});
|
|
169
|
+
let timer;
|
|
170
|
+
const budget = new Promise((resolve) => {
|
|
171
|
+
timer = setTimeout(resolve, budgetMs);
|
|
172
|
+
timer.unref?.();
|
|
173
|
+
});
|
|
174
|
+
try {
|
|
175
|
+
await Promise.race([Promise.allSettled(queries), budget]);
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
if (timer)
|
|
179
|
+
clearTimeout(timer);
|
|
180
|
+
}
|
|
181
|
+
// 在「budget 内已 settle 的命中」里按候选 index 升序取最早的一个(确定性)。
|
|
182
|
+
let best = null;
|
|
183
|
+
let bestIdx = Infinity;
|
|
184
|
+
for (const [i, route] of hits) {
|
|
185
|
+
if (i < bestIdx) {
|
|
186
|
+
bestIdx = i;
|
|
187
|
+
best = route;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (best && process.env.BOTMUX_HOOK_DEBUG === '1') {
|
|
191
|
+
process.stderr.write(`[adopt-route] matched candidate#${bestIdx} session=${best.sessionId}\n`);
|
|
192
|
+
}
|
|
193
|
+
return best;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=adopt-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt-route.js","sourceRoot":"","sources":["../../src/adapters/adopt-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,13 +115,15 @@ export declare function buildBotmuxEnvAssignments(env: NodeJS.ProcessEnv | undef
|
|
|
115
115
|
* $0 = '_' (placeholder), $1 = cwd, $2..N = KEY=VAL... bin args...
|
|
116
116
|
*
|
|
117
117
|
* The `cd` step makes the CLI's cwd survive a wayward `cd` in the user's
|
|
118
|
-
* rcfile. The `
|
|
119
|
-
*
|
|
118
|
+
* rcfile. The `unset` step removes bare creds the pane inherited from the tmux
|
|
119
|
+
* server's global env (REDACTED_ENV_UNSET_CLAUSE). The `exec /usr/bin/env` step
|
|
120
|
+
* injects botmux's per-bot/per-session overrides AFTER rcfile load so they
|
|
121
|
+
* can't be shadowed by leftover exports.
|
|
120
122
|
*
|
|
121
123
|
* POSIX-syntax (works in bash/zsh/sh); fish/csh/nu users get remapped to
|
|
122
124
|
* bash/zsh/sh by resolveUserShell() so they hit the same SCRIPT path.
|
|
123
125
|
*/
|
|
124
|
-
export declare const SHELL_WRAPPER_SCRIPT
|
|
126
|
+
export declare const SHELL_WRAPPER_SCRIPT: string;
|
|
125
127
|
/**
|
|
126
128
|
* Debug variant of the wrapper script — same prelude, but the CLI runs as
|
|
127
129
|
* a *child* (no `exec`) and the wrapper hands off to an interactive shell
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"tmux-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-backend.ts"],"names":[],"mappings":"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"}
|