@husar.ai/cli 0.4.1 → 0.4.3

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/AGENTS.md ADDED
@@ -0,0 +1,835 @@
1
+ # @husar.ai/cli
2
+
3
+ Command-line interface and MCP server for Husar CMS integration.
4
+
5
+ ## Package Overview
6
+
7
+ | Property | Value |
8
+ | -------- | --------------- |
9
+ | Name | `@husar.ai/cli` |
10
+ | Version | `0.4.1` |
11
+ | Binary | `husar.ai` |
12
+ | Location | `packages/cli` |
13
+
14
+ ## Dependencies
15
+
16
+ - `commander` - CLI framework
17
+ - `config-maker` - Configuration management (husar.json)
18
+ - `@husar.ai/ssr` - Code generation (generateZeus)
19
+ - `@husar.ai/genai` - AI tools and ORM tool definitions
20
+ - `@modelcontextprotocol/sdk` - MCP server implementation
21
+ - `zod` - Input validation
22
+ - `graphql` - Schema introspection and SDL generation
23
+
24
+ ## Source Files
25
+
26
+ | File | Purpose |
27
+ | --------------------------- | ------------------------------------------ |
28
+ | `src/cli.ts` | Main CLI entry point with commander setup |
29
+ | `src/mcp.ts` | Full MCP server implementation |
30
+ | `src/index.ts` | Exports parser function for external use |
31
+ | `src/functions/generate.ts` | Generate command implementation |
32
+ | `src/functions/parser.ts` | File parsing and CMS upload utilities |
33
+ | `src/functions/create.ts` | Create command (project scaffolding) |
34
+ | `src/auth/api.ts` | Cloud API client (getProjects, verify JWT) |
35
+ | `src/auth/login.ts` | Login flows (cloud + panel) |
36
+ | `src/auth/config.ts` | Auth config management (~/.husar/) |
37
+ | `src/types/config.ts` | Configuration type definitions |
38
+
39
+ ---
40
+
41
+ ## Configuration
42
+
43
+ The CLI uses `husar.json` configuration file managed by `config-maker`.
44
+
45
+ ### Config File Structure
46
+
47
+ ```json
48
+ {
49
+ "host": "https://your-husar-instance.com",
50
+ "adminToken": "your-admin-token",
51
+ "adminTokenEnv": "HUSAR_ADMIN_TOKEN",
52
+ "contentApiKey": "your-content-api-key",
53
+ "hostEnvironmentVariable": "HUSAR_HOST",
54
+ "authenticationEnvironmentVariable": "HUSAR_API_KEY",
55
+ "overrideHost": false
56
+ }
57
+ ```
58
+
59
+ ### Config Properties
60
+
61
+ | Property | Type | Description |
62
+ | ----------------------------------- | ------- | ------------------------------------------- |
63
+ | `host` | string | Base URL of the Husar CMS instance |
64
+ | `adminToken` | string | Admin API token (legacy, use adminTokenEnv) |
65
+ | `adminTokenEnv` | string | Env var name containing admin token |
66
+ | `contentApiKey` | string | Content API key for read-only access |
67
+ | `hostEnvironmentVariable` | string | Env var name for host (optional) |
68
+ | `authenticationEnvironmentVariable` | string | Env var name for auth token (optional) |
69
+ | `overrideHost` | boolean | Whether to override host from env |
70
+
71
+ **Note:** The `adminTokenEnv` field is preferred over `adminToken`. When set, the CLI reads the admin token from the specified environment variable (e.g., `HUSAR_ADMIN_TOKEN`). This allows `husar.json` to be safely committed to version control.
72
+
73
+ ### Environment Variables
74
+
75
+ - `HUSAR_HOST` / `NEXT_PUBLIC_HUSAR_HOST` / `VITE_HUSAR_HOST` - Host URL fallbacks
76
+ - `HUSAR_API_KEY` - Default auth environment variable
77
+ - `HUSAR_MCP_HOST` - MCP-specific host override
78
+ - `HUSAR_MCP_ADMIN_TOKEN` - MCP-specific admin token
79
+ - `MCP_PARSER_TIMEOUT_MS` - Parser timeout (default: 30000ms)
80
+
81
+ ---
82
+
83
+ ## CLI Commands
84
+
85
+ ### `husar.ai generate [folderPath]`
86
+
87
+ Generates the `cms/` folder structure with Zeus GraphQL client and helper files.
88
+
89
+ **Usage:**
90
+
91
+ ```bash
92
+ husar.ai generate # Generate in current directory
93
+ husar.ai generate ./src # Generate in ./src/cms/
94
+ ```
95
+
96
+ **Generated Files:**
97
+
98
+ ```
99
+ cms/
100
+ ├── zeus/
101
+ │ ├── index.ts # Zeus GraphQL client
102
+ │ └── const.ts # Constants and types
103
+ ├── host.ts # Host configuration and getCmsHost()
104
+ ├── ssr.ts # SSR client: husarClient setup
105
+ └── react.ts # React components: Shape, View, Model
106
+ ```
107
+
108
+ **Prerequisites:**
109
+
110
+ - `husar.json` with valid `host` configured
111
+ - Optionally set `hostEnvironmentVariable` and `authenticationEnvironmentVariable`
112
+
113
+ ---
114
+
115
+ ### `husar.ai copy <inputFile> <name>`
116
+
117
+ Parse HTML/JSX file using AI and upsert into CMS as model or shape.
118
+
119
+ **Usage:**
120
+
121
+ ```bash
122
+ husar.ai copy ./components/Hero.tsx hero_section
123
+ husar.ai copy ./components/ContactForm.tsx contact_form --type model
124
+ husar.ai copy ./pages/About.html about_page --type shape
125
+ ```
126
+
127
+ **Options:**
128
+ | Option | Default | Description |
129
+ |--------|---------|-------------|
130
+ | `-t, --type <type>` | `shape` | Target type: `model` or `shape` |
131
+
132
+ **Prerequisites:**
133
+
134
+ - `husar.json` with valid `host` and `adminToken`
135
+
136
+ **Supported File Types:**
137
+
138
+ - `.tsx`, `.jsx` - React/JSX components
139
+ - `.ts`, `.js` - TypeScript/JavaScript files
140
+ - `.html` - HTML files
141
+
142
+ ---
143
+
144
+ ### `husar.ai mcp`
145
+
146
+ Starts the MCP (Model Context Protocol) server for AI IDE integration.
147
+
148
+ **Usage:**
149
+
150
+ ```bash
151
+ husar.ai mcp
152
+ ```
153
+
154
+ **Integration with IDEs:**
155
+
156
+ For Claude Desktop, add to `claude_desktop_config.json`:
157
+
158
+ ```json
159
+ {
160
+ "mcpServers": {
161
+ "husar": {
162
+ "command": "npx",
163
+ "args": ["husar.ai", "mcp"],
164
+ "cwd": "/path/to/your/project"
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ For VS Code with Continue.dev or similar:
171
+
172
+ ```json
173
+ {
174
+ "mcpServers": {
175
+ "husar": {
176
+ "command": "husar.ai",
177
+ "args": ["mcp"]
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ---
184
+
185
+ ### `husar.ai create [projectName]`
186
+
187
+ Create a new project with Husar CMS integration. This is the recommended onboarding flow for new users.
188
+
189
+ **Usage:**
190
+
191
+ ```bash
192
+ husar.ai create # Interactive project creation
193
+ husar.ai create my-app # Create with specified name
194
+ husar.ai create my-app -f vite # Use Vite instead of Next.js
195
+ husar.ai create --skip-install # Skip npm install after scaffolding
196
+ ```
197
+
198
+ **Options:**
199
+ | Option | Default | Description |
200
+ |--------|---------|-------------|
201
+ | `-f, --framework <framework>` | `nextjs` | Framework: `nextjs` or `vite` |
202
+ | `--skip-install` | `false` | Skip package installation |
203
+
204
+ **Flow:**
205
+
206
+ 1. Choose connection method (manual URL or cloud login)
207
+ 2. If cloud login: Authenticate via browser → Select project from list
208
+ 3. Panel CMS login: Authenticate with SUPERADMIN credentials via browser
209
+ 4. Framework CLI runs (create-next-app or create-vite)
210
+ 5. Husar configuration added (`husar.json`, `.env.local`, `opencode.jsonc`)
211
+ 6. Husar packages installed (`@husar.ai/ssr`, `@husar.ai/render`)
212
+ 7. CMS client generated (`cms/` folder)
213
+
214
+ **Generated Configuration:**
215
+
216
+ ```
217
+ project/
218
+ ├── husar.json # CMS config (committal, no secrets)
219
+ ├── .env.local # Secrets (NOT committed)
220
+ └── opencode.jsonc # MCP integration for AI IDEs
221
+ ```
222
+
223
+ **husar.json (safe to commit):**
224
+
225
+ ```json
226
+ {
227
+ "host": "https://your-instance.husar.ai",
228
+ "hostEnvironmentVariable": "NEXT_PUBLIC_HUSAR_HOST",
229
+ "authenticationEnvironmentVariable": "HUSAR_API_KEY",
230
+ "adminTokenEnv": "HUSAR_ADMIN_TOKEN",
231
+ "overrideHost": false
232
+ }
233
+ ```
234
+
235
+ **.env.local (secrets - NOT committed):**
236
+
237
+ ```env
238
+ NEXT_PUBLIC_HUSAR_HOST=https://your-instance.husar.ai
239
+ HUSAR_API_KEY=
240
+ HUSAR_ADMIN_TOKEN=your-admin-token
241
+ ```
242
+
243
+ ---
244
+
245
+ ### `husar.ai login`
246
+
247
+ Log in to Husar.ai cloud via browser authentication.
248
+
249
+ **Usage:**
250
+
251
+ ```bash
252
+ husar.ai login
253
+ ```
254
+
255
+ **Flow:**
256
+
257
+ 1. Opens browser to `husar.ai/app/cli-auth`
258
+ 2. User authenticates (login or create account)
259
+ 3. JWT token is returned and saved to `~/.husar/config.json`
260
+
261
+ **Note:** Cloud login is optional. You can also use manual URL entry in the `create` command.
262
+
263
+ ---
264
+
265
+ ### `husar.ai logout`
266
+
267
+ Log out and clear stored credentials.
268
+
269
+ **Usage:**
270
+
271
+ ```bash
272
+ husar.ai logout
273
+ ```
274
+
275
+ **Clears:**
276
+
277
+ - Cloud JWT token
278
+ - Cached project authentications
279
+ - All data in `~/.husar/config.json`
280
+
281
+ ---
282
+
283
+ ### `husar.ai whoami`
284
+
285
+ Display current logged-in user and connected projects.
286
+
287
+ **Usage:**
288
+
289
+ ```bash
290
+ husar.ai whoami
291
+ ```
292
+
293
+ **Output:**
294
+
295
+ ```
296
+ 👤 Logged in as: user@example.com
297
+
298
+ 📦 Connected projects:
299
+ • my-project
300
+ Host: https://my-project.husar.ai
301
+
302
+ 📁 Config: ~/.husar/config.json
303
+ ```
304
+
305
+ ---
306
+
307
+ ## MCP Server Tools
308
+
309
+ The MCP server exposes tools for AI assistants to interact with Husar CMS.
310
+
311
+ ### Core Tools
312
+
313
+ #### `husar_copy`
314
+
315
+ Parse HTML/JSX file and upsert into CMS.
316
+
317
+ **Input Schema:**
318
+
319
+ ```typescript
320
+ {
321
+ path: string; // File path (absolute or relative to workspace)
322
+ type?: "model" | "shape"; // Target type (default: "shape")
323
+ name?: string; // CMS name (default: filename, no dashes)
324
+ workspaceRoot?: string; // Location of husar.json in monorepo
325
+ }
326
+ ```
327
+
328
+ **Example:**
329
+
330
+ ```json
331
+ {
332
+ "path": "packages/app/src/components/Hero.tsx",
333
+ "type": "shape",
334
+ "name": "hero_component"
335
+ }
336
+ ```
337
+
338
+ ---
339
+
340
+ #### `husar_generate`
341
+
342
+ Generate cms/ folder structure.
343
+
344
+ **Input Schema:**
345
+
346
+ ```typescript
347
+ {
348
+ folderPath?: string; // Target folder (default: "./src")
349
+ workspaceRoot?: string; // Location of husar.json
350
+ }
351
+ ```
352
+
353
+ **Output:**
354
+
355
+ ```json
356
+ {
357
+ "status": "ok",
358
+ "folder": "/absolute/path/to/cms"
359
+ }
360
+ ```
361
+
362
+ ---
363
+
364
+ ### GraphQL Admin API Tools
365
+
366
+ #### `husar_graphql_query`
367
+
368
+ Run a read-only GraphQL query against Admin API.
369
+
370
+ **Input Schema:**
371
+
372
+ ```typescript
373
+ {
374
+ query: string; // GraphQL query string
375
+ variables?: object; // Query variables
376
+ endpointPath?: string; // Endpoint path (default: "api/graphql")
377
+ workspaceRoot?: string;
378
+ }
379
+ ```
380
+
381
+ **Example:**
382
+
383
+ ```json
384
+ {
385
+ "query": "query { admin { models { name } } }",
386
+ "variables": {}
387
+ }
388
+ ```
389
+
390
+ ---
391
+
392
+ #### `husar_graphql_schema`
393
+
394
+ Fetch GraphQL schema (introspection JSON) from Admin API.
395
+
396
+ **Input Schema:**
397
+
398
+ ```typescript
399
+ {
400
+ endpointPath?: string; // Default: "api/graphql"
401
+ workspaceRoot?: string;
402
+ }
403
+ ```
404
+
405
+ ---
406
+
407
+ #### `husar_graphql_schema_sdl`
408
+
409
+ Fetch Admin GraphQL schema as human-readable SDL.
410
+
411
+ **Input Schema:**
412
+
413
+ ```typescript
414
+ {
415
+ endpointPath?: string; // Default: "api/graphql"
416
+ workspaceRoot?: string;
417
+ }
418
+ ```
419
+
420
+ **Output:** GraphQL SDL string
421
+
422
+ ---
423
+
424
+ ### GraphQL Content API Tools
425
+
426
+ #### `husar_content_graphql_query`
427
+
428
+ Run a read-only GraphQL query against Content API.
429
+
430
+ **Input Schema:**
431
+
432
+ ```typescript
433
+ {
434
+ query: string; // GraphQL query string
435
+ variables?: object; // Query variables
436
+ endpointPath?: string; // Default: "content/graphql"
437
+ apiKey?: string; // Content API key (or use apiKeyEnv)
438
+ apiKeyEnv?: string; // Env var name containing API key
439
+ workspaceRoot?: string;
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ #### `husar_content_graphql_schema`
446
+
447
+ Fetch GraphQL schema (introspection) from Content API.
448
+
449
+ **Input Schema:**
450
+
451
+ ```typescript
452
+ {
453
+ endpointPath?: string; // Default: "content/graphql"
454
+ apiKey?: string;
455
+ apiKeyEnv?: string;
456
+ workspaceRoot?: string;
457
+ }
458
+ ```
459
+
460
+ ---
461
+
462
+ #### `husar_content_graphql_schema_sdl`
463
+
464
+ Fetch Content GraphQL schema as SDL.
465
+
466
+ **Input Schema:**
467
+
468
+ ```typescript
469
+ {
470
+ endpointPath?: string; // Default: "content/graphql"
471
+ apiKey?: string;
472
+ apiKeyEnv?: string;
473
+ workspaceRoot?: string;
474
+ }
475
+ ```
476
+
477
+ ---
478
+
479
+ ### AI Query Suggestion Tools
480
+
481
+ #### `husar_graphql_suggest_query`
482
+
483
+ Generate a GraphQL query suggestion from SDL and task description.
484
+
485
+ **Input Schema:**
486
+
487
+ ```typescript
488
+ {
489
+ sdl: string; // GraphQL schema SDL
490
+ task: string; // Task description (e.g., "list posts by tag")
491
+ rootType?: string; // Root type (default: "Query")
492
+ }
493
+ ```
494
+
495
+ **Output:**
496
+
497
+ ```json
498
+ {
499
+ "query": "query GeneratedQuery($tag: String!) { posts(tag: $tag) { nodes { id title } } }",
500
+ "variables": { "tag": null },
501
+ "pickedField": "posts",
502
+ "rootType": "Query",
503
+ "candidates": [{ "name": "posts", "type": "PostConnection" }]
504
+ }
505
+ ```
506
+
507
+ ---
508
+
509
+ #### `husar_graphql_run_suggestion`
510
+
511
+ Generate a query from SDL + task and execute it on Admin API.
512
+
513
+ **Input Schema:**
514
+
515
+ ```typescript
516
+ {
517
+ sdl: string; // GraphQL schema SDL
518
+ task: string; // Task to execute
519
+ variables?: object; // Override variables
520
+ endpointPath?: string; // Default: "api/graphql"
521
+ workspaceRoot?: string;
522
+ }
523
+ ```
524
+
525
+ **Output:**
526
+
527
+ ```json
528
+ {
529
+ "query": "...",
530
+ "variables": { ... },
531
+ "result": { ... }
532
+ }
533
+ ```
534
+
535
+ ---
536
+
537
+ #### `husar_content_graphql_run_suggestion`
538
+
539
+ Generate a query from SDL + task and execute it on Content API.
540
+
541
+ **Input Schema:**
542
+
543
+ ```typescript
544
+ {
545
+ sdl: string;
546
+ task: string;
547
+ variables?: object;
548
+ endpointPath?: string; // Default: "content/graphql"
549
+ apiKey?: string;
550
+ apiKeyEnv?: string;
551
+ workspaceRoot?: string;
552
+ }
553
+ ```
554
+
555
+ ---
556
+
557
+ ### Admin ORM Tools
558
+
559
+ The MCP server also exposes ORM tools from `@husar.ai/genai` for CMS operations.
560
+
561
+ #### Model Tools
562
+
563
+ | Tool | Description |
564
+ | ---------------------- | -------------------------------------- |
565
+ | `model.model` | Return full model configuration |
566
+ | `model.previewFields` | Return expanded fields for model |
567
+ | `model.fieldSet` | Return admin page fieldset |
568
+ | `model.upsert` | Create or update a model document |
569
+ | `model.remove` | Remove a model entry |
570
+ | `model.list` | List model entries |
571
+ | `model.listPaginated` | List model entries (paginated) |
572
+ | `model.one` | Get one model entry |
573
+ | `model.listById` | Get entries by IDs |
574
+ | `model.getWithContent` | Get model definition + types + content |
575
+
576
+ #### View Tools
577
+
578
+ | Tool | Description |
579
+ | --------------------- | ------------------------------------- |
580
+ | `view.model` | Return full view configuration |
581
+ | `view.previewFields` | Return expanded fields for view |
582
+ | `view.fieldSet` | Return admin page fieldset |
583
+ | `view.upsert` | Create or update a view entry |
584
+ | `view.remove` | Remove a view entry |
585
+ | `view.list` | List view entries |
586
+ | `view.one` | Get one view entry |
587
+ | `view.getWithContent` | Get view definition + types + content |
588
+
589
+ #### Shape Tools
590
+
591
+ | Tool | Description |
592
+ | ------------------------- | ------------------------------- |
593
+ | `shape.model` | Return full shape configuration |
594
+ | `shape.previewFields` | Return expanded fields |
595
+ | `shape.fieldSet` | Return admin page fieldset |
596
+ | `shape.getWithDefinition` | Get shape definition + types |
597
+
598
+ #### Form Tools
599
+
600
+ | Tool | Description |
601
+ | ----------------------- | ------------------------------ |
602
+ | `form.model` | Return full form configuration |
603
+ | `form.previewFields` | Return expanded fields |
604
+ | `form.fieldSet` | Return admin page fieldset |
605
+ | `form.upsert` | Create or update a form entry |
606
+ | `form.remove` | Remove a form entry |
607
+ | `form.list` | List form entries |
608
+ | `form.one` | Get one form entry |
609
+ | `form.submitResponse` | Submit a form response |
610
+ | `form.responses` | List form responses |
611
+ | `form.response` | Get a form response by ID |
612
+ | `form.removeResponse` | Remove a form response |
613
+ | `form.responseFieldSet` | Get form response fieldset |
614
+
615
+ #### Definition Management Tools
616
+
617
+ | Tool | Description |
618
+ | -------------- | --------------------------------- |
619
+ | `upsertModel` | Create or update model definition |
620
+ | `removeModel` | Remove model definition |
621
+ | `upsertView` | Create or update view definition |
622
+ | `removeView` | Remove view definition |
623
+ | `upsertShape` | Create or update shape definition |
624
+ | `removeShape` | Remove shape definition |
625
+ | `upsertForm` | Create or update form definition |
626
+ | `removeForm` | Remove form definition |
627
+ | `listModels` | List all model definitions |
628
+ | `listViews` | List all view definitions |
629
+ | `listShapes` | List all shape definitions |
630
+ | `graphQLTypes` | Get generated GraphQL SDL schema |
631
+
632
+ #### Content & Media Tools
633
+
634
+ | Tool | Description |
635
+ | ------------------- | ------------------------------------- |
636
+ | `uploadFile` | Get signed S3 PUT URL for file upload |
637
+ | `generateContent` | Generate content using AI |
638
+ | `generateImage` | Generate an image |
639
+ | `translateDocument` | Translate a document |
640
+ | `translateView` | Translate a view |
641
+ | `translateForm` | Translate a form |
642
+
643
+ #### Link & Param Tools
644
+
645
+ | Tool | Description |
646
+ | --------------------------- | -------------------------------- |
647
+ | `upsertParam` | Create or update root param |
648
+ | `removeParam` | Remove root param |
649
+ | `upsertLink` | Create or update internal link |
650
+ | `removeLink` | Remove internal link |
651
+ | `links` | List internal links |
652
+ | `removeModelWithDocuments` | Remove model with all documents |
653
+ | `removeDocumentsWithParams` | Remove documents matching params |
654
+
655
+ #### Style Tools
656
+
657
+ | Tool | Description |
658
+ | ------------------------ | --------------------------------- |
659
+ | `style.tailwind.css.get` | Fetch current Tailwind CSS source |
660
+ | `style.tailwind.css.set` | Set Tailwind CSS source content |
661
+
662
+ #### Specialized Agent Tools
663
+
664
+ | Tool | Description |
665
+ | ---------------- | ----------------------------------------- |
666
+ | `husarViewAgent` | Create/modify views from natural language |
667
+
668
+ ---
669
+
670
+ ## Relationship with Other Packages
671
+
672
+ ```
673
+ @husar.ai/cli
674
+ ├── uses @husar.ai/ssr
675
+ │ └── generateZeus() - Creates typed GraphQL client
676
+ │ └── husarClient() - SSR client factory
677
+
678
+ ├── uses @husar.ai/genai
679
+ │ └── createOrmToolDefinitions() - Admin ORM tools
680
+ │ └── getOrmToolSpecs() - Tool specifications
681
+
682
+ └── uses @husar.ai/render (generated code references)
683
+ └── HusarComponents() - React component factory
684
+ ```
685
+
686
+ ---
687
+
688
+ ## Troubleshooting
689
+
690
+ ### "Host is not configured"
691
+
692
+ **Cause:** Missing `host` in `husar.json`
693
+
694
+ **Solution:**
695
+
696
+ 1. Run `husar.ai generate` to create config interactively
697
+ 2. Or create `husar.json` manually with `host` property
698
+
699
+ ### "Admin token is not configured"
700
+
701
+ **Cause:** Missing `adminToken` in `husar.json`
702
+
703
+ **Solution:**
704
+
705
+ 1. Get admin token from Husar CMS dashboard
706
+ 2. Add to `husar.json`: `"adminToken": "your-token"`
707
+
708
+ ### "Missing apiKey"
709
+
710
+ **Cause:** Content API operations require an API key
711
+
712
+ **Solution:**
713
+
714
+ 1. Add `contentApiKey` to `husar.json`
715
+ 2. Or pass `apiKey` directly to MCP tool
716
+ 3. Or set env var and use `apiKeyEnv` parameter
717
+
718
+ ### MCP Server Not Connecting
719
+
720
+ **Cause:** Configuration or path issues
721
+
722
+ **Solutions:**
723
+
724
+ 1. Ensure `husar.json` exists in the workspace root
725
+ 2. Check `cwd` in MCP config points to project root
726
+ 3. For monorepos, use `workspaceRoot` parameter
727
+ 4. Check stderr for error messages: `husar.ai mcp 2>&1`
728
+
729
+ ### Parser Timeout
730
+
731
+ **Cause:** AI parsing taking too long
732
+
733
+ **Solutions:**
734
+
735
+ 1. Set `MCP_PARSER_TIMEOUT_MS` env var (default: 30000)
736
+ 2. For MCP, internal timeout is configurable via code
737
+
738
+ ### "Failed to get upload URL"
739
+
740
+ **Cause:** Authentication or network issues
741
+
742
+ **Solutions:**
743
+
744
+ 1. Verify `adminToken` is valid and not expired
745
+ 2. Check `host` URL is correct and accessible
746
+ 3. Ensure the Husar instance is running
747
+
748
+ ### Generated Code Import Errors
749
+
750
+ **Cause:** Missing dependencies in target project
751
+
752
+ **Solutions:**
753
+
754
+ 1. Install required packages:
755
+ ```bash
756
+ npm install @husar.ai/ssr @husar.ai/render
757
+ ```
758
+ 2. Ensure TypeScript paths are configured if using `@/` imports
759
+
760
+ ---
761
+
762
+ ## Development Notes
763
+
764
+ ### Building
765
+
766
+ ```bash
767
+ npm run build # Compile with tspc
768
+ npm run watch # Watch mode
769
+ ```
770
+
771
+ ### Testing
772
+
773
+ ```bash
774
+ npm test # Run tests with node --test
775
+ ```
776
+
777
+ ### Running Locally
778
+
779
+ ```bash
780
+ # Direct execution
781
+ npx tsx src/cli.ts generate ./test-output
782
+
783
+ # After build
784
+ node dist/cli.js mcp
785
+ ```
786
+
787
+ ### MCP Server Debugging
788
+
789
+ The MCP server redirects console output to stderr to prevent interference with JSON-RPC communication. View logs via:
790
+
791
+ ```bash
792
+ husar.ai mcp 2>husar-mcp.log
793
+ ```
794
+
795
+ ---
796
+
797
+ ## CMS Field Types Reference
798
+
799
+ When using ORM tools, these are the available field types:
800
+
801
+ | Type | Description |
802
+ | ------------- | -------------------------- |
803
+ | `STRING` | Simple text field |
804
+ | `TITLE` | Title/heading field |
805
+ | `NUMBER` | Numeric value |
806
+ | `BOOLEAN` | True/false toggle |
807
+ | `DATE` | Date/datetime |
808
+ | `IMAGE_URL` | URL to image |
809
+ | `CONTENT` | Rich text/HTML content |
810
+ | `IMAGE` | Image with metadata |
811
+ | `VIDEO` | Video file |
812
+ | `FILE` | Generic file |
813
+ | `SHAPE` | Nested shape reference |
814
+ | `RELATION` | Reference to another model |
815
+ | `SELECT` | Dropdown selection |
816
+ | `OBJECT` | Nested object structure |
817
+ | `OBJECT_TABS` | Tabbed object structure |
818
+
819
+ ### Form Field Types
820
+
821
+ | Type | Description |
822
+ | ------------ | ---------------- |
823
+ | `TEXT` | Text display |
824
+ | `STRING` | Text input |
825
+ | `BOOLEAN` | Checkbox |
826
+ | `CONTENT` | Rich text editor |
827
+ | `STEP` | Form step/wizard |
828
+ | `INPUT` | Generic input |
829
+ | `GROUP` | Field grouping |
830
+ | `PORTAL` | Portal container |
831
+ | `SUBMIT` | Submit button |
832
+ | `RADIO_TEXT` | Radio with text |
833
+ | `BUTTON` | Action button |
834
+ | `VARIABLE` | Variable field |
835
+ | `DISPLAY` | Display only |