@glyphteck/veyl 0.2.0 → 0.3.1

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/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.