@flemo/devtools 0.2.2 → 0.4.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 +77 -302
- package/dist/__tests__/domProtocol.test.d.ts +1 -0
- package/dist/anomalies.d.ts +0 -4
- package/dist/domProtocol.d.ts +22 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +386 -380
- package/dist/noop.d.ts +1 -1
- package/dist/noop.mjs +122 -103
- package/dist/overrides.d.ts +44 -7
- package/dist/types.d.ts +0 -14
- package/package.json +7 -6
package/dist/noop.d.ts
CHANGED
|
@@ -10,4 +10,4 @@ export declare const attachFlightRecorder: (_options?: FlightRecorderOptions) =>
|
|
|
10
10
|
export declare const attachDevtoolsPanel: (_options?: DevtoolsPanelOptions) => DevtoolsPanelHandle;
|
|
11
11
|
export type { FlemoGlobal } from './recorder';
|
|
12
12
|
export type { DevtoolsPanelHandle, DevtoolsPanelOptions } from './panel';
|
|
13
|
-
export type {
|
|
13
|
+
export type { EnvironmentFingerprint, FlemoReport, FlightDriver, FlightHolds, FlightKind, FlightParticipants, FlightRecord, FlightRecorderHandle, FlightRecorderOptions, FlightTimestamp, FramePhaseStats, FrameSampleStats, LandingAudit, LongTaskSpan, ObservationCapabilities, OverridesSection, PlayerGapStats, UaBrand } from './types';
|
package/dist/noop.mjs
CHANGED
|
@@ -11,7 +11,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
11
11
|
return d.holdReassertedAtMs !== null && n.push(`hold re-asserted ${d.holdReassertedAtMs}ms into the flight, after it had already released (an interleaved commit wrote the stale paused hold attribute over a running flight — the flemo 2026-08-18 release-race signature; the motion pauses while every timing metric stays clean)`), d.pausedAfterRelease && n.push("compiled animation reported playState=paused after its release (the flight was posed and then stopped mid-motion, not merely starved of frames)"), d.longestStallMs >= 48 && n.push(`motion stalled ${d.longestStallMs}ms mid-flight (${d.stalledFrames}/${d.sampledFrames} released frames advanced neither the animation clock nor the pose — freeze, or freeze-then-leap if the flight still landed on time)`), d.sampledFrames === 0 && e.releasedAtMs !== null && n.push("no released frames were sampled (the flight ended at or before its own hold release — the visible motion, if any, was never observed)"), f.completedUnheld > 0 && n.push(`${f.completedUnheld} image(s) finished loading mid-flight without a hold (${f.completedDuringFlight} completed, ${f.heldDuringFlight} held; ${f.loadingAtStart} were loading at t0, ${f.addedDuringFlight} arrived mid-flight) — each decode rasters on the moving layer and costs a present; this is the warm-side image-hold regression`), l.orphanedHolds.length > 0 && n.push(`hold markers left on the page at rest: ${l.orphanedHolds.join("; ")} (whatever they hide has no owner left to reveal it — the permanently-blank-avatar class)`), l.residualInlineTransforms.length > 0 && n.push(`residual inline style after COMPLETED: ${l.residualInlineTransforms.join("; ")} (landing cleanup failure — the landed scope belongs to the compiled rest rules)`), l.offViewportAtRest && n.push("screen resting at from-pose while COMPLETED+active (blank-viewport signature — the flemo PR #259 class: a residual pose left the landed screen parked off-viewport)"), l.stuckStatuses.length > 0 && n.push(`transitional status stuck >${t / 1e3}s: ${l.stuckStatuses.join(", ")} (navigation queue lock or missed animationend — later navigations will be swallowed)`), i === "unknown" && n.push("driver could not be classified (no running flemo-* CSSAnimation and no player inline-style signature observed — zero-duration flight, or the sampler attached after motion ended)"), n;
|
|
12
12
|
}, s = (e) => {
|
|
13
13
|
let n = [];
|
|
14
|
-
if (e.
|
|
14
|
+
if (e.emulationSuspected) {
|
|
15
15
|
let t = /Win/i.test(e.platform) ? " (Windows touch hardware makes this signal ambiguous — confirm the DevTools device toolbar state)" : "";
|
|
16
16
|
n.push("DevTools device emulation suspected — the page composites to a rescaled surface, so visual reports from this session are untrustworthy; judge motion in a plain window or on a real device" + t);
|
|
17
17
|
}
|
|
@@ -98,157 +98,180 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
98
98
|
playerGapMirror: Array.isArray(n?.__flemoPlayerGaps)
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
|
-
}, h = [
|
|
101
|
+
}, h = "flemo:devtools-panel-height", g = [{
|
|
102
|
+
key: "flemo:devtools",
|
|
103
|
+
storage: "session",
|
|
104
|
+
kind: "opt-in-diagnostic",
|
|
105
|
+
values: "\"on\" / \"off\"",
|
|
106
|
+
fallback: "off",
|
|
107
|
+
effect: "arms this flight recorder in the playground (?devtools=on)"
|
|
108
|
+
}, {
|
|
109
|
+
key: h,
|
|
110
|
+
storage: "session",
|
|
111
|
+
kind: "production-state",
|
|
112
|
+
values: "a pixel height",
|
|
113
|
+
fallback: "(the panel's default height)",
|
|
114
|
+
effect: "the drawer height this panel was last dragged to"
|
|
115
|
+
}], _ = [], v = [..._, ...g], y = [
|
|
102
116
|
{
|
|
103
|
-
key: "flemo:
|
|
104
|
-
storage: "
|
|
105
|
-
|
|
106
|
-
description: "learned driver ledger ('css' = player demoted on this device, 'raf' = clean probe)"
|
|
117
|
+
key: "flemo:sixty",
|
|
118
|
+
storage: "session",
|
|
119
|
+
retiredWith: "the steady-60 verdict seed, now document-scoped module state (2026-08-31)"
|
|
107
120
|
},
|
|
108
121
|
{
|
|
109
|
-
key: "flemo:
|
|
122
|
+
key: "flemo:settle-gate",
|
|
110
123
|
storage: "session",
|
|
111
|
-
|
|
112
|
-
description: "hard driver pin ('css@<epoch-ms>' / 'raf@<epoch-ms>', 24h TTL) — pins EVERY transition"
|
|
124
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
113
125
|
},
|
|
114
126
|
{
|
|
115
|
-
key: "flemo:
|
|
127
|
+
key: "flemo:arrivalhold",
|
|
116
128
|
storage: "session",
|
|
117
|
-
|
|
118
|
-
description: "steady-60 display verdict seed ('high' latches, a count seeds the streak)"
|
|
129
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
119
130
|
},
|
|
120
131
|
{
|
|
121
|
-
key: "flemo:
|
|
132
|
+
key: "flemo:deskflip",
|
|
122
133
|
storage: "session",
|
|
123
|
-
|
|
124
|
-
description: "LPM release-latency seed (learned)"
|
|
134
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
125
135
|
},
|
|
126
136
|
{
|
|
127
|
-
key: "flemo:
|
|
137
|
+
key: "flemo:deskhead",
|
|
128
138
|
storage: "session",
|
|
129
|
-
|
|
130
|
-
description: "Blink landing pixel-snap easing A/B"
|
|
139
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
131
140
|
},
|
|
132
141
|
{
|
|
133
|
-
key: "flemo:
|
|
142
|
+
key: "flemo:creep",
|
|
134
143
|
storage: "session",
|
|
135
|
-
|
|
136
|
-
description: "flight-scoped <img> reveal hold"
|
|
144
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
137
145
|
},
|
|
138
146
|
{
|
|
139
|
-
key: "flemo:
|
|
147
|
+
key: "flemo:relcommit",
|
|
140
148
|
storage: "session",
|
|
141
|
-
|
|
142
|
-
description: "render-settle entry gate override"
|
|
149
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
143
150
|
},
|
|
144
151
|
{
|
|
145
|
-
key: "flemo:
|
|
152
|
+
key: "flemo:imgoffload",
|
|
146
153
|
storage: "session",
|
|
147
|
-
|
|
148
|
-
description: "anchored-opening handoff (POP-scoped)"
|
|
154
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
149
155
|
},
|
|
150
156
|
{
|
|
151
|
-
key: "flemo:
|
|
157
|
+
key: "flemo:governed",
|
|
152
158
|
storage: "session",
|
|
153
|
-
|
|
154
|
-
description: "handoff point override (ms)"
|
|
159
|
+
retiredWith: "the engine diagnostic surface (2026-08-31)"
|
|
155
160
|
},
|
|
156
161
|
{
|
|
157
|
-
key: "flemo:
|
|
162
|
+
key: "flemo:imghold",
|
|
158
163
|
storage: "session",
|
|
159
|
-
|
|
160
|
-
description: "force the scrub-WAAPI value-application tier"
|
|
164
|
+
retiredWith: "the image reveal hold, whose only arming path it was (2026-08-31)"
|
|
161
165
|
},
|
|
162
166
|
{
|
|
163
|
-
key: "flemo:
|
|
167
|
+
key: "flemo:preraster",
|
|
164
168
|
storage: "session",
|
|
165
|
-
|
|
166
|
-
description: "player device-pixel snap policy override"
|
|
169
|
+
retiredWith: "the REST-time scope promotion, whose only arming path it was (2026-08-31)"
|
|
167
170
|
},
|
|
168
171
|
{
|
|
169
|
-
key: "flemo:
|
|
172
|
+
key: "flemo:parkhead",
|
|
170
173
|
storage: "session",
|
|
171
|
-
|
|
172
|
-
description: "'hybrid' snap jitter-band width (device px)"
|
|
174
|
+
retiredWith: "the engine diagnostic surface — the park head is unconditional (2026-08-31)"
|
|
173
175
|
},
|
|
174
176
|
{
|
|
175
177
|
key: "flemo:layers",
|
|
176
178
|
storage: "session",
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
retiredWith: "the resident-layer experiment (2026-08-31)"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: "flemo:morph",
|
|
183
|
+
storage: "session",
|
|
184
|
+
retiredWith: "the morph decision trace (2026-08-31)"
|
|
179
185
|
},
|
|
180
186
|
{
|
|
181
187
|
key: "flemo:freeze",
|
|
182
188
|
storage: "session",
|
|
183
|
-
|
|
184
|
-
description: "keep the direct prev screen live"
|
|
189
|
+
retiredWith: "the shallow-freeze experiment (2026-08-31)"
|
|
185
190
|
},
|
|
186
191
|
{
|
|
187
|
-
key: "flemo:
|
|
192
|
+
key: "flemo:motion-driver",
|
|
193
|
+
storage: "local",
|
|
194
|
+
retiredWith: "the per-origin driver demotion ledger (2026-08-19)"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
key: "flemo:motion-driver-force",
|
|
188
198
|
storage: "session",
|
|
189
|
-
|
|
190
|
-
description: "promote the entering content layer through the hold"
|
|
199
|
+
retiredWith: "the hard driver pin, with the rAF player (2026-08-22)"
|
|
191
200
|
},
|
|
192
201
|
{
|
|
193
|
-
key: "flemo:
|
|
202
|
+
key: "flemo:landing-snap",
|
|
203
|
+
storage: "session",
|
|
204
|
+
retiredWith: "the integer-device-pixel landing snap, falsified on device (2026-08-22)"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
key: "flemo:handoff",
|
|
208
|
+
storage: "session",
|
|
209
|
+
retiredWith: "the player's anchored-opening handoff (2026-08-22)"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
key: "flemo:handoffms",
|
|
213
|
+
storage: "session",
|
|
214
|
+
retiredWith: "the player's anchored-opening handoff (2026-08-22)"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
key: "flemo:apply",
|
|
194
218
|
storage: "session",
|
|
195
|
-
|
|
196
|
-
description: "image decode offloader override"
|
|
219
|
+
retiredWith: "the scrub-WAAPI value-application tier (2026-08-22)"
|
|
197
220
|
},
|
|
198
221
|
{
|
|
199
|
-
key: "flemo:
|
|
222
|
+
key: "flemo:snap",
|
|
223
|
+
storage: "session",
|
|
224
|
+
retiredWith: "the player's device-pixel snap policy (2026-08-22)"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
key: "flemo:snapband",
|
|
228
|
+
storage: "session",
|
|
229
|
+
retiredWith: "the player's device-pixel snap policy (2026-08-22)"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
key: "flemo:lat",
|
|
200
233
|
storage: "session",
|
|
201
|
-
|
|
202
|
-
description: "arms this flight recorder in the playground (?devtools=on)"
|
|
234
|
+
retiredWith: "the Low Power Mode release-latency probe (2026-08-22)"
|
|
203
235
|
}
|
|
204
|
-
],
|
|
236
|
+
], b = "(retired — the library no longer reads this)", x = (e) => {
|
|
205
237
|
try {
|
|
206
238
|
let t = e === "session" ? sessionStorage : localStorage;
|
|
207
239
|
return t.length, t;
|
|
208
240
|
} catch {
|
|
209
241
|
return null;
|
|
210
242
|
}
|
|
211
|
-
},
|
|
243
|
+
}, S = (e, t) => {
|
|
212
244
|
try {
|
|
213
245
|
return e ? e.getItem(t) : null;
|
|
214
246
|
} catch {
|
|
215
247
|
return null;
|
|
216
248
|
}
|
|
217
|
-
},
|
|
218
|
-
let e = {}, t =
|
|
219
|
-
for (let r of
|
|
220
|
-
let i =
|
|
249
|
+
}, C = new Set(v.map((e) => e.key)), w = new Set(y.map((e) => e.key)), T = () => {
|
|
250
|
+
let e = {}, t = x("session"), n = x("local");
|
|
251
|
+
for (let r of v) {
|
|
252
|
+
let i = S(r.storage === "session" ? t : n, r.key);
|
|
221
253
|
i !== null && (e[r.key] = i);
|
|
222
254
|
}
|
|
223
|
-
let r
|
|
224
|
-
|
|
255
|
+
for (let r of y) for (let [i, a] of [[t, "sessionStorage"], [n, "localStorage"]]) {
|
|
256
|
+
let t = S(i, r.key);
|
|
257
|
+
t !== null && (e[`${r.key} (${a}) ${b}`] = t);
|
|
258
|
+
}
|
|
225
259
|
for (let [r, i] of [[t, "sessionStorage"], [n, "localStorage"]]) if (r) try {
|
|
226
260
|
for (let t = 0; t < r.length; t += 1) {
|
|
227
261
|
let n = r.key(t);
|
|
228
|
-
!n || !n.startsWith("flemo:") ||
|
|
262
|
+
!n || !n.startsWith("flemo:") || C.has(n) || w.has(n) || (e[`${n} (${i}, unknown key)`] = r.getItem(n) ?? "");
|
|
229
263
|
}
|
|
230
264
|
} catch {}
|
|
231
265
|
return e;
|
|
232
|
-
},
|
|
266
|
+
}, E = (e) => {
|
|
233
267
|
let t = [];
|
|
234
|
-
for (let [n, r] of Object.entries(e)) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
if (n === _) {
|
|
240
|
-
t.push(`${n}=${r} — legacy localStorage driver pin present. The library removes it on sight and never honors it, but its existence means an old A/B session left residue on this profile.`);
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
if (n.startsWith(`${g} `)) {
|
|
244
|
-
t.push(`${n}=${r} — a driver force pin was observed this session (see marker in the key). Even a since-cleared pin may have shaped early driver decisions; treat this session's routing as suspect.`);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
let e = h.find((e) => n === e.key || n.startsWith(`${e.key} `));
|
|
248
|
-
!e || e.key === "flemo:devtools" || (e.kind === "opt-in-diagnostic" ? t.push(`${n}=${r} — opt-in diagnostic active (${e.description}); behavior differs from stock. Possible left-over A/B toggle from an earlier debugging session.`) : e.kind === "production-default-with-override" && t.push(`${n}=${r} — production default overridden for this session (${e.description}).`));
|
|
268
|
+
for (let [n, r] of Object.entries(e)) if (n.includes("(retired — the library no longer reads this)")) {
|
|
269
|
+
let e = n.slice(0, n.indexOf(" (")), i = y.find((t) => t.key === e);
|
|
270
|
+
t.push(`${n}=${r} — RETIRED residue: this key went with ${i?.retiredWith ?? "a removed feature"}. The library never reads it, so it cannot explain anything you are seeing. Safe to delete; it is listed only so it does not read as an unexplained lead.`);
|
|
271
|
+
continue;
|
|
249
272
|
}
|
|
250
273
|
return t;
|
|
251
|
-
},
|
|
274
|
+
}, D = (e) => Math.round(e * 10) / 10, O = (e) => {
|
|
252
275
|
if (e.length === 0) return {
|
|
253
276
|
count: 0,
|
|
254
277
|
medianGapMs: 0,
|
|
@@ -258,11 +281,11 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
258
281
|
let t = [...e].sort((e, t) => e - t);
|
|
259
282
|
return {
|
|
260
283
|
count: e.length,
|
|
261
|
-
medianGapMs:
|
|
262
|
-
maxGapMs:
|
|
284
|
+
medianGapMs: D(t[Math.floor(t.length / 2)]),
|
|
285
|
+
maxGapMs: D(t[t.length - 1]),
|
|
263
286
|
over30Count: e.filter((e) => e >= 30).length
|
|
264
287
|
};
|
|
265
|
-
},
|
|
288
|
+
}, k = (e, t = []) => {
|
|
266
289
|
let n = [...e, ...t];
|
|
267
290
|
return {
|
|
268
291
|
...n.length === 0 ? {
|
|
@@ -273,21 +296,21 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
273
296
|
let e = [...n].sort((e, t) => e - t);
|
|
274
297
|
return {
|
|
275
298
|
count: n.length,
|
|
276
|
-
medianGapMs:
|
|
277
|
-
maxGapMs:
|
|
299
|
+
medianGapMs: D(e[Math.floor(e.length / 2)]),
|
|
300
|
+
maxGapMs: D(e[e.length - 1])
|
|
278
301
|
};
|
|
279
302
|
})(),
|
|
280
|
-
longGaps: n.filter((e) => e >= 30).map(
|
|
281
|
-
held:
|
|
282
|
-
released:
|
|
303
|
+
longGaps: n.filter((e) => e >= 30).map(D),
|
|
304
|
+
held: O(e),
|
|
305
|
+
released: O(t)
|
|
283
306
|
};
|
|
284
|
-
},
|
|
285
|
-
maxMs:
|
|
307
|
+
}, A = (e) => e.length === 0 ? null : {
|
|
308
|
+
maxMs: D(Math.max(...e)),
|
|
286
309
|
over30Count: e.filter((e) => e >= 30).length
|
|
287
|
-
},
|
|
310
|
+
}, j = (e) => {
|
|
288
311
|
let t = e.playerSuppression || e.playerAdvance;
|
|
289
312
|
return t && e.compiledAnimation ? "mixed" : t ? "player" : e.compiledAnimation ? "compiled" : "unknown";
|
|
290
|
-
},
|
|
313
|
+
}, M = (e) => e === "PUSHING" ? "PUSH" : e === "POPPING" ? "POP" : e === "REPLACING" ? "REPLACE" : null, N = (e) => {
|
|
291
314
|
let t = /^matrix3d\(([^)]+)\)$/.exec(e.trim());
|
|
292
315
|
if (t) {
|
|
293
316
|
let e = t[1].split(",").map((e) => Number(e.trim()));
|
|
@@ -299,7 +322,7 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
299
322
|
return e.length === 6 && Number.isFinite(e[4]) ? e[4] : null;
|
|
300
323
|
}
|
|
301
324
|
return null;
|
|
302
|
-
},
|
|
325
|
+
}, P = "2", F = "@flemo/devtools resolved to its production entry: nothing was recorded. Run a development build to collect a real report.", I = () => {}, L = () => ({
|
|
303
326
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
304
327
|
version: "inert",
|
|
305
328
|
environment: {
|
|
@@ -332,19 +355,15 @@ var e = 30, t = 1e4, n = 50, r = 120, i = 100, a = 48, o = (e) => {
|
|
|
332
355
|
},
|
|
333
356
|
overrides: {
|
|
334
357
|
active: {},
|
|
335
|
-
warnings: [
|
|
336
|
-
},
|
|
337
|
-
driverPolicy: {
|
|
338
|
-
demotion: null,
|
|
339
|
-
forcePin: null
|
|
358
|
+
warnings: [F]
|
|
340
359
|
},
|
|
341
360
|
flights: [],
|
|
342
|
-
anomalies: [
|
|
361
|
+
anomalies: [F],
|
|
343
362
|
blindSpots: [],
|
|
344
|
-
judgingProtocol: [
|
|
345
|
-
}),
|
|
346
|
-
detach:
|
|
347
|
-
report:
|
|
348
|
-
}),
|
|
363
|
+
judgingProtocol: [F]
|
|
364
|
+
}), R = (e) => ({
|
|
365
|
+
detach: I,
|
|
366
|
+
report: L
|
|
367
|
+
}), z = (e) => ({ detach: I });
|
|
349
368
|
//#endregion
|
|
350
|
-
export { c as BLIND_SPOTS,
|
|
369
|
+
export { c as BLIND_SPOTS, _ as CORE_FLAGS, g as DEVTOOLS_OWNED_FLAGS, v as FLAG_REGISTRY, e as LONG_GAP_MS, i as MID_FLIGHT_TASK_MS, n as OPENING_WINDOW_LEAD_MS, r as OPENING_WINDOW_TAIL_MS, h as PANEL_HEIGHT_KEY, P as REPORT_SCHEMA_VERSION, y as RETIRED_FLAGS, b as RETIRED_MARKER, a as STALL_MS, t as STUCK_STATUS_MS, z as attachDevtoolsPanel, R as attachFlightRecorder, m as captureEnvironment, j as classifyDriver, k as computeFrameStats, O as computePhaseStats, A as computePlayerGapStats, o as deriveFlightAnomalies, E as deriveOverrideWarnings, s as deriveReportAnomalies, u as detectEngine, d as isEmulationSuspected, M as kindFromStatus, N as parseTranslateX, f as sampleRafCadence, T as snapshotOverrides };
|
package/dist/overrides.d.ts
CHANGED
|
@@ -1,18 +1,55 @@
|
|
|
1
1
|
export type FlagClass = "production-state" | "production-default-with-override" | "opt-in-diagnostic";
|
|
2
|
+
/**
|
|
3
|
+
* The panel's drawer height. Declared HERE rather than in the panel so the
|
|
4
|
+
* registry below can name it: a `flemo:` key the recorder writes but does not
|
|
5
|
+
* declare shows up in its own reports as an unknown key.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PANEL_HEIGHT_KEY = "flemo:devtools-panel-height";
|
|
2
8
|
export interface FlagDescriptor {
|
|
3
9
|
key: string;
|
|
4
10
|
storage: "session" | "local";
|
|
5
11
|
kind: FlagClass;
|
|
6
|
-
|
|
12
|
+
/** Accepted values, for a report to spell out. */
|
|
13
|
+
values: string;
|
|
14
|
+
/** The default when the key is unset. */
|
|
15
|
+
fallback: string;
|
|
16
|
+
/** What arming it changes. */
|
|
17
|
+
effect: string;
|
|
7
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Keys DEVTOOLS itself owns. Core neither reads nor declares them, so they are
|
|
21
|
+
* listed here and excluded from the comparison against core — without a row
|
|
22
|
+
* each one would surface in every report as an unknown key, which is the
|
|
23
|
+
* recorder generating its own false lead.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEVTOOLS_OWNED_FLAGS: readonly FlagDescriptor[];
|
|
26
|
+
/**
|
|
27
|
+
* Every `flemo:*` key the library reads. EMPTY since 2026-08-31: the engine's
|
|
28
|
+
* diagnostic surface was removed from the shipped package outright, so a
|
|
29
|
+
* session key can no longer change what a flight does. The array stays as the
|
|
30
|
+
* shape a report reads, and so this file keeps saying so out loud.
|
|
31
|
+
*/
|
|
32
|
+
export declare const CORE_FLAGS: readonly FlagDescriptor[];
|
|
8
33
|
export declare const FLAG_REGISTRY: readonly FlagDescriptor[];
|
|
9
|
-
/** Marker suffix for the legacy-location residue of the force pin. */
|
|
10
|
-
export declare const LEGACY_LOCAL_PIN_KEY = "flemo:motion-driver-force (localStorage \u2014 legacy location)";
|
|
11
34
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
35
|
+
* Keys the library once read and no longer does. They are still ENUMERATED so
|
|
36
|
+
* a report can say "this is set, and it does nothing" — residue that is merely
|
|
37
|
+
* unknown reads as a lead worth chasing.
|
|
38
|
+
*/
|
|
39
|
+
export interface RetiredFlag {
|
|
40
|
+
key: string;
|
|
41
|
+
storage: "session" | "local";
|
|
42
|
+
/** What it used to do, and when it stopped doing it. */
|
|
43
|
+
retiredWith: string;
|
|
44
|
+
}
|
|
45
|
+
export declare const RETIRED_FLAGS: readonly RetiredFlag[];
|
|
46
|
+
/** Marker suffix appended to a retired key so a report reads as a verdict. */
|
|
47
|
+
export declare const RETIRED_MARKER = "(retired \u2014 the library no longer reads this)";
|
|
48
|
+
/**
|
|
49
|
+
* Snapshot every `flemo:*` key currently set, from both storages: the live
|
|
50
|
+
* registry keys from their native storage, any RETIRED key still persisted
|
|
51
|
+
* (marked as such), and any UNKNOWN `flemo:`-prefixed key either storage holds
|
|
52
|
+
* (a future flag, or hand-set residue).
|
|
16
53
|
*/
|
|
17
54
|
export declare const snapshotOverrides: () => Record<string, string>;
|
|
18
55
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -238,26 +238,12 @@ export interface OverridesSection {
|
|
|
238
238
|
/** Derived, prominent warnings — read these before trusting anything. */
|
|
239
239
|
warnings: string[];
|
|
240
240
|
}
|
|
241
|
-
export interface DriverPolicySection {
|
|
242
|
-
/**
|
|
243
|
-
* localStorage `flemo:motion-driver` — the learned ledger. "css" means the
|
|
244
|
-
* device earned a persisted player demotion; "raf" means a clean probe.
|
|
245
|
-
*/
|
|
246
|
-
demotion: string | null;
|
|
247
|
-
/**
|
|
248
|
-
* sessionStorage `flemo:motion-driver-force` raw value. NON-NULL MEANS A
|
|
249
|
-
* PIN IS ACTIVE: every transition is forced onto one driver. Almost always
|
|
250
|
-
* A/B residue when found unexpectedly.
|
|
251
|
-
*/
|
|
252
|
-
forcePin: string | null;
|
|
253
|
-
}
|
|
254
241
|
export interface FlemoReport {
|
|
255
242
|
generatedAt: string;
|
|
256
243
|
/** Report schema version (not the package version). */
|
|
257
244
|
version: string;
|
|
258
245
|
environment: EnvironmentFingerprint;
|
|
259
246
|
overrides: OverridesSection;
|
|
260
|
-
driverPolicy: DriverPolicySection;
|
|
261
247
|
flights: FlightRecord[];
|
|
262
248
|
/** Session-level findings (observation traps, active pins, stuck flights). */
|
|
263
249
|
anomalies: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flemo/devtools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Zero-config flight recorder for flemo screen transitions: captures per-flight driver routing, frame pacing, long tasks, landing residues, active debug overrides, and environment/observation-trap fingerprints into one JSON report readable by humans and coding agents.",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -34,16 +34,17 @@
|
|
|
34
34
|
"homepage": "https://flemo.dev",
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@flemo/core": "2.2.0",
|
|
38
|
+
"@flemo/eslint-config": "0.0.0",
|
|
39
|
+
"@flemo/tsconfig": "0.0.0",
|
|
37
40
|
"@types/node": "^24.13.1",
|
|
38
|
-
"@vitest/coverage-v8": "^4.1.
|
|
41
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
39
42
|
"eslint": "^9.39.5",
|
|
40
43
|
"jsdom": "^29.1.1",
|
|
41
44
|
"typescript": "^6.0.3",
|
|
42
|
-
"vite": "^8.2.
|
|
45
|
+
"vite": "^8.2.2",
|
|
43
46
|
"vite-plugin-dts": "^5.0.3",
|
|
44
|
-
"vitest": "^4.1.
|
|
45
|
-
"@flemo/eslint-config": "0.0.0",
|
|
46
|
-
"@flemo/tsconfig": "0.0.0"
|
|
47
|
+
"vitest": "^4.1.11"
|
|
47
48
|
},
|
|
48
49
|
"publishConfig": {
|
|
49
50
|
"access": "public"
|