howone 0.1.9 → 0.1.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "howone",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "private": false,
5
5
  "description": "HowOne command line tools for creating app templates.",
6
6
  "type": "module",
@@ -5,16 +5,28 @@ description: Build application code with @howone/sdk correctly. Use when impleme
5
5
 
6
6
  # HowOne SDK
7
7
 
8
- Use this skill when writing app code that consumes `@howone/sdk`. The goal is stable generated code: read backend-synced manifests, define zod schemas, bind entities and AI actions in the app SDK entry, then call those bindings from UI code.
8
+ Use this skill when writing app code that consumes `@howone/sdk`. The goal is stable generated code: read backend-synced manifests, define runtime schemas, bind entities and AI actions in the app SDK entry, then call those bindings from UI code.
9
+
10
+ This skill is the normal source of truth for HowOne SDK usage in generated apps. Do not inspect `node_modules/@howone/sdk` just to rediscover imports, hook names, entity methods, AI action call shapes, or Vite environment wiring. Use dependency source only for narrow missing details, signature drift proven by verification, or SDK-package development.
9
11
 
10
12
  ## Workflow
11
13
 
12
- 1. Locate the app root first. If an app was created by `howone init app <name>`, all `.howone/*` metadata and `src/lib/sdk.ts` work should happen inside that created app directory.
13
- 2. Read the existing app SDK entry, usually `src/lib/sdk.ts`, before editing. Preserve its imports and local style.
14
- 3. For Entity bindings, read `.howone/database/manifest.json`.
15
- 4. For AI action bindings, read `.howone/ai/manifest.json`.
16
- 5. Generate source code from the manifests, not from memory or tool-call summaries.
17
- 6. Keep sync tools and app-code edits separate. `sync_schema_artifacts` and `sync_ai_artifacts` write metadata only; the coding agent edits `src/lib/sdk.ts`.
14
+ 1. Establish the app root. All `.howone/*` metadata and `src/lib/sdk.ts` work belongs inside that app root.
15
+ 2. Read `references/usage-patterns.md` once before writing SDK-related code. It contains the SDK mental model, essential public API, generation recipes, and common traps.
16
+ 3. Read the existing app SDK entry, usually `src/lib/sdk.ts`, before editing. Preserve its imports and local style.
17
+ 4. For Entity bindings, read `.howone/database/manifest.json`.
18
+ 5. For AI action bindings, read `.howone/ai/manifest.json`.
19
+ 6. Generate source code from the manifests, not from memory or tool-call summaries.
20
+ 7. Keep sync tools and app-code edits separate. `sync_schema_artifacts` and `sync_ai_artifacts` write metadata only; the coding agent edits `src/lib/sdk.ts`.
21
+
22
+ ## Source Order
23
+
24
+ Use this order when deciding what to read:
25
+
26
+ 1. Current app files: `src/lib/sdk.ts`, relevant UI files, and generated manifests.
27
+ 2. This skill: `SKILL.md` plus `references/usage-patterns.md`.
28
+ 3. TypeScript/compiler errors from verification.
29
+ 4. SDK source or declaration files, only as a narrow fallback for a missing or disputed API.
18
30
 
19
31
  ## Rules
20
32
 
@@ -24,9 +36,10 @@ Use this skill when writing app code that consumes `@howone/sdk`. The goal is st
24
36
  - Current action binding shape is `howone.ai.<actionName>.run(input)`, `stream(input)`, and `events(input)`. Do not generate `howone.ai.run.<actionName>(input)` unless the SDK implementation has been changed to support that API.
25
37
  - Do not name AI actions `run`, `stream`, or `events`; those are reserved.
26
38
  - Define entity create/update types explicitly. Avoid deriving create types from `Omit<EntityRecord & ...>` when it widens the payload.
39
+ - React integration does not provide entity/query/AI hooks. Use plain async SDK calls from React state/effects or an app-level data-fetching library.
27
40
  - Never make generated SDK/type files under `.howone`. `.howone` stores manifests only.
28
41
  - If an AI-first feature persists generated results, create/update AI capability schema first, sync `.howone/ai`, then derive Entity fields from the AI `outputSchema`.
29
42
 
30
43
  ## References
31
44
 
32
- Read `references/usage-patterns.md` before writing any code. It is the complete API reference for `@howone/sdk` and `@howone/sdk/react` all type signatures, method names, import paths, and call patterns are already there.
45
+ Read `references/usage-patterns.md` before writing SDK-related code. It is the working reference for `@howone/sdk` and `@howone/sdk/react`: mental model, imports, method names, app SDK entry shape, entity examples, AI action examples, React usage, validation caveats, and when source fallback is justified.
@@ -1,8 +1,29 @@
1
1
  # HowOne SDK Usage Patterns
