khal-os 1.260324.2 → 1.260324.3

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.
Files changed (33) hide show
  1. package/docs/workos-setup.md +1 -1
  2. package/package.json +9 -9
  3. package/packages/dev3000-app/package.json +1 -1
  4. package/packages/dev3000-app/views/dev3000/service/index.ts +1 -1
  5. package/packages/files-app/package.json +1 -1
  6. package/packages/files-app/views/files/FilesApp.tsx +1 -1
  7. package/packages/files-app/views/files/service/index.ts +2 -2
  8. package/packages/genie-app/package.json +1 -1
  9. package/packages/genie-app/views/genie/service/agent-lifecycle.ts +1 -1
  10. package/packages/genie-app/views/genie/service/comms.ts +1 -1
  11. package/packages/genie-app/views/genie/service/index.ts +2 -2
  12. package/packages/genie-app/views/genie/service/teams.ts +1 -1
  13. package/packages/nats-viewer-app/package.json +1 -1
  14. package/packages/os-cli/package.json +2 -2
  15. package/packages/os-cli/src/index.ts +1 -1
  16. package/packages/os-sdk/package.json +1 -1
  17. package/packages/os-sdk/src/config.ts +1 -1
  18. package/packages/os-sdk/src/db/migrate.ts +1 -1
  19. package/packages/os-sdk/src/service/runtime.ts +1 -1
  20. package/packages/os-ui/package.json +1 -1
  21. package/packages/settings-app/package.json +1 -1
  22. package/packages/settings-app/views/settings/Settings.tsx +2 -2
  23. package/packages/terminal-app/package.json +1 -1
  24. package/packages/terminal-app/views/terminal/service/index.ts +2 -2
  25. package/src/lib/auth/roles.ts +1 -1
  26. package/src/lib/service-loader.ts +1 -1
  27. package/src/lib/ws-bridge.ts +1 -1
  28. package/src/stores/keybind-store.ts +1 -1
  29. package/src/stores/notification-store.ts +1 -1
  30. package/tauri/Cargo.toml +1 -1
  31. package/tauri/capabilities/default.json +1 -1
  32. package/tauri/src/main.rs +24 -24
  33. package/tauri/tauri.conf.json +2 -2
@@ -1,6 +1,6 @@
1
1
  # WorkOS Dashboard Setup
2
2
 
3
- Step-by-step guide for configuring WorkOS for Genie OS (Phase 1 — platform scope).
3
+ Step-by-step guide for configuring WorkOS for Khal OS (Phase 1 — platform scope).
4
4
 
5
5
  ## 1. Create Production Environment
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "khal-os",
3
- "version": "1.260324.2",
3
+ "version": "1.260324.3",
4
4
  "scripts": {
5
5
  "dev": "next dev --port 8888",
6
6
  "build": "NEXT_PRIVATE_BUILD_WORKER=false next build",
@@ -16,14 +16,14 @@
16
16
  "prepare": "husky"
17
17
  },
