milaidy 1.0.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/LICENSE +8 -0
- package/README.md +538 -0
- package/dist/argv-CfSowvEA.js +63 -0
- package/dist/config-B-mboG4v.js +4 -0
- package/dist/eliza-CPJjgw-e.js +1491 -0
- package/dist/eliza.js +2192 -0
- package/dist/entry.js +232 -0
- package/dist/index.js +209 -0
- package/dist/links-BFKlWqSe.js +15 -0
- package/dist/paths-D_yh1DEJ.js +69 -0
- package/dist/plugins-cli-B7kSre2c.js +134 -0
- package/dist/program-6KwWwKKh.js +510 -0
- package/dist/register.agents-CPVmSjMG.js +17 -0
- package/dist/register.browser-B2ooXxNx.js +15 -0
- package/dist/register.channels-CMYQ6K6Y.js +42 -0
- package/dist/register.cron-D91lY1_Y.js +9 -0
- package/dist/register.devices-rU5I5L_y.js +13 -0
- package/dist/register.gateway-82SLAvw3.js +22 -0
- package/dist/register.hooks-B_XTBEkt.js +9 -0
- package/dist/register.logs-BgEGcPd8.js +10 -0
- package/dist/register.models-BJt9eVgZ.js +26 -0
- package/dist/register.nodes-B5xY1s8a.js +9 -0
- package/dist/register.skills-SFQqYIhg.js +10 -0
- package/dist/register.subclis-uF_AsbWR.js +187 -0
- package/dist/run-main-XODklzS-.js +56 -0
- package/dist/theme-DBvtuGeq.js +36 -0
- package/dist/utils-C1AUpp_V.js +42 -0
- package/dist/version-Cpn3yr5D.js +26 -0
- package/dist/workspace-Co3Wul2D.js +206 -0
- package/dist/workspace-DCA6MNVK.js +350 -0
- package/docs/.i18n/README.md +31 -0
- package/docs/.i18n/glossary.zh-CN.json +210 -0
- package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
- package/docs/CNAME +1 -0
- package/docs/automation/cron-jobs.md +468 -0
- package/docs/automation/cron-vs-heartbeat.md +254 -0
- package/docs/automation/gmail-pubsub.md +256 -0
- package/docs/automation/poll.md +69 -0
- package/docs/automation/webhook.md +163 -0
- package/docs/bedrock.md +176 -0
- package/docs/brave-search.md +41 -0
- package/docs/broadcast-groups.md +442 -0
- package/docs/cli/acp.md +170 -0
- package/docs/cli/agent.md +24 -0
- package/docs/cli/agents.md +75 -0
- package/docs/cli/approvals.md +50 -0
- package/docs/cli/browser.md +107 -0
- package/docs/cli/channels.md +79 -0
- package/docs/cli/config.md +50 -0
- package/docs/cli/configure.md +33 -0
- package/docs/cli/cron.md +42 -0
- package/docs/cli/dashboard.md +16 -0
- package/docs/cli/devices.md +67 -0
- package/docs/cli/directory.md +63 -0
- package/docs/cli/dns.md +23 -0
- package/docs/cli/docs.md +15 -0
- package/docs/cli/doctor.md +41 -0
- package/docs/cli/gateway.md +199 -0
- package/docs/cli/health.md +21 -0
- package/docs/cli/hooks.md +291 -0
- package/docs/cli/index.md +1029 -0
- package/docs/cli/logs.md +24 -0
- package/docs/cli/memory.md +45 -0
- package/docs/cli/message.md +239 -0
- package/docs/cli/models.md +79 -0
- package/docs/cli/node.md +112 -0
- package/docs/cli/nodes.md +73 -0
- package/docs/cli/onboard.md +29 -0
- package/docs/cli/pairing.md +21 -0
- package/docs/cli/plugins.md +62 -0
- package/docs/cli/reset.md +17 -0
- package/docs/cli/sandbox.md +152 -0
- package/docs/cli/security.md +26 -0
- package/docs/cli/sessions.md +16 -0
- package/docs/cli/setup.md +29 -0
- package/docs/cli/skills.md +26 -0
- package/docs/cli/status.md +26 -0
- package/docs/cli/system.md +60 -0
- package/docs/cli/tui.md +23 -0
- package/docs/cli/uninstall.md +17 -0
- package/docs/cli/update.md +98 -0
- package/docs/cli/voicecall.md +34 -0
- package/docs/cli/webhooks.md +25 -0
- package/docs/concepts/agent-loop.md +146 -0
- package/docs/concepts/agent-workspace.md +229 -0
- package/docs/concepts/agent.md +122 -0
- package/docs/concepts/architecture.md +129 -0
- package/docs/concepts/channel-routing.md +114 -0
- package/docs/concepts/compaction.md +61 -0
- package/docs/concepts/context.md +159 -0
- package/docs/concepts/features.md +53 -0
- package/docs/concepts/group-messages.md +84 -0
- package/docs/concepts/groups.md +373 -0
- package/docs/concepts/markdown-formatting.md +130 -0
- package/docs/concepts/memory.md +546 -0
- package/docs/concepts/messages.md +154 -0
- package/docs/concepts/model-failover.md +149 -0
- package/docs/concepts/model-providers.md +315 -0
- package/docs/concepts/models.md +208 -0
- package/docs/concepts/multi-agent.md +376 -0
- package/docs/concepts/oauth.md +145 -0
- package/docs/concepts/plugins.md +454 -0
- package/docs/concepts/presence.md +102 -0
- package/docs/concepts/queue.md +89 -0
- package/docs/concepts/retry.md +69 -0
- package/docs/concepts/secrets.md +300 -0
- package/docs/concepts/session-pruning.md +122 -0
- package/docs/concepts/session-tool.md +193 -0
- package/docs/concepts/session.md +188 -0
- package/docs/concepts/sessions.md +10 -0
- package/docs/concepts/skills.md +392 -0
- package/docs/concepts/streaming.md +135 -0
- package/docs/concepts/system-prompt.md +114 -0
- package/docs/concepts/timezone.md +91 -0
- package/docs/concepts/typebox.md +289 -0
- package/docs/concepts/typing-indicators.md +68 -0
- package/docs/concepts/usage-tracking.md +35 -0
- package/docs/custom.css +4 -0
- package/docs/date-time.md +128 -0
- package/docs/debugging.md +162 -0
- package/docs/docs.json +1599 -0
- package/docs/environment.md +81 -0
- package/docs/hooks.md +876 -0
- package/docs/index.md +179 -0
- package/docs/install/ansible.md +208 -0
- package/docs/install/bun.md +59 -0
- package/docs/install/development-channels.md +75 -0
- package/docs/install/docker.md +567 -0
- package/docs/install/index.md +185 -0
- package/docs/install/installer.md +123 -0
- package/docs/install/migrating.md +192 -0
- package/docs/install/nix.md +96 -0
- package/docs/install/node.md +78 -0
- package/docs/install/uninstall.md +128 -0
- package/docs/install/updating.md +228 -0
- package/docs/logging.md +350 -0
- package/docs/multi-agent-sandbox-tools.md +395 -0
- package/docs/network.md +54 -0
- package/docs/nodes/audio.md +114 -0
- package/docs/nodes/camera.md +156 -0
- package/docs/nodes/images.md +72 -0
- package/docs/nodes/index.md +341 -0
- package/docs/nodes/location-command.md +113 -0
- package/docs/nodes/media-understanding.md +379 -0
- package/docs/nodes/talk.md +90 -0
- package/docs/nodes/voicewake.md +65 -0
- package/docs/northflank.mdx +53 -0
- package/docs/perplexity.md +80 -0
- package/docs/platforms/android.md +129 -0
- package/docs/platforms/digitalocean.md +262 -0
- package/docs/platforms/exe-dev.md +125 -0
- package/docs/platforms/fly.md +486 -0
- package/docs/platforms/gcp.md +503 -0
- package/docs/platforms/hetzner.md +330 -0
- package/docs/platforms/index.md +53 -0
- package/docs/platforms/ios.md +106 -0
- package/docs/platforms/linux.md +94 -0
- package/docs/platforms/mac/bundled-gateway.md +73 -0
- package/docs/platforms/mac/canvas.md +125 -0
- package/docs/platforms/mac/child-process.md +69 -0
- package/docs/platforms/mac/dev-setup.md +102 -0
- package/docs/platforms/mac/health.md +34 -0
- package/docs/platforms/mac/icon.md +31 -0
- package/docs/platforms/mac/logging.md +57 -0
- package/docs/platforms/mac/menu-bar.md +81 -0
- package/docs/platforms/mac/peekaboo.md +65 -0
- package/docs/platforms/mac/permissions.md +44 -0
- package/docs/platforms/mac/release.md +85 -0
- package/docs/platforms/mac/remote.md +83 -0
- package/docs/platforms/mac/signing.md +47 -0
- package/docs/platforms/mac/skills.md +33 -0
- package/docs/platforms/mac/voice-overlay.md +60 -0
- package/docs/platforms/mac/voicewake.md +67 -0
- package/docs/platforms/mac/webchat.md +41 -0
- package/docs/platforms/mac/xpc.md +61 -0
- package/docs/platforms/macos-vm.md +281 -0
- package/docs/platforms/macos.md +203 -0
- package/docs/platforms/oracle.md +303 -0
- package/docs/platforms/raspberry-pi.md +358 -0
- package/docs/platforms/windows.md +159 -0
- package/docs/plugin.md +651 -0
- package/docs/plugins/agent-tools.md +99 -0
- package/docs/plugins/manifest.md +71 -0
- package/docs/plugins/voice-call.md +273 -0
- package/docs/plugins/zalouser.md +70 -0
- package/docs/providers/anthropic.md +152 -0
- package/docs/providers/claude-max-api-proxy.md +148 -0
- package/docs/providers/cloudflare-ai-gateway.md +71 -0
- package/docs/providers/deepgram.md +93 -0
- package/docs/providers/glm.md +33 -0
- package/docs/providers/index.md +63 -0
- package/docs/providers/minimax.md +208 -0
- package/docs/providers/models.md +51 -0
- package/docs/providers/moonshot.md +142 -0
- package/docs/providers/ollama.md +223 -0
- package/docs/providers/openai.md +62 -0
- package/docs/providers/opencode.md +36 -0
- package/docs/providers/openrouter.md +37 -0
- package/docs/providers/qwen.md +53 -0
- package/docs/providers/synthetic.md +99 -0
- package/docs/providers/venice.md +267 -0
- package/docs/providers/vercel-ai-gateway.md +50 -0
- package/docs/providers/xiaomi.md +64 -0
- package/docs/providers/zai.md +36 -0
- package/docs/railway.mdx +99 -0
- package/docs/reference/templates/AGENTS.md +9 -0
- package/docs/reference/templates/BOOTSTRAP.md +3 -0
- package/docs/reference/templates/HEARTBEAT.md +3 -0
- package/docs/reference/templates/IDENTITY.md +3 -0
- package/docs/reference/templates/TOOLS.md +3 -0
- package/docs/reference/templates/USER.md +3 -0
- package/docs/render.mdx +165 -0
- package/docs/start/docs-directory.md +63 -0
- package/docs/start/getting-started.md +212 -0
- package/docs/start/milaidy.md +247 -0
- package/docs/start/onboarding.md +258 -0
- package/docs/start/pairing.md +86 -0
- package/docs/start/quickstart.md +81 -0
- package/docs/start/setup.md +149 -0
- package/docs/start/showcase.md +416 -0
- package/docs/start/wizard.md +418 -0
- package/docs/testing.md +368 -0
- package/docs/token-use.md +112 -0
- package/docs/tools/agent-send.md +53 -0
- package/docs/tools/apply-patch.md +50 -0
- package/docs/tools/browser-linux-troubleshooting.md +139 -0
- package/docs/tools/browser-login.md +68 -0
- package/docs/tools/browser.md +576 -0
- package/docs/tools/chrome-extension.md +178 -0
- package/docs/tools/clawhub.md +257 -0
- package/docs/tools/creating-skills.md +54 -0
- package/docs/tools/elevated.md +57 -0
- package/docs/tools/exec-approvals.md +246 -0
- package/docs/tools/exec.md +179 -0
- package/docs/tools/firecrawl.md +61 -0
- package/docs/tools/index.md +508 -0
- package/docs/tools/llm-task.md +115 -0
- package/docs/tools/reactions.md +22 -0
- package/docs/tools/skills-config.md +76 -0
- package/docs/tools/skills.md +300 -0
- package/docs/tools/slash-commands.md +196 -0
- package/docs/tools/subagents.md +151 -0
- package/docs/tools/thinking.md +73 -0
- package/docs/tools/web.md +261 -0
- package/docs/tui.md +159 -0
- package/docs/vps.md +43 -0
- package/docs/web/control-ui.md +221 -0
- package/docs/web/dashboard.md +46 -0
- package/docs/web/index.md +116 -0
- package/docs/web/webchat.md +49 -0
- package/milaidy.mjs +14 -0
- package/package.json +271 -0
- package/skills/.cache/catalog.json +88519 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Browser-based control UI for the Gateway (chat, nodes, config)"
|
|
3
|
+
read_when:
|
|
4
|
+
- You want to operate the Gateway from a browser
|
|
5
|
+
- You want Tailnet access without SSH tunnels
|
|
6
|
+
title: "Control UI"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Control UI (browser)
|
|
10
|
+
|
|
11
|
+
The Control UI is a small **Vite + Lit** single-page app served by the Gateway:
|
|
12
|
+
|
|
13
|
+
- default: `http://<host>:18789/`
|
|
14
|
+
- optional prefix: set `gateway.controlUi.basePath` (e.g. `/milaidy`)
|
|
15
|
+
|
|
16
|
+
It speaks **directly to the Gateway WebSocket** on the same port.
|
|
17
|
+
|
|
18
|
+
## Quick open (local)
|
|
19
|
+
|
|
20
|
+
If the Gateway is running on the same computer, open:
|
|
21
|
+
|
|
22
|
+
- http://127.0.0.1:18789/ (or http://localhost:18789/)
|
|
23
|
+
|
|
24
|
+
If the page fails to load, start the Gateway first: `milaidy gateway`.
|
|
25
|
+
|
|
26
|
+
Auth is supplied during the WebSocket handshake via:
|
|
27
|
+
|
|
28
|
+
- `connect.params.auth.token`
|
|
29
|
+
- `connect.params.auth.password`
|
|
30
|
+
The dashboard settings panel lets you store a token; passwords are not persisted.
|
|
31
|
+
The onboarding wizard generates a gateway token by default, so paste it here on first connect.
|
|
32
|
+
|
|
33
|
+
## Device pairing (first connection)
|
|
34
|
+
|
|
35
|
+
When you connect to the Control UI from a new browser or device, the Gateway
|
|
36
|
+
requires a **one-time pairing approval** — even if you're on the same Tailnet
|
|
37
|
+
with `gateway.auth.allowTailscale: true`. This is a security measure to prevent
|
|
38
|
+
unauthorized access.
|
|
39
|
+
|
|
40
|
+
**What you'll see:** "disconnected (1008): pairing required"
|
|
41
|
+
|
|
42
|
+
**To approve the device:**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# List pending requests
|
|
46
|
+
milaidy devices list
|
|
47
|
+
|
|
48
|
+
# Approve by request ID
|
|
49
|
+
milaidy devices approve <requestId>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Once approved, the device is remembered and won't require re-approval unless
|
|
53
|
+
you revoke it with `milaidy devices revoke --device <id> --role <role>`. See
|
|
54
|
+
[Devices CLI](/cli/devices) for token rotation and revocation.
|
|
55
|
+
|
|
56
|
+
**Notes:**
|
|
57
|
+
|
|
58
|
+
- Local connections (`127.0.0.1`) are auto-approved.
|
|
59
|
+
- Remote connections (LAN, Tailnet, etc.) require explicit approval.
|
|
60
|
+
- Each browser profile generates a unique device ID, so switching browsers or
|
|
61
|
+
clearing browser data will require re-pairing.
|
|
62
|
+
|
|
63
|
+
## What it can do (today)
|
|
64
|
+
|
|
65
|
+
- Chat with the model via Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`)
|
|
66
|
+
- Stream tool calls + live tool output cards in Chat (agent events)
|
|
67
|
+
- Channels: WhatsApp/Telegram/Discord/Slack + plugin channels (Mattermost, etc.) status + QR login + per-channel config (`channels.status`, `web.login.*`, `config.patch`)
|
|
68
|
+
- Instances: presence list + refresh (`system-presence`)
|
|
69
|
+
- Sessions: list + per-session thinking/verbose overrides (`sessions.list`, `sessions.patch`)
|
|
70
|
+
- Cron jobs: list/add/run/enable/disable + run history (`cron.*`)
|
|
71
|
+
- Skills: status, enable/disable, install, API key updates (`skills.*`)
|
|
72
|
+
- Nodes: list + caps (`node.list`)
|
|
73
|
+
- Exec approvals: edit gateway or node allowlists + ask policy for `exec host=gateway/node` (`exec.approvals.*`)
|
|
74
|
+
- Config: view/edit `~/.milaidy/milaidy.json` (`config.get`, `config.set`)
|
|
75
|
+
- Config: apply + restart with validation (`config.apply`) and wake the last active session
|
|
76
|
+
- Config writes include a base-hash guard to prevent clobbering concurrent edits
|
|
77
|
+
- Config schema + form rendering (`config.schema`, including plugin + channel schemas); Raw JSON editor remains available
|
|
78
|
+
- Debug: status/health/models snapshots + event log + manual RPC calls (`status`, `health`, `models.list`)
|
|
79
|
+
- Logs: live tail of gateway file logs with filter/export (`logs.tail`)
|
|
80
|
+
- Update: run a package/git update + restart (`update.run`) with a restart report
|
|
81
|
+
|
|
82
|
+
Cron jobs panel notes:
|
|
83
|
+
|
|
84
|
+
- For isolated jobs, delivery defaults to announce summary. You can switch to none if you want internal-only runs.
|
|
85
|
+
- Channel/target fields appear when announce is selected.
|
|
86
|
+
|
|
87
|
+
## Chat behavior
|
|
88
|
+
|
|
89
|
+
- `chat.send` is **non-blocking**: it acks immediately with `{ runId, status: "started" }` and the response streams via `chat` events.
|
|
90
|
+
- Re-sending with the same `idempotencyKey` returns `{ status: "in_flight" }` while running, and `{ status: "ok" }` after completion.
|
|
91
|
+
- `chat.inject` appends an assistant note to the session transcript and broadcasts a `chat` event for UI-only updates (no agent run, no channel delivery).
|
|
92
|
+
- Stop:
|
|
93
|
+
- Click **Stop** (calls `chat.abort`)
|
|
94
|
+
- Type `/stop` (or `stop|esc|abort|wait|exit|interrupt`) to abort out-of-band
|
|
95
|
+
- `chat.abort` supports `{ sessionKey }` (no `runId`) to abort all active runs for that session
|
|
96
|
+
|
|
97
|
+
## Tailnet access (recommended)
|
|
98
|
+
|
|
99
|
+
### Integrated Tailscale Serve (preferred)
|
|
100
|
+
|
|
101
|
+
Keep the Gateway on loopback and let Tailscale Serve proxy it with HTTPS:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
milaidy gateway --tailscale serve
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Open:
|
|
108
|
+
|
|
109
|
+
- `https://<magicdns>/` (or your configured `gateway.controlUi.basePath`)
|
|
110
|
+
|
|
111
|
+
By default, Serve requests can authenticate via Tailscale identity headers
|
|
112
|
+
(`tailscale-user-login`) when `gateway.auth.allowTailscale` is `true`. Milaidy
|
|
113
|
+
verifies the identity by resolving the `x-forwarded-for` address with
|
|
114
|
+
`tailscale whois` and matching it to the header, and only accepts these when the
|
|
115
|
+
request hits loopback with Tailscale’s `x-forwarded-*` headers. Set
|
|
116
|
+
`gateway.auth.allowTailscale: false` (or force `gateway.auth.mode: "password"`)
|
|
117
|
+
if you want to require a token/password even for Serve traffic.
|
|
118
|
+
|
|
119
|
+
### Bind to tailnet + token
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
milaidy gateway --bind tailnet --token "$(openssl rand -hex 32)"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then open:
|
|
126
|
+
|
|
127
|
+
- `http://<tailscale-ip>:18789/` (or your configured `gateway.controlUi.basePath`)
|
|
128
|
+
|
|
129
|
+
Paste the token into the UI settings (sent as `connect.params.auth.token`).
|
|
130
|
+
|
|
131
|
+
## Insecure HTTP
|
|
132
|
+
|
|
133
|
+
If you open the dashboard over plain HTTP (`http://<lan-ip>` or `http://<tailscale-ip>`),
|
|
134
|
+
the browser runs in a **non-secure context** and blocks WebCrypto. By default,
|
|
135
|
+
Milaidy **blocks** Control UI connections without device identity.
|
|
136
|
+
|
|
137
|
+
**Recommended fix:** use HTTPS (Tailscale Serve) or open the UI locally:
|
|
138
|
+
|
|
139
|
+
- `https://<magicdns>/` (Serve)
|
|
140
|
+
- `http://127.0.0.1:18789/` (on the gateway host)
|
|
141
|
+
|
|
142
|
+
**Downgrade example (token-only over HTTP):**
|
|
143
|
+
|
|
144
|
+
```json5
|
|
145
|
+
{
|
|
146
|
+
gateway: {
|
|
147
|
+
controlUi: { allowInsecureAuth: true },
|
|
148
|
+
bind: "tailnet",
|
|
149
|
+
auth: { mode: "token", token: "replace-me" },
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This disables device identity + pairing for the Control UI (even on HTTPS). Use
|
|
155
|
+
only if you trust the network.
|
|
156
|
+
|
|
157
|
+
See [Tailscale](/gateway/tailscale) for HTTPS setup guidance.
|
|
158
|
+
|
|
159
|
+
## Building the UI
|
|
160
|
+
|
|
161
|
+
The Gateway serves static files from `dist/control-ui`. Build them with:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
pnpm ui:build # auto-installs UI deps on first run
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Optional absolute base (when you want fixed asset URLs):
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
MILAIDY_CONTROL_UI_BASE_PATH=/milaidy/ pnpm ui:build
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
For local development (separate dev server):
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
pnpm ui:dev # auto-installs UI deps on first run
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Then point the UI at your Gateway WS URL (e.g. `ws://127.0.0.1:18789`).
|
|
180
|
+
|
|
181
|
+
## Debugging/testing: dev server + remote Gateway
|
|
182
|
+
|
|
183
|
+
The Control UI is static files; the WebSocket target is configurable and can be
|
|
184
|
+
different from the HTTP origin. This is handy when you want the Vite dev server
|
|
185
|
+
locally but the Gateway runs elsewhere.
|
|
186
|
+
|
|
187
|
+
1. Start the UI dev server: `pnpm ui:dev`
|
|
188
|
+
2. Open a URL like:
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Optional one-time auth (if needed):
|
|
195
|
+
|
|
196
|
+
```text
|
|
197
|
+
http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789&token=<gateway-token>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Notes:
|
|
201
|
+
|
|
202
|
+
- `gatewayUrl` is stored in localStorage after load and removed from the URL.
|
|
203
|
+
- `token` is stored in localStorage; `password` is kept in memory only.
|
|
204
|
+
- Use `wss://` when the Gateway is behind TLS (Tailscale Serve, HTTPS proxy, etc.).
|
|
205
|
+
- `gatewayUrl` is only accepted in a top-level window (not embedded) to prevent clickjacking.
|
|
206
|
+
- For cross-origin dev setups (e.g. `pnpm ui:dev` to a remote Gateway), add the UI
|
|
207
|
+
origin to `gateway.controlUi.allowedOrigins`.
|
|
208
|
+
|
|
209
|
+
Example:
|
|
210
|
+
|
|
211
|
+
```json5
|
|
212
|
+
{
|
|
213
|
+
gateway: {
|
|
214
|
+
controlUi: {
|
|
215
|
+
allowedOrigins: ["http://localhost:5173"],
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Remote access setup details: [Remote access](/gateway/remote).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Gateway dashboard (Control UI) access and auth"
|
|
3
|
+
read_when:
|
|
4
|
+
- Changing dashboard authentication or exposure modes
|
|
5
|
+
title: "Dashboard"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Dashboard (Control UI)
|
|
9
|
+
|
|
10
|
+
The Gateway dashboard is the browser Control UI served at `/` by default
|
|
11
|
+
(override with `gateway.controlUi.basePath`).
|
|
12
|
+
|
|
13
|
+
Quick open (local Gateway):
|
|
14
|
+
|
|
15
|
+
- http://127.0.0.1:18789/ (or http://localhost:18789/)
|
|
16
|
+
|
|
17
|
+
Key references:
|
|
18
|
+
|
|
19
|
+
- [Control UI](/web/control-ui) for usage and UI capabilities.
|
|
20
|
+
- [Tailscale](/gateway/tailscale) for Serve/Funnel automation.
|
|
21
|
+
- [Web surfaces](/web) for bind modes and security notes.
|
|
22
|
+
|
|
23
|
+
Authentication is enforced at the WebSocket handshake via `connect.params.auth`
|
|
24
|
+
(token or password). See `gateway.auth` in [Gateway configuration](/gateway/configuration).
|
|
25
|
+
|
|
26
|
+
Security note: the Control UI is an **admin surface** (chat, config, exec approvals).
|
|
27
|
+
Do not expose it publicly. The UI stores the token in `localStorage` after first load.
|
|
28
|
+
Prefer localhost, Tailscale Serve, or an SSH tunnel.
|
|
29
|
+
|
|
30
|
+
## Fast path (recommended)
|
|
31
|
+
|
|
32
|
+
- After onboarding, the CLI now auto-opens the dashboard with your token and prints the same tokenized link.
|
|
33
|
+
- Re-open anytime: `milaidy dashboard` (copies link, opens browser if possible, shows SSH hint if headless).
|
|
34
|
+
- The token stays local (query param only); the UI strips it after first load and saves it in localStorage.
|
|
35
|
+
|
|
36
|
+
## Token basics (local vs remote)
|
|
37
|
+
|
|
38
|
+
- **Localhost**: open `http://127.0.0.1:18789/`. If you see “unauthorized,” run `milaidy dashboard` and use the tokenized link (`?token=...`).
|
|
39
|
+
- **Token source**: `gateway.auth.token` (or `MILAIDY_GATEWAY_TOKEN`); the UI stores it after first load.
|
|
40
|
+
- **Not localhost**: use Tailscale Serve (tokenless if `gateway.auth.allowTailscale: true`), tailnet bind with a token, or an SSH tunnel. See [Web surfaces](/web).
|
|
41
|
+
|
|
42
|
+
## If you see “unauthorized” / 1008
|
|
43
|
+
|
|
44
|
+
- Run `milaidy dashboard` to get a fresh tokenized link.
|
|
45
|
+
- Ensure the gateway is reachable (local: `milaidy status`; remote: SSH tunnel `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/?token=...`).
|
|
46
|
+
- In the dashboard settings, paste the same token you configured in `gateway.auth.token` (or `MILAIDY_GATEWAY_TOKEN`).
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Gateway web surfaces: Control UI, bind modes, and security"
|
|
3
|
+
read_when:
|
|
4
|
+
- You want to access the Gateway over Tailscale
|
|
5
|
+
- You want the browser Control UI and config editing
|
|
6
|
+
title: "Web"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Web (Gateway)
|
|
10
|
+
|
|
11
|
+
The Gateway serves a small **browser Control UI** (Vite + Lit) from the same port as the Gateway WebSocket:
|
|
12
|
+
|
|
13
|
+
- default: `http://<host>:18789/`
|
|
14
|
+
- optional prefix: set `gateway.controlUi.basePath` (e.g. `/milaidy`)
|
|
15
|
+
|
|
16
|
+
Capabilities live in [Control UI](/web/control-ui).
|
|
17
|
+
This page focuses on bind modes, security, and web-facing surfaces.
|
|
18
|
+
|
|
19
|
+
## Webhooks
|
|
20
|
+
|
|
21
|
+
When `hooks.enabled=true`, the Gateway also exposes a small webhook endpoint on the same HTTP server.
|
|
22
|
+
See [Gateway configuration](/gateway/configuration) → `hooks` for auth + payloads.
|
|
23
|
+
|
|
24
|
+
## Config (default-on)
|
|
25
|
+
|
|
26
|
+
The Control UI is **enabled by default** when assets are present (`dist/control-ui`).
|
|
27
|
+
You can control it via config:
|
|
28
|
+
|
|
29
|
+
```json5
|
|
30
|
+
{
|
|
31
|
+
gateway: {
|
|
32
|
+
controlUi: { enabled: true, basePath: "/milaidy" }, // basePath optional
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Tailscale access
|
|
38
|
+
|
|
39
|
+
### Integrated Serve (recommended)
|
|
40
|
+
|
|
41
|
+
Keep the Gateway on loopback and let Tailscale Serve proxy it:
|
|
42
|
+
|
|
43
|
+
```json5
|
|
44
|
+
{
|
|
45
|
+
gateway: {
|
|
46
|
+
bind: "loopback",
|
|
47
|
+
tailscale: { mode: "serve" },
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then start the gateway:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
milaidy gateway
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Open:
|
|
59
|
+
|
|
60
|
+
- `https://<magicdns>/` (or your configured `gateway.controlUi.basePath`)
|
|
61
|
+
|
|
62
|
+
### Tailnet bind + token
|
|
63
|
+
|
|
64
|
+
```json5
|
|
65
|
+
{
|
|
66
|
+
gateway: {
|
|
67
|
+
bind: "tailnet",
|
|
68
|
+
controlUi: { enabled: true },
|
|
69
|
+
auth: { mode: "token", token: "your-token" },
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Then start the gateway (token required for non-loopback binds):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
milaidy gateway
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Open:
|
|
81
|
+
|
|
82
|
+
- `http://<tailscale-ip>:18789/` (or your configured `gateway.controlUi.basePath`)
|
|
83
|
+
|
|
84
|
+
### Public internet (Funnel)
|
|
85
|
+
|
|
86
|
+
```json5
|
|
87
|
+
{
|
|
88
|
+
gateway: {
|
|
89
|
+
bind: "loopback",
|
|
90
|
+
tailscale: { mode: "funnel" },
|
|
91
|
+
auth: { mode: "password" }, // or MILAIDY_GATEWAY_PASSWORD
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Security notes
|
|
97
|
+
|
|
98
|
+
- Gateway auth is required by default (token/password or Tailscale identity headers).
|
|
99
|
+
- Non-loopback binds still **require** a shared token/password (`gateway.auth` or env).
|
|
100
|
+
- The wizard generates a gateway token by default (even on loopback).
|
|
101
|
+
- The UI sends `connect.params.auth.token` or `connect.params.auth.password`.
|
|
102
|
+
- The Control UI sends anti-clickjacking headers and only accepts same-origin browser
|
|
103
|
+
websocket connections unless `gateway.controlUi.allowedOrigins` is set.
|
|
104
|
+
- With Serve, Tailscale identity headers can satisfy auth when
|
|
105
|
+
`gateway.auth.allowTailscale` is `true` (no token/password required). Set
|
|
106
|
+
`gateway.auth.allowTailscale: false` to require explicit credentials. See
|
|
107
|
+
[Tailscale](/gateway/tailscale) and [Security](/gateway/security).
|
|
108
|
+
- `gateway.tailscale.mode: "funnel"` requires `gateway.auth.mode: "password"` (shared password).
|
|
109
|
+
|
|
110
|
+
## Building the UI
|
|
111
|
+
|
|
112
|
+
The Gateway serves static files from `dist/control-ui`. Build them with:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pnpm ui:build # auto-installs UI deps on first run
|
|
116
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Loopback WebChat static host and Gateway WS usage for chat UI"
|
|
3
|
+
read_when:
|
|
4
|
+
- Debugging or configuring WebChat access
|
|
5
|
+
title: "WebChat"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# WebChat (Gateway WebSocket UI)
|
|
9
|
+
|
|
10
|
+
Status: the macOS/iOS SwiftUI chat UI talks directly to the Gateway WebSocket.
|
|
11
|
+
|
|
12
|
+
## What it is
|
|
13
|
+
|
|
14
|
+
- A native chat UI for the gateway (no embedded browser and no local static server).
|
|
15
|
+
- Uses the same sessions and routing rules as other channels.
|
|
16
|
+
- Deterministic routing: replies always go back to WebChat.
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
1. Start the gateway.
|
|
21
|
+
2. Open the WebChat UI (macOS/iOS app) or the Control UI chat tab.
|
|
22
|
+
3. Ensure gateway auth is configured (required by default, even on loopback).
|
|
23
|
+
|
|
24
|
+
## How it works (behavior)
|
|
25
|
+
|
|
26
|
+
- The UI connects to the Gateway WebSocket and uses `chat.history`, `chat.send`, and `chat.inject`.
|
|
27
|
+
- `chat.inject` appends an assistant note directly to the transcript and broadcasts it to the UI (no agent run).
|
|
28
|
+
- History is always fetched from the gateway (no local file watching).
|
|
29
|
+
- If the gateway is unreachable, WebChat is read-only.
|
|
30
|
+
|
|
31
|
+
## Remote use
|
|
32
|
+
|
|
33
|
+
- Remote mode tunnels the gateway WebSocket over SSH/Tailscale.
|
|
34
|
+
- You do not need to run a separate WebChat server.
|
|
35
|
+
|
|
36
|
+
## Configuration reference (WebChat)
|
|
37
|
+
|
|
38
|
+
Full configuration: [Configuration](/gateway/configuration)
|
|
39
|
+
|
|
40
|
+
Channel options:
|
|
41
|
+
|
|
42
|
+
- No dedicated `webchat.*` block. WebChat uses the gateway endpoint + auth settings below.
|
|
43
|
+
|
|
44
|
+
Related global options:
|
|
45
|
+
|
|
46
|
+
- `gateway.port`, `gateway.bind`: WebSocket host/port.
|
|
47
|
+
- `gateway.auth.mode`, `gateway.auth.token`, `gateway.auth.password`: WebSocket auth.
|
|
48
|
+
- `gateway.remote.url`, `gateway.remote.token`, `gateway.remote.password`: remote gateway target.
|
|
49
|
+
- `session.*`: session storage and main key defaults.
|
package/milaidy.mjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import module from "node:module";
|
|
4
|
+
|
|
5
|
+
// https://nodejs.org/api/module.html#module-compile-cache
|
|
6
|
+
if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
|
7
|
+
try {
|
|
8
|
+
module.enableCompileCache();
|
|
9
|
+
} catch {
|
|
10
|
+
// Ignore errors
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await import("./dist/entry.js");
|