@sweberdev/witness 0.0.0-stage → 0.1.1

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -2
  3. package/dist/ai-sdk.cjs +921 -0
  4. package/dist/ai-sdk.cjs.map +1 -0
  5. package/dist/ai-sdk.d.cts +95 -0
  6. package/dist/ai-sdk.d.ts +95 -0
  7. package/dist/ai-sdk.js +150 -0
  8. package/dist/ai-sdk.js.map +1 -0
  9. package/dist/bin.cjs +944 -0
  10. package/dist/bin.cjs.map +1 -0
  11. package/dist/bin.d.cts +1 -0
  12. package/dist/bin.d.ts +1 -0
  13. package/dist/bin.js +12 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/chunk-APXU3MTX.js +958 -0
  16. package/dist/chunk-APXU3MTX.js.map +1 -0
  17. package/dist/chunk-L65R2SM5.js +228 -0
  18. package/dist/chunk-L65R2SM5.js.map +1 -0
  19. package/dist/chunk-O6TADCND.js +317 -0
  20. package/dist/chunk-O6TADCND.js.map +1 -0
  21. package/dist/chunk-UBRK4CTM.js +156 -0
  22. package/dist/chunk-UBRK4CTM.js.map +1 -0
  23. package/dist/chunk-XJOQ5IUT.js +110 -0
  24. package/dist/chunk-XJOQ5IUT.js.map +1 -0
  25. package/dist/cli.cjs +964 -0
  26. package/dist/cli.cjs.map +1 -0
  27. package/dist/cli.d.cts +7 -0
  28. package/dist/cli.d.ts +7 -0
  29. package/dist/cli.js +9 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/disclosure-5a3UIVQZ.d.cts +70 -0
  32. package/dist/disclosure-C7Y_uY73.d.ts +70 -0
  33. package/dist/elements-auto.cjs +649 -0
  34. package/dist/elements-auto.cjs.map +1 -0
  35. package/dist/elements-auto.d.cts +3 -0
  36. package/dist/elements-auto.d.ts +3 -0
  37. package/dist/elements-auto.js +16 -0
  38. package/dist/elements-auto.js.map +1 -0
  39. package/dist/elements.cjs +646 -0
  40. package/dist/elements.cjs.map +1 -0
  41. package/dist/elements.d.cts +47 -0
  42. package/dist/elements.d.ts +47 -0
  43. package/dist/elements.js +13 -0
  44. package/dist/elements.js.map +1 -0
  45. package/dist/image-B7YvdITx.d.ts +49 -0
  46. package/dist/image-BNrEO-hj.d.cts +49 -0
  47. package/dist/index.cjs +1344 -0
  48. package/dist/index.cjs.map +1 -0
  49. package/dist/index.d.cts +124 -0
  50. package/dist/index.d.ts +124 -0
  51. package/dist/index.js +77 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/types-WWHzrNlc.d.cts +90 -0
  54. package/dist/types-WWHzrNlc.d.ts +90 -0
  55. package/package.json +123 -3
  56. package/src/ai-sdk.ts +252 -0
  57. package/src/bin.ts +6 -0
  58. package/src/cli.ts +160 -0
  59. package/src/disclosure.ts +172 -0
  60. package/src/elements-auto.ts +5 -0
  61. package/src/elements.ts +363 -0
  62. package/src/i18n.ts +259 -0
  63. package/src/image.ts +552 -0
  64. package/src/index.ts +66 -0
  65. package/src/inflate.ts +189 -0
  66. package/src/marking.ts +237 -0
  67. package/src/types.ts +115 -0
  68. package/src/watermark.ts +165 -0
  69. package/styles.css +103 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/disclosure.ts","../src/types.ts"],"sourcesContent":["import type { DisclosureKind } from \"./types.js\";\n\n/** Minimal key-value storage, e.g. `localStorage`. */\nexport interface DisclosureStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\nexport interface DisclosureEvent {\n type: \"shown\" | \"acknowledged\";\n /** Your id for this disclosure, e.g. \"support-chat\". */\n id: string;\n kind: DisclosureKind;\n /** Bump the version when the wording changes, so people see the new text once. */\n version: string;\n locale: string;\n /** ISO 8601 timestamp. */\n at: string;\n}\n\nexport interface DisclosureOptions {\n /** Your id for this disclosure. Default: the kind. */\n id?: string;\n /** Default `chatbot`. */\n kind?: DisclosureKind;\n /** Default `1`. */\n version?: string;\n /** Locale shown, recorded in events. Default `en`. */\n locale?: string;\n /**\n * Where the acknowledgement is remembered: `local` (default), `session`, `memory` or your\n * own storage. Falls back to memory when browser storage is unavailable.\n */\n storage?: \"local\" | \"session\" | \"memory\" | DisclosureStorage;\n /**\n * Called when the notice is shown or acknowledged. Send these to your log (for example\n * Logarithm) to keep evidence of what people were told and when.\n */\n onEvent?: (event: DisclosureEvent) => void;\n /** Clock for tests. */\n now?: () => Date;\n}\n\nexport interface Disclosure {\n readonly id: string;\n readonly kind: DisclosureKind;\n readonly version: string;\n /** True until this version was acknowledged. */\n needsAcknowledgement(): boolean;\n /** When this version was acknowledged, or `null`. */\n acknowledgedAt(): string | null;\n /** Records that the notice was rendered. Emits a `shown` event once per instance. */\n markShown(): void;\n /** Records the acknowledgement and emits an `acknowledged` event. */\n acknowledge(): void;\n /** Forgets the acknowledgement. */\n reset(): void;\n /** Called whenever the acknowledgement changes. Returns an unsubscribe function. */\n subscribe(listener: () => void): () => void;\n}\n\nconst PREFIX = \"witness:ack:\";\n\n/**\n * Tracks whether a person has seen and acknowledged an AI disclosure.\n *\n * Article 50(5) asks for the information \"at the latest at the time of the first interaction\n * or exposure\". Keep a compact label visible after the acknowledgement: the acknowledgement\n * only collapses the notice, it does not make it disappear.\n */\nexport function createDisclosure(options: DisclosureOptions = {}): Disclosure {\n const kind = options.kind ?? \"chatbot\";\n const id = options.id ?? kind;\n const version = options.version ?? \"1\";\n const locale = options.locale ?? \"en\";\n const now = options.now ?? (() => new Date());\n const storage = resolveStorage(options.storage);\n const key = `${PREFIX}${id}`;\n const listeners = new Set<() => void>();\n let shown = false;\n\n const read = (): { version: string; at: string } | null => {\n try {\n const raw = storage.getItem(key);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as { version?: unknown; at?: unknown };\n if (typeof parsed.version !== \"string\" || typeof parsed.at !== \"string\") return null;\n return { version: parsed.version, at: parsed.at };\n } catch {\n return null;\n }\n };\n\n const emit = (type: DisclosureEvent[\"type\"], at: string) => {\n options.onEvent?.({ type, id, kind, version, locale, at });\n };\n\n const notify = () => {\n for (const listener of listeners) listener();\n };\n\n return {\n id,\n kind,\n version,\n needsAcknowledgement: () => read()?.version !== version,\n acknowledgedAt: () => {\n const entry = read();\n return entry?.version === version ? entry.at : null;\n },\n markShown() {\n if (shown) return;\n shown = true;\n emit(\"shown\", now().toISOString());\n },\n acknowledge() {\n const at = now().toISOString();\n try {\n storage.setItem(key, JSON.stringify({ version, at }));\n } catch {\n // Storage full or blocked: the acknowledgement lasts for this page only.\n }\n emit(\"acknowledged\", at);\n notify();\n },\n reset() {\n try {\n storage.removeItem(key);\n } catch {\n // ignore\n }\n notify();\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\nfunction resolveStorage(option: DisclosureOptions[\"storage\"]): DisclosureStorage {\n if (option && typeof option === \"object\") return option;\n if (option !== \"memory\") {\n try {\n const candidate = option === \"session\" ? globalThis.sessionStorage : globalThis.localStorage;\n if (candidate) {\n const probe = `${PREFIX}probe`;\n candidate.setItem(probe, \"1\");\n candidate.removeItem(probe);\n return candidate;\n }\n } catch {\n // fall through to memory\n }\n }\n return memoryStorage();\n}\n\n/** In-memory storage, e.g. for server rendering or tests. */\nexport function memoryStorage(): DisclosureStorage {\n const map = new Map<string, string>();\n return {\n getItem: (key) => map.get(key) ?? null,\n setItem: (key, value) => {\n map.set(key, value);\n },\n removeItem: (key) => {\n map.delete(key);\n },\n };\n}\n","/**\n * The transparency situations Article 50 of the EU AI Act describes.\n *\n * - `chatbot`: a person interacts directly with an AI system (Art. 50(1)).\n * - `generated`: image, audio, video or text produced by an AI system (Art. 50(2) and 50(4)).\n * - `edited`: existing content altered with an AI system (Art. 50(2) and 50(4)).\n * - `deepfake`: generated or manipulated content that resembles real people, objects,\n * places or events and could falsely appear authentic (Art. 50(4)).\n * - `emotion-recognition` and `biometric-categorisation`: people are exposed to such a\n * system (Art. 50(3)).\n */\nexport type DisclosureKind =\n | \"chatbot\"\n | \"generated\"\n | \"edited\"\n | \"deepfake\"\n | \"emotion-recognition\"\n | \"biometric-categorisation\";\n\nexport const DISCLOSURE_KINDS: readonly DisclosureKind[] = [\n \"chatbot\",\n \"generated\",\n \"edited\",\n \"deepfake\",\n \"emotion-recognition\",\n \"biometric-categorisation\",\n];\n\n/** The kinds that describe a piece of content and can be written into a marking. */\nexport type ContentKind = \"generated\" | \"edited\" | \"deepfake\";\n\n/**\n * IPTC Digital Source Type values relevant to AI. See\n * https://cv.iptc.org/newscodes/digitalsourcetype/\n */\nexport type SourceType =\n | \"trainedAlgorithmicMedia\"\n | \"compositeWithTrainedAlgorithmicMedia\"\n | \"algorithmicallyEnhanced\"\n | \"algorithmicMedia\"\n | \"compositeSynthetic\";\n\n/** Wording for one disclosure kind in one language. */\nexport interface DisclosureText {\n /** Two or three words for a badge, e.g. \"AI-generated\". */\n label: string;\n /** One line for the heading of a notice. */\n title: string;\n /** One or two plain sentences that explain the label. */\n body: string;\n}\n\n/** Interface strings shared by the notice and label components. */\nexport interface UiText {\n /** Button that collapses the chatbot notice. */\n acknowledge: string;\n /** Accessible name of the button that opens label details. */\n details: string;\n /** \"Generated with {generator}\". `{generator}` is replaced. */\n generatedWith: string;\n /** \"Created on {date}\". `{date}` is replaced. */\n createdOn: string;\n /** Shown when a person reviewed the content and took editorial responsibility. */\n humanReviewed: string;\n /** Link text to a page with more information. */\n moreInfo: string;\n /** Closes the details popover. */\n close: string;\n}\n\nexport interface LocaleMessages {\n kinds: Record<DisclosureKind, DisclosureText>;\n ui: UiText;\n}\n\n/** A partial override of a locale, e.g. to switch German to the informal \"du\". */\nexport interface LocaleOverride {\n kinds?: Partial<Record<DisclosureKind, Partial<DisclosureText>>>;\n ui?: Partial<UiText>;\n}\n\n/** What a marking says about a piece of content. Input for {@link createMarking}. */\nexport interface MarkingInput {\n /** Defaults to `generated`. */\n kind?: ContentKind;\n /** Defaults from `kind`: `trainedAlgorithmicMedia`, or the composite type for `edited`. */\n sourceType?: SourceType;\n /** Name of the AI system or model, e.g. \"gpt-image-2\" or \"Claude\". */\n generator?: string;\n /** Version of the AI system, if known. */\n generatorVersion?: string;\n /** Who provides or operates the AI system, e.g. your company. */\n provider?: string;\n /** ISO 8601 timestamp. Defaults to now. */\n createdAt?: string | Date;\n /** A page that explains how and why you use AI. */\n disclosureUrl?: string;\n /** A person reviewed the content and holds editorial responsibility (Art. 50(4), text). */\n humanReviewed?: boolean;\n /** Free text, e.g. \"Image generated from the prompt by the newsroom\". */\n description?: string;\n}\n\n/** A normalised marking with all defaults applied. */\nexport interface Marking {\n kind: ContentKind;\n sourceType: SourceType;\n generator?: string;\n generatorVersion?: string;\n provider?: string;\n createdAt: string;\n disclosureUrl?: string;\n humanReviewed: boolean;\n description?: string;\n}\n"],"mappings":";AA8DA,IAAM,SAAS;AASR,SAAS,iBAAiB,UAA6B,CAAC,GAAe;AAC5E,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,KAAK,QAAQ,MAAM;AACzB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,MAAM,QAAQ,QAAQ,MAAM,oBAAI,KAAK;AAC3C,QAAM,UAAU,eAAe,QAAQ,OAAO;AAC9C,QAAM,MAAM,GAAG,MAAM,GAAG,EAAE;AAC1B,QAAM,YAAY,oBAAI,IAAgB;AACtC,MAAI,QAAQ;AAEZ,QAAM,OAAO,MAA8C;AACzD,QAAI;AACF,YAAM,MAAM,QAAQ,QAAQ,GAAG;AAC/B,UAAI,CAAC,IAAK,QAAO;AACjB,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,OAAO,OAAO,YAAY,YAAY,OAAO,OAAO,OAAO,SAAU,QAAO;AAChF,aAAO,EAAE,SAAS,OAAO,SAAS,IAAI,OAAO,GAAG;AAAA,IAClD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAAO,CAAC,MAA+B,OAAe;AAC1D,YAAQ,UAAU,EAAE,MAAM,IAAI,MAAM,SAAS,QAAQ,GAAG,CAAC;AAAA,EAC3D;AAEA,QAAM,SAAS,MAAM;AACnB,eAAW,YAAY,UAAW,UAAS;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,MAAM,KAAK,GAAG,YAAY;AAAA,IAChD,gBAAgB,MAAM;AACpB,YAAM,QAAQ,KAAK;AACnB,aAAO,OAAO,YAAY,UAAU,MAAM,KAAK;AAAA,IACjD;AAAA,IACA,YAAY;AACV,UAAI,MAAO;AACX,cAAQ;AACR,WAAK,SAAS,IAAI,EAAE,YAAY,CAAC;AAAA,IACnC;AAAA,IACA,cAAc;AACZ,YAAM,KAAK,IAAI,EAAE,YAAY;AAC7B,UAAI;AACF,gBAAQ,QAAQ,KAAK,KAAK,UAAU,EAAE,SAAS,GAAG,CAAC,CAAC;AAAA,MACtD,QAAQ;AAAA,MAER;AACA,WAAK,gBAAgB,EAAE;AACvB,aAAO;AAAA,IACT;AAAA,IACA,QAAQ;AACN,UAAI;AACF,gBAAQ,WAAW,GAAG;AAAA,MACxB,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAAA,IACA,UAAU,UAAU;AAClB,gBAAU,IAAI,QAAQ;AACtB,aAAO,MAAM,UAAU,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,eAAe,QAAyD;AAC/E,MAAI,UAAU,OAAO,WAAW,SAAU,QAAO;AACjD,MAAI,WAAW,UAAU;AACvB,QAAI;AACF,YAAM,YAAY,WAAW,YAAY,WAAW,iBAAiB,WAAW;AAChF,UAAI,WAAW;AACb,cAAM,QAAQ,GAAG,MAAM;AACvB,kBAAU,QAAQ,OAAO,GAAG;AAC5B,kBAAU,WAAW,KAAK;AAC1B,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,cAAc;AACvB;AAGO,SAAS,gBAAmC;AACjD,QAAM,MAAM,oBAAI,IAAoB;AACpC,SAAO;AAAA,IACL,SAAS,CAAC,QAAQ,IAAI,IAAI,GAAG,KAAK;AAAA,IAClC,SAAS,CAAC,KAAK,UAAU;AACvB,UAAI,IAAI,KAAK,KAAK;AAAA,IACpB;AAAA,IACA,YAAY,CAAC,QAAQ;AACnB,UAAI,OAAO,GAAG;AAAA,IAChB;AAAA,EACF;AACF;;;ACxJO,IAAM,mBAA8C;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}