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

@glyphteck/veyl

v0.2.0

Published

Programmable Bun client for Veyl accounts, vaults, chat, and wallet payments.

Readme

Veyl Headless

apps/headless is the programmable Bun client for terminal users, scripts, automations, and MCP servers.

It is a client, not a privileged backend. Headless accounts own their local machine credential, vault secret, wallet seed, and chat key material. The server should only create public account records, verify login challenges, and store encrypted vault material it cannot decrypt.

The package also supports real passkey accounts from a terminal. Passkey create/login opens the configured Veyl web origin for the WebAuthn ceremony, receives a Firebase token on a localhost callback, then pairs a local machine credential to that signed-in account for future CLI sessions. True machine-created headless accounts remain separate from passkey-created accounts.

Run the public package with Bun:

bunx @glyphteck/veyl help

Interface Boundary

headless is the client boundary. CLI, MCP, scripts, and future channel adapters are interfaces on top of the same client, not separate clients with their own account, vault, chat, or money logic.

  • src/client.js: shared programmable API.
  • src/cli.js: terminal command wrapper.
  • src/mcp.js: MCP wrapper.
  • src/passkey.js: browser-assisted passkey bridge for terminal flows.

The npm package publishes bundled dist entrypoints so callers do not need Veyl's monorepo workspace packages installed locally.

API Shape

The public surface should stay simple enough to infer from the command names:

import { open } from '@glyphteck/veyl';

const veyl = await open();

const account = await veyl.account.create({ username: 'runner' });
const vault = await veyl.vault.create();
await veyl.vault.unlock();
await veyl.chat.send('@alice', 'hello');
const messages = await veyl.chat.read('@alice');
await veyl.chat.reply({ peer: '@alice', messageId: messages.messages[0].id }, 'got it');
await veyl.chat.react('@alice', messages.messages[0].id, '+1');
await veyl.chat.save('@alice', messages.messages[0].id);
await veyl.chat.retention('@alice', '24h');

await veyl.listen({
  compact: true,
  incomingOnly: true,
  onEvent: async (event) => {
    if (event.type !== 'message') return;
    await veyl.chat.reactTo(event, '+1');
    await veyl.chat.reply(event, 'thanks');
  },
});

const receive = await veyl.money.receive();
const invoice = await veyl.money.invoice(1000, { memo: 'coffee' });
await veyl.money.send('@alice', 1000);
await veyl.money.request('@alice', 1000);
const transactions = await veyl.money.transactions();

console.log(account.uid, vault.vaultSecret, receive.address, invoice.encodedInvoice, messages, transactions);

CLI names should mirror the JS API:

veyl create --passkey @runner
veyl send @alice 1000
veyl request @alice 1000
veyl receive
veyl claim
veyl invoice 100 "coffee"
veyl pay-invoice <invoice>
veyl withdraw <address> 1000
veyl balance
veyl read @alice
veyl say @alice "hello"
veyl reply @alice <message-id> "got it"
veyl react @alice <message-id> +1
veyl save @alice <message-id>
veyl retention @alice 24h
veyl listen --agent

veyl account create @runner
veyl account create --passkey @runner
veyl account login @runner
veyl account login --passkey @runner
veyl vault create
veyl vault unlock
veyl vault lock
veyl chat read @alice
veyl chat send @alice "hello"
veyl chat reply @alice <message-id> "got it"
veyl chat react @alice <message-id> +1
veyl chat react-to @alice <message-id> +1
veyl chat unreact @alice <message-id>
veyl chat save @alice <message-id>
veyl chat unsave @alice <message-id>
veyl chat delete @alice <message-id>
veyl chat delete-chat @alice
veyl chat retention @alice seen
veyl money receive
veyl money balance
veyl money claim
veyl money invoice 100 "coffee"
veyl money pay-invoice <invoice>
veyl money send @alice 1000
veyl money request @alice 1000
veyl money withdraw-quote <address> 1000
veyl money withdraw <address> 1000
veyl transactions
veyl mcp serve

The same commands are exposed as MCP tools through veyl mcp serve.

veyl listen keeps one auth and vault session alive in the current process, then emits newline-delimited JSON events for new messages and wallet transfers. It is the terminal event-stream path for agents that do not want to speak MCP. Use veyl listen --agent for compact peer-authored message events with replyTo and reactTo handles shaped as { peer, messageId }.

Passkey browser auth defaults to https://veyl.glyphteck.com. Use --web-url or VEYL_WEB_URL to point the CLI at another allowed passkey origin, such as a local dev host or a future dedicated auth host.

From this monorepo, use the root dev helper instead of the package filter form:

bun dev headless regtest create --passkey @runner

Local Secrets

The package creates a local profile under ~/.veyl by default. It stores the machine credential and, unless saveSecret: false or --no-save-secret is used, the generated vault secret. Passkey flows pair and store a local machine credential by default so later CLI commands do not need a browser prompt; use --no-save-credential or saveCredential: false to return the credential material without saving the private key locally. Callers that already have a secret manager can pass VEYL_HOME, VEYL_PROFILE, VEYL_VAULT_SECRET, or explicit SDK options and store those secrets elsewhere.

Glyphteck-owned Google Secret Manager bot seeds are not used by this public path.

Backend Contract

The backend only verifies machine-key challenges and issues Firebase custom tokens:

  • POST /headless/account/create/start
  • POST /headless/account/create/finish
  • POST /headless/account/login/start
  • POST /headless/account/login/finish
  • POST /headless/account/credential/add/start
  • POST /headless/account/credential/add/finish

Machine-created accounts are marked as bots on their public profile so app users can tell that the account is bot-operated. Passkey-created CLI accounts are not marked as bots.

Vault secrets, wallet entropy, chat seeds, Spark wallet boot, and message/payment signing all run locally in this package through shared Veyl primitives.

Generic unlocked-account actions live in @veyl/shared/account/actions; this package only wraps them with headless account auth, local profile storage, CLI commands, and MCP serving.