@jungjaehoon/mama-os 0.18.2 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-loop.d.ts +25 -0
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +67 -14
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +98 -0
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
- package/dist/agent/code-act/type-definition-generator.js +0 -1
- package/dist/agent/code-act/type-definition-generator.js.map +1 -1
- package/dist/agent/gateway-tool-executor.d.ts +36 -1
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +938 -54
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +9 -0
- package/dist/agent/managed-agent-runtime-sync.d.ts +36 -0
- package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -0
- package/dist/agent/managed-agent-runtime-sync.js +207 -0
- package/dist/agent/managed-agent-runtime-sync.js.map +1 -0
- package/dist/agent/managed-agent-validation.d.ts +4 -0
- package/dist/agent/managed-agent-validation.d.ts.map +1 -0
- package/dist/agent/managed-agent-validation.js +84 -0
- package/dist/agent/managed-agent-validation.js.map +1 -0
- package/dist/agent/os-agent-capabilities.md +400 -0
- package/dist/agent/skill-loader.d.ts +2 -0
- package/dist/agent/skill-loader.d.ts.map +1 -1
- package/dist/agent/skill-loader.js +28 -0
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +66 -0
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +2 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/agent-handler.d.ts +34 -0
- package/dist/api/agent-handler.d.ts.map +1 -0
- package/dist/api/agent-handler.js +216 -0
- package/dist/api/agent-handler.js.map +1 -0
- package/dist/api/graph-api-types.d.ts +4 -0
- package/dist/api/graph-api-types.d.ts.map +1 -1
- package/dist/api/graph-api.d.ts +2 -2
- package/dist/api/graph-api.d.ts.map +1 -1
- package/dist/api/graph-api.js +480 -51
- package/dist/api/graph-api.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/token-handler.d.ts +1 -0
- package/dist/api/token-handler.d.ts.map +1 -1
- package/dist/api/token-handler.js +4 -3
- package/dist/api/token-handler.js.map +1 -1
- package/dist/api/ui-command-handler.d.ts +48 -0
- package/dist/api/ui-command-handler.d.ts.map +1 -0
- package/dist/api/ui-command-handler.js +160 -0
- package/dist/api/ui-command-handler.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +127 -1
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/config-manager.d.ts.map +1 -1
- package/dist/cli/config/config-manager.js +16 -31
- package/dist/cli/config/config-manager.js.map +1 -1
- package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
- package/dist/cli/runtime/agent-loop-init.js +31 -7
- package/dist/cli/runtime/agent-loop-init.js.map +1 -1
- package/dist/cli/runtime/api-routes-init.d.ts +3 -0
- package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-routes-init.js +283 -34
- package/dist/cli/runtime/api-routes-init.js.map +1 -1
- package/dist/cli/runtime/gateway-init.d.ts +2 -1
- package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
- package/dist/cli/runtime/gateway-init.js +5 -1
- package/dist/cli/runtime/gateway-init.js.map +1 -1
- package/dist/connectors/framework/raw-store.d.ts +4 -0
- package/dist/connectors/framework/raw-store.d.ts.map +1 -1
- package/dist/connectors/framework/raw-store.js +33 -10
- package/dist/connectors/framework/raw-store.js.map +1 -1
- package/dist/db/agent-store.d.ts +115 -0
- package/dist/db/agent-store.d.ts.map +1 -0
- package/dist/db/agent-store.js +248 -0
- package/dist/db/agent-store.js.map +1 -0
- package/dist/db/migrations/agent-activity-validation-columns.d.ts +3 -0
- package/dist/db/migrations/agent-activity-validation-columns.d.ts.map +1 -0
- package/dist/db/migrations/agent-activity-validation-columns.js +22 -0
- package/dist/db/migrations/agent-activity-validation-columns.js.map +1 -0
- package/dist/db/migrations/agent-metrics-response-avg.d.ts +3 -0
- package/dist/db/migrations/agent-metrics-response-avg.d.ts.map +1 -0
- package/dist/db/migrations/agent-metrics-response-avg.js +19 -0
- package/dist/db/migrations/agent-metrics-response-avg.js.map +1 -0
- package/dist/db/migrations/agent-store-tables.d.ts +3 -0
- package/dist/db/migrations/agent-store-tables.d.ts.map +1 -0
- package/dist/db/migrations/agent-store-tables.js +59 -0
- package/dist/db/migrations/agent-store-tables.js.map +1 -0
- package/dist/db/migrations/token-usage-agent-version.d.ts +3 -0
- package/dist/db/migrations/token-usage-agent-version.d.ts.map +1 -0
- package/dist/db/migrations/token-usage-agent-version.js +16 -0
- package/dist/db/migrations/token-usage-agent-version.js.map +1 -0
- package/dist/db/migrations/validation-session-tables.d.ts +3 -0
- package/dist/db/migrations/validation-session-tables.d.ts.map +1 -0
- package/dist/db/migrations/validation-session-tables.js +59 -0
- package/dist/db/migrations/validation-session-tables.js.map +1 -0
- package/dist/gateways/message-router.d.ts +10 -0
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +188 -14
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/gateways/types.d.ts +1 -1
- package/dist/gateways/types.d.ts.map +1 -1
- package/dist/multi-agent/agent-process-manager.js +1 -1
- package/dist/multi-agent/agent-process-manager.js.map +1 -1
- package/dist/multi-agent/conductor-persona.d.ts +13 -0
- package/dist/multi-agent/conductor-persona.d.ts.map +1 -0
- package/dist/multi-agent/conductor-persona.js +157 -0
- package/dist/multi-agent/conductor-persona.js.map +1 -0
- package/dist/multi-agent/dashboard-agent-persona.d.ts +1 -1
- package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.js +7 -3
- package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
- package/dist/multi-agent/delegation-manager.d.ts +5 -0
- package/dist/multi-agent/delegation-manager.d.ts.map +1 -1
- package/dist/multi-agent/delegation-manager.js +37 -0
- package/dist/multi-agent/delegation-manager.js.map +1 -1
- package/dist/multi-agent/ultrawork.d.ts +3 -0
- package/dist/multi-agent/ultrawork.d.ts.map +1 -1
- package/dist/multi-agent/ultrawork.js +9 -0
- package/dist/multi-agent/ultrawork.js.map +1 -1
- package/dist/validation/session-service.d.ts +72 -0
- package/dist/validation/session-service.d.ts.map +1 -0
- package/dist/validation/session-service.js +298 -0
- package/dist/validation/session-service.js.map +1 -0
- package/dist/validation/store.d.ts +25 -0
- package/dist/validation/store.d.ts.map +1 -0
- package/dist/validation/store.js +200 -0
- package/dist/validation/store.js.map +1 -0
- package/dist/validation/types.d.ts +119 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +57 -0
- package/dist/validation/types.js.map +1 -0
- package/package.json +3 -3
- package/public/viewer/js/modules/agents.js +1148 -0
- package/public/viewer/js/modules/chat.js +20 -11
- package/public/viewer/js/modules/connector-feed.js +35 -0
- package/public/viewer/js/modules/dashboard.js +49 -0
- package/public/viewer/js/modules/memory.js +32 -0
- package/public/viewer/js/modules/settings.js +34 -79
- package/public/viewer/js/modules/wiki.js +59 -4
- package/public/viewer/js/utils/api.js +70 -0
- package/public/viewer/js/utils/dom.js +3 -0
- package/public/viewer/js/utils/ui-commands.js +93 -0
- package/public/viewer/log-viewer.html +2 -2
- package/public/viewer/src/modules/agents.ts +1299 -0
- package/public/viewer/src/modules/chat.ts +23 -14
- package/public/viewer/src/modules/connector-feed.ts +35 -0
- package/public/viewer/src/modules/dashboard.ts +50 -0
- package/public/viewer/src/modules/memory.ts +31 -0
- package/public/viewer/src/modules/settings.ts +36 -96
- package/public/viewer/src/modules/wiki.ts +73 -6
- package/public/viewer/src/types/global.d.ts +0 -9
- package/public/viewer/src/utils/api.ts +156 -2
- package/public/viewer/src/utils/dom.ts +6 -1
- package/public/viewer/src/utils/ui-commands.ts +118 -0
- package/public/viewer/viewer.css +105 -10
- package/public/viewer/viewer.html +1868 -777
- package/scripts/generate-gateway-tools.ts +5 -1
- package/public/viewer/js/modules/playground.js +0 -148
- package/public/viewer/js/modules/skills.js +0 -451
- package/public/viewer/src/modules/playground.ts +0 -173
- package/public/viewer/src/modules/skills.ts +0 -491
- package/templates/playgrounds/cron-workflow-lab.html +0 -1601
- package/templates/playgrounds/mama-log-viewer.html +0 -1341
- package/templates/playgrounds/skill-lab-playground.html +0 -1625
- package/templates/playgrounds/wave-visualizer.html +0 -694
- package/templates/skills/playground.md +0 -197
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
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
|
-
/>
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
6
|
<title>MAMA - Memory-Augmented Assistant</title>
|
|
10
7
|
|
|
11
8
|
<meta name="theme-color" content="#F9F7F4" />
|
|
@@ -39,7 +36,10 @@
|
|
|
39
36
|
<script defer src="https://unpkg.com/vis-network@9/dist/vis-network.min.js"></script>
|
|
40
37
|
<script defer src="https://unpkg.com/lucide@0.460.0"></script>
|
|
41
38
|
<script defer src="https://cdn.jsdelivr.net/npm/marked@11/marked.min.js"></script>
|
|
42
|
-
<script
|
|
39
|
+
<script
|
|
40
|
+
defer
|
|
41
|
+
src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.5/purify.min.js"
|
|
42
|
+
></script>
|
|
43
43
|
<!-- Tailwind must load synchronously -->
|
|
44
44
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
45
45
|
<script>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
},
|
|
77
77
|
spacing: {
|
|
78
|
-
|
|
78
|
+
sidebar: 'var(--sidebar-width)',
|
|
79
79
|
},
|
|
80
80
|
borderRadius: {
|
|
81
81
|
DEFAULT: 'var(--radius)',
|
|
@@ -90,25 +90,25 @@
|
|
|
90
90
|
mono: ['var(--font-mono)', 'monospace'],
|
|
91
91
|
},
|
|
92
92
|
boxShadow: {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
soft: '0 4px 20px rgba(19, 19, 19, 0.08)',
|
|
94
|
+
medium: '0 8px 32px rgba(19, 19, 19, 0.12)',
|
|
95
|
+
float: '0 12px 40px rgba(19, 19, 19, 0.15)',
|
|
96
|
+
yellow: '0 4px 20px rgba(255, 206, 0, 0.4)',
|
|
97
97
|
},
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
101
|
</script>
|
|
102
102
|
<style>
|
|
103
103
|
:root {
|
|
104
104
|
/* MAMA Brand Colors */
|
|
105
|
-
--mama-yellow: #
|
|
106
|
-
--mama-yellow-hover: #
|
|
107
|
-
--mama-lavender: #
|
|
108
|
-
--mama-lavender-light: #
|
|
109
|
-
--mama-lavender-dark: #
|
|
105
|
+
--mama-yellow: #ffce00;
|
|
106
|
+
--mama-yellow-hover: #e6b800;
|
|
107
|
+
--mama-lavender: #eddbf7;
|
|
108
|
+
--mama-lavender-light: #f5ebf9;
|
|
109
|
+
--mama-lavender-dark: #d4c4e0;
|
|
110
110
|
--mama-black: #131313;
|
|
111
|
-
--mama-blush: #
|
|
111
|
+
--mama-blush: #ff9999;
|
|
112
112
|
|
|
113
113
|
/* Radius hierarchy: outer > inner > button */
|
|
114
114
|
--radius-card: 12px;
|
|
@@ -117,23 +117,23 @@
|
|
|
117
117
|
--radius-pill: 9999px;
|
|
118
118
|
|
|
119
119
|
/* Semantic Colors (HSL for Tailwind) */
|
|
120
|
-
--background: 40 20% 97%;
|
|
121
|
-
--foreground: 0 0% 7%;
|
|
122
|
-
--card: 0 0% 100%;
|
|
120
|
+
--background: 40 20% 97%; /* warm off-white */
|
|
121
|
+
--foreground: 0 0% 7%; /* black */
|
|
122
|
+
--card: 0 0% 100%; /* white */
|
|
123
123
|
--card-foreground: 0 0% 7%;
|
|
124
|
-
--border: 0 0% 89%;
|
|
125
|
-
--muted: 40 15% 95%;
|
|
124
|
+
--border: 0 0% 89%; /* light gray */
|
|
125
|
+
--muted: 40 15% 95%; /* warm muted */
|
|
126
126
|
--muted-foreground: 0 0% 45%;
|
|
127
|
-
--primary: 48 100% 50%;
|
|
127
|
+
--primary: 48 100% 50%; /* yellow */
|
|
128
128
|
--primary-foreground: 0 0% 7%;
|
|
129
|
-
--secondary: 280 40% 95%;
|
|
129
|
+
--secondary: 280 40% 95%; /* subtle lavender accent */
|
|
130
130
|
--secondary-foreground: 0 0% 7%;
|
|
131
131
|
--destructive: 0 84% 60%;
|
|
132
132
|
--destructive-foreground: 0 0% 98%;
|
|
133
133
|
--success: 142 76% 36%;
|
|
134
134
|
--warning: 38 92% 50%;
|
|
135
135
|
--info: 199 89% 48%;
|
|
136
|
-
--ring: 48 100% 50%;
|
|
136
|
+
--ring: 48 100% 50%; /* yellow */
|
|
137
137
|
|
|
138
138
|
/* Layout */
|
|
139
139
|
--radius: 0.75rem;
|
|
@@ -148,86 +148,174 @@
|
|
|
148
148
|
|
|
149
149
|
/* ── Sidebar Navigation ── */
|
|
150
150
|
#mama-sidebar {
|
|
151
|
-
position: fixed;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
position: fixed;
|
|
152
|
+
left: 0;
|
|
153
|
+
top: 0;
|
|
154
|
+
height: 100vh;
|
|
155
|
+
width: var(--sidebar-width);
|
|
156
|
+
background: #ffffff;
|
|
157
|
+
border-right: 1px solid #ede9e1;
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
align-items: center;
|
|
161
|
+
padding: 16px 0;
|
|
162
|
+
z-index: 100;
|
|
163
|
+
transition: width 0.2s ease;
|
|
156
164
|
overflow: hidden;
|
|
157
165
|
}
|
|
158
166
|
#mama-sidebar:hover {
|
|
159
167
|
width: var(--sidebar-width-expanded);
|
|
160
|
-
box-shadow: 4px 0 24px rgba(0,0,0,0.06);
|
|
168
|
+
box-shadow: 4px 0 24px rgba(0, 0, 0, 0.06);
|
|
161
169
|
}
|
|
162
170
|
.mama-sidebar-logo {
|
|
163
|
-
display: flex;
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
gap: 10px;
|
|
174
|
+
width: 100%;
|
|
175
|
+
padding: 0 14px;
|
|
176
|
+
margin-bottom: 24px;
|
|
177
|
+
text-decoration: none;
|
|
178
|
+
color: #1a1a1a;
|
|
179
|
+
white-space: nowrap;
|
|
180
|
+
}
|
|
181
|
+
.mama-sidebar-logo img {
|
|
182
|
+
flex-shrink: 0;
|
|
166
183
|
}
|
|
167
|
-
.mama-sidebar-logo img { flex-shrink: 0; }
|
|
168
184
|
.mama-sidebar-logo span {
|
|
169
|
-
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
|
170
|
-
font-
|
|
185
|
+
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
|
186
|
+
font-weight: 700;
|
|
187
|
+
font-size: 16px;
|
|
188
|
+
opacity: 0;
|
|
189
|
+
transition: opacity 0.15s ease;
|
|
190
|
+
}
|
|
191
|
+
#mama-sidebar:hover .mama-sidebar-logo span {
|
|
192
|
+
opacity: 1;
|
|
171
193
|
}
|
|
172
|
-
#mama-sidebar:hover .mama-sidebar-logo span { opacity: 1; }
|
|
173
194
|
|
|
174
195
|
.mama-nav-items {
|
|
175
|
-
display: flex;
|
|
176
|
-
|
|
196
|
+
display: flex;
|
|
197
|
+
flex-direction: column;
|
|
198
|
+
gap: 4px;
|
|
199
|
+
width: 100%;
|
|
200
|
+
padding: 0 8px;
|
|
177
201
|
}
|
|
178
202
|
.mama-nav-item {
|
|
179
|
-
position: relative;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
203
|
+
position: relative;
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
gap: 12px;
|
|
207
|
+
width: 100%;
|
|
208
|
+
height: 40px;
|
|
209
|
+
padding: 0 12px;
|
|
210
|
+
border-radius: 6px;
|
|
211
|
+
border: none;
|
|
212
|
+
background: transparent;
|
|
213
|
+
color: #6b6560;
|
|
214
|
+
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
|
215
|
+
font-size: 13px;
|
|
216
|
+
font-weight: 600;
|
|
217
|
+
cursor: pointer;
|
|
218
|
+
transition:
|
|
219
|
+
background 0.15s ease,
|
|
220
|
+
color 0.15s ease;
|
|
221
|
+
white-space: nowrap;
|
|
222
|
+
overflow: hidden;
|
|
223
|
+
}
|
|
224
|
+
.mama-nav-item:hover {
|
|
225
|
+
background: #f9f7f4;
|
|
226
|
+
color: #1a1a1a;
|
|
227
|
+
}
|
|
188
228
|
.mama-nav-item i,
|
|
189
|
-
.mama-nav-item svg {
|
|
229
|
+
.mama-nav-item svg {
|
|
230
|
+
flex-shrink: 0;
|
|
231
|
+
width: 18px;
|
|
232
|
+
height: 18px;
|
|
233
|
+
}
|
|
190
234
|
.mama-nav-item span {
|
|
191
|
-
opacity: 0;
|
|
235
|
+
opacity: 0;
|
|
236
|
+
transition: opacity 0.15s ease;
|
|
237
|
+
}
|
|
238
|
+
#mama-sidebar:hover .mama-nav-item span {
|
|
239
|
+
opacity: 1;
|
|
192
240
|
}
|
|
193
|
-
#mama-sidebar:hover .mama-nav-item span { opacity: 1; }
|
|
194
241
|
|
|
195
242
|
.mama-nav-item.mama-nav-active {
|
|
196
|
-
color: #
|
|
243
|
+
color: #1a1a1a;
|
|
244
|
+
background: #fef9e7;
|
|
197
245
|
}
|
|
198
246
|
.mama-nav-item.mama-nav-active::before {
|
|
199
|
-
content: '';
|
|
200
|
-
|
|
201
|
-
|
|
247
|
+
content: '';
|
|
248
|
+
position: absolute;
|
|
249
|
+
left: -8px;
|
|
250
|
+
top: 8px;
|
|
251
|
+
width: 3px;
|
|
252
|
+
height: 24px;
|
|
253
|
+
border-radius: 0 3px 3px 0;
|
|
254
|
+
background: #ffce00;
|
|
202
255
|
}
|
|
203
256
|
|
|
204
257
|
/* ── Mobile bottom tab bar ── */
|
|
205
258
|
#mama-mobile-tabs {
|
|
206
|
-
display: none;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
259
|
+
display: none;
|
|
260
|
+
position: fixed;
|
|
261
|
+
bottom: 0;
|
|
262
|
+
left: 0;
|
|
263
|
+
right: 0;
|
|
264
|
+
height: 64px;
|
|
265
|
+
background: #ffffff;
|
|
266
|
+
border-top: 1px solid #ede9e1;
|
|
267
|
+
z-index: 100;
|
|
268
|
+
padding: 0 8px;
|
|
269
|
+
align-items: center;
|
|
270
|
+
justify-content: space-around;
|
|
210
271
|
}
|
|
211
272
|
.mama-mobile-tab {
|
|
212
|
-
display: flex;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
273
|
+
display: flex;
|
|
274
|
+
flex-direction: column;
|
|
275
|
+
align-items: center;
|
|
276
|
+
gap: 2px;
|
|
277
|
+
padding: 8px 12px;
|
|
278
|
+
border: none;
|
|
279
|
+
background: transparent;
|
|
280
|
+
color: #6b6560;
|
|
281
|
+
font-size: 10px;
|
|
282
|
+
font-weight: 600;
|
|
283
|
+
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
|
284
|
+
cursor: pointer;
|
|
216
285
|
transition: color 0.15s ease;
|
|
217
286
|
}
|
|
218
287
|
.mama-mobile-tab i,
|
|
219
|
-
.mama-mobile-tab svg {
|
|
220
|
-
|
|
288
|
+
.mama-mobile-tab svg {
|
|
289
|
+
width: 20px;
|
|
290
|
+
height: 20px;
|
|
291
|
+
}
|
|
292
|
+
.mama-mobile-tab.mama-nav-active {
|
|
293
|
+
color: #ffce00;
|
|
294
|
+
position: relative;
|
|
295
|
+
}
|
|
296
|
+
.mama-mobile-tab.mama-nav-active::after {
|
|
297
|
+
content: '';
|
|
298
|
+
position: absolute;
|
|
299
|
+
top: 0;
|
|
300
|
+
left: 50%;
|
|
301
|
+
transform: translateX(-50%);
|
|
302
|
+
width: 24px;
|
|
303
|
+
height: 2px;
|
|
304
|
+
border-radius: 1px;
|
|
305
|
+
background: #ffce00;
|
|
306
|
+
}
|
|
221
307
|
|
|
222
308
|
/* ── Slot container ── */
|
|
223
309
|
.mama-slots-container {
|
|
224
|
-
display: flex;
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: column;
|
|
312
|
+
gap: 16px;
|
|
225
313
|
min-height: 200px;
|
|
226
314
|
}
|
|
227
315
|
|
|
228
316
|
/* ── Settings Sections ── */
|
|
229
317
|
.mama-settings-section {
|
|
230
|
-
border-bottom: 1px solid #
|
|
318
|
+
border-bottom: 1px solid #ede9e1;
|
|
231
319
|
padding: 16px 0;
|
|
232
320
|
border-radius: 4px;
|
|
233
321
|
}
|
|
@@ -238,7 +326,7 @@
|
|
|
238
326
|
font-family: 'Inter', 'Noto Sans KR', sans-serif;
|
|
239
327
|
font-size: 16px;
|
|
240
328
|
font-weight: 600;
|
|
241
|
-
color: #
|
|
329
|
+
color: #1a1a1a;
|
|
242
330
|
cursor: pointer;
|
|
243
331
|
display: flex;
|
|
244
332
|
align-items: center;
|
|
@@ -251,24 +339,81 @@
|
|
|
251
339
|
width: 100%;
|
|
252
340
|
text-align: left;
|
|
253
341
|
}
|
|
254
|
-
.mama-settings-heading:hover {
|
|
342
|
+
.mama-settings-heading:hover {
|
|
343
|
+
color: #3d3630;
|
|
344
|
+
}
|
|
255
345
|
.mama-collapse-icon {
|
|
256
346
|
font-size: 14px;
|
|
257
|
-
color: #
|
|
347
|
+
color: #9b9389;
|
|
258
348
|
transition: transform 0.2s ease;
|
|
259
349
|
display: inline-block;
|
|
260
350
|
}
|
|
261
|
-
.mama-settings-section.collapsed .mama-settings-body {
|
|
262
|
-
|
|
351
|
+
.mama-settings-section.collapsed .mama-settings-body {
|
|
352
|
+
display: none;
|
|
353
|
+
}
|
|
354
|
+
.mama-settings-section.collapsed .mama-collapse-icon {
|
|
355
|
+
transform: rotate(-90deg);
|
|
356
|
+
}
|
|
263
357
|
|
|
264
358
|
/* ── Responsive ── */
|
|
265
359
|
@media (max-width: 767px) {
|
|
266
|
-
#mama-sidebar {
|
|
267
|
-
|
|
268
|
-
|
|
360
|
+
#mama-sidebar {
|
|
361
|
+
display: none;
|
|
362
|
+
}
|
|
363
|
+
#mama-mobile-tabs {
|
|
364
|
+
display: flex;
|
|
365
|
+
}
|
|
366
|
+
main.flex-1 {
|
|
367
|
+
margin-left: 0 !important;
|
|
368
|
+
padding-bottom: 72px;
|
|
369
|
+
}
|
|
370
|
+
/* Hide right panel chat on mobile — use full-screen chat tab instead */
|
|
371
|
+
#chat-resize-handle-bar {
|
|
372
|
+
display: none !important;
|
|
373
|
+
}
|
|
374
|
+
#chat-panel-wrapper {
|
|
375
|
+
display: none !important;
|
|
376
|
+
}
|
|
377
|
+
#chat-collapsed-bar {
|
|
378
|
+
display: none !important;
|
|
379
|
+
}
|
|
380
|
+
/* Full-screen chat overlay when chat tab is active */
|
|
381
|
+
#chat-panel-wrapper.mobile-chat-active {
|
|
382
|
+
display: flex !important;
|
|
383
|
+
position: fixed;
|
|
384
|
+
top: 0;
|
|
385
|
+
left: 0;
|
|
386
|
+
right: 0;
|
|
387
|
+
bottom: 64px;
|
|
388
|
+
width: 100% !important;
|
|
389
|
+
height: auto !important;
|
|
390
|
+
z-index: 90;
|
|
391
|
+
border-left: none;
|
|
392
|
+
flex-direction: column;
|
|
393
|
+
}
|
|
394
|
+
#chat-panel-wrapper.mobile-chat-active #chat-panel {
|
|
395
|
+
flex: 1;
|
|
396
|
+
display: flex;
|
|
397
|
+
flex-direction: column;
|
|
398
|
+
height: 100% !important;
|
|
399
|
+
min-height: 0;
|
|
400
|
+
overflow: visible;
|
|
401
|
+
}
|
|
402
|
+
#chat-panel-wrapper.mobile-chat-active #chat-messages {
|
|
403
|
+
flex: 1;
|
|
404
|
+
min-height: 0;
|
|
405
|
+
overflow-y: auto;
|
|
406
|
+
}
|
|
407
|
+
#chat-panel-wrapper.mobile-chat-active .chat-input-area,
|
|
408
|
+
#chat-panel-wrapper.mobile-chat-active > div:last-child {
|
|
409
|
+
flex-shrink: 0;
|
|
410
|
+
padding-bottom: max(4px, env(safe-area-inset-bottom));
|
|
411
|
+
}
|
|
269
412
|
}
|
|
270
413
|
@media (min-width: 768px) {
|
|
271
|
-
main.flex-1 {
|
|
414
|
+
main.flex-1 {
|
|
415
|
+
margin-left: var(--sidebar-width);
|
|
416
|
+
}
|
|
272
417
|
}
|
|
273
418
|
</style>
|
|
274
419
|
|
|
@@ -279,663 +424,1186 @@
|
|
|
279
424
|
<!-- Sidebar Navigation -->
|
|
280
425
|
<nav id="mama-sidebar">
|
|
281
426
|
<a href="/" class="mama-sidebar-logo">
|
|
282
|
-
<img src="/viewer/icons/mama-icon.svg" alt="MAMA" width="28" height="28"
|
|
427
|
+
<img src="/viewer/icons/mama-icon.svg" alt="MAMA" width="28" height="28" />
|
|
283
428
|
<span>MAMA</span>
|
|
284
429
|
</a>
|
|
285
430
|
<div class="mama-nav-items">
|
|
286
|
-
<button
|
|
431
|
+
<button
|
|
432
|
+
class="mama-nav-item mama-nav-active"
|
|
433
|
+
data-tab="dashboard"
|
|
434
|
+
onclick="window.switchTab && window.switchTab('dashboard')"
|
|
435
|
+
>
|
|
287
436
|
<i data-lucide="layout-dashboard"></i>
|
|
288
437
|
<span>Dashboard</span>
|
|
289
438
|
</button>
|
|
290
|
-
<button
|
|
439
|
+
<button
|
|
440
|
+
class="mama-nav-item"
|
|
441
|
+
data-tab="feed"
|
|
442
|
+
onclick="window.switchTab && window.switchTab('feed')"
|
|
443
|
+
>
|
|
291
444
|
<i data-lucide="rss"></i>
|
|
292
445
|
<span>Feed</span>
|
|
293
446
|
</button>
|
|
294
|
-
<button
|
|
447
|
+
<button
|
|
448
|
+
class="mama-nav-item"
|
|
449
|
+
data-tab="wiki"
|
|
450
|
+
onclick="window.switchTab && window.switchTab('wiki')"
|
|
451
|
+
>
|
|
295
452
|
<i data-lucide="book-open"></i>
|
|
296
453
|
<span>Wiki</span>
|
|
297
454
|
</button>
|
|
298
|
-
<button
|
|
455
|
+
<button
|
|
456
|
+
class="mama-nav-item"
|
|
457
|
+
data-tab="memory"
|
|
458
|
+
onclick="window.switchTab && window.switchTab('memory')"
|
|
459
|
+
>
|
|
299
460
|
<i data-lucide="brain"></i>
|
|
300
461
|
<span>Memory</span>
|
|
301
462
|
</button>
|
|
302
|
-
<button
|
|
463
|
+
<button
|
|
464
|
+
class="mama-nav-item"
|
|
465
|
+
data-tab="logs"
|
|
466
|
+
onclick="window.switchTab && window.switchTab('logs')"
|
|
467
|
+
>
|
|
303
468
|
<i data-lucide="terminal"></i>
|
|
304
469
|
<span>Logs</span>
|
|
305
470
|
</button>
|
|
306
|
-
<button
|
|
471
|
+
<button
|
|
472
|
+
class="mama-nav-item"
|
|
473
|
+
data-tab="agents"
|
|
474
|
+
onclick="window.switchTab && window.switchTab('agents')"
|
|
475
|
+
>
|
|
476
|
+
<i data-lucide="bot"></i>
|
|
477
|
+
<span>Agents</span>
|
|
478
|
+
</button>
|
|
479
|
+
<button
|
|
480
|
+
class="mama-nav-item"
|
|
481
|
+
data-tab="settings"
|
|
482
|
+
onclick="window.switchTab && window.switchTab('settings')"
|
|
483
|
+
>
|
|
307
484
|
<i data-lucide="settings"></i>
|
|
308
485
|
<span>Settings</span>
|
|
309
486
|
</button>
|
|
310
487
|
</div>
|
|
311
488
|
</nav>
|
|
312
489
|
|
|
313
|
-
<!-- Main
|
|
314
|
-
<
|
|
315
|
-
<!--
|
|
316
|
-
<
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
<
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
<div class="progress-step"></div>
|
|
328
|
-
<div class="progress-step"></div>
|
|
329
|
-
<div class="progress-step"></div>
|
|
330
|
-
<div class="progress-step"></div>
|
|
331
|
-
<div class="progress-step"></div>
|
|
332
|
-
<div class="progress-step"></div>
|
|
490
|
+
<!-- Content Area: Main + Chat Panel (SmartStore layout) -->
|
|
491
|
+
<div id="content-area" class="flex-1 flex min-h-0 overflow-hidden">
|
|
492
|
+
<!-- Main Content -->
|
|
493
|
+
<main class="flex-1 overflow-hidden flex flex-col min-w-0">
|
|
494
|
+
<!-- Dashboard Tab -->
|
|
495
|
+
<div class="tab-content" id="tab-dashboard">
|
|
496
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-4 md:p-6">
|
|
497
|
+
<div id="dashboard-slots" class="mama-slots-container">
|
|
498
|
+
<div
|
|
499
|
+
id="slots-empty"
|
|
500
|
+
style="padding: 40px; text-align: center; color: #9e9891; font-size: 14px"
|
|
501
|
+
>
|
|
502
|
+
No briefing yet. Run the orchestrator to generate the first report.
|
|
503
|
+
</div>
|
|
333
504
|
</div>
|
|
334
505
|
</div>
|
|
506
|
+
</div>
|
|
335
507
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
<div
|
|
340
|
-
<div
|
|
341
|
-
|
|
342
|
-
<div class="typing-dot"></div>
|
|
343
|
-
</div>
|
|
344
|
-
|
|
345
|
-
<div class="chat-input-area">
|
|
346
|
-
<div class="input-row">
|
|
347
|
-
<div class="input-wrapper">
|
|
348
|
-
<textarea
|
|
349
|
-
class="chat-input"
|
|
350
|
-
id="setup-input"
|
|
351
|
-
placeholder="Type your message..."
|
|
352
|
-
rows="1"
|
|
353
|
-
disabled
|
|
354
|
-
></textarea>
|
|
355
|
-
</div>
|
|
356
|
-
<button
|
|
357
|
-
class="btn btn-send"
|
|
358
|
-
id="setup-send"
|
|
359
|
-
onclick="sendSetupMessage()"
|
|
360
|
-
disabled
|
|
361
|
-
>
|
|
362
|
-
<svg
|
|
363
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
364
|
-
width="16"
|
|
365
|
-
height="16"
|
|
366
|
-
viewBox="0 0 24 24"
|
|
367
|
-
fill="none"
|
|
368
|
-
stroke="currentColor"
|
|
369
|
-
stroke-width="2"
|
|
370
|
-
stroke-linecap="round"
|
|
371
|
-
stroke-linejoin="round"
|
|
372
|
-
>
|
|
373
|
-
<line x1="22" y1="2" x2="11" y2="13" />
|
|
374
|
-
<polygon points="22 2 15 22 11 13 2 9 22 2" />
|
|
375
|
-
</svg>
|
|
376
|
-
<span>Send</span>
|
|
377
|
-
</button>
|
|
508
|
+
<!-- Feed Tab -->
|
|
509
|
+
<div class="tab-content" id="tab-feed">
|
|
510
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-4 md:p-6">
|
|
511
|
+
<div id="feed-content">
|
|
512
|
+
<div style="padding: 40px; text-align: center; color: #9e9891; font-size: 14px">
|
|
513
|
+
Loading connectors...
|
|
378
514
|
</div>
|
|
379
515
|
</div>
|
|
380
516
|
</div>
|
|
381
517
|
</div>
|
|
382
|
-
</div>
|
|
383
518
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
519
|
+
<!-- Wiki Tab -->
|
|
520
|
+
<div class="tab-content" id="tab-wiki">
|
|
521
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-4 md:p-6">
|
|
522
|
+
<div id="wiki-content">
|
|
523
|
+
<div style="padding: 40px; text-align: center; color: #9e9891; font-size: 14px">
|
|
524
|
+
Loading wiki...
|
|
525
|
+
</div>
|
|
390
526
|
</div>
|
|
391
527
|
</div>
|
|
392
528
|
</div>
|
|
393
|
-
</div>
|
|
394
529
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
530
|
+
<!-- Logs Tab -->
|
|
531
|
+
<div class="tab-content" id="tab-logs">
|
|
532
|
+
<iframe
|
|
533
|
+
id="logs-iframe"
|
|
534
|
+
style="width: 100%; height: 100%; border: none; border-radius: 8px"
|
|
535
|
+
loading="lazy"
|
|
536
|
+
></iframe>
|
|
401
537
|
</div>
|
|
402
|
-
</div>
|
|
403
538
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
<div id="wiki-content">
|
|
408
|
-
<div style="padding:40px;text-align:center;color:#9E9891;font-size:14px">Loading wiki...</div>
|
|
409
|
-
</div>
|
|
539
|
+
<!-- Agents Tab -->
|
|
540
|
+
<div class="tab-content" id="tab-agents">
|
|
541
|
+
<div class="flex-1 overflow-y-auto p-4" id="agents-content"></div>
|
|
410
542
|
</div>
|
|
411
|
-
</div>
|
|
412
|
-
|
|
413
|
-
<!-- Logs Tab -->
|
|
414
|
-
<div class="tab-content" id="tab-logs">
|
|
415
|
-
<iframe id="logs-iframe" style="width:100%;height:100%;border:none;border-radius:8px;" loading="lazy"></iframe>
|
|
416
|
-
</div>
|
|
417
|
-
|
|
418
|
-
<!-- Settings Tab -->
|
|
419
|
-
<div class="tab-content" id="tab-settings">
|
|
420
|
-
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-2 md:p-3">
|
|
421
|
-
<!-- Compact Header -->
|
|
422
|
-
<div class="flex items-center justify-between mb-3">
|
|
423
|
-
<h1 class="text-sm font-bold text-gray-900">Settings</h1>
|
|
424
|
-
<span class="text-[10px] text-gray-400">MAMA OS Configuration</span>
|
|
425
|
-
</div>
|
|
426
543
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
<
|
|
434
|
-
<div id="settings-connectors-list" class="space-y-1.5">
|
|
435
|
-
<p class="text-[10px] text-gray-400">Loading connectors...</p>
|
|
436
|
-
</div>
|
|
544
|
+
<!-- Settings Tab -->
|
|
545
|
+
<div class="tab-content" id="tab-settings">
|
|
546
|
+
<div class="flex-1 flex flex-col min-h-0 overflow-y-auto p-2 md:p-3">
|
|
547
|
+
<!-- Compact Header -->
|
|
548
|
+
<div class="flex items-center justify-between mb-3">
|
|
549
|
+
<h1 class="text-sm font-bold text-gray-900">Settings</h1>
|
|
550
|
+
<span class="text-[10px] text-gray-400">MAMA OS Configuration</span>
|
|
437
551
|
</div>
|
|
438
|
-
</div>
|
|
439
|
-
|
|
440
|
-
<!-- Section 3: System -->
|
|
441
|
-
<div class="mama-settings-section">
|
|
442
|
-
<h3 class="mama-settings-heading" onclick="this.parentElement.classList.toggle('collapsed')">
|
|
443
|
-
System <span class="mama-collapse-icon">▾</span>
|
|
444
|
-
</h3>
|
|
445
|
-
<div class="mama-settings-body">
|
|
446
|
-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
|
447
|
-
|
|
448
|
-
<!-- Left: Health + DB Info -->
|
|
449
|
-
<div class="space-y-3">
|
|
450
|
-
|
|
451
|
-
<!-- Health Check -->
|
|
452
|
-
<section>
|
|
453
|
-
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Health</h2>
|
|
454
|
-
<div id="settings-system-health" class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm">
|
|
455
|
-
<p class="text-[10px] text-gray-400">Health status will appear here.</p>
|
|
456
|
-
</div>
|
|
457
|
-
</section>
|
|
458
|
-
|
|
459
|
-
<!-- Database Info -->
|
|
460
|
-
<section>
|
|
461
|
-
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Database</h2>
|
|
462
|
-
<div id="settings-system-db" class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm">
|
|
463
|
-
<p class="text-[10px] text-gray-400">Database info will appear here.</p>
|
|
464
|
-
</div>
|
|
465
|
-
</section>
|
|
466
552
|
|
|
553
|
+
<!-- Section 1: Connectors -->
|
|
554
|
+
<div class="mama-settings-section">
|
|
555
|
+
<h3
|
|
556
|
+
class="mama-settings-heading"
|
|
557
|
+
onclick="this.parentElement.classList.toggle('collapsed')"
|
|
558
|
+
>
|
|
559
|
+
Connectors <span class="mama-collapse-icon">▾</span>
|
|
560
|
+
</h3>
|
|
561
|
+
<div class="mama-settings-body">
|
|
562
|
+
<p class="text-[10px] text-gray-500 mb-2">
|
|
563
|
+
Data source connectors for polling external channels. Configure in
|
|
564
|
+
<code>~/.mama/connectors.json</code>.
|
|
565
|
+
</p>
|
|
566
|
+
<div id="settings-connectors-list" class="space-y-1.5">
|
|
567
|
+
<p class="text-[10px] text-gray-400">Loading connectors...</p>
|
|
467
568
|
</div>
|
|
569
|
+
</div>
|
|
570
|
+
</div>
|
|
468
571
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
572
|
+
<!-- Section 3: System -->
|
|
573
|
+
<div class="mama-settings-section">
|
|
574
|
+
<h3
|
|
575
|
+
class="mama-settings-heading"
|
|
576
|
+
onclick="this.parentElement.classList.toggle('collapsed')"
|
|
577
|
+
>
|
|
578
|
+
System <span class="mama-collapse-icon">▾</span>
|
|
579
|
+
</h3>
|
|
580
|
+
<div class="mama-settings-body">
|
|
581
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
|
582
|
+
<!-- Left: Health + DB Info -->
|
|
583
|
+
<div class="space-y-3">
|
|
584
|
+
<!-- Health Check -->
|
|
585
|
+
<section>
|
|
586
|
+
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Health</h2>
|
|
587
|
+
<div
|
|
588
|
+
id="settings-system-health"
|
|
589
|
+
class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm"
|
|
590
|
+
>
|
|
591
|
+
<p class="text-[10px] text-gray-400">Health status will appear here.</p>
|
|
485
592
|
</div>
|
|
486
|
-
</
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
593
|
+
</section>
|
|
594
|
+
|
|
595
|
+
<!-- Database Info -->
|
|
596
|
+
<section>
|
|
597
|
+
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Database</h2>
|
|
598
|
+
<div
|
|
599
|
+
id="settings-system-db"
|
|
600
|
+
class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm"
|
|
601
|
+
>
|
|
602
|
+
<p class="text-[10px] text-gray-400">Database info will appear here.</p>
|
|
603
|
+
</div>
|
|
604
|
+
</section>
|
|
605
|
+
</div>
|
|
606
|
+
|
|
607
|
+
<!-- Right: Token Usage + Metrics + Cron -->
|
|
608
|
+
<div class="space-y-3">
|
|
609
|
+
<!-- Token Usage -->
|
|
610
|
+
<section>
|
|
611
|
+
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Token Budget</h2>
|
|
612
|
+
<div
|
|
613
|
+
id="settings-system-tokens"
|
|
614
|
+
class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm"
|
|
615
|
+
>
|
|
616
|
+
<div class="grid grid-cols-2 gap-1.5">
|
|
617
|
+
<div>
|
|
618
|
+
<label class="block text-[9px] text-gray-500 mb-0.5"
|
|
619
|
+
>Daily Limit</label
|
|
620
|
+
>
|
|
621
|
+
<input
|
|
622
|
+
type="number"
|
|
623
|
+
id="settings-token-daily-limit"
|
|
624
|
+
placeholder="1000000"
|
|
625
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50"
|
|
626
|
+
/>
|
|
627
|
+
</div>
|
|
628
|
+
<div>
|
|
629
|
+
<label class="block text-[9px] text-gray-500 mb-0.5">Alert ($)</label>
|
|
630
|
+
<input
|
|
631
|
+
type="number"
|
|
632
|
+
id="settings-token-alert-threshold"
|
|
633
|
+
step="0.01"
|
|
634
|
+
placeholder="5.00"
|
|
635
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50"
|
|
636
|
+
/>
|
|
637
|
+
</div>
|
|
501
638
|
</div>
|
|
502
639
|
</div>
|
|
503
|
-
</
|
|
504
|
-
</section>
|
|
640
|
+
</section>
|
|
505
641
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
<p class="text-[10px] text-gray-500">Loading...</p>
|
|
511
|
-
</div>
|
|
512
|
-
<details class="bg-white border border-gray-200 rounded-lg shadow-sm">
|
|
513
|
-
<summary class="px-2 py-1.5 text-[10px] font-medium text-gray-600 cursor-pointer hover:bg-gray-50">+ Add New Job</summary>
|
|
514
|
-
<div class="p-2 border-t border-gray-100 space-y-1.5" id="settings-cron-form">
|
|
642
|
+
<!-- Metrics -->
|
|
643
|
+
<section>
|
|
644
|
+
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Metrics</h2>
|
|
645
|
+
<div class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm">
|
|
515
646
|
<div class="grid grid-cols-2 gap-1.5">
|
|
516
|
-
<
|
|
517
|
-
|
|
647
|
+
<div>
|
|
648
|
+
<label class="block text-[9px] text-gray-500 mb-0.5"
|
|
649
|
+
>Enable metrics</label
|
|
650
|
+
>
|
|
651
|
+
<input
|
|
652
|
+
type="checkbox"
|
|
653
|
+
id="settings-metrics-enabled"
|
|
654
|
+
checked
|
|
655
|
+
class="w-4 h-4 rounded border-gray-300 text-yellow-500 focus:ring-yellow-400"
|
|
656
|
+
/>
|
|
657
|
+
</div>
|
|
658
|
+
<div>
|
|
659
|
+
<label class="block text-[9px] text-gray-500 mb-0.5"
|
|
660
|
+
>Retention (days)</label
|
|
661
|
+
>
|
|
662
|
+
<input
|
|
663
|
+
type="number"
|
|
664
|
+
id="settings-metrics-retention"
|
|
665
|
+
min="1"
|
|
666
|
+
max="90"
|
|
667
|
+
value="7"
|
|
668
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50"
|
|
669
|
+
/>
|
|
670
|
+
</div>
|
|
518
671
|
</div>
|
|
519
|
-
<textarea id="settings-cron-prompt" rows="2" placeholder="Task prompt..." aria-label="Cron job task prompt" class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50 resize-none"></textarea>
|
|
520
|
-
<button onclick="settingsModule.addCronJob()" class="w-full px-2 py-1 text-[10px] font-medium bg-yellow-400 hover:bg-yellow-300 rounded">Add</button>
|
|
521
672
|
</div>
|
|
522
|
-
</
|
|
523
|
-
|
|
524
|
-
|
|
673
|
+
</section>
|
|
674
|
+
|
|
675
|
+
<!-- Scheduled Jobs -->
|
|
676
|
+
<section>
|
|
677
|
+
<h2 class="text-xs font-semibold text-gray-700 mb-1.5">Scheduled Jobs</h2>
|
|
678
|
+
<div
|
|
679
|
+
id="settings-cron-container"
|
|
680
|
+
class="bg-white border border-gray-200 rounded-lg p-2 shadow-sm mb-1.5"
|
|
681
|
+
>
|
|
682
|
+
<p class="text-[10px] text-gray-500">Loading...</p>
|
|
683
|
+
</div>
|
|
684
|
+
<details class="bg-white border border-gray-200 rounded-lg shadow-sm">
|
|
685
|
+
<summary
|
|
686
|
+
class="px-2 py-1.5 text-[10px] font-medium text-gray-600 cursor-pointer hover:bg-gray-50"
|
|
687
|
+
>
|
|
688
|
+
+ Add New Job
|
|
689
|
+
</summary>
|
|
690
|
+
<div
|
|
691
|
+
class="p-2 border-t border-gray-100 space-y-1.5"
|
|
692
|
+
id="settings-cron-form"
|
|
693
|
+
>
|
|
694
|
+
<div class="grid grid-cols-2 gap-1.5">
|
|
695
|
+
<input
|
|
696
|
+
type="text"
|
|
697
|
+
id="settings-cron-name"
|
|
698
|
+
placeholder="Job Name"
|
|
699
|
+
aria-label="Cron job name"
|
|
700
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50"
|
|
701
|
+
/>
|
|
702
|
+
<input
|
|
703
|
+
type="text"
|
|
704
|
+
id="settings-cron-expr"
|
|
705
|
+
placeholder="0 * * * *"
|
|
706
|
+
aria-label="Cron expression"
|
|
707
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50"
|
|
708
|
+
/>
|
|
709
|
+
</div>
|
|
710
|
+
<textarea
|
|
711
|
+
id="settings-cron-prompt"
|
|
712
|
+
rows="2"
|
|
713
|
+
placeholder="Task prompt..."
|
|
714
|
+
aria-label="Cron job task prompt"
|
|
715
|
+
class="w-full px-1.5 py-0.5 text-[10px] border border-gray-200 rounded bg-gray-50 resize-none"
|
|
716
|
+
></textarea>
|
|
717
|
+
<button
|
|
718
|
+
onclick="settingsModule.addCronJob()"
|
|
719
|
+
class="w-full px-2 py-1 text-[10px] font-medium bg-yellow-400 hover:bg-yellow-300 rounded"
|
|
720
|
+
>
|
|
721
|
+
Add
|
|
722
|
+
</button>
|
|
723
|
+
</div>
|
|
724
|
+
</details>
|
|
725
|
+
</section>
|
|
726
|
+
</div>
|
|
525
727
|
</div>
|
|
526
728
|
</div>
|
|
527
729
|
</div>
|
|
528
|
-
</div>
|
|
529
730
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
Save & Restart
|
|
731
|
+
<!-- Action Buttons -->
|
|
732
|
+
<div class="flex items-center justify-between mt-3 pt-3 border-t border-gray-200">
|
|
733
|
+
<button
|
|
734
|
+
onclick="settingsModule.resetForm()"
|
|
735
|
+
class="px-3 py-1.5 text-xs font-medium text-gray-600 bg-gray-100 hover:bg-gray-200 rounded transition-colors"
|
|
736
|
+
>
|
|
737
|
+
Reset
|
|
538
738
|
</button>
|
|
739
|
+
<div class="flex items-center gap-2">
|
|
740
|
+
<span id="settings-status" class="text-[10px] text-gray-500"></span>
|
|
741
|
+
<button
|
|
742
|
+
onclick="settingsModule.saveAndRestart()"
|
|
743
|
+
class="px-4 py-1.5 text-xs font-medium text-black bg-yellow-400 hover:bg-yellow-300 rounded transition-colors flex items-center gap-1.5"
|
|
744
|
+
>
|
|
745
|
+
<svg
|
|
746
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
747
|
+
width="12"
|
|
748
|
+
height="12"
|
|
749
|
+
viewBox="0 0 24 24"
|
|
750
|
+
fill="none"
|
|
751
|
+
stroke="currentColor"
|
|
752
|
+
stroke-width="2"
|
|
753
|
+
>
|
|
754
|
+
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
|
755
|
+
<polyline points="17 21 17 13 7 13 7 21" />
|
|
756
|
+
<polyline points="7 3 7 8 15 8" />
|
|
757
|
+
</svg>
|
|
758
|
+
Save & Restart
|
|
759
|
+
</button>
|
|
760
|
+
</div>
|
|
539
761
|
</div>
|
|
540
762
|
</div>
|
|
541
763
|
</div>
|
|
542
|
-
</div>
|
|
543
764
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
<
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
<
|
|
586
|
-
<
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
<
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
765
|
+
<div class="tab-content" id="tab-memory">
|
|
766
|
+
<div class="flex-1 flex flex-col min-h-0">
|
|
767
|
+
<!-- Compact Filter Bar (full width, top) -->
|
|
768
|
+
<div class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 bg-white">
|
|
769
|
+
<!-- Toggle sidebar -->
|
|
770
|
+
<button
|
|
771
|
+
id="checkpoint-sidebar-toggle"
|
|
772
|
+
class="w-7 h-7 bg-white border border-gray-200 rounded flex items-center justify-center text-gray-500 hover:bg-gray-100 hover:text-gray-700"
|
|
773
|
+
onclick="toggleCheckpointSidebar()"
|
|
774
|
+
title="Toggle Decision List"
|
|
775
|
+
aria-controls="checkpoint-sidebar"
|
|
776
|
+
aria-expanded="true"
|
|
777
|
+
>
|
|
778
|
+
<svg
|
|
779
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
780
|
+
width="14"
|
|
781
|
+
height="14"
|
|
782
|
+
viewBox="0 0 24 24"
|
|
783
|
+
fill="none"
|
|
784
|
+
stroke="currentColor"
|
|
785
|
+
stroke-width="2"
|
|
786
|
+
stroke-linecap="round"
|
|
787
|
+
stroke-linejoin="round"
|
|
788
|
+
>
|
|
789
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
|
790
|
+
<line x1="3" y1="9" x2="21" y2="9" />
|
|
791
|
+
<line x1="9" y1="21" x2="9" y2="9" />
|
|
792
|
+
</svg>
|
|
793
|
+
</button>
|
|
794
|
+
<!-- Stats (compact inline) -->
|
|
795
|
+
<span
|
|
796
|
+
id="memory-stats-total"
|
|
797
|
+
style="
|
|
798
|
+
font-family: Inter, 'Noto Sans KR', sans-serif;
|
|
799
|
+
font-size: 13px;
|
|
800
|
+
font-weight: 600;
|
|
801
|
+
color: #1a1a1a;
|
|
802
|
+
"
|
|
803
|
+
>-</span
|
|
804
|
+
>
|
|
805
|
+
<span style="font-size: 11px; color: #9e9891">decisions</span>
|
|
806
|
+
<span style="color: #ede9e1">|</span>
|
|
807
|
+
<span id="memory-stats-week" style="font-size: 11px; color: #6b6560"
|
|
808
|
+
>- this week</span
|
|
809
|
+
>
|
|
810
|
+
<!-- Spacer -->
|
|
811
|
+
<div style="flex: 1"></div>
|
|
812
|
+
<!-- Topic filter -->
|
|
813
|
+
<input
|
|
814
|
+
list="topic-filter-list"
|
|
815
|
+
class="px-2 py-1 bg-white border border-gray-200 rounded text-xs focus:outline-none focus:ring-1 focus:ring-yellow-400"
|
|
816
|
+
id="topic-filter"
|
|
817
|
+
placeholder="Filter topics..."
|
|
818
|
+
oninput="filterByTopic(this.value)"
|
|
819
|
+
style="width: 160px"
|
|
820
|
+
/>
|
|
821
|
+
<datalist id="topic-filter-list"></datalist>
|
|
822
|
+
<select
|
|
823
|
+
class="px-2 py-1 bg-white border border-gray-200 rounded text-xs focus:outline-none focus:ring-1 focus:ring-yellow-400"
|
|
824
|
+
id="outcome-filter"
|
|
825
|
+
onchange="filterByOutcome(this.value)"
|
|
826
|
+
style="display: none"
|
|
827
|
+
>
|
|
828
|
+
<option value="">All Outcomes</option>
|
|
829
|
+
<option value="success">Success</option>
|
|
830
|
+
<option value="failed">Failed</option>
|
|
831
|
+
<option value="partial">Partial</option>
|
|
832
|
+
<option value="pending">Pending</option>
|
|
833
|
+
</select>
|
|
834
|
+
<!-- Search -->
|
|
835
|
+
<input
|
|
836
|
+
type="text"
|
|
837
|
+
class="px-2 py-1 bg-white border border-gray-200 rounded text-xs placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-yellow-400"
|
|
838
|
+
id="search-input"
|
|
839
|
+
placeholder="Search content..."
|
|
840
|
+
onkeyup="handleGraphSearch(event)"
|
|
841
|
+
style="width: 160px"
|
|
842
|
+
/>
|
|
843
|
+
<button
|
|
844
|
+
onclick="clearFilters()"
|
|
845
|
+
class="px-2 py-1 text-[10px] text-gray-400 hover:text-gray-600"
|
|
846
|
+
>
|
|
847
|
+
Clear
|
|
848
|
+
</button>
|
|
849
|
+
<!-- Export (collapsed) -->
|
|
850
|
+
<details style="position: relative">
|
|
851
|
+
<summary
|
|
852
|
+
style="
|
|
853
|
+
font-size: 10px;
|
|
854
|
+
color: #9e9891;
|
|
855
|
+
cursor: pointer;
|
|
856
|
+
padding: 4px 8px;
|
|
857
|
+
border: 1px solid #ede9e1;
|
|
858
|
+
border-radius: 4px;
|
|
859
|
+
"
|
|
860
|
+
>
|
|
861
|
+
Export
|
|
862
|
+
</summary>
|
|
863
|
+
<div
|
|
864
|
+
style="
|
|
865
|
+
position: absolute;
|
|
866
|
+
right: 0;
|
|
867
|
+
top: 100%;
|
|
868
|
+
background: #fff;
|
|
869
|
+
border: 1px solid #ede9e1;
|
|
870
|
+
border-radius: 4px;
|
|
871
|
+
padding: 4px;
|
|
872
|
+
z-index: 10;
|
|
873
|
+
display: flex;
|
|
874
|
+
gap: 4px;
|
|
875
|
+
margin-top: 2px;
|
|
876
|
+
"
|
|
877
|
+
>
|
|
878
|
+
<button
|
|
879
|
+
onclick="exportDecisions('json')"
|
|
880
|
+
style="
|
|
881
|
+
font-size: 10px;
|
|
882
|
+
padding: 2px 8px;
|
|
883
|
+
background: #f5f2ed;
|
|
884
|
+
border: none;
|
|
885
|
+
border-radius: 2px;
|
|
886
|
+
cursor: pointer;
|
|
887
|
+
"
|
|
888
|
+
>
|
|
889
|
+
JSON
|
|
890
|
+
</button>
|
|
891
|
+
<button
|
|
892
|
+
onclick="exportDecisions('markdown')"
|
|
893
|
+
style="
|
|
894
|
+
font-size: 10px;
|
|
895
|
+
padding: 2px 8px;
|
|
896
|
+
background: #f5f2ed;
|
|
897
|
+
border: none;
|
|
898
|
+
border-radius: 2px;
|
|
899
|
+
cursor: pointer;
|
|
900
|
+
"
|
|
901
|
+
>
|
|
902
|
+
MD
|
|
903
|
+
</button>
|
|
904
|
+
<button
|
|
905
|
+
onclick="exportDecisions('csv')"
|
|
906
|
+
style="
|
|
907
|
+
font-size: 10px;
|
|
908
|
+
padding: 2px 8px;
|
|
909
|
+
background: #f5f2ed;
|
|
910
|
+
border: none;
|
|
911
|
+
border-radius: 2px;
|
|
912
|
+
cursor: pointer;
|
|
913
|
+
"
|
|
914
|
+
>
|
|
915
|
+
CSV
|
|
916
|
+
</button>
|
|
917
|
+
</div>
|
|
918
|
+
</details>
|
|
620
919
|
</div>
|
|
621
|
-
</div>
|
|
622
920
|
|
|
623
|
-
|
|
624
|
-
<
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
<span class="w-6 h-0.5" style="background: #666666;"></span>
|
|
643
|
-
<span>supersedes</span>
|
|
644
|
-
</div>
|
|
645
|
-
<div class="flex items-center gap-2 text-xs text-gray-700 mb-1">
|
|
646
|
-
<span class="w-6 h-0.5" style="background: #B8860B; border-bottom: 2px dashed #B8860B;"></span>
|
|
647
|
-
<span>builds_on</span>
|
|
648
|
-
</div>
|
|
649
|
-
<div class="flex items-center gap-2 text-xs text-gray-700 mb-1">
|
|
650
|
-
<span class="w-6 h-0.5" style="background: #DC143C; border-bottom: 2px dashed #DC143C;"></span>
|
|
651
|
-
<span>debates</span>
|
|
652
|
-
</div>
|
|
653
|
-
<div class="flex items-center gap-2 text-xs text-gray-700">
|
|
654
|
-
<span class="w-6 h-1" style="background: #6B4C9A;"></span>
|
|
655
|
-
<span>synthesizes</span>
|
|
921
|
+
<!-- Main content area: Sidebar + Graph -->
|
|
922
|
+
<div class="flex-1 flex min-h-0 relative">
|
|
923
|
+
<!-- Decision List Sidebar -->
|
|
924
|
+
<aside
|
|
925
|
+
id="checkpoint-sidebar"
|
|
926
|
+
class="checkpoint-sidebar w-64 border-r border-gray-200 bg-white flex flex-col min-h-0 overflow-hidden"
|
|
927
|
+
style="min-width: 180px; max-width: 400px"
|
|
928
|
+
>
|
|
929
|
+
<div class="p-2 border-b border-gray-200 flex items-center justify-between">
|
|
930
|
+
<span
|
|
931
|
+
style="
|
|
932
|
+
font-family: Inter, 'Noto Sans KR', sans-serif;
|
|
933
|
+
font-size: 12px;
|
|
934
|
+
font-weight: 600;
|
|
935
|
+
color: #1a1a1a;
|
|
936
|
+
"
|
|
937
|
+
>Decisions</span
|
|
938
|
+
>
|
|
939
|
+
<span id="decision-list-count" style="font-size: 10px; color: #9e9891">0</span>
|
|
656
940
|
</div>
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
<span class="w-2 h-2 rounded-full bg-indigo-500"></span>
|
|
662
|
-
<span>1-2 connections</span>
|
|
941
|
+
<div class="flex-1 overflow-y-auto" id="decision-list" style="padding: 4px">
|
|
942
|
+
<div style="padding: 16px; text-align: center; color: #9e9891; font-size: 11px">
|
|
943
|
+
Loading decisions...
|
|
944
|
+
</div>
|
|
663
945
|
</div>
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
946
|
+
</aside>
|
|
947
|
+
|
|
948
|
+
<!-- Resize handle for sidebar -->
|
|
949
|
+
<div
|
|
950
|
+
id="sidebar-resize-handle"
|
|
951
|
+
class="w-1 bg-transparent hover:bg-yellow-400 cursor-col-resize transition-colors flex-shrink-0"
|
|
952
|
+
title="Drag to resize"
|
|
953
|
+
></div>
|
|
954
|
+
|
|
955
|
+
<!-- Graph Container -->
|
|
956
|
+
<div class="flex-1 flex flex-col relative min-h-0" id="graph-container">
|
|
957
|
+
<div
|
|
958
|
+
class="px-3 py-1.5 text-[10px] text-gray-500 border-b border-gray-200 bg-white/80"
|
|
959
|
+
id="graph-stats"
|
|
960
|
+
style="display: none"
|
|
961
|
+
></div>
|
|
962
|
+
|
|
963
|
+
<div
|
|
964
|
+
id="graph-canvas"
|
|
965
|
+
class="flex-1 w-full h-full min-h-[400px]"
|
|
966
|
+
style="background: #fafafa"
|
|
967
|
+
></div>
|
|
968
|
+
|
|
969
|
+
<div
|
|
970
|
+
class="absolute inset-0 flex flex-col items-center justify-center bg-white/95"
|
|
971
|
+
id="graph-loading"
|
|
972
|
+
>
|
|
973
|
+
<div
|
|
974
|
+
class="w-6 h-6 border-2 border-gray-400 border-t-transparent rounded-full animate-spin"
|
|
975
|
+
></div>
|
|
976
|
+
<span class="mt-2 text-xs text-gray-500">Loading graph...</span>
|
|
667
977
|
</div>
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
978
|
+
|
|
979
|
+
<div
|
|
980
|
+
class="legend-panel absolute bottom-16 right-4 w-48 bg-white/95 backdrop-blur-sm border border-gray-200 rounded-lg shadow-lg p-3 z-10"
|
|
981
|
+
id="legend-panel"
|
|
982
|
+
>
|
|
983
|
+
<button
|
|
984
|
+
class="absolute top-2 right-2 p-1 rounded hover:bg-gray-100 transition-colors"
|
|
985
|
+
onclick="toggleLegend()"
|
|
986
|
+
>
|
|
987
|
+
<svg
|
|
988
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
989
|
+
width="14"
|
|
990
|
+
height="14"
|
|
991
|
+
viewBox="0 0 24 24"
|
|
992
|
+
fill="none"
|
|
993
|
+
stroke="currentColor"
|
|
994
|
+
stroke-width="2"
|
|
995
|
+
stroke-linecap="round"
|
|
996
|
+
stroke-linejoin="round"
|
|
997
|
+
>
|
|
998
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
999
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
1000
|
+
</svg>
|
|
1001
|
+
</button>
|
|
1002
|
+
<h4
|
|
1003
|
+
class="text-xs font-semibold text-gray-700 text-gray-700 flex items-center gap-1.5 mb-3"
|
|
1004
|
+
>
|
|
1005
|
+
<svg
|
|
1006
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1007
|
+
width="14"
|
|
1008
|
+
height="14"
|
|
1009
|
+
viewBox="0 0 24 24"
|
|
1010
|
+
fill="none"
|
|
1011
|
+
stroke="currentColor"
|
|
1012
|
+
stroke-width="2"
|
|
1013
|
+
stroke-linecap="round"
|
|
1014
|
+
stroke-linejoin="round"
|
|
1015
|
+
>
|
|
1016
|
+
<circle cx="12" cy="12" r="10" />
|
|
1017
|
+
<line x1="12" y1="16" x2="12" y2="12" />
|
|
1018
|
+
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
1019
|
+
</svg>
|
|
1020
|
+
Legend
|
|
1021
|
+
</h4>
|
|
1022
|
+
<div class="legend-content space-y-3">
|
|
1023
|
+
<div>
|
|
1024
|
+
<div
|
|
1025
|
+
class="text-[10px] font-semibold text-gray-600 uppercase tracking-wide mb-1.5"
|
|
1026
|
+
>
|
|
1027
|
+
Edge Types
|
|
1028
|
+
</div>
|
|
1029
|
+
<div class="flex items-center gap-2 text-xs text-gray-700 mb-1">
|
|
1030
|
+
<span class="w-6 h-0.5" style="background: #666666"></span>
|
|
1031
|
+
<span>supersedes</span>
|
|
1032
|
+
</div>
|
|
1033
|
+
<div class="flex items-center gap-2 text-xs text-gray-700 mb-1">
|
|
1034
|
+
<span
|
|
1035
|
+
class="w-6 h-0.5"
|
|
1036
|
+
style="background: #b8860b; border-bottom: 2px dashed #b8860b"
|
|
1037
|
+
></span>
|
|
1038
|
+
<span>builds_on</span>
|
|
1039
|
+
</div>
|
|
1040
|
+
<div class="flex items-center gap-2 text-xs text-gray-700 mb-1">
|
|
1041
|
+
<span
|
|
1042
|
+
class="w-6 h-0.5"
|
|
1043
|
+
style="background: #dc143c; border-bottom: 2px dashed #dc143c"
|
|
1044
|
+
></span>
|
|
1045
|
+
<span>debates</span>
|
|
1046
|
+
</div>
|
|
1047
|
+
<div class="flex items-center gap-2 text-xs text-gray-700">
|
|
1048
|
+
<span class="w-6 h-1" style="background: #6b4c9a"></span>
|
|
1049
|
+
<span>synthesizes</span>
|
|
1050
|
+
</div>
|
|
1051
|
+
</div>
|
|
1052
|
+
<div>
|
|
1053
|
+
<div
|
|
1054
|
+
class="text-[10px] font-semibold text-gray-500 text-gray-600 uppercase tracking-wide mb-1.5"
|
|
1055
|
+
>
|
|
1056
|
+
Node Size
|
|
1057
|
+
</div>
|
|
1058
|
+
<div
|
|
1059
|
+
class="flex items-center gap-2 text-xs text-gray-600 text-gray-600 mb-1"
|
|
1060
|
+
>
|
|
1061
|
+
<span class="w-2 h-2 rounded-full bg-indigo-500"></span>
|
|
1062
|
+
<span>1-2 connections</span>
|
|
1063
|
+
</div>
|
|
1064
|
+
<div
|
|
1065
|
+
class="flex items-center gap-2 text-xs text-gray-600 text-gray-600 mb-1"
|
|
1066
|
+
>
|
|
1067
|
+
<span class="w-3 h-3 rounded-full bg-indigo-500"></span>
|
|
1068
|
+
<span>3-5 connections</span>
|
|
1069
|
+
</div>
|
|
1070
|
+
<div class="flex items-center gap-2 text-xs text-gray-600 text-gray-600">
|
|
1071
|
+
<span class="w-4 h-4 rounded-full bg-indigo-500"></span>
|
|
1072
|
+
<span>6+ connections</span>
|
|
1073
|
+
</div>
|
|
1074
|
+
</div>
|
|
1075
|
+
</div>
|
|
671
1076
|
</div>
|
|
1077
|
+
<button
|
|
1078
|
+
class="legend-toggle absolute bottom-4 right-4 px-3 py-1.5 text-xs font-medium bg-gray-100 bg-white hover:bg-gray-200 hover:bg-gray-100 border border-gray-200 border-gray-300 rounded-lg transition-colors flex items-center gap-1.5 z-10"
|
|
1079
|
+
onclick="toggleLegend()"
|
|
1080
|
+
>
|
|
1081
|
+
<svg
|
|
1082
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1083
|
+
width="14"
|
|
1084
|
+
height="14"
|
|
1085
|
+
viewBox="0 0 24 24"
|
|
1086
|
+
fill="none"
|
|
1087
|
+
stroke="currentColor"
|
|
1088
|
+
stroke-width="2"
|
|
1089
|
+
stroke-linecap="round"
|
|
1090
|
+
stroke-linejoin="round"
|
|
1091
|
+
>
|
|
1092
|
+
<circle cx="12" cy="12" r="10" />
|
|
1093
|
+
<line x1="12" y1="16" x2="12" y2="12" />
|
|
1094
|
+
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
1095
|
+
</svg>
|
|
1096
|
+
Legend
|
|
1097
|
+
</button>
|
|
672
1098
|
</div>
|
|
1099
|
+
<!-- close graph-container -->
|
|
673
1100
|
</div>
|
|
1101
|
+
<!-- close flex-1 flex relative -->
|
|
674
1102
|
</div>
|
|
675
|
-
<button class="legend-toggle absolute bottom-4 right-4 px-3 py-1.5 text-xs font-medium bg-gray-100 bg-white hover:bg-gray-200 hover:bg-gray-100 border border-gray-200 border-gray-300 rounded-lg transition-colors flex items-center gap-1.5 z-10" onclick="toggleLegend()">
|
|
676
|
-
<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">
|
|
677
|
-
<circle cx="12" cy="12" r="10" />
|
|
678
|
-
<line x1="12" y1="16" x2="12" y2="12" />
|
|
679
|
-
<line x1="12" y1="8" x2="12.01" y2="8" />
|
|
680
|
-
</svg>
|
|
681
|
-
Legend
|
|
682
|
-
</button>
|
|
683
1103
|
</div>
|
|
684
|
-
</div>
|
|
685
1104
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
<
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
1105
|
+
<div
|
|
1106
|
+
class="floating-panel fixed w-[360px] min-w-[280px] max-w-[90vw] h-[400px] min-h-[200px] max-h-[80vh] bg-white/95 backdrop-blur-sm border border-gray-200 rounded-xl shadow-2xl z-[1000] flex-col overflow-hidden resize"
|
|
1107
|
+
id="decision-detail-modal"
|
|
1108
|
+
style="top: 100px; right: 20px; left: auto; transform: none"
|
|
1109
|
+
>
|
|
1110
|
+
<div
|
|
1111
|
+
class="flex items-center justify-between px-3 py-2 border-b border-gray-200 bg-gray-50/80 cursor-move select-none"
|
|
1112
|
+
id="detail-modal-header"
|
|
1113
|
+
>
|
|
1114
|
+
<h3 class="text-sm font-semibold text-gray-900 truncate flex-1" id="detail-topic">
|
|
1115
|
+
Decision Detail
|
|
1116
|
+
</h3>
|
|
1117
|
+
<button
|
|
1118
|
+
class="p-1 rounded hover:bg-gray-200 transition-colors text-gray-500 hover:text-gray-700 ml-2"
|
|
1119
|
+
onclick="closeDetailModal()"
|
|
1120
|
+
>
|
|
1121
|
+
<svg
|
|
1122
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1123
|
+
width="14"
|
|
1124
|
+
height="14"
|
|
1125
|
+
viewBox="0 0 24 24"
|
|
1126
|
+
fill="none"
|
|
1127
|
+
stroke="currentColor"
|
|
1128
|
+
stroke-width="2"
|
|
1129
|
+
stroke-linecap="round"
|
|
1130
|
+
stroke-linejoin="round"
|
|
1131
|
+
>
|
|
1132
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
1133
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
1134
|
+
</svg>
|
|
1135
|
+
</button>
|
|
716
1136
|
</div>
|
|
717
|
-
<div class="flex
|
|
1137
|
+
<div class="flex-1 p-3 overflow-y-auto space-y-3 text-xs">
|
|
718
1138
|
<div>
|
|
719
|
-
<
|
|
720
|
-
<
|
|
1139
|
+
<div class="font-semibold text-gray-500 uppercase tracking-wide mb-1">Decision</div>
|
|
1140
|
+
<div
|
|
1141
|
+
class="text-gray-900 leading-relaxed markdown-content"
|
|
1142
|
+
id="detail-decision"
|
|
1143
|
+
></div>
|
|
721
1144
|
</div>
|
|
722
1145
|
<div>
|
|
723
|
-
<
|
|
724
|
-
|
|
1146
|
+
<div
|
|
1147
|
+
class="font-semibold text-gray-500 uppercase tracking-wide mb-1 cursor-pointer hover:text-gray-700"
|
|
1148
|
+
onclick="toggleReasoning()"
|
|
1149
|
+
>
|
|
1150
|
+
<span id="reasoning-arrow">▶</span> Reasoning
|
|
1151
|
+
</div>
|
|
1152
|
+
<div
|
|
1153
|
+
class="text-gray-900 leading-relaxed markdown-content hidden"
|
|
1154
|
+
id="detail-reasoning"
|
|
1155
|
+
></div>
|
|
725
1156
|
</div>
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
1157
|
+
<div class="flex items-center gap-3">
|
|
1158
|
+
<div class="flex items-center gap-2">
|
|
1159
|
+
<span class="font-semibold text-gray-500 uppercase">Outcome:</span>
|
|
1160
|
+
<select
|
|
1161
|
+
class="px-1.5 py-0.5 bg-white border border-gray-200 rounded text-xs focus:outline-none focus:ring-1 focus:ring-yellow-400"
|
|
1162
|
+
id="detail-outcome-select"
|
|
1163
|
+
>
|
|
1164
|
+
<option value="PENDING">PENDING</option>
|
|
1165
|
+
<option value="SUCCESS">SUCCESS</option>
|
|
1166
|
+
<option value="FAILED">FAILED</option>
|
|
1167
|
+
<option value="PARTIAL">PARTIAL</option>
|
|
1168
|
+
</select>
|
|
1169
|
+
<button
|
|
1170
|
+
class="px-1.5 py-0.5 bg-gray-100 hover:bg-gray-200 rounded transition-colors"
|
|
1171
|
+
onclick="saveOutcome()"
|
|
1172
|
+
>
|
|
1173
|
+
Save
|
|
1174
|
+
</button>
|
|
1175
|
+
<span id="outcome-status"></span>
|
|
1176
|
+
</div>
|
|
731
1177
|
</div>
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
<
|
|
743
|
-
class="
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
<input id="skills-url-input" type="text"
|
|
750
|
-
class="flex-1 bg-white border border-gray-200 rounded-lg px-3 py-1.5 text-sm text-gray-900 placeholder-gray-400 focus:outline-none focus:border-mama-yellow focus:ring-2 focus:ring-yellow-200"
|
|
751
|
-
placeholder="https://github.com/owner/repo">
|
|
752
|
-
<button id="skills-url-install-btn"
|
|
753
|
-
class="px-4 py-1.5 text-xs rounded-lg bg-mama-yellow text-mama-black font-medium hover:bg-mama-yellow-hover whitespace-nowrap">
|
|
754
|
-
Install URL
|
|
755
|
-
</button>
|
|
756
|
-
</div>
|
|
757
|
-
|
|
758
|
-
<!-- Filter Bar -->
|
|
759
|
-
<div id="skills-filter-bar" class="flex gap-2 mb-4 flex-wrap">
|
|
760
|
-
<button data-filter="all" class="px-3 py-1 text-xs rounded-full bg-mama-yellow text-mama-black font-medium">All</button>
|
|
761
|
-
<button data-filter="installed" class="px-3 py-1 text-xs rounded-full bg-white text-gray-600">Installed</button>
|
|
762
|
-
<button data-filter="mama" class="px-3 py-1 text-xs rounded-full bg-white text-gray-600">MAMA</button>
|
|
763
|
-
<button data-filter="cowork" class="px-3 py-1 text-xs rounded-full bg-white text-gray-600">Cowork</button>
|
|
764
|
-
<button data-filter="external" class="px-3 py-1 text-xs rounded-full bg-white text-gray-600">External</button>
|
|
765
|
-
</div>
|
|
766
|
-
|
|
767
|
-
<!-- Skills Content (rendered by skills.js) -->
|
|
768
|
-
<div id="skills-content">
|
|
769
|
-
<div class="flex items-center justify-center p-12 text-gray-500">
|
|
770
|
-
<p class="text-sm">Loading skills...</p>
|
|
1178
|
+
<div class="flex gap-4">
|
|
1179
|
+
<div>
|
|
1180
|
+
<span class="font-semibold text-gray-500 uppercase">Confidence:</span>
|
|
1181
|
+
<span class="text-gray-900" id="detail-confidence"></span>
|
|
1182
|
+
</div>
|
|
1183
|
+
<div>
|
|
1184
|
+
<span class="font-semibold text-gray-500 uppercase">Created:</span>
|
|
1185
|
+
<span class="text-gray-900" id="detail-created"></span>
|
|
1186
|
+
</div>
|
|
1187
|
+
</div>
|
|
1188
|
+
<div>
|
|
1189
|
+
<div class="font-semibold text-gray-500 uppercase tracking-wide mb-1">
|
|
1190
|
+
Similar Decisions
|
|
1191
|
+
</div>
|
|
1192
|
+
<div class="text-gray-900" id="detail-similar">
|
|
1193
|
+
<span class="text-gray-400">Searching...</span>
|
|
1194
|
+
</div>
|
|
771
1195
|
</div>
|
|
772
1196
|
</div>
|
|
1197
|
+
<div
|
|
1198
|
+
id="decision-resize-handle"
|
|
1199
|
+
class="decision-resize-handle"
|
|
1200
|
+
aria-label="Resize decision modal"
|
|
1201
|
+
></div>
|
|
773
1202
|
</div>
|
|
774
|
-
</
|
|
775
|
-
|
|
776
|
-
<!--
|
|
777
|
-
<div
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1203
|
+
</main>
|
|
1204
|
+
|
|
1205
|
+
<!-- Chat Resize Handle (SmartStore pattern) -->
|
|
1206
|
+
<div
|
|
1207
|
+
id="chat-resize-handle-bar"
|
|
1208
|
+
class="w-1 flex-shrink-0 cursor-col-resize bg-transparent hover:bg-mama-yellow/30 active:bg-mama-yellow/50 transition-colors chat-resize-visible"
|
|
1209
|
+
></div>
|
|
1210
|
+
|
|
1211
|
+
<!-- Right Chat Panel (always visible, SmartStore Layout pattern) -->
|
|
1212
|
+
<div
|
|
1213
|
+
id="chat-panel-wrapper"
|
|
1214
|
+
class="flex-shrink-0 border-l border-gray-200"
|
|
1215
|
+
style="width: 380px; background: #f5f3ef"
|
|
1216
|
+
>
|
|
1217
|
+
<div id="chat-panel" class="flex flex-col">
|
|
1218
|
+
<!-- Header (SmartStore ChatPanel pattern) -->
|
|
1219
|
+
<div
|
|
1220
|
+
id="chat-header"
|
|
1221
|
+
class="px-4 py-3 border-b border-gray-200 flex items-center gap-2.5 bg-white flex-shrink-0"
|
|
1222
|
+
>
|
|
1223
|
+
<div
|
|
1224
|
+
class="w-7 h-7 rounded-lg flex items-center justify-center flex-shrink-0"
|
|
1225
|
+
style="background: #ffce00"
|
|
1226
|
+
>
|
|
1227
|
+
<svg
|
|
1228
|
+
class="w-4 h-4 text-white"
|
|
1229
|
+
fill="none"
|
|
1230
|
+
stroke="currentColor"
|
|
1231
|
+
stroke-width="2"
|
|
1232
|
+
viewBox="0 0 24 24"
|
|
1233
|
+
>
|
|
1234
|
+
<path
|
|
1235
|
+
stroke-linecap="round"
|
|
1236
|
+
stroke-linejoin="round"
|
|
1237
|
+
d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
|
|
1238
|
+
/>
|
|
1239
|
+
</svg>
|
|
811
1240
|
</div>
|
|
812
|
-
<div class="
|
|
813
|
-
<
|
|
814
|
-
<
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
<span
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
</div>
|
|
1241
|
+
<div class="flex-1 min-w-0">
|
|
1242
|
+
<div class="flex items-center gap-1.5">
|
|
1243
|
+
<span class="text-[13px] font-semibold text-mama-black">MAMA Chat</span>
|
|
1244
|
+
<span
|
|
1245
|
+
id="chat-tab-indicator"
|
|
1246
|
+
class="text-[10px] bg-gray-100 text-gray-500 px-1.5 py-0.5 rounded-md font-medium"
|
|
1247
|
+
>Dashboard</span
|
|
1248
|
+
>
|
|
1249
|
+
<span
|
|
1250
|
+
class="status-indicator w-1.5 h-1.5 rounded-full bg-gray-300 flex-shrink-0"
|
|
1251
|
+
id="chat-status"
|
|
1252
|
+
></span>
|
|
825
1253
|
</div>
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1254
|
+
</div>
|
|
1255
|
+
<div class="flex items-center gap-1 flex-shrink-0">
|
|
1256
|
+
<button
|
|
1257
|
+
class="w-7 h-7 rounded-lg flex items-center justify-center text-gray-400 hover:text-red-500 hover:bg-red-50 transition-colors"
|
|
1258
|
+
id="chat-clear-btn"
|
|
1259
|
+
onclick="clearChatHistory()"
|
|
1260
|
+
title="Clear chat"
|
|
1261
|
+
style="display: none"
|
|
1262
|
+
>
|
|
1263
|
+
<svg
|
|
1264
|
+
class="w-3.5 h-3.5"
|
|
1265
|
+
fill="none"
|
|
1266
|
+
stroke="currentColor"
|
|
1267
|
+
stroke-width="1.5"
|
|
1268
|
+
viewBox="0 0 24 24"
|
|
1269
|
+
>
|
|
1270
|
+
<path
|
|
1271
|
+
stroke-linecap="round"
|
|
1272
|
+
stroke-linejoin="round"
|
|
1273
|
+
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
|
1274
|
+
/>
|
|
830
1275
|
</svg>
|
|
831
1276
|
</button>
|
|
832
|
-
<button
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1277
|
+
<button
|
|
1278
|
+
id="chat-collapse-btn"
|
|
1279
|
+
class="w-7 h-7 rounded-lg flex items-center justify-center text-gray-400 hover:text-mama-black hover:bg-gray-100 transition-colors"
|
|
1280
|
+
title="Collapse chat"
|
|
1281
|
+
onclick="toggleChatPanel()"
|
|
1282
|
+
>
|
|
1283
|
+
<svg
|
|
1284
|
+
class="w-4 h-4"
|
|
1285
|
+
fill="none"
|
|
1286
|
+
stroke="currentColor"
|
|
1287
|
+
stroke-width="2"
|
|
1288
|
+
viewBox="0 0 24 24"
|
|
1289
|
+
>
|
|
1290
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
|
|
836
1291
|
</svg>
|
|
837
1292
|
</button>
|
|
838
1293
|
</div>
|
|
839
1294
|
</div>
|
|
840
1295
|
|
|
841
|
-
<!-- Messages -->
|
|
842
|
-
<div
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1296
|
+
<!-- Messages (SmartStore pattern: flex-1 overflow-auto) -->
|
|
1297
|
+
<div
|
|
1298
|
+
class="flex-1 overflow-auto p-4 space-y-3"
|
|
1299
|
+
id="chat-messages"
|
|
1300
|
+
style="background: #f5f3ef"
|
|
1301
|
+
>
|
|
1302
|
+
<div class="flex flex-col items-center justify-center h-full text-center px-6">
|
|
1303
|
+
<div
|
|
1304
|
+
class="w-12 h-12 rounded-lg bg-mama-yellow/10 flex items-center justify-center mb-4"
|
|
1305
|
+
>
|
|
1306
|
+
<svg
|
|
1307
|
+
class="w-6 h-6 text-mama-yellow"
|
|
1308
|
+
fill="none"
|
|
1309
|
+
stroke="currentColor"
|
|
1310
|
+
stroke-width="1.5"
|
|
1311
|
+
viewBox="0 0 24 24"
|
|
1312
|
+
>
|
|
1313
|
+
<path
|
|
1314
|
+
stroke-linecap="round"
|
|
1315
|
+
stroke-linejoin="round"
|
|
1316
|
+
d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z"
|
|
1317
|
+
/>
|
|
1318
|
+
</svg>
|
|
1319
|
+
</div>
|
|
1320
|
+
<p class="text-[13px] text-gray-500 font-medium">Ask MAMA anything</p>
|
|
1321
|
+
<p class="text-[11px] text-gray-400 mt-1">
|
|
1322
|
+
Current page context is sent automatically
|
|
1323
|
+
</p>
|
|
848
1324
|
</div>
|
|
849
1325
|
</div>
|
|
850
1326
|
|
|
851
|
-
<!--
|
|
852
|
-
<div
|
|
1327
|
+
<!-- Attachment preview -->
|
|
1328
|
+
<div
|
|
1329
|
+
id="chat-attachment-preview"
|
|
1330
|
+
class="hidden px-3 pt-2 border-t border-gray-200 flex items-center gap-2 flex-wrap flex-shrink-0"
|
|
1331
|
+
>
|
|
1332
|
+
<img
|
|
1333
|
+
id="chat-attachment-thumb"
|
|
1334
|
+
class="w-12 h-12 object-cover rounded-lg border border-gray-200"
|
|
1335
|
+
src="data:,"
|
|
1336
|
+
alt="preview"
|
|
1337
|
+
/>
|
|
1338
|
+
<span
|
|
1339
|
+
id="chat-attachment-name"
|
|
1340
|
+
class="text-[11px] text-gray-400 truncate max-w-[100px]"
|
|
1341
|
+
></span>
|
|
1342
|
+
<button
|
|
1343
|
+
class="text-gray-400 hover:text-red-500"
|
|
1344
|
+
onclick="clearAttachment()"
|
|
1345
|
+
title="Remove"
|
|
1346
|
+
>
|
|
1347
|
+
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1348
|
+
<line x1="18" y1="6" x2="6" y2="18" stroke-width="2" stroke-linecap="round" />
|
|
1349
|
+
<line x1="6" y1="6" x2="18" y2="18" stroke-width="2" stroke-linecap="round" />
|
|
1350
|
+
</svg>
|
|
1351
|
+
</button>
|
|
1352
|
+
</div>
|
|
1353
|
+
|
|
1354
|
+
<!-- Input (SmartStore ChatPanel pattern: inline row) -->
|
|
1355
|
+
<div class="p-3 border-t border-gray-200 bg-white flex-shrink-0">
|
|
1356
|
+
<input
|
|
1357
|
+
type="file"
|
|
1358
|
+
id="chat-file-input"
|
|
1359
|
+
class="hidden"
|
|
1360
|
+
accept="image/*,.pdf,.doc,.docx,.txt,.csv,.xls,.xlsx,.md,.json,.html,.htm,.xml,.zip,.gz,.ppt,.pptx"
|
|
1361
|
+
onchange="handleFileSelect(event)"
|
|
1362
|
+
/>
|
|
853
1363
|
<div class="flex gap-2">
|
|
854
|
-
<textarea
|
|
855
|
-
class="flex-1 px-3 py-2 border border-gray-300 rounded-lg bg-gray-50 text-mama-black placeholder-gray-500 resize-none focus:outline-none focus:ring-2 focus:ring-mama-yellow disabled:opacity-50 disabled:cursor-not-allowed text-sm"
|
|
856
|
-
id="chat-input" placeholder="Type your message..." rows="1" disabled
|
|
857
|
-
></textarea>
|
|
858
1364
|
<button
|
|
859
|
-
class="
|
|
860
|
-
id="chat-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
1365
|
+
class="w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 bg-gray-100 text-gray-400 hover:text-mama-black hover:bg-gray-200 transition-all"
|
|
1366
|
+
id="chat-attach"
|
|
1367
|
+
onclick="document.getElementById('chat-file-input').click()"
|
|
1368
|
+
title="Attach file"
|
|
1369
|
+
>
|
|
1370
|
+
<svg
|
|
1371
|
+
class="w-4 h-4"
|
|
1372
|
+
fill="none"
|
|
1373
|
+
stroke="currentColor"
|
|
1374
|
+
stroke-width="1.5"
|
|
1375
|
+
viewBox="0 0 24 24"
|
|
1376
|
+
>
|
|
1377
|
+
<path
|
|
1378
|
+
stroke-linecap="round"
|
|
1379
|
+
stroke-linejoin="round"
|
|
1380
|
+
d="M18.375 12.739l-7.693 7.693a4.5 4.5 0 01-6.364-6.364l10.94-10.94A3 3 0 1119.5 7.372L8.552 18.32m.009-.01l-.01.01m5.699-9.941l-7.81 7.81a1.5 1.5 0 002.112 2.13"
|
|
1381
|
+
/>
|
|
864
1382
|
</svg>
|
|
865
1383
|
</button>
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
<svg
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
<path
|
|
1384
|
+
<button
|
|
1385
|
+
class="w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 bg-gray-100 text-gray-400 hover:text-mama-black hover:bg-gray-200 transition-all relative"
|
|
1386
|
+
id="chat-mic"
|
|
1387
|
+
onclick="toggleVoiceInput()"
|
|
1388
|
+
title="Voice input"
|
|
1389
|
+
>
|
|
1390
|
+
<svg
|
|
1391
|
+
class="w-4 h-4"
|
|
1392
|
+
fill="none"
|
|
1393
|
+
stroke="currentColor"
|
|
1394
|
+
stroke-width="1.5"
|
|
1395
|
+
viewBox="0 0 24 24"
|
|
1396
|
+
>
|
|
1397
|
+
<path
|
|
1398
|
+
stroke-linecap="round"
|
|
1399
|
+
stroke-linejoin="round"
|
|
1400
|
+
d="M12 18.75a6 6 0 006-6v-1.5m-6 7.5a6 6 0 01-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 01-3-3V4.5a3 3 0 116 0v8.25a3 3 0 01-3 3z"
|
|
1401
|
+
/>
|
|
880
1402
|
</svg>
|
|
1403
|
+
<span
|
|
1404
|
+
class="recording-dot absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full hidden"
|
|
1405
|
+
></span>
|
|
881
1406
|
</button>
|
|
882
|
-
<
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1407
|
+
<input
|
|
1408
|
+
type="text"
|
|
1409
|
+
id="chat-input"
|
|
1410
|
+
placeholder="Type your message..."
|
|
1411
|
+
class="flex-1 bg-gray-100 border-0 rounded-lg px-3.5 py-2 text-[13px] text-mama-black placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-mama-yellow/20 transition-all disabled:opacity-50"
|
|
1412
|
+
disabled
|
|
1413
|
+
/>
|
|
1414
|
+
<button
|
|
1415
|
+
id="chat-send"
|
|
1416
|
+
onclick="sendChatMessage()"
|
|
1417
|
+
disabled
|
|
1418
|
+
class="w-9 h-9 rounded-lg bg-mama-yellow text-mama-black flex items-center justify-center flex-shrink-0 hover:bg-mama-yellow-hover disabled:opacity-40 transition-all"
|
|
1419
|
+
>
|
|
1420
|
+
<svg
|
|
1421
|
+
class="w-4 h-4"
|
|
1422
|
+
fill="none"
|
|
1423
|
+
stroke="currentColor"
|
|
1424
|
+
stroke-width="2"
|
|
1425
|
+
viewBox="0 0 24 24"
|
|
1426
|
+
>
|
|
1427
|
+
<path
|
|
1428
|
+
stroke-linecap="round"
|
|
1429
|
+
stroke-linejoin="round"
|
|
1430
|
+
d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"
|
|
1431
|
+
/>
|
|
887
1432
|
</svg>
|
|
888
|
-
<span class="recording-dot absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full hidden"></span>
|
|
889
1433
|
</button>
|
|
890
|
-
<span class="text-[10px] text-gray-400 ml-1">Enter to send, Shift+Enter for new line</span>
|
|
891
1434
|
</div>
|
|
892
1435
|
</div>
|
|
893
|
-
<div id="chat-resize-handle" class="chat-resize-handle" aria-label="Resize chat panel"></div>
|
|
894
1436
|
</div>
|
|
895
1437
|
</div>
|
|
896
|
-
|
|
1438
|
+
|
|
1439
|
+
<!-- Chat Collapsed Bar (visible when chat is collapsed) -->
|
|
1440
|
+
<div
|
|
1441
|
+
id="chat-collapsed-bar"
|
|
1442
|
+
class="hidden flex-shrink-0 border-l border-gray-200 bg-white flex flex-col items-center py-3 w-10"
|
|
1443
|
+
>
|
|
1444
|
+
<button
|
|
1445
|
+
onclick="toggleChatPanel()"
|
|
1446
|
+
class="w-8 h-8 rounded-lg flex items-center justify-center text-gray-400 hover:text-mama-yellow hover:bg-mama-yellow/10 transition-colors"
|
|
1447
|
+
title="Open chat"
|
|
1448
|
+
>
|
|
1449
|
+
<svg
|
|
1450
|
+
class="w-4 h-4"
|
|
1451
|
+
fill="none"
|
|
1452
|
+
stroke="currentColor"
|
|
1453
|
+
strokeWidth="1.5"
|
|
1454
|
+
viewBox="0 0 24 24"
|
|
1455
|
+
>
|
|
1456
|
+
<path
|
|
1457
|
+
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
1458
|
+
stroke-width="2"
|
|
1459
|
+
stroke-linecap="round"
|
|
1460
|
+
stroke-linejoin="round"
|
|
1461
|
+
/>
|
|
1462
|
+
</svg>
|
|
1463
|
+
</button>
|
|
1464
|
+
<span
|
|
1465
|
+
id="chat-badge-collapsed"
|
|
1466
|
+
class="hidden w-2 h-2 bg-red-500 rounded-full mt-1 animate-pulse"
|
|
1467
|
+
></span>
|
|
1468
|
+
</div>
|
|
1469
|
+
</div>
|
|
1470
|
+
<!-- /content-area -->
|
|
897
1471
|
|
|
898
1472
|
<!-- Mobile Bottom Tab Bar -->
|
|
899
1473
|
<div id="mama-mobile-tabs">
|
|
900
|
-
<button
|
|
1474
|
+
<button
|
|
1475
|
+
class="mama-mobile-tab mama-nav-active"
|
|
1476
|
+
data-tab="dashboard"
|
|
1477
|
+
onclick="window.switchTab && window.switchTab('dashboard')"
|
|
1478
|
+
>
|
|
901
1479
|
<i data-lucide="layout-dashboard"></i>
|
|
902
|
-
<span>
|
|
1480
|
+
<span>Home</span>
|
|
903
1481
|
</button>
|
|
904
|
-
<button
|
|
905
|
-
|
|
906
|
-
|
|
1482
|
+
<button
|
|
1483
|
+
class="mama-mobile-tab"
|
|
1484
|
+
data-tab="chat"
|
|
1485
|
+
onclick="window.switchTab && window.switchTab('chat')"
|
|
1486
|
+
>
|
|
1487
|
+
<i data-lucide="message-circle"></i>
|
|
1488
|
+
<span>Chat</span>
|
|
907
1489
|
</button>
|
|
908
|
-
<button
|
|
909
|
-
|
|
910
|
-
|
|
1490
|
+
<button
|
|
1491
|
+
class="mama-mobile-tab"
|
|
1492
|
+
data-tab="agents"
|
|
1493
|
+
onclick="window.switchTab && window.switchTab('agents')"
|
|
1494
|
+
>
|
|
1495
|
+
<i data-lucide="bot"></i>
|
|
1496
|
+
<span>Agents</span>
|
|
911
1497
|
</button>
|
|
912
|
-
<button
|
|
1498
|
+
<button
|
|
1499
|
+
class="mama-mobile-tab"
|
|
1500
|
+
data-tab="memory"
|
|
1501
|
+
onclick="window.switchTab && window.switchTab('memory')"
|
|
1502
|
+
>
|
|
913
1503
|
<i data-lucide="brain"></i>
|
|
914
1504
|
<span>Memory</span>
|
|
915
1505
|
</button>
|
|
916
|
-
<button
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
<i data-lucide="
|
|
922
|
-
<span>
|
|
1506
|
+
<button
|
|
1507
|
+
class="mama-mobile-tab"
|
|
1508
|
+
data-tab="more"
|
|
1509
|
+
onclick="window.toggleMobileMore && window.toggleMobileMore()"
|
|
1510
|
+
>
|
|
1511
|
+
<i data-lucide="menu"></i>
|
|
1512
|
+
<span>More</span>
|
|
923
1513
|
</button>
|
|
924
1514
|
</div>
|
|
1515
|
+
<!-- Mobile "More" overflow menu -->
|
|
1516
|
+
<div
|
|
1517
|
+
id="mama-mobile-more"
|
|
1518
|
+
style="
|
|
1519
|
+
display: none;
|
|
1520
|
+
position: fixed;
|
|
1521
|
+
bottom: 64px;
|
|
1522
|
+
left: 0;
|
|
1523
|
+
right: 0;
|
|
1524
|
+
background: #fff;
|
|
1525
|
+
border-top: 1px solid #ede9e1;
|
|
1526
|
+
z-index: 99;
|
|
1527
|
+
padding: 8px;
|
|
1528
|
+
"
|
|
1529
|
+
>
|
|
1530
|
+
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px">
|
|
1531
|
+
<button
|
|
1532
|
+
class="mama-mobile-tab"
|
|
1533
|
+
data-tab="feed"
|
|
1534
|
+
onclick="window.switchTab && window.switchTab('feed')"
|
|
1535
|
+
>
|
|
1536
|
+
<i data-lucide="rss"></i><span>Feed</span>
|
|
1537
|
+
</button>
|
|
1538
|
+
<button
|
|
1539
|
+
class="mama-mobile-tab"
|
|
1540
|
+
data-tab="wiki"
|
|
1541
|
+
onclick="window.switchTab && window.switchTab('wiki')"
|
|
1542
|
+
>
|
|
1543
|
+
<i data-lucide="book-open"></i><span>Wiki</span>
|
|
1544
|
+
</button>
|
|
1545
|
+
<button
|
|
1546
|
+
class="mama-mobile-tab"
|
|
1547
|
+
data-tab="logs"
|
|
1548
|
+
onclick="window.switchTab && window.switchTab('logs')"
|
|
1549
|
+
>
|
|
1550
|
+
<i data-lucide="scroll-text"></i><span>Logs</span>
|
|
1551
|
+
</button>
|
|
1552
|
+
<button
|
|
1553
|
+
class="mama-mobile-tab"
|
|
1554
|
+
data-tab="settings"
|
|
1555
|
+
onclick="window.switchTab && window.switchTab('settings')"
|
|
1556
|
+
>
|
|
1557
|
+
<i data-lucide="settings"></i><span>Settings</span>
|
|
1558
|
+
</button>
|
|
1559
|
+
</div>
|
|
1560
|
+
</div>
|
|
925
1561
|
|
|
926
|
-
<div
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1562
|
+
<div
|
|
1563
|
+
class="modal-overlay fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center"
|
|
1564
|
+
id="save-decision-modal"
|
|
1565
|
+
>
|
|
1566
|
+
<div
|
|
1567
|
+
class="bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-xl shadow-2xl w-[90%] max-w-md max-h-[90vh] flex flex-col overflow-hidden"
|
|
1568
|
+
>
|
|
1569
|
+
<div
|
|
1570
|
+
class="flex items-center justify-between px-4 py-3 border-b border-gray-200 border-gray-300 bg-gray-50 bg-gray-50/50"
|
|
1571
|
+
>
|
|
1572
|
+
<h3
|
|
1573
|
+
class="flex items-center gap-2 text-base font-semibold text-gray-900 text-mama-black"
|
|
1574
|
+
>
|
|
1575
|
+
<svg
|
|
1576
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1577
|
+
width="18"
|
|
1578
|
+
height="18"
|
|
1579
|
+
viewBox="0 0 24 24"
|
|
1580
|
+
fill="none"
|
|
1581
|
+
stroke="currentColor"
|
|
1582
|
+
stroke-width="2"
|
|
1583
|
+
stroke-linecap="round"
|
|
1584
|
+
stroke-linejoin="round"
|
|
1585
|
+
>
|
|
931
1586
|
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
|
932
1587
|
<polyline points="17 21 17 13 7 13 7 21" />
|
|
933
1588
|
<polyline points="7 3 7 8 15 8" />
|
|
934
1589
|
</svg>
|
|
935
1590
|
Save Decision
|
|
936
1591
|
</h3>
|
|
937
|
-
<button
|
|
938
|
-
|
|
1592
|
+
<button
|
|
1593
|
+
class="p-1.5 rounded-lg hover:bg-gray-200 hover:bg-gray-100 transition-colors text-gray-500 hover:text-gray-700 hover:text-mama-black"
|
|
1594
|
+
onclick="hideSaveDecisionForm()"
|
|
1595
|
+
>
|
|
1596
|
+
<svg
|
|
1597
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1598
|
+
width="18"
|
|
1599
|
+
height="18"
|
|
1600
|
+
viewBox="0 0 24 24"
|
|
1601
|
+
fill="none"
|
|
1602
|
+
stroke="currentColor"
|
|
1603
|
+
stroke-width="2"
|
|
1604
|
+
stroke-linecap="round"
|
|
1605
|
+
stroke-linejoin="round"
|
|
1606
|
+
>
|
|
939
1607
|
<line x1="18" y1="6" x2="6" y2="18" />
|
|
940
1608
|
<line x1="6" y1="6" x2="18" y2="18" />
|
|
941
1609
|
</svg>
|
|
@@ -943,7 +1611,9 @@
|
|
|
943
1611
|
</div>
|
|
944
1612
|
<div class="p-4 space-y-4">
|
|
945
1613
|
<div class="flex flex-col gap-2">
|
|
946
|
-
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-topic"
|
|
1614
|
+
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-topic"
|
|
1615
|
+
>Topic</label
|
|
1616
|
+
>
|
|
947
1617
|
<input
|
|
948
1618
|
type="text"
|
|
949
1619
|
class="w-full px-3 py-2 bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-lg text-sm text-gray-900 text-mama-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-mama-yellow transition-colors"
|
|
@@ -953,7 +1623,9 @@
|
|
|
953
1623
|
/>
|
|
954
1624
|
</div>
|
|
955
1625
|
<div class="flex flex-col gap-2">
|
|
956
|
-
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-decision"
|
|
1626
|
+
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-decision"
|
|
1627
|
+
>Decision</label
|
|
1628
|
+
>
|
|
957
1629
|
<textarea
|
|
958
1630
|
class="w-full px-3 py-2 bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-lg text-sm text-gray-900 text-mama-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-mama-yellow transition-colors resize-y min-h-[60px]"
|
|
959
1631
|
id="save-decision"
|
|
@@ -963,7 +1635,9 @@
|
|
|
963
1635
|
></textarea>
|
|
964
1636
|
</div>
|
|
965
1637
|
<div class="flex flex-col gap-2">
|
|
966
|
-
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-reasoning"
|
|
1638
|
+
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-reasoning"
|
|
1639
|
+
>Reasoning</label
|
|
1640
|
+
>
|
|
967
1641
|
<textarea
|
|
968
1642
|
class="w-full px-3 py-2 bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-lg text-sm text-gray-900 text-mama-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-mama-yellow transition-colors resize-y min-h-[100px]"
|
|
969
1643
|
id="save-reasoning"
|
|
@@ -973,7 +1647,9 @@
|
|
|
973
1647
|
></textarea>
|
|
974
1648
|
</div>
|
|
975
1649
|
<div class="flex flex-col gap-2">
|
|
976
|
-
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-confidence"
|
|
1650
|
+
<label class="text-sm font-medium text-gray-900 text-mama-black" for="save-confidence"
|
|
1651
|
+
>Confidence (0.0 - 1.0)</label
|
|
1652
|
+
>
|
|
977
1653
|
<input
|
|
978
1654
|
type="number"
|
|
979
1655
|
class="w-28 px-3 py-2 bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-lg text-sm text-gray-900 text-mama-black focus:outline-none focus:ring-2 focus:ring-mama-yellow transition-colors"
|
|
@@ -985,31 +1661,74 @@
|
|
|
985
1661
|
/>
|
|
986
1662
|
</div>
|
|
987
1663
|
</div>
|
|
988
|
-
<div
|
|
989
|
-
|
|
1664
|
+
<div
|
|
1665
|
+
class="flex justify-end gap-2 px-4 py-3 border-t border-gray-200 border-gray-300 bg-gray-50 bg-gray-50/50"
|
|
1666
|
+
>
|
|
1667
|
+
<button
|
|
1668
|
+
class="px-4 py-2 text-sm font-medium text-gray-700 text-gray-700 bg-gray-100 bg-white hover:bg-gray-200 hover:bg-gray-100 rounded-lg transition-colors"
|
|
1669
|
+
onclick="hideSaveDecisionForm()"
|
|
1670
|
+
>
|
|
1671
|
+
Cancel
|
|
1672
|
+
</button>
|
|
990
1673
|
<button
|
|
991
1674
|
class="px-4 py-2 text-sm font-medium text-white bg-mama-yellow hover:bg-mama-yellow-hover rounded-lg transition-colors"
|
|
992
1675
|
id="save-form-submit"
|
|
993
1676
|
onclick="submitSaveDecision()"
|
|
994
|
-
>
|
|
1677
|
+
>
|
|
1678
|
+
Save
|
|
1679
|
+
</button>
|
|
995
1680
|
</div>
|
|
996
1681
|
<div id="save-form-status" class="px-5 pb-4 text-center text-sm"></div>
|
|
997
1682
|
</div>
|
|
998
1683
|
</div>
|
|
999
1684
|
|
|
1000
|
-
<div
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1685
|
+
<div
|
|
1686
|
+
class="modal-overlay fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center"
|
|
1687
|
+
id="tunnel-setup-modal"
|
|
1688
|
+
>
|
|
1689
|
+
<div
|
|
1690
|
+
class="bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded-xl shadow-2xl w-[90%] max-w-[600px] max-h-[90vh] flex flex-col overflow-hidden"
|
|
1691
|
+
>
|
|
1692
|
+
<div
|
|
1693
|
+
class="flex items-center justify-between px-4 py-3 border-b border-gray-200 border-gray-300 bg-gray-50 bg-gray-50/50"
|
|
1694
|
+
>
|
|
1695
|
+
<h3
|
|
1696
|
+
class="flex items-center gap-2 text-base font-semibold text-gray-900 text-mama-black"
|
|
1697
|
+
>
|
|
1698
|
+
<svg
|
|
1699
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1700
|
+
width="18"
|
|
1701
|
+
height="18"
|
|
1702
|
+
viewBox="0 0 24 24"
|
|
1703
|
+
fill="none"
|
|
1704
|
+
stroke="currentColor"
|
|
1705
|
+
stroke-width="2"
|
|
1706
|
+
stroke-linecap="round"
|
|
1707
|
+
stroke-linejoin="round"
|
|
1708
|
+
>
|
|
1005
1709
|
<circle cx="12" cy="12" r="10" />
|
|
1006
1710
|
<line x1="2" y1="12" x2="22" y2="12" />
|
|
1007
|
-
<path
|
|
1711
|
+
<path
|
|
1712
|
+
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"
|
|
1713
|
+
/>
|
|
1008
1714
|
</svg>
|
|
1009
1715
|
External Access Setup
|
|
1010
1716
|
</h3>
|
|
1011
|
-
<button
|
|
1012
|
-
|
|
1717
|
+
<button
|
|
1718
|
+
class="p-1.5 rounded-lg hover:bg-gray-200 hover:bg-gray-100 transition-colors text-gray-500 hover:text-gray-700 hover:text-mama-black"
|
|
1719
|
+
onclick="hideTunnelSetup()"
|
|
1720
|
+
>
|
|
1721
|
+
<svg
|
|
1722
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1723
|
+
width="18"
|
|
1724
|
+
height="18"
|
|
1725
|
+
viewBox="0 0 24 24"
|
|
1726
|
+
fill="none"
|
|
1727
|
+
stroke="currentColor"
|
|
1728
|
+
stroke-width="2"
|
|
1729
|
+
stroke-linecap="round"
|
|
1730
|
+
stroke-linejoin="round"
|
|
1731
|
+
>
|
|
1013
1732
|
<line x1="18" y1="6" x2="6" y2="18" />
|
|
1014
1733
|
<line x1="6" y1="6" x2="18" y2="18" />
|
|
1015
1734
|
</svg>
|
|
@@ -1019,23 +1738,67 @@
|
|
|
1019
1738
|
<!-- ngrok section -->
|
|
1020
1739
|
<div class="bg-gray-100 bg-white border border-gray-200 border-gray-300 rounded-lg p-4">
|
|
1021
1740
|
<h4 class="text-sm text-mama-black text-mama-black mb-2 flex items-center gap-1.5">
|
|
1022
|
-
<svg
|
|
1741
|
+
<svg
|
|
1742
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1743
|
+
width="16"
|
|
1744
|
+
height="16"
|
|
1745
|
+
viewBox="0 0 24 24"
|
|
1746
|
+
fill="none"
|
|
1747
|
+
stroke="currentColor"
|
|
1748
|
+
stroke-width="2"
|
|
1749
|
+
stroke-linecap="round"
|
|
1750
|
+
stroke-linejoin="round"
|
|
1751
|
+
>
|
|
1023
1752
|
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
|
1024
1753
|
</svg>
|
|
1025
1754
|
ngrok (Quick Setup)
|
|
1026
1755
|
</h4>
|
|
1027
|
-
<p class="text-xs text-gray-500 text-gray-600 mb-3">
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1756
|
+
<p class="text-xs text-gray-500 text-gray-600 mb-3">
|
|
1757
|
+
Tunnel your local server to a public URL
|
|
1758
|
+
</p>
|
|
1759
|
+
<div
|
|
1760
|
+
class="bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded px-3 py-2 flex items-center justify-between gap-2 mb-2"
|
|
1761
|
+
>
|
|
1762
|
+
<code id="ngrok-command" class="font-mono text-sm text-green-600 text-green-600"
|
|
1763
|
+
>ngrok http 3847</code
|
|
1764
|
+
>
|
|
1765
|
+
<button
|
|
1766
|
+
class="p-1.5 rounded hover:bg-gray-100 transition-colors"
|
|
1767
|
+
onclick="copyNgrokCommand()"
|
|
1768
|
+
>
|
|
1769
|
+
<svg
|
|
1770
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1771
|
+
width="14"
|
|
1772
|
+
height="14"
|
|
1773
|
+
viewBox="0 0 24 24"
|
|
1774
|
+
fill="none"
|
|
1775
|
+
stroke="currentColor"
|
|
1776
|
+
stroke-width="2"
|
|
1777
|
+
stroke-linecap="round"
|
|
1778
|
+
stroke-linejoin="round"
|
|
1779
|
+
>
|
|
1032
1780
|
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
1033
1781
|
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
1034
1782
|
</svg>
|
|
1035
1783
|
</button>
|
|
1036
1784
|
</div>
|
|
1037
|
-
<a
|
|
1038
|
-
|
|
1785
|
+
<a
|
|
1786
|
+
href="https://ngrok.com/download"
|
|
1787
|
+
target="_blank"
|
|
1788
|
+
rel="noopener noreferrer"
|
|
1789
|
+
class="text-xs text-mama-black text-mama-black hover:underline flex items-center gap-1"
|
|
1790
|
+
>
|
|
1791
|
+
<svg
|
|
1792
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1793
|
+
width="14"
|
|
1794
|
+
height="14"
|
|
1795
|
+
viewBox="0 0 24 24"
|
|
1796
|
+
fill="none"
|
|
1797
|
+
stroke="currentColor"
|
|
1798
|
+
stroke-width="2"
|
|
1799
|
+
stroke-linecap="round"
|
|
1800
|
+
stroke-linejoin="round"
|
|
1801
|
+
>
|
|
1039
1802
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
1040
1803
|
<polyline points="7 10 12 15 17 10" />
|
|
1041
1804
|
<line x1="12" y1="15" x2="12" y2="3" />
|
|
@@ -1047,14 +1810,41 @@
|
|
|
1047
1810
|
<!-- Cloudflare section -->
|
|
1048
1811
|
<div class="bg-gray-100 bg-white border border-gray-200 border-gray-300 rounded-lg p-4">
|
|
1049
1812
|
<h4 class="text-sm text-mama-black text-mama-black mb-2 flex items-center gap-1.5">
|
|
1050
|
-
<svg
|
|
1813
|
+
<svg
|
|
1814
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1815
|
+
width="16"
|
|
1816
|
+
height="16"
|
|
1817
|
+
viewBox="0 0 24 24"
|
|
1818
|
+
fill="none"
|
|
1819
|
+
stroke="currentColor"
|
|
1820
|
+
stroke-width="2"
|
|
1821
|
+
stroke-linecap="round"
|
|
1822
|
+
stroke-linejoin="round"
|
|
1823
|
+
>
|
|
1051
1824
|
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
|
|
1052
1825
|
</svg>
|
|
1053
1826
|
Cloudflare Tunnel (Production)
|
|
1054
1827
|
</h4>
|
|
1055
|
-
<p class="text-xs text-gray-500 text-gray-600 mb-2">
|
|
1056
|
-
|
|
1057
|
-
|
|
1828
|
+
<p class="text-xs text-gray-500 text-gray-600 mb-2">
|
|
1829
|
+
Secure tunnel with custom domain support
|
|
1830
|
+
</p>
|
|
1831
|
+
<a
|
|
1832
|
+
href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/"
|
|
1833
|
+
target="_blank"
|
|
1834
|
+
rel="noopener noreferrer"
|
|
1835
|
+
class="text-xs text-mama-black text-mama-black hover:underline flex items-center gap-1"
|
|
1836
|
+
>
|
|
1837
|
+
<svg
|
|
1838
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1839
|
+
width="14"
|
|
1840
|
+
height="14"
|
|
1841
|
+
viewBox="0 0 24 24"
|
|
1842
|
+
fill="none"
|
|
1843
|
+
stroke="currentColor"
|
|
1844
|
+
stroke-width="2"
|
|
1845
|
+
stroke-linecap="round"
|
|
1846
|
+
stroke-linejoin="round"
|
|
1847
|
+
>
|
|
1058
1848
|
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
|
1059
1849
|
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
|
1060
1850
|
</svg>
|
|
@@ -1063,23 +1853,58 @@
|
|
|
1063
1853
|
</div>
|
|
1064
1854
|
|
|
1065
1855
|
<!-- Security warning -->
|
|
1066
|
-
<div
|
|
1067
|
-
|
|
1068
|
-
|
|
1856
|
+
<div
|
|
1857
|
+
class="bg-amber-50 bg-amber-100/20 border border-amber-200 border-amber-300/50 rounded-lg p-3 flex gap-3"
|
|
1858
|
+
>
|
|
1859
|
+
<svg
|
|
1860
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1861
|
+
width="16"
|
|
1862
|
+
height="16"
|
|
1863
|
+
viewBox="0 0 24 24"
|
|
1864
|
+
fill="none"
|
|
1865
|
+
stroke="currentColor"
|
|
1866
|
+
stroke-width="2"
|
|
1867
|
+
stroke-linecap="round"
|
|
1868
|
+
stroke-linejoin="round"
|
|
1869
|
+
class="text-amber-500 flex-shrink-0 mt-0.5"
|
|
1870
|
+
>
|
|
1871
|
+
<path
|
|
1872
|
+
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"
|
|
1873
|
+
/>
|
|
1069
1874
|
<line x1="12" y1="9" x2="12" y2="13" />
|
|
1070
1875
|
<line x1="12" y1="17" x2="12.01" y2="17" />
|
|
1071
1876
|
</svg>
|
|
1072
1877
|
<div class="text-xs">
|
|
1073
1878
|
<strong class="text-amber-600 text-amber-600 block mb-1">Security Notice</strong>
|
|
1074
|
-
<span class="text-gray-700 text-gray-700"
|
|
1075
|
-
|
|
1879
|
+
<span class="text-gray-700 text-gray-700"
|
|
1880
|
+
>Always set MAMA_AUTH_TOKEN environment variable before exposing your server
|
|
1881
|
+
externally.</span
|
|
1882
|
+
>
|
|
1883
|
+
<pre
|
|
1884
|
+
class="bg-white bg-gray-50 border border-gray-200 border-gray-300 rounded px-2 py-1.5 mt-2 text-[11px] text-green-600 text-green-600 overflow-x-auto"
|
|
1885
|
+
>
|
|
1886
|
+
export MAMA_AUTH_TOKEN="your-secure-token-here"</pre
|
|
1887
|
+
>
|
|
1076
1888
|
</div>
|
|
1077
1889
|
</div>
|
|
1078
1890
|
|
|
1079
1891
|
<!-- Test connection -->
|
|
1080
1892
|
<div class="border-t border-gray-200 border-gray-300 pt-4">
|
|
1081
|
-
<button
|
|
1082
|
-
|
|
1893
|
+
<button
|
|
1894
|
+
class="w-full px-4 py-2 text-sm font-medium text-white bg-mama-yellow hover:bg-mama-yellow-hover rounded-lg transition-colors flex items-center justify-center gap-2"
|
|
1895
|
+
onclick="testConnection()"
|
|
1896
|
+
>
|
|
1897
|
+
<svg
|
|
1898
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1899
|
+
width="16"
|
|
1900
|
+
height="16"
|
|
1901
|
+
viewBox="0 0 24 24"
|
|
1902
|
+
fill="none"
|
|
1903
|
+
stroke="currentColor"
|
|
1904
|
+
stroke-width="2"
|
|
1905
|
+
stroke-linecap="round"
|
|
1906
|
+
stroke-linejoin="round"
|
|
1907
|
+
>
|
|
1083
1908
|
<path d="M5 12.55a11 11 0 0 1 14.08 0" />
|
|
1084
1909
|
<path d="M1.42 9a16 16 0 0 1 21.16 0" />
|
|
1085
1910
|
<path d="M8.53 16.11a6 6 0 0 1 6.95 0" />
|
|
@@ -1104,19 +1929,93 @@
|
|
|
1104
1929
|
import { MemoryModule } from '/viewer/js/modules/memory.js';
|
|
1105
1930
|
import { DashboardModule } from '/viewer/js/modules/dashboard.js';
|
|
1106
1931
|
import { SettingsModule } from '/viewer/js/modules/settings.js';
|
|
1107
|
-
import { SkillsModule } from '/viewer/js/modules/skills.js';
|
|
1108
1932
|
import { ConnectorFeedModule } from '/viewer/js/modules/connector-feed.js';
|
|
1109
1933
|
import { WikiModule } from '/viewer/js/modules/wiki.js';
|
|
1934
|
+
import { AgentsModule } from '/viewer/js/modules/agents.js';
|
|
1110
1935
|
import { API } from '/viewer/js/utils/api.js';
|
|
1936
|
+
import { startUICommandPolling, reportPageContext } from '/viewer/js/utils/ui-commands.js';
|
|
1111
1937
|
|
|
1112
1938
|
const memory = new MemoryModule();
|
|
1113
1939
|
const chat = new ChatModule(memory);
|
|
1114
1940
|
const graph = new GraphModule();
|
|
1115
1941
|
const dashboard = new DashboardModule();
|
|
1116
1942
|
const settings = new SettingsModule();
|
|
1117
|
-
const skills = SkillsModule;
|
|
1118
1943
|
const connectorFeed = new ConnectorFeedModule();
|
|
1119
1944
|
const wiki = new WikiModule();
|
|
1945
|
+
const agentsModule = new AgentsModule();
|
|
1946
|
+
|
|
1947
|
+
// ── Chat Panel: toggle, resize, tab indicator (SmartStore pattern) ──
|
|
1948
|
+
const CHAT_WIDTH_KEY = 'mama-chat-width';
|
|
1949
|
+
const CHAT_COLLAPSED_KEY = 'mama-chat-collapsed';
|
|
1950
|
+
const MIN_CHAT = 280;
|
|
1951
|
+
const MAX_CHAT = 560;
|
|
1952
|
+
|
|
1953
|
+
function toggleChatPanel() {
|
|
1954
|
+
const wrapper = document.getElementById('chat-panel-wrapper');
|
|
1955
|
+
const bar = document.getElementById('chat-collapsed-bar');
|
|
1956
|
+
const handle = document.getElementById('chat-resize-handle-bar');
|
|
1957
|
+
if (!wrapper || !bar) return;
|
|
1958
|
+
const isCollapsed = wrapper.style.display === 'none';
|
|
1959
|
+
if (isCollapsed) {
|
|
1960
|
+
wrapper.style.display = '';
|
|
1961
|
+
bar.classList.add('hidden');
|
|
1962
|
+
if (handle) handle.classList.add('chat-resize-visible');
|
|
1963
|
+
localStorage.setItem(CHAT_COLLAPSED_KEY, 'false');
|
|
1964
|
+
} else {
|
|
1965
|
+
wrapper.style.display = 'none';
|
|
1966
|
+
bar.classList.remove('hidden');
|
|
1967
|
+
if (handle) handle.classList.remove('chat-resize-visible');
|
|
1968
|
+
localStorage.setItem(CHAT_COLLAPSED_KEY, 'true');
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
window.toggleChatPanel = toggleChatPanel;
|
|
1972
|
+
|
|
1973
|
+
// Restore collapsed state
|
|
1974
|
+
if (localStorage.getItem(CHAT_COLLAPSED_KEY) === 'true') {
|
|
1975
|
+
toggleChatPanel();
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
// Restore width
|
|
1979
|
+
{
|
|
1980
|
+
const saved = localStorage.getItem(CHAT_WIDTH_KEY);
|
|
1981
|
+
if (saved) {
|
|
1982
|
+
const w = Math.max(MIN_CHAT, Math.min(MAX_CHAT, Number(saved)));
|
|
1983
|
+
const wrapper = document.getElementById('chat-panel-wrapper');
|
|
1984
|
+
if (wrapper) wrapper.style.width = w + 'px';
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// Chat resize handle (SmartStore Layout.tsx:158-176 pattern)
|
|
1989
|
+
(function initChatResize() {
|
|
1990
|
+
const handle = document.getElementById('chat-resize-handle-bar');
|
|
1991
|
+
const wrapper = document.getElementById('chat-panel-wrapper');
|
|
1992
|
+
if (!handle || !wrapper) return;
|
|
1993
|
+
|
|
1994
|
+
handle.addEventListener('mousedown', (e) => {
|
|
1995
|
+
e.preventDefault();
|
|
1996
|
+
const startX = e.clientX;
|
|
1997
|
+
const startWidth = wrapper.offsetWidth;
|
|
1998
|
+
const onMove = (ev) => {
|
|
1999
|
+
const delta = startX - ev.clientX;
|
|
2000
|
+
const w = Math.max(MIN_CHAT, Math.min(MAX_CHAT, startWidth + delta));
|
|
2001
|
+
wrapper.style.width = w + 'px';
|
|
2002
|
+
};
|
|
2003
|
+
const onUp = () => {
|
|
2004
|
+
document.removeEventListener('mousemove', onMove);
|
|
2005
|
+
document.removeEventListener('mouseup', onUp);
|
|
2006
|
+
document.body.style.cursor = '';
|
|
2007
|
+
document.body.style.userSelect = '';
|
|
2008
|
+
localStorage.setItem(CHAT_WIDTH_KEY, String(wrapper.offsetWidth));
|
|
2009
|
+
};
|
|
2010
|
+
document.body.style.cursor = 'col-resize';
|
|
2011
|
+
document.body.style.userSelect = 'none';
|
|
2012
|
+
document.addEventListener('mousemove', onMove);
|
|
2013
|
+
document.addEventListener('mouseup', onUp);
|
|
2014
|
+
});
|
|
2015
|
+
})();
|
|
2016
|
+
|
|
2017
|
+
// Start UI command polling (SmartStore Layout pattern)
|
|
2018
|
+
startUICommandPolling(switchTab);
|
|
1120
2019
|
|
|
1121
2020
|
// Expose modules globally for debugging and onclick handlers
|
|
1122
2021
|
window.chatModule = chat;
|
|
@@ -1124,7 +2023,6 @@
|
|
|
1124
2023
|
window.memoryModule = memory;
|
|
1125
2024
|
window.dashboardModule = dashboard;
|
|
1126
2025
|
window.settingsModule = settings;
|
|
1127
|
-
window.skillsModule = skills;
|
|
1128
2026
|
|
|
1129
2027
|
// Quiz choice button handler
|
|
1130
2028
|
window.sendQuizChoice = (choice) => {
|
|
@@ -1134,24 +2032,44 @@
|
|
|
1134
2032
|
const STATE = {
|
|
1135
2033
|
currentTab: 'dashboard',
|
|
1136
2034
|
theme: 'dark',
|
|
1137
|
-
graphLoaded: false
|
|
2035
|
+
graphLoaded: false,
|
|
1138
2036
|
};
|
|
1139
2037
|
|
|
1140
|
-
async function switchTab(tabName) {
|
|
2038
|
+
async function switchTab(tabName, params) {
|
|
1141
2039
|
STATE.currentTab = tabName;
|
|
1142
2040
|
|
|
2041
|
+
// Close mobile More menu if open
|
|
2042
|
+
const moreMenu = document.getElementById('mama-mobile-more');
|
|
2043
|
+
if (moreMenu) moreMenu.style.display = 'none';
|
|
2044
|
+
const moreBtn = document.querySelector('#mama-mobile-tabs [data-tab="more"]');
|
|
2045
|
+
const overflowTabs = ['feed', 'wiki', 'logs', 'settings'];
|
|
2046
|
+
if (moreBtn) {
|
|
2047
|
+
moreBtn.classList.toggle('mama-nav-active', overflowTabs.includes(tabName));
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
// Also highlight the source tab in More menu if it was selected from there
|
|
2051
|
+
document.querySelectorAll('#mama-mobile-more .mama-mobile-tab').forEach((btn) => {
|
|
2052
|
+
btn.classList.toggle('mama-nav-active', btn.dataset.tab === tabName);
|
|
2053
|
+
});
|
|
2054
|
+
|
|
2055
|
+
// Update chat panel tab indicator
|
|
2056
|
+
const tabIndicator = document.getElementById('chat-tab-indicator');
|
|
2057
|
+
if (tabIndicator) {
|
|
2058
|
+
tabIndicator.textContent = tabName.charAt(0).toUpperCase() + tabName.slice(1);
|
|
2059
|
+
}
|
|
2060
|
+
|
|
1143
2061
|
// Update sidebar nav items
|
|
1144
|
-
document.querySelectorAll('#mama-sidebar .mama-nav-item').forEach(btn => {
|
|
2062
|
+
document.querySelectorAll('#mama-sidebar .mama-nav-item').forEach((btn) => {
|
|
1145
2063
|
btn.classList.toggle('mama-nav-active', btn.dataset.tab === tabName);
|
|
1146
2064
|
});
|
|
1147
2065
|
|
|
1148
2066
|
// Update mobile tab bar
|
|
1149
|
-
document.querySelectorAll('#mama-mobile-tabs .mama-mobile-tab').forEach(btn => {
|
|
2067
|
+
document.querySelectorAll('#mama-mobile-tabs .mama-mobile-tab').forEach((btn) => {
|
|
1150
2068
|
btn.classList.toggle('mama-nav-active', btn.dataset.tab === tabName);
|
|
1151
2069
|
});
|
|
1152
2070
|
|
|
1153
2071
|
// Legacy: update any remaining [data-tab] buttons outside sidebar/mobile
|
|
1154
|
-
document.querySelectorAll('[data-tab]').forEach(btn => {
|
|
2072
|
+
document.querySelectorAll('[data-tab]').forEach((btn) => {
|
|
1155
2073
|
if (btn.closest('#mama-sidebar') || btn.closest('#mama-mobile-tabs')) return;
|
|
1156
2074
|
const isActive = btn.dataset.tab === tabName;
|
|
1157
2075
|
btn.classList.toggle('bg-indigo-100', isActive);
|
|
@@ -1159,15 +2077,37 @@
|
|
|
1159
2077
|
btn.classList.toggle('text-mama-black', isActive);
|
|
1160
2078
|
});
|
|
1161
2079
|
|
|
1162
|
-
document.querySelectorAll('.tab-content').forEach(content => {
|
|
2080
|
+
document.querySelectorAll('.tab-content').forEach((content) => {
|
|
1163
2081
|
content.classList.toggle('active', content.id === `tab-${tabName}`);
|
|
1164
2082
|
});
|
|
1165
2083
|
|
|
2084
|
+
// Mobile chat: toggle full-screen chat overlay
|
|
2085
|
+
const chatWrapper = document.getElementById('chat-panel-wrapper');
|
|
2086
|
+
if (chatWrapper) {
|
|
2087
|
+
if (tabName === 'chat') {
|
|
2088
|
+
chatWrapper.classList.add('mobile-chat-active');
|
|
2089
|
+
} else {
|
|
2090
|
+
chatWrapper.classList.remove('mobile-chat-active');
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
const publishBasicTabContext = () => {
|
|
2095
|
+
const selectedItem =
|
|
2096
|
+
tabName === 'agents' && params?.id ? { type: 'agent', id: params.id } : undefined;
|
|
2097
|
+
reportPageContext(
|
|
2098
|
+
tabName,
|
|
2099
|
+
{ pageType: 'tab-switch', tab: tabName, ...(params || {}) },
|
|
2100
|
+
selectedItem
|
|
2101
|
+
);
|
|
2102
|
+
};
|
|
2103
|
+
|
|
1166
2104
|
if (tabName === 'dashboard') {
|
|
1167
2105
|
dashboard.init();
|
|
2106
|
+
publishBasicTabContext();
|
|
1168
2107
|
} else if (tabName === 'settings') {
|
|
1169
2108
|
settings.init();
|
|
1170
2109
|
loadConnectorsList();
|
|
2110
|
+
publishBasicTabContext();
|
|
1171
2111
|
} else if (tabName === 'memory') {
|
|
1172
2112
|
// Initialize sidebar state for current screen size
|
|
1173
2113
|
updateCheckpointSidebarForScreenSize();
|
|
@@ -1189,18 +2129,35 @@
|
|
|
1189
2129
|
} catch (error) {
|
|
1190
2130
|
console.error('[MAMA] Failed to load graph:', error);
|
|
1191
2131
|
const loadingEl = document.getElementById('graph-loading');
|
|
1192
|
-
if (loadingEl)
|
|
2132
|
+
if (loadingEl)
|
|
2133
|
+
loadingEl.innerHTML = '<span class="text-red-500">Failed to load graph data</span>';
|
|
1193
2134
|
}
|
|
1194
2135
|
}
|
|
2136
|
+
publishBasicTabContext();
|
|
1195
2137
|
} else if (tabName === 'feed') {
|
|
1196
2138
|
connectorFeed.init();
|
|
2139
|
+
publishBasicTabContext();
|
|
2140
|
+
} else if (tabName === 'agents') {
|
|
2141
|
+
agentsModule.init();
|
|
2142
|
+
// Handle deep navigation: params.id opens agent detail, params.tab selects tab
|
|
2143
|
+
if (params?.id) {
|
|
2144
|
+
await agentsModule.navigateTo(params.id, params.tab);
|
|
2145
|
+
} else {
|
|
2146
|
+
agentsModule.showList();
|
|
2147
|
+
}
|
|
1197
2148
|
} else if (tabName === 'wiki') {
|
|
1198
2149
|
wiki.init();
|
|
2150
|
+
await wiki.navigateTo(params?.path);
|
|
1199
2151
|
} else if (tabName === 'logs') {
|
|
1200
2152
|
const iframe = document.getElementById('logs-iframe');
|
|
1201
2153
|
if (iframe && !iframe.getAttribute('src')) {
|
|
1202
2154
|
iframe.src = '/viewer/log-viewer.html';
|
|
1203
2155
|
}
|
|
2156
|
+
publishBasicTabContext();
|
|
2157
|
+
} else if (tabName === 'chat') {
|
|
2158
|
+
publishBasicTabContext();
|
|
2159
|
+
} else {
|
|
2160
|
+
publishBasicTabContext();
|
|
1204
2161
|
}
|
|
1205
2162
|
}
|
|
1206
2163
|
|
|
@@ -1263,35 +2220,44 @@
|
|
|
1263
2220
|
});
|
|
1264
2221
|
|
|
1265
2222
|
// Touch drag for mobile
|
|
1266
|
-
header.addEventListener(
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
2223
|
+
header.addEventListener(
|
|
2224
|
+
'touchstart',
|
|
2225
|
+
(e) => {
|
|
2226
|
+
if (e.target.tagName === 'BUTTON') return;
|
|
2227
|
+
const touch = e.touches[0];
|
|
2228
|
+
if (!touch) return;
|
|
2229
|
+
e.preventDefault();
|
|
2230
|
+
e.stopPropagation();
|
|
2231
|
+
document.body.classList.add('no-scroll');
|
|
2232
|
+
isDragging = true;
|
|
2233
|
+
startX = touch.clientX;
|
|
2234
|
+
startY = touch.clientY;
|
|
2235
|
+
const rect = modal.getBoundingClientRect();
|
|
2236
|
+
startLeft = rect.left;
|
|
2237
|
+
startTop = rect.top;
|
|
2238
|
+
modal.style.transition = 'none';
|
|
2239
|
+
},
|
|
2240
|
+
{ passive: false }
|
|
2241
|
+
);
|
|
2242
|
+
|
|
2243
|
+
document.addEventListener(
|
|
2244
|
+
'touchmove',
|
|
2245
|
+
(e) => {
|
|
2246
|
+
if (!isDragging) return;
|
|
2247
|
+
const touch = e.touches[0];
|
|
2248
|
+
if (!touch) return;
|
|
2249
|
+
e.preventDefault();
|
|
2250
|
+
e.stopPropagation();
|
|
2251
|
+
const dx = touch.clientX - startX;
|
|
2252
|
+
const dy = touch.clientY - startY;
|
|
2253
|
+
modal.style.left =
|
|
2254
|
+
Math.max(0, Math.min(window.innerWidth - 100, startLeft + dx)) + 'px';
|
|
2255
|
+
modal.style.top = Math.max(0, Math.min(window.innerHeight - 50, startTop + dy)) + 'px';
|
|
2256
|
+
modal.style.right = 'auto';
|
|
2257
|
+
modal.style.transform = 'none';
|
|
2258
|
+
},
|
|
2259
|
+
{ passive: false }
|
|
2260
|
+
);
|
|
1295
2261
|
|
|
1296
2262
|
document.addEventListener('touchend', () => {
|
|
1297
2263
|
if (isDragging) {
|
|
@@ -1339,22 +2305,30 @@
|
|
|
1339
2305
|
document.addEventListener('mousemove', (e) => doResize(e.clientX, e.clientY));
|
|
1340
2306
|
document.addEventListener('mouseup', endResize);
|
|
1341
2307
|
|
|
1342
|
-
resizeHandle.addEventListener(
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
2308
|
+
resizeHandle.addEventListener(
|
|
2309
|
+
'touchstart',
|
|
2310
|
+
(e) => {
|
|
2311
|
+
const touch = e.touches[0];
|
|
2312
|
+
if (!touch) return;
|
|
2313
|
+
e.preventDefault();
|
|
2314
|
+
e.stopPropagation();
|
|
2315
|
+
startResize(touch.clientX, touch.clientY);
|
|
2316
|
+
document.body.classList.add('no-scroll');
|
|
2317
|
+
},
|
|
2318
|
+
{ passive: false }
|
|
2319
|
+
);
|
|
2320
|
+
document.addEventListener(
|
|
2321
|
+
'touchmove',
|
|
2322
|
+
(e) => {
|
|
2323
|
+
const touch = e.touches[0];
|
|
2324
|
+
if (!touch) return;
|
|
2325
|
+
if (!resizing) return;
|
|
2326
|
+
e.preventDefault();
|
|
2327
|
+
e.stopPropagation();
|
|
2328
|
+
doResize(touch.clientX, touch.clientY);
|
|
2329
|
+
},
|
|
2330
|
+
{ passive: false }
|
|
2331
|
+
);
|
|
1358
2332
|
document.addEventListener('touchend', () => {
|
|
1359
2333
|
endResize();
|
|
1360
2334
|
document.body.classList.remove('no-scroll');
|
|
@@ -1555,9 +2529,12 @@
|
|
|
1555
2529
|
const result = document.getElementById('tunnel-test-result');
|
|
1556
2530
|
result.innerHTML = '<span class="text-gray-500">Testing...</span>';
|
|
1557
2531
|
fetch('/health')
|
|
1558
|
-
.then(r =>
|
|
1559
|
-
|
|
1560
|
-
|
|
2532
|
+
.then((r) =>
|
|
2533
|
+
r.ok
|
|
2534
|
+
? (result.innerHTML = '<span class="text-green-500">Connection OK</span>')
|
|
2535
|
+
: (result.innerHTML = '<span class="text-red-500">Connection failed</span>')
|
|
2536
|
+
)
|
|
2537
|
+
.catch(() => (result.innerHTML = '<span class="text-red-500">Connection failed</span>'));
|
|
1561
2538
|
}
|
|
1562
2539
|
|
|
1563
2540
|
async function sendChatMessage() {
|
|
@@ -1585,21 +2562,31 @@
|
|
|
1585
2562
|
const message = input.value.trim() || defaultMsg;
|
|
1586
2563
|
|
|
1587
2564
|
const mediaUrl = '/api/media/' + encodeURIComponent(data.filename);
|
|
1588
|
-
const attachMeta = {
|
|
2565
|
+
const attachMeta = {
|
|
2566
|
+
mediaUrl,
|
|
2567
|
+
filename: data.filename,
|
|
2568
|
+
originalName: file.name,
|
|
2569
|
+
contentType: file.type,
|
|
2570
|
+
isImage,
|
|
2571
|
+
};
|
|
1589
2572
|
|
|
1590
2573
|
// Save with attachment metadata for history persistence
|
|
1591
2574
|
chat.addUserMessageWithAttachment(message, attachMeta);
|
|
1592
2575
|
|
|
1593
2576
|
chat.enableSend(false);
|
|
1594
|
-
chat.ws.send(
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
2577
|
+
chat.ws.send(
|
|
2578
|
+
JSON.stringify({
|
|
2579
|
+
type: 'send',
|
|
2580
|
+
sessionId: chat.sessionId,
|
|
2581
|
+
content: message,
|
|
2582
|
+
attachments: [
|
|
2583
|
+
{
|
|
2584
|
+
filename: data.filename,
|
|
2585
|
+
contentType: data.contentType,
|
|
2586
|
+
},
|
|
2587
|
+
],
|
|
2588
|
+
})
|
|
2589
|
+
);
|
|
1603
2590
|
|
|
1604
2591
|
// Clear attachment only after successful send
|
|
1605
2592
|
clearAttachment();
|
|
@@ -1614,7 +2601,7 @@
|
|
|
1614
2601
|
}
|
|
1615
2602
|
|
|
1616
2603
|
// Send quiz choice as message
|
|
1617
|
-
window.sendQuizChoice = function(choice) {
|
|
2604
|
+
window.sendQuizChoice = function (choice) {
|
|
1618
2605
|
if (chat && chat.ws && chat.ws.readyState === WebSocket.OPEN) {
|
|
1619
2606
|
// Set the input to the choice and send
|
|
1620
2607
|
const input = document.getElementById('chat-input');
|
|
@@ -1669,8 +2656,9 @@
|
|
|
1669
2656
|
if (!response.ok) throw new Error('Export failed');
|
|
1670
2657
|
|
|
1671
2658
|
const blob = await response.blob();
|
|
1672
|
-
const filename =
|
|
1673
|
-
||
|
|
2659
|
+
const filename =
|
|
2660
|
+
response.headers.get('Content-Disposition')?.match(/filename="(.+)"/)?.[1] ||
|
|
2661
|
+
`mama-export.${format}`;
|
|
1674
2662
|
|
|
1675
2663
|
const url = URL.createObjectURL(blob);
|
|
1676
2664
|
const a = document.createElement('a');
|
|
@@ -1744,9 +2732,10 @@
|
|
|
1744
2732
|
console.log('[MAMA] Loaded', checkpointsData.length, 'checkpoints');
|
|
1745
2733
|
|
|
1746
2734
|
if (checkpointsData.length > 0) {
|
|
1747
|
-
container.innerHTML = checkpointsData
|
|
1748
|
-
|
|
1749
|
-
|
|
2735
|
+
container.innerHTML = checkpointsData
|
|
2736
|
+
.map((cp, idx) => {
|
|
2737
|
+
const fullSummary = renderMarkdown(cp.summary || '');
|
|
2738
|
+
return `
|
|
1750
2739
|
<div class="checkpoint-item p-3 bg-white bg-white border border-gray-200 border-gray-300 rounded-lg cursor-pointer hover:border-indigo-500 transition-colors" onclick="toggleCheckpoint(${idx})">
|
|
1751
2740
|
<div class="text-xs font-semibold text-mama-black text-mama-black mb-1">${new Date(cp.timestamp).toLocaleString()}</div>
|
|
1752
2741
|
<div class="checkpoint-summary text-sm text-gray-700 text-gray-700 markdown-content line-clamp-3 overflow-hidden">${fullSummary}</div>
|
|
@@ -1754,13 +2743,17 @@
|
|
|
1754
2743
|
<div class="text-sm text-gray-700 text-gray-700 markdown-content max-h-64 overflow-y-auto">${fullSummary}</div>
|
|
1755
2744
|
</div>
|
|
1756
2745
|
</div>
|
|
1757
|
-
|
|
2746
|
+
`;
|
|
2747
|
+
})
|
|
2748
|
+
.join('');
|
|
1758
2749
|
} else {
|
|
1759
|
-
container.innerHTML =
|
|
2750
|
+
container.innerHTML =
|
|
2751
|
+
'<div class="text-center text-sm text-gray-500 py-4">No checkpoints found</div>';
|
|
1760
2752
|
}
|
|
1761
2753
|
} catch (error) {
|
|
1762
2754
|
console.error('[MAMA] Failed to load checkpoints:', error);
|
|
1763
|
-
container.innerHTML =
|
|
2755
|
+
container.innerHTML =
|
|
2756
|
+
'<div class="text-center text-sm text-red-500 py-4">Failed to load checkpoints</div>';
|
|
1764
2757
|
}
|
|
1765
2758
|
}
|
|
1766
2759
|
|
|
@@ -1783,13 +2776,27 @@
|
|
|
1783
2776
|
}
|
|
1784
2777
|
|
|
1785
2778
|
// Connector list loader for Settings
|
|
1786
|
-
const CONNECTOR_NAMES = [
|
|
2779
|
+
const CONNECTOR_NAMES = [
|
|
2780
|
+
'slack',
|
|
2781
|
+
'telegram',
|
|
2782
|
+
'discord',
|
|
2783
|
+
'chatwork',
|
|
2784
|
+
'gmail',
|
|
2785
|
+
'calendar',
|
|
2786
|
+
'notion',
|
|
2787
|
+
'obsidian',
|
|
2788
|
+
'kagemusha',
|
|
2789
|
+
'sheets',
|
|
2790
|
+
'trello',
|
|
2791
|
+
'drive',
|
|
2792
|
+
'imessage',
|
|
2793
|
+
];
|
|
1787
2794
|
const CONNECTOR_CATEGORIES = {
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
2795
|
+
Messaging: ['slack', 'telegram', 'discord', 'chatwork'],
|
|
2796
|
+
Google: ['gmail', 'calendar', 'drive', 'sheets'],
|
|
2797
|
+
Knowledge: ['notion', 'obsidian', 'kagemusha'],
|
|
1791
2798
|
'Dev Tools': ['claude-code'],
|
|
1792
|
-
|
|
2799
|
+
Other: ['trello', 'imessage'],
|
|
1793
2800
|
};
|
|
1794
2801
|
async function loadConnectorsList() {
|
|
1795
2802
|
const container = document.getElementById('settings-connectors-list');
|
|
@@ -1799,7 +2806,7 @@
|
|
|
1799
2806
|
const res = await fetch('/api/connectors/status');
|
|
1800
2807
|
if (res.ok) {
|
|
1801
2808
|
const data = await res.json();
|
|
1802
|
-
for (const c of
|
|
2809
|
+
for (const c of data.connectors || []) connectorStatus[c.name] = c;
|
|
1803
2810
|
}
|
|
1804
2811
|
} catch {}
|
|
1805
2812
|
// Load config
|
|
@@ -1817,17 +2824,24 @@
|
|
|
1817
2824
|
for (const name of names) {
|
|
1818
2825
|
const status = connectorStatus[name];
|
|
1819
2826
|
const cfg = config[name];
|
|
1820
|
-
const enabled = cfg?.enabled ||
|
|
2827
|
+
const enabled = cfg?.enabled || status?.enabled || false;
|
|
1821
2828
|
const healthy = status?.healthy || false;
|
|
1822
|
-
const lastPoll = status?.lastPollTime
|
|
2829
|
+
const lastPoll = status?.lastPollTime
|
|
2830
|
+
? new Date(status.lastPollTime).toLocaleTimeString('ko-KR', {
|
|
2831
|
+
hour: '2-digit',
|
|
2832
|
+
minute: '2-digit',
|
|
2833
|
+
})
|
|
2834
|
+
: null;
|
|
1823
2835
|
const channels = status?.channelCount || Object.keys(cfg?.channels || {}).length || 0;
|
|
1824
2836
|
const statusDot = enabled ? (healthy ? '#3A9E7E' : '#E8A040') : '#9E9891';
|
|
1825
2837
|
html += `<div style="background:#fff;border:1px solid #EDE9E1;border-radius:4px;padding:8px 10px;font-size:12px;display:flex;align-items:center;gap:8px">`;
|
|
1826
2838
|
html += `<span style="display:inline-block;width:6px;height:6px;background:${statusDot};border-radius:1px;flex-shrink:0"></span>`;
|
|
1827
2839
|
html += `<span style="font-weight:600;color:#1A1A1A;flex:1">${name}</span>`;
|
|
1828
|
-
if (channels > 0)
|
|
2840
|
+
if (channels > 0)
|
|
2841
|
+
html += `<span style="font-size:10px;color:#9E9891">${channels}ch</span>`;
|
|
1829
2842
|
if (lastPoll) html += `<span style="font-size:10px;color:#9E9891">${lastPoll}</span>`;
|
|
1830
|
-
if (!enabled)
|
|
2843
|
+
if (!enabled)
|
|
2844
|
+
html += `<span style="font-size:9px;color:#9E9891;background:#F5F2ED;padding:1px 4px;border-radius:2px">off</span>`;
|
|
1831
2845
|
html += `</div>`;
|
|
1832
2846
|
}
|
|
1833
2847
|
html += `</div></div>`;
|
|
@@ -1835,8 +2849,27 @@
|
|
|
1835
2849
|
container.innerHTML = html;
|
|
1836
2850
|
}
|
|
1837
2851
|
|
|
2852
|
+
// Mobile "More" menu
|
|
2853
|
+
function toggleMobileMore() {
|
|
2854
|
+
const more = document.getElementById('mama-mobile-more');
|
|
2855
|
+
if (!more) return;
|
|
2856
|
+
const isVisible = more.style.display !== 'none';
|
|
2857
|
+
more.style.display = isVisible ? 'none' : 'block';
|
|
2858
|
+
// Update More button active state
|
|
2859
|
+
const moreBtn = document.querySelector('#mama-mobile-tabs [data-tab="more"]');
|
|
2860
|
+
if (moreBtn) moreBtn.classList.toggle('mama-nav-active', !isVisible);
|
|
2861
|
+
}
|
|
2862
|
+
function closeMobileMore() {
|
|
2863
|
+
const more = document.getElementById('mama-mobile-more');
|
|
2864
|
+
if (more) more.style.display = 'none';
|
|
2865
|
+
const moreBtn = document.querySelector('#mama-mobile-tabs [data-tab="more"]');
|
|
2866
|
+
if (moreBtn) moreBtn.classList.remove('mama-nav-active');
|
|
2867
|
+
}
|
|
2868
|
+
|
|
1838
2869
|
// Expose to window for onclick handlers
|
|
1839
2870
|
window.switchTab = switchTab;
|
|
2871
|
+
window.toggleMobileMore = toggleMobileMore;
|
|
2872
|
+
window.closeMobileMore = closeMobileMore;
|
|
1840
2873
|
window.toggleTheme = toggleTheme;
|
|
1841
2874
|
window.toggleLegend = toggleLegend;
|
|
1842
2875
|
window.closeDetailModal = closeDetailModal;
|
|
@@ -1882,7 +2915,9 @@
|
|
|
1882
2915
|
|
|
1883
2916
|
if (file.type.startsWith('image/')) {
|
|
1884
2917
|
const reader = new FileReader();
|
|
1885
|
-
reader.onload = (e) => {
|
|
2918
|
+
reader.onload = (e) => {
|
|
2919
|
+
thumb.src = e.target.result;
|
|
2920
|
+
};
|
|
1886
2921
|
reader.readAsDataURL(file);
|
|
1887
2922
|
thumb.style.display = '';
|
|
1888
2923
|
} else {
|
|
@@ -1905,7 +2940,7 @@
|
|
|
1905
2940
|
document.getElementById('chat-attachment-preview').classList.add('hidden');
|
|
1906
2941
|
document.getElementById('chat-file-input').value = '';
|
|
1907
2942
|
const thumb = document.getElementById('chat-attachment-thumb');
|
|
1908
|
-
thumb.src = '';
|
|
2943
|
+
thumb.src = 'data:,';
|
|
1909
2944
|
thumb.style.display = '';
|
|
1910
2945
|
}
|
|
1911
2946
|
|
|
@@ -1916,38 +2951,76 @@
|
|
|
1916
2951
|
const chatMessages = document.getElementById('chat-messages');
|
|
1917
2952
|
if (chatMessages) {
|
|
1918
2953
|
const panel = chatMessages.closest('#chat-panel') || chatMessages.parentElement;
|
|
1919
|
-
['dragenter', 'dragover'].forEach(evt => {
|
|
1920
|
-
panel.addEventListener(evt, (e) => {
|
|
2954
|
+
['dragenter', 'dragover'].forEach((evt) => {
|
|
2955
|
+
panel.addEventListener(evt, (e) => {
|
|
2956
|
+
e.preventDefault();
|
|
2957
|
+
e.stopPropagation();
|
|
2958
|
+
panel.classList.add('ring-2', 'ring-mama-yellow');
|
|
2959
|
+
});
|
|
1921
2960
|
});
|
|
1922
|
-
['dragleave', 'drop'].forEach(evt => {
|
|
1923
|
-
panel.addEventListener(evt, (e) => {
|
|
2961
|
+
['dragleave', 'drop'].forEach((evt) => {
|
|
2962
|
+
panel.addEventListener(evt, (e) => {
|
|
2963
|
+
e.preventDefault();
|
|
2964
|
+
e.stopPropagation();
|
|
2965
|
+
panel.classList.remove('ring-2', 'ring-mama-yellow');
|
|
2966
|
+
});
|
|
1924
2967
|
});
|
|
1925
2968
|
panel.addEventListener('drop', (e) => {
|
|
1926
2969
|
const file = e.dataTransfer.files[0];
|
|
1927
2970
|
if (!file) return;
|
|
1928
2971
|
|
|
1929
2972
|
// Allowed MIME types and extensions (match file input accept attribute)
|
|
1930
|
-
const allowedTypes = [
|
|
2973
|
+
const allowedTypes = [
|
|
2974
|
+
'image/',
|
|
2975
|
+
'application/pdf',
|
|
2976
|
+
'application/msword',
|
|
1931
2977
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
1932
|
-
'text/plain',
|
|
1933
|
-
'
|
|
2978
|
+
'text/plain',
|
|
2979
|
+
'text/csv',
|
|
2980
|
+
'text/markdown',
|
|
2981
|
+
'text/html',
|
|
2982
|
+
'text/xml',
|
|
2983
|
+
'application/json',
|
|
2984
|
+
'application/xml',
|
|
1934
2985
|
'application/vnd.ms-excel',
|
|
1935
2986
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
1936
2987
|
'application/vnd.ms-powerpoint',
|
|
1937
2988
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
1938
|
-
'application/zip',
|
|
1939
|
-
|
|
1940
|
-
|
|
2989
|
+
'application/zip',
|
|
2990
|
+
'application/gzip',
|
|
2991
|
+
];
|
|
2992
|
+
const allowedExts = [
|
|
2993
|
+
'.pdf',
|
|
2994
|
+
'.doc',
|
|
2995
|
+
'.docx',
|
|
2996
|
+
'.txt',
|
|
2997
|
+
'.csv',
|
|
2998
|
+
'.xls',
|
|
2999
|
+
'.xlsx',
|
|
3000
|
+
'.md',
|
|
3001
|
+
'.json',
|
|
3002
|
+
'.html',
|
|
3003
|
+
'.htm',
|
|
3004
|
+
'.xml',
|
|
3005
|
+
'.zip',
|
|
3006
|
+
'.gz',
|
|
3007
|
+
'.ppt',
|
|
3008
|
+
'.pptx',
|
|
3009
|
+
];
|
|
1941
3010
|
const ext = '.' + (file.name.split('.').pop() || '').toLowerCase();
|
|
1942
3011
|
|
|
1943
|
-
const isAllowed =
|
|
3012
|
+
const isAllowed =
|
|
3013
|
+
allowedTypes.some((t) => file.type.startsWith(t)) || allowedExts.includes(ext);
|
|
1944
3014
|
if (isAllowed) {
|
|
1945
3015
|
const dt = new DataTransfer();
|
|
1946
3016
|
dt.items.add(file);
|
|
1947
3017
|
document.getElementById('chat-file-input').files = dt.files;
|
|
1948
3018
|
handleFileSelect({ target: { files: [file] } });
|
|
1949
3019
|
} else {
|
|
1950
|
-
chat.addSystemMessage(
|
|
3020
|
+
chat.addSystemMessage(
|
|
3021
|
+
'Unsupported file type. Allowed: images, PDF, DOC, TXT, CSV, XLS, PPT, MD, JSON, HTML, ZIP',
|
|
3022
|
+
'error'
|
|
3023
|
+
);
|
|
1951
3024
|
}
|
|
1952
3025
|
});
|
|
1953
3026
|
}
|
|
@@ -1978,10 +3051,16 @@
|
|
|
1978
3051
|
window.addEventListener('message', (event) => {
|
|
1979
3052
|
if (!event.data) return;
|
|
1980
3053
|
|
|
1981
|
-
//
|
|
1982
|
-
if (event.data.type === '
|
|
1983
|
-
|
|
1984
|
-
|
|
3054
|
+
// viewer:sendToChat — generic child iframe → chat handoff
|
|
3055
|
+
if (event.data.type === 'viewer:sendToChat') {
|
|
3056
|
+
const message = typeof event.data.message === 'string' ? event.data.message : '';
|
|
3057
|
+
if (!message) {
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
const input = document.getElementById('chat-input');
|
|
3061
|
+
if (input && chat) {
|
|
3062
|
+
input.value = message;
|
|
3063
|
+
setTimeout(() => chat.send(), 50);
|
|
1985
3064
|
}
|
|
1986
3065
|
}
|
|
1987
3066
|
});
|
|
@@ -2010,15 +3089,6 @@ Please explain what this tab shows:
|
|
|
2010
3089
|
- Scheduled jobs (Cron) status
|
|
2011
3090
|
Explain what each section means and what actions the user can take. Be friendly and concise.`,
|
|
2012
3091
|
|
|
2013
|
-
skills: `The user clicked the help button on the Skills tab.
|
|
2014
|
-
Please explain this tab's features:
|
|
2015
|
-
- Installed: List of installed skills (toggle enable/disable, edit, remove)
|
|
2016
|
-
- Available: Skills from the Cowork marketplace that can be installed
|
|
2017
|
-
- Install from GitHub URL for external plugins
|
|
2018
|
-
- [+ New Skill] button to create skills in Skill Lab
|
|
2019
|
-
- [Edit] button to modify existing skills in Skill Lab
|
|
2020
|
-
Explain what skills are and how they enhance the agent's capabilities. Be friendly and concise.`,
|
|
2021
|
-
|
|
2022
3092
|
memory: `The user clicked the help button on the Memory tab.
|
|
2023
3093
|
Please explain this tab's features:
|
|
2024
3094
|
- Decision Graph: Visual graph showing relationships between decisions (click nodes for details)
|
|
@@ -2044,19 +3114,21 @@ Please explain this tab's features:
|
|
|
2044
3114
|
- Filter by log level (ERROR, WARN, INFO, DEBUG)
|
|
2045
3115
|
- Search logs by keyword
|
|
2046
3116
|
- Pause/Resume auto-refresh
|
|
2047
|
-
Be friendly and concise
|
|
3117
|
+
Be friendly and concise.`,
|
|
2048
3118
|
};
|
|
2049
3119
|
|
|
2050
|
-
window.askContextHelp = function() {
|
|
3120
|
+
window.askContextHelp = function () {
|
|
2051
3121
|
const currentTab = STATE.currentTab || 'dashboard';
|
|
2052
3122
|
const prompt = TAB_HELP_PROMPTS[currentTab];
|
|
2053
3123
|
if (!prompt) return;
|
|
2054
3124
|
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
const
|
|
2059
|
-
if (
|
|
3125
|
+
if (window.innerWidth < 768) {
|
|
3126
|
+
switchTab('chat');
|
|
3127
|
+
} else {
|
|
3128
|
+
const wrapper = document.getElementById('chat-panel-wrapper');
|
|
3129
|
+
if (wrapper && wrapper.style.display === 'none') {
|
|
3130
|
+
toggleChatPanel();
|
|
3131
|
+
}
|
|
2060
3132
|
}
|
|
2061
3133
|
|
|
2062
3134
|
// Set input and send
|
|
@@ -2070,17 +3142,31 @@ Be friendly and concise.`
|
|
|
2070
3142
|
// Register Service Worker for PWA
|
|
2071
3143
|
if ('serviceWorker' in navigator) {
|
|
2072
3144
|
window.addEventListener('load', () => {
|
|
2073
|
-
navigator.serviceWorker
|
|
2074
|
-
.
|
|
2075
|
-
.
|
|
3145
|
+
navigator.serviceWorker
|
|
3146
|
+
.register('/viewer/sw.js')
|
|
3147
|
+
.then((reg) => console.log('[PWA] Service Worker registered:', reg.scope))
|
|
3148
|
+
.catch((err) => console.warn('[PWA] Service Worker registration failed:', err));
|
|
2076
3149
|
});
|
|
2077
3150
|
}
|
|
2078
3151
|
</script>
|
|
2079
3152
|
|
|
2080
3153
|
<!-- Image Lightbox -->
|
|
2081
|
-
<div
|
|
2082
|
-
|
|
2083
|
-
|
|
3154
|
+
<div
|
|
3155
|
+
id="image-lightbox"
|
|
3156
|
+
class="fixed inset-0 z-[9999] hidden items-center justify-center bg-black/80 backdrop-blur-sm cursor-pointer"
|
|
3157
|
+
onclick="closeLightbox()"
|
|
3158
|
+
>
|
|
3159
|
+
<img
|
|
3160
|
+
id="lightbox-img"
|
|
3161
|
+
class="max-w-[90vw] max-h-[90vh] rounded-lg shadow-2xl"
|
|
3162
|
+
onclick="event.stopPropagation()"
|
|
3163
|
+
/>
|
|
3164
|
+
<button
|
|
3165
|
+
class="absolute top-4 right-4 text-white text-3xl font-bold hover:text-gray-300"
|
|
3166
|
+
onclick="closeLightbox()"
|
|
3167
|
+
>
|
|
3168
|
+
×
|
|
3169
|
+
</button>
|
|
2084
3170
|
</div>
|
|
2085
3171
|
<script>
|
|
2086
3172
|
function openLightbox(src) {
|
|
@@ -2094,11 +3180,16 @@ Be friendly and concise.`
|
|
|
2094
3180
|
lb.classList.add('hidden');
|
|
2095
3181
|
lb.classList.remove('flex');
|
|
2096
3182
|
}
|
|
2097
|
-
document.addEventListener('keydown', e => {
|
|
3183
|
+
document.addEventListener('keydown', (e) => {
|
|
3184
|
+
if (e.key === 'Escape') closeLightbox();
|
|
3185
|
+
});
|
|
2098
3186
|
// Event delegation for lightbox — avoids inline onclick XSS
|
|
2099
|
-
document.addEventListener('click', e => {
|
|
3187
|
+
document.addEventListener('click', (e) => {
|
|
2100
3188
|
const el = e.target.closest('[data-lightbox]');
|
|
2101
|
-
if (el) {
|
|
3189
|
+
if (el) {
|
|
3190
|
+
e.stopPropagation();
|
|
3191
|
+
openLightbox(el.dataset.lightbox);
|
|
3192
|
+
}
|
|
2102
3193
|
});
|
|
2103
3194
|
</script>
|
|
2104
3195
|
</body>
|