@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
@@ -484,11 +484,18 @@ export class ChatModule {
484
484
  this.addUserMessage(message);
485
485
  this.enableSend(false);
486
486
 
487
+ // Include current viewer tab context (SmartStore ChatPanel pattern)
488
+ const tabIndicator = document.getElementById('chat-tab-indicator');
489
+ const viewerContext = {
490
+ currentTab: tabIndicator?.textContent?.toLowerCase() || 'unknown',
491
+ };
492
+
487
493
  this.ws.send(
488
494
  JSON.stringify({
489
495
  type: 'send',
490
496
  sessionId: this.sessionId,
491
497
  content: message,
498
+ viewerContext,
492
499
  })
493
500
  );
494
501
 
@@ -1081,34 +1088,27 @@ export class ChatModule {
1081
1088
  * Update chat status
1082
1089
  */
1083
1090
  updateStatus(status: string): void {
1084
- const statusEl = getElementByIdOrNull<HTMLDivElement>('chat-status');
1091
+ const statusEl = getElementByIdOrNull<HTMLElement>('chat-status');
1085
1092
  if (!statusEl) {
1086
1093
  logger.warn('Status element not found');
1087
1094
  return;
1088
1095
  }
1089
1096
 
1090
- const indicator = statusEl.querySelector('.status-indicator');
1091
- const text = statusEl.querySelector('span:not(.status-indicator)');
1092
-
1093
- if (!indicator || !text) {
1094
- logger.warn('Status indicator or text not found');
1095
- return;
1096
- }
1097
-
1098
- indicator.className = 'status-indicator ' + status;
1097
+ // #chat-status IS the indicator element (not a wrapper with children)
1098
+ statusEl.className = 'status-indicator w-1.5 h-1.5 rounded-full flex-shrink-0 ' + status;
1099
1099
 
1100
1100
  switch (status) {
1101
1101
  case 'connected':
1102
- text.textContent = 'Connected';
1102
+ statusEl.title = 'Connected';
1103
1103
  break;
1104
1104
  case 'disconnected':
1105
- text.textContent = 'Disconnected';
1105
+ statusEl.title = 'Disconnected';
1106
1106
  break;
1107
1107
  case 'connecting':
1108
- text.textContent = 'Connecting...';
1108
+ statusEl.title = 'Connecting...';
1109
1109
  break;
1110
1110
  default:
1111
- text.textContent = status;
1111
+ statusEl.title = status;
1112
1112
  }
1113
1113
  }
1114
1114
 
@@ -2042,6 +2042,12 @@ export class ChatModule {
2042
2042
  const panel = getElementByIdOrNull<HTMLDivElement>('chat-panel');
2043
2043
  const header = getElementByIdOrNull<HTMLDivElement>('chat-header');
2044
2044
 
2045
+ // Right panel mode: no bubble, auto-init session
2046
+ const isRightPanel = !bubble && !!document.getElementById('chat-panel-wrapper');
2047
+ if (isRightPanel && !this.ws) {
2048
+ this.initSession();
2049
+ }
2050
+
2045
2051
  if (bubble) {
2046
2052
  bubble.addEventListener('click', () => this.togglePanel());
2047
2053
  }
@@ -2049,6 +2055,9 @@ export class ChatModule {
2049
2055
  closeBtn.addEventListener('click', () => this.togglePanel(false));
2050
2056
  }
2051
2057
 
2058
+ // Right panel mode: skip drag/resize handlers (handled by viewer.html inline JS)
2059
+ if (isRightPanel) return;
2060
+
2052
2061
  if (panel && header) {
2053
2062
  let dragging = false;
2054
2063
  let startX = 0;
@@ -1,6 +1,7 @@
1
1
  import { API, type ConnectorActivitySummary, type ConnectorFeedChannel } from '../utils/api.js';
2
2
  import { DebugLogger } from '../utils/debug-logger.js';
3
3
  import { createCollapsible, createResizeHandle } from '../utils/dom.js';
4
+ import { reportPageContext } from '../utils/ui-commands.js';
4
5
 
5
6
  const logger = new DebugLogger('ConnectorFeed');
6
7
 
@@ -101,6 +102,17 @@ export class ConnectorFeedModule {
101
102
 
102
103
  private renderConnectorList(connectors: ConnectorActivitySummary[]): void {
103
104
  if (!this.container) return;
105
+ reportPageContext('feed', {
106
+ pageType: 'connector-list',
107
+ selectedConnector: this.selectedConnector,
108
+ connectorCount: connectors.length,
109
+ connectors: connectors.slice(0, 10).map((c) => ({
110
+ connector: c.connector,
111
+ status: c.status,
112
+ channel: c.channel,
113
+ timestamp: c.timestamp,
114
+ })),
115
+ });
104
116
 
105
117
  if (connectors.length === 0) {
106
118
  this.container.innerHTML =
@@ -235,10 +247,24 @@ export class ConnectorFeedModule {
235
247
 
236
248
  private showMobileList(): void {
237
249
  this.mobileShowingDetail = false;
250
+ this.selectedConnector = null;
238
251
  const list = document.getElementById('connector-list');
239
252
  const detail = document.getElementById('connector-detail');
240
253
  if (list) list.style.display = '';
241
254
  if (detail) detail.style.display = 'none';
255
+ reportPageContext('feed', {
256
+ pageType: 'connector-list',
257
+ selectedConnector: null,
258
+ connectorCount: this.cachedConnectors.length,
259
+ channelCount: 0,
260
+ channels: [],
261
+ connectors: this.cachedConnectors.slice(0, 10).map((c) => ({
262
+ connector: c.connector,
263
+ status: c.status,
264
+ channel: c.channel,
265
+ timestamp: c.timestamp,
266
+ })),
267
+ });
242
268
  }
243
269
 
244
270
  private handleResize(): void {
@@ -280,6 +306,15 @@ export class ConnectorFeedModule {
280
306
  name: string,
281
307
  feed: ConnectorFeedChannel[]
282
308
  ): void {
309
+ reportPageContext('feed', {
310
+ pageType: 'connector-detail',
311
+ selectedConnector: name,
312
+ channelCount: feed.length,
313
+ channels: feed.slice(0, 10).map((channel) => ({
314
+ channel: channel.channel,
315
+ itemCount: channel.items.length,
316
+ })),
317
+ });
283
318
  const icon = CONNECTOR_ICON[name] || '\u{1F517}';
284
319
 
285
320
  // Clear and build header
@@ -12,6 +12,7 @@ import {
12
12
  } from '../utils/api.js';
13
13
  import { DebugLogger } from '../utils/debug-logger.js';
14
14
  import { createCollapsible } from '../utils/dom.js';
15
+ import { reportPageContext } from '../utils/ui-commands.js';
15
16
 
16
17
  declare const DOMPurify: { sanitize(html: string): string };
17
18
 
@@ -85,6 +86,18 @@ export class DashboardModule {
85
86
  private container: HTMLElement | null = null;
86
87
  private eventSource: EventSource | null = null;
87
88
  private refreshTimer: ReturnType<typeof setInterval> | null = null;
89
+ private selectedProject: string | null = null;
90
+ private selectedConnector: string | null = null;
91
+
92
+ private getCurrentPageType(): 'dashboard-overview' | 'dashboard-project' | 'dashboard-connector' {
93
+ if (this.selectedConnector) {
94
+ return 'dashboard-connector';
95
+ }
96
+ if (this.selectedProject) {
97
+ return 'dashboard-project';
98
+ }
99
+ return 'dashboard-overview';
100
+ }
88
101
 
89
102
  init(): void {
90
103
  this.container = document.getElementById('dashboard-slots');
@@ -164,6 +177,17 @@ export class DashboardModule {
164
177
  briefingSlot: ReportSlot | null;
165
178
  }): void {
166
179
  if (!this.container) return;
180
+ reportPageContext('dashboard', {
181
+ pageType: this.getCurrentPageType(),
182
+ selectedProject: this.selectedProject,
183
+ selectedConnector: this.selectedConnector,
184
+ noticeCount: data.notices.length,
185
+ pipelineCount: data.pipeline.length,
186
+ connectorCount: data.connectors.length,
187
+ totalDecisions: data.totalDecisions,
188
+ agentCount: data.agentCount,
189
+ summary: data.summary.text?.slice(0, 300) ?? '',
190
+ });
167
191
 
168
192
  const emptyEl = document.getElementById('slots-empty');
169
193
  const hasData =
@@ -276,6 +300,12 @@ export class DashboardModule {
276
300
  if (isOpen) {
277
301
  detail.style.display = 'none';
278
302
  arrow.textContent = '\u25B6';
303
+ this.selectedProject = null;
304
+ reportPageContext('dashboard', {
305
+ pageType: this.getCurrentPageType(),
306
+ selectedProject: null,
307
+ selectedConnector: this.selectedConnector,
308
+ });
279
309
  } else {
280
310
  detail.style.display = '';
281
311
  arrow.textContent = '\u25BC';
@@ -283,6 +313,13 @@ export class DashboardModule {
283
313
  if (projectName && detail.textContent === 'Loading...') {
284
314
  this.loadPipelineDetail(detail, projectName);
285
315
  }
316
+ this.selectedProject = projectName ?? null;
317
+ this.selectedConnector = null;
318
+ reportPageContext('dashboard', {
319
+ pageType: 'dashboard-project',
320
+ selectedProject: this.selectedProject,
321
+ selectedConnector: this.selectedConnector,
322
+ });
286
323
  }
287
324
  });
288
325
  });
@@ -348,6 +385,12 @@ export class DashboardModule {
348
385
  if (isOpen) {
349
386
  detail.style.display = 'none';
350
387
  arrow.textContent = '\u25B6';
388
+ this.selectedConnector = null;
389
+ reportPageContext('dashboard', {
390
+ pageType: this.getCurrentPageType(),
391
+ selectedProject: this.selectedProject,
392
+ selectedConnector: null,
393
+ });
351
394
  } else {
352
395
  detail.style.display = '';
353
396
  arrow.textContent = '\u25BC';
@@ -355,6 +398,13 @@ export class DashboardModule {
355
398
  if (connName && detail.textContent === 'Loading...') {
356
399
  this.loadConnectorDetail(detail, connName);
357
400
  }
401
+ this.selectedConnector = connName ?? null;
402
+ this.selectedProject = null;
403
+ reportPageContext('dashboard', {
404
+ pageType: 'dashboard-connector',
405
+ selectedProject: this.selectedProject,
406
+ selectedConnector: this.selectedConnector,
407
+ });
358
408
  }
359
409
  });
360
410
  });
@@ -16,6 +16,7 @@ import { escapeHtml, debounce, showToast, getElementByIdOrNull } from '../utils/
16
16
  import { formatRelativeTime, truncateText } from '../utils/format.js';
17
17
  import { API, type MemorySearchItem } from '../utils/api.js';
18
18
  import { DebugLogger } from '../utils/debug-logger.js';
19
+ import { reportPageContext } from '../utils/ui-commands.js';
19
20
 
20
21
  const logger = new DebugLogger('Memory');
21
22
 
@@ -121,6 +122,17 @@ export class MemoryModule {
121
122
  this.searchData = data.results || [];
122
123
  this.renderResults(this.searchData, query);
123
124
  this.setStatus(`Found ${this.searchData.length} decision(s)`, '');
125
+ reportPageContext('memory', {
126
+ pageType: 'memory-search',
127
+ query,
128
+ resultCount: this.searchData.length,
129
+ results: this.searchData.slice(0, 10).map((item) => ({
130
+ id: item.id ?? null,
131
+ topic: item.topic ?? null,
132
+ outcome: item.outcome ?? null,
133
+ similarity: item.similarity ?? null,
134
+ })),
135
+ });
124
136
  } catch (error) {
125
137
  const message = error instanceof Error ? error.message : String(error);
126
138
  logger.error('Search error:', message);
@@ -154,6 +166,17 @@ export class MemoryModule {
154
166
  */
155
167
  async showRelatedForMessage(message: string): Promise<void> {
156
168
  const results = await this.searchRelated(message);
169
+ reportPageContext('memory', {
170
+ pageType: 'memory-related',
171
+ query: message,
172
+ resultCount: results.length,
173
+ results: results.slice(0, 10).map((item) => ({
174
+ id: item.id ?? null,
175
+ topic: item.topic ?? null,
176
+ outcome: item.outcome ?? null,
177
+ similarity: item.similarity ?? null,
178
+ })),
179
+ });
157
180
 
158
181
  if (results.length > 0) {
159
182
  this.searchData = results;
@@ -170,6 +193,8 @@ export class MemoryModule {
170
193
 
171
194
  // Show notification
172
195
  showToast(`🧠 ${results.length} related MAMA decision(s) found`);
196
+ } else {
197
+ this.setStatus('No related decisions found', '');
173
198
  }
174
199
  }
175
200
 
@@ -253,6 +278,12 @@ export class MemoryModule {
253
278
  </div>
254
279
  `;
255
280
  this.setStatus('', '');
281
+ reportPageContext('memory', {
282
+ pageType: 'memory-search',
283
+ query: '',
284
+ resultCount: 0,
285
+ results: [],
286
+ });
256
287
  // Reinitialize Lucide icons for dynamic content
257
288
  if (typeof lucide !== 'undefined' && typeof window.lucideConfig !== 'undefined') {
258
289
  lucide.createIcons(window.lucideConfig);
@@ -15,6 +15,7 @@
15
15
  import { showToast, escapeHtml, escapeAttr, getElementByIdOrNull } from '../utils/dom.js';
16
16
  import { formatModelName } from '../utils/format.js';
17
17
  import { DebugLogger } from '../utils/debug-logger.js';
18
+ import { reportPageContext } from '../utils/ui-commands.js';
18
19
  import {
19
20
  API,
20
21
  type ApiConfigResponse,
@@ -24,7 +25,6 @@ import {
24
25
  type EffortLevel,
25
26
  type McpServer,
26
27
  type McpServersResponse,
27
- type MultiAgentAgent,
28
28
  type MultiAgentAgentsResponse,
29
29
  type SkillsResponse,
30
30
  } from '../utils/api.js';
@@ -352,6 +352,14 @@ export class SettingsModule {
352
352
  }
353
353
  return;
354
354
  }
355
+
356
+ const goAgentsButton = target.closest<HTMLElement>('[data-action="go-agents-tab"]');
357
+ if (goAgentsButton) {
358
+ e.preventDefault();
359
+ if (typeof window.switchTab === 'function') {
360
+ window.switchTab('agents');
361
+ }
362
+ }
355
363
  });
356
364
  }
357
365
 
@@ -459,6 +467,24 @@ export class SettingsModule {
459
467
  this.populateSkillsSection();
460
468
  this.populateTokenSection();
461
469
  this.populateCronSection();
470
+
471
+ reportPageContext('settings', {
472
+ pageType: 'settings-overview',
473
+ gateways: {
474
+ discord: this.config.discord?.enabled ?? false,
475
+ slack: this.config.slack?.enabled ?? false,
476
+ telegram: this.config.telegram?.enabled ?? false,
477
+ chatwork: this.config.chatwork?.enabled ?? false,
478
+ },
479
+ agent: {
480
+ backend: this.config.agent?.backend ?? 'claude',
481
+ model: this.config.agent?.model ?? null,
482
+ max_turns: this.config.agent?.max_turns ?? null,
483
+ timeout: this.config.agent?.timeout ?? null,
484
+ },
485
+ multiAgentCount: this.multiAgentData.agents.length,
486
+ mcpServerCount: this.mcpServersData.servers.length,
487
+ });
462
488
  }
463
489
 
464
490
  /**
@@ -1140,6 +1166,7 @@ export class SettingsModule {
1140
1166
 
1141
1167
  /**
1142
1168
  * Populate Multi-Agent Team section (F3)
1169
+ * Agent editing has moved to the Agents tab — show redirect notice.
1143
1170
  */
1144
1171
  populateMultiAgentSection(): void {
1145
1172
  const container = getElementByIdOrNull<HTMLElement>('settings-multi-agent-container');
@@ -1147,101 +1174,14 @@ export class SettingsModule {
1147
1174
  return;
1148
1175
  }
1149
1176
 
1150
- const agents = this.multiAgentData?.agents || [];
1151
-
1152
- if (agents.length === 0) {
1153
- container.innerHTML = `
1154
- <div class="bg-white border border-gray-200 rounded-lg p-3 text-xs text-gray-500">
1155
- No agents configured. Add agents in <code class="bg-gray-100 px-1 rounded">config.yaml</code>
1156
- </div>
1157
- `;
1158
- return;
1159
- }
1160
-
1161
- // Tier badge colors
1162
- const tierColors: Record<number, string> = {
1163
- 1: 'bg-indigo-100 text-indigo-700',
1164
- 2: 'bg-green-100 text-green-700',
1165
- 3: 'bg-yellow-100 text-yellow-700',
1166
- };
1167
-
1168
- const agentCards = agents
1169
- .map((agent: MultiAgentAgent) => {
1170
- const tierValue = Number(agent.tier) || 1;
1171
- const tierColor = tierColors[tierValue] || tierColors[1];
1172
- const backend = (agent.backend || this.config?.agent?.backend || 'claude') as AgentBackend;
1173
- const normalizedModel = this.getNormalizedModelForBackend(backend, agent.model || '');
1174
- const agentId = agent.id || '';
1175
- const backendOptions = ['codex-mcp', 'claude']
1176
- .map(
1177
- (b) =>
1178
- `<option value="${escapeAttr(b)}" ${backend === b ? 'selected' : ''}>${escapeHtml(b)}</option>`
1179
- )
1180
- .join('');
1181
- const modelOptions = MODEL_OPTIONS[backend] || MODEL_OPTIONS.claude;
1182
- const modelOptionHtml = modelOptions
1183
- .map(
1184
- (m) =>
1185
- `<option value="${escapeAttr(m)}" ${m === normalizedModel ? 'selected' : ''}>${escapeHtml(formatModelName(m))}</option>`
1186
- )
1187
- .join('');
1188
-
1189
- // Effort level (Claude 4.6 models only, max on Opus).
1190
- const supportsAgentEffort = this.supportsEffortModel(normalizedModel);
1191
- const selectedAgentEffort = this.normalizeEffortForModel(
1192
- normalizedModel,
1193
- (agent.effort || 'medium') as EffortLevel
1194
- );
1195
- const effortOptions = this.buildEffortOptions(normalizedModel, selectedAgentEffort);
1196
-
1197
- // Permission flags — only check explicit tool_permissions, not tier
1198
- const canDelegate = agent.can_delegate ?? false;
1199
- const hasAllTools = agent.tool_permissions?.allowed?.includes('*') ?? false;
1200
-
1201
- return `
1202
- <div class="bg-white border border-gray-200 rounded-lg p-3 hover:shadow-md transition-shadow">
1203
- <!-- Header: Tier + Name + Toggle -->
1204
- <div class="flex items-center justify-between mb-2">
1205
- <div class="flex items-center gap-1.5">
1206
- <span class="${tierColor} text-[10px] font-bold px-1.5 py-0.5 rounded">T${escapeHtml(String(tierValue))}</span>
1207
- <span class="font-medium text-gray-900 text-xs" title="${escapeAttr(agent.display_name || agent.name)}">${escapeHtml(agent.display_name || agent.name)}</span>
1208
- </div>
1209
- <label class="relative inline-flex items-center cursor-pointer">
1210
- <input type="checkbox" class="sr-only peer" data-action="agent-toggle" data-agent-id="${escapeAttr(agentId)}" ${agent.enabled ? 'checked' : ''}>
1211
- <div class="w-7 h-4 bg-gray-200 rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-3 after:w-3 after:transition-all peer-checked:bg-green-500"></div>
1212
- </label>
1213
- </div>
1214
-
1215
- <!-- Backend -->
1216
- <select id="agent-backend-${escapeAttr(agentId)}" data-action="agent-backend" data-agent-id="${escapeAttr(agentId)}" class="w-full text-[11px] rounded border border-gray-200 px-1.5 py-1 bg-gray-50 mb-1">${backendOptions}</select>
1217
- <!-- Model -->
1218
- <select id="agent-model-${escapeAttr(agentId)}" data-action="agent-model" data-agent-id="${escapeAttr(agentId)}" class="w-full text-[11px] rounded border border-gray-200 px-1.5 py-1 bg-gray-50 mb-1">${modelOptionHtml}</select>
1219
- <!-- Effort (Claude 4.6 only) -->
1220
- <div id="agent-effort-container-${escapeAttr(agentId)}" class="mb-1" style="display: ${supportsAgentEffort ? 'block' : 'none'}">
1221
- <select id="agent-effort-${escapeAttr(agentId)}" class="w-full text-[11px] rounded border border-gray-200 px-1.5 py-1 bg-gray-50">${effortOptions}</select>
1222
- </div>
1223
-
1224
- <!-- Permissions + Save -->
1225
- <div class="flex items-center justify-between mt-2">
1226
- <div class="flex items-center gap-2 text-[10px] text-gray-600">
1227
- <label class="flex items-center gap-0.5 cursor-pointer">
1228
- <input type="checkbox" id="agent-delegate-${escapeAttr(agentId)}" class="w-3 h-3 rounded border-gray-300 text-yellow-500 focus:ring-yellow-400" ${canDelegate ? 'checked' : ''}>
1229
- <span>Delegate</span>
1230
- </label>
1231
- <label class="flex items-center gap-0.5 cursor-pointer">
1232
- <input type="checkbox" id="agent-alltools-${escapeAttr(agentId)}" class="w-3 h-3 rounded border-gray-300 text-yellow-500 focus:ring-yellow-400" ${hasAllTools ? 'checked' : ''}>
1233
- <span>All Tools</span>
1234
- </label>
1235
- </div>
1236
- <button type="button" data-action="agent-save" data-agent-id="${escapeAttr(agentId)}" class="text-[10px] px-3 py-1 rounded bg-mama-yellow text-mama-black hover:bg-mama-yellow-hover font-medium">Save</button>
1237
- </div>
1238
- </div>
1239
- `;
1240
- })
1241
- .join('');
1242
-
1243
- // Grid layout: 2 cols on mobile, 3 cols on md+
1244
- container.innerHTML = `<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">${agentCards}</div>`;
1177
+ container.innerHTML = `
1178
+ <div class="bg-white border border-gray-200 rounded-lg p-4 text-center">
1179
+ <p class="text-sm text-gray-600 mb-2">Agent management has moved to the Agents tab.</p>
1180
+ <button data-action="go-agents-tab"
1181
+ class="text-sm px-4 py-1.5 rounded-md bg-mama-yellow text-mama-black hover:bg-mama-yellow-hover font-medium">
1182
+ Go to Agents
1183
+ </button>
1184
+ </div>`;
1245
1185
  }
1246
1186
 
1247
1187
  /**
@@ -1,6 +1,7 @@
1
1
  import { API, type WikiTreeNode, type WikiPageResponse } from '../utils/api.js';
2
2
  import { DebugLogger } from '../utils/debug-logger.js';
3
3
  import { createResizeHandle } from '../utils/dom.js';
4
+ import { reportPageContext } from '../utils/ui-commands.js';
4
5
 
5
6
  declare const marked: { parse(md: string): string };
6
7
  declare const DOMPurify: { sanitize(html: string): string };
@@ -70,7 +71,12 @@ function renderTreeNode(node: WikiTreeNode, depth: number = 0): string {
70
71
  }
71
72
 
72
73
  function escapeHtml(s: string): string {
73
- return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
74
+ return s
75
+ .replace(/&/g, '&amp;')
76
+ .replace(/</g, '&lt;')
77
+ .replace(/>/g, '&gt;')
78
+ .replace(/"/g, '&quot;')
79
+ .replace(/'/g, '&#39;');
74
80
  }
75
81
 
76
82
  export class WikiModule {
@@ -79,15 +85,46 @@ export class WikiModule {
79
85
  private resizeHandler: (() => void) | null = null;
80
86
  private mobileShowingPage = false;
81
87
  private initialized = false;
88
+ private treeLoadPromise: Promise<void> | null = null;
82
89
 
83
90
  init(): void {
84
- if (this.initialized) { return; }
91
+ if (this.initialized) {
92
+ return;
93
+ }
85
94
  this.container = document.getElementById('wiki-content');
86
- if (!this.container) { return; }
95
+ if (!this.container) {
96
+ return;
97
+ }
87
98
  this.initialized = true;
88
99
  this.resizeHandler = () => this.handleResize();
89
100
  window.addEventListener('resize', this.resizeHandler);
90
- this.loadTree();
101
+ this.treeLoadPromise = this.loadTree();
102
+ }
103
+
104
+ private publishListContext(): void {
105
+ reportPageContext('wiki', {
106
+ pageType: 'wiki-list',
107
+ path: null,
108
+ activePath: this.currentPath,
109
+ });
110
+ }
111
+
112
+ private publishPageContext(page: WikiPageResponse): void {
113
+ const title =
114
+ String(page.frontmatter.title ?? '').trim() ||
115
+ page.path.split('/').pop()?.replace(/\.md$/, '') ||
116
+ page.path;
117
+ reportPageContext(
118
+ 'wiki',
119
+ {
120
+ pageType: 'wiki-page',
121
+ path: page.path,
122
+ title,
123
+ frontmatter: page.frontmatter,
124
+ content_preview: page.raw.slice(0, 400),
125
+ },
126
+ { type: 'wiki-page', id: page.path }
127
+ );
91
128
  }
92
129
 
93
130
  private async loadTree(): Promise<void> {
@@ -171,9 +208,13 @@ export class WikiModule {
171
208
  document.getElementById('wiki-new-btn')?.addEventListener('click', () => this.promptNewPage());
172
209
 
173
210
  // Auto-open index page only on initial load (no page selected yet)
174
- if (!mobile && !this.currentPath) {
211
+ if (!this.currentPath) {
175
212
  const indexNode = tree.find((n) => n.name === 'index.md');
176
- if (indexNode) { this.openPage(indexNode.path); }
213
+ if (!mobile && indexNode) {
214
+ this.openPage(indexNode.path);
215
+ } else {
216
+ this.publishListContext();
217
+ }
177
218
  }
178
219
  }
179
220
 
@@ -194,6 +235,7 @@ export class WikiModule {
194
235
  try {
195
236
  const page = await API.getWikiPage(path);
196
237
  this.renderPageView(pageEl, page);
238
+ this.publishPageContext(page);
197
239
  } catch {
198
240
  pageEl.innerHTML = `<div style="color:#D94F4F;padding:20px">Failed to load ${path}</div>`;
199
241
  }
@@ -213,10 +255,12 @@ export class WikiModule {
213
255
 
214
256
  private showMobileTree(): void {
215
257
  this.mobileShowingPage = false;
258
+ this.currentPath = null;
216
259
  const treeEl = document.getElementById('wiki-tree');
217
260
  const pageEl = document.getElementById('wiki-page');
218
261
  if (treeEl) treeEl.style.display = '';
219
262
  if (pageEl) pageEl.style.display = 'none';
263
+ this.publishListContext();
220
264
  }
221
265
 
222
266
  private handleResize(): void {
@@ -399,4 +443,27 @@ export class WikiModule {
399
443
  this.resizeHandler = null;
400
444
  }
401
445
  }
446
+
447
+ async navigateTo(path?: string): Promise<void> {
448
+ if (!this.initialized) {
449
+ this.init();
450
+ }
451
+ if (this.treeLoadPromise) {
452
+ await this.treeLoadPromise;
453
+ }
454
+ if (path) {
455
+ await this.openPage(path);
456
+ return;
457
+ }
458
+ if (this.currentPath) {
459
+ try {
460
+ const page = await API.getWikiPage(this.currentPath);
461
+ this.publishPageContext(page);
462
+ return;
463
+ } catch {
464
+ /* fall through to list context */
465
+ }
466
+ }
467
+ this.publishListContext();
468
+ }
402
469
  }
@@ -155,15 +155,6 @@ declare global {
155
155
  toggleCronJob?: (id: string, enabled: boolean) => Promise<void>;
156
156
  deleteCronJob?: (id: string) => Promise<void>;
157
157
  };
158
- skillsModule?: {
159
- closeDetail?: () => void;
160
- install?: (source: string, name: string) => Promise<void>;
161
- uninstall?: (source: string, name: string) => Promise<void>;
162
- toggle?: (source: string, name: string, enabled: boolean) => Promise<void>;
163
- init?: () => Promise<void>;
164
- loadSkills?: () => Promise<void>;
165
- render?: () => void;
166
- };
167
158
  SpeechRecognition?: SpeechRecognitionConstructor;
168
159
  webkitSpeechRecognition?: SpeechRecognitionConstructor;
169
160
  lucideConfig?: unknown;