@jungjaehoon/mama-os 0.1.1
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/CHANGELOG.md +67 -0
- package/README.md +643 -0
- package/dist/agent/agent-loop.d.ts +98 -0
- package/dist/agent/agent-loop.d.ts.map +1 -0
- package/dist/agent/agent-loop.js +417 -0
- package/dist/agent/agent-loop.js.map +1 -0
- package/dist/agent/auto-recall.d.ts +48 -0
- package/dist/agent/auto-recall.d.ts.map +1 -0
- package/dist/agent/auto-recall.js +178 -0
- package/dist/agent/auto-recall.js.map +1 -0
- package/dist/agent/claude-cli-wrapper.d.ts +130 -0
- package/dist/agent/claude-cli-wrapper.d.ts.map +1 -0
- package/dist/agent/claude-cli-wrapper.js +227 -0
- package/dist/agent/claude-cli-wrapper.js.map +1 -0
- package/dist/agent/claude-client.d.ts +50 -0
- package/dist/agent/claude-client.d.ts.map +1 -0
- package/dist/agent/claude-client.js +214 -0
- package/dist/agent/claude-client.js.map +1 -0
- package/dist/agent/gateway-tool-executor.d.ts +75 -0
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -0
- package/dist/agent/gateway-tool-executor.js +348 -0
- package/dist/agent/gateway-tool-executor.js.map +1 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +18 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/mcp-executor.d.ts +75 -0
- package/dist/agent/mcp-executor.d.ts.map +1 -0
- package/dist/agent/mcp-executor.js +307 -0
- package/dist/agent/mcp-executor.js.map +1 -0
- package/dist/agent/session-pool.d.ts +148 -0
- package/dist/agent/session-pool.d.ts.map +1 -0
- package/dist/agent/session-pool.js +272 -0
- package/dist/agent/session-pool.js.map +1 -0
- package/dist/agent/streaming-callback-manager.d.ts +85 -0
- package/dist/agent/streaming-callback-manager.d.ts.map +1 -0
- package/dist/agent/streaming-callback-manager.js +103 -0
- package/dist/agent/streaming-callback-manager.js.map +1 -0
- package/dist/agent/types.d.ts +437 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +29 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/api/cron-handler.d.ts +44 -0
- package/dist/api/cron-handler.d.ts.map +1 -0
- package/dist/api/cron-handler.js +195 -0
- package/dist/api/cron-handler.js.map +1 -0
- package/dist/api/error-handler.d.ts +22 -0
- package/dist/api/error-handler.d.ts.map +1 -0
- package/dist/api/error-handler.js +104 -0
- package/dist/api/error-handler.js.map +1 -0
- package/dist/api/heartbeat-handler.d.ts +49 -0
- package/dist/api/heartbeat-handler.d.ts.map +1 -0
- package/dist/api/heartbeat-handler.js +91 -0
- package/dist/api/heartbeat-handler.js.map +1 -0
- package/dist/api/index.d.ts +61 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +145 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/types.d.ts +156 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +62 -0
- package/dist/api/types.js.map +1 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth-manager.d.ts +59 -0
- package/dist/auth/oauth-manager.d.ts.map +1 -0
- package/dist/auth/oauth-manager.js +237 -0
- package/dist/auth/oauth-manager.js.map +1 -0
- package/dist/auth/types.d.ts +92 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +23 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +155 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.d.ts +19 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +89 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +19 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +134 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/start.d.ts +24 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +1073 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +10 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +85 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +10 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +65 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/config/config-manager.d.ts +51 -0
- package/dist/cli/config/config-manager.d.ts.map +1 -0
- package/dist/cli/config/config-manager.js +216 -0
- package/dist/cli/config/config-manager.js.map +1 -0
- package/dist/cli/config/types.d.ts +172 -0
- package/dist/cli/config/types.d.ts.map +1 -0
- package/dist/cli/config/types.js +48 -0
- package/dist/cli/config/types.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +92 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/pid-manager.d.ts +66 -0
- package/dist/cli/utils/pid-manager.d.ts.map +1 -0
- package/dist/cli/utils/pid-manager.js +167 -0
- package/dist/cli/utils/pid-manager.js.map +1 -0
- package/dist/concurrency/index.d.ts +13 -0
- package/dist/concurrency/index.d.ts.map +1 -0
- package/dist/concurrency/index.js +22 -0
- package/dist/concurrency/index.js.map +1 -0
- package/dist/concurrency/lane-manager.d.ts +113 -0
- package/dist/concurrency/lane-manager.d.ts.map +1 -0
- package/dist/concurrency/lane-manager.js +245 -0
- package/dist/concurrency/lane-manager.js.map +1 -0
- package/dist/concurrency/session-key.d.ts +41 -0
- package/dist/concurrency/session-key.d.ts.map +1 -0
- package/dist/concurrency/session-key.js +61 -0
- package/dist/concurrency/session-key.js.map +1 -0
- package/dist/concurrency/types.d.ts +69 -0
- package/dist/concurrency/types.d.ts.map +1 -0
- package/dist/concurrency/types.js +16 -0
- package/dist/concurrency/types.js.map +1 -0
- package/dist/gateways/channel-history.d.ts +102 -0
- package/dist/gateways/channel-history.d.ts.map +1 -0
- package/dist/gateways/channel-history.js +181 -0
- package/dist/gateways/channel-history.js.map +1 -0
- package/dist/gateways/context-injector.d.ts +74 -0
- package/dist/gateways/context-injector.d.ts.map +1 -0
- package/dist/gateways/context-injector.js +121 -0
- package/dist/gateways/context-injector.js.map +1 -0
- package/dist/gateways/discord.d.ts +122 -0
- package/dist/gateways/discord.d.ts.map +1 -0
- package/dist/gateways/discord.js +602 -0
- package/dist/gateways/discord.js.map +1 -0
- package/dist/gateways/index.d.ts +30 -0
- package/dist/gateways/index.d.ts.map +1 -0
- package/dist/gateways/index.js +49 -0
- package/dist/gateways/index.js.map +1 -0
- package/dist/gateways/message-router.d.ts +116 -0
- package/dist/gateways/message-router.d.ts.map +1 -0
- package/dist/gateways/message-router.js +315 -0
- package/dist/gateways/message-router.js.map +1 -0
- package/dist/gateways/message-splitter.d.ts +54 -0
- package/dist/gateways/message-splitter.d.ts.map +1 -0
- package/dist/gateways/message-splitter.js +146 -0
- package/dist/gateways/message-splitter.js.map +1 -0
- package/dist/gateways/plugin-loader.d.ts +76 -0
- package/dist/gateways/plugin-loader.d.ts.map +1 -0
- package/dist/gateways/plugin-loader.js +221 -0
- package/dist/gateways/plugin-loader.js.map +1 -0
- package/dist/gateways/session-store.d.ts +77 -0
- package/dist/gateways/session-store.d.ts.map +1 -0
- package/dist/gateways/session-store.js +233 -0
- package/dist/gateways/session-store.js.map +1 -0
- package/dist/gateways/slack.d.ts +90 -0
- package/dist/gateways/slack.d.ts.map +1 -0
- package/dist/gateways/slack.js +281 -0
- package/dist/gateways/slack.js.map +1 -0
- package/dist/gateways/telegram.d.ts +79 -0
- package/dist/gateways/telegram.d.ts.map +1 -0
- package/dist/gateways/telegram.js +207 -0
- package/dist/gateways/telegram.js.map +1 -0
- package/dist/gateways/types.d.ts +340 -0
- package/dist/gateways/types.d.ts.map +1 -0
- package/dist/gateways/types.js +6 -0
- package/dist/gateways/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/memory-logger.d.ts +47 -0
- package/dist/memory/memory-logger.d.ts.map +1 -0
- package/dist/memory/memory-logger.js +126 -0
- package/dist/memory/memory-logger.js.map +1 -0
- package/dist/onboarding/all-tools.d.ts +18 -0
- package/dist/onboarding/all-tools.d.ts.map +1 -0
- package/dist/onboarding/all-tools.js +149 -0
- package/dist/onboarding/all-tools.js.map +1 -0
- package/dist/onboarding/autonomous-discovery-tools.d.ts +13 -0
- package/dist/onboarding/autonomous-discovery-tools.d.ts.map +1 -0
- package/dist/onboarding/autonomous-discovery-tools.js +268 -0
- package/dist/onboarding/autonomous-discovery-tools.js.map +1 -0
- package/dist/onboarding/bootstrap-template.d.ts +5 -0
- package/dist/onboarding/bootstrap-template.d.ts.map +1 -0
- package/dist/onboarding/bootstrap-template.js +142 -0
- package/dist/onboarding/bootstrap-template.js.map +1 -0
- package/dist/onboarding/complete-autonomous-prompt.d.ts +13 -0
- package/dist/onboarding/complete-autonomous-prompt.d.ts.map +1 -0
- package/dist/onboarding/complete-autonomous-prompt.js +1220 -0
- package/dist/onboarding/complete-autonomous-prompt.js.map +1 -0
- package/dist/onboarding/onboarding-state.d.ts +70 -0
- package/dist/onboarding/onboarding-state.d.ts.map +1 -0
- package/dist/onboarding/onboarding-state.js +184 -0
- package/dist/onboarding/onboarding-state.js.map +1 -0
- package/dist/onboarding/personality-quiz.d.ts +35 -0
- package/dist/onboarding/personality-quiz.d.ts.map +1 -0
- package/dist/onboarding/personality-quiz.js +219 -0
- package/dist/onboarding/personality-quiz.js.map +1 -0
- package/dist/onboarding/phase-5-summary.d.ts +22 -0
- package/dist/onboarding/phase-5-summary.d.ts.map +1 -0
- package/dist/onboarding/phase-5-summary.js +151 -0
- package/dist/onboarding/phase-5-summary.js.map +1 -0
- package/dist/onboarding/phase-6-security.d.ts +33 -0
- package/dist/onboarding/phase-6-security.d.ts.map +1 -0
- package/dist/onboarding/phase-6-security.js +473 -0
- package/dist/onboarding/phase-6-security.js.map +1 -0
- package/dist/onboarding/phase-7-integrations.d.ts +66 -0
- package/dist/onboarding/phase-7-integrations.d.ts.map +1 -0
- package/dist/onboarding/phase-7-integrations.js +619 -0
- package/dist/onboarding/phase-7-integrations.js.map +1 -0
- package/dist/onboarding/phase-8-demo.d.ts +43 -0
- package/dist/onboarding/phase-8-demo.d.ts.map +1 -0
- package/dist/onboarding/phase-8-demo.js +346 -0
- package/dist/onboarding/phase-8-demo.js.map +1 -0
- package/dist/onboarding/phase-9-finalization.d.ts +22 -0
- package/dist/onboarding/phase-9-finalization.d.ts.map +1 -0
- package/dist/onboarding/phase-9-finalization.js +375 -0
- package/dist/onboarding/phase-9-finalization.js.map +1 -0
- package/dist/onboarding/ritual-prompt.d.ts +2 -0
- package/dist/onboarding/ritual-prompt.d.ts.map +1 -0
- package/dist/onboarding/ritual-prompt.js +285 -0
- package/dist/onboarding/ritual-prompt.js.map +1 -0
- package/dist/onboarding/ritual-tools.d.ts +13 -0
- package/dist/onboarding/ritual-tools.d.ts.map +1 -0
- package/dist/onboarding/ritual-tools.js +93 -0
- package/dist/onboarding/ritual-tools.js.map +1 -0
- package/dist/runners/cli-runner.d.ts +59 -0
- package/dist/runners/cli-runner.d.ts.map +1 -0
- package/dist/runners/cli-runner.js +190 -0
- package/dist/runners/cli-runner.js.map +1 -0
- package/dist/runners/index.d.ts +11 -0
- package/dist/runners/index.d.ts.map +1 -0
- package/dist/runners/index.js +15 -0
- package/dist/runners/index.js.map +1 -0
- package/dist/runners/types.d.ts +81 -0
- package/dist/runners/types.d.ts.map +1 -0
- package/dist/runners/types.js +31 -0
- package/dist/runners/types.js.map +1 -0
- package/dist/scheduler/cron-scheduler.d.ts +115 -0
- package/dist/scheduler/cron-scheduler.d.ts.map +1 -0
- package/dist/scheduler/cron-scheduler.js +320 -0
- package/dist/scheduler/cron-scheduler.js.map +1 -0
- package/dist/scheduler/heartbeat.d.ts +53 -0
- package/dist/scheduler/heartbeat.d.ts.map +1 -0
- package/dist/scheduler/heartbeat.js +160 -0
- package/dist/scheduler/heartbeat.js.map +1 -0
- package/dist/scheduler/index.d.ts +22 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +31 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/job-lock.d.ts +85 -0
- package/dist/scheduler/job-lock.d.ts.map +1 -0
- package/dist/scheduler/job-lock.js +137 -0
- package/dist/scheduler/job-lock.js.map +1 -0
- package/dist/scheduler/recovery.d.ts +78 -0
- package/dist/scheduler/recovery.d.ts.map +1 -0
- package/dist/scheduler/recovery.js +124 -0
- package/dist/scheduler/recovery.js.map +1 -0
- package/dist/scheduler/schedule-store.d.ts +112 -0
- package/dist/scheduler/schedule-store.d.ts.map +1 -0
- package/dist/scheduler/schedule-store.js +259 -0
- package/dist/scheduler/schedule-store.js.map +1 -0
- package/dist/scheduler/token-keep-alive.d.ts +49 -0
- package/dist/scheduler/token-keep-alive.d.ts.map +1 -0
- package/dist/scheduler/token-keep-alive.js +102 -0
- package/dist/scheduler/token-keep-alive.js.map +1 -0
- package/dist/scheduler/types.d.ts +96 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +21 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/setup/setup-prompt.d.ts +2 -0
- package/dist/setup/setup-prompt.d.ts.map +1 -0
- package/dist/setup/setup-prompt.js +138 -0
- package/dist/setup/setup-prompt.js.map +1 -0
- package/dist/setup/setup-server.d.ts +8 -0
- package/dist/setup/setup-server.d.ts.map +1 -0
- package/dist/setup/setup-server.js +71 -0
- package/dist/setup/setup-server.js.map +1 -0
- package/dist/setup/setup-tools.d.ts +13 -0
- package/dist/setup/setup-tools.d.ts.map +1 -0
- package/dist/setup/setup-tools.js +103 -0
- package/dist/setup/setup-tools.js.map +1 -0
- package/dist/setup/setup-websocket.d.ts +6 -0
- package/dist/setup/setup-websocket.d.ts.map +1 -0
- package/dist/setup/setup-websocket.js +312 -0
- package/dist/setup/setup-websocket.js.map +1 -0
- package/dist/skills/index.d.ts +10 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +26 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/skill-executor.d.ts +48 -0
- package/dist/skills/skill-executor.d.ts.map +1 -0
- package/dist/skills/skill-executor.js +483 -0
- package/dist/skills/skill-executor.js.map +1 -0
- package/dist/skills/skill-loader.d.ts +40 -0
- package/dist/skills/skill-loader.d.ts.map +1 -0
- package/dist/skills/skill-loader.js +225 -0
- package/dist/skills/skill-loader.js.map +1 -0
- package/dist/skills/skill-matcher.d.ts +33 -0
- package/dist/skills/skill-matcher.d.ts.map +1 -0
- package/dist/skills/skill-matcher.js +190 -0
- package/dist/skills/skill-matcher.js.map +1 -0
- package/dist/skills/types.d.ts +123 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +12 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/browser-tool.d.ts +149 -0
- package/dist/tools/browser-tool.d.ts.map +1 -0
- package/dist/tools/browser-tool.js +257 -0
- package/dist/tools/browser-tool.js.map +1 -0
- package/package.json +84 -0
- package/public/favicon.ico +0 -0
- package/public/setup.html +1026 -0
- package/public/viewer/icons/icon-192.png +0 -0
- package/public/viewer/icons/icon-512.png +0 -0
- package/public/viewer/js/modules/chat.js +1587 -0
- package/public/viewer/js/modules/dashboard.js +275 -0
- package/public/viewer/js/modules/graph.js +997 -0
- package/public/viewer/js/modules/memory.js +353 -0
- package/public/viewer/js/modules/settings.js +255 -0
- package/public/viewer/js/utils/api.js +169 -0
- package/public/viewer/js/utils/dom.js +92 -0
- package/public/viewer/js/utils/format.js +192 -0
- package/public/viewer/manifest.json +26 -0
- package/public/viewer/sw.js +131 -0
- package/public/viewer/viewer.css +500 -0
- package/public/viewer/viewer.html +1535 -0
- package/scripts/postinstall.js +118 -0
- package/templates/skills/document-analyze.md +63 -0
- package/templates/skills/heartbeat-report.md +75 -0
- package/templates/skills/image-translate.md +67 -0
- package/templates/workspace/skill-forge/DESIGN.md +115 -0
- package/templates/workspace/skill-forge/agents/architect.ts +295 -0
- package/templates/workspace/skill-forge/agents/developer.ts +364 -0
- package/templates/workspace/skill-forge/agents/qa.ts +313 -0
- package/templates/workspace/skill-forge/claude-api.ts +353 -0
- package/templates/workspace/skill-forge/discord-ui.ts +580 -0
- package/templates/workspace/skill-forge/error-handler.ts +354 -0
- package/templates/workspace/skill-forge/mama-integration.ts +357 -0
- package/templates/workspace/skill-forge/orchestrator.ts +495 -0
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/README.md +24 -0
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/index.ts +79 -0
- package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/types.ts +17 -0
- package/templates/workspace/skill-forge/package.json +21 -0
- package/templates/workspace/skill-forge/state/session.json +132 -0
- package/templates/workspace/skill-forge/test-e2e.ts +139 -0
- package/templates/workspace/skill-forge/tsconfig.json +20 -0
- package/templates/workspace/skill-forge/types.ts +159 -0
|
@@ -0,0 +1,1535 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html class="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta
|
|
6
|
+
name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
8
|
+
/>
|
|
9
|
+
<title>MAMA - Memory-Augmented Assistant</title>
|
|
10
|
+
|
|
11
|
+
<meta name="theme-color" content="#0a0a0f" />
|
|
12
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
13
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
14
|
+
<meta name="apple-mobile-web-app-title" content="MAMA" />
|
|
15
|
+
<link rel="apple-touch-icon" href="/viewer/icons/icon-192.png" />
|
|
16
|
+
|
|
17
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
18
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
19
|
+
<link
|
|
20
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
|
21
|
+
rel="stylesheet"
|
|
22
|
+
/>
|
|
23
|
+
|
|
24
|
+
<script src="https://unpkg.com/vis-network@9/dist/vis-network.min.js"></script>
|
|
25
|
+
<script src="https://unpkg.com/lucide@latest"></script>
|
|
26
|
+
<script src="https://cdn.jsdelivr.net/npm/marked@11/marked.min.js"></script>
|
|
27
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
28
|
+
<script>
|
|
29
|
+
tailwind.config = {
|
|
30
|
+
darkMode: 'class',
|
|
31
|
+
theme: {
|
|
32
|
+
extend: {
|
|
33
|
+
colors: {
|
|
34
|
+
background: 'hsl(var(--background))',
|
|
35
|
+
foreground: 'hsl(var(--foreground))',
|
|
36
|
+
card: 'hsl(var(--card))',
|
|
37
|
+
'card-foreground': 'hsl(var(--card-foreground))',
|
|
38
|
+
border: 'hsl(var(--border))',
|
|
39
|
+
muted: 'hsl(var(--muted))',
|
|
40
|
+
'muted-foreground': 'hsl(var(--muted-foreground))',
|
|
41
|
+
primary: 'hsl(var(--primary))',
|
|
42
|
+
'primary-foreground': 'hsl(var(--primary-foreground))',
|
|
43
|
+
secondary: 'hsl(var(--secondary))',
|
|
44
|
+
'secondary-foreground': 'hsl(var(--secondary-foreground))',
|
|
45
|
+
destructive: 'hsl(var(--destructive))',
|
|
46
|
+
'destructive-foreground': 'hsl(var(--destructive-foreground))',
|
|
47
|
+
success: 'hsl(var(--success))',
|
|
48
|
+
warning: 'hsl(var(--warning))',
|
|
49
|
+
info: 'hsl(var(--info))',
|
|
50
|
+
ring: 'hsl(var(--ring))',
|
|
51
|
+
},
|
|
52
|
+
spacing: {
|
|
53
|
+
'header': 'var(--header-height)',
|
|
54
|
+
'sidebar': 'var(--sidebar-width)',
|
|
55
|
+
},
|
|
56
|
+
borderRadius: {
|
|
57
|
+
DEFAULT: 'var(--radius)',
|
|
58
|
+
sm: 'var(--radius-sm)',
|
|
59
|
+
lg: 'var(--radius-lg)',
|
|
60
|
+
},
|
|
61
|
+
fontFamily: {
|
|
62
|
+
sans: ['Inter', 'sans-serif'],
|
|
63
|
+
mono: ['var(--font-mono)', 'monospace'],
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
</script>
|
|
69
|
+
<style>
|
|
70
|
+
:root {
|
|
71
|
+
--background: 0 0% 100%;
|
|
72
|
+
--foreground: 0 0% 9%;
|
|
73
|
+
--card: 0 0% 98%;
|
|
74
|
+
--card-foreground: 0 0% 9%;
|
|
75
|
+
--border: 0 0% 89%;
|
|
76
|
+
--muted: 0 0% 96%;
|
|
77
|
+
--muted-foreground: 0 0% 45%;
|
|
78
|
+
--primary: 240 80% 60%;
|
|
79
|
+
--primary-foreground: 0 0% 100%;
|
|
80
|
+
--secondary: 240 4.8% 95.9%;
|
|
81
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
82
|
+
--destructive: 0 84.2% 60.2%;
|
|
83
|
+
--destructive-foreground: 0 0% 98%;
|
|
84
|
+
--success: 142 76% 36%;
|
|
85
|
+
--warning: 38 92% 50%;
|
|
86
|
+
--info: 199 89% 48%;
|
|
87
|
+
--ring: 240 80% 60%;
|
|
88
|
+
--radius: 0.5rem;
|
|
89
|
+
--radius-sm: 0.375rem;
|
|
90
|
+
--radius-lg: 0.75rem;
|
|
91
|
+
--header-height: 56px;
|
|
92
|
+
--sidebar-width: 280px;
|
|
93
|
+
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
94
|
+
}
|
|
95
|
+
.dark {
|
|
96
|
+
--background: 222.2 84% 4.9%;
|
|
97
|
+
--foreground: 210 40% 98%;
|
|
98
|
+
--card: 222.2 84% 7%;
|
|
99
|
+
--card-foreground: 210 40% 98%;
|
|
100
|
+
--border: 217.2 32.6% 17.5%;
|
|
101
|
+
--muted: 217.2 32.6% 17.5%;
|
|
102
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
103
|
+
--primary: 240 80% 60%;
|
|
104
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
105
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
106
|
+
--secondary-foreground: 210 40% 98%;
|
|
107
|
+
--destructive: 0 62.8% 30.6%;
|
|
108
|
+
--destructive-foreground: 210 40% 98%;
|
|
109
|
+
--success: 142 76% 36%;
|
|
110
|
+
--warning: 38 92% 50%;
|
|
111
|
+
--info: 199 89% 48%;
|
|
112
|
+
--ring: 240 80% 60%;
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
115
|
+
|
|
116
|
+
<link rel="stylesheet" href="/viewer/viewer.css" />
|
|
117
|
+
</head>
|
|
118
|
+
<body class="bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100">
|
|
119
|
+
<div id="app" class="h-screen flex flex-col">
|
|
120
|
+
<!-- Header -->
|
|
121
|
+
<header class="fixed top-0 left-0 right-0 h-14 bg-white/80 dark:bg-gray-950/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-800 z-50">
|
|
122
|
+
<div class="h-full max-w-[1920px] mx-auto px-4 flex items-center justify-between">
|
|
123
|
+
<!-- Logo -->
|
|
124
|
+
<a href="/" class="flex items-center gap-2 text-lg font-semibold hover:opacity-80 transition-opacity">
|
|
125
|
+
<div class="w-6 h-6 rounded bg-gradient-to-br from-indigo-500 to-purple-600 flex items-center justify-center text-white text-sm">✦</div>
|
|
126
|
+
<span class="hidden sm:inline">MAMA</span>
|
|
127
|
+
</a>
|
|
128
|
+
|
|
129
|
+
<!-- Navigation Tabs -->
|
|
130
|
+
<nav class="flex items-center gap-1" id="nav-tabs">
|
|
131
|
+
<button
|
|
132
|
+
class="hidden px-3 py-1.5 rounded-lg text-sm font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
133
|
+
data-tab="setup"
|
|
134
|
+
onclick="window.switchTab && window.switchTab('setup')"
|
|
135
|
+
>
|
|
136
|
+
<svg
|
|
137
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
138
|
+
width="16"
|
|
139
|
+
height="16"
|
|
140
|
+
viewBox="0 0 24 24"
|
|
141
|
+
fill="none"
|
|
142
|
+
stroke="currentColor"
|
|
143
|
+
stroke-width="2"
|
|
144
|
+
stroke-linecap="round"
|
|
145
|
+
stroke-linejoin="round"
|
|
146
|
+
>
|
|
147
|
+
<path
|
|
148
|
+
d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"
|
|
149
|
+
/>
|
|
150
|
+
<circle cx="12" cy="12" r="3" />
|
|
151
|
+
</svg>
|
|
152
|
+
<span class="hidden sm:inline">Setup</span>
|
|
153
|
+
</button>
|
|
154
|
+
<button class="px-3 py-1.5 rounded-lg text-sm font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 flex items-center gap-2" data-tab="dashboard" onclick="window.switchTab && window.switchTab('dashboard')">
|
|
155
|
+
<svg
|
|
156
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
157
|
+
width="16"
|
|
158
|
+
height="16"
|
|
159
|
+
viewBox="0 0 24 24"
|
|
160
|
+
fill="none"
|
|
161
|
+
stroke="currentColor"
|
|
162
|
+
stroke-width="2"
|
|
163
|
+
stroke-linecap="round"
|
|
164
|
+
stroke-linejoin="round"
|
|
165
|
+
>
|
|
166
|
+
<rect x="3" y="3" width="7" height="7" />
|
|
167
|
+
<rect x="14" y="3" width="7" height="7" />
|
|
168
|
+
<rect x="14" y="14" width="7" height="7" />
|
|
169
|
+
<rect x="3" y="14" width="7" height="7" />
|
|
170
|
+
</svg>
|
|
171
|
+
<span class="hidden sm:inline">Dashboard</span>
|
|
172
|
+
</button>
|
|
173
|
+
<button class="px-3 py-1.5 rounded-lg text-sm font-medium transition-colors bg-indigo-100 dark:bg-indigo-900/30 text-indigo-600 dark:text-indigo-400 flex items-center gap-2" data-tab="chat" onclick="window.switchTab && window.switchTab('chat')">
|
|
174
|
+
<svg
|
|
175
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
176
|
+
width="16"
|
|
177
|
+
height="16"
|
|
178
|
+
viewBox="0 0 24 24"
|
|
179
|
+
fill="none"
|
|
180
|
+
stroke="currentColor"
|
|
181
|
+
stroke-width="2"
|
|
182
|
+
stroke-linecap="round"
|
|
183
|
+
stroke-linejoin="round"
|
|
184
|
+
>
|
|
185
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
186
|
+
</svg>
|
|
187
|
+
<span class="hidden sm:inline">Chat</span>
|
|
188
|
+
</button>
|
|
189
|
+
<button class="px-3 py-1.5 rounded-lg text-sm font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 flex items-center gap-2" data-tab="memory" onclick="window.switchTab && window.switchTab('memory')">
|
|
190
|
+
<svg
|
|
191
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
192
|
+
width="16"
|
|
193
|
+
height="16"
|
|
194
|
+
viewBox="0 0 24 24"
|
|
195
|
+
fill="none"
|
|
196
|
+
stroke="currentColor"
|
|
197
|
+
stroke-width="2"
|
|
198
|
+
stroke-linecap="round"
|
|
199
|
+
stroke-linejoin="round"
|
|
200
|
+
>
|
|
201
|
+
<path
|
|
202
|
+
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
|
203
|
+
/>
|
|
204
|
+
<polyline points="3.29 7 12 12 20.71 7" />
|
|
205
|
+
<line x1="12" y1="22" x2="12" y2="12" />
|
|
206
|
+
</svg>
|
|
207
|
+
<span class="hidden sm:inline">Memory</span>
|
|
208
|
+
</button>
|
|
209
|
+
<button class="px-3 py-1.5 rounded-lg text-sm font-medium transition-colors hover:bg-gray-100 dark:hover:bg-gray-800 flex items-center gap-2" data-tab="settings" onclick="window.switchTab && window.switchTab('settings')">
|
|
210
|
+
<svg
|
|
211
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
212
|
+
width="16"
|
|
213
|
+
height="16"
|
|
214
|
+
viewBox="0 0 24 24"
|
|
215
|
+
fill="none"
|
|
216
|
+
stroke="currentColor"
|
|
217
|
+
stroke-width="2"
|
|
218
|
+
stroke-linecap="round"
|
|
219
|
+
stroke-linejoin="round"
|
|
220
|
+
>
|
|
221
|
+
<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" />
|
|
222
|
+
<circle cx="12" cy="12" r="3" />
|
|
223
|
+
</svg>
|
|
224
|
+
<span class="hidden sm:inline">Settings</span>
|
|
225
|
+
</button>
|
|
226
|
+
</nav>
|
|
227
|
+
|
|
228
|
+
<!-- Header Actions -->
|
|
229
|
+
<div class="flex items-center gap-2">
|
|
230
|
+
<button
|
|
231
|
+
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
|
232
|
+
onclick="toggleTheme()"
|
|
233
|
+
title="Toggle theme"
|
|
234
|
+
>
|
|
235
|
+
<svg
|
|
236
|
+
id="theme-icon-light"
|
|
237
|
+
style="display: none"
|
|
238
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
239
|
+
width="16"
|
|
240
|
+
height="16"
|
|
241
|
+
viewBox="0 0 24 24"
|
|
242
|
+
fill="none"
|
|
243
|
+
stroke="currentColor"
|
|
244
|
+
stroke-width="2"
|
|
245
|
+
stroke-linecap="round"
|
|
246
|
+
stroke-linejoin="round"
|
|
247
|
+
>
|
|
248
|
+
<circle cx="12" cy="12" r="4" />
|
|
249
|
+
<path d="M12 2v2" />
|
|
250
|
+
<path d="M12 20v2" />
|
|
251
|
+
<path d="m4.93 4.93 1.41 1.41" />
|
|
252
|
+
<path d="m17.66 17.66 1.41 1.41" />
|
|
253
|
+
<path d="M2 12h2" />
|
|
254
|
+
<path d="M20 12h2" />
|
|
255
|
+
<path d="m6.34 17.66-1.41 1.41" />
|
|
256
|
+
<path d="m19.07 4.93-1.41 1.41" />
|
|
257
|
+
</svg>
|
|
258
|
+
<svg
|
|
259
|
+
id="theme-icon-dark"
|
|
260
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
261
|
+
width="16"
|
|
262
|
+
height="16"
|
|
263
|
+
viewBox="0 0 24 24"
|
|
264
|
+
fill="none"
|
|
265
|
+
stroke="currentColor"
|
|
266
|
+
stroke-width="2"
|
|
267
|
+
stroke-linecap="round"
|
|
268
|
+
stroke-linejoin="round"
|
|
269
|
+
>
|
|
270
|
+
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
|
|
271
|
+
</svg>
|
|
272
|
+
</button>
|
|
273
|
+
<button
|
|
274
|
+
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
|
275
|
+
onclick="showTunnelSetup()"
|
|
276
|
+
title="External Access"
|
|
277
|
+
>
|
|
278
|
+
<svg
|
|
279
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
280
|
+
width="16"
|
|
281
|
+
height="16"
|
|
282
|
+
viewBox="0 0 24 24"
|
|
283
|
+
fill="none"
|
|
284
|
+
stroke="currentColor"
|
|
285
|
+
stroke-width="2"
|
|
286
|
+
stroke-linecap="round"
|
|
287
|
+
stroke-linejoin="round"
|
|
288
|
+
>
|
|
289
|
+
<circle cx="12" cy="12" r="10" />
|
|
290
|
+
<line x1="2" y1="12" x2="22" y2="12" />
|
|
291
|
+
<path
|
|
292
|
+
d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"
|
|
293
|
+
/>
|
|
294
|
+
</svg>
|
|
295
|
+
</button>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
</header>
|
|
299
|
+
|
|
300
|
+
<!-- Main Content -->
|
|
301
|
+
<main class="flex-1 pt-14 overflow-hidden flex flex-col">
|
|
302
|
+
<!-- Setup tab hidden: runs on port 3848 -->
|
|
303
|
+
<div class="tab-content" id="tab-setup" style="display: none">
|
|
304
|
+
<div class="setup-container">
|
|
305
|
+
<div class="progress-section" id="progress-section" style="display: none">
|
|
306
|
+
<div class="progress-header">
|
|
307
|
+
<span class="progress-label" id="progress-label">Getting started...</span>
|
|
308
|
+
<span class="progress-count" id="progress-count">1 / 9</span>
|
|
309
|
+
</div>
|
|
310
|
+
<div class="progress-bar" id="progress-bar">
|
|
311
|
+
<div class="progress-step"></div>
|
|
312
|
+
<div class="progress-step"></div>
|
|
313
|
+
<div class="progress-step"></div>
|
|
314
|
+
<div class="progress-step"></div>
|
|
315
|
+
<div class="progress-step"></div>
|
|
316
|
+
<div class="progress-step"></div>
|
|
317
|
+
<div class="progress-step"></div>
|
|
318
|
+
<div class="progress-step"></div>
|
|
319
|
+
<div class="progress-step"></div>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
|
|
323
|
+
<div class="chat-container" id="setup-chat">
|
|
324
|
+
<div class="chat-messages" id="setup-messages"></div>
|
|
325
|
+
|
|
326
|
+
<div class="typing-indicator" id="setup-typing">
|
|
327
|
+
<div class="typing-dot"></div>
|
|
328
|
+
<div class="typing-dot"></div>
|
|
329
|
+
<div class="typing-dot"></div>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
<div class="chat-input-area">
|
|
333
|
+
<div class="input-row">
|
|
334
|
+
<div class="input-wrapper">
|
|
335
|
+
<textarea
|
|
336
|
+
class="chat-input"
|
|
337
|
+
id="setup-input"
|
|
338
|
+
placeholder="Type your message..."
|
|
339
|
+
rows="1"
|
|
340
|
+
disabled
|
|
341
|
+
></textarea>
|
|
342
|
+
</div>
|
|
343
|
+
<button
|
|
344
|
+
class="btn btn-send"
|
|
345
|
+
id="setup-send"
|
|
346
|
+
onclick="sendSetupMessage()"
|
|
347
|
+
disabled
|
|
348
|
+
>
|
|
349
|
+
<svg
|
|
350
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
351
|
+
width="16"
|
|
352
|
+
height="16"
|
|
353
|
+
viewBox="0 0 24 24"
|
|
354
|
+
fill="none"
|
|
355
|
+
stroke="currentColor"
|
|
356
|
+
stroke-width="2"
|
|
357
|
+
stroke-linecap="round"
|
|
358
|
+
stroke-linejoin="round"
|
|
359
|
+
>
|
|
360
|
+
<line x1="22" y1="2" x2="11" y2="13" />
|
|
361
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2" />
|
|
362
|
+
</svg>
|
|
363
|
+
<span>Send</span>
|
|
364
|
+
</button>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
|
|
371
|
+
<!-- Dashboard Tab -->
|
|
372
|
+
<div class="tab-content" id="tab-dashboard">
|
|
373
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-4 md:p-6">
|
|
374
|
+
<!-- Header -->
|
|
375
|
+
<div class="mb-6">
|
|
376
|
+
<h1 class="text-2xl font-bold text-gray-900 dark:text-gray-100">MAMA OS Dashboard</h1>
|
|
377
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">System status and configuration overview</p>
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
<!-- Gateway Status Cards -->
|
|
381
|
+
<section class="mb-6">
|
|
382
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Gateway Status</h2>
|
|
383
|
+
<div id="dashboard-gateways" class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
384
|
+
<!-- Gateway cards will be rendered by JavaScript -->
|
|
385
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
386
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
387
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
388
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
389
|
+
</div>
|
|
390
|
+
</section>
|
|
391
|
+
|
|
392
|
+
<!-- Memory Stats -->
|
|
393
|
+
<section class="mb-6">
|
|
394
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Memory Statistics</h2>
|
|
395
|
+
<div id="dashboard-memory" class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
396
|
+
<!-- Memory stats will be rendered by JavaScript -->
|
|
397
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
398
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
399
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
400
|
+
<div class="animate-pulse bg-gray-200 dark:bg-gray-800 rounded-lg h-24"></div>
|
|
401
|
+
</div>
|
|
402
|
+
</section>
|
|
403
|
+
|
|
404
|
+
<!-- Agent Configuration -->
|
|
405
|
+
<section class="mb-6">
|
|
406
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Agent Configuration</h2>
|
|
407
|
+
<div id="dashboard-agent" class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
408
|
+
<!-- Agent config will be rendered by JavaScript -->
|
|
409
|
+
<div class="animate-pulse space-y-2">
|
|
410
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
|
|
411
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/3"></div>
|
|
412
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-2/3"></div>
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
</section>
|
|
416
|
+
|
|
417
|
+
<!-- Top Topics -->
|
|
418
|
+
<section class="mb-6">
|
|
419
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Top Topics</h2>
|
|
420
|
+
<div id="dashboard-topics" class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
421
|
+
<!-- Topics will be rendered by JavaScript -->
|
|
422
|
+
<div class="animate-pulse space-y-2">
|
|
423
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-3/4"></div>
|
|
424
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
|
|
425
|
+
<div class="h-4 bg-gray-200 dark:bg-gray-700 rounded w-2/3"></div>
|
|
426
|
+
</div>
|
|
427
|
+
</div>
|
|
428
|
+
</section>
|
|
429
|
+
|
|
430
|
+
<!-- Status Bar -->
|
|
431
|
+
<div id="dashboard-status" class="text-sm text-gray-500 dark:text-gray-400 text-center py-2">
|
|
432
|
+
Loading...
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
|
|
437
|
+
<!-- Settings Tab -->
|
|
438
|
+
<div class="tab-content" id="tab-settings">
|
|
439
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-4 md:p-6">
|
|
440
|
+
<!-- Header -->
|
|
441
|
+
<div class="mb-6">
|
|
442
|
+
<h1 class="text-2xl font-bold text-gray-900 dark:text-gray-100">Settings</h1>
|
|
443
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Configure MAMA gateways and agent settings</p>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
<!-- Gateway Settings -->
|
|
447
|
+
<section class="mb-6">
|
|
448
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Gateway Connections</h2>
|
|
449
|
+
<div class="grid gap-4">
|
|
450
|
+
<!-- Discord -->
|
|
451
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
452
|
+
<div class="flex items-center justify-between mb-3">
|
|
453
|
+
<div class="flex items-center gap-2">
|
|
454
|
+
<span class="text-xl">💬</span>
|
|
455
|
+
<h3 class="font-semibold text-gray-900 dark:text-gray-100">Discord</h3>
|
|
456
|
+
</div>
|
|
457
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
458
|
+
<input type="checkbox" id="settings-discord-enabled" class="sr-only peer">
|
|
459
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
|
|
460
|
+
</label>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="space-y-3">
|
|
463
|
+
<div>
|
|
464
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Bot Token</label>
|
|
465
|
+
<input type="password" id="settings-discord-token" placeholder="Enter Discord bot token" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
466
|
+
</div>
|
|
467
|
+
<div>
|
|
468
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Default Channel ID</label>
|
|
469
|
+
<input type="text" id="settings-discord-channel" placeholder="Channel ID for notifications" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
470
|
+
</div>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
|
|
474
|
+
<!-- Slack -->
|
|
475
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
476
|
+
<div class="flex items-center justify-between mb-3">
|
|
477
|
+
<div class="flex items-center gap-2">
|
|
478
|
+
<span class="text-xl">📱</span>
|
|
479
|
+
<h3 class="font-semibold text-gray-900 dark:text-gray-100">Slack</h3>
|
|
480
|
+
</div>
|
|
481
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
482
|
+
<input type="checkbox" id="settings-slack-enabled" class="sr-only peer">
|
|
483
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
|
|
484
|
+
</label>
|
|
485
|
+
</div>
|
|
486
|
+
<div class="space-y-3">
|
|
487
|
+
<div>
|
|
488
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Bot Token</label>
|
|
489
|
+
<input type="password" id="settings-slack-bot-token" placeholder="xoxb-..." class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
490
|
+
</div>
|
|
491
|
+
<div>
|
|
492
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">App Token</label>
|
|
493
|
+
<input type="password" id="settings-slack-app-token" placeholder="xapp-..." class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
</div>
|
|
497
|
+
|
|
498
|
+
<!-- Telegram -->
|
|
499
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
500
|
+
<div class="flex items-center justify-between mb-3">
|
|
501
|
+
<div class="flex items-center gap-2">
|
|
502
|
+
<span class="text-xl">✈️</span>
|
|
503
|
+
<h3 class="font-semibold text-gray-900 dark:text-gray-100">Telegram</h3>
|
|
504
|
+
</div>
|
|
505
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
506
|
+
<input type="checkbox" id="settings-telegram-enabled" class="sr-only peer">
|
|
507
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
|
|
508
|
+
</label>
|
|
509
|
+
</div>
|
|
510
|
+
<div>
|
|
511
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Bot Token</label>
|
|
512
|
+
<input type="password" id="settings-telegram-token" placeholder="123456:ABC-DEF..." class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
|
|
516
|
+
<!-- Chatwork -->
|
|
517
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
518
|
+
<div class="flex items-center justify-between mb-3">
|
|
519
|
+
<div class="flex items-center gap-2">
|
|
520
|
+
<span class="text-xl">💼</span>
|
|
521
|
+
<h3 class="font-semibold text-gray-900 dark:text-gray-100">Chatwork</h3>
|
|
522
|
+
</div>
|
|
523
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
524
|
+
<input type="checkbox" id="settings-chatwork-enabled" class="sr-only peer">
|
|
525
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
|
|
526
|
+
</label>
|
|
527
|
+
</div>
|
|
528
|
+
<div>
|
|
529
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">API Token</label>
|
|
530
|
+
<input type="password" id="settings-chatwork-token" placeholder="Enter Chatwork API token" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
</div>
|
|
534
|
+
</section>
|
|
535
|
+
|
|
536
|
+
<!-- Heartbeat Settings -->
|
|
537
|
+
<section class="mb-6">
|
|
538
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Heartbeat Scheduler</h2>
|
|
539
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
540
|
+
<div class="flex items-center justify-between mb-4">
|
|
541
|
+
<span class="text-sm text-gray-700 dark:text-gray-300">Enable Heartbeat</span>
|
|
542
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
543
|
+
<input type="checkbox" id="settings-heartbeat-enabled" class="sr-only peer">
|
|
544
|
+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 dark:peer-focus:ring-indigo-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-600"></div>
|
|
545
|
+
</label>
|
|
546
|
+
</div>
|
|
547
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
548
|
+
<div>
|
|
549
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Interval (minutes)</label>
|
|
550
|
+
<input type="number" id="settings-heartbeat-interval" value="30" min="5" max="1440" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
551
|
+
</div>
|
|
552
|
+
<div>
|
|
553
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Quiet Start (hour)</label>
|
|
554
|
+
<input type="number" id="settings-heartbeat-quiet-start" value="23" min="0" max="23" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
555
|
+
</div>
|
|
556
|
+
<div>
|
|
557
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Quiet End (hour)</label>
|
|
558
|
+
<input type="number" id="settings-heartbeat-quiet-end" value="8" min="0" max="23" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
</div>
|
|
562
|
+
</section>
|
|
563
|
+
|
|
564
|
+
<!-- Agent Settings -->
|
|
565
|
+
<section class="mb-6">
|
|
566
|
+
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-3">Agent Configuration</h2>
|
|
567
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
568
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
569
|
+
<div>
|
|
570
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Model</label>
|
|
571
|
+
<select id="settings-agent-model" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
572
|
+
<option value="claude-sonnet-4-20250514">Claude Sonnet 4</option>
|
|
573
|
+
<option value="claude-3-5-sonnet-20241022">Claude 3.5 Sonnet</option>
|
|
574
|
+
<option value="claude-3-opus-20240229">Claude 3 Opus</option>
|
|
575
|
+
<option value="claude-3-haiku-20240307">Claude 3 Haiku</option>
|
|
576
|
+
</select>
|
|
577
|
+
</div>
|
|
578
|
+
<div>
|
|
579
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Max Turns</label>
|
|
580
|
+
<input type="number" id="settings-agent-max-turns" value="10" min="1" max="50" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
581
|
+
</div>
|
|
582
|
+
<div>
|
|
583
|
+
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Timeout (seconds)</label>
|
|
584
|
+
<input type="number" id="settings-agent-timeout" value="300" min="30" max="600" class="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
|
585
|
+
</div>
|
|
586
|
+
</div>
|
|
587
|
+
</div>
|
|
588
|
+
</section>
|
|
589
|
+
|
|
590
|
+
<!-- Action Buttons -->
|
|
591
|
+
<div class="flex items-center justify-between pt-4 border-t border-gray-200 dark:border-gray-700">
|
|
592
|
+
<button onclick="settingsModule.resetForm()" class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors">
|
|
593
|
+
Reset
|
|
594
|
+
</button>
|
|
595
|
+
<div class="flex items-center gap-3">
|
|
596
|
+
<span id="settings-status" class="text-sm text-gray-500 dark:text-gray-400"></span>
|
|
597
|
+
<button onclick="settingsModule.saveSettings()" class="px-6 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors flex items-center gap-2">
|
|
598
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
599
|
+
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
|
600
|
+
<polyline points="17 21 17 13 7 13 7 21"/>
|
|
601
|
+
<polyline points="7 3 7 8 15 8"/>
|
|
602
|
+
</svg>
|
|
603
|
+
Save Settings
|
|
604
|
+
</button>
|
|
605
|
+
</div>
|
|
606
|
+
</div>
|
|
607
|
+
</div>
|
|
608
|
+
</div>
|
|
609
|
+
|
|
610
|
+
<div class="tab-content" id="tab-memory">
|
|
611
|
+
<div class="flex-1 flex min-h-0">
|
|
612
|
+
<aside class="w-72 border-r border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900 flex flex-col min-h-0">
|
|
613
|
+
<div class="p-4 border-b border-gray-200 dark:border-gray-800">
|
|
614
|
+
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
|
|
615
|
+
<svg
|
|
616
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
617
|
+
width="16"
|
|
618
|
+
height="16"
|
|
619
|
+
viewBox="0 0 24 24"
|
|
620
|
+
fill="none"
|
|
621
|
+
stroke="currentColor"
|
|
622
|
+
stroke-width="2"
|
|
623
|
+
stroke-linecap="round"
|
|
624
|
+
stroke-linejoin="round"
|
|
625
|
+
>
|
|
626
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
|
627
|
+
<line x1="3" y1="9" x2="21" y2="9" />
|
|
628
|
+
<line x1="9" y1="21" x2="9" y2="9" />
|
|
629
|
+
</svg>
|
|
630
|
+
Checkpoints
|
|
631
|
+
</h3>
|
|
632
|
+
</div>
|
|
633
|
+
<div class="flex-1 flex flex-col gap-2 p-3 overflow-y-auto" id="checkpoint-list">
|
|
634
|
+
<div class="flex flex-col items-center justify-center py-8 text-gray-500">
|
|
635
|
+
<div class="w-6 h-6 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
|
|
636
|
+
<span class="mt-2 text-sm">Loading...</span>
|
|
637
|
+
</div>
|
|
638
|
+
</div>
|
|
639
|
+
</aside>
|
|
640
|
+
|
|
641
|
+
<div class="flex-1 flex flex-col relative min-h-0" id="graph-container">
|
|
642
|
+
<!-- Analytics Bar -->
|
|
643
|
+
<div class="border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950">
|
|
644
|
+
<div class="flex items-center justify-between px-4 py-2">
|
|
645
|
+
<div class="flex items-center gap-4">
|
|
646
|
+
<div id="memory-stats-total" class="text-center">
|
|
647
|
+
<p class="text-xl font-bold text-gray-900 dark:text-gray-100">-</p>
|
|
648
|
+
<p class="text-xs text-gray-500">Total</p>
|
|
649
|
+
</div>
|
|
650
|
+
<div class="h-8 w-px bg-gray-200 dark:bg-gray-700"></div>
|
|
651
|
+
<div id="memory-stats-week" class="text-center">
|
|
652
|
+
<p class="text-xl font-bold text-indigo-600 dark:text-indigo-400">-</p>
|
|
653
|
+
<p class="text-xs text-gray-500">This Week</p>
|
|
654
|
+
</div>
|
|
655
|
+
<div class="h-8 w-px bg-gray-200 dark:bg-gray-700"></div>
|
|
656
|
+
<div id="memory-stats-outcomes" class="flex items-center gap-2">
|
|
657
|
+
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400">
|
|
658
|
+
<span id="outcome-success">0</span> success
|
|
659
|
+
</span>
|
|
660
|
+
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400">
|
|
661
|
+
<span id="outcome-failed">0</span> failed
|
|
662
|
+
</span>
|
|
663
|
+
<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-400">
|
|
664
|
+
<span id="outcome-partial">0</span> partial
|
|
665
|
+
</span>
|
|
666
|
+
</div>
|
|
667
|
+
</div>
|
|
668
|
+
<div class="flex items-center gap-2">
|
|
669
|
+
<button onclick="exportDecisions('json')" class="px-3 py-1.5 text-xs font-medium bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg transition-colors">
|
|
670
|
+
Export JSON
|
|
671
|
+
</button>
|
|
672
|
+
<button onclick="exportDecisions('markdown')" class="px-3 py-1.5 text-xs font-medium bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg transition-colors">
|
|
673
|
+
Export MD
|
|
674
|
+
</button>
|
|
675
|
+
<button onclick="exportDecisions('csv')" class="px-3 py-1.5 text-xs font-medium bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg transition-colors">
|
|
676
|
+
Export CSV
|
|
677
|
+
</button>
|
|
678
|
+
</div>
|
|
679
|
+
</div>
|
|
680
|
+
</div>
|
|
681
|
+
|
|
682
|
+
<!-- Filters Bar -->
|
|
683
|
+
<div class="flex items-center gap-3 px-4 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/50">
|
|
684
|
+
<select
|
|
685
|
+
class="px-3 py-1.5 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-indigo-500 min-w-[140px]"
|
|
686
|
+
id="topic-filter"
|
|
687
|
+
onchange="filterByTopic(this.value)"
|
|
688
|
+
>
|
|
689
|
+
<option value="">All Topics</option>
|
|
690
|
+
</select>
|
|
691
|
+
<select
|
|
692
|
+
class="px-3 py-1.5 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-indigo-500 min-w-[120px]"
|
|
693
|
+
id="outcome-filter"
|
|
694
|
+
onchange="filterByOutcome(this.value)"
|
|
695
|
+
>
|
|
696
|
+
<option value="">All Outcomes</option>
|
|
697
|
+
<option value="success">Success</option>
|
|
698
|
+
<option value="failed">Failed</option>
|
|
699
|
+
<option value="partial">Partial</option>
|
|
700
|
+
<option value="pending">Pending</option>
|
|
701
|
+
</select>
|
|
702
|
+
<input
|
|
703
|
+
type="text"
|
|
704
|
+
class="px-3 py-1.5 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 w-[180px]"
|
|
705
|
+
id="search-input"
|
|
706
|
+
placeholder="Search decisions..."
|
|
707
|
+
onkeyup="handleGraphSearch(event)"
|
|
708
|
+
/>
|
|
709
|
+
<button onclick="clearFilters()" class="px-3 py-1.5 text-xs text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
|
|
710
|
+
Clear
|
|
711
|
+
</button>
|
|
712
|
+
</div>
|
|
713
|
+
|
|
714
|
+
<div class="px-4 py-2 text-xs text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950" id="graph-stats">Loading...</div>
|
|
715
|
+
|
|
716
|
+
<div id="graph-canvas" class="flex-1 w-full h-full min-h-[400px] bg-white dark:bg-gray-950"></div>
|
|
717
|
+
|
|
718
|
+
<div class="absolute inset-0 flex flex-col items-center justify-center bg-white dark:bg-gray-950" id="graph-loading">
|
|
719
|
+
<div class="w-8 h-8 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
|
|
720
|
+
<span class="mt-3 text-sm text-gray-500 dark:text-gray-400">Loading graph data...</span>
|
|
721
|
+
</div>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
<div class="legend-panel absolute bottom-16 right-4 w-48 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-lg shadow-lg p-3 z-10" id="legend-panel">
|
|
725
|
+
<button class="absolute top-2 right-2 p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onclick="toggleLegend()">
|
|
726
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
727
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
728
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
729
|
+
</svg>
|
|
730
|
+
</button>
|
|
731
|
+
<h4 class="text-xs font-semibold text-gray-700 dark:text-gray-300 flex items-center gap-1.5 mb-3">
|
|
732
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
733
|
+
<circle cx="12" cy="12" r="10" />
|
|
734
|
+
<line x1="12" y1="16" x2="12" y2="12" />
|
|
735
|
+
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
736
|
+
</svg>
|
|
737
|
+
Legend
|
|
738
|
+
</h4>
|
|
739
|
+
<div class="legend-content space-y-3">
|
|
740
|
+
<div>
|
|
741
|
+
<div class="text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1.5">Edge Types</div>
|
|
742
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 mb-1">
|
|
743
|
+
<span class="w-6 h-0.5 bg-gray-500"></span>
|
|
744
|
+
<span>supersedes</span>
|
|
745
|
+
</div>
|
|
746
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 mb-1">
|
|
747
|
+
<span class="w-6 h-0.5 bg-blue-500 border-dashed"></span>
|
|
748
|
+
<span>builds_on</span>
|
|
749
|
+
</div>
|
|
750
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 mb-1">
|
|
751
|
+
<span class="w-6 h-0.5 bg-red-500 border-dashed"></span>
|
|
752
|
+
<span>debates</span>
|
|
753
|
+
</div>
|
|
754
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400">
|
|
755
|
+
<span class="w-6 h-1 bg-purple-500"></span>
|
|
756
|
+
<span>synthesizes</span>
|
|
757
|
+
</div>
|
|
758
|
+
</div>
|
|
759
|
+
<div>
|
|
760
|
+
<div class="text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1.5">Node Size</div>
|
|
761
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 mb-1">
|
|
762
|
+
<span class="w-2 h-2 rounded-full bg-indigo-500"></span>
|
|
763
|
+
<span>1-2 connections</span>
|
|
764
|
+
</div>
|
|
765
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 mb-1">
|
|
766
|
+
<span class="w-3 h-3 rounded-full bg-indigo-500"></span>
|
|
767
|
+
<span>3-5 connections</span>
|
|
768
|
+
</div>
|
|
769
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400">
|
|
770
|
+
<span class="w-4 h-4 rounded-full bg-indigo-500"></span>
|
|
771
|
+
<span>6+ connections</span>
|
|
772
|
+
</div>
|
|
773
|
+
</div>
|
|
774
|
+
</div>
|
|
775
|
+
</div>
|
|
776
|
+
<button class="legend-toggle absolute bottom-4 right-4 px-3 py-1.5 text-xs font-medium bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 border border-gray-200 dark:border-gray-700 rounded-lg transition-colors flex items-center gap-1.5 z-10" onclick="toggleLegend()">
|
|
777
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
778
|
+
<circle cx="12" cy="12" r="10" />
|
|
779
|
+
<line x1="12" y1="16" x2="12" y2="12" />
|
|
780
|
+
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
781
|
+
</svg>
|
|
782
|
+
Legend
|
|
783
|
+
</button>
|
|
784
|
+
</div>
|
|
785
|
+
</div>
|
|
786
|
+
|
|
787
|
+
<div class="floating-panel fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[90%] max-w-[600px] max-h-[80vh] bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl shadow-2xl z-[1000] flex-col overflow-hidden" id="decision-detail-modal">
|
|
788
|
+
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50">
|
|
789
|
+
<h3 class="text-base font-semibold text-gray-900 dark:text-gray-100" id="detail-topic">Decision Detail</h3>
|
|
790
|
+
<button class="p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-gray-500 hover:text-gray-700 dark:hover:text-gray-300" onclick="closeDetailModal()">
|
|
791
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
792
|
+
</button>
|
|
793
|
+
</div>
|
|
794
|
+
<div class="flex-1 p-4 overflow-y-auto space-y-4">
|
|
795
|
+
<div>
|
|
796
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2">Decision</div>
|
|
797
|
+
<div class="text-sm text-gray-900 dark:text-gray-100 leading-relaxed markdown-content" id="detail-decision"></div>
|
|
798
|
+
</div>
|
|
799
|
+
<div>
|
|
800
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2 cursor-pointer" onclick="toggleReasoning()">
|
|
801
|
+
<span id="reasoning-arrow">▶</span> Reasoning
|
|
802
|
+
</div>
|
|
803
|
+
<div class="text-sm text-gray-900 dark:text-gray-100 leading-relaxed markdown-content hidden" id="detail-reasoning"></div>
|
|
804
|
+
</div>
|
|
805
|
+
<div>
|
|
806
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2">Outcome</div>
|
|
807
|
+
<div class="flex items-center gap-2">
|
|
808
|
+
<select class="px-2 py-1 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-indigo-500" id="detail-outcome-select">
|
|
809
|
+
<option value="PENDING">PENDING</option>
|
|
810
|
+
<option value="SUCCESS">SUCCESS</option>
|
|
811
|
+
<option value="FAILED">FAILED</option>
|
|
812
|
+
<option value="PARTIAL">PARTIAL</option>
|
|
813
|
+
</select>
|
|
814
|
+
<button class="px-2 py-1 text-sm bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors" onclick="saveOutcome()">Save</button>
|
|
815
|
+
<span id="outcome-status"></span>
|
|
816
|
+
</div>
|
|
817
|
+
</div>
|
|
818
|
+
<div>
|
|
819
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2">Confidence</div>
|
|
820
|
+
<div class="text-sm text-gray-900 dark:text-gray-100" id="detail-confidence"></div>
|
|
821
|
+
</div>
|
|
822
|
+
<div>
|
|
823
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2">Created</div>
|
|
824
|
+
<div class="text-sm text-gray-900 dark:text-gray-100" id="detail-created"></div>
|
|
825
|
+
</div>
|
|
826
|
+
<div>
|
|
827
|
+
<div class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-2">Similar Decisions</div>
|
|
828
|
+
<div class="text-sm text-gray-900 dark:text-gray-100" id="detail-similar">
|
|
829
|
+
<span class="text-gray-400">Searching...</span>
|
|
830
|
+
</div>
|
|
831
|
+
</div>
|
|
832
|
+
</div>
|
|
833
|
+
</div>
|
|
834
|
+
|
|
835
|
+
<div class="tab-content active" id="tab-chat">
|
|
836
|
+
<div class="flex-1 flex flex-col w-full max-w-6xl mx-auto p-4 h-full">
|
|
837
|
+
<div class="flex-1 flex flex-col bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl overflow-hidden shadow-sm min-h-0" id="general-chat">
|
|
838
|
+
<div class="flex-1 overflow-y-auto p-4 flex flex-col gap-4 min-h-0" id="chat-messages">
|
|
839
|
+
<div class="flex-1 flex flex-col items-center justify-center text-center p-12 text-gray-500">
|
|
840
|
+
<svg
|
|
841
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
842
|
+
width="48"
|
|
843
|
+
height="48"
|
|
844
|
+
viewBox="0 0 24 24"
|
|
845
|
+
fill="none"
|
|
846
|
+
stroke="currentColor"
|
|
847
|
+
stroke-width="1.5"
|
|
848
|
+
stroke-linecap="round"
|
|
849
|
+
stroke-linejoin="round"
|
|
850
|
+
class="mb-4 opacity-50"
|
|
851
|
+
>
|
|
852
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
853
|
+
</svg>
|
|
854
|
+
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Start a conversation</h3>
|
|
855
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 max-w-sm leading-relaxed">
|
|
856
|
+
Connect to a Claude session to start chatting. Your conversation will be saved
|
|
857
|
+
and can be resumed later.
|
|
858
|
+
</p>
|
|
859
|
+
</div>
|
|
860
|
+
</div>
|
|
861
|
+
|
|
862
|
+
<div class="border-t border-gray-200 dark:border-gray-700 p-4 space-y-3">
|
|
863
|
+
<div class="flex gap-2">
|
|
864
|
+
<textarea
|
|
865
|
+
class="flex-1 px-3 py-2 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 placeholder-gray-500 resize-none focus:outline-none focus:ring-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
866
|
+
id="chat-input"
|
|
867
|
+
placeholder="Type your message..."
|
|
868
|
+
rows="2"
|
|
869
|
+
disabled
|
|
870
|
+
></textarea>
|
|
871
|
+
<button
|
|
872
|
+
class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 disabled:bg-gray-400 text-white rounded-lg font-medium transition-colors disabled:cursor-not-allowed flex items-center gap-2"
|
|
873
|
+
id="chat-send"
|
|
874
|
+
onclick="sendChatMessage()"
|
|
875
|
+
disabled
|
|
876
|
+
>
|
|
877
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
878
|
+
<line x1="22" y1="2" x2="11" y2="13" stroke-width="2" stroke-linecap="round"/>
|
|
879
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
880
|
+
</svg>
|
|
881
|
+
<span>Send</span>
|
|
882
|
+
</button>
|
|
883
|
+
</div>
|
|
884
|
+
|
|
885
|
+
<div class="flex items-center gap-2">
|
|
886
|
+
<button
|
|
887
|
+
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
|
888
|
+
id="chat-tts-toggle"
|
|
889
|
+
onclick="toggleTTS()"
|
|
890
|
+
title="TTS Off"
|
|
891
|
+
>
|
|
892
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
893
|
+
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
894
|
+
<path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
895
|
+
</svg>
|
|
896
|
+
</button>
|
|
897
|
+
<div class="relative">
|
|
898
|
+
<span class="text-xs text-gray-600 dark:text-gray-400 cursor-pointer px-2 py-1 hover:bg-gray-100 dark:hover:bg-gray-800 rounded" id="tts-speed-label" onclick="toggleTTSPopup()">
|
|
899
|
+
1.8x
|
|
900
|
+
</span>
|
|
901
|
+
<div class="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 shadow-lg hidden" id="tts-speed-popup">
|
|
902
|
+
<div class="text-center text-sm font-semibold mb-2" id="tts-speed-value">1.8x</div>
|
|
903
|
+
<input
|
|
904
|
+
type="range"
|
|
905
|
+
class="w-full accent-indigo-600"
|
|
906
|
+
id="tts-speed-slider"
|
|
907
|
+
min="0.5"
|
|
908
|
+
max="2.0"
|
|
909
|
+
step="0.1"
|
|
910
|
+
value="1.8"
|
|
911
|
+
oninput="updateTTSSpeed(this.value)"
|
|
912
|
+
/>
|
|
913
|
+
</div>
|
|
914
|
+
</div>
|
|
915
|
+
<button
|
|
916
|
+
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
|
917
|
+
id="chat-handsfree-toggle"
|
|
918
|
+
onclick="toggleHandsFree()"
|
|
919
|
+
title="Hands-free Off"
|
|
920
|
+
>
|
|
921
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
922
|
+
<circle cx="12" cy="12" r="2" stroke-width="2"/>
|
|
923
|
+
<path d="M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
924
|
+
</svg>
|
|
925
|
+
</button>
|
|
926
|
+
<button
|
|
927
|
+
class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors relative"
|
|
928
|
+
id="chat-mic"
|
|
929
|
+
onclick="toggleVoiceInput()"
|
|
930
|
+
title="Voice input"
|
|
931
|
+
>
|
|
932
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
933
|
+
<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
934
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
935
|
+
<line x1="12" y1="19" x2="12" y2="22" stroke-width="2" stroke-linecap="round"/>
|
|
936
|
+
</svg>
|
|
937
|
+
<span class="recording-dot absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full hidden"></span>
|
|
938
|
+
</button>
|
|
939
|
+
</div>
|
|
940
|
+
|
|
941
|
+
<div class="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400" id="chat-status">
|
|
942
|
+
<span class="status-indicator w-2 h-2 rounded-full bg-red-500"></span>
|
|
943
|
+
<span>Not connected</span>
|
|
944
|
+
<button
|
|
945
|
+
class="ml-2 p-1.5 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
|
946
|
+
onclick="showTunnelSetup()"
|
|
947
|
+
title="External Access"
|
|
948
|
+
>
|
|
949
|
+
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
950
|
+
<circle cx="12" cy="12" r="10" stroke-width="2"/>
|
|
951
|
+
<line x1="2" y1="12" x2="22" y2="12" stroke-width="2"/>
|
|
952
|
+
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" stroke-width="2"/>
|
|
953
|
+
</svg>
|
|
954
|
+
</button>
|
|
955
|
+
</div>
|
|
956
|
+
</div>
|
|
957
|
+
</div>
|
|
958
|
+
</div>
|
|
959
|
+
</div>
|
|
960
|
+
</div>
|
|
961
|
+
</main>
|
|
962
|
+
|
|
963
|
+
<div class="modal-overlay fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center" id="save-decision-modal">
|
|
964
|
+
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl shadow-2xl w-[90%] max-w-md max-h-[90vh] flex flex-col overflow-hidden">
|
|
965
|
+
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50">
|
|
966
|
+
<h3 class="flex items-center gap-2 text-base font-semibold text-gray-900 dark:text-gray-100">
|
|
967
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
968
|
+
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
|
969
|
+
<polyline points="17 21 17 13 7 13 7 21" />
|
|
970
|
+
<polyline points="7 3 7 8 15 8" />
|
|
971
|
+
</svg>
|
|
972
|
+
Save Decision
|
|
973
|
+
</h3>
|
|
974
|
+
<button class="p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-gray-500 hover:text-gray-700 dark:hover:text-gray-300" onclick="hideSaveDecisionForm()">
|
|
975
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
976
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
977
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
978
|
+
</svg>
|
|
979
|
+
</button>
|
|
980
|
+
</div>
|
|
981
|
+
<div class="p-4 space-y-4">
|
|
982
|
+
<div class="flex flex-col gap-2">
|
|
983
|
+
<label class="text-sm font-medium text-gray-900 dark:text-gray-100" for="save-topic">Topic</label>
|
|
984
|
+
<input
|
|
985
|
+
type="text"
|
|
986
|
+
class="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-colors"
|
|
987
|
+
id="save-topic"
|
|
988
|
+
placeholder="e.g., auth_strategy"
|
|
989
|
+
required
|
|
990
|
+
/>
|
|
991
|
+
</div>
|
|
992
|
+
<div class="flex flex-col gap-2">
|
|
993
|
+
<label class="text-sm font-medium text-gray-900 dark:text-gray-100" for="save-decision">Decision</label>
|
|
994
|
+
<textarea
|
|
995
|
+
class="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-colors resize-y min-h-[60px]"
|
|
996
|
+
id="save-decision"
|
|
997
|
+
placeholder="What did you decide?"
|
|
998
|
+
rows="2"
|
|
999
|
+
required
|
|
1000
|
+
></textarea>
|
|
1001
|
+
</div>
|
|
1002
|
+
<div class="flex flex-col gap-2">
|
|
1003
|
+
<label class="text-sm font-medium text-gray-900 dark:text-gray-100" for="save-reasoning">Reasoning</label>
|
|
1004
|
+
<textarea
|
|
1005
|
+
class="w-full px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-colors resize-y min-h-[100px]"
|
|
1006
|
+
id="save-reasoning"
|
|
1007
|
+
placeholder="Why did you make this decision?"
|
|
1008
|
+
rows="4"
|
|
1009
|
+
required
|
|
1010
|
+
></textarea>
|
|
1011
|
+
</div>
|
|
1012
|
+
<div class="flex flex-col gap-2">
|
|
1013
|
+
<label class="text-sm font-medium text-gray-900 dark:text-gray-100" for="save-confidence">Confidence (0.0 - 1.0)</label>
|
|
1014
|
+
<input
|
|
1015
|
+
type="number"
|
|
1016
|
+
class="w-28 px-3 py-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-colors"
|
|
1017
|
+
id="save-confidence"
|
|
1018
|
+
min="0"
|
|
1019
|
+
max="1"
|
|
1020
|
+
step="0.1"
|
|
1021
|
+
value="0.8"
|
|
1022
|
+
/>
|
|
1023
|
+
</div>
|
|
1024
|
+
</div>
|
|
1025
|
+
<div class="flex justify-end gap-2 px-4 py-3 border-t border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50">
|
|
1026
|
+
<button class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-lg transition-colors" onclick="hideSaveDecisionForm()">Cancel</button>
|
|
1027
|
+
<button class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors" onclick="submitSaveDecision()">Save</button>
|
|
1028
|
+
</div>
|
|
1029
|
+
<div id="save-form-status" class="px-5 pb-4 text-center text-sm"></div>
|
|
1030
|
+
</div>
|
|
1031
|
+
</div>
|
|
1032
|
+
|
|
1033
|
+
<div class="modal-overlay fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center" id="tunnel-setup-modal">
|
|
1034
|
+
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-xl shadow-2xl w-[90%] max-w-[600px] max-h-[90vh] flex flex-col overflow-hidden">
|
|
1035
|
+
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50">
|
|
1036
|
+
<h3 class="flex items-center gap-2 text-base font-semibold text-gray-900 dark:text-gray-100">
|
|
1037
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1038
|
+
<circle cx="12" cy="12" r="10" />
|
|
1039
|
+
<line x1="2" y1="12" x2="22" y2="12" />
|
|
1040
|
+
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
|
|
1041
|
+
</svg>
|
|
1042
|
+
External Access Setup
|
|
1043
|
+
</h3>
|
|
1044
|
+
<button class="p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-gray-500 hover:text-gray-700 dark:hover:text-gray-300" onclick="hideTunnelSetup()">
|
|
1045
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1046
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
1047
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
1048
|
+
</svg>
|
|
1049
|
+
</button>
|
|
1050
|
+
</div>
|
|
1051
|
+
<div class="flex-1 p-4 overflow-y-auto space-y-4">
|
|
1052
|
+
<!-- ngrok section -->
|
|
1053
|
+
<div class="bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
1054
|
+
<h4 class="text-sm text-indigo-600 dark:text-indigo-400 mb-2 flex items-center gap-1.5">
|
|
1055
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1056
|
+
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
|
1057
|
+
</svg>
|
|
1058
|
+
ngrok (Quick Setup)
|
|
1059
|
+
</h4>
|
|
1060
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Tunnel your local server to a public URL</p>
|
|
1061
|
+
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded px-3 py-2 flex items-center justify-between gap-2 mb-2">
|
|
1062
|
+
<code id="ngrok-command" class="font-mono text-sm text-green-600 dark:text-green-400">ngrok http 3847</code>
|
|
1063
|
+
<button class="p-1.5 rounded hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" onclick="copyNgrokCommand()">
|
|
1064
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1065
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
1066
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
1067
|
+
</svg>
|
|
1068
|
+
</button>
|
|
1069
|
+
</div>
|
|
1070
|
+
<a href="https://ngrok.com/download" target="_blank" rel="noopener noreferrer" class="text-xs text-indigo-600 dark:text-indigo-400 hover:underline flex items-center gap-1">
|
|
1071
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1072
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
1073
|
+
<polyline points="7 10 12 15 17 10" />
|
|
1074
|
+
<line x1="12" y1="15" x2="12" y2="3" />
|
|
1075
|
+
</svg>
|
|
1076
|
+
Download ngrok
|
|
1077
|
+
</a>
|
|
1078
|
+
</div>
|
|
1079
|
+
|
|
1080
|
+
<!-- Cloudflare section -->
|
|
1081
|
+
<div class="bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
|
1082
|
+
<h4 class="text-sm text-indigo-600 dark:text-indigo-400 mb-2 flex items-center gap-1.5">
|
|
1083
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1084
|
+
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
|
|
1085
|
+
</svg>
|
|
1086
|
+
Cloudflare Tunnel (Production)
|
|
1087
|
+
</h4>
|
|
1088
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">Secure tunnel with custom domain support</p>
|
|
1089
|
+
<a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/" target="_blank" rel="noopener noreferrer" class="text-xs text-indigo-600 dark:text-indigo-400 hover:underline flex items-center gap-1">
|
|
1090
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1091
|
+
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
|
1092
|
+
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
|
1093
|
+
</svg>
|
|
1094
|
+
Setup Guide
|
|
1095
|
+
</a>
|
|
1096
|
+
</div>
|
|
1097
|
+
|
|
1098
|
+
<!-- Security warning -->
|
|
1099
|
+
<div class="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700/50 rounded-lg p-3 flex gap-3">
|
|
1100
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-amber-500 flex-shrink-0 mt-0.5">
|
|
1101
|
+
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" />
|
|
1102
|
+
<line x1="12" y1="9" x2="12" y2="13" />
|
|
1103
|
+
<line x1="12" y1="17" x2="12.01" y2="17" />
|
|
1104
|
+
</svg>
|
|
1105
|
+
<div class="text-xs">
|
|
1106
|
+
<strong class="text-amber-600 dark:text-amber-400 block mb-1">Security Notice</strong>
|
|
1107
|
+
<span class="text-gray-700 dark:text-gray-300">Always set MAMA_AUTH_TOKEN environment variable before exposing your server externally.</span>
|
|
1108
|
+
<pre class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded px-2 py-1.5 mt-2 text-[11px] text-green-600 dark:text-green-400 overflow-x-auto">export MAMA_AUTH_TOKEN="your-secure-token-here"</pre>
|
|
1109
|
+
</div>
|
|
1110
|
+
</div>
|
|
1111
|
+
|
|
1112
|
+
<!-- Test connection -->
|
|
1113
|
+
<div class="border-t border-gray-200 dark:border-gray-800 pt-4">
|
|
1114
|
+
<button class="w-full px-4 py-2 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors flex items-center justify-center gap-2" onclick="testConnection()">
|
|
1115
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1116
|
+
<path d="M5 12.55a11 11 0 0 1 14.08 0" />
|
|
1117
|
+
<path d="M1.42 9a16 16 0 0 1 21.16 0" />
|
|
1118
|
+
<path d="M8.53 16.11a6 6 0 0 1 6.95 0" />
|
|
1119
|
+
<line x1="12" y1="20" x2="12.01" y2="20" />
|
|
1120
|
+
</svg>
|
|
1121
|
+
Test Connection
|
|
1122
|
+
</button>
|
|
1123
|
+
<div id="tunnel-test-result" class="mt-3 min-h-[40px]"></div>
|
|
1124
|
+
</div>
|
|
1125
|
+
</div>
|
|
1126
|
+
</div>
|
|
1127
|
+
</div>
|
|
1128
|
+
|
|
1129
|
+
<div class="toast" id="toast">
|
|
1130
|
+
<span id="toast-message"></span>
|
|
1131
|
+
</div>
|
|
1132
|
+
</div>
|
|
1133
|
+
|
|
1134
|
+
<script type="module">
|
|
1135
|
+
import { ChatModule } from '/viewer/js/modules/chat.js';
|
|
1136
|
+
import { GraphModule } from '/viewer/js/modules/graph.js';
|
|
1137
|
+
import { MemoryModule } from '/viewer/js/modules/memory.js';
|
|
1138
|
+
import { DashboardModule } from '/viewer/js/modules/dashboard.js';
|
|
1139
|
+
import { SettingsModule } from '/viewer/js/modules/settings.js';
|
|
1140
|
+
|
|
1141
|
+
const memory = new MemoryModule();
|
|
1142
|
+
const chat = new ChatModule(memory);
|
|
1143
|
+
const graph = new GraphModule();
|
|
1144
|
+
const dashboard = new DashboardModule();
|
|
1145
|
+
const settings = new SettingsModule();
|
|
1146
|
+
|
|
1147
|
+
// Expose modules globally for debugging and onclick handlers
|
|
1148
|
+
window.chatModule = chat;
|
|
1149
|
+
window.graphModule = graph;
|
|
1150
|
+
window.memoryModule = memory;
|
|
1151
|
+
window.dashboardModule = dashboard;
|
|
1152
|
+
window.settingsModule = settings;
|
|
1153
|
+
|
|
1154
|
+
// Quiz choice button handler
|
|
1155
|
+
window.sendQuizChoice = (choice) => {
|
|
1156
|
+
chat.sendQuizChoice(choice);
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
const STATE = {
|
|
1160
|
+
currentTab: 'chat',
|
|
1161
|
+
theme: 'dark',
|
|
1162
|
+
graphLoaded: false
|
|
1163
|
+
};
|
|
1164
|
+
|
|
1165
|
+
async function switchTab(tabName) {
|
|
1166
|
+
STATE.currentTab = tabName;
|
|
1167
|
+
|
|
1168
|
+
document.querySelectorAll('[data-tab]').forEach(btn => {
|
|
1169
|
+
const isActive = btn.dataset.tab === tabName;
|
|
1170
|
+
btn.classList.toggle('bg-indigo-100', isActive);
|
|
1171
|
+
btn.classList.toggle('dark:bg-indigo-900/30', isActive);
|
|
1172
|
+
btn.classList.toggle('text-indigo-600', isActive);
|
|
1173
|
+
btn.classList.toggle('dark:text-indigo-400', isActive);
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
document.querySelectorAll('.tab-content').forEach(content => {
|
|
1177
|
+
content.classList.toggle('active', content.id === `tab-${tabName}`);
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
if (tabName === 'chat') {
|
|
1181
|
+
chat.initSession();
|
|
1182
|
+
} else if (tabName === 'dashboard') {
|
|
1183
|
+
dashboard.init();
|
|
1184
|
+
} else if (tabName === 'settings') {
|
|
1185
|
+
settings.init();
|
|
1186
|
+
} else if (tabName === 'memory') {
|
|
1187
|
+
// Load checkpoints
|
|
1188
|
+
loadCheckpoints();
|
|
1189
|
+
|
|
1190
|
+
// Load memory stats for analytics bar
|
|
1191
|
+
updateMemoryStats();
|
|
1192
|
+
|
|
1193
|
+
// Load graph
|
|
1194
|
+
if (!STATE.graphLoaded) {
|
|
1195
|
+
try {
|
|
1196
|
+
const data = await graph.fetchData();
|
|
1197
|
+
graph.init(data);
|
|
1198
|
+
STATE.graphLoaded = true;
|
|
1199
|
+
const loadingEl = document.getElementById('graph-loading');
|
|
1200
|
+
if (loadingEl) loadingEl.style.display = 'none';
|
|
1201
|
+
} catch (error) {
|
|
1202
|
+
console.error('[MAMA] Failed to load graph:', error);
|
|
1203
|
+
const loadingEl = document.getElementById('graph-loading');
|
|
1204
|
+
if (loadingEl) loadingEl.innerHTML = '<span class="text-red-500">Failed to load graph data</span>';
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
function toggleTheme() {
|
|
1211
|
+
const html = document.documentElement;
|
|
1212
|
+
const isDark = html.classList.toggle('dark');
|
|
1213
|
+
STATE.theme = isDark ? 'dark' : 'light';
|
|
1214
|
+
|
|
1215
|
+
const lightIcon = document.getElementById('theme-icon-light');
|
|
1216
|
+
const darkIcon = document.getElementById('theme-icon-dark');
|
|
1217
|
+
|
|
1218
|
+
if (isDark) {
|
|
1219
|
+
lightIcon.style.display = 'none';
|
|
1220
|
+
darkIcon.style.display = 'block';
|
|
1221
|
+
} else {
|
|
1222
|
+
lightIcon.style.display = 'block';
|
|
1223
|
+
darkIcon.style.display = 'none';
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
localStorage.setItem('mama_theme', STATE.theme);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
function initTheme() {
|
|
1230
|
+
const saved = localStorage.getItem('mama_theme');
|
|
1231
|
+
const html = document.documentElement;
|
|
1232
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
1233
|
+
|
|
1234
|
+
const lightIcon = document.getElementById('theme-icon-light');
|
|
1235
|
+
const darkIcon = document.getElementById('theme-icon-dark');
|
|
1236
|
+
|
|
1237
|
+
if (saved === 'dark' || (!saved && prefersDark)) {
|
|
1238
|
+
html.classList.add('dark');
|
|
1239
|
+
STATE.theme = 'dark';
|
|
1240
|
+
lightIcon.style.display = 'none';
|
|
1241
|
+
darkIcon.style.display = 'block';
|
|
1242
|
+
} else {
|
|
1243
|
+
html.classList.remove('dark');
|
|
1244
|
+
STATE.theme = 'light';
|
|
1245
|
+
lightIcon.style.display = 'block';
|
|
1246
|
+
darkIcon.style.display = 'none';
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
function toggleLegend() {
|
|
1251
|
+
const panel = document.getElementById('legend-panel');
|
|
1252
|
+
panel.classList.toggle('visible');
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
function closeDetailModal() {
|
|
1256
|
+
const modal = document.getElementById('decision-detail-modal');
|
|
1257
|
+
modal.classList.remove('visible');
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
function toggleReasoning() {
|
|
1261
|
+
const reasoning = document.getElementById('detail-reasoning');
|
|
1262
|
+
const arrow = document.getElementById('reasoning-arrow');
|
|
1263
|
+
if (reasoning.classList.contains('hidden')) {
|
|
1264
|
+
reasoning.classList.remove('hidden');
|
|
1265
|
+
arrow.textContent = '▼';
|
|
1266
|
+
} else {
|
|
1267
|
+
reasoning.classList.add('hidden');
|
|
1268
|
+
arrow.textContent = '▶';
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
function showTunnelSetup() {
|
|
1273
|
+
const modal = document.getElementById('tunnel-setup-modal');
|
|
1274
|
+
modal.classList.add('visible');
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
function hideTunnelSetup() {
|
|
1278
|
+
const modal = document.getElementById('tunnel-setup-modal');
|
|
1279
|
+
modal.classList.remove('visible');
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
function showSaveDecisionForm() {
|
|
1283
|
+
memory.showSaveForm();
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
function hideSaveDecisionForm() {
|
|
1287
|
+
memory.hideSaveForm();
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
function submitSaveDecision() {
|
|
1291
|
+
memory.submitSaveForm();
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
function copyNgrokCommand() {
|
|
1295
|
+
const cmd = document.getElementById('ngrok-command').textContent;
|
|
1296
|
+
navigator.clipboard.writeText(cmd);
|
|
1297
|
+
alert('Copied: ' + cmd);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
function testConnection() {
|
|
1301
|
+
const result = document.getElementById('tunnel-test-result');
|
|
1302
|
+
result.innerHTML = '<span class="text-gray-500">Testing...</span>';
|
|
1303
|
+
fetch('/health')
|
|
1304
|
+
.then(r => r.ok ? result.innerHTML = '<span class="text-green-500">Connection OK</span>'
|
|
1305
|
+
: result.innerHTML = '<span class="text-red-500">Connection failed</span>')
|
|
1306
|
+
.catch(() => result.innerHTML = '<span class="text-red-500">Connection failed</span>');
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
function sendChatMessage() {
|
|
1310
|
+
chat.send();
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
// Send quiz choice as message
|
|
1314
|
+
window.sendQuizChoice = function(choice) {
|
|
1315
|
+
if (chat && chat.ws && chat.ws.readyState === WebSocket.OPEN) {
|
|
1316
|
+
// Set the input to the choice and send
|
|
1317
|
+
const input = document.getElementById('chat-input');
|
|
1318
|
+
if (input) {
|
|
1319
|
+
input.value = choice;
|
|
1320
|
+
chat.send();
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
function toggleTTS() {
|
|
1326
|
+
chat.toggleTTS && chat.toggleTTS();
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
function toggleTTSPopup() {
|
|
1330
|
+
const popup = document.getElementById('tts-speed-popup');
|
|
1331
|
+
popup.classList.toggle('hidden');
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
function updateTTSSpeed(value) {
|
|
1335
|
+
document.getElementById('tts-speed-label').textContent = value + 'x';
|
|
1336
|
+
document.getElementById('tts-speed-value').textContent = value + 'x';
|
|
1337
|
+
chat.setTTSSpeed && chat.setTTSSpeed(parseFloat(value));
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
function toggleHandsFree() {
|
|
1341
|
+
chat.toggleHandsFree && chat.toggleHandsFree();
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
function toggleVoiceInput() {
|
|
1345
|
+
chat.toggleVoiceInput && chat.toggleVoiceInput();
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
function filterByTopic(topic) {
|
|
1349
|
+
graph.filterByTopic && graph.filterByTopic(topic);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
function filterByOutcome(outcome) {
|
|
1353
|
+
graph.filterByOutcome && graph.filterByOutcome(outcome);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
function clearFilters() {
|
|
1357
|
+
document.getElementById('topic-filter').value = '';
|
|
1358
|
+
document.getElementById('outcome-filter').value = '';
|
|
1359
|
+
document.getElementById('search-input').value = '';
|
|
1360
|
+
graph.clearFilters && graph.clearFilters();
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
async function exportDecisions(format) {
|
|
1364
|
+
try {
|
|
1365
|
+
const response = await fetch(`/api/memory/export?format=${format}`);
|
|
1366
|
+
if (!response.ok) throw new Error('Export failed');
|
|
1367
|
+
|
|
1368
|
+
const blob = await response.blob();
|
|
1369
|
+
const filename = response.headers.get('Content-Disposition')?.match(/filename="(.+)"/)?.[1]
|
|
1370
|
+
|| `mama-export.${format}`;
|
|
1371
|
+
|
|
1372
|
+
const url = URL.createObjectURL(blob);
|
|
1373
|
+
const a = document.createElement('a');
|
|
1374
|
+
a.href = url;
|
|
1375
|
+
a.download = filename;
|
|
1376
|
+
document.body.appendChild(a);
|
|
1377
|
+
a.click();
|
|
1378
|
+
document.body.removeChild(a);
|
|
1379
|
+
URL.revokeObjectURL(url);
|
|
1380
|
+
} catch (error) {
|
|
1381
|
+
console.error('[Export] Error:', error);
|
|
1382
|
+
alert('Export failed: ' + error.message);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
async function updateMemoryStats() {
|
|
1387
|
+
try {
|
|
1388
|
+
const response = await fetch('/api/dashboard/status');
|
|
1389
|
+
if (!response.ok) return;
|
|
1390
|
+
|
|
1391
|
+
const data = await response.json();
|
|
1392
|
+
const memory = data.memory || {};
|
|
1393
|
+
|
|
1394
|
+
document.querySelector('#memory-stats-total p').textContent = memory.total || 0;
|
|
1395
|
+
document.querySelector('#memory-stats-week p').textContent = memory.thisWeek || 0;
|
|
1396
|
+
document.getElementById('outcome-success').textContent = memory.outcomes?.success || 0;
|
|
1397
|
+
document.getElementById('outcome-failed').textContent = memory.outcomes?.failed || 0;
|
|
1398
|
+
document.getElementById('outcome-partial').textContent = memory.outcomes?.partial || 0;
|
|
1399
|
+
} catch (error) {
|
|
1400
|
+
console.error('[MemoryStats] Error:', error);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
function handleGraphSearch(event) {
|
|
1405
|
+
if (event.key === 'Enter') {
|
|
1406
|
+
graph.search && graph.search();
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function saveOutcome() {
|
|
1411
|
+
const select = document.getElementById('detail-outcome-select');
|
|
1412
|
+
const outcome = select.value;
|
|
1413
|
+
const nodeId = graph.currentNodeId;
|
|
1414
|
+
if (nodeId && outcome) {
|
|
1415
|
+
graph.updateOutcome && graph.updateOutcome(nodeId, outcome);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
let checkpointsData = [];
|
|
1420
|
+
|
|
1421
|
+
function renderMarkdown(text) {
|
|
1422
|
+
if (!text) return '';
|
|
1423
|
+
try {
|
|
1424
|
+
if (typeof marked !== 'undefined' && marked.parse) {
|
|
1425
|
+
return marked.parse(text);
|
|
1426
|
+
}
|
|
1427
|
+
} catch (e) {
|
|
1428
|
+
console.error('[MAMA] Markdown parse error:', e);
|
|
1429
|
+
}
|
|
1430
|
+
return text.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>');
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
async function loadCheckpoints() {
|
|
1434
|
+
const container = document.getElementById('checkpoint-list');
|
|
1435
|
+
if (!container) {
|
|
1436
|
+
console.error('[MAMA] checkpoint-list container not found');
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
console.log('[MAMA] Loading checkpoints...');
|
|
1441
|
+
|
|
1442
|
+
try {
|
|
1443
|
+
const response = await fetch('/api/checkpoints');
|
|
1444
|
+
const data = await response.json();
|
|
1445
|
+
checkpointsData = data.checkpoints || [];
|
|
1446
|
+
|
|
1447
|
+
console.log('[MAMA] Loaded', checkpointsData.length, 'checkpoints');
|
|
1448
|
+
|
|
1449
|
+
if (checkpointsData.length > 0) {
|
|
1450
|
+
container.innerHTML = checkpointsData.map((cp, idx) => {
|
|
1451
|
+
const fullSummary = renderMarkdown(cp.summary || '');
|
|
1452
|
+
return `
|
|
1453
|
+
<div class="checkpoint-item p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer hover:border-indigo-500 transition-colors" onclick="toggleCheckpoint(${idx})">
|
|
1454
|
+
<div class="text-xs font-semibold text-indigo-600 dark:text-indigo-400 mb-1">${new Date(cp.timestamp).toLocaleString()}</div>
|
|
1455
|
+
<div class="checkpoint-summary text-sm text-gray-700 dark:text-gray-300 markdown-content line-clamp-3 overflow-hidden">${fullSummary}</div>
|
|
1456
|
+
<div class="checkpoint-details hidden mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
|
1457
|
+
<div class="text-sm text-gray-700 dark:text-gray-300 markdown-content max-h-64 overflow-y-auto">${fullSummary}</div>
|
|
1458
|
+
</div>
|
|
1459
|
+
</div>
|
|
1460
|
+
`}).join('');
|
|
1461
|
+
} else {
|
|
1462
|
+
container.innerHTML = '<div class="text-center text-sm text-gray-500 py-4">No checkpoints found</div>';
|
|
1463
|
+
}
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
console.error('[MAMA] Failed to load checkpoints:', error);
|
|
1466
|
+
container.innerHTML = '<div class="text-center text-sm text-red-500 py-4">Failed to load checkpoints</div>';
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
function toggleCheckpoint(idx) {
|
|
1471
|
+
const items = document.querySelectorAll('.checkpoint-item');
|
|
1472
|
+
items.forEach((item, i) => {
|
|
1473
|
+
const details = item.querySelector('.checkpoint-details');
|
|
1474
|
+
const summary = item.querySelector('.checkpoint-summary');
|
|
1475
|
+
if (i === idx) {
|
|
1476
|
+
const isExpanded = !details.classList.contains('hidden');
|
|
1477
|
+
details.classList.toggle('hidden');
|
|
1478
|
+
summary.classList.toggle('hidden', !isExpanded);
|
|
1479
|
+
item.classList.toggle('border-indigo-500', !isExpanded);
|
|
1480
|
+
} else {
|
|
1481
|
+
details.classList.add('hidden');
|
|
1482
|
+
summary.classList.remove('hidden');
|
|
1483
|
+
item.classList.remove('border-indigo-500');
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// Expose to window for onclick handlers
|
|
1489
|
+
window.switchTab = switchTab;
|
|
1490
|
+
window.toggleTheme = toggleTheme;
|
|
1491
|
+
window.toggleLegend = toggleLegend;
|
|
1492
|
+
window.closeDetailModal = closeDetailModal;
|
|
1493
|
+
window.toggleReasoning = toggleReasoning;
|
|
1494
|
+
window.showTunnelSetup = showTunnelSetup;
|
|
1495
|
+
window.hideTunnelSetup = hideTunnelSetup;
|
|
1496
|
+
window.showSaveDecisionForm = showSaveDecisionForm;
|
|
1497
|
+
window.hideSaveDecisionForm = hideSaveDecisionForm;
|
|
1498
|
+
window.submitSaveDecision = submitSaveDecision;
|
|
1499
|
+
window.copyNgrokCommand = copyNgrokCommand;
|
|
1500
|
+
window.testConnection = testConnection;
|
|
1501
|
+
window.sendChatMessage = sendChatMessage;
|
|
1502
|
+
window.toggleTTS = toggleTTS;
|
|
1503
|
+
window.toggleTTSPopup = toggleTTSPopup;
|
|
1504
|
+
window.updateTTSSpeed = updateTTSSpeed;
|
|
1505
|
+
window.toggleHandsFree = toggleHandsFree;
|
|
1506
|
+
window.toggleVoiceInput = toggleVoiceInput;
|
|
1507
|
+
window.filterByTopic = filterByTopic;
|
|
1508
|
+
window.handleGraphSearch = handleGraphSearch;
|
|
1509
|
+
window.saveOutcome = saveOutcome;
|
|
1510
|
+
window.loadCheckpoints = loadCheckpoints;
|
|
1511
|
+
window.toggleCheckpoint = toggleCheckpoint;
|
|
1512
|
+
|
|
1513
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
1514
|
+
const userLang = navigator.language || navigator.userLanguage;
|
|
1515
|
+
document.documentElement.lang = userLang.split('-')[0];
|
|
1516
|
+
|
|
1517
|
+
initTheme();
|
|
1518
|
+
switchTab('chat');
|
|
1519
|
+
});
|
|
1520
|
+
|
|
1521
|
+
// Cleanup resources on page unload
|
|
1522
|
+
window.addEventListener('beforeunload', () => {
|
|
1523
|
+
// Cleanup dashboard intervals
|
|
1524
|
+
if (window.dashboardModule?.cleanup) {
|
|
1525
|
+
window.dashboardModule.cleanup();
|
|
1526
|
+
}
|
|
1527
|
+
// Cleanup chat resources
|
|
1528
|
+
if (window.chatModule?.cleanup) {
|
|
1529
|
+
window.chatModule.cleanup();
|
|
1530
|
+
}
|
|
1531
|
+
console.log('[MAMA] Resources cleaned up');
|
|
1532
|
+
});
|
|
1533
|
+
</script>
|
|
1534
|
+
</body>
|
|
1535
|
+
</html>
|