@codemieai/code 0.15.6 → 0.15.7

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 (242) hide show
  1. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  2. package/dist/agents/core/AgentCLI.js +3 -0
  3. package/dist/agents/core/AgentCLI.js.map +1 -1
  4. package/dist/agents/core/BaseAgentAdapter.d.ts +4 -1
  5. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  6. package/dist/agents/core/BaseAgentAdapter.js +15 -0
  7. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  8. package/dist/agents/core/types.d.ts +10 -0
  9. package/dist/agents/core/types.d.ts.map +1 -1
  10. package/dist/agents/core/types.js +5 -1
  11. package/dist/agents/core/types.js.map +1 -1
  12. package/dist/agents/plugins/claude/claude.models.d.ts +1 -1
  13. package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -1
  14. package/dist/agents/plugins/claude/claude.models.js +7 -3
  15. package/dist/agents/plugins/claude/claude.models.js.map +1 -1
  16. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.constants.d.ts +3 -0
  17. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.constants.d.ts.map +1 -0
  18. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.constants.js +3 -0
  19. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.constants.js.map +1 -0
  20. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.plugin.d.ts +11 -0
  21. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.plugin.d.ts.map +1 -0
  22. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.plugin.js +65 -0
  23. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.plugin.js.map +1 -0
  24. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.types.d.ts +63 -0
  25. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.types.d.ts.map +1 -0
  26. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.types.js +13 -0
  27. package/dist/agents/plugins/claude-code-otlp/claude-code-otlp.types.js.map +1 -0
  28. package/dist/agents/plugins/codemie-code.plugin.d.ts.map +1 -1
  29. package/dist/agents/plugins/codemie-code.plugin.js +6 -4
  30. package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
  31. package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -1
  32. package/dist/agents/plugins/codex/codex-models.js +9 -6
  33. package/dist/agents/plugins/codex/codex-models.js.map +1 -1
  34. package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
  35. package/dist/agents/plugins/codex/codex.plugin.js +2 -1
  36. package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
  37. package/dist/agents/plugins/opencode/opencode-dynamic-models.d.ts +3 -2
  38. package/dist/agents/plugins/opencode/opencode-dynamic-models.d.ts.map +1 -1
  39. package/dist/agents/plugins/opencode/opencode-dynamic-models.js +14 -6
  40. package/dist/agents/plugins/opencode/opencode-dynamic-models.js.map +1 -1
  41. package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -1
  42. package/dist/agents/plugins/opencode/opencode.plugin.js +6 -4
  43. package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -1
  44. package/dist/agents/plugins/utils.d.ts +11 -0
  45. package/dist/agents/plugins/utils.d.ts.map +1 -0
  46. package/dist/agents/plugins/utils.js +46 -0
  47. package/dist/agents/plugins/utils.js.map +1 -0
  48. package/dist/agents/registry.d.ts +3 -1
  49. package/dist/agents/registry.d.ts.map +1 -1
  50. package/dist/agents/registry.js +12 -0
  51. package/dist/agents/registry.js.map +1 -1
  52. package/dist/bin/proxy-daemon.js +4 -0
  53. package/dist/bin/proxy-daemon.js.map +1 -1
  54. package/dist/cli/commands/assistants/setup/configuration/selection.d.ts +3 -1
  55. package/dist/cli/commands/assistants/setup/configuration/selection.d.ts.map +1 -1
  56. package/dist/cli/commands/assistants/setup/configuration/selection.js +6 -3
  57. package/dist/cli/commands/assistants/setup/configuration/selection.js.map +1 -1
  58. package/dist/cli/commands/assistants/setup/configuration/types.d.ts +2 -0
  59. package/dist/cli/commands/assistants/setup/configuration/types.d.ts.map +1 -1
  60. package/dist/cli/commands/assistants/setup/configuration/ui.d.ts.map +1 -1
  61. package/dist/cli/commands/assistants/setup/configuration/ui.js +3 -0
  62. package/dist/cli/commands/assistants/setup/configuration/ui.js.map +1 -1
  63. package/dist/cli/commands/assistants/setup/data.d.ts +6 -2
  64. package/dist/cli/commands/assistants/setup/data.d.ts.map +1 -1
  65. package/dist/cli/commands/assistants/setup/data.js +23 -8
  66. package/dist/cli/commands/assistants/setup/data.js.map +1 -1
  67. package/dist/cli/commands/assistants/setup/helpers.d.ts +1 -0
  68. package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -1
  69. package/dist/cli/commands/assistants/setup/helpers.js +11 -0
  70. package/dist/cli/commands/assistants/setup/helpers.js.map +1 -1
  71. package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -1
  72. package/dist/cli/commands/assistants/setup/index.js +24 -6
  73. package/dist/cli/commands/assistants/setup/index.js.map +1 -1
  74. package/dist/cli/commands/assistants/setup/manualConfiguration/index.d.ts +2 -1
  75. package/dist/cli/commands/assistants/setup/manualConfiguration/index.d.ts.map +1 -1
  76. package/dist/cli/commands/assistants/setup/manualConfiguration/index.js +5 -3
  77. package/dist/cli/commands/assistants/setup/manualConfiguration/index.js.map +1 -1
  78. package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts +2 -0
  79. package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts.map +1 -1
  80. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.d.ts.map +1 -1
  81. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js +3 -0
  82. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js.map +1 -1
  83. package/dist/cli/commands/hook.d.ts.map +1 -1
  84. package/dist/cli/commands/hook.js +24 -29
  85. package/dist/cli/commands/hook.js.map +1 -1
  86. package/dist/cli/commands/proxy/connect-orchestrator.d.ts +8 -1
  87. package/dist/cli/commands/proxy/connect-orchestrator.d.ts.map +1 -1
  88. package/dist/cli/commands/proxy/connect-orchestrator.js +65 -4
  89. package/dist/cli/commands/proxy/connect-orchestrator.js.map +1 -1
  90. package/dist/cli/commands/proxy/connectors/claude-code-otlp.d.ts +33 -0
  91. package/dist/cli/commands/proxy/connectors/claude-code-otlp.d.ts.map +1 -0
  92. package/dist/cli/commands/proxy/connectors/claude-code-otlp.js +299 -0
  93. package/dist/cli/commands/proxy/connectors/claude-code-otlp.js.map +1 -0
  94. package/dist/cli/commands/proxy/connectors/managed-mcp-remote.d.ts.map +1 -1
  95. package/dist/cli/commands/proxy/connectors/managed-mcp-remote.js +5 -6
  96. package/dist/cli/commands/proxy/connectors/managed-mcp-remote.js.map +1 -1
  97. package/dist/cli/commands/proxy/disconnect-orchestrator.d.ts +2 -0
  98. package/dist/cli/commands/proxy/disconnect-orchestrator.d.ts.map +1 -1
  99. package/dist/cli/commands/proxy/disconnect-orchestrator.js +34 -5
  100. package/dist/cli/commands/proxy/disconnect-orchestrator.js.map +1 -1
  101. package/dist/cli/commands/proxy/index.d.ts.map +1 -1
  102. package/dist/cli/commands/proxy/index.js +19 -2
  103. package/dist/cli/commands/proxy/index.js.map +1 -1
  104. package/dist/cli/commands/self-update.d.ts.map +1 -1
  105. package/dist/cli/commands/self-update.js +5 -1
  106. package/dist/cli/commands/self-update.js.map +1 -1
  107. package/dist/cli/commands/shared/constants.d.ts +3 -0
  108. package/dist/cli/commands/shared/constants.d.ts.map +1 -1
  109. package/dist/cli/commands/shared/constants.js +3 -0
  110. package/dist/cli/commands/shared/constants.js.map +1 -1
  111. package/dist/cli/commands/shared/prompts/storage-scope.d.ts +3 -1
  112. package/dist/cli/commands/shared/prompts/storage-scope.d.ts.map +1 -1
  113. package/dist/cli/commands/shared/prompts/storage-scope.js +5 -1
  114. package/dist/cli/commands/shared/prompts/storage-scope.js.map +1 -1
  115. package/dist/cli/commands/skills/setup/data.d.ts +5 -1
  116. package/dist/cli/commands/skills/setup/data.d.ts.map +1 -1
  117. package/dist/cli/commands/skills/setup/data.js +17 -8
  118. package/dist/cli/commands/skills/setup/data.js.map +1 -1
  119. package/dist/cli/commands/skills/setup/helpers.d.ts +1 -0
  120. package/dist/cli/commands/skills/setup/helpers.d.ts.map +1 -1
  121. package/dist/cli/commands/skills/setup/helpers.js +11 -0
  122. package/dist/cli/commands/skills/setup/helpers.js.map +1 -1
  123. package/dist/cli/commands/skills/setup/index.d.ts.map +1 -1
  124. package/dist/cli/commands/skills/setup/index.js +7 -2
  125. package/dist/cli/commands/skills/setup/index.js.map +1 -1
  126. package/dist/cli/index.js +2 -0
  127. package/dist/cli/index.js.map +1 -1
  128. package/dist/mcp/stdio-http-bridge.d.ts.map +1 -1
  129. package/dist/mcp/stdio-http-bridge.js +4 -0
  130. package/dist/mcp/stdio-http-bridge.js.map +1 -1
  131. package/dist/providers/core/base/http-client.d.ts.map +1 -1
  132. package/dist/providers/core/base/http-client.js +16 -3
  133. package/dist/providers/core/base/http-client.js.map +1 -1
  134. package/dist/providers/core/codemie-auth-helpers.d.ts.map +1 -1
  135. package/dist/providers/core/codemie-auth-helpers.js +2 -1
  136. package/dist/providers/core/codemie-auth-helpers.js.map +1 -1
  137. package/dist/providers/core/types.d.ts +3 -0
  138. package/dist/providers/core/types.d.ts.map +1 -1
  139. package/dist/providers/core/types.js.map +1 -1
  140. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  141. package/dist/providers/plugins/sso/proxy/plugins/index.js +2 -0
  142. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  143. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/auth-state.d.ts +3 -0
  144. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/auth-state.d.ts.map +1 -0
  145. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/auth-state.js +19 -0
  146. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/auth-state.js.map +1 -0
  147. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/completeness-gate.d.ts +19 -0
  148. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/completeness-gate.d.ts.map +1 -0
  149. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/completeness-gate.js +33 -0
  150. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/completeness-gate.js.map +1 -0
  151. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/forwarder.d.ts +14 -0
  152. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/forwarder.d.ts.map +1 -0
  153. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/forwarder.js +287 -0
  154. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/forwarder.js.map +1 -0
  155. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-lock.d.ts +8 -0
  156. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-lock.d.ts.map +1 -0
  157. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-lock.js +29 -0
  158. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-lock.js.map +1 -0
  159. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.d.ts +40 -0
  160. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.d.ts.map +1 -0
  161. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.js +82 -0
  162. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.js.map +1 -0
  163. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.d.ts +36 -0
  164. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.d.ts.map +1 -0
  165. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.js +62 -0
  166. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.js.map +1 -0
  167. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.d.ts +39 -0
  168. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.d.ts.map +1 -0
  169. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.js +110 -0
  170. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.js.map +1 -0
  171. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.d.ts +24 -0
  172. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.d.ts.map +1 -0
  173. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.js +53 -0
  174. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.js.map +1 -0
  175. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.d.ts +39 -0
  176. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.d.ts.map +1 -0
  177. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.js +61 -0
  178. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.js.map +1 -0
  179. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/sweep.d.ts +20 -0
  180. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/sweep.d.ts.map +1 -0
  181. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/sweep.js +73 -0
  182. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/sweep.js.map +1 -0
  183. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/tick-processor.d.ts +12 -0
  184. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/tick-processor.d.ts.map +1 -0
  185. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/tick-processor.js +55 -0
  186. package/dist/providers/plugins/sso/proxy/plugins/otlp-spool/tick-processor.js.map +1 -0
  187. package/dist/providers/plugins/sso/proxy/plugins/otlp.plugin.d.ts +14 -0
  188. package/dist/providers/plugins/sso/proxy/plugins/otlp.plugin.d.ts.map +1 -0
  189. package/dist/providers/plugins/sso/proxy/plugins/otlp.plugin.js +221 -0
  190. package/dist/providers/plugins/sso/proxy/plugins/otlp.plugin.js.map +1 -0
  191. package/dist/providers/plugins/sso/proxy/proxy-http-client.d.ts +1 -4
  192. package/dist/providers/plugins/sso/proxy/proxy-http-client.d.ts.map +1 -1
  193. package/dist/providers/plugins/sso/proxy/proxy-http-client.js +10 -207
  194. package/dist/providers/plugins/sso/proxy/proxy-http-client.js.map +1 -1
  195. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
  196. package/dist/providers/plugins/sso/proxy/sso.proxy.js +2 -1
  197. package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
  198. package/dist/providers/plugins/sso/sso.auth-gate.d.ts +18 -0
  199. package/dist/providers/plugins/sso/sso.auth-gate.d.ts.map +1 -0
  200. package/dist/providers/plugins/sso/sso.auth-gate.js +48 -0
  201. package/dist/providers/plugins/sso/sso.auth-gate.js.map +1 -0
  202. package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -1
  203. package/dist/providers/plugins/sso/sso.auth.js +14 -4
  204. package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
  205. package/dist/providers/plugins/sso/sso.http-client.d.ts +12 -0
  206. package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -1
  207. package/dist/providers/plugins/sso/sso.http-client.js +33 -5
  208. package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
  209. package/dist/utils/auth.d.ts.map +1 -1
  210. package/dist/utils/auth.js +4 -0
  211. package/dist/utils/auth.js.map +1 -1
  212. package/dist/utils/cli-updater.d.ts +7 -0
  213. package/dist/utils/cli-updater.d.ts.map +1 -1
  214. package/dist/utils/cli-updater.js +21 -0
  215. package/dist/utils/cli-updater.js.map +1 -1
  216. package/dist/utils/paths.d.ts +1 -1
  217. package/dist/utils/paths.d.ts.map +1 -1
  218. package/dist/utils/paths.js +1 -1
  219. package/dist/utils/paths.js.map +1 -1
  220. package/dist/utils/processes.d.ts.map +1 -1
  221. package/dist/utils/processes.js +3 -2
  222. package/dist/utils/processes.js.map +1 -1
  223. package/dist/utils/project-root.d.ts +10 -0
  224. package/dist/utils/project-root.d.ts.map +1 -0
  225. package/dist/utils/project-root.js +25 -0
  226. package/dist/utils/project-root.js.map +1 -0
  227. package/dist/utils/sdk-client.d.ts.map +1 -1
  228. package/dist/utils/sdk-client.js +4 -0
  229. package/dist/utils/sdk-client.js.map +1 -1
  230. package/dist/utils/system-proxy-dispatcher.d.ts +8 -0
  231. package/dist/utils/system-proxy-dispatcher.d.ts.map +1 -0
  232. package/dist/utils/system-proxy-dispatcher.js +100 -0
  233. package/dist/utils/system-proxy-dispatcher.js.map +1 -0
  234. package/dist/utils/system-proxy.d.ts +115 -0
  235. package/dist/utils/system-proxy.d.ts.map +1 -0
  236. package/dist/utils/system-proxy.js +899 -0
  237. package/dist/utils/system-proxy.js.map +1 -0
  238. package/dist/utils/windows-path.d.ts +5 -0
  239. package/dist/utils/windows-path.d.ts.map +1 -1
  240. package/dist/utils/windows-path.js +1 -1
  241. package/dist/utils/windows-path.js.map +1 -1
  242. package/package.json +4 -1
