@takuhon/core 1.1.0 → 1.4.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.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  var $schema = "https://json-schema.org/draft/2020-12/schema";
2
- var $id = "https://takuhon.example/schemas/1.1.0/takuhon.schema.json";
2
+ var $id = "https://takuhon.example/schemas/1.4.0/takuhon.schema.json";
3
3
  var title = "Takuhon Profile";
4
4
  var description = "Portable profile data format consumed by @takuhon/core. The canonical contract for profile content authored as takuhon.json.";
5
5
  var type = "object";
@@ -125,6 +125,13 @@ var properties = {
125
125
  $ref: "#/$defs/Recommendation"
126
126
  }
127
127
  },
128
+ highlights: {
129
+ type: "array",
130
+ maxItems: 50,
131
+ items: {
132
+ $ref: "#/$defs/Highlight"
133
+ }
134
+ },
128
135
  contact: {
129
136
  $ref: "#/$defs/Contact"
130
137
  },
@@ -425,6 +432,10 @@ var $defs = {
425
432
  title: {
426
433
  $ref: "#/$defs/LocalizedTitle"
427
434
  },
435
+ role: {
436
+ $ref: "#/$defs/LocalizedTitle",
437
+ description: "The owner's role/relationship on this project (added in 1.4.0), e.g. \"Author & lead maintainer\", \"Contributor\", \"Product owner\". Rendered as a short line under the project title. Localized, like the section-entry roles in `Career`/`Membership`/`Volunteering`."
438
+ },
428
439
  description: {
429
440
  $ref: "#/$defs/LocalizedBody"
430
441
  },
@@ -480,9 +491,17 @@ var $defs = {
480
491
  $ref: "#/$defs/Visibility"
481
492
  },
482
493
  label: {
483
- type: "string",
484
- minLength: 1,
485
- maxLength: 100
494
+ anyOf: [
495
+ {
496
+ type: "string",
497
+ minLength: 1,
498
+ maxLength: 100
499
+ },
500
+ {
501
+ $ref: "#/$defs/LocalizedTitle"
502
+ }
503
+ ],
504
+ description: "Skill name. A plain string is locale-independent; a localized map (added in 1.4.0) resolves per request locale. Existing single-string labels stay valid — the map form is purely additive."
486
505
  },
487
506
  category: {
488
507
  type: "string",
@@ -496,6 +515,26 @@ var $defs = {
496
515
  }
497
516
  }
498
517
  },
518
+ SkillCategory: {
519
+ type: "object",
520
+ additionalProperties: false,
521
+ required: [
522
+ "id",
523
+ "label"
524
+ ],
525
+ properties: {
526
+ id: {
527
+ type: "string",
528
+ minLength: 1,
529
+ maxLength: 64,
530
+ description: "Matches the `category` value on the skills that belong to this group."
531
+ },
532
+ label: {
533
+ $ref: "#/$defs/LocalizedTitle",
534
+ description: "Localized display heading for the group."
535
+ }
536
+ }
537
+ },
499
538
  Contact: {
500
539
  type: "object",
501
540
  additionalProperties: false,
@@ -569,9 +608,203 @@ var $defs = {
569
608
  },
570
609
  contact: {
571
610
  $ref: "#/$defs/ContactSettings"
611
+ },
612
+ appearance: {
613
+ $ref: "#/$defs/AppearanceSettings"
614
+ },
615
+ skillCategories: {
616
+ type: "array",
617
+ maxItems: 50,
618
+ items: {
619
+ $ref: "#/$defs/SkillCategory"
620
+ },
621
+ description: "Ordered skill-category display groups (added in 1.3.0). When present, the rendered profile groups skills by their `category` under these localized headings, in array order; absent = the flat skill list. A skill whose `category` is not listed here (or which has none) renders in a trailing group so nothing is dropped."
622
+ },
623
+ sectionOrder: {
624
+ type: "array",
625
+ uniqueItems: true,
626
+ maxItems: 18,
627
+ items: {
628
+ "enum": [
629
+ "about",
630
+ "careers",
631
+ "projects",
632
+ "volunteering",
633
+ "skills",
634
+ "activity",
635
+ "education",
636
+ "certifications",
637
+ "publications",
638
+ "honors",
639
+ "memberships",
640
+ "courses",
641
+ "patents",
642
+ "testScores",
643
+ "languages",
644
+ "recommendations",
645
+ "highlights",
646
+ "contact"
647
+ ]
648
+ },
649
+ description: "Explicit section display order (added in 1.4.0). A partial list is allowed — any renderable section not named here follows, in the default order. Absent = the default order."
650
+ },
651
+ sectionLabels: {
652
+ $ref: "#/$defs/SectionLabelOverrides"
653
+ },
654
+ highlightsIntro: {
655
+ $ref: "#/$defs/LocalizedTitle",
656
+ description: "Optional localized intro line shown under the highlights section heading (added in 1.4.0). Absent = no intro line."
657
+ }
658
+ }
659
+ },
660
+ SectionLabelOverrides: {
661
+ type: "object",
662
+ additionalProperties: false,
663
+ description: "Localized overrides for section headings and chrome labels (added in 1.4.0). Each present key retitles that label; the renderer merges these over its built-in locale pack. Absent keys keep the built-in label.",
664
+ properties: {
665
+ about: {
666
+ $ref: "#/$defs/LocalizedTitle"
667
+ },
668
+ careers: {
669
+ $ref: "#/$defs/LocalizedTitle"
670
+ },
671
+ projects: {
672
+ $ref: "#/$defs/LocalizedTitle"
673
+ },
674
+ volunteering: {
675
+ $ref: "#/$defs/LocalizedTitle"
676
+ },
677
+ skills: {
678
+ $ref: "#/$defs/LocalizedTitle"
679
+ },
680
+ activity: {
681
+ $ref: "#/$defs/LocalizedTitle"
682
+ },
683
+ education: {
684
+ $ref: "#/$defs/LocalizedTitle"
685
+ },
686
+ certifications: {
687
+ $ref: "#/$defs/LocalizedTitle"
688
+ },
689
+ publications: {
690
+ $ref: "#/$defs/LocalizedTitle"
691
+ },
692
+ honors: {
693
+ $ref: "#/$defs/LocalizedTitle"
694
+ },
695
+ memberships: {
696
+ $ref: "#/$defs/LocalizedTitle"
697
+ },
698
+ courses: {
699
+ $ref: "#/$defs/LocalizedTitle"
700
+ },
701
+ patents: {
702
+ $ref: "#/$defs/LocalizedTitle"
703
+ },
704
+ testScores: {
705
+ $ref: "#/$defs/LocalizedTitle"
706
+ },
707
+ languages: {
708
+ $ref: "#/$defs/LocalizedTitle"
709
+ },
710
+ recommendations: {
711
+ $ref: "#/$defs/LocalizedTitle"
712
+ },
713
+ highlights: {
714
+ $ref: "#/$defs/LocalizedTitle"
715
+ },
716
+ contact: {
717
+ $ref: "#/$defs/LocalizedTitle"
718
+ },
719
+ skipLink: {
720
+ $ref: "#/$defs/LocalizedTitle"
721
+ },
722
+ localeNav: {
723
+ $ref: "#/$defs/LocalizedTitle"
724
+ },
725
+ featuredLinks: {
726
+ $ref: "#/$defs/LocalizedTitle"
727
+ },
728
+ otherLinks: {
729
+ $ref: "#/$defs/LocalizedTitle"
730
+ },
731
+ poweredBy: {
732
+ $ref: "#/$defs/LocalizedTitle"
733
+ }
734
+ }
735
+ },
736
+ AppearanceSettings: {
737
+ type: "object",
738
+ additionalProperties: false,
739
+ description: "Opt-in design tokens for the rendered profile (added in 1.2.0). A declarative re-skin seam: owners override the standard renderer's built-in color and font defaults. This is a token map only, not arbitrary CSS — every value is length- and pattern-constrained so it cannot break out of the inline <style>. Overriding tokens re-skins the page but cannot re-layout it (spacing/radius/type-scale are intentionally not exposed). Absent = the built-in defaults are used unchanged.",
740
+ properties: {
741
+ fontFamily: {
742
+ type: "string",
743
+ minLength: 1,
744
+ maxLength: 256,
745
+ pattern: "^[A-Za-z0-9\\s,'\"._-]+$",
746
+ description: "CSS font-family stack for the page body, e.g. \"Inter, system-ui, sans-serif\". Quotes and commas are allowed; CSS-structural characters (; { } < >) are not."
747
+ },
748
+ colors: {
749
+ $ref: "#/$defs/AppearanceColors",
750
+ description: "Light-mode (:root) color overrides."
751
+ },
752
+ colorsDark: {
753
+ $ref: "#/$defs/AppearanceColors",
754
+ description: "Dark-mode (prefers-color-scheme: dark) color overrides. Note: until the standard renderer ships a default dark palette, only the keys set here change in dark mode."
572
755
  }
573
756
  }
574
757
  },
