Libraries
Blupinta’s libraries call the public API for you: the sign-in at auth.blupinta.app, every
operation with its types, a home followed as its versions are saved. They only talk to the API: a home’s checks are
Blupinta’s, asked through POST /v1/homes/check. Their sources are public, at
github.com/blupinta/blupinta, under the Apache 2.0 licence. The examples below
are the ones the libraries’ own checks compile, so they work as written.
TypeScript: @blupinta/sdk
Section titled “TypeScript: @blupinta/sdk”For the browser and Node: every operation called by its id (client.call('getHome', …)), with its parameters and
answer typed; a refusal is a BlupintaError with the API’s code; watchHome shows the copy kept on the device, then
each new version.
npm install @blupinta/sdk// A dashboard's first lines with @blupinta/sdk: connect with a code typed on a phone, then show the home and follow// each new version. Typechecked with the package, so it can't drift from it.import { createClient } from '@blupinta/sdk'import { startDeviceSignIn, tokenKeeper } from '@blupinta/sdk/auth'import { memoryHomeStore, watchHome } from '@blupinta/sdk/watch'
const signIn = await startDeviceSignIn({ scope: 'openid offline_access projects:read' })console.log(`Open ${signIn.verificationUri} and type ${signIn.userCode}`)const tokens = await signIn.tokens()
const client = createClient({ token: tokenKeeper({ clientId: 'device', tokens }) })const { rows } = await client.call('listProjects')const project = rows[0]if (!project) throw new Error('no project was chosen')
watchHome(client, project.id, { store: memoryHomeStore(), onHome: (saved) => console.log(`${saved.home.name}: version ${saved.number}`), onError: (error) => console.error(error.code, error.problems),})React: @blupinta/react
Section titled “React: @blupinta/react”useHome, useProject and useRevisions in a BlupintaProvider, and useSignIn for the browser’s sign-in with PKCE,
finished by itself on your app’s return address (Registering it).
// A page with @blupinta/react: sign in with Blupinta, then show a home that updates as versions are saved.// Typechecked with the package, so it can't drift from it.import { useHome } from '@blupinta/react/hooks'import { BlupintaProvider } from '@blupinta/react/provider'import { useSignIn } from '@blupinta/react/sign-in'import { createClient } from '@blupinta/sdk'import { useMemo } from 'react'
export function App() { const session = useSignIn({ clientId: 'app_…', // registered in Blupinta's settings, Developers redirectUri: 'https://your.app/', // one of its return addresses: this page finishes the sign-in scope: 'openid offline_access projects:read', }) const client = useMemo(() => createClient({ token: session.token }), [session.token]) if (!session.tokens) return ( <button type="button" onClick={session.signIn}> Sign in with Blupinta </button> ) return ( <BlupintaProvider client={client}> <Home projectId="…" /> </BlupintaProvider> )}
function Home({ projectId }: { projectId: string }) { const { data, error, isLoading } = useHome(projectId) if (isLoading) return <p>Loading…</p> if (error) return <p>{error.code}</p> return ( <h1> {data?.home.name}, version {data?.number} </h1> )}The command line: blupinta
Section titled “The command line: blupinta”npx @blupinta/cli login # a code typed in your browser; the tokens in your keychainnpx @blupinta/cli pull "My home" --dir home # home.json and its filesnpx @blupinta/cli check home/home.json # Blupinta's checks on the filenpx @blupinta/cli push --dir home -m "Moved the sofa"npx @blupinta/cli watch "My home" --exec "./redraw.sh"Every command takes --json, for scripts and agents. A push made on an old version is refused, saying who saved after
it.
AI agents: @blupinta/mcp
Section titled “AI agents: @blupinta/mcp”An MCP server: an agent lists the projects, reads a home and its versions, checks a home and saves a new version. Sign
in with npx @blupinta/cli login, then add it to the agent:
{ "mcpServers": { "blupinta": { "command": "npx", "args": ["-y", "@blupinta/mcp"] } } }Python: blupinta
Section titled “Python: blupinta”Every operation in blupinta.v1, called through Blupinta.call (or acall, with asyncio); the device flow, a home
followed with watch_home, webhooks checked with is_signed_webhook.
pip install blupinta"""A script's first lines with blupinta: connect with a code typed on a phone, list the projects, read a home, thenfollow each new version. Compiled by the package's tests, so it can't drift from it."""
from blupinta import Blupinta, TokenKeeper, start_device_sign_in, watch_homefrom blupinta.v1.api.projects import get_home, list_projects
signing_in = start_device_sign_in("openid offline_access projects:read")print(f"Open {signing_in.verification_uri} and type {signing_in.user_code}")tokens = signing_in.tokens()
with Blupinta(TokenKeeper(tokens, client_id="device")) as blupinta: project = blupinta.call(list_projects).rows[0] saved = blupinta.call(get_home, project.id) print(f"{saved.home['name']}: version {saved.number}") for saved, _etag in watch_home(blupinta, project.id, etag=None): print(f"new version {saved.number}: {saved.message}")