@@ -0,0 +1,40 @@
1
+ import { type SpoolStream } from './spool-paths.js';
2
+ /** Byte offsets that have been acknowledged by the backend, per stream. */
3
+ export type SessionCursors = Record<SpoolStream, number>;
4
+ export interface SessionStatus {
5
+ /**
6
+ * Delivery progress. A cursor is a byte offset into the corresponding spool
7
+ * file and is only advanced after the backend acknowledges those bytes.
8
+ */
9
+ cursors: SessionCursors;
10
+ /** Consecutive ticks a hooks-only session has waited for OTEL data. */
11
+ waitTicks: number;
12
+ /**
13
+ * Time when a successfully forwarded hooks batch contained `SessionEnd`.
14
+ * Marks *normal completion*, not *delivery completion*: forwarding continues
15
+ * for any bytes that are still pending or appended afterwards.
16
+ */
17
+ endedAt?: number;
18
+ }
19
+ export declare function createStatus(): SessionStatus;
20
+ /** Read and normalize a session status, or `null` when there is no status file. */
21
+ export declare function readStatus(sessionId: string): Promise<SessionStatus | null>;
22
+ export declare function writeStatus(sessionId: string, status: SessionStatus): Promise<void>;
23
+ /**
24
+ * Read-modify-write a status under the session lock.
25
+ *
26
+ * NOTE: the session lock is not reentrant — never call this while already
27
+ * holding the lock for the same session.
28
+ */
29
+ export declare function updateStatus(sessionId: string, mutate: (status: SessionStatus) => void): Promise<void>;
30
+ export declare function markSessionEnded(sessionId: string): Promise<void>;
31
+ /** Advance an acknowledged cursor. Monotonic: never moves backwards. */
32
+ export declare function advanceCursor(sessionId: string, stream: SpoolStream, nextOffset: number): Promise<void>;
33
+ /**
34
+ * Create a default status if the session has none.
35
+ * Caller MUST already hold the session lock.
36
+ */
37
+ export declare function ensureStatusLocked(sessionId: string): Promise<void>;
38
+ /** Lock-acquiring variant — never call while holding the session lock. */
39
+ export declare function ensureStatus(sessionId: string): Promise<void>;
40
+ //# sourceMappingURL=session-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-status.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.ts"],"names":[],"mappings":"AACA,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG1F,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,IAAI,aAAa,CAE5C;AA0BD,mFAAmF;AACnF,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAOjF;AAED,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzF;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;AAED,wEAAwE;AACxE,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzE;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE"}
@@ -0,0 +1,82 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { SPOOL_STREAMS, spoolRoot, statusFile } from './spool-paths.js';
3
+ import { withSessionLock } from './session-lock.js';
4
+ export function createStatus() {
5
+ return { cursors: { hooks: 0, logs: 0, metrics: 0, traces: 0 }, waitTicks: 0 };
6
+ }
7
+ function toOffset(value) {
8
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
9
+ }
10
+ /**
11
+ * Coerce whatever is on disk into a well-formed status. Unknown fields (e.g.
12
+ * the removed `*Written` flags, flat cursors, `forwarded`) are dropped.
13
+ */
14
+ function normalizeStatus(raw) {
15
+ const status = createStatus();
16
+ if (typeof raw !== 'object' || raw === null)
17
+ return status;
18
+ const source = raw;
19
+ const cursors = (source['cursors'] ?? {});
20
+ for (const stream of SPOOL_STREAMS) {
21
+ status.cursors[stream] = toOffset(cursors[stream]);
22
+ }
23
+ status.waitTicks = toOffset(source['waitTicks']);
24
+ const endedAt = toOffset(source['endedAt']);
25
+ if (endedAt > 0)
26
+ status.endedAt = endedAt;
27
+ return status;
28
+ }
29
+ /** Read and normalize a session status, or `null` when there is no status file. */
30
+ export async function readStatus(sessionId) {
31
+ try {
32
+ const raw = await readFile(statusFile(sessionId), 'utf-8');
33
+ return normalizeStatus(JSON.parse(raw));
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ export async function writeStatus(sessionId, status) {
40
+ await mkdir(spoolRoot(), { recursive: true });
41
+ await writeFile(statusFile(sessionId), JSON.stringify(status), 'utf-8');
42
+ }
43
+ /**
44
+ * Read-modify-write a status under the session lock.
45
+ *
46
+ * NOTE: the session lock is not reentrant — never call this while already
47
+ * holding the lock for the same session.
48
+ */
49
+ export async function updateStatus(sessionId, mutate) {
50
+ await withSessionLock(sessionId, async () => {
51
+ const status = await readStatus(sessionId);
52
+ if (!status)
53
+ return; // session was swept — nothing to acknowledge
54
+ mutate(status);
55
+ await writeStatus(sessionId, status);
56
+ });
57
+ }
58
+ export async function markSessionEnded(sessionId) {
59
+ await updateStatus(sessionId, (status) => {
60
+ status.endedAt ??= Date.now();
61
+ });
62
+ }
63
+ /** Advance an acknowledged cursor. Monotonic: never moves backwards. */
64
+ export async function advanceCursor(sessionId, stream, nextOffset) {
65
+ await updateStatus(sessionId, (status) => {
66
+ status.cursors[stream] = Math.max(status.cursors[stream], nextOffset);
67
+ });
68
+ }
69
+ /**
70
+ * Create a default status if the session has none.
71
+ * Caller MUST already hold the session lock.
72
+ */
73
+ export async function ensureStatusLocked(sessionId) {
74
+ if (await readStatus(sessionId))
75
+ return;
76
+ await writeStatus(sessionId, createStatus());
77
+ }
78
+ /** Lock-acquiring variant — never call while holding the session lock. */
79
+ export async function ensureStatus(sessionId) {
80
+ await withSessionLock(sessionId, () => ensureStatusLocked(sessionId));
81
+ }
82
+ //# sourceMappingURL=session-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-status.js","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/session-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Env-backed tuning for the OTLP spool. Read lazily on every call so overrides
3
+ * take effect without a restart.
4
+ *
5
+ * Duration knobs are in minutes and accept fractions (`0.5` = 30s). A missing,
6
+ * unparsable, zero or negative value falls back to the default — notably, a
7
+ * zero interval would otherwise degenerate into a spin loop.
8
+ */
9
+ /** How often pending spool bytes are forwarded. */
10
+ export declare function sendIntervalMs(): number;
11
+ /** How often drained, inactive sessions are garbage-collected. */
12
+ export declare function sweepIntervalMs(): number;
13
+ /**
14
+ * Ticks a hooks-only session waits for OTEL data before being force-forwarded.
15
+ *
16
+ * NOTE: this is a tick count, so the effective wait is
17
+ * `sendIntervalMs() * hooksOnlyWaitTicks()` — currently ~6 minutes, chosen to
18
+ * out-wait one OTEL exporter flush cycle (~60s) plus a send interval.
19
+ * Revisit this value whenever OTLP_SEND_INTERVAL_MINUTES changes.
20
+ */
21
+ export declare function hooksOnlyWaitTicks(): number;
22
+ /** Whether a hooks-only session may be forwarded without any OTEL data. */
23
+ export declare function hooksOnlyForwardAllowed(): boolean;
24
+ /**
25
+ * Quiet period after a normally ended session (`endedAt`) before its drained
26
+ * spool may be deleted. Sized to cover a late OTEL export plus the send
27
+ * interval needed to forward it.
28
+ */
29
+ export declare function endedSessionGraceMs(): number;
30
+ /**
31
+ * Inactivity period after which a session that never reported `SessionEnd` is
32
+ * considered abandoned and its drained spool may be deleted. Measured from the
33
+ * latest spool-file write, never from session creation or cursor updates.
34
+ */
35
+ export declare function abandonedSessionGraceMs(): number;
36
+ //# sourceMappingURL=spool-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-config.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH,mDAAmD;AACnD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,kEAAkE;AAClE,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,2EAA2E;AAC3E,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Env-backed tuning for the OTLP spool. Read lazily on every call so overrides
3
+ * take effect without a restart.
4
+ *
5
+ * Duration knobs are in minutes and accept fractions (`0.5` = 30s). A missing,
6
+ * unparsable, zero or negative value falls back to the default — notably, a
7
+ * zero interval would otherwise degenerate into a spin loop.
8
+ */
9
+ const MINUTE_MS = 60_000;
10
+ function envMinutesMs(name, fallbackMinutes) {
11
+ const parsed = Number(process.env[name]);
12
+ const minutes = Number.isFinite(parsed) && parsed > 0 ? parsed : fallbackMinutes;
13
+ return minutes * MINUTE_MS;
14
+ }
15
+ function envCount(name, fallbackValue) {
16
+ const parsed = Number(process.env[name]);
17
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallbackValue;
18
+ }
19
+ function envBoolean(name, fallbackValue) {
20
+ const raw = process.env[name];
21
+ return raw === undefined ? fallbackValue : raw === 'true';
22
+ }
23
+ /** How often pending spool bytes are forwarded. */
24
+ export function sendIntervalMs() {
25
+ return envMinutesMs('OTLP_SEND_INTERVAL_MINUTES', 2);
26
+ }
27
+ /** How often drained, inactive sessions are garbage-collected. */
28
+ export function sweepIntervalMs() {
29
+ return envMinutesMs('OTLP_SWEEP_INTERVAL_MINUTES', 15);
30
+ }
31
+ /**
32
+ * Ticks a hooks-only session waits for OTEL data before being force-forwarded.
33
+ *
34
+ * NOTE: this is a tick count, so the effective wait is
35
+ * `sendIntervalMs() * hooksOnlyWaitTicks()` — currently ~6 minutes, chosen to
36
+ * out-wait one OTEL exporter flush cycle (~60s) plus a send interval.
37
+ * Revisit this value whenever OTLP_SEND_INTERVAL_MINUTES changes.
38
+ */
39
+ export function hooksOnlyWaitTicks() {
40
+ return envCount('OTLP_SEND_MAX_ATTEMPTS', 3);
41
+ }
42
+ /** Whether a hooks-only session may be forwarded without any OTEL data. */
43
+ export function hooksOnlyForwardAllowed() {
44
+ return envBoolean('OTLP_ALLOW_HOOKS_ONLY_FORWARD', true);
45
+ }
46
+ /**
47
+ * Quiet period after a normally ended session (`endedAt`) before its drained
48
+ * spool may be deleted. Sized to cover a late OTEL export plus the send
49
+ * interval needed to forward it.
50
+ */
51
+ export function endedSessionGraceMs() {
52
+ return envMinutesMs('OTLP_ENDED_SESSION_GRACE_MINUTES', 15);
53
+ }
54
+ /**
55
+ * Inactivity period after which a session that never reported `SessionEnd` is
56
+ * considered abandoned and its drained spool may be deleted. Measured from the
57
+ * latest spool-file write, never from session creation or cursor updates.
58
+ */
59
+ export function abandonedSessionGraceMs() {
60
+ return envMinutesMs('OTLP_ABANDONED_SESSION_GRACE_MINUTES', 60);
61
+ }
62
+ //# sourceMappingURL=spool-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-config.js","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,SAAS,YAAY,CAAC,IAAY,EAAE,eAAuB;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;IACjF,OAAO,OAAO,GAAG,SAAS,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,aAAqB;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;AACzE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,aAAsB;IACtD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC;AAC5D,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,cAAc;IAC5B,OAAO,YAAY,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,QAAQ,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,uBAAuB;IACrC,OAAO,UAAU,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,YAAY,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,YAAY,CAAC,sCAAsC,EAAE,EAAE,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { type SpoolStream } from './spool-paths.js';
2
+ /**
3
+ * Append spool bytes and make the session discoverable.
4
+ *
5
+ * Holds the session lock so an append can never interleave with a forwarder
6
+ * snapshot (torn record), a cursor advance, or a sweep deletion.
7
+ */
8
+ export declare function appendSpool(sessionId: string, stream: SpoolStream, data: string | Buffer): Promise<void>;
9
+ export interface PendingBytes {
10
+ /** Cursor the snapshot was taken from — pass it back when acknowledging. */
11
+ cursor: number;
12
+ bytes: Buffer;
13
+ }
14
+ /**
15
+ * Consistent snapshot of the bytes pending for an OTEL stream.
16
+ *
17
+ * The lock guarantees the snapshot never contains a partially written append,
18
+ * so the protobuf payload handed to the backend is always whole.
19
+ * Must NOT be called while already holding the session lock.
20
+ */
21
+ export declare function snapshotPendingBytes(sessionId: string, stream: SpoolStream): Promise<PendingBytes | null>;
22
+ export interface PendingHookBatch {
23
+ cursor: number;
24
+ /** Complete, newline-terminated NDJSON records. */
25
+ records: string[];
26
+ /** Exact number of source bytes these records occupy, including newlines. */
27
+ byteLength: number;
28
+ }
29
+ /**
30
+ * Consistent snapshot of the complete NDJSON records pending for hooks.
31
+ *
32
+ * The chunk is cut at the last newline byte, so an incomplete trailing record
33
+ * stays pending and `byteLength` is a byte-exact acknowledgement amount.
34
+ * Cutting on a newline is safe for UTF-8: `0x0a` cannot occur inside a
35
+ * multi-byte sequence.
36
+ * Must NOT be called while already holding the session lock.
37
+ */
38
+ export declare function snapshotPendingHookRecords(sessionId: string): Promise<PendingHookBatch | null>;
39
+ //# sourceMappingURL=spool-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-io.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA2C3E;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAoBf;AAID,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQ9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAoBlC"}
@@ -0,0 +1,110 @@
1
+ import { appendFile, mkdir, open, stat } from 'node:fs/promises';
2
+ import { spoolRoot, streamFile } from './spool-paths.js';
3
+ import { withSessionLock } from './session-lock.js';
4
+ import { createStatus, readStatus, writeStatus } from './session-status.js';
5
+ const NEWLINE = 0x0a;
6
+ /* ------------------------------------------------------- unlocked internals --- */
7
+ // These assume the caller already holds the session lock.
8
+ async function fileExists(path) {
9
+ try {
10
+ await stat(path);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ /** Range-read everything after `cursor`. Never touches the acknowledged prefix. */
18
+ async function readRange(sessionId, stream, cursor) {
19
+ let handle;
20
+ try {
21
+ handle = await open(streamFile(sessionId, stream), 'r');
22
+ }
23
+ catch {
24
+ return null; // missing file => nothing pending
25
+ }
26
+ try {
27
+ const { size } = await handle.stat();
28
+ if (size <= cursor)
29
+ return null; // drained
30
+ const buffer = Buffer.allocUnsafe(size - cursor);
31
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, cursor);
32
+ return bytesRead > 0 ? buffer.subarray(0, bytesRead) : null;
33
+ }
34
+ finally {
35
+ await handle.close();
36
+ }
37
+ }
38
+ /* --------------------------------------------------------------- producers --- */
39
+ /**
40
+ * Append spool bytes and make the session discoverable.
41
+ *
42
+ * Holds the session lock so an append can never interleave with a forwarder
43
+ * snapshot (torn record), a cursor advance, or a sweep deletion.
44
+ */
45
+ export async function appendSpool(sessionId, stream, data) {
46
+ await withSessionLock(sessionId, async () => {
47
+ await mkdir(spoolRoot(), { recursive: true });
48
+ const path = streamFile(sessionId, stream);
49
+ const recreated = !(await fileExists(path));
50
+ await appendFile(path, data);
51
+ const status = await readStatus(sessionId);
52
+ if (!status) {
53
+ await writeStatus(sessionId, createStatus());
54
+ return;
55
+ }
56
+ // A recreated file restarts at offset 0, so a cursor left over from a swept
57
+ // (or partially deleted) session would otherwise skip these bytes forever.
58
+ if (recreated && status.cursors[stream] !== 0) {
59
+ status.cursors[stream] = 0;
60
+ await writeStatus(sessionId, status);
61
+ }
62
+ });
63
+ }
64
+ /**
65
+ * Consistent snapshot of the bytes pending for an OTEL stream.
66
+ *
67
+ * The lock guarantees the snapshot never contains a partially written append,
68
+ * so the protobuf payload handed to the backend is always whole.
69
+ * Must NOT be called while already holding the session lock.
70
+ */
71
+ export async function snapshotPendingBytes(sessionId, stream) {
72
+ return withSessionLock(sessionId, async () => {
73
+ const status = await readStatus(sessionId);
74
+ if (!status)
75
+ return null; // session was swept
76
+ const cursor = status.cursors[stream];
77
+ const bytes = await readRange(sessionId, stream, cursor);
78
+ return bytes ? { cursor, bytes } : null;
79
+ });
80
+ }
81
+ /**
82
+ * Consistent snapshot of the complete NDJSON records pending for hooks.
83
+ *
84
+ * The chunk is cut at the last newline byte, so an incomplete trailing record
85
+ * stays pending and `byteLength` is a byte-exact acknowledgement amount.
86
+ * Cutting on a newline is safe for UTF-8: `0x0a` cannot occur inside a
87
+ * multi-byte sequence.
88
+ * Must NOT be called while already holding the session lock.
89
+ */
90
+ export async function snapshotPendingHookRecords(sessionId) {
91
+ return withSessionLock(sessionId, async () => {
92
+ const status = await readStatus(sessionId);
93
+ if (!status)
94
+ return null;
95
+ const cursor = status.cursors.hooks;
96
+ const pending = await readRange(sessionId, 'hooks', cursor);
97
+ if (!pending)
98
+ return null;
99
+ const lastNewline = pending.lastIndexOf(NEWLINE);
100
+ if (lastNewline < 0)
101
+ return null; // no complete record yet
102
+ const complete = pending.subarray(0, lastNewline + 1);
103
+ const records = complete
104
+ .toString('utf-8')
105
+ .split('\n')
106
+ .filter((line) => line.trim().length > 0);
107
+ return { cursor, records, byteLength: complete.length };
108
+ });
109
+ }
110
+ //# sourceMappingURL=spool-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-io.js","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Root directory where all OTLP analytics spool files are stored.
3
+ * Resolves to `~/.codemie/proxy/otlp-spool`.
4
+ */
5
+ export declare function spoolRoot(): string;
6
+ /** OTEL binary streams (protobuf payloads produced by the agent runtime). */
7
+ export declare const OTEL_STREAMS: readonly ["logs", "metrics", "traces"];
8
+ export type OtelStream = (typeof OTEL_STREAMS)[number];
9
+ /** Every spool stream, in a stable order. */
10
+ export declare const SPOOL_STREAMS: readonly ["hooks", "logs", "metrics", "traces"];
11
+ export type SpoolStream = (typeof SPOOL_STREAMS)[number];
12
+ export declare const STATUS_EXT = ".status";
13
+ /** Spool data file for one stream of a session. */
14
+ export declare function streamFile(sessionId: string, stream: SpoolStream): string;
15
+ /** Delivery bookkeeping file for a session. */
16
+ export declare function statusFile(sessionId: string): string;
17
+ /**
18
+ * All session ids currently present in the spool root.
19
+ *
20
+ * Derived from any spool artifact (data or status) so that a session whose
21
+ * producer crashed before writing a status file is still discoverable.
22
+ */
23
+ export declare function listSessionIds(): Promise<string[]>;
24
+ //# sourceMappingURL=spool-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-paths.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6EAA6E;AAC7E,eAAO,MAAM,YAAY,wCAAyC,CAAC;AACnE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,6CAA6C;AAC7C,eAAO,MAAM,aAAa,iDAAsC,CAAC;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AASzD,eAAO,MAAM,UAAU,YAAY,CAAC;AAEpC,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAEzE;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAcxD"}
@@ -0,0 +1,53 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { getCodemiePath } from '../../../../../../utils/paths.js';
4
+ /**
5
+ * Root directory where all OTLP analytics spool files are stored.
6
+ * Resolves to `~/.codemie/proxy/otlp-spool`.
7
+ */
8
+ export function spoolRoot() {
9
+ return getCodemiePath('proxy', 'otlp-spool');
10
+ }
11
+ /** OTEL binary streams (protobuf payloads produced by the agent runtime). */
12
+ export const OTEL_STREAMS = ['logs', 'metrics', 'traces'];
13
+ /** Every spool stream, in a stable order. */
14
+ export const SPOOL_STREAMS = ['hooks', ...OTEL_STREAMS];
15
+ const STREAM_EXT = {
16
+ hooks: '.hooks.ndjson',
17
+ logs: '.otel_logs.bin',
18
+ metrics: '.otel_metrics.bin',
19
+ traces: '.otel_traces.bin',
20
+ };
21
+ export const STATUS_EXT = '.status';
22
+ /** Spool data file for one stream of a session. */
23
+ export function streamFile(sessionId, stream) {
24
+ return join(spoolRoot(), sessionId + STREAM_EXT[stream]);
25
+ }
26
+ /** Delivery bookkeeping file for a session. */
27
+ export function statusFile(sessionId) {
28
+ return join(spoolRoot(), sessionId + STATUS_EXT);
29
+ }
30
+ const ALL_SUFFIXES = [STATUS_EXT, ...Object.values(STREAM_EXT)];
31
+ /**
32
+ * All session ids currently present in the spool root.
33
+ *
34
+ * Derived from any spool artifact (data or status) so that a session whose
35
+ * producer crashed before writing a status file is still discoverable.
36
+ */
37
+ export async function listSessionIds() {
38
+ let entries;
39
+ try {
40
+ entries = await readdir(spoolRoot());
41
+ }
42
+ catch {
43
+ return []; // spool root may not exist yet
44
+ }
45
+ const ids = new Set();
46
+ for (const entry of entries) {
47
+ const suffix = ALL_SUFFIXES.find((suffix) => entry.length > suffix.length && entry.endsWith(suffix));
48
+ if (suffix)
49
+ ids.add(entry.slice(0, -suffix.length));
50
+ }
51
+ return [...ids];
52
+ }
53
+ //# sourceMappingURL=spool-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-paths.js","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAGnE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,GAAG,YAAY,CAAU,CAAC;AAGjE,MAAM,UAAU,GAAgC;IAC9C,KAAK,EAAE,eAAe;IACtB,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,kBAAkB;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AAEpC,mDAAmD;AACnD,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,MAAmB;IAC/D,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,YAAY,GAAsB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,+BAA+B;IAC5C,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACrG,IAAI,MAAM;YAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { type SpoolStream } from './spool-paths.js';
2
+ import type { SessionStatus } from './session-status.js';
3
+ export interface StreamState {
4
+ exists: boolean;
5
+ /** Current file size in bytes (0 when missing). */
6
+ size: number;
7
+ /** Acknowledged byte offset from the status file. */
8
+ cursor: number;
9
+ /** Last write time of the spool file, or `null` when missing. */
10
+ mtimeMs: number | null;
11
+ }
12
+ export interface SpoolState {
13
+ sessionId: string;
14
+ streams: Record<SpoolStream, StreamState>;
15
+ /** Latest mtime across existing spool data files — i.e. last producer write. */
16
+ latestWriteMs: number | null;
17
+ }
18
+ /**
19
+ * Snapshot the filesystem truth for a session: spool files are the source of
20
+ * truth for *what was written*, cursors for *what was delivered*.
21
+ */
22
+ export declare function readSpoolState(sessionId: string, status: SessionStatus): Promise<SpoolState>;
23
+ /** The stream was written at some point (sticky, survives the cursor reaching EOF). */
24
+ export declare const hasData: (state: StreamState) => boolean;
25
+ /** Bytes exist after the cursor and still need to be delivered. */
26
+ export declare const hasPending: (state: StreamState) => boolean;
27
+ /** Everything written has been acknowledged (missing/empty files are drained). */
28
+ export declare const isDrained: (state: StreamState) => boolean;
29
+ export declare function hooksGroupPresent(spool: SpoolState): boolean;
30
+ export declare function otelGroupPresent(spool: SpoolState): boolean;
31
+ export declare function hasPendingData(spool: SpoolState): boolean;
32
+ export declare function isSessionDrained(spool: SpoolState): boolean;
33
+ /**
34
+ * Last producer activity. Spool appends bump spool-file mtimes; forwarding and
35
+ * cursor writes only touch the status file, so the status mtime is a fallback
36
+ * used solely when no spool data file exists.
37
+ */
38
+ export declare function lastActivityMs(spool: SpoolState): Promise<number | null>;
39
+ //# sourceMappingURL=spool-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC1C,gFAAgF;IAChF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED,uFAAuF;AACvF,eAAO,MAAM,OAAO,GAAI,OAAO,WAAW,KAAG,OAAyB,CAAC;AAEvE,mEAAmE;AACnE,eAAO,MAAM,UAAU,GAAI,OAAO,WAAW,KAAG,OAAoC,CAAC;AAErF,kFAAkF;AAClF,eAAO,MAAM,SAAS,GAAI,OAAO,WAAW,KAAG,OAAqC,CAAC;AAErF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEzD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ9E"}
@@ -0,0 +1,61 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import { OTEL_STREAMS, SPOOL_STREAMS, statusFile, streamFile, } from './spool-paths.js';
3
+ /**
4
+ * Snapshot the filesystem truth for a session: spool files are the source of
5
+ * truth for *what was written*, cursors for *what was delivered*.
6
+ */
7
+ export async function readSpoolState(sessionId, status) {
8
+ const entries = await Promise.all(SPOOL_STREAMS.map(async (stream) => {
9
+ const cursor = status.cursors[stream];
10
+ try {
11
+ const info = await stat(streamFile(sessionId, stream));
12
+ return [stream, { exists: true, size: info.size, cursor, mtimeMs: info.mtimeMs }];
13
+ }
14
+ catch {
15
+ return [stream, { exists: false, size: 0, cursor, mtimeMs: null }];
16
+ }
17
+ }));
18
+ const streams = Object.fromEntries(entries);
19
+ const latestWriteMs = SPOOL_STREAMS.reduce((latest, stream) => {
20
+ const mtimeMs = streams[stream].mtimeMs;
21
+ if (mtimeMs === null)
22
+ return latest;
23
+ return latest === null ? mtimeMs : Math.max(latest, mtimeMs);
24
+ }, null);
25
+ return { sessionId, streams, latestWriteMs };
26
+ }
27
+ /** The stream was written at some point (sticky, survives the cursor reaching EOF). */
28
+ export const hasData = (state) => state.size > 0;
29
+ /** Bytes exist after the cursor and still need to be delivered. */
30
+ export const hasPending = (state) => state.size > state.cursor;
31
+ /** Everything written has been acknowledged (missing/empty files are drained). */
32
+ export const isDrained = (state) => state.size <= state.cursor;
33
+ export function hooksGroupPresent(spool) {
34
+ return hasData(spool.streams.hooks);
35
+ }
36
+ export function otelGroupPresent(spool) {
37
+ return OTEL_STREAMS.some((stream) => hasData(spool.streams[stream]));
38
+ }
39
+ export function hasPendingData(spool) {
40
+ return SPOOL_STREAMS.some((stream) => hasPending(spool.streams[stream]));
41
+ }
42
+ export function isSessionDrained(spool) {
43
+ return SPOOL_STREAMS.every((stream) => isDrained(spool.streams[stream]));
44
+ }
45
+ /**
46
+ * Last producer activity. Spool appends bump spool-file mtimes; forwarding and
47
+ * cursor writes only touch the status file, so the status mtime is a fallback
48
+ * used solely when no spool data file exists.
49
+ */
50
+ export async function lastActivityMs(spool) {
51
+ if (spool.latestWriteMs !== null)
52
+ return spool.latestWriteMs;
53
+ try {
54
+ const info = await stat(statusFile(spool.sessionId));
55
+ return info.mtimeMs;
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ //# sourceMappingURL=spool-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool-state.js","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/spool-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Lightweight garbage collection for the OTLP spool.
3
+ *
4
+ * Two cleanup paths, both of which require every stream to be drained
5
+ * (`fileSize === cursor`) so no undelivered bytes are ever destroyed:
6
+ *
7
+ * 1. Normally ended sessions (`endedAt` set): deleted once the end grace period
8
+ * has elapsed since the later of `endedAt` and the last spool-file write, so
9
+ * late hook/OTEL writes postpone cleanup.
10
+ * 2. Abandoned sessions (no `endedAt`): deleted once the abandonment timeout has
11
+ * elapsed since the last spool-file write. Activity is read from spool-file
12
+ * mtimes, never from the status file, because cursor updates rewrite the
13
+ * status file without any new data arriving.
14
+ *
15
+ * Consequence: a live session that stays quiet (and fully drained) for longer
16
+ * than the abandonment timeout may have its spool removed. That is safe — the
17
+ * next producer write recreates the status and spool files from scratch.
18
+ */
19
+ export declare function sweepSpool(): Promise<void>;
20
+ //# sourceMappingURL=sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep.d.ts","sourceRoot":"","sources":["../../../../../../../src/providers/plugins/sso/proxy/plugins/otlp-spool/sweep.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAShD"}