botmux 2.95.0 → 2.96.1

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.
Files changed (175) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +3 -3
  3. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/tmux-backend.js +6 -10
  5. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  6. package/dist/adapters/cli/kimi.d.ts +4 -0
  7. package/dist/adapters/cli/kimi.d.ts.map +1 -0
  8. package/dist/adapters/cli/kimi.js +54 -0
  9. package/dist/adapters/cli/kimi.js.map +1 -0
  10. package/dist/adapters/cli/registry.d.ts +2 -1
  11. package/dist/adapters/cli/registry.d.ts.map +1 -1
  12. package/dist/adapters/cli/registry.js +6 -20
  13. package/dist/adapters/cli/registry.js.map +1 -1
  14. package/dist/adapters/cli/types.d.ts +1 -1
  15. package/dist/adapters/cli/types.d.ts.map +1 -1
  16. package/dist/adapters/hook-installer.d.ts.map +1 -1
  17. package/dist/adapters/hook-installer.js +138 -28
  18. package/dist/adapters/hook-installer.js.map +1 -1
  19. package/dist/bot-registry.d.ts +61 -4
  20. package/dist/bot-registry.d.ts.map +1 -1
  21. package/dist/bot-registry.js +164 -3
  22. package/dist/bot-registry.js.map +1 -1
  23. package/dist/cli/stdin-encoding.d.ts +21 -0
  24. package/dist/cli/stdin-encoding.d.ts.map +1 -1
  25. package/dist/cli/stdin-encoding.js +37 -0
  26. package/dist/cli/stdin-encoding.js.map +1 -1
  27. package/dist/cli.d.ts.map +1 -1
  28. package/dist/cli.js +14 -4
  29. package/dist/cli.js.map +1 -1
  30. package/dist/config.d.ts +18 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +27 -0
  33. package/dist/config.js.map +1 -1
  34. package/dist/core/ask-hook/opencode.d.ts +15 -17
  35. package/dist/core/ask-hook/opencode.d.ts.map +1 -1
  36. package/dist/core/ask-hook/opencode.js +17 -19
  37. package/dist/core/ask-hook/opencode.js.map +1 -1
  38. package/dist/core/command-handler.d.ts.map +1 -1
  39. package/dist/core/command-handler.js +1 -0
  40. package/dist/core/command-handler.js.map +1 -1
  41. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  42. package/dist/core/dashboard-ipc-server.js +193 -5
  43. package/dist/core/dashboard-ipc-server.js.map +1 -1
  44. package/dist/core/dashboard-rows.d.ts +2 -0
  45. package/dist/core/dashboard-rows.d.ts.map +1 -1
  46. package/dist/core/dashboard-rows.js +2 -0
  47. package/dist/core/dashboard-rows.js.map +1 -1
  48. package/dist/core/trigger-session.d.ts.map +1 -1
  49. package/dist/core/trigger-session.js +99 -7
  50. package/dist/core/trigger-session.js.map +1 -1
  51. package/dist/core/types.d.ts +16 -0
  52. package/dist/core/types.d.ts.map +1 -1
  53. package/dist/core/types.js.map +1 -1
  54. package/dist/core/worker-pool.d.ts +1 -1
  55. package/dist/core/worker-pool.d.ts.map +1 -1
  56. package/dist/core/worker-pool.js +68 -11
  57. package/dist/core/worker-pool.js.map +1 -1
  58. package/dist/dashboard/bot-payload.d.ts +7 -0
  59. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  60. package/dist/dashboard/bot-payload.js +7 -1
  61. package/dist/dashboard/bot-payload.js.map +1 -1
  62. package/dist/dashboard/session-cleanup.d.ts +1 -0
  63. package/dist/dashboard/session-cleanup.d.ts.map +1 -1
  64. package/dist/dashboard/session-cleanup.js +2 -0
  65. package/dist/dashboard/session-cleanup.js.map +1 -1
  66. package/dist/dashboard/settings-write-applier.d.ts +2 -1
  67. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  68. package/dist/dashboard/settings-write-applier.js +6 -0
  69. package/dist/dashboard/settings-write-applier.js.map +1 -1
  70. package/dist/dashboard/trigger-api.d.ts +4 -0
  71. package/dist/dashboard/trigger-api.d.ts.map +1 -1
  72. package/dist/dashboard/trigger-api.js +20 -0
  73. package/dist/dashboard/trigger-api.js.map +1 -1
  74. package/dist/dashboard/web/bot-defaults.d.ts +1 -0
  75. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  76. package/dist/dashboard/web/bot-defaults.js +247 -4
  77. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  78. package/dist/dashboard/web/connectors.d.ts +11 -0
  79. package/dist/dashboard/web/connectors.d.ts.map +1 -1
  80. package/dist/dashboard/web/connectors.js +45 -1
  81. package/dist/dashboard/web/connectors.js.map +1 -1
  82. package/dist/dashboard/web/groups.d.ts +7 -0
  83. package/dist/dashboard/web/groups.d.ts.map +1 -1
  84. package/dist/dashboard/web/groups.js +62 -15
  85. package/dist/dashboard/web/groups.js.map +1 -1
  86. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  87. package/dist/dashboard/web/i18n.js +58 -2
  88. package/dist/dashboard/web/i18n.js.map +1 -1
  89. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  90. package/dist/dashboard/web/sessions.js +149 -5
  91. package/dist/dashboard/web/sessions.js.map +1 -1
  92. package/dist/dashboard/web/settings.d.ts.map +1 -1
  93. package/dist/dashboard/web/settings.js +10 -0
  94. package/dist/dashboard/web/settings.js.map +1 -1
  95. package/dist/dashboard/webhook-routes.d.ts.map +1 -1
  96. package/dist/dashboard/webhook-routes.js +126 -6
  97. package/dist/dashboard/webhook-routes.js.map +1 -1
  98. package/dist/dashboard-web/app.js +827 -751
  99. package/dist/dashboard-web/style.css +47 -0
  100. package/dist/dashboard.js +85 -6
  101. package/dist/dashboard.js.map +1 -1
  102. package/dist/global-config.d.ts +4 -0
  103. package/dist/global-config.d.ts.map +1 -1
  104. package/dist/global-config.js +2 -0
  105. package/dist/global-config.js.map +1 -1
  106. package/dist/i18n/en.d.ts.map +1 -1
  107. package/dist/i18n/en.js +1 -0
  108. package/dist/i18n/en.js.map +1 -1
  109. package/dist/i18n/zh.d.ts.map +1 -1
  110. package/dist/i18n/zh.js +1 -0
  111. package/dist/i18n/zh.js.map +1 -1
  112. package/dist/im/lark/card-builder.d.ts.map +1 -1
  113. package/dist/im/lark/card-builder.js +1 -0
  114. package/dist/im/lark/card-builder.js.map +1 -1
  115. package/dist/im/lark/client.d.ts +12 -0
  116. package/dist/im/lark/client.d.ts.map +1 -1
  117. package/dist/im/lark/client.js +154 -9
  118. package/dist/im/lark/client.js.map +1 -1
  119. package/dist/im/lark/event-dispatcher.d.ts +13 -0
  120. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  121. package/dist/im/lark/event-dispatcher.js +200 -16
  122. package/dist/im/lark/event-dispatcher.js.map +1 -1
  123. package/dist/im/lark/message-parser.d.ts +11 -0
  124. package/dist/im/lark/message-parser.d.ts.map +1 -1
  125. package/dist/im/lark/message-parser.js +2 -1
  126. package/dist/im/lark/message-parser.js.map +1 -1
  127. package/dist/im/lark/summary-command.d.ts +19 -0
  128. package/dist/im/lark/summary-command.d.ts.map +1 -0
  129. package/dist/im/lark/summary-command.js +276 -0
  130. package/dist/im/lark/summary-command.js.map +1 -0
  131. package/dist/mir-local-runtime.d.ts +40 -0
  132. package/dist/mir-local-runtime.d.ts.map +1 -1
  133. package/dist/mir-local-runtime.js +246 -52
  134. package/dist/mir-local-runtime.js.map +1 -1
  135. package/dist/mir-runner.js +26 -1
  136. package/dist/mir-runner.js.map +1 -1
  137. package/dist/services/card-prefs-store.d.ts +2 -2
  138. package/dist/services/card-prefs-store.d.ts.map +1 -1
  139. package/dist/services/card-prefs-store.js +5 -5
  140. package/dist/services/card-prefs-store.js.map +1 -1
  141. package/dist/services/chat-reply-mode-store.d.ts +6 -4
  142. package/dist/services/chat-reply-mode-store.d.ts.map +1 -1
  143. package/dist/services/chat-reply-mode-store.js +6 -4
  144. package/dist/services/chat-reply-mode-store.js.map +1 -1
  145. package/dist/services/pi-transcript.d.ts +19 -0
  146. package/dist/services/pi-transcript.d.ts.map +1 -0
  147. package/dist/services/pi-transcript.js +222 -0
  148. package/dist/services/pi-transcript.js.map +1 -0
  149. package/dist/services/seen-message-store.d.ts +12 -0
  150. package/dist/services/seen-message-store.d.ts.map +1 -0
  151. package/dist/services/seen-message-store.js +119 -0
  152. package/dist/services/seen-message-store.js.map +1 -0
  153. package/dist/services/summary-range-store.d.ts +21 -0
  154. package/dist/services/summary-range-store.d.ts.map +1 -0
  155. package/dist/services/summary-range-store.js +89 -0
  156. package/dist/services/summary-range-store.js.map +1 -0
  157. package/dist/services/trigger-types.d.ts +14 -2
  158. package/dist/services/trigger-types.d.ts.map +1 -1
  159. package/dist/services/trigger-types.js +15 -1
  160. package/dist/services/trigger-types.js.map +1 -1
  161. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  162. package/dist/setup/bot-config-editor.js +2 -0
  163. package/dist/setup/bot-config-editor.js.map +1 -1
  164. package/dist/types.d.ts +20 -1
  165. package/dist/types.d.ts.map +1 -1
  166. package/dist/utils/executable.d.ts +3 -0
  167. package/dist/utils/executable.d.ts.map +1 -0
  168. package/dist/utils/executable.js +24 -0
  169. package/dist/utils/executable.js.map +1 -0
  170. package/dist/worker.js +75 -6
  171. package/dist/worker.js.map +1 -1
  172. package/dist/workflows/definition.d.ts +8 -8
  173. package/dist/workflows/events/payloads.d.ts +10 -10
  174. package/dist/workflows/events/schema.d.ts +28 -28
  175. package/package.json +1 -1
