npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ducking-mind/proxy-app-sdk

v0.1.0

Published

TypeScript SDK for Proxy apps using HTTP APIs and compatible iframe Bridge runtimes

Readme

@ducking-mind/proxy-app-sdk

SDK for Proxy App Market applications. It supports the published v1 iframe compatibility runtime and the v2 standalone HTTP runtime described in app/docs/HTTP_RUNTIME_DESIGN.md.

Current status: local development defaults to HTTP for both models and application resources. Update Gateway and Admin before restarting the CLI. Published iframe apps retain Bridge. Full page-runtime publishing and PKCE login are still migration targets; the local login handoff is unchanged.

import { createAppClient } from '@ducking-mind/proxy-app-sdk'

// Generated by `proxy-app init` and replaced after `proxy-app create`.
const app = createAppClient('app.proxy.local.generated')

const profile = await app.user.getProfile()
const capabilities = await app.platform.capabilities()
const value = await app.platform.call('theme.read')

// Model/media APIs use the short-lived in-memory App Session issued by the
// platform host. The SDK never persists this token.
const models = await app.api.request('/models')

// Binary media endpoints are decoded automatically from Content-Type. An
// explicit responseType is also available when the response format is known.
const video = await app.api.request<Blob>('/videos/video-id/content', {
  responseType: 'blob',
})

for await (const event of app.api.stream('/responses/stream', {
  method: 'POST',
  body: JSON.stringify({ model: 'your-model', input: 'Hello' }),
})) {
  console.log(event.data)
}

Bridge failures are returned as AppSdkError instances with stable code values such as APP_BRIDGE_TIMEOUT, APP_BRIDGE_DISCONNECTED, and APP_BRIDGE_ERROR. The SDK derives the host origin from the iframe referrer; pass targetOrigin explicitly when the host uses a non-standard embedding setup.

Data-plane failures preserve the platform error code, HTTP status, response X-Request-ID (as requestId) and structured response payload (as details). app.api.request() accepts responseType: 'auto' | 'json' | 'text' | 'blob' | 'arrayBuffer' | 'response'; auto selects JSON/text/blob from Content-Type. JSON request bodies automatically receive Content-Type: application/json when the caller did not provide a header. FormData, URLSearchParams and binary bodies are left to fetch so multipart boundaries and media types remain intact.

The SDK uses HTTP locally and in direct runtime, and the narrow Bridge protocol only when embedded. It never reads Portal tokens. Pricing, supplier costs, platform fees and commission settlement are platform infrastructure; they are not exposed as SDK methods or app runtime APIs. When embedded by Portal, the host handshake supplies an ast_ App Session; app.api.request() attaches it only to the allow-listed /v1 data plane (the Session's gateway_url already contains that prefix). Applications should handle APP_SESSION_UNAVAILABLE and ask the host to retry the handshake when a session expires. app.platform.createSession() proactively refreshes the in-memory session. Automatic replay is limited to a single 401 that explicitly identifies an App Session expiry before execution; provider authentication failures and requests with unknown execution state are returned without replay.

For local development, use proxy-app dev. It does not require AppHost, but it does require a linked platform app and the user must sign in when the app first requests a platform capability. The CLI starts a loopback Relay; the Relay uses the signed-in user's short-lived App Session and forwards requests to the real Gateway. Models, provider routing, quota and billing are real. Import the Vite helper in vite.config.ts:

import { defineConfig } from 'vite'
import { createPlatformDevProxy } from '@ducking-mind/proxy-app-sdk/vite'

export default defineConfig({
  base: './',
  server: {
    host: '127.0.0.1',
    proxy: createPlatformDevProxy(),
  },
})

Start the app with:

proxy-app dev <app-dir>

The first data-plane request may require a platform user sign-in. The SDK opens the real platform login flow automatically; applications should also expose a user-initiated fallback for browsers that block automatic popups:

try {
  await app.api.request('/models')
} catch (error) {
  // Render this action only for APP_LOGIN_REQUIRED or APP_LOGIN_POPUP_BLOCKED.
  await app.auth.login()
}

app.auth.login() opens the current platform login handoff from a user gesture. app.auth.logout() clears the local relay session and revokes the current App Session, allowing another platform user to sign in. These methods are local development helpers; embedded production apps authenticate through the host.

dev does not require PROXY_ACCESS_TOKEN; that credential is only the current user's control-plane session for commands such as create, upload and publish. The local Relay uses PROXY_API_BASE_URL and PROXY_PORTAL_URL only as platform endpoints, then obtains the user session through the browser login flow.

The CLI sets private process-only variables for the Vite helper. The default paths are /v1/* and /api/app-runtime/v1/*, including local login status. --legacy-bridge exposes the old /__platform/bridge for old SDKs; a new SDK must also set localBridgePath explicitly to select that compatibility mode. /__platform/v1 and /__platform/auth remain aliases for old clients. Application resource requests are forwarded as HTTP, without Bridge RPC. Portal tokens stay in the CLI/Relay memory and are never injected into the app. The helper is not included in the production app bundle. npm run dev remains useful for UI-only work but cannot call platform APIs without the Relay.

Standalone integrations can use the direct runtime with an externally supplied App Session and refresh callback. The platform App PKCE flow is not yet built. For both Gateway and Runtime APIs, request a v2 token through the existing session issuance API with runtime_protocol: 2:

const app = createAppClient('app.proxy.example', {
  runtime: 'direct',
  appSession,
  refreshAppSession,
  runtimeBasePath: '/api/app-runtime/v1',
})
const models = await app.api.request('/models')

ast_* is the user's runtime session, not a developer key. The Gateway still enforces installation, version, scopes, quota, billing and provider routing. Direct runtime also supports profile, capabilities, preferences and storage over HTTP. Storage retains the existing app/user data and last-write-wins semantics; CAS and development namespaces are not implemented. notification.show is not available over HTTP; render application notifications locally. Portal management APIs remain inaccessible to AppSession tokens.

After build, pack and upload, use My Apps > Test version for real permissions, models, provider routing, quota and billing.

Full platform documentation:

../docs/APP_MARKET.md