@nextsparkjs/ai-workflow 0.1.0-beta.100

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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +634 -0
  5. package/claude/agents/architecture-supervisor.md +1351 -0
  6. package/claude/agents/backend-developer.md +997 -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 +1432 -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 +1268 -0
  15. package/claude/agents/frontend-developer.md +1234 -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 +963 -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 +352 -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 +746 -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 +440 -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 +500 -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/changelog.md +115 -0
  77. package/claude/commands/session/close.md +225 -0
  78. package/claude/commands/session/commit.md +174 -0
  79. package/claude/commands/session/db-entity.md +206 -0
  80. package/claude/commands/session/db-fix.md +212 -0
  81. package/claude/commands/session/db-sample.md +206 -0
  82. package/claude/commands/session/demo.md +178 -0
  83. package/claude/commands/session/doc-bdd.md +207 -0
  84. package/claude/commands/session/doc-feature.md +218 -0
  85. package/claude/commands/session/doc-read.md +225 -0
  86. package/claude/commands/session/execute.md +204 -0
  87. package/claude/commands/session/explain.md +202 -0
  88. package/claude/commands/session/fix-bug.md +210 -0
  89. package/claude/commands/session/fix-build.md +182 -0
  90. package/claude/commands/session/fix-test.md +189 -0
  91. package/claude/commands/session/pending.md +232 -0
  92. package/claude/commands/session/refine.md +188 -0
  93. package/claude/commands/session/resume.md +192 -0
  94. package/claude/commands/session/review.md +192 -0
  95. package/claude/commands/session/scope-change.md +181 -0
  96. package/claude/commands/session/start-blocks.md +347 -0
  97. package/claude/commands/session/start.md +604 -0
  98. package/claude/commands/session/status.md +169 -0
  99. package/claude/commands/session/test-fix.md +221 -0
  100. package/claude/commands/session/test-run.md +203 -0
  101. package/claude/commands/session/test-write.md +242 -0
  102. package/claude/commands/session/validate.md +162 -0
  103. package/claude/config/context.json +40 -0
  104. package/claude/config/github.json +69 -0
  105. package/claude/config/github.schema.json +106 -0
  106. package/claude/config/team.json +46 -0
  107. package/claude/config/team.schema.json +106 -0
  108. package/claude/config/workspace.json +43 -0
  109. package/claude/config/workspace.schema.json +75 -0
  110. package/claude/skills/README.md +228 -0
  111. package/claude/skills/accessibility/SKILL.md +573 -0
  112. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  113. package/claude/skills/asana-integration/SKILL.md +499 -0
  114. package/claude/skills/better-auth/SKILL.md +666 -0
  115. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  116. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  117. package/claude/skills/clickup-integration/SKILL.md +434 -0
  118. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  119. package/claude/skills/create-plugin/SKILL.md +425 -0
  120. package/claude/skills/create-theme/SKILL.md +331 -0
  121. package/claude/skills/cypress-api/SKILL.md +511 -0
  122. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  124. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  125. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  126. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  127. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  128. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  129. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  130. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  131. package/claude/skills/database-migrations/SKILL.md +335 -0
  132. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  133. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  134. package/claude/skills/design-system/SKILL.md +682 -0
  135. package/claude/skills/documentation/SKILL.md +540 -0
  136. package/claude/skills/entity-api/SKILL.md +482 -0
  137. package/claude/skills/entity-system/SKILL.md +635 -0
  138. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  139. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  140. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  141. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  142. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  143. package/claude/skills/github/SKILL.md +467 -0
  144. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  145. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  146. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  147. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  148. package/claude/skills/impact-analysis/SKILL.md +203 -0
  149. package/claude/skills/jest-unit/SKILL.md +306 -0
  150. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  151. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  152. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  153. package/claude/skills/jira-integration/SKILL.md +539 -0
  154. package/claude/skills/media-library/SKILL.md +743 -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 +530 -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 +688 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +671 -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 +507 -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 +35 -0
  270. package/scripts/postinstall.mjs +198 -0
  271. package/scripts/setup.mjs +282 -0
  272. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,443 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Scaffold Plugin Script
