@agentdeck/bridge 1.0.20 → 1.0.22

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 (211) hide show
  1. package/dist/adapters/openclaw.d.ts +55 -1
  2. package/dist/adapters/openclaw.d.ts.map +1 -1
  3. package/dist/adapters/openclaw.js +278 -45
  4. package/dist/adapters/openclaw.js.map +1 -1
  5. package/dist/adb-reverse.d.ts +26 -3
  6. package/dist/adb-reverse.d.ts.map +1 -1
  7. package/dist/adb-reverse.js +26 -5
  8. package/dist/adb-reverse.js.map +1 -1
  9. package/dist/apme/adapters/openclaw-hook.d.ts +45 -1
  10. package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -1
  11. package/dist/apme/adapters/openclaw-hook.js +84 -4
  12. package/dist/apme/adapters/openclaw-hook.js.map +1 -1
  13. package/dist/apme/claude-transcript-reader.d.ts +54 -0
  14. package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
  15. package/dist/apme/claude-transcript-reader.js +77 -0
  16. package/dist/apme/claude-transcript-reader.js.map +1 -1
  17. package/dist/apme/collector.d.ts +63 -5
  18. package/dist/apme/collector.d.ts.map +1 -1
  19. package/dist/apme/collector.js +147 -10
  20. package/dist/apme/collector.js.map +1 -1
  21. package/dist/apme/store.d.ts +23 -1
  22. package/dist/apme/store.d.ts.map +1 -1
  23. package/dist/apme/store.js +81 -2
  24. package/dist/apme/store.js.map +1 -1
  25. package/dist/apme/types.d.ts +1 -1
  26. package/dist/apme/types.d.ts.map +1 -1
  27. package/dist/apme/types.js.map +1 -1
  28. package/dist/auth.d.ts +37 -0
  29. package/dist/auth.d.ts.map +1 -1
  30. package/dist/auth.js +23 -0
  31. package/dist/auth.js.map +1 -1
  32. package/dist/ble-sync-spawn.d.ts +27 -0
  33. package/dist/ble-sync-spawn.d.ts.map +1 -1
  34. package/dist/ble-sync-spawn.js +32 -0
  35. package/dist/ble-sync-spawn.js.map +1 -1
  36. package/dist/bridge-core.d.ts +21 -4
  37. package/dist/bridge-core.d.ts.map +1 -1
  38. package/dist/bridge-core.js +52 -23
  39. package/dist/bridge-core.js.map +1 -1
  40. package/dist/claude-interrupt-marker.d.ts +31 -0
  41. package/dist/claude-interrupt-marker.d.ts.map +1 -0
  42. package/dist/claude-interrupt-marker.js +58 -0
  43. package/dist/claude-interrupt-marker.js.map +1 -0
  44. package/dist/claude-turn-watchdog.d.ts +23 -0
  45. package/dist/claude-turn-watchdog.d.ts.map +1 -1
  46. package/dist/claude-turn-watchdog.js +30 -4
  47. package/dist/claude-turn-watchdog.js.map +1 -1
  48. package/dist/cli.d.ts +6 -0
  49. package/dist/cli.d.ts.map +1 -1
  50. package/dist/cli.js +411 -115
  51. package/dist/cli.js.map +1 -1
  52. package/dist/codex-rate-limits-live.d.ts +58 -9
  53. package/dist/codex-rate-limits-live.d.ts.map +1 -1
  54. package/dist/codex-rate-limits-live.js +64 -15
  55. package/dist/codex-rate-limits-live.js.map +1 -1
  56. package/dist/codex-rate-limits.d.ts +2 -2
  57. package/dist/codex-rate-limits.d.ts.map +1 -1
  58. package/dist/codex-rate-limits.js +34 -16
  59. package/dist/codex-rate-limits.js.map +1 -1
  60. package/dist/daemon-port.d.ts +90 -0
  61. package/dist/daemon-port.d.ts.map +1 -0
  62. package/dist/daemon-port.js +119 -0
  63. package/dist/daemon-port.js.map +1 -0
  64. package/dist/daemon-server.d.ts +60 -3
  65. package/dist/daemon-server.d.ts.map +1 -1
  66. package/dist/daemon-server.js +362 -109
  67. package/dist/daemon-server.js.map +1 -1
  68. package/dist/daemon-settings.d.ts +46 -0
  69. package/dist/daemon-settings.d.ts.map +1 -0
  70. package/dist/daemon-settings.js +85 -0
  71. package/dist/daemon-settings.js.map +1 -0
  72. package/dist/daemon-takeover.d.ts +75 -0
  73. package/dist/daemon-takeover.d.ts.map +1 -0
  74. package/dist/daemon-takeover.js +137 -0
  75. package/dist/daemon-takeover.js.map +1 -0
  76. package/dist/daemon.js +1 -1
  77. package/dist/hook-server.d.ts.map +1 -1
  78. package/dist/hook-server.js +17 -0
  79. package/dist/hook-server.js.map +1 -1
  80. package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -1
  81. package/dist/idotmatrix/idotmatrix-daemon-sync.js +13 -1
  82. package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +34 -12
  86. package/dist/index.js.map +1 -1
  87. package/dist/kiro-diagnostics.d.ts +90 -0
  88. package/dist/kiro-diagnostics.d.ts.map +1 -0
  89. package/dist/kiro-diagnostics.js +278 -0
  90. package/dist/kiro-diagnostics.js.map +1 -0
  91. package/dist/kiro-session.d.ts +113 -0
  92. package/dist/kiro-session.d.ts.map +1 -0
  93. package/dist/kiro-session.js +688 -0
  94. package/dist/kiro-session.js.map +1 -0
  95. package/dist/kiro-timeline-feed.d.ts +45 -0
  96. package/dist/kiro-timeline-feed.d.ts.map +1 -0
  97. package/dist/kiro-timeline-feed.js +116 -0
  98. package/dist/kiro-timeline-feed.js.map +1 -0
  99. package/dist/kiro-transcript-timeline.d.ts +57 -0
  100. package/dist/kiro-transcript-timeline.d.ts.map +1 -0
  101. package/dist/kiro-transcript-timeline.js +183 -0
  102. package/dist/kiro-transcript-timeline.js.map +1 -0
  103. package/dist/linux-service.d.ts +2 -1
  104. package/dist/linux-service.d.ts.map +1 -1
  105. package/dist/linux-service.js +8 -3
  106. package/dist/linux-service.js.map +1 -1
  107. package/dist/mdns-discover.d.ts +27 -0
  108. package/dist/mdns-discover.d.ts.map +1 -1
  109. package/dist/mdns-discover.js +60 -7
  110. package/dist/mdns-discover.js.map +1 -1
  111. package/dist/mdns.d.ts.map +1 -1
  112. package/dist/mdns.js +16 -3
  113. package/dist/mdns.js.map +1 -1
  114. package/dist/modules/adb-module.d.ts.map +1 -1
  115. package/dist/modules/adb-module.js +5 -2
  116. package/dist/modules/adb-module.js.map +1 -1
  117. package/dist/modules/index.d.ts +2 -1
  118. package/dist/modules/index.d.ts.map +1 -1
  119. package/dist/modules/index.js +1 -0
  120. package/dist/modules/index.js.map +1 -1
  121. package/dist/modules/types.d.ts +34 -9
  122. package/dist/modules/types.d.ts.map +1 -1
  123. package/dist/modules/types.js +34 -1
  124. package/dist/modules/types.js.map +1 -1
  125. package/dist/network-posture.d.ts +67 -0
  126. package/dist/network-posture.d.ts.map +1 -0
  127. package/dist/network-posture.js +100 -0
  128. package/dist/network-posture.js.map +1 -0
  129. package/dist/observed-steering.d.ts +14 -0
  130. package/dist/observed-steering.d.ts.map +1 -1
  131. package/dist/observed-steering.js +18 -0
  132. package/dist/observed-steering.js.map +1 -1
  133. package/dist/observed-turn-watchdogs.d.ts +84 -0
  134. package/dist/observed-turn-watchdogs.d.ts.map +1 -0
  135. package/dist/observed-turn-watchdogs.js +134 -0
  136. package/dist/observed-turn-watchdogs.js.map +1 -0
  137. package/dist/openclaw-session.d.ts +10 -0
  138. package/dist/openclaw-session.d.ts.map +1 -1
  139. package/dist/openclaw-session.js +12 -0
  140. package/dist/openclaw-session.js.map +1 -1
  141. package/dist/passive-observer.d.ts +19 -0
  142. package/dist/passive-observer.d.ts.map +1 -1
  143. package/dist/passive-observer.js +208 -24
  144. package/dist/passive-observer.js.map +1 -1
  145. package/dist/pixoo/micro-glyphs.d.ts +1 -1
  146. package/dist/pixoo/micro-glyphs.d.ts.map +1 -1
  147. package/dist/pixoo/micro-glyphs.js +2 -0
  148. package/dist/pixoo/micro-glyphs.js.map +1 -1
  149. package/dist/pixoo/official-dot-glyphs.generated.d.ts +1 -1
  150. package/dist/pixoo/official-dot-glyphs.generated.d.ts.map +1 -1
  151. package/dist/pixoo/official-dot-glyphs.generated.js +47 -0
  152. package/dist/pixoo/official-dot-glyphs.generated.js.map +1 -1
  153. package/dist/pixoo/pixoo-discover.d.ts +8 -1
  154. package/dist/pixoo/pixoo-discover.d.ts.map +1 -1
  155. package/dist/pixoo/pixoo-discover.js +15 -8
  156. package/dist/pixoo/pixoo-discover.js.map +1 -1
  157. package/dist/pixoo/pixoo-renderer.d.ts +4 -2
  158. package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
  159. package/dist/pixoo/pixoo-renderer.js +105 -36
  160. package/dist/pixoo/pixoo-renderer.js.map +1 -1
  161. package/dist/pixoo/pixoo-settings.d.ts +19 -2
  162. package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
  163. package/dist/pixoo/pixoo-settings.js +22 -4
  164. package/dist/pixoo/pixoo-settings.js.map +1 -1
  165. package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
  166. package/dist/pixoo/pixoo-sprites.js +2 -0
  167. package/dist/pixoo/pixoo-sprites.js.map +1 -1
  168. package/dist/python-ble-runtime.d.ts +2 -0
  169. package/dist/python-ble-runtime.d.ts.map +1 -1
  170. package/dist/python-ble-runtime.js +101 -7
  171. package/dist/python-ble-runtime.js.map +1 -1
  172. package/dist/session-aggregator.d.ts +9 -1
  173. package/dist/session-aggregator.d.ts.map +1 -1
  174. package/dist/session-aggregator.js +1 -1
  175. package/dist/session-aggregator.js.map +1 -1
  176. package/dist/session-registry.d.ts +71 -3
  177. package/dist/session-registry.d.ts.map +1 -1
  178. package/dist/session-registry.js +126 -19
  179. package/dist/session-registry.js.map +1 -1
  180. package/dist/subagent-timeline.d.ts +38 -7
  181. package/dist/subagent-timeline.d.ts.map +1 -1
  182. package/dist/subagent-timeline.js +154 -23
  183. package/dist/subagent-timeline.js.map +1 -1
  184. package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -1
  185. package/dist/timebox/timebox-daemon-sync.js +11 -1
  186. package/dist/timebox/timebox-daemon-sync.js.map +1 -1
  187. package/dist/timeline-store.d.ts.map +1 -1
  188. package/dist/timeline-store.js +26 -1
  189. package/dist/timeline-store.js.map +1 -1
  190. package/dist/tui/renderer.d.ts.map +1 -1
  191. package/dist/tui/renderer.js +13 -1
  192. package/dist/tui/renderer.js.map +1 -1
  193. package/dist/tui/terrarium.d.ts.map +1 -1
  194. package/dist/tui/terrarium.js +10 -5
  195. package/dist/tui/terrarium.js.map +1 -1
  196. package/dist/usage-api.d.ts +28 -1
  197. package/dist/usage-api.d.ts.map +1 -1
  198. package/dist/usage-api.js +74 -33
  199. package/dist/usage-api.js.map +1 -1
  200. package/dist/usage-event.d.ts.map +1 -1
  201. package/dist/usage-event.js +2 -17
  202. package/dist/usage-event.js.map +1 -1
  203. package/dist/utils/redact-secrets.d.ts +3 -0
  204. package/dist/utils/redact-secrets.d.ts.map +1 -0
  205. package/dist/utils/redact-secrets.js +29 -0
  206. package/dist/utils/redact-secrets.js.map +1 -0
  207. package/dist/windows-service.d.ts +2 -1
  208. package/dist/windows-service.d.ts.map +1 -1
  209. package/dist/windows-service.js +6 -3
  210. package/dist/windows-service.js.map +1 -1
  211. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"claude-transcript-reader.d.ts","sourceRoot":"","sources":["../../src/apme/claude-transcript-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAsD3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB7E;AAED,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qEAAqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAiC5E"}
