crewly 1.20.279 → 1.20.280

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 (70) hide show
  1. package/config/skills/agent/core/reply/SKILL.md +2 -1
  2. package/config/skills/agent/core/reply/execute.sh +11 -3
  3. package/config/skills/agent/core/reply/execute.test.sh +4 -0
  4. package/dist/backend/backend/src/constants.d.ts +51 -0
  5. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  6. package/dist/backend/backend/src/constants.js +51 -0
  7. package/dist/backend/backend/src/constants.js.map +1 -1
  8. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts +1 -0
  9. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
  10. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +3 -1
  11. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
  12. package/dist/backend/backend/src/index.d.ts.map +1 -1
  13. package/dist/backend/backend/src/index.js +86 -0
  14. package/dist/backend/backend/src/index.js.map +1 -1
  15. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  16. package/dist/backend/backend/src/services/agent/agent-registration.service.js +4 -2
  17. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  18. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  19. package/dist/backend/backend/src/services/agent/idle-detection.service.js +7 -0
  20. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  21. package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  22. package/dist/backend/backend/src/services/agent/resource-mode.service.js +4 -1
  23. package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
  24. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts +16 -0
  25. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts.map +1 -1
  26. package/dist/backend/backend/src/services/drive/drive-agent.service.js +37 -5
  27. package/dist/backend/backend/src/services/drive/drive-agent.service.js.map +1 -1
  28. package/dist/backend/backend/src/services/drive/drive-briefing-snapshot.d.ts +172 -0
  29. package/dist/backend/backend/src/services/drive/drive-briefing-snapshot.d.ts.map +1 -0
  30. package/dist/backend/backend/src/services/drive/drive-briefing-snapshot.js +301 -0
  31. package/dist/backend/backend/src/services/drive/drive-briefing-snapshot.js.map +1 -0
  32. package/dist/backend/backend/src/services/drive/drive-briefing-sync.service.d.ts +112 -0
  33. package/dist/backend/backend/src/services/drive/drive-briefing-sync.service.d.ts.map +1 -0
  34. package/dist/backend/backend/src/services/drive/drive-briefing-sync.service.js +247 -0
  35. package/dist/backend/backend/src/services/drive/drive-briefing-sync.service.js.map +1 -0
  36. package/dist/backend/backend/src/services/drive/drive-briefing.contract.d.ts +88 -0
  37. package/dist/backend/backend/src/services/drive/drive-briefing.contract.d.ts.map +1 -0
  38. package/dist/backend/backend/src/services/drive/drive-briefing.contract.js +18 -0
  39. package/dist/backend/backend/src/services/drive/drive-briefing.contract.js.map +1 -0
  40. package/dist/backend/backend/src/services/drive/drive-briefing.wiring.d.ts +73 -0
  41. package/dist/backend/backend/src/services/drive/drive-briefing.wiring.d.ts.map +1 -0
  42. package/dist/backend/backend/src/services/drive/drive-briefing.wiring.js +131 -0
  43. package/dist/backend/backend/src/services/drive/drive-briefing.wiring.js.map +1 -0
  44. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts +9 -2
  45. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js +9 -4
  47. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js.map +1 -1
  48. package/dist/backend/backend/src/services/drive/drive-keep-warm.d.ts +72 -0
  49. package/dist/backend/backend/src/services/drive/drive-keep-warm.d.ts.map +1 -0
  50. package/dist/backend/backend/src/services/drive/drive-keep-warm.js +109 -0
  51. package/dist/backend/backend/src/services/drive/drive-keep-warm.js.map +1 -0
  52. package/dist/backend/backend/src/services/messaging/owner-hook-message.d.ts.map +1 -1
  53. package/dist/backend/backend/src/services/messaging/owner-hook-message.js +11 -5
  54. package/dist/backend/backend/src/services/messaging/owner-hook-message.js.map +1 -1
  55. package/dist/backend/build-info.json +2 -2
  56. package/dist/cli/backend/src/constants.d.ts +51 -0
  57. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  58. package/dist/cli/backend/src/constants.js +51 -0
  59. package/dist/cli/backend/src/constants.js.map +1 -1
  60. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  61. package/dist/cli/backend/src/services/agent/agent-registration.service.js +4 -2
  62. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  63. package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
  64. package/dist/cli/backend/src/services/agent/resource-mode.service.js +4 -1
  65. package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
  66. package/dist/cli/backend/src/services/drive/drive-keep-warm.d.ts +72 -0
  67. package/dist/cli/backend/src/services/drive/drive-keep-warm.d.ts.map +1 -0
  68. package/dist/cli/backend/src/services/drive/drive-keep-warm.js +109 -0
  69. package/dist/cli/backend/src/services/drive/drive-keep-warm.js.map +1 -0
  70. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-briefing-snapshot.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-briefing-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Build the Drive mode status snapshot (specs/2026-10-09-drive-mode-v3.md §1)
