botmux 2.91.1 → 2.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/bot-registry.d.ts +1 -1
  4. package/dist/bot-registry.d.ts.map +1 -1
  5. package/dist/bot-registry.js +14 -11
  6. package/dist/bot-registry.js.map +1 -1
  7. package/dist/cli/dashboard-endpoint.d.ts +9 -6
  8. package/dist/cli/dashboard-endpoint.d.ts.map +1 -1
  9. package/dist/cli/dashboard-endpoint.js.map +1 -1
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +11 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/core/session-manager.js +2 -2
  14. package/dist/core/session-manager.js.map +1 -1
  15. package/dist/daemon.d.ts +5 -1
  16. package/dist/daemon.d.ts.map +1 -1
  17. package/dist/daemon.js +24 -6
  18. package/dist/daemon.js.map +1 -1
  19. package/dist/dashboard/bot-payload.js +1 -1
  20. package/dist/dashboard/bot-payload.js.map +1 -1
  21. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  22. package/dist/dashboard/web/bot-defaults.js +3 -2
  23. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  24. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  25. package/dist/dashboard/web/i18n.js +6 -4
  26. package/dist/dashboard/web/i18n.js.map +1 -1
  27. package/dist/dashboard-web/app.js +6 -5
  28. package/dist/dashboard.js +82 -23
  29. package/dist/dashboard.js.map +1 -1
  30. package/dist/i18n/en.js +9 -9
  31. package/dist/i18n/en.js.map +1 -1
  32. package/dist/i18n/zh.js +9 -9
  33. package/dist/i18n/zh.js.map +1 -1
  34. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  35. package/dist/im/lark/event-dispatcher.js +12 -7
  36. package/dist/im/lark/event-dispatcher.js.map +1 -1
  37. package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
  38. package/dist/im/lark/relay-target-routing.js +7 -2
  39. package/dist/im/lark/relay-target-routing.js.map +1 -1
  40. package/dist/im/lark/reply-mode-command.d.ts.map +1 -1
  41. package/dist/im/lark/reply-mode-command.js +3 -1
  42. package/dist/im/lark/reply-mode-command.js.map +1 -1
  43. package/dist/platform/tunnel-client.d.ts +10 -0
  44. package/dist/platform/tunnel-client.d.ts.map +1 -1
  45. package/dist/platform/tunnel-client.js +2 -0
  46. package/dist/platform/tunnel-client.js.map +1 -1
  47. package/dist/services/card-prefs-store.d.ts +1 -1
  48. package/dist/services/card-prefs-store.d.ts.map +1 -1
  49. package/dist/services/card-prefs-store.js +5 -5
  50. package/dist/services/card-prefs-store.js.map +1 -1
  51. package/dist/services/chat-reply-mode-store.d.ts +1 -1
  52. package/dist/services/chat-reply-mode-store.d.ts.map +1 -1
  53. package/dist/services/chat-reply-mode-store.js +17 -3
  54. package/dist/services/chat-reply-mode-store.js.map +1 -1
  55. package/dist/skills/definitions.js +1 -1
  56. package/dist/utils/listen-with-probe.d.ts +20 -1
  57. package/dist/utils/listen-with-probe.d.ts.map +1 -1
  58. package/dist/utils/listen-with-probe.js +48 -6
  59. package/dist/utils/listen-with-probe.js.map +1 -1
  60. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chat-reply-mode-store.js","sourceRoot":"","sources":["../../src/services/chat-reply-mode-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-reply-mode-store.js","sourceRoot":"","sources":["../../src/services/chat-reply-mode-store.ts"],"names":[],"mappings":"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"}
@@ -1039,7 +1039,7 @@ botmux dispatch --title "<子项目标题>" --bot "<coder_open_id>:名字:coder"
1039
1039
  - coder 写完先 @ reviewer 在本话题 review,过了再标完成。
1040
1040
 
