From 70aad53d3a288c229272feb45ab3f70e389e285c Mon Sep 17 00:00:00 2001 From: Jonathan Turnock <16135506+JonathanTurnock@users.noreply.github.com> Date: Wed, 10 Jun 2026 14:57:14 +0100 Subject: [PATCH 1/2] =?UTF-8?q?fix(ci):=20release-plz=20reads=20releases?= =?UTF-8?q?=20from=20git=20tags=20=E2=80=94=20git=5Fonly=20+=20dep=20versi?= =?UTF-8?q?on=20reqs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without git_only, release-plz consults the cargo registry; pds is never published, so every version looked perpetually unreleased and release-pr proposed the current version forever instead of bumping (hence the manual bump PRs #29/#31/#33/#47/#60). git_only resolves the last release from the v* tags. The internal path deps gain version requirements because git_only mode runs cargo package, which rejects versionless path deps; resolution is unchanged (path wins inside the workspace) and release-plz bumps the requirements on release. Co-Authored-By: Claude Fable 5 --- crates/pseudoscript-doc/Cargo.toml | 6 ++-- crates/pseudoscript-emit/Cargo.toml | 8 ++--- crates/pseudoscript-format/Cargo.toml | 2 +- crates/pseudoscript-ide/Cargo.toml | 14 ++++----- crates/pseudoscript-lsp-core/Cargo.toml | 6 ++-- crates/pseudoscript-lsp/Cargo.toml | 12 ++++---- crates/pseudoscript-model/Cargo.toml | 2 +- crates/pseudoscript-project/Cargo.toml | 2 +- crates/pseudoscript-universe/Cargo.toml | 2 +- crates/pseudoscript/Cargo.toml | 14 ++++----- crates/pseudoscript/build.rs | 39 ++++++++++++++++++++----- crates/pseudoscript/src/main.rs | 10 +++---- release-plz.toml | 5 ++++ 13 files changed, 74 insertions(+), 48 deletions(-) diff --git a/crates/pseudoscript-doc/Cargo.toml b/crates/pseudoscript-doc/Cargo.toml index 656e8988..846074fb 100644 --- a/crates/pseudoscript-doc/Cargo.toml +++ b/crates/pseudoscript-doc/Cargo.toml @@ -11,9 +11,9 @@ name = "pseudoscript_doc" path = "src/lib.rs" [dependencies] -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-emit = { path = "../pseudoscript-emit" } -pseudoscript-layout = { path = "../pseudoscript-layout" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-emit = { path = "../pseudoscript-emit", version = "0.1.5" } +pseudoscript-layout = { path = "../pseudoscript-layout", version = "0.1.5" } serde = { version = "1", features = ["derive"] } serde_json = "1" # Renders `[[doc.sidebar]]` markdown pages to HTML. Pure Rust (no C), so it diff --git a/crates/pseudoscript-emit/Cargo.toml b/crates/pseudoscript-emit/Cargo.toml index bfc8ff13..d378ddd6 100644 --- a/crates/pseudoscript-emit/Cargo.toml +++ b/crates/pseudoscript-emit/Cargo.toml @@ -13,10 +13,10 @@ path = "src/lib.rs" [dependencies] # Logging facade (target-agnostic); the subscriber is chosen at the wasm/stdio edge. tracing = "0.1" -pseudoscript-syntax = { path = "../pseudoscript-syntax" } -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-layout = { path = "../pseudoscript-layout" } -pseudoscript-dot = { path = "../pseudoscript-dot" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-layout = { path = "../pseudoscript-layout", version = "0.1.5" } +pseudoscript-dot = { path = "../pseudoscript-dot", version = "0.1.5" } serde = { version = "1", features = ["derive"] } [dev-dependencies] diff --git a/crates/pseudoscript-format/Cargo.toml b/crates/pseudoscript-format/Cargo.toml index 92a105b6..4caf5265 100644 --- a/crates/pseudoscript-format/Cargo.toml +++ b/crates/pseudoscript-format/Cargo.toml @@ -11,7 +11,7 @@ name = "pseudoscript_format" path = "src/lib.rs" [dependencies] -pseudoscript-syntax = { path = "../pseudoscript-syntax" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } [dev-dependencies] cucumber = "0.21" diff --git a/crates/pseudoscript-ide/Cargo.toml b/crates/pseudoscript-ide/Cargo.toml index 9ed2bcf5..bed5e3f0 100644 --- a/crates/pseudoscript-ide/Cargo.toml +++ b/crates/pseudoscript-ide/Cargo.toml @@ -15,15 +15,15 @@ crate-type = ["cdylib", "rlib"] path = "src/lib.rs" [dependencies] -pseudoscript-syntax = { path = "../pseudoscript-syntax" } -pseudoscript-format = { path = "../pseudoscript-format" } -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core" } -pseudoscript-emit = { path = "../pseudoscript-emit" } -pseudoscript-doc = { path = "../pseudoscript-doc" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } +pseudoscript-format = { path = "../pseudoscript-format", version = "0.1.5" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core", version = "0.1.5" } +pseudoscript-emit = { path = "../pseudoscript-emit", version = "0.1.5" } +pseudoscript-doc = { path = "../pseudoscript-doc", version = "0.1.5" } # The 3D "software universe" layout — pure, wasm-safe, permissive. Builds the whole # universe (positions + planet personalities) the in-app WebGL view renders. -pseudoscript-universe = { path = "../pseudoscript-universe" } +pseudoscript-universe = { path = "../pseudoscript-universe", version = "0.1.5" } serde = { version = "1", features = ["derive"] } serde_json = "1" # Parses a `pds.toml` string into the doc manifest for the host (`doc_manifest`). diff --git a/crates/pseudoscript-lsp-core/Cargo.toml b/crates/pseudoscript-lsp-core/Cargo.toml index c8cc2054..24a059fe 100644 --- a/crates/pseudoscript-lsp-core/Cargo.toml +++ b/crates/pseudoscript-lsp-core/Cargo.toml @@ -18,7 +18,7 @@ path = "src/lib.rs" [dependencies] # Logging facade (target-agnostic); the subscriber is chosen at the wasm/stdio edge. tracing = "0.1" -pseudoscript-syntax = { path = "../pseudoscript-syntax" } -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-format = { path = "../pseudoscript-format" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-format = { path = "../pseudoscript-format", version = "0.1.5" } lsp-types = "=0.94.1" diff --git a/crates/pseudoscript-lsp/Cargo.toml b/crates/pseudoscript-lsp/Cargo.toml index 0cc70124..eb47b99e 100644 --- a/crates/pseudoscript-lsp/Cargo.toml +++ b/crates/pseudoscript-lsp/Cargo.toml @@ -11,18 +11,18 @@ name = "pseudoscript_lsp" path = "src/lib.rs" [dependencies] -pseudoscript-syntax = { path = "../pseudoscript-syntax" } -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core" } -pseudoscript-format = { path = "../pseudoscript-format" } -pseudoscript-project = { path = "../pseudoscript-project" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core", version = "0.1.5" } +pseudoscript-format = { path = "../pseudoscript-format", version = "0.1.5" } +pseudoscript-project = { path = "../pseudoscript-project", version = "0.1.5" } tower-lsp = "0.20" tokio = { version = "1", features = ["full"] } serde_json = "1" walkdir = "2" [dev-dependencies] -pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core" } +pseudoscript-lsp-core = { path = "../pseudoscript-lsp-core", version = "0.1.5" } cucumber = "0.21" futures = "0.3" tempfile = "3" diff --git a/crates/pseudoscript-model/Cargo.toml b/crates/pseudoscript-model/Cargo.toml index 4a0d9787..05971805 100644 --- a/crates/pseudoscript-model/Cargo.toml +++ b/crates/pseudoscript-model/Cargo.toml @@ -13,7 +13,7 @@ path = "src/lib.rs" [dependencies] # Logging facade (target-agnostic); the subscriber is chosen at the wasm/stdio edge. tracing = "0.1" -pseudoscript-syntax = { path = "../pseudoscript-syntax" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } anyhow = "1" rustc-hash = "2" serde = { version = "1", features = ["derive"] } diff --git a/crates/pseudoscript-project/Cargo.toml b/crates/pseudoscript-project/Cargo.toml index d016ba96..92160622 100644 --- a/crates/pseudoscript-project/Cargo.toml +++ b/crates/pseudoscript-project/Cargo.toml @@ -15,7 +15,7 @@ path = "src/lib.rs" # modules off disk — delegating the slug/lock/prefix logic to the WASM-safe # `pseudoscript-model::deps`. Depended on by the `pds` binary and the stdio LSP. [dependencies] -pseudoscript-model = { path = "../pseudoscript-model" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } anyhow = "1" walkdir = "2" diff --git a/crates/pseudoscript-universe/Cargo.toml b/crates/pseudoscript-universe/Cargo.toml index ead694a7..e05e3854 100644 --- a/crates/pseudoscript-universe/Cargo.toml +++ b/crates/pseudoscript-universe/Cargo.toml @@ -15,7 +15,7 @@ path = "src/lib.rs" [dependencies] # The resolved C4 model — the same source of truth the 2D view consumes. WASM-safe. -pseudoscript-model = { path = "../pseudoscript-model" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } # The containment tree + relationship graph. MIT/Apache, WASM-safe. petgraph = "0.6" # Serialises the graph snapshot the renderer consumes. diff --git a/crates/pseudoscript/Cargo.toml b/crates/pseudoscript/Cargo.toml index 28d7051d..6cea5d15 100644 --- a/crates/pseudoscript/Cargo.toml +++ b/crates/pseudoscript/Cargo.toml @@ -11,13 +11,13 @@ name = "pds" path = "src/main.rs" [dependencies] -pseudoscript-syntax = { path = "../pseudoscript-syntax" } -pseudoscript-model = { path = "../pseudoscript-model" } -pseudoscript-format = { path = "../pseudoscript-format" } -pseudoscript-emit = { path = "../pseudoscript-emit" } -pseudoscript-lsp = { path = "../pseudoscript-lsp" } -pseudoscript-doc = { path = "../pseudoscript-doc" } -pseudoscript-project = { path = "../pseudoscript-project" } +pseudoscript-syntax = { path = "../pseudoscript-syntax", version = "0.1.5" } +pseudoscript-model = { path = "../pseudoscript-model", version = "0.1.5" } +pseudoscript-format = { path = "../pseudoscript-format", version = "0.1.5" } +pseudoscript-emit = { path = "../pseudoscript-emit", version = "0.1.5" } +pseudoscript-lsp = { path = "../pseudoscript-lsp", version = "0.1.5" } +pseudoscript-doc = { path = "../pseudoscript-doc", version = "0.1.5" } +pseudoscript-project = { path = "../pseudoscript-project", version = "0.1.5" } clap = { version = "4", features = ["derive"] } tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-std"] } anyhow = "1" diff --git a/crates/pseudoscript/build.rs b/crates/pseudoscript/build.rs index fb32395c..141f8785 100644 --- a/crates/pseudoscript/build.rs +++ b/crates/pseudoscript/build.rs @@ -1,10 +1,12 @@ -//! Assembles the `pds lang` reference bundle at build time. +//! Stages the repo-level sources `main.rs` embeds: the `pds lang` reference +//! bundle and the `pds skill` authoring skill. //! -//! Concatenates the spec (`LANG.md`), the patterns guide (`PATTERNS.md`), and -//! every file in the `CONFORMANCE/` grammar suite into one blob under -//! `$OUT_DIR/lang-bundle.md`, which `main.rs` embeds via `include_str!`. Each -//! file is fenced with a `===== =====` header so the -//! single stream stays unambiguously splittable. +//! The bundle concatenates the spec (`LANG.md`), the patterns guide +//! (`PATTERNS.md`), and every file in the `CONFORMANCE/` grammar suite into one +//! blob under `$OUT_DIR/lang-bundle.md`. Each file is fenced with a +//! `===== =====` header so the single stream stays +//! unambiguously splittable. The skill (`.claude/skills/pseudocode/SKILL.md`) +//! is copied verbatim to `$OUT_DIR/pds-skill.md`. use std::fmt::Write as _; use std::fs; @@ -17,6 +19,27 @@ fn main() { .join("../..") .canonicalize() .expect("workspace root resolves from the crate manifest dir"); + let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").expect("OUT_DIR")); + let bundle_out = out_dir.join("lang-bundle.md"); + let skill_out = out_dir.join("pds-skill.md"); + + // `cargo package` verify builds (release-plz runs one per release) compile + // from a tarball that cannot contain the repo-level spec sources. The crate + // is never published, so those builds get stubs; builds from the repo + // still panic on any unreadable file. + if !repo_root.join("LANG.md").exists() { + let stub = "unavailable: built outside the PseudoScript repository.\n"; + for path in [&bundle_out, &skill_out] { + fs::write(path, stub) + .unwrap_or_else(|err| panic!("writing `{}`: {err}", path.display())); + } + return; + } + + let skill = repo_root.join(".claude/skills/pseudocode/SKILL.md"); + println!("cargo:rerun-if-changed={}", skill.display()); + fs::copy(&skill, &skill_out) + .unwrap_or_else(|err| panic!("copying `{}`: {err}", skill.display())); // Spec and patterns first, then every conformance file sorted by path so a // case sits next to its expected-output pair (e.g. `*.pds` then `*.tokens`). @@ -37,8 +60,8 @@ fn main() { println!("cargo:rerun-if-changed={}", path.display()); } - let out = PathBuf::from(std::env::var_os("OUT_DIR").expect("OUT_DIR")).join("lang-bundle.md"); - fs::write(&out, bundle).unwrap_or_else(|err| panic!("writing `{}`: {err}", out.display())); + fs::write(&bundle_out, bundle) + .unwrap_or_else(|err| panic!("writing `{}`: {err}", bundle_out.display())); } /// Appends every regular file under `dir`, recursively, to `files`. diff --git a/crates/pseudoscript/src/main.rs b/crates/pseudoscript/src/main.rs index e0bb2030..2019f3bd 100644 --- a/crates/pseudoscript/src/main.rs +++ b/crates/pseudoscript/src/main.rs @@ -45,12 +45,10 @@ use serde::Serialize; /// by `build.rs` and embedded so `pds lang` always matches the installed binary. const LANG_BUNDLE: &str = include_str!(concat!(env!("OUT_DIR"), "/lang-bundle.md")); -/// The `PseudoScript` authoring-method skill, embedded verbatim so `pds skill` -/// prints it like any other skill file. -const PDS_SKILL: &str = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../.claude/skills/pseudocode/SKILL.md" -)); +/// The `PseudoScript` authoring-method skill, staged into `OUT_DIR` by +/// `build.rs` and embedded verbatim so `pds skill` prints it like any other +/// skill file. +const PDS_SKILL: &str = include_str!(concat!(env!("OUT_DIR"), "/pds-skill.md")); /// The `PseudoScript` toolchain. #[derive(Debug, Parser)] diff --git a/release-plz.toml b/release-plz.toml index bdeac1b6..a21f8f8e 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -12,12 +12,17 @@ git_tag_enable = false git_release_enable = false # The binary crate (`pseudoscript` → `pds`): the only tagged/released package. +# `git_only` makes release-plz read the last release from the `v*` git tags +# instead of the cargo registry — without it, an unpublished crate looks +# perpetually unreleased, so release-pr proposes the current version forever +# and never bumps (every release then needs a manual bump PR, e.g. #47, #60). # The release is created NOT marked latest (`git_release_latest = false`); the # release-assets workflow flips it to latest only after the installer + upgrade # smoke test passes on all three OSes, so a broken release never becomes the one # `/releases/latest`, scripts/install.*, and `pds upgrade` resolve. [[package]] name = "pseudoscript" +git_only = true git_tag_enable = true git_tag_name = "v{{ version }}" git_release_enable = true From cc6efd7ef41aedca1ace9ba825c6db78fb773c86 Mon Sep 17 00:00:00 2001 From: Jonathan Turnock <16135506+JonathanTurnock@users.noreply.github.com> Date: Wed, 10 Jun 2026 15:57:28 +0100 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20release=20v0.1.6=20=E2=80=94=20fir?= =?UTF-8?q?st=20tag=20whose=20tree=20release-plz=20can=20package?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The git_only content diff packages the latest tag's tree; v0.1.5 predates the dep version requirements, so the automation only heals once this tag exists. From v0.1.6 on, release-plz proposes version bumps itself. Co-Authored-By: Claude Fable 5 --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e56f12f9..f62695fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1341,7 +1341,7 @@ dependencies = [ [[package]] name = "pseudoscript" -version = "0.1.5" +version = "0.1.6" dependencies = [ "anyhow", "assert_cmd", @@ -1374,7 +1374,7 @@ dependencies = [ [[package]] name = "pseudoscript-doc" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1389,7 +1389,7 @@ dependencies = [ [[package]] name = "pseudoscript-dot" -version = "0.1.5" +version = "0.1.6" dependencies = [ "serde", "serde_json", @@ -1397,7 +1397,7 @@ dependencies = [ [[package]] name = "pseudoscript-emit" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1411,7 +1411,7 @@ dependencies = [ [[package]] name = "pseudoscript-format" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1420,7 +1420,7 @@ dependencies = [ [[package]] name = "pseudoscript-ide" -version = "0.1.5" +version = "0.1.6" dependencies = [ "console_error_panic_hook", "js-sys", @@ -1443,7 +1443,7 @@ dependencies = [ [[package]] name = "pseudoscript-layout" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1453,7 +1453,7 @@ dependencies = [ [[package]] name = "pseudoscript-lsp" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1471,7 +1471,7 @@ dependencies = [ [[package]] name = "pseudoscript-lsp-core" -version = "0.1.5" +version = "0.1.6" dependencies = [ "lsp-types", "pseudoscript-format", @@ -1482,7 +1482,7 @@ dependencies = [ [[package]] name = "pseudoscript-model" -version = "0.1.5" +version = "0.1.6" dependencies = [ "anyhow", "cucumber", @@ -1497,7 +1497,7 @@ dependencies = [ [[package]] name = "pseudoscript-project" -version = "0.1.5" +version = "0.1.6" dependencies = [ "anyhow", "pseudoscript-model", @@ -1507,7 +1507,7 @@ dependencies = [ [[package]] name = "pseudoscript-syntax" -version = "0.1.5" +version = "0.1.6" dependencies = [ "cucumber", "futures", @@ -1517,7 +1517,7 @@ dependencies = [ [[package]] name = "pseudoscript-universe" -version = "0.1.5" +version = "0.1.6" dependencies = [ "petgraph", "pseudoscript-model", diff --git a/Cargo.toml b/Cargo.toml index 4c0a82ff..1fcab404 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/*"] [workspace.package] -version = "0.1.5" +version = "0.1.6" edition = "2024" [workspace.lints.clippy]