feat: add system metadata plugins for file info and user context

Co-authored-by: aider (openai/andrew.openrouter.qwen.qwen3-coder) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-07-29 12:45:03 -03:00
parent ca6a1a455c
commit 46d305f13d
2 changed files with 282 additions and 0 deletions

281
src/meta_plugin/system.rs Normal file
View File

@@ -0,0 +1,281 @@
use anyhow::Result;
use std::io;
use std::io::Write;
use std::env;
use std::process;
use uzers::{get_current_uid, get_current_gid, get_current_username, get_current_groupname, get_current_user};
use crate::meta_plugin::MetaPlugin;
#[derive(Debug, Clone, Default)]
pub struct CwdMetaPlugin {
meta_name: String,
}
impl CwdMetaPlugin {
pub fn new() -> CwdMetaPlugin {
CwdMetaPlugin {
meta_name: "cwd".to_string(),
}
}
}
impl MetaPlugin for CwdMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
match env::current_dir() {
Ok(path) => Ok(path.to_string_lossy().to_string()),
Err(_) => Ok("unknown".to_string()),
}
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct UidMetaPlugin {
meta_name: String,
}
impl UidMetaPlugin {
pub fn new() -> UidMetaPlugin {
UidMetaPlugin {
meta_name: "uid".to_string(),
}
}
}
impl MetaPlugin for UidMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
Ok(get_current_uid().to_string())
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct UserMetaPlugin {
meta_name: String,
}
impl UserMetaPlugin {
pub fn new() -> UserMetaPlugin {
UserMetaPlugin {
meta_name: "user".to_string(),
}
}
}
impl MetaPlugin for UserMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
match get_current_username() {
Some(username) => Ok(username.to_string_lossy().to_string()),
None => Ok("unknown".to_string()),
}
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct GidMetaPlugin {
meta_name: String,
}
impl GidMetaPlugin {
pub fn new() -> GidMetaPlugin {
GidMetaPlugin {
meta_name: "gid".to_string(),
}
}
}
impl MetaPlugin for GidMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
Ok(get_current_gid().to_string())
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct GroupMetaPlugin {
meta_name: String,
}
impl GroupMetaPlugin {
pub fn new() -> GroupMetaPlugin {
GroupMetaPlugin {
meta_name: "group".to_string(),
}
}
}
impl MetaPlugin for GroupMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
match get_current_groupname() {
Some(groupname) => Ok(groupname.to_string_lossy().to_string()),
None => Ok("unknown".to_string()),
}
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct ShellMetaPlugin {
meta_name: String,
}
impl ShellMetaPlugin {
pub fn new() -> ShellMetaPlugin {
ShellMetaPlugin {
meta_name: "shell".to_string(),
}
}
}
impl MetaPlugin for ShellMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
match env::var("SHELL") {
Ok(shell) => Ok(shell),
Err(_) => {
match get_current_user() {
Some(user) => {
match user.shell().to_str() {
Some(shell) => Ok(shell.to_string()),
None => Ok("unknown".to_string()),
}
},
None => Ok("unknown".to_string()),
}
}
}
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct ShellPidMetaPlugin {
meta_name: String,
}
impl ShellPidMetaPlugin {
pub fn new() -> ShellPidMetaPlugin {
ShellPidMetaPlugin {
meta_name: "shell_pid".to_string(),
}
}
}
impl MetaPlugin for ShellPidMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
match env::var("PPID") {
Ok(ppid) => Ok(ppid),
Err(_) => Ok(process::id().to_string()),
}
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}
#[derive(Debug, Clone, Default)]
pub struct KeepPidMetaPlugin {
meta_name: String,
}
impl KeepPidMetaPlugin {
pub fn new() -> KeepPidMetaPlugin {
KeepPidMetaPlugin {
meta_name: "keep_pid".to_string(),
}
}
}
impl MetaPlugin for KeepPidMetaPlugin {
fn create(&self) -> Result<Box<dyn Write>> {
Ok(Box::new(io::sink()))
}
fn finalize(&mut self) -> io::Result<String> {
Ok(process::id().to_string())
}
fn update(&mut self, _data: &[u8]) {
// No update needed
}
fn meta_name(&mut self) -> String {
self.meta_name.clone()
}
}