aimeat 1.25.0 → 1.26.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/README.md +8 -1
- package/dist/locales/en.json +144 -0
- package/dist/locales/fi.json +144 -0
- package/dist/public/components/ImageDeliverable.js +2 -1
- package/dist/public/components/Modal.js +3 -2
- package/dist/public/components/NotificationBell.js +2 -1
- package/dist/public/components/PresenceDot.js +53 -0
- package/dist/public/css/components/markdown.css +67 -0
- package/dist/public/css/theme.css +30 -0
- package/dist/public/css/views/notebook.css +195 -0
- package/dist/public/css/views/profile.css +15 -0
- package/dist/public/js/api.js +5 -3
- package/dist/public/js/components/auth-image.js +3 -2
- package/dist/public/js/components/tag-cloud.js +1 -1
- package/dist/public/js/components/tag-editor.js +1 -1
- package/dist/public/js/hooks.js +1 -2
- package/dist/public/js/presence-store.js +97 -0
- package/dist/public/js/services/admin.js +14 -5
- package/dist/public/js/services/boards.js +1 -1
- package/dist/public/js/services/ecosystem.js +1 -1
- package/dist/public/js/services/foundry-prompts-base.js +2 -2
- package/dist/public/js/services/foundry-smoke.js +2 -1
- package/dist/public/js/services/foundry-validate.js +6 -8
- package/dist/public/js/services/foundry.js +4 -3
- package/dist/public/js/services/generator-prompts-base.js +2 -2
- package/dist/public/js/services/generator-smoke.js +2 -1
- package/dist/public/js/services/generator-validate.js +5 -7
- package/dist/public/js/services/generator.js +2 -1
- package/dist/public/js/services/memory.js +13 -0
- package/dist/public/js/services/messages.js +2 -1
- package/dist/public/js/services/notebook.js +124 -0
- package/dist/public/js/services/packages.js +3 -2
- package/dist/public/js/services/presence.js +35 -0
- package/dist/public/js/style-testbed.js +6 -5
- package/dist/public/lib/minidenticons.min.js +1 -0
- package/dist/public/lib/yaml.mjs +1 -0
- package/dist/public/spa.html +90 -8
- package/dist/public/types/aimeat-globals.d.ts +52 -0
- package/dist/public/types/vendored-libs.d.ts +56 -0
- package/dist/public/views/_template.js +3 -1
- package/dist/public/views/admin/agent-integration-tab.js +4 -3
- package/dist/public/views/admin/agents-tab.js +3 -2
- package/dist/public/views/admin/config-tab.js +4 -3
- package/dist/public/views/admin/economy-tab.js +4 -3
- package/dist/public/views/admin/federation-tab.js +138 -1
- package/dist/public/views/admin/maintenance-tab.js +1 -1
- package/dist/public/views/admin/messages-tab.js +115 -0
- package/dist/public/views/admin/overview-tab.js +4 -3
- package/dist/public/views/admin/portal-tab.js +90 -2
- package/dist/public/views/admin/push-tab.js +8 -6
- package/dist/public/views/admin/security-tab.js +7 -7
- package/dist/public/views/admin.js +29 -9
- package/dist/public/views/doc-solo.js +3 -1
- package/dist/public/views/guides.js +8 -4
- package/dist/public/views/hobbies.js +4 -2
- package/dist/public/views/marketplace.js +10 -9
- package/dist/public/views/openclaw.js +1 -1
- package/dist/public/views/portal-dev.js +5 -2
- package/dist/public/views/portal.js +3 -2
- package/dist/public/views/profile/agents/shared-board.js +4 -2
- package/dist/public/views/profile/agents/tab-messages.js +13 -11
- package/dist/public/views/profile/agents-messages-subtab.js +2 -1
- package/dist/public/views/profile/apps-tab.js +2 -1
- package/dist/public/views/profile/boards-tab.js +3 -2
- package/dist/public/views/profile/calibrator-batch.js +3 -2
- package/dist/public/views/profile/data-wallet-tab.js +2 -1
- package/dist/public/views/profile/extensions-tab.js +4 -3
- package/dist/public/views/profile/federation-tab.js +4 -0
- package/dist/public/views/profile/foundry-dashboard/use-autopilot.js +3 -2
- package/dist/public/views/profile/foundry-detail.js +1 -1
- package/dist/public/views/profile/generator-detail.js +1 -1
- package/dist/public/views/profile/inbox-tab.js +7 -3
- package/dist/public/views/profile/inline-panels.js +3 -1
- package/dist/public/views/profile/knowledge-tab.js +2 -1
- package/dist/public/views/profile/landing-page.js +88 -0
- package/dist/public/views/profile/memory-tab.js +6 -5
- package/dist/public/views/profile/notebook-tab.js +500 -0
- package/dist/public/views/profile/organisms/activity-panel.js +135 -0
- package/dist/public/views/profile/organisms/agents.js +141 -0
- package/dist/public/views/profile/organisms/document.js +274 -0
- package/dist/public/views/profile/organisms/helpers.js +61 -0
- package/dist/public/views/profile/organisms/home.js +315 -0
- package/dist/public/views/profile/organisms/members.js +220 -0
- package/dist/public/views/profile/organisms/panels.js +173 -0
- package/dist/public/views/profile/organisms/participants-panel.js +160 -0
- package/dist/public/views/profile/organisms/schema-form.js +127 -0
- package/dist/public/views/profile/organisms/sources-panel.js +164 -0
- package/dist/public/views/profile/organisms/widgets.js +58 -0
- package/dist/public/views/profile/organisms/workspace-comments.js +99 -0
- package/dist/public/views/profile/organisms/workspace-list.js +268 -0
- package/dist/public/views/profile/organisms/workspace.js +1272 -0
- package/dist/public/views/profile/organisms-tab.js +456 -3819
- package/dist/public/views/profile/shared.js +64 -2
- package/dist/public/views/profile/workflows-form.js +1 -1
- package/dist/public/views/profile.js +16 -14
- package/dist/public/views/public-knowledge-viewer.js +3 -2
- package/dist/public/views/public-workspace-viewer.js +2 -1
- package/dist/scripts/check-importmap.d.ts +2 -0
- package/dist/scripts/check-importmap.d.ts.map +1 -0
- package/dist/scripts/check-importmap.js +102 -0
- package/dist/scripts/check-importmap.js.map +1 -0
- package/dist/src/cli/scaffold.d.ts +26 -3
- package/dist/src/cli/scaffold.d.ts.map +1 -1
- package/dist/src/cli/scaffold.js +33 -3
- package/dist/src/cli/scaffold.js.map +1 -1
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +5 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +927 -11
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +32 -6
- package/dist/src/generated/prisma-postgres/index-browser.js +29 -3
- package/dist/src/generated/prisma-postgres/index.d.ts +1970 -160
- package/dist/src/generated/prisma-postgres/index.js +32 -6
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +45 -12
- package/dist/src/generated/prisma-postgres/wasm.js +32 -6
- package/dist/src/index.js +36 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/routes/admin-monitoring.d.ts.map +1 -1
- package/dist/src/routes/admin-monitoring.js +8 -0
- package/dist/src/routes/admin-monitoring.js.map +1 -1
- package/dist/src/routes/federation-peer.d.ts.map +1 -1
- package/dist/src/routes/federation-peer.js +327 -43
- package/dist/src/routes/federation-peer.js.map +1 -1
- package/dist/src/routes/federation-sync.d.ts +2 -0
- package/dist/src/routes/federation-sync.d.ts.map +1 -1
- package/dist/src/routes/federation-sync.js +20 -1
- package/dist/src/routes/federation-sync.js.map +1 -1
- package/dist/src/routes/librarian.d.ts +18 -0
- package/dist/src/routes/librarian.d.ts.map +1 -0
- package/dist/src/routes/librarian.js +88 -0
- package/dist/src/routes/librarian.js.map +1 -0
- package/dist/src/routes/messages.d.ts.map +1 -1
- package/dist/src/routes/messages.js +2 -1
- package/dist/src/routes/messages.js.map +1 -1
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +9 -1
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/presence.d.ts +23 -0
- package/dist/src/routes/presence.d.ts.map +1 -0
- package/dist/src/routes/presence.js +88 -0
- package/dist/src/routes/presence.js.map +1 -0
- package/dist/src/routes/site.d.ts +12 -0
- package/dist/src/routes/site.d.ts.map +1 -1
- package/dist/src/routes/site.js +45 -1
- package/dist/src/routes/site.js.map +1 -1
- package/dist/src/routes/sse.d.ts +2 -0
- package/dist/src/routes/sse.d.ts.map +1 -1
- package/dist/src/routes/sse.js +9 -0
- package/dist/src/routes/sse.js.map +1 -1
- package/dist/src/routes/wellknown.d.ts.map +1 -1
- package/dist/src/routes/wellknown.js +5 -0
- package/dist/src/routes/wellknown.js.map +1 -1
- package/dist/src/routes/work.d.ts.map +1 -1
- package/dist/src/routes/work.js +6 -0
- package/dist/src/routes/work.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +13 -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 +34 -0
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +2 -0
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/federation-availability.d.ts +28 -0
- package/dist/src/services/federation-availability.d.ts.map +1 -0
- package/dist/src/services/federation-availability.js +58 -0
- package/dist/src/services/federation-availability.js.map +1 -0
- package/dist/src/services/federation-book.d.ts +70 -0
- package/dist/src/services/federation-book.d.ts.map +1 -0
- package/dist/src/services/federation-book.js +198 -0
- package/dist/src/services/federation-book.js.map +1 -0
- package/dist/src/services/federation-tiers.d.ts +45 -0
- package/dist/src/services/federation-tiers.d.ts.map +1 -0
- package/dist/src/services/federation-tiers.js +58 -0
- package/dist/src/services/federation-tiers.js.map +1 -0
- package/dist/src/services/federation.d.ts +15 -0
- package/dist/src/services/federation.d.ts.map +1 -1
- package/dist/src/services/federation.js +12 -0
- package/dist/src/services/federation.js.map +1 -1
- package/dist/src/services/librarian.d.ts +62 -0
- package/dist/src/services/librarian.d.ts.map +1 -0
- package/dist/src/services/librarian.js +135 -0
- package/dist/src/services/librarian.js.map +1 -0
- package/dist/src/services/message-delivery.d.ts +3 -1
- package/dist/src/services/message-delivery.d.ts.map +1 -1
- package/dist/src/services/message-delivery.js +23 -2
- package/dist/src/services/message-delivery.js.map +1 -1
- package/dist/src/services/network-policy.d.ts +88 -0
- package/dist/src/services/network-policy.d.ts.map +1 -0
- package/dist/src/services/network-policy.js +154 -0
- package/dist/src/services/network-policy.js.map +1 -0
- package/dist/src/services/notebook-classify-prompt.d.ts +15 -0
- package/dist/src/services/notebook-classify-prompt.d.ts.map +1 -0
- package/dist/src/services/notebook-classify-prompt.js +39 -0
- package/dist/src/services/notebook-classify-prompt.js.map +1 -0
- package/dist/src/services/notebook-classify.d.ts +80 -0
- package/dist/src/services/notebook-classify.d.ts.map +1 -0
- package/dist/src/services/notebook-classify.js +150 -0
- package/dist/src/services/notebook-classify.js.map +1 -0
- package/dist/src/services/presence.d.ts +108 -0
- package/dist/src/services/presence.d.ts.map +1 -0
- package/dist/src/services/presence.js +304 -0
- package/dist/src/services/presence.js.map +1 -0
- package/dist/src/services/prompt-defaults.d.ts.map +1 -1
- package/dist/src/services/prompt-defaults.js +13 -0
- package/dist/src/services/prompt-defaults.js.map +1 -1
- package/dist/src/services/site.d.ts +20 -0
- package/dist/src/services/site.d.ts.map +1 -1
- package/dist/src/services/site.js +70 -0
- package/dist/src/services/site.js.map +1 -1
- package/dist/src/storage/interface.d.ts +48 -0
- 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 +11 -1
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +128 -2
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +7 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +27 -2
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts +5 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/direct-message.js +48 -0
- package/dist/src/storage/providers/sqlite/repos/direct-message.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts +2 -0
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.js +55 -0
- package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +61 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/direct-message.repository.d.ts +5 -1
- package/dist/src/storage/repositories/direct-message.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/memory.repository.d.ts +25 -0
- package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
- package/dist/src/utils/node-descriptor.d.ts +34 -0
- package/dist/src/utils/node-descriptor.d.ts.map +1 -0
- package/dist/src/utils/node-descriptor.js +42 -0
- package/dist/src/utils/node-descriptor.js.map +1 -0
- package/dist/src/utils/version.d.ts +3 -0
- package/dist/src/utils/version.d.ts.map +1 -0
- package/dist/src/utils/version.js +40 -0
- package/dist/src/utils/version.js.map +1 -0
- package/dist/static/app-catalog.html +643 -4
- package/package.json +5 -2
- package/prisma/schema.postgres.prisma +51 -18
- package/prisma/schema.prisma +29 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* @file public/views/admin.js
|
|
3
|
+
* @description Admin Dashboard SPA view — sidebar layout with data preloading and tab components.
|
|
4
|
+
* @structure Single `loadAll` fetches all dashboard data; tabs render slices of it. SSE
|
|
5
|
+
* live-updates trigger a debounced, silent background refresh.
|
|
6
|
+
* @version-history
|
|
7
|
+
* v1.1.0 — 2026-06-18 — Debounce + silence SSE-driven refresh so busy nodes don't flicker "Loading…".
|
|
8
|
+
* v1.1.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
4
9
|
*/
|
|
5
10
|
import { h } from 'preact';
|
|
6
11
|
import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
|
|
@@ -31,6 +36,7 @@ import BoardsTab from './admin/boards-tab.js';
|
|
|
31
36
|
import ChatInstancesTab from './admin/chat-instances-tab.js';
|
|
32
37
|
import RealtimeTab from './admin/realtime-tab.js';
|
|
33
38
|
import WorkTab from './admin/work-tab.js';
|
|
39
|
+
import MessagesAdminTab from './admin/messages-tab.js';
|
|
34
40
|
import EmailTab from './admin/email-tab.js';
|
|
35
41
|
import PushTab from './admin/push-tab.js';
|
|
36
42
|
import DirectoryTab from './admin/directory-tab.js';
|
|
@@ -81,6 +87,7 @@ const NAV_GROUPS = [
|
|
|
81
87
|
{ id: 'chatInstances', icon: '\u{1F4AC}', key: 'dashboard.chatInstances', component: ChatInstancesTab, count: 'chatInstances' },
|
|
82
88
|
{ id: 'realtime', icon: '\u{1F4E1}', key: 'dashboard.realtime', component: RealtimeTab, count: 'rooms' },
|
|
83
89
|
{ id: 'work', icon: '\u{1F4E6}', key: 'dashboard.work', component: WorkTab, count: 'work' },
|
|
90
|
+
{ id: 'messages', icon: '\u{1F4EC}', key: 'admin.messages.title', component: MessagesAdminTab },
|
|
84
91
|
{ id: 'memory-admin', icon: '\u{1F5C4}', key: 'dashboard.memoryAdmin', component: MemoryAdminTab },
|
|
85
92
|
{ id: 'agent-tasks', icon: '\u{1F4CB}', key: 'dashboard.agentTasksTab', component: AgentTasksAdminTab },
|
|
86
93
|
{ id: 'sharing-groups', icon: '\u{1F465}', key: 'dashboard.sharingGroupsTab', component: SharingGroupsAdminTab },
|
|
@@ -130,6 +137,7 @@ export default function Admin({ navigate, locale }) {
|
|
|
130
137
|
const [lastUpdate, setLastUpdate] = useState(null);
|
|
131
138
|
const mountRef = useRef(true);
|
|
132
139
|
const retriedRef = useRef(false);
|
|
140
|
+
const reloadTimerRef = useRef(null);
|
|
133
141
|
|
|
134
142
|
// Auth listener
|
|
135
143
|
useEffect(() => {
|
|
@@ -156,9 +164,11 @@ export default function Admin({ navigate, locale }) {
|
|
|
156
164
|
// Cleanup
|
|
157
165
|
useEffect(() => { mountRef.current = true; return () => { mountRef.current = false; }; }, []);
|
|
158
166
|
|
|
159
|
-
// Load all data — server-side auth is the source of truth
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
// Load all data — server-side auth is the source of truth.
|
|
168
|
+
// `silent` skips the loading spinner so SSE-driven background refreshes don't
|
|
169
|
+
// flicker the "Loading…" button on busy nodes (only manual refresh shows it).
|
|
170
|
+
const loadAll = useCallback(async (silent = false) => {
|
|
171
|
+
if (!silent) setLoading(true);
|
|
162
172
|
setError(null);
|
|
163
173
|
setAccessDenied(false);
|
|
164
174
|
try {
|
|
@@ -307,13 +317,23 @@ export default function Admin({ navigate, locale }) {
|
|
|
307
317
|
if (session) loadAll();
|
|
308
318
|
}, [session, loadAll]);
|
|
309
319
|
|
|
310
|
-
// SSE live updates — auto-reload on server-side data changes
|
|
320
|
+
// SSE live updates — auto-reload on server-side data changes.
|
|
321
|
+
// Debounced + silent: busy nodes emit many events per second; without this the
|
|
322
|
+
// whole dashboard re-fetches (and flickers "Loading…") on every single event.
|
|
311
323
|
useEffect(() => {
|
|
312
324
|
if (!session) return;
|
|
313
325
|
connect(() => getSession()?.jwt);
|
|
314
|
-
|
|
326
|
+
const debouncedReload = () => {
|
|
327
|
+
if (reloadTimerRef.current) clearTimeout(reloadTimerRef.current);
|
|
328
|
+
reloadTimerRef.current = setTimeout(() => {
|
|
329
|
+
reloadTimerRef.current = null;
|
|
330
|
+
if (mountRef.current) loadAll(true);
|
|
331
|
+
}, 1500);
|
|
332
|
+
};
|
|
333
|
+
onUpdate(debouncedReload);
|
|
315
334
|
return () => {
|
|
316
|
-
offUpdate(
|
|
335
|
+
offUpdate(debouncedReload);
|
|
336
|
+
if (reloadTimerRef.current) clearTimeout(reloadTimerRef.current);
|
|
317
337
|
disconnect();
|
|
318
338
|
};
|
|
319
339
|
}, [session, loadAll]);
|
|
@@ -322,7 +342,7 @@ export default function Admin({ navigate, locale }) {
|
|
|
322
342
|
function switchPage(id) {
|
|
323
343
|
setActivePage(id);
|
|
324
344
|
// Update URL without reload
|
|
325
|
-
const url = new URL(window.location);
|
|
345
|
+
const url = new URL(window.location.href);
|
|
326
346
|
url.searchParams.set('tab', id);
|
|
327
347
|
history.replaceState(null, '', url);
|
|
328
348
|
}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* @structure DocSolo (default export)
|
|
10
10
|
* @version-history
|
|
11
11
|
* v1.0.0 — 2026-06-09 — Initial: pop-out document window.
|
|
12
|
+
* v1.0.1 — 2026-06-19 — Import DocumentView/DocumentEditor from their new home
|
|
13
|
+
* (./profile/organisms/document.js) after the organisms-tab module split.
|
|
12
14
|
*/
|
|
13
15
|
import { h } from 'preact';
|
|
14
16
|
import { useState, useEffect, useRef, useCallback } from 'preact/hooks';
|
|
@@ -18,7 +20,7 @@ import { getSession } from '/js/services/auth.js';
|
|
|
18
20
|
import { connect, disconnect, onUpdate, offUpdate } from '/lib/live-updates.js';
|
|
19
21
|
import { useViewCSS } from '/components/useViewCSS.js';
|
|
20
22
|
import * as orgService from '/js/services/organisms.js';
|
|
21
|
-
import { DocumentView, DocumentEditor } from './profile/organisms
|
|
23
|
+
import { DocumentView, DocumentEditor } from './profile/organisms/document.js';
|
|
22
24
|
|
|
23
25
|
const html = htm.bind(h);
|
|
24
26
|
|
|
@@ -300,11 +300,12 @@ function GuideIndex({ locale, onSelectGuide, navigate }) {
|
|
|
300
300
|
function GuideDetail({ slug, locale, onBack }) {
|
|
301
301
|
const labels = LABELS[locale] || LABELS.en;
|
|
302
302
|
const guide = GUIDES[slug];
|
|
303
|
-
|
|
304
|
-
const data = guide[locale] || guide.en;
|
|
303
|
+
const data = guide ? (guide[locale] || guide.en) : null;
|
|
305
304
|
|
|
306
|
-
//
|
|
305
|
+
// Hooks must run unconditionally before any early return (Rules of Hooks) — guard their
|
|
306
|
+
// bodies against a missing guide instead.
|
|
307
307
|
const buildMarkdown = useCallback(() => {
|
|
308
|
+
if (!data) return '';
|
|
308
309
|
let md = '# ' + data.title + '\n\nNode URL: ' + NODE_URL + '\n\nIMPORTANT: Make it a single downloadable HTML file.\n\n';
|
|
309
310
|
data.sections.forEach(s => {
|
|
310
311
|
md += '## ' + s.heading + '\n\n' + s.body + '\n\n';
|
|
@@ -316,9 +317,12 @@ function GuideDetail({ slug, locale, onBack }) {
|
|
|
316
317
|
}, [data]);
|
|
317
318
|
|
|
318
319
|
useEffect(() => {
|
|
320
|
+
if (!data) return;
|
|
319
321
|
document.title = data.title + ' | AIME AT';
|
|
320
322
|
window.scrollTo(0, 0);
|
|
321
|
-
}, [slug, data
|
|
323
|
+
}, [slug, data]);
|
|
324
|
+
|
|
325
|
+
if (!guide) return html`<div class="gd-container"><p>Guide not found.</p></div>`;
|
|
322
326
|
|
|
323
327
|
return html`
|
|
324
328
|
<div class="gd-container">
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @file hobbies.js
|
|
3
3
|
* @description Hobbies view module — multi-view hobby directory (home, search, profile, join, me, matches) rendered with Preact + HTM.
|
|
4
4
|
* @version-history
|
|
5
|
+
* v1.3.0 — 2026-06-19 — Show a presence dot next to people in the directory results + profile header (shared <PresenceDot>)
|
|
5
6
|
* v1.1.0 — 2026-06-02 — Phase 5: tokenize for dark mode (replaced light-only rgba(255,255,255,...) divider with var(--border))
|
|
6
7
|
* v1.2.0 — 2026-06-02 — Component unification (#4 buttons): hb-btn* → canonical
|
|
7
8
|
* theme.css btn-primary / btn-outline / btn-danger / btn-sm.
|
|
@@ -15,6 +16,7 @@ import { escHtml, escAttr } from '/js/utils.js';
|
|
|
15
16
|
import { t, getLocale, switchLocale } from '/js/i18n.js';
|
|
16
17
|
import { apiGet, apiPost, apiPut, apiDelete } from '/js/api.js';
|
|
17
18
|
import { useViewCSS } from '/components/useViewCSS.js';
|
|
19
|
+
import { PresenceDot } from '/components/PresenceDot.js';
|
|
18
20
|
|
|
19
21
|
const html = htm.bind(h);
|
|
20
22
|
|
|
@@ -207,7 +209,7 @@ function SearchView({ goTo, initData }) {
|
|
|
207
209
|
<div style="display:flex;align-items:center;gap:12px;margin-bottom:8px;">
|
|
208
210
|
<span style="font-size:1.5rem;">${entry.avatar || '\uD83D\uDE0A'}</span>
|
|
209
211
|
<div>
|
|
210
|
-
<div class="hb-card-title">${entry.displayName}
|
|
212
|
+
<div class="hb-card-title">${entry.displayName} <${PresenceDot} ghii=${entry.ghii} /></div>
|
|
211
213
|
${(entry.city || entry.area) && html`<div class="hb-card-meta">${[entry.city, entry.area].filter(Boolean).join(', ')}</div>`}
|
|
212
214
|
</div>
|
|
213
215
|
</div>
|
|
@@ -282,7 +284,7 @@ function ProfileView({ goTo, ghii }) {
|
|
|
282
284
|
<div class="hb-profile-header">
|
|
283
285
|
<span class="hb-profile-avatar">${entry.avatar || '\uD83D\uDE0A'}</span>
|
|
284
286
|
<div>
|
|
285
|
-
<div class="hb-profile-name">${entry.displayName}
|
|
287
|
+
<div class="hb-profile-name">${entry.displayName} <${PresenceDot} ghii=${ghii} label=${true} /></div>
|
|
286
288
|
<div class="hb-profile-ghii">${ghii}</div>
|
|
287
289
|
</div>
|
|
288
290
|
</div>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @version-history
|
|
6
6
|
* v1.1.0 — 2026-06-02 — Component unification (#18 category cards): category tiles
|
|
7
7
|
* use canonical theme.css .category-card / -icon / -name / -count (was .mk-category-*).
|
|
8
|
+
* v1.1.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
8
9
|
*/
|
|
9
10
|
import { h } from 'preact';
|
|
10
11
|
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
@@ -379,19 +380,19 @@ function CreateListingView({ extAction, instanceConfig, onNav, tl }) {
|
|
|
379
380
|
const submit = () => {
|
|
380
381
|
setMsg(''); setErr(''); setSending(true);
|
|
381
382
|
const data = {
|
|
382
|
-
title: document.getElementById('mk-sell-title').value,
|
|
383
|
-
description: document.getElementById('mk-sell-desc').value,
|
|
384
|
-
category: document.getElementById('mk-sell-category').value,
|
|
385
|
-
price: parseInt(document.getElementById('mk-sell-price').value, 10),
|
|
383
|
+
title: /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-title')).value,
|
|
384
|
+
description: /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-desc')).value,
|
|
385
|
+
category: /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-category')).value,
|
|
386
|
+
price: parseInt(/** @type {HTMLInputElement} */ (document.getElementById('mk-sell-price')).value, 10),
|
|
386
387
|
};
|
|
387
|
-
const condition = document.getElementById('mk-sell-condition').value;
|
|
388
|
+
const condition = /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-condition')).value;
|
|
388
389
|
if (condition) data.condition = condition;
|
|
389
|
-
const availability = document.getElementById('mk-sell-avail').value;
|
|
390
|
+
const availability = /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-avail')).value;
|
|
390
391
|
if (availability) data.availability = availability;
|
|
391
|
-
const city = document.getElementById('mk-sell-city').value;
|
|
392
|
-
const area = document.getElementById('mk-sell-area').value;
|
|
392
|
+
const city = /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-city')).value;
|
|
393
|
+
const area = /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-area')).value;
|
|
393
394
|
if (city || area) { data.location = {}; if (city) data.location.city = city; if (area) data.location.area = area; }
|
|
394
|
-
const tags = document.getElementById('mk-sell-tags').value;
|
|
395
|
+
const tags = /** @type {HTMLInputElement} */ (document.getElementById('mk-sell-tags')).value;
|
|
395
396
|
if (tags) data.tags = tags.split(',').map(s => s.trim()).filter(Boolean);
|
|
396
397
|
|
|
397
398
|
extAction('create-listing', data)
|
|
@@ -176,7 +176,7 @@ function OpenClawView() {
|
|
|
176
176
|
].map(([title, steps]) => html`
|
|
177
177
|
<div class="oc-scenario">
|
|
178
178
|
<h4>${title}</h4>
|
|
179
|
-
<div class="flow"><ol>${steps.map(s => html`<li>${s}</li>`)}</ol></div>
|
|
179
|
+
<div class="flow"><ol>${(/** @type {any[]} */ (steps)).map(s => html`<li>${s}</li>`)}</ol></div>
|
|
180
180
|
</div>
|
|
181
181
|
`)}
|
|
182
182
|
</div>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* v1.1.0 — 2026-06-02 — Component unification (#11): node-badge dot uses
|
|
8
8
|
* canonical <StatusDot status="online" /> instead of bespoke .dv-dot
|
|
9
9
|
* (which had a hardcoded #22c55e — now tokenized via the component).
|
|
10
|
+
* v1.1.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
10
11
|
*/
|
|
11
12
|
import { h } from 'preact';
|
|
12
13
|
import { useState, useEffect, useRef, useCallback } from 'preact/hooks';
|
|
@@ -23,7 +24,9 @@ const NODE_URL = window.location.origin;
|
|
|
23
24
|
/* ══════════════════════════════════════════════
|
|
24
25
|
i18n — use SPA i18n.js t() with 'dev.' prefix
|
|
25
26
|
══════════════════════════════════════════════ */
|
|
26
|
-
|
|
27
|
+
// `locale` is accepted for call-site symmetry but currently unused — t() resolves against
|
|
28
|
+
// the active global locale, not a per-call override.
|
|
29
|
+
function dt(key, _locale) {
|
|
27
30
|
return globalT('dev.' + key);
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -612,7 +615,7 @@ function CommunityApps({ locale, isLoggedIn, session }) {
|
|
|
612
615
|
style="background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:.25rem .4rem;color:var(--text);font-size:.8rem;width:120px" />
|
|
613
616
|
<a href="#" onClick=${e => {
|
|
614
617
|
e.preventDefault();
|
|
615
|
-
const code = document.getElementById(codeInputId)?.value?.trim();
|
|
618
|
+
const code = /** @type {HTMLInputElement} */ (document.getElementById(codeInputId))?.value?.trim();
|
|
616
619
|
if (!code) return;
|
|
617
620
|
window.open(NODE_URL + app.download_url + '?code=' + encodeURIComponent(code));
|
|
618
621
|
}} style="font-size:.85rem">\u2b07 ${dt('download', locale)}</a>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @version-history
|
|
6
6
|
* v1.1.0 — 2026-06-02 — Component unification (#11): live-feed header dot uses
|
|
7
7
|
* canonical <StatusDot status="live" /> instead of bespoke .live-dot.
|
|
8
|
+
* v1.1.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
8
9
|
*/
|
|
9
10
|
import { h } from 'preact';
|
|
10
11
|
import { useState, useEffect, useRef, useCallback } from 'preact/hooks';
|
|
@@ -1180,7 +1181,7 @@ function TheWorld({ navigate }) {
|
|
|
1180
1181
|
// Trigger login modal
|
|
1181
1182
|
const slot = document.getElementById('headerAuth');
|
|
1182
1183
|
const loginBtn = slot && slot.querySelector('#aimeat-login-btn');
|
|
1183
|
-
if (loginBtn) loginBtn.click();
|
|
1184
|
+
if (loginBtn) /** @type {HTMLElement} */ (loginBtn).click();
|
|
1184
1185
|
}, [navigate]);
|
|
1185
1186
|
|
|
1186
1187
|
return html`
|
|
@@ -1289,7 +1290,7 @@ export default function Portal({ navigate, locale }) {
|
|
|
1289
1290
|
// Trigger login via the header auth button
|
|
1290
1291
|
const loginBtn = document.querySelector('#headerAuth #aimeat-login-btn');
|
|
1291
1292
|
if (loginBtn) {
|
|
1292
|
-
loginBtn.click();
|
|
1293
|
+
/** @type {HTMLElement} */ (loginBtn).click();
|
|
1293
1294
|
// After login, the aimeat-auth-change event will fire and we re-check
|
|
1294
1295
|
const handler = () => {
|
|
1295
1296
|
const s = getCurrentSession();
|
|
@@ -33,10 +33,10 @@ const BUCKETS = [
|
|
|
33
33
|
|
|
34
34
|
export default function SharedBoard({ agents, onboardings, onAgentClick }) {
|
|
35
35
|
const [bucketFilter, setBucketFilter] = useState(null);
|
|
36
|
-
if (!agents || agents.length === 0) return null;
|
|
37
36
|
|
|
37
|
+
// Hooks must run unconditionally before any early return (Rules of Hooks).
|
|
38
38
|
const agentStates = useMemo(() => {
|
|
39
|
-
const rows = agents.map(agent => {
|
|
39
|
+
const rows = (agents || []).map(agent => {
|
|
40
40
|
const state = detectAgentState(agent, onboardings?.[agent.name]);
|
|
41
41
|
return { agent, state, bucket: BUCKET_OF[state] || 'quiet', onboarding: onboardings?.[agent.name] };
|
|
42
42
|
});
|
|
@@ -63,6 +63,8 @@ export default function SharedBoard({ agents, onboardings, onAgentClick }) {
|
|
|
63
63
|
return tagCounts;
|
|
64
64
|
}, [agentStates]);
|
|
65
65
|
|
|
66
|
+
if (!agents || agents.length === 0) return null;
|
|
67
|
+
|
|
66
68
|
return html`
|
|
67
69
|
<div class="pf-agd-board">
|
|
68
70
|
<div class="pf-agd-board-legend">
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* v1.2.0 -- 2026-05-24 -- Add command-reply visual pairing for slash commands
|
|
19
19
|
* v1.1.0 -- 2026-05-24 -- M7: visual distinction for command messages (slash prefix)
|
|
20
20
|
* v1.0.0 -- 2026-05-24 -- Initial creation for Agent Detail Tab-View
|
|
21
|
+
* v1.6.1 -- 2026-06-19 -- JSDoc type annotations for frontend type-checking
|
|
21
22
|
*/
|
|
22
23
|
|
|
23
24
|
import { h } from 'preact';
|
|
@@ -47,6 +48,17 @@ function threadLabel(thread) {
|
|
|
47
48
|
function CommandPalette({ commands, onSend }) {
|
|
48
49
|
const [expanded, setExpanded] = useState(false);
|
|
49
50
|
|
|
51
|
+
// Hooks must run unconditionally before any early return (Rules of Hooks).
|
|
52
|
+
const categories = useMemo(() => {
|
|
53
|
+
const cats = {};
|
|
54
|
+
for (const cmd of (commands || [])) {
|
|
55
|
+
const cat = cmd.category || t('profile.agents.detail.messages.commands.defaultCategory');
|
|
56
|
+
if (!cats[cat]) cats[cat] = [];
|
|
57
|
+
cats[cat].push(cmd);
|
|
58
|
+
}
|
|
59
|
+
return cats;
|
|
60
|
+
}, [commands]);
|
|
61
|
+
|
|
50
62
|
if (!commands || commands.length === 0) {
|
|
51
63
|
// No registered commands → one quiet line, not an expandable empty box.
|
|
52
64
|
return html`
|
|
@@ -57,16 +69,6 @@ function CommandPalette({ commands, onSend }) {
|
|
|
57
69
|
`;
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
const categories = useMemo(() => {
|
|
61
|
-
const cats = {};
|
|
62
|
-
for (const cmd of commands) {
|
|
63
|
-
const cat = cmd.category || t('profile.agents.detail.messages.commands.defaultCategory');
|
|
64
|
-
if (!cats[cat]) cats[cat] = [];
|
|
65
|
-
cats[cat].push(cmd);
|
|
66
|
-
}
|
|
67
|
-
return cats;
|
|
68
|
-
}, [commands]);
|
|
69
|
-
|
|
70
72
|
return html`
|
|
71
73
|
<div class="pf-agd-commands">
|
|
72
74
|
<div class="pf-agd-commands-header" onClick=${() => setExpanded(!expanded)}>
|
|
@@ -332,7 +334,7 @@ export default function TabMessages({ agent, agentName, session, showToast }) {
|
|
|
332
334
|
${messages.length > 0 && html`
|
|
333
335
|
<div class="pf-agd-msg-history" ref=${historyRef}>
|
|
334
336
|
${(() => {
|
|
335
|
-
const sorted = [...messages].sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
|
|
337
|
+
const sorted = [...messages].sort((a, b) => +new Date(a.createdAt || 0) - +new Date(b.createdAt || 0));
|
|
336
338
|
// An option-prompt is answerable only while it is the newest message
|
|
337
339
|
// in its thread (any later message locks it). Map each thread to its
|
|
338
340
|
// last message id, and each prompt_id to the owner's chosen text.
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* v1.2.0 -- 2026-05-22 -- Fix: use camelCase field names from API (createdAt, metadata.tokensUsed)
|
|
17
17
|
* v1.1.0 -- 2026-05-22 -- Show timestamp on messages, sort oldest-first (chat-style)
|
|
18
18
|
* v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 3
|
|
19
|
+
* v1.3.1 -- 2026-06-19 -- JSDoc type annotations for frontend type-checking
|
|
19
20
|
*/
|
|
20
21
|
import { h } from 'preact';
|
|
21
22
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -262,7 +263,7 @@ export default function AgentMessagesSubtab({ agentName, session, showToast }) {
|
|
|
262
263
|
const lastSeen = null; // TODO Phase 2+: derive from agent.last_seen
|
|
263
264
|
|
|
264
265
|
// Oldest-first (chat order).
|
|
265
|
-
const sorted = [...messages].sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
|
|
266
|
+
const sorted = [...messages].sort((a, b) => +new Date(a.createdAt || 0) - +new Date(b.createdAt || 0));
|
|
266
267
|
// Latest message id per thread -> an option-prompt is answerable only while it
|
|
267
268
|
// is the newest message in its thread (any later message locks it).
|
|
268
269
|
const lastIdByThread = {};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @version-history
|
|
5
5
|
* v1.1.0 — 2026-03-19 — Add launch button to My Apps list
|
|
6
6
|
* v1.0.0 — 2026-03-17 — Refactor: replace inline styles with CSS utility classes (card-h3, text-caption, etc.)
|
|
7
|
+
* v1.1.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
7
8
|
*/
|
|
8
9
|
import { h } from 'preact';
|
|
9
10
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -42,7 +43,7 @@ export default function AppsTab({ session, showToast, onStats }) {
|
|
|
42
43
|
|
|
43
44
|
async function handleUpload(file, screenshot, accessCode) {
|
|
44
45
|
if (!file) { showToast(t('profile.apps.selectFile'), true); return; }
|
|
45
|
-
const readFile = (f) => new Promise(res => { const r = new FileReader(); r.onload = () => res(r.result.split(',')[1]); r.readAsDataURL(f); });
|
|
46
|
+
const readFile = (f) => new Promise(res => { const r = new FileReader(); r.onload = () => res(/** @type {string} */ (r.result).split(',')[1]); r.readAsDataURL(f); });
|
|
46
47
|
const contentBase64 = await readFile(file);
|
|
47
48
|
const opts = {};
|
|
48
49
|
if (accessCode) opts.accessCode = accessCode;
|
|
@@ -34,6 +34,9 @@ export default function BoardsTab({ session, showToast }) {
|
|
|
34
34
|
const [boardView, setBoardView] = useState(null);
|
|
35
35
|
const [brdSubTab, setBrdSubTab] = useState('mine');
|
|
36
36
|
const [showBrdForm, setShowBrdForm] = useState(false);
|
|
37
|
+
// Refs used by the board-detail view below — declared unconditionally (Rules of Hooks).
|
|
38
|
+
const postRef = useRef(null);
|
|
39
|
+
const memberInputRef = useRef(null);
|
|
37
40
|
|
|
38
41
|
useEffect(() => {
|
|
39
42
|
if (session) loadMyData();
|
|
@@ -176,8 +179,6 @@ export default function BoardsTab({ session, showToast }) {
|
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
if (boardView) {
|
|
179
|
-
const postRef = useRef(null);
|
|
180
|
-
const memberInputRef = useRef(null);
|
|
181
182
|
const bd = boardView.boardData;
|
|
182
183
|
const showMembers = bd && bd.visibility === 'shared' && isBoardOwner(bd);
|
|
183
184
|
return html`
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - renderStep4 — Step 4 UI (Synthesis — grouped proposals + A/B/C options)
|
|
15
15
|
* @version-history
|
|
16
16
|
* v1.0.0 — 2026-03-29 — Initial V2 implementation
|
|
17
|
+
* v1.0.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
17
18
|
*/
|
|
18
19
|
import { h } from 'preact';
|
|
19
20
|
import { useState, useEffect, useCallback } from 'preact/hooks';
|
|
@@ -40,7 +41,7 @@ import { getBatch, updateBatch, createVersion } from '/js/services/calibrator.js
|
|
|
40
41
|
|
|
41
42
|
// ── Helpers ──
|
|
42
43
|
|
|
43
|
-
async function callModel(projectId, prompt, modelId, { retries = 1, temperature, top_p, max_tokens } = {}) {
|
|
44
|
+
async function callModel(projectId, prompt, modelId, { retries = 1, temperature, top_p, max_tokens } = /** @type {{ retries?: number, temperature?: number, top_p?: number, max_tokens?: number }} */ ({})) {
|
|
44
45
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
45
46
|
const controller = new AbortController();
|
|
46
47
|
const timeoutId = setTimeout(() => controller.abort(), 1_800_000); // 30 min
|
|
@@ -436,7 +437,7 @@ export default function BatchCard({ batchSummary, index, projectId, project, cur
|
|
|
436
437
|
const { getVersion } = await import('/js/services/calibrator.js');
|
|
437
438
|
const ver = await getVersion(projectId, batchVersion);
|
|
438
439
|
if (ver?.prompt) batchPrompt = ver.prompt;
|
|
439
|
-
} catch {}
|
|
440
|
+
} catch { /* best effort — fall through to the no-prompt guard below */ }
|
|
440
441
|
}
|
|
441
442
|
if (!batchPrompt) { showToast?.('Could not load prompt for this batch\'s version', true); return; }
|
|
442
443
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* @version-history
|
|
11
11
|
* v1.0.0 — 2026-03-10 — Initial data wallet tab implementation
|
|
12
12
|
* v1.1.0 — 2026-03-17 — Refactor: replace all inline styles with CSS classes
|
|
13
|
+
* v1.1.1 — 2026-06-19 — lint fixes (misleading-char-class/unused-expression/empty-block)
|
|
13
14
|
*/
|
|
14
15
|
import { h } from 'preact';
|
|
15
16
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -279,7 +280,7 @@ export default function DataWalletTab({ session, showToast }) {
|
|
|
279
280
|
<td><input type="checkbox" checked=${selectedConsents.has(cId)}
|
|
280
281
|
onChange=${(e) => {
|
|
281
282
|
const next = new Set(selectedConsents);
|
|
282
|
-
e.target.checked
|
|
283
|
+
if (e.target.checked) next.add(cId); else next.delete(cId);
|
|
283
284
|
setSelectedConsents(next);
|
|
284
285
|
}} /></td>
|
|
285
286
|
<td><span class="dw-code-accent">${escHtml(c.data_pattern || c.pattern || '-')}</span></td>
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* v1.4.0 — 2026-06-02 — Component unification (#11): all six extension/instance
|
|
24
24
|
* status dots use the canonical <StatusDot> instead of bespoke .ext-status-dot
|
|
25
25
|
* (which had hardcoded #4ade80/#9ca3af — now tokenized via the component).
|
|
26
|
+
* v1.4.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
26
27
|
*/
|
|
27
28
|
import { h } from 'preact';
|
|
28
29
|
import { useState, useEffect } from 'preact/hooks';
|
|
@@ -577,18 +578,18 @@ export default function ExtensionsTab({ session, showToast }) {
|
|
|
577
578
|
try {
|
|
578
579
|
let manifest = '';
|
|
579
580
|
if (manifestMode === 'upload') {
|
|
580
|
-
const fileInput = document.getElementById('ext-manifest-file');
|
|
581
|
+
const fileInput = /** @type {HTMLInputElement} */ (document.getElementById('ext-manifest-file'));
|
|
581
582
|
if (!fileInput?.files[0]) throw new Error('No manifest file selected');
|
|
582
583
|
manifest = await fileInput.files[0].text();
|
|
583
584
|
} else {
|
|
584
|
-
const textarea = document.getElementById('ext-manifest-text');
|
|
585
|
+
const textarea = /** @type {HTMLInputElement} */ (document.getElementById('ext-manifest-text'));
|
|
585
586
|
manifest = textarea?.value || '';
|
|
586
587
|
if (!manifest.trim()) throw new Error('Manifest is empty');
|
|
587
588
|
}
|
|
588
589
|
|
|
589
590
|
const libs = {};
|
|
590
591
|
if (libMode === 'upload') {
|
|
591
|
-
const libInput = document.getElementById('ext-lib-files');
|
|
592
|
+
const libInput = /** @type {HTMLInputElement} */ (document.getElementById('ext-lib-files'));
|
|
592
593
|
if (libInput?.files) {
|
|
593
594
|
for (const f of libInput.files) {
|
|
594
595
|
libs[f.name] = await f.text();
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* v1.1.0 — 2026-03-17 — Replace inline styles with CSS classes
|
|
7
7
|
* v1.2.0 — 2026-06-02 — Component unification (#11): peer online/offline dot
|
|
8
8
|
* uses canonical <StatusDot> (alive/dead) instead of bespoke .peer-dot.
|
|
9
|
+
* v1.3.0 — 2026-06-19 — Show peer tier (visiting/member/genesis) + availability
|
|
10
|
+
* (temporary/permanent) pills next to the status (visiting-node feature).
|
|
9
11
|
*/
|
|
10
12
|
import { h } from 'preact';
|
|
11
13
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -56,6 +58,8 @@ export default function FederationTab({ session, showToast }) {
|
|
|
56
58
|
<div class="card-subtitle">${escHtml(p.url || '')}</div>
|
|
57
59
|
</div>
|
|
58
60
|
<div class="peer-status">
|
|
61
|
+
<span class="badge ${(p.tier || 'member') === 'visiting' ? 'badge-info' : (p.tier || 'member') === 'genesis' ? 'badge-info' : 'badge-success'}">${t('profile.federation.tier_' + (p.tier || 'member')) || (p.tier || 'member')}</span>
|
|
62
|
+
${p.availability && p.availability !== 'unknown' ? html`<span class="badge ${p.availability === 'permanent' ? 'badge-success' : 'badge-info'}">${t('profile.federation.avail_' + p.availability) || p.availability}</span>` : null}
|
|
59
63
|
<${StatusDot} status=${alive ? 'alive' : 'dead'} />
|
|
60
64
|
<span class="fed-status-text ${alive ? 'online' : 'offline'}">${alive ? t('profile.federation.online') : t('profile.federation.offline')}</span>
|
|
61
65
|
</div>
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* @version-history
|
|
28
28
|
* v1.0.0 — 2026-03-22 — Extracted from foundry-tab.js ProjectDashboard
|
|
29
29
|
* v2.0.0 — 2026-03-26 — Wire multi-pass flow: runComponentPasses for extension/cortex/app
|
|
30
|
+
* v2.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
30
31
|
*/
|
|
31
32
|
import { t } from '/js/i18n.js';
|
|
32
33
|
import { apiPost, apiDelete } from '/js/api.js';
|
|
@@ -206,7 +207,7 @@ export function useAutopilot(core, autopilotState, projectId, orSettings, sessio
|
|
|
206
207
|
* @param {string} cid - Component ID
|
|
207
208
|
* @param {Object} project - Project object (with blueprint)
|
|
208
209
|
* @param {Object} interviewSpec - Interview spec
|
|
209
|
-
* @returns {{ success: boolean, content: string|null, updated: Object }} - Final result
|
|
210
|
+
* @returns {Promise<{ success: boolean, content: string|null, updated: Object }>} - Final result
|
|
210
211
|
*/
|
|
211
212
|
async function runComponentPasses(comp, cid, project, interviewSpec) {
|
|
212
213
|
const blueprint = project.blueprint;
|
|
@@ -734,7 +735,7 @@ export function useAutopilot(core, autopilotState, projectId, orSettings, sessio
|
|
|
734
735
|
await writeProjectLog(projectId, 'extension_probe_start', { meta: { component: comp.label, extensionName: updated.registeredAs, scenarios: probeScenarios.length, by: 'autopilot' } });
|
|
735
736
|
|
|
736
737
|
const probeResp = await probeExtension(projectId, updated.registeredAs, probeScenarios);
|
|
737
|
-
const probeResults = probeResp?.data?.results || [];
|
|
738
|
+
const probeResults = /** @type {any} */ (probeResp)?.data?.results || [];
|
|
738
739
|
|
|
739
740
|
// Save probe results + context bundle — downstream prompts will inject these
|
|
740
741
|
const contextBundle = createBundle(updated, probeResults);
|
|
@@ -131,7 +131,7 @@ export function getWorkflowStep(component, validationResult, result) {
|
|
|
131
131
|
|
|
132
132
|
/** Small circle-with-arrow SVG placed inline next to the current action target.
|
|
133
133
|
* @param {Object} props
|
|
134
|
-
* @param {'right'|'down'} [props.direction='right']
|
|
134
|
+
* @param {'right'|'down'} [props.direction='right'] - arrow direction
|
|
135
135
|
*/
|
|
136
136
|
function StepArrow({ direction = 'right' } = {}) {
|
|
137
137
|
const chevron = direction === 'down'
|
|
@@ -162,7 +162,7 @@ export function getWorkflowStep(component, validationResult, result) {
|
|
|
162
162
|
|
|
163
163
|
/** Small circle-with-arrow SVG placed inline next to the current action target.
|
|
164
164
|
* @param {Object} props
|
|
165
|
-
* @param {'right'|'down'} [props.direction='right']
|
|
165
|
+
* @param {'right'|'down'} [props.direction='right'] - arrow direction
|
|
166
166
|
*/
|
|
167
167
|
function StepArrow({ direction = 'right' } = {}) {
|
|
168
168
|
const chevron = direction === 'down'
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
* @structure InboxTab (default) · Composer (Toast UI) · MessageBubble · Avatar · helpers
|
|
12
12
|
* @usage Lazy-loaded profile tab; registered in profile.js TABS as id `messages`.
|
|
13
13
|
* @version-history
|
|
14
|
+
* v1.3.0 -- 2026-06-19 -- Show a presence dot next to peers (request rows, conversation list,
|
|
15
|
+
* thread header) via the shared <PresenceDot>.
|
|
14
16
|
* v1.2.0 -- 2026-06-16 -- Composer upgraded to the shared Toast UI editor (parity with the
|
|
15
17
|
* workspace document editor) + markdown-preview fallback.
|
|
16
18
|
* v1.1.0 -- 2026-06-16 -- Redesigned as a proper messenger (avatars, bubbles, ticks, dividers).
|
|
17
19
|
* v1.0.0 -- 2026-06-16 -- Initial creation for user-to-user messaging (layer 5).
|
|
20
|
+
* v1.3.1 -- 2026-06-19 -- JSDoc type annotations for frontend type-checking
|
|
18
21
|
*/
|
|
19
22
|
import { h } from 'preact';
|
|
20
23
|
import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
|
|
@@ -24,6 +27,7 @@ import { t, getLocale } from '/js/i18n.js';
|
|
|
24
27
|
import { escHtml } from '/js/utils.js';
|
|
25
28
|
import { Markdown } from '/components/Markdown.js';
|
|
26
29
|
import { minidenticon } from '/lib/minidenticons.min.js';
|
|
30
|
+
import { PresenceDot } from '/components/PresenceDot.js';
|
|
27
31
|
import * as messages from '/js/services/messages.js';
|
|
28
32
|
|
|
29
33
|
/* Lazy-load the vendored Toast UI Editor (MIT, /lib/toastui/) — the same editor the workspace
|
|
@@ -313,7 +317,7 @@ export default function InboxTab({ showToast }) {
|
|
|
313
317
|
<div class="inbox-request-top">
|
|
314
318
|
<${Avatar} seed=${r.contactId} size=${36} />
|
|
315
319
|
<div class="inbox-request-id">
|
|
316
|
-
<div class="inbox-name">${escHtml(peerName(r.contactId))}
|
|
320
|
+
<div class="inbox-name">${escHtml(peerName(r.contactId))} <${PresenceDot} ghii=${r.contactId} /></div>
|
|
317
321
|
<div class="inbox-sub">${escHtml(r.contactId)}</div>
|
|
318
322
|
</div>
|
|
319
323
|
</div>
|
|
@@ -332,7 +336,7 @@ export default function InboxTab({ showToast }) {
|
|
|
332
336
|
<${Avatar} seed=${c.peerGhii} size=${40} />
|
|
333
337
|
<div class="inbox-conv-main">
|
|
334
338
|
<div class="inbox-conv-line1">
|
|
335
|
-
<span class="inbox-name">${escHtml(peerName(c.peerGhii))}
|
|
339
|
+
<span class="inbox-name">${escHtml(peerName(c.peerGhii))} <${PresenceDot} ghii=${c.peerGhii} /></span>
|
|
336
340
|
<span class="inbox-conv-time">${c.updatedAt ? timeShort(c.updatedAt) : ''}</span>
|
|
337
341
|
</div>
|
|
338
342
|
<div class="inbox-conv-line2">
|
|
@@ -350,7 +354,7 @@ export default function InboxTab({ showToast }) {
|
|
|
350
354
|
<div class="inbox-thread-head">
|
|
351
355
|
<${Avatar} seed=${activeConv.peerGhii} size=${36} />
|
|
352
356
|
<div class="inbox-thread-id">
|
|
353
|
-
<div class="inbox-name">${escHtml(peerName(activeConv.peerGhii))}
|
|
357
|
+
<div class="inbox-name">${escHtml(peerName(activeConv.peerGhii))} <${PresenceDot} ghii=${activeConv.peerGhii} label=${true} /></div>
|
|
354
358
|
<div class="inbox-sub">${escHtml(activeConv.peerGhii)}</div>
|
|
355
359
|
</div>
|
|
356
360
|
</div>
|
|
@@ -35,8 +35,8 @@ const PANELS = {
|
|
|
35
35
|
|
|
36
36
|
export function InlinePanel({ panelId, onClose, switchTab, session }) {
|
|
37
37
|
const cfg = PANELS[panelId];
|
|
38
|
-
if (!cfg) return null;
|
|
39
38
|
|
|
39
|
+
// Hooks must run unconditionally before any early return (Rules of Hooks).
|
|
40
40
|
const panelRef = useRef(null);
|
|
41
41
|
|
|
42
42
|
/* Smooth scroll into view after opening */
|
|
@@ -48,6 +48,8 @@ export function InlinePanel({ panelId, onClose, switchTab, session }) {
|
|
|
48
48
|
}
|
|
49
49
|
}, [panelId]);
|
|
50
50
|
|
|
51
|
+
if (!cfg) return null;
|
|
52
|
+
|
|
51
53
|
return html`
|
|
52
54
|
<div class="pf-inline-panel open" ref=${panelRef}>
|
|
53
55
|
<div class="pf-inline-panel-header">
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* pf-sharing-box, pf-sharing-heading, kpkg-detail-loading). Replace inline
|
|
19
19
|
* visibility pill with shared VisibilityPill component. Replace hardcoded English
|
|
20
20
|
* strings with i18n t() calls.
|
|
21
|
+
* v1.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
21
22
|
*/
|
|
22
23
|
import { h } from 'preact';
|
|
23
24
|
import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
|
|
@@ -393,7 +394,7 @@ export default function KnowledgeTab({ session, showToast, onStats }) {
|
|
|
393
394
|
if (!el) {
|
|
394
395
|
const all = document.querySelectorAll('[data-entry-key]');
|
|
395
396
|
for (const candidate of all) {
|
|
396
|
-
if (candidate.dataset.entryKey.endsWith('/' + entryKey)) { el = candidate; break; }
|
|
397
|
+
if (/** @type {HTMLElement} */ (candidate).dataset.entryKey.endsWith('/' + entryKey)) { el = candidate; break; }
|
|
397
398
|
}
|
|
398
399
|
}
|
|
399
400
|
if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); el.classList.add('kpkg-entry-highlight'); setTimeout(() => el.classList.remove('kpkg-entry-highlight'), 1500); }
|