@songsid/agend 2.1.12-beta.1 → 2.1.12-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/agent-cli.js +36 -4
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +3 -1
  4. package/dist/agent-endpoint.js +7 -1
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/backend/claude-code.d.ts +2 -0
  7. package/dist/backend/claude-code.js +2 -2
  8. package/dist/backend/claude-code.js.map +1 -1
  9. package/dist/backend/session-signals.d.ts +154 -0
  10. package/dist/backend/session-signals.js +430 -0
  11. package/dist/backend/session-signals.js.map +1 -0
  12. package/dist/channel/adapters/discord.d.ts +38 -1
  13. package/dist/channel/adapters/discord.js +131 -8
  14. package/dist/channel/adapters/discord.js.map +1 -1
  15. package/dist/channel/adapters/telegram.d.ts +19 -1
  16. package/dist/channel/adapters/telegram.js +55 -0
  17. package/dist/channel/adapters/telegram.js.map +1 -1
  18. package/dist/channel/mcp-tools.js +5 -1
  19. package/dist/channel/mcp-tools.js.map +1 -1
  20. package/dist/channel/message-queue.d.ts +6 -0
  21. package/dist/channel/message-queue.js +21 -0
  22. package/dist/channel/message-queue.js.map +1 -1
  23. package/dist/channel/sticker-download.d.ts +14 -0
  24. package/dist/channel/sticker-download.js +42 -0
  25. package/dist/channel/sticker-download.js.map +1 -0
  26. package/dist/channel/tool-router.js +12 -5
  27. package/dist/channel/tool-router.js.map +1 -1
  28. package/dist/channel/types.d.ts +52 -0
  29. package/dist/cli-flags.d.ts +8 -0
  30. package/dist/cli-flags.js +22 -0
  31. package/dist/cli-flags.js.map +1 -0
  32. package/dist/config-validator.js +25 -0
  33. package/dist/config-validator.js.map +1 -1
  34. package/dist/daemon.d.ts +20 -0
  35. package/dist/daemon.js +155 -3
  36. package/dist/daemon.js.map +1 -1
  37. package/dist/delivery-outbox.d.ts +8 -0
  38. package/dist/delivery-outbox.js.map +1 -1
  39. package/dist/event-loop-watch.d.ts +25 -0
  40. package/dist/event-loop-watch.js +40 -0
  41. package/dist/event-loop-watch.js.map +1 -0
  42. package/dist/fleet-manager.d.ts +38 -3
  43. package/dist/fleet-manager.js +248 -12
  44. package/dist/fleet-manager.js.map +1 -1
  45. package/dist/general-knowledge/skills/persona-emoji/SKILL.md +4 -2
  46. package/dist/locale.js +4 -0
  47. package/dist/locale.js.map +1 -1
  48. package/dist/outbound-schemas.d.ts +15 -1
  49. package/dist/outbound-schemas.js +19 -1
  50. package/dist/outbound-schemas.js.map +1 -1
  51. package/dist/tool-permissions.js +8 -1
  52. package/dist/tool-permissions.js.map +1 -1
  53. package/dist/turn-reply-guard.d.ts +7 -0
  54. package/dist/turn-reply-guard.js +11 -0
  55. package/dist/turn-reply-guard.js.map +1 -1
  56. package/dist/turn-resume.d.ts +80 -0
  57. package/dist/turn-resume.js +217 -0
  58. package/dist/turn-resume.js.map +1 -0
  59. package/dist/ui/view.html +8 -2
  60. package/dist/usage/format-rich.js +6 -1
  61. package/dist/usage/format-rich.js.map +1 -1
  62. package/dist/usage/i18n.d.ts +2 -0
  63. package/dist/usage/i18n.js +14 -1
  64. package/dist/usage/i18n.js.map +1 -1
  65. package/dist/usage/providers.d.ts +10 -0
  66. package/dist/usage/providers.js +2 -0
  67. package/dist/usage/providers.js.map +1 -1
  68. package/dist/usage/usage-api.d.ts +9 -0
  69. package/dist/usage/usage-api.js +31 -2
  70. package/dist/usage/usage-api.js.map +1 -1
  71. package/package.json +1 -1
