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.
- package/docs/workos-setup.md +1 -1
- package/package.json +9 -9
- package/packages/dev3000-app/package.json +1 -1
- package/packages/dev3000-app/views/dev3000/service/index.ts +1 -1
- package/packages/files-app/package.json +1 -1
- package/packages/files-app/views/files/FilesApp.tsx +1 -1
- package/packages/files-app/views/files/service/index.ts +2 -2
- package/packages/genie-app/package.json +1 -1
- package/packages/genie-app/views/genie/service/agent-lifecycle.ts +1 -1
- package/packages/genie-app/views/genie/service/comms.ts +1 -1
- package/packages/genie-app/views/genie/service/index.ts +2 -2
- package/packages/genie-app/views/genie/service/teams.ts +1 -1
- package/packages/nats-viewer-app/package.json +1 -1
- package/packages/os-cli/package.json +2 -2
- package/packages/os-cli/src/index.ts +1 -1
- package/packages/os-sdk/package.json +1 -1
- package/packages/os-sdk/src/config.ts +1 -1
- package/packages/os-sdk/src/db/migrate.ts +1 -1
- package/packages/os-sdk/src/service/runtime.ts +1 -1
- package/packages/os-ui/package.json +1 -1
- package/packages/settings-app/package.json +1 -1
- package/packages/settings-app/views/settings/Settings.tsx +2 -2
- package/packages/terminal-app/package.json +1 -1
- package/packages/terminal-app/views/terminal/service/index.ts +2 -2
- package/src/lib/auth/roles.ts +1 -1
- package/src/lib/service-loader.ts +1 -1
- package/src/lib/ws-bridge.ts +1 -1
- package/src/stores/keybind-store.ts +1 -1
- package/src/stores/notification-store.ts +1 -1
- package/tauri/Cargo.toml +1 -1
- package/tauri/capabilities/default.json +1 -1
- package/tauri/src/main.rs +24 -24
- package/tauri/tauri.conf.json +2 -2
package/docs/workos-setup.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "khal-os",
|
|
3
|
-
"version": "1.260324.
|
|
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
|
-
"@
|
|
20
|
-
"@
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { createService } from '@
|
|
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();
|
|
@@ -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 = '
|
|
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 '@
|
|
5
|
-
import { createService } from '@
|
|
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
|
|
|
@@ -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 '@
|
|
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 '@
|
|
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 '@
|
|
2
|
-
import { createService } from '@
|
|
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 '@
|
|
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,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@
|
|
2
|
+
"name": "@khal-os/cli",
|
|
3
3
|
"version": "0.0.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
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('
|
|
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);
|
|
@@ -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 ~/
|
|
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.
|
|
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 };
|
|
@@ -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>
|
|
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="
|
|
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
|
-
import type { NatsConnection } from '@
|
|
2
|
-
import { createService } from '@
|
|
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,
|
package/src/lib/auth/roles.ts
CHANGED
|
@@ -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 '@
|
|
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');
|
package/src/lib/ws-bridge.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
import { extractTrace, injectTrace, newSpan } from '@
|
|
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 = '
|
|
5
|
+
const STORAGE_KEY = 'khal-os:keybinds';
|
|
6
6
|
|
|
7
7
|
interface KeybindStore {
|
|
8
8
|
overrides: Record<string, KeyCombo | null>;
|
package/tauri/Cargo.toml
CHANGED
package/tauri/src/main.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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/{}",
|
|
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(
|
|
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
|
|
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
|
|
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/
|
|
193
|
+
.map(|h| h.join("Dev/namastex/khal-os-web"))
|
|
194
194
|
.unwrap_or_default()
|
|
195
195
|
});
|
|
196
196
|
|
|
197
|
-
if !
|
|
198
|
-
eprintln!("[
|
|
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!("[
|
|
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(&
|
|
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!("[
|
|
212
|
+
eprintln!("[khal-os] PM2 services started");
|
|
213
213
|
true
|
|
214
214
|
}
|
|
215
215
|
_ => {
|
|
216
|
-
eprintln!("[
|
|
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
|
|
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!("[
|
|
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!("[
|
|
291
|
+
eprintln!("[khal-os] waiting for server on :8888...");
|
|
292
292
|
if !wait_for_server(30) {
|
|
293
|
-
eprintln!("[
|
|
293
|
+
eprintln!("[khal-os] server did not start in time — opening anyway");
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
} else {
|
|
297
|
-
eprintln!("[
|
|
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("
|
|
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
|
|
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("
|
|
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
|
|
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>>() {
|
package/tauri/tauri.conf.json
CHANGED