@hybrd/utils 1.4.4 → 2.0.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.
Files changed (2) hide show
  1. package/README.md +149 -29
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,58 +1,178 @@
1
1
  # @hybrd/utils
2
2
 
3
- This package is part of the Hybrid monorepo.
3
+ General-purpose utility functions for the Hybrid AI agent framework. Compatible with Node.js, Cloudflare Workers, and browser environments.
4
4
 
5
- Hybrid makes it easy for developers to create intelligent agents that can understand natural language, process messages, and respond through XMTP's decentralized messaging protocol.
5
+ ## Overview
6
6
 
7
- See [hybrid.dev](https://hybrid.dev) for more information.
7
+ A collection of small helpers used across the monorepo. Includes environment detection, storage adapters, logging, date formatting, and cross-platform primitives.
8
8
 
9
- ## 📦 Quickstart
9
+ ## API Reference
10
10
 
11
- Getting started with Hybrid is simple:
11
+ ### Array
12
12
 
13
- ### 1. Initialize your project
13
+ ```typescript
14
+ import { chunk, uniq, shuffle } from "@hybrd/utils"
14
15
 
15
- ```bash
16
- npm create hybrid my-agent
17
- cd my-agent
16
+ chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]
17
+ uniq([1, 1, 2, 3, 3]) // [1, 2, 3]
18
+ shuffle([1, 2, 3, 4]) // [3, 1, 4, 2] (random order)
18
19
  ```
19
20
 
20
- This creates all the necessary files and configuration for your agent.
21
+ ### Cloudflare Environment Detection
22
+
23
+ Detects whether the code is running on Cloudflare Pages, Cloudflare Workers, or locally:
24
+
25
+ ```typescript
26
+ import {
27
+ getCloudflareEnvironment,
28
+ getCloudflareStoragePath,
29
+ getCloudflareServiceUrl
30
+ } from "@hybrd/utils"
21
31
 
