howone 0.1.17 → 0.1.18
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/package.json +1 -1
- package/templates/vite/.howone/skills/howone-sdk/SKILL.md +10 -2
- package/templates/vite/.howone/skills/howone-sdk/references/01-client-setup.md +28 -0
- package/templates/vite/.howone/skills/howone-sdk/references/02-entity-operations.md +99 -2
- package/templates/vite/.howone/skills/howone-sdk/references/04-auth.md +16 -1
- package/templates/vite/.howone/skills/howone-sdk/references/06-react-integration.md +10 -4
- package/templates/vite/.howone/skills/howone-sdk/references/08-manifest-codegen.md +37 -3
- package/templates/vite/package.json +1 -1
package/package.json
CHANGED
|
@@ -12,13 +12,13 @@ This skill is the authoritative source of truth for all `@howone/sdk` usage in g
|
|
|
12
12
|
| Module | File | What It Covers |
|
|
13
13
|
|---|---|---|
|
|
14
14
|
| Client Setup | `references/01-client-setup.md` | `createClient`, env vars, `CreateClientOptions`, all client fields |
|
|
15
|
-
| Entity Operations | `references/02-entity-operations.md` | CRUD,
|
|
15
|
+
| Entity Operations | `references/02-entity-operations.md` | authenticated CRUD/query, public entity reads/writes, include, pagination, typed records |
|
|
16
16
|
| AI Actions | `references/03-ai-actions.md` | `defineAiAction`, `run`/`stream`/`events`, zod schemas, SSE callbacks |
|
|
17
17
|
| Auth | `references/04-auth.md` | Email OTP, Phone OTP, OAuth (Google/GitHub), token management |
|
|
18
18
|
| File Upload | `references/05-file-upload.md` | `upload.file`, `upload.image`, `upload.batch`, progress, abort |
|
|
19
19
|
| React Integration | `references/06-react-integration.md` | `HowOneProvider`, `useHowoneContext`, `FloatingButton`, `Loading` |
|
|
20
20
|
| Raw HTTP | `references/07-raw-http.md` | `client.raw.*`, custom API calls, interceptors |
|
|
21
|
-
| Manifest Codegen | `references/08-manifest-codegen.md` | Reading `.howone/database` and `.howone/ai`, generating `src/lib/sdk.ts
|
|
21
|
+
| Manifest Codegen | `references/08-manifest-codegen.md` | Reading `.howone/database` and `.howone/ai`, generating `src/lib/sdk.ts`, public access-aware types |
|
|
22
22
|
|
|
23
23
|
## Workflow
|
|
24
24
|
|
|
@@ -52,6 +52,7 @@ export type TodoRecord = EntityRecord & {
|
|
|
52
52
|
}
|
|
53
53
|
export type TodoCreate = { title: string; completed: boolean }
|
|
54
54
|
export type TodoUpdate = Partial<TodoCreate>
|
|
55
|
+
export type TodoPublicQuery = { completed?: boolean; limit?: number }
|
|
55
56
|
|
|
56
57
|
// Schemas
|
|
57
58
|
export const summarizeTodoInputSchema = z.object({ title: z.string().min(1) })
|
|
@@ -83,7 +84,14 @@ export default howone
|
|
|
83
84
|
## Hard Rules
|
|
84
85
|
|
|
85
86
|
- **Vite env only**: use `import.meta.env.VITE_HOWONE_PROJECT_ID` and `import.meta.env.VITE_HOWONE_ENV`. Never hardcode project IDs or add `?? 'prod'` fallbacks.
|
|
87
|
+
- **Single SDK config source**: configure `projectId` and `env` only in `createClient`. Do not pass env/project config to `HowOneProvider`; the React provider reads the SDK config set by `createClient`.
|
|
88
|
+
- **Authenticated owner semantics**: authenticated entity APIs derive owner from the JWT. Do not pass `created_by_id`, `created_by_user_id`, `ownerId`, or `puid` to authenticated queries or writes.
|
|
89
|
+
- **Public namespace**: public reads/writes must use `howone.public.entities.*` or `client.public.entity(...)`. Do not call authenticated `howone.entities.*` from public landing pages.
|
|
90
|
+
- **Public scoped queries**: for `access.public.read = "scoped"`, use `queryScoped` / `query.scoped` and pass every `requiredScopes` field such as `ownerId` and `slug`.
|
|
91
|
+
- **Public writes**: only generate public `create` / `update` calls when manifest access explicitly allows them. Public create must include `created_by_user_id` or the schema-defined owner scope.
|
|
86
92
|
- **Explicit types**: define `EntityRecord`, `Create`, and `Update` types explicitly. Never derive create types from `Omit<EntityRecord & ...>` — it widens the payload.
|
|
93
|
+
- **System fields**: never include `id`, `_id`, `created_date`, `updated_date`, `created_by_id`, `schema_version_id`, `schema_version_number`, or `is_sample` in create/update input types.
|
|
94
|
+
- **Schema versions**: treat `schemaVersionId` / `schemaVersionNumber` on records as write-time schema metadata, not business versioning.
|
|
87
95
|
- **AI action naming**: do not name actions `run`, `stream`, or `events` — those are reserved method names.
|
|
88
96
|
- **Call shape**: `howone.ai.<actionName>.run(input)` / `.stream(input)` / `.events(input)`. Never `howone.ai.run.<actionName>(input)`.
|
|
89
97
|
- **No hooks**: `@howone/sdk/react` provides auth/theme/loading UI only — no entity, query, or AI data hooks.
|
|
@@ -67,6 +67,22 @@ client.entity<TRecord, TCreate, TUpdate>(entityName: string): EntityClient
|
|
|
67
67
|
// Typed entity map (populated via withEntities)
|
|
68
68
|
client.entities: Record<string, EntityClient>
|
|
69
69
|
|
|
70
|
+
// Public entity namespace (never sends Authorization)
|
|
71
|
+
client.public.entity<TRecord, TPublicCreate, TPublicUpdate>(entityName: string): PublicEntityClient
|
|
72
|
+
client.public.entities: Record<string, PublicEntityClient>
|
|
73
|
+
client.public.raw: RawHttpClient
|
|
74
|
+
|
|
75
|
+
// Schema contract/version client
|
|
76
|
+
client.schema.listDefinitions()
|
|
77
|
+
client.schema.getDefinition(entityName)
|
|
78
|
+
client.schema.operate(operation)
|
|
79
|
+
client.schema.previewPatch(patch, { expectedVersionId, reason })
|
|
80
|
+
client.schema.applyPatch(patch, { expectedVersionId, reason })
|
|
81
|
+
client.schema.getState()
|
|
82
|
+
client.schema.listVersions()
|
|
83
|
+
client.schema.getVersion(versionId)
|
|
84
|
+
client.schema.restore(versionId, reason?)
|
|
85
|
+
|
|
70
86
|
// AI action runner (low-level)
|
|
71
87
|
client.ai: AiClient
|
|
72
88
|
|
|
@@ -215,9 +231,12 @@ const client = createClient({
|
|
|
215
231
|
```ts
|
|
216
232
|
type UserProfile = {
|
|
217
233
|
id: string
|
|
234
|
+
userId?: string
|
|
235
|
+
puid?: string
|
|
218
236
|
email?: string
|
|
219
237
|
name?: string
|
|
220
238
|
avatarUrl?: string
|
|
239
|
+
appId?: string
|
|
221
240
|
roles?: string[]
|
|
222
241
|
metadata?: Record<string, unknown>
|
|
223
242
|
}
|
|
@@ -242,6 +261,15 @@ client.auth.logout()
|
|
|
242
261
|
|
|
243
262
|
---
|
|
244
263
|
|
|
264
|
+
## Client Namespace Rules
|
|
265
|
+
|
|
266
|
+
- Use `client.entities.*` / `howone.entities.*` for authenticated app data. The backend derives owner from the JWT; do not pass owner filters or owner fields.
|
|
267
|
+
- Use `client.public.entities.*` / `howone.public.entities.*` for public landing pages, public article lists, scoped QR/profile pages, and public forms.
|
|
268
|
+
- Use `client.schema.*` only for backend contract management: definitions, schema operations, schema patch preview/apply, versions, and restore.
|
|
269
|
+
- Use `client.raw.*` only for custom endpoints not covered by typed SDK methods.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
245
273
|
## HowOneAuthError
|
|
246
274
|
|
|
247
275
|
```ts
|
|
@@ -18,7 +18,9 @@ type EntityRecord = {
|
|
|
18
18
|
id: string
|
|
19
19
|
createdDate?: string
|
|
20
20
|
updatedDate?: string
|
|
21
|
-
createdById?: string
|
|
21
|
+
createdById?: string // backend owner id from created_by_id
|
|
22
|
+
schemaVersionId?: string
|
|
23
|
+
schemaVersionNumber?: number
|
|
22
24
|
isSample?: boolean
|
|
23
25
|
[key: string]: unknown // index signature — important for typing
|
|
24
26
|
}
|
|
@@ -105,6 +107,25 @@ type DeleteResult = {
|
|
|
105
107
|
}
|
|
106
108
|
```
|
|
107
109
|
|
|
110
|
+
## PublicEntityClient API
|
|
111
|
+
|
|
112
|
+
Public entity calls use `/api/entities/public/apps/:appId/...` and do not send auth headers.
|
|
113
|
+
Only use them when the entity manifest explicitly allows `access.public.read`,
|
|
114
|
+
`access.public.create`, or `access.public.update`.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
type PublicEntityClient<TRecord, TPublicCreate, TPublicUpdate> = {
|
|
118
|
+
name: string
|
|
119
|
+
query(options?: QueryOptions<TRecord>): Promise<QueryResult<TRecord>>
|
|
120
|
+
query.scoped(options: QueryOptions<TRecord>): Promise<QueryResult<TRecord>>
|
|
121
|
+
queryScoped(options: QueryOptions<TRecord>): Promise<QueryResult<TRecord>>
|
|
122
|
+
get(id: string, options?: QueryOptions<TRecord>): Promise<TRecord | null>
|
|
123
|
+
getOrThrow(id: string, options?: QueryOptions<TRecord>): Promise<TRecord>
|
|
124
|
+
create(data: TPublicCreate): Promise<TRecord>
|
|
125
|
+
update(id: string, data: TPublicUpdate): Promise<TRecord>
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
108
129
|
---
|
|
109
130
|
|
|
110
131
|
## CRUD Examples
|
|
@@ -208,7 +229,12 @@ const result = await howone.entities.Story.query({
|
|
|
208
229
|
})
|
|
209
230
|
```
|
|
210
231
|
|
|
211
|
-
### query.mine —
|
|
232
|
+
### query.mine — current authenticated user's records
|
|
233
|
+
|
|
234
|
+
`query.mine()` is the preferred way to fetch records owned by the authenticated user.
|
|
235
|
+
It requires a valid auth token, then lets the backend derive owner from the JWT. Do not
|
|
236
|
+
manually pass `created_by_id`, `created_by_user_id`, `ownerId`, or `puid` in authenticated
|
|
237
|
+
queries or writes.
|
|
212
238
|
|
|
213
239
|
```ts
|
|
214
240
|
const myStories = await howone.entities.Story.query.mine({
|
|
@@ -217,6 +243,18 @@ const myStories = await howone.entities.Story.query.mine({
|
|
|
217
243
|
})
|
|
218
244
|
```
|
|
219
245
|
|
|
246
|
+
For public pages that cannot use the current auth session, switch to `howone.public`.
|
|
247
|
+
The public endpoint is controlled by `access.public.allowedFilters` and
|
|
248
|
+
`access.public.requiredScopes`:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
const result = await howone.public.entities.Story.query({
|
|
252
|
+
published: true,
|
|
253
|
+
page: { number: 1, size: 20 },
|
|
254
|
+
orderBy: { publishedAt: 'desc' },
|
|
255
|
+
})
|
|
256
|
+
```
|
|
257
|
+
|
|
220
258
|
### WhereInput — field operators
|
|
221
259
|
|
|
222
260
|
```ts
|
|
@@ -246,6 +284,18 @@ const result = await howone.entities.Story.query({
|
|
|
246
284
|
})
|
|
247
285
|
```
|
|
248
286
|
|
|
287
|
+
### Include relations
|
|
288
|
+
|
|
289
|
+
`include` accepts a string or string array. All entities support `include: 'user'`.
|
|
290
|
+
Entity-specific relation names must come from the manifest `relations` contract.
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
const result = await howone.entities.Story.query({
|
|
294
|
+
include: ['user', 'author'],
|
|
295
|
+
page: { number: 1, size: 20 },
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
249
299
|
---
|
|
250
300
|
|
|
251
301
|
## list() — Simple Array Read
|
|
@@ -268,6 +318,53 @@ const stories = await howone.entities.Story.list({ limit: 50, sort: 'title' })
|
|
|
268
318
|
|
|
269
319
|
---
|
|
270
320
|
|
|
321
|
+
## Public Reads
|
|
322
|
+
|
|
323
|
+
Use public reads for public lists and scoped public pages.
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
const articles = await howone.public.entities.Article.query({
|
|
327
|
+
published: true,
|
|
328
|
+
category: 'ai',
|
|
329
|
+
page: { number: 1, size: 20 },
|
|
330
|
+
orderBy: { publishedAt: 'desc' },
|
|
331
|
+
})
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
For `access.public.read = "scoped"`, pass every required scope:
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
const profile = await howone.public.entities.QrProfile.queryScoped({
|
|
338
|
+
ownerId: ownerSharedUserId,
|
|
339
|
+
slug: 'wechat',
|
|
340
|
+
active: true,
|
|
341
|
+
limit: 1,
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Public query fields must be present in `access.public.allowedFilters`, and public sort
|
|
346
|
+
fields must be present in `access.public.allowedSorts`. If a public query is rejected,
|
|
347
|
+
fix the schema access contract instead of falling back to authenticated APIs.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Public Writes
|
|
352
|
+
|
|
353
|
+
Only generate public writes when `access.public.create` / `access.public.update` allows
|
|
354
|
+
them. Public create must include `created_by_user_id` unless the schema defines a
|
|
355
|
+
different required owner scope.
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
await howone.public.entities.ContactMessage.create({
|
|
359
|
+
created_by_user_id: projectUserId,
|
|
360
|
+
name: 'Ada',
|
|
361
|
+
email: 'ada@example.com',
|
|
362
|
+
message: 'Please contact me',
|
|
363
|
+
})
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
271
368
|
## Bulk Create
|
|
272
369
|
|
|
273
370
|
```ts
|
|
@@ -45,10 +45,13 @@ import { HowOneAuthError } from '@howone/sdk'
|
|
|
45
45
|
import howone from '@/lib/sdk'
|
|
46
46
|
|
|
47
47
|
type UserProfile = {
|
|
48
|
-
id: string
|
|
48
|
+
id: string // backend owner id; same as userId when JWT has userId
|
|
49
|
+
userId?: string // authenticated backend user id when present in JWT
|
|
50
|
+
puid?: string // public UUID; do not use as public ownerId scope
|
|
49
51
|
email?: string
|
|
50
52
|
name?: string
|
|
51
53
|
avatarUrl?: string
|
|
54
|
+
appId?: string
|
|
52
55
|
roles?: string[]
|
|
53
56
|
metadata?: Record<string, unknown>
|
|
54
57
|
}
|
|
@@ -66,6 +69,18 @@ const user = await howone.session.user()
|
|
|
66
69
|
const user = await howone.me({ refresh: true })
|
|
67
70
|
```
|
|
68
71
|
|
|
72
|
+
### Identity fields
|
|
73
|
+
|
|
74
|
+
HowOne JWTs may contain both `userId` and `puid`. The SDK preserves both:
|
|
75
|
+
|
|
76
|
+
- `user.id` / `user.userId` identifies the authenticated backend user.
|
|
77
|
+
- `user.puid` is the public UUID and should not be used for entity owner filters.
|
|
78
|
+
- `query.mine()` requires auth and lets the backend derive ownership from the JWT.
|
|
79
|
+
|
|
80
|
+
For public share URLs that need scoped owner data, use `howone.public.entities.*`
|
|
81
|
+
and pass the schema-required public scope, usually the shared owner id stored on a record.
|
|
82
|
+
Do not pass `puid` as `ownerId`.
|
|
83
|
+
|
|
69
84
|
### Pattern: guard a page
|
|
70
85
|
|
|
71
86
|
```tsx
|
|
@@ -31,17 +31,20 @@ import {
|
|
|
31
31
|
|
|
32
32
|
Wrap your entire app. Provides auth, theme, and toast context to all children.
|
|
33
33
|
|
|
34
|
+
`HowOneProvider` reads SDK environment and project defaults from `createClient`. Configure
|
|
35
|
+
`projectId` and `env` once in `src/lib/sdk.ts`; do not pass a separate env to the provider.
|
|
36
|
+
|
|
34
37
|
```tsx
|
|
35
38
|
// main.tsx or app/layout.tsx
|
|
36
39
|
import React from 'react'
|
|
37
40
|
import ReactDOM from 'react-dom/client'
|
|
38
41
|
import { HowOneProvider } from '@howone/sdk/react'
|
|
42
|
+
import './lib/sdk'
|
|
39
43
|
import App from './App'
|
|
40
44
|
|
|
41
45
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
42
46
|
<React.StrictMode>
|
|
43
47
|
<HowOneProvider
|
|
44
|
-
projectId={import.meta.env.VITE_HOWONE_PROJECT_ID}
|
|
45
48
|
auth="required"
|
|
46
49
|
brand="visible"
|
|
47
50
|
theme="system"
|
|
@@ -62,7 +65,7 @@ type HowOneBrandMode = 'visible' | 'hidden'
|
|
|
62
65
|
interface HowOneProviderProps {
|
|
63
66
|
children: React.ReactNode
|
|
64
67
|
|
|
65
|
-
//
|
|
68
|
+
// Optional override. Prefer configuring projectId once in createClient.
|
|
66
69
|
projectId?: string
|
|
67
70
|
|
|
68
71
|
// Auth behaviour
|
|
@@ -115,10 +118,13 @@ Access auth state inside any component wrapped by `HowOneProvider`.
|
|
|
115
118
|
```ts
|
|
116
119
|
type HowoneContextValue = {
|
|
117
120
|
user: {
|
|
118
|
-
id: string
|
|
121
|
+
id: string // backend owner id; same as userId when JWT has userId
|
|
122
|
+
userId?: string // authenticated backend user id when present in JWT
|
|
123
|
+
puid?: string // public UUID; do not use as public ownerId scope
|
|
119
124
|
email: string
|
|
120
125
|
name: string
|
|
121
126
|
avatar: string
|
|
127
|
+
appId?: string
|
|
122
128
|
} | null
|
|
123
129
|
token: string | null
|
|
124
130
|
isAuthenticated: boolean
|
|
@@ -323,6 +329,7 @@ import React from 'react'
|
|
|
323
329
|
import ReactDOM from 'react-dom/client'
|
|
324
330
|
import { HowOneProvider } from '@howone/sdk/react'
|
|
325
331
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
332
|
+
import './lib/sdk'
|
|
326
333
|
import App from './App'
|
|
327
334
|
|
|
328
335
|
const queryClient = new QueryClient()
|
|
@@ -330,7 +337,6 @@ const queryClient = new QueryClient()
|
|
|
330
337
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
331
338
|
<React.StrictMode>
|
|
332
339
|
<HowOneProvider
|
|
333
|
-
projectId={import.meta.env.VITE_HOWONE_PROJECT_ID}
|
|
334
340
|
auth="required"
|
|
335
341
|
theme="system"
|
|
336
342
|
brand="visible"
|
|
@@ -62,9 +62,41 @@ Sync tools (`sync_schema_artifacts`, `sync_ai_artifacts`) write the manifests. T
|
|
|
62
62
|
| `array` (items: object) | `Record<string, unknown>[]` or inline type |
|
|
63
63
|
| `object` | `Record<string, unknown>` |
|
|
64
64
|
| `enum` | `'value1' \| 'value2' \| ...` |
|
|
65
|
+
| `["string", "null"]` | `string \| null` |
|
|
65
66
|
|
|
66
|
-
- Fields in `required: true` are non-optional in `Record`
|
|
67
|
-
-
|
|
67
|
+
- Fields in `required: true` are non-optional in `Record` types.
|
|
68
|
+
- In `Create` types, required fields are required only when they do not have `default` or `autoGenerate`.
|
|
69
|
+
- Fields with `default`, `defaultValue`, or `autoGenerate` are optional in `Create`.
|
|
70
|
+
- Nullable fields include `null`.
|
|
71
|
+
- System response fields are never generated into `Create` or `Update`.
|
|
72
|
+
|
|
73
|
+
### Access-aware generated helpers
|
|
74
|
+
|
|
75
|
+
Use the manifest `access` block to decide which namespace UI code should call:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
export type ArticlePublicQuery = {
|
|
79
|
+
published?: boolean
|
|
80
|
+
category?: string
|
|
81
|
+
slug?: string
|
|
82
|
+
page?: { number?: number; size?: number }
|
|
83
|
+
orderBy?: { publishedAt?: 'asc' | 'desc'; updatedDate?: 'asc' | 'desc' }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const publicArticles = await howone.public.entities.Article.query({
|
|
87
|
+
published: true,
|
|
88
|
+
orderBy: { publishedAt: 'desc' },
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Rules:
|
|
93
|
+
|
|
94
|
+
- `access.authenticated.*` drives `howone.entities.*`.
|
|
95
|
+
- `access.public.read = "list"` allows `howone.public.entities.Entity.query`.
|
|
96
|
+
- `access.public.read = "scoped"` requires `queryScoped` / `query.scoped` and all `requiredScopes`.
|
|
97
|
+
- Public query types must include only `allowedFilters`, `allowedSorts`, `page`, `limit`, `search`, `include`, and `exactCount`.
|
|
98
|
+
- Public create/update types should only be emitted when `access.public.create/update` is not `"none"`.
|
|
99
|
+
- Public create must include `created_by_user_id` when the schema requires public owner assignment.
|
|
68
100
|
|
|
69
101
|
### Generated TypeScript from the example manifest
|
|
70
102
|
|
|
@@ -335,7 +367,9 @@ Before finalising generated code, verify:
|
|
|
335
367
|
|
|
336
368
|
- [ ] Every entity from `.howone/database/manifest.json` has a `Record`, `Create`, and `Update` type
|
|
337
369
|
- [ ] `Create` types are defined **explicitly** (not via `Omit`)
|
|
338
|
-
- [ ]
|
|
370
|
+
- [ ] Create optionality accounts for `required`, `default`, `defaultValue`, `autoGenerate`, and nullable types
|
|
371
|
+
- [ ] System fields are not present in create/update input types
|
|
372
|
+
- [ ] Public query/write types are generated only from `access.public.allowedFilters`, `allowedSorts`, `requiredScopes`, and write permissions
|
|
339
373
|
- [ ] Every AI action from `.howone/ai/manifest.json` has an `inputSchema` zod object
|
|
340
374
|
- [ ] Required input fields are not `.optional()` in zod
|
|
341
375
|
- [ ] AI action names match the manifest `id` exactly (case-sensitive)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@base-ui/react": "^1.4.1",
|
|
16
16
|
"@fontsource-variable/inter": "^5.2.8",
|
|
17
|
-
"@howone/sdk": "2.0.0-beta.
|
|
17
|
+
"@howone/sdk": "2.0.0-beta.15",
|
|
18
18
|
"@tailwindcss/vite": "^4.2.1",
|
|
19
19
|
"class-variance-authority": "^0.7.1",
|
|
20
20
|
"clsx": "^2.1.1",
|