v0.2.5-pre.009

This commit is contained in:
2026-08-20 09:24:10 +02:00
parent 1125ade4c1
commit e91bf36e9e
83 changed files with 2467 additions and 1801 deletions

View File

@@ -1,17 +1,8 @@
// file: crates/ksp-app-config-desk/src/app_state.rs
// version: 6
// version: 7
//! Shared backend state owned by the Tauri application.
struct LoggingRuntimeState {
guard: ksp_logging_lib::LoggingGuard,
active_profile_id: std::option::Option<String>,
selection_source: String,
generation: u32,
fallback_active: bool,
startup_diagnostic: std::option::Option<crate::CommandErrorDto>,
}
/// Shared Config Desk application state managed by Tauri.
pub(crate) struct AppState {
config_management: ksp_config_lib::ConfigManagement,
@@ -28,7 +19,7 @@ impl AppState {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let runtime_identity = crate::logging_runtime::launch_identity();
let runtime_identity = crate::launch_identity();
let runtime_identity = match runtime_identity {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -185,9 +176,9 @@ impl AppState {
application_id: identity.application_id().to_owned(),
launch_timestamp: identity.launch_timestamp().to_owned(),
console_enabled,
dropped_console_lines: crate::logging_runtime::count_to_u64(dropped.console()),
dropped_file_lines: crate::logging_runtime::count_to_u64(dropped.file()),
dropped_total_lines: crate::logging_runtime::count_to_u64(dropped.total()),
dropped_console_lines: crate::count_to_u64(dropped.console()),
dropped_file_lines: crate::count_to_u64(dropped.file()),
dropped_total_lines: crate::count_to_u64(dropped.total()),
files,
});
}
@@ -206,3 +197,12 @@ impl AppState {
.is_ok();
}
}
struct LoggingRuntimeState {
guard: ksp_logging_lib::LoggingGuard,
active_profile_id: std::option::Option<String>,
selection_source: String,
generation: u32,
fallback_active: bool,
startup_diagnostic: std::option::Option<crate::CommandErrorDto>,
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/bootstrap.rs
// version: 3
// version: 4
//! Config and Logging bootstrap for the desktop application.
@@ -71,6 +71,15 @@ pub(crate) fn initialize_logging(
};
}
fn fallback_logging_settings() -> ksp_logging_lib::LoggingSettings {
return ksp_logging_lib::LoggingSettings::new(
ksp_logging_lib::LogFilterLevel::Info,
ksp_logging_lib::SpanEvents::Off,
std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()),
std::vec::Vec::new(),
);
}
fn resolve_logging_startup(management: &ksp_config_lib::ConfigManagement) -> LoggingStartupPlan {
let environment = ksp_config_lib::ConfigEnvironment::load();
let environment = match environment {
@@ -132,15 +141,6 @@ fn initialize_planned_fallback_logging(
});
}
pub(crate) fn fallback_logging_settings() -> ksp_logging_lib::LoggingSettings {
return ksp_logging_lib::LoggingSettings::new(
ksp_logging_lib::LogFilterLevel::Info,
ksp_logging_lib::SpanEvents::Off,
std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()),
std::vec::Vec::new(),
);
}
#[cfg(test)]
#[path = "../unit_tests/bootstrap.rs"]
mod tests;

View File