758
+ AppearanceColors: {
759
+ type: "object",
760
+ additionalProperties: false,
761
+ description: "A set of overridable color tokens. Each value is a CSS color (hex, rgb()/rgba(), hsl()/hsla(), or a named color); CSS-structural characters (; { } < > \" ' \\) are disallowed so a value cannot escape the inline <style>.",
762
+ properties: {
763
+ bg: {
764
+ $ref: "#/$defs/CssColor",
765
+ description: "Page background."
766
+ },
767
+ surface: {
768
+ $ref: "#/$defs/CssColor",
769
+ description: "Raised surfaces such as skill/tag chips."
770
+ },
771
+ text: {
772
+ $ref: "#/$defs/CssColor",
773
+ description: "Primary body text."
774
+ },
775
+ textMuted: {
776
+ $ref: "#/$defs/CssColor",
777
+ description: "Secondary/muted text (taglines, meta, captions)."
778
+ },
779
+ border: {
780
+ $ref: "#/$defs/CssColor",
781
+ description: "Hairline borders and rules."
782
+ },
783
+ accent: {
784
+ $ref: "#/$defs/CssColor",
785
+ description: "Accent color for emphasis and focus affordances."
786
+ },
787
+ primary: {
788
+ $ref: "#/$defs/CssColor",
789
+ description: "Primary interactive color, e.g. links."
790
+ },
791
+ primaryContrast: {
792
+ $ref: "#/$defs/CssColor",
793
+ description: "Foreground color used on top of the primary color."
794
+ },
795
+ heading: {
796
+ $ref: "#/$defs/CssColor",
797
+ description: "Heading color for the \"About\" section's Markdown sub-headings (##/###)."
798
+ }
799
+ }
800
+ },
801
+ CssColor: {
802
+ type: "string",
803
+ minLength: 1,
804
+ maxLength: 64,
805
+ pattern: "^(?:#[0-9A-Fa-f]{3,8}|[A-Za-z]+|(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\\([A-Za-z0-9.,%/\\s-]*\\))$",
806
+ description: "A CSS color value, restricted to a safe allowlist: a hex color (#rgb/#rgba/#rrggbb/#rrggbbaa), a bare keyword (named colors, currentColor, transparent), or a color function (rgb/rgba/hsl/hsla/hwb/lab/lch/oklab/oklch/color). url(), image-set(), var(), and other fetch- or reference-bearing functions are intentionally excluded so a value can never trigger an external request or escape the inline <style>."
807
+ },
575
808
  ContactSettings: {
576
809
  type: "object",
577
810
  additionalProperties: false,
@@ -667,6 +900,10 @@ var $defs = {
667
900
  type: "boolean",
668
901
  description: "Default true. When false, recommendations[] is emitted empty on public surfaces."
669
902
  },
903
+ highlights: {
904
+ type: "boolean",
905
+ description: "Default true. When false, highlights[] is emitted empty on public surfaces."
906
+ },
670
907
  contact: {
671
908
  type: "boolean",
672
909
  description: "Default true. When false, the contact section (email, formUrl) is emitted empty on public surfaces."
@@ -968,12 +1205,34 @@ var $defs = {
968
1205
  url: {
969
1206
  $ref: "#/$defs/Url"
970
1207
  },
1208
+ secondaryLink: {
1209
+ $ref: "#/$defs/SecondaryLink",
1210
+ description: "An optional second link for this entry (added in 1.4.0), rendered as a small pill beside the description — e.g. the organization's GitHub org page next to its main site. The brand glyph is resolved from the URL host; no vendor name is hard-coded."
1211
+ },
971
1212
  order: {
972
1213
  type: "integer",
973
1214
  minimum: 0
974
1215
  }
975
1216
  }
976
1217
  },
1218
+ SecondaryLink: {
1219
+ type: "object",
1220
+ additionalProperties: false,
1221
+ required: [
1222
+ "url"
1223
+ ],
1224
+ description: "A supplementary link with an optional localized label (added in 1.4.0). When the label is absent the renderer shows the URL host. The brand glyph is resolved from the URL host.",
1225
+ properties: {
1226
+ url: {
1227
+ $ref: "#/$defs/Url",
1228
+ description: "The link target."
1229
+ },
1230
+ label: {
1231
+ $ref: "#/$defs/LocalizedTitle",
1232
+ description: "Localized display label. When absent, the renderer derives a label from the URL host."
1233
+ }
1234
+ }
1235
+ },
977
1236
  Honor: {
978
1237
  type: "object",
979
1238
  additionalProperties: false,
@@ -1377,6 +1636,74 @@ var $defs = {
1377
1636
  description: "Link to the recommender's profile, for external verification by the reader."
1378
1637
  }
1379
1638
  }
1639
+ },
1640
+ Highlight: {
1641
+ type: "object",
1642
+ additionalProperties: false,
1643
+ required: [
1644
+ "id",
1645
+ "platform",
1646
+ "url",
1647
+ "image",
1648
+ "alt",
1649
+ "title"
1650
+ ],
1651
+ description: "One curated \"selected post\" (added in 1.4.0), rendered as a card in the highlights carousel. A hand-picked link to an off-site post (Instagram, X, a blog, a talk, …) with a self-hosted thumbnail — deliberately not an automated social feed. Appears on the public page, /api/profile, /takuhon.json, and MCP; it is intentionally omitted from JSON-LD and the derived CV (no natural vocabulary/résumé slot).",
1652
+ properties: {
1653
+ id: {
1654
+ $ref: "#/$defs/Slug"
1655
+ },
1656
+ visibility: {
1657
+ $ref: "#/$defs/Visibility"
1658
+ },
1659
+ platform: {
1660
+ type: "string",
1661
+ minLength: 1,
1662
+ maxLength: 64,
1663
+ description: "Free-form source platform (e.g. 'instagram', 'x', 'github', 'blog', 'event'). A value with a matching brand glyph renders a badge icon; others fall back to a text badge. Not an enum, so new platforms need no schema change."
1664
+ },
1665
+ url: {
1666
+ $ref: "#/$defs/Url",
1667
+ description: "Permalink to the original post; the card links here."
1668
+ },
1669
+ image: {
1670
+ type: "string",
1671
+ format: "uri-reference",
1672
+ maxLength: 2048,
1673
+ description: "Self-hosted thumbnail, as an absolute URL or a root-relative path (like avatar). Serving the asset is the deployment's responsibility (a static build does not copy it; a Cloudflare deploy serves it via its assets binding / /assets/*). Do not point at a third-party CDN URL — those can be signed/expiring and leak visitor data."
1674
+ },
1675
+ alt: {
1676
+ $ref: "#/$defs/LocalizedTitle",
1677
+ description: "Required alt text for the thumbnail — the card must not depend on the image alone."
1678
+ },
1679
+ title: {
1680
+ $ref: "#/$defs/LocalizedTitle",
1681
+ description: "Localized card title / caption."
1682
+ },
1683
+ description: {
1684
+ $ref: "#/$defs/LocalizedBody",
1685
+ description: "Optional localized supporting text shown under the title."
1686
+ },
1687
+ postedAt: {
1688
+ type: "string",
1689
+ format: "date",
1690
+ pattern: "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$",
1691
+ description: "Optional post date, ISO 'YYYY-MM-DD' (full date, unlike the YYYY-MM dates used elsewhere — a post has a specific day)."
1692
+ },
1693
+ tags: {
1694
+ type: "array",
1695
+ maxItems: 30,
1696
+ items: {
1697
+ type: "string",
1698
+ minLength: 1,
1699
+ maxLength: 50
1700
+ }
1701
+ },
1702
+ order: {
1703
+ type: "integer",
1704
+ minimum: 0
1705
+ }
1706
+ }
1380
1707
  }
