@openclaw/signal 0.0.0 → 2026.6.11-beta.2

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 (49) hide show
  1. package/README.md +12 -2
  2. package/dist/accounts-hOCHbEhX.js +40 -0
  3. package/dist/api.js +16 -0
  4. package/dist/approval-handler.runtime-CeJI1wow.js +158 -0
  5. package/dist/approval-resolver-BR0MioAA.js +15 -0
  6. package/dist/channel-LmY2UpOt.js +619 -0
  7. package/dist/channel-config-api.js +2 -0
  8. package/dist/channel-entry.js +18 -0
  9. package/dist/channel-plugin-api.js +2 -0
  10. package/dist/channel.runtime-B0-YpkC4.js +65 -0
  11. package/dist/config-api-KS-qhQvD.js +2 -0
  12. package/dist/config-schema-BiojLEsX.js +27 -0
  13. package/dist/contract-api.js +3 -0
  14. package/dist/identity-B6O4k8xg.js +130 -0
  15. package/dist/index.js +18 -0
  16. package/dist/install-signal-cli-CXgTF3de.js +243 -0
  17. package/dist/message-actions-Bue0g2Kc.js +548 -0
  18. package/dist/monitor-CUhIKHJo.js +1404 -0
  19. package/dist/probe-BQ_Izoya.js +48 -0
  20. package/dist/reaction-runtime-api-C_PQ45D9.js +1074 -0
  21. package/dist/reaction-runtime-api.js +2 -0
  22. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  23. package/dist/runtime-api.js +18 -0
  24. package/dist/secret-contract-api.js +5 -0
  25. package/dist/send-CBlFUkY_.js +599 -0
  26. package/dist/send.runtime-CfaZd8X4.js +2 -0
  27. package/dist/setup-entry.js +11 -0
  28. package/node_modules/ws/LICENSE +20 -0
  29. package/node_modules/ws/README.md +548 -0
  30. package/node_modules/ws/browser.js +8 -0
  31. package/node_modules/ws/index.js +22 -0
  32. package/node_modules/ws/lib/buffer-util.js +131 -0
  33. package/node_modules/ws/lib/constants.js +19 -0
  34. package/node_modules/ws/lib/event-target.js +292 -0
  35. package/node_modules/ws/lib/extension.js +203 -0
  36. package/node_modules/ws/lib/limiter.js +55 -0
  37. package/node_modules/ws/lib/permessage-deflate.js +528 -0
  38. package/node_modules/ws/lib/receiver.js +760 -0
  39. package/node_modules/ws/lib/sender.js +607 -0
  40. package/node_modules/ws/lib/stream.js +161 -0
  41. package/node_modules/ws/lib/subprotocol.js +62 -0
  42. package/node_modules/ws/lib/validation.js +152 -0
  43. package/node_modules/ws/lib/websocket-server.js +562 -0
  44. package/node_modules/ws/lib/websocket.js +1407 -0
  45. package/node_modules/ws/package.json +70 -0
  46. package/node_modules/ws/wrapper.mjs +21 -0
  47. package/npm-shrinkwrap.json +36 -0
  48. package/openclaw.plugin.json +771 -0
  49. package/package.json +77 -7
package/README.md CHANGED
@@ -1,3 +1,13 @@
1
- # @openclaw/signal
1
+ # Signal OpenClaw channel
2
2
 
