[object Object]

← back to Cli Printing Press

fix(cli): repair v3 release — version regex, module path, CI gate (#415)

4e1db1e7612431f7d711f12d45c29557910238cf · 2026-04-29 22:48:17 -0700 · Trevin Chow

* fix(cli): handle +dirty suffix in pseudo-version detection

Strip semver build metadata before classifying a runtime build-info
version string. Without this, pseudo-versions emitted by Go for builds
off a dirty working tree (e.g. v2.4.1-0.20260430120000-abcdef123456+dirty)
slipped past the pseudo-version regex's `$` anchor, so the leaked
pseudo-version overwrote the hardcoded fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(cli): bump module path to /v3 to match release 3.0.0

Go's Semantic Import Versioning rule requires v2+ modules to embed `/vN`
in the module path and every internal import. release-please bumped
version.go to 3.0.0 in commit 10fd0405 but did not update the module
path, leaving the repo failing TestModulePathMatchesMajorVersion (the
in-tree tripwire that exists for exactly this scenario) on main.

Mass rewrite of github.com/mvanhorn/cli-printing-press/v2 to /v3 across
go.mod, internal Go imports, .goreleaser.yaml ldflags, README install
instructions, and skill setup contracts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci: let release-please use a PAT so its PRs trigger CI

The default GITHUB_TOKEN passed to release-please-action cannot trigger
other workflows. That's how PR #356 (release 3.0.0) merged with an empty
status check rollup despite TestModulePathMatchesMajorVersion failing on
that diff. Branch protection wasn't blocking, so the breakage shipped
to main.

Add a token input that prefers RELEASE_PLEASE_TOKEN when set and falls
back to GITHUB_TOKEN otherwise. Behavior is unchanged until the secret
is created — once it is, release PRs trigger pull_request workflows like
any other PR and the existing tripwire test will catch missed major-bump
follow-ups before merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 4e1db1e7612431f7d711f12d45c29557910238cf
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Wed Apr 29 22:48:17 2026 -0700

    fix(cli): repair v3 release — version regex, module path, CI gate (#415)
    
    * fix(cli): handle +dirty suffix in pseudo-version detection
    
    Strip semver build metadata before classifying a runtime build-info
    version string. Without this, pseudo-versions emitted by Go for builds
    off a dirty working tree (e.g. v2.4.1-0.20260430120000-abcdef123456+dirty)
    slipped past the pseudo-version regex's `$` anchor, so the leaked
    pseudo-version overwrote the hardcoded fallback.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(cli): bump module path to /v3 to match release 3.0.0
    
    Go's Semantic Import Versioning rule requires v2+ modules to embed `/vN`
    in the module path and every internal import. release-please bumped
    version.go to 3.0.0 in commit 10fd0405 but did not update the module
    path, leaving the repo failing TestModulePathMatchesMajorVersion (the
    in-tree tripwire that exists for exactly this scenario) on main.
    
    Mass rewrite of github.com/mvanhorn/cli-printing-press/v2 to /v3 across
    go.mod, internal Go imports, .goreleaser.yaml ldflags, README install
    instructions, and skill setup contracts.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * ci: let release-please use a PAT so its PRs trigger CI
    
    The default GITHUB_TOKEN passed to release-please-action cannot trigger
    other workflows. That's how PR #356 (release 3.0.0) merged with an empty
    status check rollup despite TestModulePathMatchesMajorVersion failing on
    that diff. Branch protection wasn't blocking, so the breakage shipped
    to main.
    
    Add a token input that prefers RELEASE_PLEASE_TOKEN when set and falls
    back to GITHUB_TOKEN otherwise. Behavior is unchanged until the secret
    is created — once it is, release PRs trigger pull_request workflows like
    any other PR and the existing tripwire test will catch missed major-bump
    follow-ups before merge.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 .github/workflows/release.yml                      |  7 ++++++
 .goreleaser.yaml                                   |  2 +-
 README.md                                          |  4 ++--
 cmd/manifest-gen/main.go                           |  8 +++----
 cmd/printing-press/main.go                         |  2 +-
 ...26-04-26-001-docs-launch-readme-rewrite-plan.md |  2 +-
 go.mod                                             |  2 +-
 internal/authdoctor/classify.go                    |  2 +-
 internal/authdoctor/classify_test.go               |  2 +-
 internal/authdoctor/scan.go                        |  2 +-
 internal/authdoctor/scan_test.go                   |  2 +-
 internal/browsersniff/analysis.go                  |  4 ++--
 internal/browsersniff/analysis_test.go             |  2 +-
 internal/browsersniff/fixtures.go                  |  2 +-
 internal/browsersniff/reachability.go              |  2 +-
 internal/browsersniff/schema.go                    |  2 +-
 internal/browsersniff/schema_test.go               |  2 +-
 internal/browsersniff/specgen.go                   |  4 ++--
 internal/browsersniff/specgen_test.go              |  2 +-
 internal/catalog/catalog_test.go                   |  2 +-
 internal/cli/auth_doctor_cmd.go                    |  2 +-
 internal/cli/browser_sniff.go                      |  4 ++--
 internal/cli/browser_sniff_test.go                 |  4 ++--
 internal/cli/bundle.go                             |  2 +-
 internal/cli/bundle_test.go                        |  2 +-
 internal/cli/catalog.go                            |  4 ++--
 internal/cli/catalog_test.go                       |  2 +-
 internal/cli/crowd_sniff.go                        |  4 ++--
 internal/cli/crowd_sniff_test.go                   |  2 +-
 internal/cli/dogfood.go                            |  2 +-
 internal/cli/dogfood_test.go                       |  2 +-
 internal/cli/emboss.go                             |  4 ++--
 internal/cli/emboss_test.go                        |  2 +-
 internal/cli/exitcodes_pipeline_test.go            |  4 ++--
 internal/cli/generate_test.go                      |  4 ++--
 internal/cli/library.go                            |  4 ++--
 internal/cli/library_test.go                       |  2 +-
 internal/cli/lock.go                               |  2 +-
 internal/cli/lock_test.go                          |  2 +-
 internal/cli/mcp_sync.go                           |  2 +-
 internal/cli/patch_cmd.go                          |  2 +-
 internal/cli/polish.go                             |  2 +-
 internal/cli/probe_reachability.go                 |  2 +-
 internal/cli/publish.go                            |  6 ++---
 internal/cli/publish_test.go                       |  4 ++--
 internal/cli/release_test.go                       |  4 ++--
 internal/cli/root.go                               | 26 +++++++++++-----------
 internal/cli/scorecard.go                          |  2 +-
 internal/cli/scorecard_test.go                     |  2 +-
 internal/cli/tools_audit.go                        |  2 +-
 internal/cli/tools_audit_test.go                   |  2 +-
 internal/cli/verify.go                             |  4 ++--
 internal/cli/vision.go                             |  4 ++--
 internal/cli/vision_test.go                        |  2 +-
 internal/cli/workflow_verify.go                    |  2 +-
 internal/crowdsniff/specgen.go                     |  4 ++--
 internal/crowdsniff/specgen_test.go                |  4 ++--
 internal/discovery/naming.go                       |  2 +-
 internal/docspec/docspec.go                        |  4 ++--
 internal/generator/async_detect.go                 |  2 +-
 internal/generator/async_detect_test.go            |  2 +-
 internal/generator/auth_optional_test.go           |  2 +-
 internal/generator/body_collision_test.go          |  2 +-
 internal/generator/entity_mapper.go                |  4 ++--
 internal/generator/enum_validation_test.go         |  2 +-
 internal/generator/first_command_example.go        |  4 ++--
 internal/generator/first_command_example_test.go   |  2 +-
 internal/generator/flag_collision.go               |  2 +-
 internal/generator/flag_collision_test.go          |  2 +-
 internal/generator/freshness_paths_test.go         |  4 ++--
 internal/generator/generator.go                    | 10 ++++-----
 internal/generator/generator_test.go               | 10 ++++-----
 internal/generator/json_string_validation_test.go  |  2 +-
 internal/generator/limit_truncation_test.go        |  2 +-
 internal/generator/plan_generate.go                |  2 +-
 internal/generator/plan_generate_test.go           |  2 +-
 internal/generator/promoted_presence_check_test.go |  2 +-
 internal/generator/readme_test.go                  |  2 +-
 internal/generator/schema_builder.go               |  2 +-
 internal/generator/schema_builder_test.go          |  2 +-
 internal/generator/session_handshake_test.go       |  2 +-
 internal/generator/skill_promoted_paths_test.go    |  2 +-
 internal/generator/skill_test.go                   |  2 +-
 internal/generator/types_keyword_test.go           |  2 +-
 internal/generator/validate.go                     |  4 ++--
 internal/generator/vision_templates.go             |  2 +-
 internal/graphql/parser.go                         |  4 ++--
 internal/graphql/parser_test.go                    |  2 +-
 internal/llmpolish/polish.go                       |  2 +-
 internal/llmpolish/vision.go                       |  6 ++---
 internal/llmpolish/vision_test.go                  |  4 ++--
 internal/mcpdesc/compose.go                        |  4 ++--
 internal/mcpdesc/compose_test.go                   |  2 +-
 internal/mcpoverrides/overrides.go                 |  4 ++--
 internal/mcpoverrides/overrides_test.go            |  2 +-
 internal/openapi/detect.go                         |  2 +-
 internal/openapi/parser.go                         |  4 ++--
 internal/openapi/parser_test.go                    |  6 ++---
 internal/patch/dropins.go                          |  2 +-
 internal/pipeline/climanifest.go                   | 12 +++++-----
 internal/pipeline/climanifest_test.go              |  4 ++--
 internal/pipeline/contracts_test.go                |  8 +++----
 internal/pipeline/dogfood.go                       |  6 ++---
 internal/pipeline/fullrun.go                       |  4 ++--
 internal/pipeline/fullrun_test.go                  |  2 +-
 internal/pipeline/lock.go                          |  2 +-
 internal/pipeline/mcpb_manifest.go                 |  2 +-
 internal/pipeline/mcpsync/sync.go                  | 12 +++++-----
 internal/pipeline/mcpsync/sync_test.go             |  6 ++---
 internal/pipeline/merge.go                         |  2 +-
 internal/pipeline/merge_test.go                    |  2 +-
 internal/pipeline/paths.go                         |  2 +-
 internal/pipeline/publish.go                       | 14 ++++++------
 internal/pipeline/renamecli.go                     |  2 +-
 internal/pipeline/renamecli_test.go                |  2 +-
 internal/pipeline/research.go                      |  6 ++---
 internal/pipeline/runtime.go                       |  6 ++---
 internal/pipeline/runtime_commands.go              |  2 +-
 internal/pipeline/runtime_exec.go                  |  2 +-
 internal/pipeline/runtime_structural.go            |  2 +-
 internal/pipeline/runtime_test.go                  |  2 +-
 internal/pipeline/scorecard.go                     |  2 +-
 internal/pipeline/spec_detect.go                   |  2 +-
 internal/pipeline/state.go                         |  2 +-
 internal/pipeline/toolsmanifest.go                 |  8 +++----
 internal/pipeline/toolsmanifest_test.go            |  2 +-
 internal/pipeline/verify.go                        |  2 +-
 internal/profiler/profiler.go                      |  4 ++--
 internal/profiler/profiler_test.go                 |  2 +-
 internal/reachability/probe.go                     |  2 +-
 internal/spec/spec.go                              |  2 +-
 internal/version/version.go                        |  6 +++++
 internal/version/version_test.go                   |  7 ++++++
 skills/printing-press-catalog/SKILL.md             |  6 ++---
 skills/printing-press-publish/SKILL.md             |  4 ++--
 skills/printing-press-score/SKILL.md               |  8 +++----
 skills/printing-press/SKILL.md                     |  6 ++---
 137 files changed, 251 insertions(+), 231 deletions(-)

diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b8f27c42..24fc3777 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -24,6 +24,13 @@ jobs:
     steps:
       - uses: googleapis/release-please-action@v4
         id: release
+        with:
+          # Fall back to GITHUB_TOKEN when RELEASE_PLEASE_TOKEN is unset.
+          # The default GITHUB_TOKEN cannot trigger workflows, so release PRs
+          # opened with it skip CI and bypass tripwires like
+          # TestModulePathMatchesMajorVersion. A PAT or App token in
+          # RELEASE_PLEASE_TOKEN restores normal pull_request triggers.
+          token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
 
   goreleaser:
     needs: release-please
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
index b0821c8a..b3b48d7f 100644
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -16,7 +16,7 @@ builds:
     flags:
       - -trimpath
     ldflags:
-      - -s -w -X github.com/mvanhorn/cli-printing-press/v2/internal/version.Version={{.Version}}
+      - -s -w -X github.com/mvanhorn/cli-printing-press/v3/internal/version.Version={{.Version}}
     mod_timestamp: "{{ .CommitTimestamp }}"
 
 archives:
diff --git a/README.md b/README.md
index 4f83c119..f9269cc0 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Browse the full catalog of printed CLIs at [printingpress.dev](https://printingp
 Install the binary, then add the Claude Code plugin. Both fit in one paste.
 
 ```bash
-go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest
+go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest
 ```
 
 ```text
@@ -350,7 +350,7 @@ Each published CLI ships a research manuscript, verification proofs, and a `.pri
 Install the binary (requires Go 1.22+):
 
 ```bash
-go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest
+go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest
 ```
 
 Then install the Claude Code plugin:
diff --git a/cmd/manifest-gen/main.go b/cmd/manifest-gen/main.go
index 2211ce05..8e518414 100644
--- a/cmd/manifest-gen/main.go
+++ b/cmd/manifest-gen/main.go
@@ -22,10 +22,10 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 func main() {
diff --git a/cmd/printing-press/main.go b/cmd/printing-press/main.go
index 58eae143..ee5583c0 100644
--- a/cmd/printing-press/main.go
+++ b/cmd/printing-press/main.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/cli"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/cli"
 )
 
 func main() {
diff --git a/docs/plans/2026-04-26-001-docs-launch-readme-rewrite-plan.md b/docs/plans/2026-04-26-001-docs-launch-readme-rewrite-plan.md
index b9aa394b..f7daa796 100644
--- a/docs/plans/2026-04-26-001-docs-launch-readme-rewrite-plan.md
+++ b/docs/plans/2026-04-26-001-docs-launch-readme-rewrite-plan.md
@@ -403,7 +403,7 @@ Browse the full catalog of printed CLIs at [printingpress.dev](https://printingp
 Install the binary, then add the Claude Code plugin. Both fit in one paste.
 
 ```bash
-go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest
+go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest
 ```
 
 ```text
diff --git a/go.mod b/go.mod
index 3138c2c0..59cbd27c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/mvanhorn/cli-printing-press/v2
+module github.com/mvanhorn/cli-printing-press/v3
 
 go 1.26.1
 
diff --git a/internal/authdoctor/classify.go b/internal/authdoctor/classify.go
index adbef6d6..b1ee36c7 100644
--- a/internal/authdoctor/classify.go
+++ b/internal/authdoctor/classify.go
@@ -3,7 +3,7 @@ package authdoctor
 import (
 	"fmt"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 // minLengthByType gives the minimum expected length of a well-formed
diff --git a/internal/authdoctor/classify_test.go b/internal/authdoctor/classify_test.go
index 26ad53a7..d81bd01e 100644
--- a/internal/authdoctor/classify_test.go
+++ b/internal/authdoctor/classify_test.go
@@ -3,7 +3,7 @@ package authdoctor
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 func envFrom(m map[string]string) getEnv {
diff --git a/internal/authdoctor/scan.go b/internal/authdoctor/scan.go
index 1959ab64..58d598ce 100644
--- a/internal/authdoctor/scan.go
+++ b/internal/authdoctor/scan.go
@@ -15,7 +15,7 @@ import (
 	"path/filepath"
 	"sort"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 // Scan inspects every installed printed CLI under the published library
diff --git a/internal/authdoctor/scan_test.go b/internal/authdoctor/scan_test.go
index 39ed9466..306e0b0a 100644
--- a/internal/authdoctor/scan_test.go
+++ b/internal/authdoctor/scan_test.go
@@ -6,7 +6,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 func writeManifest(t *testing.T, dir string, m pipeline.ToolsManifest) {
diff --git a/internal/browsersniff/analysis.go b/internal/browsersniff/analysis.go
index 5947af5b..7cde424a 100644
--- a/internal/browsersniff/analysis.go
+++ b/internal/browsersniff/analysis.go
@@ -10,8 +10,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/discovery"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/discovery"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 const trafficAnalysisVersion = "1"
diff --git a/internal/browsersniff/analysis_test.go b/internal/browsersniff/analysis_test.go
index ad132f15..e41432f0 100644
--- a/internal/browsersniff/analysis_test.go
+++ b/internal/browsersniff/analysis_test.go
@@ -7,7 +7,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/browsersniff/fixtures.go b/internal/browsersniff/fixtures.go
index 69d13aa5..b0800d4b 100644
--- a/internal/browsersniff/fixtures.go
+++ b/internal/browsersniff/fixtures.go
@@ -6,7 +6,7 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/discovery"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/discovery"
 )
 
 type TestFixture struct {
diff --git a/internal/browsersniff/reachability.go b/internal/browsersniff/reachability.go
index f791ad1f..e1f2daee 100644
--- a/internal/browsersniff/reachability.go
+++ b/internal/browsersniff/reachability.go
@@ -5,7 +5,7 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 func ApplyReachabilityDefaults(apiSpec *spec.APISpec, analysis *TrafficAnalysis) {
diff --git a/internal/browsersniff/schema.go b/internal/browsersniff/schema.go
index 25d5f4d2..1a66f7ba 100644
--- a/internal/browsersniff/schema.go
+++ b/internal/browsersniff/schema.go
@@ -10,7 +10,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 const maxSchemaDepth = 3
diff --git a/internal/browsersniff/schema_test.go b/internal/browsersniff/schema_test.go
index bbd80de2..26079b92 100644
--- a/internal/browsersniff/schema_test.go
+++ b/internal/browsersniff/schema_test.go
@@ -3,7 +3,7 @@ package browsersniff
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/browsersniff/specgen.go b/internal/browsersniff/specgen.go
index cd5564fa..337188d1 100644
--- a/internal/browsersniff/specgen.go
+++ b/internal/browsersniff/specgen.go
@@ -10,8 +10,8 @@ import (
 	"strings"
 	"unicode"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/discovery"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/discovery"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"gopkg.in/yaml.v3"
 )
 
diff --git a/internal/browsersniff/specgen_test.go b/internal/browsersniff/specgen_test.go
index 0ff29be7..77e07a03 100644
--- a/internal/browsersniff/specgen_test.go
+++ b/internal/browsersniff/specgen_test.go
@@ -5,7 +5,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/catalog/catalog_test.go b/internal/catalog/catalog_test.go
index 9b45afd7..73d8067e 100644
--- a/internal/catalog/catalog_test.go
+++ b/internal/catalog/catalog_test.go
@@ -4,7 +4,7 @@ import (
 	"testing"
 	"testing/fstest"
 
-	catalogfs "github.com/mvanhorn/cli-printing-press/v2/catalog"
+	catalogfs "github.com/mvanhorn/cli-printing-press/v3/catalog"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/auth_doctor_cmd.go b/internal/cli/auth_doctor_cmd.go
index ed8ac459..de34cdce 100644
--- a/internal/cli/auth_doctor_cmd.go
+++ b/internal/cli/auth_doctor_cmd.go
@@ -3,7 +3,7 @@ package cli
 import (
 	"fmt"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/authdoctor"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/authdoctor"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/browser_sniff.go b/internal/cli/browser_sniff.go
index 638f7373..348ee7d6 100644
--- a/internal/cli/browser_sniff.go
+++ b/internal/cli/browser_sniff.go
@@ -8,8 +8,8 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/browser_sniff_test.go b/internal/cli/browser_sniff_test.go
index 4fce584c..e9e33040 100644
--- a/internal/cli/browser_sniff_test.go
+++ b/internal/cli/browser_sniff_test.go
@@ -7,8 +7,8 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/spf13/cobra"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
diff --git a/internal/cli/bundle.go b/internal/cli/bundle.go
index 367e93ce..859caf2b 100644
--- a/internal/cli/bundle.go
+++ b/internal/cli/bundle.go
@@ -10,7 +10,7 @@ import (
 	"runtime"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 	"golang.org/x/sync/errgroup"
 )
diff --git a/internal/cli/bundle_test.go b/internal/cli/bundle_test.go
index 00024797..a410a3a1 100644
--- a/internal/cli/bundle_test.go
+++ b/internal/cli/bundle_test.go
@@ -9,7 +9,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/catalog.go b/internal/cli/catalog.go
index 28dc7055..ad02bd7b 100644
--- a/internal/cli/catalog.go
+++ b/internal/cli/catalog.go
@@ -7,8 +7,8 @@ import (
 	"sort"
 	"strings"
 
-	catalogfs "github.com/mvanhorn/cli-printing-press/v2/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
+	catalogfs "github.com/mvanhorn/cli-printing-press/v3/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/catalog_test.go b/internal/cli/catalog_test.go
index c5725a0a..c8393acd 100644
--- a/internal/cli/catalog_test.go
+++ b/internal/cli/catalog_test.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/crowd_sniff.go b/internal/cli/crowd_sniff.go
index dd91d9fe..2a27a635 100644
--- a/internal/cli/crowd_sniff.go
+++ b/internal/cli/crowd_sniff.go
@@ -11,8 +11,8 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/crowdsniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/crowdsniff"
 	"github.com/spf13/cobra"
 	"golang.org/x/sync/errgroup"
 )
diff --git a/internal/cli/crowd_sniff_test.go b/internal/cli/crowd_sniff_test.go
index c1d917bc..03a66545 100644
--- a/internal/cli/crowd_sniff_test.go
+++ b/internal/cli/crowd_sniff_test.go
@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/crowdsniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/crowdsniff"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/dogfood.go b/internal/cli/dogfood.go
index 503fb6a3..61164cba 100644
--- a/internal/cli/dogfood.go
+++ b/internal/cli/dogfood.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/dogfood_test.go b/internal/cli/dogfood_test.go
index e1174e34..60529157 100644
--- a/internal/cli/dogfood_test.go
+++ b/internal/cli/dogfood_test.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/emboss.go b/internal/cli/emboss.go
index a18e0497..71fccdc7 100644
--- a/internal/cli/emboss.go
+++ b/internal/cli/emboss.go
@@ -8,8 +8,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/emboss_test.go b/internal/cli/emboss_test.go
index 6f854a98..5d54c677 100644
--- a/internal/cli/emboss_test.go
+++ b/internal/cli/emboss_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/exitcodes_pipeline_test.go b/internal/cli/exitcodes_pipeline_test.go
index 5fd84d32..2c3b2b21 100644
--- a/internal/cli/exitcodes_pipeline_test.go
+++ b/internal/cli/exitcodes_pipeline_test.go
@@ -7,8 +7,8 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/cli"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/cli"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 // TestPrintCmd_AlreadyExists_ExitCode verifies that the "already exists"
diff --git a/internal/cli/generate_test.go b/internal/cli/generate_test.go
index 3c3f822f..76aa212e 100644
--- a/internal/cli/generate_test.go
+++ b/internal/cli/generate_test.go
@@ -8,8 +8,8 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/library.go b/internal/cli/library.go
index 1610f8be..ad6214b7 100644
--- a/internal/cli/library.go
+++ b/internal/cli/library.go
@@ -9,8 +9,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/library_test.go b/internal/cli/library_test.go
index 317d05b4..5ae8ecdd 100644
--- a/internal/cli/library_test.go
+++ b/internal/cli/library_test.go
@@ -6,7 +6,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/lock.go b/internal/cli/lock.go
index 81119419..953e60c7 100644
--- a/internal/cli/lock.go
+++ b/internal/cli/lock.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/lock_test.go b/internal/cli/lock_test.go
index 228103ef..9a0964bc 100644
--- a/internal/cli/lock_test.go
+++ b/internal/cli/lock_test.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/mcp_sync.go b/internal/cli/mcp_sync.go
index 2cbbf59f..fa611a33 100644
--- a/internal/cli/mcp_sync.go
+++ b/internal/cli/mcp_sync.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline/mcpsync"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline/mcpsync"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/patch_cmd.go b/internal/cli/patch_cmd.go
index 896be040..8f824f59 100644
--- a/internal/cli/patch_cmd.go
+++ b/internal/cli/patch_cmd.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"io"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/patch"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/patch"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/polish.go b/internal/cli/polish.go
index 9e514476..8d16d6e7 100644
--- a/internal/cli/polish.go
+++ b/internal/cli/polish.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/probe_reachability.go b/internal/cli/probe_reachability.go
index 8ee3fad7..f411ba2b 100644
--- a/internal/cli/probe_reachability.go
+++ b/internal/cli/probe_reachability.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/reachability"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/reachability"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/publish.go b/internal/cli/publish.go
index 6504f0d9..ee132d23 100644
--- a/internal/cli/publish.go
+++ b/internal/cli/publish.go
@@ -11,9 +11,9 @@ import (
 	"strings"
 	"time"
 
-	catalogpkg "github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	catalogpkg "github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/publish_test.go b/internal/cli/publish_test.go
index 115330cc..72d018f2 100644
--- a/internal/cli/publish_test.go
+++ b/internal/cli/publish_test.go
@@ -6,8 +6,8 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/release_test.go b/internal/cli/release_test.go
index 3536380f..2e2b4cb4 100644
--- a/internal/cli/release_test.go
+++ b/internal/cli/release_test.go
@@ -9,7 +9,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"golang.org/x/mod/modfile"
@@ -39,7 +39,7 @@ func TestGoreleaserLdflagsTargetMatchesVersionVar(t *testing.T) {
 
 	ldflags := strings.Join(config.Builds[0].Ldflags, " ")
 	assert.Contains(t, ldflags,
-		"github.com/mvanhorn/cli-printing-press/v2/internal/version.Version",
+		"github.com/mvanhorn/cli-printing-press/v3/internal/version.Version",
 		"goreleaser ldflags must target internal/version.Version")
 }
 
diff --git a/internal/cli/root.go b/internal/cli/root.go
index 38cfbe8b..f54717c7 100644
--- a/internal/cli/root.go
+++ b/internal/cli/root.go
@@ -14,19 +14,19 @@ import (
 	"strings"
 	"time"
 
-	catalogfs "github.com/mvanhorn/cli-printing-press/v2/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/docspec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llm"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llmpolish"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	catalogfs "github.com/mvanhorn/cli-printing-press/v3/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/docspec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llm"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llmpolish"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 	"github.com/spf13/cobra"
 	"gopkg.in/yaml.v3"
 )
diff --git a/internal/cli/scorecard.go b/internal/cli/scorecard.go
index 4d0d99cd..dfb9f72c 100644
--- a/internal/cli/scorecard.go
+++ b/internal/cli/scorecard.go
@@ -8,7 +8,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/scorecard_test.go b/internal/cli/scorecard_test.go
index d685897b..c7c82267 100644
--- a/internal/cli/scorecard_test.go
+++ b/internal/cli/scorecard_test.go
@@ -5,7 +5,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/cli/tools_audit.go b/internal/cli/tools_audit.go
index 268c755b..79d31bde 100644
--- a/internal/cli/tools_audit.go
+++ b/internal/cli/tools_audit.go
@@ -13,7 +13,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/tools_audit_test.go b/internal/cli/tools_audit_test.go
index ff66ed9d..f56e7330 100644
--- a/internal/cli/tools_audit_test.go
+++ b/internal/cli/tools_audit_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 )
 
 func TestRequiresPreDecisionFields(t *testing.T) {
diff --git a/internal/cli/verify.go b/internal/cli/verify.go
index 09b27dac..f3462bef 100644
--- a/internal/cli/verify.go
+++ b/internal/cli/verify.go
@@ -6,8 +6,8 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/artifacts"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/artifacts"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/vision.go b/internal/cli/vision.go
index f0b332d2..3678ac72 100644
--- a/internal/cli/vision.go
+++ b/internal/cli/vision.go
@@ -6,8 +6,8 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/vision"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/vision"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/cli/vision_test.go b/internal/cli/vision_test.go
index 3154ced6..9b9c3d0e 100644
--- a/internal/cli/vision_test.go
+++ b/internal/cli/vision_test.go
@@ -4,7 +4,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/cli/workflow_verify.go b/internal/cli/workflow_verify.go
index 555d55cb..6d8335e7 100644
--- a/internal/cli/workflow_verify.go
+++ b/internal/cli/workflow_verify.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
 	"github.com/spf13/cobra"
 )
 
diff --git a/internal/crowdsniff/specgen.go b/internal/crowdsniff/specgen.go
index e01478d3..ed1b5bf2 100644
--- a/internal/crowdsniff/specgen.go
+++ b/internal/crowdsniff/specgen.go
@@ -5,8 +5,8 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/discovery"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/discovery"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // BuildSpec assembles a valid spec.APISpec from aggregated endpoints.
diff --git a/internal/crowdsniff/specgen_test.go b/internal/crowdsniff/specgen_test.go
index 74bed042..d0689f19 100644
--- a/internal/crowdsniff/specgen_test.go
+++ b/internal/crowdsniff/specgen_test.go
@@ -3,8 +3,8 @@ package crowdsniff
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/discovery"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/discovery"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/discovery/naming.go b/internal/discovery/naming.go
index 118f95a5..ceace609 100644
--- a/internal/discovery/naming.go
+++ b/internal/discovery/naming.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 func ResourceKey(path string) (string, string) {
diff --git a/internal/docspec/docspec.go b/internal/docspec/docspec.go
index 27402c84..6b9d79dc 100644
--- a/internal/docspec/docspec.go
+++ b/internal/docspec/docspec.go
@@ -8,8 +8,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llm"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llm"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 var (
diff --git a/internal/generator/async_detect.go b/internal/generator/async_detect.go
index 2ab11aef..c2d35f74 100644
--- a/internal/generator/async_detect.go
+++ b/internal/generator/async_detect.go
@@ -4,7 +4,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // AsyncJobInfo describes one async-job endpoint detected from a spec.
diff --git a/internal/generator/async_detect_test.go b/internal/generator/async_detect_test.go
index 0ab89f2a..c394ba4d 100644
--- a/internal/generator/async_detect_test.go
+++ b/internal/generator/async_detect_test.go
@@ -3,7 +3,7 @@ package generator
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/generator/auth_optional_test.go b/internal/generator/auth_optional_test.go
index 62555a17..ef4fdfdc 100644
--- a/internal/generator/auth_optional_test.go
+++ b/internal/generator/auth_optional_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/generator/body_collision_test.go b/internal/generator/body_collision_test.go
index 3e495850..b9a498d9 100644
--- a/internal/generator/body_collision_test.go
+++ b/internal/generator/body_collision_test.go
@@ -9,7 +9,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/entity_mapper.go b/internal/generator/entity_mapper.go
index da9adbd4..4a3e9041 100644
--- a/internal/generator/entity_mapper.go
+++ b/internal/generator/entity_mapper.go
@@ -3,8 +3,8 @@ package generator
 import (
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/profiler"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/profiler"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 type WorkflowTemplateContext struct {
diff --git a/internal/generator/enum_validation_test.go b/internal/generator/enum_validation_test.go
index c84651d5..576cfc67 100644
--- a/internal/generator/enum_validation_test.go
+++ b/internal/generator/enum_validation_test.go
@@ -5,7 +5,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/generator/first_command_example.go b/internal/generator/first_command_example.go
index f5c3b9c5..397966e2 100644
--- a/internal/generator/first_command_example.go
+++ b/internal/generator/first_command_example.go
@@ -5,8 +5,8 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/canonicalargs"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/canonicalargs"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // firstCommandExample returns a runnable "resource [endpoint] <pos1> <pos2>..."
diff --git a/internal/generator/first_command_example_test.go b/internal/generator/first_command_example_test.go
index 05527250..2b9827f3 100644
--- a/internal/generator/first_command_example_test.go
+++ b/internal/generator/first_command_example_test.go
@@ -3,7 +3,7 @@ package generator
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/generator/flag_collision.go b/internal/generator/flag_collision.go
index 5452b3ec..0d3d2603 100644
--- a/internal/generator/flag_collision.go
+++ b/internal/generator/flag_collision.go
@@ -3,7 +3,7 @@ package generator
 import (
 	"fmt"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // dedupeFlagIdentifiers ensures that no two non-positional params or body
diff --git a/internal/generator/flag_collision_test.go b/internal/generator/flag_collision_test.go
index 6f857894..e8275773 100644
--- a/internal/generator/flag_collision_test.go
+++ b/internal/generator/flag_collision_test.go
@@ -9,7 +9,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/freshness_paths_test.go b/internal/generator/freshness_paths_test.go
index bbaa07e9..f17b5c65 100644
--- a/internal/generator/freshness_paths_test.go
+++ b/internal/generator/freshness_paths_test.go
@@ -4,8 +4,8 @@ import (
 	"sort"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/profiler"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/profiler"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/generator/generator.go b/internal/generator/generator.go
index 6fd86588..4f273083 100644
--- a/internal/generator/generator.go
+++ b/internal/generator/generator.go
@@ -17,11 +17,11 @@ import (
 	"time"
 	"unicode"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/mcpdesc"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/profiler"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/mcpdesc"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/profiler"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 )
diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go
index e83647d5..1e0a9749 100644
--- a/internal/generator/generator_test.go
+++ b/internal/generator/generator_test.go
@@ -13,11 +13,11 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/browsersniff"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/browsersniff"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/json_string_validation_test.go b/internal/generator/json_string_validation_test.go
index 8c436ab0..50206210 100644
--- a/internal/generator/json_string_validation_test.go
+++ b/internal/generator/json_string_validation_test.go
@@ -6,7 +6,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/generator/limit_truncation_test.go b/internal/generator/limit_truncation_test.go
index 2da0f282..4b1ea04d 100644
--- a/internal/generator/limit_truncation_test.go
+++ b/internal/generator/limit_truncation_test.go
@@ -3,7 +3,7 @@ package generator
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/generator/plan_generate.go b/internal/generator/plan_generate.go
index 874e440e..67fdb2ee 100644
--- a/internal/generator/plan_generate.go
+++ b/internal/generator/plan_generate.go
@@ -11,7 +11,7 @@ import (
 	"text/template"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 )
diff --git a/internal/generator/plan_generate_test.go b/internal/generator/plan_generate_test.go
index 74017066..4403871a 100644
--- a/internal/generator/plan_generate_test.go
+++ b/internal/generator/plan_generate_test.go
@@ -7,7 +7,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/promoted_presence_check_test.go b/internal/generator/promoted_presence_check_test.go
index 6c5bbdf3..5fe880ff 100644
--- a/internal/generator/promoted_presence_check_test.go
+++ b/internal/generator/promoted_presence_check_test.go
@@ -5,7 +5,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/generator/readme_test.go b/internal/generator/readme_test.go
index ca2fa3f2..8c638283 100644
--- a/internal/generator/readme_test.go
+++ b/internal/generator/readme_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/schema_builder.go b/internal/generator/schema_builder.go
index f0098885..b845b471 100644
--- a/internal/generator/schema_builder.go
+++ b/internal/generator/schema_builder.go
@@ -4,7 +4,7 @@ import (
 	"strings"
 	"unicode"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 type TableDef struct {
diff --git a/internal/generator/schema_builder_test.go b/internal/generator/schema_builder_test.go
index 82f43114..5011dc27 100644
--- a/internal/generator/schema_builder_test.go
+++ b/internal/generator/schema_builder_test.go
@@ -3,7 +3,7 @@ package generator
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/generator/session_handshake_test.go b/internal/generator/session_handshake_test.go
index a4ffe8a5..373cfa97 100644
--- a/internal/generator/session_handshake_test.go
+++ b/internal/generator/session_handshake_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // TestSessionHandshakeGeneration verifies the generator emits a working
diff --git a/internal/generator/skill_promoted_paths_test.go b/internal/generator/skill_promoted_paths_test.go
index 1f9621d1..e4dabad1 100644
--- a/internal/generator/skill_promoted_paths_test.go
+++ b/internal/generator/skill_promoted_paths_test.go
@@ -8,7 +8,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/generator/skill_test.go b/internal/generator/skill_test.go
index 6dae0d17..049842a0 100644
--- a/internal/generator/skill_test.go
+++ b/internal/generator/skill_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"gopkg.in/yaml.v3"
diff --git a/internal/generator/types_keyword_test.go b/internal/generator/types_keyword_test.go
index ca307ec8..1a3cedd6 100644
--- a/internal/generator/types_keyword_test.go
+++ b/internal/generator/types_keyword_test.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/generator/validate.go b/internal/generator/validate.go
index 2e1ccb44..bf716fec 100644
--- a/internal/generator/validate.go
+++ b/internal/generator/validate.go
@@ -10,8 +10,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/artifacts"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/artifacts"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 type validationGate struct {
diff --git a/internal/generator/vision_templates.go b/internal/generator/vision_templates.go
index 1997479d..db3d50e4 100644
--- a/internal/generator/vision_templates.go
+++ b/internal/generator/vision_templates.go
@@ -1,7 +1,7 @@
 package generator
 
 import (
-	"github.com/mvanhorn/cli-printing-press/v2/internal/vision"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/vision"
 )
 
 // VisionTemplateSet defines which visionary templates to include in generation.
diff --git a/internal/graphql/parser.go b/internal/graphql/parser.go
index d33390cb..6d894395 100644
--- a/internal/graphql/parser.go
+++ b/internal/graphql/parser.go
@@ -9,8 +9,8 @@ import (
 	"strings"
 	"unicode"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 )
diff --git a/internal/graphql/parser_test.go b/internal/graphql/parser_test.go
index 12329392..dd2e1df2 100644
--- a/internal/graphql/parser_test.go
+++ b/internal/graphql/parser_test.go
@@ -3,7 +3,7 @@ package graphql
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/llmpolish/polish.go b/internal/llmpolish/polish.go
index 633115e8..6fc7599a 100644
--- a/internal/llmpolish/polish.go
+++ b/internal/llmpolish/polish.go
@@ -6,7 +6,7 @@ import (
 	"os"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llm"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llm"
 )
 
 // PolishRequest defines what the polish pass needs.
diff --git a/internal/llmpolish/vision.go b/internal/llmpolish/vision.go
index fc34557b..670eaa11 100644
--- a/internal/llmpolish/vision.go
+++ b/internal/llmpolish/vision.go
@@ -6,9 +6,9 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llm"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/profiler"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llm"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/profiler"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // VisionCustomization holds LLM-generated customizations for vision templates.
diff --git a/internal/llmpolish/vision_test.go b/internal/llmpolish/vision_test.go
index b26f845e..078e9b06 100644
--- a/internal/llmpolish/vision_test.go
+++ b/internal/llmpolish/vision_test.go
@@ -5,8 +5,8 @@ import (
 	"os"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/profiler"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/profiler"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/mcpdesc/compose.go b/internal/mcpdesc/compose.go
index e2e3251f..df606f12 100644
--- a/internal/mcpdesc/compose.go
+++ b/internal/mcpdesc/compose.go
@@ -17,8 +17,8 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // optionalListMax caps how many optional params Compose lists inline
diff --git a/internal/mcpdesc/compose_test.go b/internal/mcpdesc/compose_test.go
index a0d97a3b..c1899c0c 100644
--- a/internal/mcpdesc/compose_test.go
+++ b/internal/mcpdesc/compose_test.go
@@ -4,7 +4,7 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/mcpoverrides/overrides.go b/internal/mcpoverrides/overrides.go
index 0f543416..38f1b129 100644
--- a/internal/mcpoverrides/overrides.go
+++ b/internal/mcpoverrides/overrides.go
@@ -18,8 +18,8 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // Filename is the per-CLI override file name. Lives at the cli-dir
diff --git a/internal/mcpoverrides/overrides_test.go b/internal/mcpoverrides/overrides_test.go
index b4dd5f0d..a32082c6 100644
--- a/internal/mcpoverrides/overrides_test.go
+++ b/internal/mcpoverrides/overrides_test.go
@@ -6,7 +6,7 @@ import (
 	"sort"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 func TestLoad_FileAbsentReturnsEmpty(t *testing.T) {
diff --git a/internal/openapi/detect.go b/internal/openapi/detect.go
index be9ae13f..ecfb3dcd 100644
--- a/internal/openapi/detect.go
+++ b/internal/openapi/detect.go
@@ -3,7 +3,7 @@ package openapi
 import (
 	"bytes"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
 )
 
 func IsOpenAPI(data []byte) bool {
diff --git a/internal/openapi/parser.go b/internal/openapi/parser.go
index cf0ee5fb..2beadd4e 100644
--- a/internal/openapi/parser.go
+++ b/internal/openapi/parser.go
@@ -13,8 +13,8 @@ import (
 	"unicode"
 
 	"github.com/getkin/kin-openapi/openapi3"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 )
diff --git a/internal/openapi/parser_test.go b/internal/openapi/parser_test.go
index c4620edf..c22ecea5 100644
--- a/internal/openapi/parser_test.go
+++ b/internal/openapi/parser_test.go
@@ -10,9 +10,9 @@ import (
 	"testing"
 
 	"github.com/getkin/kin-openapi/openapi3"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/patch/dropins.go b/internal/patch/dropins.go
index c2105d4f..74692304 100644
--- a/internal/patch/dropins.go
+++ b/internal/patch/dropins.go
@@ -10,7 +10,7 @@ import (
 	"text/template"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
 )
 
 // dropin describes one file the patcher creates from a template.
diff --git a/internal/pipeline/climanifest.go b/internal/pipeline/climanifest.go
index 7682439a..dcd96322 100644
--- a/internal/pipeline/climanifest.go
+++ b/internal/pipeline/climanifest.go
@@ -11,12 +11,12 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/catalog"
-	catalogpkg "github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/catalog"
+	catalogpkg "github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 )
 
 // CLIManifestFilename is the name of the manifest file written to each
diff --git a/internal/pipeline/climanifest_test.go b/internal/pipeline/climanifest_test.go
index 79ea17a5..b305ae83 100644
--- a/internal/pipeline/climanifest_test.go
+++ b/internal/pipeline/climanifest_test.go
@@ -9,8 +9,8 @@ import (
 	"testing"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/contracts_test.go b/internal/pipeline/contracts_test.go
index acd7f02e..478732c1 100644
--- a/internal/pipeline/contracts_test.go
+++ b/internal/pipeline/contracts_test.go
@@ -7,10 +7,10 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/dogfood.go b/internal/pipeline/dogfood.go
index 66d4fe7f..09e67ff1 100644
--- a/internal/pipeline/dogfood.go
+++ b/internal/pipeline/dogfood.go
@@ -14,9 +14,9 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	openapiparser "github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	apispec "github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	openapiparser "github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	apispec "github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"gopkg.in/yaml.v3"
 )
 
diff --git a/internal/pipeline/fullrun.go b/internal/pipeline/fullrun.go
index 252c8a58..e9427b3f 100644
--- a/internal/pipeline/fullrun.go
+++ b/internal/pipeline/fullrun.go
@@ -11,8 +11,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llmpolish"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llmpolish"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 	"gopkg.in/yaml.v3"
 )
 
diff --git a/internal/pipeline/fullrun_test.go b/internal/pipeline/fullrun_test.go
index 47ef27ee..c1ae6a47 100644
--- a/internal/pipeline/fullrun_test.go
+++ b/internal/pipeline/fullrun_test.go
@@ -9,7 +9,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llmpolish"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llmpolish"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/lock.go b/internal/pipeline/lock.go
index f45f9083..9c59cf29 100644
--- a/internal/pipeline/lock.go
+++ b/internal/pipeline/lock.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 const (
diff --git a/internal/pipeline/mcpb_manifest.go b/internal/pipeline/mcpb_manifest.go
index 5a511841..bf28c412 100644
--- a/internal/pipeline/mcpb_manifest.go
+++ b/internal/pipeline/mcpb_manifest.go
@@ -8,7 +8,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 )
 
 // MCPB-bundle constants. Promoted from string literals so a typo here can't
diff --git a/internal/pipeline/mcpsync/sync.go b/internal/pipeline/mcpsync/sync.go
index 056a1c8f..140967bb 100644
--- a/internal/pipeline/mcpsync/sync.go
+++ b/internal/pipeline/mcpsync/sync.go
@@ -10,12 +10,12 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/mcpoverrides"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/mcpoverrides"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/semver"
 )
diff --git a/internal/pipeline/mcpsync/sync_test.go b/internal/pipeline/mcpsync/sync_test.go
index fe68a85b..9c245a52 100644
--- a/internal/pipeline/mcpsync/sync_test.go
+++ b/internal/pipeline/mcpsync/sync_test.go
@@ -7,9 +7,9 @@ import (
 	"regexp"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/generator"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/pipeline"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/generator"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/pipeline"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"gopkg.in/yaml.v3"
diff --git a/internal/pipeline/merge.go b/internal/pipeline/merge.go
index b7e1cb5d..fc83ae16 100644
--- a/internal/pipeline/merge.go
+++ b/internal/pipeline/merge.go
@@ -1,7 +1,7 @@
 package pipeline
 
 import (
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // MergeOverlay applies an overlay onto an APISpec, modifying it in place.
diff --git a/internal/pipeline/merge_test.go b/internal/pipeline/merge_test.go
index 4cb0d4e6..368a1c33 100644
--- a/internal/pipeline/merge_test.go
+++ b/internal/pipeline/merge_test.go
@@ -3,7 +3,7 @@ package pipeline
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/internal/pipeline/paths.go b/internal/pipeline/paths.go
index 29dd6f24..12c5895b 100644
--- a/internal/pipeline/paths.go
+++ b/internal/pipeline/paths.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 func PressHome() string {
diff --git a/internal/pipeline/publish.go b/internal/pipeline/publish.go
index 01cf7a1f..0c2c2168 100644
--- a/internal/pipeline/publish.go
+++ b/internal/pipeline/publish.go
@@ -11,13 +11,13 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/catalog"
-	catalogpkg "github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/graphql"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/openapi"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/catalog"
+	catalogpkg "github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/graphql"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/openapi"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 )
 
 type RunManifest struct {
diff --git a/internal/pipeline/renamecli.go b/internal/pipeline/renamecli.go
index a51ce56c..c6ac1028 100644
--- a/internal/pipeline/renamecli.go
+++ b/internal/pipeline/renamecli.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 // renameExtensions lists file extensions walked during CLI rename.
diff --git a/internal/pipeline/renamecli_test.go b/internal/pipeline/renamecli_test.go
index dca74cee..5a78545f 100644
--- a/internal/pipeline/renamecli_test.go
+++ b/internal/pipeline/renamecli_test.go
@@ -6,7 +6,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/research.go b/internal/pipeline/research.go
index 08cece86..93741ac7 100644
--- a/internal/pipeline/research.go
+++ b/internal/pipeline/research.go
@@ -14,9 +14,9 @@ import (
 	"strings"
 	"time"
 
-	catalogfs "github.com/mvanhorn/cli-printing-press/v2/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/catalog"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/llm"
+	catalogfs "github.com/mvanhorn/cli-printing-press/v3/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/catalog"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/llm"
 )
 
 // ResearchResult holds the output of the research phase.
diff --git a/internal/pipeline/runtime.go b/internal/pipeline/runtime.go
index 887385a1..78f26361 100644
--- a/internal/pipeline/runtime.go
+++ b/internal/pipeline/runtime.go
@@ -12,9 +12,9 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/artifacts"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	apispec "github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/artifacts"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	apispec "github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // VerifyConfig configures a runtime verification run.
diff --git a/internal/pipeline/runtime_commands.go b/internal/pipeline/runtime_commands.go
index 2393ca4e..517dc6f9 100644
--- a/internal/pipeline/runtime_commands.go
+++ b/internal/pipeline/runtime_commands.go
@@ -10,7 +10,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/canonicalargs"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/canonicalargs"
 )
 
 func discoverCommands(dir string, binaryPath string) []discoveredCommand {
diff --git a/internal/pipeline/runtime_exec.go b/internal/pipeline/runtime_exec.go
index a3cbd9db..14b33706 100644
--- a/internal/pipeline/runtime_exec.go
+++ b/internal/pipeline/runtime_exec.go
@@ -9,7 +9,7 @@ import (
 	"sort"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 func buildCLI(dir string) (string, error) {
diff --git a/internal/pipeline/runtime_structural.go b/internal/pipeline/runtime_structural.go
index a8ae49bc..5cc77fda 100644
--- a/internal/pipeline/runtime_structural.go
+++ b/internal/pipeline/runtime_structural.go
@@ -5,7 +5,7 @@ import (
 	"os"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/artifacts"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/artifacts"
 )
 
 // runStructuralVerify runs spec-independent verification: build, --help,
diff --git a/internal/pipeline/runtime_test.go b/internal/pipeline/runtime_test.go
index 98602df4..5561f274 100644
--- a/internal/pipeline/runtime_test.go
+++ b/internal/pipeline/runtime_test.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	apispec "github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	apispec "github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/scorecard.go b/internal/pipeline/scorecard.go
index c4ac428d..2d623659 100644
--- a/internal/pipeline/scorecard.go
+++ b/internal/pipeline/scorecard.go
@@ -10,7 +10,7 @@ import (
 	"strconv"
 	"strings"
 
-	apispec "github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	apispec "github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // infraCoreFiles are CLI infrastructure files excluded from workflow/insight scoring.
diff --git a/internal/pipeline/spec_detect.go b/internal/pipeline/spec_detect.go
index 821eaa23..9ca4c0df 100644
--- a/internal/pipeline/spec_detect.go
+++ b/internal/pipeline/spec_detect.go
@@ -7,7 +7,7 @@ import (
 	"slices"
 	"strings"
 
-	apispec "github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	apispec "github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // isInternalYAMLSpec returns true if data looks like an internal YAML spec
diff --git a/internal/pipeline/state.go b/internal/pipeline/state.go
index 65e7f4e3..3beb6381 100644
--- a/internal/pipeline/state.go
+++ b/internal/pipeline/state.go
@@ -8,7 +8,7 @@ import (
 	"path/filepath"
 	"time"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 )
 
 // Phase names in execution order.
diff --git a/internal/pipeline/toolsmanifest.go b/internal/pipeline/toolsmanifest.go
index 97f039ee..73636a63 100644
--- a/internal/pipeline/toolsmanifest.go
+++ b/internal/pipeline/toolsmanifest.go
@@ -10,10 +10,10 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/mcpdesc"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/mcpoverrides"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/mcpdesc"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/mcpoverrides"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 )
 
 // ToolsManifestFilename is the name of the tools manifest file written to each
diff --git a/internal/pipeline/toolsmanifest_test.go b/internal/pipeline/toolsmanifest_test.go
index 5cf7f15b..88499b30 100644
--- a/internal/pipeline/toolsmanifest_test.go
+++ b/internal/pipeline/toolsmanifest_test.go
@@ -6,7 +6,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/pipeline/verify.go b/internal/pipeline/verify.go
index 01629421..7ac7a00c 100644
--- a/internal/pipeline/verify.go
+++ b/internal/pipeline/verify.go
@@ -11,7 +11,7 @@ import (
 	"time"
 	"unicode"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/artifacts"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/artifacts"
 )
 
 type Verifier struct {
diff --git a/internal/profiler/profiler.go b/internal/profiler/profiler.go
index 917a9d35..644a146e 100644
--- a/internal/profiler/profiler.go
+++ b/internal/profiler/profiler.go
@@ -5,8 +5,8 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/vision"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/vision"
 )
 
 type DomainArchetype string
diff --git a/internal/profiler/profiler_test.go b/internal/profiler/profiler_test.go
index c58ae004..b93e23c1 100644
--- a/internal/profiler/profiler_test.go
+++ b/internal/profiler/profiler_test.go
@@ -3,7 +3,7 @@ package profiler
 import (
 	"testing"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/spec"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/spec"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/internal/reachability/probe.go b/internal/reachability/probe.go
index 460bb62b..96984922 100644
--- a/internal/reachability/probe.go
+++ b/internal/reachability/probe.go
@@ -10,7 +10,7 @@ import (
 	"time"
 
 	"github.com/enetx/surf"
-	"github.com/mvanhorn/cli-printing-press/v2/internal/version"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/version"
 )
 
 const (
diff --git a/internal/spec/spec.go b/internal/spec/spec.go
index a8cce6b2..719cb57d 100644
--- a/internal/spec/spec.go
+++ b/internal/spec/spec.go
@@ -7,7 +7,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/mvanhorn/cli-printing-press/v2/internal/naming"
+	"github.com/mvanhorn/cli-printing-press/v3/internal/naming"
 	"gopkg.in/yaml.v3"
 )
 
diff --git a/internal/version/version.go b/internal/version/version.go
index 40953601..6fed5fe7 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -35,6 +35,12 @@ func versionFromBuildInfo(v string) string {
 	if v == "" || v == "(devel)" {
 		return ""
 	}
+	// Strip semver build metadata (e.g. `+dirty` from a build off an
+	// uncommitted working tree) before classification so the pseudo-version
+	// match isn't defeated by the trailing suffix.
+	if i := strings.IndexByte(v, '+'); i >= 0 {
+		v = v[:i]
+	}
 	if pseudoVersionSuffix.MatchString(v) {
 		return ""
 	}
diff --git a/internal/version/version_test.go b/internal/version/version_test.go
index be1a0b36..6116a504 100644
--- a/internal/version/version_test.go
+++ b/internal/version/version_test.go
@@ -33,6 +33,13 @@ func TestVersionFromBuildInfo(t *testing.T) {
 		{"pseudo after release", "v1.3.3-0.20260426011609-42b0f1f4a92a", ""},
 		{"pseudo after prerelease", "v2.4.0-pre.0.20260426011609-42b0f1f4a92a", ""},
 		{"pseudo without v prefix", "1.3.3-0.20260426011609-42b0f1f4a92a", ""},
+		// Builds off a dirty working tree get a `+dirty` semver build-metadata
+		// suffix. Any `+<meta>` suffix should be stripped before classification
+		// so it does not defeat the pseudo-version match.
+		{"pseudo dirty after release", "v2.4.1-0.20260430120000-abcdef123456+dirty", ""},
+		{"pseudo dirty no prior tag", "v0.0.0-20260328120000-abcdef123456+dirty", ""},
+		{"pseudo dirty without v prefix", "1.3.3-0.20260426011609-42b0f1f4a92a+dirty", ""},
+		{"tagged release dirty", "v3.0.0+dirty", "3.0.0"},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/skills/printing-press-catalog/SKILL.md b/skills/printing-press-catalog/SKILL.md
index 7c8b0676..64513077 100644
--- a/skills/printing-press-catalog/SKILL.md
+++ b/skills/printing-press-catalog/SKILL.md
@@ -31,7 +31,7 @@ Browse and install pre-built Go CLIs for popular APIs.
 ## Prerequisites
 
 - Go 1.21+ installed
-- `printing-press` binary on PATH (install with `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest`)
+- `printing-press` binary on PATH (install with `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest`)
 
 ## Setup
 
@@ -55,7 +55,7 @@ elif ! command -v printing-press >/dev/null 2>&1; then
     echo "Add GOPATH/bin to your PATH:  export PATH=\"\$HOME/go/bin:\$PATH\""
   else
     echo "printing-press binary not found."
-    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest"
+    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest"
   fi
   return 1 2>/dev/null || exit 1
 fi
@@ -74,7 +74,7 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY"
 ```
 <!-- PRESS_SETUP_CONTRACT_END -->
 
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
+After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
 
 Generated CLIs are published to `$PRESS_LIBRARY/`, not to the repo.
 
diff --git a/skills/printing-press-publish/SKILL.md b/skills/printing-press-publish/SKILL.md
index 6cc351e7..88e75682 100644
--- a/skills/printing-press-publish/SKILL.md
+++ b/skills/printing-press-publish/SKILL.md
@@ -45,7 +45,7 @@ elif ! command -v printing-press >/dev/null 2>&1; then
     echo "Add GOPATH/bin to your PATH:  export PATH=\"\$HOME/go/bin:\$PATH\""
   else
     echo "printing-press binary not found."
-    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest"
+    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest"
   fi
   return 1 2>/dev/null || exit 1
 fi
@@ -66,7 +66,7 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT
 ```
 <!-- PRESS_SETUP_CONTRACT_END -->
 
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
+After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
 
 ## Configuration
 
diff --git a/skills/printing-press-score/SKILL.md b/skills/printing-press-score/SKILL.md
index 7909af49..c5eeda5d 100644
--- a/skills/printing-press-score/SKILL.md
+++ b/skills/printing-press-score/SKILL.md
@@ -27,7 +27,7 @@ Score generated CLIs against the Steinberger bar. Supports rescoring, scoring by
 ## Prerequisites
 
 - Go 1.21+ installed
-- `printing-press` binary on PATH (install with `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest`)
+- `printing-press` binary on PATH (install with `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest`)
 
 ## Step 0: Setup
 
@@ -51,7 +51,7 @@ elif ! command -v printing-press >/dev/null 2>&1; then
     echo "Add GOPATH/bin to your PATH:  export PATH=\"\$HOME/go/bin:\$PATH\""
   else
     echo "printing-press binary not found."
-    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest"
+    echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest"
   fi
   return 1 2>/dev/null || exit 1
 fi
@@ -72,7 +72,7 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT
 ```
 <!-- PRESS_SETUP_CONTRACT_END -->
 
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
+After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
 
 Current-run state is resolved from `$PRESS_RUNSTATE`. Published CLIs are resolved from `$PRESS_LIBRARY`. Archived manuscripts are resolved from `$PRESS_MANUSCRIPTS`.
 
@@ -271,7 +271,7 @@ Domain Correctness (Tier 2)
 
 ## Error Handling
 
-- If the printing-press binary is not on PATH → show install instructions: `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest`
+- If the printing-press binary is not on PATH → show install instructions: `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest`
 - If the scorecard command fails → report the error with the full stderr output
 - If a CLI directory doesn't exist → report which name couldn't be resolved
 - If JSON parsing fails → show the raw output and report the parsing error
diff --git a/skills/printing-press/SKILL.md b/skills/printing-press/SKILL.md
index 18839540..e85ffd7b 100644
--- a/skills/printing-press/SKILL.md
+++ b/skills/printing-press/SKILL.md
@@ -253,11 +253,11 @@ elif ! command -v printing-press >/dev/null 2>&1; then
     echo "Added ~/go/bin to PATH"
   elif command -v go >/dev/null 2>&1; then
     echo "printing-press not found. Installing..."
-    GOPRIVATE=github.com/mvanhorn/* go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest
+    GOPRIVATE=github.com/mvanhorn/* go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest
     export PATH="$HOME/go/bin:$PATH"
   else
     echo "printing-press binary not found and Go is not installed."
-    echo "Install Go first, then run:  go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest"
+    echo "Install Go first, then run:  go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest"
     return 1 2>/dev/null || exit 1
   fi
 fi
@@ -309,7 +309,7 @@ CODEX_CONSECUTIVE_FAILURES=0
 ```
 <!-- PRESS_SETUP_CONTRACT_END -->
 
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v2/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
+After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, warn the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v3/cmd/printing-press@latest` to update." Continue anyway but surface the warning prominently.
 
 After you know `<api>`, initialize the run-scoped artifact paths:
 

← 10fd0405 chore(main): release 3.0.0 (#356)  ·  back to Cli Printing Press  ·  fix(skills): drop context: fork from output-review so AskUse ac98c00a →