···11# Mister Morph
2233-Unified Agent CLI + reusable Go agent core.
33+Desktop app, CLI, and reusable Go runtime for running local or channel-connected agents.
4455Other languages: [简体中文](docs/zh-CN/README.md) | [日本語](docs/ja-JP/README.md)
6677-## Table of contents
77+If you just want to try Mister Morph, start with the desktop App from the [GitHub Releases](https://github.com/quailyquaily/mistermorph/releases) page. It bundles the Console UI, starts the local backend for you, and walks you through first-run setup.
8899-- [Why Mister Morph](#why-mistermorph)
1010-- [Quickstart](#quickstart)
1111-- [Start Modes](#start-modes)
1212-- [Supported Models](#supported-models)
1313-- [Embedding](#embedding-to-other-projects)
1414-- [Built-in Tools](#built-in-tools)
1515-- [Skills](#skills)
1616-- [Security](#security)
1717-- [Troubleshoots](#troubleshoots)
1818-- [Debug](#debug)
1919-- [Configuration](#configuration)
99+## Why Mister Morph
1010+1111+- 🖥️ App-first onboarding: the desktop App removes the old multi-terminal setup path, but the CLI is still there when you want it.
1212+- 🧩 Reusable Go core: run Mister Morph as a desktop App, CLI, Console backend, or embed it into another Go project.
1313+- 🔀 One backend, multiple entrypoints: desktop App, Console server, CLI, and channel runtimes all build on the same core runtime.
1414+- 🛠️ Practical extension model: built-in tools, `SKILL.md` skills, and Go embedding cover local use, automation, and integration.
1515+- 🔒 Security-minded by design: auth profiles, outbound policy controls, approvals, and redaction are built into the runtime model.
20162121-## Why Mister Morph
1717+## Quick Start
22182323-What makes this project worth looking at:
1919+### Desktop App (recommended)
24202525-- 🧩 **Reusable Go core**: Run the agent as a CLI, or embed it as a library/subprocess in other apps.
2626-- 🔒 **Serious secure defaults**: Profile-based credential injection, Guard redaction, outbound policy controls, and async approvals with audit trails (see [docs/security.md](docs/security.md)).
2727-- 🧰 **Practical Skills system**: Discover + inject `SKILL.md` from `file_state_dir/skills`, with simple on/off control (see [docs/skills.md](docs/skills.md)).
2828-- 📚 **Beginner-friendly**: Built as a learning-first agent project, with detailed design docs in `docs/` and practical debugging tools like `--inspect-prompt` and `--inspect-request`.
2121+1. Download a release asset from the [GitHub Releases](https://github.com/quailyquaily/mistermorph/releases) page:
2222+ - macOS: `mistermorph-desktop-darwin-arm64.dmg`
2323+ - Linux: `mistermorph-desktop-linux-amd64.AppImage`
2424+ - Windows: `mistermorph-desktop-windows-amd64.zip`
2525+2. Launch the App.
2626+3. Complete the setup flow inside the App.
2727+4. Use the Console UI. You do not need to run `mistermorph console serve` manually.
29283030-## Quickstart
2929+Build, packaging, and platform notes: [docs/app.md](docs/app.md)
31303232-### Step 1: Install
3131+### CLI
33323434-Option A: download a prebuilt binary from GitHub Releases (recommended for production use):
3333+Install a CLI binary:
35343635```bash
3736curl -fsSL -o /tmp/install-mistermorph.sh https://raw.githubusercontent.com/quailyquaily/mistermorph/refs/heads/master/scripts/install-release.sh
3837sudo bash /tmp/install-mistermorph.sh
3938```
40394141-The installer supports:
4242-4343-- `bash install-release.sh <version-tag>`
4444-- `INSTALL_DIR=$HOME/.local/bin bash install-release.sh <version-tag>`
4545-4646-Option B: install from source with Go:
4040+Or install from source:
47414842```bash
4943go install github.com/quailyquaily/mistermorph/cmd/mistermorph@latest
5044```
51455252-### Step 2: Bootstrap the agent workspace
4646+Bootstrap a workspace, set an API key, and run one task:
53475448```bash
5549mistermorph install
5656-# or
5757-mistermorph install <dir>
5858-```
5959-6060-The `install` command initializes `config.yaml` plus the core onboarding markdown files under `~/.morph/` (or a specified directory via `<dir>`).
6161-6262-When `config.yaml` does not already exist in the install target, `install` first tries to find a readable config in this order:
6363-6464-1. `--config` path
6565-2. `<dir>/config.yaml`
6666-3. `~/.morph/config.yaml`
6767-6868-If none is found, `install` runs an interactive setup wizard (TTY only) before writing `config.yaml`:
6969-7070-1. select LLM provider (`openai-compatible|gemini|anthropic|cloudflare`)
7171-2. fill provider-specific required fields
7272-3. set model
7373-4. fill `IDENTITY.md`
7474-5. choose a `SOUL.md` preset or customize it
7575-7676-Use `mistermorph install --yes` to skip interactive prompts.
7777-7878-### Step 3: Setup an API key
7979-8080-You can run without a `config.yaml` by using environment variables:
8181-8282-```bash
8383-export MISTER_MORPH_LLM_API_KEY="YOUR_OPENAI_API_KEY_HERE"
8484-# Optional explicit defaults:
8585-export MISTER_MORPH_LLM_PROVIDER="openai"
8686-export MISTER_MORPH_LLM_MODEL="gpt-5.4"
8787-```
8888-8989-If you prefer file-based config, use `~/.morph/config.yaml`.
9090-9191-## Start Modes
9292-9393-### One-time run
9494-9595-```bash
5050+export MISTER_MORPH_LLM_API_KEY="YOUR_API_KEY"
9651mistermorph run --task "Hello!"
9752```
98539999-### Desktop App
100100-101101-The desktop wrapper starts the Console UI for you and handles first-run setup inside the app.
102102-103103-See [`docs/app.md`](docs/app.md) for build and run details.
104104-105105-### Other modes
106106-107107-Console server mode, Telegram, Slack, LINE, Lark, and runtime endpoint submission are documented in [`docs/modes.md`](docs/modes.md).
108108-109109-## Supported Models
5454+If `config.yaml` does not exist yet, `mistermorph install` launches the setup wizard and writes the initial workspace files for you.
11055111111-> Model support may vary by specific model ID, provider endpoint capability, and tool-calling behavior.
112112-113113-| Model family | Model range | Status |
114114-|---|---|---|
115115-| GPT | `gpt-5*` | ✅ Full |
116116-| GPT-OSS | `gpt-oss-120b` | ✅ Full |
117117-| Grok | `grok-4+` | ✅ Full |
118118-| Claude | `claude-3.5+` | ✅ Full |
119119-| DeepSeek | `deepseek-3*` | ✅ Full |
120120-| Gemini | `gemini-2.5+` | ✅ Full |
121121-| Kimi | `kimi-2.5+` | ✅ Full |
122122-| MiniMax | `minimax* / minimax-m2.5+` | ✅ Full |
123123-| GLM | `glm-4.6+` | ✅ Full |
124124-| Cloudflare Workers AI | `Workers AI model IDs` | ⚠️ Limited (no tool calling) |
5656+CLI modes and configuration details: [docs/modes.md](docs/modes.md), [docs/configuration.md](docs/configuration.md)
12557126126-## Embedding to other projects
5858+## What Mister Morph Includes
12759128128-See [`docs/integration.md`](docs/integration.md) for embedding patterns and examples.
6060+- A desktop App for local use with first-run setup and an embedded Console UI.
6161+- A CLI for one-shot tasks, scripting, automation, and server modes.
6262+- A local Console server for browser-based setup, runtime management, and monitoring.
6363+- Channel runtimes for Telegram, Slack, LINE, and Lark.
6464+- A reusable Go integration layer for embedding Mister Morph into other projects.
6565+- Built-in tools and a `SKILL.md`-based skills system.
6666+- Security controls for auth profiles, outbound policies, approvals, and redaction.
12967130130-## Built-in Tools
6868+## Documentation
13169132132-Core tools available to the agent:
7070+Start here:
13371134134-- `read_file`: read local text files.
135135-- `write_file`: write local text files under `file_cache_dir` or `file_state_dir`.
136136-- `bash`: run a shell command (disabled by default).
137137-- `url_fetch`: HTTP fetch with optional auth profiles.
138138-- `web_search`: web search (DuckDuckGo HTML).
139139-- `plan_create`: generate a structured plan.
7272+- [Desktop App](docs/app.md)
7373+- [Modes](docs/modes.md)
7474+- [Configuration](docs/configuration.md)
7575+- [Troubleshoots](docs/troubleshoots.md)
14076141141-Channel runtime tools:
7777+Reference:
14278143143-- `telegram_send_file`: send a file in Telegram (Telegram only).
144144-- `telegram_send_photo`: send a photo in Telegram (Telegram only).
145145-- `telegram_send_voice`: send a voice message in Telegram (Telegram only).
146146-- `message_react`: add an emoji reaction to a message (Telegram/Slack runtime; channel-specific params).
7979+- [Console](docs/console.md)
8080+- [Tools](docs/tools.md)
8181+- [Skills](docs/skills.md)
8282+- [Security](docs/security.md)
8383+- [Integration](docs/integration.md)
8484+- [Architecture](docs/arch.md)
14785148148-Please see [`docs/tools.md`](docs/tools.md) for detailed tool documentation.
8686+Channel setup:
14987150150-## Skills
8888+- [Telegram](docs/telegram.md)
8989+- [Slack](docs/slack.md)
9090+- [LINE](docs/line.md)
9191+- [Lark](docs/lark.md)
15192152152-`mistermorph` discovers skills under `file_state_dir/skills` (recursively), and injects selected `SKILL.md` content into the system prompt.
9393+Full docs index: [docs/README.md](docs/README.md)
15394154154-By default, `run` uses `skills.enabled=true`; `skills.load=[]` loads all discovered skills, and unknown skill names are ignored.
155155-You can also reference a skill directly in task text with `$skill-name` (or `$skill-id`) to trigger that skill for the run.
9595+## Development
15696157157-Docs: [`docs/skills.md`](docs/skills.md).
9797+Useful local commands:
1589815999```bash
160160-# list available skills
161161-mistermorph skills list
162162-# Use a specific skill in the run command
163163-mistermorph run --task "..." --skills-enabled --skill skill-name
164164-# install remote skills
165165-mistermorph skills install <remote-skill-url>
100100+./scripts/build-backend.sh --output ./bin/mistermorph
101101+./scripts/build-desktop.sh --release
102102+go test ./...
166103```
167104168168-### Security Mechanisms for Skills
169169-170170-1. Install audit: When installing remote skills, Mister Morph will preview the skill content and do a basic security audit (e.g., look for dangerous commands in scripts) before asking for user confirmation.
171171-2. Auth profiles: Skills can declare required auth profiles in the `auth_profiles` field. This is only a declaration for prompt/context clarity. Actual permission still comes only from host config via `secrets.allow_profiles` and `auth_profiles` (see `assets/skills/moltbook` and the config sections).
172172-173173-## Security
174174-175175-Recommended systemd hardening and secret handling: [`docs/security.md`](docs/security.md).
176176-177177-## Troubleshoots
178178-179179-Known issues and workarounds: [`docs/troubleshoots.md`](docs/troubleshoots.md).
180180-181181-## Debug
182182-183183-### Logging
184184-185185-There is an argument `--log-level` set for logging level and format:
186186-187187-```bash
188188-mistermorph run --log-level debug --task "..."
189189-```
190190-191191-### Dump internal debug data
192192-193193-There are 2 arguments `--inspect-prompt`/`--inspect-request` for dumping internal state for debugging:
194194-195195-```bash
196196-mistermorph run --inspect-prompt --inspect-request --task "..."
197197-```
198198-199199-These arguments will dump the final system/user/tool prompts and the full LLM request/response JSON as plain text files to `./dump` directory.
200200-201201-## Configuration
202202-203203-`mistermorph` uses Viper, so you can configure it via flags, env vars, or a config file.
204204-205205-- Config file: `--config /path/to/config.yaml` (supports `.yaml/.yml/.json/.toml/.ini`)
206206-- Env var prefix: `MISTER_MORPH_`
207207-- Nested keys: replace `.` and `-` with `_` (e.g. `tools.bash.enabled` → `MISTER_MORPH_TOOLS_BASH_ENABLED=true`)
208208-209209-210210-### CLI flags
211211-212212-**Global (all commands)**
213213-- `--config`
214214-- `--log-level`
215215-- `--log-format`
216216-- `--log-add-source`
217217-- `--log-include-thoughts`
218218-- `--log-include-tool-params`
219219-- `--log-include-skill-contents`
220220-- `--log-max-thought-chars`
221221-- `--log-max-json-bytes`
222222-- `--log-max-string-value-chars`
223223-- `--log-max-skill-content-chars`
224224-- `--log-redact-key` (repeatable)
225225-226226-**run**
227227-- `--task`
228228-- `--provider`
229229-- `--endpoint`
230230-- `--model`
231231-- `--api-key`
232232-- `--llm-request-timeout`
233233-- `--interactive`
234234-- `--skills-dir` (repeatable)
235235-- `--skill` (repeatable)
236236-- `--skills-enabled`
237237-- `--max-steps`
238238-- `--parse-retries`
239239-- `--max-token-budget`
240240-- `--timeout`
241241-- `--inspect-prompt`
242242-- `--inspect-request`
243243-244244-**submit**
245245-- `--task`
246246-- `--server-url`
247247-- `--auth-token`
248248-- `--model`
249249-- `--submit-timeout`
250250-- `--wait`
251251-- `--poll-interval`
252252-253253-**console serve**
254254-- `--console-listen`
255255-- `--console-base-path`
256256-- `--console-static-dir` (optional; overrides the embedded Console SPA/static root)
257257-- `--console-session-ttl`
258258-259259-**telegram**
260260-- `--telegram-bot-token`
261261-- `--telegram-allowed-chat-id` (repeatable)
262262-- `--telegram-group-trigger-mode` (`strict|smart|talkative`)
263263-- `--telegram-addressing-confidence-threshold`
264264-- `--telegram-addressing-interject-threshold`
265265-- `--telegram-poll-timeout`
266266-- `--telegram-task-timeout`
267267-- `--telegram-max-concurrency`
268268-269269-**slack**
270270-- `--slack-bot-token`
271271-- `--slack-app-token`
272272-- `--slack-allowed-team-id` (repeatable)
273273-- `--slack-allowed-channel-id` (repeatable)
274274-- `--slack-group-trigger-mode` (`strict|smart|talkative`)
275275-- `--slack-addressing-confidence-threshold`
276276-- `--slack-addressing-interject-threshold`
277277-- `--slack-task-timeout`
278278-- `--slack-max-concurrency`
279279-280280-**skills**
281281-- `skills list --skills-dir` (repeatable)
282282-- `skills install --dest --dry-run --clean --skip-existing --timeout --max-bytes --yes`
283283-284284-**install**
285285-- `install [dir]`
286286-- `--yes`
287287-288288-### Environment variables
289289-290290-Common env vars (these map to config keys):
291291-292292-- `MISTER_MORPH_CONFIG`
293293-- `MISTER_MORPH_LLM_PROVIDER`
294294-- `MISTER_MORPH_LLM_ENDPOINT`
295295-- `MISTER_MORPH_LLM_MODEL`
296296-- `MISTER_MORPH_LLM_API_KEY`
297297-- `MISTER_MORPH_LLM_REQUEST_TIMEOUT`
298298-- `MISTER_MORPH_LOGGING_LEVEL`
299299-- `MISTER_MORPH_LOGGING_FORMAT`
300300-- `MISTER_MORPH_SERVER_AUTH_TOKEN`
301301-- `MISTER_MORPH_CONSOLE_PASSWORD`
302302-- `MISTER_MORPH_CONSOLE_PASSWORD_HASH`
303303-- `MISTER_MORPH_TELEGRAM_BOT_TOKEN`
304304-- `MISTER_MORPH_SLACK_BOT_TOKEN`
305305-- `MISTER_MORPH_SLACK_APP_TOKEN`
306306-- `MISTER_MORPH_FILE_CACHE_DIR`
307307-308308-Provider-specific settings use the same mapping, for example:
309309-- `llm.azure.deployment` → `MISTER_MORPH_LLM_AZURE_DEPLOYMENT`
310310-- `llm.bedrock.model_arn` → `MISTER_MORPH_LLM_BEDROCK_MODEL_ARN`
311311-312312-Tool toggles and limits also map to env vars, for example:
313313-314314-- `MISTER_MORPH_TOOLS_BASH_ENABLED`
315315-- `MISTER_MORPH_TOOLS_URL_FETCH_ENABLED`
316316-- `MISTER_MORPH_TOOLS_URL_FETCH_MAX_BYTES`
317317-318318-All string values in config support `${ENV_VAR}` syntax for environment variable expansion (e.g. `api_key: "${OPENAI_API_KEY}"`).
105105+The Console frontend uses `pnpm` under `web/console/`. See [docs/console.md](docs/console.md) and [docs/app.md](docs/app.md) for local build details.
319106320320-Key meanings (see `assets/config/config.example.yaml` for the canonical list):
321321-- Core: `llm.provider` selects the backend. Most providers use `llm.endpoint`/`llm.api_key`/`llm.model`. Optional defaults `llm.temperature`, `llm.reasoning_effort`, and `llm.reasoning_budget_tokens` are forwarded to `uniai` only when set. Azure uses `llm.azure.deployment` for deployment name, while endpoint/key are still read from `llm.endpoint` and `llm.api_key`. Bedrock uses `llm.bedrock.*`. `llm.tools_emulation_mode` controls tool-call emulation for models without native tool calling (`off|fallback|force`). `llm.profiles` defines named profile overrides, and `llm.routes` routes semantic purposes such as `main_loop`, `addressing`, `heartbeat`, `plan_create`, and `memory_draft`.
322322-- LLM secrets: use `${ENV_VAR}` syntax in any string field to reference environment variables. Example:
323323- ```yaml
324324- llm:
325325- api_key: "${OPENAI_API_KEY}"
326326- profiles:
327327- reasoning:
328328- provider: xai
329329- model: grok-4.1-fast-reasoning
330330- api_key: "${XAI_API_KEY}"
331331- ```
332332-- LLM precedence: for config-sourced values, precedence is `CLI flag > MISTER_MORPH_* env > config.yaml > default`.
333333-- Logging: `logging.level` (`info` shows progress; `debug` adds thoughts), `logging.format` (`text|json`), plus `logging.include_thoughts` and `logging.include_tool_params` (redacted).
334334-- Loop: `max_steps` limits tool-call rounds; `parse_retries` retries invalid JSON; `max_token_budget` is a cumulative token cap (0 disables); `timeout` is the overall run timeout.
335335-- Skills: `skills.enabled` controls whether skills are used; `file_state_dir` + `skills.dir_name` define the default skills root; `skills.load=[]` loads all discovered skills, otherwise it loads only listed skills (unknown names are ignored).
336336-- Tools: all tool toggles live under `tools.*` (e.g. `tools.bash.enabled`, `tools.url_fetch.enabled`) with per-tool limits and timeouts.
337337-- Auth profiles: `secrets.allow_profiles` is the runtime allowlist. `auth_profiles.<id>.credential.secret` holds the secret value (use `${ENV_VAR}` to reference env vars). If at least one allowlisted auth profile is configured, `bash` still works but `curl` is denied by default; authenticated HTTP should go through `url_fetch + auth_profile`.
107107+## Configuration Template
338108339339-## Star History
109109+The canonical config template lives at [assets/config/config.example.yaml](assets/config/config.example.yaml).
110110+Environment variables use the `MISTER_MORPH_` prefix. Full configuration notes and common flags are in [docs/configuration.md](docs/configuration.md).
340111341112## Star History
342113
···11-# Desktop App Wrapper (Wails)
11+# Desktop App
22+33+Mister Morph ships a desktop App that wraps the existing Console backend and UI into a single local experience.
2433-This document describes the current desktop wrapper architecture for MisterMorph.
55+## User Quick Start
4655-## 1. Goal
77+Download a release asset from the [GitHub Releases](https://github.com/quailyquaily/mistermorph/releases) page:
6877-Provide a single desktop app entrypoint that:
99+- macOS `arm64`: `mistermorph-desktop-darwin-arm64.dmg`
1010+- Linux `amd64`: `mistermorph-desktop-linux-amd64.AppImage`
1111+- Windows `amd64`: `mistermorph-desktop-windows-amd64.zip`
81299-- launches the Console UI without asking users to run multiple terminal commands
1010-- supports first-run setup in Console
1111-- reuses existing backend (`mistermorph console serve`) and existing web console (`web/console`)
1313+Then:
12141313-## 2. Current Shape
1515+1. launch the App
1616+2. complete the setup flow inside the App
1717+3. let the App start and host the local Console for you
14181515-The desktop app is implemented under `desktop/wails` and built with tag `wailsdesktop production`.
1919+You do not need to run `mistermorph console serve` manually when using the App.
16201717-- Wails process hosts the native window and Go bindings.
1818-- A child process runs `mistermorph console serve`.
1919-- Wails asset handler reverse-proxies WebView requests to the child process.
2121+## Current Shape
20222121-This keeps CLI and console backend logic unchanged and limits wrapper-specific code to a small area.
2222-The desktop wrapper is intentionally thin: lifecycle + process hosting + proxy only, no business rules.
2323+The desktop code lives under `desktop/wails` and is built with `wailsdesktop production`.
23242424-## 3. ASCII Architecture
2525+- the Wails process owns the native window and Go bindings
2626+- a child process runs `mistermorph console serve`
2727+- the App routes WebView traffic to that local child process
2828+2929+The wrapper stays intentionally thin: lifecycle, process hosting, restart flow, and local proxying only.
3030+3131+## Architecture
25322633```text
2734+--------------------------------------------------------------+
2828-| Desktop App Process (Wails) |
3535+| Desktop App Process (Wails) |
2936| |
3037| +----------------------+ +------------------------+ |
3138| | WebView (UI) | <----> | Reverse Proxy Handler | |
···4956 +----------------------------------+
5057```
51585252-## 4. Startup Sequence
5959+## Startup and Restart
6060+6161+Startup sequence:
53625463```text
5555-Desktop main
6464+desktop main
5665 -> resolve backend binary path
5766 -> reserve random loopback port
5867 -> spawn child: mistermorph console serve
5959- --console-listen 127.0.0.1:<port>
6060- --console-base-path /console
6161- --allow-empty-password
6268 -> poll GET /health until ready
6363- -> start Wails window
6464- -> proxy requests to child process
6969+ -> open native window
7070+ -> proxy requests to the child process
6571```
66726767-If health check timeout is reached, app startup fails fast with stderr message.
6868-6969-## 5. First-run Setup Flow
7373+First run:
70747175```text
7276incomplete config
7377 -> console backend starts with allow-empty-password
7474- -> frontend router redirects to /setup
7575- -> user submits setup form (agent settings + identity/soul)
7676- -> frontend calls Wails binding `window.go.main.App.RestartApp()`
7878+ -> frontend routes to /setup
7979+ -> user saves agent settings + identity/soul
8080+ -> frontend calls App.RestartApp()
7781```
78827979-## 6. Restart Flow
8383+`App.RestartApp()` starts a new copy of the current desktop executable and then quits the old one.
80848181-`App.RestartApp()` in desktop binding:
8585+## Paths and Configuration
82868383-- spawns a new instance of current executable (`os.Executable()` + original args)
8484-- then quits current Wails process
8787+- Console frontend assets are embedded in the bundled `mistermorph` backend by default.
8888+- You can override static assets with:
8989+ - `console.static_dir`
9090+ - `--console-static-dir /abs/path/to/dist`
9191+- `--config <path>` passed to the desktop App is forwarded to the child `console serve` process.
85928686-This is used after successful setup apply.
9393+## Local Build and Run
87948888-## 7. Paths and Configuration
9595+On Ubuntu or Debian, install desktop build dependencies first:
89969090-- frontend static assets default: embedded in the `mistermorph` backend binary
9191-- override static assets path with existing backend settings:
9292- - `console.static_dir`
9393- - `--console-static-dir /abs/path/to/dist`
9494-- `--config <path>` passed to desktop app is forwarded to child `console serve`.
9595-9696-## 8. Build and Run
9797+```bash
9898+sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev
9999+```
971009898-Build console assets first:
101101+Build the backend binary used by the desktop wrapper:
99102100103```bash
101101-pnpm --dir web/console build
102102-./scripts/stage-console-assets.sh
103103-go build -o ./bin/mistermorph ./cmd/mistermorph
104104+./scripts/build-backend.sh --output ./bin/mistermorph
104105```
105106106106-On Ubuntu/Debian with WebKitGTK 4.1, install the native Linux desktop deps first:
107107+Build a local desktop release binary:
107108108109```bash
109109-sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev
110110+./scripts/build-desktop.sh --release
110111```
111112112112-Run desktop app:
113113+Run from source:
113114114115```bash
115116go run -tags 'wailsdesktop production' ./desktop/wails
116117```
117118118118-Build desktop binary:
119119+Build only the desktop wrapper directly:
119120120121```bash
121122go build -tags 'wailsdesktop production' -o ./bin/mistermorph-desktop ./desktop/wails
122123```
123124124124-## 9. Packaging
125125+For local debug builds with DevTools, use:
125126126126-Tag releases build these desktop assets in GitHub Actions:
127127+```bash
128128+./scripts/build-desktop.sh
129129+```
130130+131131+## Release Packaging
132132+133133+Tagged releases currently publish:
127134128135- macOS `arm64`: `mistermorph-desktop-darwin-arm64.dmg`
129136- Linux `amd64`: `mistermorph-desktop-linux-amd64.AppImage`
130130-- Windows `amd64`: `mistermorph-desktop-windows-amd64.exe`
131131-132132-The DMG and AppImage packaging steps also bundle a sibling `mistermorph` backend binary next to the desktop wrapper executable inside the package. That lets the desktop host find `console serve` locally before falling back to PATH or GitHub release download.
137137+- Windows `amd64`: `mistermorph-desktop-windows-amd64.zip`
133138134134-## 10. Security and Scope Notes
139139+The packaged desktop App includes a sibling `mistermorph` backend binary so the wrapper can start `console serve` locally without a first-run download.
135140136136-- Child process listens on loopback only (`127.0.0.1`).
137137-- Child process only binds to loopback; no external listener is exposed.
138138-- This is an MVP wrapper, not yet a full packaging/distribution pipeline.
141141+That bundled backend is intentionally built with `CGO_ENABLED=0`. Keep it that way unless there is a deliberate packaging plan to change the constraint.
139142140140-## 11. Known Gaps
143143+## Known Gaps
141144142142-- No notarization/codesign flow yet for the macOS DMG.
143143-- Windows still ships as a raw `.exe`; no NSIS/MSIX packaging yet.
144144-- No dedicated UI for backend startup failure details yet.
145145-- CLI reuse is done through child process orchestration, not an extracted in-process console module.
145145+- No notarization or codesign flow yet for the macOS DMG.
146146+- Windows ships as a zip bundle, not an installer.
147147+- No dedicated UI yet for detailed backend startup failures.
148148+- The desktop wrapper still reuses the CLI backend through child-process orchestration rather than an in-process console module.
+207
docs/configuration.md
···11+# Configuration
22+33+This page collects the configuration details that do not need to live on the top-level README.
44+55+The canonical config template is [../assets/config/config.example.yaml](../assets/config/config.example.yaml).
66+77+## Sources and Precedence
88+99+`mistermorph` uses Viper, so you can configure it with:
1010+1111+- CLI flags
1212+- environment variables
1313+- a config file
1414+1515+Precedence for config-sourced values is:
1616+1717+`CLI flag > MISTER_MORPH_* env > config.yaml > default`
1818+1919+Supported config file formats:
2020+2121+- `.yaml`
2222+- `.yml`
2323+- `.json`
2424+- `.toml`
2525+- `.ini`
2626+2727+Environment variable rules:
2828+2929+- prefix: `MISTER_MORPH_`
3030+- nested keys: replace `.` and `-` with `_`
3131+- example: `tools.bash.enabled` -> `MISTER_MORPH_TOOLS_BASH_ENABLED=true`
3232+3333+All string values in config support `${ENV_VAR}` expansion.
3434+3535+## Common CLI Flags
3636+3737+Global flags:
3838+3939+- `--config`
4040+- `--log-level`
4141+- `--log-format`
4242+- `--log-add-source`
4343+- `--log-include-thoughts`
4444+- `--log-include-tool-params`
4545+- `--log-include-skill-contents`
4646+- `--log-max-thought-chars`
4747+- `--log-max-json-bytes`
4848+- `--log-max-string-value-chars`
4949+- `--log-max-skill-content-chars`
5050+- `--log-redact-key` (repeatable)
5151+5252+`run`:
5353+5454+- `--task`
5555+- `--provider`
5656+- `--endpoint`
5757+- `--model`
5858+- `--api-key`
5959+- `--llm-request-timeout`
6060+- `--interactive`
6161+- `--skills-dir` (repeatable)
6262+- `--skill` (repeatable)
6363+- `--skills-enabled`
6464+- `--max-steps`
6565+- `--parse-retries`
6666+- `--max-token-budget`
6767+- `--timeout`
6868+- `--inspect-prompt`
6969+- `--inspect-request`
7070+7171+`submit`:
7272+7373+- `--task`
7474+- `--server-url`
7575+- `--auth-token`
7676+- `--model`
7777+- `--submit-timeout`
7878+- `--wait`
7979+- `--poll-interval`
8080+8181+`console serve`:
8282+8383+- `--console-listen`
8484+- `--console-base-path`
8585+- `--console-static-dir`
8686+- `--console-session-ttl`
8787+- `--allow-empty-password`
8888+8989+`telegram`:
9090+9191+- `--telegram-bot-token`
9292+- `--telegram-allowed-chat-id` (repeatable)
9393+- `--telegram-group-trigger-mode`
9494+- `--telegram-addressing-confidence-threshold`
9595+- `--telegram-addressing-interject-threshold`
9696+- `--telegram-poll-timeout`
9797+- `--telegram-task-timeout`
9898+- `--telegram-max-concurrency`
9999+100100+`slack`:
101101+102102+- `--slack-bot-token`
103103+- `--slack-app-token`
104104+- `--slack-allowed-team-id` (repeatable)
105105+- `--slack-allowed-channel-id` (repeatable)
106106+- `--slack-group-trigger-mode`
107107+- `--slack-addressing-confidence-threshold`
108108+- `--slack-addressing-interject-threshold`
109109+- `--slack-task-timeout`
110110+- `--slack-max-concurrency`
111111+112112+`skills`:
113113+114114+- `skills list --skills-dir` (repeatable)
115115+- `skills install --dest --dry-run --clean --skip-existing --timeout --max-bytes --yes`
116116+117117+`install`:
118118+119119+- `install [dir]`
120120+- `--yes`
121121+122122+## Common Environment Variables
123123+124124+- `MISTER_MORPH_CONFIG`
125125+- `MISTER_MORPH_LLM_PROVIDER`
126126+- `MISTER_MORPH_LLM_ENDPOINT`
127127+- `MISTER_MORPH_LLM_MODEL`
128128+- `MISTER_MORPH_LLM_API_KEY`
129129+- `MISTER_MORPH_LLM_REQUEST_TIMEOUT`
130130+- `MISTER_MORPH_LOGGING_LEVEL`
131131+- `MISTER_MORPH_LOGGING_FORMAT`
132132+- `MISTER_MORPH_SERVER_AUTH_TOKEN`
133133+- `MISTER_MORPH_CONSOLE_PASSWORD`
134134+- `MISTER_MORPH_CONSOLE_PASSWORD_HASH`
135135+- `MISTER_MORPH_TELEGRAM_BOT_TOKEN`
136136+- `MISTER_MORPH_SLACK_BOT_TOKEN`
137137+- `MISTER_MORPH_SLACK_APP_TOKEN`
138138+- `MISTER_MORPH_FILE_CACHE_DIR`
139139+140140+Provider-specific values follow the same mapping. Examples:
141141+142142+- `llm.azure.deployment` -> `MISTER_MORPH_LLM_AZURE_DEPLOYMENT`
143143+- `llm.bedrock.model_arn` -> `MISTER_MORPH_LLM_BEDROCK_MODEL_ARN`
144144+145145+## Key Config Areas
146146+147147+Core LLM:
148148+149149+- `llm.provider` selects the backend.
150150+- Most providers use `llm.endpoint`, `llm.api_key`, and `llm.model`.
151151+- Azure uses `llm.azure.deployment`.
152152+- Bedrock uses `llm.bedrock.*`.
153153+- `llm.tools_emulation_mode` controls tool-call emulation for models without native tool calling.
154154+- `llm.profiles` defines named profile overrides.
155155+- `llm.routes` routes semantic purposes such as `main_loop`, `addressing`, `heartbeat`, `plan_create`, and `memory_draft`.
156156+157157+Logging and runtime limits:
158158+159159+- `logging.level`
160160+- `logging.format`
161161+- `logging.include_thoughts`
162162+- `logging.include_tool_params`
163163+- `max_steps`
164164+- `parse_retries`
165165+- `max_token_budget`
166166+- `timeout`
167167+168168+Skills:
169169+170170+- `skills.enabled`
171171+- `skills.load`
172172+- `file_state_dir`
173173+- `skills.dir_name`
174174+175175+Tools:
176176+177177+- all tool toggles live under `tools.*`
178178+- examples: `tools.bash.enabled`, `tools.url_fetch.enabled`
179179+180180+Console:
181181+182182+- `console.listen`
183183+- `console.base_path`
184184+- `console.static_dir`
185185+- `console.session_ttl`
186186+187187+Auth profiles and secrets:
188188+189189+- `secrets.allow_profiles` is the runtime allowlist.
190190+- `auth_profiles.<id>.credential.secret` holds the secret value.
191191+- Use `${ENV_VAR}` for secret references.
192192+193193+If at least one allowlisted auth profile is configured, `bash` still works but `curl` is denied by default. Authenticated HTTP should go through `url_fetch` with an auth profile.
194194+195195+## Example
196196+197197+```yaml
198198+llm:
199199+ provider: openai
200200+ model: gpt-5.4
201201+ api_key: "${OPENAI_API_KEY}"
202202+ profiles:
203203+ reasoning:
204204+ provider: xai
205205+ model: grok-4.1-fast-reasoning
206206+ api_key: "${XAI_API_KEY}"
207207+```