3
- Bootstrap reservation for the OpenClaw Signal channel package.
3
+ Official OpenClaw channel plugin for Signal.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ openclaw plugins install @openclaw/signal
9
+ ```
10
+
11
+ ## Docs
12
+
13
+ See `docs/channels/signal.md` in the OpenClaw repository, or the published docs at `https://docs.openclaw.ai/channels/signal`.
@@ -0,0 +1,40 @@
1
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ import { createAccountListHelpers, normalizeAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
3
+ //#region extensions/signal/src/accounts.ts
4
+ const { listAccountIds, resolveDefaultAccountId } = createAccountListHelpers("signal", { implicitDefaultAccount: { channelKeys: ["account"] } });
5
+ const listSignalAccountIds = listAccountIds;
6
+ const resolveDefaultSignalAccountId = resolveDefaultAccountId;
7
+ function mergeSignalAccountConfig(cfg, accountId) {
8
+ return resolveMergedAccountConfig({
9
+ channelConfig: cfg.channels?.signal,
10
+ accounts: cfg.channels?.signal?.accounts,
11
+ accountId
12
+ });
13
+ }
14
+ function resolveSignalAccount(params) {
15
+ const accountId = normalizeAccountId(params.accountId ?? resolveDefaultSignalAccountId(params.cfg));
16
+ const baseEnabled = params.cfg.channels?.signal?.enabled !== false;
17
+ const merged = mergeSignalAccountConfig(params.cfg, accountId);
18
+ const accountEnabled = merged.enabled !== false;
19
+ const enabled = baseEnabled && accountEnabled;
20
+ const host = normalizeOptionalString(merged.httpHost) ?? "127.0.0.1";
21
+ const port = merged.httpPort ?? 8080;
22
+ const baseUrl = normalizeOptionalString(merged.httpUrl) ?? `http://${host}:${port}`;
23
+ const configured = Boolean(normalizeOptionalString(merged.account) || normalizeOptionalString(merged.configPath) || normalizeOptionalString(merged.httpUrl) || normalizeOptionalString(merged.cliPath) || normalizeOptionalString(merged.httpHost) || typeof merged.httpPort === "number" || typeof merged.autoStart === "boolean");
24
+ return {
25
+ accountId,
26
+ enabled,
27
+ name: normalizeOptionalString(merged.name),
28
+ baseUrl,
29
+ configured,
30
+ config: merged
31
+ };
32
+ }
33
+ function listEnabledSignalAccounts(cfg) {
34
+ return listSignalAccountIds(cfg).map((accountId) => resolveSignalAccount({
35
+ cfg,
36
+ accountId
37
+ })).filter((account) => account.enabled);
38
+ }
39
+ //#endregion
40
+ export { resolveSignalAccount as i, listSignalAccountIds as n, resolveDefaultSignalAccountId as r, listEnabledSignalAccounts as t };
package/dist/api.js ADDED
@@ -0,0 +1,16 @@
1
+ import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-hOCHbEhX.js";
2
+ import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
3
+ import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, r as markdownToSignalText, t as signalMessageActions } from "./message-actions-Bue0g2Kc.js";
4
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-C_PQ45D9.js";
5
+ import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-LmY2UpOt.js";
6
+ import { a as looksLikeArchive, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli } from "./install-signal-cli-CXgTF3de.js";
7
+ import { t as monitorSignalProvider } from "./monitor-CUhIKHJo.js";
8
+ import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-CBlFUkY_.js";
9
+ import { t as probeSignal } from "./probe-BQ_Izoya.js";
10
+ //#region extensions/signal/src/channel.setup.ts
11
+ const signalSetupPlugin = { ...createSignalPluginBase({
12
+ setupWizard: signalSetupWizard,
13
+ setup: signalSetupAdapter
14
+ }) };
15
+ //#endregion
16
+ export { extractSignalCliArchive, formatSignalPairingIdLine, formatSignalSenderDisplay, formatSignalSenderId, installSignalCli, isSignalSenderAllowed, listEnabledSignalAccounts, listSignalAccountIds, looksLikeArchive, looksLikeSignalTargetId, looksLikeUuid, markdownToSignalText, markdownToSignalTextChunks, monitorSignalProvider, normalizeSignalAccountInput, normalizeSignalAllowRecipient, normalizeSignalMessagingTarget, pickAsset, probeSignal, removeReactionSignal, resolveDefaultSignalAccountId, resolveSignalAccount, resolveSignalOutboundTarget, resolveSignalPeerId, resolveSignalReactionLevel, resolveSignalRecipient, resolveSignalSender, sendMessageSignal, sendReactionSignal, sendReadReceiptSignal, sendTypingSignal, signalMessageActions, signalPlugin, signalSetupPlugin };
@@ -0,0 +1,158 @@
1
+ import { d as normalizeSignalMessagingTarget } from "./identity-B6O4k8xg.js";
2
+ import { c as resolveSignalApprovalTargetAuthorKeys, i as hasSignalApprovalReactionApprovers, l as unregisterSignalApprovalReactionTarget, o as registerSignalApprovalReactionTarget, r as sendTypingSignal, s as resolveSignalApprovalConversationKey, t as sendMessageSignal } from "./send-CBlFUkY_.js";
3
+ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
4
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
+ import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
6
+ import { buildApprovalReactionPendingContent } from "openclaw/plugin-sdk/approval-reaction-runtime";
7
+ import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
8
+ import { buildChannelApprovalExpiredText, buildChannelApprovalResolvedText, createChannelApprovalNativeRuntimeAdapter, resolvePreparedApprovalAccountId } from "openclaw/plugin-sdk/approval-handler-runtime";
9
+ //#region extensions/signal/src/approval-handler.runtime.ts
10
+ const log = createSubsystemLogger("signal/approvals");
11
+ function readSignalApprovalRuntimeContext(context) {
12
+ const value = context;
13
+ return {
14
+ baseUrl: typeof value?.baseUrl === "string" && value.baseUrl.trim() ? value.baseUrl.trim() : void 0,
15
+ account: typeof value?.account === "string" && value.account.trim() ? value.account.trim() : void 0,
16
+ accountUuid: typeof value?.accountUuid === "string" && value.accountUuid.trim() ? value.accountUuid.trim() : void 0
17
+ };
18
+ }
19
+ function buildPendingPayload(params) {
20
+ return buildApprovalReactionPendingContent(params);
21
+ }
22
+ const signalApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
23
+ eventKinds: ["exec", "plugin"],
24
+ availability: {
25
+ isConfigured: ({ context }) => Boolean(context),
26
+ shouldHandle: ({ context }) => Boolean(context)
27
+ },
28
+ presentation: {
29
+ buildPendingPayload: ({ request, nowMs, view }) => buildPendingPayload({
30
+ request,
31
+ nowMs,
32
+ view
33
+ }),
34
+ buildResolvedResult: ({ request, resolved, view }) => ({
35
+ kind: "update",
36
+ payload: { text: buildChannelApprovalResolvedText({
37
+ request,
38
+ resolved,
39
+ view
40
+ }) }
41
+ }),
42
+ buildExpiredResult: ({ request, view }) => ({
43
+ kind: "update",
44
+ payload: { text: buildChannelApprovalExpiredText({
45
+ request,
46
+ view
47
+ }) }
48
+ })
49
+ },
50
+ transport: {
51
+ prepareTarget: ({ plannedTarget, accountId, context }) => {
52
+ const to = normalizeSignalMessagingTarget(plannedTarget.target.to);
53
+ if (!to) return null;
54
+ const runtimeContext = readSignalApprovalRuntimeContext(context);
55
+ const targetAuthorKeys = resolveSignalApprovalTargetAuthorKeys({
56
+ targetAuthor: runtimeContext.account,
57
+ targetAuthorUuid: runtimeContext.accountUuid
58
+ });
59
+ const prepared = {
60
+ to,
61
+ accountId: resolvePreparedApprovalAccountId({
62
+ plannedAccountId: plannedTarget.target.accountId,
63
+ contextAccountId: accountId,
64
+ fallbackAccountId: DEFAULT_ACCOUNT_ID
65
+ }),
66
+ ...runtimeContext.baseUrl ? { baseUrl: runtimeContext.baseUrl } : {},
67
+ ...runtimeContext.account ? { account: runtimeContext.account } : {},
68
+ ...runtimeContext.accountUuid ? { accountUuid: runtimeContext.accountUuid } : {},
69
+ targetAuthorKeys
70
+ };
71
+ return {
72
+ dedupeKey: `${prepared.accountId}:${buildChannelApprovalNativeTargetKey({ to: prepared.to })}`,
73
+ target: prepared
74
+ };
75
+ },
76
+ deliverPending: async ({ cfg, preparedTarget, pendingPayload }) => {
77
+ await sendTypingSignal(preparedTarget.to, {
78
+ cfg,
79
+ accountId: preparedTarget.accountId,
80
+ ...preparedTarget.baseUrl ? { baseUrl: preparedTarget.baseUrl } : {},
81
+ ...preparedTarget.account ? { account: preparedTarget.account } : {}
82
+ }).catch(() => {});
83
+ const reactionsActive = preparedTarget.targetAuthorKeys.length > 0 && hasSignalApprovalReactionApprovers({
84
+ cfg,
85
+ accountId: preparedTarget.accountId
86
+ });
87
+ const payload = reactionsActive ? pendingPayload.reactionPayload : pendingPayload.manualFallbackPayload;
88
+ const result = await sendMessageSignal(preparedTarget.to, payload.text ?? "", {
89
+ cfg,
90
+ accountId: preparedTarget.accountId,
91
+ ...preparedTarget.baseUrl ? { baseUrl: preparedTarget.baseUrl } : {},
92
+ ...preparedTarget.account ? { account: preparedTarget.account } : {},
93
+ textMode: "plain"
94
+ });
95
+ if (!result.messageId || result.messageId === "unknown") return null;
96
+ const conversationKey = resolveSignalApprovalConversationKey(preparedTarget.to);
97
+ if (!conversationKey) return null;
98
+ return {
99
+ accountId: preparedTarget.accountId,
100
+ to: preparedTarget.to,
101
+ conversationKey,
102
+ messageId: result.messageId,
103
+ targetAuthorKeys: preparedTarget.targetAuthorKeys,
104
+ reactionsActive,
105
+ ...preparedTarget.baseUrl ? { baseUrl: preparedTarget.baseUrl } : {},
106
+ ...preparedTarget.account ? { account: preparedTarget.account } : {}
107
+ };
108
+ },
109
+ updateEntry: async ({ cfg, entry, payload }) => {
110
+ await sendMessageSignal(entry.to, payload.text, {
111
+ cfg,
112
+ accountId: entry.accountId,
113
+ ...entry.baseUrl ? { baseUrl: entry.baseUrl } : {},
114
+ ...entry.account ? { account: entry.account } : {},
115
+ textMode: "plain"
116
+ });
117
+ }
118
+ },
119
+ interactions: {
120
+ bindPending: ({ entry, request, view, pendingPayload }) => {
121
+ if (!entry.reactionsActive) return null;
122
+ return registerSignalApprovalReactionTarget({
123
+ accountId: entry.accountId,
124
+ conversationKey: entry.conversationKey,
125
+ messageId: entry.messageId,
126
+ approvalId: request.id,
127
+ allowedDecisions: pendingPayload.reactionPayload.allowedDecisions,
128
+ targetAuthorKeys: entry.targetAuthorKeys,
129
+ route: {
130
+ deliveryMode: "session",
131
+ ...normalizeOptionalString(request.request.agentId) ? { agentId: normalizeOptionalString(request.request.agentId) } : {},
132
+ ...normalizeOptionalString(request.request.sessionKey) ? { sessionKey: normalizeOptionalString(request.request.sessionKey) } : {}
133
+ },
134
+ routeAllowed: true,
135
+ ttlMs: Math.max(1, view.expiresAtMs - Date.now())
136
+ }) ? true : null;
137
+ },
138
+ unbindPending: ({ entry }) => {
139
+ unregisterSignalApprovalReactionTarget({
140
+ accountId: entry.accountId,
141
+ conversationKey: entry.conversationKey,
142
+ messageId: entry.messageId
143
+ });
144
+ },
145
+ cancelDelivered: ({ entry }) => {
146
+ unregisterSignalApprovalReactionTarget({
147
+ accountId: entry.accountId,
148
+ conversationKey: entry.conversationKey,
149
+ messageId: entry.messageId
150
+ });
151
+ }
152
+ },
153
+ observe: { onDeliveryError: ({ error, request }) => {
154
+ log.error(`signal approvals: failed to send request ${request.id}: ${String(error)}`);
155
+ } }
156
+ });
157
+ //#endregion
158
+ export { signalApprovalNativeRuntime };
@@ -0,0 +1,15 @@
1
+ import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
2
+ import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
3
+ //#region extensions/signal/src/approval-resolver.ts
4
+ async function resolveSignalApproval(params) {
5
+ await resolveApprovalOverGateway({
6
+ cfg: params.cfg,
7
+ approvalId: params.approvalId,
8
+ decision: params.decision,
9
+ senderId: params.senderId,
10
+ gatewayUrl: params.gatewayUrl,
11
+ clientDisplayName: `Signal approval (${params.senderId?.trim() || "unknown"})`
12
+ });
13
+ }
14
+ //#endregion
15
+ export { isApprovalNotFoundError, resolveSignalApproval };