@pcircle/footprint 1.5.0 → 1.7.0

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 (249) hide show
  1. package/README.md +301 -132
  2. package/SKILL.md +72 -28
  3. package/bin/footprint.js +16 -0
  4. package/dist/src/adapters/claude.d.ts +2 -0
  5. package/dist/src/adapters/claude.d.ts.map +1 -0
  6. package/dist/src/adapters/claude.js +7 -0
  7. package/dist/src/adapters/claude.js.map +1 -0
  8. package/dist/src/adapters/codex.d.ts +2 -0
  9. package/dist/src/adapters/codex.d.ts.map +1 -0
  10. package/dist/src/adapters/codex.js +7 -0
  11. package/dist/src/adapters/codex.js.map +1 -0
  12. package/dist/src/adapters/gemini.d.ts +2 -0
  13. package/dist/src/adapters/gemini.d.ts.map +1 -0
  14. package/dist/src/adapters/gemini.js +7 -0
  15. package/dist/src/adapters/gemini.js.map +1 -0
  16. package/dist/src/adapters/index.d.ts +5 -0
  17. package/dist/src/adapters/index.d.ts.map +1 -0
  18. package/dist/src/adapters/index.js +12 -0
  19. package/dist/src/adapters/index.js.map +1 -0
  20. package/dist/src/adapters/structured-prefix.d.ts +10 -0
  21. package/dist/src/adapters/structured-prefix.d.ts.map +1 -0
  22. package/dist/src/adapters/structured-prefix.js +59 -0
  23. package/dist/src/adapters/structured-prefix.js.map +1 -0
  24. package/dist/src/adapters/types.d.ts +32 -0
  25. package/dist/src/adapters/types.d.ts.map +1 -0
  26. package/dist/src/adapters/types.js +2 -0
  27. package/dist/src/adapters/types.js.map +1 -0
  28. package/dist/src/cli/context-flow.d.ts +92 -0
  29. package/dist/src/cli/context-flow.d.ts.map +1 -0
  30. package/dist/src/cli/context-flow.js +724 -0
  31. package/dist/src/cli/context-flow.js.map +1 -0
  32. package/dist/src/cli/history-display.d.ts +27 -0
  33. package/dist/src/cli/history-display.d.ts.map +1 -0
  34. package/dist/src/cli/history-display.js +167 -0
  35. package/dist/src/cli/history-display.js.map +1 -0
  36. package/dist/src/cli/index.js +924 -0
  37. package/dist/src/cli/index.js.map +1 -1
  38. package/dist/src/cli/launch-spec.d.ts +31 -0
  39. package/dist/src/cli/launch-spec.d.ts.map +1 -0
  40. package/dist/src/cli/launch-spec.js +182 -0
  41. package/dist/src/cli/launch-spec.js.map +1 -0
  42. package/dist/src/cli/live-demo.d.ts +34 -0
  43. package/dist/src/cli/live-demo.d.ts.map +1 -0
  44. package/dist/src/cli/live-demo.js +254 -0
  45. package/dist/src/cli/live-demo.js.map +1 -0
  46. package/dist/src/cli/pty-transcript.d.ts +34 -0
  47. package/dist/src/cli/pty-transcript.d.ts.map +1 -0
  48. package/dist/src/cli/pty-transcript.js +174 -0
  49. package/dist/src/cli/pty-transcript.js.map +1 -0
  50. package/dist/src/cli/session-display.d.ts +74 -0
  51. package/dist/src/cli/session-display.d.ts.map +1 -0
  52. package/dist/src/cli/session-display.js +922 -0
  53. package/dist/src/cli/session-display.js.map +1 -0
  54. package/dist/src/cli/session-execution.d.ts +55 -0
  55. package/dist/src/cli/session-execution.d.ts.map +1 -0
  56. package/dist/src/cli/session-execution.js +817 -0
  57. package/dist/src/cli/session-execution.js.map +1 -0
  58. package/dist/src/cli/session-runtime.d.ts +5 -0
  59. package/dist/src/cli/session-runtime.d.ts.map +1 -0
  60. package/dist/src/cli/session-runtime.js +11 -0
  61. package/dist/src/cli/session-runtime.js.map +1 -0
  62. package/dist/src/cli/setup.d.ts.map +1 -1
  63. package/dist/src/cli/setup.js +2 -0
  64. package/dist/src/cli/setup.js.map +1 -1
  65. package/dist/src/index.d.ts +4 -0
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/index.js +148 -7
  68. package/dist/src/index.js.map +1 -1
  69. package/dist/src/ingestion/deterministic.d.ts +3 -0
  70. package/dist/src/ingestion/deterministic.d.ts.map +1 -0
  71. package/dist/src/ingestion/deterministic.js +862 -0
  72. package/dist/src/ingestion/deterministic.js.map +1 -0
  73. package/dist/src/ingestion/index.d.ts +5 -0
  74. package/dist/src/ingestion/index.d.ts.map +1 -0
  75. package/dist/src/ingestion/index.js +27 -0
  76. package/dist/src/ingestion/index.js.map +1 -0
  77. package/dist/src/ingestion/semantic.d.ts +6 -0
  78. package/dist/src/ingestion/semantic.d.ts.map +1 -0
  79. package/dist/src/ingestion/semantic.js +627 -0
  80. package/dist/src/ingestion/semantic.js.map +1 -0
  81. package/dist/src/ingestion/types.d.ts +10 -0
  82. package/dist/src/ingestion/types.d.ts.map +1 -0
  83. package/dist/src/ingestion/types.js +2 -0
  84. package/dist/src/ingestion/types.js.map +1 -0
  85. package/dist/src/lib/context-memory.d.ts +140 -0
  86. package/dist/src/lib/context-memory.d.ts.map +1 -0
  87. package/dist/src/lib/context-memory.js +974 -0
  88. package/dist/src/lib/context-memory.js.map +1 -0
  89. package/dist/src/lib/history-handoff.d.ts +43 -0
  90. package/dist/src/lib/history-handoff.d.ts.map +1 -0
  91. package/dist/src/lib/history-handoff.js +179 -0
  92. package/dist/src/lib/history-handoff.js.map +1 -0
  93. package/dist/src/lib/observability.d.ts +3 -0
  94. package/dist/src/lib/observability.d.ts.map +1 -0
  95. package/dist/src/lib/observability.js +63 -0
  96. package/dist/src/lib/observability.js.map +1 -0
  97. package/dist/src/lib/session-artifacts.d.ts +51 -0
  98. package/dist/src/lib/session-artifacts.d.ts.map +1 -0
  99. package/dist/src/lib/session-artifacts.js +132 -0
  100. package/dist/src/lib/session-artifacts.js.map +1 -0
  101. package/dist/src/lib/session-filters.d.ts +11 -0
  102. package/dist/src/lib/session-filters.d.ts.map +1 -0
  103. package/dist/src/lib/session-filters.js +16 -0
  104. package/dist/src/lib/session-filters.js.map +1 -0
  105. package/dist/src/lib/session-history.d.ts +50 -0
  106. package/dist/src/lib/session-history.d.ts.map +1 -0
  107. package/dist/src/lib/session-history.js +73 -0
  108. package/dist/src/lib/session-history.js.map +1 -0
  109. package/dist/src/lib/session-trends.d.ts +129 -0
  110. package/dist/src/lib/session-trends.d.ts.map +1 -0
  111. package/dist/src/lib/session-trends.js +361 -0
  112. package/dist/src/lib/session-trends.js.map +1 -0
  113. package/dist/src/lib/storage/database.d.ts +212 -1
  114. package/dist/src/lib/storage/database.d.ts.map +1 -1
  115. package/dist/src/lib/storage/database.js +1694 -114
  116. package/dist/src/lib/storage/database.js.map +1 -1
  117. package/dist/src/lib/storage/export-sessions.d.ts +33 -0
  118. package/dist/src/lib/storage/export-sessions.d.ts.map +1 -0
  119. package/dist/src/lib/storage/export-sessions.js +525 -0
  120. package/dist/src/lib/storage/export-sessions.js.map +1 -0
  121. package/dist/src/lib/storage/index.d.ts +7 -6
  122. package/dist/src/lib/storage/index.d.ts.map +1 -1
  123. package/dist/src/lib/storage/index.js +6 -5
  124. package/dist/src/lib/storage/index.js.map +1 -1
  125. package/dist/src/lib/storage/schema.d.ts +6 -1
  126. package/dist/src/lib/storage/schema.d.ts.map +1 -1
  127. package/dist/src/lib/storage/schema.js +337 -2
  128. package/dist/src/lib/storage/schema.js.map +1 -1
  129. package/dist/src/lib/storage/types.d.ts +122 -0
  130. package/dist/src/lib/storage/types.d.ts.map +1 -1
  131. package/dist/src/prompts/skill-prompt.d.ts.map +1 -1
  132. package/dist/src/prompts/skill-prompt.js +13 -0
  133. package/dist/src/prompts/skill-prompt.js.map +1 -1
  134. package/dist/src/tools/confirm-context-link.d.ts +62 -0
  135. package/dist/src/tools/confirm-context-link.d.ts.map +1 -0
  136. package/dist/src/tools/confirm-context-link.js +36 -0
  137. package/dist/src/tools/confirm-context-link.js.map +1 -0
  138. package/dist/src/tools/context-schemas.d.ts +694 -0
  139. package/dist/src/tools/context-schemas.d.ts.map +1 -0
  140. package/dist/src/tools/context-schemas.js +171 -0
  141. package/dist/src/tools/context-schemas.js.map +1 -0
  142. package/dist/src/tools/export-sessions.d.ts +111 -0
  143. package/dist/src/tools/export-sessions.d.ts.map +1 -0
  144. package/dist/src/tools/export-sessions.js +136 -0
  145. package/dist/src/tools/export-sessions.js.map +1 -0
  146. package/dist/src/tools/get-context.d.ts +208 -0
  147. package/dist/src/tools/get-context.d.ts.map +1 -0
  148. package/dist/src/tools/get-context.js +27 -0
  149. package/dist/src/tools/get-context.js.map +1 -0
  150. package/dist/src/tools/get-history-handoff.d.ts +109 -0
  151. package/dist/src/tools/get-history-handoff.d.ts.map +1 -0
  152. package/dist/src/tools/get-history-handoff.js +85 -0
  153. package/dist/src/tools/get-history-handoff.js.map +1 -0
  154. package/dist/src/tools/get-history-trends.d.ts +155 -0
  155. package/dist/src/tools/get-history-trends.d.ts.map +1 -0
  156. package/dist/src/tools/get-history-trends.js +123 -0
  157. package/dist/src/tools/get-history-trends.js.map +1 -0
  158. package/dist/src/tools/get-session-artifacts.d.ts +151 -0
  159. package/dist/src/tools/get-session-artifacts.d.ts.map +1 -0
  160. package/dist/src/tools/get-session-artifacts.js +184 -0
  161. package/dist/src/tools/get-session-artifacts.js.map +1 -0
  162. package/dist/src/tools/get-session-decisions.d.ts +69 -0
  163. package/dist/src/tools/get-session-decisions.d.ts.map +1 -0
  164. package/dist/src/tools/get-session-decisions.js +99 -0
  165. package/dist/src/tools/get-session-decisions.js.map +1 -0
  166. package/dist/src/tools/get-session-messages.d.ts +55 -0
  167. package/dist/src/tools/get-session-messages.d.ts.map +1 -0
  168. package/dist/src/tools/get-session-messages.js +89 -0
  169. package/dist/src/tools/get-session-messages.js.map +1 -0
  170. package/dist/src/tools/get-session-narrative.d.ts +72 -0
  171. package/dist/src/tools/get-session-narrative.d.ts.map +1 -0
  172. package/dist/src/tools/get-session-narrative.js +106 -0
  173. package/dist/src/tools/get-session-narrative.js.map +1 -0
  174. package/dist/src/tools/get-session-timeline.d.ts +55 -0
  175. package/dist/src/tools/get-session-timeline.d.ts.map +1 -0
  176. package/dist/src/tools/get-session-timeline.js +93 -0
  177. package/dist/src/tools/get-session-timeline.js.map +1 -0
  178. package/dist/src/tools/get-session-trends.d.ts +108 -0
  179. package/dist/src/tools/get-session-trends.d.ts.map +1 -0
  180. package/dist/src/tools/get-session-trends.js +130 -0
  181. package/dist/src/tools/get-session-trends.js.map +1 -0
  182. package/dist/src/tools/get-session.d.ts +251 -0
  183. package/dist/src/tools/get-session.d.ts.map +1 -0
  184. package/dist/src/tools/get-session.js +290 -0
  185. package/dist/src/tools/get-session.js.map +1 -0
  186. package/dist/src/tools/index.d.ts +22 -0
  187. package/dist/src/tools/index.d.ts.map +1 -1
  188. package/dist/src/tools/index.js +22 -0
  189. package/dist/src/tools/index.js.map +1 -1
  190. package/dist/src/tools/list-contexts.d.ts +50 -0
  191. package/dist/src/tools/list-contexts.d.ts.map +1 -0
  192. package/dist/src/tools/list-contexts.js +28 -0
  193. package/dist/src/tools/list-contexts.js.map +1 -0
  194. package/dist/src/tools/list-sessions.d.ts +86 -0
  195. package/dist/src/tools/list-sessions.d.ts.map +1 -0
  196. package/dist/src/tools/list-sessions.js +97 -0
  197. package/dist/src/tools/list-sessions.js.map +1 -0
  198. package/dist/src/tools/merge-contexts.d.ts +58 -0
  199. package/dist/src/tools/merge-contexts.d.ts.map +1 -0
  200. package/dist/src/tools/merge-contexts.js +27 -0
  201. package/dist/src/tools/merge-contexts.js.map +1 -0
  202. package/dist/src/tools/move-session-context.d.ts +62 -0
  203. package/dist/src/tools/move-session-context.d.ts.map +1 -0
  204. package/dist/src/tools/move-session-context.js +33 -0
  205. package/dist/src/tools/move-session-context.js.map +1 -0
  206. package/dist/src/tools/reingest-session.d.ts +31 -0
  207. package/dist/src/tools/reingest-session.d.ts.map +1 -0
  208. package/dist/src/tools/reingest-session.js +43 -0
  209. package/dist/src/tools/reingest-session.js.map +1 -0
  210. package/dist/src/tools/reject-context-link.d.ts +58 -0
  211. package/dist/src/tools/reject-context-link.d.ts.map +1 -0
  212. package/dist/src/tools/reject-context-link.js +26 -0
  213. package/dist/src/tools/reject-context-link.js.map +1 -0
  214. package/dist/src/tools/resolve-context.d.ts +287 -0
  215. package/dist/src/tools/resolve-context.d.ts.map +1 -0
  216. package/dist/src/tools/resolve-context.js +35 -0
  217. package/dist/src/tools/resolve-context.js.map +1 -0
  218. package/dist/src/tools/search-history.d.ts +86 -0
  219. package/dist/src/tools/search-history.d.ts.map +1 -0
  220. package/dist/src/tools/search-history.js +103 -0
  221. package/dist/src/tools/search-history.js.map +1 -0
  222. package/dist/src/tools/session-ui-metadata.d.ts +15 -0
  223. package/dist/src/tools/session-ui-metadata.d.ts.map +1 -0
  224. package/dist/src/tools/session-ui-metadata.js +15 -0
  225. package/dist/src/tools/session-ui-metadata.js.map +1 -0
  226. package/dist/src/tools/set-active-context.d.ts +58 -0
  227. package/dist/src/tools/set-active-context.d.ts.map +1 -0
  228. package/dist/src/tools/set-active-context.js +26 -0
  229. package/dist/src/tools/set-active-context.js.map +1 -0
  230. package/dist/src/tools/split-context.d.ts +62 -0
  231. package/dist/src/tools/split-context.d.ts.map +1 -0
  232. package/dist/src/tools/split-context.js +36 -0
  233. package/dist/src/tools/split-context.js.map +1 -0
  234. package/dist/src/tools/verify-footprint.js +1 -1
  235. package/dist/src/tools/verify-footprint.js.map +1 -1
  236. package/dist/src/types.d.ts +2 -0
  237. package/dist/src/types.d.ts.map +1 -1
  238. package/dist/src/ui/register.d.ts +6 -1
  239. package/dist/src/ui/register.d.ts.map +1 -1
  240. package/dist/src/ui/register.js +60 -16
  241. package/dist/src/ui/register.js.map +1 -1
  242. package/dist/ui/dashboard.html +239 -868
  243. package/dist/ui/detail.html +107 -248
  244. package/dist/ui/export.html +115 -298
  245. package/dist/ui/session-dashboard-live.html +264 -0
  246. package/dist/ui/session-dashboard.html +329 -0
  247. package/dist/ui/session-detail-live.html +336 -0
  248. package/dist/ui/session-detail.html +355 -0
  249. package/package.json +34 -9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-filters.js","sourceRoot":"","sources":["../../../src/lib/session-filters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAgBnE,MAAM,UAAU,4BAA4B,CAC1C,EAAoB,EACpB,OAAsB;IAEtB,MAAM,MAAM,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/C,OAAO;QACL,OAAO,CAAC,KAAK,IAAI,EAAE;QACnB,OAAO,CAAC,QAAQ,IAAI,EAAE;QACtB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7D,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CACzC,yBAAyB,CAAC,QAAQ,CAAC,CACpC,IAAI,EAAE,CAAC;QACR,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACnE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,EAAoB,EACpB,OAA8B;IAE9B,OAAO,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;AACrD,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { SessionMessageRecord, SessionRecord, TimelineEventRecord } from "./storage/index.js";
