@civitai/app-sdk 0.74.0 → 0.75.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.
@@ -116,7 +116,7 @@ export { isModelSlotContext, isPageSlotContext } from './types.js';
116
116
  * in `types.ts` for which of the two it uses and why.
117
117
  */
118
118
  export { isSignedIn } from './types.js';
119
- export type { BlockContext, KnownSlotId, ModelSlotId, PageSlotContext, PageSlotId, UnknownSlotContext, BlockAnalyticsDeclaration, BlockAnalyticsEventDeclaration, BlockAnalyticsPropertyDeclaration, BlockManifest, BlockManifestGood, BlockManifestV1, BlockSettings, BlockStorageCollectionDeclaration, BlockStorageDeclaration, BlockStorageIndexes, BlockStorageIndexType, BlockStoragePrivateCollectionDeclaration, BlockStorageSharedCollectionDeclaration, BlockToken, ContentRating, ManifestBooleanField, ManifestIframe, ManifestNumberField, ManifestPage, ManifestPreview, ManifestSettingField, ManifestSettings, ManifestStringField, ManifestTarget, ModelSlotContext, SettingScope, SettingWidget, Theme, ViewerInfo, BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockSourceImage, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockImagePickerSource, BlockPickedImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockTextToImageParams, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockModelSubstitution, ModelSubstitutionReason, KnownBlockWorkflowErrorCode, BlockStepToolCall, BlockTrainedEpoch, BlockPublishedModel, BuzzAccountType, ShowcaseImage, WorkflowBody, WorkflowBodyTextToImage, WorkflowBodyCustomComfy, WorkflowBodyCustomComfyRecipe, WorkflowBodyCustomComfyInline, InlineComfyNode, WorkflowBodyStep, WorkflowBodyPassThroughStep, WorkflowBodyWorkflow, WorkflowBodyWorkflowStep, WorkflowStepRef, WithWorkflowStepRefs, BlockWorkflowStepSnapshot, WorkflowStatus, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostRequest, BlockCreatePostResult, BlockCreatePostHostError, WorkflowBodyTraining, AiToolkitTrainingParams, AiToolkitTrainingParamsBase, AiToolkitPlainEcosystem, AiToolkitLrScheduler, AiToolkitOptimizerType, BlockTrainingQuote, BlockTrainingDatasetItem, BlockTrainingDatasetResult, BlockTrainingRejectionReason, BlockPrepareTrainingDatasetHostError, BlockRunTrainingHostError, BlockStepQuote, BlockModel3dOutput, BlockRunConfirmedStepHostError, } from './types.js';
119
+ export type { BlockContext, KnownSlotId, ModelSlotId, PageSlotContext, PageSlotId, UnknownSlotContext, BlockAnalyticsDeclaration, BlockAnalyticsEventDeclaration, BlockAnalyticsPropertyDeclaration, BlockManifest, BlockManifestGood, BlockManifestV1, BlockSettings, BlockStorageCollectionDeclaration, BlockStorageDeclaration, BlockStorageIndexes, BlockStorageIndexType, BlockStoragePrivateCollectionDeclaration, BlockStorageSharedCollectionDeclaration, BlockToken, ContentRating, ManifestBooleanField, ManifestIframe, ManifestNumberField, ManifestPage, ManifestPreview, ManifestSettingField, ManifestSettings, ManifestStringField, ManifestTarget, ModelSlotContext, SettingScope, SettingWidget, Theme, ViewerInfo, BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockSourceImage, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockImagePickerSource, BlockPickedImageInfo, BlockMediaKind, BlockMediaUploadInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockTextToImageParams, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockModelSubstitution, ModelSubstitutionReason, KnownBlockWorkflowErrorCode, BlockStepToolCall, BlockTrainedEpoch, BlockPublishedModel, BuzzAccountType, ShowcaseImage, WorkflowBody, WorkflowBodyTextToImage, WorkflowBodyCustomComfy, WorkflowBodyCustomComfyRecipe, WorkflowBodyCustomComfyInline, InlineComfyNode, WorkflowBodyStep, WorkflowBodyPassThroughStep, WorkflowBodyWorkflow, WorkflowBodyWorkflowStep, WorkflowStepRef, WithWorkflowStepRefs, BlockWorkflowStepSnapshot, WorkflowStatus, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, AppWorkflowImage, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostRequest, BlockCreatePostResult, BlockCreatePostHostError, WorkflowBodyTraining, AiToolkitTrainingParams, AiToolkitTrainingParamsBase, AiToolkitPlainEcosystem, AiToolkitLrScheduler, AiToolkitOptimizerType, BlockTrainingQuote, BlockTrainingDatasetItem, BlockTrainingDatasetResult, BlockTrainingRejectionReason, BlockPrepareTrainingDatasetHostError, BlockRunTrainingHostError, BlockStepQuote, BlockModel3dOutput, BlockRunConfirmedStepHostError, } from './types.js';
120
120
  /** Host bound for the App Blocks `kind: 'workflow'` body — see `WorkflowBodyWorkflow`. */
