aimeat 1.16.2 → 1.18.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/.env.example +6 -1
- package/dist/locales/en.json +166 -4
- package/dist/locales/fi.json +166 -4
- package/dist/public/components/Card.js +17 -3
- package/dist/public/components/Collapsible.js +39 -0
- package/dist/public/components/CopyButton.js +55 -24
- package/dist/public/components/DataTable.js +57 -0
- package/dist/public/components/EmptyState.js +28 -0
- package/dist/public/components/KeyValueRow.js +37 -0
- package/dist/public/components/Modal.js +22 -5
- package/dist/public/components/Pagination.js +70 -0
- package/dist/public/components/SearchBar.js +44 -0
- package/dist/public/components/StatusDot.js +29 -0
- package/dist/public/components/TagList.js +53 -0
- package/dist/public/components/ToggleSwitch.js +28 -0
- package/dist/public/components/index.js +41 -1
- package/dist/public/css/components/tags.css +24 -0
- package/dist/public/css/style-testbed.css +135 -0
- package/dist/public/css/theme.css +556 -34
- package/dist/public/css/views/admin-agent-integration.css +2 -33
- package/dist/public/css/views/admin.css +730 -686
- package/dist/public/css/views/agents-detail.css +402 -14
- package/dist/public/css/views/help.css +2 -1
- package/dist/public/css/views/hobbies.css +53 -33
- package/dist/public/css/views/marketplace.css +73 -60
- package/dist/public/css/views/openclaw.css +12 -6
- package/dist/public/css/views/portal-classic.css +34 -26
- package/dist/public/css/views/portal-dev.css +41 -32
- package/dist/public/css/views/portal.css +14 -18
- package/dist/public/css/views/profile.css +252 -164
- package/dist/public/css/views/public-knowledge-viewer.css +18 -6
- package/dist/public/css/views/scheduler.css +100 -0
- package/dist/public/js/format.js +41 -0
- package/dist/public/js/services/agent-tasks.js +14 -1
- package/dist/public/js/services/generator-spec-validate.js +5 -1
- package/dist/public/js/services/schedules.js +53 -0
- package/dist/public/js/style-testbed.js +170 -0
- package/dist/public/js/theme.js +114 -0
- package/dist/public/spa.html +74 -16
- package/dist/public/style-testbed.html +420 -0
- package/dist/public/views/admin/agent-integration-tab.js +23 -38
- package/dist/public/views/admin/agent-tasks-tab.js +14 -21
- package/dist/public/views/admin/chat-instances-tab.js +1 -1
- package/dist/public/views/admin/config-tab.js +7 -2
- package/dist/public/views/admin/cortex-tab.js +20 -14
- package/dist/public/views/admin/csm-tab.js +22 -18
- package/dist/public/views/admin/directory-tab.js +3 -3
- package/dist/public/views/admin/email-tab.js +23 -28
- package/dist/public/views/admin/federation-tab.js +15 -5
- package/dist/public/views/admin/generator-debug-tab.js +10 -8
- package/dist/public/views/admin/genesis-tab.js +4 -4
- package/dist/public/views/admin/ghii-tab.js +3 -3
- package/dist/public/views/admin/knowledge-tab.js +15 -5
- package/dist/public/views/admin/matching-tab.js +3 -3
- package/dist/public/views/admin/memory-tab.js +16 -20
- package/dist/public/views/admin/msm-tab.js +30 -17
- package/dist/public/views/admin/overview-tab.js +7 -7
- package/dist/public/views/admin/packages-tab.js +10 -9
- package/dist/public/views/admin/portal-tab.js +14 -4
- package/dist/public/views/admin/prompts-tab.js +5 -5
- package/dist/public/views/admin/push-tab.js +15 -4
- package/dist/public/views/admin/realtime-tab.js +3 -3
- package/dist/public/views/admin/services-tab.js +18 -27
- package/dist/public/views/admin/shared.js +48 -58
- package/dist/public/views/admin/sharing-groups-tab.js +5 -10
- package/dist/public/views/admin/stats-tab.js +3 -3
- package/dist/public/views/guides.js +9 -13
- package/dist/public/views/help.js +3 -24
- package/dist/public/views/hobbies.js +47 -41
- package/dist/public/views/marketplace.js +42 -34
- package/dist/public/views/openclaw.js +0 -1
- package/dist/public/views/portal-classic.js +4 -15
- package/dist/public/views/portal-dev.js +28 -30
- package/dist/public/views/portal.js +16 -21
- package/dist/public/views/portfolio.js +11 -12
- package/dist/public/views/profile/access-tab.js +250 -1
- package/dist/public/views/profile/agents/agent-card.js +75 -4
- package/dist/public/views/profile/agents/tab-activity.js +15 -13
- package/dist/public/views/profile/agents/tab-agent-config.js +60 -6
- package/dist/public/views/profile/agents/tab-integration.js +37 -60
- package/dist/public/views/profile/agents/tab-messages.js +10 -1
- package/dist/public/views/profile/agents/tab-quality.js +25 -19
- package/dist/public/views/profile/agents/tab-schedules.js +110 -0
- package/dist/public/views/profile/agents-activity-subtab.js +4 -4
- package/dist/public/views/profile/agents-services-subtab.js +5 -4
- package/dist/public/views/profile/agents-tab.js +141 -37
- package/dist/public/views/profile/agents-tasks-subtab.js +221 -26
- package/dist/public/views/profile/calibrator-batch.js +5 -11
- package/dist/public/views/profile/calibrator-tab.js +4 -9
- package/dist/public/views/profile/chat-sessions-tab.js +9 -5
- package/dist/public/views/profile/email-tab.js +2 -2
- package/dist/public/views/profile/extensions-tab.js +27 -22
- package/dist/public/views/profile/federation-tab.js +4 -1
- package/dist/public/views/profile/foundry-detail.js +22 -23
- package/dist/public/views/profile/foundry-tab.js +12 -13
- package/dist/public/views/profile/generator-dashboard/DebugPanel.js +4 -7
- package/dist/public/views/profile/generator-dashboard/use-dashboard-core.js +4 -1
- package/dist/public/views/profile/generator-dashboard/use-edit-mode.js +3 -2
- package/dist/public/views/profile/generator-detail.js +26 -30
- package/dist/public/views/profile/generator-tab.js +5 -5
- package/dist/public/views/profile/knowledge-tab.js +12 -12
- package/dist/public/views/profile/landing-page.js +100 -149
- package/dist/public/views/profile/memory-tab.js +15 -11
- package/dist/public/views/profile/node-stats-tab.js +3 -3
- package/dist/public/views/profile/nodes-tab.js +10 -3
- package/dist/public/views/profile/notifications-tab.js +3 -3
- package/dist/public/views/profile/packages-tab.js +14 -14
- package/dist/public/views/profile/scheduler-tab.js +340 -0
- package/dist/public/views/profile/services-tab.js +1 -1
- package/dist/public/views/profile/shared.js +16 -12
- package/dist/public/views/profile/wallet-tab.js +27 -50
- package/dist/public/views/profile/work-tab.js +29 -31
- package/dist/public/views/profile.js +24 -0
- package/dist/public/views/public-knowledge-viewer.js +9 -18
- package/dist/src/auth/middleware.d.ts +3 -2
- package/dist/src/auth/middleware.d.ts.map +1 -1
- package/dist/src/auth/middleware.js +78 -3
- package/dist/src/auth/middleware.js.map +1 -1
- package/dist/src/cli/init-wizard.d.ts.map +1 -1
- package/dist/src/cli/init-wizard.js +13 -1
- package/dist/src/cli/init-wizard.js.map +1 -1
- package/dist/src/config.d.ts +6 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +12 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +708 -8
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/mcp/agent-schedules.d.ts +23 -0
- package/dist/src/mcp/agent-schedules.d.ts.map +1 -0
- package/dist/src/mcp/agent-schedules.js +175 -0
- package/dist/src/mcp/agent-schedules.js.map +1 -0
- package/dist/src/mcp/annotations.d.ts.map +1 -1
- package/dist/src/mcp/annotations.js +6 -0
- package/dist/src/mcp/annotations.js.map +1 -1
- package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
- package/dist/src/mcp/catalog/definitions.js +55 -0
- package/dist/src/mcp/catalog/definitions.js.map +1 -1
- package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
- package/dist/src/mcp/catalog/scopes.js +12 -0
- package/dist/src/mcp/catalog/scopes.js.map +1 -1
- package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
- package/dist/src/mcp/catalog/surfaces.js +2 -0
- package/dist/src/mcp/catalog/surfaces.js.map +1 -1
- package/dist/src/mcp/index.d.ts.map +1 -1
- package/dist/src/mcp/index.js +2 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/models/agent-task-schemas.d.ts +6 -0
- package/dist/src/models/agent-task-schemas.d.ts.map +1 -1
- package/dist/src/models/agent-task-schemas.js +6 -0
- package/dist/src/models/agent-task-schemas.js.map +1 -1
- package/dist/src/models/schemas.d.ts +1 -0
- package/dist/src/models/schemas.d.ts.map +1 -1
- package/dist/src/models/schemas.js +4 -0
- package/dist/src/models/schemas.js.map +1 -1
- package/dist/src/routes/access-tokens.d.ts +17 -0
- package/dist/src/routes/access-tokens.d.ts.map +1 -0
- package/dist/src/routes/access-tokens.js +164 -0
- package/dist/src/routes/access-tokens.js.map +1 -0
- package/dist/src/routes/agent-tasks.d.ts +2 -0
- package/dist/src/routes/agent-tasks.d.ts.map +1 -1
- package/dist/src/routes/agent-tasks.js +118 -23
- package/dist/src/routes/agent-tasks.js.map +1 -1
- package/dist/src/routes/agents.d.ts.map +1 -1
- package/dist/src/routes/agents.js +46 -0
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/ai.d.ts +6 -9
- package/dist/src/routes/ai.d.ts.map +1 -1
- package/dist/src/routes/ai.js +26 -175
- package/dist/src/routes/ai.js.map +1 -1
- package/dist/src/routes/apps.d.ts.map +1 -1
- package/dist/src/routes/apps.js +104 -34
- package/dist/src/routes/apps.js.map +1 -1
- package/dist/src/routes/auth.d.ts.map +1 -1
- package/dist/src/routes/auth.js +77 -4
- package/dist/src/routes/auth.js.map +1 -1
- package/dist/src/routes/cortex.d.ts +2 -1
- package/dist/src/routes/cortex.d.ts.map +1 -1
- package/dist/src/routes/cortex.js +13 -8
- package/dist/src/routes/cortex.js.map +1 -1
- package/dist/src/routes/extensions.d.ts.map +1 -1
- package/dist/src/routes/extensions.js +85 -51
- package/dist/src/routes/extensions.js.map +1 -1
- package/dist/src/routes/generator.d.ts.map +1 -1
- package/dist/src/routes/generator.js +109 -43
- package/dist/src/routes/generator.js.map +1 -1
- package/dist/src/routes/ghii.d.ts.map +1 -1
- package/dist/src/routes/ghii.js +34 -13
- package/dist/src/routes/ghii.js.map +1 -1
- package/dist/src/routes/libs.d.ts +15 -0
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +178 -55
- package/dist/src/routes/libs.js.map +1 -1
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +1 -0
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/schedules.d.ts +33 -0
- package/dist/src/routes/schedules.d.ts.map +1 -0
- package/dist/src/routes/schedules.js +380 -0
- package/dist/src/routes/schedules.js.map +1 -0
- package/dist/src/server-bootstrap/config-init.js +2 -2
- package/dist/src/server-bootstrap/config-init.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +7 -0
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
- package/dist/src/server-bootstrap/service-init.js +2 -1
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/services/access-token.d.ts +28 -0
- package/dist/src/services/access-token.d.ts.map +1 -0
- package/dist/src/services/access-token.js +37 -0
- package/dist/src/services/access-token.js.map +1 -0
- package/dist/src/services/ai-completion.d.ts +83 -0
- package/dist/src/services/ai-completion.d.ts.map +1 -0
- package/dist/src/services/ai-completion.js +187 -0
- package/dist/src/services/ai-completion.js.map +1 -0
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +3 -0
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/generator-prompt-seeds.d.ts.map +1 -1
- package/dist/src/services/generator-prompt-seeds.js +6 -3
- package/dist/src/services/generator-prompt-seeds.js.map +1 -1
- package/dist/src/services/generator-prompts/spec-validate.d.ts.map +1 -1
- package/dist/src/services/generator-prompts/spec-validate.js +6 -2
- package/dist/src/services/generator-prompts/spec-validate.js.map +1 -1
- package/dist/src/services/generator-registration.d.ts +12 -4
- package/dist/src/services/generator-registration.d.ts.map +1 -1
- package/dist/src/services/generator-registration.js +71 -0
- package/dist/src/services/generator-registration.js.map +1 -1
- package/dist/src/services/generator-validate.d.ts +10 -0
- package/dist/src/services/generator-validate.d.ts.map +1 -1
- package/dist/src/services/generator-validate.js +180 -36
- package/dist/src/services/generator-validate.js.map +1 -1
- package/dist/src/services/owner-session.d.ts +43 -0
- package/dist/src/services/owner-session.d.ts.map +1 -0
- package/dist/src/services/owner-session.js +175 -0
- package/dist/src/services/owner-session.js.map +1 -0
- package/dist/src/services/schedule-constraints.d.ts +65 -0
- package/dist/src/services/schedule-constraints.d.ts.map +1 -0
- package/dist/src/services/schedule-constraints.js +106 -0
- package/dist/src/services/schedule-constraints.js.map +1 -0
- package/dist/src/services/scheduler.d.ts +34 -0
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +266 -22
- package/dist/src/services/scheduler.js.map +1 -1
- package/dist/src/services/skill-bundle/generator.js +19 -0
- package/dist/src/services/skill-bundle/generator.js.map +1 -1
- package/dist/src/storage/interface.d.ts +48 -4
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +31 -0
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +187 -9
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +31 -0
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +131 -8
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-task.js +6 -4
- package/dist/src/storage/providers/sqlite/repos/agent-task.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +79 -8
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/pat.repository.d.ts +40 -0
- package/dist/src/storage/repositories/pat.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/pat.repository.js +14 -0
- package/dist/src/storage/repositories/pat.repository.js.map +1 -0
- package/dist/src/storage/repositories/scheduler.repository.d.ts +2 -0
- package/dist/src/storage/repositories/scheduler.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/session.repository.d.ts +51 -0
- package/dist/src/storage/repositories/session.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/session.repository.js +12 -0
- package/dist/src/storage/repositories/session.repository.js.map +1 -1
- package/dist/src/utils/env-config.d.ts.map +1 -1
- package/dist/src/utils/env-config.js +25 -1
- package/dist/src/utils/env-config.js.map +1 -1
- package/dist/src/utils/env-validator.d.ts.map +1 -1
- package/dist/src/utils/env-validator.js +4 -0
- package/dist/src/utils/env-validator.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +48 -0
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* v1.3.0 -- 2026-05-21 -- Shorten agent prompt to delegate to tier1; add Download/Copy Instructions buttons
|
|
11
11
|
* v1.4.0 -- 2026-05-21 -- Add sub-tab navigation (Tasks, Directives) in expanded agent detail view
|
|
12
12
|
* v1.5.0 -- 2026-05-22 -- Add Capabilities sub-tab with technical/domain skill display
|
|
13
|
+
* v1.6.0 -- 2026-06-02 -- Component unification (#2): scope modal uses the canonical
|
|
14
|
+
* <Modal> component (className="scope-modal" preserves width; adds Escape/✕ close)
|
|
13
15
|
* v1.6.0 -- 2026-05-22 -- Add Activity sub-tab with stats, chart, scheduled jobs, event log
|
|
14
16
|
* v1.7.0 -- 2026-05-22 -- Add Services and Messages sub-tabs
|
|
15
17
|
* v2.1.0 -- 2026-05-24 -- Fix: scroll-to on board click, agent count badge in header
|
|
@@ -29,22 +31,28 @@
|
|
|
29
31
|
* v3.2.0 -- 2026-05-29 -- Tag filter bar + group-by toggle (none / tag / mode)
|
|
30
32
|
* v3.3.0 -- 2026-05-29 -- Add "Connect a task-runner" collapsible with CrewAI-shaped paste prompt
|
|
31
33
|
* v3.4.0 -- 2026-05-31 -- Drag-to-reorder agent bars (per-browser localStorage order, ungrouped/unfiltered list only) + pop-out button opening an agent in its own window (/v1/profile?solo=)
|
|
34
|
+
* v3.5.0 -- 2026-06-02 -- Component unification: replace 4 bespoke copy-prompt buttons
|
|
35
|
+
* (connect command, MCP onboarding, manual agent prompt, task-runner prompt) with the
|
|
36
|
+
* canonical <CopyButton> (className="copy-prompt-btn" preserves appearance); removed the
|
|
37
|
+
* now-dead copiedAction state + markCopied helper.
|
|
32
38
|
*/
|
|
33
39
|
import { h } from 'preact';
|
|
34
40
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
35
41
|
import htm from 'htm';
|
|
36
42
|
const html = htm.bind(h);
|
|
37
43
|
import { t } from '/js/i18n.js';
|
|
38
|
-
import { escHtml
|
|
44
|
+
import { escHtml } from '/js/utils.js';
|
|
45
|
+
import { CopyButton } from '/components/CopyButton.js';
|
|
39
46
|
import { Spinner } from './shared.js';
|
|
40
47
|
import { apiGet, apiPost, apiPatch } from '/js/api.js';
|
|
41
48
|
import { listAgents, updateAgentScopes, deleteAgent } from '/js/services/agents.js';
|
|
42
49
|
import { getNodeUrl } from '/js/services/auth.js';
|
|
43
|
-
import { useConfirm } from '/components/Modal.js';
|
|
50
|
+
import { Modal, useConfirm } from '/components/Modal.js';
|
|
44
51
|
import SharedBoard from './agents/shared-board.js';
|
|
45
52
|
import AgentCard from './agents/agent-card.js';
|
|
46
53
|
import { getOnboarding } from '/js/services/agent-integration.js';
|
|
47
54
|
import { listTasks } from '/js/services/agent-tasks.js';
|
|
55
|
+
import { listMessages } from '/js/services/agent-messages.js';
|
|
48
56
|
|
|
49
57
|
// === Scope Management Constants ===
|
|
50
58
|
const SCOPE_DOMAINS = [
|
|
@@ -58,6 +66,12 @@ const SCOPE_DOMAINS = [
|
|
|
58
66
|
{ key: 'catalogue', permissions: ['read'] },
|
|
59
67
|
{ key: 'generator', permissions: ['read', 'write', 'execute'] },
|
|
60
68
|
{ key: 'task', permissions: ['read', 'write', 'manage'] },
|
|
69
|
+
// cortex:write — install/activate/deactivate/delete cortex libraries (browser-side UI)
|
|
70
|
+
// ext:write — activate/deactivate/delete extensions, manage instances (server-side WASM)
|
|
71
|
+
// Note: extension INSTALL is requireAuth-only at the route (agents can push code that stays
|
|
72
|
+
// inert until ext:write activates it). Cortex INSTALL requires cortex:write.
|
|
73
|
+
{ key: 'cortex', permissions: ['write'] },
|
|
74
|
+
{ key: 'ext', permissions: ['write'] },
|
|
61
75
|
];
|
|
62
76
|
|
|
63
77
|
const SCOPE_TEMPLATES = {
|
|
@@ -359,6 +373,47 @@ function saveAgentOrder(owner, names) {
|
|
|
359
373
|
try { localStorage.setItem(ORDER_KEY_PREFIX + owner, JSON.stringify(names)); }
|
|
360
374
|
catch { /* ignore quota/availability errors */ }
|
|
361
375
|
}
|
|
376
|
+
|
|
377
|
+
// ── Per-browser "last seen per tab" state (localStorage) ──
|
|
378
|
+
// Drives the per-agent change badges: how many tasks / messages / memory
|
|
379
|
+
// entries have updated since the owner last opened that tab. Per-browser, keyed
|
|
380
|
+
// by owner — same rationale as the agent ordering above (no server round-trip;
|
|
381
|
+
// "what's new since I looked HERE" is inherently a per-device affordance).
|
|
382
|
+
// Shape: { [agentName]: { tasks: iso, messages: iso, memory: iso } }
|
|
383
|
+
// The three keys map to the Tasks, Messages and Memory (data-access) tabs.
|
|
384
|
+
const SEEN_KEY_PREFIX = 'aimeat-agent-seen:';
|
|
385
|
+
function loadSeen(owner) {
|
|
386
|
+
if (!owner) return {};
|
|
387
|
+
try { return JSON.parse(localStorage.getItem(SEEN_KEY_PREFIX + owner) || '{}') || {}; }
|
|
388
|
+
catch { return {}; }
|
|
389
|
+
}
|
|
390
|
+
function saveSeen(owner, data) {
|
|
391
|
+
if (!owner) return;
|
|
392
|
+
try { localStorage.setItem(SEEN_KEY_PREFIX + owner, JSON.stringify(data)); }
|
|
393
|
+
catch { /* ignore quota/availability errors */ }
|
|
394
|
+
}
|
|
395
|
+
// Stamp the given agent+tab as seen-now and persist. Read-modify-write against
|
|
396
|
+
// the freshest localStorage so a concurrent loadData() seed doesn't clobber it.
|
|
397
|
+
function markTabSeen(owner, agentName, tab) {
|
|
398
|
+
if (!owner || !agentName || !tab) return;
|
|
399
|
+
const seen = loadSeen(owner);
|
|
400
|
+
(seen[agentName] ||= {})[tab] = new Date().toISOString();
|
|
401
|
+
saveSeen(owner, seen);
|
|
402
|
+
}
|
|
403
|
+
// Count items whose newest available timestamp (first present of `fields`) is
|
|
404
|
+
// strictly newer than `since`. `since` falsy → 0 (the caller seeds a baseline
|
|
405
|
+
// on first observation, so an agent's whole history is never dumped as "new").
|
|
406
|
+
function countNewer(items, since, fields) {
|
|
407
|
+
if (!Array.isArray(items) || !since) return 0;
|
|
408
|
+
const sinceMs = new Date(since).getTime();
|
|
409
|
+
let n = 0;
|
|
410
|
+
for (const it of items) {
|
|
411
|
+
let ts = null;
|
|
412
|
+
for (const f of fields) { if (it && it[f]) { ts = it[f]; break; } }
|
|
413
|
+
if (ts && new Date(ts).getTime() > sinceMs) n++;
|
|
414
|
+
}
|
|
415
|
+
return n;
|
|
416
|
+
}
|
|
362
417
|
// Effective ordering: agents named in the saved order first (in that order),
|
|
363
418
|
// then any agents not yet ordered (e.g. newly connected) in their API order.
|
|
364
419
|
function effectiveOrderedNames(agents, order) {
|
|
@@ -382,7 +437,6 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
382
437
|
const { confirm, ConfirmUI } = useConfirm();
|
|
383
438
|
const [agents, setAgents] = useState(null);
|
|
384
439
|
const [onboardings, setOnboardings] = useState({});
|
|
385
|
-
const [copiedAction, setCopiedAction] = useState(null);
|
|
386
440
|
const [platExpand, setPlatExpand] = useState(false);
|
|
387
441
|
const [activePlat, setActivePlat] = useState('windows');
|
|
388
442
|
const [scopesModal, setScopesModal] = useState(null);
|
|
@@ -395,6 +449,10 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
395
449
|
const [taskRunnerExpanded, setTaskRunnerExpanded] = useState(false);
|
|
396
450
|
const [taskRunnerName, setTaskRunnerName] = useState('');
|
|
397
451
|
const [taskStatsMap, setTaskStatsMap] = useState({});
|
|
452
|
+
// Per-agent unseen-change counts { name: { tasks, messages, memory } } driving
|
|
453
|
+
// the collapsed mini-badge + per-tab number badges. Computed in loadData()
|
|
454
|
+
// from the localStorage "last seen per tab" baseline (see loadSeen/countNewer).
|
|
455
|
+
const [changesMap, setChangesMap] = useState({});
|
|
398
456
|
const [tagFilter, setTagFilter] = useState(new Set());
|
|
399
457
|
const [groupBy, setGroupBy] = useState('none'); // 'none' | 'tag' | 'mode'
|
|
400
458
|
// Per-browser drag-to-reorder of the agent bars (localStorage-backed).
|
|
@@ -430,9 +488,17 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
430
488
|
onDragEnd: () => { draggedName.current = null; setDraggingName(null); },
|
|
431
489
|
};
|
|
432
490
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
491
|
+
// Owner opened a tab on an agent → stamp it seen and clear that badge now.
|
|
492
|
+
// The next loadData() recomputes from the same baseline, keeping it at 0
|
|
493
|
+
// until a new change actually arrives.
|
|
494
|
+
const handleTabSeen = (agentName, tab) => {
|
|
495
|
+
if (!session) return;
|
|
496
|
+
markTabSeen(session.owner, agentName, tab);
|
|
497
|
+
setChangesMap(prev => {
|
|
498
|
+
const cur = prev[agentName];
|
|
499
|
+
if (!cur || !cur[tab]) return prev;
|
|
500
|
+
return { ...prev, [agentName]: { ...cur, [tab]: 0 } };
|
|
501
|
+
});
|
|
436
502
|
};
|
|
437
503
|
|
|
438
504
|
useEffect(() => {
|
|
@@ -468,19 +534,56 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
468
534
|
}));
|
|
469
535
|
setOnboardings(obMap);
|
|
470
536
|
const tsMap = {};
|
|
537
|
+
const seen = loadSeen(session.owner);
|
|
538
|
+
let seenSeeded = false;
|
|
539
|
+
const chMap = {};
|
|
471
540
|
await Promise.all(list.map(async (a) => {
|
|
472
541
|
try {
|
|
473
|
-
const [doneResp, activeResp] = await Promise.all([
|
|
542
|
+
const [doneResp, activeResp, msgResp, memResp] = await Promise.all([
|
|
474
543
|
listTasks(a.name, { status: 'done', per_page: 100 }),
|
|
475
544
|
listTasks(a.name, { status: 'active', per_page: 100 }),
|
|
545
|
+
listMessages(a.name, { perPage: 100 }).catch(() => null),
|
|
546
|
+
apiGet(`/v1/memory?prefix=&per_page=100&agent=${encodeURIComponent(a.gaii || a.name)}`).catch(() => null),
|
|
476
547
|
]);
|
|
477
548
|
const today = new Date().toISOString().slice(0, 10);
|
|
478
|
-
const
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
549
|
+
const doneTasks = doneResp?.data?.tasks || [];
|
|
550
|
+
const activeTasks = activeResp?.data?.tasks || [];
|
|
551
|
+
const doneToday = doneTasks.filter(tk => tk.completedAt?.startsWith(today)).length;
|
|
552
|
+
tsMap[a.name] = { done: doneToday, active: activeTasks.length };
|
|
553
|
+
|
|
554
|
+
// Per-tab unseen-change counts. First observation of a tab seeds its
|
|
555
|
+
// baseline to "now" (count 0) so an agent's whole history is never
|
|
556
|
+
// dumped as new; only changes after that point raise the badge.
|
|
557
|
+
const agentSeen = seen[a.name] || (seen[a.name] = {});
|
|
558
|
+
const nowIso = new Date().toISOString();
|
|
559
|
+
const ch = {};
|
|
560
|
+
for (const [tab, items, fields] of [
|
|
561
|
+
['tasks', [...doneTasks, ...activeTasks], ['updatedAt', 'completedAt', 'createdAt']],
|
|
562
|
+
// Only count agent→owner messages as unread; the owner's own
|
|
563
|
+
// inbound messages are not "new" to them.
|
|
564
|
+
['messages', (msgResp?.data?.messages || []).filter(m => m.direction !== 'inbound'), ['createdAt', 'created_at']],
|
|
565
|
+
['memory', (memResp?.data?.items || memResp?.data || []), ['updated_at', 'updatedAt', 'created_at', 'createdAt']],
|
|
566
|
+
]) {
|
|
567
|
+
if (agentSeen[tab] === undefined) { agentSeen[tab] = nowIso; seenSeeded = true; ch[tab] = 0; }
|
|
568
|
+
else ch[tab] = countNewer(items, agentSeen[tab], fields);
|
|
569
|
+
}
|
|
570
|
+
chMap[a.name] = ch;
|
|
571
|
+
} catch { tsMap[a.name] = null; chMap[a.name] = null; }
|
|
482
572
|
}));
|
|
483
573
|
setTaskStatsMap(tsMap);
|
|
574
|
+
// Persist any freshly-seeded baselines. Merge against the latest storage
|
|
575
|
+
// so a tab the user opened mid-fetch (markTabSeen) is not overwritten.
|
|
576
|
+
if (seenSeeded) {
|
|
577
|
+
const fresh = loadSeen(session.owner);
|
|
578
|
+
for (const name of Object.keys(seen)) {
|
|
579
|
+
const merged = fresh[name] || (fresh[name] = {});
|
|
580
|
+
for (const tab of Object.keys(seen[name])) {
|
|
581
|
+
if (merged[tab] === undefined) merged[tab] = seen[name][tab];
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
saveSeen(session.owner, fresh);
|
|
585
|
+
}
|
|
586
|
+
setChangesMap(chMap);
|
|
484
587
|
} catch { setAgents([]); }
|
|
485
588
|
}
|
|
486
589
|
|
|
@@ -643,11 +746,11 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
643
746
|
|
|
644
747
|
<p class="mb-half text-bold">${t('profile.agents.cliInstall')}</p>
|
|
645
748
|
<div class="agent-prompt-box"><code>npx aimeat connect --url ${getNodeUrl()} --owner ${session.owner}</code></div>
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
|
|
749
|
+
<${CopyButton}
|
|
750
|
+
text=${`npx aimeat connect --url ${getNodeUrl()} --owner ${session.owner}`}
|
|
751
|
+
className="copy-prompt-btn"
|
|
752
|
+
label=${t('profile.agents.copyCommand')}
|
|
753
|
+
copiedLabel=${'\u2705 ' + t('profile.agents.copied')} />
|
|
651
754
|
|
|
652
755
|
<p class="mt-1 mb-half text-bold">${t('profile.agents.cliServe')}</p>
|
|
653
756
|
<div class="agent-prompt-box"><code>npx aimeat connect serve</code></div>
|
|
@@ -657,11 +760,11 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
657
760
|
<p class="mt-1 mb-half text-bold">${t('profile.agents.agentInstructionTitle')}</p>
|
|
658
761
|
<p class="text-caption mb-half">${t('profile.agents.agentInstructionDesc')}</p>
|
|
659
762
|
<div class="agent-prompt-box">${buildMcpOnboardingPrompt()}</div>
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
}
|
|
664
|
-
|
|
763
|
+
<${CopyButton}
|
|
764
|
+
text=${buildMcpOnboardingPrompt()}
|
|
765
|
+
className="copy-prompt-btn"
|
|
766
|
+
label=${t('profile.agents.copyAgentInstruction')}
|
|
767
|
+
copiedLabel=${'\u2705 ' + t('profile.agents.copied')} />
|
|
665
768
|
|
|
666
769
|
<div class="pf-agent-divider mt-1">
|
|
667
770
|
<button class="expand-btn" onClick=${() => setPlatExpand(!platExpand)}>
|
|
@@ -690,11 +793,11 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
690
793
|
<div class="mt-half">
|
|
691
794
|
<p class="text-caption mb-half">${t('profile.agents.pasteDesc')}</p>
|
|
692
795
|
<div class="agent-prompt-box">${buildAgentPrompt(session)}</div>
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
}
|
|
697
|
-
|
|
796
|
+
<${CopyButton}
|
|
797
|
+
text=${buildAgentPrompt(session)}
|
|
798
|
+
className="copy-prompt-btn"
|
|
799
|
+
label=${t('profile.agents.copyPrompt')}
|
|
800
|
+
copiedLabel=${'\u2705 ' + t('profile.agents.copied')} />
|
|
698
801
|
</div>
|
|
699
802
|
`}
|
|
700
803
|
</div>
|
|
@@ -718,11 +821,11 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
718
821
|
onInput=${(e) => setTaskRunnerName(e.target.value)} />
|
|
719
822
|
</div>
|
|
720
823
|
<div class="agent-prompt-box">${buildTaskRunnerPrompt(session, taskRunnerName)}</div>
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
|
|
824
|
+
<${CopyButton}
|
|
825
|
+
text=${buildTaskRunnerPrompt(session, taskRunnerName)}
|
|
826
|
+
className="copy-prompt-btn"
|
|
827
|
+
label=${t('profile.agents.taskRunner.copyButton')}
|
|
828
|
+
copiedLabel=${'\u2705 ' + t('profile.agents.copied')} />
|
|
726
829
|
</div>
|
|
727
830
|
`}
|
|
728
831
|
</div>
|
|
@@ -750,6 +853,8 @@ export default function AgentsTab({ session, showToast, onStats }) {
|
|
|
750
853
|
groupBy,
|
|
751
854
|
onboardings,
|
|
752
855
|
taskStatsMap,
|
|
856
|
+
changesMap,
|
|
857
|
+
onTabSeen: handleTabSeen,
|
|
753
858
|
expandedAgent,
|
|
754
859
|
toggleAgent,
|
|
755
860
|
session,
|
|
@@ -825,7 +930,7 @@ function renderFilterBar(agents, tagFilter, setTagFilter, groupBy, setGroupBy) {
|
|
|
825
930
|
`;
|
|
826
931
|
}
|
|
827
932
|
|
|
828
|
-
function renderAgentGroups({ agents, tagFilter, groupBy, onboardings, taskStatsMap, expandedAgent, toggleAgent, session, showToast, setScopesModal, handleDeleteAgent, toggleFederate, onPopOut, dnd, agentOrder }) {
|
|
933
|
+
function renderAgentGroups({ agents, tagFilter, groupBy, onboardings, taskStatsMap, changesMap, onTabSeen, expandedAgent, toggleAgent, session, showToast, setScopesModal, handleDeleteAgent, toggleFederate, onPopOut, dnd, agentOrder }) {
|
|
829
934
|
// Tag filter: agent must have ALL selected tags (intersection)
|
|
830
935
|
const filtered = tagFilter.size === 0
|
|
831
936
|
? agents
|
|
@@ -848,6 +953,8 @@ function renderAgentGroups({ agents, tagFilter, groupBy, onboardings, taskStatsM
|
|
|
848
953
|
session=${session}
|
|
849
954
|
showToast=${showToast}
|
|
850
955
|
allAgents=${agents}
|
|
956
|
+
changes=${changesMap?.[a.name] || null}
|
|
957
|
+
onTabSeen=${onTabSeen}
|
|
851
958
|
onScopesClick=${(agent) => setScopesModal(agent)}
|
|
852
959
|
onDeleteClick=${handleDeleteAgent}
|
|
853
960
|
onFederateToggle=${toggleFederate}
|
|
@@ -1014,9 +1121,7 @@ function ScopesModal({ agent, session, onSave, onCancel }) {
|
|
|
1014
1121
|
const isReadOnly = !(session.roles?.includes('owner') || session.roles?.includes('operator'));
|
|
1015
1122
|
|
|
1016
1123
|
return html`
|
|
1017
|
-
|
|
1018
|
-
<div class="modal scope-modal">
|
|
1019
|
-
<h3>${t('profile.agents.scopeUi.scopeProfile')}: ${escHtml(agent.display_name || agent.name)}</h3>
|
|
1124
|
+
<${Modal} open=${true} onClose=${onCancel} className="scope-modal" title=${`${t('profile.agents.scopeUi.scopeProfile')}: ${agent.display_name || agent.name}`}>
|
|
1020
1125
|
<div class="scope-agent-info">${escHtml(agent.gaii || '')}</div>
|
|
1021
1126
|
|
|
1022
1127
|
${isReadOnly ? html`
|
|
@@ -1083,6 +1188,5 @@ function ScopesModal({ agent, session, onSave, onCancel }) {
|
|
|
1083
1188
|
<button class="btn-outline" onClick=${onCancel}>${t('profile.agents.scopeUi.cancel')}</button>
|
|
1084
1189
|
</div>
|
|
1085
1190
|
`}
|
|
1086
|
-
|
|
1087
|
-
</div>`;
|
|
1191
|
+
<//>`;
|
|
1088
1192
|
}
|