2
+ export interface MessageSummary {
3
+ total: number;
4
+ byRole: {
5
+ user: number;
6
+ assistant: number;
7
+ system: number;
8
+ };
9
+ firstCapturedAt: string | null;
10
+ lastCapturedAt: string | null;
11
+ preview: string | null;
12
+ }
13
+ export interface TimelineSummary {
14
+ total: number;
15
+ eventTypes: string[];
16
+ statuses: string[];
17
+ firstStartedAt: string | null;
18
+ lastEndedAt: string | null;
19
+ }
20
+ export declare const DEFAULT_SESSION_DETAIL_PAGE_LIMIT = 50;
21
+ export declare const MAX_SESSION_DETAIL_PAGE_LIMIT = 200;
22
+ export interface PageInfo {
23
+ total: number;
24
+ offset: number;
25
+ limit: number;
26
+ returned: number;
27
+ hasMore: boolean;
28
+ nextOffset: number | null;
29
+ }
30
+ export interface SessionListItem {
31
+ id: string;
32
+ host: SessionRecord["host"];
33
+ title: string | null;
34
+ label: string;
35
+ status: SessionRecord["status"];
36
+ startedAt: string;
37
+ endedAt: string | null;
38
+ cwd: string;
39
+ projectRoot: string;
40
+ }
41
+ export declare function truncateSummary(value: string, maxLength?: number): string;
42
+ export declare function getSessionLabel(session: Pick<SessionRecord, "title" | "host" | "cwd">): string;
43
+ export declare function toSessionListItem(session: SessionRecord): SessionListItem;
44
+ export declare function buildMessageSummary(messages: SessionMessageRecord[]): MessageSummary;
45
+ export declare function buildTimelineSummary(timeline: TimelineEventRecord[]): TimelineSummary;
46
+ export declare function buildPageInfo(total: number, returned: number, options?: {
47
+ offset?: number;
48
+ limit?: number;
49
+ }): PageInfo;
50
+ //# sourceMappingURL=session-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-history.d.ts","sourceRoot":"","sources":["../../../src/lib/session-history.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,MAAM,CAM7E;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,GACrD,MAAM,CAOR;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,CAYzE;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,cAAc,CAahB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,mBAAmB,EAAE,GAC9B,eAAe,CAcjB;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,QAAQ,CAiBV"}
@@ -0,0 +1,73 @@
1
+ import * as path from "node:path";
2
+ export const DEFAULT_SESSION_DETAIL_PAGE_LIMIT = 50;
3
+ export const MAX_SESSION_DETAIL_PAGE_LIMIT = 200;
4
+ export function truncateSummary(value, maxLength = 80) {
5
+ if (value.length <= maxLength) {
6
+ return value;
7
+ }
8
+ return `${value.slice(0, maxLength - 3)}...`;
9
+ }
10
+ export function getSessionLabel(session) {
11
+ if (session.title && session.title.trim()) {
12
+ return session.title;
13
+ }
14
+ const cwdLabel = path.basename(session.cwd) || session.cwd;
15
+ return `${session.host} session @ ${cwdLabel}`;
16
+ }
17
+ export function toSessionListItem(session) {
18
+ return {
19
+ id: session.id,
20
+ host: session.host,
21
+ title: session.title,
22
+ label: getSessionLabel(session),
23
+ status: session.status,
24
+ startedAt: session.startedAt,
25
+ endedAt: session.endedAt,
26
+ cwd: session.cwd,
27
+ projectRoot: session.projectRoot,
28
+ };
29
+ }
30
+ export function buildMessageSummary(messages) {
31
+ return {
32
+ total: messages.length,
33
+ byRole: {
34
+ user: messages.filter((message) => message.role === "user").length,
35
+ assistant: messages.filter((message) => message.role === "assistant")
36
+ .length,
37
+ system: messages.filter((message) => message.role === "system").length,
38
+ },
39
+ firstCapturedAt: messages[0]?.capturedAt ?? null,
40
+ lastCapturedAt: messages.at(-1)?.capturedAt ?? null,
41
+ preview: messages[0] ? truncateSummary(messages[0].content) : null,
42
+ };
43
+ }
44
+ export function buildTimelineSummary(timeline) {
45
+ return {
46
+ total: timeline.length,
47
+ eventTypes: [...new Set(timeline.map((event) => event.eventType))],
48
+ statuses: [
49
+ ...new Set(timeline
50
+ .map((event) => event.status)
51
+ .filter((status) => Boolean(status))),
52
+ ],
53
+ firstStartedAt: timeline[0]?.startedAt ?? null,
54
+ lastEndedAt: timeline.at(-1)?.endedAt ?? timeline.at(-1)?.startedAt ?? null,
55
+ };
56
+ }
57
+ export function buildPageInfo(total, returned, options) {
58
+ const offset = options?.offset ?? 0;
59
+ const normalizedTotal = Math.max(total, 0);
60
+ const normalizedReturned = Math.max(returned, 0);
61
+ const limit = options?.limit ?? Math.max(normalizedReturned, normalizedTotal - offset, 0);
62
+ const nextOffset = offset + normalizedReturned;
63
+ const hasMore = nextOffset < normalizedTotal;
64
+ return {
65
+ total: normalizedTotal,
66
+ offset,
67
+ limit,
68
+ returned: normalizedReturned,
69
+ hasMore,
70
+ nextOffset: hasMore ? nextOffset : null,
71
+ };
72
+ }
73
+ //# sourceMappingURL=session-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-history.js","sourceRoot":"","sources":["../../../src/lib/session-history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import type { EvidenceDatabase, SessionHost, SessionStatus } from "./storage/index.js";
2
+ export type HistoryTrendGroupBy = "issue" | "family";
3
+ export type TrendBlockerState = "active" | "resolved";
4
+ export type TrendRemediationState = "unresolved" | "recovered" | "regressed" | "stable";
5
+ export interface HistoryTrendSession extends Record<string, unknown> {
6
+ sessionId: string;
7
+ label: string;
8
+ host: SessionHost;
9
+ status: SessionStatus;
10
+ startedAt: string;
11
+ lastAttemptAt: string;
12
+ attempts: number;
13
+ latestOutcome: string;
14
+ }
15
+ export interface HistoryTrend extends Record<string, unknown> {
16
+ groupBy: HistoryTrendGroupBy;
17
+ issueKey: string;
18
+ label: string;
19
+ kind: string | null;
20
+ issueFamilyKey: string | null;
21
+ issueFamilyLabel: string | null;
22
+ relatedIssueKeys: string[];
23
+ blockerCategory: string;
24
+ blockerState: TrendBlockerState;
25
+ remediationState: TrendRemediationState;
26
+ remediationSummary: string;
27
+ latestOutcome: string;
28
+ latestFailureAt: string | null;
29
+ latestSuccessAt: string | null;
30
+ lastSeenAt: string;
31
+ attemptCount: number;
32
+ sessionCount: number;
33
+ failedAttempts: number;
34
+ succeededAttempts: number;
35
+ otherAttempts: number;
36
+ hosts: SessionHost[];
37
+ statuses: SessionStatus[];
38
+ sessions: HistoryTrendSession[];
39
+ }
40
+ export interface HistoryTrendSummary extends Record<string, unknown> {
41
+ groupBy: HistoryTrendGroupBy;
42
+ totalTrends: number;
43
+ matchingSessions: number;
44
+ totalAttempts: number;
45
+ activeBlockers: number;
46
+ recoveredTrends: number;
47
+ regressedTrends: number;
48
+ byOutcome: {
49
+ failed: number;
50
+ succeeded: number;
51
+ other: number;
52
+ };
53
+ }
54
+ export interface HistoryTrendReport extends Record<string, unknown> {
55
+ summary: HistoryTrendSummary;
56
+ total: number;
57
+ trends: HistoryTrend[];
58
+ }
59
+ export interface SessionTrendContextItem extends Record<string, unknown> {
60
+ issueKey: string;
61
+ label: string;
62
+ kind: string | null;
63
+ issueFamilyKey: string | null;
64
+ issueFamilyLabel: string | null;
65
+ relatedIssueKeys: string[];
66
+ blockerCategory: string;
67
+ blockerState: TrendBlockerState;
68
+ remediationState: TrendRemediationState;
69
+ remediationSummary: string;
70
+ lastSeenAt: string;
71
+ latestFailureAt: string | null;
72
+ latestSuccessAt: string | null;
73
+ sessionCount: number;
74
+ sessionAttempts: number;
75
+ globalAttempts: number;
76
+ sessionLatestOutcome: string;
77
+ latestOutcome: string;
78
+ hosts: SessionHost[];
79
+ statuses: SessionStatus[];
80
+ relatedSessionCount: number;
81
+ relatedSessions: SessionTrendContextRelatedSession[];
82
+ }
83
+ export interface SessionTrendContextRelatedSession extends Record<string, unknown> {
84
+ sessionId: string;
85
+ label: string;
86
+ host: SessionHost;
87
+ status: SessionStatus;
88
+ lastAttemptAt: string;
89
+ attempts: number;
90
+ latestOutcome: string;
91
+ }
92
+ export interface SessionTrendContextSummary extends Record<string, unknown> {
93
+ totalTrends: number;
94
+ crossSessionTrends: number;
95
+ sessionAttempts: number;
96
+ globalAttempts: number;
97
+ otherSessions: number;
98
+ activeBlockers: number;
99
+ recoveredTrends: number;
100
+ regressedTrends: number;
101
+ }
102
+ export interface SessionTrendContext extends Record<string, unknown> {
103
+ summary: SessionTrendContextSummary;
104
+ page?: {
105
+ total: number;
106
+ offset: number;
107
+ limit: number;
108
+ returned: number;
109
+ hasMore: boolean;
110
+ nextOffset: number | null;
111
+ };
112
+ trends: SessionTrendContextItem[];
113
+ }
114
+ export interface HistoryTrendQuery {
115
+ query?: string;
116
+ issueKey?: string;
117
+ host?: SessionHost;
118
+ status?: SessionStatus;
119
+ sessionIds?: string[];
120
+ groupBy?: HistoryTrendGroupBy;
121
+ limit?: number;
122
+ offset?: number;
123
+ }
124
+ export declare function buildHistoryTrendReport(db: EvidenceDatabase, options?: HistoryTrendQuery): HistoryTrendReport;
125
+ export declare function buildSessionTrendContext(db: EvidenceDatabase, sessionId: string, options?: {
126
+ limit?: number;
127
+ offset?: number;
128
+ }): SessionTrendContext;
129
+ //# sourceMappingURL=session-trends.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-trends.d.ts","sourceRoot":"","sources":["../../../src/lib/session-trends.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,CAAC;AACrD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;AACtD,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,WAAW,GACX,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAChC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,OAAO,EAAE,mBAAmB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,OAAO,EAAE,mBAAmB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,uBAAwB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAChC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,iCAAiC,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,iCAAkC,SAAQ,MAAM,CAC/D,MAAM,EACN,OAAO,CACR;IACC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA2B,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,OAAO,EAAE,0BAA0B,CAAC;IACpC,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;IACF,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkYD,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,gBAAgB,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,kBAAkB,CA4EpB;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,gBAAgB,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,mBAAmB,CA4FrB"}
@@ -0,0 +1,361 @@
1
+ import { buildPageInfo, getSessionLabel } from "./session-history.js";
2
+ import { traceSyncOperation } from "./observability.js";
3
+ function matchesTrendQuery(issueKey, label, kind, relatedIssueKeys, query, exactIssueKey) {
4
+ if (exactIssueKey &&
5
+ issueKey !== exactIssueKey &&
6
+ !relatedIssueKeys.includes(exactIssueKey)) {
7
+ return false;
8
+ }
9
+ if (!query) {
10
+ return true;
11
+ }
12
+ const loweredQuery = query.toLowerCase();
13
+ return [issueKey, label, kind ?? "", ...relatedIssueKeys]
14
+ .join(" ")
15
+ .toLowerCase()
16
+ .includes(loweredQuery);
17
+ }
18
+ function createTrendAccumulator(groupBy, issueKey, label, kind, issueFamilyKey, issueFamilyLabel, relatedIssueKeys, attempt) {
19
+ return {
20
+ groupBy,
21
+ issueKey,
22
+ label,
23
+ kind,
24
+ issueFamilyKey,
25
+ issueFamilyLabel,
26
+ relatedIssueKeys: new Set(relatedIssueKeys),
27
+ lastSeenAt: attempt.seenAt,
28
+ latestOutcome: attempt.outcome,
29
+ latestFailureAt: attempt.outcomeCategory === "failed" ? attempt.seenAt : null,
30
+ latestSuccessAt: attempt.outcomeCategory === "succeeded" ? attempt.seenAt : null,
31
+ attemptCount: 0,
32
+ failedAttempts: 0,
33
+ succeededAttempts: 0,
34
+ otherAttempts: 0,
35
+ hosts: new Set(),
36
+ statuses: new Set(),
37
+ sessions: new Map([
38
+ [
39
+ attempt.sessionId,
40
+ {
41
+ label: getSessionLabel({
42
+ title: attempt.title,
43
+ host: attempt.host,
44
+ cwd: attempt.cwd,
45
+ }),
46
+ host: attempt.host,
47
+ status: attempt.status,
48
+ startedAt: attempt.startedAt,
49
+ lastAttemptAt: attempt.seenAt,
50
+ attempts: 0,
51
+ latestOutcome: attempt.outcome,
52
+ },
53
+ ],
54
+ ]),
55
+ };
56
+ }
57
+ function isFailedOutcome(outcome) {
58
+ return /\b(?:fail|failed|error|timeout|timed-out|interrupted|non-zero)\b/i.test(outcome);
59
+ }
60
+ function classifyBlockerCategory(kind, issueKey) {
61
+ if (kind) {
62
+ return kind;
63
+ }
64
+ const prefix = issueKey.split(":", 1)[0];
65
+ return prefix?.trim() || "issue";
66
+ }
67
+ function getRemediationState(options) {
68
+ if (isFailedOutcome(options.latestOutcome)) {
69
+ return options.succeededAttempts > 0 ? "regressed" : "unresolved";
70
+ }
71
+ if (options.failedAttempts > 0 && options.succeededAttempts > 0) {
72
+ return "recovered";
73
+ }
74
+ return "stable";
75
+ }
76
+ function buildRemediationSummary(options) {
77
+ switch (options.remediationState) {
78
+ case "recovered":
79
+ return `Recovered after ${options.failedAttempts} failed attempt(s); latest ${options.latestOutcome}.`;
80
+ case "regressed":
81
+ return `Regressed after ${options.succeededAttempts} successful attempt(s); latest ${options.latestOutcome}.`;
82
+ case "unresolved":
83
+ return `Still failing after ${options.attemptCount} attempt(s); latest ${options.latestOutcome}.`;
84
+ case "stable":
85
+ default:
86
+ return options.failedAttempts > 0
87
+ ? `Mixed outcomes stabilized at ${options.latestOutcome}.`
88
+ : `No active blocker; latest outcome ${options.latestOutcome}.`;
89
+ }
90
+ }
91
+ function validateHistoryTrendQuery(options) {
92
+ const groupBy = options?.groupBy ?? "issue";
93
+ const query = options?.query?.trim();
94
+ if (options?.query !== undefined && !query) {
95
+ throw new Error("Query must not be empty");
96
+ }
97
+ if (options?.issueKey !== undefined && !options.issueKey.trim()) {
98
+ throw new Error("issueKey must not be empty");
99
+ }
100
+ if (options?.limit !== undefined &&
101
+ (!Number.isInteger(options.limit) || options.limit <= 0)) {
102
+ throw new Error("Limit must be a positive integer");
103
+ }
104
+ if (options?.offset !== undefined &&
105
+ (!Number.isInteger(options.offset) || options.offset < 0)) {
106
+ throw new Error("Offset must be a non-negative integer");
107
+ }
108
+ if (options?.sessionIds?.some((sessionId) => !sessionId.trim())) {
109
+ throw new Error("sessionIds must not contain empty values");
110
+ }
111
+ return {
112
+ groupBy,
113
+ query,
114
+ exactIssueKey: options?.issueKey?.trim(),
115
+ };
116
+ }
117
+ function materializeHistoryTrends(attempts, groupBy, query, exactIssueKey) {
118
+ const trends = new Map();
119
+ for (const attempt of attempts) {
120
+ const groupingKey = groupBy === "family" ? attempt.issueFamilyKey : attempt.issueKey;
121
+ if (!groupingKey) {
122
+ continue;
123
+ }
124
+ const relatedIssueKeys = [attempt.issueKey];
125
+ const label = (groupBy === "family" ? attempt.issueFamilyLabel : attempt.issueLabel) ??
126
+ groupingKey;
127
+ const kind = attempt.kind;
128
+ if (!matchesTrendQuery(groupingKey, label, kind, relatedIssueKeys, query, exactIssueKey)) {
129
+ continue;
130
+ }
131
+ const existing = trends.get(groupingKey) ??
132
+ createTrendAccumulator(groupBy, groupingKey, label, kind, attempt.issueFamilyKey, attempt.issueFamilyLabel, relatedIssueKeys, attempt);
133
+ existing.attemptCount += 1;
134
+ if (attempt.outcomeCategory === "failed") {
135
+ existing.failedAttempts += 1;
136
+ if (!existing.latestFailureAt ||
137
+ attempt.seenAt >= existing.latestFailureAt) {
138
+ existing.latestFailureAt = attempt.seenAt;
139
+ }
140
+ }
141
+ else if (attempt.outcomeCategory === "succeeded") {
142
+ existing.succeededAttempts += 1;
143
+ if (!existing.latestSuccessAt ||
144
+ attempt.seenAt >= existing.latestSuccessAt) {
145
+ existing.latestSuccessAt = attempt.seenAt;
146
+ }
147
+ }
148
+ else {
149
+ existing.otherAttempts += 1;
150
+ }
151
+ existing.hosts.add(attempt.host);
152
+ existing.statuses.add(attempt.status);
153
+ existing.relatedIssueKeys.add(attempt.issueKey);
154
+ if (!existing.issueFamilyKey && attempt.issueFamilyKey) {
155
+ existing.issueFamilyKey = attempt.issueFamilyKey;
156
+ }
157
+ if (!existing.issueFamilyLabel && attempt.issueFamilyLabel) {
158
+ existing.issueFamilyLabel = attempt.issueFamilyLabel;
159
+ }
160
+ if (attempt.seenAt >= existing.lastSeenAt) {
161
+ existing.lastSeenAt = attempt.seenAt;
162
+ existing.latestOutcome = attempt.outcome;
163
+ existing.label = label;
164
+ if (!existing.kind && kind) {
165
+ existing.kind = kind;
166
+ }
167
+ }
168
+ const sessionEntry = existing.sessions.get(attempt.sessionId) ?? {
169
+ label: getSessionLabel({
170
+ title: attempt.title,
171
+ host: attempt.host,
172
+ cwd: attempt.cwd,
173
+ }),
174
+ host: attempt.host,
175
+ status: attempt.status,
176
+ startedAt: attempt.startedAt,
177
+ lastAttemptAt: attempt.seenAt,
178
+ attempts: 0,
179
+ latestOutcome: attempt.outcome,
180
+ };
181
+ sessionEntry.attempts += 1;
182
+ if (attempt.seenAt >= sessionEntry.lastAttemptAt) {
183
+ sessionEntry.lastAttemptAt = attempt.seenAt;
184
+ sessionEntry.latestOutcome = attempt.outcome;
185
+ }
186
+ existing.sessions.set(attempt.sessionId, sessionEntry);
187
+ trends.set(groupingKey, existing);
188
+ }
189
+ return Array.from(trends.values())
190
+ .map((trend) => {
191
+ const remediationState = getRemediationState({
192
+ latestOutcome: trend.latestOutcome,
193
+ failedAttempts: trend.failedAttempts,
194
+ succeededAttempts: trend.succeededAttempts,
195
+ });
196
+ return {
197
+ groupBy: trend.groupBy,
198
+ issueKey: trend.issueKey,
199
+ label: trend.label,
200
+ kind: trend.kind,
201
+ issueFamilyKey: trend.issueFamilyKey,
202
+ issueFamilyLabel: trend.issueFamilyLabel,
203
+ relatedIssueKeys: Array.from(trend.relatedIssueKeys).sort(),
204
+ blockerCategory: classifyBlockerCategory(trend.kind, trend.issueKey),
205
+ blockerState: isFailedOutcome(trend.latestOutcome)
206
+ ? "active"
207
+ : "resolved",
208
+ remediationState,
209
+ remediationSummary: buildRemediationSummary({
210
+ latestOutcome: trend.latestOutcome,
211
+ attemptCount: trend.attemptCount,
212
+ failedAttempts: trend.failedAttempts,
213
+ succeededAttempts: trend.succeededAttempts,
214
+ remediationState,
215
+ }),
216
+ latestOutcome: trend.latestOutcome,
217
+ latestFailureAt: trend.latestFailureAt,
218
+ latestSuccessAt: trend.latestSuccessAt,
219
+ lastSeenAt: trend.lastSeenAt,
220
+ attemptCount: trend.attemptCount,
221
+ sessionCount: trend.sessions.size,
222
+ failedAttempts: trend.failedAttempts,
223
+ succeededAttempts: trend.succeededAttempts,
224
+ otherAttempts: trend.otherAttempts,
225
+ hosts: Array.from(trend.hosts).sort(),
226
+ statuses: Array.from(trend.statuses).sort(),
227
+ sessions: Array.from(trend.sessions.entries())
228
+ .map(([sessionId, session]) => ({
229
+ sessionId,
230
+ label: session.label,
231
+ host: session.host,
232
+ status: session.status,
233
+ startedAt: session.startedAt,
234
+ lastAttemptAt: session.lastAttemptAt,
235
+ attempts: session.attempts,
236
+ latestOutcome: session.latestOutcome,
237
+ }))
238
+ .sort((left, right) => right.lastAttemptAt.localeCompare(left.lastAttemptAt)),
239
+ };
240
+ })
241
+ .sort((left, right) => {
242
+ if (right.sessionCount !== left.sessionCount) {
243
+ return right.sessionCount - left.sessionCount;
244
+ }
245
+ if (right.failedAttempts !== left.failedAttempts) {
246
+ return right.failedAttempts - left.failedAttempts;
247
+ }
248
+ if (right.attemptCount !== left.attemptCount) {
249
+ return right.attemptCount - left.attemptCount;
250
+ }
251
+ return right.lastSeenAt.localeCompare(left.lastSeenAt);
252
+ });
253
+ }
254
+ export function buildHistoryTrendReport(db, options) {
255
+ return traceSyncOperation("history.build-trend-report", {
256
+ host: options?.host,
257
+ status: options?.status,
258
+ groupBy: options?.groupBy ?? "issue",
259
+ hasQuery: Boolean(options?.query?.trim()),
260
+ issueKey: options?.issueKey?.trim() || undefined,
261
+ sessionIds: options?.sessionIds?.length ?? 0,
262
+ limit: options?.limit,
263
+ offset: options?.offset,
264
+ }, () => {
265
+ const { groupBy, query, exactIssueKey } = validateHistoryTrendQuery(options);
266
+ const allTrends = materializeHistoryTrends(db.querySessionTrendAttempts({
267
+ host: options?.host,
268
+ status: options?.status,
269
+ sessionIds: options?.sessionIds,
270
+ }), groupBy, query, exactIssueKey);
271
+ const offset = options?.offset ?? 0;
272
+ const paginatedTrends = allTrends.slice(offset, options?.limit ? offset + options.limit : undefined);
273
+ const matchingSessions = new Set(allTrends.flatMap((trend) => trend.sessions.map((session) => session.sessionId)));
274
+ return {
275
+ summary: {
276
+ groupBy,
277
+ totalTrends: allTrends.length,
278
+ matchingSessions: matchingSessions.size,
279
+ totalAttempts: allTrends.reduce((total, trend) => total + trend.attemptCount, 0),
280
+ activeBlockers: allTrends.filter((trend) => trend.blockerState === "active").length,
281
+ recoveredTrends: allTrends.filter((trend) => trend.remediationState === "recovered").length,
282
+ regressedTrends: allTrends.filter((trend) => trend.remediationState === "regressed").length,
283
+ byOutcome: {
284
+ failed: allTrends.reduce((total, trend) => total + trend.failedAttempts, 0),
285
+ succeeded: allTrends.reduce((total, trend) => total + trend.succeededAttempts, 0),
286
+ other: allTrends.reduce((total, trend) => total + trend.otherAttempts, 0),
287
+ },
288
+ },
289
+ total: allTrends.length,
290
+ trends: paginatedTrends,
291
+ };
292
+ });
293
+ }
294
+ export function buildSessionTrendContext(db, sessionId, options) {
295
+ const allTrends = materializeHistoryTrends(db.querySessionTrendContextAttempts(sessionId), "issue", undefined, undefined);
296
+ const trends = allTrends
297
+ .map((trend) => {
298
+ const session = trend.sessions.find((item) => item.sessionId === sessionId) ?? null;
299
+ if (!session) {
300
+ return null;
301
+ }
302
+ const relatedSessions = trend.sessions.filter((item) => item.sessionId !== sessionId);
303
+ return {
304
+ issueKey: trend.issueKey,
305
+ label: trend.label,
306
+ kind: trend.kind,
307
+ issueFamilyKey: trend.issueFamilyKey,
308
+ issueFamilyLabel: trend.issueFamilyLabel,
309
+ relatedIssueKeys: trend.relatedIssueKeys,
310
+ blockerCategory: trend.blockerCategory,
311
+ blockerState: trend.blockerState,
312
+ remediationState: trend.remediationState,
313
+ remediationSummary: trend.remediationSummary,
314
+ lastSeenAt: trend.lastSeenAt,
315
+ latestFailureAt: trend.latestFailureAt,
316
+ latestSuccessAt: trend.latestSuccessAt,
317
+ sessionCount: trend.sessionCount,
318
+ sessionAttempts: session.attempts,
319
+ globalAttempts: trend.attemptCount,
320
+ sessionLatestOutcome: session.latestOutcome,
321
+ latestOutcome: trend.latestOutcome,
322
+ hosts: trend.hosts,
323
+ statuses: trend.statuses,
324
+ relatedSessionCount: relatedSessions.length,
325
+ relatedSessions: relatedSessions.slice(0, 3).map((relatedSession) => ({
326
+ sessionId: relatedSession.sessionId,
327
+ label: relatedSession.label,
328
+ host: relatedSession.host,
329
+ status: relatedSession.status,
330
+ lastAttemptAt: relatedSession.lastAttemptAt,
331
+ attempts: relatedSession.attempts,
332
+ latestOutcome: relatedSession.latestOutcome,
333
+ })),
334
+ };
335
+ })
336
+ .filter((trend) => Boolean(trend));
337
+ const offset = options?.offset ?? 0;
338
+ const limit = options?.limit ?? trends.length;
339
+ const paginatedTrends = trends.slice(offset, offset + limit);
340
+ const otherSessions = new Set(trends.flatMap((trend) => trend.relatedSessions.map((session) => session.sessionId)));
341
+ return {
342
+ summary: {
343
+ totalTrends: trends.length,
344
+ crossSessionTrends: trends.filter((trend) => trend.sessionCount > 1)
345
+ .length,
346
+ sessionAttempts: trends.reduce((total, trend) => total + trend.sessionAttempts, 0),
347
+ globalAttempts: trends.reduce((total, trend) => total + trend.globalAttempts, 0),
348
+ otherSessions: otherSessions.size,
349
+ activeBlockers: trends.filter((trend) => trend.blockerState === "active")
350
+ .length,
351
+ recoveredTrends: trends.filter((trend) => trend.remediationState === "recovered").length,
352
+ regressedTrends: trends.filter((trend) => trend.remediationState === "regressed").length,
353
+ },
354
+ page: buildPageInfo(trends.length, paginatedTrends.length, {
355
+ offset,
356
+ limit,
357
+ }),
358
+ trends: paginatedTrends,
359
+ };
360
+ }
361
+ //# sourceMappingURL=session-trends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-trends.js","sourceRoot":"","sources":["../../../src/lib/session-trends.ts"],"names":[],"mappings":"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"}