@character-foundry/character-foundry 0.4.3-dev.1766103111 → 0.4.3

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 (57) hide show
  1. package/dist/charx.cjs +52 -85
  2. package/dist/charx.cjs.map +1 -1
  3. package/dist/charx.d.cts +22 -22
  4. package/dist/charx.d.ts +22 -22
  5. package/dist/charx.js +52 -85
  6. package/dist/charx.js.map +1 -1
  7. package/dist/exporter.cjs +54 -104
  8. package/dist/exporter.cjs.map +1 -1
  9. package/dist/exporter.d.cts +19 -19
  10. package/dist/exporter.d.ts +19 -19
  11. package/dist/exporter.js +54 -104
  12. package/dist/exporter.js.map +1 -1
  13. package/dist/federation.cjs +36 -104
  14. package/dist/federation.cjs.map +1 -1
  15. package/dist/federation.d.cts +19 -54
  16. package/dist/federation.d.ts +19 -54
  17. package/dist/federation.js +36 -104
  18. package/dist/federation.js.map +1 -1
  19. package/dist/index.cjs +54 -104
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +29 -29
  22. package/dist/index.d.ts +29 -29
  23. package/dist/index.js +54 -104
  24. package/dist/index.js.map +1 -1
  25. package/dist/loader.cjs +31 -171
  26. package/dist/loader.cjs.map +1 -1
  27. package/dist/loader.d.cts +23 -37
  28. package/dist/loader.d.ts +23 -37
  29. package/dist/loader.js +31 -171
  30. package/dist/loader.js.map +1 -1
  31. package/dist/lorebook.d.cts +23 -23
  32. package/dist/lorebook.d.ts +23 -23
  33. package/dist/normalizer.cjs +18 -72
  34. package/dist/normalizer.cjs.map +1 -1
  35. package/dist/normalizer.d.cts +37 -37
  36. package/dist/normalizer.d.ts +37 -37
  37. package/dist/normalizer.js +18 -72
  38. package/dist/normalizer.js.map +1 -1
  39. package/dist/png.cjs +18 -72
  40. package/dist/png.cjs.map +1 -1
  41. package/dist/png.d.cts +25 -25
  42. package/dist/png.d.ts +25 -25
  43. package/dist/png.js +18 -72
  44. package/dist/png.js.map +1 -1
  45. package/dist/schemas.cjs +23 -80
  46. package/dist/schemas.cjs.map +1 -1
  47. package/dist/schemas.d.cts +67 -85
  48. package/dist/schemas.d.ts +67 -85
  49. package/dist/schemas.js +23 -80
  50. package/dist/schemas.js.map +1 -1
  51. package/dist/voxta.cjs +20 -91
  52. package/dist/voxta.cjs.map +1 -1
  53. package/dist/voxta.d.cts +23 -23
  54. package/dist/voxta.d.ts +23 -23
  55. package/dist/voxta.js +20 -91
  56. package/dist/voxta.js.map +1 -1
  57. package/package.json +5 -5
