@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
|
@@ -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(
|
|
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
|
+
}
|
package/public/viewer/viewer.css
CHANGED
|
@@ -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 (
|
|
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(
|
|
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
|
|
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:
|
|
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,
|
|
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: #
|
|
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
|
|
411
|
-
border: 1px solid #
|
|
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:
|
|
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
|
============================================================================ */
|