@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.
Files changed (171) hide show
  1. package/dist/agent/agent-loop.d.ts +25 -0
  2. package/dist/agent/agent-loop.d.ts.map +1 -1
  3. package/dist/agent/agent-loop.js +67 -14
  4. package/dist/agent/agent-loop.js.map +1 -1
  5. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  6. package/dist/agent/code-act/host-bridge.js +98 -0
  7. package/dist/agent/code-act/host-bridge.js.map +1 -1
  8. package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
  9. package/dist/agent/code-act/type-definition-generator.js +0 -1
  10. package/dist/agent/code-act/type-definition-generator.js.map +1 -1
  11. package/dist/agent/gateway-tool-executor.d.ts +36 -1
  12. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  13. package/dist/agent/gateway-tool-executor.js +938 -54
  14. package/dist/agent/gateway-tool-executor.js.map +1 -1
  15. package/dist/agent/gateway-tools.md +9 -0
  16. package/dist/agent/managed-agent-runtime-sync.d.ts +36 -0
  17. package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -0
  18. package/dist/agent/managed-agent-runtime-sync.js +207 -0
  19. package/dist/agent/managed-agent-runtime-sync.js.map +1 -0
  20. package/dist/agent/managed-agent-validation.d.ts +4 -0
  21. package/dist/agent/managed-agent-validation.d.ts.map +1 -0
  22. package/dist/agent/managed-agent-validation.js +84 -0
  23. package/dist/agent/managed-agent-validation.js.map +1 -0
  24. package/dist/agent/os-agent-capabilities.md +400 -0
  25. package/dist/agent/skill-loader.d.ts +2 -0
  26. package/dist/agent/skill-loader.d.ts.map +1 -1
  27. package/dist/agent/skill-loader.js +28 -0
  28. package/dist/agent/skill-loader.js.map +1 -1
  29. package/dist/agent/tool-registry.d.ts.map +1 -1
  30. package/dist/agent/tool-registry.js +66 -0
  31. package/dist/agent/tool-registry.js.map +1 -1
  32. package/dist/agent/types.d.ts +2 -1
  33. package/dist/agent/types.d.ts.map +1 -1
  34. package/dist/agent/types.js.map +1 -1
  35. package/dist/api/agent-handler.d.ts +34 -0
  36. package/dist/api/agent-handler.d.ts.map +1 -0
  37. package/dist/api/agent-handler.js +216 -0
  38. package/dist/api/agent-handler.js.map +1 -0
  39. package/dist/api/graph-api-types.d.ts +4 -0
  40. package/dist/api/graph-api-types.d.ts.map +1 -1
  41. package/dist/api/graph-api.d.ts +2 -2
  42. package/dist/api/graph-api.d.ts.map +1 -1
  43. package/dist/api/graph-api.js +480 -51
  44. package/dist/api/graph-api.js.map +1 -1
  45. package/dist/api/index.d.ts.map +1 -1
  46. package/dist/api/index.js +4 -0
  47. package/dist/api/index.js.map +1 -1
  48. package/dist/api/token-handler.d.ts +1 -0
  49. package/dist/api/token-handler.d.ts.map +1 -1
  50. package/dist/api/token-handler.js +4 -3
  51. package/dist/api/token-handler.js.map +1 -1
  52. package/dist/api/ui-command-handler.d.ts +48 -0
  53. package/dist/api/ui-command-handler.d.ts.map +1 -0
  54. package/dist/api/ui-command-handler.js +160 -0
  55. package/dist/api/ui-command-handler.js.map +1 -0
  56. package/dist/cli/commands/start.d.ts.map +1 -1
  57. package/dist/cli/commands/start.js +127 -1
  58. package/dist/cli/commands/start.js.map +1 -1
  59. package/dist/cli/config/config-manager.d.ts.map +1 -1
  60. package/dist/cli/config/config-manager.js +16 -31
  61. package/dist/cli/config/config-manager.js.map +1 -1
  62. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  63. package/dist/cli/runtime/agent-loop-init.js +31 -7
  64. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  65. package/dist/cli/runtime/api-routes-init.d.ts +3 -0
  66. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  67. package/dist/cli/runtime/api-routes-init.js +283 -34
  68. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  69. package/dist/cli/runtime/gateway-init.d.ts +2 -1
  70. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  71. package/dist/cli/runtime/gateway-init.js +5 -1
  72. package/dist/cli/runtime/gateway-init.js.map +1 -1
  73. package/dist/connectors/framework/raw-store.d.ts +4 -0
  74. package/dist/connectors/framework/raw-store.d.ts.map +1 -1
  75. package/dist/connectors/framework/raw-store.js +33 -10
  76. package/dist/connectors/framework/raw-store.js.map +1 -1
  77. package/dist/db/agent-store.d.ts +115 -0
  78. package/dist/db/agent-store.d.ts.map +1 -0
  79. package/dist/db/agent-store.js +248 -0
  80. package/dist/db/agent-store.js.map +1 -0
  81. package/dist/db/migrations/agent-activity-validation-columns.d.ts +3 -0
  82. package/dist/db/migrations/agent-activity-validation-columns.d.ts.map +1 -0
  83. package/dist/db/migrations/agent-activity-validation-columns.js +22 -0
  84. package/dist/db/migrations/agent-activity-validation-columns.js.map +1 -0
  85. package/dist/db/migrations/agent-metrics-response-avg.d.ts +3 -0
  86. package/dist/db/migrations/agent-metrics-response-avg.d.ts.map +1 -0
  87. package/dist/db/migrations/agent-metrics-response-avg.js +19 -0
  88. package/dist/db/migrations/agent-metrics-response-avg.js.map +1 -0
  89. package/dist/db/migrations/agent-store-tables.d.ts +3 -0
  90. package/dist/db/migrations/agent-store-tables.d.ts.map +1 -0
  91. package/dist/db/migrations/agent-store-tables.js +59 -0
  92. package/dist/db/migrations/agent-store-tables.js.map +1 -0
  93. package/dist/db/migrations/token-usage-agent-version.d.ts +3 -0
  94. package/dist/db/migrations/token-usage-agent-version.d.ts.map +1 -0
  95. package/dist/db/migrations/token-usage-agent-version.js +16 -0
  96. package/dist/db/migrations/token-usage-agent-version.js.map +1 -0
  97. package/dist/db/migrations/validation-session-tables.d.ts +3 -0
  98. package/dist/db/migrations/validation-session-tables.d.ts.map +1 -0
  99. package/dist/db/migrations/validation-session-tables.js +59 -0
  100. package/dist/db/migrations/validation-session-tables.js.map +1 -0
  101. package/dist/gateways/message-router.d.ts +10 -0
  102. package/dist/gateways/message-router.d.ts.map +1 -1
  103. package/dist/gateways/message-router.js +188 -14
  104. package/dist/gateways/message-router.js.map +1 -1
  105. package/dist/gateways/types.d.ts +1 -1
  106. package/dist/gateways/types.d.ts.map +1 -1
  107. package/dist/multi-agent/agent-process-manager.js +1 -1
  108. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  109. package/dist/multi-agent/conductor-persona.d.ts +13 -0
  110. package/dist/multi-agent/conductor-persona.d.ts.map +1 -0
  111. package/dist/multi-agent/conductor-persona.js +157 -0
  112. package/dist/multi-agent/conductor-persona.js.map +1 -0
  113. package/dist/multi-agent/dashboard-agent-persona.d.ts +1 -1
  114. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  115. package/dist/multi-agent/dashboard-agent-persona.js +7 -3
  116. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  117. package/dist/multi-agent/delegation-manager.d.ts +5 -0
  118. package/dist/multi-agent/delegation-manager.d.ts.map +1 -1
  119. package/dist/multi-agent/delegation-manager.js +37 -0
  120. package/dist/multi-agent/delegation-manager.js.map +1 -1
  121. package/dist/multi-agent/ultrawork.d.ts +3 -0
  122. package/dist/multi-agent/ultrawork.d.ts.map +1 -1
  123. package/dist/multi-agent/ultrawork.js +9 -0
  124. package/dist/multi-agent/ultrawork.js.map +1 -1
  125. package/dist/validation/session-service.d.ts +72 -0
  126. package/dist/validation/session-service.d.ts.map +1 -0
  127. package/dist/validation/session-service.js +298 -0
  128. package/dist/validation/session-service.js.map +1 -0
  129. package/dist/validation/store.d.ts +25 -0
  130. package/dist/validation/store.d.ts.map +1 -0
  131. package/dist/validation/store.js +200 -0
  132. package/dist/validation/store.js.map +1 -0
  133. package/dist/validation/types.d.ts +119 -0
  134. package/dist/validation/types.d.ts.map +1 -0
  135. package/dist/validation/types.js +57 -0
  136. package/dist/validation/types.js.map +1 -0
  137. package/package.json +3 -3
  138. package/public/viewer/js/modules/agents.js +1148 -0
  139. package/public/viewer/js/modules/chat.js +20 -11
  140. package/public/viewer/js/modules/connector-feed.js +35 -0
  141. package/public/viewer/js/modules/dashboard.js +49 -0
  142. package/public/viewer/js/modules/memory.js +32 -0
  143. package/public/viewer/js/modules/settings.js +34 -79
  144. package/public/viewer/js/modules/wiki.js +59 -4
  145. package/public/viewer/js/utils/api.js +70 -0
  146. package/public/viewer/js/utils/dom.js +3 -0
  147. package/public/viewer/js/utils/ui-commands.js +93 -0
  148. package/public/viewer/log-viewer.html +2 -2
  149. package/public/viewer/src/modules/agents.ts +1299 -0
  150. package/public/viewer/src/modules/chat.ts +23 -14
  151. package/public/viewer/src/modules/connector-feed.ts +35 -0
  152. package/public/viewer/src/modules/dashboard.ts +50 -0
  153. package/public/viewer/src/modules/memory.ts +31 -0
  154. package/public/viewer/src/modules/settings.ts +36 -96
  155. package/public/viewer/src/modules/wiki.ts +73 -6
  156. package/public/viewer/src/types/global.d.ts +0 -9
  157. package/public/viewer/src/utils/api.ts +156 -2
  158. package/public/viewer/src/utils/dom.ts +6 -1
  159. package/public/viewer/src/utils/ui-commands.ts +118 -0
  160. package/public/viewer/viewer.css +105 -10
  161. package/public/viewer/viewer.html +1868 -777
  162. package/scripts/generate-gateway-tools.ts +5 -1
  163. package/public/viewer/js/modules/playground.js +0 -148
  164. package/public/viewer/js/modules/skills.js +0 -451
  165. package/public/viewer/src/modules/playground.ts +0 -173
  166. package/public/viewer/src/modules/skills.ts +0 -491
  167. package/templates/playgrounds/cron-workflow-lab.html +0 -1601
  168. package/templates/playgrounds/mama-log-viewer.html +0 -1341
  169. package/templates/playgrounds/skill-lab-playground.html +0 -1625
  170. package/templates/playgrounds/wave-visualizer.html +0 -694
  171. package/templates/skills/playground.md +0 -197
