@zerwiz/ymir 0.1.34 → 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/package.json +15 -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,424 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { test } from 'node:test'
|
|
3
|
+
import {
|
|
4
|
+
buildNpmPrefixCommand,
|
|
5
|
+
escapeCmdArg,
|
|
6
|
+
escapeCmdSpawn,
|
|
7
|
+
quoteCmdProgram,
|
|
8
|
+
} from './cmd-escape'
|
|
9
|
+
|
|
10
|
+
// --- escapeCmdArg: args that need no rewriting stay byte-identical ---
|
|
11
|
+
|
|
12
|
+
test('escapeCmdArg leaves plain flags unchanged', () => {
|
|
13
|
+
assert.equal(escapeCmdArg('-p'), '-p')
|
|
14
|
+
assert.equal(escapeCmdArg('--output-format'), '--output-format')
|
|
15
|
+
assert.equal(escapeCmdArg('stream-json'), 'stream-json')
|
|
16
|
+
assert.equal(escapeCmdArg('prefix'), 'prefix')
|
|
17
|
+
assert.equal(escapeCmdArg('-g'), '-g')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('escapeCmdArg leaves a bare windows path without spaces unchanged', () => {
|
|
21
|
+
assert.equal(
|
|
22
|
+
escapeCmdArg(String.raw`C:\Users\tester\file.txt`),
|
|
23
|
+
String.raw`C:\Users\tester\file.txt`,
|
|
24
|
+
)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// --- escapeCmdArg: quoting layer (Microsoft argv backslash rules + "" quotes) ---
|
|
28
|
+
|
|
29
|
+
test('escapeCmdArg quotes an arg containing spaces', () => {
|
|
30
|
+
assert.equal(escapeCmdArg('hello world'), '"hello world"')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('escapeCmdArg quotes an arg containing a tab', () => {
|
|
34
|
+
assert.equal(escapeCmdArg('a\tb'), '"a\tb"')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('escapeCmdArg doubles embedded double quotes', () => {
|
|
38
|
+
assert.equal(escapeCmdArg('say "hi"'), '"say ""hi"""')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('escapeCmdArg escapes a quote even without surrounding spaces', () => {
|
|
42
|
+
assert.equal(escapeCmdArg('a"b'), '"a""b"')
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('escapeCmdArg doubles backslashes that precede an embedded quote', () => {
|
|
46
|
+
assert.equal(escapeCmdArg(String.raw`a\"b`), String.raw`"a\\""b"`)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('escapeCmdArg doubles trailing backslashes before the closing quote', () => {
|
|
50
|
+
assert.equal(escapeCmdArg('C:\\my dir\\'), String.raw`"C:\my dir\\"`)
|
|
51
|
+
assert.equal(escapeCmdArg(String.raw`a b\\`), String.raw`"a b\\\\"`)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('escapeCmdArg leaves interior backslashes alone', () => {
|
|
55
|
+
assert.equal(escapeCmdArg(String.raw`C:\my dir\file.txt`), String.raw`"C:\my dir\file.txt"`)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('escapeCmdArg quotes the empty string', () => {
|
|
59
|
+
assert.equal(escapeCmdArg(''), '""')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// --- escapeCmdArg: cmd.exe metacharacters are enclosed in real quotes ---
|
|
63
|
+
|
|
64
|
+
test('escapeCmdArg encloses ampersand command chaining in quotes', () => {
|
|
65
|
+
assert.equal(escapeCmdArg('a&b'), '"a&b"')
|
|
66
|
+
assert.equal(escapeCmdArg('a&&calc'), '"a&&calc"')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('escapeCmdArg encloses pipes in quotes', () => {
|
|
70
|
+
assert.equal(escapeCmdArg('a|b'), '"a|b"')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('escapeCmdArg encloses carets in quotes', () => {
|
|
74
|
+
assert.equal(escapeCmdArg('a^b'), '"a^b"')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('escapeCmdArg encloses redirects in quotes', () => {
|
|
78
|
+
assert.equal(escapeCmdArg('a<in>out'), '"a<in>out"')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('escapeCmdArg encloses parentheses in quotes', () => {
|
|
82
|
+
assert.equal(escapeCmdArg('(paren)'), '"(paren)"')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// --- escapeCmdArg: % and ! expand even inside quotes, so they are interrupted ---
|
|
86
|
+
|
|
87
|
+
test('escapeCmdArg interrupts %VAR% outside the quotes with a caret', () => {
|
|
88
|
+
assert.equal(escapeCmdArg('%PATH%'), '""^%"PATH"^%""')
|
|
89
|
+
assert.equal(escapeCmdArg('100%'), '"100"^%""')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test('escapeCmdArg interrupts delayed-expansion bangs outside the quotes', () => {
|
|
93
|
+
assert.equal(escapeCmdArg('!delayed!'), '""^!"delayed"^!""')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('escapeCmdArg doubles backslashes that precede a percent interrupt', () => {
|
|
97
|
+
// The interrupt opens with a quote, so a preceding backslash run must be
|
|
98
|
+
// doubled exactly as it would be before any other emitted quote.
|
|
99
|
+
assert.equal(escapeCmdArg(String.raw`dir\%PATH%`), String.raw`"dir\\"^%"PATH"^%""`)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('escapeCmdArg handles a realistic council prompt full of metacharacters', () => {
|
|
103
|
+
const prompt = 'Fix build & deploy | grep "error" > out.txt (100% done)'
|
|
104
|
+
assert.equal(
|
|
105
|
+
escapeCmdArg(prompt),
|
|
106
|
+
'"Fix build & deploy | grep ""error"" > out.txt (100"^%" done)"',
|
|
107
|
+
)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// --- escapeCmdArg: characters no escaping can make safe ---
|
|
111
|
+
|
|
112
|
+
test('escapeCmdArg rejects newlines, carriage returns, and NUL', () => {
|
|
113
|
+
assert.throws(() => escapeCmdArg('a\nb'), /cannot be passed through cmd\.exe/)
|
|
114
|
+
assert.throws(() => escapeCmdArg('a\rb'), /cannot be passed through cmd\.exe/)
|
|
115
|
+
assert.throws(() => escapeCmdArg('a\0b'), /cannot be passed through cmd\.exe/)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
// --- quoteCmdProgram ---
|
|
119
|
+
|
|
120
|
+
test('quoteCmdProgram leaves a bare shim name unchanged', () => {
|
|
121
|
+
assert.equal(quoteCmdProgram('npm.cmd'), 'npm.cmd')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
test('quoteCmdProgram leaves a plain absolute path unchanged', () => {
|
|
125
|
+
assert.equal(
|
|
126
|
+
quoteCmdProgram(String.raw`C:\Users\tester\AppData\Roaming\npm\claude.cmd`),
|
|
127
|
+
String.raw`C:\Users\tester\AppData\Roaming\npm\claude.cmd`,
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
test('quoteCmdProgram quotes a path containing spaces', () => {
|
|
132
|
+
assert.equal(
|
|
133
|
+
quoteCmdProgram(String.raw`C:\Program Files\nodejs\claude.cmd`),
|
|
134
|
+
String.raw`"C:\Program Files\nodejs\claude.cmd"`,
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('quoteCmdProgram quotes a path containing an ampersand', () => {
|
|
139
|
+
assert.equal(
|
|
140
|
+
quoteCmdProgram(String.raw`C:\Users\Tom & Jerry\npm\pi.cmd`),
|
|
141
|
+
String.raw`"C:\Users\Tom & Jerry\npm\pi.cmd"`,
|
|
142
|
+
)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('quoteCmdProgram quotes a path containing a caret', () => {
|
|
146
|
+
assert.equal(quoteCmdProgram(String.raw`C:\odd^dir\pi.cmd`), String.raw`"C:\odd^dir\pi.cmd"`)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('quoteCmdProgram interrupts percent signs outside the quotes for a shim target', () => {
|
|
150
|
+
assert.equal(
|
|
151
|
+
quoteCmdProgram(String.raw`C:\Users\100%cool\pi.cmd`),
|
|
152
|
+
String.raw`"C:\Users\100"^%"cool\pi.cmd"`,
|
|
153
|
+
)
|
|
154
|
+
assert.equal(quoteCmdProgram(String.raw`C:\a%b%c\pi.cmd`), String.raw`"C:\a"^%"b"^%"c\pi.cmd"`)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
test('quoteCmdProgram interrupts exclamation marks outside the quotes for a shim target', () => {
|
|
158
|
+
assert.equal(
|
|
159
|
+
quoteCmdProgram(String.raw`C:\Users\wow!\pi.cmd`),
|
|
160
|
+
String.raw`"C:\Users\wow"^!"\pi.cmd"`,
|
|
161
|
+
)
|
|
162
|
+
assert.equal(quoteCmdProgram(String.raw`C:\a!b!c\pi.bat`), String.raw`"C:\a"^!"b"^!"c\pi.bat"`)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test('quoteCmdProgram uses plain quotes for a native executable target', () => {
|
|
166
|
+
// cmd hands the token to the child verbatim; an interruption would end the
|
|
167
|
+
// CRT's argv[0] at the first quote and spill the remainder into argv[1].
|
|
168
|
+
assert.equal(
|
|
169
|
+
quoteCmdProgram(String.raw`C:\Users\100%cool\pi.exe`),
|
|
170
|
+
String.raw`"C:\Users\100%cool\pi.exe"`,
|
|
171
|
+
)
|
|
172
|
+
assert.equal(quoteCmdProgram(String.raw`C:\Users\wow!\pi.EXE`), String.raw`"C:\Users\wow!\pi.EXE"`)
|
|
173
|
+
assert.equal(quoteCmdProgram(String.raw`C:\odd dir\pi.com`), String.raw`"C:\odd dir\pi.com"`)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('quoteCmdProgram rejects embedded quotes and control characters', () => {
|
|
177
|
+
assert.throws(() => quoteCmdProgram('bad"name.cmd'), /cannot be quoted as a cmd\.exe program/)
|
|
178
|
+
assert.throws(() => quoteCmdProgram('bad\nname.cmd'), /cannot be passed through cmd\.exe/)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// --- quoteCmdProgram: end-to-end round trip through the parsers it must survive ---
|
|
182
|
+
|
|
183
|
+
const CARET = '^'
|
|
184
|
+
const QUOTE_CHAR = '"'
|
|
185
|
+
const BACKSLASH_CHAR = '\\'
|
|
186
|
+
/** Extensions cmd.exe launches through CreateProcess, leaving the CRT to re-parse argv[0]. */
|
|
187
|
+
const NATIVE_TARGET = /\.(exe|com)$/i
|
|
188
|
+
/** Fake host environment for the expansion phase; `b` proves the interruption works. */
|
|
189
|
+
const HOST_ENV: Record<string, string> = { b: 'EXPANDED', PATH: 'C:\\Windows' }
|
|
190
|
+
|
|
191
|
+
/** What the child process ends up seeing for the program token. */
|
|
192
|
+
interface ChildCommand {
|
|
193
|
+
program: string
|
|
194
|
+
extraArgs: string[]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* cmd.exe phase 1: substitute %name% pairs, quotes included. `cmd /c` keeps an
|
|
199
|
+
* undefined reference literal instead of collapsing it, so a name our escaping
|
|
200
|
+
* interrupted with a caret survives untouched.
|
|
201
|
+
*/
|
|
202
|
+
function expandPercentRefs(line: string, env: Record<string, string>): string {
|
|
203
|
+
let out = ''
|
|
204
|
+
for (let index = 0; index < line.length; index++) {
|
|
205
|
+
if (line[index] !== '%') {
|
|
206
|
+
out += line[index]
|
|
207
|
+
continue
|
|
208
|
+
}
|
|
209
|
+
const close = line.indexOf('%', index + 1)
|
|
210
|
+
const value = close === -1 ? undefined : env[line.slice(index + 1, close)]
|
|
211
|
+
if (value === undefined) {
|
|
212
|
+
out += line[index]
|
|
213
|
+
continue
|
|
214
|
+
}
|
|
215
|
+
out += value
|
|
216
|
+
index = close
|
|
217
|
+
}
|
|
218
|
+
return out
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** cmd.exe phase 2: a caret outside quotes escapes the next character and vanishes. */
|
|
222
|
+
function consumeCarets(line: string): string {
|
|
223
|
+
let out = ''
|
|
224
|
+
let inQuotes = false
|
|
225
|
+
for (let index = 0; index < line.length; index++) {
|
|
226
|
+
const char = line[index]
|
|
227
|
+
if (!inQuotes && char === CARET && index + 1 < line.length) {
|
|
228
|
+
out += line[index + 1]
|
|
229
|
+
index++
|
|
230
|
+
continue
|
|
231
|
+
}
|
|
232
|
+
if (char === QUOTE_CHAR) inQuotes = !inQuotes
|
|
233
|
+
out += char
|
|
234
|
+
}
|
|
235
|
+
return out
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Split on whitespace that is not inside a quoted span, then drop the real quotes. */
|
|
239
|
+
function splitUnquotedFields(line: string): string[] {
|
|
240
|
+
const fields: string[] = []
|
|
241
|
+
let current = ''
|
|
242
|
+
let started = false
|
|
243
|
+
let inQuotes = false
|
|
244
|
+
for (const char of line) {
|
|
245
|
+
if (char === QUOTE_CHAR) {
|
|
246
|
+
inQuotes = !inQuotes
|
|
247
|
+
started = true
|
|
248
|
+
continue
|
|
249
|
+
}
|
|
250
|
+
if (!inQuotes && /\s/.test(char)) {
|
|
251
|
+
if (started) fields.push(current)
|
|
252
|
+
current = ''
|
|
253
|
+
started = false
|
|
254
|
+
continue
|
|
255
|
+
}
|
|
256
|
+
current += char
|
|
257
|
+
started = true
|
|
258
|
+
}
|
|
259
|
+
if (started) fields.push(current)
|
|
260
|
+
return fields
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* The CRT / CommandLineToArgvW split, including the argv[0] special case: a
|
|
265
|
+
* leading quote makes argv[0] run to the NEXT quote with no escape processing,
|
|
266
|
+
* which is exactly what a program-token interruption breaks.
|
|
267
|
+
*/
|
|
268
|
+
function crtArgv(line: string): string[] {
|
|
269
|
+
const argv: string[] = []
|
|
270
|
+
let index = 0
|
|
271
|
+
if (line[0] === QUOTE_CHAR) {
|
|
272
|
+
const close = line.indexOf(QUOTE_CHAR, 1)
|
|
273
|
+
argv.push(line.slice(1, close === -1 ? line.length : close))
|
|
274
|
+
index = close === -1 ? line.length : close + 1
|
|
275
|
+
} else {
|
|
276
|
+
while (index < line.length && !/\s/.test(line[index])) index++
|
|
277
|
+
argv.push(line.slice(0, index))
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let current = ''
|
|
281
|
+
let started = false
|
|
282
|
+
let inQuotes = false
|
|
283
|
+
let backslashes = 0
|
|
284
|
+
for (; index < line.length; index++) {
|
|
285
|
+
const char = line[index]
|
|
286
|
+
if (char === BACKSLASH_CHAR) {
|
|
287
|
+
backslashes++
|
|
288
|
+
continue
|
|
289
|
+
}
|
|
290
|
+
if (char === QUOTE_CHAR) {
|
|
291
|
+
current += BACKSLASH_CHAR.repeat(Math.floor(backslashes / 2))
|
|
292
|
+
const escaped = backslashes % 2 === 1
|
|
293
|
+
backslashes = 0
|
|
294
|
+
started = true
|
|
295
|
+
if (escaped) {
|
|
296
|
+
current += QUOTE_CHAR
|
|
297
|
+
} else if (inQuotes && line[index + 1] === QUOTE_CHAR) {
|
|
298
|
+
current += QUOTE_CHAR
|
|
299
|
+
index++
|
|
300
|
+
} else {
|
|
301
|
+
inQuotes = !inQuotes
|
|
302
|
+
}
|
|
303
|
+
continue
|
|
304
|
+
}
|
|
305
|
+
current += BACKSLASH_CHAR.repeat(backslashes)
|
|
306
|
+
backslashes = 0
|
|
307
|
+
if (!inQuotes && /\s/.test(char)) {
|
|
308
|
+
if (started) argv.push(current)
|
|
309
|
+
current = ''
|
|
310
|
+
started = false
|
|
311
|
+
continue
|
|
312
|
+
}
|
|
313
|
+
current += char
|
|
314
|
+
started = true
|
|
315
|
+
}
|
|
316
|
+
current += BACKSLASH_CHAR.repeat(backslashes)
|
|
317
|
+
if (started || current !== '') argv.push(current)
|
|
318
|
+
return argv
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Push a program path through the whole Windows chain: our escaping, cmd.exe's
|
|
323
|
+
* two phases, and then whichever token parse the target type implies — cmd
|
|
324
|
+
* consuming the token for a shim, the CRT re-parsing it for a native binary.
|
|
325
|
+
*/
|
|
326
|
+
function throughCmd(program: string, env: Record<string, string> = HOST_ENV): ChildCommand {
|
|
327
|
+
const line = consumeCarets(expandPercentRefs(quoteCmdProgram(program), env))
|
|
328
|
+
const argv = NATIVE_TARGET.test(program) ? crtArgv(line) : splitUnquotedFields(line)
|
|
329
|
+
return { program: argv[0], extraArgs: argv.slice(1) }
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const ROUND_TRIP_PATHS = [
|
|
333
|
+
String.raw`C:\Users\tester\npm\pi`,
|
|
334
|
+
String.raw`C:\Program Files\nodejs\pi`,
|
|
335
|
+
String.raw`C:\Users\100%cool\pi`,
|
|
336
|
+
String.raw`C:\Users\wow!\pi`,
|
|
337
|
+
String.raw`C:\Users\Tom & Jerry\100%!\pi`,
|
|
338
|
+
String.raw`C:\odd^dir (x86)\a b\pi`,
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
test('quoteCmdProgram round-trips shim paths through cmd.exe untouched', () => {
|
|
342
|
+
for (const base of ROUND_TRIP_PATHS) {
|
|
343
|
+
const path = `${base}.cmd`
|
|
344
|
+
assert.deepEqual(throughCmd(path), { program: path, extraArgs: [] }, path)
|
|
345
|
+
}
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
test('quoteCmdProgram round-trips native executable paths through cmd.exe untouched', () => {
|
|
349
|
+
for (const base of ROUND_TRIP_PATHS) {
|
|
350
|
+
const path = `${base}.exe`
|
|
351
|
+
assert.deepEqual(throughCmd(path), { program: path, extraArgs: [] }, path)
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
test('quoteCmdProgram keeps a defined %VAR% literal in a shim path', () => {
|
|
356
|
+
const path = String.raw`C:\a%b%c\pi.cmd`
|
|
357
|
+
assert.deepEqual(throughCmd(path), { program: path, extraArgs: [] })
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
test('quoteCmdProgram cannot stop %VAR% expansion in a native executable path', () => {
|
|
361
|
+
// Documented residual: the CRT argv[0] rule forbids the caret interruption
|
|
362
|
+
// for native targets, so a defined variable reference in the path still
|
|
363
|
+
// expands. Pinned so the trade-off cannot be lost silently.
|
|
364
|
+
assert.deepEqual(throughCmd(String.raw`C:\a%b%c\pi.exe`), {
|
|
365
|
+
program: String.raw`C:\aEXPANDEDc\pi.exe`,
|
|
366
|
+
extraArgs: [],
|
|
367
|
+
})
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
// --- escapeCmdSpawn ---
|
|
371
|
+
|
|
372
|
+
test('escapeCmdSpawn passes program and args through untouched off the cmd path', () => {
|
|
373
|
+
assert.deepEqual(escapeCmdSpawn(false, '/usr/bin/claude', ['-p', 'a b', 'x&y']), {
|
|
374
|
+
file: '/usr/bin/claude',
|
|
375
|
+
args: ['-p', 'a b', 'x&y'],
|
|
376
|
+
})
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
test('escapeCmdSpawn keeps the npm prefix probe byte-identical on the cmd path', () => {
|
|
380
|
+
assert.deepEqual(escapeCmdSpawn(true, 'npm.cmd', ['prefix', '-g']), {
|
|
381
|
+
file: 'npm.cmd',
|
|
382
|
+
args: ['prefix', '-g'],
|
|
383
|
+
})
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
test('escapeCmdSpawn quotes the program and escapes each arg on the cmd path', () => {
|
|
387
|
+
assert.deepEqual(
|
|
388
|
+
escapeCmdSpawn(true, String.raw`C:\Program Files\nodejs\claude.cmd`, ['-p', 'a b', 'x&y']),
|
|
389
|
+
{
|
|
390
|
+
file: String.raw`"C:\Program Files\nodejs\claude.cmd"`,
|
|
391
|
+
args: ['-p', '"a b"', '"x&y"'],
|
|
392
|
+
},
|
|
393
|
+
)
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
test('escapeCmdSpawn does not mutate the input args array', () => {
|
|
397
|
+
const args = ['a b']
|
|
398
|
+
escapeCmdSpawn(true, 'npm.cmd', args)
|
|
399
|
+
assert.deepEqual(args, ['a b'])
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
// --- buildNpmPrefixCommand: the shared `npm prefix -g` probe ---
|
|
403
|
+
|
|
404
|
+
test('buildNpmPrefixCommand targets the npm shim through cmd.exe on Windows', () => {
|
|
405
|
+
assert.deepEqual(buildNpmPrefixCommand(true), {
|
|
406
|
+
file: 'npm.cmd',
|
|
407
|
+
args: ['prefix', '-g'],
|
|
408
|
+
})
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
test('buildNpmPrefixCommand targets plain npm off Windows', () => {
|
|
412
|
+
assert.deepEqual(buildNpmPrefixCommand(false), {
|
|
413
|
+
file: 'npm',
|
|
414
|
+
args: ['prefix', '-g'],
|
|
415
|
+
})
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
test('buildNpmPrefixCommand returns a fresh args array each call', () => {
|
|
419
|
+
// Callers hand these straight to spawn; a shared array could be mutated by one
|
|
420
|
+
// caller and observed by the next.
|
|
421
|
+
const first = buildNpmPrefixCommand(true)
|
|
422
|
+
first.args.push('--extra')
|
|
423
|
+
assert.deepEqual(buildNpmPrefixCommand(true).args, ['prefix', '-g'])
|
|
424
|
+
})
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escaping for Windows spawns that must run with shell:true.
|
|
3
|
+
*
|
|
4
|
+
* Since Node's CVE-2024-27980 fix, `.cmd`/`.bat` shims can only be launched
|
|
5
|
+
* through cmd.exe (shell:true) — and with shell:true Node performs NO quoting:
|
|
6
|
+
* it joins program and args with spaces into `cmd.exe /d /s /c "..."`. Every
|
|
7
|
+
* argument therefore traverses up to three parsers, and must survive each:
|
|
8
|
+
*
|
|
9
|
+
* 1. cmd.exe's command line: phase 1 expands %var% (even inside quotes),
|
|
10
|
+
* phase 2 honors quotes and treats & | < > ^ ( ) as operators outside
|
|
11
|
+
* them. `cmd /c` uses command-line semantics: an UNDEFINED %name%
|
|
12
|
+
* reference is left literal (in batch files it would collapse to
|
|
13
|
+
* nothing), and carets are consumed outside quotes.
|
|
14
|
+
* 2. The `.cmd` shim's own `%*` line: npm shims re-insert the args into a
|
|
15
|
+
* batch line (`"%_prog%" "%dp0%\...\cli.js" %*`) that goes through cmd's
|
|
16
|
+
* phase 2 AGAIN. `%*` substitution is single-pass and non-recursive, so
|
|
17
|
+
* percents inside argument text are not re-expanded there — but any
|
|
18
|
+
* metacharacter not enclosed in REAL quotes at this point injects (the
|
|
19
|
+
* BatBadBut pattern, CVE-2024-24576).
|
|
20
|
+
* 3. The final program's argv split (CommandLineToArgvW / CRT rules):
|
|
21
|
+
* backslashes are literal except runs preceding a quote (2n backslashes
|
|
22
|
+
* collapse to n), and inside a quoted span a PAIRED `""` yields one
|
|
23
|
+
* literal quote.
|
|
24
|
+
*
|
|
25
|
+
* Parser 2 is why the classic caret-everything approach (argv-quote with \",
|
|
26
|
+
* then ^-prefix every metacharacter) is NOT used for arguments: the outer
|
|
27
|
+
* cmd.exe consumes the carets, so by the time the shim's `%*` line re-parses
|
|
28
|
+
* the text, a quote escaped as \" has broken cmd's quote pairing and any
|
|
29
|
+
* following & | < > executes inside the shim. The encoding that survives all
|
|
30
|
+
* three parsers is:
|
|
31
|
+
*
|
|
32
|
+
* - wrap the argument in real double quotes (kept by every cmd pass, so
|
|
33
|
+
* metacharacters stay quoted through the shim), escaping embedded quotes
|
|
34
|
+
* as paired `""` — which preserves cmd's quote parity AND parses back to
|
|
35
|
+
* one literal quote under rule 3;
|
|
36
|
+
* - double every backslash run that precedes an emitted quote, per the
|
|
37
|
+
* Microsoft argv rules of parser 3;
|
|
38
|
+
* - `%` and `!` expand inside quotes, so each is moved OUTSIDE the quotes
|
|
39
|
+
* and caret-interrupted: `"^%"` / `"^!"`. The caret lands inside every
|
|
40
|
+
* candidate variable name, no such name is defined, command-line
|
|
41
|
+
* semantics keep the undefined reference literal, and phase 2 then strips
|
|
42
|
+
* the caret — restoring the original character. No whitespace is ever
|
|
43
|
+
* exposed outside quotes, so the argument cannot split.
|
|
44
|
+
*
|
|
45
|
+
* Known residual limits, unfixable at this layer: an environment variable
|
|
46
|
+
* whose name itself contains a caret would still expand, and delayed expansion
|
|
47
|
+
* can mangle `^`/`!` combinations inside a shim we do not control. Delayed
|
|
48
|
+
* expansion is OFF for `cmd /c` by default, so this affects only two host
|
|
49
|
+
* configurations: a machine whose Command Processor\DelayedExpansion registry
|
|
50
|
+
* value (HKCU or HKLM) is enabled, and a shim that runs `setlocal
|
|
51
|
+
* EnableDelayedExpansion` itself. \r, \n and NUL truncate the command line and
|
|
52
|
+
* have no escape at all, so they are rejected outright.
|
|
53
|
+
*
|
|
54
|
+
* The program token gets its own, different treatment (quoteCmdProgram):
|
|
55
|
+
* cmd.exe locates the command with genuine quote state, so its quotes must be
|
|
56
|
+
* real (a caret-escaped quote would end the token at the first space), and
|
|
57
|
+
* cmd — not the CRT — consumes them, so argv backslash doubling does not
|
|
58
|
+
* apply. What follows depends on who parses the token last:
|
|
59
|
+
*
|
|
60
|
+
* - `.cmd`/`.bat` shims, and every other target (a bare name cmd resolves
|
|
61
|
+
* through PATHEXT ends up at one): cmd alone consumes the token, so `%`
|
|
62
|
+
* and `!` are caret-interrupted exactly as in arguments and nothing
|
|
63
|
+
* re-reads the text. This is also the safe default for an unknown target,
|
|
64
|
+
* since an interruption can only be observed by a CRT argv[0] parse.
|
|
65
|
+
* - `.exe`/`.com` targets: cmd hands the command line to CreateProcess and
|
|
66
|
+
* the child's CRT re-parses argv[0], where a LEADING quote runs to the
|
|
67
|
+
* next quote with no escape processing. An interruption would therefore
|
|
68
|
+
* end argv[0] early and spill the remainder into a spurious argv[1], so
|
|
69
|
+
* the path is wrapped in plain real quotes instead. Residual risk, of the
|
|
70
|
+
* same kind as the delayed-expansion caveat above: a defined `%VAR%`
|
|
71
|
+
* reference inside such a path still expands in cmd's phase 1. Windows
|
|
72
|
+
* paths containing `%` are pathological, and no encoding can prevent it
|
|
73
|
+
* while keeping argv[0] intact.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
const BACKSLASH = '\\'
|
|
77
|
+
const QUOTE = '"'
|
|
78
|
+
/** Paired-quote escape: keeps cmd quote parity, parses back to one quote. */
|
|
79
|
+
const DOUBLED_QUOTE = '""'
|
|
80
|
+
/** Close the quotes, neutralize the character with a caret, reopen. */
|
|
81
|
+
const PERCENT_INTERRUPT = '"^%"'
|
|
82
|
+
const BANG_INTERRUPT = '"^!"'
|
|
83
|
+
/** Characters cmd.exe treats as line terminators; nothing can escape them. */
|
|
84
|
+
const CMD_UNPASSABLE_CHARS = ['\0', '\r', '\n']
|
|
85
|
+
/** Anything here forces the full quoting algorithm; a miss stays byte-identical. */
|
|
86
|
+
const ARG_NEEDS_QUOTING = /[\s"%!^&|<>()]/
|
|
87
|
+
/** Same set minus the quote, which is rejected for program paths instead. */
|
|
88
|
+
const PROGRAM_NEEDS_QUOTING = /[\s%!^&|<>()]/
|
|
89
|
+
/** Targets cmd.exe starts directly, leaving the child's CRT to re-parse argv[0]. */
|
|
90
|
+
const NATIVE_PROGRAM_PATTERN = /\.(exe|com)$/i
|
|
91
|
+
|
|
92
|
+
function assertCmdPassable(value: string, role: string): void {
|
|
93
|
+
for (const char of CMD_UNPASSABLE_CHARS) {
|
|
94
|
+
if (value.includes(char)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`${role} contains characters that cannot be passed through cmd.exe: ${JSON.stringify(value)}`,
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Escape one argv element for a Windows shell:true spawn. Safe plain args
|
|
104
|
+
* (flags, bare paths) are returned unchanged.
|
|
105
|
+
*/
|
|
106
|
+
export function escapeCmdArg(arg: string): string {
|
|
107
|
+
assertCmdPassable(arg, 'argument')
|
|
108
|
+
if (arg !== '' && !ARG_NEEDS_QUOTING.test(arg)) return arg
|
|
109
|
+
|
|
110
|
+
let out = QUOTE
|
|
111
|
+
let backslashes = 0
|
|
112
|
+
for (const char of arg) {
|
|
113
|
+
if (char === BACKSLASH) {
|
|
114
|
+
backslashes += 1
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
if (char === QUOTE || char === '%' || char === '!') {
|
|
118
|
+
// Each of these emits a quote next, so the run preceding it doubles.
|
|
119
|
+
out += BACKSLASH.repeat(backslashes * 2)
|
|
120
|
+
out += char === QUOTE ? DOUBLED_QUOTE : char === '%' ? PERCENT_INTERRUPT : BANG_INTERRUPT
|
|
121
|
+
} else {
|
|
122
|
+
out += BACKSLASH.repeat(backslashes) + char
|
|
123
|
+
}
|
|
124
|
+
backslashes = 0
|
|
125
|
+
}
|
|
126
|
+
return out + BACKSLASH.repeat(backslashes * 2) + QUOTE
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Quote the program token of a Windows shell:true spawn. Plain names and
|
|
131
|
+
* paths are returned unchanged; quotes cannot appear in Windows paths and are
|
|
132
|
+
* rejected rather than escaped, because no escape exists in command position.
|
|
133
|
+
* The encoding follows the target type (see the file header): `%`/`!` are
|
|
134
|
+
* caret-interrupted for shims, whose token only cmd itself reads, and left
|
|
135
|
+
* inside plain quotes for native binaries, whose CRT re-parses argv[0].
|
|
136
|
+
*/
|
|
137
|
+
export function quoteCmdProgram(program: string): string {
|
|
138
|
+
assertCmdPassable(program, 'program')
|
|
139
|
+
if (program.includes(QUOTE)) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`program contains a quote and cannot be quoted as a cmd.exe program: ${JSON.stringify(program)}`,
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
if (program !== '' && !PROGRAM_NEEDS_QUOTING.test(program)) return program
|
|
145
|
+
if (NATIVE_PROGRAM_PATTERN.test(program)) return QUOTE + program + QUOTE
|
|
146
|
+
return (
|
|
147
|
+
QUOTE + program.replaceAll('%', PERCENT_INTERRUPT).replaceAll('!', BANG_INTERRUPT) + QUOTE
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Prepare a program + argv pair for spawn(). With `viaCmd` false (POSIX,
|
|
153
|
+
* shell:false) both pass through untouched, keeping non-Windows spawns
|
|
154
|
+
* byte-for-byte identical; with it true both are escaped to survive the
|
|
155
|
+
* cmd.exe traversal that shell:true implies.
|
|
156
|
+
*/
|
|
157
|
+
export function escapeCmdSpawn(
|
|
158
|
+
viaCmd: boolean,
|
|
159
|
+
file: string,
|
|
160
|
+
args: readonly string[],
|
|
161
|
+
): { file: string; args: string[] } {
|
|
162
|
+
if (!viaCmd) return { file, args: [...args] }
|
|
163
|
+
return { file: quoteCmdProgram(file), args: args.map(escapeCmdArg) }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const NPM_WINDOWS_SHIM = 'npm.cmd'
|
|
167
|
+
const NPM_POSIX_BINARY = 'npm'
|
|
168
|
+
const NPM_PREFIX_ARGS = ['prefix', '-g'] as const
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The `npm prefix -g` probe used to locate globally installed CLIs. Both
|
|
172
|
+
* callers spawn it with shell:true on Windows to reach npm's `.cmd` shim.
|
|
173
|
+
*
|
|
174
|
+
* Every token is a constant that needs no rewriting, so the escaped and raw
|
|
175
|
+
* forms are byte-identical and no behavioural test can distinguish a caller
|
|
176
|
+
* that uses this helper from one that inlines the strings. Centralising it is
|
|
177
|
+
* what keeps the guarantee: a caller that later needs a variable argument
|
|
178
|
+
* inherits the escaping instead of reinventing an unescaped spawn.
|
|
179
|
+
*/
|
|
180
|
+
export function buildNpmPrefixCommand(isWindows: boolean): { file: string; args: string[] } {
|
|
181
|
+
return escapeCmdSpawn(
|
|
182
|
+
isWindows,
|
|
183
|
+
isWindows ? NPM_WINDOWS_SHIM : NPM_POSIX_BINARY,
|
|
184
|
+
NPM_PREFIX_ARGS,
|
|
185
|
+
)
|
|
186
|
+
}
|