botmux 2.93.0 → 2.94.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/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +6 -1
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/bot-registry.d.ts +10 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +2 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/dashboard-endpoint.d.ts +1 -1
- package/dist/cli/dashboard-endpoint.d.ts.map +1 -1
- package/dist/cli/dashboard-endpoint.js +3 -0
- package/dist/cli/dashboard-endpoint.js.map +1 -1
- package/dist/cli/workflow.d.ts.map +1 -1
- package/dist/cli/workflow.js +11 -4
- package/dist/cli/workflow.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +133 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +3 -0
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/inherit-peer.d.ts +5 -0
- package/dist/core/inherit-peer.d.ts.map +1 -1
- package/dist/core/inherit-peer.js +3 -0
- package/dist/core/inherit-peer.js.map +1 -1
- package/dist/core/trigger-session.d.ts +10 -0
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +22 -2
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/worker-pool.d.ts +6 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +49 -6
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +297 -13
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +7 -1
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +1 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +1 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/federation-spoke-api.d.ts +31 -0
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
- package/dist/dashboard/federation-spoke-api.js +36 -14
- package/dist/dashboard/federation-spoke-api.js.map +1 -1
- package/dist/dashboard/v3-runs-api.d.ts +26 -0
- package/dist/dashboard/v3-runs-api.d.ts.map +1 -0
- package/dist/dashboard/v3-runs-api.js +67 -0
- package/dist/dashboard/v3-runs-api.js.map +1 -0
- package/dist/dashboard/web/app.js +21 -9
- 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 +24 -1
- 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 +12 -4
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/legacy-workflow-link.d.ts +2 -0
- package/dist/dashboard/web/legacy-workflow-link.d.ts.map +1 -0
- package/dist/dashboard/web/legacy-workflow-link.js +12 -0
- package/dist/dashboard/web/legacy-workflow-link.js.map +1 -0
- package/dist/dashboard/web/v3-terminal.d.ts +11 -0
- package/dist/dashboard/web/v3-terminal.d.ts.map +1 -0
- package/dist/dashboard/web/v3-terminal.js +143 -0
- package/dist/dashboard/web/v3-terminal.js.map +1 -0
- package/dist/dashboard/web/v3.d.ts +2 -0
- package/dist/dashboard/web/v3.d.ts.map +1 -0
- package/dist/dashboard/web/v3.js +564 -0
- package/dist/dashboard/web/v3.js.map +1 -0
- package/dist/dashboard/web/workflows.d.ts.map +1 -1
- package/dist/dashboard/web/workflows.js +12 -8
- package/dist/dashboard/web/workflows.js.map +1 -1
- package/dist/dashboard-web/app.js +787 -699
- package/dist/dashboard-web/index.html +1 -1
- package/dist/dashboard-web/style.css +223 -0
- package/dist/dashboard.js +61 -40
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +6 -3
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +6 -3
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +12 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +52 -2
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/doc-comment.d.ts +20 -0
- package/dist/im/lark/doc-comment.d.ts.map +1 -1
- package/dist/im/lark/doc-comment.js +23 -0
- package/dist/im/lark/doc-comment.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +13 -9
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/v3-blocked-card-handler.d.ts +28 -0
- package/dist/im/lark/v3-blocked-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-blocked-card-handler.js +134 -0
- package/dist/im/lark/v3-blocked-card-handler.js.map +1 -0
- package/dist/im/lark/v3-blocked-card.d.ts +75 -0
- package/dist/im/lark/v3-blocked-card.d.ts.map +1 -0
- package/dist/im/lark/v3-blocked-card.js +206 -0
- package/dist/im/lark/v3-blocked-card.js.map +1 -0
- package/dist/im/lark/v3-gate-card-handler.d.ts +31 -0
- package/dist/im/lark/v3-gate-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-gate-card-handler.js +110 -0
- package/dist/im/lark/v3-gate-card-handler.js.map +1 -0
- package/dist/im/lark/v3-gate-card.d.ts +47 -0
- package/dist/im/lark/v3-gate-card.d.ts.map +1 -0
- package/dist/im/lark/v3-gate-card.js +119 -0
- package/dist/im/lark/v3-gate-card.js.map +1 -0
- package/dist/im/lark/v3-loop-grant-card-handler.d.ts +28 -0
- package/dist/im/lark/v3-loop-grant-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-loop-grant-card-handler.js +90 -0
- package/dist/im/lark/v3-loop-grant-card-handler.js.map +1 -0
- package/dist/im/lark/v3-loop-grant-card.d.ts +46 -0
- package/dist/im/lark/v3-loop-grant-card.d.ts.map +1 -0
- package/dist/im/lark/v3-loop-grant-card.js +119 -0
- package/dist/im/lark/v3-loop-grant-card.js.map +1 -0
- package/dist/im/lark/v3-revisit-grant-card-handler.d.ts +29 -0
- package/dist/im/lark/v3-revisit-grant-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-revisit-grant-card-handler.js +96 -0
- package/dist/im/lark/v3-revisit-grant-card-handler.js.map +1 -0
- package/dist/im/lark/v3-revisit-grant-card.d.ts +52 -0
- package/dist/im/lark/v3-revisit-grant-card.d.ts.map +1 -0
- package/dist/im/lark/v3-revisit-grant-card.js +123 -0
- package/dist/im/lark/v3-revisit-grant-card.js.map +1 -0
- package/dist/im/lark/workflow-cards.d.ts.map +1 -1
- package/dist/im/lark/workflow-cards.js +5 -1
- package/dist/im/lark/workflow-cards.js.map +1 -1
- package/dist/im/lark/workflow-progress-card.d.ts +1 -1
- package/dist/im/lark/workflow-progress-card.js +1 -1
- package/dist/im/lark/workflow-slash-command.d.ts +28 -0
- package/dist/im/lark/workflow-slash-command.d.ts.map +1 -1
- package/dist/im/lark/workflow-slash-command.js +61 -5
- package/dist/im/lark/workflow-slash-command.js.map +1 -1
- package/dist/platform/bind.d.ts.map +1 -1
- package/dist/platform/bind.js +17 -3
- package/dist/platform/bind.js.map +1 -1
- package/dist/services/card-prefs-store.d.ts +4 -0
- package/dist/services/card-prefs-store.d.ts.map +1 -1
- package/dist/services/card-prefs-store.js +19 -0
- package/dist/services/card-prefs-store.js.map +1 -1
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +18 -2
- package/dist/services/group-creator.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +208 -4
- package/dist/skills/definitions.js.map +1 -1
- package/dist/worker.js +79 -13
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +80 -80
- package/dist/workflows/events/payloads.d.ts +4 -4
- package/dist/workflows/events/schema.d.ts +16 -16
- package/dist/workflows/v3/architect.d.ts +37 -0
- package/dist/workflows/v3/architect.d.ts.map +1 -0
- package/dist/workflows/v3/architect.js +226 -0
- package/dist/workflows/v3/architect.js.map +1 -0
- package/dist/workflows/v3/bot-resolve.d.ts +21 -0
- package/dist/workflows/v3/bot-resolve.d.ts.map +1 -0
- package/dist/workflows/v3/bot-resolve.js +47 -0
- package/dist/workflows/v3/bot-resolve.js.map +1 -0
- package/dist/workflows/v3/cli-run.d.ts +24 -0
- package/dist/workflows/v3/cli-run.d.ts.map +1 -0
- package/dist/workflows/v3/cli-run.js +265 -0
- package/dist/workflows/v3/cli-run.js.map +1 -0
- package/dist/workflows/v3/contract.d.ts +302 -0
- package/dist/workflows/v3/contract.d.ts.map +1 -0
- package/dist/workflows/v3/contract.js +91 -0
- package/dist/workflows/v3/contract.js.map +1 -0
- package/dist/workflows/v3/daemon-run.d.ts +311 -0
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -0
- package/dist/workflows/v3/daemon-run.js +775 -0
- package/dist/workflows/v3/daemon-run.js.map +1 -0
- package/dist/workflows/v3/dag.d.ts +332 -0
- package/dist/workflows/v3/dag.d.ts.map +1 -0
- package/dist/workflows/v3/dag.js +1040 -0
- package/dist/workflows/v3/dag.js.map +1 -0
- package/dist/workflows/v3/ephemeral-pool.d.ts +29 -0
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -0
- package/dist/workflows/v3/ephemeral-pool.js +331 -0
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -0
- package/dist/workflows/v3/grill-state.d.ts +92 -0
- package/dist/workflows/v3/grill-state.d.ts.map +1 -0
- package/dist/workflows/v3/grill-state.js +151 -0
- package/dist/workflows/v3/grill-state.js.map +1 -0
- package/dist/workflows/v3/host.d.ts +88 -0
- package/dist/workflows/v3/host.d.ts.map +1 -0
- package/dist/workflows/v3/host.js +349 -0
- package/dist/workflows/v3/host.js.map +1 -0
- package/dist/workflows/v3/human-gate.d.ts +85 -0
- package/dist/workflows/v3/human-gate.d.ts.map +1 -0
- package/dist/workflows/v3/human-gate.js +153 -0
- package/dist/workflows/v3/human-gate.js.map +1 -0
- package/dist/workflows/v3/journal.d.ts +207 -0
- package/dist/workflows/v3/journal.d.ts.map +1 -0
- package/dist/workflows/v3/journal.js +74 -0
- package/dist/workflows/v3/journal.js.map +1 -0
- package/dist/workflows/v3/manifest.d.ts +17 -0
- package/dist/workflows/v3/manifest.d.ts.map +1 -0
- package/dist/workflows/v3/manifest.js +266 -0
- package/dist/workflows/v3/manifest.js.map +1 -0
- package/dist/workflows/v3/ops-projection.d.ts +110 -0
- package/dist/workflows/v3/ops-projection.d.ts.map +1 -0
- package/dist/workflows/v3/ops-projection.js +0 -0
- package/dist/workflows/v3/ops-projection.js.map +1 -0
- package/dist/workflows/v3/orchestrator.d.ts +168 -0
- package/dist/workflows/v3/orchestrator.d.ts.map +1 -0
- package/dist/workflows/v3/orchestrator.js +417 -0
- package/dist/workflows/v3/orchestrator.js.map +1 -0
- package/dist/workflows/v3/runtime.d.ts +193 -0
- package/dist/workflows/v3/runtime.d.ts.map +1 -0
- package/dist/workflows/v3/runtime.js +1284 -0
- package/dist/workflows/v3/runtime.js.map +1 -0
- package/dist/workflows/v3/spec.d.ts +32 -0
- package/dist/workflows/v3/spec.d.ts.map +1 -0
- package/dist/workflows/v3/spec.js +173 -0
- package/dist/workflows/v3/spec.js.map +1 -0
- package/dist/workflows/v3/state.d.ts +74 -0
- package/dist/workflows/v3/state.d.ts.map +1 -0
- package/dist/workflows/v3/state.js +353 -0
- package/dist/workflows/v3/state.js.map +1 -0
- package/package.json +1 -1
- package/dist/dashboard/web/workflow-catalog.d.ts +0 -2
- package/dist/dashboard/web/workflow-catalog.d.ts.map +0 -1
- package/dist/dashboard/web/workflow-catalog.js +0 -323
- package/dist/dashboard/web/workflow-catalog.js.map +0 -1
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - not depend on MCP tools (which may not be wired on every CLI)
|
|
8
8
|
* - keep frontmatter minimal — just `name` and `description` for discovery
|
|
9
9
|
*/
|
|
10
|
+
import { ASK_HUMAN_ERROR_CODE, GOAL_ASK_FILE, GOAL_ENV } from '../workflows/v3/contract.js';
|
|
10
11
|
const SCHEDULE_SKILL = `---
|
|
11
12
|
name: botmux-schedule
|
|
12
13
|
description: 在当前飞书/Lark 话题里创建、管理定时提醒(用 botmux schedule 命令,支持增删查改暂停恢复)。触发场景:用户说"每天X点"、"每周X"(任意星期,不限周一)、"每月X号"、"N分钟后/N小时后"、"明天X点"、"提醒我"、"定时任务"、"周期任务"、"recurring"、"reminder"、"crontab" 时;或显式提到 botmux schedule。到点后 daemon 会在原话题自动续一条消息并触发新 CLI 会话。注意区分:本 skill 是飞书话题内提醒;要在云端跑 remote agent 用 superpowers:schedule;要在当前会话循环跑 prompt 用 loop。
|
|
@@ -531,7 +532,7 @@ description: 根据用户自然语言描述生成 botmux workflow JSON 定义文
|
|
|
531
532
|
|
|
532
533
|
# botmux-workflow-create — Workflow 编排助手
|
|
533
534
|
|
|
534
|
-
把用户口头描述的几步任务翻译成可执行的 workflow JSON。本 skill 只负责设计、生成、校验,不负责启动 run;启动用 \`botmux workflow run <id>\` 或 IM \`/
|
|
535
|
+
把用户口头描述的几步任务翻译成可执行的 workflow JSON。本 skill 只负责设计、生成、校验,不负责启动 run;启动用 \`botmux workflow run <id>\` 或 IM \`/template run <id>\`。
|
|
535
536
|
|
|
536
537
|
## 硬规则
|
|
537
538
|
|
|
@@ -600,10 +601,10 @@ validate 能抓 JSON/schema/graph 错误;但它**不会**检查 bot 是否真
|
|
|
600
601
|
\`\`\`bash
|
|
601
602
|
botmux workflow run <workflowId> --param key=value
|
|
602
603
|
# 或在飞书话题里:
|
|
603
|
-
/
|
|
604
|
+
/template run <workflowId> key=value
|
|
604
605
|
\`\`\`
|
|
605
606
|
|
|
606
|
-
如果 workflow 定义了 object / array 类型入参,CLI 用 \`--param-json key=<json>\`;IM \`/
|
|
607
|
+
如果 workflow 定义了 object / array 类型入参,CLI 用 \`--param-json key=<json>\`;IM \`/template run\` 暂不支持 object / array 入参。
|
|
607
608
|
|
|
608
609
|
## Schema 速查
|
|
609
610
|
|
|
@@ -647,7 +648,7 @@ botmux workflow run batch-send --param-json tags='["urgent","cn"]'
|
|
|
647
648
|
botmux workflow run batch-send --param-json config='{"mode":"safe","limit":3}'
|
|
648
649
|
|
|
649
650
|
# IM: 只支持 key=value 标量;object / array 暂不支持
|
|
650
|
-
/
|
|
651
|
+
/template run weather-city city=上海 days=3 dryRun=false
|
|
651
652
|
\`\`\`
|
|
652
653
|
|
|
653
654
|
在节点里既可以用 \`{ "$ref": "params.<path>" }\` 整字段替换,也可以在字符串里 \`"\${params.<path>}"\` 内嵌(仅限值是标量时)。嵌套对象用点号路径:\`params.user.email\`。
|
|
@@ -988,6 +989,95 @@ stdout 为一行 JSON。注意:\`--json\` 覆盖所有结果类型;超时 /
|
|
|
988
989
|
- 不支持 comment / multi-select / free-form text(v0.1.7 范围外)
|
|
989
990
|
- 默认超时 300 秒,可用 \`--timeout <seconds>\` 调整
|
|
990
991
|
`;
|
|
992
|
+
const GOAL_ASK_SKILL = `---
|
|
993
|
+
name: botmux-goal-ask
|
|
994
|
+
description: v3 goal-mode 节点在真正需要人类判断时使用的文件式 ask 协议。触发场景:你运行在 botmux v3 goal-mode,必须让人做选择或补充自由文本,且无法自行研究或推断。不要调用原生 AskUserQuestion,也不要调用 botmux ask;写 ask.json + ASK_HUMAN failure manifest 后停止。
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
# botmux-goal-ask — v3 goal-mode 人类判断
|
|
998
|
+
|
|
999
|
+
你运行在 botmux v3 goal-mode 时,不能打开原生交互问答,也不能调用 \`botmux ask\`。如果且仅如果你遇到**必须由人做判断或补充信息**的问题,使用本文件协议暂停节点。
|
|
1000
|
+
|
|
1001
|
+
## 什么时候用
|
|
1002
|
+
|
|
1003
|
+
- 需要产品 / 业务 / 风险决策,不能通过读取文件、运行命令、搜索资料自行判断
|
|
1004
|
+
- 选项已经清楚,可以给出 2-6 个具体选择
|
|
1005
|
+
- 需要人补充一段规则、细节、边界说明,不能改写成有限选项
|
|
1006
|
+
- 没有人回答前继续执行会改变方向或造成风险
|
|
1007
|
+
|
|
1008
|
+
## 什么时候不要用
|
|
1009
|
+
|
|
1010
|
+
- 登录、鉴权、权限、外部确认弹窗:写普通 retryable failure manifest(如 \`AUTH_REQUIRED\`),不要 ask
|
|
1011
|
+
- 你可以自行推断、测试或查证的问题:直接处理,不要打断人
|
|
1012
|
+
- workflow 节点审批:外层 humanGate 已经处理,不要套 ask
|
|
1013
|
+
- 可以通过有限选项表达的问题:优先用 options,不要滥用自由文本
|
|
1014
|
+
|
|
1015
|
+
## 协议
|
|
1016
|
+
|
|
1017
|
+
1. 写 ask 文件到当前 attempt 目录。
|
|
1018
|
+
|
|
1019
|
+
选择题:
|
|
1020
|
+
|
|
1021
|
+
\`\`\`json
|
|
1022
|
+
{
|
|
1023
|
+
"question": "一个清晰的问题",
|
|
1024
|
+
"options": ["选项 A", "选项 B"]
|
|
1025
|
+
}
|
|
1026
|
+
\`\`\`
|
|
1027
|
+
|
|
1028
|
+
填空题:
|
|
1029
|
+
|
|
1030
|
+
\`\`\`json
|
|
1031
|
+
{
|
|
1032
|
+
"question": "请补充计费规则的边界说明",
|
|
1033
|
+
"freeText": true
|
|
1034
|
+
}
|
|
1035
|
+
\`\`\`
|
|
1036
|
+
|
|
1037
|
+
路径必须是:
|
|
1038
|
+
|
|
1039
|
+
\`\`\`bash
|
|
1040
|
+
$${GOAL_ENV.ATTEMPT_DIR}/${GOAL_ASK_FILE}
|
|
1041
|
+
\`\`\`
|
|
1042
|
+
|
|
1043
|
+
2. 立刻写 failure manifest 到:
|
|
1044
|
+
|
|
1045
|
+
\`\`\`bash
|
|
1046
|
+
$${GOAL_ENV.MANIFEST_PATH}
|
|
1047
|
+
\`\`\`
|
|
1048
|
+
|
|
1049
|
+
manifest 的要求:
|
|
1050
|
+
|
|
1051
|
+
\`\`\`json
|
|
1052
|
+
{
|
|
1053
|
+
"schemaVersion": 1,
|
|
1054
|
+
"status": "fail",
|
|
1055
|
+
"summary": "同 ask.question 的一句话摘要",
|
|
1056
|
+
"files": [],
|
|
1057
|
+
"error": {
|
|
1058
|
+
"code": "${ASK_HUMAN_ERROR_CODE}",
|
|
1059
|
+
"message": "同 ask.question",
|
|
1060
|
+
"retryable": true
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
\`\`\`
|
|
1064
|
+
|
|
1065
|
+
3. 写完 manifest 后停止,不要继续执行。
|
|
1066
|
+
|
|
1067
|
+
人类选择后,runtime 会重跑该节点,并把答案注入到:
|
|
1068
|
+
|
|
1069
|
+
\`\`\`bash
|
|
1070
|
+
$${GOAL_ENV.INPUTS_PATH}
|
|
1071
|
+
\`\`\`
|
|
1072
|
+
|
|
1073
|
+
输入的 \`inputs[]\` 里会有一个条目:
|
|
1074
|
+
|
|
1075
|
+
\`\`\`json
|
|
1076
|
+
{ "from": "human", "name": "answer", "path": "/absolute/path/to/answer.json", "kind": "json" }
|
|
1077
|
+
\`\`\`
|
|
1078
|
+
|
|
1079
|
+
读取它的 \`path\`:选择题看 \`selected\`,填空题看 \`text\`,然后继续完成原目标。
|
|
1080
|
+
`;
|
|
991
1081
|
const ORCHESTRATE_SKILL = `---
|
|
992
1082
|
name: botmux-orchestrate
|
|
993
1083
|
description: 作为「主 bot/编排者」把一个大项目拆成多个子项目,在普通群里自动开多话题、把不同 bot(常 coder+reviewer 一组)派进各话题并行干活,用飞书任务清单当共享进度板,收齐结果再汇总。触发:用户提到「多话题协作模式」,或要「把大项目拆给多个机器人并行做」「协调多个 bot」「多话题并行推进」「你当总控/编排」「一个写一个 review 多组并行」,或显式提到 botmux orchestrate / botmux dispatch 派活。
|
|
@@ -1060,6 +1150,118 @@ botmux dispatch --title "<子项目标题>" --bot "<coder_open_id>:名字:coder"
|
|
|
1060
1150
|
- 一条话题别塞太多 bot;coder+reviewer 两人一组最顺。
|
|
1061
1151
|
- 失败别硬重试同一招 ≥3 次;上报用户。
|
|
1062
1152
|
`;
|
|
1153
|
+
const WORKFLOW_V3_SKILL = `---
|
|
1154
|
+
name: botmux-workflow
|
|
1155
|
+
description: 把一个「模糊的、一次性的、需要拆成多步的目标」交给系统:先 grill 把需求问清楚 → 自动编排成 DAG 流程 → 跑完。触发场景:用户给一个复合/探索性任务且没指定具体步骤,如"帮我调研X出报告"、"把这事拆成几步自动跑完"、"做个 workflow 处理…"、"帮我把 A/B/C 串起来自动做";用户显式发 \`/workflow new <目标>\` 或裸 \`/workflow <目标>\` 也会路由到本 skill。区别:跑已存好的固定流程模板用 \`/template run <id>\`(不是本 skill);设计可复用模板用 botmux-workflow-create;本 skill 是一次性即兴 workflow。简单单步请求/普通问答/改代码不要触发;进入前先跟用户确认一句。
|
|
1156
|
+
---
|
|
1157
|
+
|
|
1158
|
+
# botmux-workflow — v3 即兴 workflow(grill → 编排 → 跑)
|
|
1159
|
+
|
|
1160
|
+
把用户一句模糊的复合目标,通过「拷问澄清 → 自动编排 DAG → 人确认 → 自动执行」一条龙做完。整个过程在当前飞书话题里**一问一答**进行(用 botmux send 跟用户对话)。
|
|
1161
|
+
|
|
1162
|
+
用户可以两种方式进入本流程:① 直接用大白话描述模糊复合目标(模型判断触发本 skill);② 显式发 \`/workflow new <目标>\` 或裸 \`/workflow <目标>\`(daemon 已把它转成触发本 skill 的 prompt,目标在消息里)。
|
|
1163
|
+
|
|
1164
|
+
## 何时用 / 不用
|
|
1165
|
+
- ✅ 用户有一个**一次性、需要拆成多步**的目标,但没给出具体步骤("调研三家竞品出对比报告"、"把日志拉下来分析再生成图表")。
|
|
1166
|
+
- ❌ 跑**已存好的固定模板** → 让用户用 \`/template run <id>\`。
|
|
1167
|
+
- ❌ **设计可复用模板** → botmux-workflow-create。
|
|
1168
|
+
- ❌ 单步请求 / 普通问答 / 改代码 → 别触发,正常回答。
|
|
1169
|
+
|
|
1170
|
+
## 0. 先确认(防误触发)
|
|
1171
|
+
真正进入 grill 前先发一句确认:
|
|
1172
|
+
|
|
1173
|
+
> 我理解你想让我做一整套 workflow:先问你几个问题把需求弄清楚,再自动编排成流程跑完。对吗?
|
|
1174
|
+
|
|
1175
|
+
用户确认了再往下。(用户已经很明确要做 workflow——比如通过 \`/workflow new\` 显式发起——时可省略此步,直接开始 grill。)
|
|
1176
|
+
|
|
1177
|
+
## 1. 建 run
|
|
1178
|
+
\`\`\`bash
|
|
1179
|
+
botmux workflow new "<把用户目标浓缩成一句话>"
|
|
1180
|
+
\`\`\`
|
|
1181
|
+
记下返回的 \`runId\`(和 \`specPath\`)——后面**每个**命令都要带这个 runId。
|
|
1182
|
+
|
|
1183
|
+
## 2. Grill:一次只问一个问题
|
|
1184
|
+
遵循 grill-me 方法:
|
|
1185
|
+
- **一次一个问题**,每个都给出你的**推荐默认答案**(不是开放式"你想怎样")。
|
|
1186
|
+
- 沿决策树走,先父决策再子决策。
|
|
1187
|
+
- 能从代码/文件查到的**别问,直接查**。
|
|
1188
|
+
- 目标:能为**每个**预想节点凑齐五件套 \`goal / input_needs / expected_outputs / acceptance / risk_gate\`,否则继续问。
|
|
1189
|
+
- **逃生阀**:用户随时可说"够了 / 用默认 / 别问了"——立即收尾,用推荐默认填满缺口,把没定的写进该节点 \`unknowns\`。
|
|
1190
|
+
- 别把用户问烦:五件套是上限不是下限,能合并的问题合并。
|
|
1191
|
+
|
|
1192
|
+
## 3. 写 spec.md
|
|
1193
|
+
往第 1 步返回的 \`specPath\` 写文件 = 人读叙事 + **唯一一个** fenced json 块(机器读的 canonical Spec)。
|
|
1194
|
+
|
|
1195
|
+
人读部分:\`## 需求\` / \`## 决策树\`(决策点+结论+拒绝的备选)/ \`## 验收标准\` / \`## 非目标\`。
|
|
1196
|
+
|
|
1197
|
+
机器读部分(**只放一个** json 代码块,schema 如下):
|
|
1198
|
+
\`\`\`json
|
|
1199
|
+
{
|
|
1200
|
+
"schemaVersion": 1,
|
|
1201
|
+
"runId": "<第1步的 runId>",
|
|
1202
|
+
"title": "<一句话标题>",
|
|
1203
|
+
"requirement": "<收敛后的清晰需求>",
|
|
1204
|
+
"acceptance": "<整体验收标准>",
|
|
1205
|
+
"nonGoals": ["<明确不做的>"],
|
|
1206
|
+
"nodes": [
|
|
1207
|
+
{
|
|
1208
|
+
"sketchId": "research",
|
|
1209
|
+
"goal": "调研 X/Y/Z 的定价与功能,写成 facts.md",
|
|
1210
|
+
"input_needs": [],
|
|
1211
|
+
"expected_outputs": ["facts.md"],
|
|
1212
|
+
"acceptance": "每家含定价档+功能矩阵",
|
|
1213
|
+
"risk_gate": false,
|
|
1214
|
+
"unknowns": []
|
|
1215
|
+
},
|
|
1216
|
+
{
|
|
1217
|
+
"sketchId": "report",
|
|
1218
|
+
"goal": "基于调研产物写竞品分析报告 report.md",
|
|
1219
|
+
"input_needs": ["research 阶段产出的竞品事实"],
|
|
1220
|
+
"expected_outputs": ["report.md"],
|
|
1221
|
+
"acceptance": "含结论与建议",
|
|
1222
|
+
"risk_gate": true,
|
|
1223
|
+
"unknowns": []
|
|
1224
|
+
}
|
|
1225
|
+
]
|
|
1226
|
+
}
|
|
1227
|
+
\`\`\`
|
|
1228
|
+
**字段铁律**:
|
|
1229
|
+
- \`input_needs\` 是**自由文本**描述"这步需要什么信息/产物",**绝不要写成上游 sketchId 列表**——画依赖边是 architect 的活,不是你的。
|
|
1230
|
+
- \`risk_gate: true\` = 这步执行期要人工审批(如对外发送)。
|
|
1231
|
+
- \`unknowns\` 放没跟用户定死、用了默认的点。
|
|
1232
|
+
|
|
1233
|
+
## 4. 校验 spec
|
|
1234
|
+
\`\`\`bash
|
|
1235
|
+
botmux workflow spec-finalize <runId>
|
|
1236
|
+
\`\`\`
|
|
1237
|
+
成功 → 下一步。失败(命令打印 problems)→ 按 problems 修 spec.md 的 json 块再跑。**校验不过不能往下走。**
|
|
1238
|
+
|
|
1239
|
+
## 5. Gate-1:确认需求
|
|
1240
|
+
给用户简明摘要(做哪几步、各自产出、验收、不做什么),问:
|
|
1241
|
+
|
|
1242
|
+
> 这是我理解的需求和拆解,对吗?确认我就编排成可执行流程。
|
|
1243
|
+
|
|
1244
|
+
用户确认 → \`botmux workflow approve-spec <runId>\`;要改 → 直接改 spec.md 再 \`botmux workflow spec-finalize <runId>\` 重新校验(spec_ready 状态可原地重定稿,不用退回)。
|
|
1245
|
+
|
|
1246
|
+
## 6. 编排 DAG
|
|
1247
|
+
\`\`\`bash
|
|
1248
|
+
botmux workflow architect <runId>
|
|
1249
|
+
\`\`\`
|
|
1250
|
+
系统自动把 spec 编译成 dag.json 并**由 host 校验**。成功 → 命令打印 \`dagPath\`/\`notesPath\`,进下一步。失败(退回 spec_approved + 打印 problems)→ 多半是 spec 还有问题:\`botmux workflow revise-spec <runId>\` 退回 grilling,按 problems 改 spec.md,再 spec-finalize → approve-spec → architect。(若判断只是 architect 偶发失败、spec 没问题,可直接重跑 architect。)
|
|
1251
|
+
|
|
1252
|
+
## 7. Gate-2:确认流程
|
|
1253
|
+
读 architect 产出的 dag.json + architect-notes.md(用第 6 步打印的路径),给用户讲清楚流程:有哪些节点、依赖顺序、哪些节点执行期会停下等人批。问:
|
|
1254
|
+
|
|
1255
|
+
> 编排好的流程是这样,对吗?确认就开跑。
|
|
1256
|
+
|
|
1257
|
+
用户确认 → \`botmux workflow approve-dag <runId>\`,然后 \`botmux workflow start <runId>\` 交 daemon 驱动开跑(**别用 \`botmux v3 run\`**——那是 dev 终端路径,没有飞书审批卡)。daemon 路径下,节点的 \`risk_gate\`(humanGate)执行期会在本话题**弹审批卡**,用户点「通过/拒绝」才继续;daemon 重启也能恢复待审批的卡。要改:需求要改 → \`botmux workflow revise-spec <runId>\`(退回 grilling,原 DAG 作废)重走 grill→spec→architect;需求没变、只是流程不满意 → \`botmux workflow revise-dag <runId>\`(退回 spec_approved)重跑 architect 重编。
|
|
1258
|
+
|
|
1259
|
+
## 关键纪律
|
|
1260
|
+
- 全程飞书一问一答,用 botmux send 对话。
|
|
1261
|
+
- \`runId\` 是贯穿全程的钥匙,每个命令都带对。
|
|
1262
|
+
- 三道确认别省:进入前确认 + Gate-1 需求 + Gate-2 流程。
|
|
1263
|
+
- 任何 \`botmux workflow\` 命令报错,把人话版原因告诉用户,别闷头重试。
|
|
1264
|
+
`;
|
|
1063
1265
|
export const WHITEBOARD_SKILL = `---
|
|
1064
1266
|
name: botmux-whiteboard
|
|
1065
1267
|
description: 使用 botmux 本地项目白板读写跨 agent 的项目摘要、关键决策、已验证命令、阻塞和交接信息。触发场景:用户说白板、上下文、项目记忆、让其他 agent 看本地总结、长任务断点、多 agent 协作、handoff、需要沉淀不适合发飞书的大段上下文时。
|
|
@@ -1193,6 +1395,8 @@ export const BUILTIN_SKILLS = [
|
|
|
1193
1395
|
{ name: 'botmux-bots', content: BOTS_SKILL },
|
|
1194
1396
|
{ name: 'botmux-handoff', content: HANDOFF_SKILL },
|
|
1195
1397
|
{ name: 'botmux-workflow-create', content: WORKFLOW_CREATE_SKILL },
|
|
1398
|
+
{ name: 'botmux-workflow', content: WORKFLOW_V3_SKILL },
|
|
1399
|
+
{ name: 'botmux-goal-ask', content: GOAL_ASK_SKILL },
|
|
1196
1400
|
{ name: 'botmux-orchestrate', content: ORCHESTRATE_SKILL },
|
|
1197
1401
|
];
|
|
1198
1402
|
/** Skills that earlier botmux versions installed but no longer ship. The
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/skills/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAS5F,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4FtB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DrB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CpB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkOlB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6ClB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCrB,CAAC;AAEF,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Y7B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiExB,CAAC;AAEF,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDpB,QAAQ,CAAC,WAAW,IAAI,aAAa;;;;;;GAMrC,QAAQ,CAAC,aAAa;;;;;;;;;;;;eAYV,oBAAoB;;;;;;;;;;;;GAYhC,QAAQ,CAAC,WAAW;;;;;;;;;;CAUtB,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEzB,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+GzB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoH/B,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAE3C;;;;;4DAK4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAEzD,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,EAAE;IACpD,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE;IAClD,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE;IAChD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE;IAC5C,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE;IAC5C,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE;IAClD,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,qBAAqB,EAAE;IAClE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,EAAE;IACvD,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,cAAc,EAAE;IACpD,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,iBAAiB,EAAE;CAC3D,CAAC;AAEF;;qCAEqC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAa;IAC3C,wBAAwB;IACxB,8EAA8E;IAC9E,wBAAwB;IACxB,mBAAmB;IACnB,qEAAqE;IACrE,yEAAyE;IACzE,gFAAgF;IAChF,sBAAsB;CACvB,CAAC"}
|
package/dist/worker.js
CHANGED
|
@@ -253,7 +253,16 @@ async function sendRawCommandLine(be, content) {
|
|
|
253
253
|
be.sendSpecialKeys('Enter');
|
|
254
254
|
}
|
|
255
255
|
else {
|
|
256
|
-
|
|
256
|
+
// PtyBackend has no sendText/sendSpecialKeys, so write the keystrokes
|
|
257
|
+
// directly — but still beat between the text and the Enter. Writing
|
|
258
|
+
// `content + '\r'` in one chunk submits before the CLI's slash-command
|
|
259
|
+
// parser has registered the `/cmd` match, so the command is left
|
|
260
|
+
// unsent in the input box (observed with `/goal <text>` on a pty
|
|
261
|
+
// workflow worker: typed but never executed). Mirror the tmux path's
|
|
262
|
+
// 200ms beat.
|
|
263
|
+
be.write(content);
|
|
264
|
+
await new Promise(r => setTimeout(r, 200));
|
|
265
|
+
be.write('\r');
|
|
257
266
|
}
|
|
258
267
|
}
|
|
259
268
|
/** Resolve once the PTY has been quiet for `quietMs`, or after `capMs` total.
|
|
@@ -4990,8 +4999,14 @@ function startWebServer(host, preferredPort) {
|
|
|
4990
4999
|
backend?.resize(msg.cols, msg.rows);
|
|
4991
5000
|
}
|
|
4992
5001
|
else if (msg.type === 'input' && typeof msg.data === 'string') {
|
|
4993
|
-
if (!authedClients.has(ws))
|
|
4994
|
-
|
|
5002
|
+
if (!authedClients.has(ws)) {
|
|
5003
|
+
// Read-only: allow ONLY wheel scroll sequences (SGR buttons 64-67).
|
|
5004
|
+
// Scrolling the CLI's own view is non-destructive and lets read-only
|
|
5005
|
+
// viewers page back through an alt-screen TUI's history (Claude etc.,
|
|
5006
|
+
// which has no local scrollback). Everything else is dropped.
|
|
5007
|
+
if (!/^(\x1b\[<6[4-7];\d+;\d+M)+$/.test(msg.data))
|
|
5008
|
+
return;
|
|
5009
|
+
}
|
|
4995
5010
|
backend?.write(msg.data);
|
|
4996
5011
|
}
|
|
4997
5012
|
}
|
|
@@ -5203,12 +5218,45 @@ window.addEventListener('resize',onViewportResize);
|
|
|
5203
5218
|
ws.onerror=function(){ws.close()};
|
|
5204
5219
|
})();
|
|
5205
5220
|
|
|
5206
|
-
// ──
|
|
5207
|
-
|
|
5208
|
-
|
|
5221
|
+
// ── Wheel / touch scroll handling ──
|
|
5222
|
+
// Alt-screen + mouse-mode CLIs (e.g. Claude Code) keep NO scrollback in xterm OR
|
|
5223
|
+
// tmux — their whole transcript is redrawn by the app inside the fixed alt-screen
|
|
5224
|
+
// grid, so term.scrollLines() reveals nothing. In the alternate buffer we forward
|
|
5225
|
+
// scrolling as SGR mouse-wheel events so the CLI scrolls its own transcript and
|
|
5226
|
+
// repaints (works in read-only too: the server only lets wheel sequences through).
|
|
5227
|
+
// Normal-buffer CLIs keep xterm's native scrollback scroll. Capture-phase +
|
|
5228
|
+
// stopPropagation pre-empts xterm's own handler. Skipped for pure tmux/zellij
|
|
5229
|
+
// ATTACH (gate), where the attach client owns scrolling via copy-mode.
|
|
5230
|
+
//
|
|
5231
|
+
// Accumulate intended scroll DISTANCE (px) and emit one wheel tick per STEP px —
|
|
5232
|
+
// decoupled from how many wheel/touch events the browser fires per gesture
|
|
5233
|
+
// (high-res trackpads fire dozens), so a small gesture stays a small scroll and
|
|
5234
|
+
// doesn't compound into a whole screen. px<0 = scroll up (toward history). The
|
|
5235
|
+
// per-call cap stops a single huge delta (page tick / fling) from over-firing.
|
|
5236
|
+
var _scrollAccum=0;var _SCROLL_STEP=33;
|
|
5237
|
+
function _fwdScroll(px){
|
|
5238
|
+
if(!ws_||ws_.readyState!==1)return;
|
|
5239
|
+
_scrollAccum+=px;var data='',n=0;
|
|
5240
|
+
while(Math.abs(_scrollAccum)>=_SCROLL_STEP&&n<6){
|
|
5241
|
+
var up=_scrollAccum<0; // px<0 → wheel-up (history)
|
|
5242
|
+
data+='\\x1b[<'+(up?64:65)+';1;1M';
|
|
5243
|
+
_scrollAccum+=up?_SCROLL_STEP:-_SCROLL_STEP;n++;
|
|
5244
|
+
}
|
|
5245
|
+
if(data)ws_.send(JSON.stringify({type:'input',data:data}));
|
|
5246
|
+
}
|
|
5247
|
+
if(!${isTmuxMode && !isPipeMode}){
|
|
5209
5248
|
document.getElementById('terminal').addEventListener('wheel',function(e){
|
|
5210
|
-
|
|
5211
|
-
|
|
5249
|
+
if(term.buffer.active.type!=='alternate'){
|
|
5250
|
+
// Normal buffer: xterm scrolls its own scrollback natively. In read-only a
|
|
5251
|
+
// mouse-mode CLI could swallow the wheel, so drive scrollback directly.
|
|
5252
|
+
if(!hasToken){e.preventDefault();e.stopPropagation();term.scrollLines(e.deltaY>0?3:-3);}
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5255
|
+
e.preventDefault();e.stopPropagation();
|
|
5256
|
+
// Normalise deltaMode to px: line→~16px, page→~one screen.
|
|
5257
|
+
var px=e.deltaMode===1?e.deltaY*16:e.deltaMode===2?e.deltaY*term.rows*16:e.deltaY;
|
|
5258
|
+
_fwdScroll(px);
|
|
5259
|
+
},{capture:true,passive:false});
|
|
5212
5260
|
}
|
|
5213
5261
|
|
|
5214
5262
|
// ── Touch shortcut toolbar ──
|
|
@@ -5238,11 +5286,29 @@ if(isTouch&&hasToken){
|
|
|
5238
5286
|
}
|
|
5239
5287
|
}
|
|
5240
5288
|
|
|
5241
|
-
// Single-finger touch scrolling
|
|
5242
|
-
// (handleTouchMove → scrollTop)
|
|
5243
|
-
//
|
|
5244
|
-
//
|
|
5245
|
-
//
|
|
5289
|
+
// Single-finger touch scrolling: normal-buffer CLIs use xterm's own Viewport
|
|
5290
|
+
// (handleTouchMove → scrollTop) natively. Alt-screen CLIs (Claude) have no xterm
|
|
5291
|
+
// scrollback, so native touch scroll does nothing — mirror the wheel fix and
|
|
5292
|
+
// forward the drag to the CLI as SGR wheel events so it scrolls its own
|
|
5293
|
+
// transcript. Only the alternate buffer is intercepted (capture + stopPropagation);
|
|
5294
|
+
// the normal buffer falls through to xterm untouched, so no double-drive of
|
|
5295
|
+
// scrollTop. overscroll-behavior:none (see <style>) kills the iOS rubber-band.
|
|
5296
|
+
if(!${isTmuxMode && !isPipeMode}){
|
|
5297
|
+
var _tTerm=document.getElementById('terminal');
|
|
5298
|
+
var _tLastY=null;
|
|
5299
|
+
_tTerm.addEventListener('touchstart',function(e){
|
|
5300
|
+
if(e.touches.length===1)_tLastY=e.touches[0].clientY;
|
|
5301
|
+
},{capture:true,passive:true});
|
|
5302
|
+
_tTerm.addEventListener('touchmove',function(e){
|
|
5303
|
+
// Normal buffer / multi-touch / no start → let xterm (or the browser) handle it.
|
|
5304
|
+
if(term.buffer.active.type!=='alternate'||_tLastY===null||e.touches.length!==1)return;
|
|
5305
|
+
e.preventDefault();e.stopPropagation();
|
|
5306
|
+
var y=e.touches[0].clientY;
|
|
5307
|
+
_fwdScroll(_tLastY-y); // finger drags down (y grows) → px<0 → scroll up (history)
|
|
5308
|
+
_tLastY=y;
|
|
5309
|
+
},{capture:true,passive:false});
|
|
5310
|
+
_tTerm.addEventListener('touchend',function(){_tLastY=null;},{capture:true,passive:true});
|
|
5311
|
+
}
|
|
5246
5312
|
</script>
|
|
5247
5313
|
</body>
|
|
5248
5314
|
</html>`;
|