@nextsparkjs/ai-workflow 0.1.0-beta.86

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.
Files changed (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +636 -0
  5. package/claude/agents/architecture-supervisor.md +1381 -0
  6. package/claude/agents/backend-developer.md +1021 -0
  7. package/claude/agents/backend-validator.md +417 -0
  8. package/claude/agents/bdd-docs-writer.md +737 -0
  9. package/claude/agents/block-developer.md +677 -0
  10. package/claude/agents/code-reviewer.md +1460 -0
  11. package/claude/agents/db-developer.md +721 -0
  12. package/claude/agents/db-validator.md +407 -0
  13. package/claude/agents/demo-video-generator.md +493 -0
  14. package/claude/agents/documentation-writer.md +1291 -0
  15. package/claude/agents/frontend-developer.md +1259 -0
  16. package/claude/agents/frontend-validator.md +777 -0
  17. package/claude/agents/functional-validator.md +630 -0
  18. package/claude/agents/mock-analyst.md +387 -0
  19. package/claude/agents/product-manager.md +971 -0
  20. package/claude/agents/qa-automation.md +1762 -0
  21. package/claude/agents/release-manager.md +634 -0
  22. package/claude/agents/selectors-translator.md +262 -0
  23. package/claude/agents/unit-test-writer.md +785 -0
  24. package/claude/agents/visual-comparator.md +329 -0
  25. package/claude/agents/workflow-maintainer.md +373 -0
  26. package/claude/commands/do/README.md +88 -0
  27. package/claude/commands/do/create-api.md +64 -0
  28. package/claude/commands/do/create-entity.md +66 -0
  29. package/claude/commands/do/create-migration.md +64 -0
  30. package/claude/commands/do/create-plugin.md +56 -0
  31. package/claude/commands/do/create-theme.md +70 -0
  32. package/claude/commands/do/mock-data.md +67 -0
  33. package/claude/commands/do/reset-db.md +71 -0
  34. package/claude/commands/do/setup-scheduled-action.md +75 -0
  35. package/claude/commands/do/sync-code-review.md +117 -0
  36. package/claude/commands/do/update-selectors.md +112 -0
  37. package/claude/commands/do/use-skills.md +90 -0
  38. package/claude/commands/do/validate-blocks.md +69 -0
  39. package/claude/commands/how-to/README.md +261 -0
  40. package/claude/commands/how-to/add-metadata.md +692 -0
  41. package/claude/commands/how-to/add-taxonomies.md +806 -0
  42. package/claude/commands/how-to/add-translations.md +571 -0
  43. package/claude/commands/how-to/create-api.md +577 -0
  44. package/claude/commands/how-to/create-block.md +575 -0
  45. package/claude/commands/how-to/create-child-entities.md +771 -0
  46. package/claude/commands/how-to/create-entity.md +597 -0
  47. package/claude/commands/how-to/create-migrations.md +605 -0
  48. package/claude/commands/how-to/create-plugin.md +654 -0
  49. package/claude/commands/how-to/customize-app.md +481 -0
  50. package/claude/commands/how-to/customize-dashboard.md +553 -0
  51. package/claude/commands/how-to/customize-theme.md +438 -0
  52. package/claude/commands/how-to/define-features-flows.md +632 -0
  53. package/claude/commands/how-to/deploy.md +507 -0
  54. package/claude/commands/how-to/handle-file-uploads.md +681 -0
  55. package/claude/commands/how-to/implement-search.md +1001 -0
  56. package/claude/commands/how-to/install-plugins.md +352 -0
  57. package/claude/commands/how-to/manage-test-coverage.md +984 -0
  58. package/claude/commands/how-to/run-tests.md +400 -0
  59. package/claude/commands/how-to/set-app-languages.md +601 -0
  60. package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
  61. package/claude/commands/how-to/set-scheduled-actions.md +527 -0
  62. package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
  63. package/claude/commands/how-to/setup-authentication.md +388 -0
  64. package/claude/commands/how-to/setup-claude-code.md +512 -0
  65. package/claude/commands/how-to/setup-database.md +274 -0
  66. package/claude/commands/how-to/setup-email-providers.md +598 -0
  67. package/claude/commands/how-to/setup-mobile-dev.md +627 -0
  68. package/claude/commands/how-to/start.md +455 -0
  69. package/claude/commands/how-to/use-devtools.md +639 -0
  70. package/claude/commands/how-to/use-superadmin.md +622 -0
  71. package/claude/commands/session/README.md +193 -0
  72. package/claude/commands/session/block-create.md +190 -0
  73. package/claude/commands/session/block-list.md +203 -0
  74. package/claude/commands/session/block-update.md +192 -0
  75. package/claude/commands/session/block-validate.md +218 -0
  76. package/claude/commands/session/close.md +146 -0
  77. package/claude/commands/session/commit.md +174 -0
  78. package/claude/commands/session/db-entity.md +206 -0
  79. package/claude/commands/session/db-fix.md +212 -0
  80. package/claude/commands/session/db-sample.md +206 -0
  81. package/claude/commands/session/demo.md +178 -0
  82. package/claude/commands/session/doc-bdd.md +207 -0
  83. package/claude/commands/session/doc-feature.md +218 -0
  84. package/claude/commands/session/doc-read.md +225 -0
  85. package/claude/commands/session/execute.md +204 -0
  86. package/claude/commands/session/explain.md +202 -0
  87. package/claude/commands/session/fix-bug.md +210 -0
  88. package/claude/commands/session/fix-build.md +182 -0
  89. package/claude/commands/session/fix-test.md +189 -0
  90. package/claude/commands/session/pending.md +232 -0
  91. package/claude/commands/session/refine.md +188 -0
  92. package/claude/commands/session/resume.md +192 -0
  93. package/claude/commands/session/review.md +192 -0
  94. package/claude/commands/session/scope-change.md +181 -0
  95. package/claude/commands/session/start-blocks.md +347 -0
  96. package/claude/commands/session/start.md +476 -0
  97. package/claude/commands/session/status.md +169 -0
  98. package/claude/commands/session/test-fix.md +221 -0
  99. package/claude/commands/session/test-run.md +203 -0
  100. package/claude/commands/session/test-write.md +242 -0
  101. package/claude/commands/session/validate.md +162 -0
  102. package/claude/config/context.json +54 -0
  103. package/claude/config/github.json +69 -0
  104. package/claude/config/github.schema.json +106 -0
  105. package/claude/config/team.json +46 -0
  106. package/claude/config/team.schema.json +106 -0
  107. package/claude/config/workspace.json +49 -0
  108. package/claude/config/workspace.schema.json +64 -0
  109. package/claude/scripts/.gitkeep +0 -0
  110. package/claude/sessions/.gitkeep +0 -0
  111. package/claude/skills/README.md +228 -0
  112. package/claude/skills/accessibility/SKILL.md +573 -0
  113. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  114. package/claude/skills/asana-integration/SKILL.md +499 -0
  115. package/claude/skills/better-auth/SKILL.md +666 -0
  116. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  117. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  118. package/claude/skills/clickup-integration/SKILL.md +434 -0
  119. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  120. package/claude/skills/create-plugin/SKILL.md +425 -0
  121. package/claude/skills/create-theme/SKILL.md +331 -0
  122. package/claude/skills/cypress-api/SKILL.md +511 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  124. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  125. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  126. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  127. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  128. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  129. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  130. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  131. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  132. package/claude/skills/database-migrations/SKILL.md +335 -0
  133. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  134. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  135. package/claude/skills/design-system/SKILL.md +682 -0
  136. package/claude/skills/documentation/SKILL.md +540 -0
  137. package/claude/skills/entity-api/SKILL.md +482 -0
  138. package/claude/skills/entity-system/SKILL.md +635 -0
  139. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  140. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  141. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  142. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  143. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  144. package/claude/skills/github/SKILL.md +467 -0
  145. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  146. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  147. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  148. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  149. package/claude/skills/impact-analysis/SKILL.md +203 -0
  150. package/claude/skills/jest-unit/SKILL.md +306 -0
  151. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  152. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  153. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  154. package/claude/skills/jira-integration/SKILL.md +539 -0
  155. package/claude/skills/mock-analysis/SKILL.md +276 -0
  156. package/claude/skills/monorepo-architecture/SKILL.md +162 -0
  157. package/claude/skills/nextjs-api-development/SKILL.md +364 -0
  158. package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
  159. package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
  160. package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
  161. package/claude/skills/notion-integration/SKILL.md +641 -0
  162. package/claude/skills/npm-development-workflow/SKILL.md +480 -0
  163. package/claude/skills/page-builder-blocks/SKILL.md +483 -0
  164. package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
  165. package/claude/skills/permissions-system/SKILL.md +619 -0
  166. package/claude/skills/plugins/SKILL.md +340 -0
  167. package/claude/skills/plugins/references/plugin-templates.md +414 -0
  168. package/claude/skills/plugins/references/plugin-testing.md +353 -0
  169. package/claude/skills/plugins/references/plugin-types.md +198 -0
  170. package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
  171. package/claude/skills/pom-patterns/SKILL.md +452 -0
  172. package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
  173. package/claude/skills/rate-limiting/SKILL.md +342 -0
  174. package/claude/skills/react-best-practices/AGENTS.md +2410 -0
  175. package/claude/skills/react-best-practices/README.md +123 -0
  176. package/claude/skills/react-best-practices/SKILL.md +125 -0
  177. package/claude/skills/react-best-practices/metadata.json +15 -0
  178. package/claude/skills/react-best-practices/rules/_sections.md +46 -0
  179. package/claude/skills/react-best-practices/rules/_template.md +28 -0
  180. package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  181. package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  182. package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  183. package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  184. package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  185. package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  186. package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  187. package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  188. package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  189. package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  190. package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  191. package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  192. package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  193. package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
  194. package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  195. package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  196. package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  197. package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  198. package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  199. package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  200. package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  201. package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  202. package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  203. package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  204. package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  205. package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  206. package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  207. package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  208. package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  209. package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  210. package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  211. package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  212. package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  213. package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  214. package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  215. package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  216. package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  217. package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  218. package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  219. package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  220. package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  221. package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  222. package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  223. package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  224. package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
  225. package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
  226. package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  227. package/claude/skills/react-patterns/SKILL.md +677 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +431 -0
  230. package/claude/skills/scope-enforcement/SKILL.md +542 -0
  231. package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
  232. package/claude/skills/server-actions/SKILL.md +493 -0
  233. package/claude/skills/service-layer/SKILL.md +587 -0
  234. package/claude/skills/session-management/SKILL.md +266 -0
  235. package/claude/skills/session-management/scripts/create-session.py +166 -0
  236. package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
  237. package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
  238. package/claude/skills/session-management/scripts/session-archive.sh +87 -0
  239. package/claude/skills/session-management/scripts/session-close.sh +133 -0
  240. package/claude/skills/session-management/scripts/session-init.sh +225 -0
  241. package/claude/skills/session-management/scripts/session-list.sh +163 -0
  242. package/claude/skills/session-management/scripts/split-plan.sh +116 -0
  243. package/claude/skills/shadcn-components/SKILL.md +586 -0
  244. package/claude/skills/shadcn-theming/SKILL.md +446 -0
  245. package/claude/skills/suspense-loading/SKILL.md +280 -0
  246. package/claude/skills/tailwind-theming/SKILL.md +479 -0
  247. package/claude/skills/tanstack-query/SKILL.md +608 -0
  248. package/claude/skills/test-coverage/SKILL.md +239 -0
  249. package/claude/skills/web-design-guidelines/SKILL.md +39 -0
  250. package/claude/skills/zod-validation/SKILL.md +537 -0
  251. package/claude/templates/blocks/progress.md +86 -0
  252. package/claude/templates/iteration/changes.md +61 -0
  253. package/claude/templates/iteration/progress.md +55 -0
  254. package/claude/templates/log.md +31 -0
  255. package/claude/templates/story/context.md +77 -0
  256. package/claude/templates/story/pendings.md +37 -0
  257. package/claude/templates/story/plan.md +299 -0
  258. package/claude/templates/story/requirements.md +109 -0
  259. package/claude/templates/story/scope.json +10 -0
  260. package/claude/templates/story/tests.md +91 -0
  261. package/claude/templates/task/progress.md +58 -0
  262. package/claude/templates/task/requirements.md +54 -0
  263. package/claude/workflows/README.md +154 -0
  264. package/claude/workflows/blocks.md +614 -0
  265. package/claude/workflows/story.md +1207 -0
  266. package/claude/workflows/task.md +927 -0
  267. package/claude/workflows/tweak.md +527 -0
  268. package/cursor/.gitkeep +0 -0
  269. package/package.json +34 -0
  270. package/scripts/setup.mjs +282 -0
  271. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @nextsparkjs/ai-workflow - Setup Script
5
+ *
6
+ * Copies AI workflow templates to the consumer's project directory.
7
+ * Uses file-by-file copy to preserve user-created files.
8
+ *
9
+ * Usage:
10
+ * node node_modules/@nextsparkjs/ai-workflow/scripts/setup.mjs [editor]
11
+ * nextspark setup:ai --editor claude
12
+ *
13
+ * Editor options:
14
+ * claude Setup Claude Code (.claude/)
15
+ * cursor Setup Cursor (coming soon)
16
+ * antigravity Setup Antigravity (coming soon)
17
+ * all Setup all available editors
18
+ * (no arg) Defaults to "claude"
19
+ *
20
+ * Copy strategy:
21
+ * agents/, commands/, skills/, templates/, workflows/, _docs/
22
+ * → Overwrite matching files, preserve user-created files
23
+ * config/*.schema.json
24
+ * → Always overwrite (schema updates)
25
+ * config/*.json (non-schema)
26
+ * → Copy only if not exists (user config — never overwrite)
27
+ * sessions/
28
+ * → Create directory if not exists, never copy content
29
+ */
30
+
31
+ import fs from 'node:fs'
32
+ import path from 'node:path'
33
+ import { fileURLToPath } from 'node:url'
34
+
35
+ const __filename = fileURLToPath(import.meta.url)
36
+ const __dirname = path.dirname(__filename)
37
+
38
+ // Package root = where this script lives (packages/ai-workflow/ or node_modules/@nextsparkjs/ai-workflow/)
39
+ const PACKAGE_ROOT = path.resolve(__dirname, '..')
40
+
41
+ // Consumer project root = where the user runs from
42
+ const PROJECT_ROOT = process.cwd()
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Editor definitions
46
+ // ---------------------------------------------------------------------------
47
+
48
+ const EDITORS = {
49
+ claude: {
50
+ enabled: true,
51
+ source: 'claude', // subdirectory in package
52
+ target: '.claude', // subdirectory in consumer project
53
+ },
54
+ cursor: {
55
+ enabled: false,
56
+ source: 'cursor',
57
+ target: '.cursor',
58
+ },
59
+ antigravity: {
60
+ enabled: false,
61
+ source: 'antigravity',
62
+ target: '.antigravity',
63
+ },
64
+ }
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Copy strategies per directory
68
+ // ---------------------------------------------------------------------------
69
+
70
+ /** Directories where matching files are overwritten */
71
+ const OVERWRITE_DIRS = new Set([
72
+ 'agents',
73
+ 'commands',
74
+ 'skills',
75
+ 'templates',
76
+ 'workflows',
77
+ '_docs',
78
+ ])
79
+
80
+ // ---------------------------------------------------------------------------
81
+ // Helpers
82
+ // ---------------------------------------------------------------------------
83
+
84
+ const colors = {
85
+ reset: '\x1b[0m',
86
+ cyan: '\x1b[36m',
87
+ green: '\x1b[32m',
88
+ yellow: '\x1b[33m',
89
+ blue: '\x1b[34m',
90
+ red: '\x1b[31m',
91
+ dim: '\x1b[2m',
92
+ bold: '\x1b[1m',
93
+ }
94
+
95
+ function log(msg, color = 'reset') {
96
+ console.log(`${colors[color]}${msg}${colors.reset}`)
97
+ }
98
+
99
+ /**
100
+ * Recursively get all files in a directory (relative paths).
101
+ */
102
+ function getAllFiles(dir, baseDir = dir) {
103
+ const results = []
104
+ if (!fs.existsSync(dir)) return results
105
+
106
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
107
+ const fullPath = path.join(dir, entry.name)
108
+ if (entry.isDirectory()) {
109
+ results.push(...getAllFiles(fullPath, baseDir))
110
+ } else if (entry.name !== '.gitkeep') {
111
+ results.push(path.relative(baseDir, fullPath))
112
+ }
113
+ }
114
+ return results
115
+ }
116
+
117
+ /**
118
+ * Copy a single file, creating parent directories as needed.
119
+ */
120
+ function copyFile(src, dest) {
121
+ const destDir = path.dirname(dest)
122
+ if (!fs.existsSync(destDir)) {
123
+ fs.mkdirSync(destDir, { recursive: true })
124
+ }
125
+ fs.copyFileSync(src, dest)
126
+ }
127
+
128
+ // ---------------------------------------------------------------------------
129
+ // Setup logic for a single editor
130
+ // ---------------------------------------------------------------------------
131
+
132
+ function setupEditor(name, cfg) {
133
+ const sourceRoot = path.join(PACKAGE_ROOT, cfg.source)
134
+ const targetRoot = path.join(PROJECT_ROOT, cfg.target)
135
+
136
+ if (!fs.existsSync(sourceRoot)) {
137
+ log(` Source not found: ${sourceRoot}`, 'red')
138
+ return { overwritten: 0, created: 0, preserved: 0 }
139
+ }
140
+
141
+ // Ensure target root exists
142
+ if (!fs.existsSync(targetRoot)) {
143
+ fs.mkdirSync(targetRoot, { recursive: true })
144
+ }
145
+
146
+ let overwritten = 0
147
+ let created = 0
148
+ let preserved = 0
149
+
150
+ // 1. Process overwrite directories (agents, commands, skills, etc.)
151
+ for (const dirName of OVERWRITE_DIRS) {
152
+ const srcDir = path.join(sourceRoot, dirName)
153
+ if (!fs.existsSync(srcDir)) continue
154
+
155
+ const files = getAllFiles(srcDir)
156
+ for (const relPath of files) {
157
+ const srcFile = path.join(srcDir, relPath)
158
+ const destFile = path.join(targetRoot, dirName, relPath)
159
+ const existed = fs.existsSync(destFile)
160
+
161
+ copyFile(srcFile, destFile)
162
+
163
+ if (existed) {
164
+ overwritten++
165
+ } else {
166
+ created++
167
+ }
168
+ }
169
+
170
+ if (files.length > 0) {
171
+ log(` ${dirName}/: ${files.length} files`, 'green')
172
+ }
173
+ }
174
+
175
+ // 2. Process config/ directory with mixed strategy
176
+ const srcConfig = path.join(sourceRoot, 'config')
177
+ const destConfig = path.join(targetRoot, 'config')
178
+
179
+ if (fs.existsSync(srcConfig)) {
180
+ if (!fs.existsSync(destConfig)) {
181
+ fs.mkdirSync(destConfig, { recursive: true })
182
+ }
183
+
184
+ let schemasCopied = 0
185
+ let configsCreated = 0
186
+ let configsPreserved = 0
187
+
188
+ for (const file of fs.readdirSync(srcConfig)) {
189
+ const srcFile = path.join(srcConfig, file)
190
+ const destFile = path.join(destConfig, file)
191
+
192
+ // Skip non-files and .gitkeep
193
+ if (!fs.statSync(srcFile).isFile() || file === '.gitkeep') continue
194
+
195
+ const isSchema = file.endsWith('.schema.json')
196
+
197
+ if (isSchema) {
198
+ // Schema files: always overwrite
199
+ copyFile(srcFile, destFile)
200
+ schemasCopied++
201
+ overwritten++
202
+ } else {
203
+ // Config files: copy only if not exists
204
+ if (fs.existsSync(destFile)) {
205
+ configsPreserved++
206
+ preserved++
207
+ } else {
208
+ copyFile(srcFile, destFile)
209
+ configsCreated++
210
+ created++
211
+ }
212
+ }
213
+ }
214
+
215
+ if (schemasCopied > 0) {
216
+ log(` config/*.schema.json: ${schemasCopied} schemas updated`, 'green')
217
+ }
218
+ if (configsCreated > 0) {
219
+ log(` config/*.json: ${configsCreated} new configs created`, 'green')
220
+ }
221
+ if (configsPreserved > 0) {
222
+ log(` config/*.json: ${configsPreserved} user configs preserved`, 'blue')
223
+ }
224
+ }
225
+
226
+ // 3. Ensure sessions/ directory exists (never copy content)
227
+ const sessionsDir = path.join(targetRoot, 'sessions')
228
+ if (!fs.existsSync(sessionsDir)) {
229
+ fs.mkdirSync(sessionsDir, { recursive: true })
230
+ log(` sessions/: created (empty)`, 'green')
231
+ } else {
232
+ log(` sessions/: exists (preserved)`, 'blue')
233
+ }
234
+
235
+ return { overwritten, created, preserved }
236
+ }
237
+
238
+ // ---------------------------------------------------------------------------
239
+ // Entry point
240
+ // ---------------------------------------------------------------------------
241
+
242
+ const editorArg = process.argv[2] || 'claude'
243
+
244
+ log(`\n${colors.bold}@nextsparkjs/ai-workflow — Setup${colors.reset}\n`, 'cyan')
245
+ log(`Package: ${PACKAGE_ROOT}`, 'dim')
246
+ log(`Project: ${PROJECT_ROOT}\n`, 'dim')
247
+
248
+ if (editorArg === 'all') {
249
+ for (const [name, cfg] of Object.entries(EDITORS)) {
250
+ if (cfg.enabled) {
251
+ log(`Setting up ${name}:`, 'cyan')
252
+ const stats = setupEditor(name, cfg)
253
+ log(` Total: ${stats.overwritten} updated, ${stats.created} created, ${stats.preserved} preserved\n`, 'dim')
254
+ } else {
255
+ log(`${name}: coming soon\n`, 'yellow')
256
+ }
257
+ }
258
+ } else {
259
+ const cfg = EDITORS[editorArg]
260
+
261
+ if (!cfg) {
262
+ log(`Unknown editor: ${editorArg}`, 'red')
263
+ log(`Available: ${Object.keys(EDITORS).join(', ')}, all`, 'dim')
264
+ process.exit(1)
265
+ }
266
+
267
+ if (!cfg.enabled) {
268
+ log(`${editorArg}: coming soon`, 'yellow')
269
+ log(`Currently supported: claude`, 'dim')
270
+ process.exit(0)
271
+ }
272
+
273
+ log(`Setting up ${editorArg}:`, 'cyan')
274
+ const stats = setupEditor(editorArg, cfg)
275
+
276
+ log('')
277
+ log(`Setup complete!`, 'green')
278
+ log(` ${stats.overwritten} files updated`, 'dim')
279
+ log(` ${stats.created} files created`, 'dim')
280
+ log(` ${stats.preserved} files preserved`, 'dim')
281
+ log('')
282
+ }
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @nextsparkjs/ai-workflow - Sync Script
5
+ *
6
+ * Syncs the monorepo's working .claude/ directory into the publishable
7
+ * packages/ai-workflow/claude/ directory. Run manually before npm publish.
8
+ *
9
+ * Usage:
10
+ * node packages/ai-workflow/scripts/sync.mjs
11
+ * # or from package dir:
12
+ * pnpm sync
13
+ */
14
+
15
+ import fs from 'node:fs'
16
+ import path from 'node:path'
17
+ import { fileURLToPath } from 'node:url'
18
+
19
+ const __filename = fileURLToPath(import.meta.url)
20
+ const __dirname = path.dirname(__filename)
21
+
22
+ // Package root = packages/ai-workflow/
23
+ const PACKAGE_ROOT = path.resolve(__dirname, '..')
24
+ // Monorepo root = repo/
25
+ const MONOREPO_ROOT = path.resolve(PACKAGE_ROOT, '../..')
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Editor definitions (future-proof)
29
+ // ---------------------------------------------------------------------------
30
+
31
+ const EDITORS = {
32
+ claude: {
33
+ sourceDir: '.claude',
34
+ targetDir: 'claude',
35
+ enabled: true,
36
+ },
37
+ cursor: {
38
+ sourceDir: '.cursor',
39
+ targetDir: 'cursor',
40
+ enabled: false,
41
+ },
42
+ antigravity: {
43
+ sourceDir: '.antigravity',
44
+ targetDir: 'antigravity',
45
+ enabled: false,
46
+ },
47
+ }
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Sync mapping: directories and files to copy from .claude/ to claude/
51
+ // ---------------------------------------------------------------------------
52
+
53
+ /** Directories to sync (cleaned before copy) */
54
+ const SYNC_DIRS = [
55
+ 'agents',
56
+ 'commands',
57
+ 'skills',
58
+ 'templates',
59
+ 'workflows',
60
+ '_docs',
61
+ ]
62
+
63
+ /** Subdirectories to exclude from sync (monorepo-only content) */
64
+ const EXCLUDE_DIRS = new Set(['_monorepo'])
65
+
66
+ /** File globs within config/ to sync (only schemas) */
67
+ const CONFIG_SYNC_PATTERN = /\.schema\.json$/
68
+
69
+ // ---------------------------------------------------------------------------
70
+ // Helpers
71
+ // ---------------------------------------------------------------------------
72
+
73
+ const colors = {
74
+ reset: '\x1b[0m',
75
+ cyan: '\x1b[36m',
76
+ green: '\x1b[32m',
77
+ yellow: '\x1b[33m',
78
+ red: '\x1b[31m',
79
+ dim: '\x1b[2m',
80
+ }
81
+
82
+ function log(msg, color = 'reset') {
83
+ console.log(`${colors[color]}${msg}${colors.reset}`)
84
+ }
85
+
86
+ function getAllFiles(dir, baseDir = dir) {
87
+ const results = []
88
+ if (!fs.existsSync(dir)) return results
89
+
90
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
91
+ if (EXCLUDE_DIRS.has(entry.name)) continue
92
+ const fullPath = path.join(dir, entry.name)
93
+ if (entry.isDirectory()) {
94
+ results.push(...getAllFiles(fullPath, baseDir))
95
+ } else {
96
+ results.push(path.relative(baseDir, fullPath))
97
+ }
98
+ }
99
+ return results
100
+ }
101
+
102
+ function removeDir(dir) {
103
+ if (fs.existsSync(dir)) {
104
+ fs.rmSync(dir, { recursive: true, force: true })
105
+ }
106
+ }
107
+
108
+ function copyFile(src, dest) {
109
+ const destDir = path.dirname(dest)
110
+ if (!fs.existsSync(destDir)) {
111
+ fs.mkdirSync(destDir, { recursive: true })
112
+ }
113
+ fs.copyFileSync(src, dest)
114
+ }
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // Main sync logic
118
+ // ---------------------------------------------------------------------------
119
+
120
+ function syncEditor(name, cfg) {
121
+ const sourceRoot = path.join(MONOREPO_ROOT, cfg.sourceDir)
122
+ const targetRoot = path.join(PACKAGE_ROOT, cfg.targetDir)
123
+
124
+ if (!fs.existsSync(sourceRoot)) {
125
+ log(` Source not found: ${sourceRoot}`, 'red')
126
+ return { copied: 0, removed: 0, skipped: 0 }
127
+ }
128
+
129
+ let copied = 0
130
+ let removed = 0
131
+ let skipped = 0
132
+
133
+ // 1. Sync directories: clean target then copy
134
+ for (const dirName of SYNC_DIRS) {
135
+ const srcDir = path.join(sourceRoot, dirName)
136
+ const destDir = path.join(targetRoot, dirName)
137
+
138
+ if (!fs.existsSync(srcDir)) {
139
+ skipped++
140
+ continue
141
+ }
142
+
143
+ // Clean target directory (remove stale files)
144
+ if (fs.existsSync(destDir)) {
145
+ const oldFiles = getAllFiles(destDir)
146
+ removeDir(destDir)
147
+ removed += oldFiles.length
148
+ }
149
+
150
+ // Copy all files
151
+ const files = getAllFiles(srcDir)
152
+ for (const relPath of files) {
153
+ copyFile(
154
+ path.join(srcDir, relPath),
155
+ path.join(destDir, relPath)
156
+ )
157
+ copied++
158
+ }
159
+
160
+ log(` ${dirName}/: ${files.length} files`, 'green')
161
+ }
162
+
163
+ // 2. Sync config/ schemas only
164
+ const srcConfig = path.join(sourceRoot, 'config')
165
+ const destConfig = path.join(targetRoot, 'config')
166
+
167
+ if (fs.existsSync(srcConfig)) {
168
+ let schemaCount = 0
169
+ for (const file of fs.readdirSync(srcConfig)) {
170
+ if (CONFIG_SYNC_PATTERN.test(file)) {
171
+ copyFile(
172
+ path.join(srcConfig, file),
173
+ path.join(destConfig, file)
174
+ )
175
+ schemaCount++
176
+ copied++
177
+ }
178
+ }
179
+ log(` config/*.schema.json: ${schemaCount} files`, 'green')
180
+ log(` config/*.json (templates): preserved`, 'dim')
181
+ }
182
+
183
+ return { copied, removed, skipped }
184
+ }
185
+
186
+ // ---------------------------------------------------------------------------
187
+ // Entry point
188
+ // ---------------------------------------------------------------------------
189
+
190
+ log('\n@nextsparkjs/ai-workflow — Sync\n', 'cyan')
191
+ log(`Source: ${MONOREPO_ROOT}/.claude/`, 'dim')
192
+ log(`Target: ${PACKAGE_ROOT}/claude/\n`, 'dim')
193
+
194
+ let totalCopied = 0
195
+ let totalRemoved = 0
196
+
197
+ for (const [name, cfg] of Object.entries(EDITORS)) {
198
+ if (!cfg.enabled) {
199
+ log(`${name}: coming soon (skipped)`, 'dim')
200
+ continue
201
+ }
202
+
203
+ log(`Syncing ${name}:`, 'cyan')
204
+ const stats = syncEditor(name, cfg)
205
+ totalCopied += stats.copied
206
+ totalRemoved += stats.removed
207
+ }
208
+
209
+ log(`\nDone: ${totalCopied} files copied, ${totalRemoved} stale files removed.\n`, 'green')