@@ -156,9 +156,10 @@ export interface ApiAgentToolsConfig {
156
156
  }
157
157
 
158
158
  export type EffortLevel = 'low' | 'medium' | 'high' | 'max';
159
+ export type ApiValidationTriggerType = 'agent_test' | 'delegate_run' | 'system_run' | 'audit';
159
160
 
160
161
  export interface ApiAgentConfig {
161
- backend?: 'claude' | 'codex-mcp';
162
+ backend?: 'claude' | 'codex' | 'codex-mcp' | 'gemini';
162
163
  model?: string;
163
164
  effort?: EffortLevel;
164
165
  tools?: ApiAgentToolsConfig;
@@ -216,7 +217,7 @@ export interface MultiAgentAgent {
216
217
  status?: string;
217
218
  model?: string;
218
219
  effort?: EffortLevel;
219
- backend?: 'claude' | 'codex-mcp';
220
+ backend?: 'claude' | 'codex' | 'codex-mcp' | 'gemini';
220
221
  bot_token?: string;
221
222
  slack_bot_token?: string | null;
222
223
  slack_app_token?: string | null;
@@ -883,6 +884,159 @@ export class API {
883
884
  return this.post(`/api/multi-agent/agents/${encodeURIComponent(agentId)}/stop`, {});
884
885
  }
885
886
 
887
+ // =============================================
888
+ // Agent Management API (Managed Agents pattern)
889
+ // =============================================
890
+
891
+ static async getAgents(): Promise<{ agents: MultiAgentAgent[] }> {
892
+ return this.get('/api/agents');
893
+ }
894
+
895
+ static async getAgent(
896
+ agentId: string
897
+ ): Promise<MultiAgentAgent & { system?: string; version?: number }> {
898
+ return this.get(`/api/agents/${encodeURIComponent(agentId)}`);
899
+ }
900
+
901
+ static async createAgent(body: {
902
+ id: string;
903
+ name: string;
904
+ model: string;
905
+ tier: number;
906
+ system?: string;
907
+ }): Promise<JsonRecord> {
908
+ return this.post('/api/agents', body);
909
+ }
910
+
911
+ static async updateAgent(
912
+ agentId: string,
913
+ body: { version?: number; changes: Record<string, unknown>; change_note?: string }
914
+ ): Promise<JsonRecord> {
915
+ return this.post(`/api/agents/${encodeURIComponent(agentId)}`, body);
916
+ }
917
+
918
+ static async archiveAgent(agentId: string): Promise<JsonRecord> {
919
+ return this.post(`/api/agents/${encodeURIComponent(agentId)}/archive`, {});
920
+ }
921
+
922
+ static async getAgentVersions(agentId: string): Promise<{ versions: JsonRecord[] }> {
923
+ return this.get(`/api/agents/${encodeURIComponent(agentId)}/versions`);
924
+ }
925
+
926
+ static async compareAgentVersions(agentId: string, v1: number, v2: number): Promise<JsonRecord> {
927
+ return this.get(`/api/agents/${encodeURIComponent(agentId)}/versions/${v1}/compare/${v2}`);
928
+ }
929
+
930
+ static async getAgentMetrics(
931
+ agentId: string,
932
+ from: string,
933
+ to: string
934
+ ): Promise<{ metrics: JsonRecord[] }> {
935
+ return this.get(`/api/agents/${encodeURIComponent(agentId)}/metrics`, { from, to });
936
+ }
937
+
938
+ static async getAgentActivity(
939
+ agentId: string,
940
+ limit = 20
941
+ ): Promise<{ activity: Array<Record<string, unknown>> }> {
942
+ return this.get(`/api/agents/${encodeURIComponent(agentId)}/activity?limit=${limit}`);
943
+ }
944
+
945
+ static async getActivitySummary(
946
+ since: string
947
+ ): Promise<{ summary: Array<Record<string, unknown>>; alerts: string[] }> {
948
+ return this.get(`/api/agents/activity-summary?since=${encodeURIComponent(since)}`);
949
+ }
950
+
951
+ // =============================================
952
+ // Validation API
953
+ // =============================================
954
+
955
+ static async getValidationSummary(
956
+ agentId: string,
957
+ triggerType: ApiValidationTriggerType = 'agent_test'
958
+ ): Promise<{ summary: Record<string, unknown> | null }> {
959
+ return this.get(
960
+ `/api/agents/${encodeURIComponent(agentId)}/validation/summary?trigger_type=${encodeURIComponent(triggerType)}`
961
+ );
962
+ }
963
+
964
+ static async getValidationHistory(
965
+ agentId: string,
966
+ limit = 50,
967
+ triggerType: ApiValidationTriggerType = 'agent_test'
968
+ ): Promise<{ history: Array<Record<string, unknown>> }> {
969
+ return this.get(
970
+ `/api/agents/${encodeURIComponent(agentId)}/validation/history?limit=${limit}&trigger_type=${encodeURIComponent(triggerType)}`
971
+ );
972
+ }
973
+
974
+ static async getValidationSessionDetail(
975
+ sessionId: string
976
+ ): Promise<{ session: Record<string, unknown>; metrics: Array<Record<string, unknown>> }> {
977
+ return this.get(`/api/validation-sessions/${encodeURIComponent(sessionId)}`);
978
+ }
979
+
980
+ static async approveValidationSession(
981
+ agentId: string,
982
+ sessionId: string
983
+ ): Promise<{ success: boolean }> {
984
+ return this.post(
985
+ `/api/agents/${encodeURIComponent(agentId)}/validation/approve?session_id=${encodeURIComponent(sessionId)}`,
986
+ {}
987
+ );
988
+ }
989
+
990
+ static async getValidationCompare(
991
+ agentId: string,
992
+ sessionId: string,
993
+ baseline = 'approved'
994
+ ): Promise<{
995
+ current: { session: Record<string, unknown>; metrics: Array<Record<string, unknown>> };
996
+ baseline: { session: Record<string, unknown>; metrics: Array<Record<string, unknown>> } | null;
997
+ deltas: Array<{
998
+ name: string;
999
+ current: number;
1000
+ baseline: number | null;
1001
+ delta: number | null;
1002
+ direction: string;
1003
+ }>;
1004
+ }> {
1005
+ return this.get(
1006
+ `/api/agents/${encodeURIComponent(agentId)}/validation/compare?session=${encodeURIComponent(sessionId)}&baseline=${encodeURIComponent(baseline)}`
1007
+ );
1008
+ }
1009
+
1010
+ // =============================================
1011
+ // UI Command API (SmartStore pattern)
1012
+ // =============================================
1013
+
1014
+ static async getUICommands(): Promise<{
1015
+ commands: Array<{ id?: string; type: string; payload: Record<string, unknown> }>;
1016
+ }> {
1017
+ return this.get('/api/ui/commands');
1018
+ }
1019
+
1020
+ static async ackUICommands(commandIds: string[]): Promise<JsonRecord> {
1021
+ return this.post('/api/ui/commands/ack', {
1022
+ command_ids: commandIds,
1023
+ });
1024
+ }
1025
+
1026
+ static async pushPageContext(
1027
+ route: string,
1028
+ data: Record<string, unknown>,
1029
+ selectedItem?: { type: string; id: string },
1030
+ channelId?: string
1031
+ ): Promise<JsonRecord> {
1032
+ return this.post('/api/ui/page-context', {
1033
+ currentRoute: route,
1034
+ pageData: data,
1035
+ ...(selectedItem ? { selectedItem } : {}),
1036
+ ...(channelId ? { channelId } : {}),
1037
+ });
1038
+ }
1039
+
886
1040
  // =============================================
887
1041
  // Metrics / Health API
888
1042
  // =============================================
@@ -123,7 +123,12 @@ export function scrollToBottom(container: HTMLElement): void {
123
123
  * @param {HTMLTextAreaElement} textarea - Textarea element
124
124
  * @param {number} maxRows - Maximum number of rows (default: 5)
125
125
  */
126
- export function autoResizeTextarea(textarea: HTMLTextAreaElement, maxRows = 5): void {
126
+ export function autoResizeTextarea(
127
+ textarea: HTMLTextAreaElement | HTMLInputElement | null,
128
+ maxRows = 5
129
+ ): void {
130
+ // Skip for non-textarea elements (e.g. input[type=text] in SmartStore-style panel)
131
+ if (!textarea || textarea.tagName !== 'TEXTAREA') return;
127
132
  // Use requestAnimationFrame to defer resize to the next frame, avoiding layout thrash from rapid input events
128
133
  requestAnimationFrame(() => {
129
134
  textarea.style.height = 'auto'; // Reset height before measuring
@@ -0,0 +1,118 @@
1
+ /**
2
+ * UI Command Polling + Page Context Reporting
3
+ *
4
+ * Ported from SmartStore's NavigationContext + Layout command polling pattern.
5
+ * - startUICommandPolling(): 1s interval, drains commands, executes navigate/notify
6
+ * - reportPageContext(): sends current page state to agent
7
+ */
8
+
9
+ import { API } from './api.js';
10
+ import { showToast } from './dom.js';
11
+
12
+ type SwitchTabFn = (tab: string, params?: Record<string, string>) => void | Promise<void>;
13
+
14
+ let polling = false;
15
+ let pollingInterval: ReturnType<typeof setInterval> | null = null;
16
+ let pollInFlight = false;
17
+ const VIEWER_FRONTDOOR_CHANNEL_ID = 'mama_os_main';
18
+ const PAGE_CONTEXT_REPUBLISH_MS = 5000;
19
+
20
+ type StoredPageContext = {
21
+ route: string;
22
+ data: Record<string, unknown>;
23
+ selectedItem?: { type: string; id: string };
24
+ };
25
+
26
+ let lastReportedPageContext: StoredPageContext | null = null;
27
+ let lastPageContextPublishAt = 0;
28
+
29
+ function getViewerChannelId(): string {
30
+ try {
31
+ const sessionId = window.localStorage.getItem('mama_chat_session_id');
32
+ if (sessionId && !sessionId.startsWith('session_')) {
33
+ return sessionId;
34
+ }
35
+ } catch {
36
+ /* ignore */
37
+ }
38
+ return VIEWER_FRONTDOOR_CHANNEL_ID;
39
+ }
40
+
41
+ export function startUICommandPolling(switchTab: SwitchTabFn): () => void {
42
+ if (polling) {
43
+ return () => {};
44
+ }
45
+ polling = true;
46
+
47
+ pollingInterval = setInterval(async () => {
48
+ if (pollInFlight) {
49
+ return;
50
+ }
51
+ pollInFlight = true;
52
+ try {
53
+ const { commands } = await API.getUICommands();
54
+ const acknowledgedCommandIds: string[] = [];
55
+ for (const cmd of commands) {
56
+ if (cmd.type === 'navigate') {
57
+ const p = cmd.payload as { route?: string; params?: Record<string, string> };
58
+ if (p.route) {
59
+ await switchTab(p.route, p.params);
60
+ if (cmd.id) {
61
+ acknowledgedCommandIds.push(cmd.id);
62
+ }
63
+ }
64
+ } else if (cmd.type === 'notify') {
65
+ const p = cmd.payload as { message?: string };
66
+ if (p.message) {
67
+ showToast(p.message);
68
+ if (cmd.id) {
69
+ acknowledgedCommandIds.push(cmd.id);
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ if (acknowledgedCommandIds.length > 0) {
76
+ await API.ackUICommands(acknowledgedCommandIds);
77
+ }
78
+
79
+ if (
80
+ lastReportedPageContext &&
81
+ Date.now() - lastPageContextPublishAt >= PAGE_CONTEXT_REPUBLISH_MS
82
+ ) {
83
+ lastPageContextPublishAt = Date.now();
84
+ await API.pushPageContext(
85
+ lastReportedPageContext.route,
86
+ lastReportedPageContext.data,
87
+ lastReportedPageContext.selectedItem,
88
+ getViewerChannelId()
89
+ );
90
+ }
91
+ } catch {
92
+ // Silently ignore polling errors (server may be restarting)
93
+ } finally {
94
+ pollInFlight = false;
95
+ }
96
+ }, 1000);
97
+
98
+ return () => {
99
+ if (pollingInterval) {
100
+ clearInterval(pollingInterval);
101
+ pollingInterval = null;
102
+ }
103
+ pollInFlight = false;
104
+ polling = false;
105
+ };
106
+ }
107
+
108
+ export function reportPageContext(
109
+ route: string,
110
+ data: Record<string, unknown>,
111
+ selectedItem?: { type: string; id: string }
112
+ ): void {
113
+ lastReportedPageContext = { route, data, selectedItem };
114
+ lastPageContextPublishAt = Date.now();
115
+ API.pushPageContext(route, data, selectedItem, getViewerChannelId()).catch(() => {
116
+ /* ignore */
117
+ });
118
+ }
@@ -1,7 +1,8 @@
1
1
  /* ============================================================================
2
2
  MAMA Viewer - Brand-Aligned CSS
3
3
  Color Palette: Yellow #FFCE00, Lavender #EDDBF7, Black #131313, Blush #FF9999
4
- Typography: Fredoka (display) + Nunito (body)
4
+ Typography: Inter (UI) + Fredoka (markdown headings) + Nunito (chat)
5
+ CJK Fallback: Noto Sans KR, Noto Sans JP
5
6
  ============================================================================ */
6
7
 
7
8
  /* ============================================================================
@@ -15,7 +16,7 @@ header {
15
16
  }
16
17
 
17
18
  main {
18
- min-height: calc(100vh - 56px);
19
+ min-height: calc(100dvh - 56px);
19
20
  }
20
21
 
21
22
  [data-tab] {
@@ -67,9 +68,13 @@ h4 { font-size: 0.8125rem; font-weight: 500; line-height: 1.4; }
67
68
  border-radius: var(--radius-card, 12px);
68
69
  }
69
70
 
70
- /* Button touch targets — minimum 32px height (44px recommended for mobile) */
71
+ /* Button touch targets — 44px minimum on mobile per WCAG 2.5.8 */
71
72
  button { min-height: 32px; }
72
73
  button:not([class*="p-"]):not([class*="px-"]):not([class*="py-"]) { padding: 6px 12px; }
74
+ @media (max-width: 768px) {
75
+ button { min-height: 44px; }
76
+ [data-tab] { min-height: 44px; }
77
+ }
73
78
 
74
79
  /* Floating Chat */
75
80
  .animate-slide-up {
@@ -111,11 +116,37 @@ button:not([class*="p-"]):not([class*="px-"]):not([class*="py-"]) { padding: 6px
111
116
  will-change: opacity;
112
117
  }
113
118
 
119
+ /* Right panel mode (SmartStore pattern) — override floating panel sizing */
120
+ #chat-panel-wrapper {
121
+ transition: width 0.15s ease;
122
+ height: 100%;
123
+ overflow: hidden;
124
+ min-width: 280px;
125
+ }
126
+ #chat-panel-wrapper #chat-panel {
127
+ width: 100%;
128
+ height: 100%;
129
+ min-width: 0;
130
+ min-height: 0;
131
+ max-width: none;
132
+ max-height: none;
133
+ resize: none;
134
+ overflow: hidden;
135
+ transform: none;
136
+ will-change: auto;
137
+ }
138
+ #chat-resize-handle-bar {
139
+ display: none;
140
+ }
141
+ #chat-resize-handle-bar.chat-resize-visible {
142
+ display: block;
143
+ }
144
+
145
+ /* Legacy bubble styles (kept for backward compat) */
114
146
  #chat-panel.chat-panel-closed {
115
147
  opacity: 0;
116
148
  pointer-events: none;
117
149
  }
118
-
119
150
  #chat-panel.chat-panel-open {
120
151
  opacity: 1;
121
152
  pointer-events: auto;
@@ -162,6 +193,57 @@ button:not([class*="p-"]):not([class*="px-"]):not([class*="py-"]) { padding: 6px
162
193
  background: #D4C4E0;
163
194
  }
164
195
 
196
+ /* Mobile chat panel overrides — fix height:100% and overflow:hidden from desktop */
197
+ @media (max-width: 767px) {
198
+ #chat-panel-wrapper {
199
+ height: auto;
200
+ }
201
+ #chat-panel-wrapper #chat-panel {
202
+ overflow: visible;
203
+ }
204
+ /* Mobile chat header — compact + brand aligned */
205
+ #chat-panel-wrapper.mobile-chat-active #chat-header {
206
+ padding: 12px 16px;
207
+ background: linear-gradient(180deg, #fff 0%, #FAFAF8 100%);
208
+ border-bottom: 1px solid #EDE9E1;
209
+ }
210
+ /* Mobile chat input — larger targets, brand colors */
211
+ #chat-panel-wrapper.mobile-chat-active .p-3 {
212
+ padding: 12px 16px;
213
+ background: #FAFAF8;
214
+ border-top: 1px solid #EDE9E1;
215
+ }
216
+ #chat-panel-wrapper.mobile-chat-active #chat-input {
217
+ background: #fff;
218
+ border: 1.5px solid #D4C4E0;
219
+ border-radius: 20px;
220
+ padding: 10px 16px;
221
+ font-size: 15px;
222
+ min-height: 44px;
223
+ }
224
+ #chat-panel-wrapper.mobile-chat-active #chat-input:focus {
225
+ border-color: #FFCE00;
226
+ box-shadow: 0 0 0 3px rgba(255, 206, 0, 0.15);
227
+ }
228
+ /* Mobile action buttons — 44px touch targets */
229
+ #chat-panel-wrapper.mobile-chat-active #chat-attach,
230
+ #chat-panel-wrapper.mobile-chat-active #chat-mic,
231
+ #chat-panel-wrapper.mobile-chat-active #chat-send {
232
+ width: 44px;
233
+ height: 44px;
234
+ border-radius: 50%;
235
+ }
236
+ #chat-panel-wrapper.mobile-chat-active #chat-send {
237
+ background: #FFCE00;
238
+ box-shadow: 0 2px 8px rgba(255, 206, 0, 0.3);
239
+ }
240
+ /* Mobile message bubbles — slightly larger text */
241
+ #chat-panel-wrapper.mobile-chat-active .chat-message .message-content {
242
+ font-size: 15px;
243
+ line-height: 1.5;
244
+ }
245
+ }
246
+
165
247
  /* Memory viewer mobile layout */
