diff --git a/package.json b/package.json
index e88ea88..926c575 100644
--- a/package.json
+++ b/package.json
@@ -19,10 +19,14 @@
"@octokit/core": "^7.0.6",
"@octokit/rest": "^22.0.1",
"@tailwindcss/postcss": "^4.1.16",
+ "@tanstack/vue-query": "^5.92.9",
"@toycode/markdown-it-class": "^1.2.4",
+ "@ts-rest/core": "^3.52.1",
+ "@ts-rest/vue-query": "^3.52.1",
"@vscode/markdown-it-katex": "^1.1.2",
"@vueuse/core": "^13.6.0",
"@vueuse/router": "^13.6.0",
+ "arktype": "^2.1.29",
"date-fns": "^4.1.0",
"events": "^3.3.0",
"font-color-contrast": "^11.1.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ac429f7..ee16d41 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,9 +20,18 @@ importers:
'@tailwindcss/postcss':
specifier: ^4.1.16
version: 4.1.16
+ '@tanstack/vue-query':
+ specifier: ^5.92.9
+ version: 5.92.9(vue@3.5.18(typescript@5.9.3))
'@toycode/markdown-it-class':
specifier: ^1.2.4
version: 1.2.4
+ '@ts-rest/core':
+ specifier: ^3.52.1
+ version: 3.52.1(@types/node@22.15.24)
+ '@ts-rest/vue-query':
+ specifier: ^3.52.1
+ version: 3.52.1(@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3)))(@ts-rest/core@3.52.1(@types/node@22.15.24))
'@vscode/markdown-it-katex':
specifier: ^1.1.2
version: 1.1.2
@@ -32,6 +41,9 @@ importers:
'@vueuse/router':
specifier: ^13.6.0
version: 13.6.0(vue-router@4.5.1(vue@3.5.18(typescript@5.9.3)))(vue@3.5.18(typescript@5.9.3))
+ arktype:
+ specifier: ^2.1.29
+ version: 2.1.29
date-fns:
specifier: ^4.1.0
version: 4.1.0
@@ -227,6 +239,12 @@ packages:
peerDependencies:
ajv: '>=8'
+ '@ark/schema@0.56.0':
+ resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==}
+
+ '@ark/util@0.56.0':
+ resolution: {integrity: sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==}
+
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
@@ -1491,9 +1509,46 @@ packages:
peerDependencies:
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
+ '@tanstack/match-sorter-utils@8.19.4':
+ resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
+ engines: {node: '>=12'}
+
+ '@tanstack/query-core@5.90.20':
+ resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==}
+
+ '@tanstack/vue-query@5.92.9':
+ resolution: {integrity: sha512-jjAZcqKveyX0C4w/6zUqbnqk/XzuxNWaFsWjGTJWULVFizUNeLGME2gf9vVSDclIyiBhR13oZJPPs6fJgfpIJQ==}
+ peerDependencies:
+ '@vue/composition-api': ^1.1.2
+ vue: ^2.6.0 || ^3.3.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
'@toycode/markdown-it-class@1.2.4':
resolution: {integrity: sha512-hA4gHBK8moObkOYdWTjhy1wYcYy0MJeM3JjSKbsXHRpRMvIKhk6Jm+t3bXsSScTdz/byWqQbs8YIwVYjHp+SlQ==}
+ '@ts-rest/core@3.52.1':
+ resolution: {integrity: sha512-tAjz7Kxq/grJodcTA1Anop4AVRDlD40fkksEV5Mmal88VoZeRKAG8oMHsDwdwPZz+B/zgnz0q2sF+cm5M7Bc7g==}
+ peerDependencies:
+ '@types/node': ^18.18.7 || >=20.8.4
+ zod: ^3.22.3
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ zod:
+ optional: true
+
+ '@ts-rest/vue-query@3.52.1':
+ resolution: {integrity: sha512-89u7aS9LGDC7uNUC5CagWX1EB7vTwyXohYcizLi1D9v7MD/Cnu5OTQNf8SY3PuAK62RcFJXB2XZGsMAPC0svNw==}
+ peerDependencies:
+ '@tanstack/vue-query': ^4.0.0
+ '@ts-rest/core': ~3.52.0
+ zod: ^3.22.3
+ peerDependenciesMeta:
+ zod:
+ optional: true
+
'@types/chai@5.2.2':
resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
@@ -1955,6 +2010,12 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ arkregex@0.0.5:
+ resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==}
+
+ arktype@2.1.29:
+ resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==}
+
array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
@@ -3675,6 +3736,9 @@ packages:
resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==}
hasBin: true
+ remove-accents@0.5.0:
+ resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==}
+
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
@@ -4415,6 +4479,12 @@ snapshots:
jsonpointer: 5.0.1
leven: 3.1.0
+ '@ark/schema@0.56.0':
+ dependencies:
+ '@ark/util': 0.56.0
+
+ '@ark/util@0.56.0': {}
+
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.27.1
@@ -5762,8 +5832,31 @@ snapshots:
postcss-selector-parser: 6.0.10
tailwindcss: 4.1.16
+ '@tanstack/match-sorter-utils@8.19.4':
+ dependencies:
+ remove-accents: 0.5.0
+
+ '@tanstack/query-core@5.90.20': {}
+
+ '@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3))':
+ dependencies:
+ '@tanstack/match-sorter-utils': 8.19.4
+ '@tanstack/query-core': 5.90.20
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.18(typescript@5.9.3)
+ vue-demi: 0.14.10(vue@3.5.18(typescript@5.9.3))
+
'@toycode/markdown-it-class@1.2.4': {}
+ '@ts-rest/core@3.52.1(@types/node@22.15.24)':
+ optionalDependencies:
+ '@types/node': 22.15.24
+
+ '@ts-rest/vue-query@3.52.1(@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3)))(@ts-rest/core@3.52.1(@types/node@22.15.24))':
+ dependencies:
+ '@tanstack/vue-query': 5.92.9(vue@3.5.18(typescript@5.9.3))
+ '@ts-rest/core': 3.52.1(@types/node@22.15.24)
+
'@types/chai@5.2.2':
dependencies:
'@types/deep-eql': 4.0.2
@@ -6389,6 +6482,16 @@ snapshots:
argparse@2.0.1: {}
+ arkregex@0.0.5:
+ dependencies:
+ '@ark/util': 0.56.0
+
+ arktype@2.1.29:
+ dependencies:
+ '@ark/schema': 0.56.0
+ '@ark/util': 0.56.0
+ arkregex: 0.0.5
+
array-buffer-byte-length@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -8205,6 +8308,8 @@ snapshots:
dependencies:
jsesc: 3.1.0
+ remove-accents@0.5.0: {}
+
require-from-string@2.0.2: {}
resolve-from@4.0.0: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
deleted file mode 100644
index c7aa842..0000000
--- a/pnpm-workspace.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-onlyBuiltDependencies:
- - '@parcel/watcher'
- - '@tailwindcss/oxide'
- - esbuild
- - vue-demi
diff --git a/src/components/WelcomeWorld.vue b/src/components/WelcomeWorld.vue
index 49e357b..e065648 100644
--- a/src/components/WelcomeWorld.vue
+++ b/src/components/WelcomeWorld.vue
@@ -19,6 +19,9 @@