package/dist/loader.cjs CHANGED
@@ -21,7 +21,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var loader_exports = {};
22
22
  __export(loader_exports, {
23
23
  computeContentHash: () => computeContentHash,
24
- computeContentHashV2: () => computeContentHashV2,
25
24
  detectFormat: () => detectFormat,
26
25
  getContainerFormat: () => getContainerFormat,
27
26
  mightBeCard: () => mightBeCard,
@@ -444,58 +443,6 @@ var import_zod = require("zod");
444
443
  var import_zod2 = require("zod");
445
444
  var import_zod3 = require("zod");
446
445
  var import_zod4 = require("zod");
447
- function preprocessTimestamp(val) {
448
- if (val === null || val === void 0) return void 0;
449
- let num;
450
- if (typeof val === "number") {
451
- num = val;
452
- } else if (typeof val === "string") {
453
- const trimmed = val.trim();
454
- if (!trimmed) return void 0;
455
- const parsed = Number(trimmed);
456
- if (!isNaN(parsed)) {
457
- num = parsed;
458
- } else {
459
- const date = new Date(trimmed);
460
- if (isNaN(date.getTime())) return void 0;
461
- num = Math.floor(date.getTime() / 1e3);
462
- }
463
- } else {
464
- return void 0;
465
- }
466
- if (num > 1e10) {
467
- num = Math.floor(num / 1e3);
468
- }
469
- if (num < 0) return void 0;
470
- return num;
471
- }
472
- function preprocessNumeric(val) {
473
- if (val === null || val === void 0) return void 0;
474
- if (typeof val === "number") {
475
- return isNaN(val) ? void 0 : val;
476
- }
477
- if (typeof val === "string") {
478
- const trimmed = val.trim();
479
- if (!trimmed) return void 0;
480
- const parsed = Number(trimmed);
481
- return isNaN(parsed) ? void 0 : parsed;
482
- }
483
- return void 0;
484
- }
485
- var KNOWN_ASSET_TYPES = /* @__PURE__ */ new Set([
486
- "icon",
487
- "background",
488
- "emotion",
489
- "user_icon",
490
- "sound",
491
- "video",
492
- "custom",
493
- "x-risu-asset"
494
- ]);
495
- function preprocessAssetType(val) {
496
- if (typeof val !== "string") return "custom";
497
- return KNOWN_ASSET_TYPES.has(val) ? val : "custom";
498
- }
499
446
  var ISO8601Schema = import_zod.z.string().datetime();
500
447
  var UUIDSchema = import_zod.z.string().uuid();
501
448
  var SpecSchema = import_zod.z.enum(["v2", "v3"]);
@@ -518,19 +465,16 @@ var SourceFormatSchema = import_zod.z.enum([
518
465
  // VoxPkg format
519
466
  ]);
520
467
  var OriginalShapeSchema = import_zod.z.enum(["wrapped", "unwrapped", "legacy"]);
521
- var AssetTypeSchema = import_zod.z.preprocess(
522
- preprocessAssetType,
523
- import_zod.z.enum([
524
- "icon",
525
- "background",
526
- "emotion",
527
- "user_icon",
528
- "sound",
529
- "video",
530
- "custom",
531
- "x-risu-asset"
532
- ])
533
- );
468
+ var AssetTypeSchema = import_zod.z.enum([
469
+ "icon",
470
+ "background",
471
+ "emotion",
472
+ "user_icon",
473
+ "sound",
474
+ "video",
475
+ "custom",
476
+ "x-risu-asset"
477
+ ]);
534
478
  var AssetDescriptorSchema = import_zod.z.object({
535
479
  type: AssetTypeSchema,
536
480
  uri: import_zod.z.string(),
@@ -564,8 +508,8 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
564
508
  var CCv2CharacterBookSchema = import_zod2.z.object({
565
509
  name: import_zod2.z.string().optional(),
566
510
  description: import_zod2.z.string().optional(),
567
- scan_depth: import_zod2.z.preprocess(preprocessNumeric, import_zod2.z.number().int().nonnegative().optional()),
568
- token_budget: import_zod2.z.preprocess(preprocessNumeric, import_zod2.z.number().int().nonnegative().optional()),
511
+ scan_depth: import_zod2.z.number().int().nonnegative().optional(),
512
+ token_budget: import_zod2.z.number().int().nonnegative().optional(),
569
513
  recursive_scanning: import_zod2.z.boolean().optional(),
570
514
  extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
571
515
  entries: import_zod2.z.array(CCv2LorebookEntrySchema)
@@ -639,8 +583,8 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
639
583
  var CCv3CharacterBookSchema = import_zod3.z.object({
640
584
  name: import_zod3.z.string().optional(),
641
585
  description: import_zod3.z.string().optional(),
642
- scan_depth: import_zod3.z.preprocess(preprocessNumeric, import_zod3.z.number().int().nonnegative().optional()),
643
- token_budget: import_zod3.z.preprocess(preprocessNumeric, import_zod3.z.number().int().nonnegative().optional()),
586
+ scan_depth: import_zod3.z.number().int().nonnegative().optional(),
587
+ token_budget: import_zod3.z.number().int().nonnegative().optional(),
644
588
  recursive_scanning: import_zod3.z.boolean().optional(),
645
589
  extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
646
590
  entries: import_zod3.z.array(CCv3LorebookEntrySchema)
@@ -672,9 +616,10 @@ var CCv3DataInnerSchema = import_zod3.z.object({
672
616
  nickname: import_zod3.z.string().optional(),
673
617
  creator_notes_multilingual: import_zod3.z.record(import_zod3.z.string()).optional(),
674
618
  source: import_zod3.z.array(import_zod3.z.string()).optional(),
675
- // Unix timestamps - preprocess to handle ISO strings, numeric strings, milliseconds
676
- creation_date: import_zod3.z.preprocess(preprocessTimestamp, import_zod3.z.number().int().nonnegative().optional()),
677
- modification_date: import_zod3.z.preprocess(preprocessTimestamp, import_zod3.z.number().int().nonnegative().optional())
619
+ creation_date: import_zod3.z.number().int().nonnegative().optional(),
620
+ // Unix timestamp in seconds
621
+ modification_date: import_zod3.z.number().int().nonnegative().optional()
622
+ // Unix timestamp in seconds
678
623
  });
679
624
  var CCv3DataSchema = import_zod3.z.object({
680
625
  spec: import_zod3.z.literal("chara_card_v3"),
@@ -8782,7 +8727,7 @@ function defaultTokenCounter(_card) {
8782
8727
  total: 0
8783
8728
  };
8784
8729
  }
8785
- function getCanonicalContentV1(card) {
8730
+ function getCanonicalContent(card) {
8786
8731
  const normalized = {
8787
8732
  name: card.data.name,
8788
8733
  description: card.data.description || "",
@@ -8804,69 +8749,6 @@ function getCanonicalContentV1(card) {
8804
8749
  };
8805
8750
  return JSON.stringify(normalized, Object.keys(normalized).sort());
8806
8751
  }
8807
- function stableStringify(value) {
8808
- if (value === null) return "null";
8809
- switch (typeof value) {
8810
- case "string":
8811
- return JSON.stringify(value);
8812
- case "number":
8813
- return Number.isFinite(value) ? String(value) : "null";
8814
- case "boolean":
8815
- return value ? "true" : "false";
8816
- case "bigint":
8817
- return JSON.stringify(value.toString());
8818
- case "undefined":
8819
- case "function":
8820
- case "symbol":
8821
- return "null";
8822
- case "object": {
8823
- if (Array.isArray(value)) {
8824
- const parts2 = value.map((item) => {
8825
- if (item === void 0 || typeof item === "function" || typeof item === "symbol") {
8826
- return "null";
8827
- }
8828
- return stableStringify(item);
8829
- });
8830
- return `[${parts2.join(",")}]`;
8831
- }
8832
- const obj = value;
8833
- const keys = Object.keys(obj).sort();
8834
- const parts = [];
8835
- for (const key of keys) {
8836
- const v = obj[key];
8837
- if (v === void 0 || typeof v === "function" || typeof v === "symbol") {
8838
- continue;
8839
- }
8840
- parts.push(`${JSON.stringify(key)}:${stableStringify(v)}`);
8841
- }
8842
- return `{${parts.join(",")}}`;
8843
- }
8844
- default:
8845
- return "null";
8846
- }
8847
- }
8848
- function getCanonicalContentV2(card) {
8849
- const normalized = {
8850
- name: card.data.name,
8851
- description: card.data.description || "",
8852
- personality: card.data.personality || "",
8853
- scenario: card.data.scenario || "",
8854
- first_mes: card.data.first_mes || "",
8855
- mes_example: card.data.mes_example || "",
8856
- system_prompt: card.data.system_prompt || "",
8857
- post_history_instructions: card.data.post_history_instructions || "",
8858
- alternate_greetings: card.data.alternate_greetings || [],
8859
- character_book: card.data.character_book ? {
8860
- entries: (card.data.character_book.entries || []).map((e) => ({
8861
- keys: e.keys,
8862
- content: e.content,
8863
- enabled: e.enabled
8864
- }))
8865
- } : null,
8866
- creator_notes: card.data.creator_notes || ""
8867
- };
8868
- return stableStringify(normalized);
8869
- }
8870
8752
  function isWithinTolerance(clientValue, computedValue, tolerance) {
8871
8753
  if (clientValue === void 0) return false;
8872
8754
  if (computedValue === 0) return clientValue === 0;
@@ -8887,18 +8769,15 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
8887
8769
  const warnings = [];
8888
8770
  const errors = [];
8889
8771
  const computedTokens = countTokens(card);
8890
- const canonicalContentV1 = getCanonicalContentV1(card);
8891
- const canonicalContentV2 = getCanonicalContentV2(card);
8892
- const computedHashV1 = await computeHash(canonicalContentV1);
8893
- const computedHashV2 = await computeHash(canonicalContentV2);
8772
+ const canonicalContent = getCanonicalContent(card);
8773
+ const computedHash = await computeHash(canonicalContent);
8894
8774
  const entries = card.data.character_book?.entries || [];
8895
8775
  const computedHasLorebook = entries.length > 0;
8896
8776
  const computedLorebookCount = entries.length;
8897
8777
  const authoritative = {
8898
8778
  name: card.data.name,
8899
8779
  tokens: computedTokens,
8900
- contentHash: computedHashV1,
8901
- contentHashV2: computedHashV2,
8780
+ contentHash: computedHash,
8902
8781
  hasLorebook: computedHasLorebook,
8903
8782
  lorebookEntriesCount: computedLorebookCount
8904
8783
  };
@@ -8910,27 +8789,21 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
8910
8789
  withinTolerance: false
8911
8790
  });
8912
8791
  }
8913
- const matchesV1 = clientMetadata.contentHash === computedHashV1;
8914
- const matchesV2 = clientMetadata.contentHash === computedHashV2;
8915
- if (!matchesV1 && !matchesV2) {
8792
+ if (clientMetadata.contentHash !== computedHash) {
8916
8793
  const disc = {
8917
8794
  field: "contentHash",
8918
8795
  clientValue: clientMetadata.contentHash,
8919
- computedValue: computedHashV1,
8796
+ computedValue: computedHash,
8920
8797
  withinTolerance: false
8921
8798
  };
8922
8799
  discrepancies.push(disc);
8923
8800
  if (allowHashMismatch) {
8924
8801
  warnings.push(
8925
- `Content hash mismatch: client=${clientMetadata.contentHash.substring(0, 8)}..., server(v1)=${computedHashV1.substring(0, 8)}..., server(v2)=${computedHashV2.substring(0, 8)}...`
8802
+ `Content hash mismatch: client=${clientMetadata.contentHash.substring(0, 8)}..., server=${computedHash.substring(0, 8)}...`
8926
8803
  );
8927
8804
  } else {
8928
8805
  errors.push("Content hash mismatch - possible tampering or encoding difference");
8929
8806
  }
8930
- } else if (matchesV1 && !matchesV2) {
8931
- warnings.push(
8932
- "Client contentHash matches legacy v1 canonicalization. Prefer authoritative.contentHashV2 for new storage."
8933
- );
8934
8807
  }
8935
8808
  const tokenFields = [
8936
8809
  "description",
@@ -9011,11 +8884,7 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
9011
8884
  };
9012
8885
  }
9013
8886
  async function computeContentHash(card) {
9014
- const content = getCanonicalContentV1(card);
9015
- return sha256Hash(content);
9016
- }
9017
- async function computeContentHashV2(card) {
9018
- const content = getCanonicalContentV2(card);
8887
+ const content = getCanonicalContent(card);
9019
8888
  return sha256Hash(content);
9020
8889
  }
9021
8890
  function validateClientMetadataSync(clientMetadata, parseResult, options) {
@@ -9031,18 +8900,15 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
9031
8900
  const warnings = [];
9032
8901
  const errors = [];
9033
8902
  const computedTokens = countTokens(card);
9034
- const canonicalContentV1 = getCanonicalContentV1(card);
9035
- const canonicalContentV2 = getCanonicalContentV2(card);
9036
- const computedHashV1 = computeHash(canonicalContentV1);
9037
- const computedHashV2 = computeHash(canonicalContentV2);
8903
+ const canonicalContent = getCanonicalContent(card);
8904
+ const computedHash = computeHash(canonicalContent);
9038
8905
  const entries = card.data.character_book?.entries || [];
9039
8906
  const computedHasLorebook = entries.length > 0;
9040
8907
  const computedLorebookCount = entries.length;
9041
8908
  const authoritative = {
9042
8909
  name: card.data.name,
9043
8910
  tokens: computedTokens,
9044
- contentHash: computedHashV1,
9045
- contentHashV2: computedHashV2,
8911
+ contentHash: computedHash,
9046
8912
  hasLorebook: computedHasLorebook,
9047
8913
  lorebookEntriesCount: computedLorebookCount
9048
8914
  };
@@ -9054,13 +8920,11 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
9054
8920
  withinTolerance: false
9055
8921
  });
9056
8922
  }
9057
- const matchesV1 = clientMetadata.contentHash === computedHashV1;
9058
- const matchesV2 = clientMetadata.contentHash === computedHashV2;
9059
- if (!matchesV1 && !matchesV2) {
8923
+ if (clientMetadata.contentHash !== computedHash) {
9060
8924
  discrepancies.push({
9061
8925
  field: "contentHash",
9062
8926
  clientValue: clientMetadata.contentHash,
9063
- computedValue: computedHashV1,
8927
+ computedValue: computedHash,
9064
8928
  withinTolerance: false
9065
8929
  });
9066
8930
  if (allowHashMismatch) {
@@ -9068,10 +8932,6 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
9068
8932
  } else {
9069
8933
  errors.push("Content hash mismatch");
9070
8934
  }
9071
- } else if (matchesV1 && !matchesV2) {
9072
- warnings.push(
9073
- "Client contentHash matches legacy v1 canonicalization. Prefer authoritative.contentHashV2 for new storage."
9074
- );
9075
8935
  }
9076
8936
  const tokenFields = [
9077
8937
  "description",