create-ekka-desktop-app 0.3.10 → 0.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ekka-desktop-app",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "description": "Create an EKKA desktop app with built-in demo backend. No setup required.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,10 +2,12 @@
2
2
  //!
3
3
  //! Standalone demo implementation for CDA-generated apps.
4
4
  //! Returns demo responses for all operations (no SDK dependencies).
5
- //! Reads branding/app.json to configure app name and home path.
5
+ //! Uses app.config.json values baked at build time.
6
6
 
7
7
  #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
8
8
 
9
+ mod config;
10
+
9
11
  use serde::{Deserialize, Serialize};
10
12
  use serde_json::{json, Value};
11
13
  use std::path::PathBuf;
@@ -56,45 +58,12 @@ impl EngineResponse {
56
58
  }
57
59
 
58
60
  // =============================================================================
59
- // Branding
61
+ // Home Path
60
62
  // =============================================================================
61
63
 
62
- #[derive(Debug, Clone, Serialize, Deserialize)]
63
- struct Branding {
64
- name: String,
65
- #[serde(rename = "bundleId")]
66
- bundle_id: String,
67
- version: String,
68
- }
69
-
70
- impl Default for Branding {
71
- fn default() -> Self {
72
- Self {
73
- name: "EKKA Desktop".to_string(),
74
- bundle_id: "ai.ekka.desktop".to_string(),
75
- version: "0.1.0".to_string(),
76
- }
77
- }
78
- }
79
-
80
- /// Convert app name to folder slug (lowercase, spaces to hyphens)
81
- fn app_name_to_slug(name: &str) -> String {
82
- name.to_lowercase()
83
- .chars()
84
- .map(|c| if c.is_alphanumeric() { c } else { '-' })
85
- .collect::<String>()
86
- .split('-')
87
- .filter(|s| !s.is_empty())
88
- .collect::<Vec<_>>()
89
- .join("-")
90
- }
91
-
92
- /// Compute home path based on app name
93
- /// Default: ~/.{slug} (dot-home) for all platforms
64
+ /// Compute home path using baked config from app.config.json
94
65
  /// Override: Set EKKA_DATA_HOME env var for custom location
95
- fn compute_home_path(app_name: &str) -> PathBuf {
96
- let slug = app_name_to_slug(app_name);
97
-
66
+ fn compute_home_path() -> PathBuf {
98
67
  // Check for env override first
99
68
  if let Ok(env_path) = std::env::var("EKKA_DATA_HOME") {
100
69
  if !env_path.is_empty() {
@@ -102,38 +71,12 @@ fn compute_home_path(app_name: &str) -> PathBuf {
102
71
  }
103
72
  }
104
73
 
105
- // Default: dot-home (~/.{slug}) for all platforms
74
+ // Use baked home folder name from app.config.json
75
+ let home_folder = config::home_folder();
76
+
106
77
  dirs::home_dir()
107
78
  .unwrap_or_else(|| PathBuf::from("/tmp"))
108
- .join(format!(".{}", slug))
109
- }
110
-
111
- /// Load branding from app.json
112
- fn load_branding() -> Branding {
113
- // Try to find branding/app.json relative to executable or current dir
114
- let paths_to_try = [
115
- // Relative to current directory (dev mode)
116
- PathBuf::from("branding/app.json"),
117
- PathBuf::from("../branding/app.json"),
118
- // Relative to executable (production bundle)
119
- std::env::current_exe()
120
- .ok()
121
- .and_then(|p| p.parent().map(|p| p.join("../Resources/branding/app.json")))
122
- .unwrap_or_default(),
123
- ];
124
-
125
- for path in &paths_to_try {
126
- if path.exists() {
127
- if let Ok(content) = std::fs::read_to_string(path) {
128
- if let Ok(branding) = serde_json::from_str::<Branding>(&content) {
129
- return branding;
130
- }
131
- }
132
- }
133
- }
134
-
135
- // Fallback to default
136
- Branding::default()
79
+ .join(home_folder)
137
80
  }
138
81
 
139
82
  // =============================================================================
@@ -144,19 +87,16 @@ pub struct EngineState {
144
87
  connected: Mutex<bool>,
145
88
  auth: Mutex<Option<AuthContext>>,
146
89
  home_granted: Mutex<bool>,
147
- branding: Branding,
148
90
  home_path: PathBuf,
149
91
  }
150
92
 
151
93
  impl Default for EngineState {
152
94
  fn default() -> Self {
153
- let branding = load_branding();
154
- let home_path = compute_home_path(&branding.name);
95
+ let home_path = compute_home_path();
155
96
  Self {
156
97
  connected: Mutex::new(false),
157
98
  auth: Mutex::new(None),
158
99
  home_granted: Mutex::new(false),
159
- branding,
160
100
  home_path,
161
101
  }
162
102
  }
@@ -198,8 +138,8 @@ fn engine_disconnect(state: State<EngineState>) {
198
138
  fn engine_request(req: EngineRequest, state: State<EngineState>) -> EngineResponse {
199
139
  let home_path_str = state.home_path.display().to_string();
200
140
 
201
- // Check connected (except for status operations)
202
- if !matches!(req.op.as_str(), "runtime.info" | "home.status") {
141
+ // Check connected (except for status operations that run pre-connect)
142
+ if !matches!(req.op.as_str(), "runtime.info" | "home.status" | "setup.status" | "nodeCredentials.status") {
203
143
  let connected = match state.connected.lock() {
204
144
  Ok(guard) => *guard,
205
145
  Err(e) => return EngineResponse::err("INTERNAL_ERROR", &e.to_string()),
@@ -224,8 +164,8 @@ fn engine_request(req: EngineRequest, state: State<EngineState>) -> EngineRespon
224
164
  "mode": "demo",
225
165
  "homeState": home_state,
226
166
  "homePath": home_path_str,
227
- "appName": state.branding.name,
228
- "appVersion": state.branding.version
167
+ "appName": config::app_name(),
168
+ "appVersion": env!("CARGO_PKG_VERSION")
229
169
  }))
230
170
  }
231
171