@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,414 @@
1
+ # Plugin Templates Reference
2
+
3
+ Copy-paste templates for plugin components, hooks, and API endpoints.
4
+
5
+ ---
6
+
7
+ ## ⭐ Plugin Environment Loader (REQUIRED)
8
+
9
+ Every plugin MUST have a `lib/plugin-env.ts` using core's centralized env-loader:
10
+
11
+ ```typescript
12
+ // contents/plugins/my-plugin/lib/plugin-env.ts
13
+ import { getPluginEnv } from '@nextsparkjs/core/lib/plugins/env-loader'
14
+
15
+ interface MyPluginEnvConfig {
16
+ MY_PLUGIN_ENABLED?: string
17
+ MY_PLUGIN_DEBUG?: string
18
+ MY_PLUGIN_API_KEY?: string
19
+ MY_PLUGIN_TIMEOUT?: string
20
+ }
21
+
22
+ class PluginEnvironment {
23
+ private static instance: PluginEnvironment
24
+ private config: MyPluginEnvConfig = {}
25
+ private loaded = false
26
+
27
+ private constructor() {
28
+ this.loadEnvironment()
29
+ }
30
+
31
+ public static getInstance(): PluginEnvironment {
32
+ if (!PluginEnvironment.instance) {
33
+ PluginEnvironment.instance = new PluginEnvironment()
34
+ }
35
+ return PluginEnvironment.instance
36
+ }
37
+
38
+ private loadEnvironment(forceReload: boolean = false): void {
39
+ if (this.loaded && !forceReload) return
40
+
41
+ try {
42
+ // Use centralized plugin env loader
43
+ // Priority: Plugin .env > Root .env > Defaults
44
+ const env = getPluginEnv('my-plugin')
45
+
46
+ this.config = {
47
+ MY_PLUGIN_ENABLED: env.MY_PLUGIN_ENABLED || 'true',
48
+ MY_PLUGIN_DEBUG: env.MY_PLUGIN_DEBUG || 'false',
49
+ MY_PLUGIN_API_KEY: env.MY_PLUGIN_API_KEY,
50
+ MY_PLUGIN_TIMEOUT: env.MY_PLUGIN_TIMEOUT || '5000',
51
+ }
52
+
53
+ this.loaded = true
54
+ } catch (error) {
55
+ console.error('[My Plugin] Failed to load environment:', error)
56
+ this.loaded = true
57
+ }
58
+ }
59
+
60
+ public getConfig(): MyPluginEnvConfig {
61
+ if (!this.loaded) this.loadEnvironment()
62
+ return this.config
63
+ }
64
+
65
+ // Type-safe helper methods
66
+ public isPluginEnabled(): boolean {
67
+ return this.getConfig().MY_PLUGIN_ENABLED !== 'false'
68
+ }
69
+
70
+ public isDebugEnabled(): boolean {
71
+ return this.getConfig().MY_PLUGIN_DEBUG === 'true'
72
+ }
73
+
74
+ public getApiKey(): string | undefined {
75
+ return this.getConfig().MY_PLUGIN_API_KEY
76
+ }
77
+
78
+ public getTimeout(): number {
79
+ return parseInt(this.getConfig().MY_PLUGIN_TIMEOUT || '5000', 10)
80
+ }
81
+
82
+ public reload(): void {
83
+ this.loaded = false
84
+ this.loadEnvironment(true)
85
+ }
86
+ }
87
+
88
+ export const pluginEnv = PluginEnvironment.getInstance()
89
+
90
+ // Convenience exports
91
+ export const isPluginEnabled = () => pluginEnv.isPluginEnabled()
92
+ export const isDebugEnabled = () => pluginEnv.isDebugEnabled()
93
+ export const getApiKey = () => pluginEnv.getApiKey()
94
+ export const getTimeout = () => pluginEnv.getTimeout()
95
+ ```
96
+
97
+ **Benefits:**
98
+ - ✅ Plugin `.env` takes priority over root `.env`
99
+ - ✅ Automatic fallback to root `.env` for shared variables (API keys, etc.)
100
+ - ✅ Type-safe configuration access
101
+ - ✅ Singleton pattern for performance
102
+ - ✅ Reload support for testing
103
+
104
+ ---
105
+
106
+ ## Type Definitions
107
+
108
+ ```typescript
109
+ // contents/plugins/my-plugin/types/my-plugin.types.ts
110
+
111
+ // Configuration types
112
+ export interface MyPluginConfig {
113
+ readonly apiKey: string
114
+ readonly timeout: number
115
+ readonly maxRetries: number
116
+ readonly debugMode: boolean
117
+ }
118
+
119
+ // Input/Output types
120
+ export interface MyPluginInput {
121
+ readonly data: string
122
+ readonly options?: MyPluginOptions
123
+ }
124
+
125
+ export interface MyPluginOutput<T = unknown> {
126
+ readonly success: boolean
127
+ readonly data?: T
128
+ readonly error?: string
129
+ readonly metadata: {
130
+ readonly processingTime: number
131
+ readonly timestamp: string
132
+ }
133
+ }
134
+
135
+ // Options type
136
+ export interface MyPluginOptions {
137
+ readonly timeout?: number
138
+ readonly retryOnError?: boolean
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Component Template
145
+
146
+ ```typescript
147
+ // contents/plugins/my-plugin/components/MyWidget.tsx
148
+ 'use client'
149
+
150
+ import { useMyPlugin } from '../hooks/useMyPlugin'
151
+ import { Card, CardHeader, CardContent } from '@/core/components/ui/card'
152
+ import { Button } from '@/core/components/ui/button'
153
+
154
+ interface MyWidgetProps {
155
+ readonly title: string
156
+ readonly onAction?: () => void
157
+ }
158
+
159
+ export function MyWidget({ title, onAction }: MyWidgetProps) {
160
+ const { data, isLoading, error } = useMyPlugin()
161
+
162
+ return (
163
+ <Card data-cy="my-plugin-widget">
164
+ <CardHeader>
165
+ <h3>{title}</h3>
166
+ </CardHeader>
167
+ <CardContent>
168
+ {isLoading && <div data-cy="my-plugin-loading">Loading...</div>}
169
+ {error && <div data-cy="my-plugin-error">{error.message}</div>}
170
+ {data && (
171
+ <div data-cy="my-plugin-content">
172
+ {/* Content */}
173
+ </div>
174
+ )}
175
+ <Button
176
+ data-cy="my-plugin-action-btn"
177
+ onClick={onAction}
178
+ >
179
+ Action
180
+ </Button>
181
+ </CardContent>
182
+ </Card>
183
+ )
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Hook Templates
190
+
191
+ ### Query Hook
192
+
193
+ ```typescript
194
+ // contents/plugins/my-plugin/hooks/useMyPlugin.ts
195
+ 'use client'
196
+
197
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
198
+ import type { MyPluginInput, MyPluginOutput } from '../types/my-plugin.types'
199
+
200
+ const QUERY_KEY = ['my-plugin'] as const
201
+
202
+ export function useMyPlugin() {
203
+ return useQuery({
204
+ queryKey: QUERY_KEY,
205
+ queryFn: async () => {
206
+ const response = await fetch('/api/plugin/my-plugin/data')
207
+ if (!response.ok) throw new Error('Failed to fetch')
208
+ return response.json()
209
+ }
210
+ })
211
+ }
212
+ ```
213
+
214
+ ### Mutation Hook
215
+
216
+ ```typescript
217
+ export function useMyPluginMutation() {
218
+ const queryClient = useQueryClient()
219
+
220
+ return useMutation({
221
+ mutationFn: async (input: MyPluginInput) => {
222
+ const response = await fetch('/api/plugin/my-plugin/process', {
223
+ method: 'POST',
224
+ headers: { 'Content-Type': 'application/json' },
225
+ body: JSON.stringify(input)
226
+ })
227
+ if (!response.ok) throw new Error('Failed to process')
228
+ return response.json() as Promise<MyPluginOutput>
229
+ },
230
+ onSuccess: () => {
231
+ queryClient.invalidateQueries({ queryKey: QUERY_KEY })
232
+ }
233
+ })
234
+ }
235
+ ```
236
+
237
+ ---
238
+
239
+ ## API Endpoint Templates
240
+
241
+ ### POST Endpoint with Validation
242
+
243
+ ```typescript
244
+ // contents/plugins/my-plugin/api/process/route.ts
245
+ import { NextRequest, NextResponse } from 'next/server'
246
+ import { z } from 'zod'
247
+ import { authenticateRequest } from '@/core/lib/auth/authenticateRequest'
248
+
249
+ const ProcessInputSchema = z.object({
250
+ data: z.string().min(1).max(10000),
251
+ options: z.object({
252
+ timeout: z.number().min(1000).max(30000).optional()
253
+ }).optional()
254
+ })
255
+
256
+ export async function POST(request: NextRequest) {
257
+ try {
258
+ // Authentication
259
+ const auth = await authenticateRequest(request)
260
+ if (!auth.isAuthenticated) {
261
+ return NextResponse.json(
262
+ { success: false, error: 'Unauthorized' },
263
+ { status: 401 }
264
+ )
265
+ }
266
+
267
+ // Validation
268
+ const body = await request.json()
269
+ const input = ProcessInputSchema.parse(body)
270
+
271
+ // Process
272
+ const result = await processData(input)
273
+
274
+ return NextResponse.json({
275
+ success: true,
276
+ data: result,
277
+ metadata: {
278
+ processingTime: Date.now(),
279
+ timestamp: new Date().toISOString()
280
+ }
281
+ })
282
+ } catch (error) {
283
+ if (error instanceof z.ZodError) {
284
+ return NextResponse.json(
285
+ { success: false, error: 'Validation error', details: error.errors },
286
+ { status: 400 }
287
+ )
288
+ }
289
+
290
+ console.error('[My Plugin] Error:', error)
291
+ return NextResponse.json(
292
+ { success: false, error: 'Internal server error' },
293
+ { status: 500 }
294
+ )
295
+ }
296
+ }
297
+ ```
298
+
299
+ ### GET Endpoint with Query Params
300
+
301
+ ```typescript
302
+ // contents/plugins/my-plugin/api/data/route.ts
303
+ import { NextRequest, NextResponse } from 'next/server'
304
+ import { authenticateRequest } from '@/core/lib/auth/authenticateRequest'
305
+
306
+ export async function GET(request: NextRequest) {
307
+ try {
308
+ const auth = await authenticateRequest(request)
309
+ if (!auth.isAuthenticated) {
310
+ return NextResponse.json(
311
+ { success: false, error: 'Unauthorized' },
312
+ { status: 401 }
313
+ )
314
+ }
315
+
316
+ // Parse query params
317
+ const { searchParams } = new URL(request.url)
318
+ const page = parseInt(searchParams.get('page') || '1', 10)
319
+ const limit = parseInt(searchParams.get('limit') || '10', 10)
320
+
321
+ // Fetch data
322
+ const data = await fetchPluginData({ page, limit })
323
+
324
+ return NextResponse.json({
325
+ success: true,
326
+ data,
327
+ pagination: {
328
+ page,
329
+ limit,
330
+ total: data.total
331
+ }
332
+ })
333
+ } catch (error) {
334
+ console.error('[My Plugin] Error:', error)
335
+ return NextResponse.json(
336
+ { success: false, error: 'Internal server error' },
337
+ { status: 500 }
338
+ )
339
+ }
340
+ }
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Provider Template
346
+
347
+ ```typescript
348
+ // contents/plugins/my-plugin/providers/MyPluginProvider.tsx
349
+ 'use client'
350
+
351
+ import { createContext, useContext, useState, ReactNode } from 'react'
352
+ import type { MyPluginConfig } from '../types/my-plugin.types'
353
+
354
+ interface MyPluginContextValue {
355
+ config: MyPluginConfig | null
356
+ isInitialized: boolean
357
+ setConfig: (config: MyPluginConfig) => void
358
+ }
359
+
360
+ const MyPluginContext = createContext<MyPluginContextValue | null>(null)
361
+
362
+ interface MyPluginProviderProps {
363
+ children: ReactNode
364
+ initialConfig?: MyPluginConfig
365
+ }
366
+
367
+ export function MyPluginProvider({
368
+ children,
369
+ initialConfig
370
+ }: MyPluginProviderProps) {
371
+ const [config, setConfig] = useState<MyPluginConfig | null>(initialConfig || null)
372
+ const [isInitialized, setIsInitialized] = useState(!!initialConfig)
373
+
374
+ const value: MyPluginContextValue = {
375
+ config,
376
+ isInitialized,
377
+ setConfig: (newConfig) => {
378
+ setConfig(newConfig)
379
+ setIsInitialized(true)
380
+ }
381
+ }
382
+
383
+ return (
384
+ <MyPluginContext.Provider value={value}>
385
+ {children}
386
+ </MyPluginContext.Provider>
387
+ )
388
+ }
389
+
390
+ export function useMyPluginContext() {
391
+ const context = useContext(MyPluginContext)
392
+ if (!context) {
393
+ throw new Error('useMyPluginContext must be used within MyPluginProvider')
394
+ }
395
+ return context
396
+ }
397
+ ```
398
+
399
+ ---
400
+
401
+ ## data-cy Selector Conventions
402
+
403
+ All plugin components MUST use data-cy selectors:
404
+
405
+ ```typescript
406
+ // Naming convention: {plugin}-{component}-{element}
407
+ data-cy="my-plugin-widget" // Container
408
+ data-cy="my-plugin-input" // Input field
409
+ data-cy="my-plugin-action-btn" // Button
410
+ data-cy="my-plugin-loading" // Loading state
411
+ data-cy="my-plugin-error" // Error state
412
+ data-cy="my-plugin-success" // Success state
413
+ data-cy="my-plugin-content" // Content area
414
+ ```