fix: rename installed binaries
This commit is contained in:
parent
e7b89a169c
commit
1e8c11c564
|
|
@ -1,4 +1,4 @@
|
||||||
//! pod バイナリをサブプロセスとして立ち上げ、`INSOMNIA-READY` を待つ
|
//! `insomnia-pod` バイナリをサブプロセスとして立ち上げ、`INSOMNIA-READY` を待つ
|
||||||
//! ハンドシェイク。
|
//! ハンドシェイク。
|
||||||
//!
|
//!
|
||||||
//! - 親プロセス (TUI / GUI / E2E) は overlay TOML を組み立ててこの関数に
|
//! - 親プロセス (TUI / GUI / E2E) は overlay TOML を組み立ててこの関数に
|
||||||
|
|
@ -258,7 +258,7 @@ async fn drain_stderr_into_tail(stderr_path: &Path, tail: &mut StderrTail, offse
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the binary used to launch a child Pod. Must point at a
|
/// Resolves the binary used to launch a child Pod. Must point at a
|
||||||
/// `pod`-compatible executable — the parent reads the child's stderr
|
/// `insomnia-pod`-compatible executable — the parent reads the child's stderr
|
||||||
/// directly looking for `INSOMNIA-READY`, so any wrapper that emits
|
/// directly looking for `INSOMNIA-READY`, so any wrapper that emits
|
||||||
/// extra lines on stderr will pollute that handshake.
|
/// extra lines on stderr will pollute that handshake.
|
||||||
///
|
///
|
||||||
|
|
@ -271,7 +271,7 @@ fn resolve_pod_command() -> PathBuf {
|
||||||
{
|
{
|
||||||
return PathBuf::from(cmd);
|
return PathBuf::from(cmd);
|
||||||
}
|
}
|
||||||
PathBuf::from("pod")
|
PathBuf::from("insomnia-pod")
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StderrTail {
|
struct StderrTail {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ version = "0.1.0"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "insomnia-pod"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
clap = { version = "4.6.0", features = ["derive"] }
|
clap = { version = "4.6.0", features = ["derive"] }
|
||||||
|
|
|
||||||
|
|
@ -596,7 +596,7 @@ fn resolve_pod_command() -> PathBuf {
|
||||||
{
|
{
|
||||||
return PathBuf::from(cmd);
|
return PathBuf::from(cmd);
|
||||||
}
|
}
|
||||||
PathBuf::from("pod")
|
PathBuf::from("insomnia-pod")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, JsonSchema)]
|
#[derive(Debug, Deserialize, JsonSchema)]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use session_store::{FsStore, PodMetadataStore, SegmentId, Store};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[command(
|
#[command(
|
||||||
name = "pod",
|
name = "insomnia-pod",
|
||||||
about = "Spawn a Pod process from manifest layers or a single manifest file"
|
about = "Spawn a Pod process from manifest layers or a single manifest file"
|
||||||
)]
|
)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
|
|
@ -364,19 +364,25 @@ permission = "write"
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn user_manifest_flag_is_not_accepted() {
|
fn user_manifest_flag_is_not_accepted() {
|
||||||
let err = Cli::try_parse_from(["pod", "--user-manifest", "manifest.toml"]).unwrap_err();
|
let err =
|
||||||
|
Cli::try_parse_from(["insomnia-pod", "--user-manifest", "manifest.toml"]).unwrap_err();
|
||||||
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
|
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn manifest_conflicts_with_project_and_overlay() {
|
fn manifest_conflicts_with_project_and_overlay() {
|
||||||
let project_err =
|
let project_err = Cli::try_parse_from([
|
||||||
Cli::try_parse_from(["pod", "--manifest", "manifest.toml", "--project", "."])
|
"insomnia-pod",
|
||||||
.unwrap_err();
|
"--manifest",
|
||||||
|
"manifest.toml",
|
||||||
|
"--project",
|
||||||
|
".",
|
||||||
|
])
|
||||||
|
.unwrap_err();
|
||||||
assert_eq!(project_err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
assert_eq!(project_err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||||
|
|
||||||
let overlay_err = Cli::try_parse_from([
|
let overlay_err = Cli::try_parse_from([
|
||||||
"pod",
|
"insomnia-pod",
|
||||||
"--manifest",
|
"--manifest",
|
||||||
"manifest.toml",
|
"manifest.toml",
|
||||||
"--overlay",
|
"--overlay",
|
||||||
|
|
@ -391,7 +397,8 @@ permission = "write"
|
||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let manifest = tmp.path().join("manifest.toml");
|
let manifest = tmp.path().join("manifest.toml");
|
||||||
write(&manifest, &manifest_toml("single", tmp.path()));
|
write(&manifest, &manifest_toml("single", tmp.path()));
|
||||||
let cli = Cli::try_parse_from(["pod", "--manifest", manifest.to_str().unwrap()]).unwrap();
|
let cli = Cli::try_parse_from(["insomnia-pod", "--manifest", manifest.to_str().unwrap()])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let err = resolve_manifest_with_user_manifest_env(&cli, Some(OsString::from("user.toml")))
|
let err = resolve_manifest_with_user_manifest_env(&cli, Some(OsString::from("user.toml")))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
@ -405,7 +412,8 @@ permission = "write"
|
||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let manifest = tmp.path().join("manifest.toml");
|
let manifest = tmp.path().join("manifest.toml");
|
||||||
write(&manifest, &manifest_toml("single", tmp.path()));
|
write(&manifest, &manifest_toml("single", tmp.path()));
|
||||||
let cli = Cli::try_parse_from(["pod", "--manifest", manifest.to_str().unwrap()]).unwrap();
|
let cli = Cli::try_parse_from(["insomnia-pod", "--manifest", manifest.to_str().unwrap()])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (manifest, loader) =
|
let (manifest, loader) =
|
||||||
resolve_manifest_with_user_manifest_env(&cli, Some(OsString::new())).unwrap();
|
resolve_manifest_with_user_manifest_env(&cli, Some(OsString::new())).unwrap();
|
||||||
|
|
@ -422,8 +430,12 @@ permission = "write"
|
||||||
write(&user_manifest, &manifest_toml("from-env", tmp.path()));
|
write(&user_manifest, &manifest_toml("from-env", tmp.path()));
|
||||||
let no_project_root = tmp.path().join("no-project");
|
let no_project_root = tmp.path().join("no-project");
|
||||||
std::fs::create_dir_all(&no_project_root).unwrap();
|
std::fs::create_dir_all(&no_project_root).unwrap();
|
||||||
let cli =
|
let cli = Cli::try_parse_from([
|
||||||
Cli::try_parse_from(["pod", "--project", no_project_root.to_str().unwrap()]).unwrap();
|
"insomnia-pod",
|
||||||
|
"--project",
|
||||||
|
no_project_root.to_str().unwrap(),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (manifest, _loader) = resolve_manifest_with_user_manifest_env(
|
let (manifest, _loader) = resolve_manifest_with_user_manifest_env(
|
||||||
&cli,
|
&cli,
|
||||||
|
|
@ -438,8 +450,8 @@ permission = "write"
|
||||||
fn pod_flag_conflicts_with_session() {
|
fn pod_flag_conflicts_with_session() {
|
||||||
let segment_id = session_store::new_segment_id();
|
let segment_id = session_store::new_segment_id();
|
||||||
let segment_id = segment_id.to_string();
|
let segment_id = segment_id.to_string();
|
||||||
let err =
|
let err = Cli::try_parse_from(["insomnia-pod", "--pod", "agent", "--session", &segment_id])
|
||||||
Cli::try_parse_from(["pod", "--pod", "agent", "--session", &segment_id]).unwrap_err();
|
.unwrap_err();
|
||||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,7 +461,7 @@ permission = "write"
|
||||||
let manifest = tmp.path().join("manifest.toml");
|
let manifest = tmp.path().join("manifest.toml");
|
||||||
write(&manifest, &manifest_toml("from-file", tmp.path()));
|
write(&manifest, &manifest_toml("from-file", tmp.path()));
|
||||||
let cli = Cli::try_parse_from([
|
let cli = Cli::try_parse_from([
|
||||||
"pod",
|
"insomnia-pod",
|
||||||
"--manifest",
|
"--manifest",
|
||||||
manifest.to_str().unwrap(),
|
manifest.to_str().unwrap(),
|
||||||
"--pod",
|
"--pod",
|
||||||
|
|
@ -471,7 +483,7 @@ permission = "write"
|
||||||
&manifest_toml("unused", tmp.path()).replace("name = \"unused\"\n", ""),
|
&manifest_toml("unused", tmp.path()).replace("name = \"unused\"\n", ""),
|
||||||
);
|
);
|
||||||
let cli = Cli::try_parse_from([
|
let cli = Cli::try_parse_from([
|
||||||
"pod",
|
"insomnia-pod",
|
||||||
"--manifest",
|
"--manifest",
|
||||||
manifest.to_str().unwrap(),
|
manifest.to_str().unwrap(),
|
||||||
"--pod",
|
"--pod",
|
||||||
|
|
@ -491,8 +503,12 @@ permission = "write"
|
||||||
write(&single_manifest, &manifest_toml("single-file", tmp.path()));
|
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("prompts")).unwrap();
|
||||||
std::fs::create_dir_all(tmp.path().join(".insomnia").join("prompts")).unwrap();
|
std::fs::create_dir_all(tmp.path().join(".insomnia").join("prompts")).unwrap();
|
||||||
let cli =
|
let cli = Cli::try_parse_from([
|
||||||
Cli::try_parse_from(["pod", "--manifest", single_manifest.to_str().unwrap()]).unwrap();
|
"insomnia-pod",
|
||||||
|
"--manifest",
|
||||||
|
single_manifest.to_str().unwrap(),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (manifest, loader) = resolve_manifest_with_user_manifest_env(&cli, None).unwrap();
|
let (manifest, loader) = resolve_manifest_with_user_manifest_env(&cli, None).unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! Wires pod-registry delegation, overlay-TOML construction, subprocess
|
//! Wires pod-registry delegation, overlay-TOML construction, subprocess
|
||||||
//! launch, and socket handoff into a single `Tool` implementation. When
|
//! launch, and socket handoff into a single `Tool` implementation. When
|
||||||
//! the LLM calls `SpawnPod`, a fresh `pod` binary is exec'd in its own
|
//! the LLM calls `SpawnPod`, a fresh `insomnia-pod` binary is exec'd in its own
|
||||||
//! process group, the pod-registry is updated atomically, and the child's
|
//! process group, the pod-registry is updated atomically, and the child's
|
||||||
//! first turn is kicked off by handing its socket a `Method::Run`.
|
//! first turn is kicked off by handing its socket a `Method::Run`.
|
||||||
|
|
||||||
|
|
@ -303,7 +303,8 @@ impl SpawnPodTool {
|
||||||
overlay_toml: &str,
|
overlay_toml: &str,
|
||||||
predicted_socket: &Path,
|
predicted_socket: &Path,
|
||||||
) -> Result<(), ToolError> {
|
) -> Result<(), ToolError> {
|
||||||
let pod_command = std::env::var("INSOMNIA_POD_COMMAND").unwrap_or_else(|_| "pod".into());
|
let pod_command =
|
||||||
|
std::env::var("INSOMNIA_POD_COMMAND").unwrap_or_else(|_| "insomnia-pod".into());
|
||||||
|
|
||||||
// Pre-create the child's runtime dir so we have a stable place to
|
// Pre-create the child's runtime dir so we have a stable place to
|
||||||
// capture its stderr before it has had a chance to bind anything.
|
// capture its stderr before it has had a chance to bind anything.
|
||||||
|
|
@ -381,7 +382,7 @@ fn parse_scope(rules: &[ScopeRuleInput]) -> Result<Vec<ScopeRule>, ToolError> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialise the overlay TOML that gets handed to the child `pod`
|
/// Serialise the overlay TOML that gets handed to the child `insomnia-pod`
|
||||||
/// binary via `--overlay`. `PodManifestConfig`'s `Serialize` impl is
|
/// binary via `--overlay`. `PodManifestConfig`'s `Serialize` impl is
|
||||||
/// the single source of truth for the on-disk manifest format.
|
/// the single source of truth for the on-disk manifest format.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! These tests exercise the tool's pod-registry delegation, subprocess
|
//! These tests exercise the tool's pod-registry delegation, subprocess
|
||||||
//! launch, socket handoff, and `spawned_pods.json` write without relying
|
//! launch, socket handoff, and `spawned_pods.json` write without relying
|
||||||
//! on the real `pod` binary. `INSOMNIA_POD_COMMAND` is pointed at
|
//! on the real `insomnia-pod` binary. `INSOMNIA_POD_COMMAND` is pointed at
|
||||||
//! `/bin/true` (which exits immediately) while a test-owned Unix
|
//! `/bin/true` (which exits immediately) while a test-owned Unix
|
||||||
//! listener pre-binds the predicted socket path, so the tool sees the
|
//! listener pre-binds the predicted socket path, so the tool sees the
|
||||||
//! "child" as live.
|
//! "child" as live.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ version = "0.1.0"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "insomnia"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
client = { workspace = true }
|
client = { workspace = true }
|
||||||
protocol = { workspace = true }
|
protocol = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -61,20 +61,20 @@ fn resolve_socket(pod_name: &str, override_path: Option<PathBuf>) -> PathBuf {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Mode {
|
enum Mode {
|
||||||
Spawn,
|
Spawn,
|
||||||
/// `tui <name>` / `tui --pod <name>`: attach to a live Pod by name if
|
/// `insomnia <name>` / `insomnia --pod <name>`: attach to a live Pod by name if
|
||||||
/// possible; otherwise launch `pod --pod <name>` so the pod process
|
/// possible; otherwise launch `insomnia-pod --pod <name>` so the pod process
|
||||||
/// resumes from name-keyed state or creates a fresh same-name Pod.
|
/// resumes from name-keyed state or creates a fresh same-name Pod.
|
||||||
PodName {
|
PodName {
|
||||||
pod_name: String,
|
pod_name: String,
|
||||||
socket_override: Option<PathBuf>,
|
socket_override: Option<PathBuf>,
|
||||||
},
|
},
|
||||||
/// `tui -r` / `tui --resume`: open the Pod picker, then attach to the
|
/// `insomnia -r` / `insomnia --resume`: open the Pod picker, then attach to the
|
||||||
/// selected live Pod or restore the selected stopped Pod by name.
|
/// selected live Pod or restore the selected stopped Pod by name.
|
||||||
Resume,
|
Resume,
|
||||||
/// `tui --session <UUID>`: skip the picker, go straight to the
|
/// `insomnia --session <UUID>`: skip the picker, go straight to the
|
||||||
/// resume name dialog with `id` baked in.
|
/// resume name dialog with `id` baked in.
|
||||||
ResumeWithSession(SegmentId),
|
ResumeWithSession(SegmentId),
|
||||||
/// `tui --multi`: open the multi-Pod dashboard. This is intentionally
|
/// `insomnia --multi`: open the multi-Pod dashboard. This is intentionally
|
||||||
/// separate from `-r`/`--resume`, which keeps its single-Pod picker
|
/// separate from `-r`/`--resume`, which keeps its single-Pod picker
|
||||||
/// meaning.
|
/// meaning.
|
||||||
Multi,
|
Multi,
|
||||||
|
|
@ -232,18 +232,18 @@ async fn main() -> ExitCode {
|
||||||
let mode = match parse_args() {
|
let mode = match parse_args() {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("tui: {e}");
|
eprintln!("insomnia: {e}");
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = enable_raw_mode() {
|
if let Err(e) = enable_raw_mode() {
|
||||||
eprintln!("tui: failed to enter raw mode: {e}");
|
eprintln!("insomnia: failed to enter raw mode: {e}");
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
}
|
}
|
||||||
if let Err(e) = execute!(io::stdout(), EnableBracketedPaste) {
|
if let Err(e) = execute!(io::stdout(), EnableBracketedPaste) {
|
||||||
let _ = disable_raw_mode();
|
let _ = disable_raw_mode();
|
||||||
eprintln!("tui: {e}");
|
eprintln!("insomnia: {e}");
|
||||||
return ExitCode::FAILURE;
|
return ExitCode::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +280,7 @@ async fn main() -> ExitCode {
|
||||||
// duplicate. Other errors (pod-name failures, terminal setup
|
// duplicate. Other errors (pod-name failures, terminal setup
|
||||||
// hiccups, etc.) need surfacing here.
|
// hiccups, etc.) need surfacing here.
|
||||||
if e.downcast_ref::<spawn::SpawnError>().is_none() {
|
if e.downcast_ref::<spawn::SpawnError>().is_none() {
|
||||||
eprintln!("tui: {e}");
|
eprintln!("insomnia: {e}");
|
||||||
}
|
}
|
||||||
ExitCode::FAILURE
|
ExitCode::FAILURE
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl std::fmt::Display for MultiPodError {
|
||||||
Self::Store(e) => write!(f, "session store error: {e}"),
|
Self::Store(e) => write!(f, "session store error: {e}"),
|
||||||
Self::NoPods => write!(
|
Self::NoPods => write!(
|
||||||
f,
|
f,
|
||||||
"no pods found — start a fresh pod with `tui` or restore one with `tui -r`"
|
"no pods found — start a fresh pod with `insomnia` or restore one with `insomnia -r`"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! Reads live Pod allocations from the runtime registry and stopped Pod state
|
//! Reads live Pod allocations from the runtime registry and stopped Pod state
|
||||||
//! from the session store's name-keyed metadata. Picking a live row attaches to
|
//! from the session store's name-keyed metadata. Picking a live row attaches to
|
||||||
//! its socket; picking a stopped row restores via `pod --pod <name>`.
|
//! its socket; picking a stopped row restores via `insomnia-pod --pod <name>`.
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -41,7 +41,7 @@ impl std::fmt::Display for PickerError {
|
||||||
Self::Store(e) => write!(f, "session store error: {e}"),
|
Self::Store(e) => write!(f, "session store error: {e}"),
|
||||||
Self::NoPods => write!(
|
Self::NoPods => write!(
|
||||||
f,
|
f,
|
||||||
"no pods found — start a fresh pod with `tui` and try again"
|
"no pods found — start a fresh pod with `insomnia` and try again"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ impl From<session_store::StoreError> for PickerError {
|
||||||
pub enum PickerOutcome {
|
pub enum PickerOutcome {
|
||||||
/// User picked a Pod. `socket_override` is set for live rows when the
|
/// User picked a Pod. `socket_override` is set for live rows when the
|
||||||
/// runtime registry knows the exact socket path; stopped rows leave it
|
/// runtime registry knows the exact socket path; stopped rows leave it
|
||||||
/// empty so the caller restores with `pod --pod <name>`.
|
/// empty so the caller restores with `insomnia-pod --pod <name>`.
|
||||||
Picked {
|
Picked {
|
||||||
pod_name: String,
|
pod_name: String,
|
||||||
socket_override: Option<PathBuf>,
|
socket_override: Option<PathBuf>,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
//! Inline-viewport "spawn Pod and attach" UX.
|
//! Inline-viewport "spawn Pod and attach" UX.
|
||||||
//!
|
//!
|
||||||
//! Rendered at the user's current cursor position when `tui` is invoked
|
//! Rendered at the user's current cursor position when `insomnia` is invoked
|
||||||
//! with no positional argument. Walks the cwd for a `.insomnia/manifest.toml`
|
//! with no positional argument. Walks the cwd for a `.insomnia/manifest.toml`
|
||||||
//! to seed defaults, prompts for the Pod's name, and on confirmation
|
//! to seed defaults, prompts for the Pod's name, and on confirmation
|
||||||
//! launches the `pod` binary as an independent process with a freshly built
|
//! launches the `insomnia-pod` binary as an independent process with a freshly built
|
||||||
//! overlay (name + cwd scope when no project manifest exists). Once
|
//! overlay (name + cwd scope when no project manifest exists). Once
|
||||||
//! the process reports its socket via the `INSOMNIA-READY` stderr line,
|
//! the process reports its socket via the `INSOMNIA-READY` stderr line,
|
||||||
//! the dialog hands control back so main can switch the terminal to
|
//! the dialog hands control back so main can switch the terminal to
|
||||||
|
|
@ -90,7 +90,7 @@ type InlineTerminal = Terminal<CrosstermBackend<io::Stdout>>;
|
||||||
|
|
||||||
/// Source session for a resume run. `None` = fresh spawn (current
|
/// Source session for a resume run. `None` = fresh spawn (current
|
||||||
/// behaviour); `Some(id)` swaps the dialog into "Resume Pod" mode and
|
/// behaviour); `Some(id)` swaps the dialog into "Resume Pod" mode and
|
||||||
/// passes `--session <id>` to the spawned `pod` child.
|
/// passes `--session <id>` to the spawned `insomnia-pod` child.
|
||||||
pub async fn run(resume_from: Option<SegmentId>) -> Result<SpawnOutcome, SpawnError> {
|
pub async fn run(resume_from: Option<SegmentId>) -> Result<SpawnOutcome, SpawnError> {
|
||||||
let defaults = load_spawn_defaults()?;
|
let defaults = load_spawn_defaults()?;
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ pub async fn run(resume_from: Option<SegmentId>) -> Result<SpawnOutcome, SpawnEr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch `pod --pod <name>` without opening the name dialog. The child Pod
|
/// Launch `insomnia-pod --pod <name>` without opening the name dialog. The child Pod
|
||||||
/// resolves persisted Pod metadata if present, or creates a fresh same-name Pod
|
/// resolves persisted Pod metadata if present, or creates a fresh same-name Pod
|
||||||
/// with the usual TUI cwd-scope fallback.
|
/// with the usual TUI cwd-scope fallback.
|
||||||
pub async fn run_pod_name(pod_name: String) -> Result<SpawnOutcome, SpawnError> {
|
pub async fn run_pod_name(pod_name: String) -> Result<SpawnOutcome, SpawnError> {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
let
|
let
|
||||||
# Dev-only wrapper. tui の spawn 経路は `pod` バイナリを直に exec し、
|
# Dev-only wrapper. tui の spawn 経路は `insomnia-pod` バイナリを直に exec し、
|
||||||
# stderr の `INSOMNIA-READY` 行で握手するので、cargo の進捗や rustc の
|
# stderr の `INSOMNIA-READY` 行で握手するので、cargo の進捗や rustc の
|
||||||
# warning が混ざると tail に余計な行が積もり本当のエラーが押し出される。
|
# warning が混ざると tail に余計な行が積もり本当のエラーが押し出される。
|
||||||
# ここで一度ビルドを切り離し、成功時はビルド出力を一切捨てて素のバイナリ
|
# ここで一度ビルドを切り離し、成功時はビルド出力を一切捨てて素のバイナリ
|
||||||
# を exec、失敗時のみ build log を stderr に流して exit する。
|
# を exec、失敗時のみ build log を stderr に流して exit する。
|
||||||
pod-dev = pkgs.writeShellScriptBin "pod" ''
|
pod-dev = pkgs.writeShellScriptBin "insomnia-pod" ''
|
||||||
set -u
|
set -u
|
||||||
buildlog=$(mktemp)
|
buildlog=$(mktemp)
|
||||||
trap 'rm -f "$buildlog"' EXIT
|
trap 'rm -f "$buildlog"' EXIT
|
||||||
|
|
@ -15,7 +15,7 @@ let
|
||||||
fi
|
fi
|
||||||
manifest=$(cargo locate-project --workspace --message-format plain 2>/dev/null)
|
manifest=$(cargo locate-project --workspace --message-format plain 2>/dev/null)
|
||||||
target_dir=''${CARGO_TARGET_DIR:-$(dirname "$manifest")/target}
|
target_dir=''${CARGO_TARGET_DIR:-$(dirname "$manifest")/target}
|
||||||
exec "$target_dir/debug/pod" "$@"
|
exec "$target_dir/debug/insomnia-pod" "$@"
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
pkgs.mkShell {
|
pkgs.mkShell {
|
||||||
|
|
|
||||||
18
docs/nix.md
18
docs/nix.md
|
|
@ -10,12 +10,12 @@ From the repository root:
|
||||||
nix build .#
|
nix build .#
|
||||||
```
|
```
|
||||||
|
|
||||||
The default package is implemented by `package.nix` and builds the Cargo workspace binaries `pod` and `tui`. The derivation uses the checked-in `Cargo.lock`, so Cargo dependencies are fetched by the normal Nix Rust packaging path instead of by network access during the build.
|
The default package is implemented by `package.nix` and builds the Cargo packages `pod` and `tui` as installed binaries `insomnia-pod` and `insomnia`. The derivation uses the checked-in `Cargo.lock`, so Cargo dependencies are fetched by the normal Nix Rust packaging path instead of by network access during the build.
|
||||||
|
|
||||||
The package output contains:
|
The package output contains:
|
||||||
|
|
||||||
- `bin/pod` — Pod CLI / runtime process.
|
- `bin/insomnia-pod` — Pod CLI / runtime process.
|
||||||
- `bin/tui` — terminal UI.
|
- `bin/insomnia` — terminal UI.
|
||||||
- `share/insomnia/resources/` — bundled runtime resources, including `resources/prompts/`.
|
- `share/insomnia/resources/` — bundled runtime resources, including `resources/prompts/`.
|
||||||
- `share/doc/insomnia/nix.md` — this document.
|
- `share/doc/insomnia/nix.md` — this document.
|
||||||
|
|
||||||
|
|
@ -24,15 +24,15 @@ The package output contains:
|
||||||
After `nix build`:
|
After `nix build`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./result/bin/pod --help
|
./result/bin/insomnia-pod --help
|
||||||
./result/bin/tui
|
./result/bin/insomnia
|
||||||
```
|
```
|
||||||
|
|
||||||
With flakes:
|
With flakes:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nix run .#tui
|
nix run .#insomnia
|
||||||
nix run .#pod -- --help
|
nix run .#insomnia-pod -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
`nix run .#` defaults to the TUI.
|
`nix run .#` defaults to the TUI.
|
||||||
|
|
@ -53,8 +53,8 @@ The Nix package does not put user configuration, sessions, sockets, or other mut
|
||||||
|
|
||||||
The package derivation has a credential-free install check that verifies:
|
The package derivation has a credential-free install check that verifies:
|
||||||
|
|
||||||
- `pod --help` starts successfully.
|
- `insomnia-pod --help` starts successfully.
|
||||||
- `tui` is installed and reaches argument parsing.
|
- `insomnia` is installed and reaches argument parsing.
|
||||||
- bundled prompt resources and this Nix usage document are present in the output.
|
- bundled prompt resources and this Nix usage document are present in the output.
|
||||||
|
|
||||||
For full validation before handing changes to review, run:
|
For full validation before handing changes to review, run:
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ unique であれば workspace を指定しなくて済む。
|
||||||
## Daemon-less リモート Pod 生成(SSH-only モデル)
|
## Daemon-less リモート Pod 生成(SSH-only モデル)
|
||||||
|
|
||||||
リモートホスト上の Pod 生成は **daemon 無しで SSH だけで成立する**。
|
リモートホスト上の Pod 生成は **daemon 無しで SSH だけで成立する**。
|
||||||
remote 側に必要なのは `pod` バイナリと SSH アクセスのみ。
|
remote 側に必要なのは `insomnia-pod` バイナリと SSH アクセスのみ。
|
||||||
|
|
||||||
### 前提
|
### 前提
|
||||||
|
|
||||||
|
|
@ -182,7 +182,7 @@ remote 側に必要なのは `pod` バイナリと SSH アクセスのみ。
|
||||||
- insomnia が転送するのは**セッション(会話履歴)と manifest overlay**
|
- insomnia が転送するのは**セッション(会話履歴)と manifest overlay**
|
||||||
だけ。コードベースの同期は外部に委ねる
|
だけ。コードベースの同期は外部に委ねる
|
||||||
- コンテナ内で動かすか bare metal で動かすかも insomnia は問わない。
|
- コンテナ内で動かすか bare metal で動かすかも insomnia は問わない。
|
||||||
`pod` バイナリが動くホストの fs 上で活動する主体がある、
|
`insomnia-pod` バイナリが動くホストの fs 上で活動する主体がある、
|
||||||
それだけが前提
|
それだけが前提
|
||||||
|
|
||||||
### フロー
|
### フロー
|
||||||
|
|
@ -193,7 +193,7 @@ host_a (spawner) host_b (remote)
|
||||||
│
|
│
|
||||||
├── ssh: session データを転送 ────────→ ファイル書き込み
|
├── ssh: session データを転送 ────────→ ファイル書き込み
|
||||||
├── ssh: overlay TOML を転送 ─────────→ ファイル書き込み
|
├── ssh: overlay TOML を転送 ─────────→ ファイル書き込み
|
||||||
├── ssh: `pod --overlay ... &` ───────→ Pod プロセス起動、socket 作成
|
├── ssh: `insomnia-pod --overlay ... &` ───────→ Pod プロセス起動、socket 作成
|
||||||
├── ssh -L: socket を tunnel ─────────→ Pod B の unix socket
|
├── ssh -L: socket を tunnel ─────────→ Pod B の unix socket
|
||||||
│
|
│
|
||||||
└── localhost:tunnel に接続 ──────────→ Method::Run / Event stream
|
└── localhost:tunnel に接続 ──────────→ Method::Run / Event stream
|
||||||
|
|
@ -209,7 +209,7 @@ tar cz session/ | ssh insomnia@host-b "tar xz -C ~/workspaces/task-123/store"
|
||||||
echo "$OVERLAY" | ssh insomnia@host-b "cat > ~/workspaces/task-123/overlay.toml"
|
echo "$OVERLAY" | ssh insomnia@host-b "cat > ~/workspaces/task-123/overlay.toml"
|
||||||
|
|
||||||
# 2. Pod を起動(detach)
|
# 2. Pod を起動(detach)
|
||||||
ssh insomnia@host-b "pod --store ~/workspaces/task-123/store \
|
ssh insomnia@host-b "insomnia-pod --store ~/workspaces/task-123/store \
|
||||||
--overlay ~/workspaces/task-123/overlay.toml &"
|
--overlay ~/workspaces/task-123/overlay.toml &"
|
||||||
|
|
||||||
# 3. socket を tunnel で引っ張る
|
# 3. socket を tunnel で引っ張る
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ manifest 中のパス(`model.auth.file` / `scope.*.target` /
|
||||||
|
|
||||||
Pod の作業ディレクトリは manifest に含まれない。プロセス起動時の
|
Pod の作業ディレクトリは manifest に含まれない。プロセス起動時の
|
||||||
`std::env::current_dir()` がそのまま Pod の pwd となるため、別の作業
|
`std::env::current_dir()` がそのまま Pod の pwd となるため、別の作業
|
||||||
ディレクトリで Pod を走らせたい場合は `cd` してから `pod` を起動する
|
ディレクトリで Pod を走らせたい場合は `cd` してから `insomnia-pod` を起動する
|
||||||
(または `SpawnPod` が子に対して行っているように、親プロセス側で
|
(または `SpawnPod` が子に対して行っているように、親プロセス側で
|
||||||
`Command::current_dir` を明示する)。
|
`Command::current_dir` を明示する)。
|
||||||
|
|
||||||
|
|
@ -297,12 +297,12 @@ import-map 形式のプレフィックスで指定する:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## `pod` CLI
|
## `insomnia-pod` CLI
|
||||||
|
|
||||||
`pod` は通常、builtin default → user manifest → project manifest → overlay の cascade で manifest を解決して起動する。
|
`insomnia-pod` は通常、builtin default → user manifest → project manifest → overlay の cascade で manifest を解決して起動する。
|
||||||
|
|
||||||
```
|
```
|
||||||
pod [--project <path>] [--overlay <toml>] [-s/--store <path>] [--session <uuid>]
|
insomnia-pod [--project <path>] [--overlay <toml>] [-s/--store <path>] [--session <uuid>]
|
||||||
```
|
```
|
||||||
|
|
||||||
| フラグ | 説明 |
|
| フラグ | 説明 |
|
||||||
|
|
@ -323,15 +323,15 @@ user manifest は CLI フラグではなく、以下の規則で解決する。
|
||||||
単一ファイルだけで起動したい場合は cascade を使わず、`--manifest` を指定する。
|
単一ファイルだけで起動したい場合は cascade を使わず、`--manifest` を指定する。
|
||||||
|
|
||||||
```
|
```
|
||||||
pod --manifest <path> [-s/--store <path>] [--session <uuid>]
|
insomnia-pod --manifest <path> [-s/--store <path>] [--session <uuid>]
|
||||||
```
|
```
|
||||||
|
|
||||||
`--manifest` は指定 TOML 1 枚だけを `PodManifest::from_toml` で読み、user / project / overlay layer は一切読まない。したがって `--project`、`--overlay`、非空の `INSOMNIA_USER_MANIFEST` とは併用不可。
|
`--manifest` は指定 TOML 1 枚だけを `PodManifest::from_toml` で読み、user / project / overlay layer は一切読まない。したがって `--project`、`--overlay`、非空の `INSOMNIA_USER_MANIFEST` とは併用不可。
|
||||||
|
|
||||||
spawn 子 Pod 用の内部フラグとして `--adopt` と `--callback <path>` がある。これらは `SpawnPod` が scope allocation と親 callback socket を引き継がせるために使うもので、通常の手動起動では使わない。
|
spawn 子 Pod 用の内部フラグとして `--adopt` と `--callback <path>` がある。これらは `SpawnPod` が scope allocation と親 callback socket を引き継がせるために使うもので、通常の手動起動では使わない。
|
||||||
|
|
||||||
Pod の作業ディレクトリは `pod` 起動時の cwd が直接使われる。別ディレクトリで
|
Pod の作業ディレクトリは `insomnia-pod` 起動時の cwd が直接使われる。別ディレクトリで
|
||||||
動かしたい場合は `cd <path> && pod ...` のように外側で `cd` してから起動する。
|
動かしたい場合は `cd <path> && insomnia-pod ...` のように外側で `cd` してから起動する。
|
||||||
|
|
||||||
引数無しで起動すると、cwd + `manifest::paths` の自動解決だけで動く最小構成になる
|
引数無しで起動すると、cwd + `manifest::paths` の自動解決だけで動く最小構成になる
|
||||||
(overlay 無し、プロジェクトに `.insomnia/manifest.toml` があればそれを使う)。
|
(overlay 無し、プロジェクトに `.insomnia/manifest.toml` があればそれを使う)。
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ Running 中に割り込みたい場合、ほとんどのケースで `Ctrl-C`(
|
||||||
|
|
||||||
`Ctrl-X` は Running 中だけ Cancel、Idle / Paused では Shutdown。`Ctrl-C` は Running 中だけ Pod に `Method::Pause` を送り、それ以外では Pod は落とさず TUI プロセスだけ抜ける。`Ctrl-D` は常に Pod へ制御メソッドを送らず TUI プロセスだけ抜ける。
|
`Ctrl-X` は Running 中だけ Cancel、Idle / Paused では Shutdown。`Ctrl-C` は Running 中だけ Pod に `Method::Pause` を送り、それ以外では Pod は落とさず TUI プロセスだけ抜ける。`Ctrl-D` は常に Pod へ制御メソッドを送らず TUI プロセスだけ抜ける。
|
||||||
|
|
||||||
TUI のダイアログから Pod を起動する経路では、起動した Pod は TUI の子プロセスとして管理・終了されず、独立したプロセスとして残る。TUI 終了後は `tui <pod-name>` で再接続できる。
|
TUI のダイアログから Pod を起動する経路では、起動した Pod は TUI の子プロセスとして管理・終了されず、独立したプロセスとして残る。TUI 終了後は `insomnia <pod-name>` で再接続できる。
|
||||||
|
|
||||||
## 履歴メモ
|
## 履歴メモ
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@
|
||||||
packages.default = insomnia;
|
packages.default = insomnia;
|
||||||
packages.insomnia = insomnia;
|
packages.insomnia = insomnia;
|
||||||
|
|
||||||
apps.default = mkApp "tui" "Run the INSOMNIA terminal UI";
|
apps.default = mkApp "insomnia" "Run the INSOMNIA terminal UI";
|
||||||
apps.tui = mkApp "tui" "Run the INSOMNIA terminal UI";
|
apps.insomnia = mkApp "insomnia" "Run the INSOMNIA terminal UI";
|
||||||
apps.pod = mkApp "pod" "Run the INSOMNIA Pod CLI";
|
apps.insomnia-pod = mkApp "insomnia-pod" "Run the INSOMNIA Pod CLI";
|
||||||
|
|
||||||
checks.default = insomnia;
|
checks.default = insomnia;
|
||||||
|
|
||||||
|
|
|
||||||
12
package.nix
12
package.nix
|
|
@ -80,13 +80,13 @@ rustPlatform.buildRustPackage rec {
|
||||||
installCheckPhase = ''
|
installCheckPhase = ''
|
||||||
runHook preInstallCheck
|
runHook preInstallCheck
|
||||||
|
|
||||||
"$out/bin/pod" --help >/dev/null
|
"$out/bin/insomnia-pod" --help >/dev/null
|
||||||
test -x "$out/bin/tui"
|
test -x "$out/bin/insomnia"
|
||||||
if "$out/bin/tui" --session not-a-uuid 2>tui.err; then
|
if "$out/bin/insomnia" --session not-a-uuid 2>insomnia.err; then
|
||||||
echo "tui unexpectedly accepted an invalid --session value" >&2
|
echo "insomnia unexpectedly accepted an invalid --session value" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
grep -q "invalid --session UUID" tui.err
|
grep -q "invalid --session UUID" insomnia.err
|
||||||
|
|
||||||
test -d "$out/share/insomnia/resources/prompts"
|
test -d "$out/share/insomnia/resources/prompts"
|
||||||
test -f "$out/share/doc/insomnia/nix.md"
|
test -f "$out/share/doc/insomnia/nix.md"
|
||||||
|
|
@ -97,7 +97,7 @@ rustPlatform.buildRustPackage rec {
|
||||||
meta = {
|
meta = {
|
||||||
description = "Agentic coding Pod runtime and terminal UI";
|
description = "Agentic coding Pod runtime and terminal UI";
|
||||||
license = lib.licenses.mit;
|
license = lib.licenses.mit;
|
||||||
mainProgram = "tui";
|
mainProgram = "insomnia";
|
||||||
platforms = lib.platforms.unix;
|
platforms = lib.platforms.unix;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user