diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb56723..1271b8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ env: GODOT_WINDOWS_SHA512: 83decd58fdf67b9d657958a1ae6bf1929c20785315a81effe245874cdc57acb709bf868e00778a96984338c1b29dafdb453c6847747694621c6ecf5da2259993 GODOT_MACOS_SHA512: 38aa16e5bba2083941fc5b3e54be0089bd4cc35e32415f5b9fd9a8a6a7b9818255d44532ea8ef94b5aef56c4b407c2d634fa4f657e4ebe681ebbf59b7bac69ca AGENT_GUILD_COMMIT: 3a3cd721f713068ff78264560e29bf951ff9a37b + COMPANIONS_COMMIT: 05dfd1f5c0d64963048c67a826f0758d31b7e83d jobs: build: @@ -105,6 +106,14 @@ jobs: run: | node tools/check_with_agent_guild.mjs build/pieces .agent-guild if ($LASTEXITCODE -ne 0) { throw "Agent Guild refused a piece Studio made." } + - name: Every character the suites made passes Grove Companion's own check + working-directory: tools/companion_check + env: + COMPANION_CHARACTERS_RS: ${{ runner.temp }}/characters.rs + run: | + Invoke-WebRequest "https://raw.githubusercontent.com/oddessentials/agent-guild-companions/$env:COMPANIONS_COMMIT/src-tauri/src/characters.rs" -OutFile $env:COMPANION_CHARACTERS_RS + cargo run --locked -- ../../build/pieces + if ($LASTEXITCODE -ne 0) { throw "Grove Companion refused a character Studio made." } - name: The agents' page gives the app's own connect commands run: | & $env:GODOT --headless --path . --script res://tests/site_commands.gd @@ -269,6 +278,14 @@ jobs: run: | node tools/check_with_agent_guild.mjs build/pieces .agent-guild if ($LASTEXITCODE -ne 0) { throw "Agent Guild refused a piece Studio made." } + - name: Every character the suites made passes Grove Companion's own check + working-directory: tools/companion_check + env: + COMPANION_CHARACTERS_RS: ${{ runner.temp }}/characters.rs + run: | + Invoke-WebRequest "https://raw.githubusercontent.com/oddessentials/agent-guild-companions/$env:COMPANIONS_COMMIT/src-tauri/src/characters.rs" -OutFile $env:COMPANION_CHARACTERS_RS + cargo run --locked -- ../../build/pieces + if ($LASTEXITCODE -ne 0) { throw "Grove Companion refused a character Studio made." } - name: The agents' page gives the app's own connect commands run: | & $env:GODOT --headless --path . --script res://tests/site_commands.gd diff --git a/.gitignore b/.gitignore index 094f10d..58a42dc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ *.tmp __pycache__/ node_modules/ +/tools/companion_check/target/ diff --git a/site/index.md b/site/index.md index beaa3c1..a26c795 100644 --- a/site/index.md +++ b/site/index.md @@ -181,3 +181,7 @@ Follow step 4 above. ## Mac update Run Mac step 2 again with the same folder. The connection, the downloaded art and the person's pieces are kept. Then start a new session, so the Studio tools load again. + +## Use a character in Agent Guild: Companions + +A character Studio makes can also be the person's desktop spirit in Agent Guild: Companions. Follow its own steps at [oddessentials.github.io/agent-guild-companions](https://oddessentials.github.io/agent-guild-companions/), with the folder `list_pieces` gives for the character. diff --git a/tools/companion_check/.gdignore b/tools/companion_check/.gdignore new file mode 100644 index 0000000..e69de29 diff --git a/tools/companion_check/Cargo.lock b/tools/companion_check/Cargo.lock new file mode 100644 index 0000000..f64588d --- /dev/null +++ b/tools/companion_check/Cargo.lock @@ -0,0 +1,249 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "companion_check" +version = "0.0.0" +dependencies = [ + "serde_json", + "uuid", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "itoa" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd1574e617a9a6c1f8f8181bd7e841e1f20e4277607ef28945765188d6284d4" + +[[package]] +name = "js-sys" +version = "0.3.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc09d2154098bbf4ef54eab6b117a3c24cbbffe94046b16ee6d6d4510584d3a" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "syn" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae9ccbea3a7b0b09443036490c8f34a8b1b760fd345e5c0dae0aac718faea79" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "uuid" +version = "1.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0e2d11620c50695fe12bbbfde96b3477fe606e7284c22d505c12ce51214514" +dependencies = [ + "getrandom", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0181c14ddd6c7b8b0b0132a5f1ea2f32be0d893cd3ea97b6e3b28886b8a3d1c" +dependencies = [ + "cfg-if", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e931a02a39abdbf66966fc35902b5ed58344750a70885bed4ebb3d8eaf28ed9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca4b54280e455bd831e33a6b8e734baf432fe63fbc35c42ac14ce67a043a53a" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b1f9c3798725016c6ee5f2f57869ec0831e8bbc0ab0310a86e787e97f41389e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/tools/companion_check/Cargo.toml b/tools/companion_check/Cargo.toml new file mode 100644 index 0000000..65884e8 --- /dev/null +++ b/tools/companion_check/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "companion_check" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +serde_json = "=1.0.154" +uuid = { version = "=1.29.0", features = ["v4"] } diff --git a/tools/companion_check/build.rs b/tools/companion_check/build.rs new file mode 100644 index 0000000..65f0859 --- /dev/null +++ b/tools/companion_check/build.rs @@ -0,0 +1,10 @@ +use std::{env, fs, path::PathBuf}; + +fn main() { + println!("cargo:rerun-if-env-changed=COMPANION_CHARACTERS_RS"); + let source = env::var("COMPANION_CHARACTERS_RS").expect("Set COMPANION_CHARACTERS_RS to Grove Companion's src-tauri/src/characters.rs."); + println!("cargo:rerun-if-changed={source}"); + let text = fs::read_to_string(&source).unwrap_or_else(|err| panic!("{source}: {err}")); + let items: String = text.lines().filter(|line| !line.starts_with("//!")).map(|line| format!("{line}\n")).collect(); + fs::write(PathBuf::from(env::var("OUT_DIR").unwrap()).join("characters.rs"), items).unwrap(); +} diff --git a/tools/companion_check/rust-toolchain.toml b/tools/companion_check/rust-toolchain.toml new file mode 100644 index 0000000..0b8307a --- /dev/null +++ b/tools/companion_check/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.99.1" +profile = "minimal" diff --git a/tools/companion_check/src/main.rs b/tools/companion_check/src/main.rs new file mode 100644 index 0000000..cf1add4 --- /dev/null +++ b/tools/companion_check/src/main.rs @@ -0,0 +1,41 @@ +use std::{env, fs, path::PathBuf, process::ExitCode}; + +#[allow(dead_code)] +mod characters { + include!(concat!(env!("OUT_DIR"), "/characters.rs")); +} + +fn kind(folder: &PathBuf) -> Option { + let manifest: serde_json::Value = serde_json::from_slice(&fs::read(folder.join("piece.json")).ok()?).ok()?; + manifest.get("kind")?.as_str().map(str::to_string) +} + +fn main() -> ExitCode { + let Some(pieces) = env::args().nth(1) else { + eprintln!("Usage: companion_check "); + return ExitCode::FAILURE; + }; + let mut folders: Vec = fs::read_dir(&pieces).expect("the pieces folder can't be read").flatten().map(|entry| entry.path()).filter(|path| path.is_dir()).collect(); + folders.sort(); + let scratch = env::temp_dir().join(format!("studio-companion-check-{}", characters::new_id())); + let (mut checked, mut refused) = (0, 0); + for folder in folders { + if kind(&folder).as_deref() != Some("character") { + continue; + } + checked += 1; + let name = folder.file_name().unwrap().to_string_lossy().into_owned(); + let token = characters::new_id(); + match characters::stage(&scratch, &folder, &token) { + Ok(title) => println!("ok {name} ({title})"), + Err(reason) => { + refused += 1; + println!("REFUSED {name}: {reason}"); + } + } + characters::discard(&scratch, &token); + } + let _ = fs::remove_dir_all(&scratch); + println!("{} of {checked} characters pass Grove Companion's check", checked - refused); + if checked == 0 || refused > 0 { ExitCode::FAILURE } else { ExitCode::SUCCESS } +}