howone 0.2.2 → 0.2.5

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 (30) hide show
  1. package/package.json +1 -1
  2. package/templates/vite/.howone/skills/howone/01-architect/01-app-generation.md +36 -7
  3. package/templates/vite/.howone/skills/howone/01-architect/02-manifest-codegen.md +121 -436
  4. package/templates/vite/.howone/skills/howone/03-ai-capabilities/03-service-capability-catalog.md +37 -19
  5. package/templates/vite/.howone/skills/howone/03-ai-capabilities/04-workflow-operations.md +14 -5
  6. package/templates/vite/.howone/skills/howone/04-app-sdk/01-client-setup.md +94 -261
  7. package/templates/vite/.howone/skills/howone/04-app-sdk/02-entity-operations.md +85 -465
  8. package/templates/vite/.howone/skills/howone/04-app-sdk/03-auth.md +11 -7
  9. package/templates/vite/.howone/skills/howone/04-app-sdk/04-react-integration.md +84 -137
  10. package/templates/vite/.howone/skills/howone/04-app-sdk/05-file-upload.md +66 -273
  11. package/templates/vite/.howone/skills/howone/04-app-sdk/06-raw-http.md +72 -249
  12. package/templates/vite/.howone/skills/howone/04-app-sdk/07-ai-action-calls.md +135 -499
  13. package/templates/vite/.howone/skills/howone/04-app-sdk/08-ai-manifest-handoff.md +49 -196
  14. package/templates/vite/.howone/skills/howone/04-app-sdk/09-extension-boundaries.md +4 -4
  15. package/templates/vite/.howone/skills/howone/04-app-sdk/10-workflow-execute-sse.md +94 -61
  16. package/templates/vite/.howone/skills/howone/04-app-sdk/11-entity-data-access-patterns.md +4 -3
  17. package/templates/vite/.howone/skills/howone/SKILL.md +110 -4
  18. package/templates/vite/.howone/skills/howone/references/audio-generation.md +30 -0
  19. package/templates/vite/.howone/skills/howone/references/audio-recognition.md +30 -0
  20. package/templates/vite/.howone/skills/howone/references/common-errors.md +27 -0
  21. package/templates/vite/.howone/skills/howone/references/finance.md +28 -0
  22. package/templates/vite/.howone/skills/howone/references/image-editing.md +30 -0
  23. package/templates/vite/.howone/skills/howone/references/image-generation.md +30 -0
  24. package/templates/vite/.howone/skills/howone/references/version-evidence.md +47 -0
  25. package/templates/vite/.howone/skills/howone/references/video-generation.md +35 -0
  26. package/templates/vite/.howone/skills/howone/scripts/verify-project.mjs +151 -0
  27. package/templates/vite/package.json +1 -1
  28. package/templates/vite/src/App.tsx +9 -5
  29. package/templates/vite/src/lib/sdk.ts +7 -5
  30. package/templates/vite/bun.lock +0 -1478
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: howone
3
- description: 'Use when deciding whether HowOne can satisfy a user request, or when the task touches HowOne platform contracts or app runtime: backend dynamic entity schemas, public/private access, database-backed persisted data, AI capabilities/workflows, external-ai workflow create/update/status, .howone manifests, src/lib/sdk.ts, auth/uploads, or app code that calls @howone/sdk/howone.*. Do not use for UI-only edits with no HowOne data, AI, auth, upload, manifest, or SDK surface.'
3
+ description: 'Use when deciding whether HowOne can satisfy a user request, or when the task touches HowOne platform contracts or app runtime: backend dynamic entity schemas, public/private access, database-backed persisted data, AI capabilities/workflows (including image, video, audio, speech recognition, and financial data), external-ai workflow create/update/status, .howone manifests, src/lib/sdk.ts, auth/uploads, or app code that calls @howone/sdk/howone.*. Do not use for UI-only edits with no HowOne data, AI, auth, upload, manifest, or SDK surface.'
4
4
  ---
5
5
 
6
6
  # HowOne
@@ -13,6 +13,24 @@ HowOne builds generated full-stack AI apps. Platform contracts are separate from
13
13
 
14
14
  Load only the track needed for the user's request. Do not read SDK files while designing backend or AI contracts unless the task has reached manifest-to-code implementation.
15
15
 
16
+ ## Version Evidence (Mastra-style)
17
+
18
+ Before writing app SDK code, establish this evidence chain:
19
+
20
+ ```text
21
+ synced project manifests
22
+ → app package.json SDK range
23
+ → installed @howone/sdk version
24
+ → installed dist/*.d.ts and runtime exports
25
+ → this Skill's matching recipe
26
+ → remote docs only as supplemental context
27
+ ```
28
+
29
+ Read `references/version-evidence.md` and run
30
+ `node .howone/skills/howone/scripts/verify-project.mjs` from the app root. If the requested and
31
+ installed SDK versions disagree, install dependencies before coding. Never solve a version mismatch
32
+ with `any`, guessed signatures, or copied latest documentation.
33
+
16
34
  ## Trigger Preconditions
17
35
 
18
36
  Use this skill before work when any condition is true:
@@ -56,11 +74,38 @@ Then read the minimum track files:
56
74
  | Backend contract | `02-entity-schema/01-schema-design.md`, `02-entity-schema/02-schema-operations.md` |