3
+ * from structured data this machine already has. Pure, no LLM calls: the
4
+ * text in it is what agents already wrote — ticket titles and log lines,
5
+ * work item `output.summary`, decision card summaries, their own messages to
6
+ * the owner.
7
+ *
8
+ * - teams: lead, members, counts (open / in progress / review / blocked /
9
+ * done today);
10
+ * - agents: state (working / idle / starting / stopped), what each is on
11
+ * and since when (its running work item, else its ticket in progress),
12
+ * its last few messages to the owner;
13
+ * - items: project tickets and work items not linked to a ticket, in order
14
+ * of attention, done / cancelled ones only from the last 24 h;
15
+ * - waiting: the briefing queue's live owner items (cards, questions,
16
+ * reviews — stale and duplicate ones are already dropped there).
17
+ *
18
+ * Every text field is made speakable, passed through the secret redactor
19
+ * and clipped; the whole snapshot is kept under
20
+ * {@link DRIVE_BRIEFING_CONSTANTS.MAX_BYTES}.
21
+ *
22
+ * @module services/drive/drive-briefing-snapshot
23
+ */
24
+ import { DRIVE_BRIEFING_CONSTANTS } from '../../constants.js';
25
+ import { redactSecrets } from '../../utils/secret-redactor.js';
26
+ import { clip, speakable } from '../briefing/briefing.utils.js';
27
+ import { messagesToOwner } from './drive-recall.js';
28
+ const C = DRIVE_BRIEFING_CONSTANTS;
29
+ /** Order of attention. */
30
+ const STATUS_RANK = { review: 0, blocked: 1, in_progress: 2, open: 3, done: 4, cancelled: 5 };
31
+ /**
32
+ * Speakable, redacted, clipped text (empty → '').
33
+ *
34
+ * @param raw - Agent-written text
35
+ * @param max - Longest length
36
+ * @returns Safe text
37
+ */
38
+ export function safeText(raw, max) {
39
+ if (typeof raw !== 'string' || !raw.trim())
40
+ return '';
41
+ return clip(speakable(redactSecrets(raw)), max - 1);
42
+ }
43
+ /**
44
+ * An agent's state from its team member record.
45
+ *
46
+ * @param agentStatus - Connection status
47
+ * @param workingStatus - Activity
48
+ * @returns State
49
+ */
50
+ export function agentStateOf(agentStatus, workingStatus) {
51
+ if (agentStatus === 'active')
52
+ return workingStatus === 'in_progress' ? 'working' : 'idle';
53
+ if (agentStatus === 'starting' || agentStatus === 'started' || agentStatus === 'activating')
54
+ return 'starting';
55
+ return 'stopped';
56
+ }
57
+ /**
58
+ * A project ticket's status for the voice (`blocked` label wins).
59
+ *
60
+ * @param status - Ticket status
61
+ * @param labels - Ticket labels
62
+ * @returns Normalised status
63
+ */
64
+ export function ticketStatus(status, labels) {
65
+ if (status === 'done')
66
+ return 'done';
67
+ if (status === 'cancelled')
68
+ return 'cancelled';
69
+ if (labels.some((l) => l.toLowerCase() === 'blocked'))
70
+ return 'blocked';
71
+ if (status === 'in_progress')
72
+ return 'in_progress';
73
+ if (status === 'review')
74
+ return 'review';
75
+ return 'open';
76
+ }
77
+ /**
78
+ * A work item's status for the voice.
79
+ *
80
+ * @param status - WorkItem status
81
+ * @returns Normalised status
82
+ */
83
+ export function workItemStatus(status) {
84
+ switch (status) {
85
+ case 'running':
86
+ case 'accepted':
87
+ return 'in_progress';
88
+ case 'done_by_worker':
89
+ return 'review';
90
+ case 'blocked':
91
+ case 'escalated':
92
+ case 'failed':
93
+ return 'blocked';
94
+ case 'verified':
95
+ case 'done':
96
+ return 'done';
97
+ case 'cancelled':
98
+ return 'cancelled';
99
+ default:
100
+ return 'open';
101
+ }
102
+ }
103
+ /**
104
+ * The words of a ticket log line (`<iso> · <actor> · <message>` → message).
105
+ *
106
+ * @param line - Log line
107
+ * @returns The message
108
+ */
109
+ export function logMessage(line) {
110
+ const parts = line.split(' · ');
111
+ return parts.length >= 3 ? parts.slice(2).join(' · ') : line;
112
+ }
113
+ /** A work item's own last word: its summary, its blocked reason, its error. */
114
+ function workItemLast(w) {
115
+ const summary = w.output && typeof w.output['summary'] === 'string' ? w.output['summary'] : '';
116
+ return summary || w.blockedReason || w.error || '';
117
+ }
118
+ const workItemUpdatedAt = (w) => w.statusChangedAt ?? w.completedAt ?? w.startedAt ?? w.createdAt;
119
+ /**
120
+ * Build the snapshot.
121
+ *
122
+ * @param src - Sources
123
+ * @returns Snapshot, under the size cap
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * const snapshot = buildBriefingSnapshot({ now: new Date(), agents, teams, tickets, workItems, waiting, ownerFeed });
128
+ * ```
129
+ */
130
+ export function buildBriefingSnapshot(src) {
131
+ const nowMs = src.now.getTime();
132
+ const nameOf = new Map(src.agents.map((a) => [a.agentSession, a.name]));
133
+ const teamOfAgent = new Map(src.agents.filter((a) => a.team).map((a) => [a.agentSession, a.team]));
134
+ const teamName = new Map(src.teams.map((t) => [t.id, t.name]));
135
+ const recentEnough = (status, at) => (status !== 'done' && status !== 'cancelled') || nowMs - Date.parse(at) < C.DONE_WINDOW_MS;
136
+ const who = (assignee) => (assignee ? safeText(nameOf.get(assignee) ?? assignee, C.NAME_MAX) || undefined : undefined);
137
+ // --- items: tickets, then work items not behind a ticket --------------------
138
+ const byWorkItem = new Map(src.workItems.map((w) => [w.id, w]));
139
+ const linked = new Set();
140
+ const items = [];
141
+ for (const t of src.tickets) {
142
+ const status = ticketStatus(t.status, t.labels);
143
+ if (!recentEnough(status, t.updatedAt))
144
+ continue;
145
+ if (t.workItemId)
146
+ linked.add(t.workItemId);
147
+ const wi = t.workItemId ? byWorkItem.get(t.workItemId) : undefined;
148
+ const logLast = t.log.length ? logMessage(t.log[t.log.length - 1]) : '';
149
+ const wiLast = wi ? workItemLast(wi) : '';
150
+ // The newer of the ticket's last log line and its work item's summary.
151
+ const last = wiLast && wi && Date.parse(workItemUpdatedAt(wi)) > Date.parse(t.updatedAt) ? wiLast : logLast || wiLast;
152
+ const team = (t.team && teamName.get(t.team)) || (t.assignee ? teamOfAgent.get(t.assignee) : undefined);
153
+ items.push({
154
+ ref: t.id,
155
+ kind: 'ticket',
156
+ title: safeText(t.title, C.TITLE_MAX) || t.id,
157
+ status,
158
+ ...(who(t.assignee) ? { assignee: who(t.assignee) } : {}),
159
+ ...(team ? { team: safeText(team, C.NAME_MAX) } : {}),
160
+ project: safeText(t.project, C.NAME_MAX),
161
+ updatedAt: t.updatedAt,
162
+ ...(safeText(last, C.TEXT_MAX) ? { last: safeText(last, C.TEXT_MAX) } : {}),
163
+ ...(t.assignee ? { session: t.assignee } : {}),
164
+ });
165
+ }
166
+ for (const w of src.workItems) {
167
+ const meta = w.metadata?.['projectTicket'];
168
+ if (linked.has(w.id) || (meta && typeof meta === 'object'))
169
+ continue;
170
+ const status = workItemStatus(w.status);
171
+ const at = workItemUpdatedAt(w);
172
+ if (!recentEnough(status, at))
173
+ continue;
174
+ const team = w.target ? teamOfAgent.get(w.target) : undefined;
175
+ const last = safeText(workItemLast(w), C.TEXT_MAX);
176
+ items.push({
177
+ ref: `wi:${w.id.slice(0, 8)}`,
178
+ kind: 'work',
179
+ title: safeText(w.title, C.TITLE_MAX) || 'Untitled work',
180
+ status,
181
+ ...(who(w.target) ? { assignee: who(w.target) } : {}),
182
+ ...(team ? { team: safeText(team, C.NAME_MAX) } : {}),
183
+ updatedAt: at,
184
+ ...(last ? { last } : {}),
185
+ ...(w.target ? { session: w.target } : {}),
186
+ });
187
+ }
188
+ items.sort((a, b) => STATUS_RANK[a.status] - STATUS_RANK[b.status] || Date.parse(b.updatedAt) - Date.parse(a.updatedAt));
189
+ // --- agents ---------------------------------------------------------------
190
+ const feed = messagesToOwner(src.ownerFeed.messages, src.ownerFeed.ownerTurns, src.agents.map((a) => a.agentSession));
191
+ const agents = src.agents.slice(0, C.MAX_AGENTS).map((a) => {
192
+ const running = src.workItems
193
+ .filter((w) => w.target === a.agentSession && (w.status === 'running' || w.status === 'accepted'))
194
+ .sort((x, y) => Date.parse(y.startedAt ?? y.createdAt) - Date.parse(x.startedAt ?? x.createdAt))[0];
195
+ const ticket = running ? undefined : items.find((i) => i.kind === 'ticket' && i.session === a.agentSession && i.status === 'in_progress');
196
+ const linkedTicket = running ? src.tickets.find((t) => t.workItemId === running.id) : undefined;
197
+ const activity = running
198
+ ? { title: safeText(linkedTicket?.title ?? running.title, C.TITLE_MAX), since: running.startedAt ?? running.createdAt, ref: linkedTicket?.id ?? `wi:${running.id.slice(0, 8)}` }
199
+ : ticket
200
+ ? { title: ticket.title, since: ticket.updatedAt, ref: ticket.ref }
201
+ : undefined;
202
+ const last = feed
203
+ .filter((m) => (m.agentSession ?? m.senderId) === a.agentSession)
204
+ .slice(0, C.MAX_LAST_TO_OWNER)
205
+ .map((m) => ({ at: new Date(m.createdAt).toISOString(), text: safeText(m.content, C.TEXT_MAX) }))
206
+ .filter((m) => m.text);
207
+ return {
208
+ session: a.agentSession,
209
+ name: safeText(a.name, C.NAME_MAX) || a.agentSession,
210
+ ...(a.team ? { team: safeText(a.team, C.NAME_MAX) } : {}),
211
+ ...(a.role ? { role: safeText(a.role, C.NAME_MAX) } : {}),
212
+ state: a.state,
213
+ ...(activity && activity.title ? { activity } : {}),
214
+ ...(last.length ? { lastToOwner: last } : {}),
215
+ };
216
+ });
217
+ // --- waiting --------------------------------------------------------------
218
+ const waiting = src.waiting.slice(0, C.MAX_WAITING).map((w) => ({
219
+ ref: waitingRef(w),
220
+ kind: w.kind,
221
+ from: safeText(w.agentName, C.NAME_MAX) || w.agentSession,
222
+ ...(w.teamName || teamOfAgent.get(w.agentSession) ? { team: safeText(w.teamName ?? teamOfAgent.get(w.agentSession) ?? '', C.NAME_MAX) } : {}),
223
+ summary: safeText(w.summary, C.TEXT_MAX) || 'Waiting on you',
224
+ since: w.since,
225
+ urgency: w.urgency,
226
+ }));
227
+ // --- teams ----------------------------------------------------------------
228
+ const teams = src.teams.slice(0, C.MAX_TEAMS).map((t) => {
229
+ const mine = items.filter((i) => i.team === safeText(t.name, C.NAME_MAX));
230
+ const n = (s) => mine.filter((i) => i.status === s).length;
231
+ return {
232
+ name: safeText(t.name, C.NAME_MAX),
233
+ ...(t.lead && nameOf.get(t.lead) ? { lead: safeText(nameOf.get(t.lead), C.NAME_MAX) } : {}),
234
+ agents: t.members.map((m) => safeText(nameOf.get(m) ?? m, C.NAME_MAX)).filter(Boolean),
235
+ open: n('open'),
236
+ inProgress: n('in_progress'),
237
+ review: n('review'),
238
+ blocked: n('blocked'),
239
+ doneToday: n('done'),
240
+ };
241
+ });
242
+ const snapshot = {
243
+ v: 1,
244
+ generatedAt: src.now.toISOString(),
245
+ teams,
246
+ agents,
247
+ items: items.slice(0, C.MAX_ITEMS).map(({ session: _session, ...i }) => i),
248
+ waiting,
249
+ };
250
+ return capSnapshot(snapshot, C.MAX_BYTES);
251
+ }
252
+ /**
253
+ * A spoken reference for a waiting item: the card id (`D-7`), the ticket
254
+ * (`TKT-5`), or a short question id.
255
+ *
256
+ * @param w - Waiting item
257
+ * @returns Reference
258
+ */
259
+ export function waitingRef(w) {
260
+ if (w.answerTarget.decisionId)
261
+ return w.answerTarget.decisionId;
262
+ if (w.answerTarget.tkt)
263
+ return w.answerTarget.tkt;
264
+ const tail = w.id.split(':').pop() ?? w.id;
265
+ return `${w.kind === 'question' ? 'Q' : 'R'}-${tail.slice(0, 6)}`;
266
+ }
267
+ /**
268
+ * Keep the snapshot under `maxBytes`: drop finished work first, then older
269
+ * messages to the owner, then the least urgent items and waiting entries.
270
+ *
271
+ * @param s - Snapshot
272
+ * @param maxBytes - Size cap (JSON)
273
+ * @returns A snapshot within the cap
274
+ */
275
+ export function capSnapshot(s, maxBytes) {
276
+ const out = { ...s, items: [...s.items], waiting: [...s.waiting], agents: s.agents.map((a) => ({ ...a })) };
277
+ const size = () => Buffer.byteLength(JSON.stringify(out), 'utf8');
278
+ while (size() > maxBytes) {
279
+ const done = out.items.map((i) => i.status).lastIndexOf('done');
280
+ if (done >= 0) {
281
+ out.items.splice(done, 1);
282
+ continue;
283
+ }
284
+ const chatty = out.agents.find((a) => (a.lastToOwner?.length ?? 0) > 1);
285
+ if (chatty) {
286
+ chatty.lastToOwner = chatty.lastToOwner?.slice(0, 1);
287
+ continue;
288
+ }
289
+ if (out.items.length > 0) {
290
+ out.items.pop();
291
+ continue;
292
+ }
293
+ if (out.waiting.length > 0) {
294
+ out.waiting.pop();
295
+ continue;
296
+ }
297
+ break;
298
+ }
299
+ return out;
300
+ }
301
+ //# sourceMappingURL=drive-briefing-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-briefing-snapshot.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-briefing-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * DriveBriefingSyncService — keeps this machine's Drive mode status snapshot
3
+ * fresh on Crewly Cloud (specs/2026-10-09-drive-mode-v3.md §1), so the voice
4
+ * answers "how is CE doing?" at once, built while work happens rather than
5
+ * pulled when the owner starts talking.
6
+ *
7
+ * - On events (a ticket changed, a work item moved, an agent wrote to the
8
+ * owner, a card was created or settled) it gathers them, rebuilds the
9
+ * snapshot and uploads it when it changed — at most one rebuild every
10
+ * 30 s; events in between are coalesced into the next one.
11
+ * - Every minute it rebuilds anyway (agent states, anything an event missed)
12
+ * and uploads only on a change; every 5 minutes it uploads regardless, so
13
+ * Cloud knows the snapshot is current.
14
+ * - Building costs no LLM call: see `drive-briefing-snapshot.ts`.
15
+ *
16
+ * Uses the machine's own Cloud token; signed out = nothing is sent.
17
+ * `CREWLY_DRIVE_BRIEFING=0` turns it off. A Cloud that does not take
18
+ * snapshots yet (404 / 400 / 503) is asked again in an hour. Never throws.
19
+ *
20
+ * @module services/drive/drive-briefing-sync.service
21
+ */
22
+ import { type ComponentLogger } from '../core/logger.service.js';
23
+ import type { BriefingSnapshot } from './drive-briefing.contract.js';
24
+ /** The Cloud session (CloudClientService). */
25
+ export interface BriefingSyncCloud {
26
+ getToken(): string | null;
27
+ getCloudUrl(): string | null;
28
+ tryRefreshToken?(): Promise<boolean>;
29
+ }
30
+ /** Subscribe to one kind of change; returns an unsubscribe function. */
31
+ export type BriefingChangeSource = (listener: () => void) => () => void;
32
+ /** Constructor dependencies. */
33
+ export interface DriveBriefingSyncDeps {
34
+ /** Build the snapshot now (from structured data only) */
35
+ build: () => Promise<BriefingSnapshot>;
36
+ cloud: BriefingSyncCloud;
37
+ /** This machine's Cloud instance id */
38
+ identity: () => Promise<{
39
+ instanceId: string;
40
+ }>;
41
+ /** Event sources that make the snapshot stale */
42
+ sources?: BriefingChangeSource[];
43
+ env?: NodeJS.ProcessEnv;
44
+ fetchImpl?: (input: string, init: RequestInit) => Promise<Response>;
45
+ now?: () => number;
46
+ setTimeout?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;
47
+ clearTimeout?: (handle: ReturnType<typeof setTimeout>) => void;
48
+ logger?: ComponentLogger;
49
+ }
50
+ /** What one pass did. */
51
+ export type BriefingSyncOutcome = 'uploaded' | 'unchanged' | 'skipped' | 'failed' | 'paused';
52
+ /**
53
+ * Whether the snapshot push is switched off.
54
+ *
55
+ * @param env - Environment
56
+ * @returns True for `CREWLY_DRIVE_BRIEFING=0|off|false|no`
57
+ */
58
+ export declare function isBriefingSyncDisabled(env: NodeJS.ProcessEnv): boolean;
59
+ /**
60
+ * The snapshot's identity for change detection (its build time left out).
61
+ *
62
+ * @param s - Snapshot
63
+ * @returns Key
64
+ */
65
+ export declare function snapshotKey(s: BriefingSnapshot): string;
66
+ /** Pushes the machine's status snapshot to Crewly Cloud — see module docs. */
67
+ export declare class DriveBriefingSyncService {
68
+ private readonly deps;
69
+ private readonly logger;
70
+ private readonly fetchImpl;
71
+ private readonly now;
72
+ private readonly setTimer;
73
+ private readonly clearTimer;
74
+ private started;
75
+ private running;
76
+ private rerun;
77
+ private checkTimer;
78
+ private debounceTimer;
79
+ private unsubscribers;
80
+ private lastKey;
81
+ private lastAccount;
82
+ private lastUploadAt;
83
+ private lastBuildAt;
84
+ private failures;
85
+ private pausedUntil;
86
+ private pauseLogged;
87
+ /**
88
+ * @param deps - Collaborators
89
+ */
90
+ constructor(deps: DriveBriefingSyncDeps);
91
+ /** Subscribe to the event sources and start the periodic check. Idempotent; never throws. */
92
+ start(): void;
93
+ /** Stop timers and subscriptions. */
94
+ stop(): void;
95
+ /**
96
+ * Something changed: rebuild after the gather window, and no sooner than
97
+ * the minimum interval after the last rebuild (events coalesce).
98
+ */
99
+ requestSync(): void;
100
+ private scheduleCheck;
101
+ /**
102
+ * Rebuild and upload when it changed (or the full resync is due). One pass
103
+ * at a time; a call during one runs again after it. Never throws.
104
+ *
105
+ * @param force - Upload even when unchanged
106
+ * @returns What happened
107
+ */
108
+ syncNow(force?: boolean): Promise<BriefingSyncOutcome>;
109
+ private pass;
110
+ private upload;
111
+ }
112
+ //# sourceMappingURL=drive-briefing-sync.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-briefing-sync.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-briefing-sync.service.ts"],"names":[],"mappings":"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"}