@glyphteck/veyl 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -100
- package/dist/cli.js +1050 -929
- package/dist/index.js +935 -569
- package/docs/agents.md +235 -0
- package/docs/api.md +647 -0
- package/docs/cli.md +169 -0
- package/docs/mcp.md +54 -0
- package/package.json +2 -1
package/docs/agents.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Agent Guide
|
|
2
|
+
|
|
3
|
+
Read this file first when operating Veyl from an agent, worker, terminal daemon, or script.
|
|
4
|
+
|
|
5
|
+
## Shape
|
|
6
|
+
|
|
7
|
+
- Package: `@glyphteck/veyl`.
|
|
8
|
+
- Runtime: Bun.
|
|
9
|
+
- Core interface: JavaScript API from `import { open } from '@glyphteck/veyl'`.
|
|
10
|
+
- Human shell interface: `veyl ...`.
|
|
11
|
+
- MCP interface: `veyl mcp serve`, a local stdio server started by the MCP host.
|
|
12
|
+
- CLI paths, CLI help, MCP schemas, MCP dispatch, and the exported command inventory come from `src/commands.js`.
|
|
13
|
+
- Hosted remote MCP: none. Veyl does not run an MCP endpoint on Vercel.
|
|
14
|
+
- Best default for agents: use the JS API for long-running sessions. Use CLI for one-off shell commands. Use MCP only when the agent host already speaks MCP tools.
|
|
15
|
+
|
|
16
|
+
Headless is a client, not a backend bypass. Auth, vault decrypt, wallet signing, and chat encryption happen locally. Machine-created accounts are public `bot` profiles. Passkey-created CLI accounts are normal human accounts.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun add @glyphteck/veyl
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
One-off:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bunx @glyphteck/veyl help
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Local State
|
|
31
|
+
|
|
32
|
+
Profiles live in `~/.veyl`, or `VEYL_HOME`.
|
|
33
|
+
|
|
34
|
+
Important env:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
VEYL_HOME=/secure/veyl-home
|
|
38
|
+
VEYL_PROFILE=runner
|
|
39
|
+
VEYL_NETWORK=REGTEST
|
|
40
|
+
VEYL_VAULT_SECRET=...
|
|
41
|
+
VEYL_WEB_URL=https://veyl.glyphteck.com
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Use `REGTEST` for dev/smoke accounts and `MAINNET` for real funds.
|
|
45
|
+
|
|
46
|
+
## Create Account
|
|
47
|
+
|
|
48
|
+
Machine account:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import { open } from '@glyphteck/veyl';
|
|
52
|
+
|
|
53
|
+
const veyl = await open({ profile: 'runner', network: 'REGTEST' });
|
|
54
|
+
await veyl.account.create({ username: 'runner', saveCredential: true });
|
|
55
|
+
await veyl.vault.create({ saveSecret: true });
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Passkey account from CLI:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
veyl --network REGTEST create --passkey @runner
|
|
62
|
+
veyl --network REGTEST vault create
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The passkey flow opens a browser URL. After WebAuthn succeeds, the CLI stores a local machine credential for later CLI sessions.
|
|
66
|
+
|
|
67
|
+
## Start Session
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const veyl = await open({ profile: 'runner', network: 'REGTEST' });
|
|
71
|
+
await veyl.account.login();
|
|
72
|
+
await veyl.vault.unlock();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Most chat and money methods auto-unlock if a vault secret is saved or available in `VEYL_VAULT_SECRET`, but long-running agents should login and unlock once.
|
|
76
|
+
|
|
77
|
+
Lock when done:
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
await veyl.vault.lock();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Message Loop
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
await veyl.listen({
|
|
87
|
+
agent: true,
|
|
88
|
+
interval: 3000,
|
|
89
|
+
replay: false,
|
|
90
|
+
onEvent: async (event) => {
|
|
91
|
+
if (event.type !== 'message') return;
|
|
92
|
+
if (event.message.type === 'txt') {
|
|
93
|
+
await veyl.chat.reply(event, `received: ${event.message.text}`);
|
|
94
|
+
await veyl.chat.reactTo(event, '+1');
|
|
95
|
+
}
|
|
96
|
+
if (event.message.type === 'req') {
|
|
97
|
+
await veyl.money.pay(event.message.requestId);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`agent: true` means compact incoming-only message events. It avoids rereading chats after every event.
|
|
104
|
+
|
|
105
|
+
Compact ready event:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
{ type: 'ready', ts, account: { uid, username, network, auth, bot, unlocked } }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Compact message event:
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
{
|
|
115
|
+
type: 'message',
|
|
116
|
+
ts,
|
|
117
|
+
peer: '@alice',
|
|
118
|
+
replyTo: { peer: '@alice', messageId: 'abc123' },
|
|
119
|
+
reactTo: { peer: '@alice', messageId: 'abc123' },
|
|
120
|
+
chat: { id, peer, username, peerChatPK, peerUid, unseen, ts },
|
|
121
|
+
message: {
|
|
122
|
+
id, cid, chatId, from, type, ts, peerChatPK,
|
|
123
|
+
text, amountSats, paid, requestId, replyId
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Transaction event:
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
{ type: 'transaction', ts, transaction }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Error event:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
{ type: 'error', ts, peer, message }
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Chat Methods
|
|
141
|
+
|
|
142
|
+
Peers may be `@username`, chat public keys, wallet public keys, or a listen event target.
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
await veyl.chat.list({ count: 20 });
|
|
146
|
+
await veyl.chat.read('@alice', { count: 30, markRead: true });
|
|
147
|
+
await veyl.chat.send('@alice', 'hello');
|
|
148
|
+
await veyl.chat.reply(event, 'reply text');
|
|
149
|
+
await veyl.chat.reply({ peer: '@alice', messageId: 'abc123' }, 'reply text');
|
|
150
|
+
await veyl.chat.reactTo(event, '+1');
|
|
151
|
+
await veyl.chat.react('@alice', 'abc123', '+1');
|
|
152
|
+
await veyl.chat.unreact('@alice', 'abc123');
|
|
153
|
+
await veyl.chat.save('@alice', 'abc123');
|
|
154
|
+
await veyl.chat.unsave('@alice', 'abc123');
|
|
155
|
+
await veyl.chat.delete('@alice', 'abc123');
|
|
156
|
+
await veyl.chat.deleteChat('@alice', { cleanup: true });
|
|
157
|
+
await veyl.chat.retention('@alice', 'seen'); // or '24h'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Use `reply(event, ...)` and `reactTo(event, ...)` inside listeners. They use the event's embedded peer/message target and avoid another lookup.
|
|
161
|
+
|
|
162
|
+
## Money Methods
|
|
163
|
+
|
|
164
|
+
Amounts are sats.
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
await veyl.money.balance();
|
|
168
|
+
await veyl.money.receive();
|
|
169
|
+
await veyl.money.claim({ count: 100 });
|
|
170
|
+
await veyl.money.transactions({ count: 50, offset: 0 });
|
|
171
|
+
|
|
172
|
+
await veyl.money.send('@alice', 1000);
|
|
173
|
+
const req = await veyl.money.request('@alice', 1000);
|
|
174
|
+
await veyl.money.pay(req.message.requestId);
|
|
175
|
+
|
|
176
|
+
await veyl.money.invoice(1000, { memo: 'coffee' });
|
|
177
|
+
await veyl.money.payInvoice(invoice, { type: 'lightning', maxFeeSats: 20 });
|
|
178
|
+
await veyl.money.lightningQuote(invoice, { amountSats: 1000 });
|
|
179
|
+
await veyl.money.lightningPay(invoice, { amountSats: 1000, maxFeeSats: 20 });
|
|
180
|
+
await veyl.money.lightningReceive(id);
|
|
181
|
+
await veyl.money.lightningSend(id);
|
|
182
|
+
|
|
183
|
+
await veyl.money.withdrawQuote(address, 10000);
|
|
184
|
+
await veyl.money.withdrawPrepare(address, 10000, { speed: 'MEDIUM' });
|
|
185
|
+
await veyl.money.withdraw(address, 10000, { speed: 'MEDIUM' });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## CLI Cheat Sheet
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
veyl create @runner
|
|
192
|
+
veyl create --passkey @runner
|
|
193
|
+
veyl login [@runner]
|
|
194
|
+
veyl vault create
|
|
195
|
+
veyl unlock
|
|
196
|
+
veyl balance
|
|
197
|
+
veyl receive
|
|
198
|
+
veyl claim
|
|
199
|
+
veyl say @alice "hello"
|
|
200
|
+
veyl reply @alice <message-id> "got it"
|
|
201
|
+
veyl react @alice <message-id> +1
|
|
202
|
+
veyl send @alice 1000
|
|
203
|
+
veyl request @alice 1000
|
|
204
|
+
veyl pay <request-id>
|
|
205
|
+
veyl transactions
|
|
206
|
+
veyl listen --agent
|
|
207
|
+
veyl mcp serve
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
CLI results are JSON. `veyl listen` emits newline-delimited JSON events.
|
|
211
|
+
|
|
212
|
+
## MCP
|
|
213
|
+
|
|
214
|
+
Run locally:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
veyl mcp serve
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
The MCP host starts that command, sends JSON-RPC over stdin, and reads JSON-RPC over stdout. Users host it themselves by running the package on their own machine or worker. Veyl does not expose a remote MCP URL.
|
|
221
|
+
|
|
222
|
+
Use MCP when the agent host prefers tools. Use the JS API when you control the runtime loop.
|
|
223
|
+
|
|
224
|
+
## Docs
|
|
225
|
+
|
|
226
|
+
- Full JS API: `docs/api.md`
|
|
227
|
+
- CLI: `docs/cli.md`
|
|
228
|
+
- MCP: `docs/mcp.md`
|
|
229
|
+
|
|
230
|
+
## Limits
|
|
231
|
+
|
|
232
|
+
- `listen` is polling-based. There is no backend wake-ping contract yet.
|
|
233
|
+
- Headless sends text chat and payment requests. Media summaries may appear in reads, but public media upload helpers are not exposed yet.
|
|
234
|
+
- Machine-created headless accounts are intentionally separate from passkey-created human accounts.
|
|
235
|
+
- Passkey create/login needs a browser-capable environment.
|