1381
1708
  };
1382
1709
  var schemaJson = {
@@ -1522,6 +1849,13 @@ declare const schema: {
1522
1849
  $ref: string;
1523
1850
  };
1524
1851
  };
1852
+ highlights: {
1853
+ type: string;
1854
+ maxItems: number;
1855
+ items: {
1856
+ $ref: string;
1857
+ };
1858
+ };
1525
1859
  contact: {
1526
1860
  $ref: string;
1527
1861
  };
@@ -1780,6 +2114,10 @@ declare const schema: {
1780
2114
  title: {
1781
2115
  $ref: string;
1782
2116
  };
2117
+ role: {
2118
+ $ref: string;
2119
+ description: string;
2120
+ };
1783
2121
  description: {
1784
2122
  $ref: string;
1785
2123
  };
@@ -1831,9 +2169,18 @@ declare const schema: {
1831
2169
  $ref: string;
1832
2170
  };
1833
2171
  label: {
1834
- type: string;
1835
- minLength: number;
1836
- maxLength: number;
2172
+ anyOf: ({
2173
+ type: string;
2174
+ minLength: number;
2175
+ maxLength: number;
2176
+ $ref?: undefined;
2177
+ } | {
2178
+ $ref: string;
2179
+ type?: undefined;
2180
+ minLength?: undefined;
2181
+ maxLength?: undefined;
2182
+ })[];
2183
+ description: string;
1837
2184
  };
1838
2185
  category: {
1839
2186
  type: string;
@@ -1847,6 +2194,23 @@ declare const schema: {
1847
2194
  };
1848
2195
  };
1849
2196
  };
