@zerwiz/ymir 0.1.33 → 0.1.35
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/CHANGELOG.md +56 -0
- package/apps/README.md +4 -0
- package/apps/hlidskjalf/README.md +68 -0
- package/apps/hlidskjalf/android/app/build.gradle +73 -0
- package/apps/hlidskjalf/android/app/capacitor.build.gradle +19 -0
- package/apps/hlidskjalf/android/app/proguard-rules.pro +21 -0
- package/apps/hlidskjalf/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
- package/apps/hlidskjalf/android/app/src/main/AndroidManifest.xml +41 -0
- package/apps/hlidskjalf/android/app/src/main/java/org/zerwiz/ymir/MainActivity.java +5 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
- package/apps/hlidskjalf/android/app/src/main/res/layout/activity_main.xml +12 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/apps/hlidskjalf/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
- package/apps/hlidskjalf/android/app/src/main/res/values/strings.xml +7 -0
- package/apps/hlidskjalf/android/app/src/main/res/values/styles.xml +22 -0
- package/apps/hlidskjalf/android/app/src/main/res/xml/file_paths.xml +5 -0
- package/apps/hlidskjalf/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
- package/apps/hlidskjalf/android/build.gradle +29 -0
- package/apps/hlidskjalf/android/capacitor.settings.gradle +3 -0
- package/apps/hlidskjalf/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/apps/hlidskjalf/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/apps/hlidskjalf/android/gradle.properties +22 -0
- package/apps/hlidskjalf/android/gradlew +248 -0
- package/apps/hlidskjalf/android/gradlew.bat +92 -0
- package/apps/hlidskjalf/android/settings.gradle +5 -0
- package/apps/hlidskjalf/android/variables.gradle +16 -0
- package/apps/hlidskjalf/capacitor.config.ts +26 -0
- package/apps/hlidskjalf/dist/apple-touch-icon.png +0 -0
- package/apps/hlidskjalf/dist/assets/index-BWmNIyaG.css +1 -0
- package/apps/hlidskjalf/dist/assets/index-k7QEfNto.js +88 -0
- package/apps/hlidskjalf/dist/assets/index-k7QEfNto.js.map +1 -0
- package/apps/hlidskjalf/dist/icon.svg +7 -0
- package/apps/hlidskjalf/dist/index.html +64 -0
- package/apps/hlidskjalf/dist/manifest.webmanifest +31 -0
- package/apps/hlidskjalf/dist/og.jpg +0 -0
- package/apps/hlidskjalf/dist/og.png +0 -0
- package/apps/hlidskjalf/dist/og.svg +64 -0
- package/apps/hlidskjalf/dist/sw.js +39 -0
- package/apps/hlidskjalf/dist/ymir-icon.png +0 -0
- package/apps/hlidskjalf/dist/ymir-mark.svg +62 -0
- package/apps/hlidskjalf/electron/icon.png +0 -0
- package/apps/hlidskjalf/electron/main.cjs +236 -0
- package/apps/hlidskjalf/electron/preload.cjs +8 -0
- package/apps/hlidskjalf/electron/smidja-icon.png +0 -0
- package/apps/hlidskjalf/electron/ymir-hlidskjalf.desktop.in +12 -0
- package/apps/hlidskjalf/electron/ymir-smidja.desktop.in +12 -0
- package/apps/hlidskjalf/index.html +63 -0
- package/apps/hlidskjalf/package-lock.json +5398 -0
- package/apps/hlidskjalf/package.json +55 -0
- package/apps/hlidskjalf/public/apple-touch-icon.png +0 -0
- package/apps/hlidskjalf/public/icon.svg +7 -0
- package/apps/hlidskjalf/public/manifest.webmanifest +31 -0
- package/apps/hlidskjalf/public/og.jpg +0 -0
- package/apps/hlidskjalf/public/og.png +0 -0
- package/apps/hlidskjalf/public/og.svg +64 -0
- package/apps/hlidskjalf/public/sw.js +39 -0
- package/apps/hlidskjalf/public/ymir-icon.png +0 -0
- package/apps/hlidskjalf/public/ymir-mark.svg +62 -0
- package/apps/hlidskjalf/server/accounts.ts +159 -0
- package/apps/hlidskjalf/server/index.ts +2045 -0
- package/apps/hlidskjalf/src/app/App.tsx +116 -0
- package/apps/hlidskjalf/src/app/BottomStream.tsx +128 -0
- package/apps/hlidskjalf/src/app/MobileNav.tsx +87 -0
- package/apps/hlidskjalf/src/app/Rail.tsx +106 -0
- package/apps/hlidskjalf/src/app/Shell.tsx +135 -0
- package/apps/hlidskjalf/src/app/Topbar.tsx +130 -0
- package/apps/hlidskjalf/src/components/AccentPicker.tsx +207 -0
- package/apps/hlidskjalf/src/components/AccountMenu.tsx +115 -0
- package/apps/hlidskjalf/src/components/AgentCard.tsx +75 -0
- package/apps/hlidskjalf/src/components/EmberBackground.tsx +36 -0
- package/apps/hlidskjalf/src/components/Emblem.tsx +48 -0
- package/apps/hlidskjalf/src/components/Halls.tsx +155 -0
- package/apps/hlidskjalf/src/components/LoginModal.tsx +329 -0
- package/apps/hlidskjalf/src/components/Markdown.tsx +10 -0
- package/apps/hlidskjalf/src/components/MetricTile.tsx +40 -0
- package/apps/hlidskjalf/src/components/ModelPicker.tsx +100 -0
- package/apps/hlidskjalf/src/components/Overlay.tsx +134 -0
- package/apps/hlidskjalf/src/components/PRCard.tsx +154 -0
- package/apps/hlidskjalf/src/components/RecallPanel.tsx +116 -0
- package/apps/hlidskjalf/src/components/RuneTag.tsx +23 -0
- package/apps/hlidskjalf/src/components/Status.tsx +35 -0
- package/apps/hlidskjalf/src/components/TaskChip.tsx +23 -0
- package/apps/hlidskjalf/src/components/TraceRow.tsx +28 -0
- package/apps/hlidskjalf/src/data/lore.ts +127 -0
- package/apps/hlidskjalf/src/data/metadata.ts +147 -0
- package/apps/hlidskjalf/src/data/mythology.ts +95 -0
- package/apps/hlidskjalf/src/data/realms.ts +167 -0
- package/apps/hlidskjalf/src/gates/Cron.tsx +77 -0
- package/apps/hlidskjalf/src/gates/Decisions.tsx +67 -0
- package/apps/hlidskjalf/src/gates/Files.tsx +138 -0
- package/apps/hlidskjalf/src/gates/Fleet.tsx +184 -0
- package/apps/hlidskjalf/src/gates/Forge.tsx +486 -0
- package/apps/hlidskjalf/src/gates/OmniChat.tsx +217 -0
- package/apps/hlidskjalf/src/gates/Processes.tsx +162 -0
- package/apps/hlidskjalf/src/gates/Profile.tsx +225 -0
- package/apps/hlidskjalf/src/gates/Reviews.tsx +33 -0
- package/apps/hlidskjalf/src/gates/Runes.tsx +116 -0
- package/apps/hlidskjalf/src/gates/Runtime.tsx +106 -0
- package/apps/hlidskjalf/src/gates/Sessions.tsx +109 -0
- package/apps/hlidskjalf/src/gates/Stats.tsx +268 -0
- package/apps/hlidskjalf/src/gates/Tasks.tsx +173 -0
- package/apps/hlidskjalf/src/gates/Trace.tsx +155 -0
- package/apps/hlidskjalf/src/gates/Well.tsx +154 -0
- package/apps/hlidskjalf/src/gates/Worktrees.tsx +48 -0
- package/apps/hlidskjalf/src/hooks/useTenantDef.ts +13 -0
- package/apps/hlidskjalf/src/main.tsx +31 -0
- package/apps/hlidskjalf/src/services/api.ts +404 -0
- package/apps/hlidskjalf/src/services/auth.ts +107 -0
- package/apps/hlidskjalf/src/services/stream.ts +35 -0
- package/apps/hlidskjalf/src/state/store.ts +648 -0
- package/apps/hlidskjalf/src/state/ui.ts +62 -0
- package/apps/hlidskjalf/src/styles/auth.css +485 -0
- package/apps/hlidskjalf/src/styles/components.css +1259 -0
- package/apps/hlidskjalf/src/styles/forge.css +115 -0
- package/apps/hlidskjalf/src/styles/global.css +167 -0
- package/apps/hlidskjalf/src/styles/menus.css +175 -0
- package/apps/hlidskjalf/src/styles/mobile.css +298 -0
- package/apps/hlidskjalf/src/styles/overlays.css +205 -0
- package/apps/hlidskjalf/src/styles/shell.css +641 -0
- package/apps/hlidskjalf/src/types.ts +251 -0
- package/apps/hlidskjalf/src/vite-env.d.ts +9 -0
- package/apps/hlidskjalf/static/landing.md +6 -0
- package/apps/hlidskjalf/tsconfig.json +25 -0
- package/apps/hlidskjalf/vite.config.ts +49 -0
- package/apps/hlidskjalf-mobile/App.tsx +93 -0
- package/apps/hlidskjalf-mobile/app.json +13 -0
- package/apps/hlidskjalf-mobile/index.ts +4 -0
- package/apps/hlidskjalf-mobile/package.json +35 -0
- package/apps/hlidskjalf-mobile/public/icon.svg +7 -0
- package/apps/hlidskjalf-mobile/tsconfig.json +4 -0
- package/apps/odrerir/.astro/content.d.ts +159 -0
- package/apps/odrerir/.astro/dev.json +24 -0
- package/apps/odrerir/.astro/settings.json +5 -0
- package/apps/odrerir/.astro/types.d.ts +2 -0
- package/apps/odrerir/astro.config.mjs +79 -0
- package/apps/odrerir/dist/apple-touch-icon.png +0 -0
- package/apps/odrerir/dist/favicon-192.png +0 -0
- package/apps/odrerir/dist/favicon-32.png +0 -0
- package/apps/odrerir/dist/favicon-512.png +0 -0
- package/apps/odrerir/dist/favicon.svg +53 -0
- package/apps/odrerir/dist/icon.svg +7 -0
- package/apps/odrerir/dist/index.html +837 -0
- package/apps/odrerir/dist/og-square.png +0 -0
- package/apps/odrerir/dist/og-story.png +0 -0
- package/apps/odrerir/dist/og.png +0 -0
- package/apps/odrerir/dist/safari-pinned-tab.svg +7 -0
- package/apps/odrerir/dist/site.webmanifest +16 -0
- package/apps/odrerir/dist/styles/cloth.css +112 -0
- package/apps/odrerir/dist/styles/livehall.css +278 -0
- package/apps/odrerir/electron/icon.png +0 -0
- package/apps/odrerir/electron/main.cjs +183 -0
- package/apps/odrerir/electron/ymir-odrerir.desktop.in +12 -0
- package/apps/odrerir/package-lock.json +4195 -0
- package/apps/odrerir/package.json +30 -0
- package/apps/odrerir/public/apple-touch-icon.png +0 -0
- package/apps/odrerir/public/favicon-192.png +0 -0
- package/apps/odrerir/public/favicon-32.png +0 -0
- package/apps/odrerir/public/favicon-512.png +0 -0
- package/apps/odrerir/public/favicon.svg +53 -0
- package/apps/odrerir/public/icon.svg +7 -0
- package/apps/odrerir/public/og-square.png +0 -0
- package/apps/odrerir/public/og-story.png +0 -0
- package/apps/odrerir/public/og.png +0 -0
- package/apps/odrerir/public/safari-pinned-tab.svg +7 -0
- package/apps/odrerir/public/site.webmanifest +16 -0
- package/apps/odrerir/scripts/extract-cloth.mjs +101 -0
- package/apps/odrerir/src/index.html +837 -0
- package/apps/odrerir/src/styles/cloth.css +112 -0
- package/apps/odrerir/src/styles/livehall.css +278 -0
- package/apps/sessrumnir/.github/ISSUE_TEMPLATE/bug_report.yml +99 -0
- package/apps/sessrumnir/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/apps/sessrumnir/.github/ISSUE_TEMPLATE/feature_request.yml +46 -0
- package/apps/sessrumnir/.github/PULL_REQUEST_TEMPLATE.md +56 -0
- package/apps/sessrumnir/.github/SUPPORT.md +18 -0
- package/apps/sessrumnir/.github/workflows/build.yml +133 -0
- package/apps/sessrumnir/AGENTS.md +540 -0
- package/apps/sessrumnir/CLA.md +63 -0
- package/apps/sessrumnir/CONTRIBUTING.md +233 -0
- package/apps/sessrumnir/LICENSE +200 -0
- package/apps/sessrumnir/NOTICE +33 -0
- package/apps/sessrumnir/README.md +329 -0
- package/apps/sessrumnir/bin/sessrumnir-web.sh +117 -0
- package/apps/sessrumnir/bin/sessrumnir.js +169 -0
- package/apps/sessrumnir/docs/CNAME +1 -0
- package/apps/sessrumnir/docs/favicon.ico +0 -0
- package/apps/sessrumnir/docs/icon-512.png +0 -0
- package/apps/sessrumnir/docs/index.html +441 -0
- package/apps/sessrumnir/docs/robots.txt +4 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_181929.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182005.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182020.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182039.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182117.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182225.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182248.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182322.png +0 -0
- package/apps/sessrumnir/docs/screenshots/Screenshot_20260824_182340.png +0 -0
- package/apps/sessrumnir/docs/sitemap.xml +9 -0
- package/apps/sessrumnir/electron.vite.config.ts +49 -0
- package/apps/sessrumnir/eslint.config.mjs +75 -0
- package/apps/sessrumnir/i18next.config.ts +33 -0
- package/apps/sessrumnir/install.sh +144 -0
- package/apps/sessrumnir/out/main/index.js +10881 -0
- package/apps/sessrumnir/out/preload/index.js +722 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-400-normal-C8QS47vb.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-400-normal-D3EsxgFc.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-500-normal-B7dJQtg-.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-500-normal-BLlg2W5x.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-600-normal-BcIsDXzC.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-600-normal-CBymlcNF.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-400-normal-Bgrpe4p1.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-400-normal-BlcaxZtM.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-500-normal-CdQuyvtc.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-500-normal-pZw22qtS.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-600-normal-Dr-wLyOm.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-cyrillic-ext-600-normal-dLR2-a_v.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-400-normal-BGH8Vunh.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-400-normal-C3_-2Ua-.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-500-normal-Dj3SQ6fR.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-500-normal-EBdSCOD3.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-600-normal-B254Xisw.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-600-normal-DUW-TI76.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-400-normal-DuQ88yz3.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-400-normal-DuXFa1Dr.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-500-normal-AH9qog1s.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-500-normal-DAuUCO41.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-600-normal-CD-dlDpD.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-latin-ext-600-normal-D3T6BBXG.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-400-normal-C-RiYxEf.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-400-normal-DmUuA7Y2.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-500-normal-DsPuwQHi.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-500-normal-tGBW_mI7.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-600-normal-Dar_cCT6.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/cormorant-vietnamese-600-normal-GIs8CF2x.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-300-normal-Ba-HN6uq.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-300-normal-ByB2hQUF.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-300-normal-B8O3uHbr.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-300-normal-BbtBtHoB.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-300-normal-BPU54Tw3.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-300-normal-BRS-C4KA.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-300-normal-BEtQ2wm2.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-300-normal-CQbCaAQ4.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-300-normal-B6fSpYYV.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-300-normal-CpdbWO_2.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
- package/apps/sessrumnir/out/renderer/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/index-BxqsRq2x.css +4858 -0
- package/apps/sessrumnir/out/renderer/assets/index-TaD69rFk.js +99435 -0
- package/apps/sessrumnir/out/renderer/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-latin-ext-wght-italic-DFS986qL.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-latin-ext-wght-normal-C-3rgBeH.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-latin-wght-italic-Bxi8ein9.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-latin-wght-normal-CCVVNp6i.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-vietnamese-wght-italic-xAqemagA.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/newsreader-vietnamese-wght-normal-Czsa-EzN.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/openmoji-color-9qo_2DLG.woff2 +0 -0
- package/apps/sessrumnir/out/renderer/assets/pi-logo-B6SVnhuS.svg +7 -0
- package/apps/sessrumnir/out/renderer/index.html +19 -0
- package/apps/sessrumnir/out/renderer/theme-boot.js +30 -0
- package/apps/sessrumnir/package-lock.json +10636 -0
- package/apps/sessrumnir/package.json +183 -0
- package/apps/sessrumnir/public/apple-touch-icon.png +0 -0
- package/apps/sessrumnir/public/icon.svg +7 -0
- package/apps/sessrumnir/resources/icons/generate_icons.py +38 -0
- package/apps/sessrumnir/resources/icons/icon-128.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-16.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-256.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-32.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-48.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-512.png +0 -0
- package/apps/sessrumnir/resources/icons/icon-64.png +0 -0
- package/apps/sessrumnir/resources/icons/icon.icns +0 -0
- package/apps/sessrumnir/resources/icons/icon.ico +0 -0
- package/apps/sessrumnir/resources/icons/icon.png +0 -0
- package/apps/sessrumnir/resources/icons/icon.svg +7 -0
- package/apps/sessrumnir/resources/linux/after-install.sh +23 -0
- package/apps/sessrumnir/resources/linux/after-remove.sh +18 -0
- package/apps/sessrumnir/resources/locales/en/translation.json +1735 -0
- package/apps/sessrumnir/resources/permission-prompt-text.test.ts +111 -0
- package/apps/sessrumnir/resources/permission-prompt-text.ts +84 -0
- package/apps/sessrumnir/resources/permission-rules.test.ts +351 -0
- package/apps/sessrumnir/resources/permission-rules.ts +293 -0
- package/apps/sessrumnir/resources/pi-desktop-permissions.ts +62 -0
- package/apps/sessrumnir/resources/ymir-sessrumnir.desktop.in +12 -0
- package/apps/sessrumnir/scripts/check-semantic-colors.mjs +57 -0
- package/apps/sessrumnir/src/main/activity-stats.test.ts +240 -0
- package/apps/sessrumnir/src/main/activity-stats.ts +596 -0
- package/apps/sessrumnir/src/main/agent-detection.test.ts +25 -0
- package/apps/sessrumnir/src/main/agent-detection.ts +114 -0
- package/apps/sessrumnir/src/main/app-data-paths.test.ts +90 -0
- package/apps/sessrumnir/src/main/app-data-paths.ts +95 -0
- package/apps/sessrumnir/src/main/app-log.test.ts +114 -0
- package/apps/sessrumnir/src/main/app-log.ts +210 -0
- package/apps/sessrumnir/src/main/archived-sessions.test.ts +50 -0
- package/apps/sessrumnir/src/main/archived-sessions.ts +95 -0
- package/apps/sessrumnir/src/main/attachment-reader.test.ts +56 -0
- package/apps/sessrumnir/src/main/attachment-reader.ts +52 -0
- package/apps/sessrumnir/src/main/auto-tag.test.ts +38 -0
- package/apps/sessrumnir/src/main/auto-tag.ts +75 -0
- package/apps/sessrumnir/src/main/autostart-linux.test.ts +56 -0
- package/apps/sessrumnir/src/main/autostart-linux.ts +58 -0
- package/apps/sessrumnir/src/main/cmd-escape.test.ts +424 -0
- package/apps/sessrumnir/src/main/cmd-escape.ts +186 -0
- package/apps/sessrumnir/src/main/council-manager.test.ts +167 -0
- package/apps/sessrumnir/src/main/council-manager.ts +265 -0
- package/apps/sessrumnir/src/main/diagnostics-report.test.ts +140 -0
- package/apps/sessrumnir/src/main/diagnostics-report.ts +91 -0
- package/apps/sessrumnir/src/main/diagnostics.ts +111 -0
- package/apps/sessrumnir/src/main/editor-guard.test.ts +59 -0
- package/apps/sessrumnir/src/main/editor-guard.ts +50 -0
- package/apps/sessrumnir/src/main/extension-ui-ipc.test.ts +299 -0
- package/apps/sessrumnir/src/main/extension-ui-ipc.ts +117 -0
- package/apps/sessrumnir/src/main/file-service.test.ts +279 -0
- package/apps/sessrumnir/src/main/file-service.ts +652 -0
- package/apps/sessrumnir/src/main/fs-errors.ts +42 -0
- package/apps/sessrumnir/src/main/get-messages-trim.test.ts +77 -0
- package/apps/sessrumnir/src/main/get-messages-trim.ts +97 -0
- package/apps/sessrumnir/src/main/git-conveyor.test.ts +305 -0
- package/apps/sessrumnir/src/main/git-conveyor.ts +338 -0
- package/apps/sessrumnir/src/main/git-worktree.test.ts +101 -0
- package/apps/sessrumnir/src/main/git-worktree.ts +201 -0
- package/apps/sessrumnir/src/main/i18n.ts +31 -0
- package/apps/sessrumnir/src/main/index.ts +619 -0
- package/apps/sessrumnir/src/main/ipc/active-engine.ts +15 -0
- package/apps/sessrumnir/src/main/ipc/context.ts +58 -0
- package/apps/sessrumnir/src/main/ipc/council-handlers.ts +126 -0
- package/apps/sessrumnir/src/main/ipc/diagnostics-handlers.ts +8 -0
- package/apps/sessrumnir/src/main/ipc/file-handlers.ts +96 -0
- package/apps/sessrumnir/src/main/ipc/git-conveyor-handlers.ts +55 -0
- package/apps/sessrumnir/src/main/ipc/model-handlers.ts +33 -0
- package/apps/sessrumnir/src/main/ipc/models-config-handlers.ts +80 -0
- package/apps/sessrumnir/src/main/ipc/notes-handlers.ts +65 -0
- package/apps/sessrumnir/src/main/ipc/package-handlers.ts +330 -0
- package/apps/sessrumnir/src/main/ipc/permission-rules-handlers.ts +223 -0
- package/apps/sessrumnir/src/main/ipc/pi-handlers.ts +136 -0
- package/apps/sessrumnir/src/main/ipc/pi-start-options.ts +150 -0
- package/apps/sessrumnir/src/main/ipc/run-pi-cli.ts +53 -0
- package/apps/sessrumnir/src/main/ipc/session-handlers.ts +491 -0
- package/apps/sessrumnir/src/main/ipc/settings.ts +120 -0
- package/apps/sessrumnir/src/main/ipc/skills-mcp-handlers.ts +192 -0
- package/apps/sessrumnir/src/main/ipc/system-handlers.ts +131 -0
- package/apps/sessrumnir/src/main/ipc/tag-handlers.ts +69 -0
- package/apps/sessrumnir/src/main/ipc/terminal-handlers.ts +41 -0
- package/apps/sessrumnir/src/main/ipc/theme-handlers.ts +131 -0
- package/apps/sessrumnir/src/main/ipc/update-handlers.ts +61 -0
- package/apps/sessrumnir/src/main/ipc/validation.ts +45 -0
- package/apps/sessrumnir/src/main/ipc/workflow-handlers.ts +108 -0
- package/apps/sessrumnir/src/main/ipc/workspace-activity-wiring.ts +179 -0
- package/apps/sessrumnir/src/main/ipc/workspace-handlers.ts +133 -0
- package/apps/sessrumnir/src/main/ipc-handlers.ts +98 -0
- package/apps/sessrumnir/src/main/map-concurrent.test.ts +80 -0
- package/apps/sessrumnir/src/main/map-concurrent.ts +30 -0
- package/apps/sessrumnir/src/main/models-file.test.ts +114 -0
- package/apps/sessrumnir/src/main/models-file.ts +89 -0
- package/apps/sessrumnir/src/main/notes-manager.test.ts +64 -0
- package/apps/sessrumnir/src/main/notes-manager.ts +183 -0
- package/apps/sessrumnir/src/main/notify-decision.test.ts +39 -0
- package/apps/sessrumnir/src/main/notify-decision.ts +25 -0
- package/apps/sessrumnir/src/main/omp-fork-points.test.ts +119 -0
- package/apps/sessrumnir/src/main/omp-fork-points.ts +105 -0
- package/apps/sessrumnir/src/main/omp-plugin-list.test.ts +94 -0
- package/apps/sessrumnir/src/main/omp-plugin-list.ts +103 -0
- package/apps/sessrumnir/src/main/package-catalog.test.ts +157 -0
- package/apps/sessrumnir/src/main/package-catalog.ts +166 -0
- package/apps/sessrumnir/src/main/package-updates.test.ts +149 -0
- package/apps/sessrumnir/src/main/package-updates.ts +185 -0
- package/apps/sessrumnir/src/main/path-authorization.test.ts +64 -0
- package/apps/sessrumnir/src/main/path-authorization.ts +31 -0
- package/apps/sessrumnir/src/main/pi-binary-resolution.test.ts +582 -0
- package/apps/sessrumnir/src/main/pi-binary-resolution.ts +649 -0
- package/apps/sessrumnir/src/main/pi-event-router.test.ts +388 -0
- package/apps/sessrumnir/src/main/pi-event-router.ts +290 -0
- package/apps/sessrumnir/src/main/pi-paths.test.ts +134 -0
- package/apps/sessrumnir/src/main/pi-paths.ts +74 -0
- package/apps/sessrumnir/src/main/pi-rpc-manager.test.ts +467 -0
- package/apps/sessrumnir/src/main/pi-rpc-manager.ts +1319 -0
- package/apps/sessrumnir/src/main/process-tree.test.ts +94 -0
- package/apps/sessrumnir/src/main/renderer-origin.test.ts +33 -0
- package/apps/sessrumnir/src/main/renderer-origin.ts +35 -0
- package/apps/sessrumnir/src/main/session-lineage-reader.test.ts +317 -0
- package/apps/sessrumnir/src/main/session-lineage-reader.ts +111 -0
- package/apps/sessrumnir/src/main/session-metadata.test.ts +508 -0
- package/apps/sessrumnir/src/main/session-metadata.ts +526 -0
- package/apps/sessrumnir/src/main/session-name.test.ts +71 -0
- package/apps/sessrumnir/src/main/session-name.ts +69 -0
- package/apps/sessrumnir/src/main/session-paths.test.ts +110 -0
- package/apps/sessrumnir/src/main/session-paths.ts +88 -0
- package/apps/sessrumnir/src/main/session-tags.test.ts +61 -0
- package/apps/sessrumnir/src/main/session-tags.ts +253 -0
- package/apps/sessrumnir/src/main/session-trash.test.ts +66 -0
- package/apps/sessrumnir/src/main/session-trash.ts +65 -0
- package/apps/sessrumnir/src/main/settings-logic.ts +66 -0
- package/apps/sessrumnir/src/main/skills-discovery.test.ts +149 -0
- package/apps/sessrumnir/src/main/skills-discovery.ts +179 -0
- package/apps/sessrumnir/src/main/startup-launch.ts +63 -0
- package/apps/sessrumnir/src/main/terminal-service.ts +96 -0
- package/apps/sessrumnir/src/main/theme-store.test.ts +440 -0
- package/apps/sessrumnir/src/main/theme-store.ts +495 -0
- package/apps/sessrumnir/src/main/tray-decision.test.ts +46 -0
- package/apps/sessrumnir/src/main/tray-decision.ts +49 -0
- package/apps/sessrumnir/src/main/tray-manager.ts +220 -0
- package/apps/sessrumnir/src/main/tsconfig.json +20 -0
- package/apps/sessrumnir/src/main/window-background.test.ts +29 -0
- package/apps/sessrumnir/src/main/window-background.ts +16 -0
- package/apps/sessrumnir/src/main/workflow-discovery.test.ts +252 -0
- package/apps/sessrumnir/src/main/workflow-monitor.test.ts +371 -0
- package/apps/sessrumnir/src/main/workflow-monitor.ts +1020 -0
- package/apps/sessrumnir/src/main/workspace-activity.test.ts +227 -0
- package/apps/sessrumnir/src/main/workspace-activity.ts +215 -0
- package/apps/sessrumnir/src/main/workspace-manager.test.ts +680 -0
- package/apps/sessrumnir/src/main/workspace-manager.ts +1199 -0
- package/apps/sessrumnir/src/main/workspace-trust.test.ts +78 -0
- package/apps/sessrumnir/src/main/workspace-trust.ts +84 -0
- package/apps/sessrumnir/src/preload/index.ts +358 -0
- package/apps/sessrumnir/src/preload/tsconfig.json +20 -0
- package/apps/sessrumnir/src/renderer/index.html +18 -0
- package/apps/sessrumnir/src/renderer/public/theme-boot.js +30 -0
- package/apps/sessrumnir/src/renderer/src/app.tsx +194 -0
- package/apps/sessrumnir/src/renderer/src/assets/openmoji-color.woff2 +0 -0
- package/apps/sessrumnir/src/renderer/src/assets/pi-logo.svg +7 -0
- package/apps/sessrumnir/src/renderer/src/assets/ymir-mark.svg +55 -0
- package/apps/sessrumnir/src/renderer/src/assets.d.ts +7 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-code-highlight.ts +239 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-file-link.ts +140 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-input.tsx +729 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-panel-widths.test.ts +175 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-panel-widths.ts +100 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-panel.tsx +523 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-project-picker.tsx +193 -0
- package/apps/sessrumnir/src/renderer/src/components/chat-search.tsx +251 -0
- package/apps/sessrumnir/src/renderer/src/components/code-editor-highlight.ts +85 -0
- package/apps/sessrumnir/src/renderer/src/components/code-editor-language.test.ts +19 -0
- package/apps/sessrumnir/src/renderer/src/components/code-editor-language.ts +88 -0
- package/apps/sessrumnir/src/renderer/src/components/code-editor.tsx +128 -0
- package/apps/sessrumnir/src/renderer/src/components/command-palette.tsx +315 -0
- package/apps/sessrumnir/src/renderer/src/components/command-results.tsx +80 -0
- package/apps/sessrumnir/src/renderer/src/components/composer-permission-menu.tsx +91 -0
- package/apps/sessrumnir/src/renderer/src/components/context-menu.tsx +457 -0
- package/apps/sessrumnir/src/renderer/src/components/copy-button.tsx +36 -0
- package/apps/sessrumnir/src/renderer/src/components/council-panels.tsx +193 -0
- package/apps/sessrumnir/src/renderer/src/components/custom-models-editor.tsx +330 -0
- package/apps/sessrumnir/src/renderer/src/components/diagnostics-panel.tsx +380 -0
- package/apps/sessrumnir/src/renderer/src/components/diff-viewer.tsx +318 -0
- package/apps/sessrumnir/src/renderer/src/components/ember-background.tsx +113 -0
- package/apps/sessrumnir/src/renderer/src/components/error-boundary.tsx +38 -0
- package/apps/sessrumnir/src/renderer/src/components/extension-ui-dialog-helpers.test.ts +43 -0
- package/apps/sessrumnir/src/renderer/src/components/extension-ui-dialog-helpers.ts +51 -0
- package/apps/sessrumnir/src/renderer/src/components/extension-ui-dialog.tsx +486 -0
- package/apps/sessrumnir/src/renderer/src/components/file-tree.tsx +784 -0
- package/apps/sessrumnir/src/renderer/src/components/git-conveyor-actions.tsx +246 -0
- package/apps/sessrumnir/src/renderer/src/components/home-screen.tsx +396 -0
- package/apps/sessrumnir/src/renderer/src/components/image-viewer.tsx +100 -0
- package/apps/sessrumnir/src/renderer/src/components/line-numbered-code.tsx +58 -0
- package/apps/sessrumnir/src/renderer/src/components/markdown-renderer.tsx +237 -0
- package/apps/sessrumnir/src/renderer/src/components/message-bubble.tsx +1006 -0
- package/apps/sessrumnir/src/renderer/src/components/mission-control.tsx +341 -0
- package/apps/sessrumnir/src/renderer/src/components/model-selector.tsx +219 -0
- package/apps/sessrumnir/src/renderer/src/components/note-picker.tsx +155 -0
- package/apps/sessrumnir/src/renderer/src/components/notes-panel.tsx +437 -0
- package/apps/sessrumnir/src/renderer/src/components/package-browser.tsx +604 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-mode.test.ts +22 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-mode.ts +49 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-rules-editor-helpers.test.ts +44 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-rules-editor-helpers.ts +35 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-rules-editor.tsx +226 -0
- package/apps/sessrumnir/src/renderer/src/components/permission-selector.tsx +104 -0
- package/apps/sessrumnir/src/renderer/src/components/resize-handle.tsx +51 -0
- package/apps/sessrumnir/src/renderer/src/components/review-rail.tsx +194 -0
- package/apps/sessrumnir/src/renderer/src/components/session-menu-position.test.ts +22 -0
- package/apps/sessrumnir/src/renderer/src/components/session-menu-position.ts +34 -0
- package/apps/sessrumnir/src/renderer/src/components/session-panel.tsx +711 -0
- package/apps/sessrumnir/src/renderer/src/components/session-runtime-indicator.tsx +43 -0
- package/apps/sessrumnir/src/renderer/src/components/settings-panel.tsx +1360 -0
- package/apps/sessrumnir/src/renderer/src/components/sidebar-activity.test.ts +47 -0
- package/apps/sessrumnir/src/renderer/src/components/sidebar-activity.ts +76 -0
- package/apps/sessrumnir/src/renderer/src/components/sidebar-session-labels.test.ts +73 -0
- package/apps/sessrumnir/src/renderer/src/components/sidebar-session-labels.ts +47 -0
- package/apps/sessrumnir/src/renderer/src/components/sidebar.tsx +1045 -0
- package/apps/sessrumnir/src/renderer/src/components/skills-panel.tsx +159 -0
- package/apps/sessrumnir/src/renderer/src/components/stats-panel.tsx +368 -0
- package/apps/sessrumnir/src/renderer/src/components/status-bar.tsx +274 -0
- package/apps/sessrumnir/src/renderer/src/components/status-popover.tsx +481 -0
- package/apps/sessrumnir/src/renderer/src/components/streaming-bubble.tsx +128 -0
- package/apps/sessrumnir/src/renderer/src/components/subagent-progress.tsx +254 -0
- package/apps/sessrumnir/src/renderer/src/components/task-launcher.tsx +168 -0
- package/apps/sessrumnir/src/renderer/src/components/terminal.tsx +203 -0
- package/apps/sessrumnir/src/renderer/src/components/theme-editor-helpers.test.ts +35 -0
- package/apps/sessrumnir/src/renderer/src/components/theme-editor-helpers.ts +35 -0
- package/apps/sessrumnir/src/renderer/src/components/theme-editor.tsx +440 -0
- package/apps/sessrumnir/src/renderer/src/components/theme-gallery.tsx +373 -0
- package/apps/sessrumnir/src/renderer/src/components/thinking-level-selector.tsx +85 -0
- package/apps/sessrumnir/src/renderer/src/components/timeline.tsx +289 -0
- package/apps/sessrumnir/src/renderer/src/components/tool-call-icon.ts +32 -0
- package/apps/sessrumnir/src/renderer/src/components/workflow-navigator.tsx +901 -0
- package/apps/sessrumnir/src/renderer/src/components/workspace-tabs.tsx +241 -0
- package/apps/sessrumnir/src/renderer/src/global.d.ts +8 -0
- package/apps/sessrumnir/src/renderer/src/hooks/use-folder-drop.ts +101 -0
- package/apps/sessrumnir/src/renderer/src/hooks.test.ts +88 -0
- package/apps/sessrumnir/src/renderer/src/hooks.ts +574 -0
- package/apps/sessrumnir/src/renderer/src/i18n.test.ts +54 -0
- package/apps/sessrumnir/src/renderer/src/i18n.ts +89 -0
- package/apps/sessrumnir/src/renderer/src/index.css +425 -0
- package/apps/sessrumnir/src/renderer/src/main.tsx +42 -0
- package/apps/sessrumnir/src/renderer/src/message-grouping.test.ts +422 -0
- package/apps/sessrumnir/src/renderer/src/message-grouping.ts +410 -0
- package/apps/sessrumnir/src/renderer/src/message-parsing.test.ts +86 -0
- package/apps/sessrumnir/src/renderer/src/message-parsing.ts +166 -0
- package/apps/sessrumnir/src/renderer/src/store-external-prompts.test.ts +161 -0
- package/apps/sessrumnir/src/renderer/src/store-session-transitions.test.ts +2090 -0
- package/apps/sessrumnir/src/renderer/src/store-timeline.test.ts +52 -0
- package/apps/sessrumnir/src/renderer/src/store-turn-error.test.ts +136 -0
- package/apps/sessrumnir/src/renderer/src/store.ts +3726 -0
- package/apps/sessrumnir/src/renderer/src/subagent-detection.test.ts +55 -0
- package/apps/sessrumnir/src/renderer/src/theme/engine.test.ts +29 -0
- package/apps/sessrumnir/src/renderer/src/theme/engine.ts +20 -0
- package/apps/sessrumnir/src/renderer/src/themes/breeze-claudius.json +69 -0
- package/apps/sessrumnir/src/renderer/src/themes/breeze-dark.json +69 -0
- package/apps/sessrumnir/src/renderer/src/themes/breeze-light.json +69 -0
- package/apps/sessrumnir/src/renderer/src/themes/builtin-themes.test.ts +95 -0
- package/apps/sessrumnir/src/renderer/src/themes/dark.json +46 -0
- package/apps/sessrumnir/src/renderer/src/themes/fensalir.json +82 -0
- package/apps/sessrumnir/src/renderer/src/themes/gruvbox.json +69 -0
- package/apps/sessrumnir/src/renderer/src/themes/index.ts +60 -0
- package/apps/sessrumnir/src/renderer/src/themes/light.json +46 -0
- package/apps/sessrumnir/src/renderer/src/themes/nord.json +69 -0
- package/apps/sessrumnir/src/renderer/src/themes/sessrumnir.json +82 -0
- package/apps/sessrumnir/src/renderer/src/utils/debounced-buffer.test.ts +81 -0
- package/apps/sessrumnir/src/renderer/src/utils/debounced-buffer.ts +57 -0
- package/apps/sessrumnir/src/renderer/src/utils/format-relative-time.test.ts +62 -0
- package/apps/sessrumnir/src/renderer/src/utils/format-relative-time.ts +28 -0
- package/apps/sessrumnir/src/renderer/src/utils/heatmap-grid.test.ts +57 -0
- package/apps/sessrumnir/src/renderer/src/utils/heatmap-grid.ts +41 -0
- package/apps/sessrumnir/src/renderer/src/utils/ipc-error.test.ts +22 -0
- package/apps/sessrumnir/src/renderer/src/utils/ipc-error.ts +12 -0
- package/apps/sessrumnir/src/renderer/src/utils/model-search.test.ts +63 -0
- package/apps/sessrumnir/src/renderer/src/utils/model-search.ts +20 -0
- package/apps/sessrumnir/src/renderer/src/utils/planning-prompt.test.ts +31 -0
- package/apps/sessrumnir/src/renderer/src/utils/planning-prompt.ts +27 -0
- package/apps/sessrumnir/src/renderer/src/utils/preview-load-error.test.ts +15 -0
- package/apps/sessrumnir/src/renderer/src/utils/preview-load-error.ts +22 -0
- package/apps/sessrumnir/src/renderer/src/utils/process-status-label.test.ts +13 -0
- package/apps/sessrumnir/src/renderer/src/utils/process-status-label.ts +19 -0
- package/apps/sessrumnir/src/renderer/src/utils/quick-switcher.test.ts +68 -0
- package/apps/sessrumnir/src/renderer/src/utils/quick-switcher.ts +52 -0
- package/apps/sessrumnir/src/renderer/src/utils/rank-file-results.test.ts +46 -0
- package/apps/sessrumnir/src/renderer/src/utils/rank-file-results.ts +23 -0
- package/apps/sessrumnir/src/renderer/src/utils/relative-time.tsx +25 -0
- package/apps/sessrumnir/src/renderer/src/utils/session-title.test.ts +98 -0
- package/apps/sessrumnir/src/renderer/src/utils/session-title.ts +58 -0
- package/apps/sessrumnir/src/renderer/src/utils/stale-guard.test.ts +29 -0
- package/apps/sessrumnir/src/renderer/src/utils/stale-guard.ts +20 -0
- package/apps/sessrumnir/src/renderer/src/utils/theme.test.ts +174 -0
- package/apps/sessrumnir/src/renderer/src/utils/theme.ts +159 -0
- package/apps/sessrumnir/src/renderer/src/utils/workflow-runs.test.ts +130 -0
- package/apps/sessrumnir/src/renderer/src/utils/workflow-runs.ts +84 -0
- package/apps/sessrumnir/src/renderer/tsconfig.json +24 -0
- package/apps/sessrumnir/src/shared/agent-engine-label.test.ts +45 -0
- package/apps/sessrumnir/src/shared/agent-engine-label.ts +53 -0
- package/apps/sessrumnir/src/shared/app-settings.test.ts +25 -0
- package/apps/sessrumnir/src/shared/app-settings.ts +23 -0
- package/apps/sessrumnir/src/shared/bridge-http.ts +341 -0
- package/apps/sessrumnir/src/shared/bridge.ts +337 -0
- package/apps/sessrumnir/src/shared/council-config.test.ts +300 -0
- package/apps/sessrumnir/src/shared/council-config.ts +356 -0
- package/apps/sessrumnir/src/shared/default-settings.ts +39 -0
- package/apps/sessrumnir/src/shared/folder-drop.test.ts +118 -0
- package/apps/sessrumnir/src/shared/folder-drop.ts +74 -0
- package/apps/sessrumnir/src/shared/fork-point.test.ts +30 -0
- package/apps/sessrumnir/src/shared/fork-point.ts +24 -0
- package/apps/sessrumnir/src/shared/i18n/i18next.d.ts +10 -0
- package/apps/sessrumnir/src/shared/i18n/index.test.ts +51 -0
- package/apps/sessrumnir/src/shared/i18n/index.ts +50 -0
- package/apps/sessrumnir/src/shared/i18n/languages.ts +12 -0
- package/apps/sessrumnir/src/shared/i18n/locale-checks.ts +98 -0
- package/apps/sessrumnir/src/shared/i18n/locales.test.ts +92 -0
- package/apps/sessrumnir/src/shared/i18n/pseudo.test.ts +39 -0
- package/apps/sessrumnir/src/shared/i18n/pseudo.ts +44 -0
- package/apps/sessrumnir/src/shared/i18n/resolve.test.ts +43 -0
- package/apps/sessrumnir/src/shared/i18n/resolve.ts +41 -0
- package/apps/sessrumnir/src/shared/i18n/resources.ts +11 -0
- package/apps/sessrumnir/src/shared/ipc-contracts.ts +1539 -0
- package/apps/sessrumnir/src/shared/models-config.test.ts +124 -0
- package/apps/sessrumnir/src/shared/models-config.ts +167 -0
- package/apps/sessrumnir/src/shared/package-filter.ts +19 -0
- package/apps/sessrumnir/src/shared/package-spec.test.ts +51 -0
- package/apps/sessrumnir/src/shared/package-spec.ts +25 -0
- package/apps/sessrumnir/src/shared/path-compare.test.ts +38 -0
- package/apps/sessrumnir/src/shared/path-compare.ts +76 -0
- package/apps/sessrumnir/src/shared/permission-mode.ts +8 -0
- package/apps/sessrumnir/src/shared/pi-command.test.ts +165 -0
- package/apps/sessrumnir/src/shared/pi-command.ts +139 -0
- package/apps/sessrumnir/src/shared/product-name.ts +7 -0
- package/apps/sessrumnir/src/shared/session-lineage.test.ts +103 -0
- package/apps/sessrumnir/src/shared/session-lineage.ts +50 -0
- package/apps/sessrumnir/src/shared/session-preview.test.ts +93 -0
- package/apps/sessrumnir/src/shared/session-preview.ts +56 -0
- package/apps/sessrumnir/src/shared/sidebar-width.test.ts +58 -0
- package/apps/sessrumnir/src/shared/sidebar-width.ts +37 -0
- package/apps/sessrumnir/src/shared/theme/builtin-ids.ts +16 -0
- package/apps/sessrumnir/src/shared/theme/resolve.test.ts +66 -0
- package/apps/sessrumnir/src/shared/theme/resolve.ts +29 -0
- package/apps/sessrumnir/src/shared/theme/syntax-defaults.ts +24 -0
- package/apps/sessrumnir/src/shared/theme/theme-file.test.ts +88 -0
- package/apps/sessrumnir/src/shared/theme/theme-file.ts +132 -0
- package/apps/sessrumnir/src/shared/theme/tokens.test.ts +35 -0
- package/apps/sessrumnir/src/shared/theme/tokens.ts +86 -0
- package/apps/sessrumnir/src/shared/tsconfig.json +17 -0
- package/apps/sessrumnir/src/shared/untrusted-data.test.ts +32 -0
- package/apps/sessrumnir/src/shared/untrusted-data.ts +22 -0
- package/apps/sessrumnir/src/shared/version-compare.test.ts +33 -0
- package/apps/sessrumnir/src/shared/version-compare.ts +50 -0
- package/apps/sessrumnir/src/shared/workflow-control.ts +33 -0
- package/apps/sessrumnir/src/web-server.ts +315 -0
- package/apps/sessrumnir/tsconfig.json +26 -0
- package/apps/smidja/smidja_build.py +45 -0
- package/apps/smidja/smidja_build_review.py +76 -0
- package/apps/smidja/smidja_build_test.py +79 -0
- package/apps/smidja/smidja_document.py +76 -0
- package/apps/smidja/smidja_modules/agent_cc.py +15 -0
- package/apps/smidja/smidja_modules/agent_opencode.py +194 -0
- package/apps/smidja/smidja_modules/agent_pi.py +392 -0
- package/apps/smidja/smidja_modules/agents.py +993 -0
- package/apps/smidja/smidja_modules/changes.py +103 -0
- package/apps/smidja/smidja_modules/console.py +131 -0
- package/apps/smidja/smidja_modules/data_types.py +447 -0
- package/apps/smidja/smidja_modules/gates.py +108 -0
- package/apps/smidja/smidja_modules/git_helper.py +120 -0
- package/apps/smidja/smidja_modules/lm_local.py +144 -0
- package/apps/smidja/smidja_modules/permissions.py +194 -0
- package/apps/smidja/smidja_modules/prompts.py +21 -0
- package/apps/smidja/smidja_modules/quality.py +240 -0
- package/apps/smidja/smidja_modules/runner.py +155 -0
- package/apps/smidja/smidja_modules/session.py +50 -0
- package/apps/smidja/smidja_modules/stall_watch.py +149 -0
- package/apps/smidja/smidja_modules/tracer.py +271 -0
- package/apps/smidja/smidja_modules/utils.py +77 -0
- package/apps/smidja/smidja_orchestrate.py +162 -0
- package/apps/smidja/smidja_plan.py +45 -0
- package/apps/smidja/smidja_plan_build.py +55 -0
- package/apps/smidja/smidja_plan_build_test.py +86 -0
- package/apps/smidja/smidja_plan_build_test_quality.py +98 -0
- package/apps/smidja/smidja_prompt.py +44 -0
- package/apps/smidja/smidja_quality.py +49 -0
- package/apps/smidja/smidja_recon_iv.py +202 -0
- package/apps/smidja/smidja_scout.py +45 -0
- package/apps/smidja/smidja_simple_sdlc.py +183 -0
- package/apps/smidja/smidja_smidja_config/smidja.config.yaml +143 -0
- package/apps/smidja-factory/AGENTS.md +165 -0
- package/apps/smidja-factory/README.md +3 -0
- package/apps/smidja-factory/SKILL.md +18 -0
- package/apps/smidja-factory/apps/visualizer/.oxlintrc.json +18 -0
- package/apps/smidja-factory/apps/visualizer/bun.lock +269 -0
- package/apps/smidja-factory/apps/visualizer/desktop/icon.png +0 -0
- package/apps/smidja-factory/apps/visualizer/desktop/main.js +140 -0
- package/apps/smidja-factory/apps/visualizer/desktop/package-lock.json +871 -0
- package/apps/smidja-factory/apps/visualizer/desktop/package.json +18 -0
- package/apps/smidja-factory/apps/visualizer/desktop/preload.js +19 -0
- package/apps/smidja-factory/apps/visualizer/index.html +28 -0
- package/apps/smidja-factory/apps/visualizer/package.json +31 -0
- package/apps/smidja-factory/apps/visualizer/public/icon.svg +7 -0
- package/apps/smidja-factory/apps/visualizer/public/models/claude.png +0 -0
- package/apps/smidja-factory/apps/visualizer/public/models/gemini.png +0 -0
- package/apps/smidja-factory/apps/visualizer/public/models/kimi.png +0 -0
- package/apps/smidja-factory/apps/visualizer/public/models/openai.png +0 -0
- package/apps/smidja-factory/apps/visualizer/public/models/zai.png +0 -0
- package/apps/smidja-factory/apps/visualizer/server/chat.ts +425 -0
- package/apps/smidja-factory/apps/visualizer/server/db.ts +1050 -0
- package/apps/smidja-factory/apps/visualizer/server/index.ts +648 -0
- package/apps/smidja-factory/apps/visualizer/server/model-catalog.ts +90 -0
- package/apps/smidja-factory/apps/visualizer/server/roster-api.ts +75 -0
- package/apps/smidja-factory/apps/visualizer/server/roster_resolve.py +170 -0
- package/apps/smidja-factory/apps/visualizer/server/settings.ts +106 -0
- package/apps/smidja-factory/apps/visualizer/shared/types.ts +630 -0
- package/apps/smidja-factory/apps/visualizer/src/App.vue +379 -0
- package/apps/smidja-factory/apps/visualizer/src/components/ChatInput.vue +155 -0
- package/apps/smidja-factory/apps/visualizer/src/components/ChatThread.vue +219 -0
- package/apps/smidja-factory/apps/visualizer/src/components/ChatView.vue +335 -0
- package/apps/smidja-factory/apps/visualizer/src/components/DecisionsView.vue +177 -0
- package/apps/smidja-factory/apps/visualizer/src/components/DetailSection.vue +76 -0
- package/apps/smidja-factory/apps/visualizer/src/components/MemoryView.vue +397 -0
- package/apps/smidja-factory/apps/visualizer/src/components/PhaseDetail.vue +1354 -0
- package/apps/smidja-factory/apps/visualizer/src/components/PhaseDots.vue +55 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionCard.vue +583 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionMiniCard.vue +58 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionPanel.vue +272 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionStartForm.vue +152 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionTrace.vue +1157 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SessionsList.vue +96 -0
- package/apps/smidja-factory/apps/visualizer/src/components/SettingsView.vue +152 -0
- package/apps/smidja-factory/apps/visualizer/src/components/StatChip.vue +98 -0
- package/apps/smidja-factory/apps/visualizer/src/components/StatsView.vue +382 -0
- package/apps/smidja-factory/apps/visualizer/src/components/StatusChip.vue +73 -0
- package/apps/smidja-factory/apps/visualizer/src/components/ToolCallCard.vue +156 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/api.ts +177 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/chat-api.ts +95 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/chat-store.ts +351 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/events.ts +131 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/format.ts +92 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/highlight.ts +54 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/markdown.ts +120 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/models.ts +42 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/router.ts +67 -0
- package/apps/smidja-factory/apps/visualizer/src/lib/types.ts +61 -0
- package/apps/smidja-factory/apps/visualizer/src/main.ts +13 -0
- package/apps/smidja-factory/apps/visualizer/src/style.css +592 -0
- package/apps/smidja-factory/apps/visualizer/tsconfig.json +30 -0
- package/apps/smidja-factory/apps/visualizer/vite.config.js +32 -0
- package/apps/smidja-factory/apps/visualizer/vite.config.ts +31 -0
- package/apps/smidja-factory/cookbooks/create_config.md +61 -0
- package/apps/smidja-factory/cookbooks/create_smidja.md +120 -0
- package/apps/smidja-factory/cookbooks/how_to_prompt_for_the_eng.md +110 -0
- package/apps/smidja-factory/cookbooks/install.md +56 -0
- package/apps/smidja-factory/cookbooks/run_smidja.md +122 -0
- package/apps/smidja-factory/cookbooks/smidja_overview.md +88 -0
- package/apps/smidja-factory/cookbooks/update_config.md +103 -0
- package/apps/smidja-factory/cookbooks/update_modules.md +100 -0
- package/apps/smidja-factory/cookbooks/update_smidja.md +90 -0
- package/apps/smidja-factory/docs/enhancement-plan.md +420 -0
- package/apps/smidja-factory/references/config.md +202 -0
- package/apps/smidja-factory/references/handoff.md +161 -0
- package/apps/smidja-factory/references/observability.md +166 -0
- package/apps/smidja-factory/scripts/install.py +113 -0
- package/apps/smidja-factory/scripts/make_config.py +35 -0
- package/apps/smidja-factory/scripts/make_smidja.py +119 -0
- package/apps/smidja-factory/skills/add-or-edit-ai-models/SKILL.md +151 -0
- package/apps/smidja-factory/skills/create-new-agent/SKILL.md +125 -0
- package/apps/smidja-factory/skills/create-new-teams/SKILL.md +151 -0
- package/apps/smidja-factory/skills/git-ops/README.md +25 -0
- package/apps/smidja-factory/skills/git-ops/SKILL.md +18 -0
- package/apps/smidja-factory/skills/git-ops/create_branch.sh +79 -0
- package/apps/smidja-factory/skills/git-ops/safe_commit.sh +82 -0
- package/apps/smidja-factory/skills/git-ops/sync_upstream.sh +94 -0
- package/apps/smidja-factory/skills/how-to-run-agent-teams/SKILL.md +117 -0
- package/apps/smidja-factory/skills/smidja-instructions/SKILL.md +168 -0
- package/apps/smidja-factory/skills/smidja-launcher/SKILL.md +155 -0
- package/apps/smidja-factory/skills/smidja-start/SKILL.md +266 -0
- package/apps/smidja-factory/skills/volundr/SKILL.md +232 -0
- package/apps/smidja-factory/skills/volundr/prompt/dispatch-prompt.md +91 -0
- package/apps/smidja-factory/skills/volundr/prompt/volundr-system.md +63 -0
- package/apps/smidja-factory/skills/volundr/scripts/volundr-observe.py +52 -0
- package/apps/smidja-factory/skills/volundr/scripts/volundr-recall.py +54 -0
- package/apps/smidja-factory/skills/volundr/scripts/volundr-status.py +51 -0
- package/apps/smidja-factory/skills/volundr/scripts/volundr-teach.py +47 -0
- package/apps/smidja-factory/templates/env.sample +28 -0
- package/apps/smidja-factory/templates/harness_engineering/subagents.ts +706 -0
- package/apps/smidja-factory/templates/harness_engineering/themeMap.ts +145 -0
- package/apps/smidja-factory/templates/justfile +89 -0
- package/apps/smidja-factory/templates/prompt_engineering/builder/system.md +13 -0
- package/apps/smidja-factory/templates/prompt_engineering/builder/user.md +34 -0
- package/apps/smidja-factory/templates/prompt_engineering/documenter/system.md +17 -0
- package/apps/smidja-factory/templates/prompt_engineering/documenter/user.md +48 -0
- package/apps/smidja-factory/templates/prompt_engineering/orchestrator/system.md +55 -0
- package/apps/smidja-factory/templates/prompt_engineering/orchestrator/user.md +39 -0
- package/apps/smidja-factory/templates/prompt_engineering/planner/system.md +21 -0
- package/apps/smidja-factory/templates/prompt_engineering/planner/user.md +45 -0
- package/apps/smidja-factory/templates/prompt_engineering/recon_orchestrator/system.md +51 -0
- package/apps/smidja-factory/templates/prompt_engineering/recon_orchestrator/user.md +26 -0
- package/apps/smidja-factory/templates/prompt_engineering/reviewer/system.md +16 -0
- package/apps/smidja-factory/templates/prompt_engineering/reviewer/user.md +44 -0
- package/apps/smidja-factory/templates/prompt_engineering/scout/system.md +32 -0
- package/apps/smidja-factory/templates/prompt_engineering/scout/user.md +34 -0
- package/apps/smidja-factory/templates/smidja/smidja_build.py +45 -0
- package/apps/smidja-factory/templates/smidja/smidja_build_review.py +76 -0
- package/apps/smidja-factory/templates/smidja/smidja_build_test.py +79 -0
- package/apps/smidja-factory/templates/smidja/smidja_document.py +76 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/agent_cc.py +15 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/agent_opencode.py +194 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/agent_pi.py +392 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/agents.py +993 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/changes.py +103 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/console.py +131 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/data_types.py +447 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/gates.py +108 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/git_helper.py +120 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/lm_local.py +144 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/permissions.py +194 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/prompts.py +21 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/quality.py +240 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/runner.py +155 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/session.py +50 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/stall_watch.py +149 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/tracer.py +271 -0
- package/apps/smidja-factory/templates/smidja/smidja_modules/utils.py +77 -0
- package/apps/smidja-factory/templates/smidja/smidja_orchestrate.py +162 -0
- package/apps/smidja-factory/templates/smidja/smidja_plan.py +45 -0
- package/apps/smidja-factory/templates/smidja/smidja_plan_build.py +55 -0
- package/apps/smidja-factory/templates/smidja/smidja_plan_build_test.py +86 -0
- package/apps/smidja-factory/templates/smidja/smidja_plan_build_test_quality.py +98 -0
- package/apps/smidja-factory/templates/smidja/smidja_prompt.py +44 -0
- package/apps/smidja-factory/templates/smidja/smidja_quality.py +49 -0
- package/apps/smidja-factory/templates/smidja/smidja_recon_iv.py +202 -0
- package/apps/smidja-factory/templates/smidja/smidja_scout.py +45 -0
- package/apps/smidja-factory/templates/smidja/smidja_simple_sdlc.py +183 -0
- package/apps/smidja-factory/templates/smidja.config.yaml +143 -0
- package/bin/app-build.sh +36 -0
- package/bin/electron-lib.sh +25 -0
- package/bin/sessrumnir.sh +1 -1
- package/bin/ymir-install.sh +7 -0
- package/install.sh +88 -0
- package/package.json +16 -7
- package/scripts/electron.sh +6 -2
- package/.agents/bus/messages.json +0 -1
- package/.agents/config/agents.machine.example.yaml +0 -16
- package/.pi/mcp.json +0 -16
- package/assets/reference/state/.branch-eligible-owner +0 -4
- package/assets/reference/state/.branch-mirror-cursor +0 -1
- package/assets/reference/state/.branch-outcomes-cursor +0 -1
- package/assets/reference/state/.branch-session +0 -1
- package/assets/reference/state/.count-default_wF_p5 +0 -1
- package/assets/reference/state/.count-default_wF_p6 +0 -1
- package/assets/reference/state/.count-default_wR_p2 +0 -1
- package/assets/reference/state/.count-default_wS_p2 +0 -1
- package/assets/reference/state/.count-firstmate_fm-server-knowledge +0 -1
- package/assets/reference/state/.hash-default_wF_p5 +0 -1
- package/assets/reference/state/.hash-default_wF_p6 +0 -1
- package/assets/reference/state/.hash-default_wR_p2 +0 -1
- package/assets/reference/state/.hash-default_wS_p2 +0 -1
- package/assets/reference/state/.hash-firstmate_fm-server-knowledge +0 -1
- package/assets/reference/state/.heartbeat-streak +0 -1
- package/assets/reference/state/.inactive-outcome-reconcile +0 -2
- package/assets/reference/state/.lock +0 -1
- package/assets/reference/state/.pi-branch-extension-loaded +0 -1
- package/assets/reference/state/.pi-turnend-extension-loaded +0 -2
- package/assets/reference/state/.pi-watch-extension-loaded +0 -2
- package/assets/reference/state/.seen-server-knowledge_turn-ended +0 -1
- package/assets/reference/state/.session-start-agents-baseline +0 -2
- package/assets/reference/state/.session-start-complete +0 -1
- package/assets/reference/state/.stale-default_wF_p5 +0 -1
- package/assets/reference/state/.stale-default_wR_p2 +0 -1
- package/assets/reference/state/.stale-firstmate_fm-server-knowledge +0 -1
- package/assets/reference/state/.stale-since-default_wF_p5 +0 -1
- package/assets/reference/state/.stale-since-default_wR_p2 +0 -1
- package/assets/reference/state/.stale-since-firstmate_fm-server-knowledge +0 -1
- package/assets/reference/state/.startup-network.delivered +0 -1
- package/assets/reference/state/.startup-network.report +0 -1
- package/assets/reference/state/.startup-network.status +0 -10
- package/assets/reference/state/.startup-network.timings +0 -6
- package/assets/reference/state/.trace-context-effective +0 -1
- package/assets/reference/state/.wake-queue +0 -0
- package/assets/reference/state/.wake-queue.seq +0 -1
- package/assets/reference/state/.wake-rows.consume.BcqXSq +0 -0
- package/assets/reference/state/.wake-rows.consume.NDZZei +0 -0
- package/assets/reference/state/.wake-rows.consume.VGkhYm +0 -0
- package/assets/reference/state/.wake-rows.consume.tR2rTy +0 -0
- package/assets/reference/state/.watch-arm-output.3581p6 +0 -0
- package/assets/reference/state/.watch-arm-output.3ciDNP +0 -0
- package/assets/reference/state/.watch-arm-output.SksR6k +0 -0
- package/assets/reference/state/.watch-cycle-exits.log +0 -22
- package/assets/reference/state/.watch-deliveries.log +0 -19
- package/assets/reference/state/.watch-triage.log +0 -38
- package/assets/reference/state/.watch.lock/fm-home +0 -1
- package/assets/reference/state/.watch.lock/pid +0 -1
- package/assets/reference/state/.watch.lock/pid-identity +0 -1
- package/assets/reference/state/.watch.lock/watcher-path +0 -1
- package/assets/reference/state/.watch.lock.owner.qqbxmS/fm-home +0 -1
- package/assets/reference/state/.watch.lock.owner.qqbxmS/pid +0 -1
- package/assets/reference/state/.watch.lock.owner.qqbxmS/pid-identity +0 -1
- package/assets/reference/state/.watch.lock.owner.qqbxmS/watcher-path +0 -1
- package/assets/reference/state/.watcher-down +0 -1
- package/assets/reference/state/branch-outcomes.jsonl +0 -1
- package/assets/reference/state/branch-session/2026-09-04T16-49-38-671Z_01a06d53-6b6f-7619-930d-e6dfd9a4a29e.jsonl +0 -211
- package/assets/reference/state/home-summary.json +0 -42
- package/assets/reference/state/server-knowledge.busy-gen +0 -1
- package/assets/reference/state/server-knowledge.busy-state +0 -1
- package/assets/reference/state/server-knowledge.herdr-presentation +0 -12
- package/assets/reference/state/server-knowledge.meta +0 -18
- package/assets/reference/state/server-knowledge.pi-ext.ts +0 -26
- package/assets/reference/state/server-knowledge.turn-ended +0 -0
- /package/{assets/reference/state/.last-check → apps/hlidskjalf/src/app/.gitkeep} +0 -0
- /package/{assets/reference/state/.last-heartbeat → apps/hlidskjalf/src/components/.gitkeep} +0 -0
- /package/{assets/reference/state/.last-watcher-beat → apps/hlidskjalf/src/services/.gitkeep} +0 -0
- /package/{assets/reference/state/.main-eligible-rows.tmp.p2HMKo → apps/smidja/smidja_modules/__init__.py} +0 -0
- /package/{assets/reference/state/.main-eligible-rows.tmp.Exxm82 → apps/smidja-factory/templates/smidja/smidja_modules/__init__.py} +0 -0
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
import { app, BrowserWindow, dialog, ipcMain, Menu, nativeImage, screen, session, shell } from 'electron'
|
|
2
|
+
import { existsSync, mkdirSync } from 'fs'
|
|
3
|
+
import { basename, join, resolve as resolvePath } from 'path'
|
|
4
|
+
import { isTrustedRendererUrl, RENDERER_INDEX_PATH } from './renderer-origin'
|
|
5
|
+
import { workspaceTrustStore } from './workspace-trust'
|
|
6
|
+
import { WorkspaceManager } from './workspace-manager'
|
|
7
|
+
import { registerIpcHandlers, loadAppSettings, saveAppSettings } from './ipc-handlers'
|
|
8
|
+
import { setPiExecutableOverride, cleanupPiChildTempDir } from './pi-rpc-manager'
|
|
9
|
+
import { applyLanguageSetting } from './i18n'
|
|
10
|
+
import { i18n, t } from '../shared/i18n'
|
|
11
|
+
import { fetchAllCatalogPackages } from './package-catalog'
|
|
12
|
+
import { activityStatsStore } from './activity-stats'
|
|
13
|
+
import { configureGuiDataDir, getCanonicalUserDataDir, getExternalGuiDataDir, migrateLegacyGuiData } from './app-data-paths'
|
|
14
|
+
import { setupTray, setTrayEnabled, isTrayEnabled, isTrayAvailable, destroyTray, notifyFirstHide } from './tray-manager'
|
|
15
|
+
import { shouldHideToTray } from './tray-decision'
|
|
16
|
+
import { createEditorGuard } from './editor-guard'
|
|
17
|
+
import { appLog } from './app-log'
|
|
18
|
+
import { IPC_CHANNELS } from '../shared/ipc-contracts'
|
|
19
|
+
|
|
20
|
+
// Env var honored on startup: if set, the named directory becomes the active
|
|
21
|
+
// workspace (created on first run, switched to on subsequent runs). The CLI
|
|
22
|
+
// launcher in bin/sessrumnir.js sets this from `sessrumnir <path>`.
|
|
23
|
+
const WORKSPACE_ENV_VAR = 'PI_DESKTOP_WORKSPACE'
|
|
24
|
+
|
|
25
|
+
// Electron's development executable otherwise registers as Electron on Windows,
|
|
26
|
+
// which makes the taskbar and notification identity use Electron branding.
|
|
27
|
+
app.setName('Sessrúmnir')
|
|
28
|
+
if (process.platform === 'win32') app.setAppUserModelId('org.ymir.sessrumnir')
|
|
29
|
+
if (process.platform === 'linux') {
|
|
30
|
+
app.setDesktopName('ymir-sessrumnir.desktop');
|
|
31
|
+
app.commandLine.appendSwitch('class', 'sessrumnir');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Suppress EPIPE errors from closed subprocess pipes
|
|
35
|
+
process.on('uncaughtException', (err) => {
|
|
36
|
+
if (err.message?.includes('EPIPE') || (err as NodeJS.ErrnoException).code === 'EPIPE') {
|
|
37
|
+
// Ignore EPIPE - happens when Pi process exits
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
console.error('Uncaught exception:', err)
|
|
41
|
+
appLog.error('app', 'Uncaught exception', err)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
const WINDOW_WIDTH = 1400
|
|
47
|
+
const WINDOW_HEIGHT = 900
|
|
48
|
+
// Minimums must stay well below the compositor's tile size on a scaled screen.
|
|
49
|
+
// On a 1920x1200 panel at 1.5 scale the logical work area is 1280x800, and a
|
|
50
|
+
// half-width tile is ~414 DIP. A min width of 800 made the app fight the
|
|
51
|
+
// compositor: the surface stayed at the tile size while the renderer viewport
|
|
52
|
+
// clamped to 800 DIP, so the right half of the UI rendered outside the window.
|
|
53
|
+
const MIN_WINDOW_WIDTH = 400
|
|
54
|
+
const MIN_WINDOW_HEIGHT = 360
|
|
55
|
+
|
|
56
|
+
// Fit the seat to the screen it lands on. A fixed 1400x900 is larger than a
|
|
57
|
+
// 1280x800 logical work area (e.g. a 1920x1200 panel at 1.5 scale), which
|
|
58
|
+
// pushes the window past the glass and clips the right side of the UI. Clamp
|
|
59
|
+
// to the work area; never below the minimums (an even smaller work area wins).
|
|
60
|
+
function fitWindowSize(): { width: number; height: number } {
|
|
61
|
+
const { width, height } = screen.getPrimaryDisplay().workAreaSize
|
|
62
|
+
const fit = (desired: number, min: number, avail: number): number =>
|
|
63
|
+
Math.max(Math.min(desired, avail), Math.min(min, avail))
|
|
64
|
+
return {
|
|
65
|
+
width: fit(WINDOW_WIDTH, MIN_WINDOW_WIDTH, width),
|
|
66
|
+
height: fit(WINDOW_HEIGHT, MIN_WINDOW_HEIGHT, height),
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const DEV_SERVER_URL = process.env.ELECTRON_RENDERER_URL
|
|
70
|
+
const PRELOAD_PATH = join(__dirname, '../preload/index.js')
|
|
71
|
+
// <webview> partitions used by the file preview (see file-tree.tsx). The HTML
|
|
72
|
+
// preview renders untrusted workspace files with scripts and network disabled;
|
|
73
|
+
// the PDF preview needs pdfium (plugins) and is confined to file:// only.
|
|
74
|
+
const HTML_PREVIEW_PARTITION = 'preview'
|
|
75
|
+
const PDF_PREVIEW_PARTITION = 'persist:pdf-preview'
|
|
76
|
+
|
|
77
|
+
// In dev: resources/ sits at the project root (app.getAppPath()).
|
|
78
|
+
// In packaged: extraResources config copies resources/ into process.resourcesPath/resources/.
|
|
79
|
+
// Computed lazily: `app` is undefined at module-eval time under electron-vite preview,
|
|
80
|
+
// so reading `app.isPackaged` at top level crashes before whenReady().
|
|
81
|
+
let cachedAppIconPath: string | null = null
|
|
82
|
+
function getAppIconPath(): string {
|
|
83
|
+
if (cachedAppIconPath !== null) return cachedAppIconPath
|
|
84
|
+
const base = app.isPackaged
|
|
85
|
+
? join(process.resourcesPath, 'resources')
|
|
86
|
+
: join(app.getAppPath(), 'resources')
|
|
87
|
+
cachedAppIconPath = join(base, 'icons', 'icon.png')
|
|
88
|
+
return cachedAppIconPath
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ─── Workspace Manager (singleton) ───────────────────────────────────────────
|
|
92
|
+
|
|
93
|
+
let workspaceManager: WorkspaceManager | null = null
|
|
94
|
+
|
|
95
|
+
// The single main window, tracked so the tray, single-instance relaunch, and
|
|
96
|
+
// macOS dock-activate can all bring it back. `isQuitting` distinguishes a real
|
|
97
|
+
// quit (menu/tray Quit, Cmd-Ctrl+Q) from a window close that should hide to tray.
|
|
98
|
+
let mainWindow: BrowserWindow | null = null
|
|
99
|
+
let isQuitting = false
|
|
100
|
+
|
|
101
|
+
// Guards the renderer's unsaved editor buffer against teardown. The renderer
|
|
102
|
+
// mirrors its dirty flag here (ui:editor-dirty-set); quit, non-tray window
|
|
103
|
+
// close, and the reload menu items all pause on the same discard dialog.
|
|
104
|
+
const editorGuard = createEditorGuard()
|
|
105
|
+
|
|
106
|
+
/** Native confirm matching the in-app discard dialog's wording. */
|
|
107
|
+
async function confirmEditorDiscard(window: BrowserWindow | null): Promise<boolean> {
|
|
108
|
+
// Tray Quit can arrive while the window is hidden; surface it so the
|
|
109
|
+
// dialog (and the edits it is asking about) are actually visible.
|
|
110
|
+
if (window && !window.isDestroyed() && !window.isVisible()) window.show()
|
|
111
|
+
const options = {
|
|
112
|
+
type: 'warning' as const,
|
|
113
|
+
title: t('editorGuard.title'),
|
|
114
|
+
message: editorGuard.promptMessage(),
|
|
115
|
+
buttons: [t('editorGuard.discardButton'), t('editorGuard.keepEditing')],
|
|
116
|
+
defaultId: 1,
|
|
117
|
+
cancelId: 1,
|
|
118
|
+
}
|
|
119
|
+
const { response } = window
|
|
120
|
+
? await dialog.showMessageBox(window, options)
|
|
121
|
+
: await dialog.showMessageBox(options)
|
|
122
|
+
return response === 0
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Menu Reload / Force Reload: ask a dirty editor first, then reload. */
|
|
126
|
+
async function reloadMainWindowWithGuard(ignoreCache: boolean): Promise<void> {
|
|
127
|
+
const window = mainWindow
|
|
128
|
+
if (!window) return
|
|
129
|
+
if (editorGuard.needsPrompt() && !(await confirmEditorDiscard(window))) return
|
|
130
|
+
// did-start-loading resets the guard once the reload actually begins.
|
|
131
|
+
if (ignoreCache) window.webContents.reloadIgnoringCache()
|
|
132
|
+
else window.webContents.reload()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Single-instance lock: with "minimize to tray" the window can be hidden while
|
|
136
|
+
// the app keeps running, so a relaunch (taskbar, launcher, `pi-desktop <path>`)
|
|
137
|
+
// must focus the existing instance instead of spawning a second one. The second
|
|
138
|
+
// process exits immediately; the first receives 'second-instance'.
|
|
139
|
+
if (!app.requestSingleInstanceLock()) {
|
|
140
|
+
app.quit()
|
|
141
|
+
} else {
|
|
142
|
+
app.on('second-instance', () => {
|
|
143
|
+
showMainWindow()
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// PI_DESKTOP_USER_DATA_DIR set by the launching process overrides the
|
|
148
|
+
// canonical appData-derived directory: that exact directory holds all GUI
|
|
149
|
+
// data and legacy migration is skipped, keeping it fully isolated.
|
|
150
|
+
const externalUserDataDir = getExternalGuiDataDir()
|
|
151
|
+
const userDataDir = externalUserDataDir ?? getCanonicalUserDataDir(app.getPath('appData'))
|
|
152
|
+
mkdirSync(userDataDir, { recursive: true })
|
|
153
|
+
app.setPath('userData', userDataDir)
|
|
154
|
+
configureGuiDataDir(userDataDir)
|
|
155
|
+
|
|
156
|
+
// ─── Window Creation ─────────────────────────────────────────────────────────
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The main window must never navigate to arbitrary content: its privileged
|
|
160
|
+
* preload (terminal + full IPC) attaches to whatever loads. In production only
|
|
161
|
+
* the exact packaged renderer file is allowed; in development only the dev
|
|
162
|
+
* server's own origin (parsed, not a fragile string prefix).
|
|
163
|
+
*/
|
|
164
|
+
function isAllowedMainWindowNavigation(targetUrl: string): boolean {
|
|
165
|
+
return isTrustedRendererUrl(targetUrl, {
|
|
166
|
+
devServerUrl: DEV_SERVER_URL,
|
|
167
|
+
rendererIndexPath: RENDERER_INDEX_PATH,
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Whether the active workspace has been trusted by the user (see workspace-trust.ts). */
|
|
172
|
+
function isActiveWorkspaceTrusted(): boolean {
|
|
173
|
+
const path = workspaceManager?.getActiveWorkspace()?.path
|
|
174
|
+
return path ? workspaceTrustStore.isTrusted(path) : false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* For an untrusted workspace, confine the HTML file-preview guest to local files:
|
|
179
|
+
* block every non-file request on its partition so malicious workspace HTML
|
|
180
|
+
* cannot beacon out or pull remote resources. Combined with scripts-disabled for
|
|
181
|
+
* untrusted previews (see will-attach-webview), this closes the exfiltration path.
|
|
182
|
+
* A trusted workspace's own pages may load resources normally (interactive preview).
|
|
183
|
+
*/
|
|
184
|
+
function hardenPreviewSession(): void {
|
|
185
|
+
session
|
|
186
|
+
.fromPartition(HTML_PREVIEW_PARTITION)
|
|
187
|
+
.webRequest.onBeforeRequest((details, callback) => {
|
|
188
|
+
const blocked = !details.url.startsWith('file://') && !isActiveWorkspaceTrusted()
|
|
189
|
+
callback({ cancel: blocked })
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function createMainWindow(): BrowserWindow {
|
|
194
|
+
const appIcon = nativeImage.createFromPath(getAppIconPath())
|
|
195
|
+
const { width, height } = fitWindowSize()
|
|
196
|
+
const window = new BrowserWindow({
|
|
197
|
+
width,
|
|
198
|
+
height,
|
|
199
|
+
minWidth: MIN_WINDOW_WIDTH,
|
|
200
|
+
minHeight: MIN_WINDOW_HEIGHT,
|
|
201
|
+
title: 'Sessrúmnir',
|
|
202
|
+
backgroundColor: '#0a1020',
|
|
203
|
+
icon: appIcon,
|
|
204
|
+
show: false,
|
|
205
|
+
webPreferences: {
|
|
206
|
+
preload: PRELOAD_PATH,
|
|
207
|
+
contextIsolation: true,
|
|
208
|
+
nodeIntegration: false,
|
|
209
|
+
sandbox: true,
|
|
210
|
+
webSecurity: true,
|
|
211
|
+
allowRunningInsecureContent: false,
|
|
212
|
+
experimentalFeatures: false,
|
|
213
|
+
// Enables the <webview> tag used by the HTML file preview to run its own
|
|
214
|
+
// JavaScript in an isolated guest process (no Node, separate origin),
|
|
215
|
+
// without loosening the app's own CSP.
|
|
216
|
+
webviewTag: true,
|
|
217
|
+
},
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
// Hide the top menu bar (File/Edit/View/Window). The application menu stays
|
|
221
|
+
// set so its accelerators (Ctrl+N, Ctrl+O, copy/paste, etc.) keep working;
|
|
222
|
+
// only the visible bar is hidden. autoHideMenuBar is left off so Alt won't
|
|
223
|
+
// reveal it.
|
|
224
|
+
window.setMenuBarVisibility(false)
|
|
225
|
+
|
|
226
|
+
// Graceful show (avoid white flash)
|
|
227
|
+
window.once('ready-to-show', () => {
|
|
228
|
+
window.show()
|
|
229
|
+
window.focus()
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// Minimize-to-tray: when enabled (Windows/Linux), a window close hides the
|
|
233
|
+
// window and keeps the app running instead of quitting. A real quit sets
|
|
234
|
+
// `isQuitting` first (see before-quit), so this only intercepts user closes.
|
|
235
|
+
window.on('close', (event) => {
|
|
236
|
+
if (shouldHideToTray({ isQuitting, enabled: isTrayEnabled(), platform: process.platform, trayAvailable: isTrayAvailable() })) {
|
|
237
|
+
event.preventDefault()
|
|
238
|
+
window.hide()
|
|
239
|
+
notifyFirstHide()
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
// A real close destroys the renderer and its unsaved editor buffer;
|
|
243
|
+
// pause for the same discard decision every in-app path gets. (Hiding to
|
|
244
|
+
// tray above loses nothing, so it never asks.)
|
|
245
|
+
if (editorGuard.needsPrompt()) {
|
|
246
|
+
event.preventDefault()
|
|
247
|
+
void confirmEditorDiscard(window).then((discard) => {
|
|
248
|
+
if (discard) {
|
|
249
|
+
editorGuard.confirmDiscard()
|
|
250
|
+
window.close()
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
// A reloaded (or crashed-and-recovered) renderer starts with a clean
|
|
257
|
+
// editor; a stale dirty flag here would make quit nag forever.
|
|
258
|
+
window.webContents.on('did-start-loading', () => editorGuard.reset())
|
|
259
|
+
window.webContents.on('render-process-gone', () => editorGuard.reset())
|
|
260
|
+
|
|
261
|
+
window.on('closed', () => {
|
|
262
|
+
if (mainWindow === window) mainWindow = null
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
// Open external links in default browser
|
|
266
|
+
window.webContents.setWindowOpenHandler(({ url }) => {
|
|
267
|
+
if (url.startsWith('https://') || url.startsWith('http://')) {
|
|
268
|
+
shell.openExternal(url)
|
|
269
|
+
}
|
|
270
|
+
return { action: 'deny' }
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// Block navigation to anything but the pinned renderer (see helper).
|
|
274
|
+
window.webContents.on('will-navigate', (event, url) => {
|
|
275
|
+
if (isAllowedMainWindowNavigation(url)) return
|
|
276
|
+
event.preventDefault()
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
// Harden the HTML file-preview <webview> guest before Electron attaches it:
|
|
280
|
+
// strip any preload/Node access it might request and reject anything that
|
|
281
|
+
// isn't the local `file://` preview it's meant for. Defense-in-depth against
|
|
282
|
+
// a renderer XSS trying to attach a guest with elevated webPreferences.
|
|
283
|
+
window.webContents.on('will-attach-webview', (event, webPreferences, params) => {
|
|
284
|
+
delete webPreferences.preload
|
|
285
|
+
webPreferences.nodeIntegration = false
|
|
286
|
+
webPreferences.nodeIntegrationInSubFrames = false
|
|
287
|
+
webPreferences.contextIsolation = true
|
|
288
|
+
webPreferences.sandbox = true
|
|
289
|
+
webPreferences.webSecurity = true
|
|
290
|
+
webPreferences.allowRunningInsecureContent = false
|
|
291
|
+
|
|
292
|
+
// Only the PDF preview needs pdfium (plugins). For the HTML preview, scripts
|
|
293
|
+
// run only when the workspace is trusted (interactive preview of your own
|
|
294
|
+
// project); for an untrusted workspace scripts are disabled so — with sandbox
|
|
295
|
+
// + webSecurity above and the partition's network block — malicious preview
|
|
296
|
+
// HTML cannot read other local files or exfiltrate data.
|
|
297
|
+
const isPdfPreview =
|
|
298
|
+
params.partition === PDF_PREVIEW_PARTITION || /\.pdf(?:[?#]|$)/i.test(params.src)
|
|
299
|
+
webPreferences.plugins = isPdfPreview
|
|
300
|
+
if (!isPdfPreview && !isActiveWorkspaceTrusted()) {
|
|
301
|
+
webPreferences.javascript = false
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (!params.src.startsWith('file://')) {
|
|
305
|
+
event.preventDefault()
|
|
306
|
+
}
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
// Load renderer
|
|
310
|
+
if (DEV_SERVER_URL) {
|
|
311
|
+
window.loadURL(DEV_SERVER_URL)
|
|
312
|
+
} else {
|
|
313
|
+
window.loadFile(RENDERER_INDEX_PATH)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Dev tools in development
|
|
317
|
+
if (process.env.NODE_ENV === 'development') {
|
|
318
|
+
window.webContents.openDevTools({ mode: 'detach' })
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
mainWindow = window
|
|
322
|
+
return window
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Bring the main window to the foreground, re-creating it if it was fully
|
|
326
|
+
// closed. Used by the tray, single-instance relaunch, and macOS dock activate.
|
|
327
|
+
function showMainWindow(): void {
|
|
328
|
+
if (mainWindow) {
|
|
329
|
+
if (mainWindow.isMinimized()) mainWindow.restore()
|
|
330
|
+
mainWindow.show()
|
|
331
|
+
mainWindow.focus()
|
|
332
|
+
} else {
|
|
333
|
+
createMainWindow()
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// ─── Application Menu ────────────────────────────────────────────────────────
|
|
338
|
+
|
|
339
|
+
// One identity covers every Ymir surface: the shared session lives at the gate,
|
|
340
|
+
// so signing out here clears it for Hlidskjalf, Smiðja, and Sessrúmnir alike.
|
|
341
|
+
const YMIR_GATE = process.env.YMIR_GATE_URL ?? 'http://127.0.0.1:3889'
|
|
342
|
+
|
|
343
|
+
async function signOutOfYmir(): Promise<void> {
|
|
344
|
+
try {
|
|
345
|
+
await fetch(`${YMIR_GATE}/api/logout`, { method: 'POST' })
|
|
346
|
+
} catch {
|
|
347
|
+
// gate down — nothing to clear server-side
|
|
348
|
+
}
|
|
349
|
+
BrowserWindow.getAllWindows().forEach((w) => w.reload())
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Move to another hall through the gate's one launcher, as the Omarchy key
|
|
353
|
+
// bindings and Hlidskjalf's switcher do.
|
|
354
|
+
async function raiseHall(view: 'hlidskjalf' | 'smidja' | 'sessrumnir'): Promise<void> {
|
|
355
|
+
try {
|
|
356
|
+
await fetch(`${YMIR_GATE}/api/desktop`, {
|
|
357
|
+
method: 'POST',
|
|
358
|
+
headers: { 'content-type': 'application/json' },
|
|
359
|
+
body: JSON.stringify({ view }),
|
|
360
|
+
})
|
|
361
|
+
} catch {
|
|
362
|
+
// launcher unreachable — stay where we are
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function createApplicationMenu(): void {
|
|
367
|
+
const template: Electron.MenuItemConstructorOptions[] = [
|
|
368
|
+
{
|
|
369
|
+
label: t('menu.file'),
|
|
370
|
+
submenu: [
|
|
371
|
+
{
|
|
372
|
+
label: t('common.newSession'),
|
|
373
|
+
accelerator: 'CmdOrCtrl+N',
|
|
374
|
+
click: () => {
|
|
375
|
+
const focusedWindow = BrowserWindow.getFocusedWindow()
|
|
376
|
+
focusedWindow?.webContents.send('menu:new-session')
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
label: t('menu.newWorkspace'),
|
|
381
|
+
accelerator: 'CmdOrCtrl+Shift+N',
|
|
382
|
+
click: () => {
|
|
383
|
+
const focusedWindow = BrowserWindow.getFocusedWindow()
|
|
384
|
+
focusedWindow?.webContents.send('menu:new-workspace')
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
label: t('menu.openProject'),
|
|
389
|
+
accelerator: 'CmdOrCtrl+O',
|
|
390
|
+
click: () => {
|
|
391
|
+
const focusedWindow = BrowserWindow.getFocusedWindow()
|
|
392
|
+
focusedWindow?.webContents.send('menu:open-project')
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
{ type: 'separator' },
|
|
396
|
+
{ label: 'Go to Hlidskjalf', click: () => { void raiseHall('hlidskjalf') } },
|
|
397
|
+
{ label: 'Go to Smiðja', click: () => { void raiseHall('smidja') } },
|
|
398
|
+
{ type: 'separator' },
|
|
399
|
+
// The gate holds the one session; Sessrúmnir has no gate cookie, so it
|
|
400
|
+
// signs in through the gate rather than claiming a session it lacks.
|
|
401
|
+
{ label: 'Sign in to Ymir…', click: () => { void shell.openExternal(`${YMIR_GATE.replace(/:3889$/, ':3888')}/`) } },
|
|
402
|
+
{ label: 'Sign out of Ymir', click: () => { void signOutOfYmir() } },
|
|
403
|
+
{ type: 'separator' },
|
|
404
|
+
// Role items get explicit labels: Electron's own role labels are English.
|
|
405
|
+
{ role: 'quit', label: t('app.quit') },
|
|
406
|
+
],
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
label: t('menu.edit'),
|
|
410
|
+
submenu: [
|
|
411
|
+
{ role: 'undo', label: t('menu.undo') },
|
|
412
|
+
{ role: 'redo', label: t('menu.redo') },
|
|
413
|
+
{ type: 'separator' },
|
|
414
|
+
{ role: 'cut', label: t('common.cut') },
|
|
415
|
+
{ role: 'copy', label: t('common.copy') },
|
|
416
|
+
{ role: 'paste', label: t('common.paste') },
|
|
417
|
+
{ role: 'selectAll', label: t('common.selectAll') },
|
|
418
|
+
],
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
label: t('menu.view'),
|
|
422
|
+
submenu: [
|
|
423
|
+
// Not the bare roles: a reload destroys the renderer and its unsaved
|
|
424
|
+
// editor buffer, so both run through the same discard guard as
|
|
425
|
+
// close/quit before touching webContents.
|
|
426
|
+
{
|
|
427
|
+
label: t('menu.reload'),
|
|
428
|
+
accelerator: 'CmdOrCtrl+R',
|
|
429
|
+
click: () => void reloadMainWindowWithGuard(false),
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
label: t('menu.forceReload'),
|
|
433
|
+
accelerator: 'Shift+CmdOrCtrl+R',
|
|
434
|
+
click: () => void reloadMainWindowWithGuard(true),
|
|
435
|
+
},
|
|
436
|
+
{ role: 'toggleDevTools', label: t('menu.toggleDevTools') },
|
|
437
|
+
{ type: 'separator' },
|
|
438
|
+
{ role: 'resetZoom', label: t('menu.actualSize') },
|
|
439
|
+
{ role: 'zoomIn', label: t('menu.zoomIn') },
|
|
440
|
+
{ role: 'zoomOut', label: t('menu.zoomOut') },
|
|
441
|
+
{ type: 'separator' },
|
|
442
|
+
{ role: 'togglefullscreen', label: t('menu.toggleFullScreen') },
|
|
443
|
+
],
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
label: t('menu.window'),
|
|
447
|
+
submenu: [
|
|
448
|
+
{ role: 'minimize', label: t('menu.minimize') },
|
|
449
|
+
{ role: 'zoom', label: t('menu.zoom') },
|
|
450
|
+
{ role: 'close', label: t('menu.close') },
|
|
451
|
+
],
|
|
452
|
+
},
|
|
453
|
+
]
|
|
454
|
+
|
|
455
|
+
Menu.setApplicationMenu(Menu.buildFromTemplate(template))
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// ─── App Lifecycle ───────────────────────────────────────────────────────────
|
|
459
|
+
|
|
460
|
+
app.whenReady().then(async () => {
|
|
461
|
+
if (!externalUserDataDir) {
|
|
462
|
+
await migrateLegacyGuiData({
|
|
463
|
+
appDataDir: app.getPath('appData'),
|
|
464
|
+
userDataDir: app.getPath('userData'),
|
|
465
|
+
})
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Set the macOS dock icon in development only. A packaged app already gets its
|
|
469
|
+
// dock icon from the bundled .icns (correct macOS geometry with padding). The
|
|
470
|
+
// raw icon.png is full-bleed, so calling setIcon in a packaged build overrode
|
|
471
|
+
// the .icns with a wrongly sized icon once the app started (issue #66).
|
|
472
|
+
if (process.platform === 'darwin' && app.dock && !app.isPackaged) {
|
|
473
|
+
app.dock.setIcon(nativeImage.createFromPath(getAppIconPath()))
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Initialize workspace manager
|
|
477
|
+
workspaceManager = new WorkspaceManager()
|
|
478
|
+
await workspaceManager.initialize()
|
|
479
|
+
|
|
480
|
+
// Honor PI_DESKTOP_WORKSPACE if set: switch to (or create) the named workspace.
|
|
481
|
+
await applyWorkspaceFromEnv(workspaceManager)
|
|
482
|
+
|
|
483
|
+
// Lock the HTML preview partition to local files before any preview can load.
|
|
484
|
+
hardenPreviewSession()
|
|
485
|
+
|
|
486
|
+
// Resolve the configured engine before exposing IPC or creating the renderer;
|
|
487
|
+
// otherwise the renderer can win the startup race and launch the default Pi
|
|
488
|
+
// binary before this setting is applied.
|
|
489
|
+
const settings = await loadAppSettings(workspaceManager)
|
|
490
|
+
setPiExecutableOverride(settings.piExecutablePath, settings.piEngine)
|
|
491
|
+
|
|
492
|
+
// Before the menu, window, and tray exist, so they are built in the saved language.
|
|
493
|
+
applyLanguageSetting(settings.language)
|
|
494
|
+
|
|
495
|
+
// Register IPC handlers before creating windows. The window getter is a
|
|
496
|
+
// lazy closure — mainWindow is created later and the notification wiring
|
|
497
|
+
// only dereferences it at event time. showMainWindow recreates the window
|
|
498
|
+
// when a notification is clicked after a full close (macOS).
|
|
499
|
+
registerIpcHandlers(workspaceManager, {
|
|
500
|
+
getWindow: () => mainWindow,
|
|
501
|
+
showWindow: showMainWindow,
|
|
502
|
+
}, getAppIconPath())
|
|
503
|
+
|
|
504
|
+
// The renderer mirrors its editor-dirty flag on every transition; the
|
|
505
|
+
// quit/close/reload guards below read the cached value.
|
|
506
|
+
ipcMain.on(IPC_CHANNELS.UI_EDITOR_DIRTY_SET, (_event, dirty: unknown, fileName: unknown) => {
|
|
507
|
+
editorGuard.setDirty(dirty === true, typeof fileName === 'string' ? fileName : null)
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
// Create the application menu, and build it again in the new language
|
|
511
|
+
// whenever the language setting changes.
|
|
512
|
+
createApplicationMenu()
|
|
513
|
+
i18n.on('languageChanged', () => createApplicationMenu())
|
|
514
|
+
|
|
515
|
+
// Create main window
|
|
516
|
+
createMainWindow()
|
|
517
|
+
|
|
518
|
+
// System tray: inject deps once, then enable it if the setting is on. The
|
|
519
|
+
// one-time "still running" hint reads/persists via app settings.
|
|
520
|
+
setupTray({
|
|
521
|
+
getWindow: () => mainWindow,
|
|
522
|
+
quit: () => app.quit(),
|
|
523
|
+
iconPath: getAppIconPath(),
|
|
524
|
+
hasSeenHint: settings.hasSeenTrayHint,
|
|
525
|
+
onHintShown: () => {
|
|
526
|
+
void saveAppSettings({ hasSeenTrayHint: true })
|
|
527
|
+
},
|
|
528
|
+
})
|
|
529
|
+
setTrayEnabled(settings.minimizeToTrayOnClose)
|
|
530
|
+
|
|
531
|
+
// Warm the package catalog cache in the background so the Catalog tab is
|
|
532
|
+
// instant when first opened. Non-blocking; failures are ignored (offline etc).
|
|
533
|
+
void fetchAllCatalogPackages().catch(() => {})
|
|
534
|
+
|
|
535
|
+
// Baseline scan of the persisted activity stats, so the store reflects reality
|
|
536
|
+
// even if the home screen is never opened this run. Non-blocking.
|
|
537
|
+
void activityStatsStore.refresh()
|
|
538
|
+
|
|
539
|
+
// macOS: re-show (or re-create) the window when the dock icon is clicked.
|
|
540
|
+
// showMainWindow handles both a hidden window and a fully-closed one.
|
|
541
|
+
app.on('activate', () => {
|
|
542
|
+
showMainWindow()
|
|
543
|
+
})
|
|
544
|
+
})
|
|
545
|
+
|
|
546
|
+
// Quit when all windows closed (except macOS)
|
|
547
|
+
app.on('window-all-closed', () => {
|
|
548
|
+
if (process.platform !== 'darwin') {
|
|
549
|
+
app.quit()
|
|
550
|
+
}
|
|
551
|
+
})
|
|
552
|
+
|
|
553
|
+
// Cleanup on quit
|
|
554
|
+
app.on('before-quit', (event) => {
|
|
555
|
+
// Gate BEFORE isQuitting is set: quitting destroys the renderer and its
|
|
556
|
+
// unsaved editor buffer, and a cancelled dialog must leave the tray-hide
|
|
557
|
+
// behavior (which reads isQuitting) exactly as it was.
|
|
558
|
+
if (editorGuard.needsPrompt()) {
|
|
559
|
+
event.preventDefault()
|
|
560
|
+
void confirmEditorDiscard(mainWindow).then((discard) => {
|
|
561
|
+
if (discard) {
|
|
562
|
+
editorGuard.confirmDiscard()
|
|
563
|
+
app.quit()
|
|
564
|
+
}
|
|
565
|
+
})
|
|
566
|
+
return
|
|
567
|
+
}
|
|
568
|
+
// Mark a real quit so the window `close` handler stops hiding to tray and lets
|
|
569
|
+
// the window actually close. This is the single choke point every quit path
|
|
570
|
+
// flows through (menu/tray Quit, Cmd-Ctrl+Q).
|
|
571
|
+
isQuitting = true
|
|
572
|
+
// Release the tray icon so it doesn't linger in the notification area.
|
|
573
|
+
destroyTray()
|
|
574
|
+
// Synchronous incremental scan + write: captures every session touched this
|
|
575
|
+
// run before we exit (async I/O isn't guaranteed to finish during shutdown).
|
|
576
|
+
activityStatsStore.flushSync()
|
|
577
|
+
appLog.flushSync()
|
|
578
|
+
workspaceManager?.stopAll()
|
|
579
|
+
// Windows: GUI-owned Pi TEMP does not get OS cleanup — wipe on quit.
|
|
580
|
+
cleanupPiChildTempDir()
|
|
581
|
+
})
|
|
582
|
+
|
|
583
|
+
// Security: prevent new window creation, and stop preview <webview> guests from
|
|
584
|
+
// navigating away from their local file (e.g. a malicious HTML file redirecting
|
|
585
|
+
// itself to a remote URL to phone home).
|
|
586
|
+
app.on('web-contents-created', (_event, contents) => {
|
|
587
|
+
contents.setWindowOpenHandler(() => {
|
|
588
|
+
return { action: 'deny' }
|
|
589
|
+
})
|
|
590
|
+
if (contents.getType() === 'webview') {
|
|
591
|
+
contents.on('will-navigate', (event, url) => {
|
|
592
|
+
// An untrusted preview may not navigate away from its local file (e.g. a
|
|
593
|
+
// malicious page redirecting itself to a remote URL). Trusted previews of
|
|
594
|
+
// your own project may navigate freely.
|
|
595
|
+
if (!url.startsWith('file://') && !isActiveWorkspaceTrusted()) event.preventDefault()
|
|
596
|
+
})
|
|
597
|
+
}
|
|
598
|
+
})
|
|
599
|
+
|
|
600
|
+
async function applyWorkspaceFromEnv(manager: WorkspaceManager): Promise<void> {
|
|
601
|
+
const raw = process.env[WORKSPACE_ENV_VAR]
|
|
602
|
+
if (!raw) return
|
|
603
|
+
|
|
604
|
+
const path = resolvePath(raw)
|
|
605
|
+
if (!existsSync(path)) {
|
|
606
|
+
console.warn(`[Sessrúmnir] ${WORKSPACE_ENV_VAR}=${raw} does not exist; ignoring`)
|
|
607
|
+
return
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const existing = manager.getWorkspaces().find((w) => w.path === path)
|
|
611
|
+
if (existing) {
|
|
612
|
+
await manager.setActiveWorkspace(existing.id)
|
|
613
|
+
return
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const name = basename(path) || path
|
|
617
|
+
const created = await manager.createWorkspace(name, path)
|
|
618
|
+
await manager.setActiveWorkspace(created.id)
|
|
619
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentEngineKind } from '../../shared/ipc-contracts'
|
|
2
|
+
import { getConfiguredEngineKind } from '../pi-rpc-manager'
|
|
3
|
+
import type { WorkspaceManager } from '../workspace-manager'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Engine the user is looking at right now: the active session's runtime
|
|
7
|
+
* engine when one is live (a Pi-store session resumes under Pi and an OMP
|
|
8
|
+
* session under OMP regardless of the configured default), else the
|
|
9
|
+
* configured default. Every per-engine IPC decision (models file, skill
|
|
10
|
+
* roots, plugin CLI) reads this one rule so the UI and the file it touches
|
|
11
|
+
* never disagree.
|
|
12
|
+
*/
|
|
13
|
+
export function activeEngineKind(workspaceManager: WorkspaceManager): AgentEngineKind {
|
|
14
|
+
return workspaceManager.getActivePiManager()?.getEngineKind() ?? getConfiguredEngineKind()
|
|
15
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { BrowserWindow } from 'electron'
|
|
2
|
+
import { PiRpcManager } from '../pi-rpc-manager'
|
|
3
|
+
import { WorkspaceManager } from '../workspace-manager'
|
|
4
|
+
import { SessionTagManager } from '../session-tags'
|
|
5
|
+
import { ArchivedSessionsManager } from '../archived-sessions'
|
|
6
|
+
import { TerminalService } from '../terminal-service'
|
|
7
|
+
import { NotesManager } from '../notes-manager'
|
|
8
|
+
|
|
9
|
+
export interface IpcContext {
|
|
10
|
+
workspaceManager: WorkspaceManager
|
|
11
|
+
broadcast(channel: string, data: unknown): void
|
|
12
|
+
getActivePi(): PiRpcManager
|
|
13
|
+
approvedAttachmentPaths: Set<string>
|
|
14
|
+
tagManager: SessionTagManager
|
|
15
|
+
archivedSessions: ArchivedSessionsManager
|
|
16
|
+
notesManager: NotesManager
|
|
17
|
+
terminalService: TerminalService
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createIpcContext(workspaceManager: WorkspaceManager): IpcContext {
|
|
21
|
+
const tagManager = new SessionTagManager()
|
|
22
|
+
const archivedSessions = new ArchivedSessionsManager()
|
|
23
|
+
const terminalService = new TerminalService()
|
|
24
|
+
const notesManager = new NotesManager()
|
|
25
|
+
|
|
26
|
+
// Absolute paths the user explicitly picked via the native open dialog. The
|
|
27
|
+
// attachment reader will only read these (or files inside the workspace), so a
|
|
28
|
+
// renderer cannot ask it to read arbitrary files by path.
|
|
29
|
+
const approvedAttachmentPaths = new Set<string>()
|
|
30
|
+
|
|
31
|
+
// Helper: get Pi manager for active workspace
|
|
32
|
+
function getActivePi(): PiRpcManager {
|
|
33
|
+
const pi = workspaceManager.getActivePiManager()
|
|
34
|
+
if (!pi) throw new Error('No active workspace or Pi not running')
|
|
35
|
+
return pi
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Helper: broadcast to all renderer windows
|
|
39
|
+
function broadcast(channel: string, data: unknown): void {
|
|
40
|
+
const windows = BrowserWindow.getAllWindows()
|
|
41
|
+
for (const win of windows) {
|
|
42
|
+
if (!win.isDestroyed()) {
|
|
43
|
+
win.webContents.send(channel, data)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
workspaceManager,
|
|
50
|
+
broadcast,
|
|
51
|
+
getActivePi,
|
|
52
|
+
approvedAttachmentPaths,
|
|
53
|
+
tagManager,
|
|
54
|
+
archivedSessions,
|
|
55
|
+
notesManager,
|
|
56
|
+
terminalService,
|
|
57
|
+
}
|
|
58
|
+
}
|