@pheem49/mint 1.8.1 → 1.9.0
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/Cargo.lock +3 -3
- package/Cargo.toml +1 -1
- package/README.md +0 -17
- package/Release_Note.md +137 -58
- package/bin/mint +0 -0
- package/crates/mint-cli/src/agent.rs +150 -45
- package/crates/mint-cli/src/image.rs +8 -8
- package/crates/mint-cli/src/main.rs +929 -412
- package/crates/mint-cli/src/onboard.rs +108 -108
- package/crates/mint-cli/src/setup.rs +143 -143
- package/crates/mint-core/src/agent_loop.rs +1 -0
- package/crates/mint-core/src/api_server.rs +108 -52
- package/crates/mint-core/src/browser.rs +56 -1
- package/crates/mint-core/src/channels.rs +1 -0
- package/crates/mint-core/src/chat.rs +126 -8
- package/crates/mint-core/src/code_tools.rs +18 -20
- package/crates/mint-core/src/config.rs +245 -17
- package/crates/mint-core/src/image_gen.rs +5 -5
- package/crates/mint-core/src/lib.rs +16 -2
- package/crates/mint-core/src/memory.rs +6 -1
- package/crates/mint-core/src/orchestration.rs +260 -72
- package/crates/mint-core/src/pictures.rs +3 -4
- package/crates/mint-core/src/semantic.rs +1 -1
- package/crates/mint-core/src/shell.rs +1 -1
- package/crates/mint-core/src/skills.rs +46 -19
- package/crates/mint-core/src/tts.rs +3 -1
- package/flatpak/com.pheem49.mint.desktop +9 -0
- package/flatpak/com.pheem49.mint.metainfo.xml +35 -0
- package/flatpak/com.pheem49.mint.yaml +52 -0
- package/package.json +1 -1
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/shared-modules/CODEOWNERS +23 -0
- package/shared-modules/README.md +79 -0
- package/shared-modules/SDL/README.md +3 -0
- package/shared-modules/SDL/SDL-1.2.15.json +51 -0
- package/shared-modules/SDL/SDL_Pango-0.1.2-API-adds.patch +118 -0
- package/shared-modules/SDL/SDL_image-1.2.12.json +25 -0
- package/shared-modules/SDL/SDL_mixer-1.2.12.json +27 -0
- package/shared-modules/SDL/SDL_net-1.2.8.json +19 -0
- package/shared-modules/SDL/SDL_pango-0.1.2.json +26 -0
- package/shared-modules/SDL/SDL_ttf-2.0.11.json +28 -0
- package/shared-modules/SDL/libsdl-1.2.15-strict-prototypes.patch +316 -0
- package/shared-modules/SDL/sdl-check-for-SDL_VIDEO_X11_BACKINGSTORE.patch +24 -0
- package/shared-modules/SDL/sdl-libx11-build.patch +59 -0
- package/shared-modules/SDL/sdl-sysloadso-buffer-length.patch +27 -0
- package/shared-modules/SDL/sdl12-compat.json +22 -0
- package/shared-modules/SDL2/SDL2_image.json +27 -0
- package/shared-modules/SDL2/SDL2_ttf.json +29 -0
- package/shared-modules/cld2/CMakeLists.txt +157 -0
- package/shared-modules/cld2/cld2.json +24 -0
- package/shared-modules/clutter/clutter.json +72 -0
- package/shared-modules/dbus-glib/dbus-glib.json +29 -0
- package/shared-modules/glew/glew.json +36 -0
- package/shared-modules/glu/glu-9.json +12 -0
- package/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch +180 -0
- package/shared-modules/gtk2/gtk2-common-themes.json +360 -0
- package/shared-modules/gtk2/gtk2-fix-crash-in-show-uri.patch +30 -0
- package/shared-modules/gtk2/gtk2-gcc14.patch +281 -0
- package/shared-modules/gtk2/gtk2-gcc15.patch +250 -0
- package/shared-modules/gtk2/gtk2-murrine-c99.patch +34 -0
- package/shared-modules/gtk2/gtk2-use-adwaita-theme.patch +80 -0
- package/shared-modules/gtk2/gtk2.json +120 -0
- package/shared-modules/gtk2/ibus-gcc15.patch +13 -0
- package/shared-modules/gtk2/murrine-engine-fix-crash.patch +12 -0
- package/shared-modules/gtk2/readme.md +10 -0
- package/shared-modules/intltool/intltool-0.51.json +20 -0
- package/shared-modules/intltool/intltool-perl5.26-regex-fixes.patch +59 -0
- package/shared-modules/lame/0001-Build-xmm_quantize_sub.c-with-msse.patch +34 -0
- package/shared-modules/lame/0002-Include-GTK-1-autoconf-directives-in-build-system.patch +222 -0
- package/shared-modules/lame/0003-Patch-out-remaining-ansi2knr.patch +70 -0
- package/shared-modules/lame/0004-initscr-is-not-used-anywhere-in-lame-sourcetree.patch +41 -0
- package/shared-modules/lame/0005-Update-autoconf.patch +81 -0
- package/shared-modules/lame/lame-3.99.5.json +32 -0
- package/shared-modules/libappindicator/libappindicator-gtk2-12.10.json +140 -0
- package/shared-modules/libappindicator/libappindicator-gtk3-12.10.json +140 -0
- package/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json +140 -0
- package/shared-modules/libappindicator/patches/0001-libappindicator-ftbfs.patch +20 -0
- package/shared-modules/libappindicator/patches/0002-libappindicator-no-python.patch +888 -0
- package/shared-modules/libappindicator/patches/0003-libappindicator-fix-crash-from-incorrect-signal-emission.patch +74 -0
- package/shared-modules/libappindicator/patches/0004-libappindicator-fix-crash-iterating-icon-themes.patch +11 -0
- package/shared-modules/libayatana-appindicator/0001-Fix-HAVE_VALGRIND-AM_CONDITIONAL.patch +51 -0
- package/shared-modules/libayatana-appindicator/0001-Make-introspection-configurable.patch +44 -0
- package/shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json +121 -0
- package/shared-modules/libcanberra/0001-gtk-Don-t-assume-all-GdkDisplays-are-GdkX11Displays-.patch +123 -0
- package/shared-modules/libcanberra/libcanberra.json +44 -0
- package/shared-modules/libmad/libmad.json +19 -0
- package/shared-modules/libsecret/libsecret.json +23 -0
- package/shared-modules/libsoup/libsoup-2.4.json +14 -0
- package/shared-modules/libusb/libusb.json +27 -0
- package/shared-modules/linux-audio/dssi.json +31 -0
- package/shared-modules/linux-audio/fftw3f-static.json +44 -0
- package/shared-modules/linux-audio/fftw3f.json +42 -0
- package/shared-modules/linux-audio/fluidsynth2-static.json +36 -0
- package/shared-modules/linux-audio/fluidsynth2.json +25 -0
- package/shared-modules/linux-audio/ladspa.json +26 -0
- package/shared-modules/linux-audio/lash.json +35 -0
- package/shared-modules/linux-audio/libinstpatch.json +16 -0
- package/shared-modules/linux-audio/liblo-static.json +22 -0
- package/shared-modules/linux-audio/liblo.json +17 -0
- package/shared-modules/linux-audio/lilv-static.json +94 -0
- package/shared-modules/linux-audio/lilv.json +89 -0
- package/shared-modules/linux-audio/lrdf.json +57 -0
- package/shared-modules/linux-audio/lv2.json +20 -0
- package/shared-modules/linux-audio/patches/lash/0001-configure-remove-aclocal-m4.patch +29 -0
- package/shared-modules/linux-audio/patches/lash/0002-Fix-build-with-recent-gcc.patch +73 -0
- package/shared-modules/linux-audio/patches/lash/0003-Fix-linking.patch +136 -0
- package/shared-modules/linux-audio/patches/raptor-libxml.patch +31 -0
- package/shared-modules/linux-audio/patches/stk-install.sh +54 -0
- package/shared-modules/linux-audio/stk.json +28 -0
- package/shared-modules/lua5.1/0004-Fix-stack-overflow-in-vararg-functions.patch +21 -0
- package/shared-modules/lua5.1/lua-5.1.5-so.patch +43 -0
- package/shared-modules/lua5.1/lua-5.1.5.json +42 -0
- package/shared-modules/lua5.3/lua-5.3.5.json +41 -0
- package/shared-modules/lua5.3/lua.pc.in +8 -0
- package/shared-modules/lua5.3/luaconf.patch +47 -0
- package/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch +47 -0
- package/shared-modules/lua5.4/lua-5.4.json +41 -0
- package/shared-modules/lua5.4/lua.pc.in +8 -0
- package/shared-modules/lua5.4/luaconf.patch +34 -0
- package/shared-modules/lua5.4/makefile-add-liblua.so-rule.patch +42 -0
- package/shared-modules/luajit/luajit.json +30 -0
- package/shared-modules/lzo/lzo.json +27 -0
- package/shared-modules/mac/mac.json +18 -0
- package/shared-modules/physfs/physfs.json +26 -0
- package/shared-modules/pygame/audiofile-gcc6.patch +21 -0
- package/shared-modules/pygame/cython-fixes.patch +34 -0
- package/shared-modules/pygame/fluidsynth-no-rawmidi.patch +69 -0
- package/shared-modules/pygame/glib.patch +25 -0
- package/shared-modules/pygame/pygame1-python2.json +157 -0
- package/shared-modules/pygtk/pygtk-c99.patch +15 -0
- package/shared-modules/pygtk/pygtk.json +117 -0
- package/shared-modules/pygtk/pygtk.patch +39 -0
- package/shared-modules/python2.7/python-2.7.json +48 -0
- package/shared-modules/smpeg/smpeg-0.4.5.json +50 -0
- package/shared-modules/smpeg/smpeg-am-prog-as.patch +12 -0
- package/shared-modules/smpeg/smpeg-export-mpegaudio-class.patch +17 -0
- package/shared-modules/smpeg/smpeg-gcc6.patch +40 -0
- package/shared-modules/smpeg/smpeg-no-gtk.patch +37 -0
- package/shared-modules/squashfs-tools/squashfs-tools.json +25 -0
- package/shared-modules/update-checker.sh +50 -0
- package/shared-modules/vorbisgain/0001-temp_files.patch +75 -0
- package/shared-modules/vorbisgain/0002-errno.patch +33 -0
- package/shared-modules/vorbisgain/0003-manpage.patch +248 -0
- package/shared-modules/vorbisgain/0004-vorbisgain_mtime.patch +183 -0
- package/shared-modules/vorbisgain/0005-double_fclose.patch +21 -0
- package/shared-modules/vorbisgain/0006-manpage_hyphens.patch +56 -0
- package/shared-modules/vorbisgain/0007-recursively_spelling.patch +14 -0
- package/shared-modules/vorbisgain/0008-manpage_recursion_mistake.patch +23 -0
- package/shared-modules/vorbisgain/0009-hardening.patch +13 -0
- package/shared-modules/vorbisgain/0010-fclose.patch +13 -0
- package/shared-modules/vorbisgain/README.md +23 -0
- package/shared-modules/vorbisgain/vorbisgain_0.37-2.json +29 -0
- package/src/renderer/shared/agentProgress.ts +145 -0
- package/src/renderer/shared/calculator.ts +52 -0
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +72 -0
- package/src/renderer/shared/components/AgentActivityTable.tsx +85 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +93 -0
- package/src/renderer/shared/components/ChatCodeBlock.tsx +75 -0
- package/src/renderer/shared/components/ThinkingBlock.tsx +101 -0
- package/src/renderer/shared/constants/models.ts +91 -0
- package/src/renderer/shared/platform.ts +82 -0
- package/src/renderer/shared/types.ts +140 -0
- package/src/renderer/shared/utils/agentActivity.ts +187 -0
- package/src/renderer/shared/utils/approval.ts +1 -0
- package/src/renderer/shared/utils/approval.tsx +64 -0
- package/src/renderer/shared/utils/fileIcons.ts +135 -0
- package/src/renderer/shared/utils/markdown.tsx +347 -0
- package/src/renderer/shared/utils/providers.ts +36 -0
- package/src/renderer/shared/utils/speech.ts +216 -0
- package/src/renderer/shared/utils/ui.ts +147 -0
- package/src/renderer/src/agentProgress.ts +11 -39
- package/src/renderer/src/calculator.ts +3 -46
- package/src/renderer/src/components/ChatPanel.tsx +219 -1308
- package/src/renderer/src/components/MintDashboard.tsx +67 -170
- package/src/renderer/src/components/PicturesLibrary.tsx +32 -8
- package/src/renderer/src/components/Settings/AgentsTab.tsx +381 -0
- package/src/renderer/src/components/Settings/AutomationTab.tsx +0 -22
- package/src/renderer/src/components/Settings/GeneralTab.tsx +256 -2
- package/src/renderer/src/components/SettingsWindow.tsx +120 -3
- package/src/renderer/src/components/WorkspacePanel.tsx +7 -125
- package/src/renderer/src/css/styles.css +100 -0
- package/src/renderer/src/tauri.ts +128 -143
- package/src/renderer/src-web/agentProgress.ts +11 -39
- package/src/renderer/src-web/calculator.ts +3 -46
- package/src/renderer/src-web/components/ChatPanel.tsx +219 -1306
- package/src/renderer/src-web/components/MintDashboard.tsx +42 -170
- package/src/renderer/src-web/components/PicturesLibrary.tsx +23 -29
- package/src/renderer/src-web/components/Settings/AgentsTab.tsx +381 -0
- package/src/renderer/src-web/components/Settings/AutomationTab.tsx +0 -22
- package/src/renderer/src-web/components/Settings/GeneralTab.tsx +254 -3
- package/src/renderer/src-web/components/SettingsWindow.tsx +127 -3
- package/src/renderer/src-web/css/styles.css +100 -0
- package/src/renderer/src-web/tauri.ts +180 -102
- package/src-tauri/src/desktop.rs +18 -16
- package/src-tauri/src/discord_rpc.rs +1 -1
- package/src-tauri/src/lib.rs +168 -40
- package/src-tauri/src/webhooks.rs +1 -0
- package/src-tauri/src/workflows.rs +1 -0
- package/src-tauri/tauri.conf.json +1 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shared/utils/fileIcons.ts
|
|
3
|
+
* Utility mapping and resolution functions for Material Icon Theme icons.
|
|
4
|
+
* Extracted from WorkspacePanel to be shared across multiple components (e.g. AgentActivityTable).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import folderIcon from 'material-icon-theme/icons/folder.svg?url'
|
|
8
|
+
import folderOpenIcon from 'material-icon-theme/icons/folder-open.svg?url'
|
|
9
|
+
import folderComponentsIcon from 'material-icon-theme/icons/folder-components.svg?url'
|
|
10
|
+
import folderComponentsOpenIcon from 'material-icon-theme/icons/folder-components-open.svg?url'
|
|
11
|
+
import folderConfigIcon from 'material-icon-theme/icons/folder-config.svg?url'
|
|
12
|
+
import folderConfigOpenIcon from 'material-icon-theme/icons/folder-config-open.svg?url'
|
|
13
|
+
import folderDistIcon from 'material-icon-theme/icons/folder-dist.svg?url'
|
|
14
|
+
import folderDistOpenIcon from 'material-icon-theme/icons/folder-dist-open.svg?url'
|
|
15
|
+
import folderDocsIcon from 'material-icon-theme/icons/folder-docs.svg?url'
|
|
16
|
+
import folderDocsOpenIcon from 'material-icon-theme/icons/folder-docs-open.svg?url'
|
|
17
|
+
import folderGitIcon from 'material-icon-theme/icons/folder-git.svg?url'
|
|
18
|
+
import folderGitOpenIcon from 'material-icon-theme/icons/folder-git-open.svg?url'
|
|
19
|
+
import folderGithubIcon from 'material-icon-theme/icons/folder-github.svg?url'
|
|
20
|
+
import folderGithubOpenIcon from 'material-icon-theme/icons/folder-github-open.svg?url'
|
|
21
|
+
import folderImagesIcon from 'material-icon-theme/icons/folder-images.svg?url'
|
|
22
|
+
import folderImagesOpenIcon from 'material-icon-theme/icons/folder-images-open.svg?url'
|
|
23
|
+
import folderLogIcon from 'material-icon-theme/icons/folder-log.svg?url'
|
|
24
|
+
import folderLogOpenIcon from 'material-icon-theme/icons/folder-log-open.svg?url'
|
|
25
|
+
import folderNodeIcon from 'material-icon-theme/icons/folder-node.svg?url'
|
|
26
|
+
import folderNodeOpenIcon from 'material-icon-theme/icons/folder-node-open.svg?url'
|
|
27
|
+
import folderPublicIcon from 'material-icon-theme/icons/folder-public.svg?url'
|
|
28
|
+
import folderPublicOpenIcon from 'material-icon-theme/icons/folder-public-open.svg?url'
|
|
29
|
+
import folderRustIcon from 'material-icon-theme/icons/folder-rust.svg?url'
|
|
30
|
+
import folderRustOpenIcon from 'material-icon-theme/icons/folder-rust-open.svg?url'
|
|
31
|
+
import folderScriptsIcon from 'material-icon-theme/icons/folder-scripts.svg?url'
|
|
32
|
+
import folderScriptsOpenIcon from 'material-icon-theme/icons/folder-scripts-open.svg?url'
|
|
33
|
+
import folderSrcIcon from 'material-icon-theme/icons/folder-src.svg?url'
|
|
34
|
+
import folderSrcOpenIcon from 'material-icon-theme/icons/folder-src-open.svg?url'
|
|
35
|
+
import folderSrcTauriIcon from 'material-icon-theme/icons/folder-src-tauri.svg?url'
|
|
36
|
+
import folderSrcTauriOpenIcon from 'material-icon-theme/icons/folder-src-tauri-open.svg?url'
|
|
37
|
+
import folderTestIcon from 'material-icon-theme/icons/folder-test.svg?url'
|
|
38
|
+
import folderTestOpenIcon from 'material-icon-theme/icons/folder-test-open.svg?url'
|
|
39
|
+
import folderUiIcon from 'material-icon-theme/icons/folder-ui.svg?url'
|
|
40
|
+
import folderUiOpenIcon from 'material-icon-theme/icons/folder-ui-open.svg?url'
|
|
41
|
+
import folderUtilsIcon from 'material-icon-theme/icons/folder-utils.svg?url'
|
|
42
|
+
import folderUtilsOpenIcon from 'material-icon-theme/icons/folder-utils-open.svg?url'
|
|
43
|
+
import cssIcon from 'material-icon-theme/icons/css.svg?url'
|
|
44
|
+
import documentIcon from 'material-icon-theme/icons/document.svg?url'
|
|
45
|
+
import htmlIcon from 'material-icon-theme/icons/html.svg?url'
|
|
46
|
+
import imageIcon from 'material-icon-theme/icons/image.svg?url'
|
|
47
|
+
import javascriptIcon from 'material-icon-theme/icons/javascript.svg?url'
|
|
48
|
+
import jsonIcon from 'material-icon-theme/icons/json.svg?url'
|
|
49
|
+
import lockIcon from 'material-icon-theme/icons/lock.svg?url'
|
|
50
|
+
import logIcon from 'material-icon-theme/icons/log.svg?url'
|
|
51
|
+
import markdownIcon from 'material-icon-theme/icons/markdown.svg?url'
|
|
52
|
+
import npmIcon from 'material-icon-theme/icons/npm.svg?url'
|
|
53
|
+
import reactIcon from 'material-icon-theme/icons/react.svg?url'
|
|
54
|
+
import reactTsIcon from 'material-icon-theme/icons/react_ts.svg?url'
|
|
55
|
+
import rustIcon from 'material-icon-theme/icons/rust.svg?url'
|
|
56
|
+
import settingsIcon from 'material-icon-theme/icons/settings.svg?url'
|
|
57
|
+
import tauriIcon from 'material-icon-theme/icons/tauri.svg?url'
|
|
58
|
+
import tomlIcon from 'material-icon-theme/icons/toml.svg?url'
|
|
59
|
+
import typescriptIcon from 'material-icon-theme/icons/typescript.svg?url'
|
|
60
|
+
import viteIcon from 'material-icon-theme/icons/vite.svg?url'
|
|
61
|
+
import yamlIcon from 'material-icon-theme/icons/yaml.svg?url'
|
|
62
|
+
|
|
63
|
+
export const FOLDER_ICONS: Record<string, { closed: string; open: string }> = {
|
|
64
|
+
'.cargo_home': { closed: folderRustIcon, open: folderRustOpenIcon },
|
|
65
|
+
'.github': { closed: folderGithubIcon, open: folderGithubOpenIcon },
|
|
66
|
+
'.git': { closed: folderGitIcon, open: folderGitOpenIcon },
|
|
67
|
+
'.rustup': { closed: folderRustIcon, open: folderRustOpenIcon },
|
|
68
|
+
'.rustup_copy': { closed: folderRustIcon, open: folderRustOpenIcon },
|
|
69
|
+
'.rustup_home': { closed: folderRustIcon, open: folderRustOpenIcon },
|
|
70
|
+
assets: { closed: folderImagesIcon, open: folderImagesOpenIcon },
|
|
71
|
+
components: { closed: folderComponentsIcon, open: folderComponentsOpenIcon },
|
|
72
|
+
crates: { closed: folderRustIcon, open: folderRustOpenIcon },
|
|
73
|
+
css: { closed: folderUiIcon, open: folderUiOpenIcon },
|
|
74
|
+
dist: { closed: folderDistIcon, open: folderDistOpenIcon },
|
|
75
|
+
docs: { closed: folderDocsIcon, open: folderDocsOpenIcon },
|
|
76
|
+
logs: { closed: folderLogIcon, open: folderLogOpenIcon },
|
|
77
|
+
node_modules: { closed: folderNodeIcon, open: folderNodeOpenIcon },
|
|
78
|
+
out: { closed: folderDistIcon, open: folderDistOpenIcon },
|
|
79
|
+
public: { closed: folderPublicIcon, open: folderPublicOpenIcon },
|
|
80
|
+
renderer: { closed: folderUiIcon, open: folderUiOpenIcon },
|
|
81
|
+
scripts: { closed: folderScriptsIcon, open: folderScriptsOpenIcon },
|
|
82
|
+
src: { closed: folderSrcIcon, open: folderSrcOpenIcon },
|
|
83
|
+
'src-tauri': { closed: folderSrcTauriIcon, open: folderSrcTauriOpenIcon },
|
|
84
|
+
tests: { closed: folderTestIcon, open: folderTestOpenIcon },
|
|
85
|
+
utils: { closed: folderUtilsIcon, open: folderUtilsOpenIcon },
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const FILE_ICONS_BY_EXTENSION: Record<string, string> = {
|
|
89
|
+
css: cssIcon,
|
|
90
|
+
html: htmlIcon,
|
|
91
|
+
jpeg: imageIcon,
|
|
92
|
+
jpg: imageIcon,
|
|
93
|
+
js: javascriptIcon,
|
|
94
|
+
json: jsonIcon,
|
|
95
|
+
lock: lockIcon,
|
|
96
|
+
log: logIcon,
|
|
97
|
+
md: markdownIcon,
|
|
98
|
+
png: imageIcon,
|
|
99
|
+
rs: rustIcon,
|
|
100
|
+
svg: imageIcon,
|
|
101
|
+
toml: tomlIcon,
|
|
102
|
+
ts: typescriptIcon,
|
|
103
|
+
tsx: reactTsIcon,
|
|
104
|
+
yaml: yamlIcon,
|
|
105
|
+
yml: yamlIcon,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const FILE_ICONS_BY_NAME: Record<string, string> = {
|
|
109
|
+
'package-lock.json': npmIcon,
|
|
110
|
+
'package.json': npmIcon,
|
|
111
|
+
'tauri.conf.json': tauriIcon,
|
|
112
|
+
'vite.config.ts': viteIcon,
|
|
113
|
+
'vite.config.web.ts': viteIcon,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getExtension(name: string): string {
|
|
117
|
+
const index = name.lastIndexOf('.')
|
|
118
|
+
return index === -1 ? '' : name.slice(index + 1).toLowerCase()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function materialFolderIcon(name: string, open: boolean): string {
|
|
122
|
+
const icon = FOLDER_ICONS[name] || FOLDER_ICONS[name.toLowerCase()]
|
|
123
|
+
if (!icon) return open ? folderOpenIcon : folderIcon
|
|
124
|
+
return open ? icon.open : icon.closed
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function materialFileIcon(name: string, fileExtension: string): string {
|
|
128
|
+
if (name.endsWith('.config.ts') || name.endsWith('.config.js')) return settingsIcon
|
|
129
|
+
if (name.endsWith('.tsx')) return reactTsIcon
|
|
130
|
+
if (name.endsWith('.jsx')) return reactIcon
|
|
131
|
+
return FILE_ICONS_BY_NAME[name.toLowerCase()] || FILE_ICONS_BY_EXTENSION[fileExtension] || documentIcon
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { folderIcon, folderOpenIcon }
|
|
135
|
+
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shared/utils/markdown.tsx
|
|
3
|
+
* Custom markdown parsing and rendering engine for message bubbles.
|
|
4
|
+
* Shared by both Desktop and Web ChatPanel — do NOT duplicate this.
|
|
5
|
+
*/
|
|
6
|
+
import { Fragment, type ReactNode } from 'react'
|
|
7
|
+
import { ChatCodeBlock } from '../components/ChatCodeBlock'
|
|
8
|
+
|
|
9
|
+
export const isTableLine = (line: string): boolean => {
|
|
10
|
+
const trimmed = line.trim()
|
|
11
|
+
return trimmed.startsWith('|') && trimmed.endsWith('|') && trimmed.length > 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function readableAssistantText(text: string): string {
|
|
15
|
+
if (typeof text !== 'string') return ''
|
|
16
|
+
const trimmed = text.trim()
|
|
17
|
+
if (!trimmed.startsWith('{')) return sanitizeLatex(text)
|
|
18
|
+
try {
|
|
19
|
+
const value = JSON.parse(trimmed)
|
|
20
|
+
if (value?.action === 'finish' && typeof value?.input?.summary === 'string' && value.input.summary.trim()) {
|
|
21
|
+
return sanitizeLatex(value.input.summary)
|
|
22
|
+
}
|
|
23
|
+
if (typeof value?.finish?.summary === 'string' && value.finish.summary.trim()) {
|
|
24
|
+
return sanitizeLatex(value.finish.summary)
|
|
25
|
+
}
|
|
26
|
+
} catch {
|
|
27
|
+
return sanitizeLatex(text)
|
|
28
|
+
}
|
|
29
|
+
return sanitizeLatex(text)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Replace common LaTeX math symbols with their Unicode equivalents */
|
|
33
|
+
function sanitizeLatex(text: string): string {
|
|
34
|
+
return text
|
|
35
|
+
// arrows
|
|
36
|
+
.replace(/\$\\rightarrow\$|\\\(\\rightarrow\\\)/g, '→')
|
|
37
|
+
.replace(/\$\\leftarrow\$|\\\(\\leftarrow\\\)/g, '←')
|
|
38
|
+
.replace(/\$\\Rightarrow\$|\\\(\\Rightarrow\\\)/g, '⇒')
|
|
39
|
+
.replace(/\$\\Leftarrow\$|\\\(\\Leftarrow\\\)/g, '⇐')
|
|
40
|
+
.replace(/\$\\leftrightarrow\$|\\\(\\leftrightarrow\\\)/g, '↔')
|
|
41
|
+
// comparison
|
|
42
|
+
.replace(/\$\\leq\$|\\\(\\leq\\\)/g, '≤')
|
|
43
|
+
.replace(/\$\\geq\$|\\\(\\geq\\\)/g, '≥')
|
|
44
|
+
.replace(/\$\\neq\$|\\\(\\neq\\\)/g, '≠')
|
|
45
|
+
.replace(/\$\\approx\$|\\\(\\approx\\\)/g, '≈')
|
|
46
|
+
// math
|
|
47
|
+
.replace(/\$\\times\$|\\\(\\times\\\)/g, '×')
|
|
48
|
+
.replace(/\$\\div\$|\\\(\\div\\\)/g, '÷')
|
|
49
|
+
.replace(/\$\\pm\$|\\\(\\pm\\\)/g, '±')
|
|
50
|
+
.replace(/\$\\infty\$|\\\(\\infty\\\)/g, '∞')
|
|
51
|
+
// other common symbols
|
|
52
|
+
.replace(/\$\\cdot\$|\\\(\\cdot\\\)/g, '·')
|
|
53
|
+
.replace(/\$\\in\$|\\\(\\in\\\)/g, '∈')
|
|
54
|
+
.replace(/\$\\subset\$|\\\(\\subset\\\)/g, '⊂')
|
|
55
|
+
.replace(/\$\\cup\$|\\\(\\cup\\\)/g, '∪')
|
|
56
|
+
.replace(/\$\\cap\$|\\\(\\cap\\\)/g, '∩')
|
|
57
|
+
// strip remaining inline math delimiters $...$ and \(...\) that weren't matched
|
|
58
|
+
.replace(/\$([^$\n]{1,60})\$/g, '$1')
|
|
59
|
+
.replace(/\\\(([^)]{1,60})\\\)/g, '$1')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
export function cleanSpeechText(text: string): string {
|
|
65
|
+
return readableAssistantText(text)
|
|
66
|
+
.replace(/\*\*([\s\S]*?)\*\*/g, '$1')
|
|
67
|
+
.replace(/[*_`#]/g, '')
|
|
68
|
+
.trim()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function renderSpeakerIcon(isSpeaking: boolean): ReactNode {
|
|
72
|
+
if (isSpeaking) {
|
|
73
|
+
return (
|
|
74
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
|
|
75
|
+
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
|
|
76
|
+
<path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
|
|
77
|
+
<path d="M19.07 4.93a10 10 0 0 1 0 14.14" />
|
|
78
|
+
</svg>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
return (
|
|
82
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block' }}>
|
|
83
|
+
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
|
|
84
|
+
</svg>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function renderFormattedMessage(text: string): ReactNode {
|
|
89
|
+
const displayText = readableAssistantText(text)
|
|
90
|
+
if (!displayText) return null
|
|
91
|
+
|
|
92
|
+
const formatInline = (str: string) => {
|
|
93
|
+
const codeParts = str.split(/`([\s\S]*?)`/g)
|
|
94
|
+
return codeParts.map((codePart, codeIndex) => {
|
|
95
|
+
if (codeIndex % 2 === 1) {
|
|
96
|
+
return (
|
|
97
|
+
<code key={`code-${codeIndex}`} className="chat-inline-code">
|
|
98
|
+
{codePart}
|
|
99
|
+
</code>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
const boldParts = codePart.split(/\*\*([\s\S]*?)\*\*/g)
|
|
103
|
+
return boldParts.map((boldPart, boldIndex) => {
|
|
104
|
+
if (boldIndex % 2 === 1) {
|
|
105
|
+
return (
|
|
106
|
+
<strong key={`bold-${boldIndex}`} className="chat-bold-highlight">
|
|
107
|
+
{boldPart}
|
|
108
|
+
</strong>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
const mentionParts = boldPart.split(/(@[\w\-\.\/]+)/g)
|
|
112
|
+
return mentionParts.map((mentionPart, mentionIndex) => {
|
|
113
|
+
if (mentionIndex % 2 === 1) {
|
|
114
|
+
return (
|
|
115
|
+
<span key={`mention-${mentionIndex}`} className="chat-mention">
|
|
116
|
+
{mentionPart}
|
|
117
|
+
</span>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
return mentionPart
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const renderHtmlTable = (tableLines: string[], key: string) => {
|
|
127
|
+
const rows: string[][] = []
|
|
128
|
+
for (const line of tableLines) {
|
|
129
|
+
const trimmed = line.trim()
|
|
130
|
+
if (!trimmed) continue
|
|
131
|
+
const content = trimmed.slice(1, -1)
|
|
132
|
+
const contentEscaped = content.replace(/\\\|/g, '\u0000')
|
|
133
|
+
const cols = contentEscaped.split('|').map(s => s.replace(/\u0000/g, '|').trim())
|
|
134
|
+
rows.push(cols)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (rows.length === 0) return null
|
|
138
|
+
|
|
139
|
+
let hasSeparator = false
|
|
140
|
+
let separatorIdx = -1
|
|
141
|
+
for (let i = 0; i < rows.length; i++) {
|
|
142
|
+
const row = rows[i]
|
|
143
|
+
if (row.length > 0 && row.every(col => /^[-\s:]+$/.test(col))) {
|
|
144
|
+
hasSeparator = true
|
|
145
|
+
separatorIdx = i
|
|
146
|
+
break
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let headerRow: string[] | null = null
|
|
151
|
+
const dataRows: string[][] = []
|
|
152
|
+
|
|
153
|
+
if (hasSeparator) {
|
|
154
|
+
if (separatorIdx > 0) {
|
|
155
|
+
headerRow = rows[separatorIdx - 1]
|
|
156
|
+
for (let i = 0; i < rows.length; i++) {
|
|
157
|
+
if (i !== separatorIdx && i !== separatorIdx - 1) {
|
|
158
|
+
dataRows.push(rows[i])
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
for (let i = 0; i < rows.length; i++) {
|
|
163
|
+
if (i !== separatorIdx) {
|
|
164
|
+
dataRows.push(rows[i])
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
headerRow = rows[0]
|
|
170
|
+
for (let i = 1; i < rows.length; i++) {
|
|
171
|
+
dataRows.push(rows[i])
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<div key={key} className="chat-table-container" style={{
|
|
177
|
+
overflowX: 'auto',
|
|
178
|
+
margin: '14px 0',
|
|
179
|
+
width: '100%',
|
|
180
|
+
borderRadius: '8px',
|
|
181
|
+
border: '1px solid rgba(255, 255, 255, 0.12)',
|
|
182
|
+
background: 'rgba(30, 41, 59, 0.35)',
|
|
183
|
+
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
184
|
+
}}>
|
|
185
|
+
<table className="chat-table" style={{
|
|
186
|
+
width: '100%',
|
|
187
|
+
borderCollapse: 'collapse',
|
|
188
|
+
fontSize: '0.86rem',
|
|
189
|
+
textAlign: 'left',
|
|
190
|
+
lineHeight: '1.5',
|
|
191
|
+
}}>
|
|
192
|
+
{headerRow && (
|
|
193
|
+
<thead>
|
|
194
|
+
<tr style={{
|
|
195
|
+
background: 'rgba(255, 255, 255, 0.04)',
|
|
196
|
+
borderBottom: '2px solid rgba(255, 255, 255, 0.15)',
|
|
197
|
+
}}>
|
|
198
|
+
{headerRow.map((col, idx) => (
|
|
199
|
+
<th key={`th-${idx}`} style={{
|
|
200
|
+
padding: '12px 16px',
|
|
201
|
+
fontWeight: 700,
|
|
202
|
+
color: 'var(--accent, #38bdf8)',
|
|
203
|
+
fontFamily: 'ui-sans-serif, system-ui, sans-serif',
|
|
204
|
+
}}>
|
|
205
|
+
{formatInline(col)}
|
|
206
|
+
</th>
|
|
207
|
+
))}
|
|
208
|
+
</tr>
|
|
209
|
+
</thead>
|
|
210
|
+
)}
|
|
211
|
+
<tbody>
|
|
212
|
+
{dataRows.map((row, rIdx) => (
|
|
213
|
+
<tr key={`tr-${rIdx}`} style={{
|
|
214
|
+
background: rIdx % 2 === 1 ? 'rgba(255, 255, 255, 0.015)' : 'transparent',
|
|
215
|
+
borderBottom: rIdx < dataRows.length - 1 ? '1px solid rgba(255, 255, 255, 0.08)' : 'none',
|
|
216
|
+
}}>
|
|
217
|
+
{row.map((col, cIdx) => (
|
|
218
|
+
<td key={`td-${cIdx}`} style={{
|
|
219
|
+
padding: '12px 16px',
|
|
220
|
+
color: 'var(--text-main, #e2e8f0)',
|
|
221
|
+
}}>
|
|
222
|
+
{formatInline(col)}
|
|
223
|
+
</td>
|
|
224
|
+
))}
|
|
225
|
+
</tr>
|
|
226
|
+
))}
|
|
227
|
+
</tbody>
|
|
228
|
+
</table>
|
|
229
|
+
</div>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const lines = displayText.split('\n')
|
|
234
|
+
const items: ReactNode[] = []
|
|
235
|
+
|
|
236
|
+
let inCodeBlock = false
|
|
237
|
+
let codeBlockLang = ''
|
|
238
|
+
let codeBlockLines: string[] = []
|
|
239
|
+
|
|
240
|
+
let inTable = false
|
|
241
|
+
let tableLines: string[] = []
|
|
242
|
+
|
|
243
|
+
const flushTable = (index: number) => {
|
|
244
|
+
if (tableLines.length > 0) {
|
|
245
|
+
items.push(renderHtmlTable(tableLines, `table-${index}`))
|
|
246
|
+
tableLines = []
|
|
247
|
+
inTable = false
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
for (let i = 0; i < lines.length; i++) {
|
|
252
|
+
const line = lines[i]
|
|
253
|
+
|
|
254
|
+
if (line.trim().startsWith('```')) {
|
|
255
|
+
if (inTable) {
|
|
256
|
+
flushTable(i)
|
|
257
|
+
}
|
|
258
|
+
if (inCodeBlock) {
|
|
259
|
+
const codeText = codeBlockLines.join('\n')
|
|
260
|
+
items.push(
|
|
261
|
+
<ChatCodeBlock
|
|
262
|
+
key={`code-block-${i}`}
|
|
263
|
+
code={codeText}
|
|
264
|
+
language={codeBlockLang}
|
|
265
|
+
/>
|
|
266
|
+
)
|
|
267
|
+
inCodeBlock = false
|
|
268
|
+
codeBlockLines = []
|
|
269
|
+
} else {
|
|
270
|
+
inCodeBlock = true
|
|
271
|
+
codeBlockLang = line.trim().slice(3).trim() || 'plaintext'
|
|
272
|
+
}
|
|
273
|
+
continue
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (inCodeBlock) {
|
|
277
|
+
codeBlockLines.push(line)
|
|
278
|
+
continue
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (isTableLine(line)) {
|
|
282
|
+
inTable = true
|
|
283
|
+
tableLines.push(line)
|
|
284
|
+
} else {
|
|
285
|
+
if (inTable) {
|
|
286
|
+
flushTable(i)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const headerMatch = line.match(/^(#{1,6})\s+(.*)$/)
|
|
290
|
+
if (headerMatch) {
|
|
291
|
+
const level = headerMatch[1].length
|
|
292
|
+
const content = headerMatch[2]
|
|
293
|
+
|
|
294
|
+
const style = {
|
|
295
|
+
fontWeight: 'bold',
|
|
296
|
+
display: 'block',
|
|
297
|
+
marginTop: level === 1 ? '16px' : level === 2 ? '14px' : '10px',
|
|
298
|
+
marginBottom: '6px',
|
|
299
|
+
fontSize: level === 1 ? '1.25em' : level === 2 ? '1.15em' : '1.05em',
|
|
300
|
+
color: 'var(--text-main)',
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
items.push(
|
|
304
|
+
<span key={`line-${i}`} style={style}>
|
|
305
|
+
{formatInline(content)}
|
|
306
|
+
</span>
|
|
307
|
+
)
|
|
308
|
+
} else {
|
|
309
|
+
const listMatch = line.match(/^(\s*)([-*+])\s+(.*)$/)
|
|
310
|
+
if (listMatch) {
|
|
311
|
+
const indent = listMatch[1]
|
|
312
|
+
const content = listMatch[3]
|
|
313
|
+
items.push(
|
|
314
|
+
<Fragment key={`line-${i}`}>
|
|
315
|
+
{indent}• {formatInline(content)}
|
|
316
|
+
{i < lines.length - 1 && '\n'}
|
|
317
|
+
</Fragment>
|
|
318
|
+
)
|
|
319
|
+
} else {
|
|
320
|
+
items.push(
|
|
321
|
+
<Fragment key={`line-${i}`}>
|
|
322
|
+
{formatInline(line)}
|
|
323
|
+
{i < lines.length - 1 && '\n'}
|
|
324
|
+
</Fragment>
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (inTable) {
|
|
332
|
+
flushTable(lines.length)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (inCodeBlock && codeBlockLines.length > 0) {
|
|
336
|
+
const codeText = codeBlockLines.join('\n')
|
|
337
|
+
items.push(
|
|
338
|
+
<ChatCodeBlock
|
|
339
|
+
key={`code-block-end`}
|
|
340
|
+
code={codeText}
|
|
341
|
+
language={codeBlockLang}
|
|
342
|
+
/>
|
|
343
|
+
)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return <>{items}</>
|
|
347
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shared/utils/providers.ts
|
|
3
|
+
* Provider label helpers — shared by both Desktop and Web ChatPanel.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Minimal shape needed — matches the full ChatResponse in both tauri.ts files. */
|
|
7
|
+
interface ProviderResponse {
|
|
8
|
+
provider: string
|
|
9
|
+
fallbackProvider?: string | null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function badge(provider: string, model: string): string {
|
|
13
|
+
return [provider, model].filter(Boolean).join(' / ')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function providerLabel(provider: string): string {
|
|
17
|
+
switch (provider) {
|
|
18
|
+
case 'gemini': return 'Gemini'
|
|
19
|
+
case 'openai': return 'OpenAI'
|
|
20
|
+
case 'openrouter': return 'OpenRouter'
|
|
21
|
+
case 'deepseek': return 'DeepSeek'
|
|
22
|
+
case 'anthropic': return 'Claude'
|
|
23
|
+
case 'huggingface': return 'Hugging Face'
|
|
24
|
+
case 'local_openai': return 'Local OpenAI'
|
|
25
|
+
case 'ollama': return 'Ollama'
|
|
26
|
+
default: return provider || 'Primary provider'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function fallbackNotice(
|
|
31
|
+
response: ProviderResponse | null | undefined,
|
|
32
|
+
): string {
|
|
33
|
+
if (!response?.fallbackProvider) return ''
|
|
34
|
+
return `${providerLabel(response.fallbackProvider)} unavailable, fell back to ${providerLabel(response.provider)}.`
|
|
35
|
+
}
|
|
36
|
+
|