diff --git a/CHANGELOG.md b/CHANGELOG.md index 264c71e..c37d4a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Data integrity of keys have been greatly improved - Unknown SSH keys will be immediately rejected unless `--ssh-accept-host` is passed. +### Documented + +- Added a real tutorial, and seperated many how-to guides. + The tutorial leads the user through creating and deploying a Wire Hive. + ## [0.5.0] - 2025-09-18 ### Added diff --git a/README.md b/README.md index 2de9b74..d019e8a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ wire is a tool to deploy nixos systems. its usage is inspired by colmena however it is not a fork. -Read the [The Guide](https://wire.althaea.zone/guide/wire.html), or continue reading this readme for development information. +Read the [The Guide](https://wire.althaea.zone/guides/installation.html), or continue reading this readme for development information. ## Tree Layout diff --git a/doc/.vitepress/config.ts b/doc/.vitepress/config.ts index 71be1de..47b6747 100644 --- a/doc/.vitepress/config.ts +++ b/doc/.vitepress/config.ts @@ -27,7 +27,8 @@ export default withMermaid( // https://vitepress.dev/reference/default-theme-config nav: [ { text: "Home", link: "/" }, - { text: "Guide", link: "/guide/wire" }, + { text: "Tutorial", link: "/tutorial/overview" }, + { text: "Guides", link: "/guides/installation" }, { text: "Reference", link: "/reference/cli" }, { text: pkg.version, @@ -41,30 +42,76 @@ export default withMermaid( ], sidebar: { - "/guide/": [ + "/": [ { - text: "Introduction", + text: "Tutorial", + collapsed: false, items: [ - { text: "What is Wire?", link: "/guide/wire" }, - { text: "Getting Started", link: "/guide/getting-started" }, - { text: "Flakes", link: "/guide/flakes" }, - { text: "Applying Your Config", link: "/guide/apply" }, - { text: "Targeting Nodes", link: "/guide/targeting" }, + { text: "Overview", link: "/tutorial/overview" }, + { + text: "Part One", + items: [ + { + text: "Nix Setup", + link: "/tutorial/part-one/nix-setup", + }, + { + text: "Preparing Repo & Shell", + link: "/tutorial/part-one/repo-setup", + }, + { + text: "Creating a Virtual Machine", + link: "/tutorial/part-one/vm-setup", + }, + { + text: "Basic Hive & Deployment", + link: "/tutorial/part-one/basic-hive", + }, + ], + }, + { + text: "Part Two", + items: [ + { + text: "Basic Deployment Keys", + link: "/tutorial/part-two/basic-keys", + }, + { + text: "Encrypted Deployment Keys", + link: "/tutorial/part-two/encryption", + }, + ], + }, ], }, { - text: "Features", + text: "How-to Guides", + collapsed: false, items: [ - { text: "Secret management", link: "/guide/keys" }, - { text: "Parallelism", link: "/guide/parallelism" }, - { text: "hive.default", link: "/guide/hive-default" }, - { text: "Magic Rollback", link: "/guide/magic-rollback" }, + { text: "Install wire", link: "/guides/installation" }, + { text: "Apply your Config", link: "/guides/apply" }, + { text: "Target Nodes", link: "/guides/targeting" }, + { + text: "Flakes", + items: [ + { text: "Use Flakes", link: "/guides/flakes/overview" }, + { + text: "Keep Using nixos-rebuild", + link: "/guides/flakes/nixos-rebuild", + }, + ], + }, + { + text: "Features", + items: [ + { text: "Manage Secrets", link: "/guides/keys" }, + { text: "Use Parallelism", link: "/guides/parallelism" }, + { text: "Use hive.default", link: "/guides/hive-default" }, + ], + }, ], }, - { - text: "Use cases", - items: [{ text: "Tailscale", link: "/guide/tailscale" }], - }, + { text: "CLI & Module Reference", link: "/reference/cli.html" }, ], "/reference/": [ { @@ -91,7 +138,9 @@ export default withMermaid( markdown: { config: (md) => { md.use(markdownItFootnote); - md.use(groupIconMdPlugin); + md.use(groupIconMdPlugin, { + titleBar: { includeSnippet: true }, + }); }, }, vite: { @@ -107,6 +156,9 @@ export default withMermaid( "hive.nix": "vscode-icons:file-type-nix", "flake.nix": "vscode-icons:file-type-nix", "module.nix": "vscode-icons:file-type-nix", + "vm.nix": "vscode-icons:file-type-nix", + "shell.nix": "vscode-icons:file-type-nix", + "secrets.nix": "vscode-icons:file-type-nix", home: localIconLoader(import.meta.url, "../assets/homemanager.svg"), ".conf": "vscode-icons:file-type-config", }, diff --git a/doc/guide/getting-started.md b/doc/guide/getting-started.md deleted file mode 100644 index b8ca5c5..0000000 --- a/doc/guide/getting-started.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -comment: true -title: Getting Started -description: Getting started with Wire Tool! ---- - -# {{ $frontmatter.title }} - -## Installation - -Wire can be heavy to compile. You should enable the substituter `wires.cachix.org`. - -::: code-group - -<<< @/snippets/getting-started/cache.nix [module.nix] -<<< @/snippets/getting-started/nix.conf - -::: - -### Supported Nix & NixOS versions - -Wire is currently _tested_ against `unstable`, `24.11` and `25.05`. -For each channel, it is tested against the given channel's `pkgs.lix`. - -There is currently a bug when our VM tests are ran with nixcpp. Nixcpp will try -to download a file in a network sandbox, whereas Lix will not. We don't know -how to solve it. Please see [#126](https://github.com/wires-org/wire/issues/126) - -### NixOS / Home Manager - -::: code-group - -<<< @/snippets/getting-started/nixos.flake.nix [flake.nix (NixOS)] -<<< @/snippets/getting-started/hm.flake.nix [flake.nix (Home Manager)] -<<< @/snippets/getting-started/configuration.nix -<<< @/snippets/getting-started/home.nix - -::: - -## Your First Hive - -Wire groups your machines into _nodes_, which are NixOS configurations with -additional information for deployment. Start by creating a `hive.nix` in the same directory as your -`configuration.nix`. - -::: info - -To include wire in these examples, we are using -[npins](https://github.com/andir/npins). To create this setup you -would run `npins add github wires-org wire`. - -::: - -A `hive.nix` is an attribute set with NixOS configurations, each with a unique -name. Add a node for your local machine: - -```nix:line-numbers [hive.nix] -let - sources = import ./npins; - wire = import sources.wire; -in wire.makeHive { - meta.nixpkgs = import sources.nixpkgs { }; - - my-local-machine = { - imports = [./configuration.nix]; - - # If you don't know, find this value by running - # `nix eval --expr 'builtins.currentSystem' --impure` - nixpkgs.hostPlatform = "x86_64-linux"; - }; -} -``` - -### A Remote Machine - -Lets add another node to your hive! This one is an example of a remote machine. - -```nix:line-numbers [hive.nix] -let - sources = import ./npins; - wire = import sources.wire; -in wire.makeHive { - meta.nixpkgs = import sources.nixpkgs { }; - - my-local-machine = { - imports = [./local-machine/configuration.nix]; - nixpkgs.hostPlatform = "x86_64-linux"; - }; - - my-remote-machine = { - deployment = { - # buildOnTarget defaults to `false`, enable this - # if the machine is strong enough to build itself. - buildOnTarget = true; - target = { - # Some IP or host that this node is reachable by ssh under, - # defaults to "my-remote-machine" (node name). - host = "10.1.1.2"; - # A user you can non-interactively login through ssh by, - # defaults to "root". - user = "root"; - }; - }; - imports = [./remote-machine/configuration.nix]; - nixpkgs.hostPlatform = "x86_64-linux"; - }; -} -``` - -> [!TIP] -> Read more options in [the reference](/reference/module#deployment-target) to adjust options such as -> ssh port. diff --git a/doc/guide/magic-rollback.md b/doc/guide/magic-rollback.md deleted file mode 100644 index 21a8990..0000000 --- a/doc/guide/magic-rollback.md +++ /dev/null @@ -1,3 +0,0 @@ -# Magic Rollback - -Magic Rollback is unimplemented. diff --git a/doc/guide/tailscale.md b/doc/guide/tailscale.md deleted file mode 100644 index 12bb51c..0000000 --- a/doc/guide/tailscale.md +++ /dev/null @@ -1 +0,0 @@ -# Wire & Tailscale diff --git a/doc/guide/wire.md b/doc/guide/wire.md deleted file mode 100644 index c123070..0000000 --- a/doc/guide/wire.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -comment: true ---- - -# What is Wire? - -

- - Rust Tests Status - - - - BuildBot Build & VM Test Status - - - - Documentation Status - -

