@mulmobridge/protocol 1.0.0 → 1.1.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.md CHANGED
@@ -98,6 +98,13 @@ Part of the [`@mulmobridge/*`](https://www.npmjs.com/~mulmobridge) package famil
98
98
  - [`@mulmobridge/xmpp`](https://www.npmjs.com/package/@mulmobridge/xmpp) — XMPP / Jabber
99
99
  - [`@mulmobridge/zulip`](https://www.npmjs.com/package/@mulmobridge/zulip) — Zulip
100
100
 
101
+ ## Related projects
102
+
103
+ Published from the MulmoClaude monorepo by [Receptron](https://github.com/receptron).
104
+
105
+ - **[MulmoClaude](https://github.com/receptron/mulmoclaude)** — an open-source AI assistant platform that runs on your own computer. Claude Code as the engine, a personal wiki for long-term memory, schema-driven collections for your data, and chat that summons the right GUI (markdown, charts, forms, spreadsheets, wikis) for each task.
106
+ - **[MulmoTerminal](https://github.com/receptron/mulmoterminal)** — a terminal-first cockpit for running many AI coding agents in parallel. One roster showing every session's summary and PR status, tmux-backed session persistence, git-worktree isolation, one-click PRs, and mobile push with remote reply.
107
+ - **[MulmoTerminal manual](https://receptron.github.io/mulmoterminal/)** — setup, workflows, feature reference, configuration, mobile notifications, and alternative / local model providers. Available in English and Japanese.
101
108
 
102
109
  ## License
103
110
 
package/dist/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export { EVENT_TYPES, type EventType, GENERATION_KINDS, type GenerationKind, typ
2
2
  export { CHAT_SOCKET_PATH, CHAT_SOCKET_EVENTS, type ChatSocketEvent, type BridgeHandshakeAuth, type BridgeOptions } from "./socket.js";
3
3
  export { type Attachment } from "./attachment.js";
4
4
  export { CHAT_SERVICE_ROUTES } from "./routes.js";
5
+ export { DEFAULT_REPLY_TIMEOUT_MS, ACK_TIMEOUT_MARGIN_MS, MAX_REPLY_TIMEOUT_MS, type ReplyTimeoutResolution, resolveReplyTimeoutMs, ackTimeoutMsFor, } from "./replyTimeout.js";
package/dist/index.js CHANGED
@@ -5,7 +5,8 @@
5
5
  // - The chat-service (server-side socket.io + REST)
6
6
  // - External bridges (CLI, Telegram, future platforms)
7
7
  //
8
- // No runtime dependencies. Types + const-only.
8
+ // No runtime dependencies. Types, constants, and small pure helpers.
9
9
  export { EVENT_TYPES, GENERATION_KINDS, generationKey } from "./events.js";
10
10
  export { CHAT_SOCKET_PATH, CHAT_SOCKET_EVENTS } from "./socket.js";
11
11
  export { CHAT_SERVICE_ROUTES } from "./routes.js";
12
+ export { DEFAULT_REPLY_TIMEOUT_MS, ACK_TIMEOUT_MARGIN_MS, MAX_REPLY_TIMEOUT_MS, resolveReplyTimeoutMs, ackTimeoutMsFor, } from "./replyTimeout.js";
@@ -0,0 +1,19 @@
1
+ export declare const DEFAULT_REPLY_TIMEOUT_MS: number;
2
+ /** How much longer the bridge waits for the ack than the server waits for the reply. */
3
+ export declare const ACK_TIMEOUT_MARGIN_MS: number;
4
+ export declare const MAX_REPLY_TIMEOUT_MS: number;
5
+ export interface ReplyTimeoutResolution {
6
+ replyTimeoutMs: number;
7
+ /** Set when the configured value was unusable and something else was used. */
8
+ warning?: string;
9
+ }
10
+ /**
11
+ * Turn `bridgeOptions.replyTimeoutMs` into the limit to use.
12
+ *
13
+ * Absent or empty means the default with no warning. Anything that is not a
14
+ * positive whole number of milliseconds falls back to the default, and a value
15
+ * past the timer ceiling is clamped — both with a warning naming the value.
16
+ */
17
+ export declare function resolveReplyTimeoutMs(raw: unknown): ReplyTimeoutResolution;
18
+ /** The bridge client's ack limit for a given reply limit. */
19
+ export declare function ackTimeoutMsFor(replyTimeoutMs: number): number;
@@ -0,0 +1,58 @@
1
+ // How long a relayed turn may take, shared by both ends of the wire.
2
+ //
3
+ // The chat-service stops collecting the agent's reply after the reply
4
+ // timeout; the bridge client stops waiting for the ack a margin later. The
5
+ // margin is the whole contract: if the client gave up first, the server's
6
+ // partial reply would arrive at a socket that had already reported a timeout.
7
+ // Both ends read the SAME `bridgeOptions.replyTimeoutMs`, so the order holds
8
+ // whatever the user sets.
9
+ const ONE_MINUTE_MS = 60 * 1000;
10
+ export const DEFAULT_REPLY_TIMEOUT_MS = 5 * ONE_MINUTE_MS;
11
+ /** How much longer the bridge waits for the ack than the server waits for the reply. */
12
+ export const ACK_TIMEOUT_MARGIN_MS = ONE_MINUTE_MS;
13
+ // Node fires a timer longer than 2^31-1 ms after 1 ms instead, which would turn
14
+ // "wait longer" into "give up at once". The client adds the margin, so the
15
+ // reply limit stops short of the ceiling by exactly that much.
16
+ const SET_TIMEOUT_CEILING_MS = 2 ** 31 - 1;
17
+ export const MAX_REPLY_TIMEOUT_MS = SET_TIMEOUT_CEILING_MS - ACK_TIMEOUT_MARGIN_MS;
18
+ const POSITIVE_INTEGER = /^[1-9]\d*$/;
19
+ function parseConfigured(raw) {
20
+ // Not `isSafeInteger`: a huge integer is still a request for "as long as possible", and the caller clamps it.
21
+ if (typeof raw === "number")
22
+ return Number.isInteger(raw) && raw > 0 ? raw : null;
23
+ return POSITIVE_INTEGER.test(raw) ? Number(raw) : null;
24
+ }
25
+ /** For the warning only. `JSON.stringify` throws on a bigint or a circular object. */
26
+ function describeRaw(raw) {
27
+ if (typeof raw === "string")
28
+ return JSON.stringify(raw);
29
+ if (typeof raw === "number" || typeof raw === "boolean" || typeof raw === "bigint")
30
+ return String(raw);
31
+ return `<${Array.isArray(raw) ? "array" : typeof raw}>`;
32
+ }
33
+ /**
34
+ * Turn `bridgeOptions.replyTimeoutMs` into the limit to use.
35
+ *
36
+ * Absent or empty means the default with no warning. Anything that is not a
37
+ * positive whole number of milliseconds falls back to the default, and a value
38
+ * past the timer ceiling is clamped — both with a warning naming the value.
39
+ */
40
+ export function resolveReplyTimeoutMs(raw) {
41
+ if (raw === undefined || raw === null || raw === "")
42
+ return { replyTimeoutMs: DEFAULT_REPLY_TIMEOUT_MS };
43
+ const configured = typeof raw === "string" || typeof raw === "number" ? parseConfigured(raw) : null;
44
+ if (configured === null) {
45
+ return {
46
+ replyTimeoutMs: DEFAULT_REPLY_TIMEOUT_MS,
47
+ warning: `replyTimeoutMs=${describeRaw(raw)} is not a positive whole number of milliseconds; using ${DEFAULT_REPLY_TIMEOUT_MS}`,
48
+ };
49
+ }
50
+ if (configured > MAX_REPLY_TIMEOUT_MS) {
51
+ return { replyTimeoutMs: MAX_REPLY_TIMEOUT_MS, warning: `replyTimeoutMs=${configured} exceeds the maximum; using ${MAX_REPLY_TIMEOUT_MS}` };
52
+ }
53
+ return { replyTimeoutMs: configured };
54
+ }
55
+ /** The bridge client's ack limit for a given reply limit. */
56
+ export function ackTimeoutMsFor(replyTimeoutMs) {
57
+ return replyTimeoutMs + ACK_TIMEOUT_MARGIN_MS;
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulmobridge/protocol",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Shared types and constants for the MulmoBridge protocol",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "scripts": {
21
21
  "build": "tsc",
22
22
  "prepack": "yarn build",
23
- "typecheck": "tsc --noEmit",
23
+ "typecheck": "tsc -p tsconfig.typecheck.json",
24
24
  "test": "tsx --test test/test_*.ts",
25
25
  "lint": "eslint src test"
26
26
  },
@@ -28,5 +28,22 @@
28
28
  "author": "Receptron Team",
29
29
  "devDependencies": {
30
30
  "typescript": "^6.0.3"
31
+ },
32
+ "homepage": "https://github.com/receptron/mulmoclaude/tree/main/packages/protocol#readme",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/receptron/mulmoclaude.git",
36
+ "directory": "packages/protocol"
37
+ },
38
+ "keywords": [
39
+ "mulmobridge",
40
+ "protocol",
41
+ "socket.io",
42
+ "chat",
43
+ "ai-agent",
44
+ "types"
45
+ ],
46
+ "bugs": {
47
+ "url": "https://github.com/receptron/mulmoclaude/issues"
31
48
  }
32
49
  }