@bettercms-ai/sdk 1.31.0 → 1.32.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.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _bettercms_ai_types from '@bettercms-ai/types';
2
- import { ContentPageResult, Content, DeliveredLayout, ContentModelField, Fieldset, BetterCMSErrorCode, ComponentPreview, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, FormField, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
2
+ import { ContentPageResult, Content, DeliveredLayout, ContentModelField, Fieldset, ComponentPreview, BetterCMSErrorCode, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, FormField, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
3
3
  export { ApiError, ApiKey, ApiKeyPermission, ApiKeyTokenType, AssertEqual, AuthSession, AuthUser, BetterCMSErrorCode, BlockType, ButtonBlock, ButtonProps, ColumnsBlock, ColumnsProps, Content, ContentBlock, ContentEntry, ContentModel, ContentModelField, ContentPageResult, ContentResponse, DeepReadonly, DeliveryComponent, DeliveryEntry, DeliveryList, DeliveryPage, Form, FormBlock, FormField, FormProps, FormSubmission, HeadingBlock, HeadingProps, ImageBlock, ImageProps, MediaAsset, Page, PageMetaJson, PaginatedResult, Perspective, Redirect, SignInInput, SignUpInput, SiteSeoDefaults, SpacerBlock, SpacerProps, TextBlock, TextProps, VideoBlock, VideoProps, Workspace, getBlockType, isBlock } from '@bettercms-ai/types';
4
4
  export { ImageFit, ImageFormat, ImageSource, ImageUrlBuilder, ImageUrlOptions, imageUrl, default as imageUrlBuilder, imageValueObjectPosition, imageValueUrl } from '@bettercms-ai/image-url';
5
5
 
@@ -387,6 +387,159 @@ declare function updateEntry(client: ManagementClient, id: string, input: Update
387
387
  ifMatch?: number;
388
388
  }): Promise<ManagedContentEntry & EntryWriteWarnings>;
389
389
 
390
+ /**
391
+ * Management API SDK methods — reusable components (discover + author).
392
+ *
393
+ * Call /api/v1/management/components (key-auth, content:manage). The MCP server wraps
394
+ * these so an agent can list/read components and author new ones (blockJson + props).
395
+ */
396
+
397
+ /** A component as returned by the Management API (render + author shape). */
398
+ interface ManagedComponent {
399
+ id: string;
400
+ projectId: string | null;
401
+ allowedOn: string[];
402
+ name: string;
403
+ slug: string;
404
+ category: string;
405
+ description: string | null;
406
+ blockJson: unknown[];
407
+ props: unknown[];
408
+ variantGroupId?: string | null;
409
+ publishedVariantGroupId?: string | null;
410
+ variantInputMappings?: Array<{
411
+ inputId: string;
412
+ targets: Array<{
413
+ blockId: string;
414
+ path: string;
415
+ }>;
416
+ }>;
417
+ publishedVariantInputMappings?: Array<{
418
+ inputId: string;
419
+ targets: Array<{
420
+ blockId: string;
421
+ path: string;
422
+ }>;
423
+ }> | null;
424
+ thumbnail?: string | null;
425
+ /** How an instance reads as a row in a parent's slot list. @see ComponentPreview */
426
+ preview?: ComponentPreview | null;
427
+ /** The block icon (a /kit schema's document-level `icon`), a dock icon name. */
428
+ icon?: string | null;
429
+ /** The /kit tabs no top-level prop sits in (declared, empty). @see ComponentTab */
430
+ tabs?: Array<{
431
+ id: string;
432
+ label: string;
433
+ icon?: string;
434
+ order?: number;
435
+ }> | null;
436
+ /** The bettercms://kit entry its V2 dock UI was built from (a kit-catalog id), or null. */
437
+ kitEntry?: string | null;
438
+ /** Send it back as `ifMatch` on updateComponent. */
439
+ optimisticVersion?: number;
440
+ }
441
+ /** Create/update input. `blockJson` is the ContentBlock tree; `props` the override allowlist. */
442
+ interface ManagedComponentInput {
443
+ projectId?: string | null;
444
+ allowedOn?: string[];
445
+ name?: string;
446
+ slug?: string;
447
+ category?: string;
448
+ sectionType?: string | null;
449
+ /**
450
+ * The organisational Group, by NAME. The API resolves it against the project's Groups and
451
+ * creates it when missing — a caller filing a whole site's components into folders has a name
452
+ * ("Sections"), never an id.
453
+ */
454
+ group?: string;
455
+ groupId?: string | null;
456
+ description?: string;
457
+ /** title/subtitle/media name top-level prop keys (422 `preview_key_unknown` otherwise); null clears it. */
458
+ preview?: ComponentPreview | null;
459
+ /** The block icon, a dock icon name (bettercms://icons/dock); null clears it. */
460
+ icon?: string | null;
461
+ /** /kit tabs no top-level prop sits in; null clears them (422 component_tab_invalid on a prop's own tab). */
462
+ tabs?: Array<{
463
+ id: string;
464
+ label: string;
465
+ icon?: string;
466
+ order?: number;
467
+ }> | null;
468
+ /** The bettercms://kit entry its V2 dock UI follows (an id from bettercms://kit); null clears it. 422 `kit_entry_unknown` for an id not in the catalogue. */
469
+ kitEntry?: string | null;
470
+ blockJson?: unknown[];
471
+ props?: unknown[];
472
+ /**
473
+ * Make this a VARIANT of that component (id or slug, same project): it joins that component's
474
+ * variant family, which is started from it when it has none.
475
+ */
476
+ variantOf?: string;
477
+ /** Create only: a built-in section id (`builtin:<key>`) to copy in; the fields you send win. */
478
+ from?: string;
479
+ /** Update only: prop chrome by prop path (`cta.label`). Any of these, or `override`, needs `ifMatch`. */
480
+ propUi?: Record<string, Record<string, unknown> | null>;
481
+ propGroup?: Record<string, Record<string, unknown> | null>;
482
+ propTab?: Record<string, Record<string, unknown> | null>;
483
+ propLabel?: Record<string, string>;
484
+ /** Replace chrome a person shaped; without it that is a 409 `ui_human_owned`. */
485
+ override?: boolean;
486
+ }
487
+ /**
488
+ * The catalogue shape: what each component IS, without its block trees.
489
+ *
490
+ * The default list carries every component's draft AND live `blockJson`, which on a
491
+ * componentized site is the largest response this API produces — and a caller asking which
492
+ * components exist wants none of it. This shape also carries `sectionType`, `status` and the
493
+ * Group, the three facts that decide whether a component is insertable, whether it is on the
494
+ * live site, and where an editor finds it.
495
+ */
496
+ interface ManagedComponentSummary {
497
+ id: string;
498
+ projectId: string | null;
499
+ name: string;
500
+ slug: string;
501
+ category: string;
502
+ sectionType: string | null;
503
+ status: string | null;
504
+ groupId: string | null;
505
+ groupName: string | null;
506
+ updatedAt: string | null;
507
+ builtin?: boolean;
508
+ }
509
+ /**
510
+ * A set of sections that repeat across the project's pages, proposed as one component.
511
+ * Derived per request from the pages' DRAFT blocks — never stored.
512
+ */
513
+ interface ExtractionCandidate {
514
+ /** Identifies the shape. Pass it back to `extractComponent`; it is re-verified server-side. */
515
+ hash: string;
516
+ blockType: string;
517
+ uses: number;
518
+ suggestedName: string;
519
+ blockJson: unknown[];
520
+ /** The leaves that differ between copies, which become the component's editable props. */
521
+ props: unknown[];
522
+ sites: {
523
+ pageId: string;
524
+ title: string;
525
+ slug: string;
526
+ blockId: string;
527
+ overrides: Record<string, unknown>;
528
+ }[];
529
+ }
530
+ /**
531
+ * Create the component from one candidate and repoint every occurrence at it.
532
+ *
533
+ * Rewrites page DRAFTS on several pages at once. `hash` is re-verified against a fresh scan,
534
+ * so a proposal that went stale 409s rather than applying against pages that have moved on.
535
+ */
536
+ /** The bettercms://kit entry an extracted component records: `link` is its resource, or bettercms://kit when none fits. */
537
+ interface ExtractedKit {
538
+ kitEntry: string | null;
539
+ score: number | null;
540
+ link: string;
541
+ }
542
+
390
543
  /**
391
544
  * Management API SDK method — media upload (P2).
392
545
  *
@@ -731,129 +884,6 @@ interface ManagedFormInput {
731
884
  notifyEmails?: string[];
732
885
  }
733
886
 
734
- /**
735
- * Management API SDK methods — reusable components (discover + author).
736
- *
737
- * Call /api/v1/management/components (key-auth, content:manage). The MCP server wraps
738
- * these so an agent can list/read components and author new ones (blockJson + props).
739
- */
740
-
741
- /** A component as returned by the Management API (render + author shape). */
742
- interface ManagedComponent {
743
- id: string;
744
- projectId: string | null;
745
- allowedOn: string[];
746
- name: string;
747
- slug: string;
748
- category: string;
749
- description: string | null;
750
- blockJson: unknown[];
751
- props: unknown[];
752
- variantGroupId?: string | null;
753
- publishedVariantGroupId?: string | null;
754
- variantInputMappings?: Array<{
755
- inputId: string;
756
- targets: Array<{
757
- blockId: string;
758
- path: string;
759
- }>;
760
- }>;
761
- publishedVariantInputMappings?: Array<{
762
- inputId: string;
763
- targets: Array<{
764
- blockId: string;
765
- path: string;
766
- }>;
767
- }> | null;
768
- thumbnail?: string | null;
769
- /** How an instance reads as a row in a parent's slot list. @see ComponentPreview */
770
- preview?: ComponentPreview | null;
771
- /** The block icon (a /kit schema's document-level `icon`), a dock icon name. */
772
- icon?: string | null;
773
- /** Send it back as `ifMatch` on updateComponent. */
774
- optimisticVersion?: number;
775
- }
776
- /** Create/update input. `blockJson` is the ContentBlock tree; `props` the override allowlist. */
777
- interface ManagedComponentInput {
778
- projectId?: string | null;
779
- allowedOn?: string[];
780
- name?: string;
781
- slug?: string;
782
- category?: string;
783
- sectionType?: string | null;
784
- /**
785
- * The organisational Group, by NAME. The API resolves it against the project's Groups and
786
- * creates it when missing — a caller filing a whole site's components into folders has a name
787
- * ("Sections"), never an id.
788
- */
789
- group?: string;
790
- groupId?: string | null;
791
- description?: string;
792
- /** title/subtitle/media name top-level prop keys (422 `preview_key_unknown` otherwise); null clears it. */
793
- preview?: ComponentPreview | null;
794
- /** The block icon, a dock icon name (bettercms://icons/dock); null clears it. */
795
- icon?: string | null;
796
- blockJson?: unknown[];
797
- props?: unknown[];
798
- /**
799
- * Make this a VARIANT of that component (id or slug, same project): it joins that component's
800
- * variant family, which is started from it when it has none.
801
- */
802
- variantOf?: string;
803
- /** Create only: a built-in section id (`builtin:<key>`) to copy in; the fields you send win. */
804
- from?: string;
805
- /** Update only: prop chrome by prop path (`cta.label`). Any of these, or `override`, needs `ifMatch`. */
806
- propUi?: Record<string, Record<string, unknown> | null>;
807
- propGroup?: Record<string, Record<string, unknown> | null>;
808
- propTab?: Record<string, Record<string, unknown> | null>;
809
- propLabel?: Record<string, string>;
810
- /** Replace chrome a person shaped; without it that is a 409 `ui_human_owned`. */
811
- override?: boolean;
812
- }
813
- /**
814
- * The catalogue shape: what each component IS, without its block trees.
815
- *
816
- * The default list carries every component's draft AND live `blockJson`, which on a
817
- * componentized site is the largest response this API produces — and a caller asking which
818
- * components exist wants none of it. This shape also carries `sectionType`, `status` and the
819
- * Group, the three facts that decide whether a component is insertable, whether it is on the
820
- * live site, and where an editor finds it.
821
- */
822
- interface ManagedComponentSummary {
823
- id: string;
824
- projectId: string | null;
825
- name: string;
826
- slug: string;
827
- category: string;
828
- sectionType: string | null;
829
- status: string | null;
830
- groupId: string | null;
831
- groupName: string | null;
832
- updatedAt: string | null;
833
- builtin?: boolean;
834
- }
835
- /**
836
- * A set of sections that repeat across the project's pages, proposed as one component.
837
- * Derived per request from the pages' DRAFT blocks — never stored.
838
- */
839
- interface ExtractionCandidate {
840
- /** Identifies the shape. Pass it back to `extractComponent`; it is re-verified server-side. */
841
- hash: string;
842
- blockType: string;
843
- uses: number;
844
- suggestedName: string;
845
- blockJson: unknown[];
846
- /** The leaves that differ between copies, which become the component's editable props. */
847
- props: unknown[];
848
- sites: {
849
- pageId: string;
850
- title: string;
851
- slug: string;
852
- blockId: string;
853
- overrides: Record<string, unknown>;
854
- }[];
855
- }
856
-
857
887
  /**
858
888
  * Management API SDK methods — AI content + SEO actions (Option B, portable skill).
859
889
  *
@@ -1036,6 +1066,7 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
1036
1066
  }): Promise<{
1037
1067
  component: ManagedComponent;
1038
1068
  replaced: number;
1069
+ kit?: ExtractedKit;
1039
1070
  }>;
1040
1071
  getManagedLayout(opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
1041
1072
  commandManagedLayout(input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _bettercms_ai_types from '@bettercms-ai/types';
2
- import { ContentPageResult, Content, DeliveredLayout, ContentModelField, Fieldset, BetterCMSErrorCode, ComponentPreview, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, FormField, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
2
+ import { ContentPageResult, Content, DeliveredLayout, ContentModelField, Fieldset, ComponentPreview, BetterCMSErrorCode, LayoutStructureDocument, LayoutDataDocument, PageLayoutOverrideDocument, ManagementLayoutCommand, AuthUser, AuthSession, SignInInput, SignUpInput, Perspective, DeliveryEntry, DeliveryList, DeliveryPage, DeliveryComponent, PageMetaJson, DeliveryEntrySeo, SiteSeoDefaults, Page, MediaAsset, FormField, Form, FormSubmission, Workspace, ApiKey, ApiKeyPermission, ApiKeyTokenType } from '@bettercms-ai/types';
3
3
  export { ApiError, ApiKey, ApiKeyPermission, ApiKeyTokenType, AssertEqual, AuthSession, AuthUser, BetterCMSErrorCode, BlockType, ButtonBlock, ButtonProps, ColumnsBlock, ColumnsProps, Content, ContentBlock, ContentEntry, ContentModel, ContentModelField, ContentPageResult, ContentResponse, DeepReadonly, DeliveryComponent, DeliveryEntry, DeliveryList, DeliveryPage, Form, FormBlock, FormField, FormProps, FormSubmission, HeadingBlock, HeadingProps, ImageBlock, ImageProps, MediaAsset, Page, PageMetaJson, PaginatedResult, Perspective, Redirect, SignInInput, SignUpInput, SiteSeoDefaults, SpacerBlock, SpacerProps, TextBlock, TextProps, VideoBlock, VideoProps, Workspace, getBlockType, isBlock } from '@bettercms-ai/types';
4
4
  export { ImageFit, ImageFormat, ImageSource, ImageUrlBuilder, ImageUrlOptions, imageUrl, default as imageUrlBuilder, imageValueObjectPosition, imageValueUrl } from '@bettercms-ai/image-url';
5
5
 
@@ -387,6 +387,159 @@ declare function updateEntry(client: ManagementClient, id: string, input: Update
387
387
  ifMatch?: number;
388
388
  }): Promise<ManagedContentEntry & EntryWriteWarnings>;
389
389
 
390
+ /**
391
+ * Management API SDK methods — reusable components (discover + author).
392
+ *
393
+ * Call /api/v1/management/components (key-auth, content:manage). The MCP server wraps
394
+ * these so an agent can list/read components and author new ones (blockJson + props).
395
+ */
396
+
397
+ /** A component as returned by the Management API (render + author shape). */
398
+ interface ManagedComponent {
399
+ id: string;
400
+ projectId: string | null;
401
+ allowedOn: string[];
402
+ name: string;
403
+ slug: string;
404
+ category: string;
405
+ description: string | null;
406
+ blockJson: unknown[];
407
+ props: unknown[];
408
+ variantGroupId?: string | null;
409
+ publishedVariantGroupId?: string | null;
410
+ variantInputMappings?: Array<{
411
+ inputId: string;
412
+ targets: Array<{
413
+ blockId: string;
414
+ path: string;
415
+ }>;
416
+ }>;
417
+ publishedVariantInputMappings?: Array<{
418
+ inputId: string;
419
+ targets: Array<{
420
+ blockId: string;
421
+ path: string;
422
+ }>;
423
+ }> | null;
424
+ thumbnail?: string | null;
425
+ /** How an instance reads as a row in a parent's slot list. @see ComponentPreview */
426
+ preview?: ComponentPreview | null;
427
+ /** The block icon (a /kit schema's document-level `icon`), a dock icon name. */
428
+ icon?: string | null;
429
+ /** The /kit tabs no top-level prop sits in (declared, empty). @see ComponentTab */
430
+ tabs?: Array<{
431
+ id: string;
432
+ label: string;
433
+ icon?: string;
434
+ order?: number;
435
+ }> | null;
436
+ /** The bettercms://kit entry its V2 dock UI was built from (a kit-catalog id), or null. */
437
+ kitEntry?: string | null;
438
+ /** Send it back as `ifMatch` on updateComponent. */
439
+ optimisticVersion?: number;
440
+ }
441
+ /** Create/update input. `blockJson` is the ContentBlock tree; `props` the override allowlist. */
442
+ interface ManagedComponentInput {
443
+ projectId?: string | null;
444
+ allowedOn?: string[];
445
+ name?: string;
446
+ slug?: string;
447
+ category?: string;
448
+ sectionType?: string | null;
449
+ /**
450
+ * The organisational Group, by NAME. The API resolves it against the project's Groups and
451
+ * creates it when missing — a caller filing a whole site's components into folders has a name
452
+ * ("Sections"), never an id.
453
+ */
454
+ group?: string;
455
+ groupId?: string | null;
456
+ description?: string;
457
+ /** title/subtitle/media name top-level prop keys (422 `preview_key_unknown` otherwise); null clears it. */
458
+ preview?: ComponentPreview | null;
459
+ /** The block icon, a dock icon name (bettercms://icons/dock); null clears it. */
460
+ icon?: string | null;
461
+ /** /kit tabs no top-level prop sits in; null clears them (422 component_tab_invalid on a prop's own tab). */
462
+ tabs?: Array<{
463
+ id: string;
464
+ label: string;
465
+ icon?: string;
466
+ order?: number;
467
+ }> | null;
468
+ /** The bettercms://kit entry its V2 dock UI follows (an id from bettercms://kit); null clears it. 422 `kit_entry_unknown` for an id not in the catalogue. */
469
+ kitEntry?: string | null;
470
+ blockJson?: unknown[];
471
+ props?: unknown[];
472
+ /**
473
+ * Make this a VARIANT of that component (id or slug, same project): it joins that component's
474
+ * variant family, which is started from it when it has none.
475
+ */
476
+ variantOf?: string;
477
+ /** Create only: a built-in section id (`builtin:<key>`) to copy in; the fields you send win. */
478
+ from?: string;
479
+ /** Update only: prop chrome by prop path (`cta.label`). Any of these, or `override`, needs `ifMatch`. */
480
+ propUi?: Record<string, Record<string, unknown> | null>;
481
+ propGroup?: Record<string, Record<string, unknown> | null>;
482
+ propTab?: Record<string, Record<string, unknown> | null>;
483
+ propLabel?: Record<string, string>;
484
+ /** Replace chrome a person shaped; without it that is a 409 `ui_human_owned`. */
485
+ override?: boolean;
486
+ }
487
+ /**
488
+ * The catalogue shape: what each component IS, without its block trees.
489
+ *
490
+ * The default list carries every component's draft AND live `blockJson`, which on a
491
+ * componentized site is the largest response this API produces — and a caller asking which
492
+ * components exist wants none of it. This shape also carries `sectionType`, `status` and the
493
+ * Group, the three facts that decide whether a component is insertable, whether it is on the
494
+ * live site, and where an editor finds it.
495
+ */
496
+ interface ManagedComponentSummary {
497
+ id: string;
498
+ projectId: string | null;
499
+ name: string;
500
+ slug: string;
501
+ category: string;
502
+ sectionType: string | null;
503
+ status: string | null;
504
+ groupId: string | null;
505
+ groupName: string | null;
506
+ updatedAt: string | null;
507
+ builtin?: boolean;
508
+ }
509
+ /**
510
+ * A set of sections that repeat across the project's pages, proposed as one component.
511
+ * Derived per request from the pages' DRAFT blocks — never stored.
512
+ */
513
+ interface ExtractionCandidate {
514
+ /** Identifies the shape. Pass it back to `extractComponent`; it is re-verified server-side. */
515
+ hash: string;
516
+ blockType: string;
517
+ uses: number;
518
+ suggestedName: string;
519
+ blockJson: unknown[];
520
+ /** The leaves that differ between copies, which become the component's editable props. */
521
+ props: unknown[];
522
+ sites: {
523
+ pageId: string;
524
+ title: string;
525
+ slug: string;
526
+ blockId: string;
527
+ overrides: Record<string, unknown>;
528
+ }[];
529
+ }
530
+ /**
531
+ * Create the component from one candidate and repoint every occurrence at it.
532
+ *
533
+ * Rewrites page DRAFTS on several pages at once. `hash` is re-verified against a fresh scan,
534
+ * so a proposal that went stale 409s rather than applying against pages that have moved on.
535
+ */
536
+ /** The bettercms://kit entry an extracted component records: `link` is its resource, or bettercms://kit when none fits. */
537
+ interface ExtractedKit {
538
+ kitEntry: string | null;
539
+ score: number | null;
540
+ link: string;
541
+ }
542
+
390
543
  /**
391
544
  * Management API SDK method — media upload (P2).
392
545
  *
@@ -731,129 +884,6 @@ interface ManagedFormInput {
731
884
  notifyEmails?: string[];
732
885
  }
733
886
 
734
- /**
735
- * Management API SDK methods — reusable components (discover + author).
736
- *
737
- * Call /api/v1/management/components (key-auth, content:manage). The MCP server wraps
738
- * these so an agent can list/read components and author new ones (blockJson + props).
739
- */
740
-
741
- /** A component as returned by the Management API (render + author shape). */
742
- interface ManagedComponent {
743
- id: string;
744
- projectId: string | null;
745
- allowedOn: string[];
746
- name: string;
747
- slug: string;
748
- category: string;
749
- description: string | null;
750
- blockJson: unknown[];
751
- props: unknown[];
752
- variantGroupId?: string | null;
753
- publishedVariantGroupId?: string | null;
754
- variantInputMappings?: Array<{
755
- inputId: string;
756
- targets: Array<{
757
- blockId: string;
758
- path: string;
759
- }>;
760
- }>;
761
- publishedVariantInputMappings?: Array<{
762
- inputId: string;
763
- targets: Array<{
764
- blockId: string;
765
- path: string;
766
- }>;
767
- }> | null;
768
- thumbnail?: string | null;
769
- /** How an instance reads as a row in a parent's slot list. @see ComponentPreview */
770
- preview?: ComponentPreview | null;
771
- /** The block icon (a /kit schema's document-level `icon`), a dock icon name. */
772
- icon?: string | null;
773
- /** Send it back as `ifMatch` on updateComponent. */
774
- optimisticVersion?: number;
775
- }
776
- /** Create/update input. `blockJson` is the ContentBlock tree; `props` the override allowlist. */
777
- interface ManagedComponentInput {
778
- projectId?: string | null;
779
- allowedOn?: string[];
780
- name?: string;
781
- slug?: string;
782
- category?: string;
783
- sectionType?: string | null;
784
- /**
785
- * The organisational Group, by NAME. The API resolves it against the project's Groups and
786
- * creates it when missing — a caller filing a whole site's components into folders has a name
787
- * ("Sections"), never an id.
788
- */
789
- group?: string;
790
- groupId?: string | null;
791
- description?: string;
792
- /** title/subtitle/media name top-level prop keys (422 `preview_key_unknown` otherwise); null clears it. */
793
- preview?: ComponentPreview | null;
794
- /** The block icon, a dock icon name (bettercms://icons/dock); null clears it. */
795
- icon?: string | null;
796
- blockJson?: unknown[];
797
- props?: unknown[];
798
- /**
799
- * Make this a VARIANT of that component (id or slug, same project): it joins that component's
800
- * variant family, which is started from it when it has none.
801
- */
802
- variantOf?: string;
803
- /** Create only: a built-in section id (`builtin:<key>`) to copy in; the fields you send win. */
804
- from?: string;
805
- /** Update only: prop chrome by prop path (`cta.label`). Any of these, or `override`, needs `ifMatch`. */
806
- propUi?: Record<string, Record<string, unknown> | null>;
807
- propGroup?: Record<string, Record<string, unknown> | null>;
808
- propTab?: Record<string, Record<string, unknown> | null>;
809
- propLabel?: Record<string, string>;
810
- /** Replace chrome a person shaped; without it that is a 409 `ui_human_owned`. */
811
- override?: boolean;
812
- }
813
- /**
814
- * The catalogue shape: what each component IS, without its block trees.
815
- *
816
- * The default list carries every component's draft AND live `blockJson`, which on a
817
- * componentized site is the largest response this API produces — and a caller asking which
818
- * components exist wants none of it. This shape also carries `sectionType`, `status` and the
819
- * Group, the three facts that decide whether a component is insertable, whether it is on the
820
- * live site, and where an editor finds it.
821
- */
822
- interface ManagedComponentSummary {
823
- id: string;
824
- projectId: string | null;
825
- name: string;
826
- slug: string;
827
- category: string;
828
- sectionType: string | null;
829
- status: string | null;
830
- groupId: string | null;
831
- groupName: string | null;
832
- updatedAt: string | null;
833
- builtin?: boolean;
834
- }
835
- /**
836
- * A set of sections that repeat across the project's pages, proposed as one component.
837
- * Derived per request from the pages' DRAFT blocks — never stored.
838
- */
839
- interface ExtractionCandidate {
840
- /** Identifies the shape. Pass it back to `extractComponent`; it is re-verified server-side. */
841
- hash: string;
842
- blockType: string;
843
- uses: number;
844
- suggestedName: string;
845
- blockJson: unknown[];
846
- /** The leaves that differ between copies, which become the component's editable props. */
847
- props: unknown[];
848
- sites: {
849
- pageId: string;
850
- title: string;
851
- slug: string;
852
- blockId: string;
853
- overrides: Record<string, unknown>;
854
- }[];
855
- }
856
-
857
887
  /**
858
888
  * Management API SDK methods — AI content + SEO actions (Option B, portable skill).
859
889
  *
@@ -1036,6 +1066,7 @@ declare class BetterCMSManagementClient extends BetterCMSDeliveryClient {
1036
1066
  }): Promise<{
1037
1067
  component: ManagedComponent;
1038
1068
  replaced: number;
1069
+ kit?: ExtractedKit;
1039
1070
  }>;
1040
1071
  getManagedLayout(opts?: GetManagedLayoutOptions): Promise<ManagedLayoutDocument>;
1041
1072
  commandManagedLayout(input: CommandManagedLayoutInput): Promise<ManagedLayoutDocument>;
package/dist/index.js CHANGED
@@ -780,7 +780,7 @@ async function extractComponent(client, input) {
780
780
  client.url("/management/components/extract"),
781
781
  { method: "POST", body: JSON.stringify(input) }
782
782
  );
783
- return { component: res.data, replaced: res.replaced };
783
+ return { component: res.data, replaced: res.replaced, ...res.kit ? { kit: res.kit } : {} };
784
784
  }
785
785
  async function updateComponent(client, id, input, opts) {
786
786
  const res = await client.fetchJSON(