4
+
5
+ Creates a new plugin with complete file structure.
6
+ Part of the plugins skill.
7
+
8
+ Usage:
9
+ python scaffold-plugin.py --name "my-plugin" --type service
10
+ python scaffold-plugin.py -n "analytics" -t utility --features "hooks,api"
11
+ """
12
+
13
+ import argparse
14
+ import os
15
+ import sys
16
+ from datetime import datetime
17
+ from pathlib import Path
18
+
19
+
20
+ def get_project_root() -> Path:
21
+ """Find the project root by looking for .claude directory."""
22
+ current = Path(__file__).resolve()
23
+
24
+ for parent in current.parents:
25
+ if (parent / ".claude").is_dir():
26
+ return parent
27
+
28
+ cwd = Path.cwd()
29
+ if (cwd / ".claude").is_dir():
30
+ return cwd
31
+
32
+ print("Error: Could not find project root (.claude directory)")
33
+ sys.exit(1)
34
+
35
+
36
+ def validate_name(name: str) -> str:
37
+ """Validate and normalize plugin name."""
38
+ normalized = name.lower().strip().replace(" ", "-").replace("_", "-")
39
+ cleaned = "".join(c for c in normalized if c.isalnum() or c == "-")
40
+
41
+ while "--" in cleaned:
42
+ cleaned = cleaned.replace("--", "-")
43
+
44
+ cleaned = cleaned.strip("-")
45
+
46
+ if not cleaned:
47
+ print("Error: Invalid plugin name. Must contain alphanumeric characters.")
48
+ sys.exit(1)
49
+
50
+ return cleaned
51
+
52
+
53
+ def to_pascal_case(name: str) -> str:
54
+ """Convert kebab-case to PascalCase."""
55
+ return "".join(word.capitalize() for word in name.split("-"))
56
+
57
+
58
+ def to_camel_case(name: str) -> str:
59
+ """Convert kebab-case to camelCase."""
60
+ pascal = to_pascal_case(name)
61
+ return pascal[0].lower() + pascal[1:] if pascal else ""
62
+
63
+
64
+ def to_upper_snake(name: str) -> str:
65
+ """Convert kebab-case to UPPER_SNAKE_CASE."""
66
+ return name.replace("-", "_").upper()
67
+
68
+
69
+ def create_plugin(name: str, plugin_type: str, features: list) -> None:
70
+ """Create a new plugin with complete file structure."""
71
+ project_root = get_project_root()
72
+ plugins_dir = project_root / "contents" / "plugins"
73
+ plugin_name = validate_name(name)
74
+ plugin_path = plugins_dir / plugin_name
75
+
76
+ if plugin_path.exists():
77
+ print(f"Error: Plugin already exists: {plugin_path}")
78
+ sys.exit(1)
79
+
80
+ plugin_path.mkdir(parents=True, exist_ok=True)
81
+ print(f"Created plugin: {plugin_name}")
82
+
83
+ # Naming variants
84
+ P = to_pascal_case(plugin_name) # PascalCase
85
+ c = to_camel_case(plugin_name) # camelCase
86
+ U = to_upper_snake(plugin_name) # UPPER_SNAKE
87
+
88
+ created_files = []
89
+
90
+ # 1. plugin.config.ts
91
+ config_content = f"""import {{ z }} from 'zod'
92
+ import type {{ PluginConfig }} from '@/core/types/plugin'
93
+
94
+ const {P}ConfigSchema = z.object({{
95
+ enabled: z.boolean().default(true),
96
+ debugMode: z.boolean().default(false),
97
+ timeout: z.number().min(1000).max(60000).default(5000)
98
+ }})
99
+
100
+ export const {c}Config: PluginConfig = {{
101
+ name: '{plugin_name}',
102
+ version: '1.0.0',
103
+ displayName: '{P}',
104
+ description: '{P} plugin for the application',
105
+ enabled: true,
106
+ dependencies: [],
107
+ components: {{ {P}Widget: undefined }},
108
+ services: {{ use{P}: undefined }},
109
+ hooks: {{
110
+ async onLoad() {{ console.log('[{P}] Loading...') }},
111
+ async onActivate() {{ console.log('[{P}] Activated') }},
112
+ async onDeactivate() {{ console.log('[{P}] Deactivated') }},
113
+ async onUnload() {{ console.log('[{P}] Unloaded') }}
114
+ }}
115
+ }}
116
+
117
+ export default {c}Config
118
+ """
119
+ (plugin_path / "plugin.config.ts").write_text(config_content)
120
+ created_files.append("plugin.config.ts")
121
+
122
+ # 2. README.md
123
+ readme_content = f"""# {P} Plugin
124
+
125
+ ## Overview
126
+
127
+ {P} plugin for the application.
128
+
129
+ ## Installation
130
+
131
+ Automatically registered when placed in `contents/plugins/{plugin_name}/`.
132
+
133
+ ## Configuration
134
+
135
+ ```bash
136
+ {U}_ENABLED=true
137
+ {U}_DEBUG=false
138
+ ```
139
+
140
+ ## Usage
141
+
142
+ ```typescript
143
+ import {{ use{P} }} from '@/contents/plugins/{plugin_name}/hooks/use{P}'
144
+
145
+ function MyComponent() {{
146
+ const {{ data, isLoading }} = use{P}()
147
+ }}
148
+ ```
149
+
150
+ ## API Endpoints
151
+
152
+ - `POST /api/plugin/{plugin_name}/process` - Process data
153
+
154
+ ## Components
155
+
156
+ - `{P}Widget` - Main widget component
157
+ """
158
+ (plugin_path / "README.md").write_text(readme_content)
159
+ created_files.append("README.md")
160
+
161
+ # 3. .env.example
162
+ env_content = f"""# {U} PLUGIN ENVIRONMENT VARIABLES
163
+ # Only {U}_* namespaced variables here
164
+ # Global variables go in root .env
165
+
166
+ {U}_ENABLED=true
167
+ {U}_DEBUG=false
168
+ {U}_TIMEOUT=5000
169
+ """
170
+ (plugin_path / ".env.example").write_text(env_content)
171
+ created_files.append(".env.example")
172
+
173
+ # 4. package.json
174
+ package_content = f"""{{
175
+ "name": "@plugins/{plugin_name}",
176
+ "version": "1.0.0",
177
+ "private": true,
178
+ "description": "{P} plugin",
179
+ "main": "plugin.config.ts"
180
+ }}
181
+ """
182
+ (plugin_path / "package.json").write_text(package_content)
183
+ created_files.append("package.json")
184
+
185
+ # 5. tsconfig.json
186
+ tsconfig_content = """{
187
+ "extends": "../../../tsconfig.json",
188
+ "compilerOptions": { "rootDir": ".", "outDir": "./dist" },
189
+ "include": ["./**/*.ts", "./**/*.tsx"],
190
+ "exclude": ["node_modules", "dist", "__tests__"]
191
+ }
192
+ """
193
+ (plugin_path / "tsconfig.json").write_text(tsconfig_content)
194
+ created_files.append("tsconfig.json")
195
+
196
+ # 6. types/
197
+ types_dir = plugin_path / "types"
198
+ types_dir.mkdir(exist_ok=True)
199
+ types_content = f"""export interface {P}Config {{
200
+ readonly enabled: boolean
201
+ readonly debugMode: boolean
202
+ readonly timeout: number
203
+ }}
204
+
205
+ export interface {P}Input {{
206
+ readonly data: string
207
+ readonly options?: {P}Options
208
+ }}
209
+
210
+ export interface {P}Output<T = unknown> {{
211
+ readonly success: boolean
212
+ readonly data?: T
213
+ readonly error?: string
214
+ readonly metadata: {{ readonly processingTime: number; readonly timestamp: string }}
215
+ }}
216
+
217
+ export interface {P}Options {{
218
+ readonly timeout?: number
219
+ }}
220
+ """
221
+ (types_dir / f"{plugin_name}.types.ts").write_text(types_content)
222
+ created_files.append(f"types/{plugin_name}.types.ts")
223
+
224
+ # 7. lib/
225
+ lib_dir = plugin_path / "lib"
226
+ lib_dir.mkdir(exist_ok=True)
227
+ lib_content = f"""import type {{ {P}Config, {P}Input, {P}Output }} from '../types/{plugin_name}.types'
228
+
229
+ export class {P}Core {{
230
+ private config: {P}Config
231
+ private initialized = false
232
+
233
+ constructor(config: {P}Config) {{ this.config = config }}
234
+
235
+ async initialize(): Promise<void> {{
236
+ if (this.initialized) return
237
+ await this.validateConfiguration()
238
+ this.initialized = true
239
+ console.log('[{P}] Initialized')
240
+ }}
241
+
242
+ private async validateConfiguration(): Promise<void> {{
243
+ if (!this.config.enabled) throw new Error('{P} plugin is disabled')
244
+ }}
245
+
246
+ async process(input: {P}Input): Promise<{P}Output> {{
247
+ if (!this.initialized) await this.initialize()
248
+ const startTime = Date.now()
249
+ try {{
250
+ const result = {{ processed: input.data }}
251
+ return {{
252
+ success: true,
253
+ data: result,
254
+ metadata: {{ processingTime: Date.now() - startTime, timestamp: new Date().toISOString() }}
255
+ }}
256
+ }} catch (error) {{
257
+ return {{
258
+ success: false,
259
+ error: error instanceof Error ? error.message : 'Unknown error',
260
+ metadata: {{ processingTime: Date.now() - startTime, timestamp: new Date().toISOString() }}
261
+ }}
262
+ }}
263
+ }}
264
+ }}
265
+ """
266
+ (lib_dir / "core.ts").write_text(lib_content)
267
+ created_files.append("lib/core.ts")
268
+
269
+ # 8. hooks/ (if service type or requested)
270
+ if "hooks" in features or plugin_type == "service":
271
+ hooks_dir = plugin_path / "hooks"
272
+ hooks_dir.mkdir(exist_ok=True)
273
+ hook_content = f"""'use client'
274
+
275
+ import {{ useQuery, useMutation, useQueryClient }} from '@tanstack/react-query'
276
+ import type {{ {P}Input, {P}Output }} from '../types/{plugin_name}.types'
277
+
278
+ const QUERY_KEY = ['{plugin_name}'] as const
279
+
280
+ export function use{P}() {{
281
+ return useQuery({{
282
+ queryKey: QUERY_KEY,
283
+ queryFn: async () => {{
284
+ const response = await fetch('/api/plugin/{plugin_name}/data')
285
+ if (!response.ok) throw new Error('Failed to fetch')
286
+ return response.json()
287
+ }}
288
+ }})
289
+ }}
290
+
291
+ export function use{P}Mutation() {{
292
+ const queryClient = useQueryClient()
293
+ return useMutation({{
294
+ mutationFn: async (input: {P}Input) => {{
295
+ const response = await fetch('/api/plugin/{plugin_name}/process', {{
296
+ method: 'POST',
297
+ headers: {{ 'Content-Type': 'application/json' }},
298
+ body: JSON.stringify(input)
299
+ }})
300
+ if (!response.ok) throw new Error('Failed to process')
301
+ return response.json() as Promise<{P}Output>
302
+ }},
303
+ onSuccess: () => {{ queryClient.invalidateQueries({{ queryKey: QUERY_KEY }}) }}
304
+ }})
305
+ }}
306
+ """
307
+ (hooks_dir / f"use{P}.ts").write_text(hook_content)
308
+ created_files.append(f"hooks/use{P}.ts")
309
+
310
+ # 9. components/ (if service type or requested)
311
+ if "components" in features or plugin_type == "service":
312
+ components_dir = plugin_path / "components"
313
+ components_dir.mkdir(exist_ok=True)
314
+ component_content = f"""'use client'
315
+
316
+ import {{ Card, CardHeader, CardContent }} from '@/core/components/ui/card'
317
+ import {{ Button }} from '@/core/components/ui/button'
318
+ import {{ use{P} }} from '../hooks/use{P}'
319
+
320
+ interface {P}WidgetProps {{
321
+ readonly title?: string
322
+ readonly onAction?: () => void
323
+ }}
324
+
325
+ export function {P}Widget({{ title = '{P}', onAction }}: {P}WidgetProps) {{
326
+ const {{ data, isLoading, error }} = use{P}()
327
+
328
+ return (
329
+ <Card data-cy="{plugin_name}-widget">
330
+ <CardHeader><h3>{{title}}</h3></CardHeader>
331
+ <CardContent>
332
+ {{isLoading && <div data-cy="{plugin_name}-loading">Loading...</div>}}
333
+ {{error && <div data-cy="{plugin_name}-error">{{error.message}}</div>}}
334
+ {{data && <div data-cy="{plugin_name}-content">{{/* Content */}}</div>}}
335
+ <Button data-cy="{plugin_name}-action-btn" onClick={{onAction}}>Action</Button>
336
+ </CardContent>
337
+ </Card>
338
+ )
339
+ }}
340
+ """
341
+ (components_dir / f"{P}Widget.tsx").write_text(component_content)
342
+ created_files.append(f"components/{P}Widget.tsx")
343
+
344
+ # 10. api/ (if service type or requested)
345
+ if "api" in features or plugin_type == "service":
346
+ api_dir = plugin_path / "api" / "process"
347
+ api_dir.mkdir(parents=True, exist_ok=True)
348
+ api_content = f"""import {{ NextRequest, NextResponse }} from 'next/server'
349
+ import {{ z }} from 'zod'
350
+ import {{ authenticateRequest }} from '@/core/lib/auth/authenticateRequest'
351
+ import {{ {P}Core }} from '../../lib/core'
352
+
353
+ const ProcessInputSchema = z.object({{
354
+ data: z.string().min(1).max(10000),
355
+ options: z.object({{ timeout: z.number().min(1000).max(30000).optional() }}).optional()
356
+ }})
357
+
358
+ export async function POST(request: NextRequest) {{
359
+ try {{
360
+ const auth = await authenticateRequest(request)
361
+ if (!auth.isAuthenticated) {{
362
+ return NextResponse.json({{ success: false, error: 'Unauthorized' }}, {{ status: 401 }})
363
+ }}
364
+
365
+ const body = await request.json()
366
+ const input = ProcessInputSchema.parse(body)
367
+
368
+ const core = new {P}Core({{ enabled: true, debugMode: false, timeout: input.options?.timeout || 5000 }})
369
+ const result = await core.process(input)
370
+
371
+ return NextResponse.json(result)
372
+ }} catch (error) {{
373
+ if (error instanceof z.ZodError) {{
374
+ return NextResponse.json({{ success: false, error: 'Validation error', details: error.errors }}, {{ status: 400 }})
375
+ }}
376
+ console.error('[{P}] API Error:', error)
377
+ return NextResponse.json({{ success: false, error: 'Internal server error' }}, {{ status: 500 }})
378
+ }}
379
+ }}
380
+ """
381
+ (api_dir / "route.ts").write_text(api_content)
382
+ created_files.append("api/process/route.ts")
383
+
384
+ # 11. docs/
385
+ docs_dir = plugin_path / "docs" / "01-getting-started"
386
+ docs_dir.mkdir(parents=True, exist_ok=True)
387
+ intro_content = f"""# {P} Plugin
388
+
389
+ ## Introduction
390
+
391
+ {P} is a plugin that provides functionality for the application.
392
+
393
+ ## Quick Start
394
+
395
+ ```typescript
396
+ import {{ use{P} }} from '@/contents/plugins/{plugin_name}/hooks/use{P}'
397
+
398
+ function MyComponent() {{
399
+ const {{ data, isLoading }} = use{P}()
400
+ if (isLoading) return <div>Loading...</div>
401
+ return <div>{{data}}</div>
402
+ }}
403
+ ```
404
+ """
405
+ (docs_dir / "01-introduction.md").write_text(intro_content)
406
+ created_files.append("docs/01-getting-started/01-introduction.md")
407
+
408
+ # Summary
409
+ print(f"\nPlugin created with {len(created_files)} files:")
410
+ for file in created_files:
411
+ print(f" {file}")
412
+
413
+ print(f"\nPlugin path: {plugin_path}")
414
+ print("\nNext steps:")
415
+ print(" 1. Configure environment variables")
416
+ print(" 2. Implement core logic in lib/core.ts")
417
+ print(" 3. Run: node core/scripts/build/registry.mjs")
418
+ print(" 4. Test with: pnpm build")
419
+
420
+
421
+ def main():
422
+ parser = argparse.ArgumentParser(
423
+ description="Create a new plugin with complete file structure",
424
+ formatter_class=argparse.RawDescriptionHelpFormatter,
425
+ epilog="""
426
+ Examples:
427
+ python scaffold-plugin.py --name "my-plugin" --type service
428
+ python scaffold-plugin.py -n "analytics" -t utility
429
+ python scaffold-plugin.py --name "payment" --type service --features "components,hooks,api"
430
+ """
431
+ )
432
+
433
+ parser.add_argument("-n", "--name", required=True, help="Plugin name (kebab-case)")
434
+ parser.add_argument("-t", "--type", choices=["utility", "service", "configuration"], default="service", help="Plugin type (default: service)")
435
+ parser.add_argument("-f", "--features", default="", help="Comma-separated: components,hooks,api")
436
+
437
+ args = parser.parse_args()
438
+ features = [f.strip() for f in args.features.split(",") if f.strip()]
439
+ create_plugin(args.name, args.type, features)
440
+
441
+
442
+ if __name__ == "__main__":
443
+ main()