@enslo/sd-metadata 2.3.0 → 3.0.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/docs/types.ja.md CHANGED
@@ -10,6 +10,8 @@
10
10
  - [`ParseResult`](#parseresult)
11
11
  - [`GenerationMetadata`](#generationmetadata)
12
12
  - [`GenerationSoftware`](#generationsoftware)
13
+ - [`C2paMetadata`](#c2pametadata)
14
+ - [`C2paVendor`](#c2pavendor)
13
15
  - [`EmbedMetadata`](#embedmetadata)
14
16
  - [`RawMetadata`](#rawmetadata)
15
17
  - [`WriteResult`](#writeresult)
@@ -47,6 +49,7 @@
47
49
  ```typescript
48
50
  type ParseResult =
49
51
  | { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
52
+ | { status: 'c2pa'; c2pa: C2paMetadata }
50
53
  | { status: 'unrecognized'; raw: RawMetadata }
51
54
  | { status: 'empty' }
52
55
  | { status: 'invalid'; message?: string };
@@ -57,6 +60,8 @@ type ParseResult =
57
60
  - **`success`**: メタデータのパースに成功
58
61
  - `metadata`: 統一されたメタデータオブジェクト
59
62
  - `raw`: ラウンドトリップ変換用の元のフォーマット固有データ
63
+ - **`c2pa`**: 画像が C2PA Content Credentials を持つが、パース可能な生成メタデータがない
64
+ - `c2pa`: 未検証の Content Credentials を表す `C2paMetadata`。`raw` フィールドは存在しません — 署名済みマニフェストはラウンドトリップ書き込み用に公開されません。
60
65
  - **`unrecognized`**: 画像にメタデータがあるがフォーマットが認識できない
61
66
  - `raw`: 元のメタデータが保持される
62
67
  - **`empty`**: 画像にメタデータが見つからない
@@ -75,7 +80,14 @@ switch (result.status) {
75
80
  console.log(`Generated by ${result.metadata.software}`);
76
81
  console.log(`Prompt: ${result.metadata.prompt}`);
77
82
  break;
78
-
83
+
84
+ case 'c2pa':
85
+ // Content Credentials を検出(例:OpenAI ChatGPT、Google Gemini)。
86
+ // 検出のみ — 署名は検証されません。
87
+ console.log(`生成元(未検証): ${result.c2pa.vendor}`);
88
+ console.log(`Claim generator: ${result.c2pa.claimGenerator ?? 'unknown'}`);
89
+ break;
90
+
79
91
  case 'unrecognized':
80
92
  console.log('不明なメタデータフォーマット');
81
93
  break;
@@ -172,6 +184,73 @@ function displaySoftware(software: GenerationSoftware): string {
172
184
 
173
185
  ---
174
186
 
187
+ ### `C2paMetadata`
188
+
189
+ 画像に埋め込まれた C2PA Content Credentials から読み取った内容。
190
+
191
+ C2PAマニフェストを持つ画像(現在は **OpenAI ChatGPT** と **Google Gemini**)で、パース可能な生成メタデータがない場合に `read()` が `{ status: 'c2pa', c2pa }` として返します。`GenerationMetadata` とは異なり、**プロンプト・シード・モデル・サイズを一切持ちません**: これらのツールは生成パラメータではなく Content Credentials を埋め込むためです。`C2paMetadata` は `BaseMetadata` を**拡張しません**。
192
+
193
+ ```typescript
194
+ export interface C2paMetadata {
195
+ /** マニフェストの claim generator/署名者から特定した粗いベンダー。 */
196
+ vendor: C2paVendor;
197
+ /**
198
+ * マニフェストが学習アルゴリズム由来(AI生成)の IPTC DigitalSourceType を
199
+ * 宣言している場合に `true`。カメラ/スキャンのソースタイプはフラグされません。
200
+ */
201
+ aiGenerated: boolean;
202
+ /** 生の IPTC DigitalSourceType URI。存在する場合はそのまま提供されます。 */
203
+ digitalSourceType?: string;
204
+ /** C2PA の `claim_generator_info.name`(存在する場合)。 */
205
+ claimGenerator?: string;
206
+ }
207
+ ```
208
+
209
+ > **重要 — 検証ではなく検出のみ。** Content Credentials の存在は真正性の証明にはなりません(文字列は偽造可能)。不在も人間由来の証明にはなりません: Content Credentials はスクリーンショット、SNSへの再アップロード、再エンコードによって日常的に剥奪されます。
210
+ >
211
+ > **現時点ではPNGのみ。** マニフェストはPNGの `caBX` チャンクから読み取られます。JPEG/WebP対応は予定されています。
212
+
213
+ **例:**
214
+
215
+ ```typescript
216
+ import { read, c2paVendorLabels } from '@enslo/sd-metadata';
217
+
218
+ const result = read(imageData);
219
+
220
+ if (result.status === 'c2pa') {
221
+ const { vendor, aiGenerated, claimGenerator } = result.c2pa;
222
+ console.log('Vendor:', c2paVendorLabels[vendor]);
223
+ console.log('Declared AI-generated:', aiGenerated);
224
+ console.log('Claim generator:', claimGenerator ?? 'unknown');
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ### `C2paVendor`
231
+
232
+ 画像の C2PA Content Credentials の粗いベンダー特定。[`C2paMetadata`](#c2pametadata) の `vendor` 判別子として、また `c2paVendorLabels` のキー型として使用します。
233
+
234
+ ```typescript
235
+ export type C2paVendor = 'openai' | 'google' | 'unknown';
236
+ ```
237
+
238
+ 設計上、これは粗い特定です: C2PAマニフェストは生成元ベンダー(`'openai'` → ChatGPT、`'google'` → Gemini、`'unknown'` → ベンダーが具体的に認識されないAI生成マニフェスト)を特定しますが、具体的なモデルは特定**しません**。
239
+
240
+ **例:**
241
+
242
+ ```typescript
243
+ import { c2paVendorLabels } from '@enslo/sd-metadata';
244
+ import type { C2paVendor } from '@enslo/sd-metadata';
245
+
246
+ function displayVendor(vendor: C2paVendor): string {
247
+ return c2paVendorLabels[vendor];
248
+ // => "OpenAI (ChatGPT)", "Google (Gemini)", "AI-generated (Content Credentials)"
249
+ }
250
+ ```
251
+
252
+ ---
253
+
175
254
  ### `EmbedMetadata`
176
255
 
177
256
  `embed()` と `stringify()` で使用するユーザー作成カスタムメタデータ型。`GenerationMetadata` が既知のAIツールからのパース結果を表すのに対し、`EmbedMetadata` はユーザーが独自にメタデータを組み立てるための型です。`BaseMetadata` にオプションのNovelAIキャラクタープロンプトと設定行への任意キーバリュー(`extras`)を追加。
package/docs/types.md CHANGED
@@ -10,6 +10,8 @@ Complete type reference for `@enslo/sd-metadata`.
10
10
  - [`ParseResult`](#parseresult)
11
11
  - [`GenerationMetadata`](#generationmetadata)
12
12
  - [`GenerationSoftware`](#generationsoftware)
13
+ - [`C2paMetadata`](#c2pametadata)
14
+ - [`C2paVendor`](#c2pavendor)
13
15
  - [`EmbedMetadata`](#embedmetadata)
14
16
  - [`RawMetadata`](#rawmetadata)
15
17
  - [`WriteResult`](#writeresult)
@@ -47,6 +49,7 @@ The result type returned by the `read()` function.
47
49
  ```typescript
48
50
  type ParseResult =
49
51
  | { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
52
+ | { status: 'c2pa'; c2pa: C2paMetadata }
50
53
  | { status: 'unrecognized'; raw: RawMetadata }
51
54
  | { status: 'empty' }
52
55
  | { status: 'invalid'; message?: string };
@@ -57,6 +60,8 @@ type ParseResult =
57
60
  - **`success`**: Metadata was successfully parsed
58
61
  - `metadata`: Unified metadata object
59
62
  - `raw`: Original format-specific data for round-trip conversion
63
+ - **`c2pa`**: Image carries C2PA Content Credentials (AI provenance) but no parseable generation metadata
64
+ - `c2pa`: `C2paMetadata` describing the declared (unverified) provenance. There is no `raw` field — the signed manifest is not exposed for round-trip writing.
60
65
  - **`unrecognized`**: Image has metadata but format is not recognized
61
66
  - `raw`: Original metadata is preserved
62
67
  - **`empty`**: No metadata found in the image
@@ -75,7 +80,14 @@ switch (result.status) {
75
80
  console.log(`Generated by ${result.metadata.software}`);
76
81
  console.log(`Prompt: ${result.metadata.prompt}`);
77
82
  break;
78
-
83
+
84
+ case 'c2pa':
85
+ // Content Credentials detected (e.g. OpenAI ChatGPT, Google Gemini).
86
+ // Detection only — the signature is NOT verified.
87
+ console.log(`Provenance vendor: ${result.c2pa.vendor} (unverified)`);
88
+ console.log(`Claim generator: ${result.c2pa.claimGenerator ?? 'unknown'}`);
89
+ break;
90
+
79
91
  case 'unrecognized':
80
92
  console.log('Unknown metadata format');
81
93
  break;
@@ -172,6 +184,73 @@ function displaySoftware(software: GenerationSoftware): string {
172
184
 
173
185
  ---
174
186
 
187
+ ### `C2paMetadata`
188
+
189
+ Content Credentials (C2PA) read from an image's signed provenance manifest.
190
+
191
+ This is returned by `read()` as `{ status: 'c2pa', c2pa }` for images that carry a C2PA manifest — currently **OpenAI ChatGPT** and **Google Gemini** — but no parseable generation metadata. Unlike `GenerationMetadata`, it carries **no prompt, seed, model, or size**: these tools embed provenance, not generation parameters. `C2paMetadata` does **not** extend `BaseMetadata`.
192
+
193
+ ```typescript
194
+ export interface C2paMetadata {
195
+ /** Coarse vendor attribution from the manifest's claim generator / signer. */
196
+ vendor: C2paVendor;
197
+ /**
198
+ * `true` when the manifest declares a trained-algorithmic (AI-generated)
199
+ * IPTC DigitalSourceType. Camera/scan source types are not flagged.
200
+ */
201
+ aiGenerated: boolean;
202
+ /** Raw IPTC DigitalSourceType URI, surfaced verbatim when present. */
203
+ digitalSourceType?: string;
204
+ /** C2PA `claim_generator_info.name`, when present. */
205
+ claimGenerator?: string;
206
+ }
207
+ ```
208
+
209
+ > **Important — detection only, not verification.** Presence of Content Credentials is not proof of authenticity (the strings are forgeable). Absence is not proof of human origin either: Content Credentials are routinely stripped by screenshots, social-media re-uploads, and re-encoding.
210
+ >
211
+ > **PNG only today.** The manifest is read from the PNG `caBX` chunk; JPEG/WebP support is planned.
212
+
213
+ **Example:**
214
+
215
+ ```typescript
216
+ import { read, c2paVendorLabels } from '@enslo/sd-metadata';
217
+
218
+ const result = read(imageData);
219
+
220
+ if (result.status === 'c2pa') {
221
+ const { vendor, aiGenerated, claimGenerator } = result.c2pa;
222
+ console.log('Vendor:', c2paVendorLabels[vendor]);
223
+ console.log('Declared AI-generated:', aiGenerated);
224
+ console.log('Claim generator:', claimGenerator ?? 'unknown');
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ### `C2paVendor`
231
+
232
+ Coarse vendor attribution for an image's C2PA Content Credentials. Used as the `vendor` discriminator on [`C2paMetadata`](#c2pametadata) and as the key type for `c2paVendorLabels`.
233
+
234
+ ```typescript
235
+ export type C2paVendor = 'openai' | 'google' | 'unknown';
236
+ ```
237
+
238
+ By design this is coarse: a C2PA manifest identifies the producing vendor (`'openai'` → ChatGPT, `'google'` → Gemini, `'unknown'` → an AI-generated manifest whose vendor is not specifically recognized) but **not** the specific model.
239
+
240
+ **Example:**
241
+
242
+ ```typescript
243
+ import { c2paVendorLabels } from '@enslo/sd-metadata';
244
+ import type { C2paVendor } from '@enslo/sd-metadata';
245
+
246
+ function displayVendor(vendor: C2paVendor): string {
247
+ return c2paVendorLabels[vendor];
248
+ // => "OpenAI (ChatGPT)", "Google (Gemini)", "AI-generated (Content Credentials)"
249
+ }
250
+ ```
251
+
252
+ ---
253
+
175
254
  ### `EmbedMetadata`
176
255
 
177
256
  User-created custom metadata for the `embed()` and `stringify()` functions. While `GenerationMetadata` represents parsed output from a known AI tool, `EmbedMetadata` is designed for composing metadata from scratch. Extends `BaseMetadata` with optional NovelAI character prompts and arbitrary key-value extras for the settings line.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enslo/sd-metadata",
3
- "version": "2.3.0",
3
+ "version": "3.0.0",
4
4
  "description": "Read and write AI-generated image metadata",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,7 +55,7 @@
55
55
  "devDependencies": {
56
56
  "@biomejs/biome": "catalog:",
57
57
  "@types/node": "catalog:",
58
- "@vitest/coverage-v8": "^4.1.7",
58
+ "@vitest/coverage-v8": "^4.1.8",
59
59
  "tsdown": "catalog:",
60
60
  "typescript": "catalog:",
61
61
  "vitest": "catalog:"