{"_id":"@archastro/movie-harness","_rev":"4-15dac0acd86d2ee8b8de3fcb56767810","name":"@archastro/movie-harness","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@archastro/movie-harness","version":"0.1.0","keywords":["astroshots","movie","screencast","playwright","pty","harness"],"license":"MIT","_id":"@archastro/movie-harness@0.1.0","maintainers":[{"name":"calvin.grunewald","email":"calvin@archastro.ai"},{"name":"vks-archastro","email":"vks@archastro.ai"},{"name":"tore-archastro","email":"tore@archastro.ai"}],"homepage":"https://github.com/ArchAstro/astroshots#readme","bugs":{"url":"https://github.com/ArchAstro/astroshots/issues"},"bin":{"astroshot-movie":"bin/astroshot-movie.mjs"},"dist":{"shasum":"7923d3db9467a5f629536f547147ee2a74aed39a","tarball":"https://registry.npmjs.org/@archastro/movie-harness/-/movie-harness-0.1.0.tgz","fileCount":32,"integrity":"sha512-AHINxsYAbtQguSgX+oDiG2yF553wqblghfaxRUbpYNiVa1P1NRdSK3MtC4bPfvsZIVLJRWmtvnIzAvTZ1sbmmA==","signatures":[{"sig":"MEYCIQCqnfVzHEoHTu8YehZaTi64pmB/vzKiLJrSqA6rgtHCRwIhAIkMCJvxvA4wIhQmJrfpN6C6y8TTJVn6pCT/VztXOFLI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115587},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.14.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d46c83fc0b007203ad503fc3fef59ca2d962c256","scripts":{"test":"npm run build && vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prepack":"npm run clean && npm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"calvin.grunewald","email":"calvin@archastro.ai"},"repository":{"url":"git+https://github.com/ArchAstro/astroshots.git","type":"git","directory":"packages/movie-harness"},"_npmVersion":"11.17.0","description":"Universal movie capture harness for browser, PTY, desktop, and raw frames into .astroshot/","directories":{},"_nodeVersion":"26.5.0","dependencies":{"yaml":"^2.8.0","playwright":"1.61.1","@xterm/headless":"^5.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.0","typescript":"^5.9.0","@types/node":"^22.0.0"},"optionalDependencies":{"node-pty":"1.2.0-beta.14"},"_npmOperationalInternal":{"tmp":"tmp/movie-harness_0.1.0_1786145823694_0.7629566643527097","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@archastro/movie-harness","version":"0.2.0","keywords":["astroshots","movie","screencast","playwright","pty","harness"],"license":"MIT","_id":"@archastro/movie-harness@0.2.0","maintainers":[{"name":"calvin.grunewald","email":"calvin@archastro.ai"},{"name":"vks-archastro","email":"vks@archastro.ai"},{"name":"tore-archastro","email":"tore@archastro.ai"}],"homepage":"https://github.com/ArchAstro/astroshots#readme","bugs":{"url":"https://github.com/ArchAstro/astroshots/issues"},"bin":{"astroshot-movie":"bin/astroshot-movie.mjs"},"dist":{"shasum":"764779d053b8123f0e0c3539a19e0bc0de093a4b","tarball":"https://registry.npmjs.org/@archastro/movie-harness/-/movie-harness-0.2.0.tgz","fileCount":32,"integrity":"sha512-T4DyqtWNGmihDqjoOMGZoYoHr6RxSWFvN7fMueaYkvw/BASI7gmoNSeUjnp5Jrty0LyRca3Co0zuRAl1WykE/w==","signatures":[{"sig":"MEQCIHp+fHKvWROcPSCjlc5sxkJKuE2b9mMtboVDEdKUs82yAiAr//sNwYJF1UUyGGkiXPoaxv7ePoq0d9Jaeo8GmIoLjQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@archastro%2fmovie-harness@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":123148},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.14.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d50b84239748475d3283edc57ca230bc255d102f","scripts":{"test":"npm run build && vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prepack":"npm run clean && npm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5714a6b0-ba0e-4bc2-9279-a7c2677f1ad4"}},"repository":{"url":"git+https://github.com/ArchAstro/astroshots.git","type":"git","directory":"packages/movie-harness"},"_npmVersion":"11.17.0","description":"Universal movie capture harness for browser, PTY, desktop, and raw frames into .astroshot/","directories":{},"_nodeVersion":"24.18.0","dependencies":{"yaml":"^2.8.0","playwright":"1.61.1","@xterm/headless":"^5.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.0","typescript":"^5.9.0","@types/node":"^22.0.0"},"optionalDependencies":{"node-pty":"1.2.0-beta.14"},"_npmOperationalInternal":{"tmp":"tmp/movie-harness_0.2.0_1786305125348_0.9640739380447088","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@archastro/movie-harness","version":"0.2.1","keywords":["astroshots","movie","screencast","playwright","pty","harness"],"license":"MIT","_id":"@archastro/movie-harness@0.2.1","maintainers":[{"name":"calvin.grunewald","email":"calvin@archastro.ai"},{"name":"vks-archastro","email":"vks@archastro.ai"},{"name":"tore-archastro","email":"tore@archastro.ai"}],"homepage":"https://github.com/ArchAstro/astroshots#readme","bugs":{"url":"https://github.com/ArchAstro/astroshots/issues"},"bin":{"astroshot-movie":"bin/astroshot-movie.mjs"},"dist":{"shasum":"070a3ab3ee788e83d9178f3ccd71eaaea4fea489","tarball":"https://registry.npmjs.org/@archastro/movie-harness/-/movie-harness-0.2.1.tgz","fileCount":32,"integrity":"sha512-cIAxW6fpV9thR9cyQgi0AxJwaVnp0FY9TXjW/s7n0URi+/+k44QuLzG20mGYTIHTTpHfkm5th3YLlVoIt/a8nw==","signatures":[{"sig":"MEYCIQC+aTE6KfZefadKSaD7WaiY0RGo4SWKOniFDkykc2neUwIhAOAqIpKngKb/odIoEzTUQ1MOxn2zgGlReZVZt8fALi+P","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@archastro%2fmovie-harness@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":123148},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.14.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f2573ed7436ed4a76e0b940024006271e625348c","scripts":{"test":"npm run build && vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prepack":"npm run clean && npm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5714a6b0-ba0e-4bc2-9279-a7c2677f1ad4"}},"repository":{"url":"git+https://github.com/ArchAstro/astroshots.git","type":"git","directory":"packages/movie-harness"},"_npmVersion":"11.17.0","description":"Universal movie capture harness for browser, PTY, desktop, and raw frames into .astroshot/","directories":{},"_nodeVersion":"24.19.0","dependencies":{"yaml":"^2.8.0","playwright":"1.61.1","@xterm/headless":"^5.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.0","typescript":"^5.9.0","@types/node":"^22.0.0"},"optionalDependencies":{"node-pty":"1.2.0-beta.14"},"_npmOperationalInternal":{"tmp":"tmp/movie-harness_0.2.1_1787184471978_0.46248430925123696","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"_id":"@archastro/movie-harness@0.2.2","bin":{"astroshot-movie":"bin/astroshot-movie.mjs"},"bugs":{"url":"https://github.com/ArchAstro/astroshots/issues"},"dist":{"shasum":"66129bcbf6a43bb1c02b256da281b9cbbbbea957","tarball":"https://registry.npmjs.org/@archastro/movie-harness/-/movie-harness-0.2.2.tgz","fileCount":32,"integrity":"sha512-kV05pfhEWm1vJrG8KsfOyXrGmj3WzMz67NeenUsRjiS0mOoxDFTudvuHNx513QCbCgKBcD6S/NTIT8p+xPx/BQ==","signatures":[{"sig":"MEQCIHRmRdzltxgHCM6DErBgZHtoYxkVW+6GPpk5BDpFZNljAiA4T/aoDnpn7Oz7ou3yO1M/cnjqiuA9gcW4A8esyrTKsA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD4pCsudgMvTKNbkt2hv82DjoEWU3PCUvvHhBZ7G1SRiAIgRegAIdw+8WI99UkHzmR2xcwSKI8CUjYXB9acIkHwLO0="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@archastro%2fmovie-harness@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":123148},"main":"./dist/index.js","name":"@archastro/movie-harness","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.14.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"5915ef1463a066b84f0c5128c06b53e6b1c3dc11","license":"MIT","scripts":{"test":"npm run build && vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","prepack":"npm run clean && npm run build","typecheck":"tsc --noEmit"},"version":"0.2.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5714a6b0-ba0e-4bc2-9279-a7c2677f1ad4"}},"homepage":"https://github.com/ArchAstro/astroshots#readme","keywords":["astroshots","movie","screencast","playwright","pty","harness"],"repository":{"url":"git+https://github.com/ArchAstro/astroshots.git","type":"git","directory":"packages/movie-harness"},"_npmVersion":"11.17.0","description":"Universal movie capture harness for browser, PTY, desktop, and raw frames into .astroshot/","directories":{},"maintainers":[{"name":"calvin.grunewald","email":"calvin@archastro.ai"},{"name":"vks-archastro","email":"vks@archastro.ai"},{"name":"tore-archastro","email":"tore@archastro.ai"}],"_nodeVersion":"24.20.0","dependencies":{"yaml":"^2.8.0","playwright":"1.61.1","@xterm/headless":"^5.5.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.0","typescript":"^5.9.0","@types/node":"^22.0.0"},"optionalDependencies":{"node-pty":"1.2.0-beta.14"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/movie-harness_0.2.2_1789431045156_0.6216036344595233"}}},"time":{"created":"2026-08-07T23:37:03.511Z","modified":"2026-09-15T00:10:45.667Z","0.1.0":"2026-08-07T23:37:03.855Z","0.2.0":"2026-08-09T19:52:05.487Z","0.2.1":"2026-08-20T00:07:52.136Z","0.2.2":"2026-09-15T00:10:45.278Z"},"bugs":{"url":"https://github.com/ArchAstro/astroshots/issues"},"license":"MIT","homepage":"https://github.com/ArchAstro/astroshots#readme","keywords":["astroshots","movie","screencast","playwright","pty","harness"],"repository":{"url":"git+https://github.com/ArchAstro/astroshots.git","type":"git","directory":"packages/movie-harness"},"description":"Universal movie capture harness for browser, PTY, desktop, and raw frames into .astroshot/","maintainers":[{"name":"calvin.grunewald","email":"calvin@archastro.ai"},{"name":"vks-archastro","email":"vks@archastro.ai"},{"name":"tore-archastro","email":"tore@archastro.ai"}],"readme":"# `@archastro/movie-harness`\n\nUniversal **movie** capture harness for Astroshots. One session API, many\nsources, one `.astroshot/` sink (poster PNG + video + manifest).\n\nAlso exposed as **`astroshot movie`** from `@archastro/astroshot` (same binary\nagents already install for stills).\n\n| Source | Status | Notes |\n|--------|--------|-------|\n| `frames` | **ready** | Push any PNG/JPEG sequence (multi-process CLI) |\n| `browser` | **ready** | Playwright `recordVideo` (headless OK) |\n| `pty` | **ready** | Truecolor SGR → xterm → Chromium samples |\n| `pty-demo` | **ready** | Truecolor smoke without a real program |\n| `desktop.window` | **ready** (macOS) | OS `screencapture -l` + shipped Swift window list |\n| `desktop.display` | stub | Use `desktop.window` or `frames` for now |\n\n## Which source? (for agents)\n\n```bash\nastroshot movie which-source \"record a ratatui TUI with truecolor\"\nastroshot movie which-source \"SwiftUI onboarding window\"\nastroshot movie help-sources\nastroshot movie --help          # full decision table\n```\n\nHard rules:\n\n1. **TUI/CLI color** → `pty` (never `desktop.window` on Terminal/iTerm/Ghostty)\n2. **Web** → `browser` (not a desktop grab of Chrome)\n3. **Native Mac app** → `desktop.window` (`--bundle-id` / `--window-id`)\n4. **Custom pixels** → `frames`\n\n## Why\n\nStills already stream through `.astroshot/`. Journeys need movies. Browser and\nPTY are off-screen (headless Chromium). Native desktop is a separate adapter\nbehind the same session contract.\n\n**PTY color is sacred:** `TERM=xterm-256color`, `COLORTERM=truecolor`, cell paint\nvia xterm (RGB / 256 / 16). Never screenshot Terminal.app.\n\n## CLI\n\n```bash\n# From monorepo after build:\nnode packages/movie-harness/bin/astroshot-movie.mjs --help\n\n# Synthetic frames demo → .astroshot/demo-journey/\nastroshot-movie run --source frames --feature demo-journey --slug flow\n\n# Browser journey\nastroshot-movie run --source browser --feature web --slug home \\\n  --url https://example.com --settle-ms 500\n\n# Truecolor terminal smoke (no fixture program)\nastroshot movie run --source pty-demo --feature tui --slug brand\n\n# Real PTY fixture\nastroshot movie run --source pty --feature tui --slug flow \\\n  --fixture ./fixtures/demo.pty.yaml\n\n# Native macOS window (uses /usr/sbin/screencapture — already on the Mac)\nastroshot movie list-windows\nastroshot movie run --source desktop.window --feature app --slug onboard \\\n  --bundle-id com.example.App --duration-ms 4000 --fps 10\n\n# Multi-process frames\nastroshot movie start --feature custom --slug walk\nastroshot movie push-frame --feature custom --file ./frame.png\nastroshot movie mark --feature custom --slug step-2\nastroshot movie stop --feature custom --status pass\n```\n\n`desktop.window` needs **Screen Recording** permission for your terminal/IDE\n(System Settings → Privacy & Security). Window listing uses Swift\n(`native/macos/WindowTools.swift`) shipped in the package — no extra download.\n\n## Library\n\n```ts\nimport { MovieSession, encodeSolidPng, recordBrowserMovie } from \"@archastro/movie-harness\";\n\nconst session = MovieSession.create({\n  feature: \"install-wizard\",\n  slug: \"journey\",\n  source: \"frames\",\n  size: { width: 1280, height: 720 },\n  fps: 15,\n});\nsession.pushFrame(encodeSolidPng(1280, 720, [124, 92, 255]));\nsession.mark(\"purple\");\nconst artifact = await session.stop({ status: \"pass\" });\n// artifact.posterPath, artifact.videoPath under .astroshot/\n```\n\n## Write contract\n\n```text\n.astroshot/<feature>/\n  manifest.json\n  0001-journey.png     # poster (tray / overlay today)\n  0001-journey.webm    # movie\n```\n\nManifest shot fields (extension):\n\n```json\n{\n  \"kind\": \"movie\",\n  \"file\": \"0001-journey.png\",\n  \"video\": \"0001-journey.webm\",\n  \"duration_ms\": 1200,\n  \"source\": \"browser\",\n  \"chapters\": [{ \"slug\": \"mid\", \"t_ms\": 400 }]\n}\n```\n\nPhase 0: Astroshots app needs no changes (poster is a normal image).  \nPhase 1: open `video` from detail when present.\n\n## Encode\n\n1. **ffmpeg** if on `PATH` (WebM VP9 or MP4 H.264)\n2. Else **Playwright** slideshow → `recordVideo` WebM (no extra native deps)\n\n## Desktop window (macOS)\n\nUses tooling already on the machine:\n\n1. **Window list** — shipped `WindowTools.swift` via `swift` (Xcode CLT)\n2. **Frames** — `/usr/sbin/screencapture -l <windowId>`\n3. **Encode** — same Playwright/ffmpeg path as other sources\n\n```bash\nastroshot movie run --source desktop.window --feature app --slug flow \\\n  --bundle-id ai.archastro.Astroshots --duration-ms 3000\n```\n","readmeFilename":"README.md"}