@gzl10/nexus-backend 0.14.0 → 0.15.0
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/claude-commands/nexus-docs.md +66 -0
- package/claude-commands/nexus-new-action.md +99 -0
- package/claude-commands/nexus-new-entity.md +142 -0
- package/claude-commands/nexus-new-module.md +78 -0
- package/claude-commands/nexus-new-plugin.md +153 -0
- package/claude-commands/nexus-update-tutorial-app.md +61 -0
- package/claude-commands/nexus-update-tutorial-plugin.md +53 -0
- package/dist/cli.js +4817 -7935
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +155 -152
- package/dist/index.js +2324 -5712
- package/dist/index.js.map +1 -1
- package/dist/main.js +2297 -5678
- package/dist/main.js.map +1 -1
- package/migrations/core__1773764515717_auto.js +193 -0
- package/migrations/core__1773864100000_audit_log.js +30 -0
- package/migrations/core__1773864200000_migrate_auth_audit.js +85 -0
- package/package.json +21 -30
- package/migrations/core__1773623432919_auto.js +0 -416
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Nexus documentation lookup
|
|
2
|
+
|
|
3
|
+
Search Nexus documentation and explain a concept with examples.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS — Concept to look up (e.g. "hooks", "tree entity", "CASL permissions", "field factories", "computed entity", "standalone actions")
|
|
8
|
+
|
|
9
|
+
## Step 1: Search documentation files
|
|
10
|
+
|
|
11
|
+
Search these files in order for relevant information:
|
|
12
|
+
|
|
13
|
+
1. **AGENTS.md** files (quick reference with gotchas):
|
|
14
|
+
- `packages/sdk/AGENTS.md`
|
|
15
|
+
- `packages/backend/AGENTS.md`
|
|
16
|
+
- `packages/client/AGENTS.md`
|
|
17
|
+
- `packages/ui/AGENTS.md`
|
|
18
|
+
|
|
19
|
+
2. **llms.txt** (project overview and file map)
|
|
20
|
+
|
|
21
|
+
3. **CLAUDE.md** (conventions and patterns)
|
|
22
|
+
|
|
23
|
+
4. **Source code** (for detailed API):
|
|
24
|
+
- `packages/sdk/src/types/` — type definitions
|
|
25
|
+
- `packages/sdk/src/fields/` — field factories
|
|
26
|
+
- `packages/backend/src/runtime/` — entity services
|
|
27
|
+
- `packages/backend/src/core/` — middleware, CASL, events
|
|
28
|
+
|
|
29
|
+
Use Grep to search for the concept across these files.
|
|
30
|
+
|
|
31
|
+
## Step 2: Search demo code
|
|
32
|
+
|
|
33
|
+
Check demos for usage examples:
|
|
34
|
+
|
|
35
|
+
- `demos/backend-demo/` — app developer patterns
|
|
36
|
+
- `demos/plugin-demo/` — plugin developer patterns
|
|
37
|
+
|
|
38
|
+
## Step 3: Explain
|
|
39
|
+
|
|
40
|
+
Present the answer in this format:
|
|
41
|
+
|
|
42
|
+
```markdown
|
|
43
|
+
## {Concept}
|
|
44
|
+
|
|
45
|
+
**What:** One-line description
|
|
46
|
+
|
|
47
|
+
**When to use:** Scenarios where this applies
|
|
48
|
+
|
|
49
|
+
**Example:**
|
|
50
|
+
{Minimal working code example}
|
|
51
|
+
|
|
52
|
+
**Gotchas:**
|
|
53
|
+
- {List of common mistakes}
|
|
54
|
+
|
|
55
|
+
**Reference files:**
|
|
56
|
+
- {Paths to relevant source files}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
|
|
61
|
+
- Always include a working code example (not pseudocode)
|
|
62
|
+
- Include gotchas specific to the concept
|
|
63
|
+
- Reference the actual source files where the implementation lives
|
|
64
|
+
- If the concept has different behavior per entity type, show each
|
|
65
|
+
- Do NOT make up API signatures — verify against actual source code
|
|
66
|
+
- This command works WITHOUT Neural MCP — it reads local files only
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Create a new Nexus standalone action
|
|
2
|
+
|
|
3
|
+
Add a standalone action to a module. Actions are operations without dedicated persistence (send email, export, batch process).
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS — Action name (e.g. "export-csv", "send-report", "sync-data"). Kebab-case.
|
|
8
|
+
|
|
9
|
+
## Step 1: Detect context
|
|
10
|
+
|
|
11
|
+
Find which module to add the action to:
|
|
12
|
+
|
|
13
|
+
1. Check current directory — if inside `src/modules/{name}/`, use that module
|
|
14
|
+
2. Otherwise, list available modules and ask
|
|
15
|
+
|
|
16
|
+
## Step 2: Ask for details
|
|
17
|
+
|
|
18
|
+
1. **Scope** — where does the action button appear?
|
|
19
|
+
- `module` — button in the module toolbar (no entity context)
|
|
20
|
+
- `entity` — button in entity list toolbar (entity context, no specific row)
|
|
21
|
+
- `row` — dropdown per row (receives `:id` param)
|
|
22
|
+
|
|
23
|
+
2. **Input fields** — does the action need a form before executing? (optional)
|
|
24
|
+
3. **Output** — what to show after execution?
|
|
25
|
+
- No output (just success notification)
|
|
26
|
+
- Structured output (modal with fields)
|
|
27
|
+
- Page redirect
|
|
28
|
+
4. **Variant** — button style: `default`, `primary`, `danger`
|
|
29
|
+
|
|
30
|
+
## Step 3: Generate action file
|
|
31
|
+
|
|
32
|
+
Create `src/modules/{module}/actions/{name}.action.ts`:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import type { ActionDefinition, ModuleContext, Request, Response } from '@gzl10/nexus-sdk'
|
|
36
|
+
import { useTextField, useSelectField } from '@gzl10/nexus-sdk/fields'
|
|
37
|
+
|
|
38
|
+
export const {camelName}Action: ActionDefinition = {
|
|
39
|
+
name: '{kebab-name}',
|
|
40
|
+
label: { en: '{Label}', es: '{Etiqueta}' },
|
|
41
|
+
icon: '{icon}',
|
|
42
|
+
scope: '{scope}', // 'module' | 'entity' | 'row'
|
|
43
|
+
variant: 'primary',
|
|
44
|
+
|
|
45
|
+
// Input form (optional — omit if no form needed)
|
|
46
|
+
input: {
|
|
47
|
+
format: useSelectField({
|
|
48
|
+
label: { en: 'Format', es: 'Formato' },
|
|
49
|
+
options: [
|
|
50
|
+
{ value: 'csv', label: 'CSV' },
|
|
51
|
+
{ value: 'json', label: 'JSON' }
|
|
52
|
+
]
|
|
53
|
+
})
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
// Handler
|
|
57
|
+
handler: (ctx: ModuleContext) => async (req: Request, res: Response) => {
|
|
58
|
+
const { format } = req.body
|
|
59
|
+
|
|
60
|
+
// Action logic here
|
|
61
|
+
// Use ctx.db, ctx.services, ctx.logger, ctx.errors
|
|
62
|
+
|
|
63
|
+
res.json({ success: true, message: 'Action completed' })
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
casl: {
|
|
67
|
+
subject: '{Subject}',
|
|
68
|
+
permissions: {
|
|
69
|
+
ADMIN: { actions: ['execute'] }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Step 4: Update module manifest
|
|
76
|
+
|
|
77
|
+
Read the module's `index.ts`, add the import, and include in `actions[]`:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { {camelName}Action } from './actions/{name}.action.js'
|
|
81
|
+
|
|
82
|
+
// Add to manifest
|
|
83
|
+
actions: [...existing, {camelName}Action]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Step 5: Verify
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx tsc --noEmit
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Gotchas
|
|
93
|
+
|
|
94
|
+
- Actions use `handler: (ctx) => async (req, res) => {}` — factory pattern like hooks
|
|
95
|
+
- `scope: 'row'` actions receive `req.params.id`
|
|
96
|
+
- `input` defines the form shown before execution (Record<string, FieldDefinition>)
|
|
97
|
+
- `output: {}` shows raw JSON result, `output` with fields shows structured modal
|
|
98
|
+
- `batch: true` + `timeout: number` for batch processing with SSE progress
|
|
99
|
+
- `disabled` accepts `FieldCondition` for per-row client-side evaluation
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Create a new Nexus entity
|
|
2
|
+
|
|
3
|
+
Add an entity to an existing module.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS — Entity type and name (e.g. "collection products", "single settings", "tree categories"). If only name given, defaults to collection.
|
|
8
|
+
|
|
9
|
+
## Step 1: Detect context
|
|
10
|
+
|
|
11
|
+
Find which module to add the entity to:
|
|
12
|
+
|
|
13
|
+
1. Check current directory — if inside `src/modules/{name}/`, use that module
|
|
14
|
+
2. Otherwise, list available modules and ask:
|
|
15
|
+
```bash
|
|
16
|
+
ls src/modules/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Step 2: Ask for details
|
|
20
|
+
|
|
21
|
+
Parse type from arguments (collection/single/tree/dag/view/computed). Then ask:
|
|
22
|
+
|
|
23
|
+
**For collection:**
|
|
24
|
+
- Table name (default: argument name)
|
|
25
|
+
- Label (en/es)
|
|
26
|
+
- Fields to include (suggest common ones)
|
|
27
|
+
- Timestamps? (default: yes)
|
|
28
|
+
- Soft delete? (default: no)
|
|
29
|
+
- CASL subject name
|
|
30
|
+
|
|
31
|
+
**For single:**
|
|
32
|
+
- Key name (e.g. "{module}_settings")
|
|
33
|
+
- Label
|
|
34
|
+
- Fields
|
|
35
|
+
- Default values
|
|
36
|
+
|
|
37
|
+
**For tree:**
|
|
38
|
+
- Table name
|
|
39
|
+
- Label
|
|
40
|
+
- Fields (id and a labelField at minimum)
|
|
41
|
+
|
|
42
|
+
## Step 3: Generate entity file
|
|
43
|
+
|
|
44
|
+
Create `src/modules/{module}/entities/{name}.ts`:
|
|
45
|
+
|
|
46
|
+
### Collection template
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import type { CollectionEntityDefinition } from '@gzl10/nexus-sdk'
|
|
50
|
+
import { useIdField, useTextField } from '@gzl10/nexus-sdk/fields'
|
|
51
|
+
|
|
52
|
+
export const {name}Entity: CollectionEntityDefinition = {
|
|
53
|
+
table: '{table_name}',
|
|
54
|
+
type: 'collection',
|
|
55
|
+
label: { en: '{Label}', es: '{Etiqueta}' },
|
|
56
|
+
labelField: '{first_text_field}',
|
|
57
|
+
timestamps: true,
|
|
58
|
+
|
|
59
|
+
fields: {
|
|
60
|
+
id: useIdField(),
|
|
61
|
+
// ... generated fields
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
casl: {
|
|
65
|
+
subject: '{Subject}',
|
|
66
|
+
permissions: {
|
|
67
|
+
ADMIN: { actions: ['manage'] },
|
|
68
|
+
EDITOR: { actions: ['read', 'create', 'update'] },
|
|
69
|
+
USER: { actions: ['read'] }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Single template
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import type { SingleEntityDefinition } from '@gzl10/nexus-sdk'
|
|
79
|
+
|
|
80
|
+
export const {name}Entity: SingleEntityDefinition = {
|
|
81
|
+
type: 'single',
|
|
82
|
+
key: '{key_name}',
|
|
83
|
+
label: { en: '{Label}', es: '{Etiqueta}' },
|
|
84
|
+
icon: 'Settings',
|
|
85
|
+
|
|
86
|
+
fields: {
|
|
87
|
+
// ... generated fields
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
defaults: {
|
|
91
|
+
// ... matching fields
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Tree template
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import type { TreeEntityDefinition } from '@gzl10/nexus-sdk'
|
|
100
|
+
import { useIdField, useTextField } from '@gzl10/nexus-sdk/fields'
|
|
101
|
+
|
|
102
|
+
export const {name}Entity: TreeEntityDefinition = {
|
|
103
|
+
table: '{table_name}',
|
|
104
|
+
type: 'tree',
|
|
105
|
+
label: { en: '{Label}', es: '{Etiqueta}' },
|
|
106
|
+
labelField: '{first_text_field}',
|
|
107
|
+
|
|
108
|
+
fields: {
|
|
109
|
+
id: useIdField(),
|
|
110
|
+
// ... generated fields
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
seed: []
|
|
114
|
+
// parent_id is auto-injected — do NOT define it
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Step 4: Update module manifest
|
|
119
|
+
|
|
120
|
+
Read the module's `index.ts`, add the import, and include in `definitions[]`:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { {name}Entity } from './entities/{name}.js'
|
|
124
|
+
|
|
125
|
+
// Add to definitions array
|
|
126
|
+
definitions: [...existing, {name}Entity]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Step 5: Run migration
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx nexus migrate dev
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Gotchas
|
|
136
|
+
|
|
137
|
+
- Always use field factories from `@gzl10/nexus-sdk/fields`
|
|
138
|
+
- `required` is top-level, not inside `validation`
|
|
139
|
+
- Select options: direct array `[{value, label}]`
|
|
140
|
+
- Tree requires `seed` (can be `[]`)
|
|
141
|
+
- Single uses `key`, not `table`
|
|
142
|
+
- Entity updates use PUT (not PATCH) — relevant for hooks
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Create a new Nexus module
|
|
2
|
+
|
|
3
|
+
Scaffold a new module in the current project. Modules are auto-discovered from `src/modules/`.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS — Module name (e.g. "inventory", "crm", "blog"). Lowercase, no spaces.
|
|
8
|
+
|
|
9
|
+
## Step 1: Detect project structure
|
|
10
|
+
|
|
11
|
+
Find the modules directory:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
src/modules/ # standard location
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If not found, ask the user where modules live.
|
|
18
|
+
|
|
19
|
+
Check existing modules to avoid name collisions:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ls src/modules/
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Step 2: Ask for details
|
|
26
|
+
|
|
27
|
+
Ask the user (if not provided in arguments):
|
|
28
|
+
|
|
29
|
+
1. **Category** — one of: content, data, assets, messaging, jobs, ai, analytics, integrations, commerce, security, legal, settings
|
|
30
|
+
2. **Icon** — Ionicons 5 icon name (suggest based on category)
|
|
31
|
+
3. **Initial entity?** — yes/no. If yes, ask type: collection, single, or tree
|
|
32
|
+
|
|
33
|
+
## Step 3: Generate module
|
|
34
|
+
|
|
35
|
+
Create `src/modules/{name}/index.ts`:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import type { ModuleManifest } from '@gzl10/nexus-sdk'
|
|
39
|
+
// import entities here
|
|
40
|
+
|
|
41
|
+
export const {name}Module: ModuleManifest = {
|
|
42
|
+
name: '{name}',
|
|
43
|
+
label: { en: '{Name}', es: '{Nombre}' },
|
|
44
|
+
icon: '{icon}',
|
|
45
|
+
category: '{category}',
|
|
46
|
+
definitions: []
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Conventions (CRITICAL):**
|
|
51
|
+
- Named export: `export const {name}Module` — NOT `export default`
|
|
52
|
+
- Category must be one of the 12 valid values — NO 'custom'
|
|
53
|
+
- definitions[] array for entities — they auto-mount, no manual routes
|
|
54
|
+
|
|
55
|
+
## Step 4: Generate initial entity (if requested)
|
|
56
|
+
|
|
57
|
+
Use the same patterns as `/nexus-new-entity` but inline here:
|
|
58
|
+
|
|
59
|
+
- **collection**: `table`, `labelField`, field factories from `@gzl10/nexus-sdk/fields`, `casl`
|
|
60
|
+
- **single**: `key` (not table), `defaults`
|
|
61
|
+
- **tree**: `table`, `seed: []`, parent_id auto-injected
|
|
62
|
+
|
|
63
|
+
Add the entity import and include it in `definitions[]`.
|
|
64
|
+
|
|
65
|
+
## Step 5: Verify
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx tsc --noEmit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
|
|
73
|
+
- Entities use `table` (collection/tree) or `key` (single), NOT `name`
|
|
74
|
+
- Field `required` is top-level in factory config, NOT inside `validation`
|
|
75
|
+
- `useSelectField` options is a direct array `[{value, label}]`, NOT `{static: [...]}`
|
|
76
|
+
- Tree entities require `seed` (can be empty `[]`)
|
|
77
|
+
- Hooks pattern: `hooks: (ctx) => ({ beforeCreate: async (data) => { return data } })`
|
|
78
|
+
- Individual hooks do NOT receive ctx — only the wrapper function does
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Create a new Nexus plugin
|
|
2
|
+
|
|
3
|
+
Scaffold a complete plugin project from scratch.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS — Plugin name (e.g. "bookmarks", "analytics", "notifications"). Lowercase, no spaces.
|
|
8
|
+
|
|
9
|
+
## Step 1: Ask for details
|
|
10
|
+
|
|
11
|
+
1. **Code** — exactly 3 lowercase chars, unique (e.g. "bkm", "anl", "ntf"). Validated: `/^[a-z]{3}$/`
|
|
12
|
+
2. **Category** — one of: content, data, assets, messaging, jobs, ai, analytics, integrations, commerce, security, legal, settings
|
|
13
|
+
3. **Description** — short description (en/es)
|
|
14
|
+
4. **Where to create** — default: current directory as `nexus-plugin-{name}/`
|
|
15
|
+
|
|
16
|
+
## Step 2: Generate scaffold
|
|
17
|
+
|
|
18
|
+
Create the following structure:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
nexus-plugin-{name}/
|
|
22
|
+
├── src/
|
|
23
|
+
│ ├── index.ts # PluginManifest + ModuleManifest
|
|
24
|
+
│ └── entities/
|
|
25
|
+
│ └── {name}.ts # Example collection entity
|
|
26
|
+
├── package.json
|
|
27
|
+
├── tsconfig.json
|
|
28
|
+
├── tsup.config.ts
|
|
29
|
+
└── README.md
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### package.json
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"name": "@{scope}/nexus-plugin-{name}",
|
|
37
|
+
"version": "1.0.0",
|
|
38
|
+
"type": "module",
|
|
39
|
+
"description": "{description}",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"exports": {
|
|
42
|
+
".": {
|
|
43
|
+
"import": "./dist/index.js",
|
|
44
|
+
"types": "./dist/index.d.ts"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": ["dist", "migrations"],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
51
|
+
"test": "vitest run --passWithNoTests"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@gzl10/nexus-sdk": ">=0.14.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@gzl10/nexus-sdk": "^0.14.0",
|
|
58
|
+
"tsup": "^8.3.0",
|
|
59
|
+
"typescript": "^5.7.0",
|
|
60
|
+
"vitest": "^4.0.18"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Ask the user for `@{scope}` (their npm scope).
|
|
66
|
+
|
|
67
|
+
### tsup.config.ts
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { defineConfig } from 'tsup'
|
|
71
|
+
export default defineConfig({
|
|
72
|
+
entry: ['src/index.ts'],
|
|
73
|
+
format: ['esm'],
|
|
74
|
+
dts: true,
|
|
75
|
+
clean: true
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### tsconfig.json
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"compilerOptions": {
|
|
84
|
+
"target": "ES2022",
|
|
85
|
+
"module": "ESNext",
|
|
86
|
+
"moduleResolution": "bundler",
|
|
87
|
+
"strict": true,
|
|
88
|
+
"esModuleInterop": true,
|
|
89
|
+
"skipLibCheck": true,
|
|
90
|
+
"outDir": "dist",
|
|
91
|
+
"rootDir": "src",
|
|
92
|
+
"declaration": true,
|
|
93
|
+
"declarationDir": "dist"
|
|
94
|
+
},
|
|
95
|
+
"include": ["src/**/*"],
|
|
96
|
+
"exclude": ["node_modules", "dist"]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### src/index.ts
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import type { PluginManifest, ModuleManifest } from '@gzl10/nexus-sdk'
|
|
104
|
+
import { {name}Entity } from './entities/{name}.js'
|
|
105
|
+
|
|
106
|
+
const {name}Module: ModuleManifest = {
|
|
107
|
+
name: '{name}',
|
|
108
|
+
label: { en: '{Name}', es: '{Nombre}' },
|
|
109
|
+
icon: '{icon}',
|
|
110
|
+
category: '{category}',
|
|
111
|
+
definitions: [{name}Entity]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { {name}Module, {name}Entity }
|
|
115
|
+
|
|
116
|
+
export const {name}Plugin: PluginManifest = {
|
|
117
|
+
name: '@{scope}/nexus-plugin-{name}',
|
|
118
|
+
code: '{code}',
|
|
119
|
+
label: { en: '{Name}', es: '{Nombre}' },
|
|
120
|
+
icon: '{icon}',
|
|
121
|
+
version: '1.0.0',
|
|
122
|
+
description: { en: '{description_en}', es: '{description_es}' },
|
|
123
|
+
category: '{category}',
|
|
124
|
+
modules: [{name}Module]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default {name}Plugin
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Example entity
|
|
131
|
+
|
|
132
|
+
Generate a collection entity using the same pattern as `/nexus-new-entity` with basic fields (id, name, description).
|
|
133
|
+
|
|
134
|
+
### README.md
|
|
135
|
+
|
|
136
|
+
Generate with: what the plugin does, installation (`nexus plugin add`), configuration (if envVars), and entity descriptions.
|
|
137
|
+
|
|
138
|
+
## Step 3: Initialize
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
cd nexus-plugin-{name}
|
|
142
|
+
pnpm install
|
|
143
|
+
pnpm typecheck
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Gotchas
|
|
147
|
+
|
|
148
|
+
- `code` must be exactly 3 lowercase chars — validated by `registerPlugin()`
|
|
149
|
+
- `export default` the PluginManifest (plugins use default export, modules use named)
|
|
150
|
+
- `peerDependencies` on `@gzl10/nexus-sdk` — not direct dependency
|
|
151
|
+
- `files: ["dist", "migrations"]` — include migrations dir even if empty initially
|
|
152
|
+
- Plugin name in PluginManifest.name must match package.json name exactly
|
|
153
|
+
- Users install with `nexus plugin add`, not `pnpm add`
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Update the App Tutorial in Notion
|
|
2
|
+
|
|
3
|
+
Regenerate the "Tutorial: App basada en Nexus" Notion page from current code and documentation.
|
|
4
|
+
|
|
5
|
+
## Target
|
|
6
|
+
|
|
7
|
+
Notion page: `3234fc3785408042be6bf648a2876c54`
|
|
8
|
+
|
|
9
|
+
## Step 1: Read current sources
|
|
10
|
+
|
|
11
|
+
Read these files to understand the current state of the API:
|
|
12
|
+
|
|
13
|
+
1. `packages/sdk/AGENTS.md` — SDK reference and gotchas
|
|
14
|
+
2. `packages/backend/AGENTS.md` — Backend reference, CLI, gotchas
|
|
15
|
+
3. `packages/client/AGENTS.md` — Client reference, NexusApi structure
|
|
16
|
+
4. `packages/ui/AGENTS.md` — UI reference, bootstrap, composables
|
|
17
|
+
5. `demos/backend-demo/src/modules/` — app developer examples
|
|
18
|
+
6. `demos/frontend-demo/src/main.ts` — frontend bootstrap example
|
|
19
|
+
7. `packages/sdk/src/types/entity.ts` — entity definition types (verify signatures)
|
|
20
|
+
8. `packages/sdk/src/types/manifest.ts` — ModuleManifest, Category (verify valid values)
|
|
21
|
+
9. `packages/sdk/src/fields/` — check for new/changed field factories
|
|
22
|
+
|
|
23
|
+
## Step 2: Read current tutorial
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
mcp__claude_ai_Notion__notion-fetch(id: "3234fc3785408042be6bf648a2876c54")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Step 3: Compare and identify changes
|
|
30
|
+
|
|
31
|
+
For each section of the tutorial, check if the code snippets and descriptions still match the current API:
|
|
32
|
+
|
|
33
|
+
- Entity definition signatures (table vs name, key, etc.)
|
|
34
|
+
- Field factory parameters and available factories
|
|
35
|
+
- Hooks signature
|
|
36
|
+
- CLI commands
|
|
37
|
+
- Client API (login, createEntityClient, PaginatedResult)
|
|
38
|
+
- bootstrap() options
|
|
39
|
+
- Available plugins list
|
|
40
|
+
- Category valid values
|
|
41
|
+
|
|
42
|
+
## Step 4: Update Notion
|
|
43
|
+
|
|
44
|
+
Use `mcp__claude_ai_Notion__notion-update-page` with `command: "update_content"` to update only the sections that changed.
|
|
45
|
+
|
|
46
|
+
**Rules:**
|
|
47
|
+
- Preserve the section structure (13 sections)
|
|
48
|
+
- Only update code snippets and descriptions that are outdated
|
|
49
|
+
- Keep cross-references to plugin tutorial intact
|
|
50
|
+
- All code examples must be verified against current source code
|
|
51
|
+
- Do NOT guess API signatures — read the actual types
|
|
52
|
+
|
|
53
|
+
## Step 5: Report
|
|
54
|
+
|
|
55
|
+
Show summary of what changed:
|
|
56
|
+
|
|
57
|
+
| Section | Status | What changed |
|
|
58
|
+
|---------|--------|-------------|
|
|
59
|
+
| 1. Prerrequisitos | unchanged | — |
|
|
60
|
+
| 5. Entity types | updated | Added new entity type X |
|
|
61
|
+
| ... | ... | ... |
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Update the Plugin Tutorial in Notion
|
|
2
|
+
|
|
3
|
+
Regenerate the "Tutorial: Plugin para Nexus" Notion page from current code and documentation.
|
|
4
|
+
|
|
5
|
+
## Target
|
|
6
|
+
|
|
7
|
+
Notion page: `3234fc37854080d9a5dece31975385d2`
|
|
8
|
+
|
|
9
|
+
## Step 1: Read current sources
|
|
10
|
+
|
|
11
|
+
Read these files to understand the current state of the plugin API:
|
|
12
|
+
|
|
13
|
+
1. `packages/sdk/AGENTS.md` — SDK reference and gotchas
|
|
14
|
+
2. `packages/backend/AGENTS.md` — Backend reference, CLI, gotchas
|
|
15
|
+
3. `demos/plugin-demo/` — plugin developer reference (all files)
|
|
16
|
+
4. `plugins/tags/src/index.ts` — simplest real plugin
|
|
17
|
+
5. `packages/sdk/src/types/manifest.ts` — PluginManifest interface (verify)
|
|
18
|
+
6. `packages/sdk/src/types/entity.ts` — entity types (verify)
|
|
19
|
+
7. `packages/backend/src/cli.ts` — CLI commands (verify plugin commands)
|
|
20
|
+
|
|
21
|
+
## Step 2: Read current tutorial
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
mcp__claude_ai_Notion__notion-fetch(id: "3234fc37854080d9a5dece31975385d2")
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Step 3: Compare and identify changes
|
|
28
|
+
|
|
29
|
+
For each section, check if snippets match current API:
|
|
30
|
+
|
|
31
|
+
- PluginManifest interface (properties, code validation)
|
|
32
|
+
- ModuleManifest within plugins
|
|
33
|
+
- Entity definition signatures
|
|
34
|
+
- Field factory parameters
|
|
35
|
+
- CLI plugin commands (add, remove, enable, disable)
|
|
36
|
+
- Migration commands for plugins
|
|
37
|
+
- ctx (ModuleContext) properties
|
|
38
|
+
- Plugin conventions (code, peerDeps, exports, files)
|
|
39
|
+
- List of existing plugins and their codes
|
|
40
|
+
|
|
41
|
+
## Step 4: Update Notion
|
|
42
|
+
|
|
43
|
+
Use `mcp__claude_ai_Notion__notion-update-page` with `command: "update_content"` to update only changed sections.
|
|
44
|
+
|
|
45
|
+
**Rules:**
|
|
46
|
+
- Preserve the 14-section structure
|
|
47
|
+
- Cross-references to App tutorial must remain valid
|
|
48
|
+
- All code examples verified against source
|
|
49
|
+
- Update the plugins reference table (section 14) if new plugins were added
|
|
50
|
+
|
|
51
|
+
## Step 5: Report
|
|
52
|
+
|
|
53
|
+
Show summary of changes per section.
|