18
18
  "dependencies": {
19
- "@genie-os/dev3000-app": "workspace:*",
20
- "@genie-os/files-app": "workspace:*",
21
- "@genie-os/genie-app": "workspace:*",
22
- "@genie-os/nats-viewer-app": "workspace:*",
23
- "@genie-os/sdk": "workspace:*",
24
- "@genie-os/settings-app": "workspace:*",
25
- "@genie-os/terminal-app": "workspace:*",
26
- "@genie-os/ui": "workspace:*",
19
+ "@khal-os/dev3000-app": "workspace:*",
20
+ "@khal-os/files-app": "workspace:*",
21
+ "@khal-os/genie-app": "workspace:*",
22
+ "@khal-os/nats-viewer-app": "workspace:*",
23
+ "@khal-os/sdk": "workspace:*",
24
+ "@khal-os/settings-app": "workspace:*",
25
+ "@khal-os/terminal-app": "workspace:*",
26
+ "@khal-os/ui": "workspace:*",
27
27
  "@json-render/core": "^0.7.0",
28
28
  "@json-render/react": "^0.7.0",
29
29
  "@nats-io/jetstream": "^3.3.1",
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/dev3000-app",
2
+ "name": "@khal-os/dev3000-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import { createService } from '@genie-os/sdk/service';
3
+ import { createService } from '@khal-os/sdk/service';
4
4
  import type { D3kCmdRequest, D3kCmdResponse, D3kRecordingEventSchema } from '../schema';
5
5
 
6
6
  const startTime = Date.now();
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/files-app",
2
+ "name": "@khal-os/files-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -16,7 +16,7 @@ import { UploadOverlay } from './UploadOverlay';
16
16
  import { useFiles } from './use-files';
17
17
  import { useUpload } from './use-upload';
18
18
 
19
- const VIEW_MODE_KEY = 'genie-os-files-view-mode';
19
+ const VIEW_MODE_KEY = 'khal-os-files-view-mode';
20
20
 
21
21
  function getStoredViewMode(): ViewMode {
22
22
  if (typeof window === 'undefined') return 'grid';
@@ -1,8 +1,8 @@
1
1
  import * as crypto from 'node:crypto';
2
2
  import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
- import type { NatsConnection } from '@genie-os/sdk/service';
5
- import { createService } from '@genie-os/sdk/service';
4
+ import type { NatsConnection } from '@khal-os/sdk/service';
5
+ import { createService } from '@khal-os/sdk/service';
6
6
  import { getFilesRoot, resolveSafePath, validateFilename } from '@/lib/files/safe-path';
7
7
  import type { FileWriteRequest, FsListRequest, FsWatchEvent } from '../schema';
8
8
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/genie-app",
2
+ "name": "@khal-os/genie-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -4,7 +4,7 @@
4
4
  * Exposes agent control operations beyond spawn (which lives in index.ts).
5
5
  */
6
6
 
7
- import type { ServiceHandler } from '@genie-os/sdk/service';
7
+ import type { ServiceHandler } from '@khal-os/sdk/service';
8
8
  import { SUBJECTS } from '../../../lib/subjects';
9
9
  import { runGenie } from './cli';
10
10
 
@@ -9,7 +9,7 @@
9
9
  * os.genie.comms.chat.read — read team chat history
10
10
  */
11
11
 
12
- import type { ServiceHandler } from '@genie-os/sdk/service';
12
+ import type { ServiceHandler } from '@khal-os/sdk/service';
13
13
  import { SUBJECTS } from '../../../lib/subjects';
14
14
  import { runGenie } from './cli';
15
15
 
@@ -1,5 +1,5 @@
1
- import type { NatsConnection } from '@genie-os/sdk/service';
2
- import { createService } from '@genie-os/sdk/service';
1
+ import type { NatsConnection } from '@khal-os/sdk/service';
2
+ import { createService } from '@khal-os/sdk/service';
3
3
  import { agentLifecycleHandlers } from './agent-lifecycle';
4
4
  import { commsHandlers } from './comms';
5
5
  import { directorySubscriptions } from './directory';
@@ -4,7 +4,7 @@
4
4
  * Exports a ServiceHandler[] array to be spread into the main service subscriptions.
5
5
  */
6
6
 
7
- import type { ServiceHandler } from '@genie-os/sdk/service';
7
+ import type { ServiceHandler } from '@khal-os/sdk/service';
8
8
  import { SUBJECTS } from '../../../lib/subjects';
9
9
  import { runGenie, runGenieAsync } from './cli';
10
10
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/nats-viewer-app",
2
+ "name": "@khal-os/nats-viewer-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -1,10 +1,10 @@
1
1
  {
2
- "name": "@genie-os/cli",
2
+ "name": "@khal-os/cli",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "bin": {
7
- "genie-os": "./dist/index.js"
7
+ "khal-os": "./dist/index.js"
8
8
  },
9
9
  "scripts": {
10
10
  "build": "bun build src/index.ts --outfile dist/index.js --target node"
@@ -5,7 +5,7 @@ import { logsCommand } from './commands/logs.js';
5
5
  import { statusCommand } from './commands/status.js';
6
6
  import { tracesCommand } from './commands/traces.js';
7
7
 
8
- const program = new Command().name('genie-os').description('Genie OS observability CLI').version('0.0.1');
8
+ const program = new Command().name('khal-os').description('Khal OS observability CLI').version('0.0.1');
9
9
 
10
10
  program.addCommand(eventsCommand);
11
11
  program.addCommand(logsCommand);
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/sdk",
2
+ "name": "@khal-os/sdk",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./src/index.ts",
@@ -45,7 +45,7 @@ export function getDatabaseUrl(): string {
45
45
 
46
46
  /**
47
47
  * Raw env var for the files root directory.
48
- * Use getFilesRoot() from @/lib/files/safe-path which applies the ~/genie-os-files default.
48
+ * Use getFilesRoot() from @/lib/files/safe-path which applies the ~/khal-os-files default.
49
49
  *
50
50
  * Server-only path config — safe to read (just a string), but the default requires node:os.
51
51
  */
@@ -18,7 +18,7 @@ export async function runMigrations(): Promise<void> {
18
18
  return;
19
19
  }
20
20
 
21
- const searchPath = process.env.GENIE_OS_SEARCH_PATH;
21
+ const searchPath = process.env.KHAL_OS_SEARCH_PATH;
22
22
  const opts: Record<string, unknown> = { max: 1 };
23
23
  if (searchPath) {
24
24
  opts.connection = { search_path: searchPath };
@@ -2,7 +2,7 @@
2
2
  * Service runtime helper — abstracts NATS connect + subscribe + graceful shutdown boilerplate.
3
3
  *
4
4
  * Usage:
5
- * import { createService } from '@genie-os/sdk';
5
+ * import { createService } from '@khal-os/sdk';
6
6
  *
7
7
  * createService({
8
8
  * name: 'my-service',
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/ui",
2
+ "name": "@khal-os/ui",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./src/index.ts",
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/settings-app",
2
+ "name": "@khal-os/settings-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -64,7 +64,7 @@ export function Settings(_props: { windowId: string; meta?: Record<string, unkno
64
64
  </SplitPane>
65
65
  </div>
66
66
  <StatusBar>
67
- <StatusBar.Item>Genie OS</StatusBar.Item>
67
+ <StatusBar.Item>Khal OS</StatusBar.Item>
68
68
  <StatusBar.Spacer />
69
69
  <StatusBar.Item variant="success">local</StatusBar.Item>
70
70
  </StatusBar>
@@ -222,7 +222,7 @@ function AboutTab() {
222
222
  return (
223
223
  <div className="flex max-w-2xl flex-col gap-8 text-gray-1000">
224
224
  <section>
225
- <SectionHeader title="Genie OS" description="Desktop-in-browser OS shell." />
225
+ <SectionHeader title="Khal OS" description="Desktop-in-browser OS shell." />
226
226
  <PropertyPanel className="rounded-lg border border-gray-alpha-200">
227
227
  <PropertyPanel.Section>
228
228
  <PropertyPanel.Row label="Version">v2-dev</PropertyPanel.Row>
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "@genie-os/terminal-app",
2
+ "name": "@khal-os/terminal-app",
3
3
  "version": "0.0.1",
4
4
  "private": true,
5
5
  "main": "./manifest.ts",
@@ -1,5 +1,5 @@
1
- import type { NatsConnection } from '@genie-os/sdk/service';
2
- import { createService } from '@genie-os/sdk/service';
1
+ import type { NatsConnection } from '@khal-os/sdk/service';
2
+ import { createService } from '@khal-os/sdk/service';
3
3
  import type {
4
4
  PtyCreateRequest,
5
5
  PtyDestroyRequest,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Role hierarchy and normalization for Genie OS RBAC.
2
+ * Role hierarchy and normalization for Khal OS RBAC.
3
3
  *
4
4
  * Forward-compatible role slugs for Phase 1 (platform scope).
5
5
  * WorkOS auto-prefixes org roles with `org-` in Phase 2,
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
2
  import { existsSync, readdirSync, readFileSync } from 'node:fs';
3
3
  import { relative, resolve } from 'node:path';
4
- import { ensureO11yStreams } from '@genie-os/sdk/service/o11y-streams';
4
+ import { ensureO11yStreams } from '@khal-os/sdk/service/o11y-streams';
5
5
  import { connect } from '@nats-io/transport-node';
6
6
 
7
7
  const ROOT = resolve(import.meta.dir, '../components/apps');
@@ -1,5 +1,5 @@
1
1
  // @ts-nocheck
2
- import { extractTrace, injectTrace, newSpan } from '@genie-os/sdk/service/trace';
2
+ import { extractTrace, injectTrace, newSpan } from '@khal-os/sdk/service/trace';
3
3
  import type { NatsConnection, Subscription } from '@nats-io/transport-node';
4
4
  import { headers } from '@nats-io/transport-node';
5
5
  import type { ServerWebSocket } from 'bun';
@@ -2,7 +2,7 @@ import { create } from 'zustand';
2
2
  import { DEFAULT_SHORTCUTS } from '@/lib/keyboard/defaults';
3
3
  import type { KeyCombo, ShortcutDefinition } from '@/lib/keyboard/types';
4
4
 
5
- const STORAGE_KEY = 'sandcastle:keybinds';
5
+ const STORAGE_KEY = 'khal-os:keybinds';
6
6
 
7
7
  interface KeybindStore {
8
8
  overrides: Record<string, KeyCombo | null>;
@@ -65,7 +65,7 @@ interface NotificationStore {
65
65
  const MAX_VISIBLE = 5;
66
66
  const MAX_HISTORY = 50;
67
67
 
68
- const PREFS_KEY = 'sandcastle_notification_prefs';
68
+ const PREFS_KEY = 'khal_os_notification_prefs';
69
69
 
70
70
  function loadPrefs(): {
71
71
  doNotDisturb: boolean;
package/tauri/Cargo.toml CHANGED
@@ -1,5 +1,5 @@
1
1
  [package]
2
- name = "genie-os"
2
+ name = "khal-os"
3
3
  version = "0.1.0"
4
4
  edition = "2021"
5
5
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "identifier": "default",
3
- "description": "Default capabilities for Genie OS",
3
+ "description": "Default capabilities for Khal OS",
4
4
  "windows": ["*"],
5
5
  "permissions": [
6
6
  "core:default",
package/tauri/src/main.rs CHANGED
@@ -1,7 +1,7 @@
1
- // Genie OS — Native wrapper for the web-based desktop shell.
1
+ // Khal OS — Native wrapper for the web-based desktop shell.
2
2
  //
3
3
  // The Tauri app is a thin client that:
4
- // 1. Starts the backend services (PM2 or genie-os CLI)
4
+ // 1. Starts the backend services (PM2 or khal-os CLI)
5
5
  // 2. Opens a webview pointing to the Next.js app at localhost:8888
6
6
  // 3. Exposes Tauri IPC so the frontend can open native windows
7
7
  //
@@ -22,7 +22,7 @@ use tauri::ipc::CapabilityBuilder;
22
22
  use tauri::menu::{MenuBuilder, MenuItemBuilder};
23
23
  use tauri::tray::TrayIconBuilder;
24
24
 
25
- const GENIE_OS_URL: &str = "http://localhost:8888";
25
+ const KHAL_OS_URL: &str = "http://localhost:8888";
26
26
  const DESKTOP_URL: &str = "http://localhost:8888/desktop";
27
27
 
28
28
  // Track whether we started the services ourselves
@@ -32,7 +32,7 @@ struct AppState {
32
32
 
33
33
  // ── Commands ─────────────────────────────────────────────────────────────────
34
34
 
35
- /// Open a native app window pointing to a URL path on the Genie OS server.
35
+ /// Open a native app window pointing to a URL path on the Khal OS server.
36
36
  /// Called from frontend when running in Tauri mode.
37
37
  #[tauri::command]
38
38
  fn open_app_window(app: tauri::AppHandle, app_id: String, title: Option<String>, url: Option<String>) {
@@ -46,7 +46,7 @@ fn open_app_window(app: tauri::AppHandle, app_id: String, title: Option<String>,
46
46
  }
47
47
 
48
48
  // Each app gets its own standalone page — no desktop shell overhead
49
- let target_url = url.unwrap_or_else(|| format!("{}/standalone/{}", GENIE_OS_URL, app_id));
49
+ let target_url = url.unwrap_or_else(|| format!("{}/standalone/{}", KHAL_OS_URL, app_id));
50
50
  let win_title = title.unwrap_or_else(|| app_id.clone());
51
51
 
52
52
  let app_clone = app.clone();
@@ -152,7 +152,7 @@ fn close_app_window(app: tauri::AppHandle, app_id: String) {
152
152
  #[tauri::command]
153
153
  async fn check_services() -> Result<bool, String> {
154
154
  // Quick HTTP check on the Next.js server
155
- let resp = reqwest::get(GENIE_OS_URL).await;
155
+ let resp = reqwest::get(KHAL_OS_URL).await;
156
156
  Ok(resp.is_ok())
157
157
  }
158
158
 
@@ -180,9 +180,9 @@ fn center_on_cursor_monitor(window: &tauri::WebviewWindow) {
180
180
  }
181
181
 
182
182
  fn start_services() -> bool {
183
- // The Tauri app lives in src-tauri/ inside the genie-os-web repo.
183
+ // The Tauri app lives in src-tauri/ inside the khal-os-web repo.
184
184
  // ecosystem.config.cjs is in the parent directory (repo root).
185
- let genie_os_web = std::env::current_exe()
185
+ let khal_os_web = std::env::current_exe()
186
186
  .ok()
187
187
  .and_then(|p| p.parent().map(|p| p.to_path_buf())) // src-tauri/target/debug/
188
188
  .map(|p| p.join("../../../..")) // up to repo root
@@ -190,37 +190,37 @@ fn start_services() -> bool {
190
190
  .unwrap_or_else(|| {
191
191
  // Fallback: try known path
192
192
  dirs::home_dir()
193
- .map(|h| h.join("Dev/namastex/genie-os-web"))
193
+ .map(|h| h.join("Dev/namastex/khal-os-web"))
194
194
  .unwrap_or_default()
195
195
  });
196
196
 
197
- if !genie_os_web.join("ecosystem.config.cjs").exists() {
198
- eprintln!("[genie-os] ecosystem.config.cjs not found at {:?}", genie_os_web);
197
+ if !khal_os_web.join("ecosystem.config.cjs").exists() {
198
+ eprintln!("[khal-os] ecosystem.config.cjs not found at {:?}", khal_os_web);
199
199
  return false;
200
200
  }
201
201
 
202
- eprintln!("[genie-os] starting services via PM2...");
202
+ eprintln!("[khal-os] starting services via PM2...");
203
203
  let status = std::process::Command::new("pm2")
204
204
  .args(["start", "ecosystem.config.cjs"])
205
- .current_dir(&genie_os_web)
205
+ .current_dir(&khal_os_web)
206
206
  .stdout(std::process::Stdio::null())
207
207
  .stderr(std::process::Stdio::null())
208
208
  .status();
209
209
 
210
210
  match status {
211
211
  Ok(s) if s.success() => {
212
- eprintln!("[genie-os] PM2 services started");
212
+ eprintln!("[khal-os] PM2 services started");
213
213
  true
214
214
  }
215
215
  _ => {
216
- eprintln!("[genie-os] failed to start PM2 services");
216
+ eprintln!("[khal-os] failed to start PM2 services");
217
217
  false
218
218
  }
219
219
  }
220
220
  }
221
221
 
222
222
  fn stop_services() {
223
- // Stop only genie-os services, not everything in PM2
223
+ // Stop only khal-os services, not everything in PM2
224
224
  for name in &["os-nats", "os-services", "os-dev", "os-ws-bridge"] {
225
225
  let _ = std::process::Command::new("pm2")
226
226
  .args(["stop", name])
@@ -228,7 +228,7 @@ fn stop_services() {
228
228
  .stderr(std::process::Stdio::null())
229
229
  .status();
230
230
  }
231
- eprintln!("[genie-os] PM2 services stopped");
231
+ eprintln!("[khal-os] PM2 services stopped");
232
232
  }
233
233
 
234
234
  fn wait_for_server(max_secs: u32) -> bool {
@@ -288,13 +288,13 @@ fn main() {
288
288
  if started {
289
289
  app.state::<Mutex<AppState>>().lock().unwrap().services_started_by_us = true;
290
290
  // Wait for Next.js to be ready
291
- eprintln!("[genie-os] waiting for server on :8888...");
291
+ eprintln!("[khal-os] waiting for server on :8888...");
292
292
  if !wait_for_server(30) {
293
- eprintln!("[genie-os] server did not start in time — opening anyway");
293
+ eprintln!("[khal-os] server did not start in time — opening anyway");
294
294
  }
295
295
  }
296
296
  } else {
297
- eprintln!("[genie-os] server already running on :8888");
297
+ eprintln!("[khal-os] server already running on :8888");
298
298
  }
299
299
 
300
300
  // ── Main window: load the web desktop ────────────────────────
@@ -303,7 +303,7 @@ fn main() {
303
303
  "main",
304
304
  WebviewUrl::External(DESKTOP_URL.parse().unwrap()),
305
305
  )
306
- .title("Genie OS")
306
+ .title("Khal OS")
307
307
  .inner_size(1280.0, 800.0)
308
308
  .resizable(true)
309
309
  .decorations(false)
@@ -321,7 +321,7 @@ fn main() {
321
321
  .build(app)?;
322
322
  let settings = MenuItemBuilder::with_id("settings", "Settings")
323
323
  .build(app)?;
324
- let quit_item = MenuItemBuilder::with_id("quit", "Quit Genie OS")
324
+ let quit_item = MenuItemBuilder::with_id("quit", "Quit Khal OS")
325
325
  .build(app)?;
326
326
 
327
327
  let tray_menu = MenuBuilder::new(app)
@@ -337,7 +337,7 @@ fn main() {
337
337
  .icon(app.default_window_icon().cloned().unwrap())
338
338
  .icon_as_template(true)
339
339
  .menu(&tray_menu)
340
- .tooltip("Genie OS")
340
+ .tooltip("Khal OS")
341
341
  .on_menu_event(move |app_handle, event| {
342
342
  match event.id().as_ref() {
343
343
  "toggle_main" => {
@@ -383,7 +383,7 @@ fn main() {
383
383
  Ok(())
384
384
  })
385
385
  .build(tauri::generate_context!())
386
- .expect("error building genie-os")
386
+ .expect("error building khal-os")
387
387
  .run(|app, event| {
388
388
  if let tauri::RunEvent::ExitRequested { .. } = event {
389
389
  if let Some(state) = app.try_state::<Mutex<AppState>>() {
@@ -1,7 +1,7 @@
1
1
  {
2
- "productName": "Genie OS",
2
+ "productName": "Khal OS",
3
3
  "version": "0.1.0",
4
- "identifier": "ai.automagik.genie-os",
4
+ "identifier": "ai.automagik.khal-os",
5
5
  "build": {
6
6
  "frontendDist": "../dist",
7
7
  "beforeDevCommand": "",