Three Windows install/launch issues reported by the user:
1. Double-click on Desktop shortcut → dialog "This is a command line
tool. You need to open cmd.exe and run it from there."
Cause: charmbracelet/huh detects no TTY when launched via Explorer
and aborts. Fix:
- cmd/muyue/commands/root.go: skip RunFirstTimeSetup when
os.Stdin is not a character device; persist config.Default()
and let the React onboarding wizard handle first-run UX.
- ci-{main,develop}.yml: build Windows binaries with
-ldflags="-H=windowsgui" so the .exe is a GUI subsystem app —
no console window flashes on double-click.
2. CLI sub-commands (`muyue scan`, `muyue install-shortcuts`, etc.)
would lose all output under -H=windowsgui when launched from
cmd.exe / PowerShell. Mitigation:
- cmd/muyue/console_windows.go (new, build-tagged): on init(),
call kernel32!AttachConsole(ATTACH_PARENT_PROCESS). If the
parent has a console, rebind os.Stdout/os.Stderr/os.Stdin to
it and call log.SetOutput(os.Stderr) so existing log.Printf
calls surface. If no parent console (Explorer), exit silently.
3. After install, `muyue` not recognized in PowerShell.
Causes: (a) the extracted binary is muyue-windows-amd64.exe, not
muyue.exe; (b) the user PATH update by install-shortcuts doesn't
propagate to the existing PowerShell session.
Fix in install-shortcuts:
- Copy self to <installDir>/muyue.exe (rename impossible — the
running .exe is locked on Windows) so `muyue` resolves once
PATH is set.
- Update Desktop + Start Menu .lnk to target the canonical
muyue.exe rather than the platform-suffixed binary.
- Print the line `$env:Path += ';<installDir>'` for the user to
paste, refreshing the current session immediately.
- ci-main.yml install snippet bumps to 5 lines, last being
`$env:Path += ";$dest"`.
- internal/version/version.go: 0.7.4 → 0.7.5
- CHANGELOG.md: v0.7.5 entry covers all three fixes
Logo dropped at project root by user. Bake it everywhere it matters:
Assets:
- assets/muyue.ico — multi-res (16/24/32/48/64/128/256) generated via PIL
- assets/muyue-{16,32,64,128,256,512}.png — clean PNG resizes
- LogoMuyue.png kept at root as the source of truth
Windows binary (.exe):
- CI runs `rsrc -ico assets/muyue.ico -arch {amd64,arm64} -o cmd/muyue/rsrc_windows_{amd64,arm64}.syso`
before `go build` (both ci-main.yml and ci-develop.yml)
- Go automatically links *.syso files matching the target GOOS/GOARCH —
no code change in the cmd/muyue main package
- .syso files are gitignored: regenerated at every build, never committed
- Existing install-shortcuts subcommand already uses IconLocation =
"$exe,0" so the embedded icon flows automatically into Desktop +
Start Menu .lnk files
Web UI:
- web/public/favicon-{16,32}.png + muyue.png + muyue-64.png
- web/index.html: real <link rel="icon"> tags (16/32 PNG + apple-touch),
replacing the placeholder SVG hexagon
- App.jsx header: 22×22 logo image rendered next to the "MUYUE" wordmark
(rounded 4px corners for visual consistency with the source logo)
Install snippet (ci-main.yml changelog template):
- Idempotent first line: `New-Item -ItemType Directory -Force -Path $dest`
to handle the case where the user re-runs after a partial install
Versioning unchanged (still v0.7.3 — these additions stay on the same
release branch / PR #9).
Two user-reported pain points:
1. First-run setup proposed only MiniMax (no MiMo step). Onboarding
now offers both keys side-by-side under a single "apikey" step,
with per-key Validate buttons. At least one must be valid to
proceed; the rest of the providers (OpenAI/Anthropic/Z.AI/Ollama)
are not shown in the wizard — they're configured later via the
Config tab. Active provider = MiniMax if valid, else MiMo.
2. Windows install instructions failed: Move-Item to C:\Windows
requires admin. Replaced with a no-admin 4-line snippet that
installs to %LOCALAPPDATA%\Muyue and calls a new subcommand
`muyue install-shortcuts` to create Desktop + Start Menu .lnk
files and add the install dir to the user PATH. Shortcut creation
uses WScript.Shell COM via PowerShell — keeps Go binary
dependency-free. Folder paths resolved through
[Environment]::GetFolderPath so OneDrive/redirected profiles
work too.
- cmd/muyue/commands/install_shortcuts.go: new file
- web/src/components/OnboardingWizard.jsx: 2-key apikey step
- .gitea/workflows/ci-main.yml: updated install snippet
- internal/version/version.go: 0.7.2 → 0.7.3
- CHANGELOG.md: v0.7.3 entry
When at least one browser_test session is connected, every chat
message in Studio now auto-enables advanced reflection regardless of
the user toggle. The intent: during AI-driven UI testing, having a
second model produce a preliminary [RAPPORT PRÉALABLE] materially
improves which clicks the active model decides to perform and the
quality of the final ✓/✗ report.
- handlers_chat: derive wantReflection from body.AdvancedReflection
OR (browserTestStore has any active session). The user toggle still
works for normal conversations; tests just override it.
- Silent fallback when no inactive provider is configured (no error,
no behaviour change for single-provider setups).
- Tests.jsx: add a hint explaining the auto-on behaviour so the user
understands why the Studio toggle appears bypassed.
- Version 0.7.1 → 0.7.2 + CHANGELOG entry.
The terminal tab was unusable on Windows: creack/pty has no native
Windows ConPTY support, so pty.Start() returned "operating system not
supported" and the WebSocket closed immediately on any tab click —
even though the menu detection (wsl --list --quiet, pwsh, cmd) worked.
Introduce a termSession interface with two implementations selected at
runtime:
- ptySession (unix): unchanged behaviour, real PTY via creack/pty,
resize works, vim/top behave normally.
- pipeSession (windows): plain stdin + merged stdout/stderr pipes,
forwarded to the WebSocket. Resize is a no-op (no SIGWINCH without a
TTY), so full-screen TUIs misbehave in this mode — but launching
wsl.exe, pwsh, or cmd works for line-based interaction, which is
what the menu shortcuts target.
handleTerminalWS now goes through startTermSession(cmd); the unix path
is unchanged, the windows fallback kicks in only when pty.Start would
have failed.
Bump v0.7.0 → v0.7.1; CHANGELOG entry added.
The suffix _test.go makes Go treat the file as a test file (only
compiled during 'go test'), so server.go could not see the exported
BrowserTestStore / NewBrowserTestStore / RegisterBrowserTestTool and
the four handler methods at build time. Rename to a non-test name
keeps the same package-level visibility but compiles into the regular
api package.
Audit corrections (security, concurrency, stability):
- chat_engine: bound resp.Choices[0] access, release tool slot per-iteration
- conversation_multi: synchronous save under existing lock (was racy fire-and-forget)
- workflow/engine: short-circuit on failed deps (no more infinite busy-wait); track failed/skipped status
- handlers_workflow: rune-aware truncate for plan goal (UTF-8 safe)
- server: CORS limited to localhost origins (was wildcard)
- handlers_info / terminal: mask API keys and SSH passwords as "***" in GET responses; preserve stored secret if "***" sent on update
- terminal: sshpass uses -e + SSHPASS env var (was both -p and -e)
- handlers_chat: MaxBytesReader 50 MB on /api/chat
- image_cache: 10 MB cap per image
- handlers_config: font size <= 72; profile-save unmarshal errors propagated
- handlers_info: /lsp/auto-install ProjectDir restricted to user home
- Shell.jsx: parenthesized resize-condition (operator precedence)
- orchestrator_test: CleanAIResponse capitalization (fixes failing vet)
New features:
- platform: detect OS name (Debian, Ubuntu, Windows 11, macOS X.Y) and inject in Studio system prompt next to the date
- agents: default timeout 30 min for crush_run/claude_run (cap also 30 min)
- agents: new cwd, wsl_distro, wsl_user params; on Windows hosts launch via "wsl -d <distro> -u <user> --cd <cwd> --"
- agents: new claude_run tool (mirror of crush_run for Claude Code CLI)
- terminal: list installed WSL distros individually in new-tab menu (Windows only)
- studio: system prompt rewritten around BMAD-METHOD personas + mandatory delegation template
- studio: "Réflexion avancée" toggle — inactive provider produces a preliminary report injected as [RAPPORT PRÉALABLE] context for the active provider
- studio: "Historique compressé" toggle — collapses past tool calls to last action only, with "Tout afficher" expansion
Replace message-count context windows with token-budget based ones for both
studio and shell. Add /api/ai/task endpoint for background tool
check/install/update. Enhance sudo blocking to catch piped/chained elevation
commands. Add SSH password support via sshpass and connection editing UI.
Remove realTokens persistence in favor of consumption tracking. Bump to 0.4.1.
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Fix token count reset on app restart: persist realTokens in conversation.json
- Fix token/context window values: Studio 150K (summarize at 120K), Terminal 100K
- Fix table rendering in terminal tab: correct thead/tbody display model
- Fix copy button always top-right in Studio code blocks
- Add markdown horizontal rule (---) support in Studio and Terminal
- Fix bullet list double dot: remove CSS ::before duplicate bullet point
- Add image attachments support (VLM description, file mentions @file.ext)
- Add sudo detection with cache (sync.Once)
- Fix message content serialization (TextContent wrapper)
- Guide AI to use read_file instead of cat in studio prompt
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Block sudo/doas commands when not running as root
- Add real token counting from API responses
- Track and display consumption by provider/day
- Add Mermaid diagram rendering in Shell and Studio
- Add copy-to-clipboard buttons for code blocks
- Support tables in AI message rendering
- Update system prompt with context (date, time, root status)
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Fix terminal default fontSize from 6px to 14px across all references
- Add terminal tool to shell AI via ChatEngine with tool_call streaming
- Fix provider key detection (apiKey → api_key, baseURL → base_url)
- Add mimo provider migration and validation endpoint
- Bump version to 0.4.0
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
Add MiMo-V2.5-Pro from Xiaomi Token Plan as a new AI provider with
base URL https://token-plan-ams.xiaomimimo.com/v1. The /model change
command now switches between MiniMax and MiMo only. ZAI is always
placed last in the fallback chain as the provider of ultimate resort.
Config panel shows MiniMax and MiMo cards.
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Add proper disposal tracking to prevent memory leaks
- Move terminal buffer from localStorage to sessionStorage
- Restore buffer immediately after first WS message
- Fix clear detection logic and error handling
- Add signal parameter support for abortable fetch requests
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Move defer cleanup after async goroutine setup to prevent premature closure
- Remove unused Password field from terminal sessions struct
- Fix line calculation in clear detection using viewportY instead of baseY
- Add onStateChange callback to connectWebSocket for connection state
- Add tabId parameter to sendToTerminal for targeted tab control
- Simplify ShellAIMessage to use specific tab for command sending
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Delay buffer restoration by 300ms to avoid race condition with WebSocket init
- Read current line from terminal buffer on Enter (reliable) instead of keystroke tracking
- Fix streaming to emit full content instead of word-by-word chunks
- Fix WebSocket readyState check in sendToTerminal
- Extract and deduplicate AI message sending logic
- Fix localStorage cleanup on tab close
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Handle all quota types in providersQuota, not just TIME_LIMIT
- Extract model name from model field or type field
- Use explicit limit value when available
- Add vertical center alignment to quota card content
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Fix AI terminal not initializing (wait for shell col visibility, remove offsetHeight guard)
- Add Shift+Tab to cycle between shell terminals
- Handle unclosed code blocks in renderContent (Shell + Studio)
- Filter irrelevant commands from history (short/non-alpha backend + expanded frontend exclude list)
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Add dedicated AI Terminal tab (non-deletable) shared between user and AI
- Add Z.AI quota display on dashboard via /api/monitor/usage/quota/limit
- Add /model change command in Studio to toggle MiniMax/ZAI
- Apply Studio formatting (formatText, renderContent) to Shell AI messages
- Add render tick refresh for Shell (1s streaming, 5s idle)
- Add analysis viewer modal (Eye button) in Shell panel
- Fix multi-shell tab creation with retry init and settings ref
- Persist shell tabs to localStorage
- Fix line spacing in Studio (line-height 1.7→1.5, cleanup stray <br/>)
- Redirect Config updates to AI terminal via custom events
- Fix CI: delete existing release before recreating
- Bump version to 0.3.4
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- New ShellConvStore with persistent history (shell_conversation.json)
- 100k token limit — input grays out, must /clear to continue
- Commands limited to /clear and /help only
- Shell AI has NO tools — read-only analysis, never executes code
- "Analyste Système" panel with system analysis button
- System analysis uses Studio AI to write system_analysis.md,
prepended as context on every conversation start
- Code blocks show "Copier" and "Terminal" buttons to copy or
send code directly to the active terminal via WebSocket
- Token bar shows usage with warning at 80%
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Add visual indicator when messages are collapsed (folder icon)
- Add animation to token bar during compression (pulse effect)
- Token bar becomes more compact after compression with "· compressé" label
- Button "voir plus" to expand collapsed messages
- Add 24px spacing at end of feed to avoid last message clipping
- Simplify provider display: show name only, badge "active" instead of key status
- Dashboard: show provider name only without model suffix
- Studio /model: show just provider name, not model
- Z.AI (GLM): mark as crush-only, no external quota check
- Claude: check /usr/bin/claude installation instead of API
💘 Generated with Crush
- Config tabs now have bottom padding for visual spacing
- Profile panel dynamically renders all config fields (strings, bools,
arrays, nested objects) — new struct fields appear automatically
- handleSaveProfile uses generic JSON merge via deepMerge, so any
new Profile field works without handler changes
- RenderFields recursively renders config sections with edit/view modes
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
Add /summarize command, token usage bar, and summary endpoint.
Add JSON tags to config/platform/scanner structs for API serialization.
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Rewrite dashboard from 4 tabs to single grid view with 5s auto-refresh
- Add live CPU/RAM/Network SVG graphs with rolling 30-point history
- Add backend /api/system/metrics reading /proc/stat, /proc/meminfo, /proc/net/dev
- Add backend /api/providers/quota for MiniMax and Z.AI quota monitoring
- Add backend /api/recent-commands reading bash/zsh history
- Add backend /api/running-processes filtering editors/IDEs/languages
- Add sudo/root indicator (⚡ ROOT) in footer when running as root
- Remove duplicate Ctrl+1-4 shortcut from page-specific footer (keep only right side)
- Add Ctrl+R shortcut on dashboard for metrics-only refresh
- Make API key mandatory in onboarding, auto-scan editors via AI chat
- Remove manual editor input, only show AI-detected editors
- Bump version to 0.3.3
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- New API endpoints: /providers/quota, /recent-commands, /running-processes
- New grid-based dashboard layout with cards for tools, quota, processes, commands
- Improved OnboardingWizard with required API key validation and scanning feedback
- Auto-initialize config on first run
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Add ChatEngine for deduplicated chat logic (handlers_chat/shell_chat)
- Add SendWithToolsStream for real-time streaming responses
- Add /help, /plan, /export, /model commands in Studio
- Fix XSS: sanitize HTML after markdown rendering
- Add ConversationStoreMulti for multi-conversation support
- Add Anthropic headers (x-api-key, anthropic-version)
- Add fallback logging when provider switch occurs
- Add API handler tests (handlers_test.go)
- Polish Studio: max-height 200px, word-break on tool args
- Update CLI version to show full info (version, go, platform)
🤖 Generated with Crush
Assisted-by: MiniMax-M2.5 via Crush <crush@charm.land>
- Fix cleanThinkingTags to use proper regex instead of naive ReplaceAll
- Send conversation history (last 20 messages + summary) to AI instead of single message
- Store tool results alongside tool calls so history shows complete execution info
- Stream words instead of characters for smoother SSE rendering
- Add stop button to cancel in-progress AI requests (AbortController)
- Fix markdown rendering: add h2 support, use div for bullets
- Add i18n keys for cancel/stop (EN + FR)
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Replace old tool-call regex with proper agent registry
- Add streaming chat via SSE (handleStreamChat / handleNonStreamChat)
- Add internal/agent package with tool definitions and execution
- Add orchestrator with system prompt and tool scaffolding
- Add internal/agent/ directory
- Studio.jsx: streaming chat with thinking indicator and tool result rendering
- global.css: chat bubble styles, streaming animation, thinking dots
- handlers_chat.go: full rewrite using new agent/orchestrator architecture
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Add apikey step in onboarding wizard (optional, with validation)
- Add ScanEditors() in scanner package detecting vim/nvim/code/emacs/nano/helix/subl/zed
- Add GET /api/editors endpoint
- Editor step now has scan button to detect installed editors via backend
- MiniMax API key is saved to provider config if provided
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Add resetConfig and applyStarshipTheme to frontend api client
- Register handleResetConfig and handleApplyStarshipTheme in server mux
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Add PanelSystem with reset config and apply starship theme (charm/zerotwo/default)
- Add OnboardingWizard that activates when profile is empty on first run
- Fix <thing> tag parsing in Shell AI messages (wait for </thing> before rendering)
- Add /api/config/reset and /api/starship/apply-theme endpoints
- Wire wizard trigger in App.jsx based on profile completeness
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
The version was incorrectly bumped to 3.2 instead of 0.3.2.
This follows the existing semver pattern (v0.2.0, v0.2.1, v0.3.1).
💾 Generated with Crush
Assisted-by: GLM-5-Turbo via Crush <crush@charm.land>
The `len(shell) <= 1` guard was too aggressive and provided no diagnostic info.
Now trims whitespace, resolves path in all cases, falls back to /bin/sh, and
logs detailed context for debugging. Also enable WebSocket proxying in Vite dev.
The ThinkingBlock component existed but was dead code — the backend
silently discarded all <think chunks. Now emits thinking SSE events
so the UI can display AI reflections in real-time.
\xe2\x98\x85 Generated with Crush
Assisted-by: GLM-5-Turbo via Crush <crush@charm.land>
Changes:
- Hide <think> tags from user in Studio chat
- Add tool call detection [TOOL_CALL:{...}] in AI responses
- Execute crush tool when requested by AI
- Show loading animation while AI is thinking
The AI can now:
1. Respond directly to user
2. Request tool execution via [TOOL_CALL:{"tool":"crush","task":"..."}]
The system automatically executes the tool and includes results.
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
Reject shell paths with length <= 1 to prevent errors when user
input is accidentally sent as init message.
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Fix shell execution to avoid --login flag causing issues on some shells
- Improve terminal initialization timing with requestAnimationFrame
- Force display visibility on xterm instances via CSS
- Ensure container has proper min-height and overflow handling
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
Break down the 627-line handlers.go into specialized modules:
- handlers_chat.go: chat and streaming endpoints
- handlers_config.go: configuration endpoints
- handlers_common.go: shared utilities
- handlers_info.go: info and status endpoints
- handlers_terminal.go: terminal/shell endpoints
- handlers_tools.go: tool-related endpoints
Also includes config improvements, orchestrator enhancements, and
web component updates.
💘 Generated with Crush
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
- Fix detectShell() to return full paths via LookPath (was returning bare
names causing exec error on some systems)
- Add shell path validation before pty.Start to prevent crashes
- Simplify CLI: remove all subcommands, keep only desktop launch with --port
- Restore missing Studio shared CSS (code blocks, input area, animations)
- Replace Config vertical sidebar with horizontal nav-tabs matching main layout
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
- Add POST /api/providers/validate backend endpoint that sends a test
request to the provider's chat/completions API to verify the key
- Add validateProvider to frontend API client
- Redesign PanelProviders: show token input inline with Validate button,
display valid/invalid badge after validation, Save only appears after
successful validation
- Add i18n keys (EN/FR) for validation flow
💾 Generated with Crush
Assisted-by: GLM-5-Turbo via Crush <crush@charm.land>
feat(shell): real terminal with xterm.js + PTY over WebSocket
Replace fake shell input with a full PTY-backed terminal using xterm.js.
Apps like btop, vim, htop now work. AI chat panel is always visible.
Backend:
- Add WebSocket handler /api/ws/terminal with creack/pty
- Allocate real pseudo-terminal with TERM=xterm-256color
- Bidirectional I/O + dynamic resize via pty.Setsize
- Skip JSON headers on /api/ws/* paths for WebSocket upgrade
Frontend:
- Integrate xterm.js with FitAddon and WebLinksAddon
- Cyberpunk color theme matching app design
- ResizeObserver for automatic terminal resizing
- AI assistant panel always visible (340px, no toggle)
- Connection status indicator (green/red dot)
Dependencies:
- Go: github.com/gorilla/websocket, github.com/creack/pty/v2
- npm: @xterm/xterm, @xterm/addon-fit, @xterm/addon-web-links
💘 Generated with Crush
Assisted-by: GLM-5.1 via Crush <crush@charm.land>
Add full internationalization system with React context, French/English
translations, and AZERTY/QWERTY keyboard layout support. Dashboard now
uses a tabbed layout (Tools, Notifications, Workflows). Config page exposes
language and keyboard preferences persisted via new /api/preferences endpoint.
💕 Generated with Crush
Assisted-by: GLM-5-Turbo via Crush <crush@charm.land>