@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 helpInterface 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 serveThe 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 @runnerLocal 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/startPOST /headless/account/create/finishPOST /headless/account/login/startPOST /headless/account/login/finishPOST /headless/account/credential/add/startPOST /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.