57
75
  | AI contract | `03-ai-capabilities/01-ai-capability-architecture.md`, `03-ai-capabilities/02-workflow-contract-rules.md`, `03-ai-capabilities/03-service-capability-catalog.md` |
58
76
  | External AI workflow submit/update | `03-ai-capabilities/04-workflow-operations.md` |
59
- | SDK binding/code | `01-architect/02-manifest-codegen.md` plus the relevant `04-app-sdk/` file |
77
+ | Image, video, audio, speech, or finance workflow | The matching file under `references/` from the detailed capability table below |
78
+ | SDK binding/code | `01-architect/02-manifest-codegen.md`, `04-app-sdk/01-client-setup.md`, `04-app-sdk/03-auth.md`, `04-app-sdk/04-react-integration.md`, plus the operation-specific SDK file |
60
79
  | AI output persistence | Backend required reads plus `02-entity-schema/05-ai-persistence-patterns.md` after AI output schema is known |
61
80
 
62
81
  Do not load all references preemptively.
63
82
 
83
+ ### Detailed Capability Routing
84
+
85
+ After `03-ai-capabilities/03-service-capability-catalog.md` confirms the workflow family, read
86
+ exactly the matching detailed reference before designing or changing its contract:
87
+
88
+ | User-visible AI behavior | Detailed service reference |
89
+ |---|---|
90
+ | Generate speech, narration, voiceover, or multilingual TTS | `references/audio-generation.md` |
91
+ | Transcribe recordings, produce meeting text, or identify speakers | `references/audio-recognition.md` |
92
+ | Retrieve historical stock or index prices | `references/finance.md` |
93
+ | Edit, transform, remove, replace, or combine image content | `references/image-editing.md` |
94
+ | Generate an image from text or reference images | `references/image-generation.md` |
95
+ | Generate a short video from text, frames, or reference images | `references/video-generation.md` |
96
+
97
+ The detailed references describe workflow-service operation parameters and limits. Use them to
98
+ avoid unsupported values and impossible combinations. They are not app SDK signatures:
99
+
100
+ 1. Expose only the inputs the product actually needs in the capability contract.
101
+ 2. Preserve closed enums, URL requirements, conditional requirements, and hard limits.
102
+ 3. Use product-oriented field names only when their descriptions map unambiguously to the service
103
+ parameter; never invent a service parameter.
104
+ 4. Return only the minimal product result from the workflow. Do not copy service metadata into the
105
+ output schema unless the UI or persistence contract uses it.
106
+ 5. After apply/sync/finalization, treat `.howone/ai/manifest.json` as the only source for SDK names,
107
+ schemas, and workflow IDs.
108
+
64
109
  ## Tool Flow
65
110
 
66
111
  Backend contract:
@@ -73,7 +118,8 @@ AI contract:
73
118
 
74
119
  ```text
75
120
  get_current_ai_capabilities -> apply_capability_patch -> sync_ai_artifacts -> external-ai-capability
76
- -> wait for terminal result -> sync_ai_artifacts -> read .howone/ai/manifest.json
121
+ -> continue independent app implementation (never end merely to wait)
122
+ -> terminal result -> sync_ai_artifacts -> read .howone/ai/manifest.json
77
123
  ```
78
124
 
79
125
  No contract dry-run step. Normal generation applies one well-formed patch directly. For destructive,
@@ -83,14 +129,45 @@ approved patch.
83
129
  SDK/code:
84
130
 
85
131
  ```text
86
- read synced manifests -> update src/lib/sdk.ts -> implement UI/server code using src/lib/sdk.ts imports
132
+ read version evidence -> read synced manifests -> choose auth posture -> update src/lib/sdk.ts
133
+ -> install HowOneProvider (client={howone}) -> implement UI calls using generated bindings
134
+ -> run project verifier -> typecheck/build
87
135
  ```
88
136
 
137
+ For fragile operations, prefer the deterministic verifier and the operation recipes over retyping
138
+ transport details in an app. Run the verifier again after manifest or dependency changes.
139
+
140
+ ## App Runtime Activation Gate
141
+
142
+ Classify runtime activation before editing the application shell:
143
+
144
+ - Pure UI/static code with no HowOne data, AI, upload, auth, manifest, or SDK call does not require
145
+ `HowOneProvider` and must not add login merely because the template supports it.
146
+ - Any app code that uses any `@howone/sdk` runtime surface—including entities, public entities, AI
147
+ actions, uploads, auth, user/session APIs, or raw SDK requests—activates the HowOne runtime. Keep
148
+ one module-level client in `src/lib/sdk.ts`, import it before Provider initialization, and wrap the
149
+ application root in `HowOneProvider`.
150
+ - HowOne AI, uploads, and `howone.entities.*` authenticated/private access require a real token path.
151
+ Use the default hosted client and pass the composed singleton to
152
+ `<HowOneProvider client={howone}>`; its required guard is inherited from `client.auth.guard`.
153
+ - A custom HowOne login requires `createClient({ auth: 'custom', loginPath })`, a real OTP/OAuth flow
154
+ that writes the returned token through `howone.auth.setToken()`, and a Provider receiving that
155
+ client. A login-looking screen without token acquisition is not completion.
156
+ - An app that uses only manifest-approved `howone.public.entities.*` access may use
157
+ `auth: 'none'`; the Provider inherits a non-required guard and must not force login.
158
+
159
+ Do not delete the scaffold Provider while replacing `App.tsx` or `main.tsx` when the HowOne runtime
160
+ is active. Before completion, verify the Provider still wraps the rendered app, the SDK module is
161
+ initialized first, unauthenticated protected use reaches the selected login flow, and authenticated
162
+ AI/entity/upload requests obtain the SDK-managed token. Never replace a missing token path with mock
163
+ data, local-only persistence, or unauthenticated fallback behavior.
164
+
89
165
  ## Source Of Truth
