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
package/README.md
CHANGED
|
@@ -389,7 +389,14 @@ prerequisites** to install. A small control panel starts/stops the node, shows s
|
|
|
389
389
|
it (port, federation role), connects a local AI (Ollama / LM Studio) to your account, and opens the web
|
|
390
390
|
dashboard in your browser. Your data lives in your own app-data folder and survives restarts.
|
|
391
391
|
|
|
392
|
-
**Download:** get the latest installer from the [GitHub Releases page](https://github.com/miikkij/aimeat-protocol/releases/latest).
|
|
392
|
+
**Download:** get the latest installer from the [GitHub Releases page](https://github.com/miikkij/aimeat-protocol/releases/latest).
|
|
393
|
+
|
|
394
|
+
> **Windows SmartScreen note.** The installer is not yet code-signed, so Windows may show a blue
|
|
395
|
+
> *"Windows protected your PC"* SmartScreen prompt the first time you run it. This is expected for
|
|
396
|
+
> new independent software and does **not** mean anything is wrong with the download. To continue,
|
|
397
|
+
> click **More info → Run anyway**. If you'd like to verify the file first, every release lists the
|
|
398
|
+
> binaries on its [Releases page](https://github.com/miikkij/aimeat-protocol/releases/latest) — you
|
|
399
|
+
> can also build it yourself from source (below). A signed installer is on our roadmap.
|
|
393
400
|
|
|
394
401
|
<p align="center">
|
|
395
402
|
<img src="assets/screenshots/aimeat-desktop.png" alt="AIMEAT Personal Node desktop app — control panel with Getting Started steps, node status (running on port 40050), and node info" width="640" />
|
package/dist/locales/en.json
CHANGED
|
@@ -18,6 +18,20 @@
|
|
|
18
18
|
"inbox.empty": "Nothing here yet.",
|
|
19
19
|
"inbox.attachmentPending": "attachment pending",
|
|
20
20
|
"inbox.attachmentExpired": "attachment expired",
|
|
21
|
+
"admin.messages.title": "Direct messages",
|
|
22
|
+
"admin.messages.desc": "Delivery telemetry for user-to-user messages. No message content or participant identities are shown.",
|
|
23
|
+
"admin.messages.total": "Total sent",
|
|
24
|
+
"admin.messages.last24h": "in 24h",
|
|
25
|
+
"admin.messages.targetNodes": "Top target nodes",
|
|
26
|
+
"admin.messages.node": "Node",
|
|
27
|
+
"admin.messages.totalCol": "Total",
|
|
28
|
+
"admin.messages.failedCol": "Failed",
|
|
29
|
+
"admin.messages.recent": "Recent attempts",
|
|
30
|
+
"admin.messages.when": "When",
|
|
31
|
+
"admin.messages.origin": "Origin",
|
|
32
|
+
"admin.messages.statusCol": "Status",
|
|
33
|
+
"admin.messages.detail": "Detail",
|
|
34
|
+
"admin.messages.none": "No deliveries yet.",
|
|
21
35
|
"inbox.attach": "Attach a file",
|
|
22
36
|
"inbox.today": "Today",
|
|
23
37
|
"inbox.yesterday": "Yesterday",
|
|
@@ -36,6 +50,62 @@
|
|
|
36
50
|
"imageDeliverable.open": "Open full image",
|
|
37
51
|
"profile.landing.home": "Home",
|
|
38
52
|
"profile.landing.menu": "Menu",
|
|
53
|
+
"profile.tabs.notebook": "Notebook",
|
|
54
|
+
"profile.notebook.title": "Notebook",
|
|
55
|
+
"profile.notebook.desc": "Write anything freely — capture it now, find it later. The librarian searches across everything you have: every organism you have contributed to, plus your personal notes.",
|
|
56
|
+
"profile.notebook.capturePlaceholder": "Write anything — a thought, an idea, a note to keep…",
|
|
57
|
+
"profile.notebook.captureBtn": "Capture",
|
|
58
|
+
"profile.notebook.captureHint": "Saved to your notebook inbox. Sorting into organisms/workspaces comes next.",
|
|
59
|
+
"profile.notebook.saved": "Captured",
|
|
60
|
+
"profile.notebook.saveFailed": "Could not capture",
|
|
61
|
+
"profile.notebook.inboxTitle": "Inbox",
|
|
62
|
+
"profile.notebook.inboxEmpty": "Nothing captured yet — write something above.",
|
|
63
|
+
"profile.notebook.inboxLoading": "Loading…",
|
|
64
|
+
"profile.notebook.deleteBtn": "Delete",
|
|
65
|
+
"profile.notebook.deleteConfirm": "Delete this note?",
|
|
66
|
+
"profile.notebook.deleted": "Deleted",
|
|
67
|
+
"profile.notebook.librarianTitle": "Librarian",
|
|
68
|
+
"profile.notebook.librarianDesc": "Ask for anything you have — it searches every organism and note, ranked.",
|
|
69
|
+
"profile.notebook.searchPlaceholder": "What are you looking for?",
|
|
70
|
+
"profile.notebook.searchBtn": "Search",
|
|
71
|
+
"profile.notebook.searching": "Searching…",
|
|
72
|
+
"profile.notebook.noHits": "No matches.",
|
|
73
|
+
"profile.notebook.hitsCount": "{n} results",
|
|
74
|
+
"profile.notebook.personalNote": "Personal",
|
|
75
|
+
"profile.notebook.openInMemory": "Open",
|
|
76
|
+
"profile.notebook.suggestBtn": "Suggest placement",
|
|
77
|
+
"profile.notebook.sorting": "Sorting…",
|
|
78
|
+
"profile.notebook.fieldOrganism": "Organism",
|
|
79
|
+
"profile.notebook.fieldWorkspace": "Workspace",
|
|
80
|
+
"profile.notebook.fieldSpace": "Document space",
|
|
81
|
+
"profile.notebook.fieldTitle": "Title",
|
|
82
|
+
"profile.notebook.fieldBody": "Document",
|
|
83
|
+
"profile.notebook.newOrganism": "New organism",
|
|
84
|
+
"profile.notebook.newWorkspace": "New workspace",
|
|
85
|
+
"profile.notebook.newOrgNamePlaceholder": "New organism name",
|
|
86
|
+
"profile.notebook.newWsNamePlaceholder": "New workspace name",
|
|
87
|
+
"profile.notebook.alternatives": "Alternatives:",
|
|
88
|
+
"profile.notebook.materializeBtn": "Save as document",
|
|
89
|
+
"profile.notebook.cancelBtn": "Cancel",
|
|
90
|
+
"profile.notebook.materialized": "Filed as a document",
|
|
91
|
+
"profile.notebook.titleRequired": "A title is required",
|
|
92
|
+
"profile.notebook.orgNameRequired": "Name the new organism",
|
|
93
|
+
"profile.notebook.step1": "Reading your organism structure…",
|
|
94
|
+
"profile.notebook.step2": "Asking the AI for the best placement — this can take up to a couple of minutes with a slow model…",
|
|
95
|
+
"profile.notebook.step3": "Preparing the suggestion…",
|
|
96
|
+
"profile.notebook.sortErrorTitle": "Sorting failed",
|
|
97
|
+
"profile.notebook.needKey": "AI sorting needs your own OpenRouter API key. Add it here, then try again:",
|
|
98
|
+
"profile.notebook.filterPlaceholder": "Filter notes…",
|
|
99
|
+
"profile.notebook.sortNew": "Newest first",
|
|
100
|
+
"profile.notebook.sortOld": "Oldest first",
|
|
101
|
+
"profile.notebook.toggleView": "Collapse / expand",
|
|
102
|
+
"profile.notebook.noMatch": "No notes match the filter.",
|
|
103
|
+
"profile.notebook.scopeOwn": "Mine",
|
|
104
|
+
"profile.notebook.scopePublic": "Public knowledge",
|
|
105
|
+
"profile.notebook.kindKnowledge": "knowledge",
|
|
106
|
+
"profile.notebook.producer": "Producer",
|
|
107
|
+
"profile.notebook.tryAgain": "Try again",
|
|
108
|
+
"profile.notebook.dismiss": "Dismiss",
|
|
39
109
|
"profile.tabs.workflows": "Workflows",
|
|
40
110
|
"profile.workflows.title": "Workflows",
|
|
41
111
|
"profile.workflows.desc": "Declared, ordered agent pipelines with per-step health checks — they show whether each step actually produced, not just that it fired.",
|
|
@@ -392,6 +462,33 @@
|
|
|
392
462
|
"workaroundNote": "Copy your memories and paste directly into any AI chat. Always works, everywhere."
|
|
393
463
|
},
|
|
394
464
|
"comingSoon": "Coming soon",
|
|
465
|
+
"presence": {
|
|
466
|
+
"status": {
|
|
467
|
+
"available": "Available",
|
|
468
|
+
"busy": "Busy",
|
|
469
|
+
"away": "Away",
|
|
470
|
+
"offline": "Offline",
|
|
471
|
+
"invisible": "Invisible",
|
|
472
|
+
"unknown": "Unknown"
|
|
473
|
+
},
|
|
474
|
+
"control": {
|
|
475
|
+
"title": "Presence",
|
|
476
|
+
"desc": "Let others see whether you're reachable. Keep it automatic, set it manually, or choose who can see it.",
|
|
477
|
+
"modeLabel": "How your status is set",
|
|
478
|
+
"modeAuto": "Automatic",
|
|
479
|
+
"modeAutoHint": "Shown as available while you have the portal open.",
|
|
480
|
+
"modeManual": "Manual",
|
|
481
|
+
"statusLabel": "Your status",
|
|
482
|
+
"visibilityLabel": "Who can see it",
|
|
483
|
+
"visEveryone": "Everyone",
|
|
484
|
+
"visEveryoneHint": "Anyone on the network (shared with federated nodes).",
|
|
485
|
+
"visContacts": "Contacts only",
|
|
486
|
+
"visContactsHint": "People you've messaged (this node only).",
|
|
487
|
+
"visNobody": "Nobody",
|
|
488
|
+
"saved": "Presence updated",
|
|
489
|
+
"saveError": "Couldn't update presence"
|
|
490
|
+
}
|
|
491
|
+
},
|
|
395
492
|
"profile": {
|
|
396
493
|
"title": "My Profile",
|
|
397
494
|
"subtitle": "Profile",
|
|
@@ -1952,6 +2049,11 @@
|
|
|
1952
2049
|
"peers": "Connected Peers",
|
|
1953
2050
|
"online": "Online",
|
|
1954
2051
|
"offline": "Offline",
|
|
2052
|
+
"tier_visiting": "Visiting",
|
|
2053
|
+
"tier_member": "Member",
|
|
2054
|
+
"tier_genesis": "Genesis",
|
|
2055
|
+
"avail_temporary": "Temporary",
|
|
2056
|
+
"avail_permanent": "Permanent",
|
|
1955
2057
|
"statusConnected": "Connected to {count} nodes",
|
|
1956
2058
|
"statusStandalone": "Standalone"
|
|
1957
2059
|
},
|
|
@@ -4128,6 +4230,17 @@
|
|
|
4128
4230
|
"portal": "Portal",
|
|
4129
4231
|
"portalDesc": "Manage your node's public portal — the landing page visitors see. Customize the HTML template, set dynamic content via memory keys and KV pairs, preview changes live, and generate an AI-friendly prompt summary of your portal for chat integrations.",
|
|
4130
4232
|
"portalTemplate": "Template Editor",
|
|
4233
|
+
"portalNavTitle": "Header Navigation",
|
|
4234
|
+
"portalNavExplain": "Choose which public links appear in the site header and in what order. Auth-only links (Apps, Profile, Admin) always follow their sign-in/role rules and aren't listed here.",
|
|
4235
|
+
"portalNavLink": "Link",
|
|
4236
|
+
"portalNavVisible": "Visible",
|
|
4237
|
+
"portalNavOrder": "Order",
|
|
4238
|
+
"portalNavShown": "Shown",
|
|
4239
|
+
"portalNavHidden": "Hidden",
|
|
4240
|
+
"portalNavMoveUp": "Move up",
|
|
4241
|
+
"portalNavMoveDown": "Move down",
|
|
4242
|
+
"portalNavSave": "Save Navigation",
|
|
4243
|
+
"portalNavSaved": "Header navigation saved",
|
|
4131
4244
|
"portalPreview": "Portal Preview",
|
|
4132
4245
|
"portalMemoryKeys": "Portal Memory Keys",
|
|
4133
4246
|
"portalKvPairs": "KV Pairs (Environment)",
|
|
@@ -4583,6 +4696,37 @@
|
|
|
4583
4696
|
"fedPeerApproved": "Peering request approved successfully",
|
|
4584
4697
|
"fedPeerRejected": "Peering request rejected",
|
|
4585
4698
|
"fedLivePeersTitle": "Live Peers",
|
|
4699
|
+
"fedTierLabel": "Tier",
|
|
4700
|
+
"fedVersionLabel": "Version",
|
|
4701
|
+
"fedBehind": "behind",
|
|
4702
|
+
"fedBookTitle": "Federation Book",
|
|
4703
|
+
"fedBookDesc": "Directory of the federation: each node's operators, offered resources, version and settings. The primary (genesis) maintains it; other nodes mirror it.",
|
|
4704
|
+
"fedBookRebuild": "Rebuild",
|
|
4705
|
+
"fedBookPull": "Mirror from genesis",
|
|
4706
|
+
"fedBookRebuilt": "Federation book rebuilt",
|
|
4707
|
+
"fedBookPulled": "Federation book mirrored",
|
|
4708
|
+
"fedBookUpToDate": "Already up to date",
|
|
4709
|
+
"fedBookEmpty": "The federation book is empty. The primary node builds it from its peers; mirrors pull it from the genesis.",
|
|
4710
|
+
"fedBookOperators": "Operators",
|
|
4711
|
+
"fedBookResources": "Resources",
|
|
4712
|
+
"fedBookSettings": "Settings",
|
|
4713
|
+
"fedBookOpenJoin": "open join",
|
|
4714
|
+
"fedBookCrossFed": "cross-fed",
|
|
4715
|
+
"fedBookVersion": "Book version",
|
|
4716
|
+
"fedTier_visiting": "Visiting",
|
|
4717
|
+
"fedTier_member": "Member",
|
|
4718
|
+
"fedTier_genesis": "Genesis",
|
|
4719
|
+
"fedAvail_temporary": "Temporary",
|
|
4720
|
+
"fedAvail_permanent": "Permanent",
|
|
4721
|
+
"fedOpenJoinLabel": "Open join",
|
|
4722
|
+
"fedOpenJoinDesc": "Let any node self-join as a low-trust visiting peer (browse + request work) without manual approval. Promote good ones to full members later.",
|
|
4723
|
+
"fedOpenJoinUpdated": "Open-join setting saved",
|
|
4724
|
+
"fedPromote": "Promote",
|
|
4725
|
+
"fedPromoteHint": "Promote this visiting node to a full member (grants provider, relay and replication rights).",
|
|
4726
|
+
"fedPromoteConfirm": "Promote this visiting node to a full member? This vouches for it and grants full federation rights.",
|
|
4727
|
+
"fedPromoteNotEligible": "Not yet eligible",
|
|
4728
|
+
"fedPromoteForceConfirm": "This node does not yet meet the promotion criteria. Promote anyway (your vouch)?",
|
|
4729
|
+
"fedPromoted": "Peer promoted to member",
|
|
4586
4730
|
"fedLivePeersExplain": "Currently registered peers and their real-time health status. The heartbeat monitor pings each peer every 5 minutes.",
|
|
4587
4731
|
"fedLivePeersHelpTitle": "Understanding peer statuses",
|
|
4588
4732
|
"fedLivePeersHelpDetail": "Active: Peer is healthy and responding to heartbeats. Approved: Peer has been approved but not yet activated (needs activation). Degraded: Peer has failed 3+ consecutive heartbeats but is still reachable. Offline: Peer has failed 10+ consecutive heartbeats. Depeering: Peer is in the grace period before removal (default 72h) — in-flight work can still complete.",
|
package/dist/locales/fi.json
CHANGED
|
@@ -18,6 +18,20 @@
|
|
|
18
18
|
"inbox.empty": "Ei mitään vielä.",
|
|
19
19
|
"inbox.attachmentPending": "liite odottaa",
|
|
20
20
|
"inbox.attachmentExpired": "liite vanhentui",
|
|
21
|
+
"admin.messages.title": "Suorat viestit",
|
|
22
|
+
"admin.messages.desc": "Toimitustelemetria käyttäjien välisille viesteille. Viestien sisältöä tai osapuolten henkilöllisyyttä ei näytetä.",
|
|
23
|
+
"admin.messages.total": "Lähetetty yhteensä",
|
|
24
|
+
"admin.messages.last24h": "24 h aikana",
|
|
25
|
+
"admin.messages.targetNodes": "Yleisimmät kohdesolmut",
|
|
26
|
+
"admin.messages.node": "Solmu",
|
|
27
|
+
"admin.messages.totalCol": "Yhteensä",
|
|
28
|
+
"admin.messages.failedCol": "Epäonnistui",
|
|
29
|
+
"admin.messages.recent": "Viimeisimmät yritykset",
|
|
30
|
+
"admin.messages.when": "Milloin",
|
|
31
|
+
"admin.messages.origin": "Alkuperä",
|
|
32
|
+
"admin.messages.statusCol": "Tila",
|
|
33
|
+
"admin.messages.detail": "Lisätieto",
|
|
34
|
+
"admin.messages.none": "Ei toimituksia vielä.",
|
|
21
35
|
"inbox.attach": "Liitä tiedosto",
|
|
22
36
|
"inbox.today": "Tänään",
|
|
23
37
|
"inbox.yesterday": "Eilen",
|
|
@@ -36,6 +50,62 @@
|
|
|
36
50
|
"imageDeliverable.open": "Avaa koko kuva",
|
|
37
51
|
"profile.landing.home": "Etusivu",
|
|
38
52
|
"profile.landing.menu": "Valikko",
|
|
53
|
+
"profile.tabs.notebook": "Muistikirja",
|
|
54
|
+
"profile.notebook.title": "Muistikirja",
|
|
55
|
+
"profile.notebook.desc": "Kirjoita vapaasti mitä vain — talteen heti, löydä myöhemmin. Kirjastonhoitaja hakee kaikesta mitä sinulla on: jokaisesta organismista johon olet tuottanut sisältöä, sekä henkilökohtaisista muistiinpanoistasi.",
|
|
56
|
+
"profile.notebook.capturePlaceholder": "Kirjoita mitä vain — ajatus, idea, muistiinpano talteen…",
|
|
57
|
+
"profile.notebook.captureBtn": "Tallenna",
|
|
58
|
+
"profile.notebook.captureHint": "Tallennettu muistikirjan inboxiin. Lajittelu organismeihin/workspaceihin tulee seuraavaksi.",
|
|
59
|
+
"profile.notebook.saved": "Tallennettu",
|
|
60
|
+
"profile.notebook.saveFailed": "Tallennus epäonnistui",
|
|
61
|
+
"profile.notebook.inboxTitle": "Inbox",
|
|
62
|
+
"profile.notebook.inboxEmpty": "Ei vielä mitään — kirjoita jotain yllä.",
|
|
63
|
+
"profile.notebook.inboxLoading": "Ladataan…",
|
|
64
|
+
"profile.notebook.deleteBtn": "Poista",
|
|
65
|
+
"profile.notebook.deleteConfirm": "Poistetaanko tämä muistiinpano?",
|
|
66
|
+
"profile.notebook.deleted": "Poistettu",
|
|
67
|
+
"profile.notebook.librarianTitle": "Kirjastonhoitaja",
|
|
68
|
+
"profile.notebook.librarianDesc": "Pyydä mitä vain mitä sinulla on — hakee kaikista organismeista ja muistiinpanoista, rankattuna.",
|
|
69
|
+
"profile.notebook.searchPlaceholder": "Mitä etsit?",
|
|
70
|
+
"profile.notebook.searchBtn": "Hae",
|
|
71
|
+
"profile.notebook.searching": "Haetaan…",
|
|
72
|
+
"profile.notebook.noHits": "Ei osumia.",
|
|
73
|
+
"profile.notebook.hitsCount": "{n} osumaa",
|
|
74
|
+
"profile.notebook.personalNote": "Henkilökohtainen",
|
|
75
|
+
"profile.notebook.openInMemory": "Avaa",
|
|
76
|
+
"profile.notebook.suggestBtn": "Ehdota sijoitus",
|
|
77
|
+
"profile.notebook.sorting": "Lajitellaan…",
|
|
78
|
+
"profile.notebook.fieldOrganism": "Organismi",
|
|
79
|
+
"profile.notebook.fieldWorkspace": "Workspace",
|
|
80
|
+
"profile.notebook.fieldSpace": "Dokumenttitila",
|
|
81
|
+
"profile.notebook.fieldTitle": "Otsikko",
|
|
82
|
+
"profile.notebook.fieldBody": "Sisältö",
|
|
83
|
+
"profile.notebook.newOrganism": "Uusi organismi",
|
|
84
|
+
"profile.notebook.newWorkspace": "Uusi workspace",
|
|
85
|
+
"profile.notebook.newOrgNamePlaceholder": "Uuden organismin nimi",
|
|
86
|
+
"profile.notebook.newWsNamePlaceholder": "Uuden workspacen nimi",
|
|
87
|
+
"profile.notebook.alternatives": "Vaihtoehdot:",
|
|
88
|
+
"profile.notebook.materializeBtn": "Tallenna dokumentiksi",
|
|
89
|
+
"profile.notebook.cancelBtn": "Peruuta",
|
|
90
|
+
"profile.notebook.materialized": "Tallennettu dokumentiksi",
|
|
91
|
+
"profile.notebook.titleRequired": "Otsikko vaaditaan",
|
|
92
|
+
"profile.notebook.orgNameRequired": "Nimeä uusi organismi",
|
|
93
|
+
"profile.notebook.step1": "Luetaan organismi-rakennettasi…",
|
|
94
|
+
"profile.notebook.step2": "Kysytään tekoälyltä paras sijoitus — tämä voi kestää jopa pari minuuttia hitaalla mallilla…",
|
|
95
|
+
"profile.notebook.step3": "Valmistellaan ehdotusta…",
|
|
96
|
+
"profile.notebook.sortErrorTitle": "Lajittelu epäonnistui",
|
|
97
|
+
"profile.notebook.needKey": "AI-lajittelu tarvitsee oman OpenRouter-API-avaimesi. Lisää se tähän ja yritä uudelleen:",
|
|
98
|
+
"profile.notebook.filterPlaceholder": "Suodata muistiinpanoja…",
|
|
99
|
+
"profile.notebook.sortNew": "Uusimmat ensin",
|
|
100
|
+
"profile.notebook.sortOld": "Vanhimmat ensin",
|
|
101
|
+
"profile.notebook.toggleView": "Pienennä / laajenna",
|
|
102
|
+
"profile.notebook.noMatch": "Mikään muistiinpano ei vastaa suodatinta.",
|
|
103
|
+
"profile.notebook.scopeOwn": "Omat",
|
|
104
|
+
"profile.notebook.scopePublic": "Julkinen tieto",
|
|
105
|
+
"profile.notebook.kindKnowledge": "tietopaketti",
|
|
106
|
+
"profile.notebook.producer": "Tuottaja",
|
|
107
|
+
"profile.notebook.tryAgain": "Yritä uudelleen",
|
|
108
|
+
"profile.notebook.dismiss": "Sulje",
|
|
39
109
|
"profile.tabs.workflows": "Työnkulut",
|
|
40
110
|
"profile.workflows.title": "Työnkulut",
|
|
41
111
|
"profile.workflows.desc": "Määritellyt, järjestetyt agenttiketjut askelkohtaisilla terveystarkistuksilla — ne näyttävät tuottiko jokainen askel oikeasti tuloksen, ei vain että se käynnistyi.",
|
|
@@ -392,6 +462,33 @@
|
|
|
392
462
|
"workaroundNote": "Kopioi muistosi ja liitä se suoraan AI-keskusteluun. Toimii aina, kaikkialla."
|
|
393
463
|
},
|
|
394
464
|
"comingSoon": "Tulossa pian",
|
|
465
|
+
"presence": {
|
|
466
|
+
"status": {
|
|
467
|
+
"available": "Tavoitettavissa",
|
|
468
|
+
"busy": "Kiireinen",
|
|
469
|
+
"away": "Poissa",
|
|
470
|
+
"offline": "Offline",
|
|
471
|
+
"invisible": "Näkymätön",
|
|
472
|
+
"unknown": "Ei tiedossa"
|
|
473
|
+
},
|
|
474
|
+
"control": {
|
|
475
|
+
"title": "Tavoitettavuus",
|
|
476
|
+
"desc": "Näytä muille, oletko tavoitettavissa. Pidä automaattisena, aseta käsin tai valitse kuka sen näkee.",
|
|
477
|
+
"modeLabel": "Miten tila määräytyy",
|
|
478
|
+
"modeAuto": "Automaattinen",
|
|
479
|
+
"modeAutoHint": "Näkyy tavoitettavissa, kun portaali on auki.",
|
|
480
|
+
"modeManual": "Käsin",
|
|
481
|
+
"statusLabel": "Tilasi",
|
|
482
|
+
"visibilityLabel": "Kuka näkee",
|
|
483
|
+
"visEveryone": "Kaikki",
|
|
484
|
+
"visEveryoneHint": "Kuka tahansa verkossa (jaetaan federoiduille nodeille).",
|
|
485
|
+
"visContacts": "Vain kontaktit",
|
|
486
|
+
"visContactsHint": "Henkilöt joille olet viestittänyt (vain tämä node).",
|
|
487
|
+
"visNobody": "Ei kukaan",
|
|
488
|
+
"saved": "Tavoitettavuus päivitetty",
|
|
489
|
+
"saveError": "Tavoitettavuuden päivitys epäonnistui"
|
|
490
|
+
}
|
|
491
|
+
},
|
|
395
492
|
"profile": {
|
|
396
493
|
"title": "Oma profiili",
|
|
397
494
|
"subtitle": "Profiili",
|
|
@@ -1952,6 +2049,11 @@
|
|
|
1952
2049
|
"peers": "Yhdistetyt vertaiset",
|
|
1953
2050
|
"online": "Online",
|
|
1954
2051
|
"offline": "Offline",
|
|
2052
|
+
"tier_visiting": "Vieraileva",
|
|
2053
|
+
"tier_member": "Jäsen",
|
|
2054
|
+
"tier_genesis": "Genesis",
|
|
2055
|
+
"avail_temporary": "Tilapäinen",
|
|
2056
|
+
"avail_permanent": "Pysyvä",
|
|
1955
2057
|
"statusConnected": "Yhdistetty {count} solmuun",
|
|
1956
2058
|
"statusStandalone": "Itsenäinen"
|
|
1957
2059
|
},
|
|
@@ -4128,6 +4230,17 @@
|
|
|
4128
4230
|
"portal": "Portaali",
|
|
4129
4231
|
"portalDesc": "Hallitse solmusi julkista portaalia — aloitussivua, jonka vierailijat näkevät. Mukauta HTML-mallipohjaa, aseta dynaamista sisältöä muistiavaimilla ja KV-pareilla, esikatsele muutoksia reaaliajassa ja luo tekoälyystävällinen kehotekooste portaalistasi chat-integraatioita varten.",
|
|
4130
4232
|
"portalTemplate": "Mallipohjan muokkaus",
|
|
4233
|
+
"portalNavTitle": "Ylävalikon linkit",
|
|
4234
|
+
"portalNavExplain": "Valitse, mitkä julkiset linkit näkyvät sivuston ylävalikossa ja missä järjestyksessä. Kirjautumista vaativat linkit (Sovellukset, Profiili, Ylläpito) noudattavat aina kirjautumis- ja roolisääntöjään, eivätkä ne näy tässä.",
|
|
4235
|
+
"portalNavLink": "Linkki",
|
|
4236
|
+
"portalNavVisible": "Näkyvissä",
|
|
4237
|
+
"portalNavOrder": "Järjestys",
|
|
4238
|
+
"portalNavShown": "Näkyvissä",
|
|
4239
|
+
"portalNavHidden": "Piilotettu",
|
|
4240
|
+
"portalNavMoveUp": "Siirrä ylös",
|
|
4241
|
+
"portalNavMoveDown": "Siirrä alas",
|
|
4242
|
+
"portalNavSave": "Tallenna valikko",
|
|
4243
|
+
"portalNavSaved": "Ylävalikko tallennettu",
|
|
4131
4244
|
"portalPreview": "Portaalin esikatselu",
|
|
4132
4245
|
"portalMemoryKeys": "Portaalin muistiavaimet",
|
|
4133
4246
|
"portalKvPairs": "KV-parit (ympäristö)",
|
|
@@ -4583,6 +4696,37 @@
|
|
|
4583
4696
|
"fedPeerApproved": "Vertaispyyntö hyväksytty onnistuneesti",
|
|
4584
4697
|
"fedPeerRejected": "Vertaispyyntö hylätty",
|
|
4585
4698
|
"fedLivePeersTitle": "Aktiiviset vertaiset",
|
|
4699
|
+
"fedTierLabel": "Taso",
|
|
4700
|
+
"fedVersionLabel": "Versio",
|
|
4701
|
+
"fedBehind": "vanhentunut",
|
|
4702
|
+
"fedBookTitle": "Federaatiokirja",
|
|
4703
|
+
"fedBookDesc": "Federaation hakemisto: kunkin noden operaattorit, tarjotut resurssit, versio ja asetukset. Primary (genesis) ylläpitää; muut nodet peilaavat.",
|
|
4704
|
+
"fedBookRebuild": "Rakenna uudelleen",
|
|
4705
|
+
"fedBookPull": "Peilaa genesikseltä",
|
|
4706
|
+
"fedBookRebuilt": "Federaatiokirja rakennettu uudelleen",
|
|
4707
|
+
"fedBookPulled": "Federaatiokirja peilattu",
|
|
4708
|
+
"fedBookUpToDate": "Jo ajan tasalla",
|
|
4709
|
+
"fedBookEmpty": "Federaatiokirja on tyhjä. Primary-node rakentaa sen peereistään; peilit vetävät sen genesikseltä.",
|
|
4710
|
+
"fedBookOperators": "Operaattorit",
|
|
4711
|
+
"fedBookResources": "Resurssit",
|
|
4712
|
+
"fedBookSettings": "Asetukset",
|
|
4713
|
+
"fedBookOpenJoin": "avoin liittyminen",
|
|
4714
|
+
"fedBookCrossFed": "cross-fed",
|
|
4715
|
+
"fedBookVersion": "Kirjan versio",
|
|
4716
|
+
"fedTier_visiting": "Vieraileva",
|
|
4717
|
+
"fedTier_member": "Jäsen",
|
|
4718
|
+
"fedTier_genesis": "Genesis",
|
|
4719
|
+
"fedAvail_temporary": "Tilapäinen",
|
|
4720
|
+
"fedAvail_permanent": "Pysyvä",
|
|
4721
|
+
"fedOpenJoinLabel": "Avoin liittyminen",
|
|
4722
|
+
"fedOpenJoinDesc": "Salli minkä tahansa noden liittyä itse matalan luottamuksen vierailevana vertaisena (selaa + tilaa työtä) ilman manuaalista hyväksyntää. Ylennä hyvät täysjäseniksi myöhemmin.",
|
|
4723
|
+
"fedOpenJoinUpdated": "Avoimen liittymisen asetus tallennettu",
|
|
4724
|
+
"fedPromote": "Ylennä",
|
|
4725
|
+
"fedPromoteHint": "Ylennä tämä vieraileva node täysjäseneksi (antaa palveluntarjoaja-, relay- ja replikointioikeudet).",
|
|
4726
|
+
"fedPromoteConfirm": "Ylennetäänkö tämä vieraileva node täysjäseneksi? Tämä on takuu siitä ja antaa täydet federaatio-oikeudet.",
|
|
4727
|
+
"fedPromoteNotEligible": "Ei vielä kelpoinen",
|
|
4728
|
+
"fedPromoteForceConfirm": "Tämä node ei vielä täytä ylennyskriteerejä. Ylennetäänkö silti (sinun takuusi)?",
|
|
4729
|
+
"fedPromoted": "Vertainen ylennetty jäseneksi",
|
|
4586
4730
|
"fedLivePeersExplain": "Tällä hetkellä rekisteröidyt vertaiset ja niiden reaaliaikainen tila. Sydämenlyöntimonitori pingaa jokaista vertaista 5 minuutin välein.",
|
|
4587
4731
|
"fedLivePeersHelpTitle": "Vertaisten tilojen ymmärtäminen",
|
|
4588
4732
|
"fedLivePeersHelpDetail": "Active: Vertainen on terve ja vastaa sydämenlyönteihin. Approved: Vertainen on hyväksytty mutta ei vielä aktivoitu (vaatii aktivoinnin). Degraded: Vertainen on epäonnistunut 3+ peräkkäisessä sydämenlyönnissä mutta on vielä tavoitettavissa. Offline: Vertainen on epäonnistunut 10+ peräkkäisessä sydämenlyönnissä. Depeering: Vertainen on armonaikajaksolla ennen poistamista (oletus 72h) — keskeneräiset työt voivat vielä valmistua.",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* v1.1.0 -- 2026-06-16 -- DeliverableBody renders STRUCTURED values (a JSON object/array, or
|
|
27
27
|
* deliverable.format:"json") as a key/value tree via the shared JsonNode, instead of raw JSON in
|
|
28
28
|
* a <pre>. Plain-string / image paths unchanged. Pairs with deliverable.format:"json".
|
|
29
|
+
* v1.1.1 -- 2026-06-19 -- JSDoc type annotations for frontend type-checking
|
|
29
30
|
*/
|
|
30
31
|
import { h } from 'preact';
|
|
31
32
|
import { useState, useEffect, useRef } from 'preact/hooks';
|
|
@@ -148,7 +149,7 @@ export function ImageView({ desc }) {
|
|
|
148
149
|
if (!authed) { setSrc(url); setFailed(false); return undefined; }
|
|
149
150
|
let cancelled = false;
|
|
150
151
|
setSrc(null); setFailed(false);
|
|
151
|
-
const headers = {};
|
|
152
|
+
const headers = /** @type {Record<string,string>} */ ({});
|
|
152
153
|
const session = window.AIMEAT?.auth?.getSession?.();
|
|
153
154
|
if (session?.jwt) headers['Authorization'] = 'Bearer ' + session.jwt;
|
|
154
155
|
fetch(url, { headers })
|
|
@@ -61,8 +61,7 @@ export function Modal({ open, onClose, title, className = '', children }) {
|
|
|
61
61
|
* - danger: if true, confirm button is styled red (for destructive actions)
|
|
62
62
|
*/
|
|
63
63
|
export function ConfirmDialog({ open, onClose, onConfirm, title, message, confirmLabel, cancelLabel, danger }) {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// Hooks must run unconditionally before any early return (Rules of Hooks).
|
|
66
65
|
const onBackdrop = useCallback((e) => {
|
|
67
66
|
if (e.target === e.currentTarget) onClose();
|
|
68
67
|
}, [onClose]);
|
|
@@ -74,6 +73,8 @@ export function ConfirmDialog({ open, onClose, onConfirm, title, message, confir
|
|
|
74
73
|
return () => document.removeEventListener('keydown', handler);
|
|
75
74
|
}, [open, onClose]);
|
|
76
75
|
|
|
76
|
+
if (!open) return null;
|
|
77
|
+
|
|
77
78
|
return html`
|
|
78
79
|
<div class="modal-overlay" onClick=${onBackdrop}>
|
|
79
80
|
<div class="modal">
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @usage import { NotificationBell } from '/components/NotificationBell.js'; html`<${NotificationBell} t=${t} onNavigate=${navigate} />`
|
|
9
9
|
* @version-history
|
|
10
10
|
* v1.0.0 — 2026-06-08 — Initial: header bell + dropdown + mark-read for the notification inbox.
|
|
11
|
+
* v1.0.1 — 2026-06-19 — JSDoc type annotations for frontend type-checking
|
|
11
12
|
*/
|
|
12
13
|
import { h } from 'preact';
|
|
13
14
|
import { useState, useEffect, useRef, useCallback } from 'preact/hooks';
|
|
@@ -26,7 +27,7 @@ async function api(path, opts = {}) {
|
|
|
26
27
|
|
|
27
28
|
function relTime(iso) {
|
|
28
29
|
try {
|
|
29
|
-
const d = new Date(iso), now = new Date(), s = Math.round((now - d) / 1000);
|
|
30
|
+
const d = new Date(iso), now = new Date(), s = Math.round((+now - +d) / 1000);
|
|
30
31
|
if (s < 60) return 'just now';
|
|
31
32
|
if (s < 3600) return Math.floor(s / 60) + 'm ago';
|
|
32
33
|
if (s < 86400) return Math.floor(s / 3600) + 'h ago';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file PresenceDot.js
|
|
3
|
+
* @description Canonical presence/availability indicator — a small colored dot
|
|
4
|
+
* (optionally with a text label) showing whether a person is reachable. Drop it
|
|
5
|
+
* next to any avatar/name across views (inbox, organism members, directory).
|
|
6
|
+
* Pass `ghii` and it self-fetches via the shared /js/presence-store.js (batched
|
|
7
|
+
* + live-refreshing), so a list of dots makes ONE request. Pass `status`
|
|
8
|
+
* directly for a controlled dot (e.g. the owner's own status in the Koti
|
|
9
|
+
* control). Colors come from theme tokens (`.presence-dot--*` in theme.css) so
|
|
10
|
+
* the dot flips correctly in dark mode.
|
|
11
|
+
* @structure PresenceDot({ ghii?, status?, size?='sm', label?=false, title? })
|
|
12
|
+
* - statuses: available (success) | busy (danger) | away (warn) |
|
|
13
|
+
* offline (muted) | unknown (faded; hidden in compact mode)
|
|
14
|
+
* @usage
|
|
15
|
+
* import { PresenceDot } from '/components/PresenceDot.js';
|
|
16
|
+
* html`<${PresenceDot} ghii=${peerGhii} />` // list dot (self-fetch)
|
|
17
|
+
* html`<${PresenceDot} status="available" label />` // controlled + label
|
|
18
|
+
* @version-history
|
|
19
|
+
* v1.0.0 — 2026-06-19 — Initial presence indicator (shared store, label option).
|
|
20
|
+
*/
|
|
21
|
+
import { h } from 'preact';
|
|
22
|
+
import htm from 'htm';
|
|
23
|
+
const html = htm.bind(h);
|
|
24
|
+
import { t } from '/js/i18n.js';
|
|
25
|
+
import { usePresence } from '/js/presence-store.js';
|
|
26
|
+
|
|
27
|
+
const LABEL_KEYS = {
|
|
28
|
+
available: 'presence.status.available',
|
|
29
|
+
busy: 'presence.status.busy',
|
|
30
|
+
away: 'presence.status.away',
|
|
31
|
+
offline: 'presence.status.offline',
|
|
32
|
+
unknown: 'presence.status.unknown',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function PresenceDot({ ghii, status, size = 'sm', label = false, title }) {
|
|
36
|
+
// Controlled mode (explicit status) skips the store entirely.
|
|
37
|
+
const fetched = usePresence(status ? null : ghii);
|
|
38
|
+
const st = status || fetched?.status || 'unknown';
|
|
39
|
+
|
|
40
|
+
// In compact (dot-only) mode, an unknown/hidden status renders nothing — no
|
|
41
|
+
// gray smudge next to every name. With a label we still show "unknown".
|
|
42
|
+
if (st === 'unknown' && !label) return null;
|
|
43
|
+
|
|
44
|
+
const labelText = t(LABEL_KEYS[st] || LABEL_KEYS.unknown);
|
|
45
|
+
const ttl = title || labelText;
|
|
46
|
+
|
|
47
|
+
return html`
|
|
48
|
+
<span class="presence presence--${size}" title=${ttl}>
|
|
49
|
+
<span class="presence-dot presence-dot--${st}" aria-label=${ttl}></span>
|
|
50
|
+
${label ? html`<span class="presence-label">${labelText}</span>` : null}
|
|
51
|
+
</span>
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file markdown.css
|
|
3
|
+
* @description THE canonical stylesheet for the shared Markdown component (components/Markdown.js).
|
|
4
|
+
* Scoped to the component's own `.md-body` wrapper and UNSCOPED to any view, so anywhere the
|
|
5
|
+
* <Markdown> component is used it renders the same readable, well-structured document — headings,
|
|
6
|
+
* tables, code blocks, blockquotes, lists, links, rules. This is the ONE place to style rendered
|
|
7
|
+
* markdown; views must NOT re-define `.md-body` rules. Loaded globally in spa.html. Dark-theme only:
|
|
8
|
+
* all colors/spacing via theme.css variables.
|
|
9
|
+
* @version-history
|
|
10
|
+
* v1.0.0 — 2026-06-19 — Initial: extracted the per-view duplicates into one global component sheet.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.md-body {
|
|
14
|
+
font-size: 0.95rem;
|
|
15
|
+
line-height: 1.7;
|
|
16
|
+
color: var(--text);
|
|
17
|
+
overflow-wrap: break-word;
|
|
18
|
+
word-break: break-word;
|
|
19
|
+
}
|
|
20
|
+
.md-body > :first-child { margin-top: 0; }
|
|
21
|
+
.md-body > :last-child { margin-bottom: 0; }
|
|
22
|
+
|
|
23
|
+
.md-body h1,
|
|
24
|
+
.md-body h2,
|
|
25
|
+
.md-body h3,
|
|
26
|
+
.md-body h4,
|
|
27
|
+
.md-body h5,
|
|
28
|
+
.md-body h6 { font-weight: 700; line-height: 1.3; color: var(--text); margin: 1.8em 0 0.6em; }
|
|
29
|
+
.md-body h1 { font-size: 1.7rem; letter-spacing: -0.01em; padding-bottom: 0.3em; border-bottom: 2px solid var(--border); margin-top: 0.2em; }
|
|
30
|
+
.md-body h2 { font-size: 1.32rem; padding-bottom: 0.25em; border-bottom: 1px solid var(--border); }
|
|
31
|
+
.md-body h3 { font-size: 1.13rem; }
|
|
32
|
+
.md-body h4 { font-size: 1rem; }
|
|
33
|
+
.md-body h5 { font-size: 0.9rem; }
|
|
34
|
+
.md-body h6 { font-size: 0.85rem; color: var(--muted); }
|
|
35
|
+
|
|
36
|
+
.md-body p { margin: 0.85em 0; }
|
|
37
|
+
.md-body ul,
|
|
38
|
+
.md-body ol { margin: 0.7em 0; padding-left: 1.7em; }
|
|
39
|
+
.md-body ul { list-style: disc; }
|
|
40
|
+
.md-body ol { list-style: decimal; }
|
|
41
|
+
.md-body li { margin: 0.32em 0; padding-left: 0.2em; }
|
|
42
|
+
.md-body li > ul,
|
|
43
|
+
.md-body li > ol { margin: 0.32em 0; }
|
|
44
|
+
|
|
45
|
+
.md-body a,
|
|
46
|
+
.md-body .md-wikilink { color: var(--accent); text-decoration: none; }
|
|
47
|
+
.md-body a:hover,
|
|
48
|
+
.md-body .md-wikilink:hover { text-decoration: underline; }
|
|
49
|
+
.md-body strong { font-weight: 700; color: var(--text); }
|
|
50
|
+
.md-body em { font-style: italic; }
|
|
51
|
+
|
|
52
|
+
.md-body .md-code { font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace); font-size: 0.85em; background: var(--bg-dim); padding: 0.12em 0.42em; border-radius: 4px; border: 1px solid var(--border-subtle, var(--border)); }
|
|
53
|
+
.md-body .md-pre { background: var(--bg-dim); border: 1px solid var(--border); border-radius: 8px; padding: 0.9em 1.1em; overflow-x: auto; margin: 1em 0; line-height: 1.5; }
|
|
54
|
+
.md-body .md-pre .md-code { background: none; border: none; padding: 0; font-size: 0.84rem; white-space: pre; }
|
|
55
|
+
|
|
56
|
+
.md-body blockquote { margin: 1em 0; padding: 0.3em 1.1em; border-left: 3px solid var(--accent); background: var(--bg-dim); border-radius: 0 6px 6px 0; color: var(--muted); }
|
|
57
|
+
.md-body blockquote p { margin: 0.4em 0; }
|
|
58
|
+
|
|
59
|
+
.md-body table { border-collapse: collapse; margin: 1em 0; width: 100%; font-size: 0.9rem; display: block; overflow-x: auto; }
|
|
60
|
+
.md-body th,
|
|
61
|
+
.md-body td { border: 1px solid var(--border); padding: 0.45em 0.75em; text-align: left; vertical-align: top; }
|
|
62
|
+
.md-body th { background: var(--bg-dim); font-weight: 600; }
|
|
63
|
+
.md-body tbody tr:nth-child(even) { background: var(--bg-dim); }
|
|
64
|
+
|
|
65
|
+
.md-body .md-img { max-width: 100%; height: auto; border-radius: 6px; margin: 0.6em 0; }
|
|
66
|
+
.md-body hr,
|
|
67
|
+
.md-body .md-hr { border: none; border-top: 1px solid var(--border); margin: 1.6em 0; }
|
|
@@ -903,6 +903,36 @@ a { color: inherit; text-decoration: none; }
|
|
|
903
903
|
animation: livePulse 1.5s ease-in-out infinite;
|
|
904
904
|
}
|
|
905
905
|
|
|
906
|
+
/* ── Presence indicator (canonical) ──
|
|
907
|
+
Backed by /components/PresenceDot.js. A small availability dot (+ optional
|
|
908
|
+
label) shown next to a person across views. Colors are theme tokens so the
|
|
909
|
+
dot flips in dark mode: available→success, busy→danger, away→warn,
|
|
910
|
+
offline/unknown→muted (unknown is extra-faded). */
|
|
911
|
+
.presence {
|
|
912
|
+
display: inline-flex;
|
|
913
|
+
align-items: center;
|
|
914
|
+
gap: 6px;
|
|
915
|
+
line-height: 1;
|
|
916
|
+
}
|
|
917
|
+
.presence-dot {
|
|
918
|
+
display: inline-block;
|
|
919
|
+
width: 8px;
|
|
920
|
+
height: 8px;
|
|
921
|
+
border-radius: 50%;
|
|
922
|
+
flex-shrink: 0;
|
|
923
|
+
background: var(--text-muted);
|
|
924
|
+
}
|
|
925
|
+
.presence--md .presence-dot { width: 10px; height: 10px; }
|
|
926
|
+
.presence-dot--available { background: var(--success); box-shadow: 0 0 6px rgba(16, 185, 129, 0.45); }
|
|
927
|
+
.presence-dot--busy { background: var(--danger); }
|
|
928
|
+
.presence-dot--away { background: var(--warn); }
|
|
929
|
+
.presence-dot--offline { background: var(--text-muted); }
|
|
930
|
+
.presence-dot--unknown { background: var(--text-muted); opacity: 0.4; }
|
|
931
|
+
.presence-label {
|
|
932
|
+
font-size: 0.85em;
|
|
933
|
+
color: var(--text-dim);
|
|
934
|
+
}
|
|
935
|
+
|
|
906
936
|
/* ── Key/value detail row (canonical) ──
|
|
907
937
|
Backed by /components/KeyValueRow.js. A label/value pair laid out flex
|
|
908
938
|
space-between: muted label on the left, emphasized value on the right,
|