@@ -919,6 +919,22 @@ button.primary {
919
919
  border: 1px solid var(--border-soft);
920
920
  }
921
921
 
922
+ .session-lock-badge {
923
+ display: inline-flex;
924
+ align-items: center;
925
+ min-height: 22px;
926
+ margin-left: 6px;
927
+ padding: 0 8px;
928
+ border-radius: var(--radius-sm);
929
+ border: 1px solid color-mix(in srgb, var(--warning) 38%, var(--border-soft));
930
+ background: color-mix(in srgb, var(--warning) 10%, var(--surface-muted));
931
+ color: var(--warning);
932
+ font-size: 11px;
933
+ font-weight: 800;
934
+ line-height: 1;
935
+ text-transform: uppercase;
936
+ }
937
+
922
938
  .cli-claude-code { background: #e8f0ff; color: #234fb4; border-color: #c8d9ff; }
923
939
  .cli-codex { background: #fff0df; color: #a14c11; border-color: #ffd8ad; }
924
940
  .cli-codex-app { background: #e9f7ff; color: #11638f; border-color: #bde4fa; }
@@ -1140,6 +1156,10 @@ button.primary {
1140
1156
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-raised));
1141
1157
  }
1142
1158
 
1159
+ .session-card.locked {
1160
+ border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
1161
+ }
1162
+
1143
1163
  @media (prefers-reduced-motion: reduce) {
1144
1164
  .session-card { animation: none; transition: none; }
1145
1165
  .session-board-needs-you h2::before { animation: none; }
@@ -1197,6 +1217,19 @@ button.primary {
1197
1217
  font-size: 12px;
1198
1218
  }
1199
1219
 
1220
+ .session-card-status-group,
1221
+ .drawer-status-line {
1222
+ display: inline-flex;
1223
+ align-items: center;
1224
+ gap: 6px;
1225
+ flex-wrap: wrap;
1226
+ }
1227
+
1228
+ .session-card-status-group .session-lock-badge,
1229
+ .drawer-status-line .session-lock-badge {
1230
+ margin-left: 0;
1231
+ }
1232
+
1200
1233
  .session-signal {
1201
1234
  display: inline-flex;
1202
1235
  align-items: center;
@@ -1487,6 +1520,10 @@ button.primary {
1487
1520
  background: color-mix(in srgb, var(--accent) 4%, var(--surface-raised));
1488
1521
  }
1489
1522
 
1523
+ .kanban-card.locked {
1524
+ border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
1525
+ }
1526
+
1490
1527
  .kanban-card:focus-visible {
1491
1528
  outline: 2px solid var(--accent);
1492
1529
  outline-offset: 1px;
@@ -1873,6 +1910,11 @@ button.primary {
1873
1910
  border-color: var(--danger);
1874
1911
  background: color-mix(in srgb, var(--danger) 9%, var(--surface-raised));
1875
1912
  }
1913
+ .card-act.locked {
1914
+ color: var(--warning);
1915
+ border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
1916
+ background: color-mix(in srgb, var(--warning) 8%, var(--surface-raised));
1917
+ }
1876
1918
  .card-act:active { transform: scale(0.9); }
1877
1919
 
1878
1920
  /* 终端访问药丸:左「终端」段(accent ghost·只读旁观) + 右「钥匙」段(accent 实心·
@@ -4216,6 +4258,11 @@ button.contrast:hover { background: var(--danger-soft); border-color: var(--dang
4216
4258
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 55%, transparent);
4217
4259
  flex: none;
4218
4260
  }
4261
+ .bd-summary-limits {
4262
+ display: grid;
4263
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4264
+ gap: 10px;
4265
+ }
4219
4266
 
4220
4267
  .settings-grid {
4221
4268
  display: grid;
package/dist/dashboard.js CHANGED
@@ -174,6 +174,7 @@ function resolveDashboardSettings() {
174
174
  return {
175
175
  publicReadOnly: dashboard.publicReadOnly ?? config.dashboard.publicReadOnly,
176
176
  openTerminalInFeishu: dashboard.openTerminalInFeishu === true,
177
+ chatBotDiscovery: dashboard.chatBotDiscovery !== false, // default ON
177
178
  repoPickerMode: global.repoPickerMode ?? 'all',
178
179
  maintenance: global.maintenance ?? {},
179
180
  localDevInstall: isLocalDevInstall(),
@@ -475,8 +476,27 @@ function configuredCliIds() {
475
476
  return new Map();
476
477
  }
477
478
  }
479
+ function configuredBotAgentFields() {
480
+ try {
481
+ return new Map(loadBotConfigs().map(b => [b.larkAppId, {
482
+ cliId: b.cliId,
483
+ wrapperCli: b.wrapperCli,
484
+ model: b.model,
485
+ }]));
486
+ }
487
+ catch {
488
+ return new Map();
489
+ }
490
+ }
478
491
  function withConfiguredCliId(bot, ids) {
479
- return bot.cliId ? bot : { ...bot, cliId: ids.get(bot.larkAppId) };
492
+ const raw = ids.get(bot.larkAppId);
493
+ const fallback = typeof raw === 'string' ? { cliId: raw } : raw;
494
+ return {
495
+ ...bot,
496
+ cliId: bot.cliId || fallback?.cliId,
497
+ wrapperCli: bot.wrapperCli || fallback?.wrapperCli,
498
+ model: bot.model || fallback?.model,
499
+ };
480
500
  }
481
501
  function liveBots() {
482
502
  const ids = configuredCliIds();
@@ -1526,9 +1546,9 @@ const server = createServer(async (req, res) => {
1526
1546
  return jsonRes(res, 400, { ok: false, error: 'bad_request' });
1527
1547
  return jsonRes(res, 200, { ok: true, entry });
1528
1548
  }
1529
- // 看板放置 / 重命名:带 JSON body 的会话写操作,原样转发给 owner daemon。
1549
+ // 看板放置 / 重命名 / 锁定:带 JSON body 的会话写操作,原样转发给 owner daemon。
1530
1550
  // 不在公开读白名单内 → 只读访客在 decideDashboardAuth 已被 401。
1531
- if (req.method === 'POST' && (m = url.pathname.match(/^\/api\/sessions\/([^/]+)\/(board|rename)$/))) {
1551
+ if (req.method === 'POST' && (m = url.pathname.match(/^\/api\/sessions\/([^/]+)\/(board|rename|lock)$/))) {
1532
1552
  const sid = decodeURIComponent(m[1]);
1533
1553
  const op = m[2];
1534
1554
  const owner = aggregator.ownerOf(sid);
@@ -1894,8 +1914,8 @@ const server = createServer(async (req, res) => {
1894
1914
  // [{larkAppId, botName, defaultOncall, ...}]
1895
1915
  // PUT /api/bots/:appId/default-oncall — proxy to that bot's daemon
1896
1916
  if (req.method === 'GET' && url.pathname === '/api/bots') {
1897
- const cliIds = configuredCliIds();
1898
- const onlineBots = [...registry.list()].map(b => withConfiguredCliId(b, cliIds)).sort((a, b) => a.botIndex - b.botIndex);
1917
+ const agentFields = configuredBotAgentFields();
1918
+ const onlineBots = [...registry.list()].map(b => withConfiguredCliId(b, agentFields)).sort((a, b) => a.botIndex - b.botIndex);
1899
1919
  const out = await Promise.all(onlineBots.map(async (d) => {
1900
1920
  try {
1901
1921
  const r = await fetch(`http://127.0.0.1:${d.ipcPort}/api/bot-default-oncall`);
@@ -1903,7 +1923,13 @@ const server = createServer(async (req, res) => {
1903
1923
  return botDefaultsPayload(d, undefined, `http_${r.status}`);
1904
1924
  }
1905
1925
  const j = await r.json();
1906
- return botDefaultsPayload({ ...d, botName: d.botName ?? j.botName }, j);
1926
+ return botDefaultsPayload({
1927
+ ...d,
1928
+ botName: d.botName ?? j.botName,
1929
+ cliId: j.cliId || d.cliId,
1930
+ wrapperCli: j.wrapperCli || d.wrapperCli,
1931
+ model: j.model || d.model,
1932
+ }, j);
1907
1933
  }
1908
1934
  catch (e) {
1909
1935
  return botDefaultsPayload(d, undefined, e?.message ?? String(e));
@@ -1946,6 +1972,24 @@ const server = createServer(async (req, res) => {
1946
1972
  res.end(await upstream.text());
1947
1973
  return;
1948
1974
  }
1975
+ // PUT /api/bots/:appId/agent — proxy to that bot's daemon. Body
1976
+ // `{ cliId, model }`; cliId is the dashboard selection key.
1977
+ let mBotAgent;
1978
+ if (req.method === 'PUT' && (mBotAgent = url.pathname.match(/^\/api\/bots\/([^/]+)\/agent$/))) {
1979
+ const appId = decodeURIComponent(mBotAgent[1]);
1980
+ const chunks = [];
1981
+ for await (const c of req)
1982
+ chunks.push(c);
1983
+ const raw = Buffer.concat(chunks).toString('utf8') || '{}';
1984
+ const upstream = await proxyToDaemon(appId, `/api/bot-agent`, {
1985
+ method: 'PUT',
1986
+ headers: { 'content-type': 'application/json' },
1987
+ body: raw,
1988
+ });
1989
+ res.writeHead(upstream.status, { 'content-type': 'application/json' });
1990
+ res.end(await upstream.text());
1991
+ return;
1992
+ }
1949
1993
  // PUT /api/bots/:appId/skills — proxy to that bot's daemon. Body accepts
1950
1994
  // `{ action:'attach'|'detach', name }` or `{ action:'set', policy|null }`.
1951
1995
  let mBotSkills;
@@ -2071,6 +2115,41 @@ const server = createServer(async (req, res) => {
2071
2115
  res.end(await upstream.text());
2072
2116
  return;
2073
2117
  }
2118
+ // PUT /api/bots/:appId/summary-range — proxy to that bot's daemon. Body
2119
+ // `{ limit, sinceHours }`; daemon updates the explicit /summary range.
2120
+ let mBotSummaryRange;
2121
+ if (req.method === 'PUT' && (mBotSummaryRange = url.pathname.match(/^\/api\/bots\/([^/]+)\/summary-range$/))) {
2122
+ const appId = decodeURIComponent(mBotSummaryRange[1]);
2123
+ const chunks = [];
2124
+ for await (const c of req)
2125
+ chunks.push(c);
2126
+ const raw = Buffer.concat(chunks).toString('utf8') || '{}';
2127
+ const upstream = await proxyToDaemon(appId, `/api/bot-summary-range`, {
2128
+ method: 'PUT',
2129
+ headers: { 'content-type': 'application/json' },
2130
+ body: raw,
2131
+ });
2132
+ res.writeHead(upstream.status, { 'content-type': 'application/json' });
2133
+ res.end(await upstream.text());
2134
+ return;
2135
+ }
2136
+ // Backward-compatible alias from the short-lived keyword-trigger dashboard.
2137
+ let mBotSummaryTrigger;
2138
+ if (req.method === 'PUT' && (mBotSummaryTrigger = url.pathname.match(/^\/api\/bots\/([^/]+)\/summary-trigger$/))) {
2139
+ const appId = decodeURIComponent(mBotSummaryTrigger[1]);
2140
+ const chunks = [];
2141
+ for await (const c of req)
2142
+ chunks.push(c);
2143
+ const raw = Buffer.concat(chunks).toString('utf8') || '{}';
2144
+ const upstream = await proxyToDaemon(appId, `/api/bot-summary-trigger`, {
2145
+ method: 'PUT',
2146
+ headers: { 'content-type': 'application/json' },
2147
+ body: raw,
2148
+ });
2149
+ res.writeHead(upstream.status, { 'content-type': 'application/json' });
2150
+ res.end(await upstream.text());
2151
+ return;
2152
+ }
2074
2153
  // PUT /api/bots/:appId/p2p-mode — proxy to that bot's daemon. Body
2075
2154
  // `{ p2pMode: 'chat' | 'thread' }` ('chat' = flat continuous DM session;
2076
2155
  // anything else clears back to the per-message thread default).