@takuhon/core 0.12.0 → 0.14.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
@@ -3712,6 +3712,204 @@ declare class ConflictError extends StorageError {
3712
3712
  */
3713
3713
  declare function renderActivitySvg(snapshot: ActivitySnapshot): string;
3714
3714
 
3715
+ /**
3716
+ * Résumé / CV projection of a profile.
3717
+ *
3718
+ * {@link deriveCv} turns one locale-resolved {@link LocalizedTakuhon} into a
3719
+ * {@link CvDocument}: a header plus the CV-relevant sections in a fixed,
3720
+ * résumé-conventional order. It is a pure, deterministic selection-and-projection
3721
+ * — no clock, no randomness, no I/O — so the static export ({@link
3722
+ * import('@takuhon/cli')}) and a React `CvView` render identical output from the
3723
+ * same input.
3724
+ *
3725
+ * A CV is a curated *subset* of the profile: the web-page-specific sections
3726
+ * (links, recommendations, the activity dashboard, test scores) are omitted,
3727
+ * and the rest appear in the order a résumé conventionally uses. Entry order
3728
+ * within a section is preserved from the input (already normalized by `order`
3729
+ * upstream), so the owner's `order` field controls it — `deriveCv` never
3730
+ * re-sorts. Empty sections are dropped so the renderer can iterate without
3731
+ * emptiness checks.
3732
+ *
3733
+ * The input must already be privacy-filtered (`applyPublicPrivacyFilter`) by the
3734
+ * caller, exactly as the public render path is: `deriveCv` does not strip
3735
+ * anything itself, it only projects what it is given.
3736
+ */
3737
+
3738
+ /** The header block of a CV: identity and contact, drawn from `profile` + `contact`. */
3739
+ interface CvHeader {
3740
+ displayName: string;
3741
+ tagline?: string;
3742
+ /** Human-readable location (the address `display` string), if present. */
3743
+ location?: string;
3744
+ bio?: string;
3745
+ /** Email, only when the profile exposed it (privacy filter already applied). */
3746
+ email?: string;
3747
+ formUrl?: string;
3748
+ }
3749
+ /**
3750
+ * One CV section, discriminated by `kind`, carrying the locale-resolved entries
3751
+ * for that section. The entry types are reused verbatim from `LocalizedTakuhon`.
3752
+ */
3753
+ type CvSection = {
3754
+ kind: 'experience';
3755
+ entries: LocalizedCareer[];
3756
+ } | {
3757
+ kind: 'education';
3758
+ entries: LocalizedEducation[];
3759
+ } | {
3760
+ kind: 'skills';
3761
+ entries: Skill[];
3762
+ } | {
3763
+ kind: 'certifications';
3764
+ entries: LocalizedCertification[];
3765
+ } | {
3766
+ kind: 'publications';
3767
+ entries: LocalizedPublication[];
3768
+ } | {
3769
+ kind: 'honors';
3770
+ entries: LocalizedHonor[];
3771
+ } | {
3772
+ kind: 'courses';
3773
+ entries: LocalizedCourse[];
3774
+ } | {
3775
+ kind: 'patents';
3776
+ entries: LocalizedPatent[];
3777
+ } | {
3778
+ kind: 'languages';
3779
+ entries: LocalizedLanguage[];
3780
+ } | {
3781
+ kind: 'volunteering';
3782
+ entries: LocalizedVolunteering[];
3783
+ } | {
3784
+ kind: 'memberships';
3785
+ entries: LocalizedMembership[];
3786
+ };
3787
+ /** Every `CvSection` discriminant, in the fixed résumé order `deriveCv` emits. */
3788
+ type CvSectionKind = CvSection['kind'];
3789
+ /** A résumé/CV view derived from a profile: a header plus ordered sections. */
3790
+ interface CvDocument {
3791
+ /** The locale this CV was resolved at (mirrors `LocalizedTakuhon.resolvedLocale`). */
3792
+ resolvedLocale: string;
3793
+ header: CvHeader;
3794
+ /** Non-empty sections only, in the fixed CV order. */
3795
+ sections: CvSection[];
3796
+ }
3797
+ /**
3798
+ * Project a locale-resolved profile into a {@link CvDocument}. Sections appear
3799
+ * in a fixed résumé-conventional order and empty ones are omitted; entry order
3800
+ * within each section is preserved from the input. Pure and deterministic.
3801
+ */
3802
+ declare function deriveCv(localized: LocalizedTakuhon): CvDocument;
3803
+
3804
+ /**
3805
+ * MCP (Model Context Protocol) projection of a profile.
3806
+ *
3807
+ * This module describes how a takuhon profile is exposed to an AI agent as a
3808
+ * set of read-only MCP tools and resources, and how each one is answered from a
3809
+ * profile document — *without* committing to a transport (stdio / HTTP) or to
3810
+ * any MCP SDK.
3811
+ *
3812
+ * The split mirrors the rest of core: deciding *what* to expose and *what it
3813
+ * returns* is a pure, deterministic projection over the canonical document
3814
+ * (exactly like {@link generateJsonLd}), so it lives here in `@takuhon/core` and
3815
+ * stays runtime-free (spec §2.3). The transport, JSON-RPC framing, and server
3816
+ * lifecycle are runtime-aware; they live in `@takuhon/mcp` and the CLI /
3817
+ * Cloudflare adapters, which call the pure executors below.
3818
+ *
3819
+ * Everything here is read-only. No tool or resource touches the admin surface,
3820
+ * and every answer passes through {@link applyPublicPrivacyFilter}, so an MCP
3821
+ * client sees exactly what `GET /api/profile`, `GET /api/jsonld`, `GET
3822
+ * /api/schema`, and `GET /takuhon.json` already expose — no more.
3823
+ *
3824
+ * The catalog ({@link MCP_TOOLS} / {@link MCP_RESOURCES}) is plain data with no
3825
+ * SDK dependency, so the `@takuhon/mcp` wiring can register it against the
3826
+ * official `@modelcontextprotocol/sdk` and later be swapped to a hand-rolled
3827
+ * dispatcher without touching this file.
3828
+ */
3829
+
3830
+ /**
3831
+ * Profile sections a `get_section` call may request: the content-bearing keys
3832
+ * of a locale-resolved profile (the spec §6 data sections). `settings`,
3833
+ * `meta`, `schemaVersion`, and `resolvedLocale` are intentionally excluded —
3834
+ * they are configuration / bookkeeping, not profile content an agent reads.
3835
+ */
3836
+ declare const MCP_PROFILE_SECTIONS: readonly ["profile", "links", "careers", "projects", "skills", "certifications", "memberships", "volunteering", "honors", "education", "publications", "languages", "courses", "patents", "testScores", "recommendations", "contact"];
3837
+ /** One of the {@link MCP_PROFILE_SECTIONS} a `get_section` call accepts. */
3838
+ type McpProfileSection = (typeof MCP_PROFILE_SECTIONS)[number];
3839
+ /** A JSON Schema (draft 2020-12) object describing a tool's input arguments. */
3840
+ type McpInputSchema = Readonly<Record<string, unknown>>;
3841
+ /** A read-only MCP tool definition — plain data, no SDK dependency. */
3842
+ interface McpToolDefinition {
3843
+ /** Stable tool id used in `tools/call`. */
3844
+ name: string;
3845
+ /** Human-readable title for display. */
3846
+ title: string;
3847
+ /** What the tool returns; shown to the agent when it chooses a tool. */
3848
+ description: string;
3849
+ /** JSON Schema for the tool's `arguments` object. */
3850
+ inputSchema: McpInputSchema;
3851
+ }
3852
+ /** A read-only MCP resource definition — plain data, no SDK dependency. */
3853
+ interface McpResourceDefinition {
3854
+ /** Stable resource URI used in `resources/read`. */
3855
+ uri: string;
3856
+ name: string;
3857
+ title: string;
3858
+ description: string;
3859
+ /** MIME type of the resource contents. */
3860
+ mimeType: string;
3861
+ }
3862
+ /** Result of {@link executeMcpTool}: the structured value the tool produced. */
3863
+ interface McpToolResult {
3864
+ /**
3865
+ * The JSON value the tool produced — already normalized, locale-resolved, and
3866
+ * privacy-filtered. The transport layer serializes this to MCP wire content.
3867
+ */
3868
+ data: unknown;
3869
+ /** Locale the result was resolved at, when the tool resolved one. */
3870
+ resolvedLocale?: string;
3871
+ }
3872
+ /** Result of {@link readMcpResource}: one resource's contents. */
3873
+ interface McpResourceResult {
3874
+ uri: string;
3875
+ mimeType: string;
3876
+ /** The JSON value of the resource. The transport layer serializes it. */
3877
+ data: unknown;
3878
+ }
3879
+ /**
3880
+ * Thrown by {@link executeMcpTool} / {@link readMcpResource} for an unknown
3881
+ * tool/resource name or invalid arguments. The transport layer maps it to the
3882
+ * appropriate MCP error (a JSON-RPC error for a malformed request, or an
3883
+ * `isError` tool result for a bad argument) — core stays transport-agnostic.
3884
+ */
3885
+ declare class McpRequestError extends Error {
3886
+ constructor(message: string, options?: {
3887
+ cause?: unknown;
3888
+ });
3889
+ }
3890
+ /** The read-only tools an MCP client may call against the profile. */
3891
+ declare const MCP_TOOLS: readonly McpToolDefinition[];
3892
+ /** The read-only resources an MCP client may read. */
3893
+ declare const MCP_RESOURCES: readonly McpResourceDefinition[];
3894
+ /**
3895
+ * Execute a read-only MCP tool against a profile document.
3896
+ *
3897
+ * `profile` is the raw validated {@link Takuhon} (the transport layer loaded it
3898
+ * from KV / a file). Locale-aware tools normalize, locale-resolve, and
3899
+ * privacy-filter it exactly as `GET /api/profile` does, then project the
3900
+ * requested view. Pure and deterministic — no clock, no randomness, no I/O.
3901
+ *
3902
+ * @throws {McpRequestError} for an unknown tool name or invalid arguments.
3903
+ */
3904
+ declare function executeMcpTool(name: string, args: Readonly<Record<string, unknown>>, profile: Takuhon): McpToolResult;
3905
+ /**
3906
+ * Read a read-only MCP resource from a profile document. Pure and
3907
+ * deterministic.
3908
+ *
3909
+ * @throws {McpRequestError} for an unknown resource URI.
3910
+ */
3911
+ declare function readMcpResource(uri: string, profile: Takuhon): McpResourceResult;
3912
+
3715
3913
  /**
3716
3914
  * Image-asset helpers for uploaded media (avatars, project images): magic-byte
3717
3915
  * type detection, header-only dimension / frame reading, and metadata stripping
@@ -3812,4 +4010,4 @@ declare function stripImageMetadata(bytes: Uint8Array, mime: AcceptedImageMime):
3812
4010
  */
3813
4011
  declare const SCHEMA_VERSION = "0.5.0";
3814
4012
 
3815
- 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 Education, type ExportOptions, type ExportedTakuhon, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, 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, type Membership, type Meta, type MetaPrivacy, type Migration, MigrationError, type NormalizedTakuhon, NotFoundError, type Patent, type PatentStatus, type Profile, type Project, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, 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, deriveRankTier, detectImageMime, exportTakuhon, formatCodingTime, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
4013
+ 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, type Education, type ExportOptions, type ExportedTakuhon, type Honor, IMAGE_EXTENSIONS, type ImageInfo, ImportError, type Iso3166Alpha2, type IsoDateTime, 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 Patent, type PatentStatus, type Profile, type Project, type Publication, RANK_FULL_CODING_HOURS, RANK_FULL_CONTRIBUTIONS, RANK_TIER_THRESHOLDS, type RankInput, type RankTier, type RankTierLabel, type Recommendation, type RecommendationAuthor, 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, generateJsonLd, generatePersonJsonLd, generateProfilePageJsonLd, importTakuhon, isActivitySnapshot, migrateTakuhon, migrations, normalize, readImageInfo, readMcpResource, renderActivitySvg, resolveLocale, schema, stripImageMetadata, validate };
package/dist/index.js CHANGED
@@ -11558,6 +11558,190 @@ function renderActivitySvg(snapshot) {
11558
11558
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${String(WIDTH)}" height="${String(height)}" viewBox="0 0 ${String(WIDTH)} ${String(height)}" role="img" aria-label="Developer activity"><title>Developer activity</title>${parts.join("")}</svg>`;
11559
11559
  }
