@powerhousedao/codegen 5.1.0-dev.39 → 5.1.0-dev.40

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": "@powerhousedao/codegen",
3
- "version": "5.1.0-dev.39",
3
+ "version": "5.1.0-dev.40",
4
4
  "license": "AGPL-3.0-only",
5
5
  "private": false,
6
6
  "type": "module",
@@ -52,16 +52,17 @@
52
52
  "hygen": "^6.2.11",
53
53
  "kysely": "^0.28.2",
54
54
  "kysely-pglite": "^0.6.1",
55
+ "package-json-validator": "^0.60.0",
55
56
  "prettier": "^3.6.2",
56
57
  "read-pkg": "^9.0.1",
57
58
  "semver": "^7.7.3",
58
59
  "ts-morph": "^26.0.0",
59
60
  "zocker": "^3.0.0",
60
- "@powerhousedao/config": "5.1.0-dev.39",
61
- "@powerhousedao/common": "5.1.0-dev.39",
62
- "@powerhousedao/design-system": "5.1.0-dev.39",
63
- "@powerhousedao/reactor-browser": "5.1.0-dev.39",
64
- "document-model": "5.1.0-dev.39"
61
+ "@powerhousedao/common": "5.1.0-dev.40",
62
+ "@powerhousedao/config": "5.1.0-dev.40",
63
+ "@powerhousedao/reactor-browser": "5.1.0-dev.40",
64
+ "@powerhousedao/design-system": "5.1.0-dev.40",
65
+ "document-model": "5.1.0-dev.40"
65
66
  },
66
67
  "devDependencies": {
67
68
  "@powerhousedao/analytics-engine-core": "^0.5.0",
@@ -74,7 +75,7 @@
74
75
  "react-dom": "^19.2.0",
75
76
  "vitest": "^3.2.4",
76
77
  "zod": "^4.1.13",
77
- "document-drive": "5.1.0-dev.39"
78
+ "document-drive": "5.1.0-dev.40"
78
79
  },