@@ -1,8 +1,28 @@
// file: crates/ksp-app-config-desk/src/constants.rs
// version: 9
// version: 10
//! Application-owned tracing targets and domains.
/// Structured domain used while bootstrapping Config and Logging.
pub(crate) const TRACING_DOMAIN_BOOTSTRAP: &str = "config.bootstrap";
/// Structured domain for Config document inventory, diagnostics and repair.
pub(crate) const TRACING_DOMAIN_DOCUMENTS: &str = "config.documents";
/// Structured domain for safe Config environment reports.
pub(crate) const TRACING_DOMAIN_ENVIRONMENT: &str = "config.environment";
/// Structured domain used by technical frontend events.
pub(crate) const TRACING_DOMAIN_FRONTEND: &str = "frontend";
/// Structured domain for typed Logging editor inspection.
pub(crate) const TRACING_DOMAIN_LOGGING_EDITOR: &str = "config.logging_editor";
/// Structured domain for active Logging runtime metadata and explicit profile application.
pub(crate) const TRACING_DOMAIN_LOGGING_RUNTIME: &str = "config.logging_runtime";
/// Structured domain used by controlled Logging test events.
pub(crate) const TRACING_DOMAIN_LOGGING_TEST: &str = "config.logging_test";
/// Structured domain for Config profile selection and provenance inspection.
pub(crate) const TRACING_DOMAIN_PROFILES: &str = "config.profiles";
/// Structured domain for explicit privileged Secret reveal operations.
pub(crate) const TRACING_DOMAIN_SECRETS: &str = "config.secrets";
/// Structured domain used by Tauri window lifecycle operations.
pub(crate) const TRACING_DOMAIN_WINDOWS: &str = "desktop.window";
/// Owning target for backend events emitted by Config Desk.
pub(crate) const TRACING_TARGET: &str = "ksp-app-config-desk";
/// Owning target for generic frontend events emitted through the KSP bridge.
@@ -13,23 +33,3 @@ pub(crate) const TRACING_TARGET_FRONTEND_MAIN: &str = "ksp-app-config-desk.front
pub(crate) const TRACING_TARGET_FRONTEND_SPLASH: &str = "ksp-app-config-desk.frontend.splash";
/// Dedicated target used by the controlled Logging test panel.
pub(crate) const TRACING_TARGET_LOGGING_TEST: &str = "ksp-app-config-desk.logging-test";
/// Structured domain used while bootstrapping Config and Logging.
pub(crate) const TRACING_DOMAIN_BOOTSTRAP: &str = "config.bootstrap";
/// Structured domain used by technical frontend events.
pub(crate) const TRACING_DOMAIN_FRONTEND: &str = "frontend";
/// Structured domain used by Tauri window lifecycle operations.
pub(crate) const TRACING_DOMAIN_WINDOWS: &str = "desktop.window";
/// Structured domain for Config document inventory, diagnostics and repair.
pub(crate) const TRACING_DOMAIN_DOCUMENTS: &str = "config.documents";
/// Structured domain for Config profile selection and provenance inspection.
pub(crate) const TRACING_DOMAIN_PROFILES: &str = "config.profiles";
/// Structured domain for safe Config environment reports.
pub(crate) const TRACING_DOMAIN_ENVIRONMENT: &str = "config.environment";
/// Structured domain for explicit privileged Secret reveal operations.
pub(crate) const TRACING_DOMAIN_SECRETS: &str = "config.secrets";
/// Structured domain for typed Logging editor inspection.
pub(crate) const TRACING_DOMAIN_LOGGING_EDITOR: &str = "config.logging_editor";
/// Structured domain for active Logging runtime metadata and explicit profile application.
pub(crate) const TRACING_DOMAIN_LOGGING_RUNTIME: &str = "config.logging_runtime";
/// Structured domain used by controlled Logging test events.
pub(crate) const TRACING_DOMAIN_LOGGING_TEST: &str = "config.logging_test";

View File