11560
11560
 
11561
+ // src/cv.ts
11562
+ function deriveCv(localized) {
11563
+ const p = localized.profile;
11564
+ const header = { displayName: p.displayName };
11565
+ if (p.tagline !== void 0) header.tagline = p.tagline;
11566
+ if (p.location?.display !== void 0) header.location = p.location.display;
11567
+ if (p.bio !== void 0) header.bio = p.bio;
11568
+ if (localized.contact.email !== void 0) header.email = localized.contact.email;
11569
+ if (localized.contact.formUrl !== void 0) header.formUrl = localized.contact.formUrl;
11570
+ const candidates = [
11571
+ { kind: "experience", entries: localized.careers },
11572
+ { kind: "education", entries: localized.education },
11573
+ { kind: "skills", entries: localized.skills },
11574
+ { kind: "certifications", entries: localized.certifications },
11575
+ { kind: "publications", entries: localized.publications },
11576
+ { kind: "honors", entries: localized.honors },
11577
+ { kind: "courses", entries: localized.courses },
11578
+ { kind: "patents", entries: localized.patents },
11579
+ { kind: "languages", entries: localized.languages },
11580
+ { kind: "volunteering", entries: localized.volunteering },
11581
+ { kind: "memberships", entries: localized.memberships }
11582
+ ];
11583
+ return {
11584
+ resolvedLocale: localized.resolvedLocale,
11585
+ header,
11586
+ sections: candidates.filter((section) => section.entries.length > 0)
11587
+ };
11588
+ }
11589
+
11590
+ // src/mcp.ts
11591
+ var MCP_PROFILE_SECTIONS = [
11592
+ "profile",
11593
+ "links",
11594
+ "careers",
11595
+ "projects",
11596
+ "skills",
11597
+ "certifications",
11598
+ "memberships",
11599
+ "volunteering",
11600
+ "honors",
11601
+ "education",
11602
+ "publications",
11603
+ "languages",
11604
+ "courses",
11605
+ "patents",
11606
+ "testScores",
11607
+ "recommendations",
11608
+ "contact"
11609
+ ];
11610
+ var McpRequestError = class extends Error {
11611
+ constructor(message, options) {
11612
+ super(message, options);
11613
+ this.name = "McpRequestError";
11614
+ }
11615
+ };
11616
+ var LANG_PROPERTY = {
11617
+ type: "string",
11618
+ description: 'BCP-47 locale tag (e.g. "ja", "en"). Resolves to the requested locale, falling back to the profile default when omitted or unavailable.'
11619
+ };
11620
+ var MCP_TOOLS = [
11621
+ {
11622
+ name: "get_profile",
11623
+ title: "Get profile",
11624
+ description: "Return the owner's full public profile, resolved to one locale and privacy-filtered (identical to the public `GET /api/profile`).",
11625
+ inputSchema: {
11626
+ type: "object",
11627
+ properties: { lang: LANG_PROPERTY },
11628
+ additionalProperties: false
11629
+ }
11630
+ },
11631
+ {
11632
+ name: "get_section",
11633
+ title: "Get profile section",
11634
+ description: "Return a single section of the public profile (e.g. careers, education, skills), resolved to one locale and privacy-filtered.",
11635
+ inputSchema: {
11636
+ type: "object",
11637
+ properties: {
11638
+ section: {
11639
+ type: "string",
11640
+ enum: [...MCP_PROFILE_SECTIONS],
11641
+ description: "Which profile section to return."
11642
+ },
11643
+ lang: LANG_PROPERTY
11644
+ },
11645
+ required: ["section"],
11646
+ additionalProperties: false
11647
+ }
11648
+ },
11649
+ {
11650
+ name: "get_jsonld",
11651
+ title: "Get JSON-LD",
11652
+ description: "Return the Schema.org JSON-LD (a `ProfilePage` wrapping a `Person`) for the profile, resolved to one locale (identical to `GET /api/jsonld`).",
11653
+ inputSchema: {
11654
+ type: "object",
11655
+ properties: { lang: LANG_PROPERTY },
11656
+ additionalProperties: false
11657
+ }
11658
+ },
11659
+ {
11660
+ name: "list_locales",
11661
+ title: "List locales",
11662
+ description: "List the locales this profile is available in, plus the default \u2014 useful before calling another tool with a `lang` argument.",
11663
+ inputSchema: { type: "object", properties: {}, additionalProperties: false }
11664
+ }
11665
+ ];
11666
+ var MCP_RESOURCES = [
11667
+ {
11668
+ uri: "takuhon://profile",
11669
+ name: "profile",
11670
+ title: "Canonical profile (takuhon.json)",
11671
+ description: "The full canonical takuhon.json, privacy-filtered, with every locale retained (identical to `GET /takuhon.json`).",
11672
+ mimeType: "application/json"
11673
+ },
11674
+ {
11675
+ uri: "takuhon://schema",
11676
+ name: "schema",
11677
+ title: "Takuhon JSON Schema",
11678
+ description: "The public JSON Schema contract the profile conforms to (identical to `GET /api/schema`). Lets an agent understand the document shape.",
11679
+ mimeType: "application/json"
11680
+ }
11681
+ ];
11682
+ function executeMcpTool(name, args, profile) {
11683
+ switch (name) {
11684
+ case "get_profile": {
11685
+ const localized = publicView(profile, readLang(args));
11686
+ return { data: localized, resolvedLocale: localized.resolvedLocale };
11687
+ }
11688
+ case "get_section": {
11689
+ const section = readSection(args);
11690
+ const localized = publicView(profile, readLang(args));
11691
+ return { data: localized[section], resolvedLocale: localized.resolvedLocale };
11692
+ }
11693
+ case "get_jsonld": {
11694
+ const localized = publicView(profile, readLang(args));
11695
+ return { data: generateJsonLd(localized), resolvedLocale: localized.resolvedLocale };
11696
+ }
11697
+ case "list_locales":
11698
+ return {
11699
+ data: {
11700
+ defaultLocale: profile.settings.defaultLocale,
11701
+ availableLocales: profile.settings.availableLocales,
11702
+ ...profile.settings.fallbackLocale !== void 0 ? { fallbackLocale: profile.settings.fallbackLocale } : {}
11703
+ }
11704
+ };
11705
+ default:
11706
+ throw new McpRequestError(`Unknown MCP tool: ${name}`);
11707
+ }
11708
+ }
11709
+ function readMcpResource(uri, profile) {
11710
+ switch (uri) {
11711
+ case "takuhon://profile":
11712
+ return {
11713
+ uri,
11714
+ mimeType: "application/json",
11715
+ data: applyPublicPrivacyFilter(profile)
11716
+ };
11717
+ case "takuhon://schema":
11718
+ return { uri, mimeType: "application/json", data: schema };
11719
+ default:
11720
+ throw new McpRequestError(`Unknown MCP resource: ${uri}`);
11721
+ }
11722
+ }
11723
+ function publicView(profile, lang) {
11724
+ return applyPublicPrivacyFilter(resolveLocale(normalize(profile), lang));
11725
+ }
11726
+ function readLang(args) {
11727
+ const lang = args.lang;
11728
+ if (lang === void 0) return void 0;
11729
+ if (typeof lang !== "string") {
11730
+ throw new McpRequestError("`lang` must be a string (a BCP-47 locale tag).");
11731
+ }
11732
+ return lang;
11733
+ }
11734
+ function readSection(args) {
11735
+ const section = args.section;
11736
+ if (typeof section !== "string" || !isProfileSection(section)) {
11737
+ throw new McpRequestError(`\`section\` must be one of: ${MCP_PROFILE_SECTIONS.join(", ")}.`);
11738
+ }
11739
+ return section;
11740
+ }
11741
+ function isProfileSection(value) {
11742
+ return MCP_PROFILE_SECTIONS.includes(value);
11743
+ }
11744
+
11561
11745
  // src/image.ts
