diff --git a/package-lock.json b/package-lock.json
index 65bac51b..47c46f59 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -113,6 +113,7 @@
"typescript": "^6.0.3",
"typescript-eslint": "^8.65.0",
"vite": "^7.3.6",
+ "vitepress": "^1.6.4",
"vitest": "^4.1.10"
},
"optionalDependencies": {
@@ -152,6 +153,264 @@
"node": ">=18"
}
},
+ "node_modules/@algolia/abtesting": {
+ "version": "1.25.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/abtesting/-/abtesting-1.25.0.tgz",
+ "integrity": "sha512-rSTin9Uta23uaewYVQEp8XI9T3iA/zrg0/1G2vhf8oFFDxFL5vybnZ5IQwsVAg4JpKxPX4/WYNKdcfWrZymk7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/autocomplete-core": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz",
+ "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-plugin-algolia-insights": "1.17.7",
+ "@algolia/autocomplete-shared": "1.17.7"
+ }
+ },
+ "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz",
+ "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "search-insights": ">= 1 < 3"
+ }
+ },
+ "node_modules/@algolia/autocomplete-preset-algolia": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz",
+ "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-shared": "1.17.7"
+ },
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/autocomplete-shared": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmmirror.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz",
+ "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@algolia/client-search": ">= 4.9.1 < 6",
+ "algoliasearch": ">= 4.9.1 < 6"
+ }
+ },
+ "node_modules/@algolia/client-abtesting": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-abtesting/-/client-abtesting-5.59.0.tgz",
+ "integrity": "sha512-bm2XN0hCSMYwStSsCBT0/PUB2BDxoyR1Lnub3c392HMEy9bi8PUSW8vR6zltVEKWG2t4PQFWMD5C07bmJxGgPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-analytics/-/client-analytics-5.59.0.tgz",
+ "integrity": "sha512-XOFPOTa69WuqHR6c5tMgnUUwwqQgNSzMpxmhrgA9KmxRf8WIqEa0cokHJvohk5CYb7CZx0xeSL6Bk2IUJ7Lv7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-common/-/client-common-5.59.0.tgz",
+ "integrity": "sha512-PC8ipLOYFKRTfIUY1J3FJxS6ryzWziaXmIX9/sNMoUR8L+XhF7hX2QAeUI87YVl5zujvlYTSOb+HAIqKXDjyHQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-insights/-/client-insights-5.59.0.tgz",
+ "integrity": "sha512-yFNcCMM5fHiyoR0HuxMrzy+VjDcmhFUZTm2IJ2DHwGsVH3B5SEob4zTmeEZ3j/AZqNnmrJOCKl/tJnBg7+84bA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-personalization/-/client-personalization-5.59.0.tgz",
+ "integrity": "sha512-GYja6HkDt2VrQhWmB2cLx3Z5fDwI9no7q+xwCWcFrTPm5CLH9QZvK0XLO9co1FcNIDxxkMaP3AXM39/XcecEOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.59.0.tgz",
+ "integrity": "sha512-Wofg7bMpWh8N5qDDZs0wy6whc+KMmdNsxgrIGp9Ug2s1Bka0uq7AjyckdxReKPHLA0Q1qH8X/SNh0wn2t2X2Lw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/client-search/-/client-search-5.59.0.tgz",
+ "integrity": "sha512-fHnALZfbEnODczGk14Y/1YBRApp6UEpZUTexGcMUPzY7RDc7q4HN2Y6jh0KUG8Jo9B+q+wOoQEc3ziR0ErbuFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/ingestion/-/ingestion-1.59.0.tgz",
+ "integrity": "sha512-Fa38s1mHgoaLCT117sfJ6P78rtxUt93CYxBYpq1VOIcslaF+cH+1h5uikAPsKfxLnsuEDZHiBiaI6eNPTsQMRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/monitoring/-/monitoring-1.59.0.tgz",
+ "integrity": "sha512-NyNsRSqM2tF1MX7ZGw/j4rduoEJiQ5wfvbSo/CFVdEzYCjyxbGFRPOZyS/GETJG9rk1TdHOq8NZqKqk/u1fm4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/recommend/-/recommend-5.59.0.tgz",
+ "integrity": "sha512-nXBK2uygWtvbCOffMWqqfjjcEtp9enDKY5/2Pw/Hhw8VVaOyK2ThbGK04bNX/Le+qoK1VHYkodWGVTKfw0Otkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.59.0.tgz",
+ "integrity": "sha512-yb+4afX/zja8QwX0KmV4/ae2kyYkRknsE79CRusYS2U5D8qwn2wq0cn1x12f3tm3F3+5FgmDdbuGdQTuCLSKMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/requester-fetch/-/requester-fetch-5.59.0.tgz",
+ "integrity": "sha512-Lp52TmpA1QtNmdHzs505Xwf4tgII7RAapkDSF9AAtWIBETcGaTIaXci4Rd9nS6SdaWK1BWTSqAPp5wzh6UN3Ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/@algolia/requester-node-http/-/requester-node-http-5.59.0.tgz",
+ "integrity": "sha512-YYHLEs5rC6oRTFwT7bJaKBR9NSFzikeVHGAT1ffATmUQzR8XqyhHXjoieAUoR7fBU6I5cfy1FVeh5GoRgriuzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
"node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
@@ -1111,13 +1370,13 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
- "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
+ "version": "7.29.9",
+ "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.9.tgz",
+ "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.29.7"
+ "@babel/types": "^7.29.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1218,9 +1477,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
- "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6845,6 +7104,57 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/@docsearch/css": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmmirror.com/@docsearch/css/-/css-3.8.2.tgz",
+ "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmmirror.com/@docsearch/js/-/js-3.8.2.tgz",
+ "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/react": "3.8.2",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/js/node_modules/@docsearch/react": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmmirror.com/@docsearch/react/-/react-3.8.2.tgz",
+ "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.2",
+ "algoliasearch": "^5.14.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@earendil-works/pi-ai": {
"version": "0.85.1",
"resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.85.1.tgz",
@@ -7921,6 +8231,16 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@iconify-json/simple-icons": {
+ "version": "1.2.99",
+ "resolved": "https://registry.npmmirror.com/@iconify-json/simple-icons/-/simple-icons-1.2.99.tgz",
+ "integrity": "sha512-kouZhqvUoNdxEe+lZksbJJZMCZv4b4Ob62O1GW3fcpz/I0mVPzM+9/Qf/DUuv5ns8l6c46D8M/ubhJjjbLp9HQ==",
+ "dev": true,
+ "license": "CC0-1.0",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
@@ -10300,6 +10620,93 @@
"selderee": "~0.12.0"
}
},
+ "node_modules/@shikijs/core": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/core/-/core-2.5.0.tgz",
+ "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.4"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz",
+ "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^3.1.0"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz",
+ "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/langs/-/langs-2.5.0.tgz",
+ "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/themes/-/themes-2.5.0.tgz",
+ "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/transformers/-/transformers-2.5.0.tgz",
+ "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/@shikijs/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmmirror.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sindresorhus/df": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-3.1.1.tgz",
@@ -11072,6 +11479,24 @@
"@types/node": "*"
}
},
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmmirror.com/@types/markdown-it/-/markdown-it-14.2.0.tgz",
+ "integrity": "sha512-NoQ2yGlLWj4wpxMs+TYmRKk3thDrQ97agr7sFqfLsAlvoS8SNQuTrlObhFqG9iugdTtgOE9jpJ6FNM4ZGsa5xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -11082,6 +11507,13 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
@@ -11220,6 +11652,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/webxr": {
"version": "0.5.24",
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
@@ -11798,6 +12237,282 @@
"win32"
]
},
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.43.tgz",
+ "integrity": "sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/shared": "3.5.43",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-core/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/@vue/compiler-core/node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.43.tgz",
+ "integrity": "sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.43.tgz",
+ "integrity": "sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/compiler-core": "3.5.43",
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/compiler-ssr": "3.5.43",
+ "@vue/shared": "3.5.43",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.28",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.43.tgz",
+ "integrity": "sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.10.tgz",
+ "integrity": "sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.10"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz",
+ "integrity": "sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.10",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.10",
+ "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz",
+ "integrity": "sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.43.tgz",
+ "integrity": "sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.43.tgz",
+ "integrity": "sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.43.tgz",
+ "integrity": "sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.43",
+ "@vue/runtime-core": "3.5.43",
+ "@vue/shared": "3.5.43",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.43.tgz",
+ "integrity": "sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.43",
+ "@vue/runtime-dom": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.43.tgz",
+ "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vueuse/core": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-12.8.2.tgz",
+ "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/integrations": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-12.8.2.tgz",
+ "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vueuse/core": "12.8.2",
+ "@vueuse/shared": "12.8.2",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.8.2.tgz",
+ "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "12.8.2",
+ "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-12.8.2.tgz",
+ "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/@wecom/aibot-node-sdk": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@wecom/aibot-node-sdk/-/aibot-node-sdk-1.0.6.tgz",
@@ -11980,6 +12695,32 @@
}
}
},
+ "node_modules/algoliasearch": {
+ "version": "5.59.0",
+ "resolved": "https://registry.npmmirror.com/algoliasearch/-/algoliasearch-5.59.0.tgz",
+ "integrity": "sha512-wUXzaeI7B526W4y1gFg3lcxgDZ67XSgRJIiellYWOas/pLpO7rOtxm9Gr2E/C8aiSDXIgx1q5TdSsvK67Uakqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/abtesting": "1.25.0",
+ "@algolia/client-abtesting": "5.59.0",
+ "@algolia/client-analytics": "5.59.0",
+ "@algolia/client-common": "5.59.0",
+ "@algolia/client-insights": "5.59.0",
+ "@algolia/client-personalization": "5.59.0",
+ "@algolia/client-query-suggestions": "5.59.0",
+ "@algolia/client-search": "5.59.0",
+ "@algolia/ingestion": "1.59.0",
+ "@algolia/monitoring": "1.59.0",
+ "@algolia/recommend": "5.59.0",
+ "@algolia/requester-browser-xhr": "5.59.0",
+ "@algolia/requester-fetch": "5.59.0",
+ "@algolia/requester-node-http": "5.59.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -12412,6 +13153,16 @@
"node": "*"
}
},
+ "node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -13233,6 +13984,19 @@
"node": ">=6.6.0"
}
},
+ "node_modules/copy-anything": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.1.5.tgz",
+ "integrity": "sha512-vePst2VLTSqPglW7Q98VwFpGiGpOHTyXIo81MO5VyLecA5zMbZw/P/V1vmwD1jksa2iJpn/YkDrJ3XhTfzUyhQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/core-js": {
"version": "3.50.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.50.0.tgz",
@@ -14950,6 +15714,13 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
+ "node_modules/emoji-regex-xs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz",
+ "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -16098,6 +16869,16 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/focus-trap": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmmirror.com/focus-trap/-/focus-trap-7.8.0.tgz",
+ "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tabbable": "^6.4.0"
+ }
+ },
"node_modules/follow-redirects": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
@@ -16850,6 +17631,30 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmmirror.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-to-jsx-runtime": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
@@ -16953,6 +17758,13 @@
"node": ">=16.9.0"
}
},
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -17039,6 +17851,17 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
@@ -18117,6 +18940,13 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
+ "node_modules/mark.js": {
+ "version": "8.11.1",
+ "resolved": "https://registry.npmmirror.com/mark.js/-/mark.js-8.11.1.tgz",
+ "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/markdown-table": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
@@ -19306,6 +20136,13 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/minisearch": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/minisearch/-/minisearch-7.2.0.tgz",
+ "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/minizlib": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
@@ -19319,6 +20156,13 @@
"node": ">= 18"
}
},
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@@ -19473,9 +20317,9 @@
"optional": true
},
"node_modules/nanoid": {
- "version": "3.3.16",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
- "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
+ "version": "3.3.20",
+ "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.20.tgz",
+ "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
"dev": true,
"funding": [
{
@@ -21809,6 +22653,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/oniguruma-to-es": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz",
+ "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex-xs": "^1.0.0",
+ "regex": "^6.0.1",
+ "regex-recursion": "^6.0.2"
+ }
+ },
"node_modules/onnxruntime-common": {
"version": "1.23.2",
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.23.2.tgz",
@@ -22433,6 +23289,13 @@
"url": "https://github.com/sponsors/KillyMXI"
}
},
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -22618,9 +23481,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.25",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz",
- "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==",
+ "version": "8.5.29",
+ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.29.tgz",
+ "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
"dev": true,
"funding": [
{
@@ -22638,9 +23501,9 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.16",
+ "nanoid": "^3.3.19",
"picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
+ "source-map-js": "^1.2.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -22739,6 +23602,25 @@
}
}
},
+ "node_modules/preact": {
+ "version": "10.29.8",
+ "resolved": "https://registry.npmmirror.com/preact/-/preact-10.29.8.tgz",
+ "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "preact-render-to-string": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "preact-render-to-string": {
+ "optional": true
+ }
+ }
+ },
"node_modules/prebuild-install": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
@@ -23466,6 +24348,33 @@
"license": "MIT",
"optional": true
},
+ "node_modules/regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmmirror.com/regex/-/regex-6.1.0.tgz",
+ "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-recursion": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmmirror.com/regex-recursion/-/regex-recursion-6.0.2.tgz",
+ "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regex-utilities": "^2.3.0"
+ }
+ },
+ "node_modules/regex-utilities": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/regex-utilities/-/regex-utilities-2.3.0.tgz",
+ "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/rehype-katex": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz",
@@ -23672,6 +24581,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/rgbcolor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
@@ -23901,6 +24817,14 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/search-insights": {
+ "version": "2.17.3",
+ "resolved": "https://registry.npmmirror.com/search-insights/-/search-insights-2.17.3.tgz",
+ "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/section-matter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
@@ -24471,6 +25395,23 @@
"win32"
]
},
+ "node_modules/shiki": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/shiki/-/shiki-2.5.0.tgz",
+ "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/langs": "2.5.0",
+ "@shikijs/themes": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
"node_modules/side-channel": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
@@ -24666,9 +25607,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.2.tgz",
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -24697,6 +25638,16 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
@@ -24910,6 +25861,19 @@
"node": ">= 8.0"
}
},
+ "node_modules/superjson": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.6.tgz",
+ "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -24947,6 +25911,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tabbable": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmmirror.com/tabbable/-/tabbable-6.5.0.tgz",
+ "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tar": {
"version": "7.5.22",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz",
@@ -26435,6 +27406,552 @@
"@esbuild/win32-x64": "0.28.1"
}
},
+ "node_modules/vitepress": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmmirror.com/vitepress/-/vitepress-1.6.4.tgz",
+ "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/css": "3.8.2",
+ "@docsearch/js": "3.8.2",
+ "@iconify-json/simple-icons": "^1.2.21",
+ "@shikijs/core": "^2.1.0",
+ "@shikijs/transformers": "^2.1.0",
+ "@shikijs/types": "^2.1.0",
+ "@types/markdown-it": "^14.1.2",
+ "@vitejs/plugin-vue": "^5.2.1",
+ "@vue/devtools-api": "^7.7.0",
+ "@vue/shared": "^3.5.13",
+ "@vueuse/core": "^12.4.0",
+ "@vueuse/integrations": "^12.4.0",
+ "focus-trap": "^7.6.4",
+ "mark.js": "8.11.1",
+ "minisearch": "^7.1.1",
+ "shiki": "^2.1.0",
+ "vite": "^5.4.14",
+ "vue": "^3.5.13"
+ },
+ "bin": {
+ "vitepress": "bin/vitepress.js"
+ },
+ "peerDependencies": {
+ "markdown-it-mathjax3": "^4",
+ "postcss": "^8"
+ },
+ "peerDependenciesMeta": {
+ "markdown-it-mathjax3": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vitepress/node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/vitepress/node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/vitepress/node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
"node_modules/vitest": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
@@ -26535,6 +28052,28 @@
"node": ">=0.10.0"
}
},
+ "node_modules/vue": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.43.tgz",
+ "integrity": "sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/compiler-sfc": "3.5.43",
+ "@vue/runtime-dom": "3.5.43",
+ "@vue/server-renderer": "3.5.43",
+ "@vue/shared": "3.5.43"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/w3c-xmlserializer": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
diff --git a/package.json b/package.json
index 8a26a74f..a2b1dfe2 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,9 @@
"type": "module",
"scripts": {
"dev": "electron-vite dev",
+ "docs:dev": "vitepress dev sites/docs --config sites/docs/.vitepress/config.mts",
+ "docs:build": "vitepress build sites/docs --outDir sites/docs-dist --config sites/docs/.vitepress/config.mts",
+ "docs:preview": "vitepress preview sites/docs-dist",
"start": "electron-vite preview",
"typecheck": "tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.agent.json && tsc --noEmit -p tsconfig.web.json",
"lint": "eslint .",
@@ -419,6 +422,7 @@
"typescript": "^6.0.3",
"typescript-eslint": "^8.65.0",
"vite": "^7.3.6",
+ "vitepress": "^1.6.4",
"vitest": "^4.1.10"
},
"optionalDependencies": {
diff --git a/sites/README.md b/sites/README.md
index 695844f8..2e80c4b8 100644
--- a/sites/README.md
+++ b/sites/README.md
@@ -1,6 +1,6 @@
# GoodBuddy 静态官网
-`sites` 是无需构建步骤或额外依赖的中英文静态官网源码,可直接托管整个目录。
+`sites` 包含中英文官网和使用 VitePress 默认主题的用户手册。官网可直接预览;手册正文使用 Markdown 维护,发布前需要构建。
正式站点地址:
@@ -16,7 +16,7 @@ x64 / arm64 安装包与独立龙芯 loong64 预览版,并说明兼容性与
首屏示意显示所选 Runtime,不展示 Ask / Execute 模式或一般工具审批。工具说明以
已启用能力和 MCP 服务分配为准;站点校验会检查中英文页面中的旧模式文案与控件。
FAQ 使用原生 details/summary,说明模型费用、数据流向、组件准备和远端使用条件。
-英文页面位于 `en.html`,用平台与架构覆盖描述同一产品事实,不使用中文信创
+英文页面位于 `en.html`,用户手册由 `docs/content/` 中按功能拆分的 Markdown 内容构建到 `docs-dist/`。英文页面用平台与架构覆盖描述同一产品事实,不使用中文信创
政策语汇;页面会标明独立的 LoongArch 实验预览,但三个平台的下载按钮仍始终
前往 GitHub 最新正式 Release。
首屏产品界面默认正面展示,在精确指针设备上使用克制的 3D 倾斜、
@@ -26,7 +26,7 @@ FAQ 使用原生 details/summary,说明模型费用、数据流向、组件准
## 部署
`.github/workflows/pages.yml` 会在 `main` 分支中的官网文件发生变化后,
-校验并部署整个 `sites` 目录。工作流也支持在 GitHub Actions 中手动运行。
+安装依赖、构建手册、校验并部署整个 `sites` 目录。工作流也支持在 GitHub Actions 中手动运行。
首次部署前,需要在 GitHub 仓库的 **Settings > Pages** 中将 **Source**
设为 **GitHub Actions**。站点使用项目 Pages 地址,不需要 `CNAME` 文件
@@ -42,17 +42,41 @@ FAQ 使用原生 details/summary,说明模型费用、数据流向、组件准
## 本地预览
+使用 Node.js 24,在仓库根目录安装依赖后运行 `npm run docs:dev`。访问终端显示的地址,在手册 base 下打开 `zh/` 或 `en/`,默认路径为 `/docs-dist/zh/` 和 `/docs-dist/en/`。Markdown 修改会触发热更新。
+
+预览构建产物时,先按下方命令使用本地 base 构建,再运行 `npm run docs:preview`;同样以终端显示的地址和端口为准,在 base 下打开 `zh/` 或 `en/`。
+
+### 维护手册
+
+- 章节顺序、双语标题和稳定 slug 维护在 `docs/manifest.ts`;VitePress 配置从该清单生成侧栏。
+- 中文正文放在 `docs/content/zh/`,英文正文放在 `docs/content/en/`。每个语言目录都必须包含 manifest 中的十二个 slug:`start`、`concepts`、`connections`、`runtimes`、`workbar`、`knowledge`、`notes`、`tasks`、`supervision`、`remote`、`privacy`、`troubleshooting`。
+- 每个章节文件以一个 `#` 标题开始,正文使用 `##` 和 `###`。除 `start.md` 的 `##` 章节标题外,其余文件的 `#` 标题应与 manifest 对应语言的标题一致。标题尽量使用普通文字。
+- VitePress 根目录为 `docs/`,`srcDir` 为 `content`。新增章节时添加两份 Markdown 并更新 manifest,同时更新校验脚本中的必需章节清单。
+- `zh/start.md` 和 `en/start.md` 分别重写为 `zh/index.md` 和 `en/index.md`,入口为 base 下的 `zh/` 和 `en/`;其余章节路径为 `zh/.html` 和 `en/.html`。
+- 配置维护在 `docs/.vitepress/config.mts`,使用默认主题的本地搜索、双语侧栏和原生语言切换,不维护自定义主题或布局。
+- 生产 base 为 `/goodbuddy/docs-dist/`,开发与预览默认使用 `/docs-dist/`,可用 `DOCS_BASE` 覆盖。构建和预览的 base 必须一致。开始页下载链接使用正式官网绝对地址:`https://mesalogo.github.io/goodbuddy/#download` 和 `https://mesalogo.github.io/goodbuddy/en.html#download`。
+- `docs-dist/` 是构建产物,已忽略,不手工编辑或提交。
+
+整站预览前先构建,以下命令在仓库根目录执行:
+
+```powershell
+$env:DOCS_BASE='/docs-dist/'
+npm run docs:build
+Remove-Item Env:DOCS_BASE
+```
+
在仓库根目录运行:
```powershell
python -m http.server 4173 --bind 127.0.0.1 --directory sites
```
-然后访问 。也可以直接用浏览器打开 `sites/index.html`。
+然后访问官网 或 ,中文手册 ,英文手册 。手册需要通过 HTTP 服务预览。
## 校验
```powershell
+npm run docs:build
node sites/scripts/validate.mjs
node --check sites/app.js
node --check sites/language.js
@@ -68,6 +92,7 @@ node --test sites/scripts/app.test.mjs sites/scripts/release-index.test.mjs
不可变 URL,并按发布生成器的实际命名绑定版本、平台、架构和格式。移动
导航行为测试同时覆盖现代 MediaQueryList 监听与旧版 Safari 的 `addListener`
回退。英文下载入口固定指向 GitHub Release。
+手册校验覆盖全部 24 个构建章节的服务端渲染标题与正文、双语侧栏、语言切换和本地资源,并检查 Markdown 标题与 manifest 一致。上述命令检查生产 base;若检查本地构建,运行校验脚本时也设置 `DOCS_BASE='/docs-dist/'`。
## 下载入口
@@ -173,10 +198,24 @@ SIL OFL 1.1 许可证位于 `assets/fonts/inter-OFL.txt`。
焦点,切换回桌面宽度也会解除隔离。媒体查询监听兼容现代浏览器和使用
`MediaQueryList.addListener` 的旧版 Safari。
+## 手册开发
+
+手册正文维护在 `docs/content/zh/` 与 `docs/content/en/`,章节清单维护在
+`docs/manifest.ts`,主题、语言、侧栏和本地搜索配置维护在 `docs/.vitepress/config.mts`。本地开发运行:
+
+```powershell
+npm run docs:dev
+```
+
+发布前清除本地 `DOCS_BASE` 覆盖并运行 `npm run docs:build`。VitePress 将中英文各十二个章节及资源生成到 `docs-dist/`,入口为 `docs-dist/zh/index.html` 和 `docs-dist/en/index.html`。Pages 工作流会在校验前自动构建;不要直接编辑构建产物。
+
## 文件
- `index.html`:页面结构与简体中文内容
- `en.html`:不包含信创适配文案的英文页面
+- `docs/content/zh/`、`docs/content/en/`:按功能拆分的中英文手册 Markdown 正文
+- `docs/manifest.ts`:手册章节顺序、标题和中英文映射
+- `docs/.vitepress/config.mts`:VitePress 默认主题、语言、路由、本地搜索和构建配置,输出到 `docs-dist/`
- `styles.css`:语义令牌、浅深主题、焦点与响应式布局
- `app.js`:主题、移动导航、当前章节和中文下载索引
- `language.js`:浏览器语言自动选择与手动语言偏好
diff --git a/sites/docs/.vitepress/config.mts b/sites/docs/.vitepress/config.mts
new file mode 100644
index 00000000..b99e606d
--- /dev/null
+++ b/sites/docs/.vitepress/config.mts
@@ -0,0 +1,55 @@
+import { defineConfig } from 'vitepress'
+import { chapters } from '../manifest'
+
+const base = process.env.DOCS_BASE ?? '/goodbuddy/docs-dist/'
+
+const sidebar = (language: 'zh' | 'en') => [
+ {
+ text: language === 'zh' ? '用户手册' : 'User guide',
+ items: chapters.map(({ slug, title }) => ({
+ text: title[language],
+ link: `/${language}/${slug === 'start' ? '' : `${slug}.html`}`,
+ })),
+ },
+]
+
+export default defineConfig({
+ title: 'GoodBuddy',
+ description: 'GoodBuddy user guide',
+ base,
+ srcDir: 'content',
+ rewrites: {
+ 'zh/start.md': 'zh/index.md',
+ 'en/start.md': 'en/index.md',
+ },
+ locales: {
+ root: { label: 'English', lang: 'en', link: '/en/' },
+ zh: { label: '简体中文', lang: 'zh-CN', link: '/zh/' },
+ },
+ themeConfig: {
+ siteTitle: 'GoodBuddy',
+ search: { provider: 'local' },
+ outline: 'deep',
+ sidebar: {
+ '/zh/': sidebar('zh'),
+ '/en/': sidebar('en'),
+ },
+ socialLinks: [{ icon: 'github', link: 'https://github.com/mesalogo/goodbuddy' }],
+ locales: {
+ root: {
+ langMenuLabel: '语言',
+ nav: [
+ { text: 'Home', link: 'https://mesalogo.github.io/goodbuddy/en.html' },
+ { text: 'GitHub', link: 'https://github.com/mesalogo/goodbuddy' },
+ ],
+ },
+ zh: {
+ langMenuLabel: 'Languages',
+ nav: [
+ { text: '官网首页', link: 'https://mesalogo.github.io/goodbuddy/' },
+ { text: 'GitHub', link: 'https://github.com/mesalogo/goodbuddy' },
+ ],
+ },
+ },
+ },
+})
diff --git a/sites/docs/content/en/concepts.md b/sites/docs/content/en/concepts.md
new file mode 100644
index 00000000..f81ba6b2
--- /dev/null
+++ b/sites/docs/content/en/concepts.md
@@ -0,0 +1,25 @@
+# Core concepts
+
+GoodBuddy connects conversations, model requests, and file work through a small set of related objects. Knowing these objects makes Runtime selection, knowledge scope, and execution history easier to understand.
+
+## Projects and conversations
+
+A Project is a working scope with a project directory, project Runtime choice, conversations, and tasks. A Conversation is a continuing chat record containing messages, tool activity, and citations. A conversation may have no Task or several Tasks; linking a Task does not change the conversation type.
+
+## Model connections and Runtimes
+
+A model connection is a reusable service configuration with a URL, protocol, model name, and credentials. A Runtime is the way a request runs: Direct models are called by GoodBuddy, while OpenCode and Continue use their native agent clients and DeepSeek Harness uses GoodBuddy's compatible managed path. See [Choose a Runtime](./runtimes.html).
+
+A Runtime uses the selected capabilities and current account permissions. A project can define the default choice, and a conversation can inherit it or select its own. If a connection is deleted or incompatible, the picker explains the fallback or failure instead of silently choosing another credentialed model.
+
+## Capabilities and execution spaces
+
+A capability is something a request may use, such as knowledge retrieval, workspace files, a terminal, a browser, or an MCP service. Availability depends on the Runtime, project settings, conversation scope, and execution space. An execution space is where files, terminals, managed processes, and the Runtime actually run: a local project directory or a remote SSH project directory.
+
+## Task, Job, and Run
+
+A Task is work that the user explicitly creates or confirms, and it has exactly one associated Conversation. A Job is an internal step or scheduled occurrence within a Task. A Run is one execution attempt and record for a Job or subjob. Ordinary chat requests, tool calls, and Runs do not become Tasks automatically. The UI primarily exposes Tasks; Job and Run details appear through activity and execution records when available.
+
+## No Ask / Execute mode
+
+GoodBuddy has no Ask / Execute work mode and does not require a mode switch before using an enabled capability. A normal request uses the selected Runtime, enabled capabilities, and current account permissions. If a Runtime lacks a capability, GoodBuddy reports that limitation. Summaries, note analysis, and supervision reviews remain dedicated text requests without tools.
diff --git a/sites/docs/content/en/connections.md b/sites/docs/content/en/connections.md
new file mode 100644
index 00000000..589c4986
--- /dev/null
+++ b/sites/docs/content/en/connections.md
@@ -0,0 +1,19 @@
+# Configure model connections
+
+A model connection stores a service URL, protocol, model name, authentication method, and optional request customization. Projects and conversations can reuse it, while credentials remain managed by GoodBuddy's main process. A usable connection does not mean every Runtime supports every field.
+
+## Create and test a connection
+
+Open Settings > Model connections > LLM. Create a connection with a name, HTTP or HTTPS URL, protocol, model ID, and API key. Save it and run Test connection. A successful test proves that the basic connection works; image generation, tools, and native Runtime clients still need their own real request path.
+
+Connections can be copied. Copy creates a new connection and leaves the original unchanged. A saved key is copied through the protected credential path and is never returned to the page or error text. Choose the connection in a project or conversation picker, or choose the Runtime default.
+
+## Custom headers and body
+
+The Advanced settings area has two JSON editors. Headers must be an object whose values are strings, and the body must be a serializable top-level JSON object. Syntax, type, size, and reserved-field errors block saving while keeping the original text for correction.
+
+Runtime, protocol, and authentication fields take precedence. Custom values cannot replace model, message, tool, streaming, or authentication fields. Body values merge only at the top level. Keep API keys and other secrets in the dedicated credential field. Direct models and Continue support both customizations; local OpenCode and DeepSeek Harness support headers but not custom body; managed remote OpenCode supports both.
+
+## Scope and diagnostics
+
+Connections are Settings resources; projects and conversations store the selection relationship. Vector connections are for knowledge indexing and do not appear in Runtime model pickers. For diagnosis, test the basic connection first, then confirm the Runtime and model used by the real request. If custom values appear to cause failure, clear them temporarily. A connection test is not a generation guarantee.
diff --git a/sites/docs/content/en/knowledge.md b/sites/docs/content/en/knowledge.md
new file mode 100644
index 00000000..5f746637
--- /dev/null
+++ b/sites/docs/content/en/knowledge.md
@@ -0,0 +1,17 @@
+# Build a knowledge base
+
+A knowledge base brings local sources or a configured external knowledge service into retrieval. For a first setup, create a base, add sources, wait until it is searchable, and use it in the current conversation.
+
+## Local workflow
+
+Create a local base, add files, directories, or web sources, and wait for parsing and indexing. In the composer, explicitly select the knowledge scope and choose Model retrieves when needed or Retrieve before every request. Open citations to inspect the matching chunk, surrounding context, and source.
+
+Knowledge scope is stored per Conversation. New conversations start with no selected base, and creating a base does not re-enable other bases you turned off. Each request uses only its explicit scope. The first mode lets the model decide whether to use read-only search; the second searches before the Runtime starts and shows zero results or degradation. Image generation does not run the pre-search.
+
+Local retrieval can use full-text, Chinese phrase, vector, and graph channels. A citation is bounded evidence for the request, not proof that every answer sentence came from it. Check parsing, full-text, vector, and graph status separately. Vector failure can leave full-text and Chinese retrieval available, with the degraded channel shown. A failed rebuild keeps the last ready index.
+
+## External knowledge bases
+
+GoodBuddy can manage Dify, FastGPT, and RAGFlow instances and bind a remote base into the local list. Retrieval sends only the current query, remote ID, and saved settings. GoodBuddy checks returned chunks before showing citations.
+
+External bindings are read-only. GoodBuddy does not create, edit, upload, or delete remote bases, documents, chunks, or graphs, and does not bulk-sync them. Removing a local binding does not delete remote data. Authentication, timeout, target, and provider failures remain visible and do not silently switch instances.
diff --git a/sites/docs/content/en/notes.md b/sites/docs/content/en/notes.md
new file mode 100644
index 00000000..1975b0db
--- /dev/null
+++ b/sites/docs/content/en/notes.md
@@ -0,0 +1,21 @@
+# Use Magic Notes
+
+Magic Notes is for meeting records, research drafts, ideas, and long-term plans. Notes are application-level data. The full workspace supports rich text, todos, and paged canvases, while the workbar provides quick browsing and appending.
+
+## Capture conversation content
+
+Choose Add to note from an assistant response, or Save current conversation to note from the conversation menu. Review the preview, source, and destination, then explicitly save. A full capture contains completed user and assistant text, preserving Markdown, line breaks, and code. Reasoning, tool logs, system prompts, binary attachments, and images are excluded.
+
+Saved entries keep structured source information. Open a source to return to the conversation or locate the message. If the source is later removed, the note body remains and the source is marked unavailable. A failed save keeps the preview and destination for retry; cancelling writes nothing.
+
+## Quick panel and full workspace
+
+Open + > Notes in the workbar to search notes, view summaries, and append text. The panel and full workspace share storage, so successful writes appear in both. Unsaved drafts stay in app memory and are protected when changing project, conversation, or workbar visibility. Leaving the panel asks whether to keep or discard a changed draft.
+
+Tags are manual. A note can have up to 10 case-insensitive tags; filter by tags or rename, merge, and delete them in tag management. Deleting a tag does not delete notes.
+
+## Canvas and AI comments
+
+Paged canvases support templates, text, handwriting, highlights, images, and PDF backgrounds. Canvas saves are manual. Zoom changes viewing only; there is no infinite canvas or separate PNG download.
+
+Request AI comments manually, or enable analysis after save. Comments use the default model's image input and the first 1 to 8 configured pages. Visual-only content requires an image-capable model; a text-only model uses a labelled text fallback. Analysis failure never undoes saved content and does not append again automatically.
diff --git a/sites/docs/content/en/privacy.md b/sites/docs/content/en/privacy.md
new file mode 100644
index 00000000..8e5af02b
--- /dev/null
+++ b/sites/docs/content/en/privacy.md
@@ -0,0 +1,19 @@
+# Data and privacy
+
+GoodBuddy is a local-first desktop app and does not require a GoodBuddy account. Whether data leaves the computer depends on the model connection, Runtime, knowledge type, remote project, and browser features you use.
+
+## Data flow
+
+Local conversations, notes, tasks, settings, and knowledge indexes are stored in the application-data directory. Direct models send requests to the selected service; OpenCode, Continue, and Harness call models according to their Runtime configuration. Installing GoodBuddy or opening an empty conversation does not upload history.
+
+With a local knowledge base, sources and indexes stay local and the Runtime receives bounded evidence and citations selected for the request. With Dify, FastGPT, or RAGFlow, the query goes to the configured instance. GoodBuddy does not upload the full conversation or local attachments or write to the external base. Returned bounded chunks and citations are stored with the local conversation.
+
+## Credentials and boundaries
+
+API keys, SSH credentials, and authentication data are managed by Main and protected storage; the Renderer does not read them directly. Custom headers and bodies are ordinary settings, not a place for secrets. Tools, MCP, terminals, and plugins use current-user permissions and enabled capabilities. Ask / Execute is not a separate privacy boundary.
+
+Remote projects send bounded model configuration to an authenticated Agent, where requests run with SSH account permissions. The Agent is not bundled with the desktop package. Reconnect restores confirmed Agent output; uncertain model calls are not replayed automatically.
+
+## Preview and clearing data
+
+Conversation HTML preview handles completed assistant HTML only. Scripts, network requests, forms, nested pages, and window operations are disabled; turning preview off still shows source. Clear local data is an explicit confirmed action and does not delete provider records, remote hosts, remote bases, exported files, or files saved in a workspace.
diff --git a/sites/docs/content/en/remote.md b/sites/docs/content/en/remote.md
new file mode 100644
index 00000000..cae5e5f1
--- /dev/null
+++ b/sites/docs/content/en/remote.md
@@ -0,0 +1,21 @@
+# Remote projects
+
+Remote projects run Workspace, terminals, and supported Runtimes on an SSH host. A remote path is never treated as local. Files, processes, network access, and model calls are bounded by the SSH account and prepared environment. The GoodBuddy Agent is not included in the desktop installer.
+
+## Prepare an SSH host
+
+Add a Host in remote-project settings with its address, port, user, and authentication method. Before authentication, inspect and explicitly accept the Host Key algorithm and SHA-256 fingerprint. A changed fingerprint requires a separate replacement confirmation. GoodBuddy can use the system SSH Agent or supported certificates; root and SSH Agent Forwarding are not required.
+
+Saving a Host does not mean the environment is ready. Use the Host card to prepare or update the signed Agent and Runtime, then wait for checks. A version-match badge is only a version fact. Failed, cancelled, or disconnected preparation keeps the Host and offers retry.
+
+## Create a project and use its space
+
+Choose a verified Host, enter or select a bounded remote workspace directory, and choose a supported Runtime such as OpenCode or Continue. The project stores the Host ID, remote path, and Runtime choice. Switching projects changes local selection only; the Agent is attached when Workspace or Runtime is first used.
+
+Remote Workspace provides bounded directories, previews, Git, and import. A terminal uses the remote shell. Operations use the SSH account permissions. Local Skills, stdio MCP servers, and tool environments are not uploaded automatically; remote capabilities are those reported by the Agent.
+
+## Failures and boundaries
+
+Check network, port, Host Key, credentials, directory permissions, Agent version, Runtime version, and project permissions separately. If the Agent is unavailable, GoodBuddy does not fall back to an SSH stdio Runtime or secretly run the request locally.
+
+An SSH relay disconnect does not necessarily stop an accepted request. Reconnect restores only output recorded and confirmed by the Agent. An uncertain model call is not replayed automatically because it could duplicate cost or side effects. Stop, Agent shutdown, and remote process failure are shown as cancellation, failure, or unknown outcome.
diff --git a/sites/docs/content/en/runtimes.md b/sites/docs/content/en/runtimes.md
new file mode 100644
index 00000000..98a73a9d
--- /dev/null
+++ b/sites/docs/content/en/runtimes.md
@@ -0,0 +1,22 @@
+# Choose a Runtime
+
+A Runtime selects the execution path for a request. A connection answers which model service to call, while the Runtime organizes the request, tools, and execution space. Each request retains visible status, tool activity, cancellation, and failure information.
+
+## The four choices
+
+| Runtime | Best for | Model configuration |
+| --- | --- | --- |
+| Direct models | Chat, retrieval, image generation, and GoodBuddy capabilities | GoodBuddy model connections |
+| OpenCode | Coding agents, files, commands, and Skills | GoodBuddy connection or OpenCode config |
+| Continue | Rules, prompt presets, and coding work | GoodBuddy connection or Continue config |
+| DeepSeek Harness | A fixed host and compatible plugin capabilities | GoodBuddy-managed compatible connection |
+
+Use Direct models for ordinary questions and retrieval. Choose OpenCode or Continue for continuing project-file and command work. Choose DeepSeek Harness when its fixed host capabilities fit. Tools and native questions differ by Runtime.
+
+## Selection and capabilities
+
+A project selects a concrete Runtime. A conversation follows the project by default, while the composer can select its own choice. The picker shows defaults, individual connections, and Runtime-owned configuration with their source. Requests use the Runtime, enabled capabilities, knowledge scope, execution space, and current account permissions.
+
+GoodBuddy has no Ask / Execute mode and no separate general tool-approval switch. Unsupported capabilities are reported clearly. Local Runtimes run locally; remote projects use the Agent and managed Runtime on the SSH host. The Agent is not bundled with the desktop app; see [Remote projects](./remote.html).
+
+The workbar shows Runtime, connection, tool state, cancellation, errors, and saved results. Closing a panel does not cancel background work, and stopping a request affects that request only.
diff --git a/sites/docs/content/en/start.md b/sites/docs/content/en/start.md
new file mode 100644
index 00000000..f06a2b6d
--- /dev/null
+++ b/sites/docs/content/en/start.md
@@ -0,0 +1,30 @@
+# GoodBuddy User Guide
+
+This guide is for a first GoodBuddy session. No GoodBuddy account is required. Conversations, projects, and notes are local by default; model providers, remote hosts, and external knowledge services receive data only when you configure and use them.
+
+## Get started
+
+### Install GoodBuddy
+
+Choose a platform, processor architecture, and package from the [home page](https://mesalogo.github.io/goodbuddy/en.html#download). Windows provides an installer and a portable ZIP. Linux provides AppImage, DEB, and RPM. LoongArch uses a separate experimental preview channel. Start the app after installation; the first launch does not require sign-in.
+
+### Initial setup
+
+1. Open Settings, confirm the local data location, and prepare a text model connection.
+2. In Model connections, enter the service URL, protocol, model name, and credentials, then run a connection test. See [Configure model connections](./connections.html) for the field rules.
+3. Create a project and choose its project directory and Runtime. A project groups conversations, workspace access, and tasks.
+4. Open or create a conversation and send a simple question first. Once that works, try files, knowledge, or remote operations.
+
+### Projects and conversations
+
+A project is a working scope that can contain many conversations. A conversation stores user messages, assistant replies, tool activity, and citations; it can also be associated with multiple tasks. New conversations usually inherit the project Runtime choice, while the composer can select a conversation-specific choice.
+
+When changing projects or working directories, check the workspace and terminal scope in the [assistant workbar](./workbar.html). Before sending a request, confirm the Runtime, model, and knowledge scope so content goes to the intended service.
+
+### Local data
+
+Conversations, notes, task records, knowledge indexes, and settings are stored in the system application-data directory. Clear local data is an explicit Settings action with confirmation. Uninstalling the app does not delete exported files, remote directories, or provider-side records. See [Data and privacy](./privacy.html) for the data boundaries.
+
+### Continue reading
+
+Read [Core concepts](./concepts.html) for the relationship between projects, conversations, and Runtimes. Then configure a [knowledge base](./knowledge.html), create [tasks](./tasks.html), or set up a [remote project](./remote.html).
diff --git a/sites/docs/content/en/supervision.md b/sites/docs/content/en/supervision.md
new file mode 100644
index 00000000..04009761
--- /dev/null
+++ b/sites/docs/content/en/supervision.md
@@ -0,0 +1,25 @@
+# Supervision
+
+Supervision reviews completed work, highlights changes and issues, and records supported results in the story graph. It does not send messages, approve tools, expand file scope, or change execution permissions. The Supervisor app is off by default.
+
+## Enablement and scope
+
+Enable Supervisor in the app center, then choose the default text model or an existing text connection in Settings. The first review requires an explicit project, conversation, and time range. Automatic supervision can target Global or selected projects; changing the active project does not change a saved scope.
+
+## Review and story graph
+
+Work review reads conversations, Tasks, notes, and sources within the selected scope and produces sourced summaries, changes, and unresolved items. With no valid new change it records no change and does not call the model. Review is incremental by default; use Reorganize for a historical interval.
+
+The story graph presents events, entities, relationships, and changes over time. Select an object to inspect its sources. Conversations, notes, and knowledge bases remain the owners of source text. You can continue a discussion after checking evidence or preview a write to a local knowledge base. External knowledge remains read-only.
+
+## Follow, pin, and intervene
+
+The Supervision panel can follow the active conversation or pin to a conversation or Task. A pinned target stays selected across page changes and reports an error if it becomes unavailable. Suggestions create editable drafts or explicit next actions; they enter a conversation only after you choose to send them.
+
+Supervisor does not execute suggestions and cannot send messages, approve tools, change capability switches, or expand workspace access. Its model calls are internal text requests without tools.
+
+## Heartbeat and failures
+
+Smart Heartbeat is the scheduled wake-up mechanism. It checks incremental changes within its scope and generates suggestions or updates memory according to the plan. The app and each plan have separate enabled states; disabling the app prevents new heartbeat runs, while an already started run may finish.
+
+Pause, cancel, and failure keep the last successful result and saved batches. The run shows covered and omitted scope and can be retried when valid. A failed suggestion stage does not undo a published graph or review. Supervisor being off by default does not affect ordinary chat or Tasks.
diff --git a/sites/docs/content/en/tasks.md b/sites/docs/content/en/tasks.md
new file mode 100644
index 00000000..3a1df8b5
--- /dev/null
+++ b/sites/docs/content/en/tasks.md
@@ -0,0 +1,19 @@
+# Tasks
+
+A Task is work that you explicitly create or confirm. It has exactly one associated Conversation, while one Conversation can have several Tasks. Ordinary chat requests and tool calls do not appear in Task Center automatically.
+
+## Immediate and scheduled work
+
+Choose New task in Task Center or the conversation task area. Enter the request; the name can be blank and GoodBuddy will derive one. Immediate execution is the default. You can choose a one-time, daily, or weekly schedule and select the current conversation, another conversation in the project, or a new conversation. The request, conversation, and schedule are submitted together.
+
+A Task uses the associated conversation's Runtime, capabilities, knowledge scope, and workspace when it runs. It has no Ask / Execute mode and does not gain permission because it runs in the background. A new conversation does not copy source history.
+
+## Task, Job, and Run
+
+Task is the user-facing object. An immediate run, schedule occurrence, or retry may create internal Jobs and Runs, but they do not become new Task entries. Task Center aggregates status, progress, schedule, and attention items; Activity and Runtime panels provide detail.
+
+A recurring schedule remains one Task. Pause, resume, run now, and cancel act on the Task. Deleting it normally stops future scheduling while keeping the Conversation and messages. Deleting one queued occurrence does not delete the Task.
+
+## Queue and Heartbeat
+
+Normal and Task messages use the same Conversation queue. A due occurrence waits while a reply is running. You can remove an unstarted item or choose Run now and interrupt. Later items can continue after cancellation or failure. Smart Heartbeat is not a Task Center item; it belongs to [Supervision](./supervision.html) and wakes incremental reviews and suggestions.
diff --git a/sites/docs/content/en/troubleshooting.md b/sites/docs/content/en/troubleshooting.md
new file mode 100644
index 00000000..ad9d3b7c
--- /dev/null
+++ b/sites/docs/content/en/troubleshooting.md
@@ -0,0 +1,23 @@
+# Troubleshooting
+
+First confirm the current project, conversation, Runtime, model, and local or remote execution space. Check request status and activity before repeating a send or rebuilding all data.
+
+## The model connection test fails
+
+Check protocol, URL, model ID, API key, proxy, certificate, and provider limits. Clear custom headers and body temporarily and test again. If the basic test succeeds but generation fails, confirm the Runtime and model capability; a connection test is not a generation guarantee.
+
+## The reply does not use tools or files
+
+Check Runtime support, execution space, workspace directory, enabled capability or MCP service, and account permissions. Open Workspace or Runtime in the workbar. For remote projects check SSH, Agent readiness, remote path, and Agent version. GoodBuddy has no Ask / Execute mode.
+
+## Knowledge retrieval returns nothing
+
+Check the conversation scope, parsing and full-text status, vector compatibility, and OCR for image-only PDFs. Use Test retrieval to see actual channels and degradation. Test with source words first, then rebuild a failed document or index. External bases also require valid authentication, remote ID, timeout, and provider status.
+
+## A note, Task, or remote project failed
+
+For notes and canvases, confirm that Save was explicitly used; AI comment failure does not undo saved content. For Tasks, check enabled state, pause state, associated conversation, app availability, and the latest error. Heartbeat is off by default. For remote work, check network, Host Key, credentials, permissions, and Agent preparation. Uncertain remote calls are not replayed automatically.
+
+## HTML preview is empty or shows source
+
+Check that the reply is complete, recognizable HTML or an `html`/`htm` block, and HTML rendering is enabled. Streaming replies, user messages, and reasoning remain source text. Scripts, network, forms, and window operations are intentionally disabled in the preview.
diff --git a/sites/docs/content/en/workbar.md b/sites/docs/content/en/workbar.md
new file mode 100644
index 00000000..51592bd4
--- /dev/null
+++ b/sites/docs/content/en/workbar.md
@@ -0,0 +1,25 @@
+# Assistant workbar
+
+The assistant workbar is the application-level workspace on the right side of the main window. It is not attached to one chat message. Chat, knowledge, task, and supervision pages can open it to show tasks, workspace, Runtime, terminals, browser tabs, notes, and supervision status.
+
+## Panels and the add menu
+
+Task Center and Workspace are always-present base panels. Use the + menu to open Runtime, Supervision, Terminal, Processes, Browser, Resources, Documents, or Notes. Terminals and browsers can have multiple instances; Notes is single-instance. Background events update badges or notifications without taking over the current panel.
+
+An open panel shows its capability, instance, and target. When a capability is unavailable, the panel explains why and provides a configuration path instead of silently hiding it. Terminals, logs, and large results may offer right, bottom, or separate-window docking.
+
+## Follow and pin
+
+Panels that can bind to a target have two scope choices: follow the active context, or pin to a conversation, Task, project, Runtime, terminal, workspace, or browser session. Follow mode changes with the project or conversation. Pinned mode stays on its target. If a pinned target disappears, the panel reports that it is unavailable and offers a repair path rather than switching silently.
+
+The active context is only a default. Opening Workspace does not expand file access, and choosing a temporary directory does not silently change project settings. GoodBuddy still validates the project, execution space, and capability before an operation.
+
+## Execution-space boundaries
+
+Workspace shows the current project directory or a local or remote directory that you explicitly choose. A new terminal binds to the project execution space and directory; with no project it uses the local home directory. Browser manages only GoodBuddy-controlled browser tabs, not a browser already open on your system. Processes shows processes created or managed by GoodBuddy, not every system process.
+
+Workspace supports file previews, Git status, and bounded directory operations. A remote workspace uses the Agent on the SSH host and does not pretend that a remote path is local. Terminal input, file operations, browser activity, and Runtime execution each keep their own scope; selecting one panel does not grant another panel more access.
+
+## A practical combination
+
+For project work, let Task Center follow the current project and pin Supervision to one conversation. Use Workspace to inspect files and create a terminal for commands. When reviewing activity, check the project, conversation, Runtime, and local or remote label at the top of the panel. Open a Task for its complete user-facing relation; Job and Run are not separate workbar panels.
diff --git a/sites/docs/content/index.md b/sites/docs/content/index.md
new file mode 100644
index 00000000..782c6824
--- /dev/null
+++ b/sites/docs/content/index.md
@@ -0,0 +1,11 @@
+---
+title: GoodBuddy User Guide
+layout: home
+---
+
+# GoodBuddy User Guide
+
+Choose a language to open the user guide:
+
+- [English](/en/)
+- [简体中文](/zh/)
diff --git a/sites/docs/content/zh/concepts.md b/sites/docs/content/zh/concepts.md
new file mode 100644
index 00000000..f8b8bff2
--- /dev/null
+++ b/sites/docs/content/zh/concepts.md
@@ -0,0 +1,25 @@
+# 核心概念
+
+GoodBuddy 把聊天、模型调用和文件操作放在几个相互关联的对象中。理解这些对象后,选择 Runtime、限制知识范围和查看执行记录会更容易。
+
+## Project 与 Conversation
+
+Project 是项目范围,包含项目目录、项目级 Runtime 选择、会话和任务。Conversation 是一条持续的聊天记录,保存消息、工具活动和引用。一条会话可以没有 Task,也可以关联多个 Task;关联 Task 不会改变会话类型。
+
+## 模型连接与 Runtime
+
+模型连接是可复用的服务配置,通常包含 URL、协议、模型名和凭据。Runtime 是执行请求的方式:直连模型由 GoodBuddy 调用模型服务,OpenCode 和 Continue 使用各自的 Agent 客户端,DeepSeek Harness 使用 GoodBuddy 管理的兼容执行路径。Runtime 的具体选择见[选择 Runtime](./runtimes.html)。
+
+Runtime 会使用当前选择的能力和当前账号权限。项目可以设置默认 Runtime,会话可以继承项目设置或单独选择。模型连接被删除或不兼容时,选择器会说明回退或失败原因,不会悄悄换成另一个有凭据的模型。
+
+## Capability 与执行空间
+
+Capability 是一次请求可以使用的能力,例如知识检索、工作区文件、终端、浏览器或 MCP 服务。能力是否可用取决于 Runtime、项目设置、会话范围和执行空间。执行空间是文件、终端、受管进程和 Runtime 实际运行的位置,可以是本机项目目录,也可以是远程 SSH 项目目录。
+
+## Task、Job 与 Run
+
+Task 是用户明确创建或确认的工作单位,并且只关联一条 Conversation。Job 是 Task 内部的一次步骤或一次调度触发,Run 是 Job 或子任务的一次执行尝试和记录。普通聊天请求、工具调用和 Run 不会自动变成 Task;用户界面主要展示 Task,Job 和 Run 的细节在活动和执行记录中按需查看。
+
+## 没有 Ask / Execute 模式
+
+GoodBuddy 不提供 Ask / Execute 工作模式,也不会要求先切换模式才能调用已启用的能力。普通请求直接使用所选 Runtime、已启用能力和当前账号权限。某个 Runtime 不支持某项能力时,界面会报告能力缺失;内部摘要、笔记分析和监督回顾仍是专用的无工具文本请求。
diff --git a/sites/docs/content/zh/connections.md b/sites/docs/content/zh/connections.md
new file mode 100644
index 00000000..608bba2f
--- /dev/null
+++ b/sites/docs/content/zh/connections.md
@@ -0,0 +1,23 @@
+# 配置模型连接
+
+模型连接保存服务地址、协议、模型名称、认证方式和可选的请求定制。连接可以被多个项目和会话复用,但凭据仍由 GoodBuddy 的主进程管理。连接本身可用,不代表每个 Runtime 都支持它的全部字段。
+
+## 新建和测试
+
+进入“设置 → 模型连接 → LLM”,新建连接并填写名称、HTTP 或 HTTPS 地址、协议、模型 ID 和 API Key。保存后执行“测试连接”。测试成功只说明当前连接的基础请求可达;图片生成、工具调用或某个 Runtime 的原生客户端仍需在实际请求中验证。
+
+连接可以复制。复制会生成新的连接,不会修改原连接;已保存的密钥通过安全凭据路径复制,不会回显到页面或错误信息。需要在项目或会话中使用时,回到选择器选中连接或选择“跟随默认”。
+
+## 自定义 Header 和 Body
+
+连接详情底部的“高级设置”提供两个 JSON 编辑器。请求头必须是字符串值的 JSON 对象,例如 `{ "X-Team": "research" }`;请求体是可序列化的顶层 JSON 对象。语法、类型、大小或保留字段错误会阻止保存,并保留原始输入供修正。
+
+Runtime、协议和认证生成的字段优先,自定义字段不能替换模型、消息、工具、流式或认证字段。请求体是顶层浅合并,不会递归合并内部对象。API Key、Cookie、签名和其他秘密信息必须放在专用凭据字段,不要写入 Header 或 Body。
+
+直连模型和 Continue 支持两项定制;本地 OpenCode 和 DeepSeek Harness 支持自定义 Header,不使用自定义 Body;受管远程 OpenCode 在其模型网关支持两项。使用 Runtime 自有配置时不引用 GoodBuddy 连接,也不会应用连接级定制。
+
+## 范围和诊断
+
+连接是设置级资源,项目和会话只保存选择关系。向量连接只用于知识库索引,不会出现在 Runtime 模型选择器中。远程项目只能使用支持的远程 Runtime。连接地址变化、证书错误、缺少 API Key、模型不兼容和服务商限流都应在连接详情或请求状态中分别处理。
+
+诊断时先执行基础连接测试,再检查实际请求使用的 Runtime 和模型。若自定义字段导致失败,暂时清空 Header 和 Body 重测;若基础测试成功而生成失败,检查协议、模型能力、输出限制和服务商的实际接口,而不要把测试结果当作生成保证。
diff --git a/sites/docs/content/zh/knowledge.md b/sites/docs/content/zh/knowledge.md
new file mode 100644
index 00000000..5e65f8f1
--- /dev/null
+++ b/sites/docs/content/zh/knowledge.md
@@ -0,0 +1,31 @@
+# 建立知识库
+
+知识库把本地资料或已配置的外部知识服务接入对话检索。第一次使用按“创建知识库 → 添加资料 → 等待可检索 → 用于当前对话”的顺序操作;高级检索参数可以在基本流程可用后再调整。
+
+## 本地知识库流程
+
+1. 在知识库页面新建本地知识库,填写名称和描述。
+2. 添加文件、目录或网页来源,等待解析、全文索引和可选向量索引完成。
+3. 打开会话输入区的知识范围,明确勾选要使用的知识库。
+4. 选择“模型按需检索”或“每次先检索”,再发送问题。
+5. 打开回答中的引用,查看命中分块、相邻上下文和原始来源。
+
+知识范围属于 Conversation。新会话默认不勾选知识库;切换会话会恢复各自的选择。新建一个知识库只把它加入当前会话,不会重新启用你以前取消的其他库。每次请求只能使用当前明确选择的范围。
+
+## 检索方式和证据
+
+“模型按需检索”只开放当前范围的只读搜索能力,由模型决定是否查询;没有调用时不会显示虚假的“已检索”。“每次先检索”会在 Runtime 启动前先查一次,零结果、失败和降级都会显示,模型仍可在同一范围内继续查询。图片生成请求不执行知识预检索。
+
+本地检索可以使用全文、中文词组、向量和知识图谱通道。引用是本次检索得到的有界证据,不等于自动证明回答中的每一句话都来自该片段。点击引用可以核对来源;来源被移动或删除时显示失效,不会打开任意替代路径。
+
+## 状态、降级和维护
+
+分别查看解析、全文、向量和图谱状态。没有向量模型、查询向量失败、索引不兼容或部分文档失败时,全文和中文检索仍可用,但页面会标明降级原因,不会悄悄切换到另一个向量服务。重建失败时,上一版已就绪索引继续服务。
+
+分块设置修改后需要显式重建。重建或大规模检索可以取消;已完成的文档保持可用。原文件移动、解析失败、OCR 不可用和零结果都应按照页面给出的原因处理,而不要只看“索引完成”这一总状态。
+
+## 外部知识库
+
+知识库页面可以管理 Dify、FastGPT 和 RAGFlow 实例,并把远端知识库绑定到 GoodBuddy 的本地列表。检索只发送本次查询、远端知识库 ID 和已保存的检索参数;返回片段经过 GoodBuddy 校验后作为引用使用。
+
+外部绑定是只读的。GoodBuddy 不在外部实例中创建、修改、上传或删除知识库、文档、分块或图谱,也不批量同步远端资料。移除本地绑定不会删除远端内容;外部请求失败时显示实例、认证、超时或目标问题,不自动改用另一个实例。
diff --git a/sites/docs/content/zh/notes.md b/sites/docs/content/zh/notes.md
new file mode 100644
index 00000000..20ee4541
--- /dev/null
+++ b/sites/docs/content/zh/notes.md
@@ -0,0 +1,21 @@
+# 使用魔法笔记
+
+魔法笔记适合保存会议记录、研究草稿、灵感和长期计划。笔记属于应用级数据,不会因为你从哪个项目或会话打开它而改变归属。完整工作区支持富文本、待办和分页画布,助手工作栏提供快速浏览和追加。
+
+## 从会话保存内容
+
+在一条助手回答的操作菜单中选择“加入笔记”,或在会话更多菜单中选择“保存当前对话到笔记”。先检查预览、来源和目标,再选择已有笔记或新建笔记并明确保存。整段会话保存的是已完成的用户和助手文字,保留 Markdown、换行和代码文本;推理、工具日志、系统提示、附件二进制和图片不会写入正文。
+
+保存后的记录保留会话、项目、消息和采集时间等结构化来源。点击来源可以回到会话或定位消息;原会话或原消息后来删除时,笔记正文仍保留,并显示来源不可用。保存失败会保留预览、目标和输入,便于重试;取消不会写入。
+
+## 快速面板和完整工作区
+
+从工作栏“+ → 笔记”打开快速面板,可以搜索笔记、查看记录摘要和快速追加文字。面板与完整笔记工作区共享同一份存储,任一处成功写入后另一处会更新。未保存草稿保存在当前应用内存中,切换项目、会话或收起工作栏不会覆盖它;离开面板、关闭笔记或用另一条采集替换草稿时会要求选择继续编辑或放弃。
+
+完整工作区可编辑记录、管理待办、搜索和调整列表。标签由用户手动维护:每篇笔记最多 10 个标签,标签不区分大小写;可以按一个或多个标签筛选,也可以在标签管理中重命名、合并或删除标签。删除标签不会删除笔记内容。
+
+## 画布和 AI 评论
+
+分页画布支持纸张模板、文字、手写、高亮、图片和 PDF 底版。画布保存是手动操作;缩放和适应宽度只影响查看,不改变已保存内容或导出尺寸。画布没有无限画布,也不提供单独的 PNG 下载按钮。
+
+AI 评论由你手动触发,或在设置为保存后自动分析时于保存完成后触发。评论使用默认模型的图像输入能力,并按设置发送画布开头的 1 至 8 页。纯视觉内容需要图像模型;文字模型只能使用明确标记的文字降级。分析失败不会撤销已经成功保存的笔记或画布内容,也不会自动重复追加。
diff --git a/sites/docs/content/zh/privacy.md b/sites/docs/content/zh/privacy.md
new file mode 100644
index 00000000..78e85e96
--- /dev/null
+++ b/sites/docs/content/zh/privacy.md
@@ -0,0 +1,21 @@
+# 数据与隐私
+
+GoodBuddy 是本地优先的桌面应用,不要求 GoodBuddy 账号。数据是否离开本机,取决于你使用的模型连接、Runtime、知识库类型、远程项目和浏览器等功能。
+
+## 数据流向
+
+本地对话、笔记、任务、设置和知识库索引保存在系统应用数据目录。使用直连模型时,请求发送到你选择的模型服务;OpenCode、Continue 和 Harness 也会按其 Runtime 配置调用模型。GoodBuddy 不会因为安装应用或打开空白会话自动上传历史。
+
+启用本地知识库时,资料和索引留在本机,Runtime 只收到本次检索选出的有界文本证据和引用。使用 Dify、FastGPT 或 RAGFlow 时,本次查询会发送到你配置的外部实例;GoodBuddy 不上传完整会话或本地附件,也不向外部知识库写入内容。实际返回的有界片段和引用会随会话保存在本机。
+
+## 凭据和 Runtime 边界
+
+API Key、SSH 凭据和其他认证信息由 Main 进程和系统安全存储管理,Renderer 不直接读取它们。自定义 Header 和 Body 属于普通连接设置,不适合保存秘密。工具、MCP、终端和插件使用当前用户权限以及明确启用的能力;没有 Ask / Execute 模式来替代这些实际配置。
+
+远程项目会把有界的模型配置交给已认证的远程 Agent,模型请求在远端按 SSH 账号权限执行。远程 Agent 不随桌面包提供,GoodBuddy 不会凭空提高远端账号权限。断线恢复只同步 Agent 已记录且能确认的结果,不会自动重放不确定的模型调用。
+
+## 预览和清除
+
+会话中的 HTML 预览只处理已完成的助手 HTML,脚本、网络请求、表单提交、嵌套页面和窗口操作均被禁用;关闭 HTML 预览后仍可查看源码。它不是联网浏览器,也不会因为预览而把页面内容上传。
+
+清除本地数据是设置中的明确操作,会先要求确认。它不删除外部模型服务、远程主机、远程知识库、导出文件或你手动保存到工作区的文件。备份、系统同步和第三方服务的保留策略由相应系统决定。
diff --git a/sites/docs/content/zh/remote.md b/sites/docs/content/zh/remote.md
new file mode 100644
index 00000000..5ece020a
--- /dev/null
+++ b/sites/docs/content/zh/remote.md
@@ -0,0 +1,21 @@
+# 远程项目
+
+远程项目让 Workspace、终端和支持的 Runtime 在 SSH Host 上执行。远程路径不会被当成本机路径处理,文件、进程、网络和模型调用都受远端登录账号及远程环境限制。GoodBuddy Agent 不随桌面安装包提供,需要单独准备。
+
+## 准备 SSH Host
+
+在设置的远程项目入口添加 Host,填写地址、端口、用户名和认证方式。首次连接先查看 Host Key 的算法和 SHA-256 指纹并明确接受;指纹变化时必须单独确认替换。可用系统 SSH Agent 或支持的证书方式,凭据由桌面安全存储管理。GoodBuddy 不要求 root,也不默认启用 SSH Agent Forwarding。
+
+Host 保存成功不等于远程环境已经就绪。按 Host 卡片的操作准备或更新签名 Agent 和 Runtime,等待环境检查通过。版本匹配只表示版本事实,不代表 Agent 正在运行或能力完整;安装失败、取消或网络中断会保留 Host 并提供重试。
+
+## 创建项目和使用空间
+
+创建远程项目时选择已验证的 Host,输入或通过有界目录选择器选择远端工作目录,再选择 OpenCode 或 Continue 等支持的远程 Runtime。项目保存 Host ID、远端路径和 Runtime 选择。普通切换项目只切换本地配置,不自动连接、安装或扫描主机;首次使用 Workspace 或 Runtime 时才建立或复用 Agent 连接。
+
+远程 Workspace 提供有界目录、文件预览、Git 和导入操作;终端使用远端默认 Shell。所有操作使用 SSH 账号权限,不能获得 root 或账号本身没有的访问权。本机 Skills、stdio MCP 和工具环境不会自动上传到远端;远程能力以 Agent 报告的实际能力为准。
+
+## 失败和边界
+
+SSH 可达、认证成功、Agent 就绪、Workspace 可用和 Runtime 可启动是不同状态。分别检查网络、防火墙、端口、Host Key、凭据、远端目录、Agent 版本、Runtime 版本和项目权限。远端 Agent 不可用时不会退化成 SSH stdio Runtime,也不会把同一请求偷偷改在本机执行。
+
+断开 SSH relay 不一定会停止已接受的远程请求;重新连接后 GoodBuddy 只恢复 Agent 已记录且能确认的输出。无法确认模型请求是否已处理时不会自动重放,以免重复计费或重复副作用。显式停止、Agent 关闭或远端进程失败会按请求状态显示取消、失败或结果未知。
diff --git a/sites/docs/content/zh/runtimes.md b/sites/docs/content/zh/runtimes.md
new file mode 100644
index 00000000..b79f95bf
--- /dev/null
+++ b/sites/docs/content/zh/runtimes.md
@@ -0,0 +1,26 @@
+# 选择 Runtime
+
+Runtime 决定请求由哪条执行路径处理。它与模型连接不同:连接回答“调用哪个模型服务”,Runtime 回答“由谁组织请求、工具和执行空间”。每次请求都会保留可查看的状态、工具活动、取消或失败结果。
+
+## 四种选择
+
+| Runtime | 适合场景 | 模型配置 |
+| --- | --- | --- |
+| 直连模型 | 普通问答、知识检索、图片生成和 GoodBuddy 内置能力 | GoodBuddy 模型连接 |
+| OpenCode | 编程 Agent、文件和命令工具、Skills | GoodBuddy 连接或 OpenCode 自有配置 |
+| Continue | 使用 Rules、Prompt 预设和编程工作 | GoodBuddy 连接或 Continue 自有配置 |
+| DeepSeek Harness | 固定 Host 和兼容插件能力 | GoodBuddy 管理的兼容连接 |
+
+先用直连模型完成普通问答或知识检索;需要持续操作项目文件、命令和 Skills 时选择 OpenCode 或 Continue;需要其固定 Host 能力时再选择 DeepSeek Harness。不同 Runtime 的工具、问答和原生客户端能力可能不同,选择器会显示当前可用项。
+
+## 选择范围和能力
+
+项目设置必须选择具体 Runtime。会话默认跟随项目,也可以在输入框的两栏选择器中为本会话单独选择。模型栏会显示“默认”、具体连接和 Runtime 自有配置,并标明来源。切换 Runtime 后,原来不属于该 Runtime 的模型选择不会被强行沿用。
+
+请求使用当前 Runtime、已启用 Capability、知识库范围、执行空间和当前账号权限。GoodBuddy 不提供 Ask / Execute 模式,也没有一个额外的通用工具审批开关;不支持的能力会明确报告,不会用隐藏模式代替。
+
+## 本地、远程和记录
+
+本地 Runtime 在本机项目执行。远程项目目前使用 SSH Host 上的 GoodBuddy Agent 和受管 Runtime,远程执行的文件、终端和进程使用 SSH 登录账号权限。远程 Agent 不随桌面安装包提供,需要先按[远程项目](./remote.html)准备。
+
+查看请求消息的活动或助手工作栏,可以看到 Runtime、模型连接、工具状态、取消、错误和已保存结果。关闭面板不会自动取消后台请求;停止请求只影响所属请求。请求失败或取消时,已经保存的正文和工具记录会保留。
diff --git a/sites/docs/content/zh/start.md b/sites/docs/content/zh/start.md
new file mode 100644
index 00000000..33711d34
--- /dev/null
+++ b/sites/docs/content/zh/start.md
@@ -0,0 +1,30 @@
+# GoodBuddy 用户手册
+
+这是一份面向第一次使用者的操作指南。GoodBuddy 不要求注册 GoodBuddy 账号,聊天、项目和笔记默认保存在本机;模型服务、远程主机和外部知识库是否收到数据,取决于你的配置。
+
+## 开始使用
+
+### 安装
+
+从[官网首页](https://mesalogo.github.io/goodbuddy/#download)选择系统、处理器架构和安装包。Windows 提供安装版和便携版,Linux 提供 AppImage、DEB 和 RPM。LoongArch 使用单独的实验预览通道。安装完成后启动 GoodBuddy,首次启动不需要登录。
+
+### 初始设置
+
+1. 打开“设置”,确认本地工作数据位置,并准备一个可用的文本模型连接。
+2. 在“模型连接”中填写服务地址、协议、模型名称和凭据,先执行连接测试。具体字段见[配置模型连接](./connections.html)。
+3. 新建一个项目,选择项目目录和 Runtime。项目用于集中管理会话、工作区和任务。
+4. 打开或新建会话,先发送一个简单问题,确认模型能正常回答,再尝试文件、知识库或远程操作。
+
+### 项目和会话
+
+项目是工作范围的容器,可以包含多个会话。会话保存用户消息、助手回复、工具活动和引用;同一个会话也可以关联多个任务。创建会话时,通常会继承项目的 Runtime 选择,之后可以在输入区为当前会话单独选择。
+
+需要换主题或工作目录时,先切换项目,再确认右侧[助手工作栏](./workbar.html)中的工作区和终端范围。发送请求前检查当前 Runtime、模型和知识库范围,避免把内容发到错误的服务。
+
+### 本地数据
+
+对话、笔记、任务记录、知识库索引和设置存放在系统应用数据目录。清除本地数据是设置中的明确操作,执行前会要求确认。卸载应用不等于删除你导出的文件、远端目录或模型服务中的记录;需要了解数据流向时查看[数据与隐私](./privacy.html)。
+
+### 下一步
+
+先读[核心概念](./concepts.html)了解 Project、Conversation 和 Runtime 的关系,再按需要配置[知识库](./knowledge.html)、[任务](./tasks.html)或[远程项目](./remote.html)。
diff --git a/sites/docs/content/zh/supervision.md b/sites/docs/content/zh/supervision.md
new file mode 100644
index 00000000..ff254e77
--- /dev/null
+++ b/sites/docs/content/zh/supervision.md
@@ -0,0 +1,27 @@
+# 监督工作
+
+监督者用于回顾已发生的工作、标出变化和问题,并把有依据的结果放进故事线图谱。它不会替你发消息、批准工具、扩大文件范围或改变执行权限。监督者应用默认关闭,启用后才会接受新的监督工作。
+
+## 启用和设置范围
+
+在应用中心启用监督者,然后在“设置”中选择跟随默认文本模型,或选择一个已有的文本模型连接。监督执行复用连接和凭据;回顾进行中修改设置只影响后续执行。
+
+首次使用需要明确选择项目、会话和时间范围。自动监督可以选择 Global 或一个或多个项目,当前项目切换不会改变已保存的范围。启用应用不会自动观察全部历史,也不会自动创建计划。
+
+## 工作回顾和故事线图谱
+
+工作回顾按所选范围读取会话、任务、笔记和已有来源,生成带来源的阶段总结、变化和未解决事项。没有新的有效变化时记录“无变化”,不重复调用模型或发送通知。默认“回顾”处理新增和修订内容;需要重新阅读历史区间时,使用明确的“重新整理”操作。
+
+故事线图谱展示事件、实体、关系和随时间的变化。点击结果或图谱对象可以查看来源和定位。来源正文仍由会话、笔记或知识库维护,图谱不会复制一套可编辑原文。核对后可以继续讨论,也可以预览并确认写入本地知识库;外部知识库保持只读。
+
+## 跟随、固定和介入
+
+助手工作栏中的监督面板可以跟随当前会话,也可以固定到会话或 Task。切换页面不会改变固定目标;目标失效时保留错误并提供修复入口。监督建议只生成可编辑草稿或明确的后续操作,用户确认“发到当前会话”后才会写入聊天。
+
+监督者不会自动执行建议。它不能替用户发送消息、批准工具、修改能力开关或扩大工作区。监督模型调用是无工具的内部文本请求,普通聊天和 Task 不会被监督并发设置改成同一队列。
+
+## 智能心跳和失败处理
+
+智能心跳是监督者的定时唤醒机制。它按计划检查指定范围的增量变化,并按设置生成建议或只更新记忆。心跳应用和计划分别有启停状态;关闭应用后不领取新的心跳,但已经开始的运行可以完成。
+
+暂停、取消或失败会保留上次成功结果和已保存的成功批次,当前运行显示覆盖范围和遗漏。可以重试或继续仍有效的工作。建议生成失败不会撤销已经发布的图谱或回顾结果;活动记录会明确显示失败阶段。监督者默认关闭不会影响普通聊天和普通任务。
diff --git a/sites/docs/content/zh/tasks.md b/sites/docs/content/zh/tasks.md
new file mode 100644
index 00000000..52a5c7ed
--- /dev/null
+++ b/sites/docs/content/zh/tasks.md
@@ -0,0 +1,25 @@
+# 任务
+
+Task 是你明确创建或确认的一项工作。它只关联一条 Conversation,但一条 Conversation 可以有多个 Task。普通聊天请求和工具调用不会自动出现在任务中心。
+
+## 创建立即或定时任务
+
+在任务中心或会话任务区选择“新建任务”。填写任务要求,名称可以留空让 GoodBuddy 根据内容生成。默认立即执行,也可以选择单次、每日或每周计划,并选择当前项目中的当前会话、其他会话或新会话。内容、会话和计划会一起提交,失败时保留表单。
+
+任务使用关联会话在实际执行时的 Runtime、能力、知识范围和工作区。它没有 Ask / Execute 模式,也不会因为后台运行而扩大权限。新会话不会复制来源会话历史;已有会话会使用自己的最新上下文。
+
+## Task、Job 和 Run
+
+Task 是用户可见的工作对象。每次立即运行、计划触发或重试,内部都可能创建 Job 和 Run,但它们不会变成新的任务条目。任务中心聚合显示任务状态、最近进展、计划时间和需要关注的错误;活动和 Runtime 面板显示更详细的工具与执行信息。
+
+一个周期任务始终是一条 Task。取消、暂停、恢复和重新运行都作用于 Task;删除 Task 默认停止后续计划并解除关联,保留会话和已有消息。删除一次待执行的计划项不会删除 Task。
+
+## 排队和控制
+
+同一 Conversation 的普通消息和任务消息按队列顺序执行。当前回复期间到期的任务会等待,不会把另一条回复插入正在生成的时间线。你可以删除尚未执行的队列项,或使用“立即中断并插入”让任务成为下一项;取消或失败后,后续队列项可以继续。
+
+任务卡提供暂停、继续、立即运行、编辑和取消等操作。暂停阻止新的执行,不撤销已经完成的外部操作;取消会停止所属执行,但已经保存的消息、工具记录和成果不会伪装成回滚。
+
+## 任务与心跳
+
+智能心跳不是任务中心里的 Task。它属于[监督工作](./supervision.html),用于按计划唤醒增量回顾和生成建议。需要一项明确的结果、文件或周期性消息时创建 Task;需要观察工作变化时配置监督计划。
diff --git a/sites/docs/content/zh/troubleshooting.md b/sites/docs/content/zh/troubleshooting.md
new file mode 100644
index 00000000..44d63e4a
--- /dev/null
+++ b/sites/docs/content/zh/troubleshooting.md
@@ -0,0 +1,23 @@
+# 问题排查
+
+先确认当前项目、会话、Runtime、模型和本机或远程执行空间,再根据症状处理。不要重复点击发送或立即重建全部资料;先查看请求状态、活动记录和错误原因。
+
+## 模型连接测试失败
+
+检查协议、URL、模型 ID、API Key、代理、证书和服务商限流。若填写了自定义 Header 或 Body,先暂时清空后重测基础连接。基础测试成功但生成失败时,确认当前会话选择的 Runtime 和模型能力。
+
+## 回复没有使用工具或文件
+
+检查 Runtime 是否支持所需能力,项目或会话是否使用正确执行空间,工作区目录是否存在,能力或 MCP 是否启用,以及当前账号是否有权限。打开工作栏的 Workspace 或 Runtime 确认目标;远程项目另外检查 SSH、Agent、远端路径和 Agent 版本。GoodBuddy 没有 Ask / Execute 模式。
+
+## 知识库没有返回内容
+
+确认会话勾选了目标知识库,文档已解析,全文索引可用,向量没有失败或不兼容,图片型 PDF 已做 OCR。用“测试检索”查看实际通道和降级原因;先用原文关键词测试,再重建失败文档或索引。外部库还要检查认证、远端 ID、超时和 Provider 状态。
+
+## 笔记、任务或远程项目失败
+
+笔记和画布先确认明确保存;AI 评论失败不会撤销已保存内容。任务检查启用、暂停、关联会话、GoodBuddy 是否运行及最近错误;心跳默认关闭。远程检查网络、Host Key、凭据、目录权限和 Agent/Runtime 准备状态。结果未知的远程请求不会自动重放,先查看活动再决定是否重新运行。
+
+## HTML 预览为空或显示源码
+
+确认回复已完成,内容是 HTML 文档或 `html`/`htm` 代码块,并且设置已开启会话 HTML 渲染。流式回复、用户消息和推理只显示源码。预览故意禁用脚本、网络、表单和窗口操作;需要交互页面时导出到你信任的环境。
diff --git a/sites/docs/content/zh/workbar.md b/sites/docs/content/zh/workbar.md
new file mode 100644
index 00000000..48df7dff
--- /dev/null
+++ b/sites/docs/content/zh/workbar.md
@@ -0,0 +1,25 @@
+# 助手工作栏
+
+助手工作栏是主窗口右侧的应用级工作区。它不属于某一条聊天消息,聊天、知识库、任务和监督页面都可以打开它,用来查看任务、工作区、Runtime、终端、浏览器、笔记和监督状态。
+
+## 面板和加号目录
+
+任务中心和工作区是默认存在、不可关闭的基础面板。点击“+”可以打开 Runtime、监督、终端、进程、浏览器、资源监控、文档或笔记等能力。终端和浏览器可以创建多个实例;笔记是单实例。后台状态会更新徽标或通知,不会无故把当前页面切走。
+
+工作栏面板显示能力名称、实例和当前目标。能力不可用时应显示原因及配置入口,而不是把入口悄悄隐藏。面板可以收起,终端、日志和较大的成果可以按界面提供的选项停靠到底部或独立窗口。
+
+## 跟随和固定
+
+可绑定目标的面板有两种范围:跟随当前上下文,或固定到指定会话、Task、项目、Runtime、终端、工作区或浏览器实例。跟随模式会随项目或会话切换;固定模式保持原目标。固定目标失效时显示“目标不可用”和修复入口,不自动改到另一个目标。
+
+工作栏的当前上下文只是默认值。打开工作区不会自动扩大文件范围,临时选择目录也不会静默修改项目设置。确认目标后,GoodBuddy 仍会检查项目、执行空间和当前能力。
+
+## 执行空间边界
+
+工作区显示当前项目目录或你明确选择的本机、远程目录。终端创建时绑定项目执行空间和目录;没有项目时使用本机 Home。浏览器只管理 GoodBuddy 创建的受控浏览器标签,不控制你已经打开的系统浏览器。进程面板只显示 GoodBuddy 创建或托管的进程,不是系统级进程管理器。
+
+工作区支持文件预览、Git 状态和有界目录操作。远程工作区使用 SSH Host 上的 Agent,不把远程路径伪装成本机路径。终端输入、文件操作、浏览器和 Runtime 各自有明确范围;一个面板的选择不会给另一个面板额外权限。
+
+## 实际使用
+
+处理一个项目时,可以让任务中心跟随当前项目,同时把监督固定到某个会话;打开工作区查看文件,再创建一个终端执行命令。查看活动时确认面板顶部的项目、会话、Runtime 和本机或远程标识。需要完整任务关系时打开 Task;Job 和 Run 不作为工作栏中的独立面板。
diff --git a/sites/docs/manifest.ts b/sites/docs/manifest.ts
new file mode 100644
index 00000000..c696f487
--- /dev/null
+++ b/sites/docs/manifest.ts
@@ -0,0 +1,21 @@
+export type Language = 'zh' | 'en'
+
+export type Chapter = {
+ slug: string
+ title: { zh: string; en: string }
+}
+
+export const chapters: Chapter[] = [
+ { slug: 'start', title: { zh: '开始使用', en: 'Get started' } },
+ { slug: 'concepts', title: { zh: '核心概念', en: 'Core concepts' } },
+ { slug: 'connections', title: { zh: '配置模型连接', en: 'Configure model connections' } },
+ { slug: 'runtimes', title: { zh: '选择 Runtime', en: 'Choose a Runtime' } },
+ { slug: 'workbar', title: { zh: '助手工作栏', en: 'Assistant workbar' } },
+ { slug: 'knowledge', title: { zh: '建立知识库', en: 'Build a knowledge base' } },
+ { slug: 'notes', title: { zh: '使用魔法笔记', en: 'Use Magic Notes' } },
+ { slug: 'tasks', title: { zh: '任务', en: 'Tasks' } },
+ { slug: 'supervision', title: { zh: '监督工作', en: 'Supervision' } },
+ { slug: 'remote', title: { zh: '远程项目', en: 'Remote projects' } },
+ { slug: 'privacy', title: { zh: '数据与隐私', en: 'Data and privacy' } },
+ { slug: 'troubleshooting', title: { zh: '问题排查', en: 'Troubleshooting' } },
+]
diff --git a/sites/en.html b/sites/en.html
index 5a7d99af..2f377c2d 100644
--- a/sites/en.html
+++ b/sites/en.html
@@ -75,6 +75,7 @@
Workflows
Features
Assistant
+ User guide
FAQ
@@ -495,6 +496,7 @@
Download
Workflows
Features
+ User guide
FAQ
Getting started
diff --git a/sites/index.html b/sites/index.html
index 0ebfb455..0e18fece 100644
--- a/sites/index.html
+++ b/sites/index.html
@@ -75,6 +75,7 @@
场景
功能
助手
+ 用户手册
FAQ
@@ -514,6 +515,7 @@
选择你的桌面版本
↓
+ 阅读用户手册 →
@@ -583,6 +585,7 @@
下载
场景
功能
+
用户手册
FAQ
入门指南
diff --git a/sites/scripts/validate.mjs b/sites/scripts/validate.mjs
index 5194e7cc..0d04adc9 100644
--- a/sites/scripts/validate.mjs
+++ b/sites/scripts/validate.mjs
@@ -4,10 +4,28 @@ import { fileURLToPath } from "node:url";
const siteRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const errors = [];
-
+const chapterSlugs = [
+ "start",
+ "concepts",
+ "connections",
+ "runtimes",
+ "workbar",
+ "knowledge",
+ "notes",
+ "tasks",
+ "supervision",
+ "remote",
+ "privacy",
+ "troubleshooting",
+];
const requiredFiles = [
"index.html",
"en.html",
+ "docs/manifest.ts",
+ ...chapterSlugs.flatMap((slug) => [`docs/content/zh/${slug}.md`, `docs/content/en/${slug}.md`]),
+ "docs/.vitepress/config.mts",
+ ...chapterSlugs.flatMap((slug) => ["zh", "en"].map((language) =>
+ `docs-dist/${language}/${slug === "start" ? "index" : slug}.html`)),
"styles.css",
"app.js",
"language.js",
@@ -49,10 +67,12 @@ await Promise.all(
}),
);
-const [html, englishHtml, css, appJs, languageJs, releaseIndexJs, fontLicense] =
+const [html, englishHtml, docsManifest, docsConfig, css, appJs, languageJs, releaseIndexJs, fontLicense] =
await Promise.all([
readSiteFile("index.html"),
readSiteFile("en.html"),
+ readSiteFile("docs/manifest.ts"),
+ readSiteFile("docs/.vitepress/config.mts"),
readSiteFile("styles.css"),
readSiteFile("app.js"),
readSiteFile("language.js"),
@@ -63,6 +83,8 @@ const [html, englishHtml, css, appJs, languageJs, releaseIndexJs, fontLicense] =
for (const [relativePath, content] of [
["index.html", html],
["en.html", englishHtml],
+ ["docs/manifest.ts", docsManifest],
+ ["docs/.vitepress/config.mts", docsConfig],
["styles.css", css],
["app.js", appJs],
["language.js", languageJs],
@@ -112,6 +134,59 @@ report(
(englishHtml.match(/]/g) ?? []).length === 1,
"英文页面必须且只能包含一个 h1",
);
+report(chapterSlugs.every((slug) => docsManifest.includes(`slug: '${slug}'`)), "手册 manifest 缺少章节或顺序不完整");
+const manifestEntries = [...docsManifest.matchAll(/slug: '([^']+)', title: \{ zh: '([^']+)', en: '([^']+)' \}/g)];
+report(manifestEntries.length === chapterSlugs.length && manifestEntries.every((entry, index) => entry[1] === chapterSlugs[index]), "手册 manifest 章节顺序不完整");
+const docsBase = process.env.DOCS_BASE || "/goodbuddy/docs-dist/";
+const docsOrigin = "https://docs.example";
+const renderedText = (value) => value
+ .replace(/<[^>]*>/g, "")
+ .replace(/&(?:amp|lt|gt|quot|apos|#39|nbsp);/g, (entity) => ({
+ "&": "&", "<": "<", ">": ">", """: '"',
+ "'": "'", "'": "'", " ": " ",
+ })[entity])
+ .replace(/\s+/g, " ").trim();
+for (const slug of chapterSlugs) {
+ const [zh, en] = await Promise.all([readSiteFile(`docs/content/zh/${slug}.md`), readSiteFile(`docs/content/en/${slug}.md`)]);
+ const manifestEntry = manifestEntries.find((entry) => entry[1] === slug);
+ const titleMatches = slug === "start"
+ ? manifestEntry && zh.includes(`## ${manifestEntry[2]}`) && en.includes(`## ${manifestEntry[3]}`)
+ : manifestEntry && zh.startsWith(`# ${manifestEntry[2]}`) && en.startsWith(`# ${manifestEntry[3]}`);
+ report(titleMatches, `${slug} 章节标题必须与 manifest 保持一致`);
+ report(zh.trim().length > 20 && en.trim().length > 20, `${slug} 章节正文过短`);
+ for (const [content, languageCode] of [[zh, "zh"], [en, "en"]]) {
+ const chapterPath = `${languageCode}/${slug === "start" ? "index" : slug}.html`;
+ const relativePath = `docs-dist/${chapterPath}`;
+ const built = await readSiteFile(relativePath);
+ if (!built) continue;
+ const pageUrl = new URL(`${docsBase}${chapterPath}`, docsOrigin);
+ const main = built.match(/]*>([\s\S]*?)<\/main>/)?.[1] ?? "";
+ const heading = content.match(/^# (.+)$/m)?.[1];
+ const firstBodyLine = content.split(/\r?\n/).find((line) => line.trim() && !line.startsWith("#")) ?? "";
+ const paragraphText = firstBodyLine.replace(/^\s*(?:[-*+]|\d+\.)\s+/, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[*`]/g, "");
+ report((main.match(/]*>([\s\S]*?)<\/h1>/)?.[1] ?? "").includes(heading), `${relativePath} 缺少服务端渲染的 Markdown 主标题`);
+ report(paragraphText.length > 20 && renderedText(main).includes(renderedText(paragraphText)), `${relativePath} 缺少服务端渲染的章节正文`);
+ report(built.includes(`lang="${languageCode === "zh" ? "zh-CN" : "en"}"`), `${relativePath} 页面语言不正确`);
+ for (const entry of manifestEntries) {
+ const route = `${docsBase}${languageCode}/${entry[1] === "start" ? "" : `${entry[1]}.html`}`;
+ report(built.includes(`href="${route}"`) || (entry[1] === "start" && built.includes(`href="${route}index.html"`)), `${relativePath} 侧栏缺少章节:${entry[1]}`);
+ report(renderedText(built).includes(entry[languageCode === "zh" ? 2 : 3]), `${relativePath} 侧栏标题与 manifest 不一致:${entry[1]}`);
+ }
+ const otherLanguage = languageCode === "zh" ? "en" : "zh";
+ report(built.includes("VPNavBarTranslations") && built.includes(`href="${docsBase}${otherLanguage}/`), `${relativePath} 缺少原生语言切换入口`);
+ report(/