- -Wire is a tool to deploy NixOS systems. Its usage is inspired by [colmena](https://colmena.cli.rs/). In many places it's configuration attempts to remain a superset[^1] of colmena, however it is **not** a fork. - -[^1]: A lot of your colmena module options will continue to work with wire, but wire has additional ergonomic changes you can take advantage of. - -::: warning -Wire is alpha software, please use at your own risk. Many features listed in this documentation may not be complete / implemented. -::: - -
- -Ready? Skip to the [Quickstart](./getting-started). - -
- -## Why Wire? - -::: info -The following is the goal for a stable release and not fully implemented. -::: - -| Features | Wire | Colmena | -| ------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------- | -| Secret Management | :white_check_mark: | :white_check_mark: | -| Parallel Evaluation | :white_check_mark: | [Experimental](https://colmena.cli.rs/unstable/features/parallelism.html#parallel-evaluation-experimental) | -| Node Tagging | :white_check_mark: | :white_check_mark: | -| Pipeline Support | :white_check_mark: | :x:[^2] | -| Magic Rollback | :white_check_mark: (Planned) | :x: | - -[^2]: You need to write custom nix code to use Colmena hive metadata inside environments like CI pipelines, bash scripting, etc., which requires a knowledge of its internals. diff --git a/doc/guide/apply.md b/doc/guides/apply.md similarity index 97% rename from doc/guide/apply.md rename to doc/guides/apply.md index 7002350..1688471 100644 --- a/doc/guide/apply.md +++ b/doc/guides/apply.md @@ -1,6 +1,6 @@ --- comment: true -title: Applying Your Config +title: Apply your Config description: How to apply a node with wire. --- @@ -10,7 +10,7 @@ description: How to apply a node with wire. ## What does it mean to 'apply'? -Once you have [created a hive](./getting-started), you can now "apply" your +Once you have created a hive, you can now "apply" your configuration to nodes in your hive. Simply, "applying" is the term used by wire to describe **deploying the config**. diff --git a/doc/guide/flakes.md b/doc/guides/flakes/nixos-rebuild.md similarity index 70% rename from doc/guide/flakes.md rename to doc/guides/flakes/nixos-rebuild.md index 572fd66..9dc66c1 100644 --- a/doc/guide/flakes.md +++ b/doc/guides/flakes/nixos-rebuild.md @@ -1,35 +1,14 @@ --- comment: true -title: Flakes -description: Learn how to output a hive from a flake. +title: How-to Keep Using nixos-rebuild +description: How to combine outputs.nixosConfigurations with outputs.wire --- # {{ $frontmatter.title }} {{ $frontmatter.description }} -## Output a hive - -::: tip -If you have skipped ahead, please read the previous page to understand the -concept of a hive. -::: - -You can use wire with a flake by outputting a hive with the `wire` flake output. -Just like when using a `hive.nix`, you must provide `meta.nixpkgs` which will -come from an input. - -::: code-group -<<< @/snippets/getting-started/flake.nix [flake.nix] -::: - -``` -❯ nix flake show -git+file:///some/path -└───colmena: unknown -``` - -## How to keep using `nixos-rebuild` +## An Example You can provide `makeHive` with your `nixosConfigurations` with the `inherit` nix keyword. `makeHive` will merge any nodes and nixosConfigurations that share diff --git a/doc/guides/flakes/overview.md b/doc/guides/flakes/overview.md new file mode 100644 index 0000000..3016079 --- /dev/null +++ b/doc/guides/flakes/overview.md @@ -0,0 +1,30 @@ +--- +comment: true +title: Flakes +description: How to output a hive from a flake. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +## Output a hive + +::: tip +If you have skipped ahead, please read the previous page to understand the +concept of a hive. +::: + +You can use wire with a flake by outputting a hive with the `wire` flake output. +Just like when using a `hive.nix`, you must provide `meta.nixpkgs` which will +come from an input. + +::: code-group +<<< @/snippets/getting-started/flake.nix [flake.nix] +::: + +``` +❯ nix flake show +git+file:///some/path +└───colmena: unknown +``` diff --git a/doc/guide/hive-default.md b/doc/guides/hive-default.md similarity index 97% rename from doc/guide/hive-default.md rename to doc/guides/hive-default.md index 0368fe3..f6f09cb 100644 --- a/doc/guide/hive-default.md +++ b/doc/guides/hive-default.md @@ -1,6 +1,6 @@ --- comment: true -title: hive.default +title: Use hive.default description: Deduplicate options with default node configuration. --- diff --git a/doc/guides/installation.md b/doc/guides/installation.md new file mode 100644 index 0000000..0c9015f --- /dev/null +++ b/doc/guides/installation.md @@ -0,0 +1,5 @@ +--- +comment: false +--- + +# Install Wire diff --git a/doc/guide/keys.md b/doc/guides/keys.md similarity index 99% rename from doc/guide/keys.md rename to doc/guides/keys.md index e3e827c..485a54c 100644 --- a/doc/guide/keys.md +++ b/doc/guides/keys.md @@ -1,6 +1,6 @@ --- comment: true -title: Secret Management +title: Manage Secrets description: Keys, files, and other out-of-store paths with Wire Tool. --- diff --git a/doc/guide/parallelism.md b/doc/guides/parallelism.md similarity index 97% rename from doc/guide/parallelism.md rename to doc/guides/parallelism.md index 249db59..e50ec91 100644 --- a/doc/guide/parallelism.md +++ b/doc/guides/parallelism.md @@ -1,6 +1,6 @@ --- comment: true -title: Parallelism +title: Use Parallelism description: A deeper dive into parallelism with Wire Tool. --- diff --git a/doc/guide/targeting.md b/doc/guides/targeting.md similarity index 98% rename from doc/guide/targeting.md rename to doc/guides/targeting.md index 265b9ba..452e633 100644 --- a/doc/guide/targeting.md +++ b/doc/guides/targeting.md @@ -1,6 +1,6 @@ --- comment: true -title: Targeting Nodes +title: Target Nodes description: Tags, nodes, and how to target them with Wire Tool. --- diff --git a/doc/index.md b/doc/index.md index a102abd..0cf3c47 100644 --- a/doc/index.md +++ b/doc/index.md @@ -8,11 +8,11 @@ hero: # tagline: My great project tagline actions: - theme: brand - text: Read Guide - link: /guide/wire + text: Read Tutorial + link: /tutorial/overview - theme: alt - text: Reference - link: /reference/cli + text: Guides + link: /guides/installation features: - title: Parallelism diff --git a/doc/package.nix b/doc/package.nix index 6cb327e..b1188bd 100644 --- a/doc/package.nix +++ b/doc/package.nix @@ -51,7 +51,7 @@ stdenv.mkDerivation (finalAttrs: { pnpmDeps = pnpm.fetchDeps { inherit (finalAttrs) pname version src; fetcherVersion = 1; - hash = "sha256-fFQ2/APhVCA3tSi3BsVB+Ym/N7eJZZoD/+lO04lf63g="; + hash = "sha256-bcjSzdG8AwqjWlCy3eN/Z7nKZ6pr13XXu2tJlWKBkgc="; }; patchPhase = '' cat ${optionsDoc} >> ./reference/module.md diff --git a/doc/pnpm-lock.yaml b/doc/pnpm-lock.yaml index 1984e62..adadd80 100644 --- a/doc/pnpm-lock.yaml +++ b/doc/pnpm-lock.yaml @@ -16,25 +16,25 @@ importers: version: 1.1.15(vue@3.5.22) vitepress-plugin-group-icons: specifier: ^1.6.3 - version: 1.6.3(markdown-it@14.1.0)(vite@5.4.19) + version: 1.6.3(markdown-it@14.1.0)(vite@5.4.20) devDependencies: mermaid: specifier: ^11.12.0 version: 11.12.0 vitepress: specifier: ^1.6.4 - version: 1.6.4(@algolia/client-search@5.35.0)(postcss@8.5.6)(search-insights@2.17.3) + version: 1.6.4(@algolia/client-search@5.40.0)(postcss@8.5.6)(search-insights@2.17.3) vitepress-plugin-mermaid: specifier: ^2.0.17 - version: 2.0.17(mermaid@11.12.0)(vitepress@1.6.4(@algolia/client-search@5.35.0)(postcss@8.5.6)(search-insights@2.17.3)) + version: 2.0.17(mermaid@11.12.0)(vitepress@1.6.4(@algolia/client-search@5.40.0)(postcss@8.5.6)(search-insights@2.17.3)) vue: specifier: ^3.5.22 version: 3.5.22 packages: - '@algolia/abtesting@1.1.0': - resolution: {integrity: sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow==} + '@algolia/abtesting@1.6.0': + resolution: {integrity: sha512-c4M/Z/KWkEG+RHpZsWKDTTlApXu3fe4vlABNcpankWBhdMe4oPZ/r4JxEr2zKUP6K+BT66tnp8UbHmgOd/vvqQ==} engines: {node: '>= 14.0.0'} '@algolia/autocomplete-core@1.17.7': @@ -57,63 +57,63 @@ packages: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.35.0': - resolution: {integrity: sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ==} + '@algolia/client-abtesting@5.40.0': + resolution: {integrity: sha512-qegVlgHtmiS8m9nEsuKUVhlw1FHsIshtt5nhNnA6EYz3g+tm9+xkVZZMzkrMLPP7kpoheHJZAwz2MYnHtwFa9A==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.35.0': - resolution: {integrity: sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw==} + '@algolia/client-analytics@5.40.0': + resolution: {integrity: sha512-Dw2c+6KGkw7mucnnxPyyMsIGEY8+hqv6oB+viYB612OMM3l8aNaWToBZMnNvXsyP+fArwq7XGR+k3boPZyV53A==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.35.0': - resolution: {integrity: sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w==} + '@algolia/client-common@5.40.0': + resolution: {integrity: sha512-dbE4+MJIDsTghG3hUYWBq7THhaAmqNqvW9g2vzwPf5edU4IRmuYpKtY3MMotes8/wdTasWG07XoaVhplJBlvdg==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.35.0': - resolution: {integrity: sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA==} + '@algolia/client-insights@5.40.0': + resolution: {integrity: sha512-SH6zlROyGUCDDWg71DlCnbbZ/zEHYPZC8k901EAaBVhvY43Ju8Wa6LAcMPC4tahcDBgkG2poBy8nJZXvwEWAlQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.35.0': - resolution: {integrity: sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA==} + '@algolia/client-personalization@5.40.0': + resolution: {integrity: sha512-EgHjJEEf7CbUL9gJHI1ULmAtAFeym2cFNSAi1uwHelWgLPcnLjYW2opruPxigOV7NcetkGu+t2pcWOWmZFuvKQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.35.0': - resolution: {integrity: sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w==} + '@algolia/client-query-suggestions@5.40.0': + resolution: {integrity: sha512-HvE1jtCag95DR41tDh7cGwrMk4X0aQXPOBIhZRmsBPolMeqRJz0kvfVw8VCKvA1uuoAkjFfTG0X0IZED+rKXoA==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.35.0': - resolution: {integrity: sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg==} + '@algolia/client-search@5.40.0': + resolution: {integrity: sha512-nlr/MMgoLNUHcfWC5Ns2ENrzKx9x51orPc6wJ8Ignv1DsrUmKm0LUih+Tj3J+kxYofzqQIQRU495d4xn3ozMbg==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.35.0': - resolution: {integrity: sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA==} + '@algolia/ingestion@1.40.0': + resolution: {integrity: sha512-OfHnhE+P0f+p3i90Kmshf9Epgesw5oPV1IEUOY4Mq1HV7cQk16gvklVN1EaY/T9sVavl+Vc3g4ojlfpIwZFA4g==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.35.0': - resolution: {integrity: sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw==} + '@algolia/monitoring@1.40.0': + resolution: {integrity: sha512-SWANV32PTKhBYvwKozeWP9HOnVabOixAuPdFFGoqtysTkkwutrtGI/rrh80tvG+BnQAmZX0vUmD/RqFZVfr/Yg==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.35.0': - resolution: {integrity: sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ==} + '@algolia/recommend@5.40.0': + resolution: {integrity: sha512-1Qxy9I5bSb3mrhPk809DllMa561zl5hLsMR6YhIqNkqQ0OyXXQokvJ2zApSxvd39veRZZnhN+oGe+XNoNwLgkw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.35.0': - resolution: {integrity: sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==} + '@algolia/requester-browser-xhr@5.40.0': + resolution: {integrity: sha512-MGt94rdHfkrVjfN/KwUfWcnaeohYbWGINrPs96f5J7ZyRYpVLF+VtPQ2FmcddFvK4gnKXSu8BAi81hiIhUpm3w==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.35.0': - resolution: {integrity: sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==} + '@algolia/requester-fetch@5.40.0': + resolution: {integrity: sha512-wXQ05JZZ10Dr642QVAkAZ4ZZlU+lh5r6dIBGmm9WElz+1EaQ6BNYtEOTV6pkXuFYsZpeJA89JpDOiwBOP9j24w==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.35.0': - resolution: {integrity: sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ==} + '@algolia/requester-node-http@5.40.0': + resolution: {integrity: sha512-5qCRoySnzpbQVg2IPLGFCm4LF75pToxI5tdjOYgUMNL/um91aJ4dH3SVdBEuFlVsalxl8mh3bWPgkUmv6NpJiQ==} engines: {node: '>= 14.0.0'} '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@antfu/utils@9.2.0': - resolution: {integrity: sha512-Oq1d9BGZakE/FyoEtcNeSwM7MpDO2vUBi11RWBZXf75zPsbUVWmUs03EqkRFrcgbXyKTas0BdZWC1wcuSoqSAw==} + '@antfu/utils@9.3.0': + resolution: {integrity: sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA==} '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} @@ -322,18 +322,15 @@ packages: '@iconify-json/logos@1.2.9': resolution: {integrity: sha512-G6VCdFnwZcrT6Eveq3m43oJfLw/CX8plwFcE+2jgv3fiGB64pTmnU7Yd1MNZ/eA+/Re2iEDhuCfSNOWTHwwK8w==} - '@iconify-json/simple-icons@1.2.47': - resolution: {integrity: sha512-wa/2O7G4sBmwSEWWLh5C+HeY00lVOoWYRKJOYQtk7lAbQrHUReD1ijiGOyTynV1YavxtNueL1CBA1UZmYJfOrQ==} + '@iconify-json/simple-icons@1.2.54': + resolution: {integrity: sha512-OQQYl8yC5j3QklZOYnK31QYe5h47IhyCoxSLd53f0e0nA4dgi8VOZS30SgSAbsecQ+S0xlGJMjXIHTIqZ+ML3w==} - '@iconify-json/vscode-icons@1.2.29': - resolution: {integrity: sha512-ByqO3YPYs0n7hakQ/ZUXltJQnYibeOv41H1AdciOs7Pmba5/OsKKK1/oOjcBmvXrYuENO+IvIzORYkl6sFXgqA==} + '@iconify-json/vscode-icons@1.2.31': + resolution: {integrity: sha512-lVb4R5CxosCsnGnQQ3NzrXWLgSeQoq+I2sYCowveVNHFwO2fGGbVmUTc6ApFkjxlqT1i43lNgM9zZuhnkL64hQ==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@iconify/utils@3.0.1': - resolution: {integrity: sha512-A78CUEnFGX8I/WlILxJCuIJXloL0j/OJ9PSchPAfCargEIKmUBWvvEMmKWB5oONwiUqlNt+5eRufdkLxeHIWYw==} - '@iconify/utils@3.0.2': resolution: {integrity: sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ==} @@ -349,106 +346,116 @@ packages: '@mermaid-js/mermaid-mindmap@9.3.0': resolution: {integrity: sha512-IhtYSVBBRYviH1Ehu8gk69pMDF8DSRqXBRDMWrEfHoaMruHeaP2DXA3PBnuwsMaCdPQhlUUcy/7DBLAEIXvCAw==} - '@mermaid-js/parser@0.6.2': - resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==} + '@mermaid-js/parser@0.6.3': + resolution: {integrity: sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==} - '@rollup/rollup-android-arm-eabi@4.46.2': - resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} + '@rollup/rollup-android-arm-eabi@4.52.4': + resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.46.2': - resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} + '@rollup/rollup-android-arm64@4.52.4': + resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.46.2': - resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} + '@rollup/rollup-darwin-arm64@4.52.4': + resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.46.2': - resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} + '@rollup/rollup-darwin-x64@4.52.4': + resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.46.2': - resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==} + '@rollup/rollup-freebsd-arm64@4.52.4': + resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.46.2': - resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==} + '@rollup/rollup-freebsd-x64@4.52.4': + resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.46.2': - resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.46.2': - resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==} + '@rollup/rollup-linux-arm-musleabihf@4.52.4': + resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.46.2': - resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==} + '@rollup/rollup-linux-arm64-gnu@4.52.4': + resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.46.2': - resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==} + '@rollup/rollup-linux-arm64-musl@4.52.4': + resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.46.2': - resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==} + '@rollup/rollup-linux-loong64-gnu@4.52.4': + resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.46.2': - resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==} + '@rollup/rollup-linux-ppc64-gnu@4.52.4': + resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.46.2': - resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==} + '@rollup/rollup-linux-riscv64-gnu@4.52.4': + resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.46.2': - resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==} + '@rollup/rollup-linux-riscv64-musl@4.52.4': + resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.46.2': - resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==} + '@rollup/rollup-linux-s390x-gnu@4.52.4': + resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.46.2': - resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==} + '@rollup/rollup-linux-x64-gnu@4.52.4': + resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.46.2': - resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==} + '@rollup/rollup-linux-x64-musl@4.52.4': + resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.46.2': - resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==} + '@rollup/rollup-openharmony-arm64@4.52.4': + resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.4': + resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.46.2': - resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==} + '@rollup/rollup-win32-ia32-msvc@4.52.4': + resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.46.2': - resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==} + '@rollup/rollup-win32-x64-gnu@4.52.4': + resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.4': + resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} cpu: [x64] os: [win32] @@ -644,9 +651,6 @@ packages: peerDependencies: vue: 3.5.22 - '@vue/shared@3.5.18': - resolution: {integrity: sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==} - '@vue/shared@3.5.22': resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} @@ -705,15 +709,15 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - algoliasearch@5.35.0: - resolution: {integrity: sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg==} + algoliasearch@5.40.0: + resolution: {integrity: sha512-a9aIL2E3Z7uYUPMCmjMFFd5MWhn+ccTubEvnMy7rOTZCB62dXBJtz0R5BZ/TPuX3R9ocBsgWuAbGWQ+Ph4Fmlg==} engines: {node: '>= 14.0.0'} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - birpc@2.5.0: - resolution: {integrity: sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==} + birpc@2.6.1: + resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -921,15 +925,6 @@ packages: dayjs@1.11.18: resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1015,8 +1010,8 @@ packages: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} - katex@0.16.22: - resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + katex@0.16.23: + resolution: {integrity: sha512-7VlC1hsEEolL9xNO05v9VjrvWZePkCVBJqj8ruICxYjZfHaHbaU53AlP+PODyFIXEnaEIEWi3wJy7FPZ95JAVg==} hasBin: true khroma@2.1.0: @@ -1067,8 +1062,8 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true - marked@16.3.0: - resolution: {integrity: sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w==} + marked@16.4.0: + resolution: {integrity: sha512-CTPAcRBq57cn3R8n3hwc2REddc28hjR7RzDXQ+lXLmMJYqn20BaI2cGw6QjgZGIgVfp2Wdfw4aMzgNteQ6qJgQ==} engines: {node: '>= 20'} hasBin: true @@ -1096,8 +1091,8 @@ packages: micromark-util-types@2.0.2: resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - minisearch@7.1.2: - resolution: {integrity: sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==} + minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -1119,8 +1114,8 @@ packages: oniguruma-to-es@3.1.1: resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} - package-manager-detector@1.3.0: - resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + package-manager-detector@1.4.0: + resolution: {integrity: sha512-rRZ+pR1Usc+ND9M2NkmCvE/LYJS+8ORVV9X0KuNSY/gFsp7RBHJM/ADh9LYq4Vvfq6QkKrW6/weuh8SMEtN5gw==} path-data-parser@0.1.0: resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} @@ -1150,8 +1145,8 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - preact@10.27.0: - resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==} + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -1178,8 +1173,8 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rollup@4.46.2: - resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==} + rollup@4.52.4: + resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1263,8 +1258,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + vite@5.4.20: + resolution: {integrity: sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1354,124 +1349,124 @@ packages: snapshots: - '@algolia/abtesting@1.1.0': + '@algolia/abtesting@1.6.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)': + '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) - '@algolia/client-search': 5.35.0 - algoliasearch: 5.35.0 + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0) + '@algolia/client-search': 5.40.0 + algoliasearch: 5.40.0 - '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)': + '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)': dependencies: - '@algolia/client-search': 5.35.0 - algoliasearch: 5.35.0 + '@algolia/client-search': 5.40.0 + algoliasearch: 5.40.0 - '@algolia/client-abtesting@5.35.0': + '@algolia/client-abtesting@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/client-analytics@5.35.0': + '@algolia/client-analytics@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/client-common@5.35.0': {} + '@algolia/client-common@5.40.0': {} - '@algolia/client-insights@5.35.0': + '@algolia/client-insights@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/client-personalization@5.35.0': + '@algolia/client-personalization@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/client-query-suggestions@5.35.0': + '@algolia/client-query-suggestions@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/client-search@5.35.0': + '@algolia/client-search@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/ingestion@1.35.0': + '@algolia/ingestion@1.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/monitoring@1.35.0': + '@algolia/monitoring@1.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/recommend@5.35.0': + '@algolia/recommend@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + '@algolia/client-common': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 - '@algolia/requester-browser-xhr@5.35.0': + '@algolia/requester-browser-xhr@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 + '@algolia/client-common': 5.40.0 - '@algolia/requester-fetch@5.35.0': + '@algolia/requester-fetch@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 + '@algolia/client-common': 5.40.0 - '@algolia/requester-node-http@5.35.0': + '@algolia/requester-node-http@5.40.0': dependencies: - '@algolia/client-common': 5.35.0 + '@algolia/client-common': 5.40.0 '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 1.3.0 + package-manager-detector: 1.4.0 tinyexec: 1.0.1 - '@antfu/utils@9.2.0': {} + '@antfu/utils@9.3.0': {} '@babel/helper-string-parser@7.27.1': {} @@ -1510,10 +1505,10 @@ snapshots: '@docsearch/css@3.8.2': {} - '@docsearch/js@3.8.2(@algolia/client-search@5.35.0)(search-insights@2.17.3)': + '@docsearch/js@3.8.2(@algolia/client-search@5.40.0)(search-insights@2.17.3)': dependencies: - '@docsearch/react': 3.8.2(@algolia/client-search@5.35.0)(search-insights@2.17.3) - preact: 10.27.0 + '@docsearch/react': 3.8.2(@algolia/client-search@5.40.0)(search-insights@2.17.3) + preact: 10.27.2 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -1521,12 +1516,12 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.8.2(@algolia/client-search@5.35.0)(search-insights@2.17.3)': + '@docsearch/react@3.8.2(@algolia/client-search@5.40.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.35.0)(algoliasearch@5.35.0) + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.40.0)(algoliasearch@5.40.0) '@docsearch/css': 3.8.2 - algoliasearch: 5.35.0 + algoliasearch: 5.40.0 optionalDependencies: search-insights: 2.17.3 transitivePeerDependencies: @@ -1610,33 +1605,20 @@ snapshots: dependencies: '@iconify/types': 2.0.0 - '@iconify-json/simple-icons@1.2.47': + '@iconify-json/simple-icons@1.2.54': dependencies: '@iconify/types': 2.0.0 - '@iconify-json/vscode-icons@1.2.29': + '@iconify-json/vscode-icons@1.2.31': dependencies: '@iconify/types': 2.0.0 '@iconify/types@2.0.0': {} - '@iconify/utils@3.0.1': - dependencies: - '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 9.2.0 - '@iconify/types': 2.0.0 - debug: 4.4.1 - globals: 15.15.0 - kolorist: 1.8.0 - local-pkg: 1.1.2 - mlly: 1.8.0 - transitivePeerDependencies: - - supports-color - '@iconify/utils@3.0.2': dependencies: '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 9.2.0 + '@antfu/utils': 9.3.0 '@iconify/types': 2.0.0 debug: 4.4.3 globals: 15.15.0 @@ -1665,68 +1647,74 @@ snapshots: non-layered-tidy-tree-layout: 2.0.2 optional: true - '@mermaid-js/parser@0.6.2': + '@mermaid-js/parser@0.6.3': dependencies: langium: 3.3.1 - '@rollup/rollup-android-arm-eabi@4.46.2': + '@rollup/rollup-android-arm-eabi@4.52.4': + optional: true + + '@rollup/rollup-android-arm64@4.52.4': optional: true - '@rollup/rollup-android-arm64@4.46.2': + '@rollup/rollup-darwin-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-arm64@4.46.2': + '@rollup/rollup-darwin-x64@4.52.4': optional: true - '@rollup/rollup-darwin-x64@4.46.2': + '@rollup/rollup-freebsd-arm64@4.52.4': optional: true - '@rollup/rollup-freebsd-arm64@4.46.2': + '@rollup/rollup-freebsd-x64@4.52.4': optional: true - '@rollup/rollup-freebsd-x64@4.46.2': + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.46.2': + '@rollup/rollup-linux-arm-musleabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.46.2': + '@rollup/rollup-linux-arm64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.46.2': + '@rollup/rollup-linux-arm64-musl@4.52.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.46.2': + '@rollup/rollup-linux-loong64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.46.2': + '@rollup/rollup-linux-ppc64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.46.2': + '@rollup/rollup-linux-riscv64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.46.2': + '@rollup/rollup-linux-riscv64-musl@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.46.2': + '@rollup/rollup-linux-s390x-gnu@4.52.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.46.2': + '@rollup/rollup-linux-x64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.46.2': + '@rollup/rollup-linux-x64-musl@4.52.4': optional: true - '@rollup/rollup-linux-x64-musl@4.46.2': + '@rollup/rollup-openharmony-arm64@4.52.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.46.2': + '@rollup/rollup-win32-arm64-msvc@4.52.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.46.2': + '@rollup/rollup-win32-ia32-msvc@4.52.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.46.2': + '@rollup/rollup-win32-x64-gnu@4.52.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.4': optional: true '@shikijs/core@2.5.0': @@ -1915,9 +1903,9 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@5.2.4(vite@5.4.19)(vue@3.5.22)': + '@vitejs/plugin-vue@5.2.4(vite@5.4.20)(vue@3.5.22)': dependencies: - vite: 5.4.19 + vite: 5.4.20 vue: 3.5.22 '@vue/compiler-core@3.5.22': @@ -1957,7 +1945,7 @@ snapshots: '@vue/devtools-kit@7.7.7': dependencies: '@vue/devtools-shared': 7.7.7 - birpc: 2.5.0 + birpc: 2.6.1 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 @@ -1990,8 +1978,6 @@ snapshots: '@vue/shared': 3.5.22 vue: 3.5.22 - '@vue/shared@3.5.18': {} - '@vue/shared@3.5.22': {} '@vueuse/core@12.8.2': @@ -2023,26 +2009,26 @@ snapshots: acorn@8.15.0: {} - algoliasearch@5.35.0: - dependencies: - '@algolia/abtesting': 1.1.0 - '@algolia/client-abtesting': 5.35.0 - '@algolia/client-analytics': 5.35.0 - '@algolia/client-common': 5.35.0 - '@algolia/client-insights': 5.35.0 - '@algolia/client-personalization': 5.35.0 - '@algolia/client-query-suggestions': 5.35.0 - '@algolia/client-search': 5.35.0 - '@algolia/ingestion': 1.35.0 - '@algolia/monitoring': 1.35.0 - '@algolia/recommend': 5.35.0 - '@algolia/requester-browser-xhr': 5.35.0 - '@algolia/requester-fetch': 5.35.0 - '@algolia/requester-node-http': 5.35.0 + algoliasearch@5.40.0: + dependencies: + '@algolia/abtesting': 1.6.0 + '@algolia/client-abtesting': 5.40.0 + '@algolia/client-analytics': 5.40.0 + '@algolia/client-common': 5.40.0 + '@algolia/client-insights': 5.40.0 + '@algolia/client-personalization': 5.40.0 + '@algolia/client-query-suggestions': 5.40.0 + '@algolia/client-search': 5.40.0 + '@algolia/ingestion': 1.40.0 + '@algolia/monitoring': 1.40.0 + '@algolia/recommend': 5.40.0 + '@algolia/requester-browser-xhr': 5.40.0 + '@algolia/requester-fetch': 5.40.0 + '@algolia/requester-node-http': 5.40.0 argparse@2.0.1: {} - birpc@2.5.0: {} + birpc@2.6.1: {} ccount@2.0.1: {} @@ -2274,10 +2260,6 @@ snapshots: dayjs@1.11.18: {} - debug@4.4.1: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -2377,7 +2359,7 @@ snapshots: is-what@4.1.16: {} - katex@0.16.22: + katex@0.16.23: dependencies: commander: 8.3.0 @@ -2442,7 +2424,7 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 - marked@16.3.0: {} + marked@16.4.0: {} mdast-util-to-hast@13.2.0: dependencies: @@ -2462,7 +2444,7 @@ snapshots: dependencies: '@braintree/sanitize-url': 7.1.1 '@iconify/utils': 3.0.2 - '@mermaid-js/parser': 0.6.2 + '@mermaid-js/parser': 0.6.3 '@types/d3': 7.4.3 cytoscape: 3.33.1 cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) @@ -2472,10 +2454,10 @@ snapshots: dagre-d3-es: 7.0.11 dayjs: 1.11.18 dompurify: 3.2.7 - katex: 0.16.22 + katex: 0.16.23 khroma: 2.1.0 lodash-es: 4.17.21 - marked: 16.3.0 + marked: 16.4.0 roughjs: 4.6.6 stylis: 4.3.6 ts-dedent: 2.2.0 @@ -2500,7 +2482,7 @@ snapshots: micromark-util-types@2.0.2: {} - minisearch@7.1.2: {} + minisearch@7.2.0: {} mitt@3.0.1: {} @@ -2524,7 +2506,7 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 - package-manager-detector@1.3.0: {} + package-manager-detector@1.4.0: {} path-data-parser@0.1.0: {} @@ -2559,7 +2541,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.27.0: {} + preact@10.27.2: {} property-information@7.1.0: {} @@ -2581,30 +2563,32 @@ snapshots: robust-predicates@3.0.2: {} - rollup@4.46.2: + rollup@4.52.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.46.2 - '@rollup/rollup-android-arm64': 4.46.2 - '@rollup/rollup-darwin-arm64': 4.46.2 - '@rollup/rollup-darwin-x64': 4.46.2 - '@rollup/rollup-freebsd-arm64': 4.46.2 - '@rollup/rollup-freebsd-x64': 4.46.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.46.2 - '@rollup/rollup-linux-arm-musleabihf': 4.46.2 - '@rollup/rollup-linux-arm64-gnu': 4.46.2 - '@rollup/rollup-linux-arm64-musl': 4.46.2 - '@rollup/rollup-linux-loongarch64-gnu': 4.46.2 - '@rollup/rollup-linux-ppc64-gnu': 4.46.2 - '@rollup/rollup-linux-riscv64-gnu': 4.46.2 - '@rollup/rollup-linux-riscv64-musl': 4.46.2 - '@rollup/rollup-linux-s390x-gnu': 4.46.2 - '@rollup/rollup-linux-x64-gnu': 4.46.2 - '@rollup/rollup-linux-x64-musl': 4.46.2 - '@rollup/rollup-win32-arm64-msvc': 4.46.2 - '@rollup/rollup-win32-ia32-msvc': 4.46.2 - '@rollup/rollup-win32-x64-msvc': 4.46.2 + '@rollup/rollup-android-arm-eabi': 4.52.4 + '@rollup/rollup-android-arm64': 4.52.4 + '@rollup/rollup-darwin-arm64': 4.52.4 + '@rollup/rollup-darwin-x64': 4.52.4 + '@rollup/rollup-freebsd-arm64': 4.52.4 + '@rollup/rollup-freebsd-x64': 4.52.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 + '@rollup/rollup-linux-arm-musleabihf': 4.52.4 + '@rollup/rollup-linux-arm64-gnu': 4.52.4 + '@rollup/rollup-linux-arm64-musl': 4.52.4 + '@rollup/rollup-linux-loong64-gnu': 4.52.4 + '@rollup/rollup-linux-ppc64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-musl': 4.52.4 + '@rollup/rollup-linux-s390x-gnu': 4.52.4 + '@rollup/rollup-linux-x64-gnu': 4.52.4 + '@rollup/rollup-linux-x64-musl': 4.52.4 + '@rollup/rollup-openharmony-arm64': 4.52.4 + '@rollup/rollup-win32-arm64-msvc': 4.52.4 + '@rollup/rollup-win32-ia32-msvc': 4.52.4 + '@rollup/rollup-win32-x64-gnu': 4.52.4 + '@rollup/rollup-win32-x64-msvc': 4.52.4 fsevents: 2.3.3 roughjs@4.6.6: @@ -2695,11 +2679,11 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@5.4.19: + vite@5.4.20: dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.46.2 + rollup: 4.52.4 optionalDependencies: fsevents: 2.3.3 @@ -2709,42 +2693,42 @@ snapshots: transitivePeerDependencies: - vue - vitepress-plugin-group-icons@1.6.3(markdown-it@14.1.0)(vite@5.4.19): + vitepress-plugin-group-icons@1.6.3(markdown-it@14.1.0)(vite@5.4.20): dependencies: '@iconify-json/logos': 1.2.9 - '@iconify-json/vscode-icons': 1.2.29 - '@iconify/utils': 3.0.1 + '@iconify-json/vscode-icons': 1.2.31 + '@iconify/utils': 3.0.2 markdown-it: 14.1.0 - vite: 5.4.19 + vite: 5.4.20 transitivePeerDependencies: - supports-color - vitepress-plugin-mermaid@2.0.17(mermaid@11.12.0)(vitepress@1.6.4(@algolia/client-search@5.35.0)(postcss@8.5.6)(search-insights@2.17.3)): + vitepress-plugin-mermaid@2.0.17(mermaid@11.12.0)(vitepress@1.6.4(@algolia/client-search@5.40.0)(postcss@8.5.6)(search-insights@2.17.3)): dependencies: mermaid: 11.12.0 - vitepress: 1.6.4(@algolia/client-search@5.35.0)(postcss@8.5.6)(search-insights@2.17.3) + vitepress: 1.6.4(@algolia/client-search@5.40.0)(postcss@8.5.6)(search-insights@2.17.3) optionalDependencies: '@mermaid-js/mermaid-mindmap': 9.3.0 - vitepress@1.6.4(@algolia/client-search@5.35.0)(postcss@8.5.6)(search-insights@2.17.3): + vitepress@1.6.4(@algolia/client-search@5.40.0)(postcss@8.5.6)(search-insights@2.17.3): dependencies: '@docsearch/css': 3.8.2 - '@docsearch/js': 3.8.2(@algolia/client-search@5.35.0)(search-insights@2.17.3) - '@iconify-json/simple-icons': 1.2.47 + '@docsearch/js': 3.8.2(@algolia/client-search@5.40.0)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.54 '@shikijs/core': 2.5.0 '@shikijs/transformers': 2.5.0 '@shikijs/types': 2.5.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.4(vite@5.4.19)(vue@3.5.22) + '@vitejs/plugin-vue': 5.2.4(vite@5.4.20)(vue@3.5.22) '@vue/devtools-api': 7.7.7 - '@vue/shared': 3.5.18 + '@vue/shared': 3.5.22 '@vueuse/core': 12.8.2 '@vueuse/integrations': 12.8.2(focus-trap@7.6.5) focus-trap: 7.6.5 mark.js: 8.11.1 - minisearch: 7.1.2 + minisearch: 7.2.0 shiki: 2.5.0 - vite: 5.4.19 + vite: 5.4.20 vue: 3.5.22 optionalDependencies: postcss: 8.5.6 diff --git a/doc/snippets/getting-started/cache.nix b/doc/snippets/getting-started/cache.nix index 52b9abd..1489826 100644 --- a/doc/snippets/getting-started/cache.nix +++ b/doc/snippets/getting-started/cache.nix @@ -1,11 +1,12 @@ { nix.settings = { substituters = [ - "https://wires.cachix.org" + "https://cache.nixos.org" + "https://cache.althaea.zone" # ... ]; trusted-public-keys = [ - "wires.cachix.org-1:7XQoG91Bh+Aj01mAJi77Ui5AYyM1uEyV0h1wOomqjpk=" + "cache.althaea.zone:BelRpa863X9q3Y+AOnl5SM7QFzre3qb+5I7g2s/mqHI=" # ... ]; }; diff --git a/doc/snippets/getting-started/nix.conf b/doc/snippets/getting-started/nix.conf index c0a8db4..c4fb0c7 100644 --- a/doc/snippets/getting-started/nix.conf +++ b/doc/snippets/getting-started/nix.conf @@ -1,2 +1,3 @@ -substituters = https://wires.cachix.org -trusted-public-keys = wires.cachix.org-1:7XQoG91Bh+Aj01mAJi77Ui5AYyM1uEyV0h1wOomqjpk= \ No newline at end of file +# /etc/nix/nix.conf +trusted-substituters = https://cache.nixos.org https://cache.althaea.zone +trusted-public-keys = ... cache.althaea.zone:BelRpa863X9q3Y+AOnl5SM7QFzre3qb+5I7g2s/mqHI= diff --git a/doc/snippets/tutorial/extra-experimental-features.conf b/doc/snippets/tutorial/extra-experimental-features.conf new file mode 100644 index 0000000..a6d85dc --- /dev/null +++ b/doc/snippets/tutorial/extra-experimental-features.conf @@ -0,0 +1,2 @@ +# /etc/nix/nix.conf +experimental-features = nix-command diff --git a/doc/snippets/tutorial/extra-experimental-features.nix b/doc/snippets/tutorial/extra-experimental-features.nix new file mode 100644 index 0000000..213346d --- /dev/null +++ b/doc/snippets/tutorial/extra-experimental-features.nix @@ -0,0 +1,7 @@ +{ + nix.settings = { + experimental-features = [ + "nix-command" + ]; + }; +} diff --git a/doc/tutorial/overview.md b/doc/tutorial/overview.md new file mode 100644 index 0000000..a77b063 --- /dev/null +++ b/doc/tutorial/overview.md @@ -0,0 +1,48 @@ +--- +comment: false +title: Wire Tutorial Overview +description: In this tutorial we will create and deploy a Wire Hive. +--- + +# {{ $frontmatter.title }} + +Wire is a tool to deploy NixOS systems. Its usage is inspired by [colmena](https://colmena.cli.rs/). In many places it's configuration attempts to remain a superset[^1] of colmena, however it is **not** a fork. + +[^1]: A lot of your colmena module options will continue to work with wire, but wire has additional ergonomic changes you can take advantage of. + +::: warning +Wire is alpha software, please use at your own risk. Many features listed in this documentation overall may not be complete / implemented, however features covered in this this tutorial are considered complete. +::: + +--- + +In this tutorial we will create and deploy a Wire Hive. Along the way we will +encounter [npins](https://github.com/andir/npins), simple NixOS +configurations, virutal machines, and deployment keys. + +
+ +Ready? Skip to [Nix Setup](./part-one/nix-setup). + +
+ +## Why Wire? + +| Features | Wire | Colmena | +| ------------------------ | ------------------ | ------------------ | +| Node Tagging | :white_check_mark: | :white_check_mark: | +| Secret Management | :white_check_mark: | :white_check_mark: | +| Parallel Evaluation | :white_check_mark: | :white_check_mark: | +| Node Tagging | :white_check_mark: | :white_check_mark: | +| Remote Builds | :white_check_mark: | :white_check_mark: | +| Pipeline Support | :white_check_mark: | :x:[^2] | +| Non-Root Deployments[^4] | :white_check_mark: | :x:[^3] | + +[^2]: You need to write custom nix code to use Colmena hive metadata inside environments like CI pipelines, bash scripting, etc., which requires a knowledge of its internals. Recently it agained the [eval feature](https://colmena.cli.rs/unstable/features/eval.html) which has improved the situation since wire was first started. + +[^3]: See https://github.com/zhaofengli/colmena/issues/120 + +[^4]: + You may deploy with _any_ user who can login through SSH, whether they be + `wheel` or not. You may need to enter your password multiple times for the various elevated + steps wire needs to perform. diff --git a/doc/tutorial/part-one/basic-hive.md b/doc/tutorial/part-one/basic-hive.md new file mode 100644 index 0000000..3da2f5b --- /dev/null +++ b/doc/tutorial/part-one/basic-hive.md @@ -0,0 +1,188 @@ +--- +comment: true +title: Basic Hive & Deployment +description: Creating a basic hive and deploying changes to the virtual machine. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +## Editing `hive.nix` + +Open a text editor and edit `hive.nix`. You should copy this example, which imports +the npins sources we added. It also calls `makeHive`, and gives Wire `nixpkgs` +from npins as well. + +```nix:line-numbers [hive.nix] +let + # import npins sources + sources = import ./npins; + # import `wire` from npins sources + wire = import sources.wire; +in +wire.makeHive { + # give Wire nixpkgs from npins + meta.nixpkgs = import sources.nixpkgs { }; + + # we'll edit this part +} +``` + +Lets check out what wire sees with `wire show`. + +```sh +[nix-shell]$ wire show + WARN wire: use --json to output something scripting suitable +Hive { + nodes: {}, + schema: 0, +} +``` + +The line `nodes: {}` means theres no "nodes" in our hive. + +## Adding The First Node + +Lets add the virtual machine as a node to the hive with the name +`virtual-machine`. Additionally, we will add `deployment.target`, recalling we +forwarded sshd `virtual-machine:22` to the port `localhost:2222`: + +```nix:line-numbers [hive.nix] +let + sources = import ./npins; + wire = import sources.wire; +in +wire.makeHive { + meta.nixpkgs = import sources.nixpkgs { }; + + virtual-machine = { # [!code ++] + deployment.target = { # [!code ++] + port = 2222; # [!code ++] + hosts = [ "localhost" ]; # [!code ++] + }; # [!code ++] + + nixpkgs.hostPlatform = "x86_64-linux"; # [!code ++] + }; # [!code ++] +} +``` + +## A naive `wire apply` + +If we tried to run `wire apply` on our hive at this stage, it likely won't work. +If you've used NixOS before, you'll notice that many important options are +missing. But let's try anyway: + +```sh +[nix-shell]$ wire apply +ERROR apply{goal=Switch on=}:goal{node=virtual-machine}: lib::hive::node: Failed to execute `Evaluate the node` +Error: × 1 node(s) failed to apply. + +Error: + × node virtual-machine failed to apply + ├─▶ wire::Evaluate + │ + │ × failed to evaluate `--file /home/marsh/scratch/wire-tutorial/hive.nix topLevels.virtual-machine` from the context + │ │ of a hive. + │ + ╰─▶ nix --extra-experimental-features nix-command --extra-experimental-features flakes eval --json --file /home/marsh/scratch/ + wire-tutorial/hive.nix topLevels.virtual-machine --log-format internal-json failed (reason: known-status) with code 1 (last 20 + lines): + error: + … while evaluating '(evaluateNode node).config.system.build.toplevel' to select 'drvPath' on it + at /nix/store/5pfz0v479gnciac17rcqi2gwyz8pl4s0-source/runtime/evaluate.nix:65:23: + 64| + 65| getTopLevel = node: (evaluateNode node).config.system.build.toplevel.drvPath; + | ^ + 66| in + + … while calling the 'head' builtin + at /nix/store/n3d1ricw0cb5jd8vvfym6ig0mw7x7sv9-source/lib/attrsets.nix:1701:13: + 1700| if length values == 1 || pred here (elemAt values 1) (head values) then + 1701| head values + | ^ + 1702| else + + (stack trace truncated; use '--show-trace' to show the full trace) + + error: + Failed assertions: + - The ‘fileSystems’ option does not specify your root file system. + - You must set the option ‘boot.loader.grub.devices’ or 'boot.loader.grub.mirroredBoots' to make the system bootable. + trace: evaluation warning: system.stateVersion is not set, defaulting to 25.11. Read why this matters on https://nixos.org/ + manual/nixos/stable/options.html#opt-system.stateVersion. + +``` + +The command complained about not defining any fileSystems or a boot loader. +The `${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix` imported in +`vm.nix` does +extra work to make our virtual machine work, which we are currently missing. + +## Importing `vm.nix` + +Lets import our `vm.nix` to this hive to fix our evaluation errors. +Additionally, add a new package such as `vim` to our configuration: + +```nix:line-numbers [hive.nix] +let + sources = import ./npins; + wire = import sources.wire; +in +wire.makeHive { + meta.nixpkgs = import sources.nixpkgs { }; + + virtual-machine = { + deployment.target = { + port = 2222; + hosts = [ "localhost" ]; + }; + + imports = [ # [!code ++] + ./vm.nix # [!code ++] + ]; # [!code ++] + + environment.systemPackages = [ pkgs.vim ]; # [!code ++] + + nixpkgs.hostPlatform = "x86_64-linux"; + }; +} +``` + +## Our first deploy + +Trying our basic `wire apply` again with these changes: + +```sh +[nix-shell]$ wire apply +... + INFO lib::nix_log: stopping the following units: boot.mount + INFO lib::nix_log: NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2dlabel-ESP.service + INFO lib::nix_log: activating the configuration... + INFO lib::nix_log: setting up /etc... + INFO lib::nix_log: restarting systemd... + INFO lib::nix_log: reloading user units for root... + INFO lib::nix_log: restarting sysinit-reactivation.target + INFO lib::nix_log: reloading the following units: dbus.service + INFO lib::nix_log: the following new units were started: boot.automount, sysinit-reactivation.target, systemd-tmpfiles-resetup.service + INFO apply{goal=Switch on=}:goal{node=virtual-machines}: lib::hive::node: Executing step `Upload key @ PostActivation` + INFO apply{goal=Switch on=}: wire::apply: Successfully applied goal to 1 node(s): [Name("virtual-machines")] +``` + +Now, lets confirm these changes were applied to the virtual machine by executing +`vim` in the virtual machine window: + +```sh [Virtual Machine] +[root@wire-tutorial:~]# vim --version +VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 01 1980 00:00:00) +``` + +Nice! You successfully deployed a new NixOS configuration to a **remote host**! + +::: info +This followed common steps of adding the node's `deployment.target` details and +importing it's pre-existing NixOS configuration (in this case, `vm.nix`), a +pattern you'll be using a lot if you chose to adopt wire. +::: + +In the next section, we'll cover how to deploy secrets / keys to our remote node. diff --git a/doc/tutorial/part-one/nix-setup.md b/doc/tutorial/part-one/nix-setup.md new file mode 100644 index 0000000..861f2ce --- /dev/null +++ b/doc/tutorial/part-one/nix-setup.md @@ -0,0 +1,44 @@ +--- +comment: true +title: Nix Setup +description: Installing npins, nix, and enabling the binary cache. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +::: warning +This page is for the purposes for the **Tutorial**. +You should read [Guides - Installation](/guides/installation.html) for installing Wire for +regular use. +::: + +## Nix Installation + +You should install nix if you do not have it on your system already. +There are detailed steps to installing Nix on [nix.dev](https://nix.dev/install-nix). + +By the end of the installation, you should see something like this: + +```sh +$ nix --version +nix (Nix) 2.11.0 +``` + +## Using `cache.althaea.zone` + +Because Wire can be heavy to compile, it is distributed with a [binary +cache](https://wiki.nixos.org/wiki/Binary_Cache). It's URL is +`https://cache.althaea.zone` and it's public key is +`cache.althaea.zone:BelRpa863X9q3Y+AOnl5SM7QFzre3qb+5I7g2s/mqHI=`. + +You should trust the substituter `https://wires.cachix.org` by +either editing `/etc/nix/nix.conf` or updating your NixOS configuration: + +::: code-group + +<<< @/snippets/getting-started/nix.conf +<<< @/snippets/getting-started/cache.nix [configuration.nix] + +::: diff --git a/doc/tutorial/part-one/repo-setup.md b/doc/tutorial/part-one/repo-setup.md new file mode 100644 index 0000000..554710e --- /dev/null +++ b/doc/tutorial/part-one/repo-setup.md @@ -0,0 +1,110 @@ +--- +comment: true +title: Preparing Repo & Shell +description: Adding npins sources and a nix development shell. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +## Initialising with Git & `npins` + +First, lets create an adhoc shell to bring these two tools into our $PATH. + +```sh +$ nix-shell -p git npins +[nix-shell]$ git --version +git version 2.51.0 +[nix-shell]$ npins --version +npins 0.3.1 +``` + +Great! Now lets use Git & `npins` to create a new Git repo and initialise it. +`npins init` may take a while to download `nixpkgs`. + +```sh +[nix-shell]$ git init wire-tutorial +Initialized empty Git repository in /home/.../wire-tutorial/.git/ +[nix-shell]$ cd wire-tutorial/ +[nix-shell]$ npins init +[INFO ] Welcome to npins! +[INFO ] Creating `npins` directory +[INFO ] Writing default.nix +[INFO ] Writing initial lock file with nixpkgs entry (need to fetch latest commit first) +[INFO ] Successfully written initial files to 'npins/sources.json'. +``` + +This has created a pinned version of `nixpkgs` for us to use in our Wire hive. + +## Adding wire as a dependency + +We can now need to tell `npins` to use `wires-org/wire` as a dependency. + +```sh +[nix-shell]$ npins add github wires-org wire +[INFO ] Adding 'wire' … + repository: https://github.com/wires-org/wire.git + pre_releases: false + submodules: false + version: v0.4.0 + revision: f33d80c15b17c85d557d533441609a59a2210941 + hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr + frozen: false +``` + +Great, now lets confirm the two dependencies we have added to this `npins` +project: + +```sh +[nix-shell]$ npins show +nixpkgs: (Nix channel) + name: nixpkgs-unstable + url: https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre861972.88cef159e47c/nixexprs.tar.xz + hash: 0zscvr0qa3capyzhmp798hgncz2qy8ggm843y10wk35jk7p0174f + frozen: false + +wire: (git release tag) + repository: https://github.com/wires-org/wire.git + pre_releases: false + submodules: false + version: v0.4.0 + revision: f33d80c15b17c85d557d533441609a59a2210941 + hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr + frozen: false +``` + +## Creating a `shell.nix` + +Open a text editor to edit `shell.nix` in the `wire-tutorial` directory. + +```nix:line-numbers [shell.nix] +let + sources = import ./npins; + pkgs = import sources.nixpkgs { }; + wire = import sources.wire; +in +pkgs.mkShell { + packages = [ + wire.packages.x86_64-linux.wire-small + pkgs.npins + pkgs.git + ]; + + NIX_PATH = "nixpkgs=${sources.nixpkgs.outPath}"; +} +``` + +You should now `exit` to quit the old shell, and +enter a new shell with `nix-shell`. Since we added wire as a package, our new +shell should have wire in the $PATH: + +```sh +[nix-shell]$ exit +exit +$ nix-shell +[nix-shell]$ wire --version +wire 0.5.0 +Debug: Hive::SCHEMA_VERSION 0 + +``` diff --git a/doc/tutorial/part-one/vm-setup.md b/doc/tutorial/part-one/vm-setup.md new file mode 100644 index 0000000..9b0587d --- /dev/null +++ b/doc/tutorial/part-one/vm-setup.md @@ -0,0 +1,132 @@ +--- +comment: true +title: Creating a Virtual Machine +description: Creating a NixOS virtual machine to use as a deployment target. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +## Creating a `vm.nix` + +Open a text editor and edit `vm.nix`. Place in it this basic NixOS +virtual machine configuration, which enables openssh and forwards it's 22 port: + +```nix:line-numbers [vm.nix] +let + sources = import ./npins; +in +{ + imports = [ "${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ]; + + networking.hostName = "wire-tutorial"; + + boot = { + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + kernelParams = [ "console=ttyS0" ]; + }; + + # enable openssh + services = { + openssh = { + enable = true; + settings.PermitRootLogin = "yes"; + }; + + getty.autologinUser = "root"; + }; + + virtualisation = { + graphics = false; + useBootLoader = true; + + # forward `openssh` port 22 to localhost:2222. + forwardPorts = [ + { + from = "host"; + host.port = 2222; + guest.port = 22; + } + ]; + }; + + users.users.root.initialPassword = "root"; + + system.stateVersion = "23.11"; +} +``` + +If you like, you may take a moment to understand each line of this +configuration. + +## Building & Running the virtual machine + +Open a seperate Terminal tab/window/instance, ensuring you enter the development +shell with `nix-shell`. +Then, build the virtual machine with a bootloader, +taking our `vm.nix` as the nixos configuration. + +```sh +$ nix-shell +[nix-shell]$ nix-build '' -A vmWithBootLoader -I nixos-config=./vm.nix +``` + +Building the virtual machine can take some time, but once it completes, start it +by running: + +```sh +[nix-shell]$ ./result/bin/run-wire-tutorial-vm +``` + +You will see boot-up logs fly across the screen and eventually you will be placed +into shell inside the virtual machine. + +```sh [Virtual Machine] +running activation script... +setting up /etc... + +Welcome to NixOS 25.11 (Xantusia)! + +[ OK ] Created slice Slice /system/getty. +[ OK ] Created slice Slice /system/modprobe. +... +<<< Welcome to NixOS 25.11pre861972.88cef159e47c (x86_64) - hvc0 >>> + +Run 'nixos-help' for the NixOS manual. + +wire-tutorial login: root (automatic login) + +[root@wire-tutorial:~]# + +``` + +::: details +Further details on how the above commands work can be found at +[nix.dev](https://nix.dev/tutorials/nixos/nixos-configuration-on-vm.html#creating-a-qemu-based-virtual-machine-from-a-nixos-configuration) +::: + +## Summary + +Congratulations, you created a virtual machine in your terminal. +We'll be deploying to this virtual machine, so keep the +terminal instance open. + +::: info +From now on, commands ran inside the virtual machine will be lead with the +following prompt: + +```sh [Virtual Machine] +[root@wire-tutorial:~]# + +``` + +::: + +::: tip +If you ever want to quit the virtual machine, run the command `poweroff`. +::: diff --git a/doc/tutorial/part-two/basic-keys.md b/doc/tutorial/part-two/basic-keys.md new file mode 100644 index 0000000..9965a35 --- /dev/null +++ b/doc/tutorial/part-two/basic-keys.md @@ -0,0 +1,142 @@ +--- +comment: true +title: Deployment Keys Basics +description: Deploy some basic secrets with Wire tool. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +## Creating a `secrets.nix` + +Lets create a NixOS module that will contain our secret keys, and import it: + +```nix:line-numbers [hive.nix] +let + sources = import ./npins; + wire = import sources.wire; +in +wire.makeHive { + meta.nixpkgs = import sources.nixpkgs { }; + + virtual-machine = { + deployment.target = { + port = 2222; + hosts = [ "localhost" ]; + }; + + imports = [ + ./vm.nix + ./secrets.nix # [!code ++] + ]; + + environment.systemPackages = [ pkgs.vim ]; + + nixpkgs.hostPlatform = "x86_64-linux"; + }; +} +``` + +```nix:line-numbers [secrets.nix] +{ + deployment.keys = { + # the key's unique name is `"basic.txt"`. + "basic.txt" = { + # In this key's case, the source is a literal string: + source = '' + Hello World + ''; + }; + }; +} +``` + +::: details +Further details on the `deployment.keys` options can be found +[in the reference](/reference/module.html#deployment-keys) +::: + +Once we deploy this new configuration to the virtul machine, +`/run/keys/basic.txt` will be created with the contents of the key. + +```sh +[nix-shell]$ wire apply keys + WARN lib::nix_log: Store URL: ssh://root@localhost +(root@localhost) Password: + +``` + +```sh [Virtual Machine] +[root@wire-tutorial:~]# cat /run/keys/basic.txt +Hello World + +``` + +You successfully deployed your first, albeit not-so-secret, secret key! Let's +move on from literal-text keys and use something a bit more powerful. + +## File-sourced keys Optional + +This section is optional to try, but you can also pass `deployment.keys..source` +a file path. It's contents is read and treated as literal text. + +```sh +$ echo hello world > very-important-secret.txt +``` + +```nix:line-numbers [secrets.nix] +{ + deployment.keys = { + # ... + + "very-important-secret.txt" = { # [!code ++] + source = ./very-important-secret.txt; # [!code ++] + }; # [!code ++] + }; +} +``` + +```sh [Virtual Machine] +[root@wire-tutorial:~]# cat /run/keys/very-important-secret.txt +hello world + +``` + +## Command-sourced keys + +Command-sourced keys are where the real power of wire keys lie. By passing a +list of strings, wire will execute them as a command and create a key out of it's `stdout`. + +Because the command's output is never written to the nix store, these can be +considered real secrets. + +To create a basic example, update your `secrets.nix` to include a secret that +echos "hello world": + +```nix:line-numbers [secrets.nix] +{ + deployment.keys = { + # ... + + "command.txt" = { # [!code ++] + source = [ # [!code ++] + "echo" # [!code ++] + "hello world" # [!code ++] + ]; # [!code ++] + }; # [!code ++] + }; +} +``` + +After a quick `wire deploy secrets`, the `/run/keys/command.txt` file is +created: + +```sh [Virtual Machine] +[root@wire-tutorial:~]# cat /run/keys/command.txt +hello world + +``` + +Hopefully you can see the potential of command-sourced keys, as these are the +basic building block of how we achieve encrypted secrets with wire. diff --git a/doc/tutorial/part-two/encryption.md b/doc/tutorial/part-two/encryption.md new file mode 100644 index 0000000..446be16 --- /dev/null +++ b/doc/tutorial/part-two/encryption.md @@ -0,0 +1,105 @@ +--- +comment: true +title: Deployment Keys Basics +description: Deploy a age-encrypted secret with Wire tool. +--- + +# {{ $frontmatter.title }} + +{{ $frontmatter.description }} + +::: tip +For this tutorial we will be using [`age`](https://github.com/FiloSottile/age), +but other encryption cli tools work just as well such as GnuPG. +::: + +## Installing age + +Alter your shell.nix to include age: + +```nix:line-numbers [shell.nix] +let + sources = import ./npins; + pkgs = import sources.nixpkgs { }; + wire = import sources.wire; +in +pkgs.mkShell { + packages = [ + wire.packages.x86_64-linux.wire-small + pkgs.npins + pkgs.git + pkgs.age # [!code ++] + ]; + + NIX_PATH = "nixpkgs=${sources.nixpkgs.outPath}"; +} +``` + +Quit and re-open your shell, and confirm age is now available: + +```sh +[nix-shell]$ exit +exit +$ nix-shell +[nix-shell]$ age --version +1.2.1 + +``` + +## Encrypting a secret + +First create an age private key: + +```sh +[nix-shell]$ age-keygen -o key.txt +Public key: age1j08s3kmr8zw4w8k99vs4nut5mg03dm8nfuaajuekdyzlujxply5qwsv4g0 + +``` + +::: details +Further details on how age works can be found on in the +[age manual](https://man.archlinux.org/man/age.1.en.txt). +::: + +Now, lets encrypt the words `"!! encrypted string !!"` with age and save it to the +file `top-secret.age`. + +We will use a pipeline to echo the encrypted string into +age, and use `age-keygent -y` to give age the public key we generated, then we +use the redirection operator to save the encrypted data to `top-secret.age`. + +```sh +[nix-shell]$ echo "!! encrypted string !!" | age --encrypt --recipient $(age-keygen -y key.txt) > top-secret.age +``` + +## Adding an age-encrypted key + +Now, lets combine our previous command-sourced key with `age`. Pass the +arguments `age --decrypt --identity key.txt ./age-secret.age` to wire: + +```nix:line-numbers [secrets.nix] +{ + deployment.keys = { + # ... + + "age-secret" = { # [!code ++] + source = [ # [!code ++] + "age" # [!code ++] + "--decrypt" # [!code ++] + "--identity" # [!code ++] + "key.txt" # [!code ++] + "${./age-secret.age}" # [!code ++] + ]; # [!code ++] + }; # [!code ++] + }; +} +``` + +One `wire apply keys` later, and you have successfully deployed an encrypted +key: + +```sh [Virtual Machine] +[root@wire-tutorial:~]# cat /run/keys/age-secret +!! encrypted string !! + +```