@cello-protocol/daemon 0.0.52 → 0.0.54
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/dist/agent-handlers.d.ts +57 -0
- package/dist/agent-handlers.d.ts.map +1 -0
- package/dist/agent-handlers.js +360 -0
- package/dist/agent-handlers.js.map +1 -0
- package/dist/agent-id-migration.d.ts.map +1 -1
- package/dist/agent-id-migration.js +1 -0
- package/dist/agent-id-migration.js.map +1 -1
- package/dist/agent-loader.d.ts +3 -4
- package/dist/agent-loader.d.ts.map +1 -1
- package/dist/agent-loader.js +3 -4
- package/dist/agent-loader.js.map +1 -1
- package/dist/cbor-blob-migration.d.ts +8 -0
- package/dist/cbor-blob-migration.d.ts.map +1 -0
- package/dist/cbor-blob-migration.js +115 -0
- package/dist/cbor-blob-migration.js.map +1 -0
- package/dist/close-session-handler.d.ts +41 -0
- package/dist/close-session-handler.d.ts.map +1 -0
- package/dist/close-session-handler.js +399 -0
- package/dist/close-session-handler.js.map +1 -0
- package/dist/consortium-bootstrap.d.ts +83 -0
- package/dist/consortium-bootstrap.d.ts.map +1 -0
- package/dist/consortium-bootstrap.js +120 -0
- package/dist/consortium-bootstrap.js.map +1 -0
- package/dist/contact-handlers.d.ts +56 -0
- package/dist/contact-handlers.d.ts.map +1 -0
- package/dist/contact-handlers.js +303 -0
- package/dist/contact-handlers.js.map +1 -0
- package/dist/content-park-client.d.ts.map +1 -1
- package/dist/content-park-client.js +7 -7
- package/dist/content-park-client.js.map +1 -1
- package/dist/content-park.d.ts +15 -0
- package/dist/content-park.d.ts.map +1 -0
- package/dist/content-park.js +227 -0
- package/dist/content-park.js.map +1 -0
- package/dist/daemon.d.ts +0 -11
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +407 -4552
- package/dist/daemon.js.map +1 -1
- package/dist/db-identity-store.d.ts +31 -35
- package/dist/db-identity-store.d.ts.map +1 -1
- package/dist/db-identity-store.js +62 -66
- package/dist/db-identity-store.js.map +1 -1
- package/dist/directory-bootstrap.d.ts +27 -31
- package/dist/directory-bootstrap.d.ts.map +1 -1
- package/dist/directory-bootstrap.js +18 -21
- package/dist/directory-bootstrap.js.map +1 -1
- package/dist/frame-values.d.ts +3 -0
- package/dist/frame-values.d.ts.map +1 -0
- package/dist/frame-values.js +73 -0
- package/dist/frame-values.js.map +1 -0
- package/dist/identity-migration.d.ts +8 -8
- package/dist/identity-migration.d.ts.map +1 -1
- package/dist/identity-migration.js +30 -31
- package/dist/identity-migration.js.map +1 -1
- package/dist/inbound-seal-request.d.ts +17 -0
- package/dist/inbound-seal-request.d.ts.map +1 -0
- package/dist/inbound-seal-request.js +155 -0
- package/dist/inbound-seal-request.js.map +1 -0
- package/dist/inbound-sessions.d.ts +54 -0
- package/dist/inbound-sessions.d.ts.map +1 -0
- package/dist/inbound-sessions.js +603 -0
- package/dist/inbound-sessions.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/dist/initiate-session-handler.d.ts +22 -0
- package/dist/initiate-session-handler.d.ts.map +1 -0
- package/dist/initiate-session-handler.js +150 -0
- package/dist/initiate-session-handler.js.map +1 -0
- package/dist/network-directory-node.d.ts +6 -6
- package/dist/network-directory-node.d.ts.map +1 -1
- package/dist/network-directory-node.js +29 -28
- package/dist/network-directory-node.js.map +1 -1
- package/dist/notification-handlers.d.ts +32 -0
- package/dist/notification-handlers.d.ts.map +1 -0
- package/dist/notification-handlers.js +73 -0
- package/dist/notification-handlers.js.map +1 -0
- package/dist/outbound-sessions.d.ts +54 -0
- package/dist/outbound-sessions.d.ts.map +1 -0
- package/dist/outbound-sessions.js +429 -0
- package/dist/outbound-sessions.js.map +1 -0
- package/dist/park-envelope.d.ts.map +1 -1
- package/dist/park-envelope.js +3 -2
- package/dist/park-envelope.js.map +1 -1
- package/dist/register-handler.d.ts +35 -0
- package/dist/register-handler.d.ts.map +1 -0
- package/dist/register-handler.js +179 -0
- package/dist/register-handler.js.map +1 -0
- package/dist/registration-manager.d.ts.map +1 -1
- package/dist/registration-manager.js +3 -6
- package/dist/registration-manager.js.map +1 -1
- package/dist/relay-receipt-store.d.ts.map +1 -1
- package/dist/relay-receipt-store.js +1 -2
- package/dist/relay-receipt-store.js.map +1 -1
- package/dist/retry-queue.d.ts +18 -60
- package/dist/retry-queue.d.ts.map +1 -1
- package/dist/retry-queue.js +46 -97
- package/dist/retry-queue.js.map +1 -1
- package/dist/seal-coordinator.d.ts +47 -0
- package/dist/seal-coordinator.d.ts.map +1 -0
- package/dist/seal-coordinator.js +551 -0
- package/dist/seal-coordinator.js.map +1 -0
- package/dist/seal-flows.d.ts +50 -0
- package/dist/seal-flows.d.ts.map +1 -0
- package/dist/seal-flows.js +454 -0
- package/dist/seal-flows.js.map +1 -0
- package/dist/seal-frontier-verify.d.ts +9 -9
- package/dist/seal-frontier-verify.d.ts.map +1 -1
- package/dist/seal-frontier-verify.js +11 -12
- package/dist/seal-frontier-verify.js.map +1 -1
- package/dist/seal-leaf.d.ts +58 -0
- package/dist/seal-leaf.d.ts.map +1 -0
- package/dist/seal-leaf.js +111 -0
- package/dist/seal-leaf.js.map +1 -0
- package/dist/seal-receipt-upgrade.d.ts +1 -1
- package/dist/seal-receipt-upgrade.js +1 -1
- package/dist/seal-upgrade.d.ts +10 -10
- package/dist/seal-upgrade.d.ts.map +1 -1
- package/dist/seal-upgrade.js +23 -24
- package/dist/seal-upgrade.js.map +1 -1
- package/dist/session-assignment-parser.d.ts +16 -19
- package/dist/session-assignment-parser.d.ts.map +1 -1
- package/dist/session-assignment-parser.js +30 -29
- package/dist/session-assignment-parser.js.map +1 -1
- package/dist/session-ceremony.d.ts +3 -6
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +7 -9
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-content-handlers.d.ts +25 -0
- package/dist/session-content-handlers.d.ts.map +1 -0
- package/dist/session-content-handlers.js +436 -0
- package/dist/session-content-handlers.js.map +1 -0
- package/dist/session-name.d.ts +35 -0
- package/dist/session-name.d.ts.map +1 -0
- package/dist/session-name.js +60 -0
- package/dist/session-name.js.map +1 -0
- package/dist/session-node-manager.d.ts +26 -62
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +115 -92
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-read-handlers.d.ts +38 -0
- package/dist/session-read-handlers.d.ts.map +1 -0
- package/dist/session-read-handlers.js +233 -0
- package/dist/session-read-handlers.js.map +1 -0
- package/dist/session-relay-client.d.ts +8 -8
- package/dist/session-relay-client.d.ts.map +1 -1
- package/dist/session-relay-client.js +44 -46
- package/dist/session-relay-client.js.map +1 -1
- package/dist/session-tree.d.ts +11 -23
- package/dist/session-tree.d.ts.map +1 -1
- package/dist/session-tree.js +14 -26
- package/dist/session-tree.js.map +1 -1
- package/dist/signaling-connect.d.ts +2 -5
- package/dist/signaling-connect.d.ts.map +1 -1
- package/dist/signaling-connect.js +7 -12
- package/dist/signaling-connect.js.map +1 -1
- package/dist/sqlcipher-db.d.ts +18 -19
- package/dist/sqlcipher-db.d.ts.map +1 -1
- package/dist/sqlcipher-db.js +30 -30
- package/dist/sqlcipher-db.js.map +1 -1
- package/dist/telegram-doorbell.d.ts +38 -0
- package/dist/telegram-doorbell.d.ts.map +1 -0
- package/dist/telegram-doorbell.js +139 -0
- package/dist/telegram-doorbell.js.map +1 -0
- package/dist/types.d.ts +86 -79
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/dist/vocabulary.d.ts +30 -30
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +41 -49
- package/dist/vocabulary.js.map +1 -1
- package/package.json +5 -5
package/dist/sqlcipher-db.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The daemon's single encrypted store.
|
|
3
3
|
*
|
|
4
4
|
* The daemon DB is a SQLCipher database (whole-file AES-256 at rest). This module is the ONE
|
|
5
|
-
* engine site: it loads @signalapp/sqlcipher (prebuilt —
|
|
5
|
+
* engine site: it loads @signalapp/sqlcipher (prebuilt — never compiled from source), opens the DB with a
|
|
6
6
|
* PRAGMA key, verifies the key, enables WAL, and presents a thin `DaemonDatabase` adapter so the
|
|
7
7
|
* rest of the daemon (SessionNodeManager, RetryQueue, NonceDedupStore) keeps its node:sqlite-style
|
|
8
8
|
* varargs call sites unchanged.
|
|
@@ -13,19 +13,18 @@
|
|
|
13
13
|
* satisfies them too (used for in-memory test handles and for reading a legacy plaintext DB during
|
|
14
14
|
* migration), and `SqlcipherDatabase` implements them by forwarding varargs as an array.
|
|
15
15
|
*
|
|
16
|
-
* Key custody
|
|
17
|
-
*
|
|
18
|
-
* the
|
|
16
|
+
* Key custody: the SQLCipher key is a standalone random 32-byte 0600 key file beside the DB. It is
|
|
17
|
+
* NOT derived from K_local — that is a chicken-and-egg, since K_local itself lives inside the DB. It
|
|
18
|
+
* is the ONE plaintext key file on disk.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* FAILS CLOSED: there is no plaintext fallback anywhere. A wrong/missing key on an existing DB throws
|
|
21
|
+
* `db_encryption_key_mismatch`; the daemon never opens, creates, or migrates to a plaintext store as
|
|
22
|
+
* a fallback.
|
|
23
23
|
*
|
|
24
24
|
* Security invariants:
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* encrypted at rest.
|
|
25
|
+
* - The db key is NEVER logged, serialized, or placed in an error message — only the raw
|
|
26
|
+
* `PRAGMA key` string uses the hex, and that string is never logged.
|
|
27
|
+
* - WAL mode is enabled only AFTER key verification, so WAL files are encrypted at rest.
|
|
29
28
|
*/
|
|
30
29
|
import { createRequire } from "node:module";
|
|
31
30
|
import { existsSync, readFileSync, readSync, openSync, writeSync, fsyncSync, closeSync, renameSync, mkdirSync, unlinkSync, } from "node:fs";
|
|
@@ -79,8 +78,8 @@ class SqlcipherDatabase {
|
|
|
79
78
|
}
|
|
80
79
|
// ─── The raw SQLite magic — used to distinguish a plaintext DB from an encrypted one ──
|
|
81
80
|
// A plaintext SQLite file begins with "SQLite format 3\0". A SQLCipher database encrypts the
|
|
82
|
-
// header too, so its first bytes are ciphertext and never match. The migration path
|
|
83
|
-
//
|
|
81
|
+
// header too, so its first bytes are ciphertext and never match. The migration path uses this to
|
|
82
|
+
// detect a legacy plaintext DB that must be migrated.
|
|
84
83
|
const SQLITE_MAGIC = Buffer.concat([Buffer.from("SQLite format 3", "latin1"), Buffer.from([0x00])]);
|
|
85
84
|
/** True when the file at `dbPath` exists and is an UNENCRYPTED node:sqlite database. */
|
|
86
85
|
export function isPlaintextSqliteFile(dbPath) {
|
|
@@ -104,16 +103,16 @@ export function isPlaintextSqliteFile(dbPath) {
|
|
|
104
103
|
}
|
|
105
104
|
return head.equals(SQLITE_MAGIC);
|
|
106
105
|
}
|
|
107
|
-
// ─── Key custody
|
|
106
|
+
// ─── Key custody ─────────────────────────────────────────────────────────────────
|
|
108
107
|
/**
|
|
109
108
|
* Resolve the SQLCipher key, generating it on a genuinely fresh install only.
|
|
110
109
|
*
|
|
111
|
-
* Fail-closed matrix
|
|
110
|
+
* Fail-closed matrix:
|
|
112
111
|
* key present → load it (must be 32 bytes).
|
|
113
112
|
* key absent + DB absent → generate + persist (0600), proceed (fresh install).
|
|
114
113
|
* key absent + DB present → THROW db_encryption_key_mismatch (never overwrite an
|
|
115
114
|
* existing DB with a new key — that would be data loss; and
|
|
116
|
-
* a
|
|
115
|
+
* a legacy PLAINTEXT DB must be migrated first, not opened).
|
|
117
116
|
*/
|
|
118
117
|
export function resolveDbKey(dbPath, keyPath) {
|
|
119
118
|
if (existsSync(keyPath)) {
|
|
@@ -137,8 +136,8 @@ export function resolveDbKey(dbPath, keyPath) {
|
|
|
137
136
|
fsyncSync(fd);
|
|
138
137
|
}
|
|
139
138
|
catch (err) {
|
|
140
|
-
// Never leave a stray plaintext key fragment on disk if the write/fsync failed partway
|
|
141
|
-
//
|
|
139
|
+
// Never leave a stray plaintext key fragment on disk if the write/fsync failed partway — the
|
|
140
|
+
// only plaintext key on disk is the one sanctioned key file.
|
|
142
141
|
closeSync(fd);
|
|
143
142
|
try {
|
|
144
143
|
unlinkSync(tmp);
|
|
@@ -179,9 +178,9 @@ export function resolveDbKey(dbPath, keyPath) {
|
|
|
179
178
|
}
|
|
180
179
|
// ─── Open ────────────────────────────────────────────────────────────────────────
|
|
181
180
|
/**
|
|
182
|
-
* Load the SQLCipher native module. Exported because the daemon's singleton lock
|
|
183
|
-
*
|
|
184
|
-
*
|
|
181
|
+
* Load the SQLCipher native module. Exported because the daemon's singleton lock needs the same
|
|
182
|
+
* engine for its kernel-level file lock — one place that knows how to load the prebuilt, and one
|
|
183
|
+
* error when it will not load.
|
|
185
184
|
*/
|
|
186
185
|
export function loadSignalModule() {
|
|
187
186
|
const require = createRequire(import.meta.url);
|
|
@@ -196,7 +195,7 @@ export function loadSignalModule() {
|
|
|
196
195
|
/**
|
|
197
196
|
* Open `dbPath` as a SQLCipher database keyed by `dbKey`. Verifies the key (reads sqlite_master)
|
|
198
197
|
* and enables WAL after verification. Throws DbEncryptionError on any failure — never returns a
|
|
199
|
-
* plaintext handle
|
|
198
|
+
* plaintext handle.
|
|
200
199
|
*/
|
|
201
200
|
export function openEncryptedDatabase(dbPath, dbKey, logger) {
|
|
202
201
|
const mod = loadSignalModule();
|
|
@@ -209,9 +208,10 @@ export function openEncryptedDatabase(dbPath, dbKey, logger) {
|
|
|
209
208
|
const reason = err instanceof Error ? err.message : String(err);
|
|
210
209
|
throw new DbEncryptionError("db_open_failed", reason, `Could not open the database file at ${dbPath}.`);
|
|
211
210
|
}
|
|
212
|
-
//
|
|
213
|
-
// thrown/logged error string even if a future SQLCipher build echoed the pragma
|
|
214
|
-
// A well-formed `key` pragma does not throw; a wrong key surfaces at the verify
|
|
211
|
+
// The key is set OUTSIDE the message-bearing try below — keep it there. The key hex must never be
|
|
212
|
+
// able to reach a thrown/logged error string, even if a future SQLCipher build echoed the pragma
|
|
213
|
+
// source on error. A well-formed `key` pragma does not throw; a wrong key surfaces at the verify
|
|
214
|
+
// read instead.
|
|
215
215
|
const keyHex = Buffer.from(dbKey).toString("hex");
|
|
216
216
|
inner.pragma(`key = "x'${keyHex}'"`);
|
|
217
217
|
try {
|
|
@@ -225,12 +225,12 @@ export function openEncryptedDatabase(dbPath, dbKey, logger) {
|
|
|
225
225
|
catch {
|
|
226
226
|
/* ignore */
|
|
227
227
|
}
|
|
228
|
-
//
|
|
229
|
-
//
|
|
228
|
+
// Do NOT echo the underlying SQLITE message into guidance verbatim, and log nothing here (the
|
|
229
|
+
// caller logs). No key material may appear in the message.
|
|
230
230
|
const reason = err instanceof Error ? err.message : String(err);
|
|
231
231
|
throw new DbEncryptionError("db_encryption_key_mismatch", `database did not decrypt with the supplied key (${reason})`, "The SQLCipher key does not match this database. Restore the correct key file; the daemon will not fall back to a plaintext store.");
|
|
232
232
|
}
|
|
233
|
-
//
|
|
233
|
+
// WAL only AFTER key verification, so WAL/SHM files are encrypted.
|
|
234
234
|
try {
|
|
235
235
|
const mode = inner.pragma("journal_mode=WAL", { simple: true });
|
|
236
236
|
if (mode !== "wal") {
|
|
@@ -257,7 +257,7 @@ export function openEncryptedDatabaseAtPath(dbPath, keyPath) {
|
|
|
257
257
|
const key = readFileSync(kp);
|
|
258
258
|
return openEncryptedDatabase(dbPath, new Uint8Array(key));
|
|
259
259
|
}
|
|
260
|
-
/** The key file path the daemon uses for a given DB path
|
|
260
|
+
/** The key file path the daemon uses for a given DB path — the one plaintext key file. */
|
|
261
261
|
export function dbKeyPathFor(dbPath) {
|
|
262
262
|
return `${dbPath}.key`;
|
|
263
263
|
}
|
package/dist/sqlcipher-db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlcipher-db.js","sourceRoot":"","sources":["../src/sqlcipher-db.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlcipher-db.js","sourceRoot":"","sources":["../src/sqlcipher-db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M8C-TGDOOR-1: the Telegram doorbell.
|
|
3
|
+
*
|
|
4
|
+
* A daemon-owned bot pushes discrete, CONTENT-FREE events (session request / message waiting /
|
|
5
|
+
* state change) to one allowlisted operator chat. It is a convenience, never load-bearing: a
|
|
6
|
+
* network hiccup backs off and retries rather than killing the poller, and an unconfigured
|
|
7
|
+
* doorbell is INERT, not an error.
|
|
8
|
+
*
|
|
9
|
+
* Two invariants worth stating at the boundary, because the boundary is what enforces them now:
|
|
10
|
+
*
|
|
11
|
+
* DOD-INV-CONTENTFREE — the doorbell sends a fixed label per event kind, NEVER message text.
|
|
12
|
+
* This module cannot leak conversation content because it is never given any: its whole
|
|
13
|
+
* dependency list is a logger, the stored settings, and a bot client.
|
|
14
|
+
* D6 — an inbound Telegram message from ANY chat is acknowledged and dropped. Nothing from
|
|
15
|
+
* Telegram enters a CELLO content path. Inside startDaemon that was a promise; here it is
|
|
16
|
+
* structural — there is no session-send seam in this module to abuse.
|
|
17
|
+
*/
|
|
18
|
+
import { type TelegramBotClient } from "./telegram-bot-client.js";
|
|
19
|
+
import type { Logger } from "./types.js";
|
|
20
|
+
export interface TelegramDoorbellDeps {
|
|
21
|
+
logger: Logger;
|
|
22
|
+
/** The persisted bot token + allowlisted chat id, or null when TGDOOR was never configured. */
|
|
23
|
+
getTelegramSettings: () => {
|
|
24
|
+
botToken: string;
|
|
25
|
+
allowlistedChatId: string;
|
|
26
|
+
} | null;
|
|
27
|
+
/** Test injection. Production passes nothing and a real HttpTelegramBotClient is built per token. */
|
|
28
|
+
injectedClient?: TelegramBotClient | null;
|
|
29
|
+
}
|
|
30
|
+
export interface TelegramDoorbell {
|
|
31
|
+
sendTelegramDoorbell: (agentName: string, sessionId: string, kind: "session_request" | "message_waiting" | "state_change", detail: string) => Promise<void>;
|
|
32
|
+
clearTelegramRung: (agentName: string, sessionId: string) => void;
|
|
33
|
+
startTelegramPollerIfConfigured: () => void;
|
|
34
|
+
/** Shutdown: invalidate the running loop. It exits on its next generation check. */
|
|
35
|
+
stopTelegramPoller: () => void;
|
|
36
|
+
}
|
|
37
|
+
export declare function createTelegramDoorbell(deps: TelegramDoorbellDeps): TelegramDoorbell;
|
|
38
|
+
//# sourceMappingURL=telegram-doorbell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-doorbell.d.ts","sourceRoot":"","sources":["../src/telegram-doorbell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAyB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,mBAAmB,EAAE,MAAM;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClF,qGAAqG;IACrG,cAAc,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,cAAc,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5J,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,+BAA+B,EAAE,MAAM,IAAI,CAAC;IAC5C,oFAAoF;IACpF,kBAAkB,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CA+HnF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M8C-TGDOOR-1: the Telegram doorbell.
|
|
3
|
+
*
|
|
4
|
+
* A daemon-owned bot pushes discrete, CONTENT-FREE events (session request / message waiting /
|
|
5
|
+
* state change) to one allowlisted operator chat. It is a convenience, never load-bearing: a
|
|
6
|
+
* network hiccup backs off and retries rather than killing the poller, and an unconfigured
|
|
7
|
+
* doorbell is INERT, not an error.
|
|
8
|
+
*
|
|
9
|
+
* Two invariants worth stating at the boundary, because the boundary is what enforces them now:
|
|
10
|
+
*
|
|
11
|
+
* DOD-INV-CONTENTFREE — the doorbell sends a fixed label per event kind, NEVER message text.
|
|
12
|
+
* This module cannot leak conversation content because it is never given any: its whole
|
|
13
|
+
* dependency list is a logger, the stored settings, and a bot client.
|
|
14
|
+
* D6 — an inbound Telegram message from ANY chat is acknowledged and dropped. Nothing from
|
|
15
|
+
* Telegram enters a CELLO content path. Inside startDaemon that was a promise; here it is
|
|
16
|
+
* structural — there is no session-send seam in this module to abuse.
|
|
17
|
+
*/
|
|
18
|
+
import { HttpTelegramBotClient } from "./telegram-bot-client.js";
|
|
19
|
+
export function createTelegramDoorbell(deps) {
|
|
20
|
+
const { logger, getTelegramSettings, injectedClient } = deps;
|
|
21
|
+
// M8C-TGDOOR-1: Telegram Mode 1 doorbell — a daemon-owned bot pushes discrete, content-free
|
|
22
|
+
// events (session request / message-waiting / state change) to one allowlisted operator chat.
|
|
23
|
+
// "NO channel machinery" (DoD) — this talks to the Telegram Bot API directly, unrelated to the
|
|
24
|
+
// claude/channel MCP capability from Tiers 1-2. Inert until telegram_settings exist.
|
|
25
|
+
let telegramBotClient = injectedClient ?? null;
|
|
26
|
+
let telegramChatId = null;
|
|
27
|
+
let telegramBotToken = null; // tracked only to detect an actual token CHANGE
|
|
28
|
+
// Generation counter, NOT a shared boolean — a boolean flip-to-false-then-true-again (e.g. a
|
|
29
|
+
// settings update that restarts the poller) would let the OLD loop's `while` condition still
|
|
30
|
+
// read true on its next check, running TWO concurrent loops. Each loop instance captures its
|
|
31
|
+
// OWN generation at start and exits the instant the counter no longer matches (a new start, or
|
|
32
|
+
// shutdown, both just bump it).
|
|
33
|
+
let telegramPollerGeneration = 0;
|
|
34
|
+
let telegramUpdateOffset = 0;
|
|
35
|
+
// Coalescing: ring once for the FIRST message-waiting event since a session was last fully
|
|
36
|
+
// read; cleared on read (cello_receive/since_seq advancing that session's watermark). Session
|
|
37
|
+
// requests and state changes bypass this Set entirely — DoD says they always ring.
|
|
38
|
+
const telegramRungUnread = new Set();
|
|
39
|
+
async function sendTelegramDoorbell(agentName, sessionId, kind, detail) {
|
|
40
|
+
if (!telegramBotClient || !telegramChatId)
|
|
41
|
+
return; // TGDOOR not configured — inert, not an error
|
|
42
|
+
if (kind === "message_waiting") {
|
|
43
|
+
const rungKey = `${agentName}:${sessionId}`;
|
|
44
|
+
if (telegramRungUnread.has(rungKey))
|
|
45
|
+
return; // already rung, still unread — coalesced
|
|
46
|
+
telegramRungUnread.add(rungKey);
|
|
47
|
+
}
|
|
48
|
+
// DOD-INV-CONTENTFREE: `detail` is a fixed, content-free label per kind — NEVER message text.
|
|
49
|
+
const text = `[${agentName} · ${sessionId.slice(0, 8)}] ${detail}`;
|
|
50
|
+
try {
|
|
51
|
+
const result = await telegramBotClient.sendMessage(telegramChatId, text);
|
|
52
|
+
if (!result.ok) {
|
|
53
|
+
logger.warn("telegram.doorbell.send.failed", { agentName, sessionId, kind, reason: result.error });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
logger.info("telegram.doorbell.sent", { agentName, sessionId, kind });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
logger.warn("telegram.doorbell.send.failed", { agentName, sessionId, kind, error: err instanceof Error ? err.message : String(err) });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Read clears the ring (DoD: "ring-once-until-read") — called wherever a receive advances a
|
|
63
|
+
// session's read watermark, mirroring AWAY-1's own dedup-clear-on-attend pattern.
|
|
64
|
+
function clearTelegramRung(agentName, sessionId) {
|
|
65
|
+
telegramRungUnread.delete(`${agentName}:${sessionId}`);
|
|
66
|
+
}
|
|
67
|
+
async function handleInboundTelegramUpdate(update, client) {
|
|
68
|
+
const chatId = update.message?.chat?.id !== undefined ? String(update.message.chat.id) : undefined;
|
|
69
|
+
if (!chatId)
|
|
70
|
+
return;
|
|
71
|
+
if (chatId !== telegramChatId) {
|
|
72
|
+
// D6: any other chat is silently dropped — nothing enters CELLO content paths.
|
|
73
|
+
logger.info("telegram.inbound.rejected", { chatId });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
logger.info("telegram.inbound.acknowledged", { chatId });
|
|
77
|
+
try {
|
|
78
|
+
await client.sendMessage(chatId, "CELLO doesn't process messages here — this channel only sends you notifications. Use your CELLO client to reply.");
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger.warn("telegram.inbound.ack.failed", { chatId, error: err instanceof Error ? err.message : String(err) });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Single long-lived getUpdates poller (DoD) — one in-flight loop per daemon; started once
|
|
85
|
+
// settings exist, stopped on daemon shutdown. A network hiccup backs off and retries rather
|
|
86
|
+
// than killing the poller (best-effort — the doorbell is a convenience, never load-bearing).
|
|
87
|
+
// The client is a PARAMETER and must never be re-read from the shared, reassignable
|
|
88
|
+
// telegramBotClient: a settings update mid-await would otherwise let a stale response from the OLD
|
|
89
|
+
// client still be processed once (the generation check blocks the loop's NEXT iteration, not an
|
|
90
|
+
// in-flight call), and stomp telegramUpdateOffset with the OLD bot's update_id numbering, which is
|
|
91
|
+
// meaningless to a new token (Telegram scopes update_id per bot). Re-check the generation
|
|
92
|
+
// immediately after EVERY await, before acting on its result or touching shared state.
|
|
93
|
+
async function runTelegramPollerLoop(myGeneration, myClient) {
|
|
94
|
+
let myOffset = telegramUpdateOffset;
|
|
95
|
+
while (telegramPollerGeneration === myGeneration) {
|
|
96
|
+
try {
|
|
97
|
+
const updates = await myClient.getUpdates(myOffset, 25);
|
|
98
|
+
if (telegramPollerGeneration !== myGeneration)
|
|
99
|
+
break; // superseded while awaiting — drop stale results
|
|
100
|
+
for (const u of updates) {
|
|
101
|
+
myOffset = u.update_id + 1;
|
|
102
|
+
telegramUpdateOffset = myOffset;
|
|
103
|
+
if (u.message)
|
|
104
|
+
void handleInboundTelegramUpdate(u, myClient);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (telegramPollerGeneration !== myGeneration)
|
|
109
|
+
break; // superseded — don't retry under a dead generation
|
|
110
|
+
logger.warn("telegram.poller.error", { error: err instanceof Error ? err.message : String(err) });
|
|
111
|
+
await new Promise((r) => setTimeout(r, 2000)); // back off before retrying
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Always bumps the generation (invalidating any prior loop, which exits on its next check) and
|
|
116
|
+
// starts a fresh one — correct both for the first start AND a settings-change restart.
|
|
117
|
+
function startTelegramPollerIfConfigured() {
|
|
118
|
+
const settings = getTelegramSettings();
|
|
119
|
+
if (!settings)
|
|
120
|
+
return; // not configured — TGDOOR stays inert
|
|
121
|
+
// Reviewer MEDIUM fix: reset the offset on an actual token/chat CHANGE — a prior bot's
|
|
122
|
+
// update_id numbering is meaningless to a new one (Telegram scopes it per bot token).
|
|
123
|
+
if (telegramBotToken !== settings.botToken || telegramChatId !== settings.allowlistedChatId) {
|
|
124
|
+
telegramUpdateOffset = 0;
|
|
125
|
+
}
|
|
126
|
+
telegramBotToken = settings.botToken;
|
|
127
|
+
telegramChatId = settings.allowlistedChatId;
|
|
128
|
+
const client = injectedClient ?? new HttpTelegramBotClient(settings.botToken);
|
|
129
|
+
telegramBotClient = client;
|
|
130
|
+
telegramPollerGeneration += 1;
|
|
131
|
+
void runTelegramPollerLoop(telegramPollerGeneration, client);
|
|
132
|
+
logger.info("telegram.poller.started", {});
|
|
133
|
+
}
|
|
134
|
+
function stopTelegramPoller() {
|
|
135
|
+
telegramPollerGeneration += 1;
|
|
136
|
+
}
|
|
137
|
+
return { sendTelegramDoorbell, clearTelegramRung, startTelegramPollerIfConfigured, stopTelegramPoller };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=telegram-doorbell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-doorbell.js","sourceRoot":"","sources":["../src/telegram-doorbell.ts"],"names":[],"mappings":"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"}
|