@nextsparkjs/ai-workflow 0.1.0-beta.87 → 0.1.0-beta.89
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/agents/architecture-supervisor.md +2 -2
- package/claude/agents/backend-developer.md +1 -1
- package/claude/agents/block-developer.md +14 -14
- package/claude/agents/db-developer.md +13 -13
- package/claude/agents/db-validator.md +2 -2
- package/claude/commands/do/update-selectors.md +2 -2
- package/claude/skills/create-plugin/SKILL.md +2 -2
- package/claude/skills/create-theme/SKILL.md +2 -2
- package/package.json +3 -2
- package/scripts/postinstall.mjs +170 -0
|
@@ -277,7 +277,7 @@ await Read('core/docs/18-page-builder/01-introduction.md')
|
|
|
277
277
|
|
|
278
278
|
**CRITICAL: When planning entity features, reference the presets.**
|
|
279
279
|
|
|
280
|
-
Location: `core/
|
|
280
|
+
Location: `core/templates/contents/themes/starter/entities/tasks/`
|
|
281
281
|
|
|
282
282
|
### Required Files (4-File Structure)
|
|
283
283
|
|
|
@@ -299,7 +299,7 @@ Location: `core/presets/theme/entities/tasks/`
|
|
|
299
299
|
**Include in plan.md when planning entity features:**
|
|
300
300
|
```markdown
|
|
301
301
|
## Entity Structure Reference
|
|
302
|
-
Use `core/
|
|
302
|
+
Use `core/templates/contents/themes/starter/entities/tasks/` as reference for:
|
|
303
303
|
- Entity config structure (5 sections) - `tasks.config.ts`
|
|
304
304
|
- Field definitions pattern - `tasks.fields.ts`
|
|
305
305
|
- TypeScript types - `tasks.types.ts`
|
|
@@ -108,7 +108,7 @@ await clickup.addComment(taskId, "🚀 Starting backend development")
|
|
|
108
108
|
|
|
109
109
|
**When creating or modifying entities, use presets as reference:**
|
|
110
110
|
|
|
111
|
-
Location: `core/
|
|
111
|
+
Location: `core/templates/contents/themes/starter/entities/tasks/`
|
|
112
112
|
|
|
113
113
|
### Required Files (4-File Structure)
|
|
114
114
|
|
|
@@ -129,7 +129,7 @@ await Read('.rules/testing.md')
|
|
|
129
129
|
These are **implicit system fields** - see `core/lib/entities/system-fields.ts`
|
|
130
130
|
|
|
131
131
|
**Entity Presets Available:**
|
|
132
|
-
- `core/
|
|
132
|
+
- `core/templates/contents/themes/starter/entities/tasks/` - Complete entity example
|
|
133
133
|
|
|
134
134
|
**Note:** Most blocks do NOT require custom entities. Only use this if your block needs persistent data storage beyond page content.
|
|
135
135
|
|
|
@@ -139,7 +139,7 @@ These are **implicit system fields** - see `core/lib/entities/system-fields.ts`
|
|
|
139
139
|
|
|
140
140
|
### Available Block Presets
|
|
141
141
|
|
|
142
|
-
Location: `core/
|
|
142
|
+
Location: `core/templates/blocks/`
|
|
143
143
|
|
|
144
144
|
| Block | Category | Description |
|
|
145
145
|
|-------|----------|-------------|
|
|
@@ -155,7 +155,7 @@ Location: `core/presets/blocks/`
|
|
|
155
155
|
|
|
156
156
|
```bash
|
|
157
157
|
# 1. Copy the preset to the theme
|
|
158
|
-
cp -r core/
|
|
158
|
+
cp -r core/templates/blocks/hero contents/themes/{THEME}/blocks/
|
|
159
159
|
|
|
160
160
|
# 2. Customize as needed (config.ts, schema.ts, fields.ts, component.tsx)
|
|
161
161
|
|
|
@@ -167,11 +167,11 @@ node core/scripts/build/registry.mjs
|
|
|
167
167
|
|
|
168
168
|
| Scenario | Approach |
|
|
169
169
|
|----------|----------|
|
|
170
|
-
| Need a hero section | **Copy** `core/
|
|
171
|
-
| Need a CTA block | **Copy** `core/
|
|
172
|
-
| Need a features grid | **Copy** `core/
|
|
173
|
-
| Need testimonials | **Copy** `core/
|
|
174
|
-
| Need rich text | **Copy** `core/
|
|
170
|
+
| Need a hero section | **Copy** `core/templates/blocks/hero`, customize |
|
|
171
|
+
| Need a CTA block | **Copy** `core/templates/blocks/cta-section`, customize |
|
|
172
|
+
| Need a features grid | **Copy** `core/templates/blocks/features-grid`, customize |
|
|
173
|
+
| Need testimonials | **Copy** `core/templates/blocks/testimonials`, customize |
|
|
174
|
+
| Need rich text | **Copy** `core/templates/blocks/text-content`, customize |
|
|
175
175
|
| Completely unique block | Create from scratch using preset as reference |
|
|
176
176
|
|
|
177
177
|
### Preset Inspection Before Creating
|
|
@@ -180,14 +180,14 @@ node core/scripts/build/registry.mjs
|
|
|
180
180
|
|
|
181
181
|
```bash
|
|
182
182
|
# List available presets
|
|
183
|
-
ls core/
|
|
183
|
+
ls core/templates/blocks/
|
|
184
184
|
|
|
185
185
|
# Read preset README
|
|
186
|
-
cat core/
|
|
186
|
+
cat core/templates/blocks/README.md
|
|
187
187
|
|
|
188
188
|
# Inspect a specific preset for patterns
|
|
189
|
-
cat core/
|
|
190
|
-
cat core/
|
|
189
|
+
cat core/templates/blocks/hero/schema.ts
|
|
190
|
+
cat core/templates/blocks/hero/component.tsx
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
## BLOCKS Workflow Integration
|
|
@@ -226,7 +226,7 @@ blocks/YYYY-MM-DD-{name}/
|
|
|
226
226
|
- File structure requirements
|
|
227
227
|
- Base schemas and helpers
|
|
228
228
|
- Development rules and anti-patterns
|
|
229
|
-
- **Block presets in `core/
|
|
229
|
+
- **Block presets in `core/templates/blocks/`** ← NEW
|
|
230
230
|
|
|
231
231
|
**You DISCOVER at runtime** (dynamic knowledge):
|
|
232
232
|
- Which theme to work with
|
|
@@ -261,7 +261,7 @@ At the start of task:execute, scope is documented in `context.md` showing allowe
|
|
|
261
261
|
- `theme: "default"` → You CAN only create/modify blocks in `contents/themes/default/blocks/**/*`
|
|
262
262
|
- `theme: false` → You CANNOT create blocks (report as blocker - need theme scope)
|
|
263
263
|
- `core: false` → You CANNOT modify core block types in `core/types/blocks.ts`
|
|
264
|
-
- Preset copying from `core/
|
|
264
|
+
- Preset copying from `core/templates/blocks/` is READ-ONLY (always allowed for copying)
|
|
265
265
|
|
|
266
266
|
**Integration with theme determination:**
|
|
267
267
|
When determining which theme to work in (STEP 1), also verify that scope allows access to that theme:
|
|
@@ -76,11 +76,11 @@ await Read('.rules/api.md') // API patterns (entity registry, metadat
|
|
|
76
76
|
|
|
77
77
|
### Migration Presets (USE THESE TEMPLATES)
|
|
78
78
|
|
|
79
|
-
**CRITICAL: Use the standardized templates from `core/
|
|
79
|
+
**CRITICAL: Use the standardized templates from `core/templates/migrations/`**
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
82
|
// Step 1: Determine RLS mode based on entity requirements
|
|
83
|
-
await Read('core/
|
|
83
|
+
await Read('core/templates/migrations/README.md')
|
|
84
84
|
|
|
85
85
|
// Step 2: Select appropriate template folder
|
|
86
86
|
// - team-mode/ → Multi-tenant apps with team isolation
|
|
@@ -153,7 +153,7 @@ At the start of task:execute, scope is documented in `context.md` showing allowe
|
|
|
153
153
|
|
|
154
154
|
**CRITICAL: Use entity presets as reference when creating new entities.**
|
|
155
155
|
|
|
156
|
-
Location: `core/
|
|
156
|
+
Location: `core/templates/contents/themes/starter/entities/tasks/`
|
|
157
157
|
|
|
158
158
|
### Required Files (4-File Structure)
|
|
159
159
|
|
|
@@ -176,10 +176,10 @@ Location: `core/presets/theme/entities/tasks/`
|
|
|
176
176
|
**Usage:**
|
|
177
177
|
```bash
|
|
178
178
|
# Inspect preset for patterns before creating new entity
|
|
179
|
-
cat core/
|
|
180
|
-
cat core/
|
|
181
|
-
cat core/
|
|
182
|
-
cat core/
|
|
179
|
+
cat core/templates/contents/themes/starter/entities/tasks/tasks.config.ts # Entity config
|
|
180
|
+
cat core/templates/contents/themes/starter/entities/tasks/tasks.fields.ts # Field definitions
|
|
181
|
+
cat core/templates/contents/themes/starter/entities/tasks/tasks.types.ts # TypeScript types
|
|
182
|
+
cat core/templates/contents/themes/starter/entities/tasks/tasks.service.ts # Service pattern
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
### Entity Service Pattern
|
|
@@ -334,7 +334,7 @@ For detailed patterns including:
|
|
|
334
334
|
|
|
335
335
|
**Always read:** `.claude/skills/database-migrations/SKILL.md`
|
|
336
336
|
|
|
337
|
-
**Always use templates from:** `core/
|
|
337
|
+
**Always use templates from:** `core/templates/migrations/[mode]/`
|
|
338
338
|
|
|
339
339
|
### Quick Reference (full details in skill)
|
|
340
340
|
|
|
@@ -520,7 +520,7 @@ core/migrations/
|
|
|
520
520
|
|
|
521
521
|
### Migration Template (USE PRESETS)
|
|
522
522
|
|
|
523
|
-
**IMPORTANT: Use templates from `core/
|
|
523
|
+
**IMPORTANT: Use templates from `core/templates/migrations/[mode]/` instead of writing from scratch!**
|
|
524
524
|
|
|
525
525
|
See `.claude/skills/database-migrations/SKILL.md` for complete SQL patterns including:
|
|
526
526
|
- Table structure with field ordering (id → FK → business → system)
|
|
@@ -559,8 +559,8 @@ await Read(`${sessionPath}/clickup_task.md`) // For Team Mode decision
|
|
|
559
559
|
|
|
560
560
|
```typescript
|
|
561
561
|
const mode = 'team-mode' // or 'private-mode', 'shared-mode', 'public-mode'
|
|
562
|
-
await Read(`core/
|
|
563
|
-
await Read(`core/
|
|
562
|
+
await Read(`core/templates/migrations/${mode}/001_entity_table.sql.template`)
|
|
563
|
+
await Read(`core/templates/migrations/${mode}/002_entity_metas.sql.template`)
|
|
564
564
|
```
|
|
565
565
|
|
|
566
566
|
### Step 3: Create Migrations from Templates
|
|
@@ -592,7 +592,7 @@ Check PM Decisions in requirements.md:
|
|
|
592
592
|
|
|
593
593
|
### Step 3: Create Migrations
|
|
594
594
|
|
|
595
|
-
1. **Select RLS mode** from `core/
|
|
595
|
+
1. **Select RLS mode** from `core/templates/migrations/`
|
|
596
596
|
2. Copy and customize template files
|
|
597
597
|
3. Create sample data migration file
|
|
598
598
|
4. Create/update test users migration
|
|
@@ -652,7 +652,7 @@ Before completing, verify:
|
|
|
652
652
|
- [ ] Created migration files in `migrations/` folder
|
|
653
653
|
|
|
654
654
|
### Template Compliance
|
|
655
|
-
- [ ] Used template from `core/
|
|
655
|
+
- [ ] Used template from `core/templates/migrations/[mode]/`
|
|
656
656
|
- [ ] Selected correct RLS mode (team/private/shared/public)
|
|
657
657
|
- [ ] All `{{VARIABLE}}` placeholders replaced
|
|
658
658
|
|
|
@@ -39,7 +39,7 @@ You are an expert Database Validator responsible for verifying that database mig
|
|
|
39
39
|
## Core Mission
|
|
40
40
|
|
|
41
41
|
Validate that the database is **100% ready for development** by checking:
|
|
42
|
-
1. **Template Compliance**: Migrations follow `core/
|
|
42
|
+
1. **Template Compliance**: Migrations follow `core/templates/migrations/` standards
|
|
43
43
|
2. **Schema Correctness**: Proper types, naming, and structure
|
|
44
44
|
3. Migrations execute without errors
|
|
45
45
|
4. All expected tables exist with correct schema
|
|
@@ -372,7 +372,7 @@ psql $DATABASE_URL -c "SELECT p.id, u.email FROM \"product\" p JOIN \"user\" u O
|
|
|
372
372
|
|
|
373
373
|
Before completing, verify:
|
|
374
374
|
|
|
375
|
-
### Template Compliance (from `core/
|
|
375
|
+
### Template Compliance (from `core/templates/migrations/`)
|
|
376
376
|
- [ ] No snake_case field names
|
|
377
377
|
- [ ] ID type is TEXT (not UUID)
|
|
378
378
|
- [ ] Timestamps use TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
@@ -71,7 +71,7 @@ sortableBlockGeneric: '[data-cy^="sortable-block-"]', // OK - needed for prefix
|
|
|
71
71
|
| Core Selectors | `packages/core/src/lib/selectors/domains/*.selectors.ts` |
|
|
72
72
|
| Component Usage | `packages/core/src/components/**/*.tsx` |
|
|
73
73
|
| POM Classes | `themes/*/tests/cypress/src/core/*POM.ts` |
|
|
74
|
-
| POM Presets | `packages/core/
|
|
74
|
+
| POM Presets | `packages/core/templates/contents/themes/starter/tests/cypress/src/core/*POM.ts` |
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
@@ -93,7 +93,7 @@ sortableBlockGeneric: '[data-cy^="sortable-block-"]', // OK - needed for prefix
|
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
4. **After sync, update presets:**
|
|
96
|
-
- `packages/core/
|
|
96
|
+
- `packages/core/templates/contents/themes/starter/tests/cypress/src/core/`
|
|
97
97
|
- `packages/core/templates/contents/themes/starter/tests/cypress/src/core/`
|
|
98
98
|
|
|
99
99
|
---
|
|
@@ -57,7 +57,7 @@ Cada plugin DEBE tener un `package.json` con esta estructura:
|
|
|
57
57
|
## Prerequisites
|
|
58
58
|
|
|
59
59
|
- **Command:** `pnpm create:plugin <plugin-name>`
|
|
60
|
-
- **Preset Location:** `core/
|
|
60
|
+
- **Preset Location:** `core/templates/contents/plugins/starter/`
|
|
61
61
|
- **Output Location (monorepo):** `plugins/<plugin-name>/`
|
|
62
62
|
- **Output Location (user project):** `contents/plugins/<plugin-name>/`
|
|
63
63
|
|
|
@@ -361,7 +361,7 @@ Each entity requires 4 files:
|
|
|
361
361
|
| `[entity].types.ts` | TypeScript types |
|
|
362
362
|
| `[entity].service.ts` | Data access service |
|
|
363
363
|
|
|
364
|
-
**Reference:** `core/
|
|
364
|
+
**Reference:** `core/templates/contents/themes/starter/entities/tasks/`
|
|
365
365
|
|
|
366
366
|
---
|
|
367
367
|
|
|
@@ -53,7 +53,7 @@ Complete guide for scaffolding and configuring new themes from the preset templa
|
|
|
53
53
|
## Prerequisites
|
|
54
54
|
|
|
55
55
|
- **Command:** `pnpm create:theme <theme-name>`
|
|
56
|
-
- **Preset Location:** `core/
|
|
56
|
+
- **Preset Location:** `core/templates/contents/themes/starter/`
|
|
57
57
|
- **Output Location:** `themes/<theme-name>/`
|
|
58
58
|
|
|
59
59
|
---
|
|
@@ -250,7 +250,7 @@ Each theme entity requires 4 files:
|
|
|
250
250
|
| `[entity].types.ts` | TypeScript types |
|
|
251
251
|
| `[entity].service.ts` | Data access service |
|
|
252
252
|
|
|
253
|
-
**Reference:** `core/
|
|
253
|
+
**Reference:** `core/templates/contents/themes/starter/entities/tasks/`
|
|
254
254
|
|
|
255
255
|
---
|
|
256
256
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextsparkjs/ai-workflow",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.89",
|
|
4
4
|
"description": "AI workflow templates for NextSpark - Claude Code agents, commands, skills, and multi-editor support",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NextSpark <hello@nextspark.dev>",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
31
|
"setup": "node scripts/setup.mjs",
|
|
32
|
-
"sync": "node scripts/sync.mjs"
|
|
32
|
+
"sync": "node scripts/sync.mjs",
|
|
33
|
+
"postinstall": "node scripts/postinstall.mjs"
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @nextsparkjs/ai-workflow postinstall hook
|
|
4
|
+
*
|
|
5
|
+
* Automatically syncs AI workflow files (.claude/, .cursor/, etc.) when the package is updated.
|
|
6
|
+
* Only runs in NextSpark projects that already have AI workflow set up.
|
|
7
|
+
*
|
|
8
|
+
* Debug mode: Set NEXTSPARK_DEBUG=1 to see detailed logs
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
import { existsSync, readFileSync } from 'fs';
|
|
13
|
+
import { join, dirname, resolve, isAbsolute } from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
|
|
16
|
+
const DEBUG = process.env.NEXTSPARK_DEBUG === '1';
|
|
17
|
+
|
|
18
|
+
function debug(message) {
|
|
19
|
+
if (DEBUG) {
|
|
20
|
+
console.log(` [DEBUG] ${message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Find the project root by walking up from the current directory
|
|
26
|
+
* until we find a package.json that isn't inside node_modules
|
|
27
|
+
*/
|
|
28
|
+
function findProjectRoot() {
|
|
29
|
+
// When running postinstall, we're in node_modules/@nextsparkjs/ai-workflow
|
|
30
|
+
// We need to find the project root (where the user's package.json is)
|
|
31
|
+
let current = process.cwd();
|
|
32
|
+
|
|
33
|
+
// If we're inside node_modules, walk up to find the project root
|
|
34
|
+
if (current.includes('node_modules')) {
|
|
35
|
+
// Go up until we're out of node_modules
|
|
36
|
+
const parts = current.split('node_modules');
|
|
37
|
+
current = parts[0].replace(/[/\\]$/, ''); // Remove trailing slash
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return current;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Validate that the project root path is safe to use
|
|
45
|
+
*/
|
|
46
|
+
function validateProjectRoot(projectRoot) {
|
|
47
|
+
// Must be an absolute path
|
|
48
|
+
if (!isAbsolute(projectRoot)) {
|
|
49
|
+
debug(`Invalid path: not absolute - ${projectRoot}`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Must exist
|
|
54
|
+
if (!existsSync(projectRoot)) {
|
|
55
|
+
debug(`Invalid path: does not exist - ${projectRoot}`);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Resolve to canonical path and verify it doesn't escape
|
|
60
|
+
const resolved = resolve(projectRoot);
|
|
61
|
+
if (resolved !== projectRoot && !projectRoot.startsWith(resolved)) {
|
|
62
|
+
debug(`Invalid path: resolution mismatch - ${projectRoot} vs ${resolved}`);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Detect if we're in a NextSpark project (not the monorepo)
|
|
71
|
+
*/
|
|
72
|
+
function isNextSparkProject(projectRoot) {
|
|
73
|
+
// If we're in the monorepo, skip
|
|
74
|
+
const pnpmWorkspace = join(projectRoot, 'pnpm-workspace.yaml');
|
|
75
|
+
if (existsSync(pnpmWorkspace)) {
|
|
76
|
+
debug('Skipping: monorepo detected (pnpm-workspace.yaml exists)');
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Check for package.json with nextspark dependency
|
|
81
|
+
const pkgPath = join(projectRoot, 'package.json');
|
|
82
|
+
if (!existsSync(pkgPath)) {
|
|
83
|
+
debug('Skipping: no package.json found');
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
89
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
90
|
+
|
|
91
|
+
const hasNextSpark = !!(deps['@nextsparkjs/core'] || deps['@nextsparkjs/cli']);
|
|
92
|
+
if (!hasNextSpark) {
|
|
93
|
+
debug('Skipping: no NextSpark dependencies found');
|
|
94
|
+
}
|
|
95
|
+
return hasNextSpark;
|
|
96
|
+
} catch {
|
|
97
|
+
debug('Skipping: failed to parse package.json');
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Check if the project has a .claude/ folder (AI workflow already set up)
|
|
104
|
+
*/
|
|
105
|
+
function hasAIWorkflowSetup(projectRoot) {
|
|
106
|
+
const hasClaudeDir = existsSync(join(projectRoot, '.claude'));
|
|
107
|
+
if (!hasClaudeDir) {
|
|
108
|
+
debug('Skipping: no .claude/ folder found (AI workflow not set up yet)');
|
|
109
|
+
}
|
|
110
|
+
return hasClaudeDir;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Find the setup.mjs script path relative to this postinstall script
|
|
115
|
+
*/
|
|
116
|
+
function getSetupScriptPath() {
|
|
117
|
+
// This script is at packages/ai-workflow/scripts/postinstall.mjs
|
|
118
|
+
// setup.mjs is at packages/ai-workflow/scripts/setup.mjs
|
|
119
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
120
|
+
const __dirname = dirname(__filename);
|
|
121
|
+
const setupPath = join(__dirname, 'setup.mjs');
|
|
122
|
+
|
|
123
|
+
if (existsSync(setupPath)) {
|
|
124
|
+
return setupPath;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
debug(`Setup script not found at ${setupPath}`);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Main execution
|
|
132
|
+
try {
|
|
133
|
+
const projectRoot = findProjectRoot();
|
|
134
|
+
debug(`Project root: ${projectRoot}`);
|
|
135
|
+
|
|
136
|
+
// Validate project root path
|
|
137
|
+
if (!validateProjectRoot(projectRoot)) {
|
|
138
|
+
debug('Skipping: invalid project root path');
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Only run in NextSpark projects with an existing .claude/ folder
|
|
143
|
+
if (isNextSparkProject(projectRoot) && hasAIWorkflowSetup(projectRoot)) {
|
|
144
|
+
console.log('\n 📦 @nextsparkjs/ai-workflow updated - syncing AI workflow files...\n');
|
|
145
|
+
|
|
146
|
+
const setupScript = getSetupScriptPath();
|
|
147
|
+
if (setupScript) {
|
|
148
|
+
try {
|
|
149
|
+
execSync(`node "${setupScript}" claude`, {
|
|
150
|
+
stdio: 'inherit',
|
|
151
|
+
cwd: projectRoot,
|
|
152
|
+
});
|
|
153
|
+
} catch (syncError) {
|
|
154
|
+
console.warn('\n ⚠️ Auto-sync failed. Run manually: npx nextspark sync:ai\n');
|
|
155
|
+
debug(`Sync error: ${syncError.message}`);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
debug('Skipping: setup.mjs script not found');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
// Postinstall hooks should not break installations
|
|
163
|
+
// The user can always run the sync manually
|
|
164
|
+
if (DEBUG) {
|
|
165
|
+
console.warn('\n [DEBUG] Postinstall error:', error.message);
|
|
166
|
+
if (error.stack) {
|
|
167
|
+
console.warn(error.stack);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|