rename: adopt yoi identity

This commit is contained in:
2026-06-01 18:49:23 +09:00
parent 6e133a7229
commit e6c458021c
115 changed files with 945 additions and 732 deletions
+1 -1
View File
@@ -18,5 +18,5 @@
### ランタイム
- `RuntimeDir``$XDG_RUNTIME_DIR/insomnia/{pod_name}/` 配下のランタイムディレクトリ管理(ステータス・履歴のアトミック書き込み)
- `RuntimeDir``$XDG_RUNTIME_DIR/yoi/{pod_name}/` 配下のランタイムディレクトリ管理(ステータス・履歴のアトミック書き込み)
- `SocketServer` — Pod Protocol 用 Unix ソケットサーバー
+1 -1
View File
@@ -1,6 +1,6 @@
//! Minimal example: Pod running a single prompt with persistence.
//!
//! Demonstrates the core insomnia abstraction — a TOML manifest drives
//! Demonstrates the core yoi abstraction — a TOML manifest drives
//! provider selection, model config, and system prompt, while FsStore
//! persists the session to disk automatically.
//!
+1 -1
View File
@@ -822,7 +822,7 @@ mod tests {
let runtime_base = root.path().join("runtime");
std::fs::create_dir_all(&runtime_base).unwrap();
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", &runtime_base);
std::env::set_var("YOI_RUNTIME_DIR", &runtime_base);
}
let store = FsPodStore::new(&store_dir).unwrap();
+31 -47
View File
@@ -191,7 +191,7 @@ fn load_single_manifest(
}
pub async fn run_cli() -> ExitCode {
run_cli_from("insomnia pod", std::env::args_os().skip(1)).await
run_cli_from("yoi pod", std::env::args_os().skip(1)).await
}
pub async fn run_cli_from<I, T>(bin_name: &'static str, args: I) -> ExitCode
@@ -246,7 +246,7 @@ async fn run_cli_inner(cli: Cli) -> ExitCode {
};
// Initialize persistent store. `paths::sessions_dir()` only
// returns None when none of INSOMNIA_HOME / INSOMNIA_DATA_DIR /
// returns None when none of YOI_HOME / YOI_DATA_DIR /
// HOME is set — surface that as a hard error to match the
// runtime-dir resolution below, rather than silently writing to a
// relative path under cwd.
@@ -257,7 +257,7 @@ async fn run_cli_inner(cli: Cli) -> ExitCode {
None => {
eprintln!(
"error: could not resolve sessions directory \
(set --store, INSOMNIA_HOME, INSOMNIA_DATA_DIR, or HOME)"
(set --store, YOI_HOME, YOI_DATA_DIR, or HOME)"
);
return ExitCode::FAILURE;
}
@@ -375,7 +375,7 @@ async fn run_cli_inner(cli: Cli) -> ExitCode {
None => {
eprintln!(
"error: could not resolve runtime directory \
(set INSOMNIA_HOME, INSOMNIA_RUNTIME_DIR, XDG_RUNTIME_DIR, or HOME)"
(set YOI_HOME, YOI_RUNTIME_DIR, XDG_RUNTIME_DIR, or HOME)"
);
return ExitCode::FAILURE;
}
@@ -393,7 +393,7 @@ async fn run_cli_inner(cli: Cli) -> ExitCode {
// (e.g. the TUI's interactive `spawn` flow). Tab-separated so a
// pod name with spaces still parses cleanly. Emit before the
// human line so a stderr-watching parent sees it first.
eprintln!("INSOMNIA-READY\t{pod_name}\t{}", socket_path.display());
eprintln!("YOI-READY\t{pod_name}\t{}", socket_path.display());
eprintln!("pod: {pod_name} listening on {:?}", socket_path);
tokio::select! {
@@ -443,36 +443,30 @@ permission = "write"
#[test]
fn user_manifest_flag_is_not_accepted() {
let err =
Cli::try_parse_from(["insomnia pod", "--user-manifest", "manifest.toml"]).unwrap_err();
let err = Cli::try_parse_from(["yoi pod", "--user-manifest", "manifest.toml"]).unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
}
#[test]
fn subcommand_help_uses_insomnia_pod_invocation() {
let err = parse_cli_from("insomnia pod", ["--help"]).unwrap_err();
fn subcommand_help_uses_yoi_pod_invocation() {
let err = parse_cli_from("yoi pod", ["--help"]).unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp);
let help = err.to_string();
assert!(help.contains("Usage: insomnia pod"), "{help}");
assert!(help.contains("Usage: yoi pod"), "{help}");
assert!(help.contains("--pod <NAME>"), "{help}");
}
#[test]
fn manifest_conflicts_with_project() {
let project_err = Cli::try_parse_from([
"insomnia pod",
"--manifest",
"manifest.toml",
"--project",
".",
])
.unwrap_err();
let project_err =
Cli::try_parse_from(["yoi pod", "--manifest", "manifest.toml", "--project", "."])
.unwrap_err();
assert_eq!(project_err.kind(), clap::error::ErrorKind::ArgumentConflict);
}
#[test]
fn overlay_flag_is_not_accepted() {
let err = Cli::try_parse_from(["insomnia pod", "--overlay", "pod.name = 'x'"]).unwrap_err();
let err = Cli::try_parse_from(["yoi pod", "--overlay", "pod.name = 'x'"]).unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
}
@@ -481,8 +475,8 @@ permission = "write"
let tmp = TempDir::new().unwrap();
let manifest = tmp.path().join("manifest.toml");
write(&manifest, &manifest_toml("single", tmp.path()));
let cli = Cli::try_parse_from(["insomnia pod", "--manifest", manifest.to_str().unwrap()])
.unwrap();
let cli =
Cli::try_parse_from(["yoi pod", "--manifest", manifest.to_str().unwrap()]).unwrap();
let (manifest, loader) = resolve_manifest(&cli).unwrap();
@@ -496,7 +490,7 @@ permission = "write"
let tmp = TempDir::new().unwrap();
let profile = tmp.path().join("profile.lua");
let cli = Cli::try_parse_from([
"insomnia pod",
"yoi pod",
"--profile",
profile.to_str().unwrap(),
"--profile-pod-name",
@@ -529,7 +523,7 @@ permission = "write"
fn profile_accepts_source_qualified_discovered_name() {
let tmp = TempDir::new().unwrap();
let cli = Cli::try_parse_from([
"insomnia pod",
"yoi pod",
"--profile",
"project:coder",
"--profile-pod-name",
@@ -564,7 +558,7 @@ permission = "write"
#[test]
fn normal_startup_uses_default_profile() {
let tmp = TempDir::new().unwrap();
let cli = Cli::try_parse_from(["insomnia pod"]).unwrap();
let cli = Cli::try_parse_from(["yoi pod"]).unwrap();
let mut called = false;
let (manifest, _loader) =
@@ -585,7 +579,7 @@ permission = "write"
#[test]
fn project_flag_no_longer_enables_ambient_manifest_cascade() {
let cli = Cli::try_parse_from(["insomnia pod", "--project", "."]).unwrap();
let cli = Cli::try_parse_from(["yoi pod", "--project", "."]).unwrap();
let err = resolve_manifest_with_profile_loader(&cli, |_, _| {
panic!("default profile loader must not run when deprecated --project is present")
})
@@ -597,7 +591,7 @@ permission = "write"
fn pod_flag_conflicts_with_session() {
let segment_id = session_store::new_segment_id();
let segment_id = segment_id.to_string();
let err = Cli::try_parse_from(["insomnia pod", "--pod", "agent", "--session", &segment_id])
let err = Cli::try_parse_from(["yoi pod", "--pod", "agent", "--session", &segment_id])
.unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
}
@@ -608,7 +602,7 @@ permission = "write"
let manifest = tmp.path().join("manifest.toml");
write(&manifest, &manifest_toml("from-file", tmp.path()));
let cli = Cli::try_parse_from([
"insomnia pod",
"yoi pod",
"--manifest",
manifest.to_str().unwrap(),
"--pod",
@@ -640,7 +634,7 @@ permission = "write"
"#,
);
let cli = Cli::try_parse_from([
"insomnia pod",
"yoi pod",
"--manifest",
manifest.to_str().unwrap(),
"--pod",
@@ -657,7 +651,7 @@ permission = "write"
#[test]
fn pod_flag_with_no_manifest_creates_from_default_profile_with_typed_name() {
let tmp = TempDir::new().unwrap();
let cli = Cli::try_parse_from(["insomnia pod", "--pod", "agent"]).unwrap();
let cli = Cli::try_parse_from(["yoi pod", "--pod", "agent"]).unwrap();
let mut called = false;
let (manifest, _loader) =
@@ -683,15 +677,9 @@ permission = "write"
fn profile_conflicts_with_manifest_and_restore_modes() {
let segment_id = session_store::new_segment_id().to_string();
for args in [
vec!["insomnia pod", "--profile", "p.lua", "--manifest", "m.toml"],
vec!["insomnia pod", "--profile", "p.lua", "--pod", "agent"],
vec![
"insomnia pod",
"--profile",
"p.lua",
"--session",
&segment_id,
],
vec!["yoi pod", "--profile", "p.lua", "--manifest", "m.toml"],
vec!["yoi pod", "--profile", "p.lua", "--pod", "agent"],
vec!["yoi pod", "--profile", "p.lua", "--session", &segment_id],
] {
let err = Cli::try_parse_from(args).unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
@@ -700,14 +688,14 @@ permission = "write"
#[test]
fn profile_pod_name_requires_profile() {
let err = Cli::try_parse_from(["insomnia pod", "--profile-pod-name", "agent"]).unwrap_err();
let err = Cli::try_parse_from(["yoi pod", "--profile-pod-name", "agent"]).unwrap_err();
assert_eq!(err.kind(), clap::error::ErrorKind::MissingRequiredArgument);
}
#[test]
fn profile_pod_name_is_not_restore_pod_flag() {
let cli = Cli::try_parse_from([
"insomnia pod",
"yoi pod",
"--profile",
"p.lua",
"--profile-pod-name",
@@ -724,13 +712,9 @@ permission = "write"
let single_manifest = tmp.path().join("single.toml");
write(&single_manifest, &manifest_toml("single-file", tmp.path()));
std::fs::create_dir_all(tmp.path().join("prompts")).unwrap();
std::fs::create_dir_all(tmp.path().join(".insomnia").join("prompts")).unwrap();
let cli = Cli::try_parse_from([
"insomnia pod",
"--manifest",
single_manifest.to_str().unwrap(),
])
.unwrap();
std::fs::create_dir_all(tmp.path().join(".yoi").join("prompts")).unwrap();
let cli = Cli::try_parse_from(["yoi pod", "--manifest", single_manifest.to_str().unwrap()])
.unwrap();
let (manifest, loader) = resolve_manifest(&cli).unwrap();
+8 -8
View File
@@ -333,7 +333,7 @@ pub struct Pod<C: LlmClient, St: Store> {
/// [`Self::from_manifest`], or defaults to the builtin pack when a
/// Pod is constructed through lower-level paths that have no loader.
prompts: Arc<PromptCatalog>,
/// Registry loaded from `<workspace>/.insomnia/workflow/*.md` when
/// Registry loaded from `<workspace>/.yoi/workflow/*.md` when
/// memory is enabled. Missing memory config keeps this empty.
workflow_registry: workflow_crate::WorkflowRegistry,
/// Memory workspace layout used by the workflow resolver to load required
@@ -5337,21 +5337,21 @@ mod build_summary_prompt_tests {
let pwd = dir.path().join("workspace");
std::fs::create_dir_all(&pwd).unwrap();
if let Some(doc) = summary_doc {
std::fs::create_dir_all(pwd.join(".insomnia/memory")).unwrap();
std::fs::write(pwd.join(".insomnia/memory/summary.md"), doc).unwrap();
std::fs::create_dir_all(pwd.join(".yoi/memory")).unwrap();
std::fs::write(pwd.join(".yoi/memory/summary.md"), doc).unwrap();
}
if include_knowledge {
std::fs::create_dir_all(pwd.join(".insomnia/knowledge")).unwrap();
std::fs::create_dir_all(pwd.join(".yoi/knowledge")).unwrap();
std::fs::write(
pwd.join(".insomnia/knowledge/resident-policy.md"),
pwd.join(".yoi/knowledge/resident-policy.md"),
knowledge_doc("knowledge resident desc"),
)
.unwrap();
}
if include_workflow {
std::fs::create_dir_all(pwd.join(".insomnia/workflow")).unwrap();
std::fs::create_dir_all(pwd.join(".yoi/workflow")).unwrap();
std::fs::write(
pwd.join(".insomnia/workflow/resident-flow.md"),
pwd.join(".yoi/workflow/resident-flow.md"),
workflow_doc("workflow resident desc"),
)
.unwrap();
@@ -5379,7 +5379,7 @@ mod build_summary_prompt_tests {
pod.set_resident_workflow_injection(gates.workflows);
}
let template = SystemPromptTemplate::parse(
"$insomnia/default",
"$yoi/default",
crate::prompt::loader::PromptLoader::builtins_only(),
)
.unwrap();
+5 -5
View File
@@ -18,7 +18,7 @@
//! binary. Must cover every [`PodPrompt`] variant (build-time check).
//! 2. **user** — `<config_dir>/prompts.toml`, when a caller supplies it.
//! Optional.
//! 3. **workspace** — `<project>/.insomnia/prompts.toml`, when a caller
//! 3. **workspace** — `<project>/.yoi/prompts.toml`, when a caller
//! supplies it. Optional.
//! 4. **manifest pack** — `manifest.pod.prompt_pack`, an explicit path
//! per-Pod. Optional.
@@ -258,7 +258,7 @@ struct PackFile {
/// Owns a `minijinja::Environment` with one template registered per
/// [`PodPrompt`] key (after the 4-layer merge). Includes inside templates
/// are resolved via a provided [`PromptLoader`], so values can pull from
/// `$insomnia` / `$user` / `$workspace`.
/// `$yoi` / `$user` / `$workspace`.
pub struct PromptCatalog {
env: Environment<'static>,
}
@@ -271,7 +271,7 @@ impl std::fmt::Debug for PromptCatalog {
impl PromptCatalog {
/// Builtin-only catalog. All `{% include %}` references must resolve
/// through `$insomnia` (user/workspace prefixes are unavailable).
/// through `$yoi` (user/workspace prefixes are unavailable).
pub fn builtins_only() -> Result<Arc<Self>, CatalogError> {
Self::load(&PromptLoader::builtins_only(), None)
}
@@ -707,7 +707,7 @@ interrupt_system_note = "[FROM-MANIFEST-PACK]"
#[test]
fn value_can_pull_long_text_via_include() {
// A runtime pack that overrides `compact_system` with an
// `{% include %}` into the same `$insomnia` namespace — exercises
// `{% include %}` into the same `$yoi` namespace — exercises
// the template resolver path through all four layers.
let tmp = TempDir::new().unwrap();
let pack = tmp.path().join("p.toml");
@@ -715,7 +715,7 @@ interrupt_system_note = "[FROM-MANIFEST-PACK]"
&pack,
r#"
[prompt]
compact_system = "PREFIX\n{% include \"$insomnia/internal/compact_system\" %}"
compact_system = "PREFIX\n{% include \"$yoi/internal/compact_system\" %}"
"#,
)
.unwrap();
+21 -25
View File
@@ -4,12 +4,12 @@
//!
//! | prefix | location |
//! |--------------|---------------------------------------------------------|
//! | `$insomnia` | builtin, baked into the binary via `include_dir!` |
//! | `$yoi` | builtin, baked into the binary via `include_dir!` |
//! | `$user` | `<config_dir>/prompts/` (resolved by `manifest::paths`) |
//! | `$workspace` | `<project>/.insomnia/prompts/` |
//! | `$workspace` | `<project>/.yoi/prompts/` |
//!
//! A reference is `$<prefix>/<path>` where `<path>` is a `/`-separated
//! name without the `.md` extension (e.g. `$insomnia/common/header`).
//! name without the `.md` extension (e.g. `$yoi/common/header`).
//! Unqualified names (no `$prefix/` at the front) are resolved relative
//! to an optional current reference — typically the file that issued
//! the `{% include %}` — so a prompt library can be authored as a
@@ -25,13 +25,13 @@ use thiserror::Error;
static BUILTIN_PROMPTS: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/../../resources/prompts");
const PREFIX_INSOMNIA: &str = "$insomnia";
const PREFIX_YOI: &str = "$yoi";
const PREFIX_USER: &str = "$user";
const PREFIX_WORKSPACE: &str = "$workspace";
/// Prefix-resolved reference to a prompt asset. Produced by
/// [`PromptLoader::parse_ref`] from a user-supplied string such as
/// `"$insomnia/default"`.
/// `"$yoi/default"`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PromptRef {
prefix: Prefix,
@@ -42,7 +42,7 @@ pub struct PromptRef {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Prefix {
Insomnia,
Yoi,
User,
Workspace,
}
@@ -50,7 +50,7 @@ enum Prefix {
impl Prefix {
fn as_str(self) -> &'static str {
match self {
Self::Insomnia => PREFIX_INSOMNIA,
Self::Yoi => PREFIX_YOI,
Self::User => PREFIX_USER,
Self::Workspace => PREFIX_WORKSPACE,
}
@@ -116,7 +116,7 @@ pub struct PromptLoader {
}
impl PromptLoader {
/// Loader with only the builtin `$insomnia` library available.
/// Loader with only the builtin `$yoi` library available.
/// `$user` / `$workspace` references fail with
/// [`LoaderError::PrefixNotConfigured`].
pub fn builtins_only() -> Self {
@@ -221,7 +221,7 @@ impl PromptLoader {
/// when the prefix is not configured or the file does not exist.
pub fn load(&self, reference: &PromptRef) -> Result<String, LoaderError> {
match reference.prefix {
Prefix::Insomnia => load_from_include_dir(&BUILTIN_PROMPTS, reference),
Prefix::Yoi => load_from_include_dir(&BUILTIN_PROMPTS, reference),
Prefix::User => match self.user_dir.as_deref() {
Some(dir) => load_from_dir(dir, reference),
None => Err(LoaderError::PrefixNotConfigured {
@@ -252,7 +252,7 @@ impl PromptLoader {
fn parse_prefix(raw: &str, prefix_name: &str) -> Result<Prefix, LoaderError> {
match prefix_name {
"insomnia" => Ok(Prefix::Insomnia),
"yoi" => Ok(Prefix::Yoi),
"user" => Ok(Prefix::User),
"workspace" => Ok(Prefix::Workspace),
_ => Err(LoaderError::UnknownPrefix {
@@ -311,15 +311,15 @@ mod tests {
#[test]
fn builtin_default_resolves() {
let loader = PromptLoader::builtins_only();
let (r, source) = loader.resolve("$insomnia/default", None).unwrap();
assert_eq!(r.to_qualified_string(), "$insomnia/default");
let (r, source) = loader.resolve("$yoi/default", None).unwrap();
assert_eq!(r.to_qualified_string(), "$yoi/default");
assert!(!source.is_empty());
}
#[test]
fn builtin_subdirectory_lookup() {
let loader = PromptLoader::builtins_only();
let (_, source) = loader.resolve("$insomnia/common/tool-usage", None).unwrap();
let (_, source) = loader.resolve("$yoi/common/tool-usage", None).unwrap();
assert!(source.contains("tool"));
}
@@ -346,9 +346,7 @@ mod tests {
#[test]
fn missing_file_is_hard_error() {
let loader = PromptLoader::builtins_only();
let err = loader
.resolve("$insomnia/definitely-missing", None)
.unwrap_err();
let err = loader.resolve("$yoi/definitely-missing", None).unwrap_err();
assert!(matches!(err, LoaderError::NotFound { .. }));
}
@@ -379,20 +377,18 @@ mod tests {
#[test]
fn unqualified_ref_resolves_relative_to_current() {
let loader = PromptLoader::builtins_only();
let current = loader
.parse_ref("$insomnia/common/tool-usage", None)
.unwrap();
let current = loader.parse_ref("$yoi/common/tool-usage", None).unwrap();
// Sibling lookup under the same prefix and directory.
let sibling = loader.parse_ref("workspace", Some(&current)).unwrap();
assert_eq!(sibling.to_qualified_string(), "$insomnia/common/workspace");
assert_eq!(sibling.to_qualified_string(), "$yoi/common/workspace");
}
#[test]
fn unqualified_ref_from_root_file_has_empty_dir() {
let loader = PromptLoader::builtins_only();
let current = loader.parse_ref("$insomnia/default", None).unwrap();
let current = loader.parse_ref("$yoi/default", None).unwrap();
let sibling = loader.parse_ref("other", Some(&current)).unwrap();
assert_eq!(sibling.to_qualified_string(), "$insomnia/other");
assert_eq!(sibling.to_qualified_string(), "$yoi/other");
}
#[test]
@@ -402,8 +398,8 @@ mod tests {
std::fs::write(user_dir.join("custom.md"), "user-body").unwrap();
let loader = PromptLoader::new(Some(user_dir), None);
let current = loader.parse_ref("$insomnia/default", None).unwrap();
// Even with an $insomnia-rooted current, an explicit $user
let current = loader.parse_ref("$yoi/default", None).unwrap();
// Even with an $yoi-rooted current, an explicit $user
// prefix must win.
let (reference, source) = loader.resolve("$user/custom", Some(&current)).unwrap();
assert_eq!(reference.to_qualified_string(), "$user/custom");
@@ -413,7 +409,7 @@ mod tests {
#[test]
fn traversal_segments_rejected() {
let loader = PromptLoader::builtins_only();
let err = loader.resolve("$insomnia/../etc/passwd", None).unwrap_err();
let err = loader.resolve("$yoi/../etc/passwd", None).unwrap_err();
assert!(matches!(err, LoaderError::InvalidRef { .. }));
}
}
+10 -10
View File
@@ -155,7 +155,7 @@ pub struct SystemPromptContext<'a> {
/// Not visible from the template; consumed by the trailing-section
/// formatter in [`SystemPromptTemplate::render`].
pub agents_md: Option<String>,
/// The body of `<workspace>/.insomnia/memory/summary.md`, with
/// The body of `<workspace>/.yoi/memory/summary.md`, with
/// frontmatter stripped. `None` disables the resident summary section;
/// empty strings are ignored by the trailing-section formatter.
pub resident_summary: Option<&'a str>,
@@ -164,7 +164,7 @@ pub struct SystemPromptContext<'a> {
/// section entirely (memory disabled, or a consolidation worker that opts
/// out); `Some(&[])` also yields no section.
pub resident_knowledge: Option<&'a [ResidentKnowledgeEntry]>,
/// Resident workflow descriptions from `<workspace>/.insomnia/workflow/*`
/// Resident workflow descriptions from `<workspace>/.yoi/workflow/*`
/// whose frontmatter has `model_invokation: true`. `None` disables the
/// section; consolidation workers opt out together with resident Knowledge.
pub resident_workflows: Option<&'a [ResidentWorkflowEntry]>,
@@ -557,9 +557,9 @@ mod tests {
}
#[test]
fn instruction_default_resolves_to_insomnia_default() {
fn instruction_default_resolves_to_yoi_default() {
let loader = PromptLoader::builtins_only();
let tmpl = SystemPromptTemplate::parse("$insomnia/default", loader).unwrap();
let tmpl = SystemPromptTemplate::parse("$yoi/default", loader).unwrap();
let dir = TempDir::new().unwrap();
let scope = build_scope(dir.path());
let rendered = tmpl
@@ -582,7 +582,7 @@ mod tests {
#[test]
fn instruction_default_omits_memory_guidance_without_memory_tools() {
let loader = PromptLoader::builtins_only();
let tmpl = SystemPromptTemplate::parse("$insomnia/default", loader).unwrap();
let tmpl = SystemPromptTemplate::parse("$yoi/default", loader).unwrap();
let dir = TempDir::new().unwrap();
let scope = build_scope(dir.path());
let rendered = tmpl
@@ -608,7 +608,7 @@ mod tests {
#[test]
fn memory_guidance_names_only_available_memory_tools() {
let loader = PromptLoader::builtins_only();
let tmpl = SystemPromptTemplate::parse("$insomnia/default", loader).unwrap();
let tmpl = SystemPromptTemplate::parse("$yoi/default", loader).unwrap();
let dir = TempDir::new().unwrap();
let scope = build_scope(dir.path());
let rendered = tmpl
@@ -632,7 +632,7 @@ mod tests {
#[test]
fn pod_orchestration_guidance_is_included_for_pod_management_tools() {
let loader = PromptLoader::builtins_only();
let tmpl = SystemPromptTemplate::parse("$insomnia/default", loader).unwrap();
let tmpl = SystemPromptTemplate::parse("$yoi/default", loader).unwrap();
let dir = TempDir::new().unwrap();
let scope = build_scope(dir.path());
let rendered = tmpl
@@ -651,7 +651,7 @@ mod tests {
#[test]
fn pod_orchestration_guidance_is_omitted_without_pod_management_tools() {
let loader = PromptLoader::builtins_only();
let tmpl = SystemPromptTemplate::parse("$insomnia/default", loader).unwrap();
let tmpl = SystemPromptTemplate::parse("$yoi/default", loader).unwrap();
let dir = TempDir::new().unwrap();
let scope = build_scope(dir.path());
let rendered = tmpl
@@ -735,7 +735,7 @@ mod tests {
let tmp = TempDir::new().unwrap();
std::fs::write(
tmp.path().join("root.md"),
"U-ROOT\n{% include \"$insomnia/common/tool-usage\" %}",
"U-ROOT\n{% include \"$yoi/common/tool-usage\" %}",
)
.unwrap();
let loader = PromptLoader::new(Some(tmp.path().to_path_buf()), None);
@@ -758,7 +758,7 @@ mod tests {
#[test]
fn prefix_with_missing_file_is_hard_error() {
let loader = PromptLoader::builtins_only();
let err = SystemPromptTemplate::parse("$insomnia/definitely-missing", loader).unwrap_err();
let err = SystemPromptTemplate::parse("$yoi/definitely-missing", loader).unwrap_err();
assert!(matches!(err, SystemPromptError::LoaderResolve(_)));
}
+4 -4
View File
@@ -116,8 +116,8 @@ pub fn default_base() -> Result<PathBuf, io::Error> {
paths::runtime_dir().ok_or_else(|| {
io::Error::new(
io::ErrorKind::NotFound,
"could not resolve runtime directory (no INSOMNIA_HOME / \
INSOMNIA_RUNTIME_DIR / XDG_RUNTIME_DIR / HOME)",
"could not resolve runtime directory (no YOI_HOME / \
YOI_RUNTIME_DIR / XDG_RUNTIME_DIR / HOME)",
)
})
}
@@ -203,13 +203,13 @@ mod tests {
let records = vec![SpawnedPodRecord {
pod_name: "child".into(),
socket_path: "/run/insomnia/child/sock".into(),
socket_path: "/run/yoi/child/sock".into(),
scope_delegated: vec![ScopeRule {
target: "/tmp/work".into(),
permission: Permission::Write,
recursive: true,
}],
callback_address: "/run/insomnia/my-pod/sock".into(),
callback_address: "/run/yoi/my-pod/sock".into(),
}];
rt.write_spawned_pods(&records).await.unwrap();
+20 -29
View File
@@ -48,7 +48,7 @@ struct SpawnPodInput {
/// unambiguous profile slug. Raw/path selectors are rejected.
#[serde(default)]
profile: Option<String>,
/// Instruction-file reference (e.g. `$insomnia/default`, `$user/my-agent`).
/// Instruction-file reference (e.g. `$yoi/default`, `$user/my-agent`).
#[serde(default)]
instruction: Option<String>,
/// First message sent to the spawned Pod via `Method::Run`.
@@ -214,7 +214,7 @@ pub struct SpawnPodTool {
/// Path to the spawner's Unix socket. Handed to the child via
/// `--callback` so its `PodEvent` callbacks have somewhere to land.
callback_socket: PathBuf,
/// Root of the `$XDG_RUNTIME_DIR/insomnia/` tree, used to predict
/// Root of the `$XDG_RUNTIME_DIR/yoi/` tree, used to predict
/// the spawned Pod's socket path before the child has bound it.
runtime_base: PathBuf,
/// Directory the spawned Pod should run in when the LLM did not
@@ -890,7 +890,7 @@ mod tests {
..Default::default()
},
worker: WorkerManifestConfig {
instruction: Some("$insomnia/parent".into()),
instruction: Some("$yoi/parent".into()),
language: Some("Parentish".into()),
max_tokens: Some(1234),
stop_sequences: Some(vec!["STOP".into()]),
@@ -916,8 +916,8 @@ mod tests {
default: Option<&str>,
profiles: &[(&str, &str, &str)],
) -> AvailableProfiles {
let insomnia = project.join(".insomnia");
let profile_dir = insomnia.join("profiles");
let yoi = project.join(".yoi");
let profile_dir = yoi.join("profiles");
std::fs::create_dir_all(&profile_dir).unwrap();
let mut registry_toml = String::new();
if let Some(default) = default {
@@ -928,7 +928,7 @@ mod tests {
std::fs::write(profile_dir.join(file), body).unwrap();
registry_toml.push_str(&format!("{name} = \"profiles/{file}\"\n"));
}
let registry_path = insomnia.join("profiles.toml");
let registry_path = yoi.join("profiles.toml");
std::fs::write(&registry_path, registry_toml).unwrap();
AvailableProfiles {
registry: Some(
@@ -963,23 +963,23 @@ mod tests {
}
const CODER_PROFILE: &str = r#"
local profile = require("insomnia.profile")
local scope = require("insomnia.scope")
local profile = require("yoi.profile")
local scope = require("yoi.scope")
return profile {
slug = "coder",
model = { scheme = "anthropic", model_id = "coder-model" },
worker = { instruction = "$insomnia/coder", language = "Coderish", max_tokens = 2222 },
worker = { instruction = "$yoi/coder", language = "Coderish", max_tokens = 2222 },
scope = scope.workspace_write(),
}
"#;
const REVIEWER_PROFILE: &str = r#"
local profile = require("insomnia.profile")
local scope = require("insomnia.scope")
local profile = require("yoi.profile")
local scope = require("yoi.scope")
return profile {
slug = "reviewer",
model = { scheme = "anthropic", model_id = "reviewer-model" },
worker = { instruction = "$insomnia/reviewer", language = "Reviewerish", max_tokens = 3333 },
worker = { instruction = "$yoi/reviewer", language = "Reviewerish", max_tokens = 3333 },
scope = scope.workspace_write(),
}
"#;
@@ -997,7 +997,7 @@ return profile {
};
let config_json =
build_spawn_config_json("child", "$insomnia/default", &[], &model, false).unwrap();
build_spawn_config_json("child", "$yoi/default", &[], &model, false).unwrap();
let parsed: PodManifestConfig = serde_json::from_str(&config_json).unwrap();
assert_eq!(parsed.model.scheme, Some(SchemeKind::Anthropic));
@@ -1020,7 +1020,7 @@ return profile {
..Default::default()
};
let config_json =
build_spawn_config_json("child", "$insomnia/default", &[], &model, false).unwrap();
build_spawn_config_json("child", "$yoi/default", &[], &model, false).unwrap();
let parsed: PodManifestConfig = serde_json::from_str(&config_json).unwrap();
assert_eq!(
parsed.model.ref_.as_deref(),
@@ -1041,7 +1041,7 @@ return profile {
}];
let config_json =
build_spawn_config_json("child", "$insomnia/default", &scope, &model, true).unwrap();
build_spawn_config_json("child", "$yoi/default", &scope, &model, true).unwrap();
let parsed: PodManifestConfig = serde_json::from_str(&config_json).unwrap();
assert_eq!(
parsed.session.as_ref().and_then(|s| s.record_event_trace),
@@ -1062,7 +1062,7 @@ return profile {
..Default::default()
};
let config_json =
build_spawn_config_json("child", "$insomnia/default", &[], &model, false).unwrap();
build_spawn_config_json("child", "$yoi/default", &[], &model, false).unwrap();
let parsed: PodManifestConfig = serde_json::from_str(&config_json).unwrap();
assert!(parsed.session.is_none());
@@ -1098,10 +1098,7 @@ return profile {
assert_eq!(config.pod.name.as_deref(), Some("child-default"));
assert_eq!(config.model.model_id.as_deref(), Some("reviewer-model"));
assert_eq!(
config.worker.instruction.as_deref(),
Some("$insomnia/reviewer")
);
assert_eq!(config.worker.instruction.as_deref(), Some("$yoi/reviewer"));
assert_eq!(config.worker.language.as_deref(), Some("Reviewerish"));
assert_eq!(config.scope.allow, scope);
assert!(config.scope.deny.is_empty());
@@ -1140,10 +1137,7 @@ return profile {
assert_eq!(config.pod.name.as_deref(), Some("review-child"));
assert_eq!(config.model.model_id.as_deref(), Some("reviewer-model"));
assert_eq!(
config.worker.instruction.as_deref(),
Some("$insomnia/reviewer")
);
assert_eq!(config.worker.instruction.as_deref(), Some("$yoi/reviewer"));
assert_eq!(config.worker.language.as_deref(), Some("Reviewerish"));
assert_eq!(config.worker.max_tokens, Some(3333));
assert_eq!(config.scope.allow, scope);
@@ -1177,10 +1171,7 @@ return profile {
assert_eq!(config.pod.name.as_deref(), Some("inherited-child"));
assert_eq!(config.model.model_id.as_deref(), Some("parent-model"));
assert_eq!(
config.worker.instruction.as_deref(),
Some("$insomnia/parent")
);
assert_eq!(config.worker.instruction.as_deref(), Some("$yoi/parent"));
assert_eq!(config.worker.language.as_deref(), Some("Parentish"));
assert_eq!(config.worker.max_tokens, Some(1234));
assert_eq!(
@@ -1313,7 +1304,7 @@ return profile {
let user_config = tmp.path().join("user-profiles.toml");
std::fs::write(&user_config, "[profile]\ncoder = \"user-coder.lua\"\n").unwrap();
let project_config = project.join(".insomnia/profiles.toml");
let project_config = project.join(".yoi/profiles.toml");
let ambiguous = AvailableProfiles {
registry: Some(
ProfileDiscovery::with_sources(Some(user_config), Some(project_config))
+4 -4
View File
@@ -145,11 +145,11 @@ mod tests {
let dir = TempDir::new().unwrap();
let layout = WorkspaceLayout::new(dir.path().to_path_buf());
write(
&dir.path().join(".insomnia/knowledge/policy.md"),
&dir.path().join(".yoi/knowledge/policy.md"),
"---\ncreated_at: 2026-01-01T00:00:00Z\nupdated_at: 2026-01-01T00:00:00Z\nkind: policy\ndescription: p\nmodel_invokation: false\nuser_invocable: true\nlast_sources: []\n---\npolicy body\n",
);
write(
&dir.path().join(".insomnia/workflow/run-it.md"),
&dir.path().join(".yoi/workflow/run-it.md"),
"---\ndescription: run\nrequires: [policy]\n---\nworkflow body\n",
);
let registry = workflow_crate::load_workflows(&layout).unwrap();
@@ -173,7 +173,7 @@ mod tests {
fn user_invocable_false_errors() {
let (dir, layout, _registry) = setup();
write(
&dir.path().join(".insomnia/workflow/hidden.md"),
&dir.path().join(".yoi/workflow/hidden.md"),
"---\ndescription: hidden\nuser_invocable: false\n---\nbody\n",
);
let registry = workflow_crate::load_workflows(&layout).unwrap();
@@ -186,7 +186,7 @@ mod tests {
let dir = TempDir::new().unwrap();
let layout = WorkspaceLayout::new(dir.path().to_path_buf());
write(
&dir.path().join(".insomnia/workflow/bad.md"),
&dir.path().join(".yoi/workflow/bad.md"),
"---\ndescription: bad\nrequires: [ghost]\n---\nbody\n",
);
let registry = workflow_crate::load_workflows(&layout).unwrap();
+11 -11
View File
@@ -29,11 +29,11 @@ use tokio::sync::mpsc;
use tokio::task::JoinHandle;
/// Serialises env-mutating tests. The test harness runs tasks across
/// threads, and `INSOMNIA_RUNTIME_DIR` is a process-wide resource.
/// threads, and `YOI_RUNTIME_DIR` is a process-wide resource.
static ENV_LOCK: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
/// Take `ENV_LOCK` and clear any env vars that would outrank
/// `INSOMNIA_RUNTIME_DIR` in `paths::runtime_dir` resolution; restore
/// `YOI_RUNTIME_DIR` in `paths::runtime_dir` resolution; restore
/// previous values on drop.
struct EnvGuard {
prev_home: Option<String>,
@@ -44,10 +44,10 @@ struct EnvGuard {
impl EnvGuard {
fn acquire() -> Self {
let lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let prev_home = std::env::var("INSOMNIA_HOME").ok();
let prev_home = std::env::var("YOI_HOME").ok();
let prev_xdg = std::env::var("XDG_RUNTIME_DIR").ok();
unsafe {
std::env::remove_var("INSOMNIA_HOME");
std::env::remove_var("YOI_HOME");
std::env::remove_var("XDG_RUNTIME_DIR");
}
Self {
@@ -62,14 +62,14 @@ impl Drop for EnvGuard {
fn drop(&mut self) {
unsafe {
match &self.prev_home {
Some(v) => std::env::set_var("INSOMNIA_HOME", v),
None => std::env::remove_var("INSOMNIA_HOME"),
Some(v) => std::env::set_var("YOI_HOME", v),
None => std::env::remove_var("YOI_HOME"),
}
match &self.prev_xdg {
Some(v) => std::env::set_var("XDG_RUNTIME_DIR", v),
None => std::env::remove_var("XDG_RUNTIME_DIR"),
}
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
std::env::remove_var("YOI_RUNTIME_DIR");
}
}
}
@@ -400,7 +400,7 @@ async fn stop_pod_sends_shutdown_and_releases_scope() {
.unwrap(),
);
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", tmp.path());
std::env::set_var("YOI_RUNTIME_DIR", tmp.path());
}
let lock_path = tmp.path().join("pods.json");
@@ -486,7 +486,7 @@ async fn stop_pod_succeeds_even_when_child_unreachable() {
let _env = EnvGuard::acquire();
let (tmp, registry, _rd) = setup_registry().await;
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", tmp.path());
std::env::set_var("YOI_RUNTIME_DIR", tmp.path());
}
// No live listener — socket never bound. Registered record points
@@ -518,7 +518,7 @@ async fn restored_registry_uses_pod_state_without_runtime_file() {
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
);
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", runtime_tmp.path());
std::env::set_var("YOI_RUNTIME_DIR", runtime_tmp.path());
}
let rd = Arc::new(
@@ -633,7 +633,7 @@ async fn load_from_pod_state_reclaims_missing_child_scope_and_records_history()
FsPodStore::new(store_tmp.path().join("pods")).unwrap(),
);
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", runtime_tmp.path());
std::env::set_var("YOI_RUNTIME_DIR", runtime_tmp.path());
}
let rd = Arc::new(
RuntimeDir::create(runtime_tmp.path(), "spawner")
+10 -10
View File
@@ -18,11 +18,11 @@ use protocol::{Event, Greeting, Method, Permission, PodEvent, PodStatus, ScopeRu
use tempfile::TempDir;
use tokio::net::UnixListener;
/// Serialises tests that mutate `INSOMNIA_RUNTIME_DIR`.
/// Serialises tests that mutate `YOI_RUNTIME_DIR`.
static ENV_LOCK: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
/// Take `ENV_LOCK` and clear any env vars that would outrank
/// `INSOMNIA_RUNTIME_DIR`; restore previous values on drop.
/// `YOI_RUNTIME_DIR`; restore previous values on drop.
struct EnvGuard {
prev_home: Option<String>,
prev_xdg: Option<String>,
@@ -32,10 +32,10 @@ struct EnvGuard {
impl EnvGuard {
fn acquire() -> Self {
let lock = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let prev_home = std::env::var("INSOMNIA_HOME").ok();
let prev_home = std::env::var("YOI_HOME").ok();
let prev_xdg = std::env::var("XDG_RUNTIME_DIR").ok();
unsafe {
std::env::remove_var("INSOMNIA_HOME");
std::env::remove_var("YOI_HOME");
std::env::remove_var("XDG_RUNTIME_DIR");
}
Self {
@@ -50,29 +50,29 @@ impl Drop for EnvGuard {
fn drop(&mut self) {
unsafe {
match &self.prev_home {
Some(v) => std::env::set_var("INSOMNIA_HOME", v),
None => std::env::remove_var("INSOMNIA_HOME"),
Some(v) => std::env::set_var("YOI_HOME", v),
None => std::env::remove_var("YOI_HOME"),
}
match &self.prev_xdg {
Some(v) => std::env::set_var("XDG_RUNTIME_DIR", v),
None => std::env::remove_var("XDG_RUNTIME_DIR"),
}
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
std::env::remove_var("YOI_RUNTIME_DIR");
}
}
}
/// Point `INSOMNIA_RUNTIME_DIR` at `dir`. The pod-registry then lives at
/// Point `YOI_RUNTIME_DIR` at `dir`. The pod-registry then lives at
/// `<dir>/pods.json` and Pod runtime sub-dirs at `<dir>/{pod_name}/`.
fn set_runtime_dir(dir: &std::path::Path) {
unsafe {
std::env::set_var("INSOMNIA_RUNTIME_DIR", dir);
std::env::set_var("YOI_RUNTIME_DIR", dir);
}
}
fn clear_runtime_dir() {
unsafe {
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
std::env::remove_var("YOI_RUNTIME_DIR");
}
}
+5 -5
View File
@@ -26,7 +26,7 @@ use std::sync::Arc;
use tempfile::TempDir;
use tokio::net::UnixListener;
/// Serialises tests that mutate `INSOMNIA_RUNTIME_DIR` across the
/// Serialises tests that mutate `YOI_RUNTIME_DIR` across the
/// thread-pooled test harness.
static ENV_LOCK: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
@@ -42,7 +42,7 @@ impl EnvGuard {
}
}
/// Set up a tempdir, point `INSOMNIA_RUNTIME_DIR` at it (so
/// Set up a tempdir, point `YOI_RUNTIME_DIR` at it (so
/// `pods.json` and per-Pod runtime subdirs both land in the
/// sandbox), and install a live top-level "spawner" allocation so the
/// tool has something to delegate from. Returns the tempdir (keeps it
@@ -57,9 +57,9 @@ async fn setup_spawner(
unsafe {
// Outranking env vars must be cleared so `paths::runtime_dir`
// resolves to our sandbox instead of the developer's real one.
std::env::remove_var("INSOMNIA_HOME");
std::env::remove_var("YOI_HOME");
std::env::remove_var("XDG_RUNTIME_DIR");
std::env::set_var("INSOMNIA_RUNTIME_DIR", &runtime_base);
std::env::set_var("YOI_RUNTIME_DIR", &runtime_base);
}
let spawner_rd = RuntimeDir::create(&runtime_base, spawner_name)
@@ -209,7 +209,7 @@ fn shared_scope_for(allow_root: &Path) -> SharedScope {
fn clear_env() {
unsafe {
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
std::env::remove_var("YOI_RUNTIME_DIR");
}
}