2
2
 
3
- Complete API reference for `@howone/sdk` and `@howone/sdk/react`. Covers all type signatures, method names, import paths, and usage patterns needed to wire up entities, AI actions, and React components in a HowOne app.
3
+ Working reference for `@howone/sdk` and `@howone/sdk/react`. It covers the SDK surface that generated HowOne apps normally need: client setup, entity bindings, AI action bindings, React provider usage, and the known traps that cause repeated source inspection.
4
4
 
5
- ## Complete Import Reference
5
+ ## Reading Strategy
6
+
7
+ Use this file as the working SDK manual for normal app generation. It intentionally includes the public imports, client shape, entity methods, AI action bindings, React exports, app SDK entry shape, and known validation caveats.
8
+
9
+ Do not inspect `node_modules/@howone/sdk` for the same information unless:
10
+
11
+ - This file does not cover the exact API needed.
12
+ - TypeScript or runtime verification contradicts this file.
13
+ - You are intentionally updating the SDK package itself, not an app that consumes it.
14
+
15
+ When source fallback is necessary, keep it narrow: inspect the exact exported symbol or declaration that is missing, then return to app code. Do not glob or read the whole SDK package to relearn the basic usage below.
16
+
17
+ ## SDK Mental Model
18
+
19
+ - `createClient(...)` creates the base HowOne client with auth, entity, AI, upload, and user helpers.
20
+ - `client.entity<TRecord, TCreate, TUpdate>('EntityName')` creates one typed entity client.
21
+ - `defineEntities(...)` plus `withEntities(client, entities)` makes `howone.entities.<EntityName>` typed in app code.
22
+ - `defineAiAction(...)` plus `defineAiActions(...)` plus `withAiActions(...)` makes `howone.ai.<actionName>.run|stream|events` typed in app code.
23
+ - `@howone/sdk/react` provides auth/theme/loading UI primitives only. It does not provide entity, query, or AI data hooks.
24
+ - `.howone/database/manifest.json` and `.howone/ai/manifest.json` are the generated contracts. App source should be generated from those manifests, not from memory.
25
+
26
+ ## Import Reference
6
27
 
7
28
  ```ts
8
29
  // @howone/sdk — all public exports
@@ -51,7 +72,7 @@ import { z } from 'zod'
51
72
 
52
73
  ---
53
74
 
54
- ## createClient — signature & return shape
75
+ ## createClient
55
76
 
56
77
  ```ts