166
248
  @media (max-width: 768px) {
167
249
  #tab-memory .flex-1.flex.min-h-0.relative {
@@ -372,7 +454,7 @@ button:not([class*="p-"]):not([class*="px-"]):not([class*="py-"]) { padding: 6px
372
454
  .chat-message {
373
455
  display: flex;
374
456
  flex-direction: column;
375
- max-width: 80%;
457
+ max-width: 100%;
376
458
  animation: message-appear 0.2s ease-out;
377
459
  }
378
460
 
@@ -393,22 +475,22 @@ button:not([class*="p-"]):not([class*="px-"]):not([class*="py-"]) { padding: 6px
393
475
  box-shadow: 0 4px 12px rgba(255, 206, 0, 0.3);
394
476
  }
395
477
 
396
- /* Assistant messages - left aligned, lavender bubble */
478
+ /* Assistant messages - left aligned, white bubble */
397
479
  .chat-message.assistant {
398
480
  align-self: flex-start;
399
481
  align-items: flex-start;
400
482
  }
401
483
 
402
484
  .chat-message.assistant .message-content {
403
- background: #F5EBF9;
485
+ background: #FFFFFF;
404
486
  color: #131313;
405
487
  padding: 12px 16px;
406
488
  border-radius: 20px 20px 20px 4px;
407
489
  font-size: 15px;
408
490
  line-height: 1.5;
409
491
  word-break: break-word;
410
- box-shadow: 0 2px 8px rgba(19, 19, 19, 0.08);
411
- border: 1px solid #D4C4E0;
492
+ box-shadow: 0 1px 4px rgba(19, 19, 19, 0.06);
493
+ border: 1px solid #EDE9E1;
412
494
  }
413
495
 
414
496
  /* System messages - centered, subtle */
@@ -796,7 +878,7 @@ body,
796
878
  font-weight: 700;
797
879
  border-radius: 9999px;
798
880
  box-shadow: 0 4px 20px rgba(255, 206, 0, 0.4);
799
- transition: all 0.2s ease;
881
+ transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
800
882
  border: none;
801
883
  cursor: pointer;
802
884
  }
@@ -827,6 +909,19 @@ body,
827
909
  box-shadow: 0 8px 32px rgba(19, 19, 19, 0.12);
828
910
  }
829
911
 
912
+ /* Agent card hover (replaces inline JS handlers) */
913
+ .agent-card:hover {
914
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
915
+ transform: translateY(-1px);
916
+ }
917
+
918
+ /* Agent form inputs — focus matches chat input style */
919
+ .agent-input:focus {
920
+ outline: none;
921
+ border-color: #FFCE00;
922
+ box-shadow: 0 0 0 3px rgba(255, 206, 0, 0.2);
923
+ }
924
+
830
925
  /* ============================================================================
831
926
  INPUT STYLES - Brand aligned
832
927
  ============================================================================ */