1041
1041
  > repo 预设:\`--repo\` 让子 bot 起会话直接进该目录、免手点「选仓库」卡。注意**跨 owner 的 repo 预设可能受授权限制**——若子 bot 已配 defaultWorkingDir,可省略 \`--repo\`。
1042
- > **OnCall 群可省 \`--repo\`**:群若开了 OnCall 并绑了工作目录(\`/oncall <仓库路径>\` dashboard),所有 dispatch 都不用再传 \`--repo\`——子 bot spawn 时按群查 OnCall 绑定(写在共享 bots.json,跨 bot/跨 daemon 都读得到)自动继承该目录,子话题同理。只有当某子项目要用**和群目录不同的仓库**时才单独传 \`--repo\` 覆盖。
1042
+ > **OnCall \`--repo\` 现按 bot 计**:OnCall 绑定是 per-bot 的——只有**目标子 bot 自己**在该群绑了 OnCall(\`@该bot /oncall bind <仓库路径>\`,多个 bot 一起绑用 \`@bot1 @bot2 /oncall bind <路径>\`)或配了 \`defaultWorkingDir\` 时,dispatch 才可省 \`--repo\`。否则子 bot **不会**跨 bot 继承群目录(除非同话题已有 sibling 在跑可继承),dispatch 仍应显式传 \`--repo\`,不然子 bot 会弹「选仓库」卡。
1043
1043
  > 想「先把 bot 拉起待命、稍后再派具体任务」:用 \`--standby\`(只定目录不派简报),之后用 \`botmux dispatch --into <话题root> --bot ... --brief ...\` 激活。
1044
1044
 
1045
1045
  ### 6. 收结果 + 推进
@@ -1,13 +1,32 @@
1
1
  import type { Server } from 'node:http';
2
+ /**
3
+ * Default upward-probe span on EADDRINUSE when a caller doesn't pass `maxProbe`.
4
+ * The dashboard binds wildcard at config.dashboard.port and can walk this many
5
+ * ports up, so config.dashboard.ipcBasePort is kept clear of
6
+ * [port, port + DEFAULT_PROBE_SPAN] to stop the dashboard from ever landing on a
7
+ * loopback-shadowed IPC port (see config.ts + test/dashboard-ipc-port-range.test.ts).
8
+ */
9
+ export declare const DEFAULT_PROBE_SPAN = 20;
2
10
  export interface ListenWithProbeOpts {
3
11
  server: Server;
4
12
  /** Preferred port to try first. */
5
13
  port: number;
6
14
  host: string;
7
- /** Max upward probes on EADDRINUSE before rejecting (default 20). */
15
+ /** Max upward probes on EADDRINUSE before rejecting (default DEFAULT_PROBE_SPAN). */
8
16
  maxProbe?: number;
9
17
  /** Optional caller-specific availability gate before attempting a bind. */
10
18
  portAvailable?: (port: number) => boolean | Promise<boolean>;
19
+ /**
20
+ * Optional post-bind verification, run AFTER a successful listen with the
21
+ * actually-bound port. Return false to REJECT the port: the server is closed
22
+ * and the probe steps to port+1. This exists to catch a wildcard (0.0.0.0)
23
+ * bind that succeeds at the OS level yet is shadowed on loopback — on macOS
24
+ * another process holding 127.0.0.1:port coexists with the wildcard bind and
25
+ * wins loopback routing, so clients dialing 127.0.0.1:port reach the shadow,
26
+ * not us. A loopback self-check (does 127.0.0.1:port answer as ME?) detects
27
+ * that and re-probes, independent of which port number collided.
28
+ */
29
+ verifyBound?: (port: number) => boolean | Promise<boolean>;
11
30
  log?: (msg: string) => void;
12
31
  }
13
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"listen-with-probe.d.ts","sourceRoot":"","sources":["../../src/utils/listen-with-probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgF1E"}
1
+ {"version":3,"file":"listen-with-probe.d.ts","sourceRoot":"","sources":["../../src/utils/listen-with-probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwG1E"}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Default upward-probe span on EADDRINUSE when a caller doesn't pass `maxProbe`.
3
+ * The dashboard binds wildcard at config.dashboard.port and can walk this many
4
+ * ports up, so config.dashboard.ipcBasePort is kept clear of
5
+ * [port, port + DEFAULT_PROBE_SPAN] to stop the dashboard from ever landing on a
6
+ * loopback-shadowed IPC port (see config.ts + test/dashboard-ipc-port-range.test.ts).
7
+ */
8
+ export const DEFAULT_PROBE_SPAN = 20;
1
9
  /**
2
10
  * Bind `server` to `port`, walking port+1, port+2 … up to `maxProbe` times when
3
11
  * the port is already in use, and resolve with the actually-bound port.
@@ -14,8 +22,9 @@
14
22
  */
15
23
  export function listenWithProbe(opts) {
16
24
  const { server, host } = opts;
17
- const maxProbe = opts.maxProbe ?? 20;
25
+ const maxProbe = opts.maxProbe ?? DEFAULT_PROBE_SPAN;
18
26
  const portAvailable = opts.portAvailable;
27
+ const verifyBound = opts.verifyBound;
19
28
  const log = opts.log ?? (() => { });
20
29
  return new Promise((resolve, reject) => {
21
30
  let port = opts.port;
@@ -30,18 +39,51 @@ export function listenWithProbe(opts) {
30
39
  server.removeListener('listening', onListening);
31
40
  server.removeListener('error', onError);
32
41
  };
33
- const onListening = () => {
34
- if (settled)
35
- return;
42
+ const finalize = (bound) => {
36
43
  settled = true;
37
44
  cleanup();
38
- const addr = server.address();
39
- const bound = typeof addr === 'object' && addr ? addr.port : port;
40
45
  // Keep a permanent handler so a post-bind runtime error can't become an
41
46
  // unhandled 'error' event (which would crash the process).
42
47
  server.on('error', (e) => log(`server error: ${e.message}`));
43
48
  resolve(bound);
44
49
  };
50
+ // Release the just-bound port and step upward. Used when verifyBound rejects
51
+ // a port that listen() accepted (loopback shadow). The same http.Server can
52
+ // re-listen after close(); since a shadowed loopback request reached the
53
+ // OTHER process, our server has no in-flight verify connection to drain here.
54
+ const releaseAndStep = (bound, reason) => {
55
+ server.close(() => {
56
+ if (settled)
57
+ return;
58
+ port = bound;
59
+ if (!tryNext(reason))
60
+ rejectUnavailable();
61
+ });
62
+ };
63
+ const onListening = () => {
64
+ if (settled)
65
+ return;
66
+ const addr = server.address();
67
+ const bound = typeof addr === 'object' && addr ? addr.port : port;
68
+ if (!verifyBound) {
69
+ finalize(bound);
70
+ return;
71
+ }
72
+ Promise.resolve(verifyBound(bound)).then((ok) => {
73
+ if (settled)
74
+ return;
75
+ if (ok) {
76
+ finalize(bound);
77
+ return;
78
+ }
79
+ releaseAndStep(bound, 'shadowed');
80
+ }).catch(() => {
81
+ if (settled)
82
+ return;
83
+ // Couldn't confirm we own the port — treat conservatively as unusable.
84
+ releaseAndStep(bound, 'verify-failed');
85
+ });
86
+ };
45
87
  const rejectUnavailable = () => {
46
88
  const err = new Error(`No usable port found starting at ${opts.port}`);
47
89
  err.code = 'EADDRINUSE';
@@ -1 +1 @@
1
- {"version":3,"file":"listen-with-probe.js","sourceRoot":"","sources":["../../src/utils/listen-with-probe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"listen-with-probe.js","sourceRoot":"","sources":["../../src/utils/listen-with-probe.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botmux",
3
- "version": "2.91.1",
3
+ "version": "2.93.0",
4
4
  "description": "Bridge between IM platforms and AI coding CLIs — one topic, one CLI session with live streaming",
5
5
  "type": "module",
6
6
  "main": "dist/index-daemon.js",