57
78
  const client = createClient({
@@ -79,7 +100,7 @@ client.upload.batch({ files, concurrent?, onProgress?, onFileComplete? }): Promi
79
100
 
80
101
  ---
81
102
 
82
- ## EntityClient — complete method signatures
103
+ ## EntityClient
83
104
 
84
105
  ```ts
85
106
  type EntityClient<TRecord, TCreate, TUpdate> = {
@@ -126,7 +147,7 @@ type EntityRecord = {
126
147
 
127
148
  ---
128
149
 
129
- ## AI Action — complete signatures
150
+ ## AI Action
130
151
 
131
152
  ```ts
132
153
  // Define a typed action
@@ -215,7 +236,6 @@ export const entities = defineEntities({
215
236
  export const ai = defineAiActions({
216
237
  // generateImage: defineAiAction('generateImage', {
217
238
  // inputSchema: generateImageInputSchema,
218
- // outputSchema: generateImageOutputSchema,
219
239
  // }),
220
240
  })
221
241
 
@@ -224,6 +244,29 @@ const howone = withAiActions(withEntities(client, entities), ai)
224
244
  export default howone
225
245
  ```
226
246
 
247
+ ## Manifest-To-Code Recipe
248
+
249
+ When backend metadata has been synced, generate app SDK code in this order:
250
+
251
+ 1. Read `src/lib/sdk.ts` to preserve the template's import style and existing bindings.
252
+ 2. Read `.howone/database/manifest.json` for entity names and fields. Generate `Record`, `Create`, and `Update` types, then bind each entity with `client.entity<Record, Create, Update>('EntityName')`.
253
+ 3. Read `.howone/ai/manifest.json` for AI capability names and JSON schemas. Generate zod input schemas and, only when safe, output schemas.
254
+ 4. Export a single default `howone` client built by composing `withEntities` and `withAiActions`.
255
+ 5. In UI code, import the default client and call `howone.entities.<Entity>.*` or `howone.ai.<action>.run(...)`.
256
+
257
+ Basic JSON schema mapping for generated zod:
258
+
259
+ ```ts
260
+ string -> z.string()
261
+ number -> z.number()
262
+ integer -> z.number().int()
263
+ boolean -> z.boolean()
264
+ array -> z.array(...)
265
+ object -> z.object({ ... })
266
+ enum -> z.enum([...])
267
+ missing from required[] -> .optional()
268
+ ```
269
+
227
270
  ## Entity Types
228
271
 
229
272
  Prefer explicit payload types:
@@ -248,6 +291,22 @@ export const entities = defineEntities({
248
291
  })
249
292
  ```
250
293
 
294
+ Generated entity app code usually needs only these calls:
295
+
296
+ ```ts
297
+ const result = await howone.entities.Story.query({
298
+ search,
299
+ page: { number: 1, size: 20 },
300
+ orderBy: { createdDate: 'desc' },
301
+ })
302
+
303
+ await howone.entities.Story.create({ title, content, prompt })
304
+ await howone.entities.Story.update(id, { title })
305
+ await howone.entities.Story.delete(id)
306
+ ```
307
+
308
+ Prefer `query()` for list UIs that need paging/search/sort metadata. Use `list()` only for simple array reads.
309
+
251
310
  Avoid this for generated create payloads:
252
311
 
253
312
  ```ts
@@ -277,7 +336,6 @@ export type GenerateStoryOutput = z.infer<typeof generateStoryOutputSchema>
277
336
  export const ai = defineAiActions({
278
337
  generateStory: defineAiAction('generateStory', {
279
338
  inputSchema: generateStoryInputSchema,
280
- outputSchema: generateStoryOutputSchema,
281
339
  mode: 'run',
282
340
  }),
283
341
  })
@@ -290,6 +348,7 @@ const result = await howone.ai.generateStory.run({
290
348
  topic,
291
349
  ageRange,
292
350
  })
351
+ const story = result.finalResult as GenerateStoryOutput
293
352
  ```
294
353
 
295
354
  For streaming:
@@ -311,15 +370,15 @@ for await (const event of howone.ai.generateStory.events(input)) {
311
370
 
312
371
  `run()` validates input with `inputSchema`, calls the workflow, then validates the **raw `ExecutionResult`** (the full SSE envelope) with `outputSchema`. It does **not** automatically unwrap `result.finalResult`.
313
372
 
314
- If you want to type the final result only, either:
315
- 1. Define `outputSchema` to match the full `ExecutionResult` shape, or
316
- 2. Omit `outputSchema` and unwrap manually:
373
+ If you want to type the final result only, omit `outputSchema` and unwrap manually:
317
374
 
318
375
  ```ts
319
376
  const result = await howone.ai.generateStory.run(input) // returns AiResult
320
377
  const finalResult = result.finalResult as GenerateStoryOutput
321
378
  ```
322
379
 
380
+ Only define `outputSchema` when it matches the full `ExecutionResult` envelope or after verifying the SDK has changed to validate `finalResult` directly.
381
+
323
382
  ## AI Result Persistence
324
383
 
325
384
  For AI-generated data that should be saved:
@@ -333,14 +392,46 @@ Example:
333
392
 
334
393
  ```ts
335
394
  const story = await howone.ai.generateStory.run(input)
395
+ const finalResult = story.finalResult as GenerateStoryOutput
336
396
 
337
397
  await howone.entities.Story.create({
338
- title: story.title,
339
- content: story.content,
398
+ title: finalResult.title,
399
+ content: finalResult.content,
340
400
  prompt: input.topic,
341
401
  })
342
402
  ```
343
403
 
404
+ ## Do Not Generate
405
+
406
+ Avoid these patterns unless the SDK has explicitly added them:
407
+
408
+ ```ts
409
+ // No data hooks in @howone/sdk/react
410
+ const todos = useEntity('Todo')
411
+ const query = useQuery(...)
412
+ const result = useAi(...)
413
+
414
+ // Wrong AI binding shape
415
+ await howone.ai.run.generateStory(input)
416
+
417
+ // Too-loose create payload
418
+ type StoryCreate = Omit<StoryRecord, 'id' | 'createdDate' | 'updatedDate'>
419
+
420
+ // Generated files do not belong under .howone
421
+ // .howone stores synced manifests only.
422
+ ```
423
+
424
+ ## When To Read SDK Source
425
+
426
+ Read SDK source or declaration files only for details not covered above, for example:
427
+
428
+ - A newly added public method not listed here.
429
+ - A TypeScript error proving a signature drifted.
430
+ - A runtime error that points to a specific SDK helper.
431
+ - Work that intentionally modifies `packages/sdk` itself.
432
+
433
+ For app generation, do not inspect SDK source to rediscover `createClient`, entity CRUD, AI action binding shape, React exports, or Vite env setup.
434
+
344
435
  ## Generated Code Checklist
345
436
 
346
437
  - `src/lib/sdk.ts` imports only APIs it uses.