@@ -1,44 +1,42 @@
// file: crates/ksp-app-config-desk/src/errors.rs
// version: 9
// version: 10
//! Application-local error codes for the configuration desktop shell.
/// Tauri runtime assembly or execution failed.
pub(crate) const ERROR_CODE_TAURI_RUNTIME_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "tauri_runtime_failed");
/// Shared Config Desk application state is internally inconsistent.
pub(crate) const ERROR_CODE_APP_STATE_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_invalid");
/// Shared Config Desk runtime state cannot be locked safely.
pub(crate) const ERROR_CODE_APP_STATE_LOCK_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_lock_failed");
/// A Documents command requested a registered file that is not a Config-kind document.
pub(crate) const ERROR_CODE_DOCUMENT_KIND_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "document_kind_invalid");
/// Frontend logging requested an unsupported level.
pub(crate) const ERROR_CODE_FRONTEND_LOG_LEVEL_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_level_invalid");
/// Frontend logging requested a target outside the application whitelist.
pub(crate) const ERROR_CODE_FRONTEND_LOG_TARGET_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_target_invalid");
/// Config Desk could not install the managed Logging runtime or its safe fallback.
pub(crate) const ERROR_CODE_LOGGING_BOOTSTRAP_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "logging_bootstrap_failed");
/// Config Desk persisted a Logging candidate but could not restore the previous source after runtime application failed.
pub(crate) const ERROR_CODE_LOGGING_SOURCE_ROLLBACK_FAILED: ksp_core_lib::ErrorCode =
ksp_core_lib::ErrorCode::new("config_desk", "logging_source_rollback_failed");
/// Shared Config Desk application state is internally inconsistent.
pub(crate) const ERROR_CODE_APP_STATE_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_invalid");
/// Shared Config Desk runtime state cannot be locked safely.
pub(crate) const ERROR_CODE_APP_STATE_LOCK_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "app_state_lock_failed");
/// Frontend logging requested an unsupported level.
pub(crate) const ERROR_CODE_FRONTEND_LOG_LEVEL_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_level_invalid");
/// Frontend logging requested a target outside the application whitelist.
pub(crate) const ERROR_CODE_FRONTEND_LOG_TARGET_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "frontend_log_target_invalid");
/// Controlled Logging test request contains an unsupported or invalid selector.
pub(crate) const ERROR_CODE_LOGGING_TEST_REQUEST_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "logging_test_request_invalid");
/// A validated Config document does not expose the standard profile contract expected by the Profiles panel.
pub(crate) const ERROR_CODE_PROFILE_CONTRACT_MISSING: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "profile_contract_missing");
/// Config profile data could not be projected safely for the frontend.
pub(crate) const ERROR_CODE_PROFILE_PROJECTION_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "profile_projection_failed");
/// A KSP desk splash environment duration is malformed or exceeds its safety bound.
pub(crate) const ERROR_CODE_SPLASH_SETTING_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "splash_setting_invalid");
/// Splash readiness was invoked from a window other than the splash window.
pub(crate) const ERROR_CODE_SPLASH_ORIGIN_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "splash_origin_invalid");
/// A required Tauri window is missing from the configured application runtime.
pub(crate) const ERROR_CODE_TAURI_WINDOW_MISSING: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "tauri_window_missing");
/// A Tauri window show/focus/destroy/event operation failed.
pub(crate) const ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED: ksp_core_lib::ErrorCode =
ksp_core_lib::ErrorCode::new("config_desk", "tauri_window_operation_failed");
/// A Documents command requested a registered file that is not a Config-kind document.
pub(crate) const ERROR_CODE_DOCUMENT_KIND_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "document_kind_invalid");
/// Privileged reveal was requested for a non-Secret KSP/KSPB namespace.
pub(crate) const ERROR_CODE_SECRET_REVEAL_REQUIRES_SECRET: ksp_core_lib::ErrorCode =
ksp_core_lib::ErrorCode::new("config_desk", "secret_reveal_requires_secret");
/// Privileged reveal requested an unsupported source selector.
pub(crate) const ERROR_CODE_SECRET_REVEAL_SOURCE_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "secret_reveal_source_invalid");
/// Splash readiness was invoked from a window other than the splash window.
pub(crate) const ERROR_CODE_SPLASH_ORIGIN_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "splash_origin_invalid");
/// A KSP desk splash environment duration is malformed or exceeds its safety bound.
pub(crate) const ERROR_CODE_SPLASH_SETTING_INVALID: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "splash_setting_invalid");
/// Tauri runtime assembly or execution failed.
pub(crate) const ERROR_CODE_TAURI_RUNTIME_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "tauri_runtime_failed");
/// A required Tauri window is missing from the configured application runtime.
pub(crate) const ERROR_CODE_TAURI_WINDOW_MISSING: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "tauri_window_missing");
/// A Tauri window show/focus/destroy/event operation failed.
pub(crate) const ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED: ksp_core_lib::ErrorCode =
ksp_core_lib::ErrorCode::new("config_desk", "tauri_window_operation_failed");

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/lib.rs
// version: 14
// version: 15
//! Tauri desktop application for managing and validating KSP configuration.
@@ -73,16 +73,25 @@ pub(crate) use self::errors::ERROR_CODE_TAURI_WINDOW_MISSING;
pub(crate) use self::errors::ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED;
pub(crate) use self::frontend_logging::FrontendLogPayloadDto;
pub(crate) use self::frontend_logging::emit_frontend_log_event;
pub(crate) use self::logging_editor::LoggingConsoleDto;
pub(crate) use self::logging_editor::LoggingDocumentCandidateDto;
pub(crate) use self::logging_editor::LoggingDocumentDto;
pub(crate) use self::logging_editor::LoggingDocumentSaveResultDto;
pub(crate) use self::logging_runtime::{LoggingRuntimeFileDto, LoggingRuntimeStatusDto};
pub(crate) use self::logging_test::{LoggingTestRequestDto, LoggingTestResultDto};
pub(crate) use self::logging_editor::LoggingFileDto;
pub(crate) use self::logging_editor::LoggingOutputFilterDto;
pub(crate) use self::logging_editor::LoggingProfileDto;
pub(crate) use self::logging_editor::LoggingTargetFilterDto;
pub(crate) use self::logging_runtime::LoggingRuntimeFileDto;
pub(crate) use self::logging_runtime::LoggingRuntimeStatusDto;
pub(crate) use self::logging_runtime::count_to_u64;
pub(crate) use self::logging_runtime::launch_identity;
pub(crate) use self::logging_test::LoggingTestRequestDto;
pub(crate) use self::logging_test::LoggingTestResultDto;
pub(crate) use self::profiles::ConfigProfileDetailDto;
pub(crate) use self::profiles::ConfigProfileDocumentDto;
pub(crate) use self::secrets::SecretRevealRequestDto;
pub(crate) use self::secrets::SecretRevealResponseDto;
pub(crate) use self::splash::SplashOrderDto;
pub(crate) use self::splash::SplashSettings;
pub(crate) use self::tw_main::show_and_focus as show_main_window;
pub(crate) use self::tw_splash::frontend_ready as splash_frontend_ready_service;
pub(crate) use self::tw_main::show_main_window;
pub(crate) use self::tw_splash::splash_frontend_ready_service;

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/logging_editor.rs
// version: 4
// version: 5
//! Typed Logging document projection and validated persistence for the Config Desk Logging editor.
@@ -32,7 +32,7 @@ pub(crate) struct LoggingConsoleDto {
/// Console format source text.
pub(crate) format: String,
/// Sink-local selectors.
pub(crate) filter: LoggingOutputFilterDto,
pub(crate) filter: crate::LoggingOutputFilterDto,
}
/// One persistent file sink exposed to the editor.
@@ -53,7 +53,7 @@ pub(crate) struct LoggingFileDto {
/// Whether ANSI output is requested.
pub(crate) ansi: bool,
/// Sink-local selectors.
pub(crate) filter: LoggingOutputFilterDto,
pub(crate) filter: crate::LoggingOutputFilterDto,
}
/// One global Logging target override exposed to the editor.
@@ -79,11 +79,11 @@ pub(crate) struct LoggingProfileDto {
/// Span lifecycle source text.
pub(crate) span_events: String,
/// Console sink configuration.
pub(crate) console: LoggingConsoleDto,
pub(crate) console: crate::LoggingConsoleDto,
/// Persistent file sinks in source order.
pub(crate) files: std::vec::Vec<LoggingFileDto>,
pub(crate) files: std::vec::Vec<crate::LoggingFileDto>,
/// Global target overrides in source order.
pub(crate) target_filters: std::vec::Vec<LoggingTargetFilterDto>,
pub(crate) target_filters: std::vec::Vec<crate::LoggingTargetFilterDto>,
}
/// Complete typed Logging document exposed to the editor.
@@ -102,7 +102,7 @@ pub(crate) struct LoggingDocumentDto {
/// Autonomous default profile identifier.
pub(crate) default_profile: String,
/// Typed profiles in source order.
pub(crate) profiles: std::vec::Vec<LoggingProfileDto>,
pub(crate) profiles: std::vec::Vec<crate::LoggingProfileDto>,
}
/// Complete editable Logging candidate accepted from the frontend.
@@ -115,7 +115,7 @@ pub(crate) struct LoggingDocumentCandidateDto {
/// Autonomous default profile identifier.
pub(crate) default_profile: String,
/// Typed profiles in source order.
pub(crate) profiles: std::vec::Vec<LoggingProfileDto>,
pub(crate) profiles: std::vec::Vec<crate::LoggingProfileDto>,
}
/// Result of one validated typed Logging persistence operation.
@@ -255,7 +255,7 @@ fn document_from_management(management: &ksp_config_lib::ConfigManagement) -> ks
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let mut profiles = std::vec::Vec::<LoggingProfileDto>::with_capacity(source.profiles().len());
let mut profiles = std::vec::Vec::<crate::LoggingProfileDto>::with_capacity(source.profiles().len());
let mut file_count = 0usize;
let mut target_filter_count = 0usize;
for profile in source.profiles() {
@@ -291,7 +291,7 @@ fn config_candidate(candidate: LoggingDocumentCandidateDto) -> ksp_config_lib::L
return ksp_config_lib::LoggingConfigDocument::new(candidate.logs_directory, candidate.default_profile, profiles);
}
fn config_profile(profile: LoggingProfileDto) -> ksp_config_lib::LoggingProfileConfig {
fn config_profile(profile: crate::LoggingProfileDto) -> ksp_config_lib::LoggingProfileConfig {
let mut files = std::vec::Vec::<ksp_config_lib::LoggingFileConfig>::with_capacity(profile.files.len());
for file in profile.files {
let mut config =
@@ -319,14 +319,14 @@ fn config_profile(profile: LoggingProfileDto) -> ksp_config_lib::LoggingProfileC
);
}
fn config_output_filter(filter: LoggingOutputFilterDto) -> ksp_config_lib::LoggingOutputFilterConfig {
fn config_output_filter(filter: crate::LoggingOutputFilterDto) -> ksp_config_lib::LoggingOutputFilterConfig {
return ksp_config_lib::LoggingOutputFilterConfig::new(filter.level, filter.targets, filter.domains);
}
fn project_profile(profile: &ksp_config_lib::LoggingProfileConfig) -> LoggingProfileDto {
let mut files = std::vec::Vec::<LoggingFileDto>::with_capacity(profile.files().len());
fn project_profile(profile: &ksp_config_lib::LoggingProfileConfig) -> crate::LoggingProfileDto {
let mut files = std::vec::Vec::<crate::LoggingFileDto>::with_capacity(profile.files().len());
for file in profile.files() {
files.push(LoggingFileDto {
files.push(crate::LoggingFileDto {
output_id: file.output_id().to_owned(),
enabled: file.enabled(),
path: file.path().to_owned(),
@@ -336,15 +336,15 @@ fn project_profile(profile: &ksp_config_lib::LoggingProfileConfig) -> LoggingPro
filter: project_output_filter(file.filter()),
});
}
let mut target_filters = std::vec::Vec::<LoggingTargetFilterDto>::with_capacity(profile.target_filters().len());
let mut target_filters = std::vec::Vec::<crate::LoggingTargetFilterDto>::with_capacity(profile.target_filters().len());
for target_filter in profile.target_filters() {
target_filters.push(LoggingTargetFilterDto { target_prefix: target_filter.target_prefix().to_owned(), level: target_filter.level().to_owned() });
target_filters.push(crate::LoggingTargetFilterDto { target_prefix: target_filter.target_prefix().to_owned(), level: target_filter.level().to_owned() });
}
return LoggingProfileDto {
return crate::LoggingProfileDto {
profile_id: profile.profile_id().to_owned(),
default_filter: profile.default_filter().to_owned(),
span_events: profile.span_events().to_owned(),
console: LoggingConsoleDto {
console: crate::LoggingConsoleDto {
enabled: profile.console().enabled(),
output: profile.console().output().to_owned(),
ansi: profile.console().ansi(),
@@ -356,8 +356,8 @@ fn project_profile(profile: &ksp_config_lib::LoggingProfileConfig) -> LoggingPro
};
}
fn project_output_filter(filter: &ksp_config_lib::LoggingOutputFilterConfig) -> LoggingOutputFilterDto {
return LoggingOutputFilterDto {
fn project_output_filter(filter: &ksp_config_lib::LoggingOutputFilterConfig) -> crate::LoggingOutputFilterDto {
return crate::LoggingOutputFilterDto {
level: filter.level().to_owned(),
targets: filter.targets().to_vec(),
domains: filter.domains().to_vec(),

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/logging_runtime.rs
// version: 2
// version: 3
//! Runtime Logging metadata, launch identity and explicit profile application for Config Desk.
@@ -97,7 +97,7 @@ pub(crate) fn project_file(metadata: &ksp_logging_lib::RuntimeFileMetadata) -> L
};
}
pub(crate) const fn rotation_label(rotation: ksp_logging_lib::FileRotation) -> &'static str {
const fn rotation_label(rotation: ksp_logging_lib::FileRotation) -> &'static str {
return match rotation {
ksp_logging_lib::FileRotation::Never => "never",
ksp_logging_lib::FileRotation::Hourly => "hourly",

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/profiles.rs
// version: 1
// version: 2
//! Safe Config profile inspection and provenance projections for Config Desk.
@@ -77,6 +77,11 @@ pub(crate) struct ConfigProfileDetailDto {
pub(crate) environment_provenance: std::vec::Vec<ConfigProfileEnvironmentProvenanceDto>,
}
struct ProfileContract {
default_profile: String,
profile_ids: std::vec::Vec<String>,
}
/// Lists validated Config documents that expose standard profiles.
pub(crate) fn inventory(state: &crate::AppState) -> ksp_core_lib::Result<std::vec::Vec<ConfigProfileDocumentDto>> {
return inventory_from_management(state.config_management());
@@ -213,11 +218,6 @@ fn detail_from_management(
});
}
struct ProfileContract {
default_profile: String,
profile_ids: std::vec::Vec<String>,
}
fn profile_contract(document: &ksp_config_lib::ConfigJsonDocument) -> ksp_core_lib::Result<std::option::Option<ProfileContract>> {
let root = match document.value().as_object() {
std::option::Option::Some(value) => value,

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/splash.rs
// version: 3
// version: 4
//! Common splash settings and frontend event contracts for Config Desk.
@@ -94,14 +94,6 @@ impl SplashSettings {
}
}
const fn environment_source_code(source: ksp_config_lib::ConfigEnvironmentSource) -> &'static str {
return match source {
ksp_config_lib::ConfigEnvironmentSource::Process => "process",
ksp_config_lib::ConfigEnvironmentSource::DotEnv => "dotenv",
ksp_config_lib::ConfigEnvironmentSource::Fallback => "fallback",
};
}
/// Command emitted by Rust to the splash frontend.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[serde(rename_all = "camelCase")]
@@ -122,6 +114,14 @@ impl SplashOrderDto {
}
}
const fn environment_source_code(source: ksp_config_lib::ConfigEnvironmentSource) -> &'static str {
return match source {
ksp_config_lib::ConfigEnvironmentSource::Process => "process",
ksp_config_lib::ConfigEnvironmentSource::DotEnv => "dotenv",
ksp_config_lib::ConfigEnvironmentSource::Fallback => "fallback",
};
}
fn parse_u64_setting(variable_name: &str, value: &str, maximum: u64) -> ksp_core_lib::Result<u64> {
let parsed = value.parse::<u64>();
let parsed = match parsed {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/tw_main.rs
// version: 1
// version: 2
//! Tauri-window helpers for the Config Desk main window.
@@ -18,7 +18,7 @@ pub(crate) fn require_window(manager: &impl Manager<tauri::Wry>) -> ksp_core_lib
};
}
pub(crate) fn show_and_focus(app: &tauri::AppHandle) -> ksp_core_lib::Result<()> {
pub(crate) fn show_main_window(app: &tauri::AppHandle) -> ksp_core_lib::Result<()> {
let window = require_window(app);
let window = match window {
std::result::Result::Ok(value) => value,

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/src/tw_splash.rs
// version: 2
// version: 3
//! Tauri-window lifecycle for the Config Desk splash window.
@@ -20,7 +20,11 @@ pub(crate) fn require_window(manager: &impl Manager<tauri::Wry>) -> ksp_core_lib
};
}
pub(crate) async fn frontend_ready(app: tauri::AppHandle, invoking_window: tauri::WebviewWindow, state: &crate::AppState) -> ksp_core_lib::Result<()> {
pub(crate) async fn splash_frontend_ready_service(
app: tauri::AppHandle,
invoking_window: tauri::WebviewWindow,
state: &crate::AppState,
) -> ksp_core_lib::Result<()> {
if invoking_window.label() != WINDOW_LABEL_SPLASH {
return std::result::Result::Err(
ksp_core_lib::Error::new(crate::ERROR_CODE_SPLASH_ORIGIN_INVALID, "Splash readiness may only originate from the splash window")

View File

@@ -1,31 +1,29 @@
// file: crates/ksp-app-config-desk/unit_tests/documents.rs
// version: 1
use super::*;
// version: 2
#[test]
fn diagnostic_classifier_distinguishes_json_schema_semantic_and_effective_errors() {
let json = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_JSON_SYNTAX_INVALID, "json");
assert_eq!(classify_error(&json), STAGE_JSON);
assert_eq!(super::classify_error(&json), super::STAGE_JSON);
let schema = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_SCHEMA_VALIDATION_FAILED, "schema");
assert_eq!(classify_error(&schema), STAGE_SCHEMA);
assert_eq!(super::classify_error(&schema), super::STAGE_SCHEMA);
let semantic = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_DOCUMENT_SEMANTIC_INVALID, "semantic");
assert_eq!(classify_error(&semantic), STAGE_SEMANTIC);
assert_eq!(super::classify_error(&semantic), super::STAGE_SEMANTIC);
let effective = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_EFFECTIVE_CONFIG_INVALID, "effective");
assert_eq!(classify_error(&effective), STAGE_EFFECTIVE);
assert_eq!(super::classify_error(&effective), super::STAGE_EFFECTIVE);
}
#[test]
fn schema_source_read_errors_are_classified_as_schema_failures() {
let error = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_JSON_FILE_READ_FAILED, "missing schema").with_context("file_id", "schema.std.logging");
assert_eq!(classify_error(&error), STAGE_SCHEMA);
assert_eq!(super::classify_error(&error), super::STAGE_SCHEMA);
}
#[test]
fn document_error_projection_does_not_expose_arbitrary_error_context() {
let error = ksp_core_lib::Error::new(ksp_config_lib::ERROR_CODE_JSON_SYNTAX_INVALID, "invalid source").with_context("detail", "sensitive-canary");
let projection = ConfigDocumentErrorDto::from_error(&error);
assert_eq!(projection.diagnostic_stage, STAGE_JSON);
let projection = crate::ConfigDocumentErrorDto::from_error(&error);
assert_eq!(projection.diagnostic_stage, super::STAGE_JSON);
assert_eq!(projection.error.domain, "config");
assert_eq!(projection.error.code, "json_syntax_invalid");
assert_eq!(projection.error.message, "invalid source");

View File

@@ -1,10 +1,10 @@
// file: crates/ksp-app-config-desk/unit_tests/dto_common.rs
// version: 1
// version: 2
#[test]
fn command_error_projection_excludes_context_values() {
let error = ksp_core_lib::Error::new(ksp_core_lib::ErrorCode::new("test", "failure"), "safe message").with_context("secret_canary", "must-not-be-exported");
let dto = super::CommandErrorDto::from_error(&error);
let dto = crate::CommandErrorDto::from_error(&error);
assert_eq!(dto.domain, "test");
assert_eq!(dto.code, "failure");
assert_eq!(dto.message, "safe message");

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/unit_tests/logging_editor.rs
// version: 4
// version: 5
#[test]
fn committed_logging_document_maps_complete_read_only_editor_contract() {
@@ -66,7 +66,7 @@ fn editor_candidate_round_trips_through_typed_config_contract() {
let document = super::document_from_management(&management);
assert!(document.is_ok(), "Logging editor document should load: {document:?}");
if let std::result::Result::Ok(document) = document {
let candidate = super::LoggingDocumentCandidateDto {
let candidate = crate::LoggingDocumentCandidateDto {
logs_directory: document.logs_directory.clone(),
default_profile: document.default_profile.clone(),
profiles: document.profiles.clone(),
@@ -89,42 +89,42 @@ fn editor_candidate_round_trips_through_typed_config_contract() {
#[test]
fn profile_candidate_preserves_multi_file_and_target_filter_shape() {
let profile = super::LoggingProfileDto {
let profile = crate::LoggingProfileDto {
profile_id: "clone_test".to_owned(),
default_filter: "info".to_owned(),
span_events: "full".to_owned(),
console: super::LoggingConsoleDto {
console: crate::LoggingConsoleDto {
enabled: true,
output: "stdout".to_owned(),
ansi: false,
format: "human".to_owned(),
filter: super::LoggingOutputFilterDto { level: "info".to_owned(), targets: std::vec!["*".to_owned()], domains: std::vec!["*".to_owned()] },
filter: crate::LoggingOutputFilterDto { level: "info".to_owned(), targets: std::vec!["*".to_owned()], domains: std::vec!["*".to_owned()] },
},
files: std::vec![
super::LoggingFileDto {
crate::LoggingFileDto {
output_id: "file.one".to_owned(),
enabled: true,
path: "one.log".to_owned(),
rotation: "daily".to_owned(),
format: "human".to_owned(),
ansi: false,
filter: super::LoggingOutputFilterDto { level: "debug".to_owned(), targets: std::vec!["*".to_owned()], domains: std::vec!["*".to_owned()] },
filter: crate::LoggingOutputFilterDto { level: "debug".to_owned(), targets: std::vec!["*".to_owned()], domains: std::vec!["*".to_owned()] },
},
super::LoggingFileDto {
crate::LoggingFileDto {
output_id: "file.two".to_owned(),
enabled: false,
path: "two.jsonl".to_owned(),
rotation: "hourly".to_owned(),
format: "json".to_owned(),
ansi: false,
filter: super::LoggingOutputFilterDto {
filter: crate::LoggingOutputFilterDto {
level: "error".to_owned(),
targets: std::vec!["ksp-config-lib".to_owned()],
domains: std::vec!["config".to_owned()],
},
},
],
target_filters: std::vec![super::LoggingTargetFilterDto { target_prefix: "ksp-app-config-desk".to_owned(), level: "trace".to_owned() }],
target_filters: std::vec![crate::LoggingTargetFilterDto { target_prefix: "ksp-app-config-desk".to_owned(), level: "trace".to_owned() }],
};
let config = super::config_profile(profile);
assert_eq!(config.profile_id(), "clone_test");

View File

@@ -1,9 +1,9 @@
// file: crates/ksp-app-config-desk/unit_tests/logging_runtime.rs
// version: 1
// version: 2
#[test]
fn launch_identity_is_safe_and_contains_application_and_process_identity() {
let identity = super::launch_identity();
let identity = crate::launch_identity();
assert!(identity.is_ok());
if let std::result::Result::Ok(identity) = identity {
assert_eq!(identity.application_id(), crate::TRACING_TARGET);
@@ -21,6 +21,6 @@ fn runtime_rotation_labels_are_stable() {
#[test]
fn runtime_count_projection_is_non_lossy_for_normal_values() {
assert_eq!(super::count_to_u64(0), 0);
assert_eq!(super::count_to_u64(42), 42);
assert_eq!(crate::count_to_u64(0), 0);
assert_eq!(crate::count_to_u64(42), 42);
}

View File

@@ -1,25 +1,23 @@
// file: crates/ksp-app-config-desk/unit_tests/logging_test.rs
// version: 1
use super::{LoggingTestLevel, LoggingTestTarget};
// version: 2
#[test]
fn controlled_logging_test_levels_include_all_five_levels_and_batch_mode() {
assert!(matches!(super::parse_level("trace"), std::result::Result::Ok(LoggingTestLevel::Trace)));
assert!(matches!(super::parse_level("debug"), std::result::Result::Ok(LoggingTestLevel::Debug)));
assert!(matches!(super::parse_level("info"), std::result::Result::Ok(LoggingTestLevel::Info)));
assert!(matches!(super::parse_level("warn"), std::result::Result::Ok(LoggingTestLevel::Warn)));
assert!(matches!(super::parse_level("error"), std::result::Result::Ok(LoggingTestLevel::Error)));
assert!(matches!(super::parse_level("all"), std::result::Result::Ok(LoggingTestLevel::All)));
assert!(matches!(super::parse_level("trace"), std::result::Result::Ok(super::LoggingTestLevel::Trace)));
assert!(matches!(super::parse_level("debug"), std::result::Result::Ok(super::LoggingTestLevel::Debug)));
assert!(matches!(super::parse_level("info"), std::result::Result::Ok(super::LoggingTestLevel::Info)));
assert!(matches!(super::parse_level("warn"), std::result::Result::Ok(super::LoggingTestLevel::Warn)));
assert!(matches!(super::parse_level("error"), std::result::Result::Ok(super::LoggingTestLevel::Error)));
assert!(matches!(super::parse_level("all"), std::result::Result::Ok(super::LoggingTestLevel::All)));
assert!(super::parse_level("fatal").is_err());
}
#[test]
fn controlled_logging_test_targets_are_static_ksp_targets() {
assert!(matches!(super::parse_target("app"), std::result::Result::Ok(LoggingTestTarget::App)));
assert!(matches!(super::parse_target("logging_test"), std::result::Result::Ok(LoggingTestTarget::Dedicated)));
assert_eq!(super::target_value(LoggingTestTarget::App), crate::TRACING_TARGET);
assert_eq!(super::target_value(LoggingTestTarget::Dedicated), crate::TRACING_TARGET_LOGGING_TEST);
assert!(matches!(super::parse_target("app"), std::result::Result::Ok(super::LoggingTestTarget::App)));
assert!(matches!(super::parse_target("logging_test"), std::result::Result::Ok(super::LoggingTestTarget::Dedicated)));
assert_eq!(super::target_value(super::LoggingTestTarget::App), crate::TRACING_TARGET);
assert_eq!(super::target_value(super::LoggingTestTarget::Dedicated), crate::TRACING_TARGET_LOGGING_TEST);
assert!(super::parse_target("external").is_err());
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-config-desk/unit_tests/secrets.rs
// version: 1
// version: 2
#[test]
fn reveal_policy_accepts_only_secret_names_and_supported_sources() {
@@ -21,7 +21,7 @@ fn reveal_policy_accepts_only_secret_names_and_supported_sources() {
#[test]
fn reveal_response_type_does_not_require_debug_or_clone_contracts() {
let response = super::SecretRevealResponseDto {
let response = crate::SecretRevealResponseDto {
variable_name: "KSP_SECRET_TEST_VALUE".to_owned(),
source: "dotenv".to_owned(),
value: std::option::Option::Some("secret-canary".to_owned()),