@zhixuan92/multi-model-agent 4.9.1 → 5.0.1

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 (251) hide show
  1. package/README.md +4 -3
  2. package/bin/mmagent.mjs +47 -0
  3. package/package.json +24 -43
  4. package/postinstall.mjs +8 -0
  5. package/dist/cli/index.d.ts +0 -62
  6. package/dist/cli/index.d.ts.map +0 -1
  7. package/dist/cli/index.js +0 -345
  8. package/dist/cli/index.js.map +0 -1
  9. package/dist/cli/info.d.ts +0 -22
  10. package/dist/cli/info.d.ts.map +0 -1
  11. package/dist/cli/info.js +0 -100
  12. package/dist/cli/info.js.map +0 -1
  13. package/dist/cli/logs.d.ts +0 -15
  14. package/dist/cli/logs.d.ts.map +0 -1
  15. package/dist/cli/logs.js +0 -102
  16. package/dist/cli/logs.js.map +0 -1
  17. package/dist/cli/print-token.d.ts +0 -18
  18. package/dist/cli/print-token.d.ts.map +0 -1
  19. package/dist/cli/print-token.js +0 -60
  20. package/dist/cli/print-token.js.map +0 -1
  21. package/dist/cli/serve.d.ts +0 -28
  22. package/dist/cli/serve.d.ts.map +0 -1
  23. package/dist/cli/serve.js +0 -405
  24. package/dist/cli/serve.js.map +0 -1
  25. package/dist/cli/status.d.ts +0 -49
  26. package/dist/cli/status.d.ts.map +0 -1
  27. package/dist/cli/status.js +0 -155
  28. package/dist/cli/status.js.map +0 -1
  29. package/dist/cli/sync-skills.d.ts +0 -58
  30. package/dist/cli/sync-skills.d.ts.map +0 -1
  31. package/dist/cli/sync-skills.js +0 -266
  32. package/dist/cli/sync-skills.js.map +0 -1
  33. package/dist/cli/telemetry.d.ts +0 -10
  34. package/dist/cli/telemetry.d.ts.map +0 -1
  35. package/dist/cli/telemetry.js +0 -161
  36. package/dist/cli/telemetry.js.map +0 -1
  37. package/dist/cli/toggle.d.ts +0 -26
  38. package/dist/cli/toggle.d.ts.map +0 -1
  39. package/dist/cli/toggle.js +0 -185
  40. package/dist/cli/toggle.js.map +0 -1
  41. package/dist/http/async-dispatch.d.ts +0 -44
  42. package/dist/http/async-dispatch.d.ts.map +0 -1
  43. package/dist/http/async-dispatch.js +0 -175
  44. package/dist/http/async-dispatch.js.map +0 -1
  45. package/dist/http/auth.d.ts +0 -20
  46. package/dist/http/auth.d.ts.map +0 -1
  47. package/dist/http/auth.js +0 -56
  48. package/dist/http/auth.js.map +0 -1
  49. package/dist/http/canonicalize-file-paths.d.ts +0 -8
  50. package/dist/http/canonicalize-file-paths.d.ts.map +0 -1
  51. package/dist/http/canonicalize-file-paths.js +0 -43
  52. package/dist/http/canonicalize-file-paths.js.map +0 -1
  53. package/dist/http/cwd-validator.d.ts +0 -11
  54. package/dist/http/cwd-validator.d.ts.map +0 -1
  55. package/dist/http/cwd-validator.js +0 -130
  56. package/dist/http/cwd-validator.js.map +0 -1
  57. package/dist/http/errors.d.ts +0 -4
  58. package/dist/http/errors.d.ts.map +0 -1
  59. package/dist/http/errors.js +0 -9
  60. package/dist/http/errors.js.map +0 -1
  61. package/dist/http/execution-context.d.ts +0 -18
  62. package/dist/http/execution-context.d.ts.map +0 -1
  63. package/dist/http/execution-context.js +0 -61
  64. package/dist/http/execution-context.js.map +0 -1
  65. package/dist/http/handler-deps.d.ts +0 -19
  66. package/dist/http/handler-deps.d.ts.map +0 -1
  67. package/dist/http/handler-deps.js +0 -2
  68. package/dist/http/handler-deps.js.map +0 -1
  69. package/dist/http/handlers/control/batch-slice.d.ts +0 -4
  70. package/dist/http/handlers/control/batch-slice.d.ts.map +0 -1
  71. package/dist/http/handlers/control/batch-slice.js +0 -40
  72. package/dist/http/handlers/control/batch-slice.js.map +0 -1
  73. package/dist/http/handlers/control/batch.d.ts +0 -23
  74. package/dist/http/handlers/control/batch.d.ts.map +0 -1
  75. package/dist/http/handlers/control/batch.js +0 -332
  76. package/dist/http/handlers/control/batch.js.map +0 -1
  77. package/dist/http/handlers/control/context-blocks.d.ts +0 -22
  78. package/dist/http/handlers/control/context-blocks.d.ts.map +0 -1
  79. package/dist/http/handlers/control/context-blocks.js +0 -111
  80. package/dist/http/handlers/control/context-blocks.js.map +0 -1
  81. package/dist/http/handlers/introspection/health.d.ts +0 -20
  82. package/dist/http/handlers/introspection/health.d.ts.map +0 -1
  83. package/dist/http/handlers/introspection/health.js +0 -18
  84. package/dist/http/handlers/introspection/health.js.map +0 -1
  85. package/dist/http/handlers/introspection/status.d.ts +0 -26
  86. package/dist/http/handlers/introspection/status.d.ts.map +0 -1
  87. package/dist/http/handlers/introspection/status.js +0 -136
  88. package/dist/http/handlers/introspection/status.js.map +0 -1
  89. package/dist/http/handlers/tools/audit.d.ts +0 -4
  90. package/dist/http/handlers/tools/audit.d.ts.map +0 -1
  91. package/dist/http/handlers/tools/audit.js +0 -43
  92. package/dist/http/handlers/tools/audit.js.map +0 -1
  93. package/dist/http/handlers/tools/debug.d.ts +0 -4
  94. package/dist/http/handlers/tools/debug.d.ts.map +0 -1
  95. package/dist/http/handlers/tools/debug.js +0 -43
  96. package/dist/http/handlers/tools/debug.js.map +0 -1
  97. package/dist/http/handlers/tools/delegate.d.ts +0 -4
  98. package/dist/http/handlers/tools/delegate.d.ts.map +0 -1
  99. package/dist/http/handlers/tools/delegate.js +0 -43
  100. package/dist/http/handlers/tools/delegate.js.map +0 -1
  101. package/dist/http/handlers/tools/execute-plan.d.ts +0 -4
  102. package/dist/http/handlers/tools/execute-plan.d.ts.map +0 -1
  103. package/dist/http/handlers/tools/execute-plan.js +0 -45
  104. package/dist/http/handlers/tools/execute-plan.js.map +0 -1
  105. package/dist/http/handlers/tools/investigate.d.ts +0 -4
  106. package/dist/http/handlers/tools/investigate.d.ts.map +0 -1
  107. package/dist/http/handlers/tools/investigate.js +0 -64
  108. package/dist/http/handlers/tools/investigate.js.map +0 -1
  109. package/dist/http/handlers/tools/journal-recall.d.ts +0 -4
  110. package/dist/http/handlers/tools/journal-recall.d.ts.map +0 -1
  111. package/dist/http/handlers/tools/journal-recall.js +0 -40
  112. package/dist/http/handlers/tools/journal-recall.js.map +0 -1
  113. package/dist/http/handlers/tools/journal-record.d.ts +0 -4
  114. package/dist/http/handlers/tools/journal-record.d.ts.map +0 -1
  115. package/dist/http/handlers/tools/journal-record.js +0 -35
  116. package/dist/http/handlers/tools/journal-record.js.map +0 -1
  117. package/dist/http/handlers/tools/research.d.ts +0 -4
  118. package/dist/http/handlers/tools/research.d.ts.map +0 -1
  119. package/dist/http/handlers/tools/research.js +0 -64
  120. package/dist/http/handlers/tools/research.js.map +0 -1
  121. package/dist/http/handlers/tools/retry.d.ts +0 -4
  122. package/dist/http/handlers/tools/retry.d.ts.map +0 -1
  123. package/dist/http/handlers/tools/retry.js +0 -73
  124. package/dist/http/handlers/tools/retry.js.map +0 -1
  125. package/dist/http/handlers/tools/review.d.ts +0 -4
  126. package/dist/http/handlers/tools/review.d.ts.map +0 -1
  127. package/dist/http/handlers/tools/review.js +0 -43
  128. package/dist/http/handlers/tools/review.js.map +0 -1
  129. package/dist/http/middleware/body-reader.d.ts +0 -16
  130. package/dist/http/middleware/body-reader.d.ts.map +0 -1
  131. package/dist/http/middleware/body-reader.js +0 -44
  132. package/dist/http/middleware/body-reader.js.map +0 -1
  133. package/dist/http/middleware/caller-identity.d.ts +0 -16
  134. package/dist/http/middleware/caller-identity.d.ts.map +0 -1
  135. package/dist/http/middleware/caller-identity.js +0 -16
  136. package/dist/http/middleware/caller-identity.js.map +0 -1
  137. package/dist/http/middleware/decompress.d.ts +0 -14
  138. package/dist/http/middleware/decompress.d.ts.map +0 -1
  139. package/dist/http/middleware/decompress.js +0 -51
  140. package/dist/http/middleware/decompress.js.map +0 -1
  141. package/dist/http/project-registry.d.ts +0 -54
  142. package/dist/http/project-registry.d.ts.map +0 -1
  143. package/dist/http/project-registry.js +0 -130
  144. package/dist/http/project-registry.js.map +0 -1
  145. package/dist/http/request-observability.d.ts +0 -8
  146. package/dist/http/request-observability.d.ts.map +0 -1
  147. package/dist/http/request-observability.js +0 -20
  148. package/dist/http/request-observability.js.map +0 -1
  149. package/dist/http/request-pipeline.d.ts +0 -16
  150. package/dist/http/request-pipeline.d.ts.map +0 -1
  151. package/dist/http/request-pipeline.js +0 -144
  152. package/dist/http/request-pipeline.js.map +0 -1
  153. package/dist/http/server.d.ts +0 -17
  154. package/dist/http/server.d.ts.map +0 -1
  155. package/dist/http/server.js +0 -300
  156. package/dist/http/server.js.map +0 -1
  157. package/dist/http/types.d.ts +0 -20
  158. package/dist/http/types.d.ts.map +0 -1
  159. package/dist/http/types.js +0 -2
  160. package/dist/http/types.js.map +0 -1
  161. package/dist/skill-install/disabled-state.d.ts +0 -35
  162. package/dist/skill-install/disabled-state.d.ts.map +0 -1
  163. package/dist/skill-install/disabled-state.js +0 -96
  164. package/dist/skill-install/disabled-state.js.map +0 -1
  165. package/dist/skill-install/discover.d.ts +0 -29
  166. package/dist/skill-install/discover.d.ts.map +0 -1
  167. package/dist/skill-install/discover.js +0 -104
  168. package/dist/skill-install/discover.js.map +0 -1
  169. package/dist/skill-install/include-utils.d.ts +0 -27
  170. package/dist/skill-install/include-utils.d.ts.map +0 -1
  171. package/dist/skill-install/include-utils.js +0 -90
  172. package/dist/skill-install/include-utils.js.map +0 -1
  173. package/dist/skill-install/manifest.d.ts +0 -82
  174. package/dist/skill-install/manifest.d.ts.map +0 -1
  175. package/dist/skill-install/manifest.js +0 -215
  176. package/dist/skill-install/manifest.js.map +0 -1
  177. package/dist/skill-install/skill-installer-common.d.ts +0 -26
  178. package/dist/skill-install/skill-installer-common.d.ts.map +0 -1
  179. package/dist/skill-install/skill-installer-common.js +0 -139
  180. package/dist/skill-install/skill-installer-common.js.map +0 -1
  181. package/dist/skill-install/skill-installers/claude-code.d.ts +0 -43
  182. package/dist/skill-install/skill-installers/claude-code.d.ts.map +0 -1
  183. package/dist/skill-install/skill-installers/claude-code.js +0 -65
  184. package/dist/skill-install/skill-installers/claude-code.js.map +0 -1
  185. package/dist/skill-install/skill-installers/codex-cli.d.ts +0 -27
  186. package/dist/skill-install/skill-installers/codex-cli.d.ts.map +0 -1
  187. package/dist/skill-install/skill-installers/codex-cli.js +0 -84
  188. package/dist/skill-install/skill-installers/codex-cli.js.map +0 -1
  189. package/dist/skill-install/skill-installers/cursor.d.ts +0 -72
  190. package/dist/skill-install/skill-installers/cursor.d.ts.map +0 -1
  191. package/dist/skill-install/skill-installers/cursor.js +0 -81
  192. package/dist/skill-install/skill-installers/cursor.js.map +0 -1
  193. package/dist/skill-install/skill-installers/gemini-cli.d.ts +0 -50
  194. package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +0 -1
  195. package/dist/skill-install/skill-installers/gemini-cli.js +0 -72
  196. package/dist/skill-install/skill-installers/gemini-cli.js.map +0 -1
  197. package/dist/skill-install/skill-manifest-sync.d.ts +0 -11
  198. package/dist/skill-install/skill-manifest-sync.d.ts.map +0 -1
  199. package/dist/skill-install/skill-manifest-sync.js +0 -65
  200. package/dist/skill-install/skill-manifest-sync.js.map +0 -1
  201. package/dist/skills/_shared/auth.md +0 -41
  202. package/dist/skills/_shared/error-handling.md +0 -31
  203. package/dist/skills/_shared/polling.md +0 -88
  204. package/dist/skills/_shared/response-shape.md +0 -55
  205. package/dist/skills/_shared/review-policy.md +0 -15
  206. package/dist/skills/mma-audit/SKILL.md +0 -270
  207. package/dist/skills/mma-context-blocks/SKILL.md +0 -148
  208. package/dist/skills/mma-debug/SKILL.md +0 -208
  209. package/dist/skills/mma-delegate/SKILL.md +0 -216
  210. package/dist/skills/mma-execute-plan/SKILL.md +0 -214
  211. package/dist/skills/mma-explore/SKILL.md +0 -190
  212. package/dist/skills/mma-investigate/SKILL.md +0 -258
  213. package/dist/skills/mma-journal-recall/SKILL.md +0 -242
  214. package/dist/skills/mma-journal-record/SKILL.md +0 -189
  215. package/dist/skills/mma-research/SKILL.md +0 -223
  216. package/dist/skills/mma-retry/SKILL.md +0 -221
  217. package/dist/skills/mma-review/SKILL.md +0 -209
  218. package/dist/skills/multi-model-agent/SKILL.md +0 -206
  219. package/dist/telemetry/consent.d.ts +0 -4
  220. package/dist/telemetry/consent.d.ts.map +0 -1
  221. package/dist/telemetry/consent.js +0 -40
  222. package/dist/telemetry/consent.js.map +0 -1
  223. package/dist/telemetry/flusher.d.ts +0 -19
  224. package/dist/telemetry/flusher.d.ts.map +0 -1
  225. package/dist/telemetry/flusher.js +0 -277
  226. package/dist/telemetry/flusher.js.map +0 -1
  227. package/dist/telemetry/generation.d.ts +0 -9
  228. package/dist/telemetry/generation.d.ts.map +0 -1
  229. package/dist/telemetry/generation.js +0 -33
  230. package/dist/telemetry/generation.js.map +0 -1
  231. package/dist/telemetry/identity.d.ts +0 -9
  232. package/dist/telemetry/identity.d.ts.map +0 -1
  233. package/dist/telemetry/identity.js +0 -35
  234. package/dist/telemetry/identity.js.map +0 -1
  235. package/dist/telemetry/install-id.d.ts +0 -13
  236. package/dist/telemetry/install-id.d.ts.map +0 -1
  237. package/dist/telemetry/install-id.js +0 -49
  238. package/dist/telemetry/install-id.js.map +0 -1
  239. package/dist/telemetry/install-meta.d.ts +0 -10
  240. package/dist/telemetry/install-meta.d.ts.map +0 -1
  241. package/dist/telemetry/install-meta.js +0 -15
  242. package/dist/telemetry/install-meta.js.map +0 -1
  243. package/dist/telemetry/queue.d.ts +0 -35
  244. package/dist/telemetry/queue.d.ts.map +0 -1
  245. package/dist/telemetry/queue.js +0 -287
  246. package/dist/telemetry/queue.js.map +0 -1
  247. package/dist/telemetry/recorder.d.ts +0 -39
  248. package/dist/telemetry/recorder.d.ts.map +0 -1
  249. package/dist/telemetry/recorder.js +0 -173
  250. package/dist/telemetry/recorder.js.map +0 -1
  251. 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"}