@husar.ai/cli 0.4.0 → 0.4.2
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 +835 -0
- package/MCP_SERVER.md +92 -0
- package/dist/auth/api.d.ts +15 -0
- package/dist/auth/api.js +86 -0
- package/dist/auth/api.js.map +1 -0
- package/dist/auth/config.d.ts +32 -0
- package/dist/auth/config.js +95 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/login.d.ts +30 -0
- package/dist/auth/login.js +450 -0
- package/dist/auth/login.js.map +1 -0
- package/dist/cli.js +83 -3
- package/dist/cli.js.map +1 -1
- package/dist/functions/create.d.ts +6 -0
- package/dist/functions/create.js +311 -0
- package/dist/functions/create.js.map +1 -0
- package/dist/mcp.js +20 -14
- package/dist/mcp.js.map +1 -1
- package/dist/types/config.d.ts +3 -1
- package/dist/types/config.js +12 -1
- package/dist/types/config.js.map +1 -1
- package/dist/zeus/const.js +1410 -218
- package/dist/zeus/const.js.map +1 -1
- package/dist/zeus/index.d.ts +6889 -1508
- package/dist/zeus/index.js +197 -11
- package/dist/zeus/index.js.map +1 -1
- package/package.json +3 -3
- package/src/auth/api.ts +133 -0
- package/src/auth/config.ts +198 -0
- package/src/auth/login.ts +631 -0
- package/src/cli.ts +96 -4
- package/src/functions/create.ts +489 -0
- package/src/mcp.ts +47 -27
- package/src/types/config.ts +32 -1
- package/src/zeus/const.ts +1418 -218
- package/src/zeus/index.ts +6969 -1611
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 |
|