@glyphteck/veyl 0.61.12 → 0.63.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/docs/agents.md CHANGED
@@ -6,7 +6,7 @@ The SDK is not a privileged backend. It authenticates, decrypts the vault, signs
6
6
 
7
7
  ## Setup
8
8
 
9
- Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/legal#terms) and [Community Rules](https://veyl.glyphteck.com/community-rules).
9
+ Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/terms#terms), which include the community rules.
10
10
 
11
11
  ```js
12
12
  import { open } from '@glyphteck/veyl';
package/docs/api.md CHANGED
@@ -188,7 +188,7 @@ An unknown Spark send, payment-request payment, invoice payment, or withdrawal o
188
188
 
189
189
  ## Account
190
190
 
191
- Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/legal#terms) and [Community Rules](https://veyl.glyphteck.com/community-rules).
191
+ Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/terms#terms), which include the community rules.
192
192
 
193
193
  ```js
194
194
  const accountKey = await veyl.account.create({
@@ -210,7 +210,7 @@ await veyl.account.delete({ confirm: true });
210
210
  - `login({ username?, key?, saveKey? })` authenticates with an account key. The key can instead come from `open({ accountKey })` or `VEYL_ACCOUNT_KEY`.
211
211
  - `loginPasskey({ username?, webUrl?, onUrl? })` authenticates through the browser-assisted passkey flow.
212
212
  - `me` returns the local account summary without forcing login.
213
- - `terms` reports the canonical Terms/Community Rules links, whether the account's acceptance is current, and when it last accepted an agreement.
213
+ - `terms` reports the canonical Terms link, whether the account's acceptance is current, and when it last accepted the Terms.
214
214
  - `acceptTerms()` records the current agreement through the shared user owner without forcing a vault unlock.
215
215
  - `logout` signs out and tears down only this runtime.
216
216
  - `logoutAll` revokes every product session generation, tears down this runtime locally, and stops a persistent CLI owner after its in-flight work drains.
@@ -435,7 +435,7 @@ await veyl.listen({
435
435
  });
436
436
  ```
437
437
 
438
- `listen` subscribes to the shared live chat-list and transfer-store owners. It emits `ready`, `message`, `message-delete`, `transaction`, and `error` events. Message events carry a stable `chatId`, verified actor/member summaries, and a qualified message target. Compact, incoming-only events and transient chat subscriptions are the defaults: the encrypted chat list acts as a wake index, so a changed chat opens briefly, processes its current and history pages, and releases instead of retaining one listener per chat. Set `compact: false`, `incomingOnly: false`, or `persistentChats: true` only when the caller needs those broader behaviors. A headless viewer may set `read: true, relayReads: true`; the listener then advances each peer read from its existing decrypted batch through a short encrypted live-room lease before emitting the event, while the durable write remains coalesced.
438
+ `listen` subscribes to the shared live chat-list and transfer-store owners. It emits `ready`, `message`, `message-delete`, `transaction`, and `error` events. Message events carry a stable `chatId`, verified actor/member summaries, and a qualified message target. Replies retain `message.replyId`; reaction controls are emitted as `message.type === 'rxn'` with `reactTo` pointing at the original message, so agents can preserve the exact action instead of flattening it into presentation text. Compact, incoming-only events and transient chat subscriptions are the defaults: the encrypted chat list acts as a wake index, so a changed chat opens briefly, processes its current and history pages, and releases instead of retaining one listener per chat. Set `compact: false`, `incomingOnly: false`, or `persistentChats: true` only when the caller needs those broader behaviors. A headless viewer may set `read: true, relayReads: true`; the listener then advances each peer read from its existing decrypted batch through a short encrypted live-room lease before emitting the event, while the durable write remains coalesced.
439
439
 
440
440
  Use `listen` for account-wide agent wakeups. Use `chat.enterById` when an agent is actively inside any notes/direct/group chat; use `chat.enter(peer)` only as a canonical-direct convenience.
441
441
 
package/docs/cli.md CHANGED
@@ -32,7 +32,7 @@ veyl vault lock
32
32
  veyl vault export [--key VALUE]
33
33
  ```
34
34
 
35
- Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/legal#terms) and [Community Rules](https://veyl.glyphteck.com/community-rules). `account accept-terms` accepts their current revisions for an existing account. `account terms` reports the canonical links and whether the account's acceptance is current without unlocking the vault.
35
+ Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/terms#terms), which include the community rules. `account accept-terms` accepts the current Terms for an existing account. `account terms` reports the canonical link and whether the account's acceptance is current without unlocking the vault.
36
36
 
37
37
  `vault export` returns the Spark mnemonic. Treat its JSON output as a secret.
38
38
 
@@ -119,6 +119,37 @@ function sendAttachmentToEventChat(client, event, attachment, options) {
119
119
  : client.chat.sendAttachment(event.peer, attachment, options);
120
120
  }
121
121
 
122
+ function eventMessageTarget(event, messageId) {
123
+ const id = String(messageId || '').trim();
124
+ if (!id) return null;
125
+ return {
126
+ chatId: eventChatId(event) || null,
127
+ peer: event.peer || null,
128
+ messageId: id,
129
+ };
130
+ }
131
+
132
+ function sendEchoText(account, client, event) {
133
+ const options = { cid: botActionCid(event, 'echo', account) };
134
+ const replyTarget = eventMessageTarget(event, event.message?.replyId);
135
+ return replyTarget
136
+ ? client.chat.reply(replyTarget, event.message.text || '', options)
137
+ : sendToEventChat(client, event, event.message.text || '', options);
138
+ }
139
+
140
+ function mirrorReaction(account, client, event) {
141
+ const payload = event.message?.payload || {};
142
+ const emoji = String(event.message?.emoji || payload.emoji || '').trim();
143
+ const target = event.reactTo || eventMessageTarget(
144
+ event,
145
+ event.message?.target || payload.target
146
+ );
147
+ if (!emoji || !target?.messageId) return null;
148
+ return client.chat.reactTo(target, emoji, {
149
+ cid: botActionCid(event, 'echo-reaction', account),
150
+ });
151
+ }
152
+
122
153
  function groupEchoWinner(event, echoChatKeys) {
123
154
  const eligible = [...new Set(
124
155
  (event?.chat?.members || [])
@@ -218,9 +249,17 @@ async function mirrorEcho(journal, account, client, event) {
218
249
  event,
219
250
  'echo-text',
220
251
  { replaySafe: true },
221
- () => sendToEventChat(client, event, event.message.text || '', {
222
- cid: botActionCid(event, 'echo', account),
223
- })
252
+ () => sendEchoText(account, client, event)
253
+ );
254
+ }
255
+ if (event.message.type === 'rxn') {
256
+ return runAction(
257
+ journal,
258
+ account,
259
+ event,
260
+ 'echo-reaction',
261
+ { replaySafe: true },
262
+ () => mirrorReaction(account, client, event)
224
263
  );
225
264
  }
226
265
  if (event.message.type === 'req') {
@@ -575,6 +614,16 @@ export function createBotFleetPolicy(options = {}) {
575
614
  },
576
615
  async onEvent({ account, client, event }) {
577
616
  const roles = rolesFor(account);
617
+ if (!baseline && roles.has('live') && event?.type === 'message') {
618
+ const state = liveStates.get(account.profile);
619
+ if (state) {
620
+ await ensureLiveChat(
621
+ account,
622
+ state,
623
+ eventChatId(event)
624
+ );
625
+ }
626
+ }
578
627
  if (checkpoint?.has(account.profile, event)) {
579
628
  return null;
580
629
  }
package/package.json CHANGED
@@ -41,5 +41,5 @@
41
41
  "start": "node src/cli.js",
42
42
  "lint": "eslint src --quiet"
43
43
  },
44
- "version": "0.61.12"
44
+ "version": "0.63.0"
45
45
  }
package/readme.md CHANGED
@@ -34,7 +34,7 @@ await veyl.close();
34
34
 
35
35
  To store the keys in your own secret manager, pass `saveKey: false` to both creation calls and provide them later through `open({ accountKey, vaultKey })`, `VEYL_ACCOUNT_KEY`, and `VEYL_VAULT_KEY`. Never log or commit either key.
36
36
 
37
- Use `REGTEST` for development and disposable accounts. `MAINNET` uses real funds. Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/legal#terms) and [Community Rules](https://veyl.glyphteck.com/community-rules).
37
+ Use `REGTEST` for development and disposable accounts. `MAINNET` uses real funds. Creating an account accepts Veyl's [Terms](https://veyl.glyphteck.com/terms#terms), which include the community rules.
38
38
 
39
39
  ## CLI
40
40