{"_id":"@a2native/js","_rev":"3-4ae72ad0f41e5956969a67fb4e52072a","name":"@a2native/js","dist-tags":{"latest":"0.1.1"},"versions":{"0.0.1":{"name":"@a2native/js","version":"0.0.1","keywords":["a2native","ai-agent","generative-ui","human-in-the-loop","native-ui","form","egui"],"author":{"name":"a2native contributors"},"license":"Apache-2.0","_id":"@a2native/js@0.0.1","maintainers":[{"name":"weloveayaka","email":"weloveayaka@gmail.com"}],"homepage":"https://a2native.github.io","bugs":{"url":"https://github.com/a2native/a2native-js/issues"},"dist":{"shasum":"1198ae8c01239cd06f45f1ee0a244f81385e14cd","tarball":"https://registry.npmjs.org/@a2native/js/-/js-0.0.1.tgz","fileCount":33,"integrity":"sha512-Im95QPhqOo4/VfcUCCesi04juFn9pCJzuI6u9WlIkUX0Ihrb/66sgX1WIJMSen9ux/ua2hkwArxVa5YSf3wb4Q==","signatures":[{"sig":"MEQCIGr2Rhi8aGLF9MWWVZSnBXaVqrMfxiUTYFoq62m8xs1pAiB31p8F5U5AFDRKBxFUd5+p0F01znDqjuRupTaD2NId+Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88441},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"2dcf135dfb2821858c5c378af4f34fe7663ab22d","scripts":{"test":"node --test","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"weloveayaka","email":"weloveayaka@gmail.com"},"repository":{"url":"git+https://github.com/a2native/a2native-js.git","type":"git"},"_npmVersion":"11.11.0","description":"JavaScript/TypeScript SDK for a2native — native desktop UI forms for AI agents","directories":{},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"optionalDependencies":{"@a2native/a2native":"*"},"_npmOperationalInternal":{"tmp":"tmp/js_0.0.1_1774839106057_0.5818954941196384","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@a2native/js","version":"0.1.0","keywords":["a2native","ai-agent","generative-ui","human-in-the-loop","native-ui","form","egui"],"author":{"name":"a2native contributors"},"license":"Apache-2.0","_id":"@a2native/js@0.1.0","maintainers":[{"name":"weloveayaka","email":"weloveayaka@gmail.com"}],"homepage":"https://a2native.github.io","bugs":{"url":"https://github.com/a2native/a2native-js/issues"},"dist":{"shasum":"47a9cc006185725cfa4715f87a52e97f520e9143","tarball":"https://registry.npmjs.org/@a2native/js/-/js-0.1.0.tgz","fileCount":33,"integrity":"sha512-FbPoHT4AJf+g7uNz7okXGZFcJpr13zEwKb5tCxJbIhYXu5WgMFzLpOgOe8vILU0qJi5oiqr8Lh3RW2FTUwHKsg==","signatures":[{"sig":"MEQCIGnQ3ZDOpXYY6sH07qPaF/QiQBuaPK+0uoM7vD33aE8vAiBNsApTtMiwjRb8sjYL0dchXSsLTzyrwn9RgrFudY9WdQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@a2native%2fjs@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":87268},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"10d22895284065ed411cad86c4e24f6a8af719ae","scripts":{"test":"node --test","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:300a3114-3463-4725-b9bd-ac2b256d897b"}},"repository":{"url":"git+https://github.com/a2native/a2native-js.git","type":"git"},"_npmVersion":"11.9.0","description":"JavaScript/TypeScript SDK for a2native — native desktop UI forms for AI agents","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^25.5.0"},"optionalDependencies":{"@a2native/a2native":"*"},"_npmOperationalInternal":{"tmp":"tmp/js_0.1.0_1774839410578_0.003946497498990453","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@a2native/js","version":"0.1.1","description":"JavaScript/TypeScript SDK for a2native — native desktop UI forms for AI agents","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc","test":"node --test","prepublishOnly":"npm run build"},"keywords":["a2native","ai-agent","generative-ui","human-in-the-loop","native-ui","form","egui"],"author":{"name":"a2native contributors"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/a2native/a2native-js.git"},"homepage":"https://a2native.github.io","bugs":{"url":"https://github.com/a2native/a2native-js/issues"},"engines":{"node":">=18.0.0"},"devDependencies":{"@types/node":"^25.5.0","typescript":"^5.4.0"},"optionalDependencies":{"@a2native/a2native":"*"},"gitHead":"0d67fb91a5adb4755e590886107a70ef996a9e55","_id":"@a2native/js@0.1.1","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-Uj4nvyhSKF0OguwaZGiGdkwZyhqQIO5Z9vjcR3/GyG1ekdaf7gKvR4SMJqPKpUiLZ1sWJzXp5tRKKu/y1bkjLQ==","shasum":"812f2363ef832c74bc3c962b92ddd1d5f95b6ecb","tarball":"https://registry.npmjs.org/@a2native/js/-/js-0.1.1.tgz","fileCount":33,"unpackedSize":87268,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@a2native%2fjs@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEcBTfHsG7GbV/Xh0wUKRqRhoPQEXBKzHbKaybBg6WsmAiBeopfX7zecjwzLexxvVg/tXdXrEpZXLiKO03OC+h0JdA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:300a3114-3463-4725-b9bd-ac2b256d897b"}},"directories":{},"maintainers":[{"name":"weloveayaka","email":"weloveayaka@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/js_0.1.1_1774878697453_0.2869396233735637"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-30T02:51:45.935Z","modified":"2026-03-30T13:51:37.903Z","0.0.1":"2026-03-30T02:51:46.201Z","0.1.0":"2026-03-30T02:56:50.722Z","0.1.1":"2026-03-30T13:51:37.610Z"},"bugs":{"url":"https://github.com/a2native/a2native-js/issues"},"author":{"name":"a2native contributors"},"license":"Apache-2.0","homepage":"https://a2native.github.io","keywords":["a2native","ai-agent","generative-ui","human-in-the-loop","native-ui","form","egui"],"repository":{"type":"git","url":"git+https://github.com/a2native/a2native-js.git"},"description":"JavaScript/TypeScript SDK for a2native — native desktop UI forms for AI agents","maintainers":[{"name":"weloveayaka","email":"weloveayaka@gmail.com"}],"readme":"# @a2native/js\n\n> JavaScript/TypeScript SDK for **[a2native](https://github.com/a2native/a2native)** — native desktop UI forms for AI agents.\n\n[![npm](https://img.shields.io/npm/v/@a2native/js)](https://www.npmjs.com/package/@a2native/js)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n[![CI](https://github.com/a2native/a2native-js/actions/workflows/ci.yml/badge.svg)](https://github.com/a2native/a2native-js/actions)\n\na2native lets AI agents collect structured user input via **native OS windows** — one JSON in, one native form, one JSON out. No browser, no server, no chat loop.\n\nThis SDK wraps a2native's three integration modes so Node.js / Bun agents can use it without shell-scripting.\n\n---\n\n## Prerequisites\n\nInstall the `a2n` binary (one of):\n\n```bash\n# via npm (installs the right platform binary automatically)\nnpm install @a2native/a2native\n\n# or download from GitHub Releases\n# https://github.com/a2native/a2native/releases\n\n# or build from source\ncargo install a2native\n```\n\n---\n\n## Installation\n\n```bash\nnpm install @a2native/js\n```\n\nRequires **Node.js ≥ 18**.\n\n---\n\n## Usage\n\n### Mode 1 — One-shot (`showForm`)\n\nSpawn a window, wait for the user, get the result. The simplest integration.\n\n```typescript\nimport { showForm } from '@a2native/js';\n\nconst result = await showForm({\n  title: \"Deploy to production?\",\n  components: [\n    {\n      id: \"env\",\n      type: \"radio-group\",\n      label: \"Target environment\",\n      options: [\n        { value: \"prod\",  label: \"Production\" },\n        { value: \"stag\",  label: \"Staging\" },\n        { value: \"dev\",   label: \"Development\" },\n      ],\n    },\n    {\n      id: \"confirm\",\n      type: \"checkbox\",\n      label: \"I understand this will affect live users\",\n    },\n    { id: \"go\", type: \"button\", label: \"Deploy\", action: \"submit\" },\n  ],\n});\n\nif (result.status === \"submitted\") {\n  console.log(\"Environment:\", result.values.env);  // \"prod\"\n  console.log(\"Confirmed:\",   result.values.confirm); // true\n}\n```\n\n### Mode 2 — Session (multi-turn)\n\nKeep the same window open across multiple agent turns. No flicker, no re-spawn — inspired by [agent-browser](https://github.com/vercel-labs/agent-browser)'s client-daemon pattern.\n\n```typescript\nimport { Session } from '@a2native/js';\n\nconst session = new Session(); // auto-generates a UUID\n\n// Turn 1 — window opens\nconst step1 = await session.show({\n  title: \"New project — Step 1/3: Basics\",\n  components: [\n    { id: \"name\",  type: \"text-field\", label: \"Project name\", required: true },\n    { id: \"lang\",  type: \"dropdown\",   label: \"Language\",\n      options: [{ value: \"ts\", label: \"TypeScript\" }, { value: \"py\", label: \"Python\" }] },\n    { id: \"next\",  type: \"button\", label: \"Next →\", action: \"submit\" },\n  ],\n});\n\n// Turn 2 — same window, form replaced, no flicker\nconst step2 = await session.show({\n  title: \"New project — Step 2/3: Config\",\n  components: [\n    { id: \"port\",  type: \"number-input\", label: \"Port\", default_value: 3000, min: 1024, max: 65535 },\n    { id: \"next\",  type: \"button\", label: \"Next →\", action: \"submit\" },\n  ],\n});\n\n// Turn 3\nconst step3 = await session.show({\n  title: \"New project — Step 3/3: Confirm\",\n  components: [\n    { id: \"summary\", type: \"markdown\", content: `**${step1.values.name}** on port ${step2.values.port}` },\n    { id: \"ok\",  type: \"button\", label: \"Create project\", action: \"submit\" },\n    { id: \"cancel\", type: \"button\", label: \"Cancel\", action: \"cancel\" },\n  ],\n});\n\nawait session.close(); // closes the window\n```\n\nYou can also provide an explicit session ID (useful for reconnecting to an existing window):\n\n```typescript\nconst session = new Session({ sessionId: \"my-stable-id\" });\n```\n\n### Mode 3 — SSE daemon (HTTP / Server-Sent Events)\n\nStart the daemon separately, then push forms over HTTP. Ideal when your agent is a long-running server process.\n\n```bash\n# Start the daemon (no initial form needed)\na2n --session my-session --sse 8080\n```\n\n```typescript\nimport { SseClient } from '@a2native/js';\n\nconst client = new SseClient({ url: \"http://127.0.0.1:8080\" });\n\n// Optional liveness check\nawait client.health();\n\nconst result = await client.showForm({\n  title: \"Approve pull request merge?\",\n  components: [\n    { id: \"pr\",     type: \"text\",    content: \"PR #42: feat: add caching layer\" },\n    { id: \"action\", type: \"radio-group\", label: \"Decision\",\n      options: [{ value: \"merge\", label: \"Merge\" }, { value: \"close\", label: \"Close\" }] },\n    { id: \"note\",   type: \"textarea\", label: \"Comment (optional)\" },\n    { id: \"ok\",     type: \"button\", label: \"Submit\", action: \"submit\" },\n  ],\n});\n```\n\n### Mode 4 — WebSocket daemon\n\nFor persistent bidirectional connections. One connection handles multiple sequential forms.\n\n```bash\na2n --session my-session --ws 8081\n```\n\n```typescript\nimport { WsClient } from '@a2native/js';\n\nconst client = new WsClient({ url: \"ws://127.0.0.1:8081\" });\nawait client.connect();\n\n// Send multiple forms on the same connection\nconst r1 = await client.showForm({ title: \"Step 1\", components: [...] });\nconst r2 = await client.showForm({ title: \"Step 2\", components: [...] });\n\nclient.close();\n```\n\n---\n\n## API Reference\n\n### `showForm(spec, options?)`\n\n| Param | Type | Description |\n|-------|------|-------------|\n| `spec` | `FormSpec` | The form to display |\n| `options.binary` | `string` | Override path to `a2n` binary |\n\nReturns `Promise<FormResult>`.\n\n### `new Session(options?)`\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `sessionId` | `string` | UUID for the session (auto-generated if omitted) |\n| `binary` | `string` | Override path to `a2n` binary |\n\nMethods: `show(spec): Promise<FormResult>`, `close(): Promise<void>`\n\n### `new SseClient(options)`\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `url` | `string` | Base URL, e.g. `\"http://127.0.0.1:8080\"` |\n| `timeout` | `number` | Request timeout ms (default 300 000) |\n\nMethods: `health(): Promise<void>`, `showForm(spec): Promise<FormResult>`\n\n### `new WsClient(options)`\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `url` | `string` | WebSocket URL, e.g. `\"ws://127.0.0.1:8081\"` |\n| `timeout` | `number` | Response timeout ms (default 300 000) |\n\nMethods: `connect(): Promise<void>`, `showForm(spec): Promise<FormResult>`, `close(): void`\n\n---\n\n## `FormSpec` and component types\n\nFull TypeScript types are exported. Quick reference:\n\n```typescript\ninterface FormSpec {\n  title?:      string;\n  timeout?:    number;   // auto-close after N seconds\n  theme?:      { dark_mode?: boolean; accent_color?: string };\n  components:  Component[];\n}\n\ninterface FormResult {\n  status: \"submitted\" | \"cancelled\" | \"timeout\";\n  values: Record<string, unknown>;\n}\n```\n\n**Component types:**\n\n| Type | Output | Notes |\n|------|--------|-------|\n| `text-field` | string | Single-line text |\n| `textarea` | string | Multi-line, `rows` option |\n| `password` | string | Masked input |\n| `number-input` | number | `min` / `max` / `step` |\n| `dropdown` | string | ComboBox |\n| `checkbox` | boolean | Single toggle |\n| `toggle` | boolean | On/off switch |\n| `checkbox-group` | string[] | Multi-select |\n| `radio-group` | string | Single-select |\n| `slider` | number | Range slider |\n| `rating` | number | Star rating (0 = unset) |\n| `date-picker` | string | YYYY-MM-DD |\n| `time-picker` | string | HH:MM |\n| `file-upload` | string | Native file dialog |\n| `button` | — | `action: \"submit\"` \\| `\"cancel\"` |\n| `card` | — | Nested vertical group |\n| `row` | — | Horizontal layout |\n| `text` / `markdown` / `code` / `image` / `divider` | — | Display only |\n\n---\n\n## Security\n\nEvery a2native window shows an amber warning banner:\n\n> ⚠ This interface was generated by an AI agent. Your input will be sent to the agent and may be seen by others — do not enter sensitive information.\n\nThis banner cannot be suppressed by the form spec. See the [security section](https://a2native.github.io/#security) of the docs.\n\n**Never** use a2native to collect real passwords, private keys, or payment information.\n\n---\n\n## Related\n\n- **[a2native](https://github.com/a2native/a2native)** — the core Rust binary\n- **[a2native.github.io](https://a2native.github.io)** — documentation site\n- **[Google A2UI](https://github.com/google/a2ui)** — declarative JSON UI spec (a2native is compatible)\n- **[AG-UI](https://github.com/ag-ui-protocol/ag-ui)** — streaming web agent protocol (a2native is compatible)\n\n---\n\n## License\n\nApache-2.0 © a2native contributors\n","readmeFilename":"README.md"}