2197
+ SkillCategory: {
2198
+ type: string;
2199
+ additionalProperties: boolean;
2200
+ required: string[];
2201
+ properties: {
2202
+ id: {
2203
+ type: string;
2204
+ minLength: number;
2205
+ maxLength: number;
2206
+ description: string;
2207
+ };
2208
+ label: {
2209
+ $ref: string;
2210
+ description: string;
2211
+ };
2212
+ };
2213
+ };
1850
2214
  Contact: {
1851
2215
  type: string;
1852
2216
  additionalProperties: boolean;
@@ -1918,11 +2282,186 @@ declare const schema: {
1918
2282
  contact: {
1919
2283
  $ref: string;
1920
2284
  };
1921
- };
1922
- };
1923
- ContactSettings: {
1924
- type: string;
1925
- additionalProperties: boolean;
2285
+ appearance: {
2286
+ $ref: string;
2287
+ };
2288
+ skillCategories: {
2289
+ type: string;
2290
+ maxItems: number;
2291
+ items: {
2292
+ $ref: string;
2293
+ };
2294
+ description: string;
2295
+ };
2296
+ sectionOrder: {
2297
+ type: string;
2298
+ uniqueItems: boolean;
2299
+ maxItems: number;
2300
+ items: {
2301
+ enum: string[];
2302
+ };
2303
+ description: string;
2304
+ };
2305
+ sectionLabels: {
2306
+ $ref: string;
2307
+ };
2308
+ highlightsIntro: {
2309
+ $ref: string;
2310
+ description: string;
2311
+ };
2312
+ };
2313
+ };
2314
+ SectionLabelOverrides: {
2315
+ type: string;
2316
+ additionalProperties: boolean;
2317
+ description: string;
2318
+ properties: {
2319
+ about: {
2320
+ $ref: string;
2321
+ };
2322
+ careers: {
2323
+ $ref: string;
2324
+ };
2325
+ projects: {
2326
+ $ref: string;
2327
+ };
2328
+ volunteering: {
2329
+ $ref: string;
2330
+ };
2331
+ skills: {
2332
+ $ref: string;
2333
+ };
2334
+ activity: {
2335
+ $ref: string;
2336
+ };
2337
+ education: {
2338
+ $ref: string;
2339
+ };
2340
+ certifications: {
2341
+ $ref: string;
2342
+ };
2343
+ publications: {
2344
+ $ref: string;
2345
+ };
2346
+ honors: {
2347
+ $ref: string;
2348
+ };
2349
+ memberships: {
2350
+ $ref: string;
2351
+ };
2352
+ courses: {
2353
+ $ref: string;
2354
+ };
2355
+ patents: {
2356
+ $ref: string;
2357
+ };
2358
+ testScores: {
2359
+ $ref: string;
2360
+ };
2361
+ languages: {
2362
+ $ref: string;
2363
+ };
2364
+ recommendations: {
2365
+ $ref: string;
2366
+ };
2367
+ highlights: {
2368
+ $ref: string;
2369
+ };
2370
+ contact: {
2371
+ $ref: string;
2372
+ };
2373
+ skipLink: {
2374
+ $ref: string;
2375
+ };
2376
+ localeNav: {
2377
+ $ref: string;
2378
+ };
2379
+ featuredLinks: {
2380
+ $ref: string;
2381
+ };
2382
+ otherLinks: {
2383
+ $ref: string;
2384
+ };
2385
+ poweredBy: {
2386
+ $ref: string;
2387
+ };
2388
+ };
2389
+ };
2390
+ AppearanceSettings: {
2391
+ type: string;
2392
+ additionalProperties: boolean;
2393
+ description: string;
2394
+ properties: {
2395
+ fontFamily: {
2396
+ type: string;
2397
+ minLength: number;
2398
+ maxLength: number;
2399
+ pattern: string;
2400
+ description: string;
2401
+ };
2402
+ colors: {
2403
+ $ref: string;
2404
+ description: string;
2405
+ };
2406
+ colorsDark: {
2407
+ $ref: string;
2408
+ description: string;
2409
+ };
2410
+ };
2411
+ };
2412
+ AppearanceColors: {
2413
+ type: string;
2414
+ additionalProperties: boolean;
2415
+ description: string;
2416
+ properties: {
2417
+ bg: {
2418
+ $ref: string;
2419
+ description: string;
2420
+ };
2421
+ surface: {
2422
+ $ref: string;
2423
+ description: string;
2424
+ };
2425
+ text: {
2426
+ $ref: string;
2427
+ description: string;
2428
+ };
2429
+ textMuted: {
2430
+ $ref: string;
2431
+ description: string;
2432
+ };
2433
+ border: {
2434
+ $ref: string;
2435
+ description: string;
2436
+ };
2437
+ accent: {
2438
+ $ref: string;
2439
+ description: string;
2440
+ };
2441
+ primary: {
2442
+ $ref: string;
2443
+ description: string;
2444
+ };
2445
+ primaryContrast: {
2446
+ $ref: string;
2447
+ description: string;
2448
+ };
2449
+ heading: {
2450
+ $ref: string;
2451
+ description: string;
2452
+ };
2453
+ };
2454
+ };
2455
+ CssColor: {
2456
+ type: string;
2457
+ minLength: number;
2458
+ maxLength: number;
2459
+ pattern: string;
2460
+ description: string;
2461
+ };
2462
+ ContactSettings: {
2463
+ type: string;
2464
+ additionalProperties: boolean;
1926
2465
  description: string;
1927
2466
  properties: {
1928
2467
  enabled: {
@@ -2015,6 +2554,10 @@ declare const schema: {
2015
2554
  type: string;
2016
2555
  description: string;
2017
2556
  };
2557
+ highlights: {
2558
+ type: string;
2559
+ description: string;
2560
+ };
2018
2561
  contact: {
2019
2562
  type: string;
2020
2563
  description: string;
@@ -2291,12 +2834,32 @@ declare const schema: {
2291
2834
  url: {
2292
2835
  $ref: string;
2293
2836
  };
2837
+ secondaryLink: {
2838
+ $ref: string;
2839
+ description: string;
2840
+ };
2294
2841
  order: {
2295
2842
  type: string;
2296
2843
  minimum: number;
2297
2844
  };
2298
2845
  };
2299
2846
  };
2847
+ SecondaryLink: {
2848
+ type: string;
2849
+ additionalProperties: boolean;
2850
+ required: string[];
2851
+ description: string;
2852
+ properties: {
2853
+ url: {
2854
+ $ref: string;
2855
+ description: string;
2856
+ };
2857
+ label: {
2858
+ $ref: string;
2859
+ description: string;
2860
+ };
2861
+ };
2862
+ };
2300
2863
  Honor: {
2301
2864
  type: string;
2302
2865
  additionalProperties: boolean;
@@ -2653,10 +3216,115 @@ declare const schema: {
2653
3216
  };
2654
3217
  };
2655
3218
  };
3219
+ Highlight: {
3220
+ type: string;
3221
+ additionalProperties: boolean;
3222
+ required: string[];
3223
+ description: string;
3224
+ properties: {
3225
+ id: {
3226
+ $ref: string;
3227
+ };
3228
+ visibility: {
3229
+ $ref: string;
3230
+ };
3231
+ platform: {
3232
+ type: string;
3233
+ minLength: number;
3234
+ maxLength: number;
3235
+ description: string;
3236
+ };
3237
+ url: {
3238
+ $ref: string;
3239
+ description: string;
3240
+ };
3241
+ image: {
3242
+ type: string;
3243
+ format: string;
3244
+ maxLength: number;
3245
+ description: string;
3246
+ };
3247
+ alt: {
3248
+ $ref: string;
3249
+ description: string;
3250
+ };
3251
+ title: {
3252
+ $ref: string;
3253
+ description: string;
3254
+ };
3255
+ description: {
3256
+ $ref: string;
3257
+ description: string;
3258
+ };
3259
+ postedAt: {
3260
+ type: string;
3261
+ format: string;
3262
+ pattern: string;
3263
+ description: string;
3264
+ };
3265
+ tags: {
3266
+ type: string;
3267
+ maxItems: number;
3268
+ items: {
3269
+ type: string;
3270
+ minLength: number;
3271
+ maxLength: number;
3272
+ };
3273
+ };
3274
+ order: {
3275
+ type: string;
3276
+ minimum: number;
3277
+ };
3278
+ };
3279
+ };
2656
3280
  };
2657
3281
  };
2658
3282
  type Schema = typeof schemaJson;
2659
3283
 
