feat(native): add inspection primitives, dispatch traces and approved UI observation (#500)

* fix(hopper): normalize string-backed addresses and update verification

* feat(native): add inspection primitives, dispatch traces and approved UI observation

* test: prioritize real artifact E2E and captured golden regressions

* fix(process): queue observed output before reactive rendering actions

* test: prune redundant cases and strengthen boundary assertions

* fix(cli): route native value tracing through shared workflows

* test: replace synthetic success with real workflows and captured data

* fix(catalog): separate portable metadata from native host availability
This commit is contained in:
morluto authored and GitHub committed 2026-10-04 16:02:36 +08:00
1 parent 0356f7677f
commit 4fbc501121
205 files changed
+8136 -1816

No files matched your search

@@ -43,8 +43,13 @@ it("returns detached terminal and filesystem checkpoint observations", async ()
expect(frames).toHaveLength(22);
expect(frames.slice(0, 2).map(({ at_ms }) => at_ms)).toEqual([20, 10]);
expect(observed).toHaveLength(22);
if (frames[0] !== undefined) Reflect.set(frames[0], "cursor_x", 999);
expect((await renderer.frames())[0]?.cursor_x).not.toBe(999);
const frame = frames[0];
if (frame === undefined) throw new Error("expected observed frame");
const originalCursor = frame.cursor_x;
Reflect.set(frame, "cursor_x", 999);
const reread = await renderer.frames();
expect(reread).toHaveLength(frames.length);
expect(reread[0]?.cursor_x).toBe(originalCursor);
await renderer.dispose();
const scenario = parseProcessScenario(base);
@@ -55,7 +60,9 @@ it("returns detached terminal and filesystem checkpoint observations", async ()
{ signal: undefined },
);
const first = await checkpoints.finish({ files: [], truncated: false });
if (first[0] !== undefined) Reflect.set(first[0], "name", "tampered");
const checkpoint = first[0];
if (checkpoint === undefined) throw new Error("expected checkpoint");
Reflect.set(checkpoint, "name", "tampered");
const second = await checkpoints.finish({ files: [], truncated: false });
expect(second[0]?.name).toBe("before");
await checkpoints.dispose();
@@ -276,7 +283,7 @@ it("cancels filesystem snapshots before traversing declared roots", async () =>
});
it("parses bounded scenarios and rejects unordered events", () => {
expect(parseProcessScenario(base).timeout_ms).toBe(30_000);
const timeoutMs = parseProcessScenario(base).timeout_ms;
expect(() =>
parseProcessScenario({
...base,
@@ -295,7 +302,7 @@ it("parses bounded scenarios and rejects unordered events", () => {
expect(() =>
parseProcessScenario({
...base,
events: [{ type: "input", at_ms: 31_000, data: "late" }],
events: [{ type: "input", at_ms: timeoutMs + 1, data: "late" }],
}),
).toThrow(/after the scenario timeout/);
});