22
- ### 2. Get your OpenRouter API key
23
-
24
- Visit [OpenRouter](https://openrouter.ai/keys), create an account and generate an API key
32
+ const env = getCloudflareEnvironment()
33
+ // { isCloudflare: boolean, platform: 'pages' | 'workers' | 'local', storagePath: string }
25
34
 
26
- Add it to your `.env` file:
35
+ // Returns '/tmp/xmtp' on Cloudflare, '.data/xmtp' locally
36
+ const storagePath = getCloudflareStoragePath("xmtp")
27
37
 
28
- ```env
29
- OPENROUTER_API_KEY=your_openrouter_api_key_here
38
+ // Returns CF_PAGES_URL, CF_WORKER_URL, or 'http://localhost:3000'
39
+ const serviceUrl = getCloudflareServiceUrl(3000)
30
40
  ```
31
41
 
32
- ### 3. Generate XMTP keys
42
+ ### Date Formatting
33
43
 
34
- ```bash
35
- hybrid keys
44
+ ```typescript
45
+ import { formatDate, formatRelativeDate } from "@hybrd/utils"
46
+
47
+ formatDate(new Date()) // "Mar 2, 2026"
48
+ formatDate("2026-01-15") // "Jan 15, 2026"
49
+
50
+ formatRelativeDate(new Date()) // "Today, 3:45 PM"
51
+ formatRelativeDate(yesterday) // "Yesterday, 3:45 PM"
52
+ formatRelativeDate(lastWeek) // "Feb 23, 3:45 PM"
53
+ formatRelativeDate(lastYear) // "Feb 23, 2025"
36
54
  ```
37
55
 
38
- or automatically add it to your `.env` file:
56
+ ### Logger
39
57
 
40
- ```bash
41
- hybrid keys --write
58
+ Environment-aware logger. Debug output is suppressed unless `DEBUG` or `XMTP_DEBUG` is set:
59
+
60
+ ```typescript
61
+ import { logger } from "@hybrd/utils"
62
+
63
+ logger.debug("Verbose detail") // Only logs if DEBUG or XMTP_DEBUG env var is set
64
+ logger.log("General message")
65
+ logger.info("Info message")
66
+ logger.warn("Warning")
67
+ logger.error("Error occurred")
42
68
  ```
43
69
 
44
- ### 4. Register your wallet with XMTP
70
+ ### Markdown
45
71
 
46
- ```bash
47
- hybrid register
72
+ ```typescript
73
+ import { stripMarkdown } from "@hybrd/utils"
74
+
75
+ const plain = await stripMarkdown("**bold** and _italic_ text")
76
+ // "bold and italic text"
48
77
  ```
49
78
 
50
- This generates secure wallet and encryption keys for your XMTP agent.
79
+ ### Object
80
+
81
+ ```typescript
82
+ import { stringifyValues, pruneEmpty } from "@hybrd/utils"
83
+
84
+ stringifyValues({ a: 1, b: { nested: true }, c: null })
85
+ // { a: "1", b: '{"nested":true}', c: "null" }
86
+
87
+ pruneEmpty({ a: 1, b: undefined, c: null, d: "" })
88
+ // { a: 1 }
89
+ ```
90
+
91
+ ### Storage
92
+
93
+ Auto-detects the available storage backend and returns an adapter:
94
+
95
+ ```typescript
96
+ import { createStorageAdapter } from "@hybrd/utils"
97
+
98
+ const adapter = createStorageAdapter()
99
+ // Returns R2StorageAdapter if globalThis.XMTP_STORAGE exists (Cloudflare)
100
+ // Returns null if no storage is configured (local dev)
101
+
102
+ if (adapter) {
103
+ await adapter.uploadFile("/local/path/file.db3", "remote/path/file.db3")
104
+ await adapter.downloadFile("remote/path/file.db3", "/local/path/file.db3")
105
+ const exists = await adapter.exists("remote/path/file.db3")
106
+ await adapter.delete("remote/path/file.db3")
107
+ }
108
+ ```
109
+
110
+ #### R2StorageAdapter
111
+
112
+ Used automatically on Cloudflare Workers when `globalThis.XMTP_STORAGE` is bound:
51
113
 
52
- ### 5. Start developing
114
+ ```typescript
115
+ import { R2StorageAdapter } from "@hybrd/utils"
116
+
117
+ const adapter = new R2StorageAdapter(env.XMTP_STORAGE)
118
+ await adapter.uploadFile(localPath, remotePath)
119
+ await adapter.downloadFile(remotePath, localPath)
120
+ ```
121
+
122
+ ### String
123
+
124
+ ```typescript
125
+ import { truncate } from "@hybrd/utils"
126
+
127
+ truncate("A very long string that needs to be shortened", 20)
128
+ // "A very long string t..."
129
+ ```
130
+
131
+ ### URLs
132
+
133
+ Resolves the base URL for the agent service, with priority:
134
+ `AGENT_URL` env → `RAILWAY_PUBLIC_DOMAIN` → `http://localhost:8454`
135
+
136
+ ```typescript
137
+ import { getUrl } from "@hybrd/utils"
138
+
139
+ getUrl() // "http://localhost:8454"
140
+ getUrl("/api/chat") // "http://localhost:8454/api/chat"
141
+
142
+ // With AGENT_URL=https://my-agent.fly.dev
143
+ getUrl("/api/chat") // "https://my-agent.fly.dev/api/chat"
144
+ ```
145
+
146
+ ### UUID
147
+
148
+ Cross-platform UUID v4 generation. Works in Node.js, Cloudflare Workers, and browsers:
149
+
150
+ ```typescript
151
+ import { randomUUID } from "@hybrd/utils"
152
+
153
+ randomUUID() // "550e8400-e29b-41d4-a716-446655440000"
154
+ ```
155
+
156
+ Uses the `uuid` package rather than `node:crypto.randomUUID` for compatibility with environments where Node.js crypto is not available.
157
+
158
+ ## Environment Variables
159
+
160
+ | Variable | Description |
161
+ |----------|-------------|
162
+ | `DEBUG` | Enable debug logging |
163
+ | `XMTP_DEBUG` | Enable debug logging (XMTP-specific alias) |
164
+ | `AGENT_URL` | Override agent service base URL |
165
+ | `RAILWAY_PUBLIC_DOMAIN` | Railway deployment domain (auto-set by Railway) |
166
+ | `CF_PAGES_BRANCH` | Set by Cloudflare Pages (used for environment detection) |
167
+ | `CF_WORKER_NAME` | Set by Cloudflare Workers (used for environment detection) |
168
+
169
+ ## Testing
53
170
 
54
171
  ```bash
55
- hybrid dev
172
+ cd packages/utils
173
+ pnpm test
56
174
  ```
57
175
 
58
- Your agent will start listening for XMTP messages and you're ready to build!
176
+ ## License
177
+
178
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybrd/utils",
3
- "version": "1.4.4",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",