khal-os 1.260324.2
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/.env.example +23 -0
- package/.genie/mailbox/cli-sent.jsonl +3 -0
- package/.genie/mailbox/ds1-wave2-engineer-1.json +15 -0
- package/.genie/mailbox/ds1-wave2-engineer-2.json +15 -0
- package/.genie/mailbox/ds1-wave2-engineer-3.json +15 -0
- package/.genie/state/os-observability.json +39 -0
- package/.genie/state/tmux-control-mode-terminal.json +28 -0
- package/.genie/wishes/genieos-one-theme/WISH.md +417 -0
- package/.genie/wishes/workos-prod-rbac/WISH.md +345 -0
- package/.github/workflows/ci.yml +39 -0
- package/.github/workflows/release.yml +78 -0
- package/.github/workflows/version.yml +122 -0
- package/.husky/pre-commit +1 -0
- package/.pnpm-approve-builds.json +1 -0
- package/CLAUDE.md +117 -0
- package/LICENSE +21 -0
- package/README.md +38 -0
- package/biome.json +124 -0
- package/bun.lock +1249 -0
- package/docs/workos-setup.md +116 -0
- package/ecosystem.config.cjs +26 -0
- package/instrumentation.ts +8 -0
- package/knip.json +35 -0
- package/nats.conf +7 -0
- package/next.config.ts +25 -0
- package/package.json +78 -0
- package/packages/dev3000-app/components.ts +12 -0
- package/packages/dev3000-app/manifest.ts +19 -0
- package/packages/dev3000-app/package.json +23 -0
- package/packages/dev3000-app/views/dev3000/Dev3000App.tsx +758 -0
- package/packages/dev3000-app/views/dev3000/ErrorsPanel.tsx +160 -0
- package/packages/dev3000-app/views/dev3000/dev3000-context.tsx +21 -0
- package/packages/dev3000-app/views/dev3000/index.ts +4 -0
- package/packages/dev3000-app/views/dev3000/schema.ts +55 -0
- package/packages/dev3000-app/views/dev3000/service/index.ts +358 -0
- package/packages/dev3000-app/views/dev3000/service/runtime +1 -0
- package/packages/dev3000-app/views/dev3000/subjects.ts +9 -0
- package/packages/dev3000-app/views/dev3000/types.ts +77 -0
- package/packages/files-app/components.ts +12 -0
- package/packages/files-app/manifest.ts +19 -0
- package/packages/files-app/package.json +23 -0
- package/packages/files-app/views/files/ContextMenu.tsx +151 -0
- package/packages/files-app/views/files/DeleteConfirmDialog.tsx +39 -0
- package/packages/files-app/views/files/FileItem.tsx +128 -0
- package/packages/files-app/views/files/FilesApp.tsx +509 -0
- package/packages/files-app/views/files/FilesListView.tsx +201 -0
- package/packages/files-app/views/files/FilesToolbar.tsx +117 -0
- package/packages/files-app/views/files/GridView.tsx +90 -0
- package/packages/files-app/views/files/InlineInput.tsx +131 -0
- package/packages/files-app/views/files/UploadOverlay.tsx +61 -0
- package/packages/files-app/views/files/schema.ts +49 -0
- package/packages/files-app/views/files/service/index.ts +184 -0
- package/packages/files-app/views/files/service/runtime +1 -0
- package/packages/files-app/views/files/use-files.ts +201 -0
- package/packages/files-app/views/files/use-upload.ts +105 -0
- package/packages/genie-app/components.ts +12 -0
- package/packages/genie-app/lib/subjects.ts +87 -0
- package/packages/genie-app/manifest.ts +19 -0
- package/packages/genie-app/package.json +29 -0
- package/packages/genie-app/views/genie/service/agent-lifecycle.ts +136 -0
- package/packages/genie-app/views/genie/service/cli.ts +114 -0
- package/packages/genie-app/views/genie/service/comms.ts +141 -0
- package/packages/genie-app/views/genie/service/directory.ts +167 -0
- package/packages/genie-app/views/genie/service/index.ts +219 -0
- package/packages/genie-app/views/genie/service/system.ts +123 -0
- package/packages/genie-app/views/genie/service/teams.ts +191 -0
- package/packages/genie-app/views/genie/service/terminal-proxy.ts +184 -0
- package/packages/genie-app/views/genie/service/tmux-control.ts +318 -0
- package/packages/genie-app/views/genie/service/wishes.ts +270 -0
- package/packages/genie-app/views/genie/ui/GenieApp.tsx +5 -0
- package/packages/genie-app/views/genie/ui/PaneCard.tsx +307 -0
- package/packages/genie-app/views/genie/ui/Sidebar.tsx +212 -0
- package/packages/genie-app/views/genie/ui/TabBar.tsx +70 -0
- package/packages/genie-app/views/genie/ui/WorkspaceCanvas.tsx +343 -0
- package/packages/genie-app/views/genie/ui/XTermPane.tsx +306 -0
- package/packages/genie-app/views/genie/ui/hooks/useNatsAction.ts +54 -0
- package/packages/genie-app/views/genie/ui/hooks/useNatsRequest.ts +68 -0
- package/packages/genie-app/views/genie/ui/panels/AgentsPanel.tsx +399 -0
- package/packages/genie-app/views/genie/ui/panels/ChatPanel.tsx +351 -0
- package/packages/genie-app/views/genie/ui/panels/SystemPanel.tsx +195 -0
- package/packages/genie-app/views/genie/ui/panels/TeamsPanel.tsx +560 -0
- package/packages/genie-app/views/genie/ui/panels/WishesPanel.tsx +424 -0
- package/packages/nats-viewer-app/components.ts +12 -0
- package/packages/nats-viewer-app/manifest.ts +18 -0
- package/packages/nats-viewer-app/package.json +14 -0
- package/packages/nats-viewer-app/views/nats-viewer/ActiveSubs.tsx +34 -0
- package/packages/nats-viewer-app/views/nats-viewer/MessageLog.tsx +247 -0
- package/packages/nats-viewer-app/views/nats-viewer/NatsViewer.tsx +209 -0
- package/packages/nats-viewer-app/views/nats-viewer/PublishPanel.tsx +111 -0
- package/packages/nats-viewer-app/views/nats-viewer/RequestPanel.tsx +165 -0
- package/packages/nats-viewer-app/views/nats-viewer/Sidebar.tsx +59 -0
- package/packages/nats-viewer-app/views/nats-viewer/SubjectCatalog.tsx +63 -0
- package/packages/nats-viewer-app/views/nats-viewer/SubscribeInput.tsx +59 -0
- package/packages/nats-viewer-app/views/nats-viewer/index.ts +5 -0
- package/packages/nats-viewer-app/views/nats-viewer/nats-viewer-context.tsx +31 -0
- package/packages/nats-viewer-app/views/nats-viewer/types.ts +7 -0
- package/packages/nats-viewer-app/views/nats-viewer/use-message-buffer.ts +55 -0
- package/packages/os-cli/package.json +18 -0
- package/packages/os-cli/src/commands/events.ts +176 -0
- package/packages/os-cli/src/commands/logs.ts +96 -0
- package/packages/os-cli/src/commands/status.ts +53 -0
- package/packages/os-cli/src/commands/traces.ts +115 -0
- package/packages/os-cli/src/index.ts +15 -0
- package/packages/os-cli/src/lib/formatter.ts +123 -0
- package/packages/os-cli/src/lib/nats.ts +16 -0
- package/packages/os-cli/src/lib/trace-tree.ts +144 -0
- package/packages/os-cli/tsconfig.json +12 -0
- package/packages/os-sdk/package.json +27 -0
- package/packages/os-sdk/src/api/handler.ts +67 -0
- package/packages/os-sdk/src/config.ts +68 -0
- package/packages/os-sdk/src/db/factory.test.ts +42 -0
- package/packages/os-sdk/src/db/factory.ts +72 -0
- package/packages/os-sdk/src/db/migrate.ts +140 -0
- package/packages/os-sdk/src/db/provision.ts +44 -0
- package/packages/os-sdk/src/index.ts +36 -0
- package/packages/os-sdk/src/service/console-intercept.ts +60 -0
- package/packages/os-sdk/src/service/logger.ts +88 -0
- package/packages/os-sdk/src/service/o11y-streams.ts +88 -0
- package/packages/os-sdk/src/service/runtime.ts +259 -0
- package/packages/os-sdk/src/service/trace.ts +71 -0
- package/packages/os-sdk/tsconfig.json +16 -0
- package/packages/os-ui/package.json +13 -0
- package/packages/os-ui/src/index.ts +29 -0
- package/packages/os-ui/src/server.ts +4 -0
- package/packages/os-ui/tsconfig.json +19 -0
- package/packages/settings-app/components.ts +12 -0
- package/packages/settings-app/manifest.ts +18 -0
- package/packages/settings-app/package.json +14 -0
- package/packages/settings-app/views/settings/Settings.tsx +492 -0
- package/packages/terminal-app/components.ts +12 -0
- package/packages/terminal-app/manifest.ts +20 -0
- package/packages/terminal-app/package.json +23 -0
- package/packages/terminal-app/views/terminal/schema.ts +82 -0
- package/packages/terminal-app/views/terminal/service/index.ts +133 -0
- package/packages/terminal-app/views/terminal/service/runtime +1 -0
- package/packages/terminal-app/views/terminal/service/session.ts +290 -0
- package/packages/terminal-app/views/terminal/service/shell-hooks/bashrc-hook.sh +21 -0
- package/packages/terminal-app/views/terminal/types.ts +26 -0
- package/packages/terminal-app/views/terminal/ui/MultiTerminalApp.tsx +615 -0
- package/packages/terminal-app/views/terminal/ui/SplitDragHandle.tsx +91 -0
- package/packages/terminal-app/views/terminal/ui/SplitPaneRenderer.tsx +112 -0
- package/packages/terminal-app/views/terminal/ui/TerminalPane.tsx +478 -0
- package/packages/terminal-app/views/terminal/ui/TerminalTabBar.tsx +131 -0
- package/pnpm-workspace.yaml +9 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/icons/code-server.svg +6 -0
- package/public/icons/default.svg +5 -0
- package/public/icons/dusk/1password.svg +1 -0
- package/public/icons/dusk/activity_monitor.svg +1 -0
- package/public/icons/dusk/app_store.svg +1 -0
- package/public/icons/dusk/atom.svg +1 -0
- package/public/icons/dusk/brave.svg +1 -0
- package/public/icons/dusk/calculator.svg +1 -0
- package/public/icons/dusk/calendar.svg +1 -0
- package/public/icons/dusk/chrome.svg +1 -0
- package/public/icons/dusk/chrome2.svg +1 -0
- package/public/icons/dusk/dashboard.svg +13 -0
- package/public/icons/dusk/discord.svg +1 -0
- package/public/icons/dusk/dropbox.svg +1 -0
- package/public/icons/dusk/electron.svg +1 -0
- package/public/icons/dusk/figma.svg +1 -0
- package/public/icons/dusk/finder.svg +1 -0
- package/public/icons/dusk/finder2.svg +1 -0
- package/public/icons/dusk/finder3.svg +1 -0
- package/public/icons/dusk/firefox.svg +1 -0
- package/public/icons/dusk/framer.svg +1 -0
- package/public/icons/dusk/gimp.svg +1 -0
- package/public/icons/dusk/github_desktop.svg +1 -0
- package/public/icons/dusk/hyper.svg +1 -0
- package/public/icons/dusk/hyper3.svg +1 -0
- package/public/icons/dusk/intellij.svg +1 -0
- package/public/icons/dusk/iterm2.svg +1 -0
- package/public/icons/dusk/itunes.svg +1 -0
- package/public/icons/dusk/mail.svg +1 -0
- package/public/icons/dusk/messenger.svg +1 -0
- package/public/icons/dusk/mongodb.svg +1 -0
- package/public/icons/dusk/notes.svg +1 -0
- package/public/icons/dusk/notion.svg +1 -0
- package/public/icons/dusk/obs.svg +1 -0
- package/public/icons/dusk/pages.svg +1 -0
- package/public/icons/dusk/photos.svg +1 -0
- package/public/icons/dusk/postman.svg +1 -0
- package/public/icons/dusk/preview.svg +1 -0
- package/public/icons/dusk/reminders.svg +1 -0
- package/public/icons/dusk/safari.svg +1 -0
- package/public/icons/dusk/sequel_pro.svg +1 -0
- package/public/icons/dusk/sketch.svg +1 -0
- package/public/icons/dusk/skype.svg +1 -0
- package/public/icons/dusk/slack.svg +1 -0
- package/public/icons/dusk/slack2.svg +1 -0
- package/public/icons/dusk/spotify.svg +1 -0
- package/public/icons/dusk/steam.svg +1 -0
- package/public/icons/dusk/system_preferences.svg +1 -0
- package/public/icons/dusk/tableplus.svg +1 -0
- package/public/icons/dusk/teams.svg +1 -0
- package/public/icons/dusk/telegram.svg +1 -0
- package/public/icons/dusk/terminal.svg +1 -0
- package/public/icons/dusk/todoist.svg +1 -0
- package/public/icons/dusk/trash.svg +1 -0
- package/public/icons/dusk/trello.svg +1 -0
- package/public/icons/dusk/vivaldi.svg +1 -0
- package/public/icons/dusk/vlc.svg +1 -0
- package/public/icons/dusk/vscode.svg +1 -0
- package/public/icons/dusk/whatsapp.svg +1 -0
- package/public/icons/dusk/xeyes.svg +1 -0
- package/public/icons/dusk/zoom.svg +1 -0
- package/public/icons/files.svg +5 -0
- package/public/icons/pwa/icon-192.png +0 -0
- package/public/icons/pwa/icon-512.png +0 -0
- package/public/icons/settings.svg +14 -0
- package/public/icons/terminal.svg +5 -0
- package/public/icons/text-editor.svg +7 -0
- package/public/manifest.json +38 -0
- package/public/next.svg +1 -0
- package/public/sw.js +41 -0
- package/public/vercel.svg +1 -0
- package/public/wallpapers/default.svg +10 -0
- package/public/window.svg +1 -0
- package/scripts/generate-pwa-icons.mjs +33 -0
- package/scripts/install-nats.sh +37 -0
- package/sentry.client.config.ts +21 -0
- package/sentry.edge.config.ts +12 -0
- package/sentry.server.config.ts +12 -0
- package/src/app/api/files/download/route.ts +81 -0
- package/src/app/api/files/download-zip/route.ts +102 -0
- package/src/app/api/files/upload/route.ts +58 -0
- package/src/app/api/webhooks/workos/route.ts +98 -0
- package/src/app/auth/callback/route.ts +16 -0
- package/src/app/auth/logout/route.ts +15 -0
- package/src/app/desktop/desktop-shell.tsx +110 -0
- package/src/app/desktop/layout.tsx +8 -0
- package/src/app/desktop/page.tsx +24 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +7 -0
- package/src/app/layout.tsx +64 -0
- package/src/app/offline/page.tsx +83 -0
- package/src/app/page.tsx +5 -0
- package/src/app/standalone/[appId]/page.tsx +28 -0
- package/src/app/standalone/layout.tsx +10 -0
- package/src/components/app-icon.tsx +55 -0
- package/src/components/apps/_echo/schema.ts +14 -0
- package/src/components/apps/_echo/service/index.ts +42 -0
- package/src/components/apps/app-manifest.ts +97 -0
- package/src/components/apps/app-registry.ts +55 -0
- package/src/components/apps/dev3000/Dev3000App.tsx +224 -0
- package/src/components/apps/dev3000/ErrorsPanel.tsx +160 -0
- package/src/components/apps/dev3000/Sidebar.tsx +41 -0
- package/src/components/apps/dev3000/TimelineLog.tsx +173 -0
- package/src/components/apps/dev3000/dev3000-context.tsx +29 -0
- package/src/components/apps/dev3000/index.ts +4 -0
- package/src/components/apps/dev3000/schema.ts +48 -0
- package/src/components/apps/dev3000/service/index.ts +520 -0
- package/src/components/apps/dev3000/service/runtime +1 -0
- package/src/components/apps/dev3000/types.ts +15 -0
- package/src/components/apps/dev3000/use-message-buffer.ts +46 -0
- package/src/components/apps/files/ContextMenu.tsx +151 -0
- package/src/components/apps/files/DeleteConfirmDialog.tsx +78 -0
- package/src/components/apps/files/FileItem.tsx +128 -0
- package/src/components/apps/files/FilesApp.tsx +509 -0
- package/src/components/apps/files/FilesListView.tsx +201 -0
- package/src/components/apps/files/FilesToolbar.tsx +117 -0
- package/src/components/apps/files/GridView.tsx +90 -0
- package/src/components/apps/files/InlineInput.tsx +131 -0
- package/src/components/apps/files/UploadOverlay.tsx +61 -0
- package/src/components/apps/files/schema.ts +49 -0
- package/src/components/apps/files/service/index.ts +227 -0
- package/src/components/apps/files/service/runtime +1 -0
- package/src/components/apps/files/use-files.ts +201 -0
- package/src/components/apps/files/use-upload.ts +105 -0
- package/src/components/apps/nats-viewer/ActiveSubs.tsx +34 -0
- package/src/components/apps/nats-viewer/MessageLog.tsx +247 -0
- package/src/components/apps/nats-viewer/NatsViewer.tsx +209 -0
- package/src/components/apps/nats-viewer/PublishPanel.tsx +113 -0
- package/src/components/apps/nats-viewer/RequestPanel.tsx +167 -0
- package/src/components/apps/nats-viewer/Sidebar.tsx +62 -0
- package/src/components/apps/nats-viewer/SubjectCatalog.tsx +64 -0
- package/src/components/apps/nats-viewer/SubscribeInput.tsx +59 -0
- package/src/components/apps/nats-viewer/index.ts +5 -0
- package/src/components/apps/nats-viewer/nats-viewer-context.tsx +31 -0
- package/src/components/apps/nats-viewer/types.ts +7 -0
- package/src/components/apps/nats-viewer/use-message-buffer.ts +55 -0
- package/src/components/apps/settings/Settings.tsx +492 -0
- package/src/components/apps/terminal/schema.ts +82 -0
- package/src/components/apps/terminal/service/index.ts +189 -0
- package/src/components/apps/terminal/service/runtime +1 -0
- package/src/components/apps/terminal/service/session.ts +296 -0
- package/src/components/apps/terminal/service/shell-hooks/bashrc-hook.sh +21 -0
- package/src/components/apps/terminal/types.ts +26 -0
- package/src/components/apps/terminal/ui/MultiTerminalApp.tsx +617 -0
- package/src/components/apps/terminal/ui/SplitDragHandle.tsx +91 -0
- package/src/components/apps/terminal/ui/SplitPaneRenderer.tsx +112 -0
- package/src/components/apps/terminal/ui/TerminalPane.tsx +476 -0
- package/src/components/apps/terminal/ui/TerminalTabBar.tsx +131 -0
- package/src/components/desktop/AnimatedBackground.tsx +69 -0
- package/src/components/desktop/Desktop.tsx +79 -0
- package/src/components/desktop/DesktopBackground.tsx +16 -0
- package/src/components/desktop/DesktopIcon.tsx +49 -0
- package/src/components/desktop/ShortcutViewer.tsx +136 -0
- package/src/components/desktop/WindowRenderer.tsx +34 -0
- package/src/components/desktop/WindowSwitcher.tsx +42 -0
- package/src/components/notifications/NotificationCenter.tsx +153 -0
- package/src/components/notifications/NotificationToasts.tsx +66 -0
- package/src/components/notifications/OrphanSessionToast.tsx +293 -0
- package/src/components/os-primitives/collapsible-sidebar.tsx +226 -0
- package/src/components/os-primitives/dialog.tsx +76 -0
- package/src/components/os-primitives/empty-state.tsx +43 -0
- package/src/components/os-primitives/index.ts +21 -0
- package/src/components/os-primitives/list-view.tsx +155 -0
- package/src/components/os-primitives/property-panel.tsx +108 -0
- package/src/components/os-primitives/section-header.tsx +19 -0
- package/src/components/os-primitives/sidebar-nav.tsx +110 -0
- package/src/components/os-primitives/split-pane.tsx +146 -0
- package/src/components/os-primitives/status-badge.tsx +10 -0
- package/src/components/os-primitives/status-bar.tsx +100 -0
- package/src/components/os-primitives/toolbar.tsx +152 -0
- package/src/components/taskbar/AppLauncher.tsx +114 -0
- package/src/components/taskbar/RunningApps.tsx +71 -0
- package/src/components/taskbar/SystemTray.tsx +134 -0
- package/src/components/taskbar/Taskbar.tsx +45 -0
- package/src/components/taskbar/UserMenu.tsx +138 -0
- package/src/components/taskbar/WorkspaceSwitcher.tsx +9 -0
- package/src/components/ui/ContextMenu.tsx +130 -0
- package/src/components/ui/badge.tsx +39 -0
- package/src/components/ui/button.tsx +102 -0
- package/src/components/ui/command.tsx +165 -0
- package/src/components/ui/dropdown-menu.tsx +233 -0
- package/src/components/ui/input.tsx +48 -0
- package/src/components/ui/note.tsx +55 -0
- package/src/components/ui/separator.tsx +25 -0
- package/src/components/ui/spinner.tsx +42 -0
- package/src/components/ui/switch.tsx +36 -0
- package/src/components/ui/theme-provider.tsx +24 -0
- package/src/components/ui/theme-switcher.tsx +51 -0
- package/src/components/ui/tooltip.tsx +62 -0
- package/src/components/window/MobileWindowStack.tsx +218 -0
- package/src/components/window/SnapPreview.tsx +37 -0
- package/src/components/window/StandaloneFrame.tsx +170 -0
- package/src/components/window/Window.tsx +423 -0
- package/src/components/window/WindowContent.tsx +14 -0
- package/src/components/window/WindowControlsOverlay.tsx +89 -0
- package/src/components/window/WindowFrame.tsx +124 -0
- package/src/lib/auth/index.ts +27 -0
- package/src/lib/auth/roles.ts +50 -0
- package/src/lib/auth/types.ts +32 -0
- package/src/lib/auth/use-auth.ts +53 -0
- package/src/lib/auth/webhook-handler.ts +87 -0
- package/src/lib/auth/workos.ts +67 -0
- package/src/lib/constants.ts +1 -0
- package/src/lib/desktop/dedup.ts +57 -0
- package/src/lib/desktop/schema.ts +55 -0
- package/src/lib/files/filename-validation.ts +41 -0
- package/src/lib/files/safe-path.ts +49 -0
- package/src/lib/hooks/use-desktop-nats.ts +438 -0
- package/src/lib/hooks/use-is-mobile.ts +23 -0
- package/src/lib/hooks/use-launch-app.ts +79 -0
- package/src/lib/hooks/use-nats-notifications.ts +84 -0
- package/src/lib/hooks/use-nats.ts +60 -0
- package/src/lib/hooks/use-visual-viewport.ts +72 -0
- package/src/lib/icons/resolve-window-icon.ts +10 -0
- package/src/lib/keyboard/defaults.ts +146 -0
- package/src/lib/keyboard/types.ts +52 -0
- package/src/lib/keyboard/use-global-keybinds.ts +231 -0
- package/src/lib/nats-client.ts +255 -0
- package/src/lib/nats.ts +35 -0
- package/src/lib/notifications/schema.ts +12 -0
- package/src/lib/service-loader.ts +171 -0
- package/src/lib/subjects.ts +64 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/ws-bridge.ts +288 -0
- package/src/lib/ws-protocol.ts +53 -0
- package/src/lib/ws-server.ts +167 -0
- package/src/middleware.ts +57 -0
- package/src/stores/desktop-store.ts +112 -0
- package/src/stores/keybind-store.ts +66 -0
- package/src/stores/notification-store.ts +271 -0
- package/src/stores/theme-store.ts +25 -0
- package/src/stores/window-store.ts +294 -0
- package/src/theme/animations.css +68 -0
- package/src/theme/base.css +123 -0
- package/src/theme/controls.css +35 -0
- package/src/theme/design-tokens.css +276 -0
- package/src/theme/index.css +23 -0
- package/src/theme/menus.css +45 -0
- package/src/theme/status.css +41 -0
- package/src/theme/surfaces.css +94 -0
- package/src/theme/tailwind-map.css +138 -0
- package/src/theme/taskbar.css +25 -0
- package/src/theme/terminal.css +55 -0
- package/src/theme/typography.css +26 -0
- package/src/theme/utilities.css +156 -0
- package/src/theme/window.css +103 -0
- package/src/types/desktop-entry.ts +12 -0
- package/src/types/use-descendants.d.ts +13 -0
- package/src/types/window.ts +28 -0
- package/src/types.d.ts +9 -0
- package/tauri/Cargo.lock +5464 -0
- package/tauri/Cargo.toml +19 -0
- package/tauri/build.rs +3 -0
- package/tauri/capabilities/default.json +36 -0
- package/tauri/icons/128x128.png +0 -0
- package/tauri/icons/128x128@2x.png +0 -0
- package/tauri/icons/32x32.png +0 -0
- package/tauri/icons/icon.png +0 -0
- package/tauri/src/main.rs +396 -0
- package/tauri/tauri.conf.json +23 -0
- package/tsconfig.json +43 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service runtime helper — abstracts NATS connect + subscribe + graceful shutdown boilerplate.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { createService } from '@genie-os/sdk';
|
|
6
|
+
*
|
|
7
|
+
* createService({
|
|
8
|
+
* name: 'my-service',
|
|
9
|
+
* subscriptions: [
|
|
10
|
+
* { subject: 'os.myapp.foo', handler: (msg, nc) => { ... } },
|
|
11
|
+
* ],
|
|
12
|
+
* onReady: async (nc, log) => { log.info('ready'); },
|
|
13
|
+
* onShutdown: async () => { ... },
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { Msg } from '@nats-io/nats-core';
|
|
18
|
+
import { connect, type NatsConnection } from '@nats-io/transport-node';
|
|
19
|
+
import { NATS_URL } from '../config';
|
|
20
|
+
import { interceptConsole } from './console-intercept';
|
|
21
|
+
import type { Logger } from './logger';
|
|
22
|
+
import { createLogger } from './logger';
|
|
23
|
+
import { extractTrace, newSpan } from './trace';
|
|
24
|
+
|
|
25
|
+
// Re-export types so callers don't need to import from @nats-io directly.
|
|
26
|
+
export type { NatsConnection, Msg };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A single NATS subject subscription with its message handler.
|
|
30
|
+
*/
|
|
31
|
+
export interface ServiceHandler {
|
|
32
|
+
/** NATS subject pattern to subscribe to (wildcards supported). */
|
|
33
|
+
subject: string;
|
|
34
|
+
/** Called for each incoming message. Errors are caught and logged. */
|
|
35
|
+
handler: (msg: Msg, nc: NatsConnection) => void | Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Observability configuration for auto-instrumentation.
|
|
40
|
+
*/
|
|
41
|
+
export interface ObserveConfig {
|
|
42
|
+
/** Additional subject patterns to exclude from auto-capture. */
|
|
43
|
+
exclude?: string[];
|
|
44
|
+
/** Minimum log level (default: 'info'). */
|
|
45
|
+
level?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for a managed NATS service.
|
|
50
|
+
*/
|
|
51
|
+
export interface ServiceConfig {
|
|
52
|
+
/** Human-readable name used in log output, e.g. 'pty-service'. */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Subscriptions to set up after connecting. */
|
|
55
|
+
subscriptions?: ServiceHandler[];
|
|
56
|
+
/** Called once after all subscriptions are registered. Receives logger as second arg (backward compatible). */
|
|
57
|
+
onReady?: (nc: NatsConnection, log: Logger) => void | Promise<void>;
|
|
58
|
+
/** Called during graceful shutdown before draining NATS. */
|
|
59
|
+
onShutdown?: () => void | Promise<void>;
|
|
60
|
+
/** Observability config for auto-instrumentation. */
|
|
61
|
+
observe?: ObserveConfig;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Default subject patterns excluded from handler event auto-capture. */
|
|
65
|
+
const DEFAULT_EXCLUDE_PATTERNS = ['os.o11y.*', '*.data', '*.input', '*.resize', 'os.pty.*'];
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check if a NATS subject matches any exclusion pattern.
|
|
69
|
+
* Supports `*` as a single-token wildcard and `>` as a multi-token wildcard.
|
|
70
|
+
*/
|
|
71
|
+
function matchesExclusion(subject: string, patterns: string[]): boolean {
|
|
72
|
+
for (const pattern of patterns) {
|
|
73
|
+
if (matchPattern(subject, pattern)) return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function matchPattern(subject: string, pattern: string): boolean {
|
|
79
|
+
const subParts = subject.split('.');
|
|
80
|
+
const patParts = pattern.split('.');
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < patParts.length; i++) {
|
|
83
|
+
const pat = patParts[i];
|
|
84
|
+
if (pat === '>') return true; // multi-token wildcard matches rest
|
|
85
|
+
if (i >= subParts.length) return false;
|
|
86
|
+
if (pat !== '*' && pat !== subParts[i]) return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return subParts.length === patParts.length;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Spawn the async message loop for a subscription. */
|
|
93
|
+
function spawnMessageLoop(
|
|
94
|
+
sub: AsyncIterable<Msg>,
|
|
95
|
+
shouldInstrument: boolean,
|
|
96
|
+
nc: NatsConnection,
|
|
97
|
+
log: Logger,
|
|
98
|
+
serviceName: string,
|
|
99
|
+
subject: string,
|
|
100
|
+
handler: (msg: Msg, nc: NatsConnection) => void | Promise<void>
|
|
101
|
+
): void {
|
|
102
|
+
(async () => {
|
|
103
|
+
for await (const msg of sub) {
|
|
104
|
+
if (shouldInstrument) {
|
|
105
|
+
await instrumentedHandler(nc, log, serviceName, subject, msg, handler);
|
|
106
|
+
} else {
|
|
107
|
+
await plainHandler(log, subject, msg, handler, nc);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Handle a message without instrumentation, just error catching. */
|
|
114
|
+
async function plainHandler(
|
|
115
|
+
log: Logger,
|
|
116
|
+
subject: string,
|
|
117
|
+
msg: Msg,
|
|
118
|
+
handler: (msg: Msg, nc: NatsConnection) => void | Promise<void>,
|
|
119
|
+
nc: NatsConnection
|
|
120
|
+
): Promise<void> {
|
|
121
|
+
try {
|
|
122
|
+
await handler(msg, nc);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
log.error(`handler error on ${subject}`, {
|
|
125
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Connect to NATS, register subscriptions, handle graceful shutdown, and keep the process alive.
|
|
132
|
+
*
|
|
133
|
+
* This function never resolves (it awaits nc.closed()), so it should be the last thing called.
|
|
134
|
+
* Errors during startup cause process.exit(1) via the .catch() wrapper.
|
|
135
|
+
*/
|
|
136
|
+
export async function createService(config: ServiceConfig): Promise<void> {
|
|
137
|
+
const { name, subscriptions = [], onReady, onShutdown, observe } = config;
|
|
138
|
+
|
|
139
|
+
const nc = await connect({ servers: NATS_URL });
|
|
140
|
+
|
|
141
|
+
// Create structured logger and intercept console for this service.
|
|
142
|
+
const log = createLogger(name, nc);
|
|
143
|
+
const _restoreConsole = interceptConsole(log);
|
|
144
|
+
|
|
145
|
+
log.info(`connected to NATS (${NATS_URL})`);
|
|
146
|
+
|
|
147
|
+
// Build merged exclusion list for auto-capture.
|
|
148
|
+
const excludePatterns = [...DEFAULT_EXCLUDE_PATTERNS, ...(observe?.exclude ?? [])];
|
|
149
|
+
|
|
150
|
+
// Register all subscriptions and spawn async iterators.
|
|
151
|
+
const subs = subscriptions.map(({ subject, handler }) => {
|
|
152
|
+
const sub = nc.subscribe(subject);
|
|
153
|
+
log.info(`subscribed to ${subject}`);
|
|
154
|
+
|
|
155
|
+
const shouldInstrument = !matchesExclusion(subject, excludePatterns);
|
|
156
|
+
spawnMessageLoop(sub, shouldInstrument, nc, log, name, subject, handler);
|
|
157
|
+
|
|
158
|
+
return sub;
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Notify the service that everything is wired up.
|
|
162
|
+
if (onReady) {
|
|
163
|
+
await onReady(nc, log);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Graceful shutdown — guard against being called twice (e.g. SIGINT + SIGTERM).
|
|
167
|
+
let shuttingDown = false;
|
|
168
|
+
|
|
169
|
+
const shutdown = async () => {
|
|
170
|
+
if (shuttingDown) return;
|
|
171
|
+
shuttingDown = true;
|
|
172
|
+
|
|
173
|
+
log.info('shutting down...');
|
|
174
|
+
|
|
175
|
+
for (const sub of subs) {
|
|
176
|
+
sub.unsubscribe();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (onShutdown) {
|
|
180
|
+
try {
|
|
181
|
+
await onShutdown();
|
|
182
|
+
} catch (err) {
|
|
183
|
+
log.error('onShutdown error', {
|
|
184
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
_restoreConsole();
|
|
190
|
+
|
|
191
|
+
// drain() waits for in-flight messages before closing — safer than close().
|
|
192
|
+
await nc.drain();
|
|
193
|
+
process.exit(0);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
process.on('SIGTERM', shutdown);
|
|
197
|
+
process.on('SIGINT', shutdown);
|
|
198
|
+
|
|
199
|
+
// Keep the process alive until NATS connection closes.
|
|
200
|
+
await nc.closed();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Wraps a handler invocation with observability: trace extraction, timing, and event emission.
|
|
205
|
+
*/
|
|
206
|
+
async function instrumentedHandler(
|
|
207
|
+
nc: NatsConnection,
|
|
208
|
+
log: Logger,
|
|
209
|
+
serviceName: string,
|
|
210
|
+
subject: string,
|
|
211
|
+
msg: Msg,
|
|
212
|
+
handler: (msg: Msg, nc: NatsConnection) => void | Promise<void>
|
|
213
|
+
): Promise<void> {
|
|
214
|
+
// Extract or generate trace context.
|
|
215
|
+
const inbound = extractTrace(msg);
|
|
216
|
+
const span = newSpan(inbound.traceId);
|
|
217
|
+
if (inbound.spanId) {
|
|
218
|
+
span.parentSpanId = inbound.spanId;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const payloadBytes = msg.data?.length ?? 0;
|
|
222
|
+
const start = performance.now();
|
|
223
|
+
let error: { message: string; stack?: string } | undefined;
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
await handler(msg, nc);
|
|
227
|
+
} catch (err) {
|
|
228
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
229
|
+
error = { message: e.message, stack: e.stack };
|
|
230
|
+
log.error(`handler error on ${subject}`, {
|
|
231
|
+
error: e,
|
|
232
|
+
trace_id: span.traceId,
|
|
233
|
+
span_id: span.spanId,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const durationMs = Math.round((performance.now() - start) * 100) / 100;
|
|
238
|
+
|
|
239
|
+
// Emit observability event (fire-and-forget).
|
|
240
|
+
const event = {
|
|
241
|
+
subject,
|
|
242
|
+
service: serviceName,
|
|
243
|
+
duration_ms: durationMs,
|
|
244
|
+
payload_bytes: payloadBytes,
|
|
245
|
+
trace_id: span.traceId,
|
|
246
|
+
span_id: span.spanId,
|
|
247
|
+
parent_span_id: span.parentSpanId,
|
|
248
|
+
ts: new Date().toISOString(),
|
|
249
|
+
...(error ? { error } : {}),
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// Publish to subject-domain stream: os.o11y.events.<original-subject>
|
|
253
|
+
const eventSubject = `os.o11y.events.${subject}`;
|
|
254
|
+
try {
|
|
255
|
+
nc.publish(eventSubject, JSON.stringify(event));
|
|
256
|
+
} catch {
|
|
257
|
+
// Never let observability failures affect service operation.
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distributed trace context utilities for NATS header propagation.
|
|
3
|
+
*
|
|
4
|
+
* Trace context is carried via NATS headers:
|
|
5
|
+
* x-trace-id — root trace identifier (shared across all spans in a request)
|
|
6
|
+
* x-span-id — unique identifier for this specific operation
|
|
7
|
+
* x-parent-span-id — the span that initiated this one
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
import type { Msg } from '@nats-io/nats-core';
|
|
12
|
+
import { headers } from '@nats-io/transport-node';
|
|
13
|
+
|
|
14
|
+
export const TRACE_HEADER = 'x-trace-id';
|
|
15
|
+
export const SPAN_HEADER = 'x-span-id';
|
|
16
|
+
export const PARENT_SPAN_HEADER = 'x-parent-span-id';
|
|
17
|
+
|
|
18
|
+
export interface TraceContext {
|
|
19
|
+
traceId: string;
|
|
20
|
+
spanId: string;
|
|
21
|
+
parentSpanId?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Generate a short unique ID suitable for span/trace identifiers. */
|
|
25
|
+
function generateId(): string {
|
|
26
|
+
return randomUUID().replace(/-/g, '').slice(0, 16);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Extract trace context from an inbound NATS message's headers.
|
|
31
|
+
* Returns whatever headers are present; missing fields are undefined.
|
|
32
|
+
*/
|
|
33
|
+
export function extractTrace(msg: Msg): Partial<TraceContext> {
|
|
34
|
+
const hdrs = msg.headers;
|
|
35
|
+
if (!hdrs) return {};
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
traceId: hdrs.get(TRACE_HEADER) || undefined,
|
|
39
|
+
spanId: hdrs.get(SPAN_HEADER) || undefined,
|
|
40
|
+
parentSpanId: hdrs.get(PARENT_SPAN_HEADER) || undefined,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create a new span, optionally continuing an existing trace.
|
|
46
|
+
* If no traceId is provided, starts a new trace root.
|
|
47
|
+
*/
|
|
48
|
+
export function newSpan(traceId?: string): TraceContext {
|
|
49
|
+
return {
|
|
50
|
+
traceId: traceId || generateId(),
|
|
51
|
+
spanId: generateId(),
|
|
52
|
+
parentSpanId: undefined,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Inject trace context into NATS headers for outbound messages.
|
|
58
|
+
* Creates a new MsgHdrs if none provided.
|
|
59
|
+
*/
|
|
60
|
+
export function injectTrace(
|
|
61
|
+
hdrs: ReturnType<typeof headers> | null | undefined,
|
|
62
|
+
ctx: TraceContext
|
|
63
|
+
): ReturnType<typeof headers> {
|
|
64
|
+
const h = hdrs || headers();
|
|
65
|
+
h.set(TRACE_HEADER, ctx.traceId);
|
|
66
|
+
h.set(SPAN_HEADER, ctx.spanId);
|
|
67
|
+
if (ctx.parentSpanId) {
|
|
68
|
+
h.set(PARENT_SPAN_HEADER, ctx.parentSpanId);
|
|
69
|
+
}
|
|
70
|
+
return h;
|
|
71
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"strict": true,
|
|
6
|
+
"noEmit": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"module": "esnext",
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"jsx": "react-jsx",
|
|
11
|
+
"incremental": true,
|
|
12
|
+
"composite": true,
|
|
13
|
+
"outDir": "./dist"
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// App component props type
|
|
2
|
+
export type { AppComponentProps } from '@/components/apps/app-registry';
|
|
3
|
+
|
|
4
|
+
// UI Components — re-export from OS host
|
|
5
|
+
|
|
6
|
+
// OS Primitives
|
|
7
|
+
export * from '@/components/os-primitives';
|
|
8
|
+
// shadcn/ui components
|
|
9
|
+
export * from '@/components/ui/badge';
|
|
10
|
+
export * from '@/components/ui/button';
|
|
11
|
+
export * from '@/components/ui/ContextMenu';
|
|
12
|
+
export * from '@/components/ui/command';
|
|
13
|
+
export * from '@/components/ui/dropdown-menu';
|
|
14
|
+
export * from '@/components/ui/input';
|
|
15
|
+
export * from '@/components/ui/note';
|
|
16
|
+
export * from '@/components/ui/separator';
|
|
17
|
+
export * from '@/components/ui/spinner';
|
|
18
|
+
export * from '@/components/ui/switch';
|
|
19
|
+
export * from '@/components/ui/theme-provider';
|
|
20
|
+
export * from '@/components/ui/theme-switcher';
|
|
21
|
+
export * from '@/components/ui/tooltip';
|
|
22
|
+
// Auth
|
|
23
|
+
export { useKhalAuth, useKhalAuth as useOSAuth } from '@/lib/auth/use-auth';
|
|
24
|
+
export { useNats, useNatsSubscription } from '@/lib/hooks/use-nats';
|
|
25
|
+
export { SUBJECTS } from '@/lib/subjects';
|
|
26
|
+
export { cn } from '@/lib/utils';
|
|
27
|
+
// Stores (OS-level state)
|
|
28
|
+
export { useNotificationStore } from '@/stores/notification-store';
|
|
29
|
+
export { useThemeStore } from '@/stores/theme-store';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"strict": true,
|
|
6
|
+
"noEmit": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"module": "esnext",
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"jsx": "react-jsx",
|
|
11
|
+
"incremental": true,
|
|
12
|
+
"composite": true,
|
|
13
|
+
"outDir": "./dist",
|
|
14
|
+
"paths": {
|
|
15
|
+
"@/*": ["../../src/*"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type ComponentType, lazy } from 'react';
|
|
4
|
+
|
|
5
|
+
interface AppComponentProps {
|
|
6
|
+
windowId: string;
|
|
7
|
+
meta?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const components: Record<string, ComponentType<AppComponentProps>> = {
|
|
11
|
+
settings: lazy(() => import('./views/settings/Settings').then((m) => ({ default: m.Settings }))),
|
|
12
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: 'settings-app',
|
|
3
|
+
views: [
|
|
4
|
+
{
|
|
5
|
+
id: 'settings',
|
|
6
|
+
label: 'Settings',
|
|
7
|
+
permission: 'settings',
|
|
8
|
+
minRole: 'platform-dev' as const,
|
|
9
|
+
defaultSize: { width: 800, height: 600 },
|
|
10
|
+
component: './views/settings/Settings',
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
desktop: {
|
|
14
|
+
icon: '/icons/dusk/system_preferences.svg',
|
|
15
|
+
categories: ['System'],
|
|
16
|
+
comment: 'Desktop settings',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@genie-os/settings-app",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "./manifest.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./manifest.ts",
|
|
8
|
+
"./components": "./components.ts",
|
|
9
|
+
"./views/*": "./views/*"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"react": ">=19"
|
|
13
|
+
}
|
|
14
|
+
}
|