feat: Add HTTPS/Traefik support with centralized endpoints

- Create traefik/agent-ui.yml with full routing config for domain z590.nucleoriofrio.com
- Add frontend/src/config/endpoints.ts for automatic HTTP/HTTPS detection
- Update all hardcoded localhost URLs to use relative paths
- WebSocket connections auto-detect wss:// vs ws:// based on page protocol
- Configure path-based WebSocket routing (/ws/terminal, /ws/mcp, /ws/status, /ws/whisper)
- Add commented IP whitelist middleware for future security
This commit is contained in:
2026-02-14 03:20:51 -06:00
parent 47f5524416
commit 902029c805
18 changed files with 471 additions and 26 deletions

View File

@@ -6,6 +6,7 @@ import { WebLinksAddon } from '@xterm/addon-web-links'
import '@xterm/xterm/css/xterm.css'
import { connectWithToken, stopTokenPolling } from '../services/webmcp'
import { useCanvasStore } from '../stores/canvas'
import { endpoints } from '../config/endpoints'
const props = defineProps<{
modelValue: boolean
@@ -47,7 +48,7 @@ let tokenBuffer = ''
let tokenTimeout: number | null = null
const waitingForToken = ref(false)
const WS_URL = `ws://${window.location.hostname}:4103`
const WS_URL = endpoints.terminal
// Mouse position tracking for Ctrl+E
const mousePos = ref({ x: 0, y: 0 })

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { useCanvasStore } from '../stores/canvas'
import { endpoints } from '../config/endpoints'
const props = defineProps<{
modelValue: boolean
@@ -39,7 +40,7 @@ const containerRef = ref<HTMLElement | null>(null)
let recognition: SpeechRecognition | null = null
// WebSocket connection to terminal
const WS_URL = `ws://${window.location.hostname}:4103`
const WS_URL = endpoints.terminal
let socket: WebSocket | null = null
const connected = ref(false)
@@ -53,7 +54,7 @@ let pendingWhisperSend = false // Flag to send transcript when Whisper responds
const useWhisper = ref(false)
const whisperReady = ref(false)
const whisperLoading = ref(false)
const WHISPER_WS_URL = `ws://${window.location.hostname}:4104`
const WHISPER_WS_URL = endpoints.whisper
let whisperSocket: WebSocket | null = null
let mediaRecorder: MediaRecorder | null = null
let audioChunks: Blob[] = []
@@ -112,7 +113,7 @@ async function saveRecordingToBackend(blob: Blob) {
reader.onloadend = async () => {
const base64 = (reader.result as string).split(',')[1]
const response = await fetch(`http://${window.location.hostname}:4100/api/recordings`, {
const response = await fetch('/api/recordings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -254,7 +255,7 @@ function initRecognition() {
async function checkWhisperStatus(updateLoading = true) {
try {
const res = await fetch(`http://${window.location.hostname}:4100/api/whisper/status`)
const res = await fetch('/api/whisper/status')
const data = await res.json()
useWhisper.value = data.enabled
whisperReady.value = data.running
@@ -288,7 +289,7 @@ async function toggleWhisperMode() {
}
try {
const res = await fetch(`http://${window.location.hostname}:4100/api/whisper/toggle`, {
const res = await fetch('/api/whisper/toggle', {
method: 'POST'
})
const data = await res.json()