@hyperframes/inspector 0.8.155 → 0.8.157
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 +22 -8
- package/dist/inspection.js +42 -14
- package/dist/live.js +482 -370
- package/dist/server.js +142 -0
- package/dist/service.js +491 -88
- package/dist/types/core/src/runtime/inspectionTypes.d.ts +1 -0
- package/dist/types/core/src/runtime/timelineValues.d.ts +1 -1
- package/dist/types/inspector/src/authoredState.d.ts +3 -0
- package/dist/types/inspector/src/elementMap.d.ts +2 -0
- package/dist/types/inspector/src/engine.d.ts +2 -1
- package/dist/types/inspector/src/live.d.ts +1 -2
- package/dist/types/inspector/src/pageQueries.d.ts +1 -0
- package/dist/types/inspector/src/server.d.ts +6 -0
- package/dist/types/inspector/src/service.d.ts +1 -0
- package/dist/types/inspector/src/sources.d.ts +17 -9
- package/package.json +11 -4
- package/dist/types/inspector/src/outputSchemas.d.ts +0 -12
- package/dist/types/inspector/src/tools.d.ts +0 -18
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Recover original HTML/CSS/GSAP context for **known elements before an edit**. This is not a video check, screenshot, diff, or affected-component verifier. It combines the I002 runtime/compiler provenance approach with the I003 HF-owned service boundary. The agent adapter holds no DOM or animation state.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Published as `@hyperframes/inspector`. It does not modify the shared installation or register itself in a harness.
|
|
6
6
|
|
|
7
7
|
## Start
|
|
8
8
|
|
|
@@ -17,13 +17,9 @@ export HF_INSPECT_CHROME=/absolute/path/to/chrome
|
|
|
17
17
|
bun packages/inspector/src/server.ts /absolute/video/project
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The service prints its loopback URL. Starting it does **not** start a browser. First inspection loads the project once.
|
|
20
|
+
The service prints its loopback URL. Starting it does **not** start a browser. First inspection loads the project once.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
HF_INSPECT_URL=http://127.0.0.1:PRINTED_PORT bun packages/inspector/src/mcp.ts
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Tool: `inspect_components`. Direct HTTP equivalent: `POST /inspect` with the same JSON. The service is bound to one project at startup, so no per-call project path is needed. `GET /info` returns project identity and startup/query counters. Stop with SIGINT/SIGTERM; the service disposes its own pages/browser.
|
|
22
|
+
The package ships the capability, not agent tools: a harness defines its own tool names, descriptions and schemas, and calls `POST /inspect` with the JSON below. The service is bound to one project at startup, so no per-call project path is needed. `GET /info` returns project identity and startup/query counters. Stop with SIGINT/SIGTERM; the service disposes its own pages/browser.
|
|
27
23
|
|
|
28
24
|
## Input
|
|
29
25
|
|
|
@@ -83,7 +79,25 @@ Code blocks are atomic. `omitted`, `omittedCount`, and `nextOffset` describe mis
|
|
|
83
79
|
|
|
84
80
|
`maxBytes` can be raised explicitly (2,048–256,000). A block larger than the budget is not cut in half: request that ID with a larger budget or read its file/range. Pagination can therefore remain at the same offset until the budget increases. Old-generation continuations are rejected.
|
|
85
81
|
|
|
86
|
-
Full runtime evidence is only available by an explicit HTTP request with `debug: true`; it is deliberately not part of the
|
|
82
|
+
Full runtime evidence is only available by an explicit HTTP request with `debug: true`; it is deliberately not part of the default request or its output budget.
|
|
83
|
+
|
|
84
|
+
## Timeline
|
|
85
|
+
|
|
86
|
+
`POST /timeline` answers which animations are scheduled when, from the same browser, page and generation as `/inspect`. It never seeks, renders or edits files.
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{ "component": { "selector": "#title" }, "boundary": 7.9 }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`component` is optional and resolves like an `/inspect` target; omit it for every registered HF timeline. Give at most one of `at`, `range: [start, end]` or `boundary`, in global seconds; omit all three for the schedule overview. Results are short text grouped by component, with event times, targets, properties and source locations; `generation` and `offset` page through them. Coverage is registered DOM-target GSAP animations and explicit HF items only; anything outside that, or past the expansion limits, is reported as incomplete coverage rather than guessed.
|
|
93
|
+
|
|
94
|
+
## Element map
|
|
95
|
+
|
|
96
|
+
`POST /element-map` returns the composition's element map from the same page. It reads no query fields. A project with no `index.html` answers `404` `{ "error": "no-composition", "code": "no-composition" }`.
|
|
97
|
+
|
|
98
|
+
## Errors
|
|
99
|
+
|
|
100
|
+
Every refusal is JSON `{ "error", "code" }`. `code` is the stable token (`no-composition`, `stale_generation`, `source_changed_during_query`, `request_too_large`); a sentence with no token is `invalid_request`. A missing browser is `503` `browser_unavailable`, and an unexpected failure is `500` `internal_error`. Importing the module does not listen; `createInspectorServer(project)` builds one. An unknown route is `404` `{ "error": "not_found", "code": "not_found" }`. `GET /info` adds `version`, this package's version. The process listens on `127.0.0.1` and refuses a `Host` that is not loopback, so a rebinding request cannot read the project path. Install the server with the package: `hyperframes-inspector <project> [port]`, or `node dist/server.js`.
|
|
87
101
|
|
|
88
102
|
## Lifecycle and overhead
|
|
89
103
|
|
package/dist/inspection.js
CHANGED
|
@@ -10,16 +10,32 @@
|
|
|
10
10
|
}
|
|
11
11
|
return unknown();
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
14
|
+
function declaredEase(ease) {
|
|
15
|
+
return typeof ease === "function" ? { kind: "expression", value: "custom function" } : declared(ease);
|
|
16
|
+
}
|
|
17
|
+
function animationValues(vars, properties, keyframesEase) {
|
|
18
|
+
const startAt = record(vars.startAt);
|
|
19
|
+
const endpoints = (property, end, start) => ({
|
|
20
|
+
property,
|
|
21
|
+
from: declared(vars.runBackwards ? end : start),
|
|
22
|
+
to: vars.runBackwards ? unknown() : declared(end)
|
|
23
|
+
});
|
|
24
|
+
const segment = declaredEase(vars.ease);
|
|
25
|
+
const whole = keyframesEase === void 0 ? void 0 : declaredEase(keyframesEase);
|
|
15
26
|
return {
|
|
16
27
|
basis: "authored-tween",
|
|
17
|
-
properties: properties.
|
|
18
|
-
property
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
properties: properties.flatMap((property) => {
|
|
29
|
+
const nested = record(vars[property]);
|
|
30
|
+
const keys = property === "attr" || property === "css" ? Object.keys(nested) : [];
|
|
31
|
+
if (!keys.length) return [endpoints(property, vars[property], startAt[property])];
|
|
32
|
+
const nestedStart = record(startAt[property]);
|
|
33
|
+
return keys.map((key) => endpoints(`${property}.${key}`, nested[key], nestedStart[key]));
|
|
34
|
+
}),
|
|
35
|
+
ease: whole ? {
|
|
36
|
+
kind: "expression",
|
|
37
|
+
value: `${whole.value ?? "?"} across keyframes, ${segment.value ?? "?"} per segment`
|
|
38
|
+
} : segment
|
|
23
39
|
};
|
|
24
40
|
}
|
|
25
41
|
|
|
@@ -1610,7 +1626,8 @@
|
|
|
1610
1626
|
const seen = /* @__PURE__ */ new Set();
|
|
1611
1627
|
const resolver = createRuntimeStartTimeResolver({
|
|
1612
1628
|
timelineRegistry: registry,
|
|
1613
|
-
documentRef: scope.ownerDocument
|
|
1629
|
+
documentRef: scope.ownerDocument,
|
|
1630
|
+
includeAuthoredTimingAttrs: true
|
|
1614
1631
|
});
|
|
1615
1632
|
const rootElement = findRootCompositionElement(scope.ownerDocument);
|
|
1616
1633
|
const clocks = /* @__PURE__ */ new Map();
|
|
@@ -1665,7 +1682,11 @@
|
|
|
1665
1682
|
const properties = Object.keys(piece.vars ?? {}).filter(
|
|
1666
1683
|
(k) => !reserved2.has(k) && !k.startsWith("on")
|
|
1667
1684
|
);
|
|
1668
|
-
const values = animationValues(
|
|
1685
|
+
const values = animationValues(
|
|
1686
|
+
piece.vars ?? {},
|
|
1687
|
+
properties,
|
|
1688
|
+
internal && a.vars?.keyframes ? a.vars.ease : void 0
|
|
1689
|
+
);
|
|
1669
1690
|
const localIntervals = internal ? globalIntervals(
|
|
1670
1691
|
a,
|
|
1671
1692
|
clock,
|
|
@@ -1782,15 +1803,22 @@
|
|
|
1782
1803
|
}
|
|
1783
1804
|
return value2;
|
|
1784
1805
|
};
|
|
1806
|
+
const ancestorId = (el) => {
|
|
1807
|
+
for (let parent = el.parentElement; parent; parent = parent.parentElement) {
|
|
1808
|
+
if (parent.id) return parent.id;
|
|
1809
|
+
}
|
|
1810
|
+
return "";
|
|
1811
|
+
};
|
|
1785
1812
|
const describe = (el) => ({
|
|
1786
1813
|
ref: ref(el),
|
|
1787
1814
|
tag: el.tagName.toLowerCase(),
|
|
1788
1815
|
id: el.id,
|
|
1789
1816
|
hfId: el.getAttribute("data-hf-id"),
|
|
1790
1817
|
classes: [...el.classList],
|
|
1791
|
-
composition: el.closest("[data-composition-id]")?.getAttribute("data-composition-id") ?? null
|
|
1818
|
+
composition: el.closest("[data-composition-id]")?.getAttribute("data-composition-id") ?? null,
|
|
1819
|
+
withinId: ancestorId(el)
|
|
1792
1820
|
});
|
|
1793
|
-
function
|
|
1821
|
+
function record2(value2, stack) {
|
|
1794
1822
|
if (animation(value2) && !records.has(value2) && count < limit) {
|
|
1795
1823
|
records.set(value2, stack);
|
|
1796
1824
|
count++;
|
|
@@ -1816,8 +1844,8 @@
|
|
|
1816
1844
|
if (name === "add" && animation(args[0])) attachments.set(args[0], stack);
|
|
1817
1845
|
else if (before) {
|
|
1818
1846
|
for (const child of self?.getChildren?.(false, true, true) ?? [])
|
|
1819
|
-
if (!before.has(child))
|
|
1820
|
-
} else
|
|
1847
|
+
if (!before.has(child)) record2(child, stack);
|
|
1848
|
+
} else record2(result, stack);
|
|
1821
1849
|
}
|
|
1822
1850
|
return result;
|
|
1823
1851
|
};
|