11562
11746
  var ACCEPTED_IMAGE_MIME_TYPES = [
11563
11747
  "image/jpeg",
@@ -11898,6 +12082,10 @@ export {
11898
12082
  MAX_IMAGE_BYTES,
11899
12083
  MAX_IMAGE_DIMENSION,
11900
12084
  MAX_IMAGE_FRAMES,
12085
+ MCP_PROFILE_SECTIONS,
12086
+ MCP_RESOURCES,
12087
+ MCP_TOOLS,
12088
+ McpRequestError,
11901
12089
  MigrationError,
11902
12090
  NotFoundError,
11903
12091
  RANK_FULL_CODING_HOURS,
@@ -11908,8 +12096,10 @@ export {
11908
12096
  StorageError,
11909
12097
  applyPublicPrivacyFilter,
11910
12098
  computeLanguagePercentages,
12099
+ deriveCv,
11911
12100
  deriveRankTier,
11912
12101
  detectImageMime,
12102
+ executeMcpTool,
11913
12103
  exportTakuhon,
11914
12104
  formatCodingTime,
11915
12105
  generateJsonLd,
@@ -11921,6 +12111,7 @@ export {
11921
12111
  migrations,
11922
12112
  normalize,
11923
12113
  readImageInfo,
12114
+ readMcpResource,
11924
12115
  renderActivitySvg,
11925
12116
  resolveLocale,
11926
12117
  schema,