diff --git a/Cargo.lock b/Cargo.lock
index 1c84dec380c..5e8e9149477 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,6 +58,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "allocator-api2"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+
 [[package]]
 name = "ambient-authority"
 version = "0.0.2"
@@ -544,13 +550,14 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
 
 [[package]]
 name = "cached"
-version = "0.45.1"
+version = "0.46.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90eb5776f28a149524d1d8623035760b4454ec881e8cf3838fa8d7e1b11254b3"
+checksum = "8cead8ece0da6b744b2ad8ef9c58a4cdc7ef2921e60a6ddfb9eaaa86839b5fc5"
 dependencies = [
+ "ahash 0.8.3",
  "cached_proc_macro",
  "cached_proc_macro_types",
- "hashbrown 0.13.2",
+ "hashbrown 0.14.0",
  "instant",
  "once_cell",
  "thiserror",
@@ -2208,6 +2215,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
 dependencies = [
  "ahash 0.8.3",
+ "allocator-api2",
 ]
 
 [[package]]
@@ -4689,9 +4697,9 @@ dependencies = [
 
 [[package]]
 name = "proto_core"
-version = "0.18.6"
+version = "0.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe929fdf894df177f0812c3567a39ecaedf6d1d3d723c4bcd79ca3943158579e"
+checksum = "9c27854ec66a980607216b7e415a2d2354aea5fceaef9fab4732d4636f92557a"
 dependencies = [
  "cached",
  "extism",
@@ -4720,23 +4728,24 @@ dependencies = [
 
 [[package]]
 name = "proto_pdk_api"
-version = "0.7.2"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a35152b2019ada980d05aee93c0dd1224b91013c6db0c61854a10bdd060afdcd"
+checksum = "fbd3aa9e83629f274dba31ed08d5d6d80a2d07d81c333f298a6d2518023cd144"
 dependencies = [
  "anyhow",
  "semver",
  "serde",
  "serde_json",
+ "system_env",
  "thiserror",
  "warpgate_api",
 ]
 
 [[package]]
 name = "proto_wasm_plugin"
-version = "0.6.7"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdb73a4e0527cf8846435fb5bc568f71a59916a43fbaff35bf056c7302d0720"
+checksum = "b071ce67ba3635587bd88d82a3fd7f1fd158786509555d6aeb93cacc1edc0388"
 dependencies = [
  "extism",
  "proto_pdk_api",
@@ -5356,9 +5365,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.7"
+version = "0.10.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -5734,6 +5743,17 @@ dependencies = [
  "winx 0.36.1",
 ]
 
+[[package]]
+name = "system_env"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19f0bb1e81abbd0fb277368d39b0470f4bbc01b1f4c6cede760f3e4d4b5d9bfe"
+dependencies = [
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
 [[package]]
 name = "tar"
 version = "0.4.40"
@@ -5851,18 +5871,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
 
 [[package]]
 name = "thiserror"
-version = "1.0.48"
+version = "1.0.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
+checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.48"
+version = "1.0.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
+checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -6425,9 +6445,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "version_spec"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf76e050d169eab93ec6369ec26d60748d48f2f2edb59ed8f357e7d7242e809c"
+checksum = "5babc3fe9e74e0559d8f8a825b6dcfec6f0dbf04db30926eaaf3caddcb4fb8ef"
 dependencies = [
  "human-sort",
  "once_cell",
@@ -6480,9 +6500,9 @@ dependencies = [
 
 [[package]]
 name = "warpgate"
-version = "0.5.7"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cbf79662d393831516fe10316f9613a4810db388adf86a57c763cf72b32e68b"
+checksum = "b86b10e880209a6cf820f5c33101a4c7e98f5121ff8466ab0f2ba517e656d514"
 dependencies = [
  "extism",
  "miette",
@@ -6503,9 +6523,9 @@ dependencies = [
 
 [[package]]
 name = "warpgate_api"
-version = "0.1.3"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c87f4f62fa42fa715ce697387b4c5c66ae0380723b841b1e0ff9fd285c78ab5f"
+checksum = "88d55e21fc85ba24a15b008acf53638354e81d14ba966bb909918271b1f0138d"
 dependencies = [
  "serde",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 57e6f7a8dc7..11c19461ebe 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ default-members = ["crates/cli"]
 
 [workspace.dependencies]
 async-trait = "0.1.73"
-cached = "0.45.1"
+cached = "0.46.0"
 chrono = { version = "0.4.31", features = ["serde"] }
 cd_env = "0.1.2"
 ci_env = "0.2.1"
@@ -39,7 +39,7 @@ pathdiff = "0.2.1"
 petgraph = { version = "0.6.4", default-features = false, features = [
 	"serde-1",
 ] }
-proto_core = "0.18.6"
+proto_core = "0.19.0"
 relative-path = { version = "1.9.0", features = ["serde"] }
 regex = "1.9.5"
 reqwest = { version = "0.11.20", default-features = false, features = [
diff --git a/crates/node/tool/src/node_tool.rs b/crates/node/tool/src/node_tool.rs
index 36f655565f4..cd90a6ae64b 100644
--- a/crates/node/tool/src/node_tool.rs
+++ b/crates/node/tool/src/node_tool.rs
@@ -185,7 +185,7 @@ impl Tool for NodeTool {
                 if setup || !self.tool.get_tool_dir().exists() {
                     print_checkpoint(format!("installing node {version}"), Checkpoint::Setup);
 
-                    if self.tool.setup(version).await? {
+                    if self.tool.setup(version, false).await? {
                         last_versions.insert("node".into(), version.to_owned());
                         installed += 1;
                     }
diff --git a/crates/node/tool/src/npm_tool.rs b/crates/node/tool/src/npm_tool.rs
index 82644c1605e..b11ce68c737 100644
--- a/crates/node/tool/src/npm_tool.rs
+++ b/crates/node/tool/src/npm_tool.rs
@@ -86,7 +86,7 @@ impl Tool for NpmTool {
 
         print_checkpoint(format!("installing npm {version}"), Checkpoint::Setup);
 
-        if self.tool.setup(version).await? {
+        if self.tool.setup(version, false).await? {
             last_versions.insert("npm".into(), version.to_owned());
             count += 1;
         }
diff --git a/crates/node/tool/src/pnpm_tool.rs b/crates/node/tool/src/pnpm_tool.rs
index e66262f4028..742fe0a11a8 100644
--- a/crates/node/tool/src/pnpm_tool.rs
+++ b/crates/node/tool/src/pnpm_tool.rs
@@ -92,7 +92,7 @@ impl Tool for PnpmTool {
 
         print_checkpoint(format!("installing pnpm {version}"), Checkpoint::Setup);
 
-        if self.tool.setup(version).await? {
+        if self.tool.setup(version, false).await? {
             last_versions.insert("pnpm".into(), version.to_owned());
             count += 1;
         }
diff --git a/crates/node/tool/src/yarn_tool.rs b/crates/node/tool/src/yarn_tool.rs
index 173da9d18bd..c0933f499cf 100644
--- a/crates/node/tool/src/yarn_tool.rs
+++ b/crates/node/tool/src/yarn_tool.rs
@@ -148,7 +148,7 @@ impl Tool for YarnTool {
 
         print_checkpoint(format!("installing yarn {version}"), Checkpoint::Setup);
 
-        if self.tool.setup(version).await? {
+        if self.tool.setup(version, false).await? {
             last_versions.insert("yarn".into(), version.to_owned());
             count += 1;
         }
diff --git a/crates/rust/tool/src/rust_tool.rs b/crates/rust/tool/src/rust_tool.rs
index 872e14a43e6..84a63a58423 100644
--- a/crates/rust/tool/src/rust_tool.rs
+++ b/crates/rust/tool/src/rust_tool.rs
@@ -99,7 +99,7 @@ impl Tool for RustTool {
             if setup || !self.tool.get_tool_dir().exists() {
                 print_checkpoint(format!("installing rust {version}"), Checkpoint::Setup);
 
-                if self.tool.setup(version).await? {
+                if self.tool.setup(version, false).await? {
                     last_versions.insert("rust".into(), version.to_owned());
                     installed += 1;
                 }
diff --git a/nextgen/app/src/systems/startup.rs b/nextgen/app/src/systems/startup.rs
index 15466010532..4f79346b908 100644
--- a/nextgen/app/src/systems/startup.rs
+++ b/nextgen/app/src/systems/startup.rs
@@ -136,7 +136,7 @@ pub fn load_toolchain_config(workspace_root: StateRef<WorkspaceRoot>, resources:
         );
     }
 
-    let mut proto_tools = ToolsConfig::load(proto_path)?;
+    let mut proto_tools = ToolsConfig::load_from(workspace_root)?;
     proto_tools.inherit_builtin_plugins();
 
     let config = if config_path.exists() {
diff --git a/nextgen/workspace/src/workspace.rs b/nextgen/workspace/src/workspace.rs
index abb37f46527..3c27d2329c4 100644
--- a/nextgen/workspace/src/workspace.rs
+++ b/nextgen/workspace/src/workspace.rs
@@ -5,7 +5,7 @@ use moon_common::consts;
 use moon_config::{InheritedTasksManager, ToolchainConfig, WorkspaceConfig};
 use moon_hash::HashEngine;
 use moon_vcs::{BoxedVcs, Git};
-use proto_core::{ProtoEnvironment, ToolsConfig, Version, TOOLS_CONFIG_NAME};
+use proto_core::{ProtoEnvironment, ToolsConfig, Version};
 use starbase::Resource;
 use starbase_styles::color;
 use starbase_utils::{dirs, fs};
@@ -176,7 +176,7 @@ impl Workspace {
 
         // Load proto tools
         let proto_env = ProtoEnvironment::new()?;
-        let mut proto_tools = ToolsConfig::load(root_dir.join(TOOLS_CONFIG_NAME))?;
+        let mut proto_tools = ToolsConfig::load_from(&root_dir)?;
         proto_tools.inherit_builtin_plugins();
 
         // Load configs
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index e6213b99683..d8e74420483 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -15,6 +15,7 @@
 #### 🚀 Updates
 
 - Updated `moon dep-graph` to support a task in closest project, similar to `moon run`.
+- Updated to proto v0.19.
 
 #### 🐞 Fixes
 
diff --git a/website/blog/2023-09-29_proto-v0.19.mdx b/website/blog/2023-09-29_proto-v0.19.mdx
new file mode 100644
index 00000000000..f3b92679d90
--- /dev/null
+++ b/website/blog/2023-09-29_proto-v0.19.mdx
@@ -0,0 +1,78 @@
+---
+slug: proto-v0.19
+title: proto v0.19 - Version pinning and outdated checks
+authors: [milesj]
+tags: [proto, pin, global, local, outdated]
+image: ./img/proto/v0.18.png
+---
+
+In this release, we're improving version pinning and introducing a new command to check for outdated
+versions.
+
+<!--truncate-->
+
+## New `proto pin` command (breaking)
+
+Before our official v1 release, which is relatively soon, we'll be making some breaking changes with
+the proto APIs. The first is the introduction of the new [`proto pin`](/docs/proto/commands/pin)
+command, which replaces the previous `proto local` and `proto global` commands. We felt this was a
+much cleaner change, and far easier to understand than the previous command names.
+
+```shell
+# v0.18
+$ proto local go 1.20
+$ proto global node 20
+
+# v0.19+
+$ proto pin go 1.20
+$ proto pin node 20 --global
+```
+
+## New `pin-latest` setting
+
+While we're on the subject of pinning versions, we've also introduced a new
+[`pin-latest`](/docs/proto/config#pin-latest) setting. Do you want the latest version to always be
+pinned? Do you forgot to pass `--pin` when installing? Do you forget to run the `proto global` or
+`proto local` commands (now `proto pin`)? If you answered yes to any of these questions, then this
+setting is for you.
+
+When enabled, and a tool is installed with the "latest" version, the resolved version will
+automatically be pinned to the configuration of your choice. For example, say we have the following
+user config:
+
+```toml title="~/.proto/config.toml"
+pin-latest = "local"
+```
+
+And we run one of the following commands:
+
+```shell
+$ proto install go
+$ proto install node latest
+```
+
+Then the resolved version of the tool will automatically be set to the `.prototools` file in the
+current directory. Handy right?
+
+## New `proto outdated` command
+
+By request of the community, we're introducing yet another new command,
+[`proto outdated`](/docs/proto/commands/outdated). If you're familiar with package managers, you can
+probably guess what this command does! It'll check for newer available versions, for all tools
+configured in the closest `.prototools` file. Very handy for keeping your tools up to date.
+
+```
+$ proto outdated
+
+go - current version 1.20.2 (via ~1.20), newer version 1.20.8, update available!
+node - current version 20.7.0 (via 20.7.0), latest version 20.8.0, update available!
+```
+
+## Other changes
+
+View the [official release](https://github.com/moonrepo/proto/releases/tag/v0.19.0) for a full list
+of changes.
+
+- Added `PROTO_WASM_LOG` environment variable to toggle the logging of messages from Extism and WASM
+  plugins. Useful for debugging.
+- Updated `proto install` to auto-clean stale plugins after a successful installation.
diff --git a/website/blog/img/proto/v0.19.png b/website/blog/img/proto/v0.19.png
new file mode 100644
index 00000000000..101718a43eb
Binary files /dev/null and b/website/blog/img/proto/v0.19.png differ
diff --git a/website/docs/proto/commands/add-plugin.mdx b/website/docs/proto/commands/add-plugin.mdx
index fdc4a49e7d1..258665fc33e 100644
--- a/website/docs/proto/commands/add-plugin.mdx
+++ b/website/docs/proto/commands/add-plugin.mdx
@@ -2,6 +2,10 @@
 title: add-plugin
 ---
 
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.16.0" header />
+
 The `proto add-plugin <id> <locator>` (or `proto ap`) command will add the provided plugin ID and
 locator string to the `[plugins]` section of the local (`.prototools`) or global
 (`~/.proto/config.toml`) config file.
diff --git a/website/docs/proto/commands/global.mdx b/website/docs/proto/commands/global.mdx
deleted file mode 100644
index 86ffce85926..00000000000
--- a/website/docs/proto/commands/global.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: global
----
-
-The `proto global <tool> <version>` command will set the global default version (or alias) of a
-tool, by pinning the version in `~/.proto/tools/<tool>/manifest.json`. This version will be used
-when attempting to [detect a version](../detection).
-
-```shell
-$ proto global go 1.20
-```
-
-### Arguments
-
-- `<tool>` - Type of tool.
-- `<version>` - Version of tool.
diff --git a/website/docs/proto/commands/local.mdx b/website/docs/proto/commands/local.mdx
deleted file mode 100644
index f4b1d41a446..00000000000
--- a/website/docs/proto/commands/local.mdx
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: local
----
-
-The `proto local <tool> <version>` command will set the local version (or alias) of a tool by
-creating a `.prototools` file (if it does not exist) in the current working directory with the
-appropriate tool and version. This version will be used when attempting to
-[detect a version](../detection).
-
-```shell
-$ proto local go 1.20
-```
-
-> [Learn more about the `.prototools` configuration file!](../config)
-
-### Arguments
-
-- `<tool>` - Type of tool.
-- `<version>` - Version of tool.
diff --git a/website/docs/proto/commands/outdated.mdx b/website/docs/proto/commands/outdated.mdx
new file mode 100644
index 00000000000..30a3de97f6d
--- /dev/null
+++ b/website/docs/proto/commands/outdated.mdx
@@ -0,0 +1,27 @@
+---
+title: outdated
+---
+
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.19.0" header />
+
+The `proto outdated` command will load the closest `.prototools` file and check for newer versions
+of each configured tool. By default, only newer versions that match the configured version
+requirements or ranges will be used. To ignore this and use the latest version, pass `--latest`.
+
+```
+$ proto outdated
+
+go - current version 1.20.2 (via ~1.20), newer version 1.20.8, update available!
+node - current version 20.7.0 (via 20.7.0), latest version 20.8.0, update available!
+```
+
+> [Learn more about the `.prototools` configuration file!](../config)
+
+### Options
+
+- `--json` - Print the list in JSON format.
+- `--latest` - Check for the latest available version, ignoring any version requirements, ranges, or
+  constraints.
+- `--update` - Update the loaded `.prototools` file with newer versions if available.
diff --git a/website/docs/proto/commands/pin.mdx b/website/docs/proto/commands/pin.mdx
new file mode 100644
index 00000000000..2563540456d
--- /dev/null
+++ b/website/docs/proto/commands/pin.mdx
@@ -0,0 +1,34 @@
+---
+title: pin
+---
+
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.19.0" header />
+
+The `proto pin <tool> <version>` command will pin a version (or alias) of a tool. By default it will
+pin to a `.prototools` file in the current directory. This version will be used when attempting to
+[detect a version](../detection).
+
+```shell
+$ proto pin go 1.20
+```
+
+When the `--global` option is passed, the version will be pinned globally in
+`~/.proto/tools/<tool>/manifest.json`. This version will be used as a global fallback when
+attempting to [detect a version](../detection).
+
+```shell
+$ proto pin go 1.20 --global
+```
+
+> [Learn more about the `.prototools` configuration file!](../config)
+
+### Arguments
+
+- `<tool>` - Type of tool.
+- `<version>` - Version of tool.
+
+### Options
+
+- `--global` - Pin the version globally, rather than in the current directory.
diff --git a/website/docs/proto/commands/plugins.mdx b/website/docs/proto/commands/plugins.mdx
index c01a8b5e3a5..85d53e375e7 100644
--- a/website/docs/proto/commands/plugins.mdx
+++ b/website/docs/proto/commands/plugins.mdx
@@ -2,11 +2,16 @@
 title: plugins
 ---
 
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.14.0" header />
+
 The `proto plugins` command will list all available and configured plugins. Will load all
 `.prototools` traversing upwards, and the `~/.proto/config.toml` file.
 
-```shell
+```
 $ proto plugins
+
 bun - Bun v1.2
   Source: https://github.com/moonrepo/bun-plugin/releases/latest/download/bun_plugin.wasm
 
diff --git a/website/docs/proto/commands/remove-plugin.mdx b/website/docs/proto/commands/remove-plugin.mdx
index 56a5b5e26f8..f496bec2324 100644
--- a/website/docs/proto/commands/remove-plugin.mdx
+++ b/website/docs/proto/commands/remove-plugin.mdx
@@ -2,6 +2,10 @@
 title: remove-plugin
 ---
 
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.16.0" header />
+
 The `proto remove-plugin <id>` (or `proto rp`) command will remove the provided plugin ID from to
 the `[plugins]` section of the local (`.prototools`) or global (`~/.proto/config.toml`) config file.
 
diff --git a/website/docs/proto/commands/tools.mdx b/website/docs/proto/commands/tools.mdx
index a54bd631056..243a52cdd76 100644
--- a/website/docs/proto/commands/tools.mdx
+++ b/website/docs/proto/commands/tools.mdx
@@ -2,11 +2,16 @@
 title: tools
 ---
 
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.18.0" header />
+
 The `proto tools` command will list all tools that have been installed, along with their installed
 versions, relevant timestamps, available aliases, and store location.
 
-```shell
+```
 $ proto tools
+
 go - Go
   Store: ~/.proto/tools/go
   Versions:
diff --git a/website/docs/proto/commands/uninstall-global.mdx b/website/docs/proto/commands/uninstall-global.mdx
index 52457e114db..f15df86dfdf 100644
--- a/website/docs/proto/commands/uninstall-global.mdx
+++ b/website/docs/proto/commands/uninstall-global.mdx
@@ -2,6 +2,10 @@
 title: uninstall-global
 ---
 
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
+
+<VersionLabel version="0.15.0" header />
+
 The `proto uninstall-global <tool> ...<dependencies>` (or `proto ug`) command will uninstall one or
 many global packages/modules/dependencies for the provided tool.
 
diff --git a/website/docs/proto/config.mdx b/website/docs/proto/config.mdx
index 32b12086dc4..6e0c456697d 100644
--- a/website/docs/proto/config.mdx
+++ b/website/docs/proto/config.mdx
@@ -3,6 +3,7 @@ title: Configuration
 ---
 
 import HeaderLabel from '@site/src/components/Docs/HeaderLabel';
+import VersionLabel from '@site/src/components/Docs/VersionLabel';
 
 <HeaderLabel text="1 min" />
 
@@ -13,7 +14,7 @@ We support configuration for both projects and users. Both config files are in
 
 proto supports pinning versions of tools on a per-project or per-directory basis through our
 `.prototools` configuration file. This file takes precedence during [version detection](./detection)
-and can be created/updated with [`proto local`](./commands/local).
+and can be created/updated with [`proto pin`](./commands/pin).
 
 This configuration simply maps tools to versions for the current directory.
 
@@ -81,7 +82,19 @@ When enabled, will intercept global package installs for node/npm/pnpm/yarn and
 node-intercept-globals = false
 ```
 
-### `[http]`
+### `pin-latest`<VersionLabel version="0.19.0" />
+
+When defined and a tool is installed with the "latest" version, will automatically pin the resolved
+version to the configured location. Accepts the following locations:
+
+- `global` - Pins globally to `~/.proto/config.toml`.
+- `local` - Pins locally to `.prototools`.
+
+```toml title="~/.proto/config.toml"
+pin-latest = "local"
+```
+
+### `[http]`<VersionLabel version="0.18.0" />
 
 Can be used to customize the HTTP client used by proto and warpgate, primarily for requesting files
 to download, available versions, and more. The following settings are available:
diff --git a/website/docs/proto/detection.mdx b/website/docs/proto/detection.mdx
index 0fa0411ec05..d1a765ca360 100644
--- a/website/docs/proto/detection.mdx
+++ b/website/docs/proto/detection.mdx
@@ -35,7 +35,7 @@ and traverse upwards through parent directories until a file is found.
 ##### 3.1. Version is defined locally in `.prototools`
 
 A `.prototools` file was found and a version entry exists for the current tool. This is also known
-as a "local version" and can be created with [`proto local`](./commands/local).
+as a "local version" and can be created with [`proto pin`](./commands/pin).
 
 ```toml title=".prototools"
 node = "18.0.0"
@@ -54,7 +54,7 @@ more.
 #### 4. Version is defined globally
 
 As the last check, we look for a "global version" that was pinned with
-[`proto global`](./commands/global). This version is stored at `~/.proto/tools/*/manifest.json`.
+[`proto pin --global`](./commands/pin). This version is stored at `~/.proto/tools/*/manifest.json`.
 
 #### 5. Version _could not_ be detected
 
diff --git a/website/sidebars.js b/website/sidebars.js
index acd966885f4..3ead0dd75f5 100644
--- a/website/sidebars.js
+++ b/website/sidebars.js
@@ -280,13 +280,13 @@ const sidebars = {
 				'proto/commands/bin',
 				'proto/commands/clean',
 				'proto/commands/completions',
-				'proto/commands/global',
 				'proto/commands/install',
 				'proto/commands/install-global',
 				'proto/commands/list',
 				'proto/commands/list-global',
 				'proto/commands/list-remote',
-				'proto/commands/local',
+				'proto/commands/outdated',
+				'proto/commands/pin',
 				'proto/commands/plugins',
 				'proto/commands/remove-plugin',
 				'proto/commands/run',
diff --git a/website/src/components/Products/Proto/ToolCard.tsx b/website/src/components/Products/Proto/ToolCard.tsx
index 612ad87e47d..f2e7d0085a3 100644
--- a/website/src/components/Products/Proto/ToolCard.tsx
+++ b/website/src/components/Products/Proto/ToolCard.tsx
@@ -13,6 +13,7 @@ export interface ToolCardProps {
 	tool: ProtoTool;
 }
 
+// eslint-disable-next-line complexity
 export default function ToolCard({ id, tool }: ToolCardProps) {
 	const bins = tool.bins ?? [];
 	const dirs = tool.globalsDirs ?? [];
@@ -30,7 +31,7 @@ export default function ToolCard({ id, tool }: ToolCardProps) {
 			{tool.pluginType === 'wasm' && <WasmLink to={tool.repoUrl} noMargin />}
 
 			<Heading level={5} className="mb-1">
-				<Link href={tool.homepageUrl}>{tool.name}</Link>
+				<Link href={tool.homepageUrl ?? tool.repoUrl}>{tool.name}</Link>
 			</Heading>
 
 			<Text>{tool.description}</Text>
diff --git a/website/src/data/proto-tools.tsx b/website/src/data/proto-tools.tsx
index c1d7358b85b..ba0c553d172 100644
--- a/website/src/data/proto-tools.tsx
+++ b/website/src/data/proto-tools.tsx
@@ -109,6 +109,7 @@ export const BUILT_IN_TOOLS: Record<string, ProtoTool> = {
 		description: 'Python is a high-level, general-purpose programming language.',
 		detectionSources: [{ file: '.python-version', url: 'https://github.com/pyenv/pyenv' }],
 		globalsDirs: ['~/.local/bin'],
+		homepageUrl: 'https://www.python.org/',
 		name: 'Python (experimental)',
 		pluginType: 'wasm',
 		repoUrl: 'https://github.com/moonrepo/python-plugin',
@@ -117,6 +118,7 @@ export const BUILT_IN_TOOLS: Record<string, ProtoTool> = {
 		description: `Rust is a blazingly fast and memory-efficient systems language.`,
 		detectionSources: [{ file: 'rust-toolchain.toml' }, { file: 'rust-toolchain' }],
 		globalsDirs: ['~/.cargo/bin'],
+		homepageUrl: 'https://www.rust-lang.org/',
 		name: 'Rust',
 		pluginType: 'wasm',
 		repoUrl: 'https://github.com/moonrepo/rust-plugin',