79
80
  "scripts": {
80
81
  "tsc": "tsc",
@@ -1,2 +0,0 @@
1
- export declare const claudeTemplate: string;
2
- //# sourceMappingURL=CLAUDE.md.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CLAUDE.md.d.ts","sourceRoot":"","sources":["../../../../src/templates/boilerplate/CLAUDE.md.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAqZtB,CAAC"}
@@ -1,408 +0,0 @@
1
- import { md } from "@tmpl/core";
2
- export const claudeTemplate = md `
3
- # Powerhouse Document Models Assistant
4
-
5
- This project creates document models, editors, processors and subgraphs for the Powerhouse ecosystem. Your role is to help users create these modules based on their needs.
6
-
7
- ## Core Concepts
8
-
9
- - **Document Model**: A template for creating documents. Defines schema and allowed operations for a document type.
10
- - **Document**: An instance of a document model containing actual data that follows the model's structure and can be modified using operations.
11
- - **Drive**: A document of type "powerhouse/document-drive" representing a collection of documents and folders. Add documents using "addActions" with "ADD_FILE" action.
12
- - **Action**: A proposed change to a document (JSON object with action name and input). Dispatch using "addActions" tool.
13
- - **Operation**: A completed change to a document containing the action plus metadata (index, timestamp, hash, errors). Actions become operations after dispatch.
14
-
15
- ## CRITICAL: MCP Tool Usage Rules
16
-
17
- **MANDATORY**: The \`reactor-mcp\` MUST BE USED when handling documents or document-models for the Powerhouse/Vetra ecosystem.
18
- If the \`reactor-mcp\` server is unavailable, ask the user to run \`ph vetra\` on a separate terminal to start the server and try to reconnect to the MCP server, DO NOT run it yourself.
19
-
20
- ### Key Requirements:
21
-
22
- - Never set document IDs manually - they're auto-generated by 'createDocument'
23
- - Minimize "addActions" calls by batching multiple actions together
24
- - Add new document model documents to "vetra-{hash}" drive unless specified otherwise
25
- - Always check document model schema before calling addActions
26
- - Use MCP tools for ALL document and document-model operations
27
-
28
- ## Document Model Creation Workflow
29
-
30
- ### 1. Planning Phase
31
-
32
- **MANDATORY**: Present your proposal to the user and ask for confirmation before implementing ANY document model.
33
-
34
- - **ALWAYS** describe the proposed document model structure (state schema, operations, modules) before creating
35
- - **NEVER** proceed with implementation without explicit user approval of your proposal
36
- - When in doubt, ask for clarification
37
- - Break complex models into logical modules and operations
38
-
39
- ### 2. Pre-Implementation Requirements
40
-
41
- **MANDATORY**: Check document model schema before making any MCP tool calls.
42
-
43
- - **ALWAYS** use \`mcp__reactor-mcp__getDocumentModelSchema\` with \`type: "powerhouse/document-model"\` first
44
- - Review input schema requirements for operations like \`ADD_MODULE\`, \`ADD_OPERATION\`, etc.
45
- - Ensure all required parameters (like \`id\` or \`scope\` fields) are included in action inputs
46
- - This prevents failed tool calls and reduces iteration
47
-
48
- ### 3. Implementation Requirements
49
-
50
- - Document model reducers must be **pure synchronous functions**
51
- - Reducers receive current state and operation, always returning the same result
52
- - Values like dates/IDs must come from operation input, not generated in reducer
53
- - Reducer code goes into SET_OPERATION_REDUCER action (no function header needed)
54
- - Reducers are wrapped with Mutative - you can mutate the state object directly
55
- - External imports go at the beginning of the actual reducer file in \`src/\`
56
- - Ensure that the reducer code of each operation in the document model schema is applied in \`document-models/<document-model-name>/src/reducers/<module-name>.ts\`
57
-
58
- ### 4. Quality assurance
59
-
60
- After doing changes to the code, or after creating a new document model or a new editor, _YOU MUST RUN_ the following commands to check for errors in your implementation:
61
-
62
- - **TypeScript Check**: Run \`npm run tsc\` to validate type safety
63
- - **ESLint Check**: Run \`npm run lint:fix\` to check for errors with ESLint
64
-
65
- ## Document editor creation flow
66
-
67
- When the user requests to create or make changes on a document editor, follow these steps:
68
-
69
- - Check if the document editor already exists and if it does, ask the user if a new one should be created or if the existing one should be reimplemented
70
- - If it's a new editor, create a new editor document on the "vetra-{hash}" drive if available, of type \`powerhouse/document-editor\`
71
- - Check the document editor schema and comply with it
72
- - After adding the editor document to the \`vetra-{hash}\` drive, a new editor will be generated in the \`editors\` folder
73
- - Inspect the hooks in \`editors/hooks\` as they should be useful
74
- - Read the schema of the document model that the editor is for to know how to interact with it
75
- - Style the editor using tailwind classes or a style tag. If using a style tag, make sure to make the selectors specific to only apply to the editor component.
76
- - Create modular components for the UI elements and place them on separate files to make it easier to maintain and update
77
- - Consider using the React Components exported by \`@powerhousedao/design-system\` and \`@powerhousedao/document-engineering\`
78
- - Separate business logic from presentation logic
79
- - Use TypeScript for type safety, avoid using any and type casting
80
- - Always check for type and lint errors after creating or modifying the editor
81
-
82
- ### Document Editor Implementation Pattern
83
-
84
- **CRITICAL**: When implementing document editors, use the modern React hooks pattern from \`@powerhousedao/reactor-browser\`.
85
-
86
- The following section is valid for editors that edit a single document type.
87
-
88
- #### Required Imports and Setup
89
-
90
- Using a "Todo" document model as example:
91
-
92
- ~~~typescript
93
- import { generateId } from "document-model/core";
94
- import { useSelectedTodoDocument } from "../hooks/useTodoDocument.js";
95
- import {
96
- addTodo,
97
- } from "../../document-models/todo/gen/creators.js";
98
-
99
- export default function Editor() {
100
- const [document, dispatch] = useSelectedTodoDocument();
101
-
102
- function handleAddTodo(values: { title: string }) {
103
- if (values.title) {
104
- dispatch(addTodo({ id: generateId(), title: values.title }));
105
- }
106
- };
107
- ~~~
108
-
109
- The \`useSelectedTodoDocument\` gets generated automatically so you don't need to implement it yourself.
110
-
111
- ## ⚠️ CRITICAL: Generated Files & Modification Rules
112
-
113
- ### Generated Files Rule
114
-
115
- **NEVER edit files in \`gen/\` folders** - they are auto-generated and will be overwritten.
116
-
117
- ### Document Model Modification Process
118
-
119
- For ANY document model changes, follow this **mandatory** two-step process:
120
-
121
- #### Step 1: Update Document Model via MCP
122
-
123
- Use \`mcp__reactor-mcp__addActions\` with operations like:
124
-
125
- - \`SET_OPERATION_SCHEMA\` - update input/output schemas
126
- - \`SET_OPERATION_REDUCER\` - update reducer code
127
- - \`SET_STATE_SCHEMA\` - update state definitions
128
-
129
- #### Step 2: Update Existing Source Files
130
-
131
- **ALSO manually update existing reducer files in \`src/\` folder** - these are NOT auto-generated.
132
- Make sure to check if the operation reducer code needs to be updated after changing the state schema.
133
-
134
- ### ⚠️ Critical Reminder
135
-
136
- **ALWAYS do BOTH steps when fixing reducer issues:**
137
-
138
- 1. ✅ Fix existing reducer files in \`src/\` manually
139
- 2. ✅ Update document model via MCP with same fixes
140
-
141
- **Forgetting step 2 means future code generations will still contain the bugs!**
142
-
143
- ## Reducer Implementation Guidelines
144
-
145
- ### ❌ Forbidden in Reducers (Non-Deterministic)
146
-
147
- - \`crypto.randomUUID()\`, \`Math.random()\`, \`Date.now()\`, \`new Date()\`
148
- - External API calls or side effects
149
- - Asynchronous functions
150
- - Any non-deterministic functions
151
-
152
- ### ❌ Forbidden Patterns
153
-
154
- ~~~typescript
155
- // NEVER use fallback values with non-deterministic functions
156
- id: action.input.id || crypto.randomUUID(); // ❌ FORBIDDEN
157
- timestamp: action.input.timestamp || new Date(); // ❌ FORBIDDEN
158
- ~~~
159
-
160
- ### ✅ Required Pattern
161
-
162
- All dynamic values must come from action input:
163
-
164
- - **IDs**: Include \`id: OID!\` in input schema, use \`action.input.id\` in reducer
165
- - **Timestamps**: Include \`timestamp: DateTime!\` in input schema
166
- - **Computed values**: Calculate before dispatching action
167
-
168
- ### Example
169
-
170
- ~~~typescript
171
- // ❌ BAD - impure reducer
172
- const newItem = {
173
- id: crypto.randomUUID(), // Non-deterministic
174
- createdAt: new Date(), // Non-deterministic
175
- };
176
-
177
- // ✅ GOOD - pure reducer
178
- const newItem = {
179
- id: action.input.id, // From action input
180
- createdAt: action.input.createdAt, // From action input
181
- };
182
- ~~~
183
-
184
- ### Handling Nullable Input Types
185
-
186
- **CRITICAL**: Be careful when handling optional input types:
187
-
188
- - Optional input types use \`InputMaybe<T>\` allowing \`null | undefined | T\`.
189
- - Optional state types use \`Maybe<T>\` = \`T | null\`.
190
- - If there is no applicable default value then use \`|| null\`.
191
-
192
- ~~~typescript
193
- // ❌ BAD - Type error with Maybe<string>
194
- amount: action.input.amount,
195
- notes: action.input.notes,
196
-
197
- // ✅ GOOD - Matches Maybe<T> = T | null
198
- amount: action.input.amount || null,
199
- notes: action.input.notes || [],
200
- ~~~
201
-
202
- Use truthy checks when conditionally assigning optional values from input to state:
203
-
204
- ~~~typescript
205
- // ❌ BAD - Type 'string | null' is not assignable to type 'string'.
206
- if (action.input.field !== undefined) entry.field = action.input.field;
207
-
208
- // ✅ GOOD - use truthy checks
209
- if (action.input.field) state.field = action.input.field;
210
-
211
- // ✅ GOOD - For booleans use explicit null/undefined checks
212
- if (action.input.field !== undefined && action.input.field !== null)
213
- state.field = action.input.field;
214
- ~~~
215
-
216
- ### Error Handling in Operations
217
-
218
- **MANDATORY**: Define specific error types for each operation to handle invalid inputs and edge cases properly.
219
- Action inputs are validated so they are guaranteed to respect the input schema.
220
- Errors referenced in the reducer code will be imported automatically.
221
-
222
- #### Error Definition Requirements
223
-
224
- 1. **Add error definitions** to operations using \`ADD_OPERATION_ERROR\`:
225
- - \`code\`: Uppercase snake_case (e.g., \`"MISSING_ID"\`, \`"ENTRY_NOT_FOUND"\`)
226
- - \`name\`: PascalCase ending with "Error" (e.g., \`"MissingIdError"\`, \`"EntryNotFoundError"\`)
227
- - \`description\`: Human-readable description of the error condition
228
-
229
- 2. **Error names must end with "Error"** for consistency and code generation
230
-
231
- 3. **Use specific error types** rather than generic validation
232
-
233
- 4. **Must use unique error names and ids**
234
-
235
- #### Error Usage in Reducers
236
-
237
- ~~~typescript
238
- // ✅ GOOD - Throw specific errors by name
239
- if (!action.input.id) {
240
- throw new MissingIdError("ID is required for operation");
241
- }
242
-
243
- if (entryIndex === -1) {
244
- throw new EntryNotFoundError(\`Entry not found\`);
245
- }
246
-
247
- // ❌ BAD - Generic Error
248
- throw new Error("Something went wrong");
249
-
250
- // ❌ BAD - Nested error access
251
- throw new errors.ModuleName.MissingIdError("message");
252
-
253
- // ❌ BAD - Do not import error classes in the reducer code,
254
- import { MissingIdError } from "../../gen/module-name/error.js";
255
-
256
- // ✅ GOOD - Simply reference the error and it will be imported automatically
257
- throw new MissingIdError("message");
258
- ~~~
259
-
260
- #### Common Error Patterns
261
-
262
- - **EntityNotFoundError**: Referenced entity doesn't exist
263
- - **DuplicateIdError**: ID already exists when creating new entries
264
- - **InvalidInputError**: Business logic violations
265
- - **PermissionDeniedError**: Access control violations
266
-
267
- ## Document Model Structure
268
-
269
- ### Core Components
270
-
271
- - **Basic Metadata**: \`id\`, \`name\`, \`extension\`, \`description\`, \`author\` (name + website)
272
- - **Specifications**: Versioned specs with \`version\`, \`changeLog\`, \`state\` (global/local with schema, initialValue, examples)
273
- - **Modules**: Operational modules containing their operations
274
-
275
- ## Available Document Model Operations (37 total)
276
-
277
- | Category | Operations | Count |
278
- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
279
- | **Header Management** | \`SET_MODEL_NAME\`, \`SET_MODEL_ID\`, \`SET_MODEL_EXTENSION\`, \`SET_MODEL_DESCRIPTION\`, \`SET_AUTHOR_NAME\`, \`SET_AUTHOR_WEBSITE\` | 6 |
280
- | **Versioning** | ⚠️ **DO NOT USE** - Not implemented | 0 |
281
- | **Module Management** | \`ADD_MODULE\`, \`SET_MODULE_NAME\`, \`SET_MODULE_DESCRIPTION\`, \`DELETE_MODULE\`, \`REORDER_MODULES\` | 5 |
282
- | **Operation Management** | \`ADD_OPERATION\`, \`SET_OPERATION_NAME\`, \`SET_OPERATION_SCHEMA\`, \`SET_OPERATION_DESCRIPTION\`, \`SET_OPERATION_TEMPLATE\`, \`SET_OPERATION_REDUCER\`, \`MOVE_OPERATION\`, \`DELETE_OPERATION\`, \`REORDER_MODULE_OPERATIONS\` | 9 |
283
- | **Operation Error Management** | \`ADD_OPERATION_ERROR\`, \`SET_OPERATION_ERROR_CODE\`, \`SET_OPERATION_ERROR_NAME\`, \`SET_OPERATION_ERROR_DESCRIPTION\`, \`SET_OPERATION_ERROR_TEMPLATE\`, \`DELETE_OPERATION_ERROR\`, \`REORDER_OPERATION_ERRORS\` | 7 |
284
- | **Operation Example Management** | \`ADD_OPERATION_EXAMPLE\`, \`UPDATE_OPERATION_EXAMPLE\`, \`DELETE_OPERATION_EXAMPLE\`, \`REORDER_OPERATION_EXAMPLES\` | 4 |
285
- | **State Management** | \`SET_STATE_SCHEMA\`, \`SET_INITIAL_STATE\`, \`ADD_STATE_EXAMPLE\`, \`UPDATE_STATE_EXAMPLE\`, \`DELETE_STATE_EXAMPLE\`, \`REORDER_STATE_EXAMPLES\` | 6 |
286
-
287
- ## Best Practices & Design Principles
288
-
289
- ### Scope Selection
290
-
291
- - **\`scope: "global"\`**: State shared among all users with document access
292
- - **\`scope: "local"\`**: State private to each individual user
293
-
294
- ### Operation Design
295
-
296
- - Use descriptive operation names (e.g., \`ADD_LINE_ITEM\`, \`UPDATE_RECIPIENT\`)
297
- - One operation per user intent (separate concerns)
298
- - Include comprehensive examples and error definitions
299
- - Organize related operations into logical modules
300
-
301
- ## GraphQL Schema Guidelines
302
-
303
- ### Document State Schema
304
-
305
- - **Most fields optional** to support creating empty documents
306
- - Use required fields \`!\` only when absolutely necessary
307
- - Defaults handled by operations, not schema
308
-
309
- ### ⚠️ CRITICAL: State Type Naming Convention
310
-
311
- **MANDATORY**: The global state type name MUST follow this exact pattern:
312
-
313
- ~~~graphql
314
- type <DocumentModelName>State {
315
- # your fields here
316
- }
317
- ~~~
318
-
319
- **DO NOT** append "Global" to the state type name, even when defining global state:
320
-
321
- ~~~graphql
322
- // ❌ WRONG - Do not use "GlobalState" suffix
323
- type TodoListGlobalState {
324
- todos: [Todo!]!
325
- }
326
-
327
- // ✅ CORRECT - Use only "State" suffix
328
- type TodoListState {
329
- todos: [Todo!]!
330
- }
331
-
332
- // ✅ CORRECT - Use "LocalState" suffix for Local scope
333
- type TodoListLocalState {
334
- localTodos: [Todo!]!
335
- }
336
- ~~~
337
-
338
- **Why this matters:**
339
-
340
- - The code generator expects the type to be named \`<DocumentModelName>State\`
341
- - Using \`GlobalState\` or \`LocalState\` suffix will cause TypeScript compilation errors
342
- - This applies when using \`SET_STATE_SCHEMA\` with \`scope: "global"\`
343
-
344
- **Rule**: For global state, the type should be \`<DocumentModelName>State\`. For local state (if needed), the type name should be \`<DocumentModelName>LocalState\`.
345
-
346
- ### Available Scalar Types
347
-
348
- | Standard | Custom Identity | Custom Amounts | Custom Specialized |
349
- | --------- | ---------------------- | ------------------- | ------------------ |
350
- | \`String\` | \`OID\` (Object ID) | \`Amount\` | \`EthereumAddress\` |
351
- | \`Int\` | \`PHID\` (Powerhouse ID) | \`Amount_Tokens\` | \`EmailAddress\` |
352
- | \`Float\` | \`OLabel\` | \`Amount_Money\` | \`Date\` |
353
- | \`Boolean\` | | \`Amount_Fiat\` | \`DateTime\` |
354
- | | | \`Amount_Currency\` | \`URL\` |
355
- | | | \`Amount_Crypto\` | \`Currency\` |
356
- | | | \`Amount_Percentage\` | |
357
-
358
- ### Arrays and Objects
359
-
360
- - **Arrays**: Must be mandatory \`[ObjectType!]!\`
361
- - **Objects in arrays**: Must include \`OID!\` field for unique identification
362
- - Include \`OLabel\` for metadata when relevant
363
-
364
- ### Input Types
365
-
366
- - Reflect user intent with descriptive names
367
- - Simple, specific fields over complex nested types
368
- - System auto-generates \`OID\` for new objects (users don't provide manually)
369
-
370
- ## Working with Drives
371
-
372
- **MANDATORY**: Check the document-drive schema before performing drive operations.
373
-
374
- ### Drive Types
375
-
376
- There might be two drives available with a special use case:
377
-
378
- 1. **Vetra Drive** (\`vetra-{hash}\`):
379
- - Contains **source documents**: document models and document editors
380
- - Used for development
381
- - Add document model and editor definitions here
382
-
383
- 2. **Preview Drive** (\`preview-{hash}\`, named "Vetra Preview"):
384
- - Contains **demo and preview documents** (document instances)
385
- - Used for showcasing and testing document models
386
- - Add actual document instances here
387
-
388
- ### Drive Operations
389
-
390
- When working with drives (adding/removing documents, creating folders, etc.):
391
-
392
- 1. **Always get the drive schema first**:
393
-
394
- ~~~typescript
395
- mcp__reactor -
396
- mcp__getDocumentModelSchema({ type: "powerhouse/document-drive" });
397
- ~~~
398
-
399
- 2. **Review available operations** in the schema, such as:
400
- - \`ADD_FILE\` - Add a document to the drive
401
- - \`ADD_FOLDER\` - Create a new folder
402
- - \`DELETE_NODE\` - Remove a file or folder (use this, NOT "DELETE_FILE")
403
- - \`UPDATE_NODE\` - Update node properties
404
- - \`MOVE_NODE\` - Move a node to different location
405
-
406
- 3. **Check input schemas** for each operation to ensure you're passing correct parameters
407
- `.raw;
408
- //# sourceMappingURL=CLAUDE.md.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CLAUDE.md.js","sourceRoot":"","sources":["../../../../src/templates/boilerplate/CLAUDE.md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqZ/B,CAAC,GAAG,CAAC"}