g3 console init

This commit is contained in:
Dhanji Prasanna
2025-11-07 09:25:17 +11:00
parent aaf918828f
commit cb43fcdecf
24 changed files with 2860 additions and 498 deletions

View File

@@ -1,5 +1,5 @@
use crate::models::*;
use crate::process::{ProcessController, ProcessDetector};
use crate::process::ProcessController;
use axum::{extract::State, http::StatusCode, Json};
use std::sync::Arc;
use tokio::sync::Mutex;
@@ -82,7 +82,14 @@ pub async fn launch_instance(
// Validate binary path if provided
if let Some(ref binary_path) = request.g3_binary_path {
let path = std::path::Path::new(binary_path);
// Expand relative paths and resolve to absolute
let path = if binary_path.starts_with("./") || binary_path.starts_with("../") {
std::env::current_dir()
.map(|cwd| cwd.join(binary_path))
.unwrap_or_else(|_| std::path::PathBuf::from(binary_path))
} else {
std::path::PathBuf::from(binary_path)
};
// Check if file exists
if !path.exists() {

View File

@@ -1,7 +1,8 @@
use crate::logs::{LogParser, StatsAggregator};
use crate::models::*;
use crate::process::ProcessDetector;
use axum::{extract::State, http::StatusCode, Json};
use axum::{extract::{Query, State}, http::StatusCode, Json};
use serde::Deserialize;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::{debug, error, warn};
@@ -187,3 +188,34 @@ fn read_file_snippet(workspace: &std::path::Path, filename: &str) -> Option<Stri
.join("\n")
})
}
#[derive(Deserialize)]
pub struct FileQuery {
name: String,
}
pub async fn get_file_content(
axum::extract::Path(id): axum::extract::Path<String>,
Query(query): Query<FileQuery>,
State(detector): State<AppState>,
) -> Result<Json<serde_json::Value>, StatusCode> {
let mut detector = detector.lock().await;
// Find the instance
let instances = detector.detect_instances().map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let instance = instances.iter().find(|i| i.id == id).ok_or(StatusCode::NOT_FOUND)?;
// Read the full file
let file_path = instance.workspace.join(&query.name);
if !file_path.exists() {
return Err(StatusCode::NOT_FOUND);
}
let content = std::fs::read_to_string(&file_path)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(serde_json::json!({
"name": query.name,
"content": content,
})))
}

View File

@@ -1,5 +1,4 @@
use crate::logs::LogParser;
use crate::models::*;
use crate::process::ProcessDetector;
use axum::{extract::State, http::StatusCode, Json};
use std::sync::Arc;

View File

@@ -2,8 +2,3 @@ pub mod instances;
pub mod control;
pub mod logs;
pub mod state;
pub use instances::*;
pub use control::*;
pub use logs::*;
pub use state::*;

View File

@@ -44,7 +44,7 @@ pub struct BrowseResponse {
pub struct FileEntry {
pub name: String,
pub path: String,
pub is_directory: bool,
pub is_dir: bool,
pub is_executable: bool,
}
@@ -76,7 +76,7 @@ pub async fn browse_filesystem(
entries.push(FileEntry {
name: entry.file_name().to_string_lossy().to_string(),
path: entry.path().to_string_lossy().to_string(),
is_directory: metadata.is_dir(),
is_dir: metadata.is_dir(),
is_executable: metadata.permissions().mode() & 0o111 != 0,
});
}
@@ -84,7 +84,7 @@ pub async fn browse_filesystem(
}
entries.sort_by(|a, b| {
match (a.is_directory, b.is_directory) {
match (a.is_dir, b.is_dir) {
(true, false) => std::cmp::Ordering::Less,
(false, true) => std::cmp::Ordering::Greater,
_ => a.name.cmp(&b.name),