90
166
 
91
167
  - Backend fields/access/indexes: `{appRoot}/.howone/database/manifest.json` after sync.
92
168
  - AI names/workflow IDs/schemas: `{appRoot}/.howone/ai/manifest.json` after sync.
93
169
  - App runtime entry: `{appRoot}/src/lib/sdk.ts`.
170
+ - Installed SDK typings/runtime: `{appRoot}/node_modules/@howone/sdk/dist/*` after package install.
94
171
  - Do not handwrite `.howone/` metadata.
95
172
  - Do not infer contract identifiers from prompts, memory, or dependency source.
96
173
 
@@ -123,6 +200,9 @@ read synced manifests -> update src/lib/sdk.ts -> implement UI/server code using
123
200
  | `03-ai-capabilities/04-workflow-operations.md` | External workflow create/update/status |
124
201
  | `03-ai-capabilities/05-ai-feature-playbooks.md` | Reusable AI product patterns |
125
202
 
203
+ Detailed workflow-service parameters live under `references/` and are routed by the table above.
204
+ Do not read unrelated capability references.
205
+
126
206
  ### SDK
127
207
 
128
208
  | File | Use |
@@ -140,10 +220,36 @@ read synced manifests -> update src/lib/sdk.ts -> implement UI/server code using
140
220
  | `04-app-sdk/11-entity-data-access-patterns.md` | App entity access calls from synced manifest |
141
221
  | `04-app-sdk/12-query-dsl-and-responses.md` | App query/filter/sort/pagination calls |
142
222
 
223
+ ### References and scripts
224
+
225
+ | Resource | Use |
226
+ |---|---|
227
+ | `references/version-evidence.md` | Verify installed SDK version and declaration/runtime evidence before coding |
228
+ | `references/common-errors.md` | Diagnose stale signatures, routing, auth, query, upload, and AI failures |
229
+ | `scripts/verify-project.mjs` | Deterministically check project wiring and manifest workflow IDs |
230
+
143
231
  ## Hard Rules
144
232
 
145
233
  - Backend and AI design references must not include SDK implementation work.
146
234
  - SDK references must not invent backend or AI contracts; they consume synced manifests.
235
+ - App code must consume HowOne backend and AI capabilities through the generated bindings exported
236
+ by `src/lib/sdk.ts`. Do not replace SDK entity/action calls with direct requests to internal
237
+ platform endpoints.
238
+ - An active HowOne app runtime must include `src/lib/sdk.ts`, `HowOneProvider`, and the auth posture
239
+ required by its AI/entity/upload access. Contract creation without usable authenticated app wiring
240
+ is incomplete.
241
+ - New app code must pass the composed singleton to `<HowOneProvider client={howone}>`; the Provider
242
+ derives its default route guard from `client.auth.guard`.
243
+ - EAX workflow URLs are owned by `env`: `local/dev` use
244
+ `https://eax-backend-orchestrator-dev.fly.dev`, and `prod` uses
245
+ `https://eax-backend-orchestrator-prod.fly.dev`. Do not add `aiUrl`, `aiBaseUrl`, or a raw EAX URL.
246
+ - `howone.raw.*` resolves to response data, not an AxiosResponse. Its REST base already includes
247
+ `/api`; app-owned paths must not repeat that prefix.
248
+ - Use `@howone/sdk/devtools` for `ElementSelectorProvider`; keep core free of React imports.
147
249
  - AI workflows must not perform database CRUD; persistence is app code through entities.
250
+ - Detailed capability references constrain workflow design; they do not replace synced manifests or
251
+ define direct app SDK calls.
252
+ - Never copy all service parameters or technical response metadata into a capability contract by
253
+ default. Model only the product inputs and outputs while preserving service limits.
148
254
  - Explicit user-owned integrations are app code, not a platform gap.
149
255
  - Platform gap means missing HowOne contract/tool/catalog support, not an unsupported technology name.
