@mulmobridge/protocol 0.1.3 → 1.0.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 +42 -1
- package/dist/attachment.d.ts +11 -4
- package/dist/attachment.js +16 -0
- package/dist/events.d.ts +2 -1
- package/dist/events.js +10 -1
- package/dist/index.d.ts +1 -1
- package/dist/socket.d.ts +27 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ npm install @mulmobridge/protocol
|
|
|
18
18
|
| `CHAT_SOCKET_PATH` | Socket.io endpoint path (`"/ws/chat"`) |
|
|
19
19
|
| `ChatSocketEvent` | Union type of socket event names |
|
|
20
20
|
| `CHAT_SERVICE_ROUTES` | REST endpoint patterns for the bridge API |
|
|
21
|
-
| `Attachment` | File attachment interface
|
|
21
|
+
| `Attachment` | File attachment interface — either inline base64 `data` or workspace `path`, with optional `mimeType`/`filename` |
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
@@ -58,6 +58,47 @@ const attachment: Attachment = {
|
|
|
58
58
|
| [@mulmobridge/cli](https://www.npmjs.com/package/@mulmobridge/cli) | CLI bridge |
|
|
59
59
|
| [@mulmobridge/telegram](https://www.npmjs.com/package/@mulmobridge/telegram) | Telegram bridge |
|
|
60
60
|
|
|
61
|
+
## Ecosystem
|
|
62
|
+
|
|
63
|
+
Part of the [`@mulmobridge/*`](https://www.npmjs.com/~mulmobridge) package family.
|
|
64
|
+
|
|
65
|
+
**Shared libraries:**
|
|
66
|
+
|
|
67
|
+
- [`@mulmobridge/client`](https://www.npmjs.com/package/@mulmobridge/client) — socket.io client library used by every bridge below
|
|
68
|
+
- [`@mulmobridge/protocol`](https://www.npmjs.com/package/@mulmobridge/protocol) — wire types and constants ← **this package**
|
|
69
|
+
- [`@mulmobridge/chat-service`](https://www.npmjs.com/package/@mulmobridge/chat-service) — server-side relay + session store
|
|
70
|
+
- [`@mulmobridge/relay`](https://www.npmjs.com/package/@mulmobridge/relay) — Cloudflare Workers webhook proxy
|
|
71
|
+
- [`@mulmobridge/mock-server`](https://www.npmjs.com/package/@mulmobridge/mock-server) — mock server for local bridge development
|
|
72
|
+
|
|
73
|
+
**Bridges** (one npm package per platform):
|
|
74
|
+
|
|
75
|
+
- [`@mulmobridge/bluesky`](https://www.npmjs.com/package/@mulmobridge/bluesky) — Bluesky DMs over atproto
|
|
76
|
+
- [`@mulmobridge/chatwork`](https://www.npmjs.com/package/@mulmobridge/chatwork) — Chatwork (Japanese business chat)
|
|
77
|
+
- [`@mulmobridge/cli`](https://www.npmjs.com/package/@mulmobridge/cli) — interactive terminal bridge
|
|
78
|
+
- [`@mulmobridge/discord`](https://www.npmjs.com/package/@mulmobridge/discord) — Discord bot via Gateway
|
|
79
|
+
- [`@mulmobridge/email`](https://www.npmjs.com/package/@mulmobridge/email) — IMAP poll + SMTP reply, threading preserved
|
|
80
|
+
- [`@mulmobridge/google-chat`](https://www.npmjs.com/package/@mulmobridge/google-chat) — Google Chat via MulmoBridge relay
|
|
81
|
+
- [`@mulmobridge/irc`](https://www.npmjs.com/package/@mulmobridge/irc) — IRC (Libera, Freenode, custom)
|
|
82
|
+
- [`@mulmobridge/line`](https://www.npmjs.com/package/@mulmobridge/line) — LINE Messaging API via MulmoBridge relay
|
|
83
|
+
- [`@mulmobridge/line-works`](https://www.npmjs.com/package/@mulmobridge/line-works) — LINE Works (enterprise LINE)
|
|
84
|
+
- [`@mulmobridge/mastodon`](https://www.npmjs.com/package/@mulmobridge/mastodon) — Mastodon DMs + mentions
|
|
85
|
+
- [`@mulmobridge/matrix`](https://www.npmjs.com/package/@mulmobridge/matrix) — Matrix / Element
|
|
86
|
+
- [`@mulmobridge/mattermost`](https://www.npmjs.com/package/@mulmobridge/mattermost) — Mattermost
|
|
87
|
+
- [`@mulmobridge/messenger`](https://www.npmjs.com/package/@mulmobridge/messenger) — Facebook Messenger via MulmoBridge relay
|
|
88
|
+
- [`@mulmobridge/nostr`](https://www.npmjs.com/package/@mulmobridge/nostr) — Nostr NIP-04 encrypted DMs
|
|
89
|
+
- [`@mulmobridge/rocketchat`](https://www.npmjs.com/package/@mulmobridge/rocketchat) — Rocket.Chat
|
|
90
|
+
- [`@mulmobridge/signal`](https://www.npmjs.com/package/@mulmobridge/signal) — Signal via signal-cli-rest-api
|
|
91
|
+
- [`@mulmobridge/slack`](https://www.npmjs.com/package/@mulmobridge/slack) — Slack Socket Mode
|
|
92
|
+
- [`@mulmobridge/teams`](https://www.npmjs.com/package/@mulmobridge/teams) — Microsoft Teams via Bot Framework
|
|
93
|
+
- [`@mulmobridge/telegram`](https://www.npmjs.com/package/@mulmobridge/telegram) — Telegram bot
|
|
94
|
+
- [`@mulmobridge/twilio-sms`](https://www.npmjs.com/package/@mulmobridge/twilio-sms) — SMS via Twilio Programmable Messaging
|
|
95
|
+
- [`@mulmobridge/viber`](https://www.npmjs.com/package/@mulmobridge/viber) — Viber Public Account bots
|
|
96
|
+
- [`@mulmobridge/webhook`](https://www.npmjs.com/package/@mulmobridge/webhook) — generic HTTP webhook bridge
|
|
97
|
+
- [`@mulmobridge/whatsapp`](https://www.npmjs.com/package/@mulmobridge/whatsapp) — WhatsApp Cloud API via MulmoBridge relay
|
|
98
|
+
- [`@mulmobridge/xmpp`](https://www.npmjs.com/package/@mulmobridge/xmpp) — XMPP / Jabber
|
|
99
|
+
- [`@mulmobridge/zulip`](https://www.npmjs.com/package/@mulmobridge/zulip) — Zulip
|
|
100
|
+
|
|
101
|
+
|
|
61
102
|
## License
|
|
62
103
|
|
|
63
104
|
MIT — [Receptron Team](https://github.com/receptron)
|
package/dist/attachment.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
export interface Attachment {
|
|
2
|
-
/** IANA media type, e.g. "image/png".
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
data
|
|
2
|
+
/** IANA media type, e.g. "image/png". Optional when only `path` is
|
|
3
|
+
* set — the server infers the type from the path extension. */
|
|
4
|
+
mimeType?: string;
|
|
5
|
+
/** Raw base64-encoded payload (no `data:` prefix, no whitespace).
|
|
6
|
+
* Required when `path` is not set. */
|
|
7
|
+
data?: string;
|
|
8
|
+
/** Workspace-relative path to a file the server can read. Required
|
|
9
|
+
* when `data` is not set. Must live under one of the allowed roots
|
|
10
|
+
* (e.g. `artifacts/images/...`, `data/attachments/...`); the
|
|
11
|
+
* server enforces this with `safeResolve`. */
|
|
12
|
+
path?: string;
|
|
6
13
|
/** Optional original filename. Untrusted — sanitise before use on disk. */
|
|
7
14
|
filename?: string;
|
|
8
15
|
}
|
package/dist/attachment.js
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
// File attachment schema for chat messages (images, documents, etc.).
|
|
2
|
+
//
|
|
3
|
+
// One of `data` (inline base64 bytes) or `path` (workspace-relative
|
|
4
|
+
// path) MUST be set. The two carriers exist because:
|
|
5
|
+
//
|
|
6
|
+
// - Bridge clients (Telegram, LINE, Mastodon, ...) ship raw bytes
|
|
7
|
+
// over the wire, so they populate `data`.
|
|
8
|
+
// - The Vue UI uploads paste/drop and sidebar-pick images to disk
|
|
9
|
+
// before send (so the data layer is path-first), so it populates
|
|
10
|
+
// `path`. The server reads bytes from disk on receipt.
|
|
11
|
+
//
|
|
12
|
+
// Server-internal normalisation (e.g. `prepareRequestExtras` in the
|
|
13
|
+
// agent route) loads bytes for path-only entries before downstream
|
|
14
|
+
// consumers see the array, so anything reading `data` after that
|
|
15
|
+
// boundary can rely on it being present. Outside that boundary
|
|
16
|
+
// (i.e. when first received), readers MUST runtime-check which
|
|
17
|
+
// carrier is set and handle the path case explicitly.
|
|
2
18
|
export {};
|
package/dist/events.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export declare const EVENT_TYPES: {
|
|
2
2
|
readonly status: "status";
|
|
3
3
|
readonly text: "text";
|
|
4
|
+
readonly skill: "skill";
|
|
4
5
|
readonly toolCall: "tool_call";
|
|
5
6
|
readonly toolCallResult: "tool_call_result";
|
|
6
7
|
readonly toolResult: "tool_result";
|
|
7
|
-
readonly switchRole: "switch_role";
|
|
8
8
|
readonly error: "error";
|
|
9
9
|
readonly claudeSessionId: "claude_session_id";
|
|
10
10
|
readonly sessionFinished: "session_finished";
|
|
@@ -27,6 +27,7 @@ export declare const GENERATION_KINDS: {
|
|
|
27
27
|
readonly characterImage: "characterImage";
|
|
28
28
|
readonly beatAudio: "beatAudio";
|
|
29
29
|
readonly movie: "movie";
|
|
30
|
+
readonly pdf: "pdf";
|
|
30
31
|
};
|
|
31
32
|
export type GenerationKind = (typeof GENERATION_KINDS)[keyof typeof GENERATION_KINDS];
|
|
32
33
|
export interface GenerationEvent {
|
package/dist/events.js
CHANGED
|
@@ -6,10 +6,18 @@
|
|
|
6
6
|
export const EVENT_TYPES = {
|
|
7
7
|
status: "status",
|
|
8
8
|
text: "text",
|
|
9
|
+
// #1218 — assistant text whose content is the body of an invoked
|
|
10
|
+
// SKILL.md, synthesised by Claude CLI when the model calls the
|
|
11
|
+
// `Skill` tool. Tagged separately from `text` so the canvas can
|
|
12
|
+
// collapse it (skill bodies are huge and not actual prose).
|
|
13
|
+
// Detected server-side via the preceding tool_call's
|
|
14
|
+
// toolName === "Skill" (structural — survives Claude CLI body-text
|
|
15
|
+
// changes), then enriched with `skillName` / `skillScope` /
|
|
16
|
+
// `skillPath` resolved against `discoverSkills()`.
|
|
17
|
+
skill: "skill",
|
|
9
18
|
toolCall: "tool_call",
|
|
10
19
|
toolCallResult: "tool_call_result",
|
|
11
20
|
toolResult: "tool_result",
|
|
12
|
-
switchRole: "switch_role",
|
|
13
21
|
error: "error",
|
|
14
22
|
claudeSessionId: "claude_session_id",
|
|
15
23
|
sessionFinished: "session_finished",
|
|
@@ -31,6 +39,7 @@ export const GENERATION_KINDS = {
|
|
|
31
39
|
characterImage: "characterImage",
|
|
32
40
|
beatAudio: "beatAudio",
|
|
33
41
|
movie: "movie",
|
|
42
|
+
pdf: "pdf",
|
|
34
43
|
};
|
|
35
44
|
/**
|
|
36
45
|
* Stable map-key for a generation: the triple (kind, filePath, key).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { EVENT_TYPES, type EventType, GENERATION_KINDS, type GenerationKind, type GenerationEvent, type PendingGeneration, generationKey } from "./events.js";
|
|
2
|
-
export { CHAT_SOCKET_PATH, CHAT_SOCKET_EVENTS, type ChatSocketEvent } from "./socket.js";
|
|
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";
|
package/dist/socket.d.ts
CHANGED
|
@@ -9,3 +9,30 @@ export declare const CHAT_SOCKET_EVENTS: {
|
|
|
9
9
|
readonly textChunk: "textChunk";
|
|
10
10
|
};
|
|
11
11
|
export type ChatSocketEvent = (typeof CHAT_SOCKET_EVENTS)[keyof typeof CHAT_SOCKET_EVENTS];
|
|
12
|
+
/**
|
|
13
|
+
* Bridge → host-app option bag carried on the handshake.
|
|
14
|
+
*
|
|
15
|
+
* Values are restricted to flat primitives (string / number /
|
|
16
|
+
* boolean). The restriction serves two purposes:
|
|
17
|
+
*
|
|
18
|
+
* 1. The wire contract is explicit — no surprise nested objects
|
|
19
|
+
* slip through to the host app's callback where a downstream
|
|
20
|
+
* merge might reintroduce prototype-pollution risk.
|
|
21
|
+
* 2. The scrape-from-env path produces strings anyway, so the
|
|
22
|
+
* ceiling is already flat primitives in practice.
|
|
23
|
+
*
|
|
24
|
+
* Protocol does not interpret any keys — bridges and host apps agree
|
|
25
|
+
* on names (`defaultRole`, …) out of band.
|
|
26
|
+
*/
|
|
27
|
+
export type BridgeOptions = Readonly<Record<string, string | number | boolean>>;
|
|
28
|
+
/**
|
|
29
|
+
* Shape of `socket.handshake.auth` on the bridge chat socket. The
|
|
30
|
+
* server validates `transportId` + `token`; `options` is the opaque-
|
|
31
|
+
* but-primitive bag forwarded to the host application's startChat
|
|
32
|
+
* callback. See `plans/done/feat-bridge-options-passthrough.md`.
|
|
33
|
+
*/
|
|
34
|
+
export interface BridgeHandshakeAuth {
|
|
35
|
+
transportId: string;
|
|
36
|
+
token?: string;
|
|
37
|
+
options?: BridgeOptions;
|
|
38
|
+
}
|