@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 +906 -24
- package/dist/index.js +4928 -422
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/takuhon.schema.json +242 -3
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.
|
|
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
|
-
|
|
484
|
-
|
|
485
|
-
|
|
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
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
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
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
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
|
-
|
|
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
|
-
* `
|
|
3348
|
-
*
|
|
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:
|
|
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:
|
|
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
|
|
4189
|
-
* and the rest appear in the 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:
|
|
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.
|
|
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 };
|