@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.
- package/README.md +328 -0
- package/dist/.creezio-src-hash.json +4 -0
- package/dist/api-endpoints/http-routes.d.ts +11 -0
- package/dist/api-endpoints/http-routes.d.ts.map +1 -0
- package/dist/api-endpoints/http-routes.js +11 -0
- package/dist/api-endpoints/http-routes.js.map +1 -0
- package/dist/api-endpoints/index.d.ts +4 -0
- package/dist/api-endpoints/index.d.ts.map +1 -0
- package/dist/api-endpoints/index.js +3 -0
- package/dist/api-endpoints/index.js.map +1 -0
- package/dist/api-endpoints/registry.d.ts +66 -0
- package/dist/api-endpoints/registry.d.ts.map +1 -0
- package/dist/api-endpoints/registry.js +102 -0
- package/dist/api-endpoints/registry.js.map +1 -0
- package/dist/api-mount.d.ts +7 -0
- package/dist/api-mount.d.ts.map +1 -0
- package/dist/api-mount.js +114 -0
- package/dist/api-mount.js.map +1 -0
- package/dist/helpers.d.ts +23 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +36 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/memory-store.d.ts +3 -0
- package/dist/memory-store.d.ts.map +1 -0
- package/dist/memory-store.js +113 -0
- package/dist/memory-store.js.map +1 -0
- package/dist/ops/emit.d.ts +8 -0
- package/dist/ops/emit.d.ts.map +1 -0
- package/dist/ops/emit.js +15 -0
- package/dist/ops/emit.js.map +1 -0
- package/dist/ops/fleet-activity.d.ts +50 -0
- package/dist/ops/fleet-activity.d.ts.map +1 -0
- package/dist/ops/fleet-activity.js +123 -0
- package/dist/ops/fleet-activity.js.map +1 -0
- package/dist/ops/fleet-agent.d.ts +102 -0
- package/dist/ops/fleet-agent.d.ts.map +1 -0
- package/dist/ops/fleet-agent.js +352 -0
- package/dist/ops/fleet-agent.js.map +1 -0
- package/dist/ops/fleet-samples.d.ts +33 -0
- package/dist/ops/fleet-samples.d.ts.map +1 -0
- package/dist/ops/fleet-samples.js +223 -0
- package/dist/ops/fleet-samples.js.map +1 -0
- package/dist/ops/journal.d.ts +56 -0
- package/dist/ops/journal.d.ts.map +1 -0
- package/dist/ops/journal.js +307 -0
- package/dist/ops/journal.js.map +1 -0
- package/dist/ops/rules.d.ts +16 -0
- package/dist/ops/rules.d.ts.map +1 -0
- package/dist/ops/rules.js +98 -0
- package/dist/ops/rules.js.map +1 -0
- package/dist/ops/types.d.ts +69 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +119 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/request-logs/config.d.ts +19 -0
- package/dist/request-logs/config.d.ts.map +1 -0
- package/dist/request-logs/config.js +36 -0
- package/dist/request-logs/config.js.map +1 -0
- package/dist/request-logs/http-routes.d.ts +8 -0
- package/dist/request-logs/http-routes.d.ts.map +1 -0
- package/dist/request-logs/http-routes.js +29 -0
- package/dist/request-logs/http-routes.js.map +1 -0
- package/dist/request-logs/index.d.ts +6 -0
- package/dist/request-logs/index.d.ts.map +1 -0
- package/dist/request-logs/index.js +5 -0
- package/dist/request-logs/index.js.map +1 -0
- package/dist/request-logs/middleware.d.ts +11 -0
- package/dist/request-logs/middleware.d.ts.map +1 -0
- package/dist/request-logs/middleware.js +198 -0
- package/dist/request-logs/middleware.js.map +1 -0
- package/dist/request-logs/request-logs.d.ts +60 -0
- package/dist/request-logs/request-logs.d.ts.map +1 -0
- package/dist/request-logs/request-logs.js +260 -0
- package/dist/request-logs/request-logs.js.map +1 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +21 -0
- package/dist/schema.js.map +1 -0
- package/dist/sqlite-driver.d.ts +16 -0
- package/dist/sqlite-driver.d.ts.map +1 -0
- package/dist/sqlite-driver.js +15 -0
- package/dist/sqlite-driver.js.map +1 -0
- package/dist/sqlite-store.d.ts +12 -0
- package/dist/sqlite-store.d.ts.map +1 -0
- package/dist/sqlite-store.js +176 -0
- package/dist/sqlite-store.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/usage/adapters.d.ts +31 -0
- package/dist/usage/adapters.d.ts.map +1 -0
- package/dist/usage/adapters.js +37 -0
- package/dist/usage/adapters.js.map +1 -0
- package/dist/usage/http-routes.d.ts +23 -0
- package/dist/usage/http-routes.d.ts.map +1 -0
- package/dist/usage/http-routes.js +150 -0
- package/dist/usage/http-routes.js.map +1 -0
- package/dist/usage/index.d.ts +11 -0
- package/dist/usage/index.d.ts.map +1 -0
- package/dist/usage/index.js +7 -0
- package/dist/usage/index.js.map +1 -0
- package/dist/usage/ui-brand.d.ts +23 -0
- package/dist/usage/ui-brand.d.ts.map +1 -0
- package/dist/usage/ui-brand.js +18 -0
- package/dist/usage/ui-brand.js.map +1 -0
- package/dist/usage/usage-analytics-productivity.d.ts +73 -0
- package/dist/usage/usage-analytics-productivity.d.ts.map +1 -0
- package/dist/usage/usage-analytics-productivity.js +317 -0
- package/dist/usage/usage-analytics-productivity.js.map +1 -0
- package/dist/usage/usage-analytics-shared.d.ts +5 -0
- package/dist/usage/usage-analytics-shared.d.ts.map +1 -0
- package/dist/usage/usage-analytics-shared.js +20 -0
- package/dist/usage/usage-analytics-shared.js.map +1 -0
- package/dist/usage/usage-analytics.d.ts +127 -0
- package/dist/usage/usage-analytics.d.ts.map +1 -0
- package/dist/usage/usage-analytics.js +338 -0
- package/dist/usage/usage-analytics.js.map +1 -0
- package/dist-cjs/api-endpoints/http-routes.js +14 -0
- package/dist-cjs/api-endpoints/http-routes.js.map +1 -0
- package/dist-cjs/api-endpoints/index.js +10 -0
- package/dist-cjs/api-endpoints/index.js.map +1 -0
- package/dist-cjs/api-endpoints/registry.js +107 -0
- package/dist-cjs/api-endpoints/registry.js.map +1 -0
- package/dist-cjs/api-mount.js +117 -0
- package/dist-cjs/api-mount.js.map +1 -0
- package/dist-cjs/helpers.js +41 -0
- package/dist-cjs/helpers.js.map +1 -0
- package/dist-cjs/index.js +118 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/memory-store.js +119 -0
- package/dist-cjs/memory-store.js.map +1 -0
- package/dist-cjs/ops/emit.js +18 -0
- package/dist-cjs/ops/emit.js.map +1 -0
- package/dist-cjs/ops/fleet-activity.js +131 -0
- package/dist-cjs/ops/fleet-activity.js.map +1 -0
- package/dist-cjs/ops/fleet-agent.js +358 -0
- package/dist-cjs/ops/fleet-agent.js.map +1 -0
- package/dist-cjs/ops/fleet-samples.js +229 -0
- package/dist-cjs/ops/fleet-samples.js.map +1 -0
- package/dist-cjs/ops/journal.js +326 -0
- package/dist-cjs/ops/journal.js.map +1 -0
- package/dist-cjs/ops/rules.js +102 -0
- package/dist-cjs/ops/rules.js.map +1 -0
- package/dist-cjs/ops/types.js +126 -0
- package/dist-cjs/ops/types.js.map +1 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/request-logs/config.js +42 -0
- package/dist-cjs/request-logs/config.js.map +1 -0
- package/dist-cjs/request-logs/http-routes.js +32 -0
- package/dist-cjs/request-logs/http-routes.js.map +1 -0
- package/dist-cjs/request-logs/index.js +27 -0
- package/dist-cjs/request-logs/index.js.map +1 -0
- package/dist-cjs/request-logs/middleware.js +203 -0
- package/dist-cjs/request-logs/middleware.js.map +1 -0
- package/dist-cjs/request-logs/request-logs.js +277 -0
- package/dist-cjs/request-logs/request-logs.js.map +1 -0
- package/dist-cjs/schema.js +24 -0
- package/dist-cjs/schema.js.map +1 -0
- package/dist-cjs/sqlite-driver.js +18 -0
- package/dist-cjs/sqlite-driver.js.map +1 -0
- package/dist-cjs/sqlite-store.js +182 -0
- package/dist-cjs/sqlite-store.js.map +1 -0
- package/dist-cjs/types.js +12 -0
- package/dist-cjs/types.js.map +1 -0
- package/dist-cjs/usage/adapters.js +47 -0
- package/dist-cjs/usage/adapters.js.map +1 -0
- package/dist-cjs/usage/http-routes.js +154 -0
- package/dist-cjs/usage/http-routes.js.map +1 -0
- package/dist-cjs/usage/index.js +34 -0
- package/dist-cjs/usage/index.js.map +1 -0
- package/dist-cjs/usage/ui-brand.js +23 -0
- package/dist-cjs/usage/ui-brand.js.map +1 -0
- package/dist-cjs/usage/usage-analytics-productivity.js +321 -0
- package/dist-cjs/usage/usage-analytics-productivity.js.map +1 -0
- package/dist-cjs/usage/usage-analytics-shared.js +23 -0
- package/dist-cjs/usage/usage-analytics-shared.js.map +1 -0
- package/dist-cjs/usage/usage-analytics.js +353 -0
- package/dist-cjs/usage/usage-analytics.js.map +1 -0
- package/fleet-collector/AGENTS.md +7 -0
- package/fleet-collector/README.md +83 -0
- package/fleet-collector/configure-fleet-npm.sh +108 -0
- package/fleet-collector/env.mjs +174 -0
- package/fleet-collector/ops-api.mjs +455 -0
- package/fleet-collector/public/admin.html +696 -0
- package/fleet-collector/public/index.html +941 -0
- package/fleet-collector/server.mjs +564 -0
- package/fleet-collector/test-fleet-collector.mjs +413 -0
- package/fleet-collector/test-server-admin.mjs +475 -0
- package/package.json +109 -0
- package/scripts/test-api-endpoints-registry.mjs +60 -0
- package/ui/analytics-client.tsx +834 -0
- package/ui/analytics-productivity-panel.tsx +513 -0
- package/ui/api-endpoints-client.tsx +228 -0
- package/ui/index.ts +39 -0
- package/ui/primitives/badge.tsx +37 -0
- package/ui/primitives/button.tsx +44 -0
- package/ui/primitives/card.tsx +44 -0
- package/ui/primitives/cn.ts +6 -0
- package/ui/primitives/input.tsx +19 -0
- package/ui/primitives/tabs.tsx +51 -0
- package/ui/request-logs-client.tsx +327 -0
- package/ui/session-usage-analytics-provider.tsx +28 -0
- package/ui/usage-analytics-client.ts +479 -0
- package/ui/usage-analytics-provider.tsx +84 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Échantillons télémétrie flotte (best-effort, lecture seule, redactée).
|
|
3
|
+
* Pas de better-sqlite3 dans le process Electron (ABI) — spawn Node vanilla.
|
|
4
|
+
* Extrait TempoFlow fleet-samples.ts (M7) — chemins = hooks marque.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { spawnSync } from "node:child_process";
|
|
9
|
+
function redactText(s, max = 800) {
|
|
10
|
+
return String(s || "")
|
|
11
|
+
.replace(/Bearer\s+[A-Za-z0-9._\-]+/gi, "Bearer ***")
|
|
12
|
+
.replace(/sk-[A-Za-z0-9]{10,}/g, "sk-***")
|
|
13
|
+
.replace(/api[_-]?key["']?\s*[:=]\s*["']?[^\s"']+/gi, "api_key=***")
|
|
14
|
+
.slice(0, max);
|
|
15
|
+
}
|
|
16
|
+
function walkRecent(dir, out, max, depth = 0) {
|
|
17
|
+
if (out.length >= max || depth > 3)
|
|
18
|
+
return;
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
for (const e of entries) {
|
|
27
|
+
if (out.length >= max)
|
|
28
|
+
return;
|
|
29
|
+
const full = path.join(dir, e.name);
|
|
30
|
+
if (e.isDirectory()) {
|
|
31
|
+
if (e.name === "node_modules" || e.name === ".git")
|
|
32
|
+
continue;
|
|
33
|
+
walkRecent(full, out, max, depth + 1);
|
|
34
|
+
}
|
|
35
|
+
else if (/\.(json|jsonl|md|txt)$/i.test(e.name)) {
|
|
36
|
+
out.push(full);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function createFleetSamples(paths) {
|
|
41
|
+
function sampleAssistantChats(limit = 30) {
|
|
42
|
+
const dbFile = paths.assistantDbPath();
|
|
43
|
+
if (!fs.existsSync(dbFile))
|
|
44
|
+
return [];
|
|
45
|
+
const script = `
|
|
46
|
+
const Database = require("better-sqlite3");
|
|
47
|
+
const db = new Database(process.env.CREEZIO_ASSISTANT_DB, { readonly: true, fileMustExist: true });
|
|
48
|
+
const rows = db.prepare(\`
|
|
49
|
+
SELECT m.id, m.conversation_id, m.role, m.content, m.created_at, c.title
|
|
50
|
+
FROM messages m
|
|
51
|
+
LEFT JOIN conversations c ON c.id = m.conversation_id
|
|
52
|
+
ORDER BY m.created_at DESC
|
|
53
|
+
LIMIT ?
|
|
54
|
+
\`).all(Number(process.env.CREEZIO_SAMPLE_LIMIT || 30));
|
|
55
|
+
db.close();
|
|
56
|
+
process.stdout.write(JSON.stringify(rows));
|
|
57
|
+
`;
|
|
58
|
+
try {
|
|
59
|
+
const r = spawnSync(paths.nodeBinary(), ["-e", script], {
|
|
60
|
+
env: {
|
|
61
|
+
...process.env,
|
|
62
|
+
CREEZIO_ASSISTANT_DB: dbFile,
|
|
63
|
+
CREEZIO_SAMPLE_LIMIT: String(limit),
|
|
64
|
+
NODE_PATH: paths.nodeModulesPathForScripts(),
|
|
65
|
+
},
|
|
66
|
+
encoding: "utf8",
|
|
67
|
+
timeout: 8_000,
|
|
68
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
69
|
+
});
|
|
70
|
+
if (r.status !== 0 || !r.stdout)
|
|
71
|
+
return [];
|
|
72
|
+
const rows = JSON.parse(r.stdout);
|
|
73
|
+
return rows.map((row) => ({
|
|
74
|
+
id: row.id,
|
|
75
|
+
conversationId: row.conversation_id,
|
|
76
|
+
title: row.title,
|
|
77
|
+
role: row.role,
|
|
78
|
+
content: redactText(String(row.content || "")),
|
|
79
|
+
createdAt: row.created_at,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function sampleHermesChats(limit = 20) {
|
|
87
|
+
const home = paths.hermesHomeDir();
|
|
88
|
+
const candidates = [
|
|
89
|
+
path.join(home, "sessions"),
|
|
90
|
+
path.join(home, "workspace"),
|
|
91
|
+
path.join(home, ".hermes"),
|
|
92
|
+
];
|
|
93
|
+
const files = [];
|
|
94
|
+
for (const dir of candidates) {
|
|
95
|
+
try {
|
|
96
|
+
if (!fs.existsSync(dir))
|
|
97
|
+
continue;
|
|
98
|
+
walkRecent(dir, files, 40);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* ignore */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
files.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
105
|
+
return files.slice(0, limit).map((f) => {
|
|
106
|
+
let preview = "";
|
|
107
|
+
try {
|
|
108
|
+
preview = redactText(fs.readFileSync(f, "utf8"), 600);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
preview = "";
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
path: path.relative(home, f).slice(0, 200),
|
|
115
|
+
mtime: fs.statSync(f).mtime.toISOString(),
|
|
116
|
+
preview,
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function sampleUsers() {
|
|
121
|
+
const db = paths.dbPath();
|
|
122
|
+
if (!fs.existsSync(db))
|
|
123
|
+
return [];
|
|
124
|
+
const script = `
|
|
125
|
+
const Database = require("better-sqlite3");
|
|
126
|
+
const db = new Database(process.env.CREEZIO_DB, { readonly: true, fileMustExist: true });
|
|
127
|
+
const has = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='users'").get();
|
|
128
|
+
if (!has) { db.close(); process.stdout.write("[]"); process.exit(0); }
|
|
129
|
+
const cols = db.prepare("PRAGMA table_info(users)").all().map(c => c.name);
|
|
130
|
+
const kindSel = cols.includes("kind") ? "kind" : "'human' AS kind";
|
|
131
|
+
const rows = db.prepare(\`SELECT id, username, role, \${kindSel}, active FROM users ORDER BY role, username COLLATE NOCASE\`).all();
|
|
132
|
+
db.close();
|
|
133
|
+
process.stdout.write(JSON.stringify(rows));
|
|
134
|
+
`;
|
|
135
|
+
try {
|
|
136
|
+
const r = spawnSync(paths.nodeBinary(), ["-e", script], {
|
|
137
|
+
env: {
|
|
138
|
+
...process.env,
|
|
139
|
+
CREEZIO_DB: db,
|
|
140
|
+
NODE_PATH: paths.nodeModulesPathForScripts(),
|
|
141
|
+
},
|
|
142
|
+
encoding: "utf8",
|
|
143
|
+
timeout: 8_000,
|
|
144
|
+
maxBuffer: 1024 * 1024,
|
|
145
|
+
});
|
|
146
|
+
if (r.status !== 0 || !r.stdout)
|
|
147
|
+
return [];
|
|
148
|
+
const rows = JSON.parse(r.stdout);
|
|
149
|
+
return rows.map((row) => ({
|
|
150
|
+
id: String(row.id || ""),
|
|
151
|
+
username: String(row.username || ""),
|
|
152
|
+
role: String(row.role || "collaborator"),
|
|
153
|
+
kind: String(row.kind || "human"),
|
|
154
|
+
active: Number(row.active) === 1,
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function sampleSessions() {
|
|
162
|
+
const file = path.join(paths.userDataDir(), "fleet-state", "sessions.json");
|
|
163
|
+
try {
|
|
164
|
+
if (!fs.existsSync(file))
|
|
165
|
+
return [];
|
|
166
|
+
const map = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
167
|
+
return Object.values(map).map((s) => ({
|
|
168
|
+
userId: String(s.userId || ""),
|
|
169
|
+
username: s.username ? String(s.username) : undefined,
|
|
170
|
+
lastSeen: s.lastSeen ? String(s.lastSeen) : undefined,
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function sampleRequestLogs(limit = 40) {
|
|
178
|
+
const root = paths.userDataDir();
|
|
179
|
+
const candidates = [
|
|
180
|
+
path.join(root, "fleet-state", "request-logs.jsonl"),
|
|
181
|
+
path.join(root, "logs", "request-logs.jsonl"),
|
|
182
|
+
path.join(root, "request-logs.jsonl"),
|
|
183
|
+
];
|
|
184
|
+
for (const file of candidates) {
|
|
185
|
+
try {
|
|
186
|
+
if (!fs.existsSync(file))
|
|
187
|
+
continue;
|
|
188
|
+
const lines = fs
|
|
189
|
+
.readFileSync(file, "utf8")
|
|
190
|
+
.trim()
|
|
191
|
+
.split("\n")
|
|
192
|
+
.slice(-limit);
|
|
193
|
+
return lines.map((line) => {
|
|
194
|
+
try {
|
|
195
|
+
const j = JSON.parse(line);
|
|
196
|
+
return {
|
|
197
|
+
at: j.at || j.timestamp,
|
|
198
|
+
method: j.method,
|
|
199
|
+
path: j.path || j.url,
|
|
200
|
+
status: j.status,
|
|
201
|
+
summary: redactText(JSON.stringify(j), 400),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return { summary: redactText(line, 200) };
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
/* next */
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
sampleAssistantChats,
|
|
217
|
+
sampleHermesChats,
|
|
218
|
+
sampleUsers,
|
|
219
|
+
sampleSessions,
|
|
220
|
+
sampleRequestLogs,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=fleet-samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-samples.js","sourceRoot":"","sources":["../../src/ops/fleet-samples.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boîte noire desktop — journal d'événements structurés (JSONL / boot).
|
|
3
|
+
* Extrait de TempoFlow ops-journal.ts (R4). Hooks marque pour log + anomaly.
|
|
4
|
+
*
|
|
5
|
+
* Best-effort intégral : le journal ne doit JAMAIS être une source de crash.
|
|
6
|
+
*/
|
|
7
|
+
import { type OpsBootSummary, type OpsEvent, type OpsEventInput } from "./types.js";
|
|
8
|
+
export type OpsJournalHooks = {
|
|
9
|
+
/** Miroir texte (logger marque). */
|
|
10
|
+
log?: (scope: string, line: string) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Anomalies → canal always-on (crash-reporter marque).
|
|
13
|
+
* Jamais de re-entrée vers trackCrashMirror.
|
|
14
|
+
*/
|
|
15
|
+
onAnomaly?: (evt: OpsEvent) => void;
|
|
16
|
+
};
|
|
17
|
+
export declare function setOpsJournalHooks(next: OpsJournalHooks): void;
|
|
18
|
+
export declare function getOpsBootId(): string;
|
|
19
|
+
export declare function getOpsDir(): string | null;
|
|
20
|
+
/** À appeler tôt (après initLogger) avec le dossier userData. */
|
|
21
|
+
export declare function initOpsJournal(userDataDir: string, version: string, nextHooks?: OpsJournalHooks): void;
|
|
22
|
+
/**
|
|
23
|
+
* Enregistre un événement : JSONL local + file flotte + miroir log texte.
|
|
24
|
+
* `source` défaut "main". Jamais de throw.
|
|
25
|
+
*/
|
|
26
|
+
export declare function track(input: OpsEventInput): void;
|
|
27
|
+
/** Décision : sucre pour les gates. */
|
|
28
|
+
export declare function trackDecision(kind: string, outcome: string, opts?: {
|
|
29
|
+
reason?: string;
|
|
30
|
+
durationMs?: number;
|
|
31
|
+
ctx?: Record<string, unknown>;
|
|
32
|
+
source?: string;
|
|
33
|
+
}): void;
|
|
34
|
+
/**
|
|
35
|
+
* Miroir des crashes (appelé par crash-reporter via import dynamique).
|
|
36
|
+
* Journal uniquement — PAS de re-déclenchement reportCrash.
|
|
37
|
+
*/
|
|
38
|
+
export declare function trackCrashMirror(kind: string, detail: Record<string, unknown>): void;
|
|
39
|
+
/**
|
|
40
|
+
* Ligne stdout d'un sous-process : consommée si `TF2EVENT {json}`.
|
|
41
|
+
* Renvoie true si la ligne était un événement (à ne pas logger en texte).
|
|
42
|
+
*/
|
|
43
|
+
export declare function consumeOpsLine(source: string, line: string): boolean;
|
|
44
|
+
/** Événement venant d'un canal non fiable (IPC renderer) : sanitizé. */
|
|
45
|
+
export declare function trackExternal(raw: unknown, source: string): boolean;
|
|
46
|
+
/** Drain de la file pour l'agent flotte (bundle kind=ops_events). */
|
|
47
|
+
export declare function drainPendingOpsEvents(max?: number): OpsEvent[];
|
|
48
|
+
/** Résumé du boot courant (index.json + heartbeat flotte). */
|
|
49
|
+
export declare function currentBootSummary(): OpsBootSummary;
|
|
50
|
+
/** Écrit / met à jour le résumé du boot courant dans ops/index.json. */
|
|
51
|
+
export declare function persistBootSummary(extra?: Partial<OpsBootSummary>): void;
|
|
52
|
+
/** Résumés des boots précédents (le courant exclu), du plus récent au plus ancien. */
|
|
53
|
+
export declare function readPreviousBootSummaries(limit?: number): OpsBootSummary[];
|
|
54
|
+
/** Tests : reset état module. */
|
|
55
|
+
export declare function __resetOpsJournalForTests(): void;
|
|
56
|
+
//# sourceMappingURL=journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/ops/journal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAEnB,MAAM,YAAY,CAAC;AAOpB,MAAM,MAAM,eAAe,GAAG;IAC5B,oCAAoC;IACpC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;CACrC,CAAC;AAcF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAE9D;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzC;AA2CD,iEAAiE;AACjE,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,eAAe,GAC1B,IAAI,CAiBN;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAwDhD;AAED,uCAAuC;AACvC,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,IAAI,CA2BN;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CASpE;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CASnE;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,CAAC,GAAG,SAAM,GAAG,QAAQ,EAAE,CAI3D;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI,cAAc,CAUnD;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAwBxE;AAED,sFAAsF;AACtF,wBAAgB,yBAAyB,CAAC,KAAK,SAAK,GAAG,cAAc,EAAE,CAetE;AAED,iCAAiC;AACjC,wBAAgB,yBAAyB,IAAI,IAAI,CAWhD"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boîte noire desktop — journal d'événements structurés (JSONL / boot).
|
|
3
|
+
* Extrait de TempoFlow ops-journal.ts (R4). Hooks marque pour log + anomaly.
|
|
4
|
+
*
|
|
5
|
+
* Best-effort intégral : le journal ne doit JAMAIS être une source de crash.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import crypto from "node:crypto";
|
|
10
|
+
import { parseOpsLine, redactOpsCtx, sanitizeOpsEventInput, serializeOpsEvent, } from "./types.js";
|
|
11
|
+
const OPS_KEEP_FILES = 30;
|
|
12
|
+
const OPS_MAX_TOTAL_BYTES = 100 * 1024 * 1024;
|
|
13
|
+
const INDEX_MAX_BOOTS = 60;
|
|
14
|
+
const PENDING_MAX = 500;
|
|
15
|
+
let hooks = {};
|
|
16
|
+
let opsDir = null;
|
|
17
|
+
let bootId = "";
|
|
18
|
+
let bootStartedAt = "";
|
|
19
|
+
let appVersion = "0.0.0";
|
|
20
|
+
let seq = 0;
|
|
21
|
+
const pending = [];
|
|
22
|
+
const counts = {};
|
|
23
|
+
const decisions = {};
|
|
24
|
+
const durations = {};
|
|
25
|
+
export function setOpsJournalHooks(next) {
|
|
26
|
+
hooks = next || {};
|
|
27
|
+
}
|
|
28
|
+
export function getOpsBootId() {
|
|
29
|
+
return bootId;
|
|
30
|
+
}
|
|
31
|
+
export function getOpsDir() {
|
|
32
|
+
return opsDir;
|
|
33
|
+
}
|
|
34
|
+
function bootFile() {
|
|
35
|
+
return opsDir && bootId ? path.join(opsDir, `${bootId}.jsonl`) : null;
|
|
36
|
+
}
|
|
37
|
+
function indexFile() {
|
|
38
|
+
return opsDir ? path.join(opsDir, "index.json") : null;
|
|
39
|
+
}
|
|
40
|
+
/** Purge rétention : garde les OPS_KEEP_FILES plus récents / plafond octets. */
|
|
41
|
+
function pruneOldBootFiles() {
|
|
42
|
+
if (!opsDir)
|
|
43
|
+
return;
|
|
44
|
+
try {
|
|
45
|
+
const files = fs
|
|
46
|
+
.readdirSync(opsDir)
|
|
47
|
+
.filter((f) => f.endsWith(".jsonl"))
|
|
48
|
+
.map((f) => {
|
|
49
|
+
const full = path.join(opsDir, f);
|
|
50
|
+
try {
|
|
51
|
+
const st = fs.statSync(full);
|
|
52
|
+
return { full, mtime: st.mtimeMs, size: st.size };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { full, mtime: 0, size: 0 };
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
59
|
+
let total = 0;
|
|
60
|
+
files.forEach((f, i) => {
|
|
61
|
+
total += f.size;
|
|
62
|
+
if (i >= OPS_KEEP_FILES || total > OPS_MAX_TOTAL_BYTES) {
|
|
63
|
+
try {
|
|
64
|
+
fs.unlinkSync(f.full);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* best-effort */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* best-effort */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** À appeler tôt (après initLogger) avec le dossier userData. */
|
|
77
|
+
export function initOpsJournal(userDataDir, version, nextHooks) {
|
|
78
|
+
try {
|
|
79
|
+
if (nextHooks)
|
|
80
|
+
hooks = nextHooks;
|
|
81
|
+
appVersion = version;
|
|
82
|
+
opsDir = path.join(userDataDir, "ops");
|
|
83
|
+
fs.mkdirSync(opsDir, { recursive: true });
|
|
84
|
+
bootId = crypto.randomUUID();
|
|
85
|
+
bootStartedAt = new Date().toISOString();
|
|
86
|
+
seq = 0;
|
|
87
|
+
pending.length = 0;
|
|
88
|
+
for (const k of Object.keys(counts))
|
|
89
|
+
delete counts[k];
|
|
90
|
+
for (const k of Object.keys(decisions))
|
|
91
|
+
delete decisions[k];
|
|
92
|
+
for (const k of Object.keys(durations))
|
|
93
|
+
delete durations[k];
|
|
94
|
+
pruneOldBootFiles();
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
opsDir = null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Enregistre un événement : JSONL local + file flotte + miroir log texte.
|
|
102
|
+
* `source` défaut "main". Jamais de throw.
|
|
103
|
+
*/
|
|
104
|
+
export function track(input) {
|
|
105
|
+
try {
|
|
106
|
+
const evt = {
|
|
107
|
+
...input,
|
|
108
|
+
ctx: input.ctx
|
|
109
|
+
? redactOpsCtx(input.ctx)
|
|
110
|
+
: undefined,
|
|
111
|
+
source: input.source || "main",
|
|
112
|
+
ts: new Date().toISOString(),
|
|
113
|
+
bootId,
|
|
114
|
+
seq: seq++,
|
|
115
|
+
};
|
|
116
|
+
counts[evt.level] = (counts[evt.level] || 0) + 1;
|
|
117
|
+
if (evt.level === "decision") {
|
|
118
|
+
decisions[evt.kind] = { outcome: evt.outcome, reason: evt.reason };
|
|
119
|
+
}
|
|
120
|
+
if (evt.durationMs != null) {
|
|
121
|
+
durations[evt.kind] = Math.max(durations[evt.kind] || 0, evt.durationMs);
|
|
122
|
+
}
|
|
123
|
+
const line = serializeOpsEvent(evt);
|
|
124
|
+
const file = bootFile();
|
|
125
|
+
if (file) {
|
|
126
|
+
try {
|
|
127
|
+
fs.appendFileSync(file, line + "\n");
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* disque plein / permissions */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
pending.push(evt);
|
|
134
|
+
if (pending.length > PENDING_MAX)
|
|
135
|
+
pending.shift();
|
|
136
|
+
try {
|
|
137
|
+
hooks.log?.("ops", `${evt.level} ${evt.kind}` +
|
|
138
|
+
(evt.outcome ? ` outcome=${evt.outcome}` : "") +
|
|
139
|
+
(evt.reason ? ` reason=${evt.reason}` : "") +
|
|
140
|
+
(evt.durationMs != null ? ` ${evt.durationMs}ms` : ""));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
/* best-effort */
|
|
144
|
+
}
|
|
145
|
+
if (evt.level === "anomaly") {
|
|
146
|
+
try {
|
|
147
|
+
hooks.onAnomaly?.(evt);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* best-effort */
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
/* best-effort */
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Décision : sucre pour les gates. */
|
|
159
|
+
export function trackDecision(kind, outcome, opts) {
|
|
160
|
+
track({ level: "decision", kind, outcome, ...opts });
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Miroir des crashes (appelé par crash-reporter via import dynamique).
|
|
164
|
+
* Journal uniquement — PAS de re-déclenchement reportCrash.
|
|
165
|
+
*/
|
|
166
|
+
export function trackCrashMirror(kind, detail) {
|
|
167
|
+
try {
|
|
168
|
+
const evt = {
|
|
169
|
+
level: "crash",
|
|
170
|
+
kind: `crash.${kind}`,
|
|
171
|
+
source: "main",
|
|
172
|
+
reason: typeof detail.message === "string"
|
|
173
|
+
? detail.message.slice(0, 300)
|
|
174
|
+
: undefined,
|
|
175
|
+
ctx: redactOpsCtx({
|
|
176
|
+
child: detail.child,
|
|
177
|
+
code: detail.code,
|
|
178
|
+
step: detail.step,
|
|
179
|
+
}),
|
|
180
|
+
ts: new Date().toISOString(),
|
|
181
|
+
bootId,
|
|
182
|
+
seq: seq++,
|
|
183
|
+
};
|
|
184
|
+
counts.crash = (counts.crash || 0) + 1;
|
|
185
|
+
const file = bootFile();
|
|
186
|
+
if (file)
|
|
187
|
+
fs.appendFileSync(file, serializeOpsEvent(evt) + "\n");
|
|
188
|
+
pending.push(evt);
|
|
189
|
+
if (pending.length > PENDING_MAX)
|
|
190
|
+
pending.shift();
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
/* best-effort */
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Ligne stdout d'un sous-process : consommée si `TF2EVENT {json}`.
|
|
198
|
+
* Renvoie true si la ligne était un événement (à ne pas logger en texte).
|
|
199
|
+
*/
|
|
200
|
+
export function consumeOpsLine(source, line) {
|
|
201
|
+
try {
|
|
202
|
+
const input = parseOpsLine(line);
|
|
203
|
+
if (!input)
|
|
204
|
+
return false;
|
|
205
|
+
track({ ...input, source: input.source || source });
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** Événement venant d'un canal non fiable (IPC renderer) : sanitizé. */
|
|
213
|
+
export function trackExternal(raw, source) {
|
|
214
|
+
const input = sanitizeOpsEventInput(raw);
|
|
215
|
+
if (!input)
|
|
216
|
+
return false;
|
|
217
|
+
// Le renderer ne peut pas émettre de crash/anomaly (anti-spam canal always-on).
|
|
218
|
+
if (input.level === "crash" || input.level === "anomaly") {
|
|
219
|
+
input.level = "error";
|
|
220
|
+
}
|
|
221
|
+
track({ ...input, source });
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
/** Drain de la file pour l'agent flotte (bundle kind=ops_events). */
|
|
225
|
+
export function drainPendingOpsEvents(max = 100) {
|
|
226
|
+
const out = pending.slice(0, max);
|
|
227
|
+
pending.splice(0, out.length);
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
/** Résumé du boot courant (index.json + heartbeat flotte). */
|
|
231
|
+
export function currentBootSummary() {
|
|
232
|
+
const summary = {
|
|
233
|
+
bootId,
|
|
234
|
+
startedAt: bootStartedAt,
|
|
235
|
+
appVersion,
|
|
236
|
+
counts: { ...counts },
|
|
237
|
+
decisions: { ...decisions },
|
|
238
|
+
durations: { ...durations },
|
|
239
|
+
};
|
|
240
|
+
return summary;
|
|
241
|
+
}
|
|
242
|
+
/** Écrit / met à jour le résumé du boot courant dans ops/index.json. */
|
|
243
|
+
export function persistBootSummary(extra) {
|
|
244
|
+
const file = indexFile();
|
|
245
|
+
if (!file)
|
|
246
|
+
return;
|
|
247
|
+
try {
|
|
248
|
+
let boots = [];
|
|
249
|
+
try {
|
|
250
|
+
const raw = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
251
|
+
if (Array.isArray(raw.boots))
|
|
252
|
+
boots = raw.boots;
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
/* premier boot */
|
|
256
|
+
}
|
|
257
|
+
const summary = { ...currentBootSummary(), ...extra };
|
|
258
|
+
const idx = boots.findIndex((b) => b.bootId === bootId);
|
|
259
|
+
if (idx >= 0)
|
|
260
|
+
boots[idx] = summary;
|
|
261
|
+
else
|
|
262
|
+
boots.push(summary);
|
|
263
|
+
if (boots.length > INDEX_MAX_BOOTS)
|
|
264
|
+
boots = boots.slice(-INDEX_MAX_BOOTS);
|
|
265
|
+
const tmp = `${file}.tmp`;
|
|
266
|
+
fs.writeFileSync(tmp, JSON.stringify({ boots }, null, 1));
|
|
267
|
+
fs.renameSync(tmp, file);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
/* best-effort */
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/** Résumés des boots précédents (le courant exclu), du plus récent au plus ancien. */
|
|
274
|
+
export function readPreviousBootSummaries(limit = 10) {
|
|
275
|
+
const file = indexFile();
|
|
276
|
+
if (!file)
|
|
277
|
+
return [];
|
|
278
|
+
try {
|
|
279
|
+
const raw = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
280
|
+
if (!Array.isArray(raw.boots))
|
|
281
|
+
return [];
|
|
282
|
+
return raw.boots
|
|
283
|
+
.filter((b) => b.bootId !== bootId)
|
|
284
|
+
.sort((a, b) => String(b.startedAt).localeCompare(String(a.startedAt)))
|
|
285
|
+
.slice(0, limit);
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/** Tests : reset état module. */
|
|
292
|
+
export function __resetOpsJournalForTests() {
|
|
293
|
+
hooks = {};
|
|
294
|
+
opsDir = null;
|
|
295
|
+
bootId = "";
|
|
296
|
+
bootStartedAt = "";
|
|
297
|
+
appVersion = "0.0.0";
|
|
298
|
+
seq = 0;
|
|
299
|
+
pending.length = 0;
|
|
300
|
+
for (const k of Object.keys(counts))
|
|
301
|
+
delete counts[k];
|
|
302
|
+
for (const k of Object.keys(decisions))
|
|
303
|
+
delete decisions[k];
|
|
304
|
+
for (const k of Object.keys(durations))
|
|
305
|
+
delete durations[k];
|
|
306
|
+
}
|
|
307
|
+
//# 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,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boîte noire — moteur d'anomalies générique.
|
|
3
|
+
* Extrait de TempoFlow ops-rules.ts (R4).
|
|
4
|
+
*/
|
|
5
|
+
import type { OpsBootSummary } from "./types.js";
|
|
6
|
+
export type BootRuleFinding = {
|
|
7
|
+
rule: "repeated-negative-decision" | "duration-over-threshold" | "recurring-errors";
|
|
8
|
+
kind: string;
|
|
9
|
+
detail: string;
|
|
10
|
+
ctx?: Record<string, unknown>;
|
|
11
|
+
};
|
|
12
|
+
/** Pure — testable sans I/O. */
|
|
13
|
+
export declare function evaluateRulesPure(current: OpsBootSummary, previous: OpsBootSummary[]): BootRuleFinding[];
|
|
14
|
+
/** À appeler en fin de boot (après persistBootSummary). Jamais de throw. */
|
|
15
|
+
export declare function evaluateBootRules(): BootRuleFinding[];
|
|
16
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/ops/rules.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA6BjD,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EACA,4BAA4B,GAC5B,yBAAyB,GACzB,kBAAkB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAEF,gCAAgC;AAChC,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,EAAE,GACzB,eAAe,EAAE,CAgDnB;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,IAAI,eAAe,EAAE,CAmBrD"}
|