@wp-typia/project-tools 0.20.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/runtime/ai-feature-capability.js +2 -33
  2. package/dist/runtime/built-in-block-artifact-types.js +11 -0
  3. package/dist/runtime/built-in-block-code-artifacts.js +5 -1
  4. package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +4 -3
  5. package/dist/runtime/built-in-block-code-templates/interactivity.js +259 -100
  6. package/dist/runtime/built-in-block-code-templates.d.ts +1 -1
  7. package/dist/runtime/built-in-block-code-templates.js +1 -1
  8. package/dist/runtime/cli-add-shared.d.ts +74 -5
  9. package/dist/runtime/cli-add-shared.js +61 -11
  10. package/dist/runtime/cli-add-workspace-ability.js +14 -61
  11. package/dist/runtime/cli-add-workspace-admin-view.d.ts +25 -0
  12. package/dist/runtime/cli-add-workspace-admin-view.js +1401 -0
  13. package/dist/runtime/cli-add-workspace-ai-anchors.js +2 -5
  14. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +0 -4
  15. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +7 -17
  16. package/dist/runtime/cli-add-workspace-ai.js +4 -6
  17. package/dist/runtime/cli-add-workspace-assets.d.ts +13 -5
  18. package/dist/runtime/cli-add-workspace-assets.js +290 -106
  19. package/dist/runtime/cli-add-workspace-rest-anchors.js +2 -5
  20. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +0 -1
  21. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +7 -14
  22. package/dist/runtime/cli-add-workspace-rest.js +4 -6
  23. package/dist/runtime/cli-add-workspace.d.ts +58 -1
  24. package/dist/runtime/cli-add-workspace.js +588 -18
  25. package/dist/runtime/cli-add.d.ts +1 -1
  26. package/dist/runtime/cli-add.js +1 -1
  27. package/dist/runtime/cli-core.d.ts +8 -5
  28. package/dist/runtime/cli-core.js +7 -4
  29. package/dist/runtime/cli-diagnostics.d.ts +83 -1
  30. package/dist/runtime/cli-diagnostics.js +85 -2
  31. package/dist/runtime/cli-doctor-workspace.js +553 -13
  32. package/dist/runtime/cli-doctor.d.ts +4 -2
  33. package/dist/runtime/cli-doctor.js +2 -1
  34. package/dist/runtime/cli-help.js +22 -9
  35. package/dist/runtime/cli-init.d.ts +67 -3
  36. package/dist/runtime/cli-init.js +603 -64
  37. package/dist/runtime/cli-validation.js +4 -3
  38. package/dist/runtime/external-layer-selection.d.ts +8 -2
  39. package/dist/runtime/external-layer-selection.js +3 -4
  40. package/dist/runtime/index.d.ts +9 -4
  41. package/dist/runtime/index.js +7 -3
  42. package/dist/runtime/package-json-types.d.ts +12 -0
  43. package/dist/runtime/package-json-types.js +1 -0
  44. package/dist/runtime/package-versions.d.ts +30 -2
  45. package/dist/runtime/package-versions.js +59 -1
  46. package/dist/runtime/php-utils.d.ts +16 -0
  47. package/dist/runtime/php-utils.js +59 -0
  48. package/dist/runtime/scaffold-answer-resolution.js +7 -6
  49. package/dist/runtime/scaffold-apply-utils.d.ts +2 -3
  50. package/dist/runtime/scaffold-apply-utils.js +3 -43
  51. package/dist/runtime/scaffold-compatibility.d.ts +2 -2
  52. package/dist/runtime/scaffold-compatibility.js +22 -48
  53. package/dist/runtime/template-source-cache.d.ts +112 -0
  54. package/dist/runtime/template-source-cache.js +434 -0
  55. package/dist/runtime/template-source-seeds.js +319 -53
  56. package/dist/runtime/version-floor.d.ts +26 -0
  57. package/dist/runtime/version-floor.js +56 -0
  58. package/dist/runtime/workspace-inventory.d.ts +44 -2
  59. package/dist/runtime/workspace-inventory.js +138 -5
  60. package/package.json +4 -3