1
+ {"version":3,"file":"claude-transcript-reader.d.ts","sourceRoot":"","sources":["../../src/apme/claude-transcript-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAsD3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB7E;AAED,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qEAAqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;2EACuE;IACvE,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;gCAWgC;AAChC,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;qDAEqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sEAAsE;IACtE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;mEAC+D;IAC/D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAkC5E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA8BrG"}
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import { readFileSync, openSync, readSync, fstatSync, closeSync } from 'fs';
19
19
  import { debug } from '../logger.js';
20
+ import { isClaudeInterruptRecord } from '../claude-interrupt-marker.js';
20
21
  /**
21
22
  * Parse the last user→assistant turn from a Claude Code transcript JSONL.
22
23
  *
@@ -123,6 +124,19 @@ export function readModelFromTranscript(transcriptPath) {
123
124
  }
124
125
  return null;
125
126
  }
127
+ /** `stop_reason` Claude Code writes when the CLIENT ended the turn instead of
128
+ * the model: usage limit, expired auth, credit limit, an API 429/529. The
129
+ * record carries the user-facing message ("You've hit your session limit ·
130
+ * resets 5:50pm") and NO Stop hook follows it — so a turn that ends this way
131
+ * owes no Stop and must not be charged to the dropped-hook rate.
132
+ *
133
+ * Measured before it was trusted: across 211 local transcripts holding 61,281
134
+ * assistant records, `stop_reason` was `tool_use` 58,765 times, `end_turn`
135
+ * 2,513 times, and `stop_sequence` 37 times — every one of those 37 a client
136
+ * abort message, none followed by a `stop_hook_summary` record, and none
137
+ * followed by further assistant work in the same turn. There is no benign
138
+ * shape to confuse it with. */
139
+ export const CLIENT_ABORT_STOP_REASON = 'stop_sequence';
126
140
  /**
127
141
  * Probe whether the transcript's most recent turn has finished. A completed
128
142
  * turn's last message-bearing record is `role: "assistant"` with
@@ -131,6 +145,11 @@ export function readModelFromTranscript(transcriptPath) {
131
145
  * can trail the assistant message, so the walk skips records without a
132
146
  * `message.role`. Never throws; returns null when unreadable/empty.
133
147
  *
148
+ * The OTHER way a turn ends is the user pressing ESC, which produces no
149
+ * assistant `end_turn` at all — just the interrupt marker record — so
150
+ * `interrupted` is reported alongside, and a caller that only checked for
151
+ * `end_turn` would wait forever on a turn nothing will ever close.
152
+ *
134
153
  * Used by the turn watchdog to close a turn whose Stop hook was dropped —
135
154
  * the caller must additionally check `timestampMs` against its own turn-open
136
155
  * time, because at turn start the tail still shows the PREVIOUS turn's
@@ -167,10 +186,68 @@ export function readTurnEndProbe(transcriptPath) {
167
186
  role,
168
187
  stopReason: rec.message?.stop_reason ?? null,
169
188
  timestampMs: Number.isFinite(ts) ? ts : null,
189
+ interrupted: isClaudeInterruptRecord(rec),
170
190
  };
171
191
  }
172
192
  return null;
173
193
  }
194
+ /**
195
+ * Everything a bounded tail read can say about a turn that opened at `sinceMs`
196
+ * and is still open. Returns null when the transcript is unreadable — the
197
+ * absence of evidence, which callers must never resolve as a verdict.
198
+ *
199
+ * Three questions, one read, because the close path that runs at the next
200
+ * prompt has to ask all of them and each answer is a different bucket:
201
+ *
202
+ * - Did the user cancel? `readTurnEndProbe` only sees the ESC marker while it
203
+ * is still the tail, and the common shape is "cancel, then immediately
204
+ * retype", which buries it under the new user message within seconds.
205
+ * - Did the CLIENT abort (usage limit, auth, API error)? Same burial, and
206
+ * Claude Code owes no Stop for it either.
207
+ * - Did the assistant write anything at all? If not, this prompt never got a
208
+ * turn of its own — a second prompt landed first and one model turn served
209
+ * both, so the displaced row is a counting artifact, not a lost hook.
210
+ *
211
+ * The backward walk stops at the first record older than the window, so
212
+ * evidence belonging to an earlier turn can neither be found nor paid for.
213
+ */
214
+ export function readOpenTurnEvidence(transcriptPath, sinceMs) {
215
+ const EVIDENCE_TAIL_BYTES = 256 * 1024;
216
+ const tail = readTailString(transcriptPath, EVIDENCE_TAIL_BYTES);
217
+ if (tail == null)
218
+ return null;
219
+ const evidence = { interruptedAt: null, abortedAt: null, sawAssistant: false };
220
+ const lines = tail.split('\n');
221
+ for (let i = lines.length - 1; i >= 0; i--) {
222
+ const line = lines[i];
223
+ if (!line.trim())
224
+ continue;
225
+ let rec;
226
+ try {
227
+ rec = JSON.parse(line);
228
+ }
229
+ catch {
230
+ continue; // skip malformed (possibly truncated) line
231
+ }
232
+ const ts = rec.timestamp ? Date.parse(rec.timestamp) : NaN;
233
+ // A record with no usable timestamp cannot be placed in or out of the
234
+ // window, so it is skipped rather than ending the walk — ending here
235
+ // would let one stampless line hide every marker behind it.
236
+ if (!Number.isFinite(ts))
237
+ continue;
238
+ if (ts < sinceMs)
239
+ break;
240
+ if (evidence.interruptedAt == null && isClaudeInterruptRecord(rec))
241
+ evidence.interruptedAt = ts;
242
+ if (rec.message?.role === 'assistant') {
243
+ evidence.sawAssistant = true;
244
+ if (evidence.abortedAt == null && rec.message?.stop_reason === CLIENT_ABORT_STOP_REASON) {
245
+ evidence.abortedAt = ts;
246
+ }
247
+ }
248
+ }
249
+ return evidence;
250
+ }
174
251
  /** Read at most `maxBytes` from the end of a file without loading the rest.
175
252
  * Returns null when the file is unreadable. */
176
253
  function readTailString(path, maxBytes) {
@@ -1 +1 @@
1
- {"version":3,"file":"claude-transcript-reader.js","sourceRoot":"","sources":["../../src/apme/claude-transcript-reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-transcript-reader.js","sourceRoot":"","sources":["../../src/apme/claude-transcript-reader.ts"],"names":[],"mappings":"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"}
@@ -14,8 +14,9 @@
14
14
  import type { UsageSnapshot } from '../types.js';
15
15
  import type { SessionEntry } from '../session-registry.js';
16
16
  import type { ApmeStore } from './store.js';
17
- import type { AgentType, TelemetrySpan, ApmeSampleEventRow } from '@agentdeck/shared';
17
+ import type { AgentType, TelemetrySpan, ApmeSampleEventRow, TurnEndSource } from '@agentdeck/shared';
18
18
  import type { ApmeHwSampler } from './hw-sampler.js';
19
+ import { type OpenTurnEvidence } from './claude-transcript-reader.js';
19
20
  export interface OpenRunInput {
20
21
  sessionId: string;
21
22
  agentType: AgentType;
@@ -87,6 +88,10 @@ export type OnTaskMilestone = (args: {
87
88
  export declare class ApmeCollector {
88
89
  private readonly store;
89
90
  private readonly hwSampler?;
91
+ /** What the transcript proves about a turn open since a timestamp — cancel,
92
+ * client abort, or never having run at all. Injectable for tests; the
93
+ * default reads the Claude transcript tail once for all three. */
94
+ private readonly openTurnProbe;
90
95
  private readonly sessionToRun;
91
96
  private readonly sessionToAgentType;
92
97
  private readonly sessionToTurn;
@@ -109,7 +114,11 @@ export declare class ApmeCollector {
109
114
  /** Last milestone key (`taskId:turnIndex`) per session — a turn can carry
110
115
  * several all-completed TodoWrite calls; surface only the first. */
111
116
  private readonly sessionToLastMilestone;
112
- constructor(store: ApmeStore, hwSampler?: ApmeHwSampler | undefined);
117
+ constructor(store: ApmeStore, hwSampler?: ApmeHwSampler | undefined,
118
+ /** What the transcript proves about a turn open since a timestamp — cancel,
119
+ * client abort, or never having run at all. Injectable for tests; the
120
+ * default reads the Claude transcript tail once for all three. */
121
+ openTurnProbe?: (transcriptPath: string, sinceMs: number) => OpenTurnEvidence | null);
113
122
  /** Start a new run and return its id. Safe to call if store disabled (returns ''). */
114
123
  openRun(input: OpenRunInput): string;
115
124
  /** Record a hook event as a step + manage turn lifecycle.
@@ -128,8 +137,57 @@ export declare class ApmeCollector {
128
137
  * to finalize the turn row immediately rather than wait for the next
129
138
  * UserPromptSubmit / closeRun to flush endedAt + buffered counters.
130
139
  * Idempotent — no-op when no active turn for the session. */
131
- closeTurnForSession(sessionId: string): void;
132
- /** Close the current turn for a session (called on new prompt or session end). */
140
+ closeTurnForSession(sessionId: string, source?: TurnEndSource): void;
141
+ /** The agent reported its turn finished (Claude `Stop`, real or synthetic).
142
+ *
143
+ * Two jobs, both of which need to happen at the Stop and not one prompt
144
+ * later. First, `ended_at` is stamped HERE, so a turn's duration is the
145
+ * agent's working time instead of that plus however long the user took to
146
+ * type the next thing — before this, an overnight gap between prompts was
147
+ * indistinguishable from a 5-hour turn, and every duration-derived
148
+ * efficiency number was reading user think time. Second, `end_source`
149
+ * records WHICH signal closed it, which is the whole Stop-delivery
150
+ * instrument: a turn that reaches the next prompt still open is a Stop that
151
+ * was lost, and one closed by `synthetic_stop` is a Stop that was lost and
152
+ * recovered. Neither is visible if every turn closes the same way.
153
+ *
154
+ * Callers must record the response BEFORE calling this — `setTurnResponse`
155
+ * does fall back to the last-closed turn, but the sample trajectory and the
156
+ * `response_kind` tag read cleaner while the turn is still active.
157
+ *
158
+ * Idempotent: a duplicate or late Stop finds no active turn and no-ops, so
159
+ * a synthetic Stop racing a real one cannot overwrite the real attribution. */
160
+ noteTurnStop(sessionId: string, opts?: {
161
+ synthetic?: boolean;
162
+ interrupted?: boolean;
163
+ aborted?: boolean;
164
+ }): void;
165
+ /** Attribute a turn that is still open when the next prompt arrives.
166
+ *
167
+ * `next_prompt` is the only bucket that means "a Stop was owed and never
168
+ * came", so everything that reaches here for some other reason has to be
169
+ * told apart before it inflates the very loss rate this instrument
170
+ * measures. Three do, and one bounded tail read answers all three — on this
171
+ * path only, since a healthy turn is closed by its Stop long before this
172
+ * runs:
173
+ *
174
+ * - A CANCEL. The watchdog catches one only while the interrupt marker is
175
+ * still the transcript's tail; the commonest ESC shape — cancel, then
176
+ * retype straight away — buries it under the new user message in seconds
177
+ * and fires a fresh `UserPromptSubmit`.
178
+ * - A CLIENT ABORT (usage limit, expired auth, API error). The watchdog
179
+ * closes those at +15s, but not if it was swept for idleness first
180
+ * (30 min) or the daemon restarted mid-turn — and an abort is exactly
181
+ * the shape that then sits open for hours.
182
+ * - A turn that NEVER RAN. Queued prompts and `<task-notification>`
183
+ * injections arrive in pairs ~130 ms apart; Claude serves both with one
184
+ * model turn and owes exactly one Stop, which closes the LAST of them.
185
+ * A displaced row with no assistant record behind it at all is that
186
+ * artifact, not a lost hook. */
187
+ private resolveDisplacedTurnSource;
188
+ /** Close the current turn for a session (called on Stop, new prompt, or
189
+ * session end). `source` records which of those it was — see
190
+ * `TurnEndSource`. */
133
191
  private closeTurn;
134
192
  /** Get the current active turn ID for a session (if any). */
135
193
  getActiveTurnId(sessionId: string): string | null;
@@ -233,7 +291,7 @@ export declare class ApmeCollector {
233
291
  /** Finalize a run. Returns the runId so callers can enqueue evaluation.
234
292
  * Empty runs (no prompts, no steps, no turns) are deleted — they're just
235
293
  * connection noise and clutter the dashboard. */
236
- closeRun(sessionId: string, exitCode?: number, projectPath?: string): string | null;
294
+ closeRun(sessionId: string, exitCode?: number, projectPath?: string, turnEndSource?: TurnEndSource): string | null;
237
295
  /** Save the git diff produced by this run as an artifact file. */
238
296
  private saveDiffArtifact;
239
297
  /** Translate a `SessionEntry` + optional extras into an OpenRunInput. */
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/apme/collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/apme/collector.ts"],"names":[],"mappings":"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"}
@@ -20,14 +20,22 @@ import { debug } from '../logger.js';
20
20
  import { resolveProjectName } from '../utils/project-name.js';
21
21
  import { priceUsd, providerFor } from '@agentdeck/shared';
22
22
  import { classifyRunSmart, computeSignals, classify } from './classifier.js';
23
+ import { readOpenTurnEvidence } from './claude-transcript-reader.js';
23
24
  /** A turn_start with the same prompt landing on a fresh, still-empty turn
24
25
  * within this window is treated as a transport echo (e.g. OpenClaw
25
26
  * `chat.send` span + the gateway's `session.message` role=user re-delivery
26
27
  * of the same text), not a new turn. */
27
28
  const DUPLICATE_TURN_OPEN_WINDOW_MS = 15_000;
29
+ /** Clock slack when asking whether an interrupt marker belongs to THIS turn.
30
+ * The turn's `startedAt` is the daemon's clock at the hook POST while the
31
+ * marker carries Claude Code's own record timestamp; without a little give,
32
+ * a cancel milliseconds into a turn reads as belonging to the previous one.
33
+ * Matches the watchdog's `TURN_OPEN_SLACK_MS` — same comparison, same risk. */
34
+ const TURN_INTERRUPT_SLACK_MS = 2_000;
28
35
  export class ApmeCollector {
29
36
  store;
30
37
  hwSampler;
38
+ openTurnProbe;
31
39
  sessionToRun = new Map(); // sessionId → runId
32
40
  sessionToAgentType = new Map(); // sessionId → agentType (survives closeRun for late-attributed timeline rows)
33
41
  sessionToTurn = new Map(); // sessionId → current turn
@@ -50,9 +58,14 @@ export class ApmeCollector {
50
58
  /** Last milestone key (`taskId:turnIndex`) per session — a turn can carry
51
59
  * several all-completed TodoWrite calls; surface only the first. */
52
60
  sessionToLastMilestone = new Map();
53
- constructor(store, hwSampler) {
61
+ constructor(store, hwSampler,
62
+ /** What the transcript proves about a turn open since a timestamp — cancel,
63
+ * client abort, or never having run at all. Injectable for tests; the
64
+ * default reads the Claude transcript tail once for all three. */
65
+ openTurnProbe = readOpenTurnEvidence) {
54
66
  this.store = store;
55
67
  this.hwSampler = hwSampler;
68
+ this.openTurnProbe = openTurnProbe;
56
69
  }
57
70
  /** Start a new run and return its id. Safe to call if store disabled (returns ''). */
58
71
  openRun(input) {
@@ -133,7 +146,11 @@ export class ApmeCollector {
133
146
  prevIndex = lastIdx;
134
147
  }
135
148
  }
136
- this.closeTurn(sessionId);
149
+ // A turn still open when the NEXT prompt arrives never got its Stop —
150
+ // and no watchdog recovered it either, or the synthetic Stop would have
151
+ // closed it already. That is the unrecovered-loss bucket, UNLESS the
152
+ // user cancelled it, in which case no Stop was ever owed.
153
+ this.closeTurn(sessionId, this.resolveDisplacedTurnSource(sessionId, data));
137
154
  // Open new turn
138
155
  const turnIndex = prevIndex + 1;
139
156
  const run = this.store.getRun(runId);
@@ -275,11 +292,107 @@ export class ApmeCollector {
275
292
  * to finalize the turn row immediately rather than wait for the next
276
293
  * UserPromptSubmit / closeRun to flush endedAt + buffered counters.
277
294
  * Idempotent — no-op when no active turn for the session. */
278
- closeTurnForSession(sessionId) {
279
- this.closeTurn(sessionId);
295
+ closeTurnForSession(sessionId, source = 'stop') {
296
+ this.closeTurn(sessionId, source);
280
297
  }
281
- /** Close the current turn for a session (called on new prompt or session end). */
282
- closeTurn(sessionId) {
298
+ /** The agent reported its turn finished (Claude `Stop`, real or synthetic).
299
+ *
300
+ * Two jobs, both of which need to happen at the Stop and not one prompt
301
+ * later. First, `ended_at` is stamped HERE, so a turn's duration is the
302
+ * agent's working time instead of that plus however long the user took to
303
+ * type the next thing — before this, an overnight gap between prompts was
304
+ * indistinguishable from a 5-hour turn, and every duration-derived
305
+ * efficiency number was reading user think time. Second, `end_source`
306
+ * records WHICH signal closed it, which is the whole Stop-delivery
307
+ * instrument: a turn that reaches the next prompt still open is a Stop that
308
+ * was lost, and one closed by `synthetic_stop` is a Stop that was lost and
309
+ * recovered. Neither is visible if every turn closes the same way.
310
+ *
311
+ * Callers must record the response BEFORE calling this — `setTurnResponse`
312
+ * does fall back to the last-closed turn, but the sample trajectory and the
313
+ * `response_kind` tag read cleaner while the turn is still active.
314
+ *
315
+ * Idempotent: a duplicate or late Stop finds no active turn and no-ops, so
316
+ * a synthetic Stop racing a real one cannot overwrite the real attribution. */
317
+ noteTurnStop(sessionId, opts = {}) {
318
+ if (!this.store.enabled)
319
+ return;
320
+ // `interrupted` and `aborted` both outrank `synthetic`: neither ending
321
+ // produces a real Stop, so each can only ever arrive AS a synthetic one,
322
+ // and reading the flags the other way round would file every user cancel
323
+ // and every usage-limit abort as a dropped hook. Cancel wins over abort on
324
+ // the impossible both-set case, for the same reason it wins over synthetic
325
+ // — it is the narrower, user-caused claim.
326
+ const source = opts.interrupted ? 'interrupted'
327
+ : opts.aborted ? 'aborted'
328
+ : opts.synthetic ? 'synthetic_stop'
329
+ : 'stop';
330
+ this.closeTurn(sessionId, source);
331
+ }
332
+ /** Attribute a turn that is still open when the next prompt arrives.
333
+ *
334
+ * `next_prompt` is the only bucket that means "a Stop was owed and never
335
+ * came", so everything that reaches here for some other reason has to be
336
+ * told apart before it inflates the very loss rate this instrument
337
+ * measures. Three do, and one bounded tail read answers all three — on this
338
+ * path only, since a healthy turn is closed by its Stop long before this
339
+ * runs:
340
+ *
341
+ * - A CANCEL. The watchdog catches one only while the interrupt marker is
342
+ * still the transcript's tail; the commonest ESC shape — cancel, then
343
+ * retype straight away — buries it under the new user message in seconds
344
+ * and fires a fresh `UserPromptSubmit`.
345
+ * - A CLIENT ABORT (usage limit, expired auth, API error). The watchdog
346
+ * closes those at +15s, but not if it was swept for idleness first
347
+ * (30 min) or the daemon restarted mid-turn — and an abort is exactly
348
+ * the shape that then sits open for hours.
349
+ * - A turn that NEVER RAN. Queued prompts and `<task-notification>`
350
+ * injections arrive in pairs ~130 ms apart; Claude serves both with one
351
+ * model turn and owes exactly one Stop, which closes the LAST of them.
352
+ * A displaced row with no assistant record behind it at all is that
353
+ * artifact, not a lost hook. */
354
+ resolveDisplacedTurnSource(sessionId, data) {
355
+ const turn = this.sessionToTurn.get(sessionId);
356
+ // No open turn: closeTurn no-ops, so the value is immaterial.
357
+ if (!turn)
358
+ return 'next_prompt';
359
+ // Claude-only: the marker and the JSONL shape are Claude Code's.
360
+ if (this.sessionToAgentType.get(sessionId) !== 'claude-code')
361
+ return 'next_prompt';
362
+ const transcriptPath = typeof data.transcript_path === 'string' ? data.transcript_path : '';
363
+ if (!transcriptPath)
364
+ return 'next_prompt';
365
+ try {
366
+ const evidence = this.openTurnProbe(transcriptPath, turn.startedAt - TURN_INTERRUPT_SLACK_MS);
367
+ // An unreadable transcript is no evidence of anything — never guess.
368
+ if (!evidence)
369
+ return 'next_prompt';
370
+ if (evidence.interruptedAt != null)
371
+ return 'interrupted';
372
+ if (evidence.abortedAt != null)
373
+ return 'aborted';
374
+ // Ordered last on purpose: a cancelled or aborted turn that also wrote
375
+ // nothing is still a cancel or an abort, not a superseded prompt.
376
+ //
377
+ // Two independent facts must agree before a turn is called one that
378
+ // never ran, because the transcript walk alone is not quite enough for
379
+ // this claim: it stops at the first record older than the window, and
380
+ // Claude Code's JSONL is not strictly ordered (auxiliary records land
381
+ // tens of ms out of sequence), so one inverted stamp near the tail could
382
+ // truncate the walk and hide the assistant work behind it. A turn that
383
+ // called tools demonstrably ran whatever the transcript says.
384
+ if (!evidence.sawAssistant && turn.toolCalls === 0)
385
+ return 'superseded';
386
+ return 'next_prompt';
387
+ }
388
+ catch {
389
+ return 'next_prompt';
390
+ }
391
+ }
392
+ /** Close the current turn for a session (called on Stop, new prompt, or
393
+ * session end). `source` records which of those it was — see
394
+ * `TurnEndSource`. */
395
+ closeTurn(sessionId, source) {
283
396
  const turn = this.sessionToTurn.get(sessionId);
284
397
  if (!turn)
285
398
  return;
@@ -295,8 +408,9 @@ export class ApmeCollector {
295
408
  filesModified: turn.filesModified,
296
409
  filesCreated: turn.filesCreated,
297
410
  gitAfter,
411
+ endSource: source,
298
412
  });
299
- debug('APME', `closeTurn ${turn.id.slice(0, 8)} index=${turn.index} tools=${turn.toolCalls}`);
413
+ debug('APME', `closeTurn ${turn.id.slice(0, 8)} index=${turn.index} tools=${turn.toolCalls} src=${source}`);
300
414
  }
301
415
  catch (err) {
302
416
  debug('APME', `closeTurn failed: ${String(err)}`);
@@ -792,6 +906,29 @@ export class ApmeCollector {
792
906
  }
793
907
  return;
794
908
  }
909
+ case 'agent_error': {
910
+ // Record the failure in the trajectory. Deliberately does NOT close
911
+ // the turn or the task: the agent may retry the same prompt, and the
912
+ // adapter owns the boundary (OpenClaw re-arms its idle-gap timer).
913
+ // Without this the judge sees a turn_start with no response and no
914
+ // reason — indistinguishable from a dropped event.
915
+ const label = a['agentdeck.error_label']?.trim();
916
+ if (!label)
917
+ return;
918
+ const detail = a['agentdeck.error_detail']?.trim();
919
+ const task = this.sessionToTask.get(sessionId);
920
+ const turnIndex = this.sessionToTurn.get(sessionId)?.index;
921
+ if (!task || turnIndex === undefined) {
922
+ debug('APME', `agent_error span dropped: no open task/turn for ${sessionId}`);
923
+ return;
924
+ }
925
+ this.appendSampleEvent({ taskId: task.id, runId: task.runId, turnIndex, turnId: this.turnIdFor(sessionId) }, {
926
+ kind: 'info',
927
+ dedupCore: `agent_error:${label}`,
928
+ payloadObj: { label, ...(detail ? { detail } : {}) },
929
+ });
930
+ return;
931
+ }
795
932
  case 'raw_step': {
796
933
  const event = a['agentdeck.raw_event'] ?? 'raw';
797
934
  const payload = a['agentdeck.raw_payload'] ?? {};
@@ -880,7 +1017,7 @@ export class ApmeCollector {
880
1017
  // boundary=clear before closeRun tears everything down.
881
1018
  this.closeTask(sessionId, 'clear');
882
1019
  // Close current run (no exitCode — session is still alive)
883
- this.closeRun(sessionId, undefined, projectPath);
1020
+ this.closeRun(sessionId, undefined, projectPath, 'clear');
884
1021
  // Open a new run with the same session parameters, pointing back at the run
885
1022
  // it continues. `/clear` resets the agent's context, not the user's work —
886
1023
  // without this edge one conversation becomes N disconnected runs (a live
@@ -916,14 +1053,14 @@ export class ApmeCollector {
916
1053
  /** Finalize a run. Returns the runId so callers can enqueue evaluation.
917
1054
  * Empty runs (no prompts, no steps, no turns) are deleted — they're just
918
1055
  * connection noise and clutter the dashboard. */
919
- closeRun(sessionId, exitCode, projectPath) {
1056
+ closeRun(sessionId, exitCode, projectPath, turnEndSource = 'session_end') {
920
1057
  if (!this.store.enabled)
921
1058
  return null;
922
1059
  const runId = this.sessionToRun.get(sessionId);
923
1060
  if (!runId)
924
1061
  return null;
925
1062
  // Close the last open turn + task before finalizing the run.
926
- this.closeTurn(sessionId);
1063
+ this.closeTurn(sessionId, turnEndSource);
927
1064
  // splitRun already called closeTask('clear') before us, so this is usually
928
1065
  // a no-op in the split path. Direct closeRun (session exit) still needs it.
929
1066
  this.closeTask(sessionId, 'session_end');