{"_id":"@arlopass/web-sdk","name":"@arlopass/web-sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@arlopass/web-sdk","version":"0.1.0","license":"MIT","type":"module","publishConfig":{"access":"public","provenance":true},"repository":{"type":"git","url":"git+https://github.com/arlopass/arlopass.git","directory":"packages/web-sdk"},"homepage":"https://github.com/arlopass/arlopass/tree/main/packages/web-sdk#readme","bugs":{"url":"https://github.com/arlopass/arlopass/issues"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint \"src/**/*.ts\"","test":"vitest run --passWithNoTests"},"dependencies":{"@arlopass/protocol":"workspace:*","@arlopass/telemetry":"workspace:*"},"_id":"@arlopass/web-sdk@0.1.0","gitHead":"524008c81190adecca51ec54fbe99d77ebdd056f","description":"Connect web applications to a user's own AI providers without handling their credentials.","_nodeVersion":"22.22.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-s6oHKNC9FcYdF6pq5m9hTHXYE2hviWhzQNnLgyM2kWhO8L6Elra7cPi4TTpdLkN/VZDffxIkY0qv0LVb4pjiIg==","shasum":"acc30d3ec415db4f7fba364e65457c8a2bc6c4fa","tarball":"https://registry.npmjs.org/@arlopass/web-sdk/-/web-sdk-0.1.0.tgz","fileCount":55,"unpackedSize":222849,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arlopass%2fweb-sdk@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD92bJdavQ+HBMFAkCXgjRE9U9q7MOkM6ABwB/V6EvOHQIgeNNFy5gRD9/7rQegC6t3YMXk0KXNN2ede9Wu7uLhsdU="}]},"_npmUser":{"name":"davidszakacs","email":"szakacs_david@hotmail.com"},"directories":{},"maintainers":[{"name":"davidszakacs","email":"szakacs_david@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web-sdk_0.1.0_1774820870034_0.3400908356851913"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-29T21:47:49.970Z","0.1.0":"2026-03-29T21:47:50.166Z","modified":"2026-03-29T21:47:50.561Z"},"maintainers":[{"name":"davidszakacs","email":"szakacs_david@hotmail.com"}],"description":"Connect web applications to a user's own AI providers without handling their credentials.","homepage":"https://github.com/arlopass/arlopass/tree/main/packages/web-sdk#readme","repository":{"type":"git","url":"git+https://github.com/arlopass/arlopass.git","directory":"packages/web-sdk"},"bugs":{"url":"https://github.com/arlopass/arlopass/issues"},"license":"MIT","readme":"# @arlopass/web-sdk\n\nConnect web applications to a user's own AI providers without handling their credentials.\n\n```ts\nimport { ArlopassClient } from \"@arlopass/web-sdk\";\n\nconst client = new ArlopassClient({ transport: window.arlopass, origin: location.origin });\n\nawait client.connect({ appId: \"com.acme.app\" });\n\nconst { providers } = await client.listProviders();\nawait client.selectProvider({\n  providerId: providers[0].providerId,\n  modelId: providers[0].models[0],\n});\n\nconst reply = await client.chat.send({\n  messages: [{ role: \"user\", content: \"Hello!\" }],\n});\nconsole.log(reply.message.content);\n\nawait client.disconnect();\n```\n\nThe Arlopass extension injects a transport at `window.arlopass`. Install with:\n\n```bash\npnpm add @arlopass/web-sdk\n```\n\n## Streaming\n\n```ts\nfor await (const event of client.chat.stream({\n  messages: [{ role: \"user\", content: \"Explain zero-trust architecture\" }],\n})) {\n  if (event.type === \"chunk\") process.stdout.write(event.delta);\n  if (event.type === \"done\") console.log(\"\\n[done]\");\n}\n```\n\n---\n\n## API Reference\n\n### `ArlopassClient`\n\nManages the full lifecycle: connect, select provider, chat, stream, disconnect.\n\n```ts\nconst client = new ArlopassClient(options: ArlopassClientOptions);\n```\n\n#### Constructor Options (`ArlopassClientOptions`)\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `transport` | `ArlopassTransport` | — | Required. Transport implementation |\n| `origin` | `string` | — | Page origin for permission scoping |\n| `protocolVersion` | `string` | `\"1.0.0\"` | Protocol version to negotiate |\n| `timeoutMs` | `number` | `5000` | Request timeout in milliseconds |\n| `envelopeTtlMs` | `number` | `60000` | Envelope time-to-live |\n| `nonce` | `string` | — | Override nonce (testing) |\n| `now` | `() => Date` | `() => new Date()` | Clock override (testing) |\n| `randomId` | `() => string` | — | ID generator override (testing) |\n| `defaultCapabilities` | `readonly ProtocolCapability[]` | All capabilities | Capabilities to request on connect |\n| `defaultProviderId` | `string` | — | Auto-select provider on connect |\n| `defaultModelId` | `string` | — | Auto-select model on connect |\n| `tracing` | `TelemetryTracing` | — | Trace span propagation |\n\n#### Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `state` | `ClientState` | Current connection state |\n| `sessionId` | `SessionId \\| undefined` | Active session ID |\n| `selectedProvider` | `{ providerId: string; modelId: string } \\| undefined` | Active provider/model |\n\n#### Methods\n\n**`connect(options: ConnectOptions): Promise<ConnectResult>`**\n\nEstablish a session with the Arlopass wallet.\n\n```ts\ntype ConnectOptions = { appId: string; origin?: string; timeoutMs?: number }\ntype ConnectResult = { sessionId: SessionId; capabilities: readonly ProtocolCapability[]; protocolVersion: string; correlationId: CorrelationId }\n```\n\n**`listProviders(): Promise<ListProvidersResult>`**\n\nDiscover available providers and their models. Requires connected state.\n\n```ts\ntype ListProvidersResult = { providers: readonly ProviderDescriptor[]; correlationId: CorrelationId }\ntype ProviderDescriptor = { providerId: string; providerName: string; models: readonly string[] }\n```\n\n**`selectProvider(input: SelectProviderInput): Promise<SelectProviderResult>`**\n\nSet the active provider and model for chat operations.\n\n```ts\ntype SelectProviderInput = { providerId: string; modelId: string }\ntype SelectProviderResult = { providerId: string; modelId: string; correlationId: CorrelationId }\n```\n\n**`chat.send(input: ChatInput, options?: ChatOperationOptions): Promise<ChatSendResult>`**\n\nSend a message and receive a complete response.\n\n```ts\ntype ChatInput = { messages: readonly ChatMessage[] }\ntype ChatMessage = { role: ChatRole; content: string }\ntype ChatRole = \"system\" | \"user\" | \"assistant\"\ntype ChatSendResult = { message: ChatMessage; correlationId: CorrelationId }\n```\n\n**`chat.stream(input: ChatInput, options?: ChatOperationOptions): AsyncIterable<ChatStreamEvent>`**\n\nStream a response with real-time chunks.\n\n```ts\ntype ChatStreamEvent =\n  | { type: \"chunk\"; delta: string; index: number; correlationId: CorrelationId }\n  | { type: \"done\"; correlationId: CorrelationId }\n```\n\n**`disconnect(): Promise<void>`**\n\nTear down the session and reset state.\n\n---\n\n### `ArlopassStateMachine`\n\nTracks client connection state with validated transitions.\n\n```ts\nimport { ArlopassStateMachine } from \"@arlopass/web-sdk\";\n\nconst sm = new ArlopassStateMachine(\"disconnected\");\nsm.canTransition(\"connecting\"); // true\nsm.transition(\"connecting\");    // \"connecting\"\nsm.state;                       // \"connecting\"\nsm.history;                     // [{ from: \"disconnected\", to: \"connecting\", timestamp }]\n```\n\n**States (`ClientState`):**\n\n`\"disconnected\"` | `\"connecting\"` | `\"connected\"` | `\"degraded\"` | `\"reconnecting\"` | `\"failed\"`\n\n---\n\n### `ArlopassTransport`\n\nInterface for routing requests to the Arlopass wallet. The extension injects one at `window.arlopass`.\n\n```ts\ninterface ArlopassTransport {\n  request<TReq, TRes>(request: TransportRequest<TReq>): Promise<TransportResponse<TRes>>;\n  stream<TReq, TRes>(request: TransportRequest<TReq>): Promise<TransportStream<TRes>>;\n  disconnect?(sessionId: string): Promise<void>;\n}\n\ntype TransportRequest<TPayload> = { envelope: ProtocolEnvelopePayload<TPayload>; timeoutMs?: number }\ntype TransportResponse<TPayload> = { envelope: ProtocolEnvelopePayload<TPayload> }\ntype TransportStream<TPayload> = AsyncIterable<TransportResponse<TPayload>>\n```\n\n---\n\n### Error Classes\n\nAll errors extend `ArlopassSDKError`:\n\n```ts\nclass ArlopassSDKError extends Error {\n  machineCode: SDKMachineCode;\n  reasonCode: ProtocolReasonCode;\n  retryable: boolean;\n  correlationId: string | undefined;\n  details: SDKErrorDetails | undefined;\n}\n```\n\n| Class | When thrown |\n|-------|------------|\n| `ArlopassStateError` | Operating in wrong state (e.g., `chat.send` before `connect`) |\n| `ArlopassInvalidStateTransitionError` | Invalid state transition attempted |\n| `ArlopassProtocolBoundaryError` | Protocol-level failures from wallet/bridge |\n| `ArlopassTransportError` | Transport layer failures |\n| `ArlopassTimeoutError` | Request or stream exceeded timeout |\n\n**SDK Machine Codes (`SDK_MACHINE_CODES`):**\n\n| Code | Meaning |\n|------|---------|\n| `ARLOPASS_SDK_INVALID_STATE_TRANSITION` | Attempted illegal state change |\n| `ARLOPASS_SDK_INVALID_STATE_OPERATION` | Operation not valid for current state |\n| `ARLOPASS_SDK_MISSING_PROVIDER_SELECTION` | Chat called without selecting provider |\n| `ARLOPASS_SDK_PROTOCOL_VIOLATION` | Protocol envelope violated constraints |\n| `ARLOPASS_SDK_TRANSPORT_ERROR` | Transport request failed |\n\n---\n\n### Helper Functions\n\n**`withTimeout<T>(operation: Promise<T>, timeoutMs: number, timeoutMessage: string): Promise<T>`**\n\nRace a promise against a timeout. Throws `ArlopassTimeoutError` on expiry.\n\n**`withStreamTimeout<T>(stream: TransportStream<T>, timeoutMs: number, timeoutMessage: string): AsyncIterable<TransportResponse<T>>`**\n\nWrap an async iterable with per-chunk timeout enforcement.\n\n**`normalizeSDKError(error: unknown, fallback: SDKErrorFallback): ArlopassSDKError`**\n\nWrap any thrown value in the appropriate `ArlopassSDKError` subclass based on protocol error codes.\n\n---\n\n### Constants\n\n| Constant | Value | Description |\n|----------|-------|-------------|\n| `SDK_PROTOCOL_VERSION` | `\"1.0.0\"` | Protocol version the SDK implements |\n| `DEFAULT_REQUEST_TIMEOUT_MS` | `5000` | Default request timeout |\n| `DEFAULT_ENVELOPE_TTL_MS` | `60000` | Default envelope time-to-live |\n| `SDK_ENVELOPE_NONCE` | `\"AQIDBAUGBwgJCgsMDQ4PEA\"` | Default nonce |\n\n---\n\n### Dependencies\n\n- `@arlopass/protocol` — Envelope, capability model, error taxonomy\n- `@arlopass/telemetry` — Request metrics and trace propagation\n","readmeFilename":"README.md","_rev":"1-604c2570d176dc035162ab4a5ea33181"}