121
121
  export { BLOCK_WORKFLOW_MAX_STEPS, BLOCK_WORKFLOW_REPEAT_MAX_ITERATIONS } from './types.js';
122
122
  /**
@@ -8,7 +8,7 @@
8
8
  * Wire format: `window.postMessage({ type, payload }, targetOrigin)`.
9
9
  */
10
10
  import type { ColorDomain } from './browsingLevel.js';
11
- import type { BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockImagePickerSource, BlockPickedImageInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockContext, BlockSettings, Theme, ViewerInfo, WorkflowBody, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostResult, BlockTrainingDatasetItem, BlockTrainingDatasetResult, WorkflowBodyTraining, WorkflowBodyPassThroughStep } from './types.js';
11
+ import type { BlockCheckpointInfo, BlockResourceInfo, BlockResourcePickerType, BlockUploadedImageInfo, BlockGenerationSourceImageInfo, BlockImagePickerSource, BlockPickedImageInfo, BlockMediaKind, BlockMediaUploadInfo, BlockPendingImageInfo, BlockImageScanResult, BlockUploadPurpose, BlockNavigateScope, BlockContext, BlockSettings, Theme, ViewerInfo, WorkflowBody, BlockWorkflowSnapshot, BlockEstimateBatchAggregate, BlockBuzzTransaction, BlockBuzzAccount, BlockDailyCompensationResource, BlockViewer, BlockWildcardPack, BlockWildcardPackErrorCode, AppWorkflow, BlockGatedImage, BlockCollectionFollowErrorCode, BlockCollectionFollowResult, BlockPostSource, BlockCreatePostResult, BlockTrainingDatasetItem, BlockTrainingDatasetResult, WorkflowBodyTraining, WorkflowBodyPassThroughStep } from './types.js';
12
12
  import type { BlockAppReaction, BlockEntityReactionErrorCode, BlockEntityReactionResult, BlockEntityReactionsResult, BlockReactionEntityType } from './reactions.js';
13
13
  /**
14
14
  * Filter params for `GET_BUZZ_TRANSACTIONS`. All optional; the host validates
@@ -592,6 +592,13 @@ export type ParentToBlockMessage = {
592
592
  selectedImages?: BlockPickedImageInfo[];
593
593
  error?: string;
594
594
  };
595
+ } | {
596
+ type: 'MEDIA_UPLOAD_RESULT';
597
+ payload: {
598
+ requestId: string;
599
+ selected?: BlockMediaUploadInfo;
600
+ error?: string;
601
+ };
595
602
  } | {
596
603
  type: 'USER_CHECKPOINT_SET';
597
604
  payload: {
@@ -973,6 +980,19 @@ export type BlockToParentMessage = {
973
980
  */
974
981
  publicOnly?: boolean;
975
982
  };