@@ -0,0 +1,30 @@
1
+ # Audio Generation
2
+
3
+ Generates single-speaker audio (text-to-speech) from text, with configurable language, gender, and a natural-language voice hint. Supports multilingual audio by mixing Chinese and English in the same text. For multi-speaker dialogue, call this tool once per speaker and merge the results separately.
4
+
5
+ Use this file for workflow-service feasibility and parameter constraints. Do not expose every
6
+ parameter or raw response field in the app capability contract. Select the product-relevant subset,
7
+ then normalize the workflow output to the minimal URL/data fields the app consumes.
8
+
9
+ ## Parameters
10
+
11
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
12
+ |---|---|---|---|---|
13
+ | text_to_generate | string | Yes | — | — |
14
+ | languages | array[string] | No | items: `en-US`, `zh-CN`, `en-GB`, `en-AU`, `ja-JP`, `es-ES`; multilingual mixing only supported for zh/en | `['en-US']` |
15
+ | gender | string | No | `male`, `female` | `female` |
16
+ | audio_hint | string | No | must be written in English regardless of input/target language | — |
17
+ | audio_output | object | No | object with `audio_name` (string, ASCII only) and `audio_format` (`mp3`, `wav`) | audio_name auto-generated; audio_format `mp3` |
18
+
19
+ ## Service Output
20
+
21
+ The operation returns `success`, `audio_url`, `audio_metadata`, `voice_name`, and `emotion` when
22
+ available. A normal app capability should usually return only `audio_url` unless the product renders
23
+ or persists another field.
24
+
25
+ ## Constraints
26
+
27
+ - Use one speaker per call. Generate each speaker separately and use audio merging for dialogue.
28
+ - Only Chinese and English can be mixed in one multilingual request.
29
+ - Write `audio_hint` in English. Describe role, gender, language style, emotion, and scenario.
30
+ - Use URL outputs; do not request inline audio bytes or base64.
@@ -0,0 +1,30 @@
1
+ # Audio Recognition
2
+
3
+ Transcribes an audio file to text (speech-to-text), optionally with inverse text normalization and speaker diarization. Use for transcription, meeting minutes, or extracting text content from voice recordings.
4
+
5
+ Use this file for workflow-service feasibility and parameter constraints. The app capability may use
6
+ a clearer product field such as `source_audio_url`, but its description must map to the service
7
+ `audio_url` input. Never pass browser `File`, raw bytes, or base64 into the workflow.
8
+
9
+ ## Parameters
10
+
11
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
12
+ |---|---|---|---|---|
13
+ | audio_url | string | Yes | — | — |
14
+ | audio_format | string | No | e.g. `wav`, `mp3` | `mp3` |
15
+ | language | string | No | `en-US`, `zh-CN`, `en-GB`, `en-AU`, `ja-JP`, `es-ES` | `en-US` |
16
+ | use_itn | boolean | No | `true`, `false` | `true` |
17
+ | with_speaker_info | boolean | No | `true`, `false` | `false` |
18
+
19
+ ## Service Output
20
+
21
+ The operation returns `success`, `text`, and optional `utterances` with timestamps and speaker
22
+ identification. A capability contract should rename `text` to an unambiguous product result such as
23
+ `transcript_text`; include `utterances` only when the UI uses diarization.
24
+
25
+ ## Constraints
26
+
27
+ - `audio_url` must be reachable by the workflow service.
28
+ - Maximum processing wait time is 300 seconds.
29
+ - A single audio packet is limited to 2 MB; do not promise support for arbitrary large inputs.
30
+ - Silent audio may return empty text. Speaker quality depends on recording clarity.
@@ -0,0 +1,27 @@
1
+ # Common SDK Errors
2
+
3
+ Use this reference when typecheck, build, authentication, entity access, upload, or AI execution
4
+ fails.
5
+
6
+ | Symptom | Cause | Fix |
7
+ |---|---|---|
8
+ | `AI_WORKFLOW_CONFIGURATION_ERROR` | Missing or non-UUID `workflowId` | Re-read `.howone/ai/manifest.json`; pass its exact workflow config UUID. There is no action-name fallback. |
9
+ | `AI_SCHEMA_CONFIGURATION_ERROR` | JSON Schema passed to `defineAiAction` | Convert manifest JSON Schema to a Zod schema. |
10
+ | `AI_SCHEMA_VALIDATION_ERROR` on output | Workflow `finalResult` disagrees with manifest output schema | Fix the workflow or contract. Do not add `.passthrough()` or make required fields optional. |
11
+ | `WorkflowExecutionError` | `run_error` or `credit_insufficient` terminal event | Inspect `error.outcome`, `error.result.errors`, and `error.runId`; show app-owned UI or retry only when appropriate. |
12
+ | `aiUrl` / `aiBaseUrl` is not accepted | EAX routing is environment-owned | Remove the URL override and set `env` to `local`, `dev`, or `prod`. |
13
+ | Request hits `/api/api/...` | Raw path included `/api` even though the base already ends in `/api` | Use a path such as `/custom/stats`, not `/api/custom/stats`. |
14
+ | `response.data` is undefined | `howone.raw.*` already returns response data | Use `const data = await howone.raw.get<T>(...)`. |
15
+ | Provider renders blank forever in a public app | Provider guard conflicts with client auth or no client was passed | Pass `<HowOneProvider client={howone}>`; its guard defaults to `howone.auth.guard`. |
16
+ | `useHowoneContext must be used within HowOneProvider` | Hook called outside the Provider | Keep one root Provider and move the hook below it. |
17
+ | `ElementSelectorProvider` import fails from `/react` | Devtools moved to a separate entry | Import it from `@howone/sdk/devtools`. |
18
+ | Entity method is absent at typecheck/runtime | Manifest access forbids that capability and contract wrappers pruned it | Use the allowed namespace/operation or change and re-sync the platform contract. Do not cast the method back. |
19
+ | Public query rejects a filter/sort/scope | Query violates `access.public` | Put filters under `where`; use only `allowedFilters`, `allowedSorts`, and every `requiredScopes` field. |
20
+ | Nested JSON keys unexpectedly changed | `caseDepth: 'deep'` was enabled | Prefer the default `caseDepth: 'top-level'` for business JSON. |
21
+ | `HowOneProtocolError` key collision | snake_case and camelCase keys normalize to the same key | Fix the backend response contract; the SDK refuses silent overwrite. |
22
+ | Upload has no progress updates | Transport did not provide total bytes | Keep a loading state; `onProgress` fires only when total size is available. |
23
+ | Batch upload loops/fails immediately | `concurrent` is not a positive integer | Use `concurrent: 1` or higher. |
24
+ | Core import pulls React or React is missing | Framework code imported from the wrong entry | Use `@howone/sdk` for core, `@howone/sdk/react` for React, and `@howone/sdk/devtools` for selector tooling. |
25
+
26
+ After a fix, run the project verifier, typecheck, and production build. A successful build alone does
27
+ not prove that workflow IDs or manifest access rules are correct.
@@ -0,0 +1,28 @@
1
+ # Finance
2
+
3
+ Retrieves historical price and volume (open, high, low, close, volume) for stocks and market indices within a UTC time range. Supports US stocks, international stocks, and market indices. Does not provide company fundamentals, news, or real-time streaming data.
4
+
5
+ Use this file for historical market-data workflow feasibility and exact parameter constraints. Do
6
+ not reclassify live quotes, fundamentals, earnings, or news as this capability.
7
+
8
+ ## Parameters
9
+
10
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
11
+ |---|---|---|---|---|
12
+ | trading_symbol | string | Yes | trading symbol (e.g. `AAPL`, `SHEL.L`, `^GSPC`) or company/index name (e.g. `Apple`, `S&P 500`) | — |
13
+ | unit | string | Yes | `daily`, `minute`; market indices only support `daily` | — |
14
+ | start | string | Yes | UTC; `YYYY-MM-DD` for `daily` unit, `YYYY-MM-DDTHH:MM:SSZ` for `minute` unit | — |
15
+ | end | string | Yes | UTC, inclusive; `YYYY-MM-DD` for `daily` unit, `YYYY-MM-DDTHH:MM:SSZ` for `minute` unit; must be ≥ `start` | — |
16
+
17
+ ## Service Output
18
+
19
+ The operation returns `data` containing date/datetime, open, high, low, close, and volume records,
20
+ plus the resolved `trading_symbol` and an optional `warning`. Name the app-facing result according
21
+ to the product, for example `price_history`, while retaining the resolved symbol when it matters.
22
+
23
+ ## Constraints
24
+
25
+ - This is historical retrieval, not real-time streaming.
26
+ - Market indices such as `^GSPC` and `^DJI` support `daily` only.
27
+ - Prefer exact exchange-qualified tickers; company-name resolution is fuzzy.
28
+ - Availability depends on trading hours and provider coverage.
@@ -0,0 +1,30 @@
1
+ # Image Editing
2
+
3
+ Edits, transforms, or combines one or more existing images based on a natural language prompt. Supports basic operations (resize, rotate, crop, color adjustment, grayscale, blur, sharpen) and AI-powered operations (background removal/replacement, face swap, object removal/addition, style transfer, enhancement, image merging), which can be chained together.
4
+
5
+ Use this file for workflow-service feasibility and parameter constraints. `prompt` and `image_urls`
6
+ are service operation parameters; the app capability may expose product-oriented names such as
7
+ `edit_instruction` and `source_image_urls` when their descriptions preserve the mapping.
8
+
9
+ ## Parameters
10
+
11
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
12
+ |---|---|---|---|---|
13
+ | prompt | string | Yes | — | — |
14
+ | image_urls | array[string] | Yes | HTTP(S) or Supabase URLs; use array format even for a single image | — |
15
+ | image_names | array[string] | No | ASCII only; use array format even for a single image | auto-generated |
16
+ | size | string | No | `WxH` format (e.g. `512x512`, `1024x768`); applies to all edited images | original dimensions preserved |
17
+ | output_format | string | No | `png`, `jpeg`, `webp` | original format preserved |
18
+
19
+ ## Service Output
20
+
21
+ The operation returns `success`, `images` (each with `image_url` and `image_metadata`), and optional
22
+ `warnings`. A single-result app flow should normally return one `edited_image_url`; return an array
23
+ only when the product supports multiple edited outputs.
24
+
25
+ ## Constraints
26
+
27
+ - Require at least one reachable HTTP(S) image URL, even for operations described as text edits.
28
+ - Refer to inputs by position or visible content in `prompt`, not by repeating their URLs.
29
+ - Put output dimensions in `size`, not in `prompt`.
30
+ - Prefer focused edits. Chained complex edits can reduce quality.
@@ -0,0 +1,30 @@
1
+ # Image Generation
2
+
3
+ Generates images from a natural language prompt, optionally guided by reference images for text-and-image(s)-to-image generation. Produces illustrations, photographs, artwork, diagrams, logos, mockups, and other visual content.
4
+
5
+ Use this file for workflow-service feasibility and parameter constraints. `prompt`,
6
+ `reference_img_urls`, and the output controls are service operation parameters. Expose only the
7
+ subset that the product lets users control.
8
+
9
+ ## Parameters
10
+
11
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
12
+ |---|---|---|---|---|
13
+ | prompt | string | Yes | — | — |
14
+ | image_names | array[string] | No | ASCII only; use array format even for a single image | — |
15
+ | size | string | No | `WxH` format (e.g. `1024x768`); applies to all generated images | — |
16
+ | output_format | string | No | `png`, `jpeg`, `webp` | — |
17
+ | reference_img_urls | array[string] | No | list of image URLs to provide as reference | — |
18
+
19
+ ## Service Output
20
+
21
+ The operation returns `success`, `images` (each with `image_url` and `image_metadata`), and optional
22
+ `warnings`. Most app capabilities should normalize this to one `generated_image_url`; use an array
23
+ only when multiple generated images are an explicit product feature.
24
+
25
+ ## Constraints
26
+
27
+ - Put scene, style, composition, and content in `prompt`; put dimensions in `size`.
28
+ - Refer to reference images by position or content, not by URL text inside the prompt.
29
+ - Prefer one image per request. Two or three are possible but less consistent.
30
+ - Reference images guide style/content and do not guarantee pixel-perfect reproduction.
@@ -0,0 +1,47 @@
1
+ # SDK Version Evidence
2
+
3
+ Use this reference before writing or repairing `@howone/sdk` bindings. HowOne app contracts and
4
+ SDK APIs change independently; verify both.
5
+
6
+ ## Evidence Order
7
+
8
+ 1. Read `.howone/database/manifest.json` and `.howone/ai/manifest.json` for project-specific names,
9
+ fields, access rules, schemas, and workflow UUIDs.
10
+ 2. Read the app `package.json` for the requested `@howone/sdk` version.
11
+ 3. Read `node_modules/@howone/sdk/package.json` for the version actually installed.
12
+ 4. Inspect the installed version's public typings:
13
+ - `node_modules/@howone/sdk/dist/index.d.ts`
14
+ - `node_modules/@howone/sdk/dist/react.d.ts`
15
+ - `node_modules/@howone/sdk/dist/devtools.d.ts`
16
+ 5. Use this Skill for the workflow and code-generation recipe.
17
+ 6. Use official remote documentation only as supplemental evidence. Never let latest remote docs
18
+ override installed typings for an older app.
19
+
20
+ If steps 2 and 3 disagree, run the project's package manager install before coding. Do not repair
21
+ types by casting around a stale installation.
22
+
23
+ ## Deterministic Check
24
+
25
+ From the app root, run:
26
+
27
+ ```bash
28
+ node .howone/skills/howone/scripts/verify-project.mjs
29
+ ```
30
+
31
+ Fix every reported error before final validation. Warnings identify missing evidence or code that
32
+ still relies on compatibility behavior.
33
+
34
+ ## Lookup Patterns
35
+
36
+ Use `rg` against installed declarations instead of relying on remembered signatures:
37
+
38
+ ```bash
39
+ rg -n "CreateClientOptions|HowOneClientRuntime" node_modules/@howone/sdk/dist/index.d.ts
40
+ rg -n "defineAiAction|AiActionClient|WorkflowExecutionError" node_modules/@howone/sdk/dist/index.d.ts
41
+ rg -n "EntityClient|withEntityContract|withPublicEntities" node_modules/@howone/sdk/dist/index.d.ts
42
+ rg -n "HowOneProviderProps" node_modules/@howone/sdk/dist/react.d.ts
43
+ rg -n "ElementSelectorProviderProps" node_modules/@howone/sdk/dist/devtools.d.ts
44
+ ```
45
+
46
+ When declarations and this Skill disagree, use the installed declarations for signatures and this
47
+ Skill for platform ordering. Report the mismatch instead of silently inventing an adapter.
@@ -0,0 +1,35 @@
1
+ # Video Generation
2
+
3
+ Generates a video from a text prompt, with optional image-to-video (first/last frame), reference images for style guidance, and optional synchronized audio.
4
+
5
+ Use this file for workflow-service feasibility and parameter constraints. Keep the app capability
6
+ contract smaller than the service operation unless the product genuinely exposes every control.
7
+
8
+ ## Parameters
9
+
10
+ | Parameter | Type | Required | Allowed Values / Constraints | Default |
11
+ |---|---|---|---|---|
12
+ | prompt | string | Yes | — | — |
13
+ | video_name | string | No | ASCII characters only | auto-generated |
14
+ | aspect_ratio | string | No | `16:9`, `9:16`, `4:3`, `3:4`, `1:1`, `21:9` | `16:9` |
15
+ | resolution | string | No | `480p`, `720p`, `1080p` | `720p` |
16
+ | duration | integer | No | 4-10 seconds | 4 |
17
+ | first_frame_url | string | No | image URL, for image-to-video (starting frame) | — |
18
+ | last_frame_url | string | No | requires `first_frame_url` to be set | — |
19
+ | reference_images | array[string] | No | up to 3 image URLs | — |
20
+ | negative_prompt | string | No | — | — |
21
+ | generate_audio | boolean | No | `true`, `false` | `false` |
22
+
23
+ ## Service Output
24
+
25
+ The operation returns `success`, `video_url`, `video_metadata`, and the selected `model`. A normal
26
+ app capability should return only `video_url` unless technical metadata is visible or persisted.
27
+
28
+ ## Constraints
29
+
30
+ - `last_frame_url` is valid only when `first_frame_url` is also present.
31
+ - Use at most 3 `reference_images`.
32
+ - Generate 4-10 second clips. Build longer output from multiple clips plus video concatenation.
33
+ - Use `first_frame_url` for stronger character/style consistency across clips.
34
+ - When `generate_audio` is true, describe dialogue, sound effects, ambience, and music in `prompt`;
35
+ one speaker per clip is the most reliable.
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs'
4
+ import path from 'node:path'
5
+
6
+ const appRoot = path.resolve(process.argv[2] || process.cwd())
7
+ const errors = []
8
+ const warnings = []
9
+ const facts = []
10
+
11
+ function relative(filePath) {
12
+ return path.relative(appRoot, filePath) || '.'
13
+ }
14
+
15
+ function readText(filePath) {
16
+ return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null
17
+ }
18
+
19
+ function readJson(filePath, required = false) {
20
+ const source = readText(filePath)
21
+ if (source === null) {
22
+ if (required) errors.push(`Missing ${relative(filePath)}`)
23
+ return null
24
+ }
25
+ try {
26
+ return JSON.parse(source)
27
+ } catch (error) {
28
+ errors.push(`Invalid JSON in ${relative(filePath)}: ${error.message}`)
29
+ return null
30
+ }
31
+ }
32
+
33
+ function dependencySpec(pkg, name) {
34
+ return (
35
+ pkg?.dependencies?.[name] ??
36
+ pkg?.devDependencies?.[name] ??
37
+ pkg?.peerDependencies?.[name] ??
38
+ null
39
+ )
40
+ }
41
+
42
+ function collectWorkflowIds(value, output = []) {
43
+ if (Array.isArray(value)) {
44
+ for (const entry of value) collectWorkflowIds(entry, output)
45
+ return output
46
+ }
47
+ if (!value || typeof value !== 'object') return output
48
+ for (const [key, entry] of Object.entries(value)) {
49
+ if (key === 'workflowId' && typeof entry === 'string') output.push(entry)
50
+ collectWorkflowIds(entry, output)
51
+ }
52
+ return output
53
+ }
54
+
55
+ const packagePath = path.join(appRoot, 'package.json')
56
+ const pkg = readJson(packagePath, true)
57
+ const requested = dependencySpec(pkg, '@howone/sdk')
58
+ if (!requested) errors.push('package.json does not declare @howone/sdk')
59
+ else facts.push(`requested @howone/sdk: ${requested}`)
60
+
61
+ const installedPackagePath = path.join(appRoot, 'node_modules/@howone/sdk/package.json')
62
+ const installed = readJson(installedPackagePath)
63
+ if (!installed) {
64
+ errors.push('node_modules/@howone/sdk is missing; run the project package manager install')
65
+ } else {
66
+ facts.push(`installed @howone/sdk: ${installed.version}`)
67
+ const normalizedRequest = String(requested || '').replace(/^[~^]/, '')
68
+ if (/^\d/.test(normalizedRequest) && normalizedRequest !== installed.version) {
69
+ errors.push(`SDK version mismatch: package.json requests ${requested}, installed ${installed.version}`)
70
+ }
71
+ for (const declaration of ['index.d.ts', 'react.d.ts', 'devtools.d.ts']) {
72
+ const declarationPath = path.join(appRoot, 'node_modules/@howone/sdk/dist', declaration)
73
+ if (!fs.existsSync(declarationPath)) {
74
+ errors.push(`Installed SDK is missing dist/${declaration}`)
75
+ }
76
+ }
77
+ }
78
+
79
+ const databaseManifestPath = path.join(appRoot, '.howone/database/manifest.json')
80
+ const aiManifestPath = path.join(appRoot, '.howone/ai/manifest.json')
81
+ const databaseManifest = readJson(databaseManifestPath)
82
+ const aiManifest = readJson(aiManifestPath)
83
+ if (databaseManifest) facts.push(`database manifest: ${relative(databaseManifestPath)}`)
84
+ else warnings.push('No synced database manifest found')
85
+ if (aiManifest) {
86
+ facts.push(`AI manifest: ${relative(aiManifestPath)}`)
87
+ const workflowIds = collectWorkflowIds(aiManifest)
88
+ const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
89
+ for (const workflowId of workflowIds) {
90
+ if (!uuid.test(workflowId)) errors.push(`AI manifest contains invalid workflowId: ${workflowId}`)
91
+ }
92
+ if (workflowIds.length === 0) warnings.push('AI manifest contains no workflowId values')
93
+ } else {
94
+ warnings.push('No synced AI manifest found')
95
+ }
96
+
97
+ const sdkSourcePath = path.join(appRoot, 'src/lib/sdk.ts')
98
+ const sdkSource = readText(sdkSourcePath)
99
+ if (sdkSource === null) {
100
+ warnings.push('src/lib/sdk.ts is missing')
101
+ } else {
102
+ facts.push(`SDK binding: ${relative(sdkSourcePath)}`)
103
+ if (/\b(?:aiUrl|aiBaseUrl)\s*:/.test(sdkSource)) {
104
+ errors.push('src/lib/sdk.ts overrides the EAX URL; use createClient env only')
105
+ }
106
+ if (/\bmode\s*:\s*['"](?:auto|standalone|embedded)['"]/.test(sdkSource)) {
107
+ errors.push('src/lib/sdk.ts uses the removed createClient mode option')
108
+ }
109
+ }
110
+
111
+ const sourceRoot = path.join(appRoot, 'src')
112
+ if (fs.existsSync(sourceRoot)) {
113
+ const sourceFiles = []
114
+ const visit = (directory) => {
115
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
116
+ const entryPath = path.join(directory, entry.name)
117
+ if (entry.isDirectory()) visit(entryPath)
118
+ else if (/\.[cm]?[jt]sx?$/.test(entry.name)) sourceFiles.push(entryPath)
119
+ }
120
+ }
121
+ visit(sourceRoot)
122
+
123
+ for (const filePath of sourceFiles) {
124
+ const source = readText(filePath) || ''
125
+ if (
126
+ /import\s*\{[^}]*\bElementSelectorProvider\b[^}]*\}\s*from\s*['"]@howone\/sdk\/react['"]/.test(
127
+ source,
128
+ )
129
+ ) {
130
+ errors.push(`${relative(filePath)} imports ElementSelectorProvider from /react; use /devtools`)
131
+ }
132
+ if (/\burl\s*:\s*[`'"]\/api\//.test(source)) {
133
+ warnings.push(`${relative(filePath)} contains a raw /api/... path; the SDK REST base already includes /api`)
134
+ }
135
+ if (/<HowOneProvider\b(?![^>]*\bclient=)[^>]*>/.test(source)) {
136
+ errors.push(`${relative(filePath)} renders HowOneProvider without client={howone}`)
137
+ }
138
+ }
139
+ }
140
+
141
+ console.log(`HowOne project verification: ${appRoot}`)
142
+ for (const fact of facts) console.log(` ok: ${fact}`)
143
+ for (const warning of [...new Set(warnings)]) console.warn(` warning: ${warning}`)
144
+ for (const error of [...new Set(errors)]) console.error(` error: ${error}`)
145
+
146
+ if (errors.length > 0) {
147
+ console.error(`Verification failed with ${new Set(errors).size} error(s).`)
148
+ process.exit(1)
149
+ }
150
+
151
+ console.log('Verification passed.')
@@ -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.31",
17
+ "@howone/sdk": "2.0.0-beta.32",
18
18
  "@tailwindcss/vite": "^4.2.1",
19
19
  "class-variance-authority": "^0.7.1",
20
20
  "clsx": "^2.1.1",
@@ -1,12 +1,16 @@
1
+ import howone from '@/lib/sdk'
2
+ import { ElementSelectorProvider } from '@howone/sdk/devtools'
1
3
  import { HowOneProvider } from '@howone/sdk/react'
2
4
 
3
5
  function App() {
4
6
  return (
5
- <HowOneProvider brand="visible">
6
- <div className="App">
7
- <h1>Hello HowOne</h1>
8
- </div>
9
- </HowOneProvider>
7
+ <ElementSelectorProvider>
8
+ <HowOneProvider client={howone} brand="visible">
9
+ <div className="App">
10
+ <h1>Hello HowOne</h1>
11
+ </div>
12
+ </HowOneProvider>
13
+ </ElementSelectorProvider>
10
14
  )
11
15
  }
12
16
 
@@ -12,17 +12,19 @@ const client = createClient({
12
12
  })
13
13
 
14
14
  export const entities = defineEntities({
15
- // Add generated entity bindings here, for example:
16
- // Todo: client.entity<Todo, TodoCreate, TodoUpdate>("Todo"),
15
+ // Generate bindings from .howone/database/manifest.json.
16
+ // Wrap each client.entity(...) with withEntityContract(..., entityDefinition).
17
+ // Generate manifest-approved public bindings separately with
18
+ // definePublicEntities + withPublicEntityContract + withPublicEntities.
17
19
  })
18
20
 
19
21
  export const ai = defineAiActions({
20
- // Add generated AI action bindings here, for example:
21
- // import { z } from "zod" and define Zod schemas before using defineAiAction.
22
+ // Generate bindings from .howone/ai/manifest.json.
23
+ // Import z from "zod" and convert manifest JSON Schema before using defineAiAction.
22
24
  // Do not paste JSON Schema objects from .howone/ai/manifest.json here directly.
23
25
  // With outputSchema configured, howone.ai.<action>.run() returns the validated finalResult payload.
24
26
  // generateImage: defineAiAction("generateImage", {
25
- // workflowId: "<workflow-config-id>", // config_id for this capability
27
+ // workflowId: "<exact-manifest-uuid>", // required; there is no action-name fallback
26
28
  // inputSchema: generateImageInputSchema,
27
29
  // outputSchema: generateImageOutputSchema,
28
30
  // }),