diff --git a/docs/docs/03-guides/01-first-tool.md b/docs/docs/03-guides/01-first-tool.md
deleted file mode 100644
index 51e2401c..00000000
--- a/docs/docs/03-guides/01-first-tool.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Writing your First Tool
-This should be a brief guide that shows how to write a simple "hello world" type tool. It would be good to show the tool doing something dynamic like generating a random number or returning the current date time.
-
-I'd like us to have repos for each supported language and a version of the tool in each language. You can link to the repo in this guide and assume the user knows how to code and use github.
-
-SHow the basic layout of a tool (keep the code as simple as possible). Show a tool.gpt. Show the metadata stuff for category and image.
-
-Highlight that the tool needs to be pushed to github and then registered in the ui and end with explaining how it can then be added to an agent.
\ No newline at end of file
diff --git a/docs/docs/03-guides/01-first-tool.mdx b/docs/docs/03-guides/01-first-tool.mdx
new file mode 100644
index 00000000..6f9498c4
--- /dev/null
+++ b/docs/docs/03-guides/01-first-tool.mdx
@@ -0,0 +1,29 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+import PythonHashToolReadme from '../../snippets/python-hash-tool-readme.md.mdx';
+import NodeHashToolReadme from '../../snippets/node-hash-tool-readme.md.mdx';
+import GoHashToolReadme from '../../snippets/go-hash-tool-readme.md.mdx';
+
+# Writing your First Tool
+
+While Otto8 ships with a robust library of built-in [Tools](../02-concepts/03-tools.md), building custom
+Tools tailored to your ecosystem will supercharge your Agents.
+
+The following guides will show you how to write and package custom Tools in Python, Node.js, and Go;
+unleashing the full potential of your Agents by enabling them to integrate with any data source, service,
+or platform with just a few lines of code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 15df0fde..224f977c 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -37,6 +37,10 @@ const config: Config = {
],
],
+ plugins: [
+ require.resolve('./src/plugins/fetch-snippets'),
+ ],
+
themeConfig: {
// Replace with your project's social card
image: 'img/otto8-logo-blue-black-text.svg',
diff --git a/docs/package-lock.json b/docs/package-lock.json
index df8707ad..c8357c27 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -11,6 +11,7 @@
"@docusaurus/core": "3.6.1",
"@docusaurus/preset-classic": "3.6.1",
"@mdx-js/react": "^3.0.0",
+ "axios": "^1.7.7",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
@@ -27,34 +28,34 @@
}
},
"node_modules/@algolia/autocomplete-core": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.6.tgz",
- "integrity": "sha512-lkDoW4I7h2kKlIgf3pUt1LqvxyYKkVyiypoGLlUnhPSnCpmeOwudM6rNq6YYsCmdQtnDQoW5lUNNuj6ASg3qeg==",
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz",
+ "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==",
"license": "MIT",
"dependencies": {
- "@algolia/autocomplete-plugin-algolia-insights": "1.17.6",
- "@algolia/autocomplete-shared": "1.17.6"
+ "@algolia/autocomplete-plugin-algolia-insights": "1.17.7",
+ "@algolia/autocomplete-shared": "1.17.7"
}
},
"node_modules/@algolia/autocomplete-plugin-algolia-insights": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.6.tgz",
- "integrity": "sha512-17NnaacuFzSWVuZu4NKzVeaFIe9Abpw8w+/gjc7xhZFtqj+GadufzodIdchwiB2eM2cDdiR3icW7gbNTB3K2YA==",
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz",
+ "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==",
"license": "MIT",
"dependencies": {
- "@algolia/autocomplete-shared": "1.17.6"
+ "@algolia/autocomplete-shared": "1.17.7"
},
"peerDependencies": {
"search-insights": ">= 1 < 3"
}
},
"node_modules/@algolia/autocomplete-preset-algolia": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz",
- "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==",
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz",
+ "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==",
"license": "MIT",
"dependencies": {
- "@algolia/autocomplete-shared": "1.17.6"
+ "@algolia/autocomplete-shared": "1.17.7"
},
"peerDependencies": {
"@algolia/client-search": ">= 4.9.1 < 6",
@@ -62,9 +63,9 @@
}
},
"node_modules/@algolia/autocomplete-shared": {
- "version": "1.17.6",
- "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz",
- "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==",
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz",
+ "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==",
"license": "MIT",
"peerDependencies": {
"@algolia/client-search": ">= 4.9.1 < 6",
@@ -610,9 +611,9 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
- "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+ "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
"license": "MIT",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
@@ -2149,20 +2150,20 @@
}
},
"node_modules/@docsearch/css": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.7.0.tgz",
- "integrity": "sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.0.tgz",
+ "integrity": "sha512-pieeipSOW4sQ0+bE5UFC51AOZp9NGxg89wAlZ1BAQFaiRAGK1IKUaPQ0UGZeNctJXyqZ1UvBtOQh2HH+U5GtmA==",
"license": "MIT"
},
"node_modules/@docsearch/react": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.7.0.tgz",
- "integrity": "sha512-8e6tdDfkYoxafEEPuX5eE1h9cTkLvhe4KgoFkO5JCddXSQONnN1FHcDZRI4r8894eMpbYq6rdJF0dVYh8ikwNQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.0.tgz",
+ "integrity": "sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==",
"license": "MIT",
"dependencies": {
- "@algolia/autocomplete-core": "1.17.6",
- "@algolia/autocomplete-preset-algolia": "1.17.6",
- "@docsearch/css": "3.7.0",
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.0",
"algoliasearch": "^5.12.0"
},
"peerDependencies": {
@@ -4066,27 +4067,6 @@
"node": ">= 0.6"
}
},
- "node_modules/accepts/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/accepts/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/accepts/node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -4411,6 +4391,12 @@
"astring": "bin/astring"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -4457,6 +4443,17 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/axios": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
+ "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/babel-loader": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz",
@@ -4484,13 +4481,13 @@
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.11",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
- "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+ "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -4520,12 +4517,12 @@
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
- "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+ "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.2"
+ "@babel/helper-define-polyfill-provider": "^0.6.3"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -4819,9 +4816,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001679",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001679.tgz",
- "integrity": "sha512-j2YqID/YwpLnKzCmBOS4tlZdWprXm3ZmQLBH9ZBXFOhoxLA46fwyBvx6toCBWBmnuwUY/qB3kEU6gFx8qgCroA==",
+ "version": "1.0.30001680",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz",
+ "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==",
"funding": [
{
"type": "opencollective",
@@ -5148,6 +5145,18 @@
"node": ">=10"
}
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/comma-separated-tokens": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
@@ -5185,15 +5194,6 @@
"node": ">= 0.6"
}
},
- "node_modules/compressible/node_modules/mime-db": {
- "version": "1.53.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz",
- "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/compression": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz",
@@ -5962,6 +5962,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -6199,9 +6208,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.55",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz",
- "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==",
+ "version": "1.5.57",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz",
+ "integrity": "sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg==",
"license": "ISC"
},
"node_modules/emoji-regex": {
@@ -7133,6 +7142,20 @@
"node": ">=6"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/form-data-encoder": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
@@ -9016,9 +9039,9 @@
}
},
"node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9098,9 +9121,9 @@
}
},
"node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9118,9 +9141,9 @@
}
},
"node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9405,9 +9428,9 @@
}
},
"node_modules/micromark": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz",
- "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz",
+ "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9440,9 +9463,9 @@
}
},
"node_modules/micromark-core-commonmark": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz",
- "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz",
+ "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9474,9 +9497,9 @@
}
},
"node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9494,9 +9517,9 @@
}
},
"node_modules/micromark-core-commonmark/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9514,9 +9537,9 @@
}
},
"node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9549,9 +9572,9 @@
}
},
"node_modules/micromark-extension-directive/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9569,9 +9592,9 @@
}
},
"node_modules/micromark-extension-directive/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9589,9 +9612,9 @@
}
},
"node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9621,9 +9644,9 @@
}
},
"node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9641,9 +9664,9 @@
}
},
"node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9693,9 +9716,9 @@
}
},
"node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9713,9 +9736,9 @@
}
},
"node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9749,9 +9772,9 @@
}
},
"node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9769,9 +9792,9 @@
}
},
"node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9789,9 +9812,9 @@
}
},
"node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9823,9 +9846,9 @@
}
},
"node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9856,9 +9879,9 @@
}
},
"node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9876,9 +9899,9 @@
}
},
"node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9896,9 +9919,9 @@
}
},
"node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9942,9 +9965,9 @@
}
},
"node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9962,9 +9985,9 @@
}
},
"node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -9982,9 +10005,9 @@
}
},
"node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10024,9 +10047,9 @@
}
},
"node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10044,9 +10067,9 @@
}
},
"node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10064,9 +10087,9 @@
}
},
"node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10103,9 +10126,9 @@
}
},
"node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10123,9 +10146,9 @@
}
},
"node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10143,9 +10166,9 @@
}
},
"node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10213,9 +10236,9 @@
}
},
"node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10233,9 +10256,9 @@
}
},
"node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10249,9 +10272,9 @@
"license": "MIT"
},
"node_modules/micromark-factory-destination": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz",
- "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10270,9 +10293,9 @@
}
},
"node_modules/micromark-factory-destination/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10290,9 +10313,9 @@
}
},
"node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10306,9 +10329,9 @@
"license": "MIT"
},
"node_modules/micromark-factory-label": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz",
- "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10328,9 +10351,9 @@
}
},
"node_modules/micromark-factory-label/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10348,9 +10371,9 @@
}
},
"node_modules/micromark-factory-label/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10391,9 +10414,9 @@
}
},
"node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10411,9 +10434,9 @@
}
},
"node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10431,9 +10454,9 @@
}
},
"node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10483,9 +10506,9 @@
"license": "MIT"
},
"node_modules/micromark-factory-title": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz",
- "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10505,9 +10528,9 @@
}
},
"node_modules/micromark-factory-title/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10525,9 +10548,9 @@
}
},
"node_modules/micromark-factory-title/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10545,9 +10568,9 @@
}
},
"node_modules/micromark-factory-title/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10561,9 +10584,9 @@
"license": "MIT"
},
"node_modules/micromark-factory-whitespace": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz",
- "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10583,9 +10606,9 @@
}
},
"node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10603,9 +10626,9 @@
}
},
"node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10623,9 +10646,9 @@
}
},
"node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10675,9 +10698,9 @@
"license": "MIT"
},
"node_modules/micromark-util-chunked": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz",
- "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10694,9 +10717,9 @@
}
},
"node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10710,9 +10733,9 @@
"license": "MIT"
},
"node_modules/micromark-util-classify-character": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz",
- "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10731,9 +10754,9 @@
}
},
"node_modules/micromark-util-classify-character/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10751,9 +10774,9 @@
}
},
"node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10767,9 +10790,9 @@
"license": "MIT"
},
"node_modules/micromark-util-combine-extensions": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz",
- "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10787,9 +10810,9 @@
}
},
"node_modules/micromark-util-decode-numeric-character-reference": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz",
- "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10806,9 +10829,9 @@
}
},
"node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10822,9 +10845,9 @@
"license": "MIT"
},
"node_modules/micromark-util-decode-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz",
- "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
+ "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10844,9 +10867,9 @@
}
},
"node_modules/micromark-util-decode-string/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10864,9 +10887,9 @@
}
},
"node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10880,9 +10903,9 @@
"license": "MIT"
},
"node_modules/micromark-util-encode": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz",
- "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10922,9 +10945,9 @@
}
},
"node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10938,9 +10961,9 @@
"license": "MIT"
},
"node_modules/micromark-util-html-tag-name": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz",
- "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10954,9 +10977,9 @@
"license": "MIT"
},
"node_modules/micromark-util-normalize-identifier": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz",
- "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10973,9 +10996,9 @@
}
},
"node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -10989,9 +11012,9 @@
"license": "MIT"
},
"node_modules/micromark-util-resolve-all": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz",
- "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11008,9 +11031,9 @@
}
},
"node_modules/micromark-util-sanitize-uri": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz",
- "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11029,9 +11052,9 @@
}
},
"node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11049,9 +11072,9 @@
}
},
"node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11065,9 +11088,9 @@
"license": "MIT"
},
"node_modules/micromark-util-subtokenize": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz",
- "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.2.tgz",
+ "integrity": "sha512-xKxhkB62vwHUuuxHe9Xqty3UaAsizV2YKq5OV344u3hFBbf8zIYrhYOWhAQb94MtMPkjTOzzjJ/hid9/dR5vFA==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11087,9 +11110,9 @@
}
},
"node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11119,9 +11142,9 @@
"license": "MIT"
},
"node_modules/micromark-util-types": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz",
- "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz",
+ "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11135,9 +11158,9 @@
"license": "MIT"
},
"node_modules/micromark/node_modules/micromark-factory-space": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz",
- "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11155,9 +11178,9 @@
}
},
"node_modules/micromark/node_modules/micromark-util-character": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz",
- "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11175,9 +11198,9 @@
}
},
"node_modules/micromark/node_modules/micromark-util-symbol": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz",
- "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
"funding": [
{
"type": "GitHub Sponsors",
@@ -11216,21 +11239,21 @@
}
},
"node_modules/mime-db": {
- "version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
- "version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
- "mime-db": "~1.33.0"
+ "mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
@@ -12033,9 +12056,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.47",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
- "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"funding": [
{
"type": "opencollective",
@@ -12053,7 +12076,7 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.1.0",
+ "picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
@@ -12322,13 +12345,13 @@
}
},
"node_modules/postcss-modules-local-by-default": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz",
- "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz",
+ "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==",
"license": "MIT",
"dependencies": {
"icss-utils": "^5.0.0",
- "postcss-selector-parser": "^6.0.2",
+ "postcss-selector-parser": "^7.0.0",
"postcss-value-parser": "^4.1.0"
},
"engines": {
@@ -12338,13 +12361,26 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+ "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-scope": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz",
- "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
"license": "ISC",
"dependencies": {
- "postcss-selector-parser": "^6.0.4"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
"node": "^10 || ^12 || >= 14"
@@ -12353,6 +12389,19 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+ "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-values": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
@@ -12749,6 +12798,12 @@
"node": ">= 0.10"
}
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -14028,6 +14083,27 @@
"range-parser": "1.2.0"
}
},
+ "node_modules/serve-handler/node_modules/mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-handler/node_modules/mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "~1.33.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/serve-handler/node_modules/path-to-regexp": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz",
@@ -14907,27 +14983,6 @@
"node": ">= 0.6"
}
},
- "node_modules/type-is/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/type-is/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -15309,27 +15364,6 @@
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"license": "MIT"
},
- "node_modules/url-loader/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/url-loader/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/url-loader/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
@@ -15580,27 +15614,6 @@
"webpack": "^4.0.0 || ^5.0.0"
}
},
- "node_modules/webpack-dev-middleware/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/webpack-dev-middleware/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/webpack-dev-middleware/node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -15744,27 +15757,6 @@
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"license": "MIT"
},
- "node_modules/webpack/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/webpack/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/webpack/node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
diff --git a/docs/package.json b/docs/package.json
index 9e92627d..bb4b7e02 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -18,6 +18,7 @@
"@docusaurus/core": "3.6.1",
"@docusaurus/preset-classic": "3.6.1",
"@mdx-js/react": "^3.0.0",
+ "axios": "^1.7.7",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
diff --git a/docs/snippets/go-hash-tool-readme.md.mdx b/docs/snippets/go-hash-tool-readme.md.mdx
new file mode 100644
index 00000000..2331c674
--- /dev/null
+++ b/docs/snippets/go-hash-tool-readme.md.mdx
@@ -0,0 +1,395 @@
+## Writing your first tool in Go
+
+[go-hash-tool](https://github.com/otto8-ai/go-hash-tool) contains a reference `Go` implementation of the `Hash` Tool.
+
+This guide walks through the structure and design of the Tool and outlines the packaging requirements for [Otto8](https://docs.otto8.ai/concepts/agents)
+
+To clone this repo and follow along, run the following command:
+
+```bash
+git clone git@github.com:otto8-ai/go-hash-tool
+```
+
+---
+
+### Tool Repo Structure
+
+The directory tree below highlights the files required to implement `Hash` in Go and package it for `Otto8`.
+
+```
+go-hash-tool
+├── tool.gpt
+├── go.mod
+├── main.go
+└── commands
+ └── hash.go
+```
+
+**Note:** Most Tools implemented in Go will also have a `go.sum` file that is also required when present. It is not present in the reference implementation because it has no external dependencies and relies solely on the Go standard library.
+
+---
+
+### Defining the `Hash` Tool
+
+The `tool.gpt` file contains [GPTScript Tool Definitions](https://docs.gptscript.ai/tools/gpt-file-reference) which describe a set of Tools that can be used by Agents in `Otto8`.
+Every Tool repository must have a `tool.gpt` file in its root directory.
+
+The Tools defined in this file must have a descriptive `Name` and `Description` that will help Agents understand what the Tool does, what it returns (if anything), and all the `Parameters` it takes.
+Agents use these details to infer a Tool's usage.
+We call the section of a Tool definition that contains this info a `Preamble`.
+
+We want the `Hash` Tool to return the hash of some given `data`. It would also be nice to support a few different algorithms for the Agent to choose from.
+Let's take a look at the `Preamble` for `Hash` to see how that's achieved:
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+```
+
+Breaking this down a bit:
+
+- The `Preamble` above declares a Tool named `Hash`.
+- The `Param` fields enumerate the arguments that an Agent must provide when calling `Hash`, `data` and `algo`.
+- In this case, the description of the `algo` parameter outlines the valid options (`sha256` or `md5`) and defines a default value (`sha256`)
+- The `Description` explains what `Hash` returns with respect to the given arguments; the hash of `data` using the algorithm selected with `algo`.
+
+Immediately below the `Preamble` is the `Tool Body`, which tells `Otto8` how to execute the Tool:
+
+```text
+#!{GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool hash
+```
+
+This is where the magic happens.
+
+To oversimplify, when an Agent calls the `Hash` Tool, `Otto8` reads this line and then:
+
+1. Downloads the appropriate `Go` tool chain
+2. Sets up a working directory for the Tool
+3. Runs `go build` to install dependencies (from `go.mod` and `go.sum`) and build a binary named `gptscript-go-tool` (`gptscript-go-tool.exe` on Windows)
+4. Projects the call arguments onto environment variables (`DATA` and `ALGO`)
+5. Runs `gptscript-go-tool hash`.
+
+Putting it all together, here's the complete definition of the `Hash` Tool:
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Default is "sha256". Supports "sha256" and "md5".
+
+#!{GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool hash
+```
+
+### Tool Metadata
+
+The `tool.gpt` file also provides the following metadata for use in `Otto8`:
+
+- `!metadata:*:category` which tags Tools with the `Crypto` category to promote organization and discovery
+- `!metadata:*:icon` which assigns `https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg` as the Tool icon
+
+Where `*` is a wild card pattern that applies the metadata to all Tools in a `tool.gpt`.
+
+```text
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+**Note:** Metadata can be applied to a specific Tool by either specifying the exact name (e.g. `!metadata:Hash:category`) or by adding the metadata directly to a Tool's `Preamble`:
+
+```text
+Name: Hash
+Metadata: category: Crypto
+Metadata: icon: https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+### Complete `tool.gpt`
+
+```text
+---
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+
+#!{GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool hash
+
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+---
+
+### Implementing Business Logic
+
+The `main.go` file is the entry point of the `gptscript-go-tool` binary that is executed by `Otto8` when the `Hash` Tool is called.
+
+Let's walk through the the code to understand what happens at runtime:
+
+```go
+ // ...
+ switch cmd := os.Args[1]; cmd {
+ case "hash":
+ res, err = commands.Hash(os.Getenv("DATA"), os.Getenv("ALGO"))
+ default:
+ err = fmt.Errorf("Unsupported command: %s", cmd)
+ }
+
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ if res != "" {
+ fmt.Println(res)
+ }
+```
+
+This code implements a simple CLI responsible for dispatching the `commands.Hash` function on request -- when `hash` is passed in as an argument -- after extracting the Tool arguments, `data` and `algo`, from the respective environment variables.
+
+It also ensures that the return value and errors of the call to `commands.Hash` are written to stdout. This is crucial because only stdout is returned to the Agent, while stderr is discarded.
+
+The simple CLI pattern showcased above is also easily extensible; adding business logic for new tools becomes a matter of adding a new case to the `switch` statement.
+
+For example, to add business logic for a new Tool to verify a hash, we just have to tack on `verify` case:
+
+```go
+// ...
+case "verify":
+ res, err = commands.Verify(os.Getenv("HASH"), os.Getenv("DATA"), os.Getenv("ALGO"))
+case "hash":
+ // ...
+default:
+ //...
+```
+
+The Body of the `Verify` Tool definition would then simply pass `verify` to `gptscript-go-tool` instead of `hash`:
+
+```text
+Name: Verify
+# ...
+
+#!{GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool verify
+```
+
+Getting back to the business logic for the `Hash` Tool, `commands.Hash` is does the bulk of the heavy lifting.
+
+```go
+func Hash(data, algo string) (string, error) {
+ if data == "" {
+ return "", fmt.Errorf("A non-empty data argument must be provided")
+ }
+
+ if algo == "" {
+ algo = "sha256"
+ }
+
+ // ...
+}
+```
+
+It starts off by validating the `data` and `algo` arguments.
+When an argument is invalid, the function throws an exception that describes the validation issue in detail.
+The goal is to provide useful information that an Agent can use to construct valid arguments for future calls.
+For example, when an invalid `algo` argument is provided, the code returns an error that contains the complete list of valid algorithms.
+
+Once it determines that all of the arguments are valid, it then calculates the hash and writes a JSON object to stdout.
+This object contains both the hash and the algorithm used to generate it.
+
+```go
+func Hash(data, algo string) (string, error) {
+ // ...
+
+ sum, ok := hashFunctions[algo]
+ if !ok {
+ return "", fmt.Errorf("Unsupported hash algorithm: %s not in [%s]", algo, hashFunctions)
+ }
+
+ hash, err := json.Marshal(hashResult{
+ Algo: algo,
+ Hash: hex.EncodeToString(sum([]byte(data))),
+ })
+ if err != nil {
+ return "", fmt.Errorf("Failed to marshal hash result: %w", err)
+ }
+
+ return string(hash), nil
+}
+```
+
+Producing structured data with extra contextual info (e.g. the algorithm) is considered good form.
+It's a pattern that improves the Agent's ability to correctly use the Tool's result over time.
+
+### Complete `main.go` and `commands/hash.go`
+
+```go
+// main.go
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/njhale/go-hash-tool/commands"
+)
+
+func main() {
+ if len(os.Args) != 2 {
+ fmt.Println("Usage: gptscript-go-tool ")
+ os.Exit(1)
+ }
+
+ var (
+ err error
+ res string
+ )
+ switch cmd := os.Args[1]; cmd {
+ case "hash":
+ res, err = commands.Hash(os.Getenv("DATA"), os.Getenv("ALGO"))
+ default:
+ err = fmt.Errorf("Unsupported command: %s", cmd)
+ }
+
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ if res != "" {
+ fmt.Println(res)
+ }
+}
+```
+
+```go
+// commands/hash.go
+package commands
+
+import (
+ "hash/md5"
+ "hash/sha256"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "sort"
+ "strings"
+)
+
+func Hash(data, algo string) (string, error) {
+ if data == "" {
+ return "", fmt.Errorf("A non-empty data argument must be provided")
+ }
+
+ if algo == "" {
+ algo = "sha256"
+ }
+
+ sum, ok := hashFunctions[algo]
+ if !ok {
+ return "", fmt.Errorf("Unsupported hash algorithm: %s not in [%s]", algo, hashFunctions)
+ }
+
+ hash, err := json.Marshal(hashResult{
+ Algo: algo,
+ Hash: hex.EncodeToString(sum([]byte(data))),
+ })
+ if err != nil {
+ return "", fmt.Errorf("Failed to marshal hash result: %w", err)
+ }
+
+ return string(hash), nil
+}
+
+type hashResult struct {
+ Algo string `json:"algo"`
+ Hash string `json:"hash"`
+}
+
+var hashFunctions = hashFuncSet{
+ "sha256": func(d []byte) []byte { h := sha256.Sum256(d); return h[:] },
+ "md5": func(d []byte) []byte { h := md5.Sum(d); return h[:] },
+}
+
+type hashFuncSet map[string]func([]byte) []byte
+
+func (s hashFuncSet) String() string {
+ return strings.Join(keys(s), ", ")
+}
+
+func keys[V any](m map[string]V) []string {
+ set := make([]string, 0, len(m))
+ for k := range m {
+ set = append(set, k)
+ }
+
+ sort.Strings(set)
+ return set
+}
+
+---
+
+### Testing `main.go` Locally
+
+Before adding a Tool to `Otto8`, verify that the Go business logic works on your machine.
+
+To do this, run through the following steps in the root of your local fork:
+
+1. Install dependencies and build the binary
+
+ ```bash
+ make build
+ ```
+
+2. Run the Tool with some test arguments:
+
+ | **Command** |**Output** |
+ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+ | `DATA='foo' bin/gptscript-go-tool hash` | `{ "algo": "sha256", "hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" }` |
+ | `DATA='' bin/gptscript-go-tool hash` | `Error: A data argument must be provided` |
+ | `DATA='foo' ALGO='md5' bin/gptscript-go-tool hash` | `{ "algo": "md5", "hash": "acbd18db4cc2f85cedef654fccc4a4d8" }` |
+ | `DATA='foo' ALGO='whirlpool' bin/gptscript-go-tool hash` | `Error: Unsupported hash algorithm: whirlpool not in ['sha256', 'md5']` |
+
+---
+
+### Adding The `Hash` Tool to `Otto8`
+
+Before a Tool can be used by an Agent, an admin must first add the Tool to `Otto8` by performing the steps below:
+
+1. Navigate to the `Otto8` admin UI in a browser and open the Tools page by clicking the "Tools" button in the left drawer
+ ![Open The Tools Page](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/add-tools-step-0.png "Open The Tools Page")
+
+2. Click the "Register New Tool" button on the right
+ ![Click The Register New Tool Button](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/add-tools-step-1.png "Click The Register New Tool Button")
+
+3. Type the Tool repo reference into the modal's input box -- in this example `github.com/otto8-ai/go-hash-tool` -- and click "Register Tool"
+ ![Enter Tool Repo Reference](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/add-tools-step-2.png "Enter Tool Repo Reference")
+
+Afterwords, the Tool will be available for use in `Otto8`.
+
+You can search for the Tool by category or name on the Tools page to verify:
+
+![Search For Newly Added Tools](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/add-tools-step-3.png "Search For Newly Added Tools")
+
+### Using The `Hash` Tool in an Agent
+
+To use the `Hash` Tool in an Agent, open the Agent's Edit page, then:
+
+1. Click the "Add Tool" button under either the "Agent Tools" or "User Tools" sections
+ ![Click The Add Tool Button](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/use-tools-step-0.png "Click The Add Tool Button")
+
+2. Search for "Hash" or "Crypto" in the Tool search pop-out and select the `Hash` Tool
+ ![Add Hash Tool To Agent](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/use-tools-step-1.png "Add Hash Tool To Agent")
+
+3. Ask the Agent to generate a hash
+ ![Ask The Agent To Generate a Hash](https://raw.githubusercontent.com/otto8-ai/go-hash-tool/refs/heads/main/docs/use-tools-step-2.png "Ask The Agent To Generate a Hash")
diff --git a/docs/snippets/node-hash-tool-readme.md.mdx b/docs/snippets/node-hash-tool-readme.md.mdx
new file mode 100644
index 00000000..a7fa8615
--- /dev/null
+++ b/docs/snippets/node-hash-tool-readme.md.mdx
@@ -0,0 +1,377 @@
+## Writing your first tool in Node.js (with Typescript)
+
+[node-hash-tool](https://github.com/otto8-ai/node-hash-tool) contains a reference Typescript `Node.js` implementation of the `Hash` Tool.
+
+This guide walks through the structure and design of the Tool and outlines the packaging requirements for [Otto8](https://docs.otto8.ai/concepts/agents)
+
+To clone this repo and follow along, run the following command:
+
+```bash
+git clone git@github.com:otto8-ai/node-hash-tool
+```
+
+---
+
+### Tool Repo Structure
+
+The directory tree below highlights the files required to implement `Hash` in Typescript and package it for `Otto8`.
+
+```
+node-hash-tool
+├── package-lock.json
+├── package.json
+├── tsconfig.json
+├── tool.gpt
+└── src
+ ├── hash.ts
+ └── tools.ts
+```
+
+**Note:** The `tsconfig.json` file is only required for tools written in Typescript. It is not necessary for tools written in JavaScript.
+
+---
+
+### Defining the `Hash` Tool
+
+The `tool.gpt` file contains [GPTScript Tool Definitions](https://docs.gptscript.ai/tools/gpt-file-reference) which describe a set of Tools that can be used by Agents in `Otto8`.
+Every Tool repository must have a `tool.gpt` file in its root directory.
+
+The Tools defined in this file must have a descriptive `Name` and `Description` that will help Agents understand what the Tool does, what it returns (if anything), and all the `Parameters` it takes.
+Agents use these details to infer a Tool's usage.
+We call the section of a Tool definition that contains this info a `Preamble`.
+
+We want the `Hash` Tool to return the hash of some given `data`. It would also be nice to support a few different algorithms for the Agent to choose from.
+Let's take a look at the `Preamble` for `Hash` to see how that's achieved:
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+```
+
+Breaking this down a bit:
+
+- The `Preamble` above declares a Tool named `Hash`.
+- The `Param` fields enumerate the arguments that an Agent must provide when calling `Hash`, `data` and `algo`.
+- In this case, the description of the `algo` parameter outlines the valid options (`sha256` or `md5`) and defines a default value (`sha256`)
+- The `Description` explains what `Hash` returns with respect to the given arguments; the hash of `data` using the algorithm selected with `algo`.
+
+Immediately below the `Preamble` is the `Tool Body`, which tells `Otto8` how to execute the Tool:
+
+```text
+#!/usr/bin/env npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- hash
+```
+
+This is where the magic happens.
+
+To oversimplify, when an Agent calls the `Hash` Tool, `Otto8` reads this line and then:
+
+1. Downloads the appropriate `Node.js` tool chain (`node` and `npm`)
+2. Sets up a working directory for the Tool
+3. Installs the dependencies from the Tool's `package.json` and `package-lock.json`
+4. Projects the call arguments onto environment variables (`DATA` and `ALGO`)
+5. Runs `npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- hash`.
+
+Putting it all together, here's the complete definition of the `Hash` Tool.
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Default is "sha256". Supports "sha256" and "md5".
+
+#!/usr/bin/env npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- hash
+```
+
+### Tool Metadata
+
+The `tool.gpt` file also provides the following metadata for use in `Otto8`:
+
+- `!metadata:*:category` which tags Tools with the `Crypto` category to promote organization and discovery
+- `!metadata:*:icon` which assigns `https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg` as the Tool icon
+
+Where `*` is a wild card pattern that applies the metadata to all Tools in a `tool.gpt`.
+
+```text
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+**Note:** Metadata can be applied to a specific Tool by either specifying the exact name (e.g. `!metadata:Hash:category`) or by adding the metadata directly to a Tool's `Preamble`:
+
+```text
+Name: Hash
+Metadata: category: Crypto
+Metadata: icon: https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+### Complete `tool.gpt`
+
+```text
+---
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+
+#!/usr/bin/env npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- hash
+
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+---
+
+### Implementing Business Logic
+
+As we saw earlier, the `npm` command invoked by the `Tool Body` passes `hash` as an argument to the `tool` script.
+
+```bash
+npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- hash
+```
+
+To figure out what this resolves to, let's inspect the `tool` script defined by `package.json`:
+
+```json
+ "scripts": {
+ "tool": "node --no-warnings --loader ts-node/esm src/tools.ts"
+ },
+```
+
+This means that when the `Tool Body` is executed, the effective command that runs is:
+
+```bash
+node --no-warnings --loader ts-node/esm src/tools.ts hash
+```
+
+**Note:** The `--loader ts-node/esm` option, in conjunction with the contents of `tsconfig.json`, is the "special sauce" that lets us run Typescript code directly without transpiling it to JavaScript first.
+
+To summarize, when the `Hash` Tool is called by an Agent, `src/tools.ts` gets run with `hash` as an argument.
+
+Let's walk through the `src/tools.ts` to understand what happens at runtime:
+
+```typescript
+// ...
+const cmd = process.argv[2]
+try {
+ switch (cmd) {
+ case 'hash':
+ console.log(hash(process.env.DATA, process.env.ALGO))
+ break
+ default:
+ console.log(`Unknown command: ${cmd}`)
+ process.exit(1)
+ }
+
+} catch (error) {
+ // Print the error to stdout so that it can be captured by the GPTScript
+ console.log(`${error}`)
+ process.exit(1)
+}
+```
+
+This code implements a simple CLI that wraps business logic -- e.g. the `hash` function from `src/hash.ts` -- in a try/catch block and forwards any exceptions to stdout.
+Writing errors to stdout instead of stderr is crucial because only stdout is returned to the Agent, while sdterr is discarded.
+
+The simple CLI pattern showcased above is also easily extensible; adding business logic for new tools becomes a matter of adding a new case to the `switch` statement.
+
+For example, if we wanted to add a new Tool to verify a given hash, we'd add a `verify` case:
+
+```typescript
+switch (cmd) {
+ case 'verify':
+ console.log(verify(process.env.HASH, process.env.DATA, process.env.ALGO))
+ break
+ case 'hash':
+ // ...
+ default:
+ // ...
+ }
+```
+
+And the Body of the `Verify` Tool would pass `verify` to the `tool` script instead of `hash`:
+
+```text
+Name: Verify
+# ...
+
+#!/usr/bin/env npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- verify
+```
+
+Getting back to the `Hash` Tool, when invoked, the code calls the `hash` function with `data` and `algo` arguments extracted from the respective environment variables.
+
+The `hash` function is where the bulk of the `Hash` Tool's business logic is implemented.
+
+```typescript
+import { createHash } from 'node:hash';
+
+const SUPPORTED_ALGORITHMS = ['sha256', 'md5'];
+
+export function hash(data: string = '', algo = 'sha256'): string {
+ if (data === '') {
+ throw new Error("A non-empty data argument must be provided");
+ }
+
+ if (!SUPPORTED_ALGORITHMS.includes(algo)) {
+ throw new Error(`Unsupported hash algorithm ${algo} not in [${SUPPORTED_ALGORITHMS.join(', ')}]`);
+ }
+
+ return JSON.stringify({
+ algo,
+ hash: createHash(algo).update(data).digest('hex'),
+ });
+}
+```
+
+It starts off by validating the `data` and `algo` arguments.
+When an argument is invalid, the function throws an exception that describes the validation issue in detail.
+The goal is to provide useful information that an Agent can use to construct valid arguments for future calls.
+For example, when an invalid `algo` argument is provided, the code returns an error that contains the complete list of valid algorithms.
+
+Once it determines that all of the arguments are valid, it calculates the hash and writes a JSON object to stdout.
+This object contains the hash and the algorithm used to generate it.
+
+```typescript
+ // ...
+ return JSON.stringify({
+ algo,
+ hash: createHash(algo).update(data).digest('hex'),
+ });
+```
+
+Producing structured data with extra contextual info (e.g. the algorithm) is considered good form.
+It's a pattern that improves the Agent's ability to correctly use the Tool's result over time.
+
+### Complete `package.json`, `src/tools.ts`, and `src/hash.ts`
+
+```json
+{
+ "type": "module",
+ "scripts": {
+ "tool": "node --no-warnings --loader ts-node/esm src/tools.ts"
+ },
+ "dependencies": {
+ "@types/node": "^20.16.11",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.4.5"
+ },
+ "devDependencies": {}
+}
+```
+
+```typescript
+// src/tools.ts
+import { hash } from './hash.ts'
+
+if (process.argv.length !== 3) {
+ console.error('Usage: node tool.ts ')
+ process.exit(1)
+}
+
+const cmd = process.argv[2]
+try {
+ switch (cmd) {
+ case 'hash':
+ console.log(hash(process.env.DATA, process.env.ALGO))
+ break
+ default:
+ console.log(`Unknown command: ${cmd}`)
+ process.exit(1)
+ }
+
+} catch (error) {
+ // Print the error to stdout so that it can be captured by the GPTScript
+ console.log(`${error}`)
+ process.exit(1)
+}
+```
+
+```typescript
+// src/hash.ts
+import { createHash } from 'node:hash';
+
+const SUPPORTED_ALGORITHMS = ['sha256', 'md5'];
+
+export function hash(data: string = '', algo = 'sha256'): string {
+ if (data === '') {
+ throw new Error("A non-empty data argument must be provided");
+ }
+
+ if (!SUPPORTED_ALGORITHMS.includes(algo)) {
+ throw new Error(`Unsupported hash algorithm ${algo} not in [${SUPPORTED_ALGORITHMS.join(', ')}]`);
+ }
+
+ return JSON.stringify({
+ algo,
+ hash: createHash(algo).update(data).digest('hex'),
+ });
+}
+```
+
+---
+
+### Testing `src/tools.ts` and `src/hash.ts` Locally
+
+Before adding a Tool to `Otto8`, verify that the Typescript business logic works on your machine.
+
+To do this, run through the following steps in the root of your local fork:
+
+1. Install dependencies
+
+ ```bash
+ npm install
+ ```
+
+2. Run the Tool with some test arguments:
+
+ | **Command** |**Output** |
+ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+ | `DATA='foo' npm run tool hash` | `{ "algo": "sha256", "hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" }` |
+ | `npm run tool hash` | `Error: A data argument must be provided` |
+ | `DATA='foo' ALGO='md5' npm run tool hash` | `{ "algo": "md5", "hash": "acbd18db4cc2f85cedef654fccc4a4d8" }` |
+ | `DATA='foo' ALGO='whirlpool' npm run tool hash` | `Error: Unsupported hash algorithm: whirlpool not in ['sha256', 'md5']` |
+
+---
+
+### Adding The `Hash` Tool to `Otto8`
+
+Before a Tool can be used by an Agent, an admin must first add the Tool to `Otto8` by performing the steps below:
+
+1. Navigate to the `Otto8` admin UI in a browser and open the Tools page by clicking the "Tools" button in the left drawer
+ ![Open The Tools Page](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/add-tools-step-0.png "Open The Tools Page")
+
+2. Click the "Register New Tool" button on the right
+ ![Click The Register New Tool Button](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/add-tools-step-1.png "Click The Register New Tool Button")
+
+3. Type the Tool repo reference into the modal's input box -- in this example `github.com/otto8-ai/node-hash-tool` -- and click "Register Tool"
+ ![Enter Tool Repo Reference](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/add-tools-step-2.png "Enter Tool Repo Reference")
+
+Afterwords, the Tool will be available for use in `Otto8`.
+
+You can search for the Tool by category or name on the Tools page to verify:
+
+![Search For Newly Added Tools](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/add-tools-step-3.png "Search For Newly Added Tools")
+
+### Using The `Hash` Tool in an Agent
+
+To use the `Hash` Tool in an Agent, open the Agent's Edit page, then:
+
+1. Click the "Add Tool" button under either the "Agent Tools" or "User Tools" sections
+ ![Click The Add Tool Button](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/use-tools-step-0.png "Click The Add Tool Button")
+
+2. Search for "Hash" or "Crypto" in the Tool search pop-out and select the `Hash` Tool
+ ![Add Hash Tool To Agent](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/use-tools-step-1.png "Add Hash Tool To Agent")
+
+3. Ask the Agent to generate a hash
+ ![Ask The Agent To Generate a Hash](https://raw.githubusercontent.com/otto8-ai/node-hash-tool/refs/heads/main/docs/use-tools-step-2.png "Ask The Agent To Generate a Hash")
diff --git a/docs/snippets/python-hash-tool-readme.md.mdx b/docs/snippets/python-hash-tool-readme.md.mdx
new file mode 100644
index 00000000..b950a112
--- /dev/null
+++ b/docs/snippets/python-hash-tool-readme.md.mdx
@@ -0,0 +1,311 @@
+## Writing your first tool in Python
+
+[python-hash-tool](https://github.com/otto8-ai/python-hash-tool) contains a reference `Python` implementation of the `Hash` Tool.
+
+This guide walks through the structure and design of the Tool and outlines the packaging requirements for [Otto8](https://docs.otto8.ai/concepts/agents)
+
+To clone this repo and follow along, run the following command:
+
+```bash
+git clone git@github.com:otto8-ai/python-hash-tool
+```
+
+---
+
+### Tool Repo Structure
+
+The directory tree below highlights the files required to implement `Hash` in Python and package it for `Otto8`.
+
+```
+python-hash-tool
+├── hash.py
+├── requirements.txt
+└── tool.gpt
+```
+
+---
+
+### Defining the `Hash` Tool
+
+The `tool.gpt` file contains [GPTScript Tool Definitions](https://docs.gptscript.ai/tools/gpt-file-reference) which describe a set of Tools that
+can be used by Agents in `Otto8`.
+Every Tool repository must have a `tool.gpt` file in its root directory.
+
+The Tools defined in this file must have a descriptive `Name` and `Description` that will help Agents understand what the Tool does, what it returns (if anything), and all the `Parameters` it takes.
+Agents use these details to figure out when and how to use the Tool. We call the section of a Tool definition that contains this info a `Preamble`.
+
+We want the `Hash` Tool to return the hash of some given `data`. It would also be nice to support a few different algorithms for the Agent to choose from.
+Let's take a look at the `Preamble` for `Hash` to see how that's achieved:
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+```
+
+Breaking this down a bit:
+
+- The `Preamble` above declares a Tool named `Hash`.
+- The `Param` fields enumerate the arguments that an Agent must provide when calling `Hash`, `data` and `algo`.
+- In this case, the description of the `algo` parameter outlines the valid options (`sha256` or `md5`) and defines a default value (`sha256`)
+- The `Description` explains what `Hash` returns with respect to the given arguments; the hash of `data` using the algorithm selected with `algo`.
+
+Immediately below the `Preamble` is the `Tool Body`, which tells `Otto8` how to execute the Tool:
+
+```text
+ #!/usr/bin/env python3 ${GPTSCRIPT_TOOL_DIR}/hash.py
+```
+
+This is where the magic happens.
+
+To oversimplify, when an Agent calls the `Hash` Tool, `Otto8` reads this line and then:
+
+1. Downloads the appropriate `Python` tool chain
+2. Sets up a working directory for the Tool and creates a virtual environment
+3. Installs the dependencies from the `requirements.txt`, if present
+4. Projects the call arguments onto environment variables (`DATA` and `ALGO`)
+5. Runs `python3 ${GPTSCRIPT_TOOL_DIR}/hash.py`.
+
+Putting it all together, here's the complete definition of the `Hash` Tool.
+
+```text
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Default is "sha256". Supports "sha256" and "md5".
+
+#!/usr/bin/env python3 ${GPTSCRIPT_TOOL_DIR}/hash.py
+```
+
+### Tool Metadata
+
+The `tool.gpt` file also provides the following metadata for use in `Otto8`:
+
+- `!metadata:*:category` which tags Tools with the `Crypto` category to promote organization and discovery
+- `!metadata:*:icon` which assigns `https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg` as the Tool icon
+
+Where `*` is a wild card pattern that applies the metadata to all Tools in a `tool.gpt`.
+
+```text
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+**Note:** Metadata can be applied to a specific Tool by either specifying the exact name (e.g. `!metadata:Hash:category`) or by adding the metadata directly to a Tool's `Preamble`:
+
+```text
+Name: Hash
+Metadata: category: Crypto
+Metadata: icon: https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+### Complete `tool.gpt`
+
+```text
+---
+Name: Hash
+Description: Generate a hash of data using the given algorithm and return the result as a hexadecimal string
+Param: data: The data to hash
+Param: algo: The algorithm to generate a hash with. Supports "sha256" and "md5". Default is "sha256"
+
+#!/usr/bin/env python3 ${GPTSCRIPT_TOOL_DIR}/hash.py
+
+---
+!metadata:*:category
+Crypto
+
+---
+!metadata:*:icon
+https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/fingerprint-duotone.svg
+```
+
+---
+
+### Implementing Business Logic
+
+The `hash.py` file executed by the `Tool Body` is the concrete implementation of the Tool's business logic.
+
+Let's walk through the code to understand how it works.
+
+```python
+if __name__ == '__main__':
+ try:
+ main()
+ except Exception as err:
+ # Print err to stdout to return the error to the agent
+ print(f'Error: {err}')
+ sys.exit(1)
+```
+
+Starting at the bottom, the `main` function is called in a `try` block so that any runtime exceptions caught are written to stdout.
+This is important because everything written to stdout is returned to the Agent when the Tool call is completed, while everything written to stderr is discarded.
+Using this pattern ensures that when a Tool call fails, the calling Agent is informed of the failure.
+
+Moving on, the `main` function implements the meat and potatoes of the `Hash` Tool.
+
+```python
+SUPPORTED_HASH_ALGORITHMS = ['sha256', 'md5']
+
+def main():
+ # Extract the tool's `data` argument from the env
+ data = os.getenv('DATA')
+ if not data:
+ raise ValueError('A data argument must be provided')
+
+ # Extract the tool's `algo` argument from the env and default to `sha256`
+ algo = os.getenv('ALGO', 'sha256')
+ if algo not in SUPPORTED_HASH_ALGORITHMS:
+ # Return the supported algorithms in the error message to help agents choose a valid
+ # algorithm the next time they call this tool
+ raise ValueError(f'Unsupported hash algorithm: {algo} not in {SUPPORTED_HASH_ALGORITHMS}')
+ #...
+```
+
+It starts off by extracting the Tool's arguments from the respective environment variables and validates them.
+When an argument is invalid, the function raises an exception that describes the validation issue in detail.
+The goal is to provide useful information that an Agent can use to construct valid arguments for future calls.
+For example, when an invalid `algo` argument is provided, the code returns an error that contains the complete list of valid algorithms.
+
+After validating the Tool arguments, it calculates the hash and writes a JSON object to stdout.
+This object contains the hash and the algorithm used to generate it.
+
+```python
+ # ...
+ # Generate the hash
+ hash_obj = hashlib.new(algo)
+ hash_obj.update(data.encode('utf-8'))
+
+ # Return the hash along with the algorithm used to generate it.
+ # Providing more information in the tool's response makes it easier for agents to keep
+ # track of the context.
+ print(json.dumps({
+ 'algo': algo,
+ 'hash': hash_obj.hexdigest()
+ }))
+```
+
+Producing structured data with extra contextual info (e.g. the algorithm) is considered good form.
+It's a pattern that improves the Agent's ability to correctly use the Tool's result over time.
+
+### Complete `hash.py`
+
+```python
+import hashlib
+import json
+import os
+import sys
+
+SUPPORTED_HASH_ALGORITHMS = ['sha256', 'md5']
+
+
+def main():
+ # Extract the tool's `data` argument from the env
+ data = os.getenv('DATA')
+ if not data:
+ raise ValueError('A data argument must be provided')
+
+ # Extract the tool's `algo` argument from the env and default to `sha256`
+ algo = os.getenv('ALGO', 'sha256')
+ if algo not in SUPPORTED_HASH_ALGORITHMS:
+ # Return the supported algorithms in the error message to help assistants choose a valid
+ # algorithm the next time they call this tool
+ raise ValueError(f'Unsupported hash algorithm: {algo} not in {SUPPORTED_HASH_ALGORITHMS}')
+
+ # Generate the hash
+ hash_obj = hashlib.new(algo)
+ hash_obj.update(data.encode('utf-8'))
+
+ # Return the hash along with the algorithm used to generate it.
+ # Providing more information in the tool's response makes it easier for assistants to keep
+ # track of the context.
+ print(json.dumps({
+ 'algo': algo,
+ 'hash': hash_obj.hexdigest()
+ }))
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Exception as err:
+ # Print err to stdout to return the error to the assistant
+ print(f'Error: {err}')
+ sys.exit(1)
+```
+
+---
+
+### Testing `hash.py` Locally
+
+Before adding a Tool to `Otto8`, verify that the Python business logic works on your machine.
+
+To do this, run through the following steps in the root of your local fork:
+
+1. Set up a virtual environment:
+
+ ```bash
+ python3 -m venv venv
+ source venv/bin/activate
+ ```
+
+2. Activate the virtual environment:
+
+ ```bash
+ source venv/bin/activate
+ ```
+
+3. Install and freeze dependencies:
+
+ ```bash
+ pip install -r requirements.txt
+ pip freeze > requirements.txt
+ ```
+
+4. Run the Tool with some test arguments:
+
+ | **Command** | **Output** |
+ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+ | `DATA='foo' python3 hash.py` | `{ "algo": "sha256", "hash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" }` |
+ | `python3 hash.py` | `Error: A data argument must be provided` |
+ | `DATA='foo' ALGO='md5' python3 hash.py` | `{ "algo": "md5", "hash": "acbd18db4cc2f85cedef654fccc4a4d8" }` |
+ | `DATA='foo' ALGO='whirlpool' python3 hash.py` | `Error: Unsupported hash algorithm: whirlpool not in ['sha256', 'md5']` |
+
+---
+
+### Adding The `Hash` Tool to `Otto8`
+
+Before a Tool can be used by an Agent, an admin must first add the Tool to `Otto8` by performing the steps below:
+
+1. Navigate to the `Otto8` admin UI in a browser and open the Tools page by clicking the "Tools" button in the left drawer
+ ![Open The Tools Page](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/add-tools-step-0.png "Open The Tools Page")
+
+2. Click the "Register New Tool" button on the right
+ ![Click The Register New Tool Button](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/add-tools-step-1.png "Click The Register New Tool Button")
+
+3. Type the Tool repo reference into the modal's input box -- in this example `github.com/otto8-ai/python-hash-tool` -- and click "Register Tool"
+ ![Enter Tool Repo Reference](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/add-tools-step-2.png "Enter Tool Repo Reference")
+
+Afterwords, the Tool will be available for use in `Otto8`.
+
+You can search for the Tool by category or name on the Tools page to verify:
+
+![Search For Newly Added Tools](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/add-tools-step-3.png "Search For Newly Added Tools")
+
+### Using The `Hash` Tool in an Agent
+
+To use the `Hash` Tool in an Agent, open the Agent's Edit page, then:
+
+1. Click the "Add Tool" button under either the "Agent Tools" or "User Tools" sections
+ ![Click The Add Tool Button](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/use-tools-step-0.png "Click The Add Tool Button")
+
+2. Search for "Hash" or "Crypto" in the Tool search pop-out and select the `Hash` Tool
+ ![Add Hash Tool To Agent](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/use-tools-step-1.png "Add Hash Tool To Agent")
+
+3. Ask the Agent to generate a hash
+ ![Ask The Agent To Generate a Hash](https://raw.githubusercontent.com/otto8-ai/python-hash-tool/refs/heads/main/docs/use-tools-step-2.png "Ask The Agent To Generate a Hash")
diff --git a/docs/src/plugins/fetch-snippets/index.ts b/docs/src/plugins/fetch-snippets/index.ts
new file mode 100644
index 00000000..5f03b321
--- /dev/null
+++ b/docs/src/plugins/fetch-snippets/index.ts
@@ -0,0 +1,73 @@
+import fs from 'fs';
+import path from 'path';
+import axios from 'axios';
+import { LoadContext, Plugin } from '@docusaurus/types';
+
+// Array of permalinks to raw files in different repositories
+const FILE_URLS = [
+ 'https://raw.githubusercontent.com/otto8-ai/python-hash-tool/main/README.md',
+ 'https://raw.githubusercontent.com/otto8-ai/go-hash-tool/main/README.md',
+ 'https://raw.githubusercontent.com/otto8-ai/node-hash-tool/main/README.md',
+];
+
+// Mapping of file extensions to code block languages for syntax highlighting
+const EXTENSION_LANGUAGE_MAP: Record = {
+ '.py': 'python',
+ '.go': 'go',
+ '.mod': 'go',
+ '.ts': 'typescript',
+ '.js': 'javascript',
+ '.json': 'json',
+ '.yaml': 'yaml',
+ '.yml': 'yaml',
+ '.gpt': 'yaml',
+ '.md': 'markdown',
+ '.txt': 'text',
+};
+
+async function fetchFiles(outputDir: string) {
+ if (!fs.existsSync(outputDir)) {
+ fs.mkdirSync(outputDir, { recursive: true });
+ }
+
+ await Promise.all(
+ FILE_URLS.map(async (url) => {
+ try {
+ const { data } = await axios.get(url);
+
+ // Extract the repository name and file path from the URL
+ const match = url.match(/githubusercontent\.com\/([^/]+)\/([^/]+)\/[^/]+\/(.+)$/);
+ if (!match) throw new Error(`Invalid URL format: ${url}`);
+
+ const repoName = match[2].toLowerCase();
+ const filePath = match[3].toLowerCase().replace(/\//g, '-');
+
+ // Get the file extension and corresponding language for syntax highlighting
+ const ext = path.extname(filePath);
+ const language = EXTENSION_LANGUAGE_MAP[ext] || ''; // Default to plain text if extension is unknown
+
+ // Wrap content in a Markdown code block for supported file types
+ let wrappedContent = data;
+ if (language != 'markdown') {
+ wrappedContent = language ? `\`\`\`${language}\n${data}\n\`\`\`` : data;
+ }
+
+ const outputFilePath = path.join(outputDir, `${repoName}-${filePath}.mdx`);
+ fs.writeFileSync(outputFilePath, wrappedContent);
+ console.log(`Fetched and saved ${outputFilePath}`);
+ } catch (error) {
+ console.error(`Failed to fetch file from ${url}:`, error);
+ }
+ })
+ );
+}
+
+export default function pluginFetchSnippets(context: LoadContext): Plugin {
+ return {
+ name: 'fetch-snippets',
+ async loadContent() {
+ const outputDir = path.join(__dirname, '../../../snippets');
+ await fetchFiles(outputDir);
+ }
+ };
+}