@@ -4,6 +4,7 @@ import { useBlockProps, InspectorControls, RichText, BlockControls, AlignmentToo
4
4
  import { PanelBody, RangeControl, Button, Notice } from '@wordpress/components';
5
5
  import { useState } from '@wordpress/element';
6
6
  import currentManifest from './manifest-document';
7
+ import { {{slugCamelCase}}Store } from './interactivity-store';
7
8
  import {
8
9
  InspectorFromManifest,
9
10
  useEditorFields,
@@ -84,17 +85,22 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
84
85
 
85
86
  const blockProps = useBlockProps({
86
87
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
87
- 'data-wp-interactive': '{{slugKebabCase}}',
88
- 'data-wp-context': JSON.stringify({
89
- clicks: clickCount,
90
- isAnimating,
91
- isVisible,
92
- animation,
93
- maxClicks,
94
- })
88
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
89
+ 'data-wp-context': JSON.stringify(
90
+ {{slugCamelCase}}Store.createContext({
91
+ clicks: clickCount,
92
+ isAnimating,
93
+ isVisible,
94
+ animation,
95
+ maxClicks,
96
+ })
97
+ )
95
98
  });
96
99
  const previewContentStyle = { textAlign: alignmentValue };
97
100
  const progressBarStyle = { width: \`\${(clickCount / maxClicks) * 100}%\` };
101
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
102
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
103
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
98
104
 
99
105
  const resetCounter = () => {
100
106
  updateField('clickCount', 0);
@@ -191,9 +197,9 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
191
197
  <div
192
198
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
193
199
  style={previewContentStyle}
194
- data-wp-on--click={isPreviewing ? 'actions.handleClick' : undefined}
195
- data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
196
- data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
200
+ data-wp-on--click={isPreviewing ? {{slugCamelCase}}Store.directive.action('handleClick') : undefined}
201
+ data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
202
+ data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
197
203
  >
198
204
  <RichText
199
205
  tagName="p"
@@ -222,7 +228,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
222
228
  </span>
223
229
  <span
224
230
  className="{{cssClassName}}__counter-value"
225
- data-wp-text="state.clicks"
231
+ data-wp-text={clicksDirective}
226
232
  >
227
233
  {clickCount}
228
234
  </span>
@@ -234,7 +240,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
234
240
  <div
235
241
  className="{{cssClassName}}__progress-bar"
236
242
  style={progressBarStyle}
237
- data-wp-style--width="state.progress + '%'"
243
+ data-wp-style--width={progressDirective}
238
244
  />
239
245
  </div>
240
246
  )}
@@ -242,7 +248,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
242
248
  {animation !== 'none' && (
243
249
  <div
244
250
  className={\`{{cssClassName}}__animation \${isAnimating ? 'is-active' : ''}\`}
245
- data-wp-class--is-active="state.isAnimating"
251
+ data-wp-class--is-active={isAnimatingDirective}
246
252
  >
247
253
  {animation}
248
254
  </div>
@@ -255,6 +261,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
255
261
  `;
256
262
  export const INTERACTIVITY_SAVE_TEMPLATE = `import { useBlockProps, RichText } from '@wordpress/block-editor';
257
263
  import { __ } from '@wordpress/i18n';
264
+ import { {{slugCamelCase}}Store } from './interactivity-store';
258
265
  import type { {{pascalCase}}Attributes } from './types';
259
266
 
260
267
  export default function Save({ attributes }: { attributes: {{pascalCase}}Attributes }) {
@@ -266,27 +273,41 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
266
273
  const maxClicks = attributes.maxClicks ?? 0;
267
274
  const showCounter = attributes.showCounter ?? true;
268
275
  const contentStyle = { textAlign: attributes.alignment };
276
+ const clickActionDirective = {{slugCamelCase}}Store.directive.action('handleClick');
277
+ const visibilityHiddenDirective = {{slugCamelCase}}Store.directive.negate(
278
+ {{slugCamelCase}}Store.directive.state('isVisible')
279
+ );
280
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
281
+ const clampedClicksDirective = {{slugCamelCase}}Store.directive.state('clampedClicks');
282
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
283
+ const completionHiddenDirective = {{slugCamelCase}}Store.directive.negate(
284
+ {{slugCamelCase}}Store.directive.state('isComplete')
285
+ );
286
+ const resetActionDirective = {{slugCamelCase}}Store.directive.action('reset');
269
287
  const blockProps = useBlockProps.save({
270
288
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
271
- 'data-wp-interactive': '{{slugKebabCase}}',
272
- 'data-wp-context': JSON.stringify({
273
- clicks: clickCount,
274
- isAnimating,
275
- isVisible,
276
- animation,
277
- maxClicks,
278
- })
289
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
290
+ 'data-wp-context': JSON.stringify(
291
+ {{slugCamelCase}}Store.createContext({
292
+ clicks: clickCount,
293
+ isAnimating,
294
+ isVisible,
295
+ animation,
296
+ maxClicks,
297
+ })
298
+ )
279
299
  });
300
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
280
301
 
281
302
  return (
282
303
  <div {...blockProps}>
283
304
  <div
284
305
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
285
306
  style={contentStyle}
286
- data-wp-on--click="actions.handleClick"
287
- data-wp-on--mouseenter={interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
288
- data-wp-on--mouseleave={interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
289
- data-wp-bind--hidden="!state.isVisible"
307
+ data-wp-on--click={clickActionDirective}
308
+ data-wp-on--mouseenter={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
309
+ data-wp-on--mouseleave={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
310
+ data-wp-bind--hidden={visibilityHiddenDirective}
290
311
  >
291
312
  <RichText.Content
292
313
  tagName="p"
@@ -306,7 +327,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
306
327
  </span>
307
328
  <span
308
329
  className="{{cssClassName}}__counter-value"
309
- data-wp-text="state.clicks"
330
+ data-wp-text={clicksDirective}
310
331
  >
311
332
  {clickCount}
312
333
  </span>
@@ -322,8 +343,8 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
322
343
  aria-valuemin={0}
323
344
  aria-valuemax={maxClicks}
324
345
  aria-valuenow={Math.min(clickCount, maxClicks)}
325
- data-wp-bind--aria-valuenow="state.clampedClicks"
326
- data-wp-style--width="state.progress + '%'"
346
+ data-wp-bind--aria-valuenow={clampedClicksDirective}
347
+ data-wp-style--width={progressDirective}
327
348
  />
328
349
  </div>
329
350
  )}
@@ -331,7 +352,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
331
352
  <div
332
353
  className={\`{{cssClassName}}__animation \${animation}\`}
333
354
  aria-hidden="true"
334
- data-wp-class--is-active="state.isAnimating"
355
+ data-wp-class--is-active={isAnimatingDirective}
335
356
  />
336
357
 
337
358
  {maxClicks > 0 && (
@@ -340,7 +361,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
340
361
  role="status"
341
362
  aria-live="polite"
342
363
  aria-atomic="true"
343
- data-wp-bind--hidden="!state.isComplete"
364
+ data-wp-bind--hidden={completionHiddenDirective}
344
365
  >
345
366
  { __( '🎉 Complete!', '{{textDomain}}' ) }
346
367
  </div>
@@ -348,7 +369,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
348
369
 
349
370
  <button
350
371
  className="{{cssClassName}}__reset"
351
- data-wp-on--click="actions.reset"
372
+ data-wp-on--click={resetActionDirective}
352
373
  aria-label={ __( 'Reset counter', '{{textDomain}}' ) }
353
374
  >
354
375
  <span aria-hidden="true">↻</span>
@@ -398,20 +419,214 @@ const registration = buildScaffoldBlockRegistration(
398
419
 
399
420
  registerScaffoldBlockType(registration.name, registration.settings);
400
421
  `;
422
+ export const INTERACTIVITY_STORE_TEMPLATE = `import type {
423
+ {{pascalCase}}Context,
424
+ {{pascalCase}}State,
425
+ } from './types';
426
+
427
+ type InteractivityActionShape = object;
428
+ type InteractivityCallbackShape = object;
429
+ type InteractivityContextShape = object;
430
+ type InteractivityStateShape = object;
431
+ type InteractivityCallable = Function;
432
+ type InteractivityKey<T extends object> = Extract<keyof T, string>;
433
+ type InteractivityMethodKey<T extends object> = {
434
+ [Key in InteractivityKey<T>]: T[Key] extends InteractivityCallable ? Key : never;
435
+ }[InteractivityKey<T>];
436
+
437
+ type InteractivityDirectivePath<
438
+ Root extends string,
439
+ Key extends string,
440
+ > = \`\${Root}.\${Key}\`;
441
+
442
+ type NegatedInteractivityDirectivePath<Path extends string> = \`!\${Path}\`;
443
+
444
+ export interface TypedInteractivityDirectiveHelpers<
445
+ State extends InteractivityStateShape,
446
+ Context extends InteractivityContextShape,
447
+ Actions extends InteractivityActionShape,
448
+ Callbacks extends InteractivityCallbackShape,
449
+ Namespace extends string,
450
+ > {
451
+ readonly interactive: Namespace;
452
+ action<Key extends InteractivityMethodKey<Actions>>(
453
+ key: Key,
454
+ ): InteractivityDirectivePath<'actions', Key>;
455
+ callback<Key extends InteractivityMethodKey<Callbacks>>(
456
+ key: Key,
457
+ ): InteractivityDirectivePath<'callbacks', Key>;
458
+ state<Key extends InteractivityKey<State>>(
459
+ key: Key,
460
+ ): InteractivityDirectivePath<'state', Key>;
461
+ context<Key extends InteractivityKey<Context>>(
462
+ key: Key,
463
+ ): InteractivityDirectivePath<'context', Key>;
464
+ negate<Path extends string>(
465
+ path: Path,
466
+ ): NegatedInteractivityDirectivePath<Path>;
467
+ }
468
+
469
+ export interface TypedInteractivityStore<
470
+ Namespace extends string,
471
+ State extends InteractivityStateShape,
472
+ Context extends InteractivityContextShape,
473
+ Actions extends InteractivityActionShape,
474
+ Callbacks extends InteractivityCallbackShape,
475
+ > {
476
+ readonly namespace: Namespace;
477
+ readonly state: State;
478
+ readonly context: Context;
479
+ readonly actions: Actions;
480
+ readonly callbacks: Callbacks;
481
+ readonly directive: TypedInteractivityDirectiveHelpers<
482
+ State,
483
+ Context,
484
+ Actions,
485
+ Callbacks,
486
+ Namespace
487
+ >;
488
+ createContext(value: Context): Context;
489
+ }
490
+
491
+ export function defineInteractivityStore<
492
+ Namespace extends string,
493
+ State extends InteractivityStateShape,
494
+ Context extends InteractivityContextShape,
495
+ Actions extends InteractivityActionShape,
496
+ Callbacks extends InteractivityCallbackShape,
497
+ >(config: {
498
+ readonly namespace: Namespace;
499
+ readonly state: State;
500
+ readonly context: Context;
501
+ readonly actions: Actions;
502
+ readonly callbacks: Callbacks;
503
+ }): TypedInteractivityStore<Namespace, State, Context, Actions, Callbacks> {
504
+ return {
505
+ namespace: config.namespace,
506
+ state: config.state,
507
+ context: config.context,
508
+ actions: config.actions,
509
+ callbacks: config.callbacks,
510
+ directive: {
511
+ interactive: config.namespace,
512
+ action<Key extends InteractivityMethodKey<Actions>>(key: Key) {
513
+ return \`actions.\${key}\` as InteractivityDirectivePath<'actions', Key>;
514
+ },
515
+ callback<Key extends InteractivityMethodKey<Callbacks>>(key: Key) {
516
+ return \`callbacks.\${key}\` as InteractivityDirectivePath<'callbacks', Key>;
517
+ },
518
+ state<Key extends InteractivityKey<State>>(key: Key) {
519
+ return \`state.\${key}\` as InteractivityDirectivePath<'state', Key>;
520
+ },
521
+ context<Key extends InteractivityKey<Context>>(key: Key) {
522
+ return \`context.\${key}\` as InteractivityDirectivePath<'context', Key>;
523
+ },
524
+ negate<Path extends string>(path: Path) {
525
+ return \`!\${path}\` as NegatedInteractivityDirectivePath<Path>;
526
+ },
527
+ },
528
+ createContext(value) {
529
+ return value;
530
+ },
531
+ };
532
+ }
533
+
534
+ type InteractivityActionHandler = Function;
535
+
536
+ export interface {{pascalCase}}StoreActions {
537
+ handleClick: InteractivityActionHandler;
538
+ handleMouseEnter: InteractivityActionHandler;
539
+ handleMouseLeave: InteractivityActionHandler;
540
+ reset: InteractivityActionHandler;
541
+ }
542
+
543
+ export interface {{pascalCase}}StoreCallbacks {}
544
+
545
+ export const {{slugCamelCase}}Store = defineInteractivityStore({
546
+ namespace: '{{slugKebabCase}}',
547
+ state: {} as {{pascalCase}}State,
548
+ context: {} as {{pascalCase}}Context,
549
+ actions: {} as {{pascalCase}}StoreActions,
550
+ callbacks: {} as {{pascalCase}}StoreCallbacks,
551
+ });
552
+ `;
401
553
  export const INTERACTIVITY_SCRIPT_TEMPLATE = `/**
402
554
  * WordPress Interactivity API implementation for {{title}} block
403
555
  */
404
556
  import { store, getContext, getElement, withSyncEvent } from '@wordpress/interactivity';
405
- import type { {{pascalCase}}Context } from './types';
557
+ import {
558
+ {{slugCamelCase}}Store,
559
+ type {{pascalCase}}StoreActions,
560
+ } from './interactivity-store';
561
+ import type { {{pascalCase}}Context, {{pascalCase}}State } from './types';
406
562
 
407
563
  function getBlockContext() {
408
564
  return getContext<{{pascalCase}}Context>();
409
565
  }
410
566
 
411
- // Store configuration
412
- store('{{slugKebabCase}}', {
413
- // State - reactive data that updates the UI
414
- state: {
567
+ const actions: {{pascalCase}}StoreActions = {
568
+ // Handle block click
569
+ handleClick: () => {
570
+ const context = getBlockContext();
571
+ const { ref } = getElement();
572
+
573
+ if (!ref) {
574
+ return;
575
+ }
576
+
577
+ if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
578
+ return;
579
+ }
580
+
581
+ const previousClicks = context.clicks;
582
+
583
+ // Increment click counter
584
+ context.clicks += 1;
585
+
586
+ // Trigger animation
587
+ if (context.animation !== 'none') {
588
+ context.isAnimating = true;
589
+ setTimeout(() => {
590
+ context.isAnimating = false;
591
+ }, 1000);
592
+ }
593
+
594
+ // Emit custom event
595
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
596
+ detail: { clicks: context.clicks }
597
+ }));
598
+
599
+ // Check if max clicks reached
600
+ if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
601
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
602
+ detail: { totalClicks: context.clicks }
603
+ }));
604
+ }
605
+ },
606
+
607
+ // Handle hover events
608
+ handleMouseEnter: () => {
609
+ const context = getBlockContext();
610
+ if (context.animation === 'none') return;
611
+ context.isAnimating = true;
612
+ },
613
+
614
+ handleMouseLeave: () => {
615
+ const context = getBlockContext();
616
+ if (context.animation === 'none') return;
617
+ context.isAnimating = false;
618
+ },
619
+
620
+ // Reset counter
621
+ reset: withSyncEvent((event: Event) => {
622
+ event.stopPropagation();
623
+ const context = getBlockContext();
624
+ context.clicks = 0;
625
+ context.isAnimating = false;
626
+ })
627
+ };
628
+
629
+ const state = {
415
630
  get clicks() {
416
631
  return getBlockContext().clicks;
417
632
  },
@@ -439,70 +654,14 @@ store('{{slugKebabCase}}', {
439
654
  const context = getBlockContext();
440
655
  return context.clicks >= context.maxClicks && context.maxClicks > 0;
441
656
  }
442
- },
443
-
444
- // Actions - user interactions
445
- actions: {
446
- // Handle block click
447
- handleClick: () => {
448
- const context = getBlockContext();
449
- const { ref } = getElement();
450
-
451
- if (!ref) {
452
- return;
453
- }
454
-
455
- if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
456
- return;
457
- }
458
-
459
- const previousClicks = context.clicks;
460
-
461
- // Increment click counter
462
- context.clicks += 1;
657
+ } satisfies {{pascalCase}}State;
463
658
 
464
- // Trigger animation
465
- if (context.animation !== 'none') {
466
- context.isAnimating = true;
467
- setTimeout(() => {
468
- context.isAnimating = false;
469
- }, 1000);
470
- }
471
-
472
- // Emit custom event
473
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
474
- detail: { clicks: context.clicks }
475
- }));
476
-
477
- // Check if max clicks reached
478
- if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
479
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
480
- detail: { totalClicks: context.clicks }
481
- }));
482
- }
483
- },
484
-
485
- // Handle hover events
486
- handleMouseEnter: () => {
487
- const context = getBlockContext();
488
- if (context.animation === 'none') return;
489
- context.isAnimating = true;
490
- },
491
-
492
- handleMouseLeave: () => {
493
- const context = getBlockContext();
494
- if (context.animation === 'none') return;
495
- context.isAnimating = false;
496
- },
497
-
498
- // Reset counter
499
- reset: withSyncEvent((event: Event) => {
500
- event.stopPropagation();
501
- const context = getBlockContext();
502
- context.clicks = 0;
503
- context.isAnimating = false;
504
- })
505
- }
659
+ // Store configuration
660
+ store({{slugCamelCase}}Store.namespace, {
661
+ // State - reactive data that updates the UI
662
+ state,
663
+ actions,
664
+ callbacks: {{slugCamelCase}}Store.callbacks,
506
665
  });
507
666
  `;
508
667
  export const INTERACTIVITY_VALIDATORS_TEMPLATE = `import typia from 'typia';
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates/shared.js";
6
6
  export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
7
- export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
7
+ export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_STORE_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
8
8
  export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
9
9
  export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
10
10
  export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates/shared.js";
6
6
  export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
7
- export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
7
+ export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_STORE_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
8
8
  export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
9
9
  export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
10
10
  export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
@@ -5,7 +5,7 @@ export { normalizeBlockSlug, } from "./scaffold-identifiers.js";
5
5
  /**
6
6
  * Supported top-level `wp-typia add` kinds exposed by the canonical CLI.
7
7
  */
8
- export declare const ADD_KIND_IDS: readonly ["block", "variation", "pattern", "binding-source", "rest-resource", "ability", "ai-feature", "hooked-block", "editor-plugin"];
8
+ export declare const ADD_KIND_IDS: readonly ["admin-view", "block", "variation", "style", "transform", "pattern", "binding-source", "rest-resource", "ability", "ai-feature", "hooked-block", "editor-plugin"];
9
9
  export type AddKindId = (typeof ADD_KIND_IDS)[number];
10
10
  /**
11
11
  * Supported plugin-level REST resource methods accepted by
@@ -14,10 +14,18 @@ export type AddKindId = (typeof ADD_KIND_IDS)[number];
14
14
  export declare const REST_RESOURCE_METHOD_IDS: readonly ["list", "read", "create", "update", "delete"];
15
15
  export type RestResourceMethodId = (typeof REST_RESOURCE_METHOD_IDS)[number];
16
16
  /**
17
- * Supported editor-plugin shell slots accepted by `wp-typia add editor-plugin --slot`.
17
+ * Supported editor-plugin shell surfaces accepted by
18
+ * `wp-typia add editor-plugin --slot`.
18
19
  */
19
- export declare const EDITOR_PLUGIN_SLOT_IDS: readonly ["PluginSidebar"];
20
+ export declare const EDITOR_PLUGIN_SLOT_IDS: readonly ["sidebar", "document-setting-panel"];
20
21
  export type EditorPluginSlotId = (typeof EDITOR_PLUGIN_SLOT_IDS)[number];
22
+ export declare const EDITOR_PLUGIN_SLOT_ALIASES: {
23
+ readonly PluginDocumentSettingPanel: "document-setting-panel";
24
+ readonly PluginSidebar: "sidebar";
25
+ readonly "document-setting-panel": "document-setting-panel";
26
+ readonly sidebar: "sidebar";
27
+ };
28
+ export declare function resolveEditorPluginSlotAlias(slot: string): EditorPluginSlotId | undefined;
21
29
  /**
22
30
  * Supported built-in block families accepted by `wp-typia add block --template`.
23
31
  */
@@ -29,11 +37,45 @@ export interface RunAddVariationCommandOptions {
29
37
  cwd?: string;
30
38
  variationName: string;
31
39
  }
40
+ /**
41
+ * Options for `wp-typia add style`.
42
+ *
43
+ * @property blockName Existing workspace block slug that owns the style.
44
+ * @property cwd Working directory used to resolve the nearest official workspace.
45
+ * Defaults to `process.cwd()`.
46
+ * @property styleName Human-entered style name that will be normalized into the
47
+ * generated style slug.
48
+ */
49
+ export interface RunAddBlockStyleCommandOptions {
50
+ blockName: string;
51
+ cwd?: string;
52
+ styleName: string;
53
+ }
54
+ /**
55
+ * Options for `wp-typia add transform`.
56
+ *
57
+ * @property cwd Working directory used to resolve the nearest official workspace.
58
+ * Defaults to `process.cwd()`.
59
+ * @property fromBlockName Full `namespace/block` source block name accepted by
60
+ * WordPress block transform definitions.
61
+ * @property toBlockName Existing workspace block slug or full block name that
62
+ * owns the generated transform.
63
+ * @property transformName Human-entered transform name that will be normalized
64
+ * into the generated transform slug.
65
+ */
66
+ export interface RunAddBlockTransformCommandOptions {
67
+ cwd?: string;
68
+ fromBlockName: string;
69
+ toBlockName: string;
70
+ transformName: string;
71
+ }
32
72
  export interface RunAddPatternCommandOptions {
33
73
  cwd?: string;
34
74
  patternName: string;
35
75
  }
36
76
  export interface RunAddBindingSourceCommandOptions {
77
+ attributeName?: string;
78
+ blockName?: string;
37
79
  bindingSourceName: string;
38
80
  cwd?: string;
39
81
  }
@@ -43,6 +85,23 @@ export interface RunAddRestResourceCommandOptions {
43
85
  namespace?: string;
44
86
  restResourceName: string;
45
87
  }
88
+ /**
89
+ * Options for `wp-typia add admin-view`.
90
+ *
91
+ * @property adminViewName Human-entered admin screen name that will be
92
+ * normalized into the generated slug.
93
+ * @property cwd Working directory used to resolve the nearest official workspace.
94
+ * Defaults to `process.cwd()`.
95
+ * @property source Optional data source locator. `rest-resource:<slug>` wires
96
+ * the generated screen to an existing list-capable REST resource.
97
+ * `core-data:<kind>/<name>` binds the screen to a supported WordPress-owned
98
+ * entity collection such as `core-data:postType/post`.
99
+ */
100
+ export interface RunAddAdminViewCommandOptions {
101
+ adminViewName: string;
102
+ cwd?: string;
103
+ source?: string;
104
+ }
46
105
  /**
47
106
  * Options for `wp-typia add ability`.
48
107
  *
@@ -73,7 +132,7 @@ export interface RunAddHookedBlockCommandOptions {
73
132
  * Defaults to `process.cwd()`.
74
133
  * @property editorPluginName Human-entered editor plugin name that will be
75
134
  * normalized into the generated slug.
76
- * @property slot Optional editor shell slot. Defaults to `PluginSidebar`.
135
+ * @property slot Optional editor shell slot. Defaults to `sidebar`.
77
136
  */
78
137
  export interface RunAddEditorPluginCommandOptions {
79
138
  cwd?: string;
@@ -143,7 +202,7 @@ export declare function assertValidHookAnchor(anchorBlockName: string): string;
143
202
  /**
144
203
  * Validate and normalize the editor plugin shell slot.
145
204
  *
146
- * @param slot Optional shell slot. Defaults to `PluginSidebar`.
205
+ * @param slot Optional shell slot. Defaults to `sidebar`.
147
206
  * @returns The canonical editor plugin slot id.
148
207
  * @throws {Error} When the slot is not supported by the workspace scaffold.
149
208
  */
@@ -157,6 +216,16 @@ export declare function assertVariationDoesNotExist(projectDir: string, blockSlu
157
216
  export declare function assertPatternDoesNotExist(projectDir: string, patternSlug: string, inventory: WorkspaceInventory): void;
158
217
  export declare function assertBindingSourceDoesNotExist(projectDir: string, bindingSourceSlug: string, inventory: WorkspaceInventory): void;
159
218
  export declare function assertRestResourceDoesNotExist(projectDir: string, restResourceSlug: string, inventory: WorkspaceInventory): void;
219
+ /**
220
+ * Ensure a DataViews admin screen scaffold does not already exist on disk or in
221
+ * the workspace inventory.
222
+ *
223
+ * @param projectDir Workspace root directory.
224
+ * @param adminViewSlug Normalized admin screen slug.
225
+ * @param inventory Parsed workspace inventory.
226
+ * @throws {Error} When the directory, PHP bootstrap, or inventory entry already exists.
227
+ */
228
+ export declare function assertAdminViewDoesNotExist(projectDir: string, adminViewSlug: string, inventory: WorkspaceInventory): void;
160
229
  /**
161
230
  * Ensure a workflow ability scaffold does not already exist on disk or in the
162
231
  * workspace inventory.