983
+ } | {
984
+ type: 'OPEN_MEDIA_UPLOAD';
985
+ payload: {
986
+ requestId: string;
987
+ /** What kind of media to upload. The host refuses any other value. */
988
+ kind: BlockMediaKind;
989
+ /** Required. The only accepted value today. */
990
+ purpose: 'generationSource';
991
+ /** In-tab bytes: present = bytes mode (no picker), absent = picker mode. */
992
+ bytes?: ArrayBuffer;
993
+ /** Bytes mode only: the type the app believes it is sending; must match the content. */
994
+ mimeType?: string;
995
+ };
976
996
  } | {
977
997
  type: 'SET_USER_CHECKPOINT';
978
998
  payload: {
@@ -1194,7 +1214,7 @@ export type BlockToParentMessageType = BlockToParentMessage['type'];
1194
1214
  * it is a measurement, not an invariant, and civitai's own compile-time gate
1195
1215
  * (published SDK union ⊆ `keyof INVENTORY`) is what holds one direction of it.
1196
1216
  */
1197
- export declare const BLOCK_TO_PARENT_MESSAGE_TYPES: readonly ["BLOCK_HELLO", "BLOCK_READY", "BLOCK_ERROR", "BLOCK_MESSAGE_REJECTED", "REQUEST_TOKEN", "RESIZE_IFRAME", "SUBMIT_WORKFLOW", "ESTIMATE_WORKFLOW", "ESTIMATE_WORKFLOW_BATCH", "POLL_WORKFLOW", "CANCEL_WORKFLOW", "OPEN_BUZZ_PURCHASE", "GET_BUZZ_BALANCE", "GET_VIEWER", "GET_BUZZ_TRANSACTIONS", "GET_BUZZ_ACCOUNTS", "GET_DAILY_COMPENSATION", "GET_WILDCARD_PACK", "QUERY_APP_WORKFLOWS", "PUBLISH_GENERATION_OUTPUTS", "CREATE_POST_FROM_APP", "PREPARE_TRAINING_DATASET", "RUN_TRAINING", "RUN_CONFIRMED_STEP", "GET_IMAGES_BY_IDS", "CANCEL_APP_WORKFLOW", "OPEN_CHECKPOINT_PICKER", "OPEN_RESOURCE_PICKER", "OPEN_IMAGE_UPLOAD", "OPEN_IMAGE_PICKER", "SET_USER_CHECKPOINT", "NAVIGATE", "REQUEST_SIGN_IN", "REQUEST_CONSENT", "TRACK_EVENT", "APP_STORAGE_GET", "APP_STORAGE_SET", "APP_STORAGE_DELETE", "APP_STORAGE_LIST", "APP_STORAGE_QUOTA", "SHARED_LIST", "SHARED_GET_COUNT", "SHARED_GET_COUNTS", "SHARED_APPEND", "SHARED_VOTE", "SHARED_UNVOTE", "SHARED_WITHDRAW", "SHARED_UPDATE", "SHARED_GET", "SHARED_REPORT", "SAVE_IMAGE", "SET_COLLECTION_FOLLOW", "SET_ENTITY_REACTION", "GET_ENTITY_REACTIONS"];
1217
+ export declare const BLOCK_TO_PARENT_MESSAGE_TYPES: readonly ["BLOCK_HELLO", "BLOCK_READY", "BLOCK_ERROR", "BLOCK_MESSAGE_REJECTED", "REQUEST_TOKEN", "RESIZE_IFRAME", "SUBMIT_WORKFLOW", "ESTIMATE_WORKFLOW", "ESTIMATE_WORKFLOW_BATCH", "POLL_WORKFLOW", "CANCEL_WORKFLOW", "OPEN_BUZZ_PURCHASE", "GET_BUZZ_BALANCE", "GET_VIEWER", "GET_BUZZ_TRANSACTIONS", "GET_BUZZ_ACCOUNTS", "GET_DAILY_COMPENSATION", "GET_WILDCARD_PACK", "QUERY_APP_WORKFLOWS", "PUBLISH_GENERATION_OUTPUTS", "CREATE_POST_FROM_APP", "PREPARE_TRAINING_DATASET", "RUN_TRAINING", "RUN_CONFIRMED_STEP", "GET_IMAGES_BY_IDS", "CANCEL_APP_WORKFLOW", "OPEN_CHECKPOINT_PICKER", "OPEN_RESOURCE_PICKER", "OPEN_IMAGE_UPLOAD", "OPEN_IMAGE_PICKER", "OPEN_MEDIA_UPLOAD", "SET_USER_CHECKPOINT", "NAVIGATE", "REQUEST_SIGN_IN", "REQUEST_CONSENT", "TRACK_EVENT", "APP_STORAGE_GET", "APP_STORAGE_SET", "APP_STORAGE_DELETE", "APP_STORAGE_LIST", "APP_STORAGE_QUOTA", "SHARED_LIST", "SHARED_GET_COUNT", "SHARED_GET_COUNTS", "SHARED_APPEND", "SHARED_VOTE", "SHARED_UNVOTE", "SHARED_WITHDRAW", "SHARED_UPDATE", "SHARED_GET", "SHARED_REPORT", "SAVE_IMAGE", "SET_COLLECTION_FOLLOW", "SET_ENTITY_REACTION", "GET_ENTITY_REACTIONS"];
1198
1218
  /**
1199
1219
  * The bucket a message type falls into when the protocol does not declare it.
1200
1220
  *
@@ -79,6 +79,7 @@ export const BLOCK_TO_PARENT_MESSAGE_TYPES = [
79
79
  'OPEN_RESOURCE_PICKER',
80
80
  'OPEN_IMAGE_UPLOAD',
81
81
  'OPEN_IMAGE_PICKER',
82
+ 'OPEN_MEDIA_UPLOAD',
82
83
  'SET_USER_CHECKPOINT',
83
84
  'NAVIGATE',
84
85
  'REQUEST_SIGN_IN',
@@ -372,6 +372,51 @@ export interface BlockPickedImageInfo {
372
372
  */
373
373
  imageId?: number;
374
374
  }
375
+ /**
376
+ * What kind of media `OPEN_MEDIA_UPLOAD` (via `useMediaUpload`) uploads. The
377
+ * host decides the file's real type from its MAGIC BYTES, never from a declared
378
+ * MIME type, and accepts per kind:
379
+ * - `'image'`: PNG, JPEG or WebP;
380
+ * - `'video'`: MP4 or WebM;
381
+ * - `'audio'`: MP3, WAV or WebM.
382
+ */
383
+ export type BlockMediaKind = 'image' | 'video' | 'audio';
384
+ /**
385
+ * One media file the host uploaded for the block as a GENERATION INPUT
386
+ * (`MEDIA_UPLOAD_RESULT.selected`, via `useMediaUpload`).
387
+ *
388
+ * `url` is a PRIVATE generation-input URL: pass it into a workflow step input
389
+ * (an image, video or audio input). It is not a public Civitai image and has no
390
+ * `imageId`. The host refuses data URIs and inline
391
+ * base64 in step inputs, so this is how a block gets media it holds (a picked
392
+ * file, a canvas, a recording) into a step.
393
+ *
394
+ * Per kind:
395
+ * - `'image'`: the host RESIZES the picture so both sides are within 64–2048
396
+ * pixels and RE-ENCODES it as JPEG. `mimeType` is always `'image/jpeg'`,
397
+ * and `sizeBytes`, `width` and `height` describe that JPEG.
398
+ * - `'video'`: uploaded as sent. `width` / `height` are always set (the host
399
+ * refuses a file with no video track); `durationMs` is set when the browser
400
+ * reports a finite duration.
401
+ * - `'audio'`: uploaded as sent. No `width` / `height`; `durationMs` as for
402
+ * video. A `MediaRecorder` WebM can report no duration, so do not rely on it.
403
+ */
404
+ export interface BlockMediaUploadInfo {
405
+ /** The private generation-input URL. Pass it into a step input. */
406
+ url: string;
407
+ /** The kind that was requested. */
408
+ kind: BlockMediaKind;
409
+ /** The type actually uploaded. Always `'image/jpeg'` for `'image'`. */
410
+ mimeType: string;
411
+ /** Bytes actually uploaded (for `'image'`, the re-encoded JPEG's size). */
412
+ sizeBytes: number;
413
+ /** Pixel width. Always set for `'image'` and `'video'`; absent for `'audio'`. */
414
+ width?: number;
415
+ /** Pixel height. Always set for `'image'` and `'video'`; absent for `'audio'`. */
416
+ height?: number;
417
+ /** Duration in milliseconds, for `'video'` / `'audio'` when known. Never set for `'image'`. */
418
+ durationMs?: number;
419
+ }
375
420
  /**
376
421
  * One of the model version's curated preview images, with the standard
377
422
  * gen params extracted from its source meta. Block UIs use these to let
@@ -1295,8 +1340,14 @@ export type WorkflowBodyPassThroughStep = {
1295
1340
  *
1296
1341
  * Consequently the orchestrator's per-`$type` schema is the ONLY authority for
1297
1342
  * what a given `$type` accepts; nothing in this package or on the host mirrors
1298
- * it. Bounded only by size: at most **262144 bytes** (256 KB) serialized, which
1299
- * is a payload-DoS bound and not a shape gate.
1343
+ * it. Its shape is not checked; its size is: at most **262144 bytes** (256 KB)
1344
+ * serialized, which is a payload-DoS bound and not a shape gate.
1345
+ *
1346
+ * 🔴 **No inline media.** The host refuses a `data:image|video|audio` URI or a
1347
+ * long raw base64 string anywhere in here: upload the image, video or audio
1348
+ * with `useMediaUpload()` (an image also works with
1349
+ * `useImageUpload({ purpose: 'generationSource' })` or `useImagePicker()`)
1350
+ * and pass the returned `url`.
1300
1351
  */
1301
1352
  input: Record<string, unknown>;
1302
1353
  /**
package/dist/index.d.ts CHANGED
@@ -25,11 +25,11 @@
25
25
  *
26
26
  * - **`./blocks`** — importing it RUNS `./safe-storage` for its side effect
27
27
  * (repairing `localStorage`/`sessionStorage` at an opaque origin). Folding
28
- * 180 symbols and that side effect into the root would make every OAuth app
28
+ * 198 symbols and that side effect into the root would make every OAuth app
29
29
  * that writes `import { exchangeCode } from '@civitai/app-sdk'` pay for the
30
30
  * Civitai-Apps contract it does not use. Blocks and OAuth apps are disjoint
31
31
  * audiences; see this package's README.
32
- * 🔴 That 180 is ASSERTED, not merely quoted — by
32
+ * 🔴 That 198 is ASSERTED, not merely quoted — by
33
33
  * `packages/civitai-app-sdk/test/export-surface.test.ts`, which pins
34
34
  * `surface.get('./blocks').size`. It said 119 here against a real 125 until
35
35
  * 2026-10-04, because the existing checks pin the root as an exact union and
package/dist/index.js CHANGED
@@ -25,11 +25,11 @@
25
25
  *
26
26
  * - **`./blocks`** — importing it RUNS `./safe-storage` for its side effect
27
27
  * (repairing `localStorage`/`sessionStorage` at an opaque origin). Folding
28
- * 180 symbols and that side effect into the root would make every OAuth app
28
+ * 198 symbols and that side effect into the root would make every OAuth app
29
29
  * that writes `import { exchangeCode } from '@civitai/app-sdk'` pay for the
30
30
  * Civitai-Apps contract it does not use. Blocks and OAuth apps are disjoint
31
31
  * audiences; see this package's README.
32
- * 🔴 That 180 is ASSERTED, not merely quoted — by
32
+ * 🔴 That 198 is ASSERTED, not merely quoted — by
33
33
  * `packages/civitai-app-sdk/test/export-surface.test.ts`, which pins
34
34
  * `surface.get('./blocks').size`. It said 119 here against a real 125 until
35
35
  * 2026-10-04, because the existing checks pin the root as an exact union and
@@ -430,11 +430,14 @@ export interface BuildImageGenBodyOptions {
430
430
  *
431
431
  * @example Nano Banana 2 with a reference image
432
432
  * ```ts
433
+ * // Pass a hosted image URL, not a data URI or raw base64. In an App Block, the
434
+ * // `url` from `useImageUpload({ purpose: 'generationSource' })` or `useImagePicker()`;
435
+ * // the block host refuses inline media in a step input.
433
436
  * const body = buildImageGenBody({
434
437
  * engine: 'google',
435
438
  * model: 'nano-banana-2',
436
439
  * prompt: 'turn this into a cartoon sticker',
437
- * images: ['data:image/png;base64,...'],
440
+ * images: [source.url],
438
441
  * aspectRatio: '1:1',
439
442
  * numImages: 1,
440
443
  * resolution: '1K',
@@ -393,11 +393,14 @@ export function buildTextToImageBody(input, opts = {}) {
393
393
  *
394
394
  * @example Nano Banana 2 with a reference image
395
395
  * ```ts
396
+ * // Pass a hosted image URL, not a data URI or raw base64. In an App Block, the
397
+ * // `url` from `useImageUpload({ purpose: 'generationSource' })` or `useImagePicker()`;
398
+ * // the block host refuses inline media in a step input.
396
399
  * const body = buildImageGenBody({
397
400
  * engine: 'google',
398
401
  * model: 'nano-banana-2',
399
402
  * prompt: 'turn this into a cartoon sticker',
400
- * images: ['data:image/png;base64,...'],
403
+ * images: [source.url],
401
404
  * aspectRatio: '1:1',
402
405
  * numImages: 1,
403
406
  * resolution: '1K',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civitai/app-sdk",
3
- "version": "0.74.0",
3
+ "version": "0.75.0",
4
4
  "description": "OAuth + PKCE, encrypted-cookie sessions, scopes, and orchestrator helpers for building third-party Civitai apps.",
5
5
  "license": "MIT",
6
6
  "type": "module",