3284
+ /**
3285
+ * The canonical set — and default order — of the profile sections the standard
3286
+ * renderer emits. One key per orderable `<section>`.
3287
+ *
3288
+ * This is the single source of truth for section identity and default ordering,
3289
+ * shared so the renderer, `settings.sectionOrder`, and the section-level privacy
3290
+ * controls cannot drift apart. Two kinds of keys appear:
3291
+ *
3292
+ * - **Data sections** — the array/object sections of the document, named exactly
3293
+ * as in {@link PublicVisibility} (`careers`, `projects`, `highlights`, …). A
3294
+ * parity test guarantees every visibility-controlled data section is
3295
+ * represented here. `highlights` (the curated "selected posts" carousel, its
3296
+ * own top-level array added in 1.4.0) is one of these.
3297
+ * - **Page-only sections** — `about` (rendered from `profile.bio`) and
3298
+ * `activity` (rendered from a synced snapshot, not stored document data).
3299
+ *
3300
+ * `links` is deliberately absent: featured links render at the top and the
3301
+ * remaining links render as a fixed bottom section, so link placement is not
3302
+ * part of the reorderable section flow.
3303
+ *
3304
+ * The array order is the renderer's default section order; a caller may render a
3305
+ * subset in a different order, but unlisted sections keep this ordering.
3306
+ */
3307
+ declare const SECTION_KEYS: readonly ["about", "careers", "projects", "volunteering", "skills", "activity", "education", "certifications", "publications", "honors", "memberships", "courses", "patents", "testScores", "languages", "recommendations", "highlights", "contact"];
3308
+ /** One of the canonical {@link SECTION_KEYS}. */
3309
+ type SectionKey = (typeof SECTION_KEYS)[number];
3310
+ /**
3311
+ * Non-section "chrome" labels the renderer emits (skip link, nav aria-labels,
3312
+ * the other-links heading, the footer credit lead-in). Together with the
3313
+ * section headings these form the full set of localizable labels a caller can
3314
+ * override.
3315
+ */
3316
+ declare const CHROME_LABEL_KEYS: readonly ["skipLink", "localeNav", "featuredLinks", "otherLinks", "poweredBy"];
3317
+ /**
3318
+ * Every overridable label key: one per {@link SECTION_KEYS} heading plus the
3319
+ * {@link CHROME_LABEL_KEYS}. This is the single source of truth for the label
3320
+ * set shared by the renderer's `SectionLabels`, the `settings.sectionLabels`
3321
+ * data override, and the per-request label override — so all three stay in
3322
+ * lock-step.
3323
+ */
3324
+ declare const LABEL_KEYS: readonly ["about", "careers", "projects", "volunteering", "skills", "activity", "education", "certifications", "publications", "honors", "memberships", "courses", "patents", "testScores", "languages", "recommendations", "highlights", "contact", "skipLink", "localeNav", "featuredLinks", "otherLinks", "poweredBy"];
3325
+ /** One of the {@link LABEL_KEYS}. */
3326
+ type LabelKey = (typeof LABEL_KEYS)[number];
3327
+
2660
3328
  /**
2661
3329
  * TypeScript types for takuhon profile data.
2662
3330
  *
@@ -2699,6 +3367,7 @@ type Schema = typeof schemaJson;
2699
3367
  * alongside a profile should keep it in a sibling structure rather than
2700
3368
  * smuggling undeclared keys into the contract — schema 1.0.0 now rejects them.
2701
3369
  */
3370
+
2702
3371
  /** BCP-47 language tag, e.g. 'en', 'ja', 'zh-Hant', 'pt-BR'. */
2703
3372
  type LocaleTag = string;
2704
3373
  /** ISO 3166-1 alpha-2 country code, uppercase, two letters (e.g. 'JP', 'PT'). */
