@moxxy/plugin-channel-signal 0.27.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/LICENSE +21 -0
- package/dist/channel/chunker.d.ts +69 -0
- package/dist/channel/chunker.d.ts.map +1 -0
- package/dist/channel/chunker.js +133 -0
- package/dist/channel/chunker.js.map +1 -0
- package/dist/channel/turn-runner.d.ts +33 -0
- package/dist/channel/turn-runner.d.ts.map +1 -0
- package/dist/channel/turn-runner.js +70 -0
- package/dist/channel/turn-runner.js.map +1 -0
- package/dist/channel/voice.d.ts +37 -0
- package/dist/channel/voice.d.ts.map +1 -0
- package/dist/channel/voice.js +88 -0
- package/dist/channel/voice.js.map +1 -0
- package/dist/channel.d.ts +154 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +468 -0
- package/dist/channel.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +215 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonrpc.d.ts +53 -0
- package/dist/jsonrpc.d.ts.map +1 -0
- package/dist/jsonrpc.js +167 -0
- package/dist/jsonrpc.js.map +1 -0
- package/dist/keys.d.ts +37 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +55 -0
- package/dist/keys.js.map +1 -0
- package/dist/pair-flow.d.ts +21 -0
- package/dist/pair-flow.d.ts.map +1 -0
- package/dist/pair-flow.js +136 -0
- package/dist/pair-flow.js.map +1 -0
- package/dist/permission.d.ts +21 -0
- package/dist/permission.d.ts.map +1 -0
- package/dist/permission.js +27 -0
- package/dist/permission.js.map +1 -0
- package/dist/schema.d.ts +4295 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +84 -0
- package/dist/schema.js.map +1 -0
- package/dist/setup-wizard.d.ts +14 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +85 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/sidecar.d.ts +137 -0
- package/dist/sidecar.d.ts.map +1 -0
- package/dist/sidecar.js +421 -0
- package/dist/sidecar.js.map +1 -0
- package/package.json +89 -0
- package/src/channel/chunker.test.ts +135 -0
- package/src/channel/chunker.ts +147 -0
- package/src/channel/turn-runner.ts +97 -0
- package/src/channel/voice.test.ts +136 -0
- package/src/channel/voice.ts +118 -0
- package/src/channel.test.ts +364 -0
- package/src/channel.ts +607 -0
- package/src/index.ts +289 -0
- package/src/jsonrpc.test.ts +128 -0
- package/src/jsonrpc.ts +198 -0
- package/src/keys.test.ts +45 -0
- package/src/keys.ts +56 -0
- package/src/pair-flow.ts +161 -0
- package/src/permission.ts +36 -0
- package/src/schema.ts +98 -0
- package/src/setup-wizard.ts +98 -0
- package/src/sidecar.test.ts +276 -0
- package/src/sidecar.ts +511 -0
- package/src/subcommands.test.ts +206 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { log, outro, spinner } from '@clack/prompts';
|
|
2
|
+
import QRCode from 'qrcode';
|
|
3
|
+
import { exitAfterPairRequested } from '@moxxy/sdk';
|
|
4
|
+
import { SignalChannel } from './channel.js';
|
|
5
|
+
// Tiny zero-dep ANSI dim helper, so this flow stays inside the plugin.
|
|
6
|
+
const ANSI = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
7
|
+
const dim = (s) => (ANSI ? `\x1b[2m${s}\x1b[22m` : s);
|
|
8
|
+
/**
|
|
9
|
+
* Drive the Signal linked-device pairing end-to-end in a terminal — the SAME
|
|
10
|
+
* mechanism the desktop Channels panel uses (the channel's `pair: true` link
|
|
11
|
+
* window), just rendered inline here.
|
|
12
|
+
*
|
|
13
|
+
* Steps:
|
|
14
|
+
* 1. Build a SignalChannel from the subcommand ctx and wire the session's
|
|
15
|
+
* permission resolver.
|
|
16
|
+
* 2. Subscribe to "linked" BEFORE starting so a fast scan can't race us.
|
|
17
|
+
* 3. Start the channel in pairing mode — it spawns `signal-cli link` and
|
|
18
|
+
* publishes the `sgnl://linkdevice…` URI as `channel.requestUrl`.
|
|
19
|
+
* 4. Render that URI as a scannable QR (+ the raw URI).
|
|
20
|
+
* 5. On the phone: Signal → Settings → Linked Devices → Link New Device →
|
|
21
|
+
* scan; the channel stores the account and boots the daemon.
|
|
22
|
+
* 6. Keep the channel running until the user Ctrl-Cs.
|
|
23
|
+
*/
|
|
24
|
+
export async function runSignalPairFlow(ctx, overrides = {}) {
|
|
25
|
+
const session = ctx.session;
|
|
26
|
+
const channel = new SignalChannel({
|
|
27
|
+
vault: ctx.deps.vault,
|
|
28
|
+
...(typeof ctx.deps.options?.['account'] === 'string'
|
|
29
|
+
? { account: ctx.deps.options['account'] }
|
|
30
|
+
: {}),
|
|
31
|
+
...(overrides.allowedTools ? { allowedTools: overrides.allowedTools } : {}),
|
|
32
|
+
logger: ctx.deps.logger,
|
|
33
|
+
});
|
|
34
|
+
session.setPermissionResolver(channel.permissionResolver);
|
|
35
|
+
// Subscribe BEFORE start so the first scan can't fire before us.
|
|
36
|
+
let linkedResolve = null;
|
|
37
|
+
const linkedPromise = new Promise((resolve) => {
|
|
38
|
+
linkedResolve = resolve;
|
|
39
|
+
});
|
|
40
|
+
const unsubscribe = channel.onLinked((account) => {
|
|
41
|
+
linkedResolve?.(account);
|
|
42
|
+
linkedResolve = null;
|
|
43
|
+
});
|
|
44
|
+
outro(dim('opening Signal linking window...'));
|
|
45
|
+
const handle = await channel.start({ session, pair: true });
|
|
46
|
+
const stopChannel = async () => {
|
|
47
|
+
unsubscribe();
|
|
48
|
+
try {
|
|
49
|
+
await handle.stop('pair-flow');
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* ignore */
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// Already linked (no window was opened): nothing to scan.
|
|
56
|
+
if (channel.connected) {
|
|
57
|
+
log.info('This machine is already linked to a Signal account. The channel is running; ' +
|
|
58
|
+
'to link a different account, remove this device from Signal → Linked Devices first, ' +
|
|
59
|
+
'then run `moxxy channels signal unpair` and pair again.');
|
|
60
|
+
if (exitAfterPairRequested(ctx)) {
|
|
61
|
+
await stopChannel();
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
log.info('Press Ctrl+C to stop.');
|
|
65
|
+
installSignalHandlers(stopChannel, session);
|
|
66
|
+
await handle.running;
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
const uri = channel.requestUrl;
|
|
70
|
+
if (!uri) {
|
|
71
|
+
log.error('Could not obtain a linking URI from signal-cli.');
|
|
72
|
+
await stopChannel();
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
await printLinkQr(uri);
|
|
76
|
+
log.info('On your phone: Signal → Settings → Linked Devices → Link New Device, then scan the QR. ' +
|
|
77
|
+
'The QR expires after a few minutes; re-run `moxxy channels signal pair` if it does.');
|
|
78
|
+
const removeSignalHandlers = installSignalHandlers(stopChannel, session);
|
|
79
|
+
const spin = spinner();
|
|
80
|
+
spin.start('Waiting for you to scan in Signal...');
|
|
81
|
+
const account = await Promise.race([
|
|
82
|
+
linkedPromise,
|
|
83
|
+
handle.running.then(() => null),
|
|
84
|
+
]).catch((err) => {
|
|
85
|
+
spin.stop('Linking failed.');
|
|
86
|
+
log.error(err instanceof Error ? err.message : String(err));
|
|
87
|
+
return null;
|
|
88
|
+
});
|
|
89
|
+
if (account == null) {
|
|
90
|
+
await stopChannel();
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
spin.stop(`Linked ✓ — this machine is now a device of ${account}.`);
|
|
94
|
+
if (exitAfterPairRequested(ctx)) {
|
|
95
|
+
// Orchestrated pairing (`moxxy onboard`): hand control back — the caller
|
|
96
|
+
// starts the channel under its own service afterwards. Our SIGINT
|
|
97
|
+
// handlers would `process.exit` the orchestrator, so drop them first.
|
|
98
|
+
removeSignalHandlers();
|
|
99
|
+
await stopChannel();
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
log.info('Message your own "Note to Self" in Signal to talk to moxxy. The channel is running; press Ctrl+C to stop.');
|
|
103
|
+
await handle.running;
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
function installSignalHandlers(stopChannel, session) {
|
|
107
|
+
let stopping = false;
|
|
108
|
+
const shutdown = async () => {
|
|
109
|
+
if (stopping)
|
|
110
|
+
return;
|
|
111
|
+
stopping = true;
|
|
112
|
+
await stopChannel();
|
|
113
|
+
await session.close('SIGINT').catch(() => undefined);
|
|
114
|
+
process.exit(0);
|
|
115
|
+
};
|
|
116
|
+
const onSignal = () => void shutdown();
|
|
117
|
+
process.once('SIGINT', onSignal);
|
|
118
|
+
process.once('SIGTERM', onSignal);
|
|
119
|
+
return () => {
|
|
120
|
+
process.removeListener('SIGINT', onSignal);
|
|
121
|
+
process.removeListener('SIGTERM', onSignal);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** Render the linking URI as a scannable terminal QR + the raw URI. */
|
|
125
|
+
async function printLinkQr(uri) {
|
|
126
|
+
let qr = '';
|
|
127
|
+
try {
|
|
128
|
+
qr = await QRCode.toString(uri, { type: 'terminal', small: true });
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
qr = '';
|
|
132
|
+
}
|
|
133
|
+
// CLI surface — intentional stdout.
|
|
134
|
+
console.log(['', qr, ` link URI: ${uri}`, ''].join('\n'));
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=pair-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pair-flow.js","sourceRoot":"","sources":["../src/pair-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PermissionResolver } from '@moxxy/sdk';
|
|
2
|
+
export interface SignalPermissionLogger {
|
|
3
|
+
info?(msg: string, meta?: Record<string, unknown>): void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Build the Signal channel's autonomous permission resolver.
|
|
7
|
+
*
|
|
8
|
+
* Like Slack (and unlike Telegram's inline-keyboard prompts), the Signal
|
|
9
|
+
* channel runs hands-off: the operator declares trust upfront via
|
|
10
|
+
* `channels.signal.allowedTools`, and any tool NOT in that list is denied.
|
|
11
|
+
* The trust check + `'*'` expansion + audit-on-auto-approve wiring is the
|
|
12
|
+
* shared {@link createAuditedAllowListResolver} from `@moxxy/channel-kit`;
|
|
13
|
+
* this wrapper binds it to the channel logger so every auto-approved call
|
|
14
|
+
* leaves a trail. An empty list denies everything (effectively read-only).
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildSignalPermissionResolver(opts: {
|
|
17
|
+
allowedTools: ReadonlyArray<string>;
|
|
18
|
+
allToolNames: ReadonlyArray<string>;
|
|
19
|
+
logger?: SignalPermissionLogger;
|
|
20
|
+
}): PermissionResolver;
|
|
21
|
+
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC,GAAG,kBAAkB,CAarB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createAuditedAllowListResolver } from '@moxxy/channel-kit';
|
|
2
|
+
/**
|
|
3
|
+
* Build the Signal channel's autonomous permission resolver.
|
|
4
|
+
*
|
|
5
|
+
* Like Slack (and unlike Telegram's inline-keyboard prompts), the Signal
|
|
6
|
+
* channel runs hands-off: the operator declares trust upfront via
|
|
7
|
+
* `channels.signal.allowedTools`, and any tool NOT in that list is denied.
|
|
8
|
+
* The trust check + `'*'` expansion + audit-on-auto-approve wiring is the
|
|
9
|
+
* shared {@link createAuditedAllowListResolver} from `@moxxy/channel-kit`;
|
|
10
|
+
* this wrapper binds it to the channel logger so every auto-approved call
|
|
11
|
+
* leaves a trail. An empty list denies everything (effectively read-only).
|
|
12
|
+
*/
|
|
13
|
+
export function buildSignalPermissionResolver(opts) {
|
|
14
|
+
return createAuditedAllowListResolver({
|
|
15
|
+
name: 'signal-allow-list',
|
|
16
|
+
allowedTools: opts.allowedTools,
|
|
17
|
+
allToolNames: opts.allToolNames,
|
|
18
|
+
onAutoApprove: (call, { wildcard }) => {
|
|
19
|
+
opts.logger?.info?.('signal: auto-approved tool call', {
|
|
20
|
+
tool: call.name,
|
|
21
|
+
callId: call.callId,
|
|
22
|
+
wildcard,
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=permission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAOpE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,6BAA6B,CAAC,IAI7C;IACC,OAAO,8BAA8B,CAAC;QACpC,IAAI,EAAE,mBAAmB;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YACpC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,iCAAiC,EAAE;gBACrD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|