crewly 1.20.361 → 1.20.362

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 (145) hide show
  1. package/config/roles/team-leader/prompt.md +1 -1
  2. package/config/roles/team-leader/tl-addon.md +1 -1
  3. package/config/skills/team-leader/delegate-task/SKILL.md +21 -6
  4. package/config/skills/team-leader/delegate-task/execute.sh +12 -1
  5. package/dist/backend/backend/src/constants.d.ts +153 -6
  6. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  7. package/dist/backend/backend/src/constants.js +153 -6
  8. package/dist/backend/backend/src/constants.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  10. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +7 -4
  11. package/dist/backend/backend/src/controllers/task-pool/task-pool.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 +53 -1
  14. package/dist/backend/backend/src/index.js.map +1 -1
  15. package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts.map +1 -1
  16. package/dist/backend/backend/src/services/agent/follow-through.wiring.js +2 -0
  17. package/dist/backend/backend/src/services/agent/follow-through.wiring.js.map +1 -1
  18. package/dist/backend/backend/src/services/agent/handover-interrupted.d.ts +76 -0
  19. package/dist/backend/backend/src/services/agent/handover-interrupted.d.ts.map +1 -0
  20. package/dist/backend/backend/src/services/agent/handover-interrupted.js +139 -0
  21. package/dist/backend/backend/src/services/agent/handover-interrupted.js.map +1 -0
  22. package/dist/backend/backend/src/services/agent/handover-pointers.d.ts +4 -0
  23. package/dist/backend/backend/src/services/agent/handover-pointers.d.ts.map +1 -1
  24. package/dist/backend/backend/src/services/agent/handover-pointers.js +11 -4
  25. package/dist/backend/backend/src/services/agent/handover-pointers.js.map +1 -1
  26. package/dist/backend/backend/src/services/agent/idle-work-guard.d.ts +3 -1
  27. package/dist/backend/backend/src/services/agent/idle-work-guard.d.ts.map +1 -1
  28. package/dist/backend/backend/src/services/agent/idle-work-guard.js +2 -0
  29. package/dist/backend/backend/src/services/agent/idle-work-guard.js.map +1 -1
  30. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts +5 -1
  31. package/dist/backend/backend/src/services/agent/resource-mode-protection.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/agent/resource-mode-protection.js +6 -1
  33. package/dist/backend/backend/src/services/agent/resource-mode-protection.js.map +1 -1
  34. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +7 -0
  35. package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +18 -1
  37. package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  38. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +8 -0
  39. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +10 -0
  41. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -1
  42. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts +43 -2
  43. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/open-items/open-item-extractor.js +124 -13
  45. package/dist/backend/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  46. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +40 -1
  47. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/open-items/open-items.service.js +76 -3
  49. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/open-items/open-items.wiring.d.ts +8 -0
  51. package/dist/backend/backend/src/services/open-items/open-items.wiring.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/open-items/open-items.wiring.js +19 -1
  53. package/dist/backend/backend/src/services/open-items/open-items.wiring.js.map +1 -1
  54. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +35 -19
  55. package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -1
  56. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +60 -63
  57. package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -1
  58. package/dist/backend/backend/src/services/orc/owner-completion-report.text.d.ts +86 -0
  59. package/dist/backend/backend/src/services/orc/owner-completion-report.text.d.ts.map +1 -0
  60. package/dist/backend/backend/src/services/orc/owner-completion-report.text.js +170 -0
  61. package/dist/backend/backend/src/services/orc/owner-completion-report.text.js.map +1 -0
  62. package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts +24 -0
  63. package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts.map +1 -1
  64. package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js +38 -1
  65. package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js.map +1 -1
  66. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +2 -0
  67. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  68. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +8 -3
  69. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  70. package/dist/backend/backend/src/services/orc/work-item-destination.d.ts +76 -0
  71. package/dist/backend/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
  72. package/dist/backend/backend/src/services/orc/work-item-destination.js +83 -3
  73. package/dist/backend/backend/src/services/orc/work-item-destination.js.map +1 -1
  74. package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts +31 -2
  75. package/dist/backend/backend/src/services/orc/work-item-destination.wiring.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js +38 -0
  77. package/dist/backend/backend/src/services/orc/work-item-destination.wiring.js.map +1 -1
  78. package/dist/backend/backend/src/services/stall/background-run-detector.d.ts +56 -0
  79. package/dist/backend/backend/src/services/stall/background-run-detector.d.ts.map +1 -0
  80. package/dist/backend/backend/src/services/stall/background-run-detector.js +93 -0
  81. package/dist/backend/backend/src/services/stall/background-run-detector.js.map +1 -0
  82. package/dist/backend/backend/src/services/stall/claim-check.d.ts +60 -0
  83. package/dist/backend/backend/src/services/stall/claim-check.d.ts.map +1 -0
  84. package/dist/backend/backend/src/services/stall/claim-check.js +98 -0
  85. package/dist/backend/backend/src/services/stall/claim-check.js.map +1 -0
  86. package/dist/backend/backend/src/services/stall/in-flight-runs.store.d.ts +110 -0
  87. package/dist/backend/backend/src/services/stall/in-flight-runs.store.d.ts.map +1 -0
  88. package/dist/backend/backend/src/services/stall/in-flight-runs.store.js +109 -0
  89. package/dist/backend/backend/src/services/stall/in-flight-runs.store.js.map +1 -0
  90. package/dist/backend/backend/src/services/stall/stall-watcher.service.d.ts +456 -0
  91. package/dist/backend/backend/src/services/stall/stall-watcher.service.d.ts.map +1 -0
  92. package/dist/backend/backend/src/services/stall/stall-watcher.service.js +854 -0
  93. package/dist/backend/backend/src/services/stall/stall-watcher.service.js.map +1 -0
  94. package/dist/backend/backend/src/services/stall/stall-watcher.wiring.d.ts +98 -0
  95. package/dist/backend/backend/src/services/stall/stall-watcher.wiring.d.ts.map +1 -0
  96. package/dist/backend/backend/src/services/stall/stall-watcher.wiring.js +217 -0
  97. package/dist/backend/backend/src/services/stall/stall-watcher.wiring.js.map +1 -0
  98. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +53 -0
  99. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  100. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +162 -15
  101. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  102. package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.js +1 -1
  103. package/dist/backend/backend/src/services/tl-delegation/tl-delegation.service.js.map +1 -1
  104. package/dist/backend/backend/src/types/v2/open-item.types.d.ts +2 -0
  105. package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  106. package/dist/backend/build-info.json +2 -2
  107. package/dist/cli/backend/src/constants.d.ts +153 -6
  108. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  109. package/dist/cli/backend/src/constants.js +153 -6
  110. package/dist/cli/backend/src/constants.js.map +1 -1
  111. package/dist/cli/backend/src/services/agent/handover-interrupted.d.ts +76 -0
  112. package/dist/cli/backend/src/services/agent/handover-interrupted.d.ts.map +1 -0
  113. package/dist/cli/backend/src/services/agent/handover-interrupted.js +139 -0
  114. package/dist/cli/backend/src/services/agent/handover-interrupted.js.map +1 -0
  115. package/dist/cli/backend/src/services/agent/handover-pointers.d.ts +4 -0
  116. package/dist/cli/backend/src/services/agent/handover-pointers.d.ts.map +1 -1
  117. package/dist/cli/backend/src/services/agent/handover-pointers.js +11 -4
  118. package/dist/cli/backend/src/services/agent/handover-pointers.js.map +1 -1
  119. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +7 -0
  120. package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
  121. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +18 -1
  122. package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
  123. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts +8 -0
  124. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -1
  125. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js +10 -0
  126. package/dist/cli/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -1
  127. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts +43 -2
  128. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  129. package/dist/cli/backend/src/services/open-items/open-item-extractor.js +124 -13
  130. package/dist/cli/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  131. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +40 -1
  132. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  133. package/dist/cli/backend/src/services/open-items/open-items.service.js +76 -3
  134. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  135. package/dist/cli/backend/src/services/orc/work-item-destination.d.ts +76 -0
  136. package/dist/cli/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
  137. package/dist/cli/backend/src/services/orc/work-item-destination.js +83 -3
  138. package/dist/cli/backend/src/services/orc/work-item-destination.js.map +1 -1
  139. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +53 -0
  140. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  141. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +162 -15
  142. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  143. package/dist/cli/backend/src/types/v2/open-item.types.d.ts +2 -0
  144. package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  145. package/package.json +1 -1
