@creezio/observability 0.22.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 (209) hide show
  1. package/README.md +328 -0
  2. package/dist/.creezio-src-hash.json +4 -0
  3. package/dist/api-endpoints/http-routes.d.ts +11 -0
  4. package/dist/api-endpoints/http-routes.d.ts.map +1 -0
  5. package/dist/api-endpoints/http-routes.js +11 -0
  6. package/dist/api-endpoints/http-routes.js.map +1 -0
  7. package/dist/api-endpoints/index.d.ts +4 -0
  8. package/dist/api-endpoints/index.d.ts.map +1 -0
  9. package/dist/api-endpoints/index.js +3 -0
  10. package/dist/api-endpoints/index.js.map +1 -0
  11. package/dist/api-endpoints/registry.d.ts +66 -0
  12. package/dist/api-endpoints/registry.d.ts.map +1 -0
  13. package/dist/api-endpoints/registry.js +102 -0
  14. package/dist/api-endpoints/registry.js.map +1 -0
  15. package/dist/api-mount.d.ts +7 -0
  16. package/dist/api-mount.d.ts.map +1 -0
  17. package/dist/api-mount.js +114 -0
  18. package/dist/api-mount.js.map +1 -0
  19. package/dist/helpers.d.ts +23 -0
  20. package/dist/helpers.d.ts.map +1 -0
  21. package/dist/helpers.js +36 -0
  22. package/dist/helpers.js.map +1 -0
  23. package/dist/index.d.ts +35 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +24 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/memory-store.d.ts +3 -0
  28. package/dist/memory-store.d.ts.map +1 -0
  29. package/dist/memory-store.js +113 -0
  30. package/dist/memory-store.js.map +1 -0
  31. package/dist/ops/emit.d.ts +8 -0
  32. package/dist/ops/emit.d.ts.map +1 -0
  33. package/dist/ops/emit.js +15 -0
  34. package/dist/ops/emit.js.map +1 -0
  35. package/dist/ops/fleet-activity.d.ts +50 -0
  36. package/dist/ops/fleet-activity.d.ts.map +1 -0
  37. package/dist/ops/fleet-activity.js +123 -0
  38. package/dist/ops/fleet-activity.js.map +1 -0
  39. package/dist/ops/fleet-agent.d.ts +102 -0
  40. package/dist/ops/fleet-agent.d.ts.map +1 -0
  41. package/dist/ops/fleet-agent.js +352 -0
  42. package/dist/ops/fleet-agent.js.map +1 -0
  43. package/dist/ops/fleet-samples.d.ts +33 -0
  44. package/dist/ops/fleet-samples.d.ts.map +1 -0
  45. package/dist/ops/fleet-samples.js +223 -0
  46. package/dist/ops/fleet-samples.js.map +1 -0
  47. package/dist/ops/journal.d.ts +56 -0
  48. package/dist/ops/journal.d.ts.map +1 -0
  49. package/dist/ops/journal.js +307 -0
  50. package/dist/ops/journal.js.map +1 -0
  51. package/dist/ops/rules.d.ts +16 -0
  52. package/dist/ops/rules.d.ts.map +1 -0
  53. package/dist/ops/rules.js +98 -0
  54. package/dist/ops/rules.js.map +1 -0
  55. package/dist/ops/types.d.ts +69 -0
  56. package/dist/ops/types.d.ts.map +1 -0
  57. package/dist/ops/types.js +119 -0
  58. package/dist/ops/types.js.map +1 -0
  59. package/dist/request-logs/config.d.ts +19 -0
  60. package/dist/request-logs/config.d.ts.map +1 -0
  61. package/dist/request-logs/config.js +36 -0
  62. package/dist/request-logs/config.js.map +1 -0
  63. package/dist/request-logs/http-routes.d.ts +8 -0
  64. package/dist/request-logs/http-routes.d.ts.map +1 -0
  65. package/dist/request-logs/http-routes.js +29 -0
  66. package/dist/request-logs/http-routes.js.map +1 -0
  67. package/dist/request-logs/index.d.ts +6 -0
  68. package/dist/request-logs/index.d.ts.map +1 -0
  69. package/dist/request-logs/index.js +5 -0
  70. package/dist/request-logs/index.js.map +1 -0
  71. package/dist/request-logs/middleware.d.ts +11 -0
  72. package/dist/request-logs/middleware.d.ts.map +1 -0
  73. package/dist/request-logs/middleware.js +198 -0
  74. package/dist/request-logs/middleware.js.map +1 -0
  75. package/dist/request-logs/request-logs.d.ts +60 -0
  76. package/dist/request-logs/request-logs.d.ts.map +1 -0
  77. package/dist/request-logs/request-logs.js +260 -0
  78. package/dist/request-logs/request-logs.js.map +1 -0
  79. package/dist/schema.d.ts +3 -0
  80. package/dist/schema.d.ts.map +1 -0
  81. package/dist/schema.js +21 -0
  82. package/dist/schema.js.map +1 -0
  83. package/dist/sqlite-driver.d.ts +16 -0
  84. package/dist/sqlite-driver.d.ts.map +1 -0
  85. package/dist/sqlite-driver.js +15 -0
  86. package/dist/sqlite-driver.js.map +1 -0
  87. package/dist/sqlite-store.d.ts +12 -0
  88. package/dist/sqlite-store.d.ts.map +1 -0
  89. package/dist/sqlite-store.js +176 -0
  90. package/dist/sqlite-store.js.map +1 -0
  91. package/dist/types.d.ts +67 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +9 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/usage/adapters.d.ts +31 -0
  96. package/dist/usage/adapters.d.ts.map +1 -0
  97. package/dist/usage/adapters.js +37 -0
  98. package/dist/usage/adapters.js.map +1 -0
  99. package/dist/usage/http-routes.d.ts +23 -0
  100. package/dist/usage/http-routes.d.ts.map +1 -0
  101. package/dist/usage/http-routes.js +150 -0
  102. package/dist/usage/http-routes.js.map +1 -0
  103. package/dist/usage/index.d.ts +11 -0
  104. package/dist/usage/index.d.ts.map +1 -0
  105. package/dist/usage/index.js +7 -0
  106. package/dist/usage/index.js.map +1 -0
  107. package/dist/usage/ui-brand.d.ts +23 -0
  108. package/dist/usage/ui-brand.d.ts.map +1 -0
  109. package/dist/usage/ui-brand.js +18 -0
  110. package/dist/usage/ui-brand.js.map +1 -0
  111. package/dist/usage/usage-analytics-productivity.d.ts +73 -0
  112. package/dist/usage/usage-analytics-productivity.d.ts.map +1 -0
  113. package/dist/usage/usage-analytics-productivity.js +317 -0
  114. package/dist/usage/usage-analytics-productivity.js.map +1 -0
  115. package/dist/usage/usage-analytics-shared.d.ts +5 -0
  116. package/dist/usage/usage-analytics-shared.d.ts.map +1 -0
  117. package/dist/usage/usage-analytics-shared.js +20 -0
  118. package/dist/usage/usage-analytics-shared.js.map +1 -0
  119. package/dist/usage/usage-analytics.d.ts +127 -0
  120. package/dist/usage/usage-analytics.d.ts.map +1 -0
  121. package/dist/usage/usage-analytics.js +338 -0
  122. package/dist/usage/usage-analytics.js.map +1 -0
  123. package/dist-cjs/api-endpoints/http-routes.js +14 -0
  124. package/dist-cjs/api-endpoints/http-routes.js.map +1 -0
  125. package/dist-cjs/api-endpoints/index.js +10 -0
  126. package/dist-cjs/api-endpoints/index.js.map +1 -0
  127. package/dist-cjs/api-endpoints/registry.js +107 -0
  128. package/dist-cjs/api-endpoints/registry.js.map +1 -0
  129. package/dist-cjs/api-mount.js +117 -0
  130. package/dist-cjs/api-mount.js.map +1 -0
  131. package/dist-cjs/helpers.js +41 -0
  132. package/dist-cjs/helpers.js.map +1 -0
  133. package/dist-cjs/index.js +118 -0
  134. package/dist-cjs/index.js.map +1 -0
  135. package/dist-cjs/memory-store.js +119 -0
  136. package/dist-cjs/memory-store.js.map +1 -0
  137. package/dist-cjs/ops/emit.js +18 -0
  138. package/dist-cjs/ops/emit.js.map +1 -0
  139. package/dist-cjs/ops/fleet-activity.js +131 -0
  140. package/dist-cjs/ops/fleet-activity.js.map +1 -0
  141. package/dist-cjs/ops/fleet-agent.js +358 -0
  142. package/dist-cjs/ops/fleet-agent.js.map +1 -0
  143. package/dist-cjs/ops/fleet-samples.js +229 -0
  144. package/dist-cjs/ops/fleet-samples.js.map +1 -0
  145. package/dist-cjs/ops/journal.js +326 -0
  146. package/dist-cjs/ops/journal.js.map +1 -0
  147. package/dist-cjs/ops/rules.js +102 -0
  148. package/dist-cjs/ops/rules.js.map +1 -0
  149. package/dist-cjs/ops/types.js +126 -0
  150. package/dist-cjs/ops/types.js.map +1 -0
  151. package/dist-cjs/package.json +3 -0
  152. package/dist-cjs/request-logs/config.js +42 -0
  153. package/dist-cjs/request-logs/config.js.map +1 -0
  154. package/dist-cjs/request-logs/http-routes.js +32 -0
  155. package/dist-cjs/request-logs/http-routes.js.map +1 -0
  156. package/dist-cjs/request-logs/index.js +27 -0
  157. package/dist-cjs/request-logs/index.js.map +1 -0
  158. package/dist-cjs/request-logs/middleware.js +203 -0
  159. package/dist-cjs/request-logs/middleware.js.map +1 -0
  160. package/dist-cjs/request-logs/request-logs.js +277 -0
  161. package/dist-cjs/request-logs/request-logs.js.map +1 -0
  162. package/dist-cjs/schema.js +24 -0
  163. package/dist-cjs/schema.js.map +1 -0
  164. package/dist-cjs/sqlite-driver.js +18 -0
  165. package/dist-cjs/sqlite-driver.js.map +1 -0
  166. package/dist-cjs/sqlite-store.js +182 -0
  167. package/dist-cjs/sqlite-store.js.map +1 -0
  168. package/dist-cjs/types.js +12 -0
  169. package/dist-cjs/types.js.map +1 -0
  170. package/dist-cjs/usage/adapters.js +47 -0
  171. package/dist-cjs/usage/adapters.js.map +1 -0
  172. package/dist-cjs/usage/http-routes.js +154 -0
  173. package/dist-cjs/usage/http-routes.js.map +1 -0
  174. package/dist-cjs/usage/index.js +34 -0
  175. package/dist-cjs/usage/index.js.map +1 -0
  176. package/dist-cjs/usage/ui-brand.js +23 -0
  177. package/dist-cjs/usage/ui-brand.js.map +1 -0
  178. package/dist-cjs/usage/usage-analytics-productivity.js +321 -0
  179. package/dist-cjs/usage/usage-analytics-productivity.js.map +1 -0
  180. package/dist-cjs/usage/usage-analytics-shared.js +23 -0
  181. package/dist-cjs/usage/usage-analytics-shared.js.map +1 -0
  182. package/dist-cjs/usage/usage-analytics.js +353 -0
  183. package/dist-cjs/usage/usage-analytics.js.map +1 -0
  184. package/fleet-collector/AGENTS.md +7 -0
  185. package/fleet-collector/README.md +83 -0
  186. package/fleet-collector/configure-fleet-npm.sh +108 -0
  187. package/fleet-collector/env.mjs +174 -0
  188. package/fleet-collector/ops-api.mjs +455 -0
  189. package/fleet-collector/public/admin.html +696 -0
  190. package/fleet-collector/public/index.html +941 -0
  191. package/fleet-collector/server.mjs +564 -0
  192. package/fleet-collector/test-fleet-collector.mjs +413 -0
  193. package/fleet-collector/test-server-admin.mjs +475 -0
  194. package/package.json +109 -0
  195. package/scripts/test-api-endpoints-registry.mjs +60 -0
  196. package/ui/analytics-client.tsx +834 -0
  197. package/ui/analytics-productivity-panel.tsx +513 -0
  198. package/ui/api-endpoints-client.tsx +228 -0
  199. package/ui/index.ts +39 -0
  200. package/ui/primitives/badge.tsx +37 -0
  201. package/ui/primitives/button.tsx +44 -0
  202. package/ui/primitives/card.tsx +44 -0
  203. package/ui/primitives/cn.ts +6 -0
  204. package/ui/primitives/input.tsx +19 -0
  205. package/ui/primitives/tabs.tsx +51 -0
  206. package/ui/request-logs-client.tsx +327 -0
  207. package/ui/session-usage-analytics-provider.tsx +28 -0
  208. package/ui/usage-analytics-client.ts +479 -0
  209. package/ui/usage-analytics-provider.tsx +84 -0
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+ /**
3
+ * Boîte noire desktop — journal d'événements structurés (JSONL / boot).
4
+ * Extrait de TempoFlow ops-journal.ts (R4). Hooks marque pour log + anomaly.
5
+ *
6
+ * Best-effort intégral : le journal ne doit JAMAIS être une source de crash.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.setOpsJournalHooks = setOpsJournalHooks;
13
+ exports.getOpsBootId = getOpsBootId;
14
+ exports.getOpsDir = getOpsDir;
15
+ exports.initOpsJournal = initOpsJournal;
16
+ exports.track = track;
17
+ exports.trackDecision = trackDecision;
18
+ exports.trackCrashMirror = trackCrashMirror;
19
+ exports.consumeOpsLine = consumeOpsLine;
20
+ exports.trackExternal = trackExternal;
21
+ exports.drainPendingOpsEvents = drainPendingOpsEvents;
22
+ exports.currentBootSummary = currentBootSummary;
23
+ exports.persistBootSummary = persistBootSummary;
24
+ exports.readPreviousBootSummaries = readPreviousBootSummaries;
25
+ exports.__resetOpsJournalForTests = __resetOpsJournalForTests;
26
+ const node_fs_1 = __importDefault(require("node:fs"));
27
+ const node_path_1 = __importDefault(require("node:path"));
28
+ const node_crypto_1 = __importDefault(require("node:crypto"));
29
+ const types_js_1 = require("./types.js");
30
+ const OPS_KEEP_FILES = 30;
31
+ const OPS_MAX_TOTAL_BYTES = 100 * 1024 * 1024;
32
+ const INDEX_MAX_BOOTS = 60;
33
+ const PENDING_MAX = 500;
34
+ let hooks = {};
35
+ let opsDir = null;
36
+ let bootId = "";
37
+ let bootStartedAt = "";
38
+ let appVersion = "0.0.0";
39
+ let seq = 0;
40
+ const pending = [];
41
+ const counts = {};
42
+ const decisions = {};
43
+ const durations = {};
44
+ function setOpsJournalHooks(next) {
45
+ hooks = next || {};
46
+ }
47
+ function getOpsBootId() {
48
+ return bootId;
49
+ }
50
+ function getOpsDir() {
51
+ return opsDir;
52
+ }
53
+ function bootFile() {
54
+ return opsDir && bootId ? node_path_1.default.join(opsDir, `${bootId}.jsonl`) : null;
55
+ }
56
+ function indexFile() {
57
+ return opsDir ? node_path_1.default.join(opsDir, "index.json") : null;
58
+ }
59
+ /** Purge rétention : garde les OPS_KEEP_FILES plus récents / plafond octets. */
60
+ function pruneOldBootFiles() {
61
+ if (!opsDir)
62
+ return;
63
+ try {
64
+ const files = node_fs_1.default
65
+ .readdirSync(opsDir)
66
+ .filter((f) => f.endsWith(".jsonl"))
67
+ .map((f) => {
68
+ const full = node_path_1.default.join(opsDir, f);
69
+ try {
70
+ const st = node_fs_1.default.statSync(full);
71
+ return { full, mtime: st.mtimeMs, size: st.size };
72
+ }
73
+ catch {
74
+ return { full, mtime: 0, size: 0 };
75
+ }
76
+ })
77
+ .sort((a, b) => b.mtime - a.mtime);
78
+ let total = 0;
79
+ files.forEach((f, i) => {
80
+ total += f.size;
81
+ if (i >= OPS_KEEP_FILES || total > OPS_MAX_TOTAL_BYTES) {
82
+ try {
83
+ node_fs_1.default.unlinkSync(f.full);
84
+ }
85
+ catch {
86
+ /* best-effort */
87
+ }
88
+ }
89
+ });
90
+ }
91
+ catch {
92
+ /* best-effort */
93
+ }
94
+ }
95
+ /** À appeler tôt (après initLogger) avec le dossier userData. */
96
+ function initOpsJournal(userDataDir, version, nextHooks) {
97
+ try {
98
+ if (nextHooks)
99
+ hooks = nextHooks;
100
+ appVersion = version;
101
+ opsDir = node_path_1.default.join(userDataDir, "ops");
102
+ node_fs_1.default.mkdirSync(opsDir, { recursive: true });
103
+ bootId = node_crypto_1.default.randomUUID();
104
+ bootStartedAt = new Date().toISOString();
105
+ seq = 0;
106
+ pending.length = 0;
107
+ for (const k of Object.keys(counts))
108
+ delete counts[k];
109
+ for (const k of Object.keys(decisions))
110
+ delete decisions[k];
111
+ for (const k of Object.keys(durations))
112
+ delete durations[k];
113
+ pruneOldBootFiles();
114
+ }
115
+ catch {
116
+ opsDir = null;
117
+ }
118
+ }
119
+ /**
120
+ * Enregistre un événement : JSONL local + file flotte + miroir log texte.
121
+ * `source` défaut "main". Jamais de throw.
122
+ */
123
+ function track(input) {
124
+ try {
125
+ const evt = {
126
+ ...input,
127
+ ctx: input.ctx
128
+ ? (0, types_js_1.redactOpsCtx)(input.ctx)
129
+ : undefined,
130
+ source: input.source || "main",
131
+ ts: new Date().toISOString(),
132
+ bootId,
133
+ seq: seq++,
134
+ };
135
+ counts[evt.level] = (counts[evt.level] || 0) + 1;
136
+ if (evt.level === "decision") {
137
+ decisions[evt.kind] = { outcome: evt.outcome, reason: evt.reason };
138
+ }
139
+ if (evt.durationMs != null) {
140
+ durations[evt.kind] = Math.max(durations[evt.kind] || 0, evt.durationMs);
141
+ }
142
+ const line = (0, types_js_1.serializeOpsEvent)(evt);
143
+ const file = bootFile();
144
+ if (file) {
145
+ try {
146
+ node_fs_1.default.appendFileSync(file, line + "\n");
147
+ }
148
+ catch {
149
+ /* disque plein / permissions */
150
+ }
151
+ }
152
+ pending.push(evt);
153
+ if (pending.length > PENDING_MAX)
154
+ pending.shift();
155
+ try {
156
+ hooks.log?.("ops", `${evt.level} ${evt.kind}` +
157
+ (evt.outcome ? ` outcome=${evt.outcome}` : "") +
158
+ (evt.reason ? ` reason=${evt.reason}` : "") +
159
+ (evt.durationMs != null ? ` ${evt.durationMs}ms` : ""));
160
+ }
161
+ catch {
162
+ /* best-effort */
163
+ }
164
+ if (evt.level === "anomaly") {
165
+ try {
166
+ hooks.onAnomaly?.(evt);
167
+ }
168
+ catch {
169
+ /* best-effort */
170
+ }
171
+ }
172
+ }
173
+ catch {
174
+ /* best-effort */
175
+ }
176
+ }
177
+ /** Décision : sucre pour les gates. */
178
+ function trackDecision(kind, outcome, opts) {
179
+ track({ level: "decision", kind, outcome, ...opts });
180
+ }
181
+ /**
182
+ * Miroir des crashes (appelé par crash-reporter via import dynamique).
183
+ * Journal uniquement — PAS de re-déclenchement reportCrash.
184
+ */
185
+ function trackCrashMirror(kind, detail) {
186
+ try {
187
+ const evt = {
188
+ level: "crash",
189
+ kind: `crash.${kind}`,
190
+ source: "main",
191
+ reason: typeof detail.message === "string"
192
+ ? detail.message.slice(0, 300)
193
+ : undefined,
194
+ ctx: (0, types_js_1.redactOpsCtx)({
195
+ child: detail.child,
196
+ code: detail.code,
197
+ step: detail.step,
198
+ }),
199
+ ts: new Date().toISOString(),
200
+ bootId,
201
+ seq: seq++,
202
+ };
203
+ counts.crash = (counts.crash || 0) + 1;
204
+ const file = bootFile();
205
+ if (file)
206
+ node_fs_1.default.appendFileSync(file, (0, types_js_1.serializeOpsEvent)(evt) + "\n");
207
+ pending.push(evt);
208
+ if (pending.length > PENDING_MAX)
209
+ pending.shift();
210
+ }
211
+ catch {
212
+ /* best-effort */
213
+ }
214
+ }
215
+ /**
216
+ * Ligne stdout d'un sous-process : consommée si `TF2EVENT {json}`.
217
+ * Renvoie true si la ligne était un événement (à ne pas logger en texte).
218
+ */
219
+ function consumeOpsLine(source, line) {
220
+ try {
221
+ const input = (0, types_js_1.parseOpsLine)(line);
222
+ if (!input)
223
+ return false;
224
+ track({ ...input, source: input.source || source });
225
+ return true;
226
+ }
227
+ catch {
228
+ return false;
229
+ }
230
+ }
231
+ /** Événement venant d'un canal non fiable (IPC renderer) : sanitizé. */
232
+ function trackExternal(raw, source) {
233
+ const input = (0, types_js_1.sanitizeOpsEventInput)(raw);
234
+ if (!input)
235
+ return false;
236
+ // Le renderer ne peut pas émettre de crash/anomaly (anti-spam canal always-on).
237
+ if (input.level === "crash" || input.level === "anomaly") {
238
+ input.level = "error";
239
+ }
240
+ track({ ...input, source });
241
+ return true;
242
+ }
243
+ /** Drain de la file pour l'agent flotte (bundle kind=ops_events). */
244
+ function drainPendingOpsEvents(max = 100) {
245
+ const out = pending.slice(0, max);
246
+ pending.splice(0, out.length);
247
+ return out;
248
+ }
249
+ /** Résumé du boot courant (index.json + heartbeat flotte). */
250
+ function currentBootSummary() {
251
+ const summary = {
252
+ bootId,
253
+ startedAt: bootStartedAt,
254
+ appVersion,
255
+ counts: { ...counts },
256
+ decisions: { ...decisions },
257
+ durations: { ...durations },
258
+ };
259
+ return summary;
260
+ }
261
+ /** Écrit / met à jour le résumé du boot courant dans ops/index.json. */
262
+ function persistBootSummary(extra) {
263
+ const file = indexFile();
264
+ if (!file)
265
+ return;
266
+ try {
267
+ let boots = [];
268
+ try {
269
+ const raw = JSON.parse(node_fs_1.default.readFileSync(file, "utf8"));
270
+ if (Array.isArray(raw.boots))
271
+ boots = raw.boots;
272
+ }
273
+ catch {
274
+ /* premier boot */
275
+ }
276
+ const summary = { ...currentBootSummary(), ...extra };
277
+ const idx = boots.findIndex((b) => b.bootId === bootId);
278
+ if (idx >= 0)
279
+ boots[idx] = summary;
280
+ else
281
+ boots.push(summary);
282
+ if (boots.length > INDEX_MAX_BOOTS)
283
+ boots = boots.slice(-INDEX_MAX_BOOTS);
284
+ const tmp = `${file}.tmp`;
285
+ node_fs_1.default.writeFileSync(tmp, JSON.stringify({ boots }, null, 1));
286
+ node_fs_1.default.renameSync(tmp, file);
287
+ }
288
+ catch {
289
+ /* best-effort */
290
+ }
291
+ }
292
+ /** Résumés des boots précédents (le courant exclu), du plus récent au plus ancien. */
293
+ function readPreviousBootSummaries(limit = 10) {
294
+ const file = indexFile();
295
+ if (!file)
296
+ return [];
297
+ try {
298
+ const raw = JSON.parse(node_fs_1.default.readFileSync(file, "utf8"));
299
+ if (!Array.isArray(raw.boots))
300
+ return [];
301
+ return raw.boots
302
+ .filter((b) => b.bootId !== bootId)
303
+ .sort((a, b) => String(b.startedAt).localeCompare(String(a.startedAt)))
304
+ .slice(0, limit);
305
+ }
306
+ catch {
307
+ return [];
308
+ }
309
+ }
310
+ /** Tests : reset état module. */
311
+ function __resetOpsJournalForTests() {
312
+ hooks = {};
313
+ opsDir = null;
314
+ bootId = "";
315
+ bootStartedAt = "";
316
+ appVersion = "0.0.0";
317
+ seq = 0;
318
+ pending.length = 0;
319
+ for (const k of Object.keys(counts))
320
+ delete counts[k];
321
+ for (const k of Object.keys(decisions))
322
+ delete decisions[k];
323
+ for (const k of Object.keys(durations))
324
+ delete durations[k];
325
+ }
326
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/ops/journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Boîte noire — moteur d'anomalies générique.
4
+ * Extrait de TempoFlow ops-rules.ts (R4).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.evaluateRulesPure = evaluateRulesPure;
8
+ exports.evaluateBootRules = evaluateBootRules;
9
+ const journal_js_1 = require("./journal.js");
10
+ /**
11
+ * Règle 1 — décision négative répétée : si la MÊME décision négative est
12
+ * prise à N boots consécutifs, quelque chose ne s'auto-répare pas.
13
+ */
14
+ const NEGATIVE_OUTCOMES = {
15
+ "meili.ready": ["full-reindex", "skip-no-meili"],
16
+ "meili.start": ["unavailable"],
17
+ "tunnel.connect": ["error"],
18
+ };
19
+ const REPEAT_BOOTS = 2;
20
+ /** Règle 2 — durée anormale par kind (ms). */
21
+ const DURATION_THRESHOLDS_MS = {
22
+ "boot.done": 8 * 60_000,
23
+ "index.run": 10 * 60_000,
24
+ "migrations.done": 3 * 60_000,
25
+ "catalog.ensure": 30 * 60_000,
26
+ };
27
+ /** Règle 3 — erreurs récurrentes dans un même boot. */
28
+ const ERROR_COUNT_THRESHOLD = 10;
29
+ function isNegative(kind, outcome) {
30
+ if (!outcome)
31
+ return false;
32
+ return (NEGATIVE_OUTCOMES[kind] || []).includes(outcome);
33
+ }
34
+ /** Pure — testable sans I/O. */
35
+ function evaluateRulesPure(current, previous) {
36
+ const findings = [];
37
+ for (const [kind, d] of Object.entries(current.decisions || {})) {
38
+ if (!isNegative(kind, d.outcome))
39
+ continue;
40
+ let consecutive = 1;
41
+ for (const prev of previous) {
42
+ const pd = prev.decisions?.[kind];
43
+ if (pd && isNegative(kind, pd.outcome))
44
+ consecutive++;
45
+ else
46
+ break;
47
+ }
48
+ if (consecutive >= REPEAT_BOOTS) {
49
+ findings.push({
50
+ rule: "repeated-negative-decision",
51
+ kind,
52
+ detail: `${kind} outcome=${d.outcome} sur ${consecutive} boots consécutifs (reason=${d.reason || "?"})`,
53
+ ctx: {
54
+ outcome: d.outcome,
55
+ reason: d.reason,
56
+ consecutiveBoots: consecutive,
57
+ },
58
+ });
59
+ }
60
+ }
61
+ for (const [kind, threshold] of Object.entries(DURATION_THRESHOLDS_MS)) {
62
+ const observed = current.durations?.[kind];
63
+ if (observed != null && observed > threshold) {
64
+ findings.push({
65
+ rule: "duration-over-threshold",
66
+ kind,
67
+ detail: `${kind} a duré ${Math.round(observed / 1000)}s (seuil ${Math.round(threshold / 1000)}s)`,
68
+ ctx: { durationMs: observed, thresholdMs: threshold },
69
+ });
70
+ }
71
+ }
72
+ const errorCount = (current.counts?.error || 0) + (current.counts?.crash || 0);
73
+ if (errorCount >= ERROR_COUNT_THRESHOLD) {
74
+ findings.push({
75
+ rule: "recurring-errors",
76
+ kind: "boot.errors",
77
+ detail: `${errorCount} erreurs/crashes pendant le boot`,
78
+ ctx: { errorCount },
79
+ });
80
+ }
81
+ return findings;
82
+ }
83
+ /** À appeler en fin de boot (après persistBootSummary). Jamais de throw. */
84
+ function evaluateBootRules() {
85
+ try {
86
+ const findings = evaluateRulesPure((0, journal_js_1.currentBootSummary)(), (0, journal_js_1.readPreviousBootSummaries)(REPEAT_BOOTS + 2));
87
+ for (const f of findings) {
88
+ (0, journal_js_1.track)({
89
+ level: "anomaly",
90
+ kind: `anomaly.${f.rule}`,
91
+ outcome: f.kind,
92
+ reason: f.detail,
93
+ ctx: f.ctx,
94
+ });
95
+ }
96
+ return findings;
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ }
102
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/ops/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * Boîte noire desktop — types + helpers PURS (aucun import Electron).
4
+ * Contrat JSONL ops (R4 / P29) — préfixe d'émission historique `TF2EVENT`
5
+ * conservé (wire sous-process Electron ×3). Lecture = dual-read via
6
+ * `OPS_EVENT_PREFIXES` ; ne pas retirer `TF2EVENT` sans cutover marques.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.MAX_CTX_BYTES = exports.OPS_LEVELS = exports.OPS_EVENT_PREFIXES = exports.OPS_EVENT_PREFIX = exports.TF2EVENT_PREFIX = void 0;
10
+ exports.redactOpsCtx = redactOpsCtx;
11
+ exports.sanitizeOpsEventInput = sanitizeOpsEventInput;
12
+ exports.serializeOpsEvent = serializeOpsEvent;
13
+ exports.parseOpsLine = parseOpsLine;
14
+ exports.TF2EVENT_PREFIX = "TF2EVENT ";
15
+ /** Alias générique — même valeur que `TF2EVENT_PREFIX` (émission). */
16
+ exports.OPS_EVENT_PREFIX = exports.TF2EVENT_PREFIX;
17
+ /**
18
+ * Préfixes stdout acceptés en lecture (M7p / P29) :
19
+ * - émission SoT = `TF2EVENT`
20
+ * - `CertivanEVENT` = dual-read legacy marques (ne pas casser)
21
+ */
22
+ exports.OPS_EVENT_PREFIXES = [
23
+ exports.TF2EVENT_PREFIX,
24
+ "CertivanEVENT ",
25
+ ];
26
+ exports.OPS_LEVELS = [
27
+ "decision",
28
+ "event",
29
+ "anomaly",
30
+ "error",
31
+ "crash",
32
+ ];
33
+ /** Taille max du ctx sérialisé (au-delà : tronqué avec marqueur). */
34
+ exports.MAX_CTX_BYTES = 4096;
35
+ const SECRET_KEY_RE = /token|secret|password|passwd|api[-_]?key|jwt|auth|bearer|cookie|master[-_]?key/i;
36
+ const SECRET_VALUE_RE = /(sk-[A-Za-z0-9_-]{10,}|tf2_live_[A-Za-z0-9_-]+|eyJ[A-Za-z0-9_-]{20,}|Bearer\s+[A-Za-z0-9._-]{10,})/g;
37
+ /** Redaction récursive : clés sensibles masquées, motifs secrets dans les strings. */
38
+ function redactOpsCtx(value, depth = 0) {
39
+ if (depth > 6)
40
+ return "[depth]";
41
+ if (typeof value === "string") {
42
+ return value.replace(SECRET_VALUE_RE, "[redacted]").slice(0, 800);
43
+ }
44
+ if (typeof value === "number" || typeof value === "boolean" || value === null) {
45
+ return value;
46
+ }
47
+ if (Array.isArray(value)) {
48
+ return value.slice(0, 50).map((v) => redactOpsCtx(v, depth + 1));
49
+ }
50
+ if (typeof value === "object" && value !== undefined) {
51
+ const out = {};
52
+ for (const [k, v] of Object.entries(value)) {
53
+ out[k] = SECRET_KEY_RE.test(k) ? "[redacted]" : redactOpsCtx(v, depth + 1);
54
+ }
55
+ return out;
56
+ }
57
+ return value === undefined ? undefined : String(value);
58
+ }
59
+ /** Valide + normalise un input (renvoie null si inutilisable). */
60
+ function sanitizeOpsEventInput(raw) {
61
+ if (!raw || typeof raw !== "object")
62
+ return null;
63
+ const o = raw;
64
+ const level = exports.OPS_LEVELS.includes(o.level)
65
+ ? o.level
66
+ : null;
67
+ const kind = typeof o.kind === "string" && /^[a-z0-9_-]+\.[a-z0-9._-]+$/i.test(o.kind)
68
+ ? o.kind.slice(0, 80)
69
+ : null;
70
+ if (!level || !kind)
71
+ return null;
72
+ const evt = { level, kind };
73
+ if (typeof o.source === "string")
74
+ evt.source = o.source.slice(0, 40);
75
+ if (typeof o.outcome === "string")
76
+ evt.outcome = o.outcome.slice(0, 120);
77
+ if (typeof o.reason === "string")
78
+ evt.reason = o.reason.slice(0, 300);
79
+ if (typeof o.durationMs === "number" && Number.isFinite(o.durationMs)) {
80
+ evt.durationMs = Math.max(0, Math.round(o.durationMs));
81
+ }
82
+ if (o.ctx && typeof o.ctx === "object" && !Array.isArray(o.ctx)) {
83
+ evt.ctx = redactOpsCtx(o.ctx);
84
+ }
85
+ return evt;
86
+ }
87
+ /** Sérialise en plafonnant le ctx (jamais de throw). */
88
+ function serializeOpsEvent(evt) {
89
+ try {
90
+ let line = JSON.stringify(evt);
91
+ if (evt.ctx && Buffer.byteLength(line, "utf8") > exports.MAX_CTX_BYTES + 1024) {
92
+ line = JSON.stringify({ ...evt, ctx: { _truncated: true } });
93
+ }
94
+ return line;
95
+ }
96
+ catch {
97
+ return JSON.stringify({
98
+ ts: evt.ts,
99
+ bootId: evt.bootId,
100
+ seq: evt.seq,
101
+ source: evt.source,
102
+ level: evt.level,
103
+ kind: evt.kind,
104
+ reason: "serialize-error",
105
+ });
106
+ }
107
+ }
108
+ /**
109
+ * Parse une ligne stdout d'un sous-process.
110
+ * Renvoie l'input si la ligne est un TF2EVENT valide, sinon null.
111
+ */
112
+ function parseOpsLine(line) {
113
+ const trimmed = line.trim();
114
+ for (const prefix of exports.OPS_EVENT_PREFIXES) {
115
+ if (!trimmed.startsWith(prefix))
116
+ continue;
117
+ try {
118
+ return sanitizeOpsEventInput(JSON.parse(trimmed.slice(prefix.length)));
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ return null;
125
+ }
126
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ops/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Injection host pour request-logs (évite imports `@/` marque).
4
+ * O5 — noyau générique kit.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.configureRequestLogs = configureRequestLogs;
8
+ exports.getRequestLogsConfig = getRequestLogsConfig;
9
+ exports.resetRequestLogsConfigForTests = resetRequestLogsConfigForTests;
10
+ exports.resolveFleetStateDir = resolveFleetStateDir;
11
+ let config = {};
12
+ function configureRequestLogs(next) {
13
+ config = next ?? {};
14
+ }
15
+ function getRequestLogsConfig() {
16
+ return config;
17
+ }
18
+ function resetRequestLogsConfigForTests() {
19
+ config = {};
20
+ }
21
+ const FLEET_STATE_DIR_SUFFIX = "_FLEET_STATE_DIR";
22
+ /** Résout le dir miroir (config marque, env générique, ou envKey manifest). */
23
+ function resolveFleetStateDir() {
24
+ const custom = config.getFleetStateDir?.();
25
+ if (custom)
26
+ return custom;
27
+ const generic = process.env.CREEZIO_FLEET_STATE_DIR;
28
+ if (generic)
29
+ return generic;
30
+ // Dérivation manifest/envKey : le host pose `${envPrefix}_FLEET_STATE_DIR`
31
+ // (préfixe issu du manifest marque) — on accepte n'importe quel préfixe,
32
+ // ce qui couvre aussi les préfixes legacy sans les câbler ici.
33
+ for (const [key, value] of Object.entries(process.env)) {
34
+ if (value &&
35
+ key.endsWith(FLEET_STATE_DIR_SUFFIX) &&
36
+ key !== "CREEZIO_FLEET_STATE_DIR") {
37
+ return value;
38
+ }
39
+ }
40
+ return undefined;
41
+ }
42
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/request-logs/config.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAcH,oDAEC;AAED,oDAEC;AAED,wEAEC;AAKD,oDAkBC;AAnCD,IAAI,MAAM,GAAsB,EAAE,CAAC;AAEnC,SAAgB,oBAAoB,CAAC,IAAuB;IAC1D,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAgB,oBAAoB;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,8BAA8B;IAC5C,MAAM,GAAG,EAAE,CAAC;AACd,CAAC;AAED,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAElD,+EAA+E;AAC/E,SAAgB,oBAAoB;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC;IAC3C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IACpD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,yEAAyE;IACzE,+DAA+D;IAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,IACE,KAAK;YACL,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YACpC,GAAG,KAAK,yBAAyB,EACjC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRequestLogsRoutes = createRequestLogsRoutes;
4
+ /**
5
+ * Admin — lecture / purge des logs API + MCP (session UI).
6
+ * Hono « nu » : hors doc OpenAPI publique.
7
+ * O5 — extrait TempoFlow (gold). Auth owner reste côté marque (montage).
8
+ */
9
+ const hono_1 = require("hono");
10
+ const request_logs_js_1 = require("./request-logs.js");
11
+ function createRequestLogsRoutes() {
12
+ const app = new hono_1.Hono();
13
+ app.get("/request-logs", (c) => {
14
+ const limit = Number(c.req.query("limit")) || 100;
15
+ const sourceRaw = (c.req.query("source") || "all").toLowerCase();
16
+ const source = sourceRaw === "mcp" || sourceRaw === "api"
17
+ ? sourceRaw
18
+ : "all";
19
+ const q = c.req.query("q") || undefined;
20
+ const errorsOnly = c.req.query("errorsOnly") === "1" ||
21
+ c.req.query("errorsOnly") === "true" ||
22
+ c.req.query("errors") === "1";
23
+ const result = (0, request_logs_js_1.listRequestLogs)({ limit, source, q, errorsOnly });
24
+ return c.json(result);
25
+ });
26
+ app.delete("/request-logs", (c) => {
27
+ const { cleared } = (0, request_logs_js_1.clearRequestLogs)();
28
+ return c.json({ ok: true, cleared });
29
+ });
30
+ return app;
31
+ }
32
+ //# sourceMappingURL=http-routes.js.map