{"_id":"@absolutejs/demo","name":"@absolutejs/demo","dist-tags":{"latest":"0.0.1-beta.0"},"versions":{"0.0.1-beta.0":{"name":"@absolutejs/demo","version":"0.0.1-beta.0","description":"Automated product-demo runtime for AbsoluteJS — drives browser and desktop workflows, records the screen, adds presenter-style highlights, and coordinates AI voiceover.","repository":{"type":"git","url":"https://github.com/absolutejs/demo.git"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./playwright":{"import":"./dist/playwright.js","types":"./dist/playwright.d.ts"},"./desktop":{"import":"./dist/desktop.js","types":"./dist/desktop.d.ts"},"./recording":{"import":"./dist/recording.js","types":"./dist/recording.d.ts"},"./script":{"import":"./dist/script.js","types":"./dist/script.d.ts"},"./auth":{"import":"./dist/auth.js","types":"./dist/auth.d.ts"},"./voiceover":{"import":"./dist/voiceover.js","types":"./dist/voiceover.d.ts"},"./manifest":{"import":"./dist/manifest.js","types":"./dist/manifest.d.ts"},"./timeline":{"import":"./dist/timeline.js","types":"./dist/timeline.d.ts"},"./composition":{"import":"./dist/composition.js","types":"./dist/composition.d.ts"},"./sync-plan":{"import":"./dist/syncPlan.js","types":"./dist/syncPlan.d.ts"}},"license":"BSL-1.1","author":"Alex Kahn","scripts":{"build":"rm -rf dist && bun build ./src/index.ts ./src/playwright.ts ./src/desktop.ts ./src/recording.ts ./src/script.ts ./src/auth.ts ./src/voiceover.ts ./src/manifest.ts ./src/timeline.ts ./src/composition.ts ./src/syncPlan.ts --root src --outdir dist --target bun --external playwright --external @absolutejs/auth --external @absolutejs/sync --external @absolutejs/voice --external @absolutejs/voice-tester --external @absolutejs/ai && bun x tsc --emitDeclarationOnly --project tsconfig.json","format":"absolute prettier --write","lint":"absolute eslint","release":"bun run format && bun run build && bun publish","test":"bun test","typecheck":"absolute typecheck"},"peerDependencies":{"@absolutejs/ai":">=0.0.5","@absolutejs/auth":">=0.44.0","@absolutejs/sync":">=1.8.0","@absolutejs/voice":">=0.0.22-beta.550","@absolutejs/voice-tester":">=0.0.4-beta.0","playwright":">=1.40.0"},"peerDependenciesMeta":{"@absolutejs/ai":{"optional":true},"@absolutejs/auth":{"optional":true},"@absolutejs/sync":{"optional":true},"@absolutejs/voice":{"optional":true},"@absolutejs/voice-tester":{"optional":true},"playwright":{"optional":true}},"devDependencies":{"@absolutejs/absolute":"0.19.0-beta.1009","@absolutejs/ai":"*","@absolutejs/auth":"0.44.1","@absolutejs/sync":"1.8.0","@absolutejs/voice":"0.0.22-beta.550","@absolutejs/voice-tester":"0.0.4-beta.2","@eslint/js":"^10.0.1","@types/bun":"1.3.9","@typescript-eslint/parser":"^8.57.2","eslint":"^10.1.0","eslint-plugin-absolute":"0.11.0-beta.3","eslint-plugin-promise":"^7.2.1","eslint-plugin-security":"^4.0.0","globals":"^17.4.0","playwright":"^1.57.0","prettier":"^3.4.0","typescript":"^5.9.3","typescript-eslint":"^8.57.2"},"_id":"@absolutejs/demo@0.0.1-beta.0","_integrity":"sha512-Ht/RD0ogImqZUyXr+mg3I0cIxlCdgfBI/3RKrT8wnzkhc8Q4TM/7dKzd+TOD2QluH4NLMnzqoDQXdtslpnQIgw==","_nodeVersion":"24.3.0","_npmVersion":"10.8.3","shasum":"238acf35b5b23131c4282c15f128d9c0bbbdb357","dist":{"integrity":"sha512-Ht/RD0ogImqZUyXr+mg3I0cIxlCdgfBI/3RKrT8wnzkhc8Q4TM/7dKzd+TOD2QluH4NLMnzqoDQXdtslpnQIgw==","shasum":"238acf35b5b23131c4282c15f128d9c0bbbdb357","tarball":"https://registry.npmjs.org/@absolutejs/demo/-/demo-0.0.1-beta.0.tgz","fileCount":40,"unpackedSize":137974,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEdOT5nvhYNLrc7GkGEUpZ6Uvr9jvDcLJcdZ8blvCzmEAiEAifRIegNYJ8bQF9mFv8F2Bn9Kg0FNklhlw5LGAW45GbE="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/demo_0.0.1-beta.0_1780073655697_0.5175475407553154"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T16:54:15.576Z","0.0.1-beta.0":"2026-05-29T16:54:15.848Z","modified":"2026-05-29T16:54:16.041Z"},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"description":"Automated product-demo runtime for AbsoluteJS — drives browser and desktop workflows, records the screen, adds presenter-style highlights, and coordinates AI voiceover.","repository":{"type":"git","url":"https://github.com/absolutejs/demo.git"},"author":"Alex Kahn","license":"BSL-1.1","readme":"# @absolutejs/demo\n\nAutomated product-demo runtime for AbsoluteJS.\n\n`@absolutejs/demo` is the orchestration layer for enterprise-grade AI demos:\ndrive the product, narrate with AI voiceover, record the screen, and draw\npresenter-style highlights over the UI.\n\nIt is intentionally adapter-first. Playwright is excellent for web apps, but\nreal demos often need Discord, Google Meet, native apps, screen switching, and\nOS-level focus control. This package keeps those capabilities behind stable\ninterfaces so each environment can provide the right driver.\n\n## Install\n\n```sh\nbun add @absolutejs/demo\n```\n\nInstall optional drivers only when needed:\n\n```sh\nbun add -d playwright\n```\n\n## Browser demo\n\n```ts\nimport {\n\tcreateDemoRunner,\n\tgoto,\n\tnarrate,\n\tsignIn,\n\tspotlight,\n\twriteDemoManifest,\n} from \"@absolutejs/demo\";\nimport { createDemoAuthDriver } from \"@absolutejs/demo/auth\";\nimport {\n\tcreatePlaywrightDemoSession,\n} from \"@absolutejs/demo/playwright\";\n\nconst session = await createPlaywrightDemoSession({\n\theadless: false,\n\trecordVideoDir: \".demo-video\",\n\tscreenshotDir: \".demo-shots\",\n});\n\nconst runner = createDemoRunner({\n\tauth: createDemoAuthDriver(),\n\tbrowser: session.browserDriver,\n\tannotations: session.annotations,\n\tvoiceover: {\n\t\tspeak: async ({ text }) => {\n\t\t\tconsole.log(\"[voiceover]\", text);\n\t\t},\n\t},\n});\n\nconst report = await runner.run({\n\tprofiles: [\n\t\t{\n\t\t\tid: \"ae\",\n\t\t\tkind: \"absolute\",\n\t\t\tbaseUrl: \"http://localhost:3000\",\n\t\t\temail: { env: \"DEMO_EMAIL\" },\n\t\t\tpassword: { env: \"DEMO_PASSWORD\" },\n\t\t\tafterLoginUrl: \"http://localhost:3000/pipeline\",\n\t\t},\n\t],\n\tid: \"crm-demo\",\n\ttitle: \"CRM demo\",\n\tsteps: [\n\t\tsignIn(\"ae\"),\n\t\tnarrate(\"Here is the live pipeline view.\"),\n\t\tgoto(\"http://localhost:3000/pipeline\"),\n\t\tspotlight({\n\t\t\tselector: \"[data-demo='pipeline-total']\",\n\t\t\tlabel: \"Revenue at risk\",\n\t\t\tdurationMs: 1800,\n\t\t}),\n\t],\n});\n\nawait writeDemoManifest(report, \".demo-artifacts/crm-demo.manifest.json\");\nconsole.log(report.status, report.artifacts);\nawait session.close();\n```\n\n## Authentication\n\nSign-in is profile-based. Declare named credential `profiles` on the script and\ntrigger them with `signIn(\"<id>\")` steps. Credentials are passed as env\n*references* (`{ env: \"VAR_NAME\" }`) — the runner resolves them at sign-in time,\nso real secrets never enter the script object, the manifest, or the recording.\nA missing env var throws an error naming the variable, never its value.\n\nThree profile kinds cover the common cases:\n\n- `absolute` — a site you own that uses `@absolutejs/auth`. Posts to the auth\n  login route (`/auth/login` by default, or `routes.login`).\n- `form` — **any** site, including ones you don't control. Drives the real login\n  UI: navigates to `loginUrl`, fills `fields` (with secrets from env), clicks\n  `submitSelector`, and confirms via a `success` selector and/or URL. A `steps`\n  array handles multi-step flows (username → Next → password).\n- `storage-state` — reuse a saved Playwright session; applied when the browser\n  context is created.\n\n```ts\n// A third-party site you do not control:\n{\n\tid: \"saucedemo\",\n\tkind: \"form\",\n\tloginUrl: \"https://www.saucedemo.com/\",\n\tfields: [\n\t\t{ selector: \"#user-name\", value: { env: \"SAUCE_USERNAME\" } },\n\t\t{ selector: \"#password\", value: { env: \"SAUCE_PASSWORD\" } },\n\t],\n\tsubmitSelector: \"#login-button\",\n\tsuccess: { selector: \".inventory_list\" },\n}\n```\n\nSee `examples/demo/src/sign-in.ts` for runnable own-site (`absolute`) and\nthird-party (`form`) examples. For bespoke auth screens, provide your own\n`DemoAuthDriver`.\n\n## Desktop control\n\nUse `createCommandDesktopDriver` for native-app automation. On macOS,\n`createMacDesktopDriver()` can open/focus apps and send basic keystrokes via\n`osascript`; Linux and Windows can provide equivalent command factories using\n`xdotool`, `wmctrl`, PowerShell, or a UIA bridge.\n\n```ts\nimport { createDemoRunner, focusApp, openApp, wait } from \"@absolutejs/demo\";\nimport { createMacDesktopDriver } from \"@absolutejs/demo/desktop\";\n\nconst runner = createDemoRunner({\n\tdesktop: createMacDesktopDriver(),\n});\n\nawait runner.run({\n\tid: \"discord-demo\",\n\tsteps: [\n\t\topenApp(\"Discord\"),\n\t\twait(1000),\n\t\tfocusApp(\"Discord\"),\n\t],\n});\n```\n\n## Recording\n\n`createCommandRecorder` wraps tools such as `ffmpeg`, OBS command bridges, or\nplatform-native recorders. Browser-only demos can also use Playwright video and\nadd the resulting path as a recording artifact.\n\n## Voiceover\n\nElevenLabs is the recommended tier for client demos — Deepgram Aura is faster\nand cheaper but reads more synthetic. `createElevenLabsVoiceover` defaults to an\nAmerican voice (Rachel) and the tuned runtime settings from the Dealroom voice\nupgrade (`eleven_flash_v2_5`, stability `0.42`, similarity boost `0.78`, style\n`0.35`, speaker boost on), rendering high-fidelity `mp3_44100_128` files.\n\n```ts\nimport {\n\tcreateElevenLabsVoiceover,\n\twithPronunciationAliases,\n\twithRenderCache,\n} from \"@absolutejs/demo/voiceover\";\n\n// Premium voiceover, with demo-vocabulary pronunciation fixes (onSpark,\n// AbsoluteJS, PDL, …) applied before TTS, and identical lines cached so\n// re-runs skip re-synthesis.\nconst voiceover = withRenderCache(\n\twithPronunciationAliases(\n\t\tcreateElevenLabsVoiceover({\n\t\t\tapiKey: process.env.ELEVENLABS_API_KEY!,\n\t\t\toutputDir: \".demo-voiceover\",\n\t\t}),\n\t),\n\t{ cacheDir: \".demo-voiceover/cache\", salt: \"rachel:flash_v2_5\" },\n);\n```\n\n`input.emotion` (`neutral` | `confident` | `excited` | `calm`) nudges the\nexpressive controls. The narration `voice` field overrides the voice id per\nline. Both pronunciation aliasing and the render cache are provider-agnostic\nwrappers — they work over the Aura and generic-adapter voiceovers too.\n\nSet `ELEVENLABS_API_KEY` (restricted synthesis key) for rendering;\n`ELEVENLABS_ADMIN_API_KEY` (write-capable) is reserved for future\npronunciation-dictionary sync and should stay out of the synthesis path. See\n`.env.example`.\n\n## Composition\n\n`composeDemoWithFFmpeg` creates a final video artifact from the run recording\nand voiceover artifacts. It uses the demo timeline to offset narration against\nthe recorded screen.\n\n```ts\nimport { composeDemoWithFFmpeg } from \"@absolutejs/demo/composition\";\n\nconst finalVideo = await composeDemoWithFFmpeg(report, {\n\toutputPath: \".demo-artifacts/crm-demo.mp4\",\n});\n```\n","readmeFilename":"README.md","_rev":"1-77b31179040e39af07356174ceac3586"}