From c1722e1069347b527856799d196cb11204303664 Mon Sep 17 00:00:00 2001 From: sam-bellen_atko Date: Thu, 2 Apr 2026 16:12:52 +0200 Subject: [PATCH 1/3] Add a jwt-skills banner --- package-lock.json | 33 +++-- public.key | 51 ++++++++ .../components/assets/assets.component.tsx | 5 + .../home/components/assets/assets.module.scss | 4 +- .../assets/skills-card.component.tsx | 49 ++++++++ .../assets/skills-cta.component.tsx | 48 ++++++++ .../components/assets/skills-cta.module.scss | 113 ++++++++++++++++++ .../localization/dictionaries/jwt/en.ts | 12 ++ .../localization/dictionaries/jwt/ja.ts | 12 ++ .../models/jwt-dictionary.model.ts | 7 ++ 10 files changed, 320 insertions(+), 14 deletions(-) create mode 100644 public.key create mode 100644 src/features/home/components/assets/skills-card.component.tsx create mode 100644 src/features/home/components/assets/skills-cta.component.tsx create mode 100644 src/features/home/components/assets/skills-cta.module.scss diff --git a/package-lock.json b/package-lock.json index e1b77310..cc15e73a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -109,6 +109,7 @@ "version": "7.24.4", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", @@ -2636,6 +2637,7 @@ "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-3.1.0.tgz", "integrity": "sha512-xU/lwKdOyfXtQGqn3VnJjlDrmKXEvMi1mgYxVmukEUtVycIz1nh7oQ40bKTd4cA7rLStqu0740pnhGYxGoqsCg==", "license": "MIT", + "peer": true, "dependencies": { "@mdx-js/mdx": "^3.0.0", "source-map": "^0.7.0" @@ -2694,6 +2696,7 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -3456,7 +3459,6 @@ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "license": "MIT", - "peer": true, "engines": { "node": ">= 18" } @@ -3524,7 +3526,6 @@ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/types": "^13.1.0", "universal-user-agent": "^6.0.0" @@ -3538,7 +3539,6 @@ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/request": "^8.3.0", "@octokit/types": "^13.0.0", @@ -3833,7 +3833,6 @@ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/endpoint": "^9.0.6", "@octokit/request-error": "^5.1.1", @@ -3849,7 +3848,6 @@ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/types": "^13.1.0", "deprecation": "^2.0.0", @@ -3864,7 +3862,6 @@ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", "license": "MIT", - "peer": true, "dependencies": { "@octokit/types": "^13.1.0", "deprecation": "^2.0.0", @@ -3947,6 +3944,7 @@ "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "playwright": "1.49.1" }, @@ -6123,6 +6121,7 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -6363,6 +6362,7 @@ "version": "18.2.73", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.73.tgz", "integrity": "sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -6692,6 +6692,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -7129,8 +7130,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -7200,6 +7200,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -7805,8 +7806,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/dequal": { "version": "2.0.3", @@ -8253,6 +8253,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -8405,6 +8406,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, + "peer": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -11322,6 +11324,7 @@ "resolved": "https://registry.npmjs.org/next/-/next-14.2.35.tgz", "integrity": "sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==", "license": "MIT", + "peer": true, "dependencies": { "@next/env": "14.2.35", "@swc/helpers": "0.5.5", @@ -11594,6 +11597,7 @@ "version": "6.1.2", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", + "peer": true, "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.0.0", @@ -12210,6 +12214,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -12318,6 +12323,7 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -12856,6 +12862,7 @@ "version": "1.74.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.74.1.tgz", "integrity": "sha512-w0Z9p/rWZWelb88ISOLyvqTWGmtmu2QJICqDBGyNnfG4OUnPX9BBjjYIXUpXCMOOg5MQWNpqzt876la1fsTvUA==", + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -14081,6 +14088,7 @@ "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14272,8 +14280,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/update-browserslist-db": { "version": "1.1.1", @@ -14382,6 +14389,7 @@ "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -14532,6 +14540,7 @@ "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "1.6.1", "@vitest/runner": "1.6.1", diff --git a/public.key b/public.key new file mode 100644 index 00000000..efeab717 --- /dev/null +++ b/public.key @@ -0,0 +1,51 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=eAMi +-----END PGP PUBLIC KEY BLOCK----- diff --git a/src/features/home/components/assets/assets.component.tsx b/src/features/home/components/assets/assets.component.tsx index 441e7795..bcc45ce4 100644 --- a/src/features/home/components/assets/assets.component.tsx +++ b/src/features/home/components/assets/assets.component.tsx @@ -19,6 +19,7 @@ import { Button } from "react-aria-components"; import { ArrowHeadIconComponent } from "@/features/common/assets/arrow-head-icon.component"; import { Auth0DictionaryModel } from "@/features/localization/models/auth0-dictionary.model"; import { Auth0CtaComponent } from "@/features/common/components/auth0-cta/auth0-cta.component"; +import { SkillsCtaComponent } from "./skills-cta.component"; type AssetsComponentProps = { languageCode: string; @@ -63,6 +64,10 @@ export const AssetsComponent: React.FC = ({ languageCode={languageCode} dictionary={auth0Dictionary.banner} /> + ); }; diff --git a/src/features/home/components/assets/assets.module.scss b/src/features/home/components/assets/assets.module.scss index 5654af3f..c8b33b1a 100644 --- a/src/features/home/components/assets/assets.module.scss +++ b/src/features/home/components/assets/assets.module.scss @@ -28,8 +28,7 @@ width: calc(100% - 2rem); max-width: 1312px; margin: 0 auto; - grid-row-gap: unset; - row-gap: unset; + row-gap: 1rem; } } @@ -52,6 +51,7 @@ } } + .assets__title { width: 100%; margin: 0; diff --git a/src/features/home/components/assets/skills-card.component.tsx b/src/features/home/components/assets/skills-card.component.tsx new file mode 100644 index 00000000..9c736aa2 --- /dev/null +++ b/src/features/home/components/assets/skills-card.component.tsx @@ -0,0 +1,49 @@ +import React from "react"; +import { JwtDictionaryModel } from "@/features/localization/models/jwt-dictionary.model"; +import { CardWithHeadlineComponent } from "@/features/common/components/card/card.component"; +import { CardToolbarComponent } from "@/features/common/components/card-toolbar/card-toolbar.component"; +import { CardToolbarCopyButtonComponent } from "@/features/common/components/card-toolbar-buttons/card-toolbar-copy-button/card-toolbar-copy-button.component"; + +const COMMAND = "npx skills add jsonwebtoken/jwt-skills"; +const COMMAND_SPECIFIC = "npx skills add jsonwebtoken/jwt-skills -s jwt-decode"; + +const labelStyle: React.CSSProperties = { + fontSize: "0.75rem", + lineHeight: "1.25rem", + opacity: 0.6, +}; + +interface Props { + languageCode: string; + dictionary: JwtDictionaryModel["skills"]; +} + +export const SkillsCardComponent: React.FC = ({ languageCode, dictionary }) => { + return ( + + + + ), + }} + messages={null} + > +

{dictionary.installAllSkills}

+ {"$ " + COMMAND} +

{dictionary.installSpecificSkill}

+ {"$ " + COMMAND_SPECIFIC} +
+ ); +}; diff --git a/src/features/home/components/assets/skills-cta.component.tsx b/src/features/home/components/assets/skills-cta.component.tsx new file mode 100644 index 00000000..9fab0063 --- /dev/null +++ b/src/features/home/components/assets/skills-cta.component.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import styles from "./skills-cta.module.scss"; +import { clsx } from "clsx"; +import Link from "next/link"; +import { JwtDictionaryModel } from "@/features/localization/models/jwt-dictionary.model"; +import { getLocalizedSecondaryFont } from "@/libs/theme/fonts"; +import { ArrowHeadIconComponent } from "@/features/common/assets/arrow-head-icon.component"; +import { SkillsCardComponent } from "./skills-card.component"; + +interface SkillsCtaComponentProps { + languageCode: string; + dictionary: JwtDictionaryModel["skills"]; +} + +export const SkillsCtaComponent: React.FC = ({ + languageCode, + dictionary, +}) => { + return ( +
+
+

+ {dictionary.title} +

+
+

{dictionary.description}

+ + {dictionary.ctaButton.label} + + +
+
+
+ +
+
+ ); +}; diff --git a/src/features/home/components/assets/skills-cta.module.scss b/src/features/home/components/assets/skills-cta.module.scss new file mode 100644 index 00000000..2692917e --- /dev/null +++ b/src/features/home/components/assets/skills-cta.module.scss @@ -0,0 +1,113 @@ +@use "@/libs/theme/styles/variables" as *; + +.container { + color: var(--color_fg_default); + display: flex; + flex-direction: column; + gap: 2rem; + border: 1px solid var(--color_border_default); + border-radius: 1rem; + padding: 2.5rem; + background-color: var(--color_bg_layer); + box-shadow: 0 2px 12px -4px rgba(0,0,0,.08),0 2px 1px -.5px rgba(0,0,0,.04),0 2px 4px -4px rgba(0,0,0,.05),inset -.5px -.5px 2px rgba(0,0,0,.04); + + @media #{$breakpoint-dimension-md} { + flex-direction: row; + align-items: center; + gap: 3rem; + grid-column: 1 / -1; + } +} + +.left { + display: flex; + flex-direction: column; + gap: 1.25rem; + + @media #{$breakpoint-dimension-sm} { + gap: 2rem; + } + + @media #{$breakpoint-dimension-md} { + flex: 1; + } +} + +.right { + @media #{$breakpoint-dimension-md} { + flex: 1; + align-self: flex-start; + } +} + +.title { + width: 100%; + margin: 0; + text-align: left; + font-size: 1.5rem; + line-height: 1.15; + font-weight: 500; + color: var(--color_fg_bold); + font-feature-settings: lining-nums proportional-nums; + font-variant-numeric: lining-nums proportional-nums; + font-style: normal; + + @media #{$breakpoint-dimension-lg} { + font-size: 2.5rem; + } +} + +.content { + display: flex; + flex-direction: column; + gap: 1.5rem; + + @media #{$breakpoint-dimension-sm} { + gap: 2rem; + } +} + +.description { + font-size: 1rem; + line-height: 1.5rem; +} + +.code { + font-family: var(--font-mono), monospace; + font-size: 0.875em; + color: var(--color_fg_bold); + background-color: var(--color_bg_layer_alternate); + border: 1px solid var(--color_border_default); + border-radius: 0.25rem; + padding: 0.1em 0.35em; +} + +.link { + width: fit-content; + display: flex; + padding: .25rem .75rem; + justify-content: center; + align-items: center; + gap: .25rem; + border-radius: 9999px; + background: var(--color_bg_layer); + border: 1px solid var(--color_border_default); + font-size: .875rem; + font-weight: 500; + line-height: 1.375rem; + letter-spacing: -.2px; + transition: all .3s ease-in-out; + + &:focus-visible { + outline: solid 1px var(--color_border_focus); + outline-offset: 0.125rem; + border-radius: 0.125rem; + } + + &:hover { + border: 1px solid var(--color_border_bold); + box-shadow: 0 0 0 4px rgba(0,0,0,.12); + transition: all .2s ease-out; + } + +} diff --git a/src/features/localization/dictionaries/jwt/en.ts b/src/features/localization/dictionaries/jwt/en.ts index 2d5ea8b5..a27b8530 100644 --- a/src/features/localization/dictionaries/jwt/en.ts +++ b/src/features/localization/dictionaries/jwt/en.ts @@ -10,6 +10,18 @@ export const enJwtDictionary: JwtDictionaryModel = { path: "/libraries", }, }, + skills: { + title: "Give your AI Agents JWT skills", + description: + "Use agent skills to decode, encode and validate JSON Web Tokens in your favorite agentic coding harness.", + installAllSkills: "Install all skills", + installSpecificSkill: "Install a specific skill", + ctaButton: { + label: "See the skills", + path: "https://github.com/jsonwebtoken/jwt-skills", + isExternal: true, + }, + }, assets: { badges: { title: "Badges", diff --git a/src/features/localization/dictionaries/jwt/ja.ts b/src/features/localization/dictionaries/jwt/ja.ts index a0706b34..fb3a1917 100644 --- a/src/features/localization/dictionaries/jwt/ja.ts +++ b/src/features/localization/dictionaries/jwt/ja.ts @@ -11,6 +11,18 @@ export const jaJwtDictionary: JwtDictionaryModel = { path: sitePaths.libraries, }, }, + skills: { + title: "Give your AI Agents JWT skills", + description: + "Use agent skills to decode, encode and validate JSON Web Tokens in your favorite agentic coding harness.", + installAllSkills: "Install all skills", + installSpecificSkill: "Install a specific skill", + ctaButton: { + label: "See the skills", + path: "https://github.com/jsonwebtoken/jwt-skills", + isExternal: true, + }, + }, assets: { badges: { title: "バッジ", diff --git a/src/features/localization/models/jwt-dictionary.model.ts b/src/features/localization/models/jwt-dictionary.model.ts index 6fc6f7d7..813e51db 100644 --- a/src/features/localization/models/jwt-dictionary.model.ts +++ b/src/features/localization/models/jwt-dictionary.model.ts @@ -7,6 +7,13 @@ export interface JwtDictionaryModel { description: string; ctaButton: LinkMetadataModel; }; + skills: { + title: string; + description: string; + installAllSkills: string; + installSpecificSkill: string; + ctaButton: LinkMetadataModel; + }; assets: { badges: { title: string; From 1ba561de7d0c45648c3e9296a8b4cb8b7b00ccbb Mon Sep 17 00:00:00 2001 From: sam-bellen_atko Date: Thu, 2 Apr 2026 16:20:03 +0200 Subject: [PATCH 2/3] remove test key --- public.key | 51 --------------------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 public.key diff --git a/public.key b/public.key deleted file mode 100644 index efeab717..00000000 --- a/public.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -=eAMi ------END PGP PUBLIC KEY BLOCK----- From 3f4c5ee30411849e66769aaf584a9476d8439c43 Mon Sep 17 00:00:00 2001 From: sam-bellen_atko Date: Fri, 3 Apr 2026 08:05:05 +0200 Subject: [PATCH 3/3] Add Japanese translations --- src/features/localization/dictionaries/jwt/ja.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/features/localization/dictionaries/jwt/ja.ts b/src/features/localization/dictionaries/jwt/ja.ts index fb3a1917..b0f4b82e 100644 --- a/src/features/localization/dictionaries/jwt/ja.ts +++ b/src/features/localization/dictionaries/jwt/ja.ts @@ -12,13 +12,13 @@ export const jaJwtDictionary: JwtDictionaryModel = { }, }, skills: { - title: "Give your AI Agents JWT skills", + title: "AIエージェントにJWT Skillsを追加", description: - "Use agent skills to decode, encode and validate JSON Web Tokens in your favorite agentic coding harness.", - installAllSkills: "Install all skills", - installSpecificSkill: "Install a specific skill", + "Agent Skillsを利用し、エージェントハーネスでJSWON Web Tokensのデコード、エンコード、検証を実現しましょう。", + installAllSkills: "すべてのSkillsをインストール", + installSpecificSkill: "特定のSkillsをインストール", ctaButton: { - label: "See the skills", + label: "Skillsを確認", path: "https://github.com/jsonwebtoken/jwt-skills", isExternal: true, },