Skip to main content

kaish_tool_api/
ctx.rs

1//! The trimmed execution context exposed to tools.
2
3use std::any::Any;
4use std::path::{Path, PathBuf};
5use std::sync::Arc;
6
7use kaish_types::{OutputFormat, Value};
8
9use crate::backend::KernelBackend;
10
11/// The portable execution context a tool sees.
12///
13/// This is deliberately small: it carries only what a well-behaved,
14/// out-of-tree tool needs. The kernel's full `ExecContext` implements this
15/// trait; trusted in-tree builtins that need deeper state (job control,
16/// streaming pipes, the dispatcher) downcast through [`ToolCtx::as_any_mut`].
17///
18/// `Send + Sync` are supertraits because tool execution is async: a `&dyn
19/// ToolCtx` shared with an async helper is held across await points, and for
20/// the resulting future to be `Send` the referent must be `Sync`. The kernel's
21/// `ExecContext` already satisfies both.
22pub trait ToolCtx: Send + Sync {
23    /// The backend for file I/O and tool dispatch.
24    ///
25    /// Tools reach the VFS (and re-dispatch other tools) through this handle.
26    fn backend(&self) -> &Arc<dyn KernelBackend>;
27
28    /// The current working directory, as a VFS path.
29    fn cwd(&self) -> &Path;
30
31    /// Resolve a (possibly relative) path against the cwd, normalizing `.`
32    /// and `..` lexically. Never touches the real filesystem.
33    fn resolve_path(&self, path: &str) -> PathBuf;
34
35    /// Read a variable from the current scope, cloned.
36    ///
37    /// Returns `None` if the name is unset. Tools use this for configuration
38    /// supplied by the frontend (e.g. `HOSTNAME`).
39    fn var(&self, name: &str) -> Option<Value>;
40
41    /// Set a variable in the current scope.
42    fn set_var(&mut self, name: &str, value: Value);
43
44    /// Set the per-execution output format override (e.g. from `--json`).
45    ///
46    /// The dispatcher reads this after `execute()` returns and applies the
47    /// format to the result.
48    fn set_output_format(&mut self, format: OutputFormat);
49
50    /// Escape hatch for trusted in-tree tools: recover the concrete context.
51    ///
52    /// Out-of-tree tools must not rely on this — downcasting to a kernel type
53    /// is exactly the coupling this trait exists to avoid. It is here so
54    /// in-tree builtins needing job control / pipes / the dispatcher can keep
55    /// full access without those internals leaking into the public surface.
56    fn as_any(&self) -> &dyn Any;
57
58    /// Mutable counterpart to [`ToolCtx::as_any`].
59    fn as_any_mut(&mut self) -> &mut dyn Any;
60}