Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
6.9 KiB
fxnode orb workflow
This repository is a TypeScript node-editor library with a browser client and worker-owned authority. This guide is the operating checklist for Amp orbs and future implementation threads.
Environment and services
- No
.envfile or secrets are required for development or tests. .agents/setupinstalls the exactpackage-lock.jsondependency tree, Chromium, Firefox, and their Linux runtime dependencies. It then typechecks the repository and starts declared services..agents/resumeonly reconciles declared services. Keep it fast and idempotent; do not install dependencies there..amp/services.yamldeclares the examples gallery. Useamp orb services ensureto start it and obtain its portal. Inspect it withamp orb service status examplesandamp orb service logs examples.- Run
npm run examplesoutside an orb when a local Vite server is sufficient. Vite usesexamples/as its root. - Generated
.amp/portals/manifests and resume logs are local runtime state and must not be committed.
Architectural invariants
Preserve these unless the user explicitly requests an architectural change:
- The main-thread root is a message-passing facade. Graph state, composition, history, commands, selection behavior, and rendering authority live in the worker.
- A root can be headless or own multiple attached views. Views share graph/history while camera, selection, pointer lane, host requests, and render barriers remain view-local.
- The worker lazily owns one
OffscreenCanvasatlas and one retained worker 2D context. Views occupy atlas slots; paint and cropped bitmap production are serialized. The final detach releases the atlas. - Main-thread HTML canvases necessarily have one presentation context each. Do not describe the design as one context across the entire browser application.
- RAF polling remains continuous for responsive shared-pointer-lane input, but layout, atlas paint, bitmap creation, worker frame messages, and presentation remain dirty/on-demand.
FxNodeView.setViewport()is acknowledged and transactional. Runtime hosts await it before changing canvas backing dimensions. Surface generations and dimensions reject stale or incoherent frames.- The core library does not register DOM listeners, observers, menus, modals, or file pickers. Those are application policy. The example browser host demonstrates explicit cleanup and opt-in detach-on-disconnect behavior.
- Composition definitions are collections installed through
setTheme,setHeaderStyles,composeSocket, andcomposeNode; initial graph layout is applied afterward withsetState. - Durable save/load uses command journals plus save-time composition.
setState/getStateare portable layout/state APIs, not the preferred persistence mechanism. - Commands distinguish durable graph mutations from transient UI previews and provide undo/redo semantics.
The implementation history and Oracle-reviewed atlas/multi-view decisions are in the originating Amp thread. Treat the current code, tests, README, and authored docs as authoritative when they differ from historical discussion.
Design and implementation process
- Read the nearest code, applicable
AGENTS.md, public types, protocol validators, and focused tests before editing. - Prefer the smallest change at the existing ownership boundary. Remove obsolete paths rather than layering adapters.
- For cross-layer architectural work, ask Oracle for a phased plan. Before each phase ask for concrete implementation details; after each phase ask for a high-confidence blocker review. Address blockers before moving on.
- Keep protocol boundaries exact and hostile-safe. A public type change normally requires protocol validation, client, worker, declaration/type tests, docs, and real-worker browser coverage.
- Keep DOM policy outside
src/browser/client.ts. Extend application hosts or examples instead of secretly attaching listeners inattachView(). - For rendering changes, reason explicitly about device/logical coordinates, DPR, atlas slot clipping, transforms,
putImageDataignoring clip/CTM, bitmap ownership/closing, frame ACKs, and context-loss generations. - Do not revert unrelated worktree changes. Do not commit generated
.ampruntime files. Commit/push only when asked.
Verification ladder
Choose the narrowest useful checks while iterating, then broaden according to blast radius.
Fast and focused
npx prettier --write <touched-files>
npm run typecheck -- --pretty false
node --import tsx --test test/<focused>.test.ts
npx playwright test test/browser/<focused>.spec.ts --config playwright.config.ts --project chromium
For multi-view or worker lifecycle changes, run focused tests in both supported engines:
npx playwright test \
test/browser/client-multiview.spec.ts \
test/browser/worker-multiview.spec.ts \
--config playwright.config.ts
Test groups
npm test # Node unit, protocol, layout, persistence, atlas, and scheduler tests
npm run test:browser # Real browser behavior in Chromium and Firefox
npm run test:visual # Core Chromium screenshot baselines
npm run test:examples:visual # Documentation/example screenshots
npm run check:performance # Large-layout performance budgets
npm run check:docs # TypeDoc generation plus VitePress build
npm run check:readme # README structure and link checks
npm run check:package # Packed-package and worker-asset smoke test
npm run build # Vite library bundle and declaration build
Full release gate
Run this after shared contracts, architecture, rendering, examples, persistence, or release-facing docs change:
npm run release:check
git diff --check
npm run format:check
release:check includes typecheck, all unit/browser/visual/example tests, fixture and reference checks, performance,
build, docs, README, composition, and package smoke verification.
Visual review policy
- Never update screenshots merely to make a failure green.
- Inspect expected, actual, and diff images under
test-results/. Confirm whether changes are intended and localized. - Use
npm run test:visual:updateonly for reviewed core baseline changes. - Use
npm run test:examples:visual:updateonly for reviewed example/documentation image changes. - Re-run the corresponding non-update command after refreshing a baseline.
- Save one-off user-review screenshots under
.amp/in/artifacts/; keep transient inspection images intest-results/.
Documentation expectations
- README and VitePress learning docs explain user workflows and ownership boundaries.
- TypeDoc is the API contract; regenerate it with
npm run docs:apiafter public type changes. - Examples import library source through
@lib/, never relative../srcpaths. - Keep the examples gallery linked to every standalone application and relevant focused scene.