@@ -0,0 +1,456 @@
1
+ /**
2
+ * Stall watcher (crewly#1363, crewly#1362, specs/2026-10-17-stall-watcher.md).
3
+ *
4
+ * Stalls used to be a metric only (`TRACE_CONSTANTS.STALL_MINUTES`). This
5
+ * service acts on three kinds of in-flight work, each keyed to the agent's
6
+ * own estimate when it gave one:
7
+ *
8
+ * - **Promises to the owner** (open-items commitments): at 1.5× the estimate
9
+ * past the promise with nothing posted, the agent is re-briefed once with
10
+ * the last message from someone else before the promise (the approval it
11
+ * may be re-waiting for, crewly#1361); at 3× the team lead is told once;
12
+ * when the lead has not answered in the thread within LEAD_GRACE_MS, the
13
+ * owner gets one plain line (at most one per item per day).
14
+ * - **Claimed WorkItems**: the run trace's ongoing stall (no tool calls,
15
+ * posts or worktree changes for CLAIM_STALL_MS) nudges the claimer once
16
+ * with the cause; a second window with no progress releases the claim
17
+ * (unassigned, so the route sweep hands it to the lead and then the
18
+ * orchestrator) and tells the lead. Tickets the ticket autopilot already
19
+ * watches are left to it.
20
+ * - **Background runs**: an agent saying it started something that takes a
21
+ * while ("已经开跑…预计 1 小时左右") is recorded in
22
+ * `CREWLY_HOME/in-flight-runs.json`; the agent is protected from idle stops
23
+ * and evictions until expectedBy + grace; the same ladder as promises
24
+ * applies when nothing (a file, a link, a finished / failed report) lands in
25
+ * the thread.
26
+ *
27
+ * Plus the claim check (crewly#1362): "X is doing it" told to the owner with
28
+ * no WorkItem or ticket for X within CLAIM_CHECK_WINDOW_MS gets the speaker
29
+ * one internal line; the owner hears nothing.
30
+ *
31
+ * Cost control: every line to an agent is one line and tagged; one nudge per
32
+ * agent per NUDGE_COOLDOWN_MS; the owner is never the retry loop. The first
33
+ * ARM_DELAY_MS after the first pass is a dry run (logs only).
34
+ *
35
+ * @module services/stall/stall-watcher.service
36
+ */
37
+ import { type ComponentLogger } from '../core/logger.service.js';
38
+ import type { Request } from '../../types/v2/request.types.js';
39
+ import type { WorkItem } from '../../types/v2/work-item.types.js';
40
+ import type { TaskClaim } from '../../types/v2/claim.types.js';
41
+ import type { StallCause } from '../trace/trace-metrics.js';
42
+ import { type ClaimableMember } from './claim-check.js';
43
+ import { type InFlightRun, type InFlightRunsStore, type StallWatcherState } from './in-flight-runs.store.js';
44
+ /** A chat-v2 message as the watcher reads it (from the thread or the live event). */
45
+ export interface StallThreadMessage {
46
+ id: string;
47
+ senderType: string;
48
+ senderId: string;
49
+ content: string;
50
+ /** Epoch ms */
51
+ createdAt: number;
52
+ /** Attachments on the post */
53
+ attachmentCount?: number;
54
+ metadata?: Record<string, unknown>;
55
+ }
56
+ /** A live chat-v2 message (the `chat_message` event). */
57
+ export interface StallIncomingMessage extends StallThreadMessage {
58
+ channelId: string;
59
+ /** Thread root; absent for a root post */
60
+ threadId?: string;
61
+ }
62
+ /** Where a conversation lives in chat-v2. */
63
+ export interface StallThreadRef {
64
+ channelId: string;
65
+ threadId: string;
66
+ }
67
+ /** An ongoing stall on a trace, as the traces service sees it. */
68
+ export interface StallSignal {
69
+ /** Length of the gap so far (ms) */
70
+ ms: number;
71
+ cause: StallCause;
72
+ detail: string;
73
+ }
74
+ /** A step of the ladder. */
75
+ export type LadderStep = 'agent' | 'lead' | 'owner';
76
+ /** The owner's language, read from the owner's own messages in the thread. */
77
+ export type OwnerLanguage = 'zh' | 'en';
78
+ /** The boot-pressure gate (same shape as the wiki maintenance one). */
79
+ export type StallBootGate = () => Promise<{
80
+ reduced: boolean;
81
+ waitedMs: number;
82
+ reason?: string;
83
+ }>;
84
+ /** Collaborators. */
85
+ export interface StallWatcherDeps {
86
+ /** Every request (tickets with open items) */
87
+ listRequests: () => Promise<Request[]>;
88
+ /** Every WorkItem */
89
+ listWorkItems: () => Promise<WorkItem[]>;
90
+ /** Active claims (running items with a holder) */
91
+ activeClaims: () => Promise<TaskClaim[]>;
92
+ /** WorkItems that belong to an in-progress project ticket (the ticket autopilot watches those) */
93
+ ticketLinkedWorkItemIds?: () => Promise<ReadonlySet<string>>;
94
+ /** Every message of a thread, oldest first */
95
+ threadMessages: (ref: StallThreadRef) => Promise<StallThreadMessage[]>;
96
+ /** The ongoing stall of the trace a claimed item (or its holder) is on, or null when it is moving */
97
+ stallOf: (ref: {
98
+ workItemId: string;
99
+ session: string;
100
+ }) => Promise<StallSignal | null>;
101
+ /** Release a stalled claim: the item goes back to the queue, unassigned */
102
+ releaseClaim: (workItemId: string, reason: string) => Promise<void>;
103
+ /** One line to an agent (wakes it); false when it could not be delivered */
104
+ deliverToAgent: (session: string, text: string) => Promise<boolean>;
105
+ /** The agent's team lead, or null */
106
+ leadOf: (session: string) => Promise<string | null>;
107
+ /** Display name ("Pia") */
108
+ displayName: (session: string) => Promise<string>;
109
+ /** One plain line to the owner (the owner-alert notifier); false when not sent */
110
+ notifyOwner: (line: string) => Promise<boolean>;
111
+ /** Stamp a ladder step on an open-items commitment, so the open-items sweep does not repeat it */
112
+ recordPromiseStep: (requestId: string, itemId: string, step: LadderStep, at: Date) => Promise<void>;
113
+ /** The speaker's teammates (for "X is doing it") */
114
+ teammatesOf: (session: string) => Promise<ClaimableMember[]>;
115
+ /** A WorkItem or ticket for `member`, created by `speaker` or the harness, within ±windowMs of `saidAt` */
116
+ assignmentExists: (speaker: string, member: string, saidAt: number, windowMs: number) => Promise<boolean>;
117
+ /** Whether a live message is a reply to the owner (claims elsewhere are not checked); absent = every agent post */
118
+ isOwnerThread?: (message: StallIncomingMessage) => Promise<boolean>;
119
+ /** Record a harness nudge on the session's trace */
120
+ trace?: (input: {
121
+ session: string;
122
+ summary: string;
123
+ workItemId?: string;
124
+ data?: Record<string, unknown>;
125
+ }) => void;
126
+ bootGate?: StallBootGate;
127
+ store: InFlightRunsStore;
128
+ now?: () => number;
129
+ env?: NodeJS.ProcessEnv;
130
+ logger?: ComponentLogger;
131
+ }
132
+ /** What one pass did. */
133
+ export interface StallTickResult {
134
+ /** Set when the pass did not run */
135
+ skipped?: 'disabled';
136
+ dryRun: boolean;
137
+ promises: {
138
+ agent: number;
139
+ lead: number;
140
+ owner: number;
141
+ };
142
+ claims: {
143
+ nudged: number;
144
+ released: number;
145
+ };
146
+ runs: {
147
+ agent: number;
148
+ lead: number;
149
+ owner: number;
150
+ cleared: number;
151
+ };
152
+ teammateClaims: {
153
+ checked: number;
154
+ nudged: number;
155
+ };
156
+ }
157
+ /**
158
+ * Clip text to one line of at most `max` characters.
159
+ *
160
+ * @param text - Text
161
+ * @param max - Max characters
162
+ * @returns Clipped text
163
+ */
164
+ export declare function clip(text: string, max: number): string;
165
+ /**
166
+ * A duration in words, in the owner's language.
167
+ *
168
+ * @param ms - Milliseconds
169
+ * @param lang - Language
170
+ * @returns "40 分钟" / "1.5 小时" / "40 minutes" / "1.5 hours"
171
+ */
172
+ export declare function durationWords(ms: number, lang?: OwnerLanguage): string;
173
+ /**
174
+ * The owner's language in a thread: Chinese when the owner's own messages
175
+ * hold more CJK characters than Latin letters, else English (CLAUDE.md:
176
+ * harness text is English; a line to the owner follows the owner).
177
+ *
178
+ * @param messages - The thread
179
+ * @returns 'zh' or 'en'
180
+ */
181
+ export declare function ownerLanguage(messages: readonly StallThreadMessage[]): OwnerLanguage;
182
+ /**
183
+ * The last message by someone other than the agent before a time: the
184
+ * approval or instruction the promise answered (crewly#1361 expectation 2).
185
+ *
186
+ * @param messages - The thread
187
+ * @param agent - The promising agent
188
+ * @param before - Epoch ms of the promise
189
+ * @returns That message, or null
190
+ */
191
+ export declare function contextBefore(messages: readonly StallThreadMessage[], agent: string, before: number): StallThreadMessage | null;
192
+ /**
193
+ * Whether a run's agent posted a deliverable or a finished / failed report in
194
+ * the thread after the run started.
195
+ *
196
+ * @param messages - The thread
197
+ * @param run - The run
198
+ * @returns True when the run is over as far as the thread shows
199
+ */
200
+ export declare function runDeliveredIn(messages: readonly StallThreadMessage[], run: Pick<InFlightRun, 'agent' | 'startedAt' | 'id'>): boolean;
201
+ /**
202
+ * The time each ladder step is due.
203
+ *
204
+ * @param madeAt - Promise / run start (ms)
205
+ * @param estimateMs - The agent's estimate
206
+ * @returns Due times (ms)
207
+ */
208
+ export declare function ladderDue(madeAt: number, estimateMs: number): {
209
+ agentDue: number;
210
+ leadDue: number;
211
+ };
212
+ /**
213
+ * The idle-stop / eviction protection reason for a session with a run in
214
+ * flight, or null.
215
+ *
216
+ * @param runs - Recorded runs
217
+ * @param session - Agent session
218
+ * @param now - Epoch ms
219
+ * @returns English reason, or null
220
+ */
221
+ export declare function runProtectionReason(runs: readonly InFlightRun[], session: string, now: number): string | null;
222
+ /**
223
+ * Whether the watcher is switched on.
224
+ *
225
+ * @param env - Environment
226
+ * @returns False when CREWLY_STALL_WATCHER=false
227
+ */
228
+ export declare function stallWatcherEnabled(env?: NodeJS.ProcessEnv): boolean;
229
+ /**
230
+ * Whether a pass is a dry run: CREWLY_STALL_WATCHER_DRY_RUN=true/false wins;
231
+ * otherwise dry until ARM_DELAY_MS after the first pass.
232
+ *
233
+ * @param armedAt - When the first pass ran (ms), or undefined
234
+ * @param now - Epoch ms
235
+ * @param env - Environment
236
+ * @returns True to only log
237
+ */
238
+ export declare function stallWatcherDryRun(armedAt: number | undefined, now: number, env?: NodeJS.ProcessEnv): boolean;
239
+ /**
240
+ * The agent-facing stall cause: the trace's label plus its detail.
241
+ *
242
+ * @param signal - Stall signal
243
+ * @returns One clause
244
+ */
245
+ export declare function causeText(signal: StallSignal): string;
246
+ /**
247
+ * The one plain line the owner gets about a promise.
248
+ *
249
+ * @param lang - Owner's language
250
+ * @param input - Names and times
251
+ * @returns The line
252
+ */
253
+ export declare function promiseOwnerLine(lang: OwnerLanguage, input: {
254
+ name: string;
255
+ what: string;
256
+ estimateMs: number;
257
+ elapsedMs: number;
258
+ leadName: string | null;
259
+ }): string;
260
+ /**
261
+ * The one plain line the owner gets about a background run.
262
+ *
263
+ * @param lang - Owner's language
264
+ * @param input - Names and times
265
+ * @returns The line
266
+ */
267
+ export declare function runOwnerLine(lang: OwnerLanguage, input: {
268
+ name: string;
269
+ head: string;
270
+ estimateMs: number;
271
+ elapsedMs: number;
272
+ leadName: string | null;
273
+ }): string;
274
+ /**
275
+ * The running watcher, if any.
276
+ *
277
+ * @returns The service, or null
278
+ */
279
+ export declare function getStallWatcher(): StallWatcherService | null;
280
+ /**
281
+ * Install (or clear) the process-wide watcher.
282
+ *
283
+ * @param service - The service, or null
284
+ */
285
+ export declare function setStallWatcher(service: StallWatcherService | null): void;
286
+ /**
287
+ * Watches in-flight work and climbs the agent → lead → owner ladder.
288
+ */
289
+ export declare class StallWatcherService {
290
+ private readonly deps;
291
+ private readonly logger;
292
+ private readonly now;
293
+ private readonly env;
294
+ private state;
295
+ private loaded;
296
+ private timer;
297
+ private bootTimer;
298
+ private chain;
299
+ /**
300
+ * @param deps - Collaborators
301
+ */
302
+ constructor(deps: StallWatcherDeps);
303
+ /**
304
+ * Whether the kill switch is off.
305
+ *
306
+ * @returns True when the watcher may run
307
+ */
308
+ enabled(): boolean;
309
+ /**
310
+ * Load the state file, then schedule the first pass (after the boot
311
+ * gate and BOOT_DELAY_MS) and the periodic passes. No-op when disabled.
312
+ */
313
+ start(): void;
314
+ /** Stop the passes. Safe to call more than once. */
315
+ stop(): void;
316
+ /**
317
+ * Read the state file once (later passes keep the in-memory copy).
318
+ *
319
+ * @returns The state
320
+ */
321
+ load(): Promise<StallWatcherState>;
322
+ /**
323
+ * The first pass: waits at the boot-pressure gate like the other
324
+ * maintenance passes, then ticks.
325
+ *
326
+ * @returns What the pass did
327
+ */
328
+ bootTick(): Promise<StallTickResult>;
329
+ /**
330
+ * Why an agent must not be idle-stopped or evicted right now: a run it
331
+ * announced is still expected. Synchronous, from the in-memory state.
332
+ *
333
+ * @param session - Agent session
334
+ * @returns English reason, or null
335
+ */
336
+ protectedRunReason(session: string): string | null;
337
+ /**
338
+ * The runs recorded for a session (tests and the status endpoint).
339
+ *
340
+ * @param session - Agent session
341
+ * @returns Runs, newest last
342
+ */
343
+ runsOf(session: string): InFlightRun[];
344
+ /**
345
+ * A chat-v2 message arrived. Agent posts can start a background run,
346
+ * close one (a deliverable or a finished / failed report in its thread)
347
+ * or claim that a teammate is doing something. Other posts are ignored
348
+ * here; the lead's answer is read from the thread when the ladder needs it.
349
+ *
350
+ * @param message - The message
351
+ */
352
+ onMessage(message: StallIncomingMessage): Promise<void>;
353
+ /**
354
+ * One pass over every kind of in-flight work.
355
+ *
356
+ * @returns What the pass did
357
+ */
358
+ tick(): Promise<StallTickResult>;
359
+ /**
360
+ * Run `fn` after every earlier change to the state (one writer).
361
+ *
362
+ * @param fn - Work
363
+ * @returns Its result
364
+ */
365
+ private serial;
366
+ /**
367
+ * The pass itself (under {@link serial}).
368
+ *
369
+ * @returns What it did
370
+ */
371
+ private pass;
372
+ /**
373
+ * One line to an agent, at most one per agent per NUDGE_COOLDOWN_MS.
374
+ *
375
+ * @param agent - Session
376
+ * @param text - The line
377
+ * @param now - Epoch ms
378
+ * @param dry - Dry run: log only
379
+ * @param recentNudgeAt - A nudge from elsewhere that counts for the cooldown
380
+ * @returns What happened
381
+ */
382
+ private nudgeAgent;
383
+ /**
384
+ * One line to an agent's lead.
385
+ *
386
+ * @param agent - The agent whose lead is told
387
+ * @param text - The line (built with the lead's name)
388
+ * @param dry - Dry run
389
+ * @returns The lead session when told (or would be), null when there is no lead or it failed
390
+ */
391
+ private tellLead;
392
+ /**
393
+ * Display name of a session (falls back to the session).
394
+ *
395
+ * @param session - Session
396
+ * @returns Name
397
+ */
398
+ private name;
399
+ /**
400
+ * Climb one step of the ladder for an item, when it is due.
401
+ *
402
+ * @param item - The item
403
+ * @param now - Epoch ms
404
+ * @param dry - Dry run
405
+ * @returns The step taken, or null
406
+ */
407
+ private climb;
408
+ /**
409
+ * Active commitments with a due time: the ladder keyed to the agent's
410
+ * estimate (due − made). The open-items sweep's own stamps count as steps.
411
+ *
412
+ * @param now - Epoch ms
413
+ * @param dry - Dry run
414
+ * @param result - Counters
415
+ */
416
+ private promisesPass;
417
+ /**
418
+ * The ladder item of a commitment.
419
+ *
420
+ * @param request - Its request
421
+ * @param item - The commitment
422
+ * @param madeAt - Promise time (ms)
423
+ * @param estimateMs - due − made
424
+ * @param now - Epoch ms
425
+ * @returns Ladder item
426
+ */
427
+ private promiseLadderItem;
428
+ /**
429
+ * Running items with an active claim: the trace's ongoing stall nudges the
430
+ * claimer once; a second window releases the claim and tells the lead.
431
+ *
432
+ * @param now - Epoch ms
433
+ * @param dry - Dry run
434
+ * @param result - Counters
435
+ */
436
+ private claimsPass;
437
+ /**
438
+ * Runs agents announced: closed when the thread shows a deliverable or a
439
+ * report, else the same ladder as promises from the run's start.
440
+ *
441
+ * @param now - Epoch ms
442
+ * @param dry - Dry run
443
+ * @param result - Counters
444
+ */
445
+ private runsPass;
446
+ /**
447
+ * Claims past their window: a WorkItem or ticket for the teammate exists,
448
+ * or the speaker is told once. Never the owner.
449
+ *
450
+ * @param now - Epoch ms
451
+ * @param dry - Dry run
452
+ * @param result - Counters
453
+ */
454
+ private teammateClaimsPass;
455
+ }
456
+ //# sourceMappingURL=stall-watcher.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stall-watcher.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/stall/stall-watcher.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAI5D,OAAO,EAAwC,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAA0B,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAuC,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAQ1K,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,yDAAyD;AACzD,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC3B,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;AAExC,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEnG,qBAAqB;AACrB,MAAM,WAAW,gBAAgB;IAChC,8CAA8C;IAC9C,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,qBAAqB;IACrB,aAAa,EAAE,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,kDAAkD;IAClD,YAAY,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACzC,kGAAkG;IAClG,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,8CAA8C;IAC9C,cAAc,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACvE,qGAAqG;IACrG,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACvF,2EAA2E;IAC3E,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,4EAA4E;IAC5E,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,qCAAqC;IACrC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpD,2BAA2B;IAC3B,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,kFAAkF;IAClF,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,kGAAkG;IAClG,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpG,oDAAoD;IACpD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7D,2GAA2G;IAC3G,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1G,mHAAmH;IACnH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,oDAAoD;IACpD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IACnH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,yBAAyB;AACzB,MAAM,WAAW,eAAe;IAC/B,oCAAoC;IACpC,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,cAAc,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AAuBD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,aAAoB,GAAG,MAAM,CAO5E;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,GAAG,aAAa,CASpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAO/H;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAAC,GAAG,OAAO,CAUrI;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAKnG;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7G;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAEjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK1H;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAIrD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CASnK;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAS/J;AAqBD;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,mBAAmB,GAAG,IAAI,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI,CAEzE;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAanB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAZjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,KAAK,CAAuC;IAEpD;;OAEG;gBAC0B,IAAI,EAAE,gBAAgB;IAMnD;;;;OAIG;IACH,OAAO,IAAI,OAAO;IAIlB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAiBb,oDAAoD;IACpD,IAAI,IAAI,IAAI;IAWZ;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAQxC;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC;IAY1C;;;;;;OAMG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIlD;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE;IAItC;;;;;;;OAOG;IACH,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DvD;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAIhC;;;;;OAKG;IACH,OAAO,CAAC,MAAM;IAMd;;;;OAIG;YACW,IAAI;IAmClB;;;;;;;;;OASG;YACW,UAAU;IAaxB;;;;;;;OAOG;YACW,QAAQ;IAYtB;;;;;OAKG;YACW,IAAI;IAQlB;;;;;;;OAOG;YACW,KAAK;IA4DnB;;;;;;;OAOG;YACW,YAAY;IAe1B;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IA4CzB;;;;;;;OAOG;YACW,UAAU;IAwDxB;;;;;;;OAOG;YACW,QAAQ;IA8CtB;;;;;;;OAOG;YACW,kBAAkB;CAwBhC"}