@moxxy/sdk 0.21.0 → 0.22.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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Process-independent control surface for dedicated channel runners.
3
+ *
4
+ * A dedicated channel (Slack, Telegram, …) runs as its OWN isolated runner
5
+ * subprocess that publishes a tiny status file (`channel-<name>.status.json`,
6
+ * see {@link ./channel-status}) on ready and clears it on graceful shutdown. That
7
+ * file — NOT a held child handle — is the source of truth for "is it running",
8
+ * so a channel started from anywhere (the TUI `/channels` panel, `moxxy channels
9
+ * start`, the desktop panel) is visible and stoppable from everywhere, and keeps
10
+ * running after the launcher exits.
11
+ *
12
+ * These helpers are the shared spine for those surfaces:
13
+ * - {@link spawnDedicatedChannel} — start one, detached, on its own runner.
14
+ * - {@link liveChannelStatus}/{@link listLiveChannelStatuses} — discover the
15
+ * running ones (with stale-file self-healing).
16
+ * - {@link stopDedicatedChannel} — signal one to stop.
17
+ *
18
+ * Node-only (`node:child_process`, `node:fs`) — exported from `@moxxy/sdk/server`.
19
+ */
20
+ import { type ChannelRunStatus } from './channel-status.js';
21
+ /**
22
+ * Start a channel on its own dedicated, detached runner by re-invoking this very
23
+ * moxxy binary as `moxxy <name>` with `MOXXY_DEDICATED_RUNNER=1`. The child is
24
+ * `detached` + `unref`'d with no stdio, so it OUTLIVES the launcher (the user can
25
+ * quit the TUI and the bot keeps serving) and reports itself via its status file.
26
+ *
27
+ * Returns the child pid, or undefined if the spawn produced none. Throws if the
28
+ * moxxy CLI entry can't be resolved (no `process.argv[1]`).
29
+ *
30
+ * Caller's job (this is fire-and-forget): poll {@link liveChannelStatus} to learn
31
+ * when it's ready / failed (no status file within a timeout ⇒ it died on boot —
32
+ * re-run `moxxy <name>` in the foreground to see why).
33
+ */
34
+ export declare function spawnDedicatedChannel(name: string): number | undefined;
35
+ /**
36
+ * Is `pid` a live process? `kill(pid, 0)` sends no signal — it only probes:
37
+ * - resolves ⇒ alive,
38
+ * - `ESRCH` ⇒ gone,
39
+ * - `EPERM` ⇒ alive but owned by another user (treat as alive — it exists).
40
+ */
41
+ export declare function isPidAlive(pid: number): boolean;
42
+ /**
43
+ * The status of channel `name` IF it is actually running. Reads its status file
44
+ * and verifies the pid is alive; a file whose pid is dead (the runner crashed or
45
+ * was SIGKILL'd without clearing it) is treated as not-running AND removed, so a
46
+ * stale file never masquerades as a live channel.
47
+ */
48
+ export declare function liveChannelStatus(name: string): ChannelRunStatus | null;
49
+ /**
50
+ * Every currently-running dedicated channel, discovered by scanning the moxxy
51
+ * home for status files and filtering to live pids (self-healing stale ones).
52
+ * Returns [] when the home dir doesn't exist yet.
53
+ */
54
+ export declare function listLiveChannelStatuses(): ChannelRunStatus[];
55
+ /**
56
+ * Ask channel `name` to stop by SIGTERM-ing its runner. The runner's own signal
57
+ * handler tears down gracefully and clears its status file. Returns `'stopped'`
58
+ * if a live runner was signaled, `'not-running'` if there was nothing to stop.
59
+ *
60
+ * This is a single, synchronous SIGTERM — callers that want a hard backstop poll
61
+ * {@link liveChannelStatus} afterwards and escalate (SIGKILL + {@link clearChannelStatus})
62
+ * if it ignores the term within a grace period.
63
+ */
64
+ export declare function stopDedicatedChannel(name: string): 'stopped' | 'not-running';
65
+ //# sourceMappingURL=channel-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-control.d.ts","sourceRoot":"","sources":["../src/channel-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,qBAAqB,CAAC;AAS7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAatE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ/C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQvE;AAQD;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,gBAAgB,EAAE,CAe5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAU5E"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Process-independent control surface for dedicated channel runners.
3
+ *
4
+ * A dedicated channel (Slack, Telegram, …) runs as its OWN isolated runner
5
+ * subprocess that publishes a tiny status file (`channel-<name>.status.json`,
6
+ * see {@link ./channel-status}) on ready and clears it on graceful shutdown. That
7
+ * file — NOT a held child handle — is the source of truth for "is it running",
8
+ * so a channel started from anywhere (the TUI `/channels` panel, `moxxy channels
9
+ * start`, the desktop panel) is visible and stoppable from everywhere, and keeps
10
+ * running after the launcher exits.
11
+ *
12
+ * These helpers are the shared spine for those surfaces:
13
+ * - {@link spawnDedicatedChannel} — start one, detached, on its own runner.
14
+ * - {@link liveChannelStatus}/{@link listLiveChannelStatuses} — discover the
15
+ * running ones (with stale-file self-healing).
16
+ * - {@link stopDedicatedChannel} — signal one to stop.
17
+ *
18
+ * Node-only (`node:child_process`, `node:fs`) — exported from `@moxxy/sdk/server`.
19
+ */
20
+ import { spawn } from 'node:child_process';
21
+ import { readdirSync } from 'node:fs';
22
+ import { clearChannelStatus, readChannelStatus, } from './channel-status.js';
23
+ import { moxxyHome } from './fs-utils.js';
24
+ /** Env vars that ADDRESS a runner (socket + sticky session). We scrub these from
25
+ * a spawned channel's env so `applyDedicatedRunnerEnv` (which only fills UNSET
26
+ * vars) derives the channel's OWN isolated socket/session from its name — rather
27
+ * than the channel silently inheriting and sharing the launcher's runner. */
28
+ const ADDRESSING_ENV = ['MOXXY_RUNNER_SOCKET', 'MOXXY_SESSION_ID', 'MOXXY_SESSION_SOURCE'];
29
+ /**
30
+ * Start a channel on its own dedicated, detached runner by re-invoking this very
31
+ * moxxy binary as `moxxy <name>` with `MOXXY_DEDICATED_RUNNER=1`. The child is
32
+ * `detached` + `unref`'d with no stdio, so it OUTLIVES the launcher (the user can
33
+ * quit the TUI and the bot keeps serving) and reports itself via its status file.
34
+ *
35
+ * Returns the child pid, or undefined if the spawn produced none. Throws if the
36
+ * moxxy CLI entry can't be resolved (no `process.argv[1]`).
37
+ *
38
+ * Caller's job (this is fire-and-forget): poll {@link liveChannelStatus} to learn
39
+ * when it's ready / failed (no status file within a timeout ⇒ it died on boot —
40
+ * re-run `moxxy <name>` in the foreground to see why).
41
+ */
42
+ export function spawnDedicatedChannel(name) {
43
+ const node = process.execPath; // the running Node binary (pnpm `moxxy` launches via Node)
44
+ const entry = process.argv[1]; // the resolved CLI entry (…/cli/dist/bin.js)
45
+ if (!entry) {
46
+ throw new Error('cannot start a channel: the moxxy CLI entry is unknown (process.argv[1] missing)');
47
+ }
48
+ const env = { ...process.env, MOXXY_DEDICATED_RUNNER: '1' };
49
+ for (const key of ADDRESSING_ENV)
50
+ delete env[key];
51
+ const child = spawn(node, [entry, name], { detached: true, stdio: 'ignore', env });
52
+ child.unref();
53
+ return child.pid;
54
+ }
55
+ /**
56
+ * Is `pid` a live process? `kill(pid, 0)` sends no signal — it only probes:
57
+ * - resolves ⇒ alive,
58
+ * - `ESRCH` ⇒ gone,
59
+ * - `EPERM` ⇒ alive but owned by another user (treat as alive — it exists).
60
+ */
61
+ export function isPidAlive(pid) {
62
+ if (!Number.isInteger(pid) || pid <= 0)
63
+ return false;
64
+ try {
65
+ process.kill(pid, 0);
66
+ return true;
67
+ }
68
+ catch (err) {
69
+ return err.code === 'EPERM';
70
+ }
71
+ }
72
+ /**
73
+ * The status of channel `name` IF it is actually running. Reads its status file
74
+ * and verifies the pid is alive; a file whose pid is dead (the runner crashed or
75
+ * was SIGKILL'd without clearing it) is treated as not-running AND removed, so a
76
+ * stale file never masquerades as a live channel.
77
+ */
78
+ export function liveChannelStatus(name) {
79
+ const status = readChannelStatus(name);
80
+ if (!status)
81
+ return null;
82
+ if (!isPidAlive(status.pid)) {
83
+ clearChannelStatus(name);
84
+ return null;
85
+ }
86
+ return status;
87
+ }
88
+ /** The channel name encoded in a `channel-<name>.status.json` file, or null. */
89
+ function statusFileChannelName(file) {
90
+ const m = /^channel-(.+)\.status\.json$/.exec(file);
91
+ return m ? (m[1] ?? null) : null;
92
+ }
93
+ /**
94
+ * Every currently-running dedicated channel, discovered by scanning the moxxy
95
+ * home for status files and filtering to live pids (self-healing stale ones).
96
+ * Returns [] when the home dir doesn't exist yet.
97
+ */
98
+ export function listLiveChannelStatuses() {
99
+ let files;
100
+ try {
101
+ files = readdirSync(moxxyHome());
102
+ }
103
+ catch {
104
+ return []; // no ~/.moxxy yet ⇒ nothing running
105
+ }
106
+ const live = [];
107
+ for (const file of files) {
108
+ const name = statusFileChannelName(file);
109
+ if (!name)
110
+ continue;
111
+ const status = liveChannelStatus(name);
112
+ if (status)
113
+ live.push(status);
114
+ }
115
+ return live;
116
+ }
117
+ /**
118
+ * Ask channel `name` to stop by SIGTERM-ing its runner. The runner's own signal
119
+ * handler tears down gracefully and clears its status file. Returns `'stopped'`
120
+ * if a live runner was signaled, `'not-running'` if there was nothing to stop.
121
+ *
122
+ * This is a single, synchronous SIGTERM — callers that want a hard backstop poll
123
+ * {@link liveChannelStatus} afterwards and escalate (SIGKILL + {@link clearChannelStatus})
124
+ * if it ignores the term within a grace period.
125
+ */
126
+ export function stopDedicatedChannel(name) {
127
+ const status = liveChannelStatus(name);
128
+ if (!status)
129
+ return 'not-running';
130
+ try {
131
+ process.kill(status.pid, 'SIGTERM');
132
+ }
133
+ catch {
134
+ // Raced us to exit between the liveness check and here — already stopped.
135
+ clearChannelStatus(name);
136
+ }
137
+ return 'stopped';
138
+ }
139
+ //# sourceMappingURL=channel-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-control.js","sourceRoot":"","sources":["../src/channel-control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The on-disk status a dedicated channel runner publishes so an out-of-process
3
+ * supervisor (the desktop "Channels" panel) can observe it without the runner
4
+ * protocol. Written by `moxxy <channel>` when it self-hosts a dedicated runner,
5
+ * read by the desktop host; removed on graceful shutdown.
6
+ *
7
+ * It is intentionally tiny — readiness + the public ingest URL — not a mirror of
8
+ * the session. The supervisor owns liveness (it holds the child handle); this
9
+ * file is the channel's own report of "I'm up, and here's the URL to paste".
10
+ */
11
+ export interface ChannelRunStatus {
12
+ /** Channel name (e.g. `slack`, `telegram`). */
13
+ readonly name: string;
14
+ /** PID of the channel runner process. */
15
+ readonly pid: number;
16
+ /** ISO timestamp the channel reported ready. */
17
+ readonly startedAt: string;
18
+ /** The session source the runner stamped (e.g. `slack`). */
19
+ readonly source?: string;
20
+ /** Public ingest URL (e.g. Slack's Events Request URL) once the tunnel is up;
21
+ * null for channels with no inbound endpoint (Telegram long-polls). */
22
+ readonly requestUrl?: string | null;
23
+ }
24
+ /** `~/.moxxy/channel-<name>.status.json` (honors `$MOXXY_HOME`). */
25
+ export declare function channelStatusPath(name: string): string;
26
+ /** Atomically publish a channel's run status (0600 — it may carry a URL). */
27
+ export declare function writeChannelStatus(status: ChannelRunStatus): void;
28
+ /** Read a channel's published status, or null if absent/unparseable. */
29
+ export declare function readChannelStatus(name: string): ChannelRunStatus | null;
30
+ /** Remove a channel's status file (best-effort; called on graceful shutdown). */
31
+ export declare function clearChannelStatus(name: string): void;
32
+ //# sourceMappingURL=channel-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-status.d.ts","sourceRoot":"","sources":["../src/channel-status.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;4EACwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAEjE;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAMvE;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMrD"}
@@ -0,0 +1,29 @@
1
+ import { readFileSync, rmSync } from 'node:fs';
2
+ import { moxxyPath, writeFileAtomicSync } from './fs-utils.js';
3
+ /** `~/.moxxy/channel-<name>.status.json` (honors `$MOXXY_HOME`). */
4
+ export function channelStatusPath(name) {
5
+ return moxxyPath(`channel-${name}.status.json`);
6
+ }
7
+ /** Atomically publish a channel's run status (0600 — it may carry a URL). */
8
+ export function writeChannelStatus(status) {
9
+ writeFileAtomicSync(channelStatusPath(status.name), JSON.stringify(status), { mode: 0o600 });
10
+ }
11
+ /** Read a channel's published status, or null if absent/unparseable. */
12
+ export function readChannelStatus(name) {
13
+ try {
14
+ return JSON.parse(readFileSync(channelStatusPath(name), 'utf8'));
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ /** Remove a channel's status file (best-effort; called on graceful shutdown). */
21
+ export function clearChannelStatus(name) {
22
+ try {
23
+ rmSync(channelStatusPath(name), { force: true });
24
+ }
25
+ catch {
26
+ /* best-effort */
27
+ }
28
+ }
29
+ //# sourceMappingURL=channel-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-status.js","sourceRoot":"","sources":["../src/channel-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AA0B/D,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,SAAS,CAAC,WAAW,IAAI,cAAc,CAAC,CAAC;AAClD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,MAAwB;IACzD,mBAAmB,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAqB,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC;QACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC"}
package/dist/channel.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { PermissionResolver } from './permission.js';
2
2
  import type { ClientSession } from './client-session.js';
3
+ import type { SessionSource } from './event-store.js';
3
4
  /**
4
5
  * A Channel is a bidirectional surface that drives a Session: it feeds user
5
6
  * prompts in, renders assistant chunks + tool activity out, and implements a
@@ -22,6 +23,14 @@ export interface Channel<TStartOpts = unknown> {
22
23
  * resolves when the channel exits gracefully.
23
24
  */
24
25
  start(opts: TStartOpts): Promise<ChannelHandle>;
26
+ /**
27
+ * The public ingest URL this channel exposes once running — e.g. Slack's
28
+ * Events Request URL after its proxy tunnel opens — or null when it has none
29
+ * (Telegram long-polls). Read by the dedicated-runner host to publish the URL
30
+ * the user must paste into the provider's config. Optional: channels with no
31
+ * inbound endpoint omit it.
32
+ */
33
+ readonly requestUrl?: string | null;
25
34
  }
26
35
  export interface ChannelHandle {
27
36
  /**
@@ -121,6 +130,61 @@ export interface ChannelDef<TStartOpts = unknown> {
121
130
  * starts the channel.
122
131
  */
123
132
  readonly interactiveCommand?: string;
133
+ /**
134
+ * Declare that this channel runs on its OWN dedicated, isolated runner: a
135
+ * distinct runner socket (`channel-<name>.sock`) + a stable sticky session id
136
+ * (`moxxy-channel-<name>`), so the channel acts as its own agent thread,
137
+ * separate from whatever runner serves the desktop/TUI. NO runner-protocol
138
+ * change — one dedicated runner is still one Session. Channels that should
139
+ * operate autonomously (slack, telegram) set this; the CLI reads it generically
140
+ * (see `applyDedicatedRunnerEnv`) so no per-channel name list is needed. Any
141
+ * channel can also opt in at runtime via `--dedicated` / `MOXXY_DEDICATED_RUNNER=1`.
142
+ */
143
+ readonly dedicatedRunner?: boolean;
144
+ /**
145
+ * The {@link SessionSource} to stamp on this channel's sessions when it runs
146
+ * dedicated (persisted into the meta sidecar; surfaces filter history by it).
147
+ * Only honored alongside `dedicatedRunner`. When unset, the source falls back
148
+ * to the usual env/default resolution.
149
+ */
150
+ readonly sessionSource?: SessionSource;
151
+ /**
152
+ * Declarative config the channel needs to run (its secret fields + where they
153
+ * live in the vault, plus pairing hints). This is what a control surface — the
154
+ * TUI `/channels` panel, `moxxy channels start`, the desktop "Channels" panel —
155
+ * renders to let the user configure + start the channel WITHOUT hardcoding a
156
+ * per-channel table. The channel self-describes here; the vault keys named are
157
+ * the same ones the channel actually reads at boot (its `keys.ts`). Channels
158
+ * with no setup (web/http) omit this.
159
+ */
160
+ readonly config?: ChannelConfigDescriptor;
161
+ }
162
+ /** One secret/config input a channel exposes for a control surface to collect. */
163
+ export interface ChannelConfigField {
164
+ /** Option key (e.g. `botToken`). Stable identifier within the channel. */
165
+ readonly name: string;
166
+ /** Short human label (e.g. `Bot token`). */
167
+ readonly label: string;
168
+ /** The vault key the channel reads this value from (e.g. `slack_bot_token`). */
169
+ readonly vaultKey: string;
170
+ /** Must be present for the channel to count as "configured". */
171
+ readonly required?: boolean;
172
+ /** Treat as a secret — mask the input and never echo the stored value. */
173
+ readonly secret?: boolean;
174
+ /** Placeholder shown in an empty input (e.g. `xoxb-…`). */
175
+ readonly placeholder?: string;
176
+ /** One-line guidance on where to obtain the value. */
177
+ readonly help?: string;
178
+ }
179
+ /** What a channel declares about being configured + run from a control surface. */
180
+ export interface ChannelConfigDescriptor {
181
+ /** The fields to collect, in display order. */
182
+ readonly fields: ReadonlyArray<ChannelConfigField>;
183
+ /** The channel exposes a public ingest URL (Slack's Request URL) once started,
184
+ * so a control surface should poll for + surface it. */
185
+ readonly hasRequestUrl?: boolean;
186
+ /** Post-start pairing/setup instructions to show the user. */
187
+ readonly runHint?: string;
124
188
  }
125
189
  export interface ChannelAvailability {
126
190
  readonly ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAgDA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,IAAsB;IACvE,oEAAoE;IACpE,8EAA8E;IAC9E,oEAAoE;IACpE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAa,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AA0DA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB,EAAE,IAAsB;IACvE,oEAAoE;IACpE,8EAA8E;IAC9E,oEAAoE;IACpE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAa,CAAC,CAAC;AACtC,CAAC"}
@@ -11,7 +11,7 @@ import type { SessionId } from './ids.js';
11
11
  * event (prompts, tool I/O), so that explicit opt-in is the trust boundary.
12
12
  */
13
13
  /** Originating channel of a session (persisted into the meta sidecar). */
14
- export type SessionSource = 'cli' | 'tui' | 'desktop' | 'mobile';
14
+ export type SessionSource = 'cli' | 'tui' | 'desktop' | 'mobile' | 'slack' | 'telegram';
15
15
  /**
16
16
  * The single per-session metadata record (the JSONL impl writes it to
17
17
  * `~/.moxxy/sessions/<id>.json`). ONE per session — the unit every surface
@@ -1 +1 @@
1
- {"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export type { TunnelProviderDef, TunnelHandle, TunnelOpenOptions } from './tunne
21
21
  export type { EventStoreDef, EventStoreSession, EventStoreScope, EventLogLike, EventPage, SessionMeta, SessionSource, } from './event-store.js';
22
22
  export { isRetryableError, toFriendlyError, zodToJsonSchema, estimateTextTokens, type StopReason } from './provider-utils.js';
23
23
  export type { WriteFileAtomicOptions } from './fs-utils.js';
24
+ export type { ChannelRunStatus } from './channel-status.js';
24
25
  export type { CrossProcessFireLock, CrossProcessFireLockOptions } from './cross-process-lock.js';
25
26
  export { createMutex, type Mutex } from './mutex.js';
26
27
  export { createJsonFileStore, type JsonFileStore, type JsonFileStoreOptions, } from './json-file-store.js';
@@ -46,7 +47,7 @@ export type { AppContext, TurnContext, ToolCallContext, ToolResultContext, ToolC
46
47
  export type { ServiceRegistry, NamedRegistry } from './services.js';
47
48
  export type { PluginKind, PluginSpec, Plugin, PluginManifest, ResolvedPluginManifest, } from './plugin.js';
48
49
  export { startChannelWith } from './channel.js';
49
- export type { Channel, ChannelHandle, ChannelStartArgs, ChannelStartOptsBase, ChannelFactoryDeps, ChannelDef, ChannelAvailability, ChannelRegistry, ChannelSubcommand, ChannelSubcommandContext, ChannelCommandArgs, } from './channel.js';
50
+ export type { Channel, ChannelHandle, ChannelStartArgs, ChannelStartOptsBase, ChannelFactoryDeps, ChannelDef, ChannelConfigField, ChannelConfigDescriptor, ChannelAvailability, ChannelRegistry, ChannelSubcommand, ChannelSubcommandContext, ChannelCommandArgs, } from './channel.js';
50
51
  export type { EmbeddingProvider, EmbedderDef } from './embedding.js';
51
52
  export { CachedEmbeddingProvider } from './embedding-cache.js';
52
53
  export { defineSurface } from './surface.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA6GjG,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA2BhD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAWpC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,GACX,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWpH,+DAA+D;AAC/D,0EAA0E;AAC1E,yEAAyE;AACzE,iEAAiE;AACjE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAmB,MAAM,qBAAqB,CAAC;AAI9H,OAAO,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AACrD,OAAO,EACL,mBAAmB,GAGpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI7D,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,gBAAgB,GAKjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,oBAAoB,GAGrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,cAAc,EACd,aAAa,GAQd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,0BAA0B,GAE3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GAGvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,GAEvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,GAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,GAEhB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,sBAAsB,EACtB,gCAAgC,EAChC,sBAAsB,EACtB,cAAc,EACd,gBAAgB,GAGjB,MAAM,uBAAuB,CAAC;AAyE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiBhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA+B7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAc1D,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EACd,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,WAAW,EACX,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE9D,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAIlB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,cAAc,GAGf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
package/dist/server.d.ts CHANGED
@@ -17,5 +17,7 @@
17
17
  export { writeFileAtomic, writeFileAtomicSync, moxxyHome, moxxyPath, } from './fs-utils.js';
18
18
  export { CrossProcessFireLock } from './cross-process-lock.js';
19
19
  export { readRequestBody, bearerTokenMatches } from './http-utils.js';
20
+ export { channelStatusPath, writeChannelStatus, readChannelStatus, clearChannelStatus, } from './channel-status.js';
21
+ export { spawnDedicatedChannel, isPidAlive, liveChannelStatus, listLiveChannelStatuses, stopDedicatedChannel, } from './channel-control.js';
20
22
  export { resolveChannelToken, rotateChannelToken, bearerGuard, encodeWsBearerProtocol, tokenFromWsProtocolHeader, MOXXY_WS_SUBPROTOCOL, MOXXY_WS_BEARER_PROTOCOL_PREFIX, } from './channel-auth.js';
21
23
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,SAAS,GACV,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,SAAS,GACV,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAItE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,mBAAmB,CAAC"}
package/dist/server.js CHANGED
@@ -19,5 +19,13 @@ export { writeFileAtomic, writeFileAtomicSync, moxxyHome, moxxyPath, } from './f
19
19
  // options type is re-exported from the main barrel like other erased types.
20
20
  export { CrossProcessFireLock } from './cross-process-lock.js';
21
21
  export { readRequestBody, bearerTokenMatches } from './http-utils.js';
22
+ // Dedicated-channel run-status file: a channel publishes readiness + its public
23
+ // ingest URL so the desktop "Channels" supervisor can observe it out-of-process
24
+ // (node:fs). The `ChannelRunStatus` *type* rides the main barrel like the others.
25
+ export { channelStatusPath, writeChannelStatus, readChannelStatus, clearChannelStatus, } from './channel-status.js';
26
+ // Process-independent control of dedicated channel runners (start detached,
27
+ // discover via status files, stop) — shared by the TUI `/channels` panel and the
28
+ // `moxxy channels start|stop|status` subcommands (node:child_process + node:fs).
29
+ export { spawnDedicatedChannel, isPidAlive, liveChannelStatus, listLiveChannelStatuses, stopDedicatedChannel, } from './channel-control.js';
22
30
  export { resolveChannelToken, rotateChannelToken, bearerGuard, encodeWsBearerProtocol, tokenFromWsProtocolHeader, MOXXY_WS_SUBPROTOCOL, MOXXY_WS_BEARER_PROTOCOL_PREFIX, } from './channel-auth.js';
23
31
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,0EAA0E;AAC1E,4EAA4E;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,0EAA0E;AAC1E,4EAA4E;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,gFAAgF;AAChF,gFAAgF;AAChF,kFAAkF;AAClF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,4EAA4E;AAC5E,iFAAiF;AACjF,iFAAiF;AACjF,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moxxy/sdk",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Typed public surface for the moxxy framework: event types, define* factories, lifecycle hook signatures.",
5
5
  "keywords": [
6
6
  "moxxy",
@@ -0,0 +1,141 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+
6
+ // `spawnDedicatedChannel` re-invokes the CLI via node:child_process — mock it so
7
+ // the test asserts the spawn shape without launching a real process. `vi.hoisted`
8
+ // makes the mock fn available to the hoisted `vi.mock` factory.
9
+ const { spawnMock } = vi.hoisted(() => ({
10
+ spawnMock: vi.fn(() => ({ pid: 4321, unref: (): void => {} })),
11
+ }));
12
+ vi.mock('node:child_process', () => ({ spawn: spawnMock }));
13
+
14
+ import {
15
+ isPidAlive,
16
+ listLiveChannelStatuses,
17
+ liveChannelStatus,
18
+ spawnDedicatedChannel,
19
+ stopDedicatedChannel,
20
+ } from './channel-control.js';
21
+ import { channelStatusPath, writeChannelStatus } from './channel-status.js';
22
+
23
+ // A pid that is essentially never alive (above the platform max) → ESRCH.
24
+ const DEAD_PID = 2_000_000_000;
25
+
26
+ let home: string;
27
+ let prevHome: string | undefined;
28
+
29
+ beforeEach(() => {
30
+ home = fs.mkdtempSync(path.join(os.tmpdir(), 'moxxy-channel-control-'));
31
+ prevHome = process.env.MOXXY_HOME;
32
+ process.env.MOXXY_HOME = home;
33
+ spawnMock.mockClear();
34
+ });
35
+
36
+ afterEach(() => {
37
+ if (prevHome === undefined) delete process.env.MOXXY_HOME;
38
+ else process.env.MOXXY_HOME = prevHome;
39
+ fs.rmSync(home, { recursive: true, force: true });
40
+ vi.restoreAllMocks();
41
+ });
42
+
43
+ describe('isPidAlive', () => {
44
+ it('is true for the current process, false for a dead/invalid pid', () => {
45
+ expect(isPidAlive(process.pid)).toBe(true);
46
+ expect(isPidAlive(DEAD_PID)).toBe(false);
47
+ expect(isPidAlive(0)).toBe(false);
48
+ expect(isPidAlive(-1)).toBe(false);
49
+ });
50
+ });
51
+
52
+ describe('liveChannelStatus', () => {
53
+ it('returns null when no status file exists', () => {
54
+ expect(liveChannelStatus('slack')).toBeNull();
55
+ });
56
+
57
+ it('returns the status when the runner pid is alive', () => {
58
+ writeChannelStatus({
59
+ name: 'slack',
60
+ pid: process.pid,
61
+ startedAt: new Date().toISOString(),
62
+ requestUrl: 'https://example.test/slack',
63
+ });
64
+ const s = liveChannelStatus('slack');
65
+ expect(s?.pid).toBe(process.pid);
66
+ expect(s?.requestUrl).toBe('https://example.test/slack');
67
+ });
68
+
69
+ it('self-heals a stale file (dead pid) — returns null AND removes it', () => {
70
+ writeChannelStatus({ name: 'ghost', pid: DEAD_PID, startedAt: new Date().toISOString() });
71
+ expect(fs.existsSync(channelStatusPath('ghost'))).toBe(true);
72
+ expect(liveChannelStatus('ghost')).toBeNull();
73
+ expect(fs.existsSync(channelStatusPath('ghost'))).toBe(false);
74
+ });
75
+ });
76
+
77
+ describe('listLiveChannelStatuses', () => {
78
+ it('returns only live channels, drops stale files, ignores unrelated files', () => {
79
+ writeChannelStatus({ name: 'slack', pid: process.pid, startedAt: new Date().toISOString() });
80
+ writeChannelStatus({ name: 'telegram', pid: process.pid, startedAt: new Date().toISOString() });
81
+ writeChannelStatus({ name: 'ghost', pid: DEAD_PID, startedAt: new Date().toISOString() });
82
+ fs.writeFileSync(path.join(home, 'vault.json'), '{}'); // unrelated file in ~/.moxxy
83
+
84
+ const names = listLiveChannelStatuses()
85
+ .map((s) => s.name)
86
+ .sort();
87
+ expect(names).toEqual(['slack', 'telegram']);
88
+ expect(fs.existsSync(channelStatusPath('ghost'))).toBe(false);
89
+ });
90
+
91
+ it('returns [] when the home dir does not exist', () => {
92
+ process.env.MOXXY_HOME = path.join(home, 'does-not-exist');
93
+ expect(listLiveChannelStatuses()).toEqual([]);
94
+ });
95
+ });
96
+
97
+ describe('stopDedicatedChannel', () => {
98
+ it('reports not-running when there is no live status', () => {
99
+ expect(stopDedicatedChannel('slack')).toBe('not-running');
100
+ });
101
+
102
+ it('SIGTERMs the live runner and reports stopped', () => {
103
+ // Intercept kill so the liveness probe (signal 0) reports alive and the
104
+ // SIGTERM is recorded rather than actually delivered.
105
+ const killSpy = vi
106
+ .spyOn(process, 'kill')
107
+ .mockImplementation(((_pid: number, _sig?: string | number) => true) as typeof process.kill);
108
+ writeChannelStatus({ name: 'slack', pid: 999_999, startedAt: new Date().toISOString() });
109
+
110
+ expect(stopDedicatedChannel('slack')).toBe('stopped');
111
+ expect(killSpy).toHaveBeenCalledWith(999_999, 'SIGTERM');
112
+ });
113
+ });
114
+
115
+ describe('spawnDedicatedChannel', () => {
116
+ it('spawns a detached, dedicated runner with a scrubbed env', () => {
117
+ process.env.MOXXY_RUNNER_SOCKET = '/tmp/should-be-scrubbed.sock';
118
+ process.env.MOXXY_SESSION_ID = 'should-be-scrubbed';
119
+ try {
120
+ const pid = spawnDedicatedChannel('slack');
121
+ expect(pid).toBe(4321);
122
+ expect(spawnMock).toHaveBeenCalledTimes(1);
123
+ const [bin, argsArg, optsArg] = spawnMock.mock.calls[0] as [
124
+ string,
125
+ string[],
126
+ { detached?: boolean; stdio?: string; env?: NodeJS.ProcessEnv },
127
+ ];
128
+ expect(bin).toBe(process.execPath);
129
+ expect(argsArg).toEqual([process.argv[1], 'slack']);
130
+ expect(optsArg.detached).toBe(true);
131
+ expect(optsArg.stdio).toBe('ignore');
132
+ // Dedicated flag set; addressing vars scrubbed so the channel isolates.
133
+ expect(optsArg.env?.MOXXY_DEDICATED_RUNNER).toBe('1');
134
+ expect(optsArg.env?.MOXXY_RUNNER_SOCKET).toBeUndefined();
135
+ expect(optsArg.env?.MOXXY_SESSION_ID).toBeUndefined();
136
+ } finally {
137
+ delete process.env.MOXXY_RUNNER_SOCKET;
138
+ delete process.env.MOXXY_SESSION_ID;
139
+ }
140
+ });
141
+ });
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Process-independent control surface for dedicated channel runners.
3
+ *
4
+ * A dedicated channel (Slack, Telegram, …) runs as its OWN isolated runner
5
+ * subprocess that publishes a tiny status file (`channel-<name>.status.json`,
6
+ * see {@link ./channel-status}) on ready and clears it on graceful shutdown. That
7
+ * file — NOT a held child handle — is the source of truth for "is it running",
8
+ * so a channel started from anywhere (the TUI `/channels` panel, `moxxy channels
9
+ * start`, the desktop panel) is visible and stoppable from everywhere, and keeps
10
+ * running after the launcher exits.
11
+ *
12
+ * These helpers are the shared spine for those surfaces:
13
+ * - {@link spawnDedicatedChannel} — start one, detached, on its own runner.
14
+ * - {@link liveChannelStatus}/{@link listLiveChannelStatuses} — discover the
15
+ * running ones (with stale-file self-healing).
16
+ * - {@link stopDedicatedChannel} — signal one to stop.
17
+ *
18
+ * Node-only (`node:child_process`, `node:fs`) — exported from `@moxxy/sdk/server`.
19
+ */
20
+
21
+ import { spawn } from 'node:child_process';
22
+ import { readdirSync } from 'node:fs';
23
+
24
+ import {
25
+ type ChannelRunStatus,
26
+ clearChannelStatus,
27
+ readChannelStatus,
28
+ } from './channel-status.js';
29
+ import { moxxyHome } from './fs-utils.js';
30
+
31
+ /** Env vars that ADDRESS a runner (socket + sticky session). We scrub these from
32
+ * a spawned channel's env so `applyDedicatedRunnerEnv` (which only fills UNSET
33
+ * vars) derives the channel's OWN isolated socket/session from its name — rather
34
+ * than the channel silently inheriting and sharing the launcher's runner. */
35
+ const ADDRESSING_ENV = ['MOXXY_RUNNER_SOCKET', 'MOXXY_SESSION_ID', 'MOXXY_SESSION_SOURCE'] as const;
36
+
37
+ /**
38
+ * Start a channel on its own dedicated, detached runner by re-invoking this very
39
+ * moxxy binary as `moxxy <name>` with `MOXXY_DEDICATED_RUNNER=1`. The child is
40
+ * `detached` + `unref`'d with no stdio, so it OUTLIVES the launcher (the user can
41
+ * quit the TUI and the bot keeps serving) and reports itself via its status file.
42
+ *
43
+ * Returns the child pid, or undefined if the spawn produced none. Throws if the
44
+ * moxxy CLI entry can't be resolved (no `process.argv[1]`).
45
+ *
46
+ * Caller's job (this is fire-and-forget): poll {@link liveChannelStatus} to learn
47
+ * when it's ready / failed (no status file within a timeout ⇒ it died on boot —
48
+ * re-run `moxxy <name>` in the foreground to see why).
49
+ */
50
+ export function spawnDedicatedChannel(name: string): number | undefined {
51
+ const node = process.execPath; // the running Node binary (pnpm `moxxy` launches via Node)
52
+ const entry = process.argv[1]; // the resolved CLI entry (…/cli/dist/bin.js)
53
+ if (!entry) {
54
+ throw new Error('cannot start a channel: the moxxy CLI entry is unknown (process.argv[1] missing)');
55
+ }
56
+
57
+ const env: NodeJS.ProcessEnv = { ...process.env, MOXXY_DEDICATED_RUNNER: '1' };
58
+ for (const key of ADDRESSING_ENV) delete env[key];
59
+
60
+ const child = spawn(node, [entry, name], { detached: true, stdio: 'ignore', env });
61
+ child.unref();
62
+ return child.pid;
63
+ }
64
+
65
+ /**
66
+ * Is `pid` a live process? `kill(pid, 0)` sends no signal — it only probes:
67
+ * - resolves ⇒ alive,
68
+ * - `ESRCH` ⇒ gone,
69
+ * - `EPERM` ⇒ alive but owned by another user (treat as alive — it exists).
70
+ */
71
+ export function isPidAlive(pid: number): boolean {
72
+ if (!Number.isInteger(pid) || pid <= 0) return false;
73
+ try {
74
+ process.kill(pid, 0);
75
+ return true;
76
+ } catch (err) {
77
+ return (err as NodeJS.ErrnoException).code === 'EPERM';
78
+ }
79
+ }
80
+
81
+ /**
82
+ * The status of channel `name` IF it is actually running. Reads its status file
83
+ * and verifies the pid is alive; a file whose pid is dead (the runner crashed or
84
+ * was SIGKILL'd without clearing it) is treated as not-running AND removed, so a
85
+ * stale file never masquerades as a live channel.
86
+ */
87
+ export function liveChannelStatus(name: string): ChannelRunStatus | null {
88
+ const status = readChannelStatus(name);
89
+ if (!status) return null;
90
+ if (!isPidAlive(status.pid)) {
91
+ clearChannelStatus(name);
92
+ return null;
93
+ }
94
+ return status;
95
+ }
96
+
97
+ /** The channel name encoded in a `channel-<name>.status.json` file, or null. */
98
+ function statusFileChannelName(file: string): string | null {
99
+ const m = /^channel-(.+)\.status\.json$/.exec(file);
100
+ return m ? (m[1] ?? null) : null;
101
+ }
102
+
103
+ /**
104
+ * Every currently-running dedicated channel, discovered by scanning the moxxy
105
+ * home for status files and filtering to live pids (self-healing stale ones).
106
+ * Returns [] when the home dir doesn't exist yet.
107
+ */
108
+ export function listLiveChannelStatuses(): ChannelRunStatus[] {
109
+ let files: string[];
110
+ try {
111
+ files = readdirSync(moxxyHome());
112
+ } catch {
113
+ return []; // no ~/.moxxy yet ⇒ nothing running
114
+ }
115
+ const live: ChannelRunStatus[] = [];
116
+ for (const file of files) {
117
+ const name = statusFileChannelName(file);
118
+ if (!name) continue;
119
+ const status = liveChannelStatus(name);
120
+ if (status) live.push(status);
121
+ }
122
+ return live;
123
+ }
124
+
125
+ /**
126
+ * Ask channel `name` to stop by SIGTERM-ing its runner. The runner's own signal
127
+ * handler tears down gracefully and clears its status file. Returns `'stopped'`
128
+ * if a live runner was signaled, `'not-running'` if there was nothing to stop.
129
+ *
130
+ * This is a single, synchronous SIGTERM — callers that want a hard backstop poll
131
+ * {@link liveChannelStatus} afterwards and escalate (SIGKILL + {@link clearChannelStatus})
132
+ * if it ignores the term within a grace period.
133
+ */
134
+ export function stopDedicatedChannel(name: string): 'stopped' | 'not-running' {
135
+ const status = liveChannelStatus(name);
136
+ if (!status) return 'not-running';
137
+ try {
138
+ process.kill(status.pid, 'SIGTERM');
139
+ } catch {
140
+ // Raced us to exit between the liveness check and here — already stopped.
141
+ clearChannelStatus(name);
142
+ }
143
+ return 'stopped';
144
+ }
@@ -0,0 +1,55 @@
1
+ import { readFileSync, rmSync } from 'node:fs';
2
+
3
+ import { moxxyPath, writeFileAtomicSync } from './fs-utils.js';
4
+
5
+ /**
6
+ * The on-disk status a dedicated channel runner publishes so an out-of-process
7
+ * supervisor (the desktop "Channels" panel) can observe it without the runner
8
+ * protocol. Written by `moxxy <channel>` when it self-hosts a dedicated runner,
9
+ * read by the desktop host; removed on graceful shutdown.
10
+ *
11
+ * It is intentionally tiny — readiness + the public ingest URL — not a mirror of
12
+ * the session. The supervisor owns liveness (it holds the child handle); this
13
+ * file is the channel's own report of "I'm up, and here's the URL to paste".
14
+ */
15
+ export interface ChannelRunStatus {
16
+ /** Channel name (e.g. `slack`, `telegram`). */
17
+ readonly name: string;
18
+ /** PID of the channel runner process. */
19
+ readonly pid: number;
20
+ /** ISO timestamp the channel reported ready. */
21
+ readonly startedAt: string;
22
+ /** The session source the runner stamped (e.g. `slack`). */
23
+ readonly source?: string;
24
+ /** Public ingest URL (e.g. Slack's Events Request URL) once the tunnel is up;
25
+ * null for channels with no inbound endpoint (Telegram long-polls). */
26
+ readonly requestUrl?: string | null;
27
+ }
28
+
29
+ /** `~/.moxxy/channel-<name>.status.json` (honors `$MOXXY_HOME`). */
30
+ export function channelStatusPath(name: string): string {
31
+ return moxxyPath(`channel-${name}.status.json`);
32
+ }
33
+
34
+ /** Atomically publish a channel's run status (0600 — it may carry a URL). */
35
+ export function writeChannelStatus(status: ChannelRunStatus): void {
36
+ writeFileAtomicSync(channelStatusPath(status.name), JSON.stringify(status), { mode: 0o600 });
37
+ }
38
+
39
+ /** Read a channel's published status, or null if absent/unparseable. */
40
+ export function readChannelStatus(name: string): ChannelRunStatus | null {
41
+ try {
42
+ return JSON.parse(readFileSync(channelStatusPath(name), 'utf8')) as ChannelRunStatus;
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+
48
+ /** Remove a channel's status file (best-effort; called on graceful shutdown). */
49
+ export function clearChannelStatus(name: string): void {
50
+ try {
51
+ rmSync(channelStatusPath(name), { force: true });
52
+ } catch {
53
+ /* best-effort */
54
+ }
55
+ }
package/src/channel.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { PermissionResolver } from './permission.js';
2
2
  import type { ClientSession } from './client-session.js';
3
+ import type { SessionSource } from './event-store.js';
3
4
 
4
5
  /**
5
6
  * A Channel is a bidirectional surface that drives a Session: it feeds user
@@ -25,6 +26,15 @@ export interface Channel<TStartOpts = unknown> {
25
26
  * resolves when the channel exits gracefully.
26
27
  */
27
28
  start(opts: TStartOpts): Promise<ChannelHandle>;
29
+
30
+ /**
31
+ * The public ingest URL this channel exposes once running — e.g. Slack's
32
+ * Events Request URL after its proxy tunnel opens — or null when it has none
33
+ * (Telegram long-polls). Read by the dedicated-runner host to publish the URL
34
+ * the user must paste into the provider's config. Optional: channels with no
35
+ * inbound endpoint omit it.
36
+ */
37
+ readonly requestUrl?: string | null;
28
38
  }
29
39
 
30
40
  export interface ChannelHandle {
@@ -134,6 +144,63 @@ export interface ChannelDef<TStartOpts = unknown> {
134
144
  * starts the channel.
135
145
  */
136
146
  readonly interactiveCommand?: string;
147
+ /**
148
+ * Declare that this channel runs on its OWN dedicated, isolated runner: a
149
+ * distinct runner socket (`channel-<name>.sock`) + a stable sticky session id
150
+ * (`moxxy-channel-<name>`), so the channel acts as its own agent thread,
151
+ * separate from whatever runner serves the desktop/TUI. NO runner-protocol
152
+ * change — one dedicated runner is still one Session. Channels that should
153
+ * operate autonomously (slack, telegram) set this; the CLI reads it generically
154
+ * (see `applyDedicatedRunnerEnv`) so no per-channel name list is needed. Any
155
+ * channel can also opt in at runtime via `--dedicated` / `MOXXY_DEDICATED_RUNNER=1`.
156
+ */
157
+ readonly dedicatedRunner?: boolean;
158
+ /**
159
+ * The {@link SessionSource} to stamp on this channel's sessions when it runs
160
+ * dedicated (persisted into the meta sidecar; surfaces filter history by it).
161
+ * Only honored alongside `dedicatedRunner`. When unset, the source falls back
162
+ * to the usual env/default resolution.
163
+ */
164
+ readonly sessionSource?: SessionSource;
165
+ /**
166
+ * Declarative config the channel needs to run (its secret fields + where they
167
+ * live in the vault, plus pairing hints). This is what a control surface — the
168
+ * TUI `/channels` panel, `moxxy channels start`, the desktop "Channels" panel —
169
+ * renders to let the user configure + start the channel WITHOUT hardcoding a
170
+ * per-channel table. The channel self-describes here; the vault keys named are
171
+ * the same ones the channel actually reads at boot (its `keys.ts`). Channels
172
+ * with no setup (web/http) omit this.
173
+ */
174
+ readonly config?: ChannelConfigDescriptor;
175
+ }
176
+
177
+ /** One secret/config input a channel exposes for a control surface to collect. */
178
+ export interface ChannelConfigField {
179
+ /** Option key (e.g. `botToken`). Stable identifier within the channel. */
180
+ readonly name: string;
181
+ /** Short human label (e.g. `Bot token`). */
182
+ readonly label: string;
183
+ /** The vault key the channel reads this value from (e.g. `slack_bot_token`). */
184
+ readonly vaultKey: string;
185
+ /** Must be present for the channel to count as "configured". */
186
+ readonly required?: boolean;
187
+ /** Treat as a secret — mask the input and never echo the stored value. */
188
+ readonly secret?: boolean;
189
+ /** Placeholder shown in an empty input (e.g. `xoxb-…`). */
190
+ readonly placeholder?: string;
191
+ /** One-line guidance on where to obtain the value. */
192
+ readonly help?: string;
193
+ }
194
+
195
+ /** What a channel declares about being configured + run from a control surface. */
196
+ export interface ChannelConfigDescriptor {
197
+ /** The fields to collect, in display order. */
198
+ readonly fields: ReadonlyArray<ChannelConfigField>;
199
+ /** The channel exposes a public ingest URL (Slack's Request URL) once started,
200
+ * so a control surface should poll for + surface it. */
201
+ readonly hasRequestUrl?: boolean;
202
+ /** Post-start pairing/setup instructions to show the user. */
203
+ readonly runHint?: string;
137
204
  }
138
205
 
139
206
  export interface ChannelAvailability {
@@ -13,7 +13,7 @@ import type { SessionId } from './ids.js';
13
13
  */
14
14
 
15
15
  /** Originating channel of a session (persisted into the meta sidecar). */
16
- export type SessionSource = 'cli' | 'tui' | 'desktop' | 'mobile';
16
+ export type SessionSource = 'cli' | 'tui' | 'desktop' | 'mobile' | 'slack' | 'telegram';
17
17
 
18
18
  /**
19
19
  * The single per-session metadata record (the JSONL impl writes it to
package/src/index.ts CHANGED
@@ -194,6 +194,7 @@ export type {
194
194
  // builtins and would break a browser/RN bundle. See ./server.ts.
195
195
  export { isRetryableError, toFriendlyError, zodToJsonSchema, estimateTextTokens, type StopReason } from './provider-utils.js';
196
196
  export type { WriteFileAtomicOptions } from './fs-utils.js';
197
+ export type { ChannelRunStatus } from './channel-status.js';
197
198
  export type { CrossProcessFireLock, CrossProcessFireLockOptions } from './cross-process-lock.js';
198
199
  export { createMutex, type Mutex } from './mutex.js';
199
200
  export {
@@ -372,6 +373,8 @@ export type {
372
373
  ChannelStartOptsBase,
373
374
  ChannelFactoryDeps,
374
375
  ChannelDef,
376
+ ChannelConfigField,
377
+ ChannelConfigDescriptor,
375
378
  ChannelAvailability,
376
379
  ChannelRegistry,
377
380
  ChannelSubcommand,
package/src/server.ts CHANGED
@@ -25,6 +25,25 @@ export {
25
25
  // options type is re-exported from the main barrel like other erased types.
26
26
  export { CrossProcessFireLock } from './cross-process-lock.js';
27
27
  export { readRequestBody, bearerTokenMatches } from './http-utils.js';
28
+ // Dedicated-channel run-status file: a channel publishes readiness + its public
29
+ // ingest URL so the desktop "Channels" supervisor can observe it out-of-process
30
+ // (node:fs). The `ChannelRunStatus` *type* rides the main barrel like the others.
31
+ export {
32
+ channelStatusPath,
33
+ writeChannelStatus,
34
+ readChannelStatus,
35
+ clearChannelStatus,
36
+ } from './channel-status.js';
37
+ // Process-independent control of dedicated channel runners (start detached,
38
+ // discover via status files, stop) — shared by the TUI `/channels` panel and the
39
+ // `moxxy channels start|stop|status` subcommands (node:child_process + node:fs).
40
+ export {
41
+ spawnDedicatedChannel,
42
+ isPidAlive,
43
+ liveChannelStatus,
44
+ listLiveChannelStatuses,
45
+ stopDedicatedChannel,
46
+ } from './channel-control.js';
28
47
  export {
29
48
  resolveChannelToken,
30
49
  rotateChannelToken,