@@ -2790,6 +3459,12 @@ interface Career extends VisibilityControlled {
2790
3459
  interface Project extends VisibilityControlled {
2791
3460
  id: Slug;
2792
3461
  title: LocalizedTitle;
3462
+ /**
3463
+ * The owner's role/relationship on this project (added in 1.4.0), e.g.
3464
+ * "Author & lead maintainer". Rendered as a short line under the title.
3465
+ * Localized, like {@link Career.role}.
3466
+ */
3467
+ role?: LocalizedTitle;
2793
3468
  description?: LocalizedBody;
2794
3469
  url?: string;
2795
3470
  tags?: string[];
@@ -2801,7 +3476,12 @@ interface Project extends VisibilityControlled {
2801
3476
  }
2802
3477
  interface Skill extends VisibilityControlled {
2803
3478
  id: Slug;
2804
- label: string;
3479
+ /**
3480
+ * Skill name. A plain `string` is locale-independent; a {@link LocalizedTitle}
3481
+ * map (added in 1.4.0) resolves per request locale. The map form is purely
3482
+ * additive — existing single-string labels stay valid.
3483
+ */
3484
+ label: string | LocalizedTitle;
2805
3485
  /**
2806
3486
  * Recommended values (extensible): programming, design, business, communication,
2807
3487
  * language, music, art, sports, other.
@@ -2846,8 +3526,20 @@ interface Volunteering extends VisibilityControlled {
2846
3526
  endDate?: YearMonth | null;
2847
3527
  isCurrent?: boolean;
2848
3528
  url?: string;
3529
+ /** An optional second link (added in 1.4.0), e.g. the organization's GitHub org page. */
3530
+ secondaryLink?: SecondaryLink;
2849
3531
  order?: number;
2850
3532
  }
3533
+ /**
3534
+ * A supplementary link with an optional localized label (added in 1.4.0). Used by
3535
+ * {@link Volunteering.secondaryLink}. The renderer resolves the brand glyph from
3536
+ * the URL host and, when {@link SecondaryLink.label} is absent, derives a display
3537
+ * label from the host too.
3538
+ */
3539
+ interface SecondaryLink {
3540
+ url: string;
3541
+ label?: LocalizedTitle;
3542
+ }
2851
3543
  interface Honor extends VisibilityControlled {
2852
3544
  id: Slug;
2853
3545
  title: LocalizedTitle;
@@ -2964,6 +3656,41 @@ interface Recommendation extends VisibilityControlled {
2964
3656
  relatedEducationId?: Slug;
2965
3657
  order?: number;
2966
3658
  }
3659
+ /**
3660
+ * One curated "selected post" (added in 1.4.0), rendered as a card in the
3661
+ * highlights carousel: a hand-picked link to an off-site post (Instagram, X, a
3662
+ * blog, a talk, …) with a self-hosted thumbnail — deliberately not an automated
3663
+ * social feed. It appears on the public page, `/api/profile`, `/takuhon.json`,
3664
+ * and MCP, but is intentionally omitted from JSON-LD and the derived CV (no
3665
+ * natural vocabulary / résumé slot for it).
3666
+ */
3667
+ interface Highlight extends VisibilityControlled {
3668
+ id: Slug;
3669
+ /**
3670
+ * Free-form source platform (e.g. `'instagram'`, `'x'`, `'github'`, `'blog'`,
3671
+ * `'event'`). A value with a matching brand glyph renders a badge icon; others
3672
+ * fall back to a text badge. Not an enum, so new platforms need no schema
3673
+ * change.
3674
+ */
3675
+ platform: string;
3676
+ /** Permalink to the original post; the card links here. */
3677
+ url: string;
3678
+ /**
3679
+ * Self-hosted thumbnail, as an absolute URL or a root-relative path (like
3680
+ * {@link Avatar.url}). Serving the asset is the deployment's responsibility.
3681
+ */
3682
+ image: string;
3683
+ /** Required alt text for the thumbnail — the card must not rely on the image alone. */
3684
+ alt: LocalizedTitle;
3685
+ /** Localized card title / caption. */
3686
+ title: LocalizedTitle;
3687
+ /** Optional localized supporting text shown under the title. */
3688
+ description?: LocalizedBody;
3689
+ /** Optional post date, ISO `YYYY-MM-DD` (a full date, unlike the YYYY-MM used elsewhere). */
3690
+ postedAt?: string;
3691
+ tags?: string[];
3692
+ order?: number;
3693
+ }
2967
3694
  interface Contact {
2968
3695
  email?: string;
2969
3696
  showEmail?: boolean;
@@ -2989,6 +3716,98 @@ interface Settings {
2989
3716
  publicVisibility?: PublicVisibility;
2990
3717
  /** Opt-in contact form (added in 1.1.0). Absent = no contact form. */
2991
3718
  contact?: ContactSettings;
3719
+ /** Opt-in design tokens for the rendered profile (added in 1.2.0). Absent = built-in defaults. */
3720
+ appearance?: AppearanceSettings;
3721
+ /**
3722
+ * Ordered skill-category display groups (added in 1.3.0). When present, the
3723
+ * rendered profile groups skills by their `category` under these localized
3724
+ * headings, in array order; absent = the flat skill list. A skill whose
3725
+ * `category` is unlisted (or absent) renders in a trailing group.
3726
+ */
3727
+ skillCategories?: SkillCategory[];
3728
+ /**
3729
+ * Explicit section display order (added in 1.4.0). A partial list is allowed:
3730
+ * any renderable section not named here follows, in the default order. Absent
3731
+ * = the default order. Keys are the canonical {@link SectionKey}s.
3732
+ */
3733
+ sectionOrder?: SectionKey[];
3734
+ /**
3735
+ * Localized overrides for section headings and chrome labels (added in 1.4.0).
3736
+ * A partial map keyed by {@link LabelKey}; the renderer merges it over the
3737
+ * built-in locale pack and under a per-request override, so an owner can
3738
+ * retitle any section or chrome label straight from `takuhon.json`. Absent =
3739
+ * the built-in labels.
3740
+ */
3741
+ sectionLabels?: SectionLabelOverrides;
3742
+ /**
3743
+ * Localized intro line shown under the highlights section heading (added in
3744
+ * 1.4.0). Absent = no intro line.
3745
+ */
3746
+ highlightsIntro?: LocalizedTitle;
3747
+ }
3748
+ /** Localized label overrides for {@link Settings.sectionLabels}. */
3749
+ type SectionLabelOverrides = Partial<Record<LabelKey, LocalizedTitle>>;
3750
+ /**
3751
+ * One skill-category display group (added in 1.3.0). Maps a `Skill.category`
3752
+ * value to a localized heading; the array position in {@link
3753
+ * Settings.skillCategories} defines the group's display order.
3754
+ */
3755
+ interface SkillCategory {
3756
+ /** Matches the `category` value on the skills that belong to this group. */
3757
+ id: string;
3758
+ /** Localized display heading for the group. */
3759
+ label: LocalizedTitle;
3760
+ }
3761
+ /**
3762
+ * Opt-in design tokens for the rendered profile (added in 1.2.0).
3763
+ *
3764
+ * A declarative re-skin seam: owners override the standard renderer's built-in
3765
+ * color and font defaults. This is a token map only — never arbitrary CSS — so
3766
+ * every value is length- and pattern-constrained (see the schema) and cannot
3767
+ * break out of the inline `<style>`. Overriding tokens re-skins the page but
3768
+ * cannot re-layout it; spacing, radius, and the type scale are intentionally
3769
+ * not exposed. An absent block leaves the built-in defaults unchanged.
3770
+ */
3771
+ interface AppearanceSettings {
3772
+ /** CSS font-family stack for the page body, e.g. `"Inter, system-ui, sans-serif"`. */
3773
+ fontFamily?: string;
3774
+ /** Light-mode (`:root`) color overrides. */
3775
+ colors?: AppearanceColors;
3776
+ /**
3777
+ * Dark-mode (`prefers-color-scheme: dark`) color overrides. Until the
3778
+ * standard renderer ships a default dark palette, only the keys set here
3779
+ * change in dark mode.
3780
+ */
3781
+ colorsDark?: AppearanceColors;
3782
+ }
3783
+ /**
3784
+ * Overridable color tokens (added in 1.2.0). Each value is a CSS color (hex,
3785
+ * `rgb()`/`rgba()`, `hsl()`/`hsla()`, or a named color); CSS-structural
3786
+ * characters are disallowed so a value cannot escape the inline `<style>`.
3787
+ */
3788
+ interface AppearanceColors {
3789
+ /** Page background. */
3790
+ bg?: string;
3791
+ /** Raised surfaces such as skill/tag chips. */
3792
+ surface?: string;
3793
+ /** Primary body text. */
3794
+ text?: string;
3795
+ /** Secondary/muted text (taglines, meta, captions). */
3796
+ textMuted?: string;
3797
+ /** Hairline borders and rules. */
3798
+ border?: string;
3799
+ /** Accent color for emphasis and focus affordances. */
3800
+ accent?: string;
3801
+ /** Primary interactive color, e.g. links. */
3802
+ primary?: string;
3803
+ /** Foreground color used on top of the primary color. */
3804
+ primaryContrast?: string;
3805
+ /**
3806
+ * Heading color for the "About" section's Markdown sub-headings (`##`/`###`).
3807
+ * Defaults to a deep indigo (light) / soft indigo (dark) so sub-headings stand
3808
+ * out from body text; override to re-tint them.
3809
+ */
3810
+ heading?: string;
2992
3811
  }
2993
3812
  /**
2994
3813
  * Owner-curated configuration for the opt-in contact form (added in 1.1.0).
@@ -3040,6 +3859,7 @@ interface PublicVisibility {
3040
3859
  patents?: boolean;
3041
3860
  testScores?: boolean;
3042
3861
  recommendations?: boolean;
3862
+ highlights?: boolean;
3043
3863
  contact?: boolean;
3044
3864
  }
3045
3865
  /**
@@ -3125,6 +3945,7 @@ interface Takuhon {
3125
3945
  patents: Patent[];
3126
3946
  testScores: TestScore[];
3127
3947
  recommendations: Recommendation[];
3948
+ highlights: Highlight[];
3128
3949
  contact: Contact;
3129
3950
  settings: Settings;
3130
3951
  meta: Meta;
@@ -3196,6 +4017,8 @@ interface LocalizedCareer extends VisibilityControlled {
3196
4017
  interface LocalizedProject extends VisibilityControlled {
3197
4018
  id: Slug;
3198
4019
  title: string;
4020
+ /** Resolved {@link Project.role} for the active locale (added in 1.4.0). */
4021
+ role?: string;
3199
4022
  description?: string;
3200
4023
  url?: string;
3201
4024
  tags?: string[];
@@ -3228,6 +4051,11 @@ interface LocalizedMembership extends VisibilityControlled {
3228
4051
  url?: string;
3229
4052
  order?: number;
3230
4053
  }
4054
+ /** {@link SecondaryLink} with its localized label collapsed to a single string. */
4055
+ interface LocalizedSecondaryLink {
4056
+ url: string;
4057
+ label?: string;
4058
+ }
3231
4059
  /** Volunteering with localized fields collapsed to single strings. */
3232
4060
  interface LocalizedVolunteering extends VisibilityControlled {
3233
4061
  id: Slug;
@@ -3239,6 +4067,7 @@ interface LocalizedVolunteering extends VisibilityControlled {
3239
4067
  endDate?: YearMonth | null;
3240
4068
  isCurrent?: boolean;
3241
4069
  url?: string;
4070
+ secondaryLink?: LocalizedSecondaryLink;
3242
4071
  order?: number;
3243
4072
  }
3244
4073
  /** Honor with localized fields collapsed to single strings. */
@@ -3339,13 +4168,60 @@ interface LocalizedRecommendation extends VisibilityControlled {
3339
4168
  relatedEducationId?: Slug;
3340
4169
  order?: number;
3341
4170
  }
4171
+ /** Highlight with `alt`, `title`, `description` collapsed to single strings. */
4172
+ interface LocalizedHighlight extends VisibilityControlled {
4173
+ id: Slug;
4174
+ platform: string;
4175
+ url: string;
4176
+ image: string;
4177
+ alt: string;
4178
+ title: string;
4179
+ description?: string;
4180
+ postedAt?: string;
4181
+ tags?: string[];
4182
+ order?: number;
4183
+ }
4184
+ /**
4185
+ * {@link Skill} after locale resolution: its `label` — a plain string or a
4186
+ * localized map — collapsed to the single resolved string. Every other field
4187
+ * passes through unchanged.
4188
+ */
4189
+ interface LocalizedSkill extends VisibilityControlled {
4190
+ id: Slug;
4191
+ label: string;
4192
+ category?: string;
4193
+ order?: number;
4194
+ }
4195
+ /**
4196
+ * One skill-category group after locale resolution: the localized `label` map
4197
+ * collapsed to the single resolved string. See {@link SkillCategory}.
4198
+ */
4199
+ interface LocalizedSkillCategory {
4200
+ id: string;
4201
+ label: string;
4202
+ }
4203
+ /**
4204
+ * {@link Settings} after locale resolution. Identical to the raw settings
4205
+ * except `skillCategories` labels are collapsed to single resolved strings
4206
+ * ({@link LocalizedSkillCategory}); every other settings field is passed
4207
+ * through unchanged.
4208
+ */
4209
+ type LocalizedSettings = Omit<Settings, 'skillCategories' | 'sectionLabels' | 'highlightsIntro'> & {
4210
+ skillCategories?: LocalizedSkillCategory[];
4211
+ /** {@link Settings.sectionLabels} with each value collapsed to the resolved string. */
4212
+ sectionLabels?: Partial<Record<LabelKey, string>>;
4213
+ /** {@link Settings.highlightsIntro} collapsed to the resolved string. */
4214
+ highlightsIntro?: string;
4215
+ };
3342
4216
  /**
3343
4217
  * A takuhon document with every localized map flattened to a single string,
3344
4218
  * plus a `resolvedLocale` field recording which tag was actually used as the
3345
4219
  * head of the fallback chain. `resolveLocale()` returns this shape.
3346
4220
  *
3347
- * `Skill`, `Contact`, `Settings`, and `Meta` carry no localized fields and
3348
- * pass through unchanged.
4221
+ * `Contact` and `Meta` carry no localized fields and pass through unchanged;
4222
+ * `Settings` passes through too, except its `skillCategories` labels are
4223
+ * resolved to the single locale string (see {@link LocalizedSettings}). `Skill`
4224
+ * becomes {@link LocalizedSkill} once its `label` can be a localized map (1.4.0).
3349
4225
  */
3350
4226
  interface LocalizedTakuhon {
3351
4227
  schemaVersion: string;
@@ -3353,7 +4229,7 @@ interface LocalizedTakuhon {
3353
4229
  links: LocalizedLink[];
3354
4230
  careers: LocalizedCareer[];
3355
4231
  projects: LocalizedProject[];
3356
- skills: Skill[];
4232
+ skills: LocalizedSkill[];
3357
4233
  certifications: LocalizedCertification[];
3358
4234
  memberships: LocalizedMembership[];
3359
4235
  volunteering: LocalizedVolunteering[];
@@ -3365,8 +4241,9 @@ interface LocalizedTakuhon {
3365
4241
  patents: LocalizedPatent[];
3366
4242
  testScores: LocalizedTestScore[];
3367
4243
  recommendations: LocalizedRecommendation[];
4244
+ highlights: LocalizedHighlight[];
3368
4245
  contact: Contact;
3369
- settings: Settings;
4246
+ settings: LocalizedSettings;
3370
4247
  meta: Meta;
3371
4248
  /**
3372
4249
  * The locale tag that was matched first by the fallback chain and used as
@@ -3412,7 +4289,7 @@ interface LocalizedTakuhon {
3412
4289
  * versions whose JSON Schema this package literally bundles, not the full
3413
4290
  * support window seen by end users.
3414
4291
  */
3415
- declare const SUPPORTED_SCHEMA_VERSIONS: readonly ["0.1.0", "0.2.0", "0.3.0", "0.4.0", "0.5.0", "0.6.0", "0.7.0", "1.0.0", "1.1.0"];
4292
+ declare const SUPPORTED_SCHEMA_VERSIONS: readonly ["0.1.0", "0.2.0", "0.3.0", "0.4.0", "0.5.0", "0.6.0", "0.7.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0", "1.4.0"];
3416
4293
  /**
3417
4294
  * A single validation failure.
3418
4295
  *
@@ -3553,6 +4430,10 @@ declare function resolveLocale(data: Takuhon, locale?: string, fallbackLocale?:
3553
4430
  * no placeholder is fabricated.
3554
4431
  * - `profile.tagline` is intentionally not surfaced. `description` carries
3555
4432
  * `profile.bio` only, matching the spec exemplar. Phase 2 may revisit.
4433
+ * - The curated `highlights` (selected posts) are intentionally NOT surfaced:
4434
+ * Schema.org has no natural vocabulary for an owner-curated set of off-site
4435
+ * posts, so they stay a page/API/MCP feature and are absent from JSON-LD (a
4436
+ * deliberate omission, consistent with the derived CV).
3556
4437
  * - `contact.email` is surfaced only when `contact.showEmail === true`
3557
4438
  * (privacy by default).
3558
4439
  * - URLs pass through verbatim. Relative paths in the input remain relative
@@ -4185,8 +5066,9 @@ declare function renderActivitySvg(snapshot: ActivitySnapshot, options?: RenderA
4185
5066
  * same input.
4186
5067
  *
4187
5068
  * A CV is a curated *subset* of the profile: the web-page-specific sections
4188
- * (links, recommendations, the activity dashboard, test scores) are omitted,
4189
- * and the rest appear in the order a résumé conventionally uses. Entry order
5069
+ * (links, recommendations, the activity dashboard, test scores, and the
5070
+ * curated `highlights` carousel) are omitted, and the rest appear in the order
5071
+ * a résumé conventionally uses. Entry order
4190
5072
  * within a section is preserved from the input (already normalized by `order`
4191
5073
  * upstream), so the owner's `order` field controls it — `deriveCv` never
4192
5074
  * re-sorts. Empty sections are dropped so the renderer can iterate without
@@ -4220,7 +5102,7 @@ type CvSection = {
4220
5102
  entries: LocalizedEducation[];
4221
5103
  } | {
4222
5104
  kind: 'skills';
4223
- entries: Skill[];
5105
+ entries: LocalizedSkill[];
4224
5106
  } | {
4225
5107
  kind: 'certifications';
4226
5108
  entries: LocalizedCertification[];
@@ -4367,7 +5249,7 @@ declare function getPresentLabel(locale: LocaleTag): string;
4367
5249
  * `meta`, `schemaVersion`, and `resolvedLocale` are intentionally excluded —
4368
5250
  * they are configuration / bookkeeping, not profile content an agent reads.
4369
5251
  */
4370
- declare const MCP_PROFILE_SECTIONS: readonly ["profile", "links", "careers", "projects", "skills", "certifications", "memberships", "volunteering", "honors", "education", "publications", "languages", "courses", "patents", "testScores", "recommendations", "contact"];
5252
+ declare const MCP_PROFILE_SECTIONS: readonly ["profile", "links", "careers", "projects", "skills", "certifications", "memberships", "volunteering", "honors", "education", "publications", "languages", "courses", "patents", "testScores", "recommendations", "highlights", "contact"];
4371
5253
  /** One of the {@link MCP_PROFILE_SECTIONS} a `get_section` call accepts. */
4372
5254
  type McpProfileSection = (typeof MCP_PROFILE_SECTIONS)[number];
4373
5255
  /** A JSON Schema (draft 2020-12) object describing a tool's input arguments. */
@@ -4542,6 +5424,6 @@ declare function stripImageMetadata(bytes: Uint8Array, mime: AcceptedImageMime):
4542
5424
  * A takuhon profile document's `schemaVersion` field must be migrate-compatible
4543
5425
  * with this version. See operational-lifecycle docs for the migration policy.
4544
5426
  */
4545
- declare const SCHEMA_VERSION = "1.1.0";
5427
+ declare const SCHEMA_VERSION = "1.4.0";
4546
5428
 
4547
- export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AssetOptions, type AssetRecord, type Avatar, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, DARK_PALETTE, type Education, type ExportOptions, type ExportedTakuhon, type GravatarOptions, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, LIGHT_PALETTE, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, MCP_PROFILE_SECTIONS, MCP_RESOURCES, MCP_TOOLS, type McpInputSchema, type McpProfileSection, McpRequestError, type McpResourceDefinition, type McpResourceResult, type McpToolDefinition, type McpToolResult, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Palette, type Patent, type PatentStatus, type Profile, type Project, type PublicVisibility, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, type RenderActivitySvgOptions, SCHEMA_VERSION, SUPPORTED_SCHEMA_VERSIONS, type Schema, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, executeMcpTool, exportTakuhon, formatCodingTime, formatDate, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, getPresentLabel, gravatarUrl, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
5429
+ export { ACCEPTED_IMAGE_MIME_TYPES, type AcceptedImageMime, type ActivitySettings, type ActivitySnapshot, type ActivityStorage, type Address, type AppearanceColors, type AppearanceSettings, type AssetOptions, type AssetRecord, type Avatar, CHROME_LABEL_KEYS, type Career, type Certification, type CodingTime, ConflictError, type Contact, type ContentLicense, type ContentLicenseAttribution, type ContributionCalendar, type ContributionDay, type Course, type CvDocument, type CvHeader, type CvSection, type CvSectionKind, DARK_PALETTE, type Education, type ExportOptions, type ExportedTakuhon, type GravatarOptions, type Highlight, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, LABEL_KEYS, LIGHT_PALETTE, type LabelKey, type Language, type LanguageBreakdown, type LanguageProficiency, type Link, type LinkBuiltin, type LinkCustom, type LinkType, type LocaleTag, type LocalizedAddress, type LocalizedAvatar, type LocalizedBody, type LocalizedCareer, type LocalizedCertification, type LocalizedCourse, type LocalizedEducation, type LocalizedHighlight, type LocalizedHonor, type LocalizedLanguage, type LocalizedLink, type LocalizedLinkBuiltin, type LocalizedLinkCustom, type LocalizedMembership, type LocalizedPatent, type LocalizedProfile, type LocalizedProject, type LocalizedPublication, type LocalizedRecommendation, type LocalizedRecommendationAuthor, type LocalizedSecondaryLink, type LocalizedSkill, type LocalizedTakuhon, type LocalizedTestScore, type LocalizedTitle, type LocalizedVolunteering, MAX_IMAGE_BYTES, MAX_IMAGE_DIMENSION, MAX_IMAGE_FRAMES, MCP_PROFILE_SECTIONS, MCP_RESOURCES, MCP_TOOLS, type McpInputSchema, type McpProfileSection, McpRequestError, type McpResourceDefinition, type McpResourceResult, type McpToolDefinition, type McpToolResult, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Palette, type Patent, type PatentStatus, type Profile, type Project, type PublicVisibility, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, type RenderActivitySvgOptions, SCHEMA_VERSION, SECTION_KEYS, SUPPORTED_SCHEMA_VERSIONS, type Schema, type SecondaryLink, type SectionKey, type Settings, type Skill, type Slug, StorageError, type Takuhon, type TakuhonAssetStorage, type TakuhonStorage, type TestScore, type ValidationError, type ValidationResult, type Volunteering, type YearMonth, applyPublicPrivacyFilter, computeLanguagePercentages, deriveCv, deriveRankTier, detectImageMime, executeMcpTool, exportTakuhon, formatCodingTime, formatDate, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, getPresentLabel, gravatarUrl, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };