@zhixuan92/multi-model-agent 4.9.0 → 5.0.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 (252) hide show
  1. package/bin/mmagent.mjs +47 -0
  2. package/package.json +19 -57
  3. package/postinstall.mjs +8 -0
  4. package/LICENSE +0 -21
  5. package/README.md +0 -306
  6. package/dist/cli/index.d.ts +0 -62
  7. package/dist/cli/index.d.ts.map +0 -1
  8. package/dist/cli/index.js +0 -345
  9. package/dist/cli/index.js.map +0 -1
  10. package/dist/cli/info.d.ts +0 -22
  11. package/dist/cli/info.d.ts.map +0 -1
  12. package/dist/cli/info.js +0 -100
  13. package/dist/cli/info.js.map +0 -1
  14. package/dist/cli/logs.d.ts +0 -15
  15. package/dist/cli/logs.d.ts.map +0 -1
  16. package/dist/cli/logs.js +0 -102
  17. package/dist/cli/logs.js.map +0 -1
  18. package/dist/cli/print-token.d.ts +0 -18
  19. package/dist/cli/print-token.d.ts.map +0 -1
  20. package/dist/cli/print-token.js +0 -60
  21. package/dist/cli/print-token.js.map +0 -1
  22. package/dist/cli/serve.d.ts +0 -28
  23. package/dist/cli/serve.d.ts.map +0 -1
  24. package/dist/cli/serve.js +0 -405
  25. package/dist/cli/serve.js.map +0 -1
  26. package/dist/cli/status.d.ts +0 -49
  27. package/dist/cli/status.d.ts.map +0 -1
  28. package/dist/cli/status.js +0 -155
  29. package/dist/cli/status.js.map +0 -1
  30. package/dist/cli/sync-skills.d.ts +0 -58
  31. package/dist/cli/sync-skills.d.ts.map +0 -1
  32. package/dist/cli/sync-skills.js +0 -266
  33. package/dist/cli/sync-skills.js.map +0 -1
  34. package/dist/cli/telemetry.d.ts +0 -10
  35. package/dist/cli/telemetry.d.ts.map +0 -1
  36. package/dist/cli/telemetry.js +0 -161
  37. package/dist/cli/telemetry.js.map +0 -1
  38. package/dist/cli/toggle.d.ts +0 -26
  39. package/dist/cli/toggle.d.ts.map +0 -1
  40. package/dist/cli/toggle.js +0 -185
  41. package/dist/cli/toggle.js.map +0 -1
  42. package/dist/http/async-dispatch.d.ts +0 -44
  43. package/dist/http/async-dispatch.d.ts.map +0 -1
  44. package/dist/http/async-dispatch.js +0 -175
  45. package/dist/http/async-dispatch.js.map +0 -1
  46. package/dist/http/auth.d.ts +0 -20
  47. package/dist/http/auth.d.ts.map +0 -1
  48. package/dist/http/auth.js +0 -56
  49. package/dist/http/auth.js.map +0 -1
  50. package/dist/http/canonicalize-file-paths.d.ts +0 -8
  51. package/dist/http/canonicalize-file-paths.d.ts.map +0 -1
  52. package/dist/http/canonicalize-file-paths.js +0 -43
  53. package/dist/http/canonicalize-file-paths.js.map +0 -1
  54. package/dist/http/cwd-validator.d.ts +0 -11
  55. package/dist/http/cwd-validator.d.ts.map +0 -1
  56. package/dist/http/cwd-validator.js +0 -130
  57. package/dist/http/cwd-validator.js.map +0 -1
  58. package/dist/http/errors.d.ts +0 -4
  59. package/dist/http/errors.d.ts.map +0 -1
  60. package/dist/http/errors.js +0 -9
  61. package/dist/http/errors.js.map +0 -1
  62. package/dist/http/execution-context.d.ts +0 -18
  63. package/dist/http/execution-context.d.ts.map +0 -1
  64. package/dist/http/execution-context.js +0 -61
  65. package/dist/http/execution-context.js.map +0 -1
  66. package/dist/http/handler-deps.d.ts +0 -19
  67. package/dist/http/handler-deps.d.ts.map +0 -1
  68. package/dist/http/handler-deps.js +0 -2
  69. package/dist/http/handler-deps.js.map +0 -1
  70. package/dist/http/handlers/control/batch-slice.d.ts +0 -4
  71. package/dist/http/handlers/control/batch-slice.d.ts.map +0 -1
  72. package/dist/http/handlers/control/batch-slice.js +0 -40
  73. package/dist/http/handlers/control/batch-slice.js.map +0 -1
  74. package/dist/http/handlers/control/batch.d.ts +0 -23
  75. package/dist/http/handlers/control/batch.d.ts.map +0 -1
  76. package/dist/http/handlers/control/batch.js +0 -332
  77. package/dist/http/handlers/control/batch.js.map +0 -1
  78. package/dist/http/handlers/control/context-blocks.d.ts +0 -22
  79. package/dist/http/handlers/control/context-blocks.d.ts.map +0 -1
  80. package/dist/http/handlers/control/context-blocks.js +0 -111
  81. package/dist/http/handlers/control/context-blocks.js.map +0 -1
  82. package/dist/http/handlers/introspection/health.d.ts +0 -20
  83. package/dist/http/handlers/introspection/health.d.ts.map +0 -1
  84. package/dist/http/handlers/introspection/health.js +0 -18
  85. package/dist/http/handlers/introspection/health.js.map +0 -1
  86. package/dist/http/handlers/introspection/status.d.ts +0 -26
  87. package/dist/http/handlers/introspection/status.d.ts.map +0 -1
  88. package/dist/http/handlers/introspection/status.js +0 -136
  89. package/dist/http/handlers/introspection/status.js.map +0 -1
  90. package/dist/http/handlers/tools/audit.d.ts +0 -4
  91. package/dist/http/handlers/tools/audit.d.ts.map +0 -1
  92. package/dist/http/handlers/tools/audit.js +0 -43
  93. package/dist/http/handlers/tools/audit.js.map +0 -1
  94. package/dist/http/handlers/tools/debug.d.ts +0 -4
  95. package/dist/http/handlers/tools/debug.d.ts.map +0 -1
  96. package/dist/http/handlers/tools/debug.js +0 -43
  97. package/dist/http/handlers/tools/debug.js.map +0 -1
  98. package/dist/http/handlers/tools/delegate.d.ts +0 -4
  99. package/dist/http/handlers/tools/delegate.d.ts.map +0 -1
  100. package/dist/http/handlers/tools/delegate.js +0 -43
  101. package/dist/http/handlers/tools/delegate.js.map +0 -1
  102. package/dist/http/handlers/tools/execute-plan.d.ts +0 -4
  103. package/dist/http/handlers/tools/execute-plan.d.ts.map +0 -1
  104. package/dist/http/handlers/tools/execute-plan.js +0 -45
  105. package/dist/http/handlers/tools/execute-plan.js.map +0 -1
  106. package/dist/http/handlers/tools/investigate.d.ts +0 -4
  107. package/dist/http/handlers/tools/investigate.d.ts.map +0 -1
  108. package/dist/http/handlers/tools/investigate.js +0 -64
  109. package/dist/http/handlers/tools/investigate.js.map +0 -1
  110. package/dist/http/handlers/tools/journal-recall.d.ts +0 -4
  111. package/dist/http/handlers/tools/journal-recall.d.ts.map +0 -1
  112. package/dist/http/handlers/tools/journal-recall.js +0 -40
  113. package/dist/http/handlers/tools/journal-recall.js.map +0 -1
  114. package/dist/http/handlers/tools/journal-record.d.ts +0 -4
  115. package/dist/http/handlers/tools/journal-record.d.ts.map +0 -1
  116. package/dist/http/handlers/tools/journal-record.js +0 -35
  117. package/dist/http/handlers/tools/journal-record.js.map +0 -1
  118. package/dist/http/handlers/tools/research.d.ts +0 -4
  119. package/dist/http/handlers/tools/research.d.ts.map +0 -1
  120. package/dist/http/handlers/tools/research.js +0 -64
  121. package/dist/http/handlers/tools/research.js.map +0 -1
  122. package/dist/http/handlers/tools/retry.d.ts +0 -4
  123. package/dist/http/handlers/tools/retry.d.ts.map +0 -1
  124. package/dist/http/handlers/tools/retry.js +0 -73
  125. package/dist/http/handlers/tools/retry.js.map +0 -1
  126. package/dist/http/handlers/tools/review.d.ts +0 -4
  127. package/dist/http/handlers/tools/review.d.ts.map +0 -1
  128. package/dist/http/handlers/tools/review.js +0 -43
  129. package/dist/http/handlers/tools/review.js.map +0 -1
  130. package/dist/http/middleware/body-reader.d.ts +0 -16
  131. package/dist/http/middleware/body-reader.d.ts.map +0 -1
  132. package/dist/http/middleware/body-reader.js +0 -44
  133. package/dist/http/middleware/body-reader.js.map +0 -1
  134. package/dist/http/middleware/caller-identity.d.ts +0 -16
  135. package/dist/http/middleware/caller-identity.d.ts.map +0 -1
  136. package/dist/http/middleware/caller-identity.js +0 -16
  137. package/dist/http/middleware/caller-identity.js.map +0 -1
  138. package/dist/http/middleware/decompress.d.ts +0 -14
  139. package/dist/http/middleware/decompress.d.ts.map +0 -1
  140. package/dist/http/middleware/decompress.js +0 -51
  141. package/dist/http/middleware/decompress.js.map +0 -1
  142. package/dist/http/project-registry.d.ts +0 -54
  143. package/dist/http/project-registry.d.ts.map +0 -1
  144. package/dist/http/project-registry.js +0 -130
  145. package/dist/http/project-registry.js.map +0 -1
  146. package/dist/http/request-observability.d.ts +0 -8
  147. package/dist/http/request-observability.d.ts.map +0 -1
  148. package/dist/http/request-observability.js +0 -20
  149. package/dist/http/request-observability.js.map +0 -1
  150. package/dist/http/request-pipeline.d.ts +0 -16
  151. package/dist/http/request-pipeline.d.ts.map +0 -1
  152. package/dist/http/request-pipeline.js +0 -144
  153. package/dist/http/request-pipeline.js.map +0 -1
  154. package/dist/http/server.d.ts +0 -17
  155. package/dist/http/server.d.ts.map +0 -1
  156. package/dist/http/server.js +0 -300
  157. package/dist/http/server.js.map +0 -1
  158. package/dist/http/types.d.ts +0 -20
  159. package/dist/http/types.d.ts.map +0 -1
  160. package/dist/http/types.js +0 -2
  161. package/dist/http/types.js.map +0 -1
  162. package/dist/skill-install/disabled-state.d.ts +0 -35
  163. package/dist/skill-install/disabled-state.d.ts.map +0 -1
  164. package/dist/skill-install/disabled-state.js +0 -96
  165. package/dist/skill-install/disabled-state.js.map +0 -1
  166. package/dist/skill-install/discover.d.ts +0 -29
  167. package/dist/skill-install/discover.d.ts.map +0 -1
  168. package/dist/skill-install/discover.js +0 -104
  169. package/dist/skill-install/discover.js.map +0 -1
  170. package/dist/skill-install/include-utils.d.ts +0 -27
  171. package/dist/skill-install/include-utils.d.ts.map +0 -1
  172. package/dist/skill-install/include-utils.js +0 -90
  173. package/dist/skill-install/include-utils.js.map +0 -1
  174. package/dist/skill-install/manifest.d.ts +0 -82
  175. package/dist/skill-install/manifest.d.ts.map +0 -1
  176. package/dist/skill-install/manifest.js +0 -215
  177. package/dist/skill-install/manifest.js.map +0 -1
  178. package/dist/skill-install/skill-installer-common.d.ts +0 -26
  179. package/dist/skill-install/skill-installer-common.d.ts.map +0 -1
  180. package/dist/skill-install/skill-installer-common.js +0 -139
  181. package/dist/skill-install/skill-installer-common.js.map +0 -1
  182. package/dist/skill-install/skill-installers/claude-code.d.ts +0 -43
  183. package/dist/skill-install/skill-installers/claude-code.d.ts.map +0 -1
  184. package/dist/skill-install/skill-installers/claude-code.js +0 -65
  185. package/dist/skill-install/skill-installers/claude-code.js.map +0 -1
  186. package/dist/skill-install/skill-installers/codex-cli.d.ts +0 -27
  187. package/dist/skill-install/skill-installers/codex-cli.d.ts.map +0 -1
  188. package/dist/skill-install/skill-installers/codex-cli.js +0 -84
  189. package/dist/skill-install/skill-installers/codex-cli.js.map +0 -1
  190. package/dist/skill-install/skill-installers/cursor.d.ts +0 -72
  191. package/dist/skill-install/skill-installers/cursor.d.ts.map +0 -1
  192. package/dist/skill-install/skill-installers/cursor.js +0 -81
  193. package/dist/skill-install/skill-installers/cursor.js.map +0 -1
  194. package/dist/skill-install/skill-installers/gemini-cli.d.ts +0 -50
  195. package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +0 -1
  196. package/dist/skill-install/skill-installers/gemini-cli.js +0 -72
  197. package/dist/skill-install/skill-installers/gemini-cli.js.map +0 -1
  198. package/dist/skill-install/skill-manifest-sync.d.ts +0 -11
  199. package/dist/skill-install/skill-manifest-sync.d.ts.map +0 -1
  200. package/dist/skill-install/skill-manifest-sync.js +0 -65
  201. package/dist/skill-install/skill-manifest-sync.js.map +0 -1
  202. package/dist/skills/_shared/auth.md +0 -41
  203. package/dist/skills/_shared/error-handling.md +0 -31
  204. package/dist/skills/_shared/polling.md +0 -88
  205. package/dist/skills/_shared/response-shape.md +0 -55
  206. package/dist/skills/_shared/review-policy.md +0 -15
  207. package/dist/skills/mma-audit/SKILL.md +0 -270
  208. package/dist/skills/mma-context-blocks/SKILL.md +0 -148
  209. package/dist/skills/mma-debug/SKILL.md +0 -208
  210. package/dist/skills/mma-delegate/SKILL.md +0 -216
  211. package/dist/skills/mma-execute-plan/SKILL.md +0 -214
  212. package/dist/skills/mma-explore/SKILL.md +0 -190
  213. package/dist/skills/mma-investigate/SKILL.md +0 -258
  214. package/dist/skills/mma-journal-recall/SKILL.md +0 -242
  215. package/dist/skills/mma-journal-record/SKILL.md +0 -189
  216. package/dist/skills/mma-research/SKILL.md +0 -223
  217. package/dist/skills/mma-retry/SKILL.md +0 -221
  218. package/dist/skills/mma-review/SKILL.md +0 -209
  219. package/dist/skills/multi-model-agent/SKILL.md +0 -206
  220. package/dist/telemetry/consent.d.ts +0 -4
  221. package/dist/telemetry/consent.d.ts.map +0 -1
  222. package/dist/telemetry/consent.js +0 -40
  223. package/dist/telemetry/consent.js.map +0 -1
  224. package/dist/telemetry/flusher.d.ts +0 -19
  225. package/dist/telemetry/flusher.d.ts.map +0 -1
  226. package/dist/telemetry/flusher.js +0 -277
  227. package/dist/telemetry/flusher.js.map +0 -1
  228. package/dist/telemetry/generation.d.ts +0 -9
  229. package/dist/telemetry/generation.d.ts.map +0 -1
  230. package/dist/telemetry/generation.js +0 -33
  231. package/dist/telemetry/generation.js.map +0 -1
  232. package/dist/telemetry/identity.d.ts +0 -9
  233. package/dist/telemetry/identity.d.ts.map +0 -1
  234. package/dist/telemetry/identity.js +0 -35
  235. package/dist/telemetry/identity.js.map +0 -1
  236. package/dist/telemetry/install-id.d.ts +0 -13
  237. package/dist/telemetry/install-id.d.ts.map +0 -1
  238. package/dist/telemetry/install-id.js +0 -49
  239. package/dist/telemetry/install-id.js.map +0 -1
  240. package/dist/telemetry/install-meta.d.ts +0 -10
  241. package/dist/telemetry/install-meta.d.ts.map +0 -1
  242. package/dist/telemetry/install-meta.js +0 -15
  243. package/dist/telemetry/install-meta.js.map +0 -1
  244. package/dist/telemetry/queue.d.ts +0 -35
  245. package/dist/telemetry/queue.d.ts.map +0 -1
  246. package/dist/telemetry/queue.js +0 -287
  247. package/dist/telemetry/queue.js.map +0 -1
  248. package/dist/telemetry/recorder.d.ts +0 -39
  249. package/dist/telemetry/recorder.d.ts.map +0 -1
  250. package/dist/telemetry/recorder.js +0 -173
  251. package/dist/telemetry/recorder.js.map +0 -1
  252. package/scripts/postinstall.js +0 -36
@@ -1,277 +0,0 @@
1
- import { gzipSync } from 'node:zlib';
2
- import { readGeneration } from './generation.js';
3
- import { getOrCreateIdentity, sign } from './identity.js';
4
- import { SCHEMA_VERSION } from '@zhixuan92/multi-model-agent-core/events/wire-schema';
5
- const MAX_BATCH = 500;
6
- const INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
7
- const BOOT_DELAY_MS = 5_000; // 5 seconds
8
- const QUEUE_SIZE_TRIGGER = 100;
9
- const DRAIN_BUDGET_MS = 2_000; // 2 seconds
10
- const MAX_BACKOFF_MS = 60 * 60 * 1000; // 1 hour cap
11
- const NO_RETRY_AFTER_DEFAULT = 60 * 60 * 1000; // 1 hour
12
- const INITIAL_BACKOFF_MS = 5 * 60 * 1000; // 5 minutes
13
- function groupKey(record) {
14
- return `${record.schemaVersion}|${record.installId}|${record.mmagentVersion}|${record.os}|${record.nodeMajor}|${record.generation}`;
15
- }
16
- export class Flusher {
17
- #queue;
18
- #dir;
19
- #endpoint;
20
- #controller;
21
- #timer = null;
22
- #bootTimer = null;
23
- #backoffTimer = null;
24
- #backoffMs = 0;
25
- #inFlight = false;
26
- #dropped = 0;
27
- constructor(opts) {
28
- this.#queue = opts.queue;
29
- this.#dir = opts.dir;
30
- this.#endpoint = opts.endpoint;
31
- this.#controller = new AbortController();
32
- }
33
- get controller() {
34
- return this.#controller;
35
- }
36
- get dropped() {
37
- return this.#dropped;
38
- }
39
- get backoffActive() {
40
- return this.#backoffTimer !== null;
41
- }
42
- start() {
43
- this.#timer = setInterval(() => {
44
- if (!this.#inFlight && !this.backoffActive) {
45
- this.flush().catch(() => { });
46
- }
47
- }, INTERVAL_MS);
48
- this.#timer.unref();
49
- this.#bootTimer = setTimeout(() => {
50
- this.#bootTimer = null;
51
- this.flush().catch(() => { });
52
- }, BOOT_DELAY_MS);
53
- this.#bootTimer.unref();
54
- }
55
- stop() {
56
- if (this.#timer) {
57
- clearInterval(this.#timer);
58
- this.#timer = null;
59
- }
60
- if (this.#bootTimer) {
61
- clearTimeout(this.#bootTimer);
62
- this.#bootTimer = null;
63
- }
64
- this.clearBackoff();
65
- this.#controller.abort();
66
- }
67
- async drain() {
68
- this.stop();
69
- const deadline = Date.now() + DRAIN_BUDGET_MS;
70
- const drainSignal = AbortSignal.timeout(DRAIN_BUDGET_MS);
71
- try {
72
- await this.#doFlush(drainSignal, deadline);
73
- }
74
- catch {
75
- // drain is best-effort
76
- }
77
- }
78
- async flush() {
79
- if (this.#inFlight)
80
- return;
81
- if (this.backoffActive)
82
- return;
83
- return this.#doFlush(this.#controller.signal);
84
- }
85
- async #doFlush(signal, deadline) {
86
- if (signal.aborted)
87
- return;
88
- this.#inFlight = true;
89
- try {
90
- // Step 1: read up to 500 records + capture generation snapshot
91
- let batch = await this.#queue.readBatch(MAX_BATCH);
92
- if (batch.records.length === 0) {
93
- this.clearBackoff();
94
- return;
95
- }
96
- // Single identity snapshot per flush — threaded into both head-truncation and uploadBatch.
97
- const identity = getOrCreateIdentity(this.#dir);
98
- // V4-only: drop EVERY record that can't be authenticated, not just a
99
- // contiguous head-prefix. Records older than SCHEMA_VERSION or whose
100
- // installId doesn't match the current identity are permanently
101
- // un-authenticatable; retrying the same signed payload always fails.
102
- // Previously we only dropped a contiguous head — a sandwiched older
103
- // record (e.g. queued during a roll-back/forward, or installId churn)
104
- // would either propagate into an upload or split the upload into
105
- // versioned groups. Now: full-batch filter, then re-read to refresh
106
- // meta byteOffsets after the file rewrite.
107
- const dropHashes = new Set();
108
- for (let i = 0; i < batch.records.length; i++) {
109
- const r = batch.records[i];
110
- if (r.schemaVersion < SCHEMA_VERSION || r.installId !== identity.installId) {
111
- dropHashes.add(batch.meta[i].sha256);
112
- }
113
- }
114
- if (dropHashes.size > 0) {
115
- const removed = await this.#queue.removeRecords(dropHashes);
116
- this.#dropped += removed;
117
- batch = await this.#queue.readBatch(MAX_BATCH);
118
- if (batch.records.length === 0) {
119
- this.clearBackoff();
120
- return;
121
- }
122
- }
123
- const genSnapshot = readGeneration(this.#dir);
124
- // Step 4: Group consecutive records by (schemaVersion, install, generation)
125
- const groups = [];
126
- let currentKey = '';
127
- let currentRecords = [];
128
- let currentMeta = [];
129
- for (let i = 0; i < batch.records.length; i++) {
130
- const key = groupKey(batch.records[i]);
131
- if (currentKey && key !== currentKey) {
132
- groups.push({ records: currentRecords, meta: currentMeta });
133
- currentRecords = [];
134
- currentMeta = [];
135
- }
136
- currentKey = key;
137
- currentRecords.push(batch.records[i]);
138
- currentMeta.push(batch.meta[i]);
139
- }
140
- if (currentRecords.length > 0) {
141
- groups.push({ records: currentRecords, meta: currentMeta });
142
- }
143
- // Steps 5-6: Process each batch in order
144
- let acknowledgedCount = 0;
145
- let shouldBackoff = false;
146
- let backoffDuration = 0;
147
- for (const group of groups) {
148
- if (deadline && Date.now() > deadline)
149
- break;
150
- // Re-check generation; if changed since read, abort
151
- const currentGen = readGeneration(this.#dir);
152
- if (currentGen !== genSnapshot)
153
- break;
154
- if (signal.aborted)
155
- break;
156
- const result = await this.#uploadBatch(group, signal, identity);
157
- if (result.status === '204' || result.status === '400' || result.status === '413') {
158
- acknowledgedCount += group.records.length;
159
- if (result.status === '400' || result.status === '413') {
160
- this.#dropped += group.records.length;
161
- }
162
- }
163
- else {
164
- shouldBackoff = true;
165
- if (result.status === '429') {
166
- backoffDuration = result.retryAfterSeconds !== null
167
- ? result.retryAfterSeconds * 1000
168
- : NO_RETRY_AFTER_DEFAULT;
169
- }
170
- else {
171
- backoffDuration = this.#nextBackoff();
172
- }
173
- break; // stop iterating on non-success
174
- }
175
- }
176
- // Steps 7-9: truncate acknowledged prefix
177
- if (acknowledgedCount > 0) {
178
- await this.#queue.truncate(batch.meta.slice(0, acknowledgedCount));
179
- }
180
- // Apply or clear backoff
181
- if (shouldBackoff) {
182
- this.#scheduleBackoff(backoffDuration);
183
- }
184
- else {
185
- // Reset backoff on successful drain (all batches processed)
186
- this.clearBackoff();
187
- }
188
- }
189
- finally {
190
- this.#inFlight = false;
191
- }
192
- }
193
- async #uploadBatch(group, signal, identity) {
194
- const first = group.records[0];
195
- const events = group.records.flatMap(r => r.events);
196
- const jsonBody = JSON.stringify({
197
- schemaVersion: first.schemaVersion,
198
- installId: first.installId,
199
- mmagentVersion: first.mmagentVersion,
200
- os: first.os,
201
- nodeMajor: first.nodeMajor,
202
- events,
203
- });
204
- const signature = sign(identity.privateKeyPkcs8, jsonBody);
205
- const body = gzipSync(Buffer.from(jsonBody, 'utf8'));
206
- try {
207
- const response = await fetch(this.#endpoint, {
208
- method: 'POST',
209
- headers: {
210
- 'Content-Encoding': 'gzip',
211
- 'Content-Type': 'application/json',
212
- 'X-Mmagent-Install-Id': identity.installId,
213
- 'X-Mmagent-Signature': signature,
214
- 'X-Mmagent-Pubkey': identity.publicKeyRaw,
215
- },
216
- body,
217
- signal,
218
- });
219
- const status = response.status;
220
- if (status === 204)
221
- return { status: '204', retryAfterSeconds: null };
222
- if (status === 400 || status === 413) {
223
- let body = '';
224
- try {
225
- body = (await response.text()).slice(0, 200);
226
- }
227
- catch { /* ignore */ }
228
- process.stderr.write(`[mmagent] telemetry upload dropped: status=${status} records=${group.records.length} body=${body}\n`);
229
- return { status: status === 400 ? '400' : '413', retryAfterSeconds: null };
230
- }
231
- if (status === 429) {
232
- const retryAfter = response.headers.get('Retry-After');
233
- const seconds = retryAfter ? parseInt(retryAfter, 10) : null;
234
- return { status: '429', retryAfterSeconds: Number.isFinite(seconds) ? seconds : null };
235
- }
236
- if (status >= 500)
237
- return { status: '5xx', retryAfterSeconds: null };
238
- // Unexpected status: treat as 5xx
239
- return { status: '5xx', retryAfterSeconds: null };
240
- }
241
- catch (err) {
242
- if (err instanceof DOMException && err.name === 'AbortError') {
243
- throw err;
244
- }
245
- return { status: 'network', retryAfterSeconds: null };
246
- }
247
- }
248
- #nextBackoff() {
249
- if (this.#backoffMs === 0) {
250
- this.#backoffMs = INITIAL_BACKOFF_MS;
251
- }
252
- else {
253
- this.#backoffMs = Math.min(this.#backoffMs * 2, MAX_BACKOFF_MS);
254
- }
255
- return this.#backoffMs;
256
- }
257
- #scheduleBackoff(ms) {
258
- if (this.#backoffTimer) {
259
- clearTimeout(this.#backoffTimer);
260
- this.#backoffTimer = null;
261
- }
262
- this.#backoffTimer = setTimeout(() => {
263
- this.#backoffTimer = null;
264
- this.flush().catch(() => { });
265
- }, ms);
266
- if (this.#backoffTimer.unref)
267
- this.#backoffTimer.unref();
268
- }
269
- clearBackoff() {
270
- if (this.#backoffTimer) {
271
- clearTimeout(this.#backoffTimer);
272
- this.#backoffTimer = null;
273
- }
274
- this.#backoffMs = 0;
275
- }
276
- }
277
- //# sourceMappingURL=flusher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flusher.js","sourceRoot":"","sources":["../../src/telemetry/flusher.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- export declare function readGeneration(dir: string): number;
2
- /**
3
- * Atomic increment. Uses proper-lockfile (already a dep for queue.ts) so two
4
- * simultaneous `mmagent telemetry disable` invocations cannot both read N and
5
- * both write N+1 (which would silently lose a generation bump and leave a
6
- * revoked identity's events accepted by the backend).
7
- */
8
- export declare function bumpGeneration(dir: string): Promise<number>;
9
- //# sourceMappingURL=generation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/telemetry/generation.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYjE"}
@@ -1,33 +0,0 @@
1
- import { readFileSync, writeFileSync, existsSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import lockfile from 'proper-lockfile';
4
- const FILE = 'telemetry-generation';
5
- export function readGeneration(dir) {
6
- const p = join(dir, FILE);
7
- if (!existsSync(p))
8
- return 0;
9
- const n = Number.parseInt(readFileSync(p, 'utf8').trim(), 10);
10
- return Number.isFinite(n) && n >= 0 ? n : 0;
11
- }
12
- /**
13
- * Atomic increment. Uses proper-lockfile (already a dep for queue.ts) so two
14
- * simultaneous `mmagent telemetry disable` invocations cannot both read N and
15
- * both write N+1 (which would silently lose a generation bump and leave a
16
- * revoked identity's events accepted by the backend).
17
- */
18
- export async function bumpGeneration(dir) {
19
- const p = join(dir, FILE);
20
- if (!existsSync(p))
21
- writeFileSync(p, '0', { mode: 0o600 });
22
- const release = await lockfile.lock(p, { retries: { retries: 15, minTimeout: 50, maxTimeout: 500 } });
23
- try {
24
- const current = readGeneration(dir);
25
- const next = current + 1;
26
- writeFileSync(p, String(next), { mode: 0o600 });
27
- return next;
28
- }
29
- finally {
30
- await release();
31
- }
32
- }
33
- //# sourceMappingURL=generation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generation.js","sourceRoot":"","sources":["../../src/telemetry/generation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAEvC,MAAM,IAAI,GAAG,sBAAsB,CAAC;AAEpC,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACtG,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC;QACzB,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1,9 +0,0 @@
1
- export interface Identity {
2
- installId: string;
3
- generatedAt: string;
4
- privateKeyPkcs8: string;
5
- publicKeyRaw: string;
6
- }
7
- export declare function getOrCreateIdentity(homeDir: string): Identity;
8
- export declare function sign(privateKeyPkcs8Base64: string, jsonBody: string): string;
9
- //# sourceMappingURL=identity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/telemetry/identity.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAqB7D;AAED,wBAAgB,IAAI,CAAC,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO5E"}
@@ -1,35 +0,0 @@
1
- import { createPrivateKey, generateKeyPairSync, randomUUID, sign as edSign, } from 'node:crypto';
2
- import { readFileSync, writeFileSync } from 'node:fs';
3
- import { join } from 'node:path';
4
- export function getOrCreateIdentity(homeDir) {
5
- const path = join(homeDir, 'identity.json');
6
- try {
7
- const id = JSON.parse(readFileSync(path, 'utf8'));
8
- const ageMs = Date.now() - new Date(id.generatedAt).getTime();
9
- if (ageMs < 365 * 24 * 3600 * 1000) {
10
- return id;
11
- }
12
- // Older than 365 days → falls through to regeneration block below.
13
- }
14
- catch {
15
- // missing or corrupt → regenerate
16
- }
17
- const { privateKey, publicKey } = generateKeyPairSync('ed25519');
18
- const id = {
19
- installId: randomUUID(),
20
- generatedAt: new Date().toISOString(),
21
- privateKeyPkcs8: privateKey.export({ type: 'pkcs8', format: 'der' }).toString('base64'),
22
- publicKeyRaw: publicKey.export({ type: 'spki', format: 'der' }).toString('base64'),
23
- };
24
- writeFileSync(path, JSON.stringify(id), { mode: 0o600 });
25
- return id;
26
- }
27
- export function sign(privateKeyPkcs8Base64, jsonBody) {
28
- const key = createPrivateKey({
29
- key: Buffer.from(privateKeyPkcs8Base64, 'base64'),
30
- format: 'der',
31
- type: 'pkcs8',
32
- });
33
- return edSign(null, Buffer.from(jsonBody, 'utf8'), key).toString('base64');
34
- }
35
- //# sourceMappingURL=identity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/telemetry/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACV,IAAI,IAAI,MAAM,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAa,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9D,IAAI,KAAK,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,mEAAmE;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,EAAE,GAAa;QACnB,SAAS,EAAE,UAAU,EAAE;QACvB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvF,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;KACnF,CAAC;IACF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,qBAA6B,EAAE,QAAgB;IAClE,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC;QACjD,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7E,CAAC"}
@@ -1,13 +0,0 @@
1
- export declare function hasInstallId(dir: string): boolean;
2
- /**
3
- * Atomic create-or-read.
4
- * - `openSync(path, 'wx')` is exclusive — succeeds only if the file does not exist.
5
- * - Two concurrent processes racing here: one wins the create, the other gets EEXIST
6
- * and falls through to the read path. No `proper-lockfile` needed for this one.
7
- * - We `fsyncSync` the WRITE descriptor (not a re-opened read fd) so the kernel
8
- * actually flushes the bytes; this is the data-durability guarantee that survives
9
- * power loss.
10
- */
11
- export declare function getOrCreateInstallId(dir: string): string;
12
- export declare function deleteInstallId(dir: string): void;
13
- //# sourceMappingURL=install-id.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"install-id.d.ts","sourceRoot":"","sources":["../../src/telemetry/install-id.ts"],"names":[],"mappings":"AAMA,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAwBxD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGjD"}
@@ -1,49 +0,0 @@
1
- import { readFileSync, openSync, closeSync, writeSync, fsyncSync, existsSync, unlinkSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { randomUUID } from 'node:crypto';
4
- const FILE = 'install-id';
5
- export function hasInstallId(dir) {
6
- return existsSync(join(dir, FILE));
7
- }
8
- /**
9
- * Atomic create-or-read.
10
- * - `openSync(path, 'wx')` is exclusive — succeeds only if the file does not exist.
11
- * - Two concurrent processes racing here: one wins the create, the other gets EEXIST
12
- * and falls through to the read path. No `proper-lockfile` needed for this one.
13
- * - We `fsyncSync` the WRITE descriptor (not a re-opened read fd) so the kernel
14
- * actually flushes the bytes; this is the data-durability guarantee that survives
15
- * power loss.
16
- */
17
- export function getOrCreateInstallId(dir) {
18
- const path = join(dir, FILE);
19
- // Fast path: file already exists.
20
- if (existsSync(path)) {
21
- return readFileSync(path, 'utf8').trim();
22
- }
23
- // Race-safe create.
24
- const id = randomUUID();
25
- let fd;
26
- try {
27
- fd = openSync(path, 'wx', 0o600); // EEXIST if a concurrent process beat us
28
- }
29
- catch (e) {
30
- if (e.code === 'EEXIST') {
31
- return readFileSync(path, 'utf8').trim();
32
- }
33
- throw e;
34
- }
35
- try {
36
- writeSync(fd, id);
37
- fsyncSync(fd); // flush data to durable storage on the WRITE fd
38
- }
39
- finally {
40
- closeSync(fd);
41
- }
42
- return id;
43
- }
44
- export function deleteInstallId(dir) {
45
- const path = join(dir, FILE);
46
- if (existsSync(path))
47
- unlinkSync(path);
48
- }
49
- //# sourceMappingURL=install-id.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"install-id.js","sourceRoot":"","sources":["../../src/telemetry/install-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1G,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,IAAI,GAAG,YAAY,CAAC;AAE1B,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7B,kCAAkC;IAClC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IACD,oBAAoB;IACpB,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IACxB,IAAI,EAAU,CAAC;IACf,IAAI,CAAC;QACH,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,yCAAyC;IAC9E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnD,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;IACD,IAAI,CAAC;QACH,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAClB,SAAS,CAAC,EAAE,CAAC,CAAC,CAAE,gDAAgD;IAClE,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC"}
@@ -1,10 +0,0 @@
1
- export declare function buildInstallMeta(args: {
2
- installId: string;
3
- mmagentVersion: string;
4
- }): {
5
- installId: string;
6
- mmagentVersion: string;
7
- os: "darwin" | "linux" | "win32" | "other";
8
- nodeMajor: number;
9
- };
10
- //# sourceMappingURL=install-meta.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"install-meta.d.ts","sourceRoot":"","sources":["../../src/telemetry/install-meta.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE;;;;;EAOnF"}
@@ -1,15 +0,0 @@
1
- function bucketOs() {
2
- const p = process.platform;
3
- if (p === 'darwin' || p === 'linux' || p === 'win32')
4
- return p;
5
- return 'other';
6
- }
7
- export function buildInstallMeta(args) {
8
- return {
9
- installId: args.installId,
10
- mmagentVersion: args.mmagentVersion,
11
- os: bucketOs(),
12
- nodeMajor: Number(process.versions.node.split('.')[0]),
13
- };
14
- }
15
- //# sourceMappingURL=install-meta.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"install-meta.js","sourceRoot":"","sources":["../../src/telemetry/install-meta.ts"],"names":[],"mappings":"AAAA,SAAS,QAAQ;IACf,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAmD;IAClF,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,EAAE,EAAE,QAAQ,EAAE;QACd,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KACvD,CAAC;AACJ,CAAC"}
@@ -1,35 +0,0 @@
1
- declare function resetCapWarning(): void;
2
- export interface QueueRecord {
3
- schemaVersion: number;
4
- installId: string;
5
- mmagentVersion: string;
6
- os: 'darwin' | 'linux' | 'win32' | 'other';
7
- nodeMajor: number;
8
- generation: number;
9
- events: Record<string, unknown>[];
10
- }
11
- export interface RecordMeta {
12
- byteOffset: number;
13
- byteLength: number;
14
- sha256: string;
15
- }
16
- export interface ReadBatchResult {
17
- records: QueueRecord[];
18
- meta: RecordMeta[];
19
- }
20
- export declare class Queue {
21
- #private;
22
- constructor(dir: string);
23
- get queuePath(): string;
24
- append(record: QueueRecord): Promise<void>;
25
- readBatch(maxRecords?: number): Promise<ReadBatchResult>;
26
- /**
27
- * Remove records whose SHA-256 hashes are in the provided set.
28
- * Rebuilds the queue file from scratch — safe for arbitrary (non-contiguous)
29
- * removal. Returns the number of records actually removed.
30
- */
31
- removeRecords(hashes: Set<string>): Promise<number>;
32
- truncate(expectedMeta: RecordMeta[]): Promise<void>;
33
- }
34
- export { resetCapWarning };
35
- //# sourceMappingURL=queue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/telemetry/queue.ts"],"names":[],"mappings":"AAkBA,iBAAS,eAAe,IAAI,IAAI,CAE/B;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,IAAI,EAAE,UAAU,EAAE,CAAC;CACpB;AAgCD,qBAAa,KAAK;;gBAMJ,GAAG,EAAE,MAAM;IAKvB,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B1C,SAAS,CAAC,UAAU,SAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAqDtE;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAyCnD,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+G1D;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}