@@ -0,0 +1,430 @@
1
+ /**
2
+ * Detection-signal seam: the shared base for #1209 / #1217a / #1210 / #1215.
3
+ *
4
+ * A read-only, query-only observation layer answering ONE question without
5
+ * pane pixels: did the CLI itself re-engage a turn since the checkpoint
6
+ * (double-drive guard)? Per-backend adapters discover the workspace's session
7
+ * in the CLI's own session store and produce a `TurnFingerprint`; the
8
+ * backend-agnostic `compareFingerprints` diffs a pre-action checkpoint
9
+ * against a post-action read.
10
+ *
11
+ * RED LINE: this seam never touches the idle/busy state machine.
12
+ * `readinessFromStore` always returns `unknown` — the pane stays the
13
+ * busyness authority, exactly as today. Nothing here drives, resumes, or
14
+ * writes any CLI state; every read is out-of-band and defensive (an absent
15
+ * field is null, never an exception).
16
+ *
17
+ * SYNC I/O WARNING: every read below is synchronous blocking file/database
18
+ * I/O. Never resolve fingerprints on the fleet event loop or inside a tool
19
+ * handler — use a bounded worker context.
20
+ *
21
+ * What counts as re-engagement: a new TURN, not a store write. CLIs
22
+ * bookkeep without turns (claude `cost-state`/`ai-title`, codex threads-row
23
+ * touches, muse `session.workspace_branch.observed`), so both the mtime and
24
+ * the tail path are gated on turn-shaped journal entries (`isTurnKind`):
25
+ * file mtime is recorded for grace bookkeeping but never drives the verdict
26
+ * alone. Kinds this seam does not recognise default to bookkeeping — a new
27
+ * turn vocabulary delays detection to the next recognised write instead of
28
+ * fabricating or blocking on it.
29
+ *
30
+ * Daemon exclusion covers BOTH paths: the daemon's own action (e.g. a resume)
31
+ * writes tail entries too, so a turn tail counts only past
32
+ * `max(before.tail, daemonCausedMtimeMs) + tailSkewMs`. The skew (default 2s:
33
+ * filesystem timestamp granularity plus entry-ts vs flush-mtime reorder —
34
+ * a live codex tail was observed 2ms AFTER its row mtime) keeps a
35
+ * daemon-caused tail from reading as someone else's turn.
36
+ *
37
+ * Tail-timestamp fields were verified against live stores, not assumed:
38
+ * - claude-code 2.1.289 transcript JSONL: user/assistant/system entries carry
39
+ * ISO `timestamp`, but the tail is usually bookkeeping (`cost-state`,
40
+ * `last-prompt`, `mode`, `ai-title`, …) with NO timestamp — so the reader
41
+ * scans backwards for the newest timestamped TURN entry instead of taking
42
+ * the last line.
43
+ * - codex rollout JSONL: every line of a lived-in 53k-line rollout carries
44
+ * top-level ISO `timestamp`; `type` + `payload.type` name the kind
45
+ * (`response_item:message`, `event_msg:task_started`, `turn_context`,
46
+ * `token_usage_record`, …). threads row verified with `updated_at_ms` /
47
+ * `recency_at_ms` epoch millis.
48
+ * - muse 1.4.x `session.jsonl`: entries carry NO `timestamp` at all — time is
49
+ * `recorded_at` in epoch MICROseconds, kind is `payload_type` (plus inner
50
+ * `payload.kind` for the `runtime.session` envelope: `task`/`run` are the
51
+ * turn frames, surveyed live over 49k lines); the first line is a
52
+ * `retained_frame` wrapper with neither.
53
+ *
54
+ * Flush grace and its residual: a CLI that just re-engaged may not have
55
+ * flushed its store yet, so a checkpoint taken too early reads `quiet` for a
56
+ * live turn. Inside `flushGraceMs` after the daemon's own write the seam
57
+ * answers `unknown` instead of `quiet`. Residual, by design and bounded: a
58
+ * re-engagement that flushes after this compare is caught by the NEXT
59
+ * checkpoint compare (at most one grace period of delayed detection, never a
60
+ * fabricated verdict). A re-engagement that never writes to the session store
61
+ * is invisible to this seam. Callers MUST re-compare across checkpoints; a
62
+ * single `quiet` inside the grace window must never authorize driving.
63
+ *
64
+ * kiro-classic `data.sqlite3` and KAS are deliberately NOT covered here: the
65
+ * classic schema needs its own round (see #1210) and the spike's KAS field
66
+ * assumptions were never verified against a live store.
67
+ */
68
+ import { closeSync, openSync, readFileSync, readSync, readdirSync, statSync } from "node:fs";
69
+ import { join } from "node:path";
70
+ import { claudeProjectKey } from "./claude-code.js";
71
+ import { findExactCwdCodexSession, openCodexStateReadonly, rolloutRecordsTurn } from "./codex-session-lookup.js";
72
+ import { museSessionCwd, museSessionDirs } from "./muse.js";
73
+ /**
74
+ * How long after the daemon's own store write a `quiet` read is untrustworthy.
75
+ * 10 s matches the transcript-marker wait bound (#758): a journal flush lands
76
+ * well inside it, while the window stays short enough to schedule around.
77
+ */
78
+ export const DEFAULT_FLUSH_GRACE_MS = 10_000;
79
+ /**
80
+ * Entry-ts vs daemon-mtime skew bound (ms). A daemon-caused tail must clear
81
+ * the daemon's own mtime by more than this to count as someone else's turn.
82
+ */
83
+ export const DEFAULT_TAIL_SKEW_MS = 2_000;
84
+ /** Epoch microseconds at or above this are muse `recorded_at`, not millis. */
85
+ const MICROSECONDS_FLOOR = 1e14;
86
+ /**
87
+ * Parse an ISO instant, epoch millis, or epoch micros (muse `recorded_at`);
88
+ * anything else is null. Numbers below the micros floor pass through as
89
+ * millis; what no tailed store emits (e.g. epoch seconds) is out of scope.
90
+ */
91
+ export function asTimestampMs(v) {
92
+ if (typeof v === "number") {
93
+ if (!Number.isFinite(v))
94
+ return null;
95
+ return v >= MICROSECONDS_FLOOR ? v / 1000 : v;
96
+ }
97
+ if (typeof v === "string") {
98
+ const ms = Date.parse(v);
99
+ return Number.isFinite(ms) ? ms : null;
100
+ }
101
+ return null;
102
+ }
103
+ function str(v) {
104
+ return typeof v === "string" && v !== "" ? v : null;
105
+ }
106
+ /**
107
+ * Best-effort kind of one journal entry across the three store shapes:
108
+ * claude `type`/`subtype`, codex `type` + `payload.type`, muse `payload_type`
109
+ * (+ inner `payload.kind` for the `runtime.session` envelope).
110
+ */
111
+ export function entryKind(entry) {
112
+ const payload = entry.payload;
113
+ const payloadObj = payload && typeof payload === "object" && !Array.isArray(payload)
114
+ ? payload
115
+ : null;
116
+ const base = str(entry.type) ?? str(entry.kind) ?? str(entry.payload_type)
117
+ ?? str(payloadObj?.type) ?? str(payloadObj?.payload_type) ?? str(payloadObj?.kind);
118
+ if (!base)
119
+ return null;
120
+ const detail = str(entry.subtype) ?? str(payloadObj?.kind) ?? str(entry.payload_type)
121
+ ?? str(payloadObj?.type) ?? str(payloadObj?.payload_type);
122
+ return detail && detail !== base ? `${base}:${detail}` : base;
123
+ }
124
+ /** Newest timestamp one journal entry carries across the three store shapes. */
125
+ export function entryTimestampMs(entry) {
126
+ return asTimestampMs(entry.recorded_at ?? entry.timestamp ?? entry.time ?? entry.createdAt ?? entry.lastModifiedAt);
127
+ }
128
+ /**
129
+ * Whether a tail kind proves a turn ran (as opposed to CLI bookkeeping).
130
+ * Unrecognised kinds default to bookkeeping: a new turn vocabulary delays
131
+ * detection instead of blocking legitimate resumes on false positives.
132
+ */
133
+ export function isTurnKind(backend, kind) {
134
+ if (!kind)
135
+ return false;
136
+ if (backend === "claude")
137
+ return kind === "user" || kind === "assistant";
138
+ if (backend === "codex") {
139
+ return kind === "response_item" || kind.startsWith("response_item:")
140
+ || kind.startsWith("event_msg:task_");
141
+ }
142
+ if (kind === "command.invoked" || kind === "session.resumed")
143
+ return true;
144
+ if (kind.startsWith("runtime.user_intent."))
145
+ return true;
146
+ if (kind.startsWith("tool_batch.effect."))
147
+ return true;
148
+ return kind === "runtime.session.task" || kind === "runtime.session.task_source_committed"
149
+ || kind === "runtime.session:task" || kind === "runtime.session:run";
150
+ }
151
+ /** Bytes scanned back from the end of a journal looking for tail entries. */
152
+ const TAIL_SCAN_BYTES = 1024 * 1024;
153
+ /**
154
+ * Read-only tail of a JSONL journal: the newest `want` parseable entries
155
+ * within the last 1 MB, newest first. A truncated line at the window edge or
156
+ * a corrupt line is skipped, never fatal. Windowed by design: when the tail
157
+ * itself is one entry larger than the window, the read still returns the
158
+ * file mtime with an empty entry list (detection delayed, never fabricated).
159
+ * Synchronous blocking I/O — see the module warning.
160
+ */
161
+ export function readJsonlTailEntries(path, want = 8) {
162
+ if (!(want >= 1))
163
+ want = 1;
164
+ try {
165
+ const st = statSync(path);
166
+ if (!st.isFile())
167
+ return null;
168
+ const window = Math.min(st.size, TAIL_SCAN_BYTES);
169
+ const buf = Buffer.alloc(window);
170
+ const fd = openSync(path, "r");
171
+ try {
172
+ readSync(fd, buf, 0, window, st.size - window);
173
+ }
174
+ finally {
175
+ try {
176
+ closeSync(fd);
177
+ }
178
+ catch { /* already closed */ }
179
+ }
180
+ const lines = buf.toString("utf8").split("\n");
181
+ const entries = [];
182
+ for (let i = lines.length - 1; i >= 0 && entries.length < want; i--) {
183
+ const line = lines[i].trim();
184
+ if (!line)
185
+ continue;
186
+ try {
187
+ const parsed = JSON.parse(line);
188
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
189
+ entries.push(parsed);
190
+ }
191
+ }
192
+ catch { /* partial line at the window edge or corrupt: skip */ }
193
+ }
194
+ return { entries, mtimeMs: st.mtimeMs };
195
+ }
196
+ catch {
197
+ return null;
198
+ }
199
+ }
200
+ /**
201
+ * Newest timestamped TURN entry of a tail: skips timestamp-less bookkeeping
202
+ * (claude `cost-state`/`last-prompt`, muse `retained_frame`) AND timestamped
203
+ * non-turn writes (codex `token_count`, muse `workspace_branch.observed`).
204
+ * Null when no turn entry carries time.
205
+ */
206
+ export function tailEvidence(entries, backend) {
207
+ for (const entry of entries) {
208
+ const kind = entryKind(entry);
209
+ if (!isTurnKind(backend, kind))
210
+ continue;
211
+ const timestampMs = entryTimestampMs(entry);
212
+ if (timestampMs !== null)
213
+ return { timestampMs, kind };
214
+ }
215
+ return null;
216
+ }
217
+ /**
218
+ * Backend-agnostic re-engagement verdict. A changed session id means the
219
+ * store now belongs to a different conversation (feeds #1217a). Otherwise
220
+ * only a TURN-tail advance past the daemon's own writes (plus skew) means
221
+ * the CLI wrote on its own — plain mtime movement is bookkeeping until a
222
+ * turn entry says otherwise. Inside the flush-grace window after a daemon
223
+ * write, `quiet` is withheld as `unknown` (see module doc).
224
+ */
225
+ export function compareFingerprints(before, after, options = {}) {
226
+ if (!before || !after || before.storeMtimeMs < 0 || after.storeMtimeMs < 0)
227
+ return "unknown";
228
+ if (before.sessionId && after.sessionId && before.sessionId !== after.sessionId)
229
+ return "reengaged";
230
+ const daemonCausedMtimeMs = options.daemonCausedMtimeMs ?? -1;
231
+ const tailSkewMs = Math.max(0, options.tailSkewMs ?? DEFAULT_TAIL_SKEW_MS);
232
+ const afterTail = after.tailTimestampMs;
233
+ const pastBefore = afterTail !== null
234
+ && (before.tailTimestampMs === null || afterTail > before.tailTimestampMs);
235
+ const pastDaemon = afterTail !== null
236
+ && (daemonCausedMtimeMs < 0 || afterTail > daemonCausedMtimeMs + tailSkewMs);
237
+ if (pastBefore && pastDaemon)
238
+ return "reengaged";
239
+ if (daemonCausedMtimeMs >= 0) {
240
+ const nowMs = options.nowMs ?? Date.now();
241
+ const flushGraceMs = options.flushGraceMs ?? DEFAULT_FLUSH_GRACE_MS;
242
+ if (nowMs - daemonCausedMtimeMs <= flushGraceMs)
243
+ return "unknown";
244
+ }
245
+ return "quiet";
246
+ }
247
+ /**
248
+ * Store-corroborated busyness, by design always unknown: append-only journals
249
+ * carry no verified completion semantics, so a store alone cannot say "busy"
250
+ * vs "ready" — it can only say "wrote recently". The pane stays authoritative;
251
+ * this seam MUST NOT feed the idle/busy state machine.
252
+ */
253
+ export function readinessFromStore(_fp) {
254
+ return {
255
+ readiness: "unknown",
256
+ reason: "append-only journal without verified completion entries; pane stays authoritative",
257
+ };
258
+ }
259
+ /**
260
+ * Newest `<sessionId>.jsonl` of `~/.claude/projects/<key>/` plus its newest
261
+ * timestamped TURN tail entry. The session id is discovered from the store,
262
+ * never caller-supplied, so a conversation switch surfaces as an id change.
263
+ */
264
+ export function claudeFingerprint(r) {
265
+ const dir = join(r.configDir, "projects", claudeProjectKey(r.cwd));
266
+ let names;
267
+ try {
268
+ names = readdirSync(dir);
269
+ }
270
+ catch {
271
+ return null;
272
+ }
273
+ let bestFile = null;
274
+ let bestMtime = -1;
275
+ for (const name of names) {
276
+ if (!name.endsWith(".jsonl"))
277
+ continue;
278
+ try {
279
+ const m = statSync(join(dir, name)).mtimeMs;
280
+ if (m > bestMtime) {
281
+ bestMtime = m;
282
+ bestFile = name;
283
+ }
284
+ }
285
+ catch { /* raced with deletion */ }
286
+ }
287
+ if (!bestFile)
288
+ return null;
289
+ const tail = readJsonlTailEntries(join(dir, bestFile));
290
+ const evidence = tail && tailEvidence(tail.entries, "claude");
291
+ return {
292
+ sessionId: bestFile.slice(0, -".jsonl".length),
293
+ storeMtimeMs: tail?.mtimeMs ?? bestMtime,
294
+ tailTimestampMs: evidence?.timestampMs ?? null,
295
+ tailKind: evidence?.kind ?? null,
296
+ };
297
+ }
298
+ /**
299
+ * The exact-cwd session from `state_5.sqlite` (same lookup as #984: newest
300
+ * interactive thread of this directory, never `--last`), then its threads
301
+ * row (`updated_at_ms`/`recency_at_ms`) plus rollout tail. The database is
302
+ * opened read-only (never created, checkpointed, or migrated); an unknown
303
+ * session or a schema that no longer matches is null (unknown), never a
304
+ * guess. The session id is discovered from the store, never caller-supplied.
305
+ */
306
+ export function codexFingerprint(r) {
307
+ const openDb = r.openDb ?? ((path) => openCodexStateReadonly(path));
308
+ const rolloutTail = r.rolloutTail ?? ((path) => readJsonlTailEntries(path));
309
+ const rolloutHasTurn = r.rolloutHasTurn ?? rolloutRecordsTurn;
310
+ const discoveryOpen = (path) => {
311
+ let db = null;
312
+ try {
313
+ db = openDb(path);
314
+ }
315
+ catch { /* fall through to throw */ }
316
+ if (!db)
317
+ throw new Error(`codex state unreadable: ${path}`);
318
+ return db;
319
+ };
320
+ let sessionId;
321
+ try {
322
+ const lookup = findExactCwdCodexSession(r.stateDbPath, r.cwd, discoveryOpen, rolloutHasTurn);
323
+ if (lookup.kind !== "found")
324
+ return null;
325
+ sessionId = lookup.id;
326
+ }
327
+ catch {
328
+ return null;
329
+ }
330
+ let db = null;
331
+ try {
332
+ try {
333
+ db = openDb(r.stateDbPath);
334
+ }
335
+ catch {
336
+ return null;
337
+ }
338
+ if (!db)
339
+ return null;
340
+ const row = db.prepare("SELECT updated_at_ms, recency_at_ms, rollout_path FROM threads WHERE id = ?").get(sessionId);
341
+ if (!row)
342
+ return null;
343
+ let tailTimestampMs = null;
344
+ let tailKind = null;
345
+ let fileMtime = -1;
346
+ if (typeof row.rollout_path === "string") {
347
+ const tail = rolloutTail(row.rollout_path);
348
+ if (tail) {
349
+ fileMtime = tail.mtimeMs;
350
+ const evidence = tailEvidence(tail.entries, "codex");
351
+ tailTimestampMs = evidence?.timestampMs ?? null;
352
+ tailKind = evidence?.kind ?? null;
353
+ }
354
+ }
355
+ const storeMtimeMs = Math.max(typeof row.updated_at_ms === "number" ? row.updated_at_ms : -1, typeof row.recency_at_ms === "number" ? row.recency_at_ms : -1, fileMtime);
356
+ return storeMtimeMs < 0
357
+ ? null
358
+ : { sessionId, storeMtimeMs, tailTimestampMs, tailKind };
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ finally {
364
+ try {
365
+ db?.close();
366
+ }
367
+ catch { /* already closed */ }
368
+ }
369
+ }
370
+ /** Session-id pattern, mirroring muse.ts (MuseBackend session ids are UUIDs). */
371
+ const MUSE_SESSION_ID_RE = /^[0-9a-fA-F-]{8,}$/;
372
+ /** Log head scanned for the workspace marker, mirroring muse.ts. */
373
+ const MUSE_SESSION_HEAD_BYTES = 65_536;
374
+ /**
375
+ * The most recently active session started in this working directory,
376
+ * mirroring MuseBackend.getSessionId (workspace read out of each session's
377
+ * own log, activity = newest inner-file mtime), plus its newest timestamped
378
+ * TURN tail entry. The session id is discovered from the store, never
379
+ * caller-supplied, so a conversation switch surfaces as an id change.
380
+ */
381
+ export function museFingerprint(r) {
382
+ if (!r.cwd)
383
+ return null;
384
+ let bestId = null;
385
+ let bestDir = "";
386
+ let bestActivity = -1;
387
+ for (const sessionDir of museSessionDirs(r.sessionsRoot)) {
388
+ const name = sessionDir.slice(sessionDir.lastIndexOf("/") + 1);
389
+ if (!MUSE_SESSION_ID_RE.test(name))
390
+ continue;
391
+ let head;
392
+ try {
393
+ head = readFileSync(join(sessionDir, "session.jsonl"), { encoding: "utf-8", flag: "r" })
394
+ .slice(0, MUSE_SESSION_HEAD_BYTES);
395
+ }
396
+ catch {
397
+ continue;
398
+ }
399
+ if (museSessionCwd(head) !== r.cwd)
400
+ continue;
401
+ let activity = -1;
402
+ try {
403
+ for (const f of readdirSync(sessionDir)) {
404
+ try {
405
+ const m = statSync(join(sessionDir, f)).mtimeMs;
406
+ if (m > activity)
407
+ activity = m;
408
+ }
409
+ catch { /* raced with deletion */ }
410
+ }
411
+ }
412
+ catch { /* unreadable */ }
413
+ if (activity > bestActivity) {
414
+ bestActivity = activity;
415
+ bestId = name;
416
+ bestDir = sessionDir;
417
+ }
418
+ }
419
+ if (!bestId)
420
+ return null;
421
+ const tail = readJsonlTailEntries(join(bestDir, "session.jsonl"));
422
+ const evidence = tail && tailEvidence(tail.entries, "muse");
423
+ return {
424
+ sessionId: bestId,
425
+ storeMtimeMs: bestActivity,
426
+ tailTimestampMs: evidence?.timestampMs ?? null,
427
+ tailKind: evidence?.kind ?? null,
428
+ };
429
+ }
430
+ //# sourceMappingURL=session-signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-signals.js","sourceRoot":"","sources":["../../src/backend/session-signals.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { Client, ActionRowBuilder, ButtonBuilder } from "discord.js";
3
- import type { ChannelAdapter, ApprovalHandle, SendOpts, SentMessage, PermissionPrompt, Choice, AlertData, AdapterHealthSnapshot, TopicPresence } from "../types.js";
3
+ import type { ChannelAdapter, ApprovalHandle, SendOpts, SentMessage, PermissionPrompt, Choice, AlertData, AdapterHealthSnapshot, TopicPresence, StickerInfo, StickerList, StickerPreview, StickerTarget } from "../types.js";
4
4
  import type { AccessManager } from "../access-manager.js";
5
5
  /** Curated ClassicBot backends for Discord's native slash-option dropdown. */
6
6
  export declare const DISCORD_START_BACKEND_CHOICES: readonly [{
@@ -129,6 +129,24 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
129
129
  private startGatewayWatchdog;
130
130
  private checkGatewayLiveness;
131
131
  getHealthSnapshot(): AdapterHealthSnapshot;
132
+ /**
133
+ * #1231: how late a slash command was by the time it was acknowledged.
134
+ * `createdTimestamp` is Discord's clock (the interaction's snowflake), so
135
+ * "age" also carries clock skew; the defer's own round trip is local. Over
136
+ * half the 3 s window is worth a line: it says whether the time went in
137
+ * delivery (gateway, a blocked event loop) or in the acknowledgement (REST).
138
+ */
139
+ private noteSlashAckTiming;
140
+ /**
141
+ * #1231: a slash command whose acknowledgement failed. It is NOT run: the
142
+ * user was shown "did not respond" (or will be) and may well run it again,
143
+ * so running it now could do it twice. Already acknowledged (40060) means
144
+ * another session of this bot answered it — that one handles the command,
145
+ * so stay silent. Otherwise say so where the user can see it: a private
146
+ * follow-up when the acknowledgement did land after all, else a message in
147
+ * the channel, never a silent drop.
148
+ */
149
+ private reportSlashDeferFailure;
132
150
  /**
133
151
  * Update the bot's profile activity without touching any channel messages.
134
152
  * Presence is deliberately best-effort: a reconnecting or not-yet-ready
@@ -171,6 +189,25 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
171
189
  animated: boolean;
172
190
  available: boolean;
173
191
  }>>;
192
+ /**
193
+ * The server a channel belongs to (#1226): stickers are per server, and a bot can send only the stickers of the
194
+ * server it posts in. In the channels topology `chatId` can be the server id itself; that is the answer then.
195
+ */
196
+ private guildOfChannel;
197
+ /**
198
+ * The stickers of the server `target`'s channel is in (#1226) — the only ones this bot can send there. Discord's
199
+ * standard sticker packs are not listed (they are hundreds, and not what an agent picks from).
200
+ */
201
+ listStickers(target: StickerTarget): Promise<StickerList>;
202
+ /** A still picture of a listed sticker, from Discord's media CDN; null for a Lottie sticker (no still image). */
203
+ fetchStickerPreview(sticker: StickerInfo): Promise<StickerPreview | null>;
204
+ /**
205
+ * Stickers on one message (#1226): with the text's last chunk when there is text (Discord sends both together),
206
+ * alone otherwise. Earlier chunks of a long text go first, as plain messages.
207
+ */
208
+ sendStickers(chatId: string, stickers: string[], opts?: SendOpts & {
209
+ text?: string;
210
+ }): Promise<SentMessage>;
174
211
  /**
175
212
  * The servers this bot is a member of, primary first (#1021). A bot can
176
213
  * react with a custom emoji from any server it is in, so these are where