aimeat 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +22 -1
  2. package/dist/.env.example +6 -1
  3. package/dist/locales/en.json +163 -4
  4. package/dist/locales/fi.json +163 -4
  5. package/dist/public/components/Card.js +17 -3
  6. package/dist/public/components/Collapsible.js +39 -0
  7. package/dist/public/components/CopyButton.js +55 -24
  8. package/dist/public/components/DataTable.js +57 -0
  9. package/dist/public/components/EmptyState.js +28 -0
  10. package/dist/public/components/KeyValueRow.js +37 -0
  11. package/dist/public/components/Modal.js +22 -5
  12. package/dist/public/components/Pagination.js +70 -0
  13. package/dist/public/components/SearchBar.js +44 -0
  14. package/dist/public/components/StatusDot.js +29 -0
  15. package/dist/public/components/TagList.js +53 -0
  16. package/dist/public/components/ToggleSwitch.js +28 -0
  17. package/dist/public/components/index.js +41 -1
  18. package/dist/public/css/components/tags.css +24 -0
  19. package/dist/public/css/style-testbed.css +135 -0
  20. package/dist/public/css/theme.css +556 -34
  21. package/dist/public/css/views/admin-agent-integration.css +2 -33
  22. package/dist/public/css/views/admin.css +730 -686
  23. package/dist/public/css/views/agents-detail.css +440 -26
  24. package/dist/public/css/views/help.css +2 -1
  25. package/dist/public/css/views/hobbies.css +53 -33
  26. package/dist/public/css/views/marketplace.css +73 -60
  27. package/dist/public/css/views/openclaw.css +12 -6
  28. package/dist/public/css/views/portal-classic.css +34 -26
  29. package/dist/public/css/views/portal-dev.css +41 -32
  30. package/dist/public/css/views/portal.css +14 -18
  31. package/dist/public/css/views/profile.css +252 -164
  32. package/dist/public/css/views/public-knowledge-viewer.css +18 -6
  33. package/dist/public/css/views/scheduler.css +116 -0
  34. package/dist/public/js/format.js +41 -0
  35. package/dist/public/js/services/admin.js +3 -0
  36. package/dist/public/js/services/generator-spec-validate.js +5 -1
  37. package/dist/public/js/services/schedules.js +53 -0
  38. package/dist/public/js/style-testbed.js +170 -0
  39. package/dist/public/js/theme.js +114 -0
  40. package/dist/public/llms-template.txt +170 -2
  41. package/dist/public/oauth-consent.html +7 -1
  42. package/dist/public/spa.html +74 -16
  43. package/dist/public/style-testbed.html +420 -0
  44. package/dist/public/views/admin/agent-integration-tab.js +23 -38
  45. package/dist/public/views/admin/agent-tasks-tab.js +14 -21
  46. package/dist/public/views/admin/chat-instances-tab.js +1 -1
  47. package/dist/public/views/admin/config-tab.js +7 -2
  48. package/dist/public/views/admin/cortex-tab.js +20 -14
  49. package/dist/public/views/admin/csm-tab.js +22 -18
  50. package/dist/public/views/admin/directory-tab.js +3 -3
  51. package/dist/public/views/admin/email-tab.js +23 -28
  52. package/dist/public/views/admin/federation-tab.js +15 -5
  53. package/dist/public/views/admin/generator-debug-tab.js +10 -8
  54. package/dist/public/views/admin/genesis-tab.js +4 -4
  55. package/dist/public/views/admin/ghii-tab.js +3 -3
  56. package/dist/public/views/admin/knowledge-tab.js +15 -5
  57. package/dist/public/views/admin/matching-tab.js +3 -3
  58. package/dist/public/views/admin/memory-tab.js +16 -20
  59. package/dist/public/views/admin/msm-tab.js +30 -17
  60. package/dist/public/views/admin/overview-tab.js +7 -7
  61. package/dist/public/views/admin/packages-tab.js +10 -9
  62. package/dist/public/views/admin/portal-tab.js +108 -13
  63. package/dist/public/views/admin/prompts-tab.js +5 -5
  64. package/dist/public/views/admin/push-tab.js +15 -4
  65. package/dist/public/views/admin/realtime-tab.js +3 -3
  66. package/dist/public/views/admin/services-tab.js +18 -27
  67. package/dist/public/views/admin/shared.js +48 -58
  68. package/dist/public/views/admin/sharing-groups-tab.js +5 -10
  69. package/dist/public/views/admin/stats-tab.js +3 -3
  70. package/dist/public/views/guides.js +9 -13
  71. package/dist/public/views/help.js +3 -24
  72. package/dist/public/views/hobbies.js +47 -41
  73. package/dist/public/views/marketplace.js +42 -34
  74. package/dist/public/views/openclaw.js +0 -1
  75. package/dist/public/views/portal-classic.js +4 -15
  76. package/dist/public/views/portal-dev.js +28 -30
  77. package/dist/public/views/portal.js +16 -21
  78. package/dist/public/views/portfolio.js +11 -12
  79. package/dist/public/views/profile/access-tab.js +250 -1
  80. package/dist/public/views/profile/agents/agent-card.js +98 -7
  81. package/dist/public/views/profile/agents/tab-activity.js +15 -13
  82. package/dist/public/views/profile/agents/tab-agent-config.js +60 -6
  83. package/dist/public/views/profile/agents/tab-integration.js +37 -60
  84. package/dist/public/views/profile/agents/tab-messages.js +10 -1
  85. package/dist/public/views/profile/agents/tab-quality.js +25 -19
  86. package/dist/public/views/profile/agents/tab-schedules.js +81 -0
  87. package/dist/public/views/profile/agents/tab-tasks.js +5 -2
  88. package/dist/public/views/profile/agents-activity-subtab.js +4 -4
  89. package/dist/public/views/profile/agents-services-subtab.js +5 -4
  90. package/dist/public/views/profile/agents-tab.js +224 -37
  91. package/dist/public/views/profile/agents-tasks-subtab.js +164 -20
  92. package/dist/public/views/profile/calibrator-batch.js +5 -11
  93. package/dist/public/views/profile/calibrator-tab.js +4 -9
  94. package/dist/public/views/profile/chat-sessions-tab.js +9 -5
  95. package/dist/public/views/profile/email-tab.js +2 -2
  96. package/dist/public/views/profile/extensions-tab.js +27 -22
  97. package/dist/public/views/profile/federation-tab.js +4 -1
  98. package/dist/public/views/profile/foundry-detail.js +22 -23
  99. package/dist/public/views/profile/foundry-tab.js +12 -13
  100. package/dist/public/views/profile/generator-dashboard/DebugPanel.js +4 -7
  101. package/dist/public/views/profile/generator-dashboard/use-dashboard-core.js +4 -1
  102. package/dist/public/views/profile/generator-dashboard/use-edit-mode.js +3 -2
  103. package/dist/public/views/profile/generator-detail.js +26 -30
  104. package/dist/public/views/profile/generator-tab.js +5 -5
  105. package/dist/public/views/profile/knowledge-tab.js +12 -12
  106. package/dist/public/views/profile/landing-page.js +100 -149
  107. package/dist/public/views/profile/memory-tab.js +15 -11
  108. package/dist/public/views/profile/node-stats-tab.js +3 -3
  109. package/dist/public/views/profile/nodes-tab.js +10 -3
  110. package/dist/public/views/profile/notifications-tab.js +3 -3
  111. package/dist/public/views/profile/packages-tab.js +14 -14
  112. package/dist/public/views/profile/schedule-item.js +177 -0
  113. package/dist/public/views/profile/scheduler-tab.js +294 -0
  114. package/dist/public/views/profile/services-tab.js +1 -1
  115. package/dist/public/views/profile/shared.js +16 -12
  116. package/dist/public/views/profile/wallet-tab.js +27 -50
  117. package/dist/public/views/profile/work-tab.js +29 -31
  118. package/dist/public/views/profile.js +24 -0
  119. package/dist/public/views/public-knowledge-viewer.js +9 -18
  120. package/dist/src/auth/middleware.d.ts +3 -2
  121. package/dist/src/auth/middleware.d.ts.map +1 -1
  122. package/dist/src/auth/middleware.js +78 -3
  123. package/dist/src/auth/middleware.js.map +1 -1
  124. package/dist/src/cli/init-wizard.d.ts.map +1 -1
  125. package/dist/src/cli/init-wizard.js +13 -1
  126. package/dist/src/cli/init-wizard.js.map +1 -1
  127. package/dist/src/config.d.ts +4 -0
  128. package/dist/src/config.d.ts.map +1 -1
  129. package/dist/src/config.js +10 -1
  130. package/dist/src/config.js.map +1 -1
  131. package/dist/src/generated/api-types.d.ts +926 -29
  132. package/dist/src/generated/api-types.d.ts.map +1 -1
  133. package/dist/src/mcp/agent-schedules.d.ts +23 -0
  134. package/dist/src/mcp/agent-schedules.d.ts.map +1 -0
  135. package/dist/src/mcp/agent-schedules.js +175 -0
  136. package/dist/src/mcp/agent-schedules.js.map +1 -0
  137. package/dist/src/mcp/annotations.d.ts.map +1 -1
  138. package/dist/src/mcp/annotations.js +6 -0
  139. package/dist/src/mcp/annotations.js.map +1 -1
  140. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  141. package/dist/src/mcp/catalog/definitions.js +55 -0
  142. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  143. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  144. package/dist/src/mcp/catalog/scopes.js +12 -0
  145. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  146. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  147. package/dist/src/mcp/catalog/surfaces.js +2 -0
  148. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  149. package/dist/src/mcp/index.d.ts.map +1 -1
  150. package/dist/src/mcp/index.js +14 -0
  151. package/dist/src/mcp/index.js.map +1 -1
  152. package/dist/src/models/schemas.d.ts +1 -0
  153. package/dist/src/models/schemas.d.ts.map +1 -1
  154. package/dist/src/models/schemas.js +4 -0
  155. package/dist/src/models/schemas.js.map +1 -1
  156. package/dist/src/routes/access-tokens.d.ts +17 -0
  157. package/dist/src/routes/access-tokens.d.ts.map +1 -0
  158. package/dist/src/routes/access-tokens.js +164 -0
  159. package/dist/src/routes/access-tokens.js.map +1 -0
  160. package/dist/src/routes/agents.d.ts.map +1 -1
  161. package/dist/src/routes/agents.js +46 -0
  162. package/dist/src/routes/agents.js.map +1 -1
  163. package/dist/src/routes/ai.d.ts +6 -9
  164. package/dist/src/routes/ai.d.ts.map +1 -1
  165. package/dist/src/routes/ai.js +26 -175
  166. package/dist/src/routes/ai.js.map +1 -1
  167. package/dist/src/routes/apps.d.ts.map +1 -1
  168. package/dist/src/routes/apps.js +104 -34
  169. package/dist/src/routes/apps.js.map +1 -1
  170. package/dist/src/routes/auth.d.ts.map +1 -1
  171. package/dist/src/routes/auth.js +77 -4
  172. package/dist/src/routes/auth.js.map +1 -1
  173. package/dist/src/routes/bootstrap.d.ts +2 -1
  174. package/dist/src/routes/bootstrap.d.ts.map +1 -1
  175. package/dist/src/routes/bootstrap.js +14 -3
  176. package/dist/src/routes/bootstrap.js.map +1 -1
  177. package/dist/src/routes/cortex.d.ts +15 -1
  178. package/dist/src/routes/cortex.d.ts.map +1 -1
  179. package/dist/src/routes/cortex.js +224 -8
  180. package/dist/src/routes/cortex.js.map +1 -1
  181. package/dist/src/routes/extensions.d.ts +14 -0
  182. package/dist/src/routes/extensions.d.ts.map +1 -1
  183. package/dist/src/routes/extensions.js +340 -160
  184. package/dist/src/routes/extensions.js.map +1 -1
  185. package/dist/src/routes/generator.d.ts.map +1 -1
  186. package/dist/src/routes/generator.js +109 -43
  187. package/dist/src/routes/generator.js.map +1 -1
  188. package/dist/src/routes/ghii.d.ts.map +1 -1
  189. package/dist/src/routes/ghii.js +34 -13
  190. package/dist/src/routes/ghii.js.map +1 -1
  191. package/dist/src/routes/lib-header.d.ts +22 -0
  192. package/dist/src/routes/lib-header.d.ts.map +1 -0
  193. package/dist/src/routes/lib-header.js +244 -0
  194. package/dist/src/routes/lib-header.js.map +1 -0
  195. package/dist/src/routes/libs.d.ts +15 -0
  196. package/dist/src/routes/libs.d.ts.map +1 -1
  197. package/dist/src/routes/libs.js +191 -55
  198. package/dist/src/routes/libs.js.map +1 -1
  199. package/dist/src/routes/portal.d.ts.map +1 -1
  200. package/dist/src/routes/portal.js +1 -0
  201. package/dist/src/routes/portal.js.map +1 -1
  202. package/dist/src/routes/schedules.d.ts +33 -0
  203. package/dist/src/routes/schedules.d.ts.map +1 -0
  204. package/dist/src/routes/schedules.js +394 -0
  205. package/dist/src/routes/schedules.js.map +1 -0
  206. package/dist/src/routes/site.d.ts.map +1 -1
  207. package/dist/src/routes/site.js +39 -1
  208. package/dist/src/routes/site.js.map +1 -1
  209. package/dist/src/server-bootstrap/config-init.js +2 -2
  210. package/dist/src/server-bootstrap/config-init.js.map +1 -1
  211. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  212. package/dist/src/server-bootstrap/routes-loader.js +12 -2
  213. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  214. package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
  215. package/dist/src/server-bootstrap/service-init.js +2 -1
  216. package/dist/src/server-bootstrap/service-init.js.map +1 -1
  217. package/dist/src/services/access-token.d.ts +28 -0
  218. package/dist/src/services/access-token.d.ts.map +1 -0
  219. package/dist/src/services/access-token.js +37 -0
  220. package/dist/src/services/access-token.js.map +1 -0
  221. package/dist/src/services/ai-completion.d.ts +83 -0
  222. package/dist/src/services/ai-completion.d.ts.map +1 -0
  223. package/dist/src/services/ai-completion.js +187 -0
  224. package/dist/src/services/ai-completion.js.map +1 -0
  225. package/dist/src/services/generator-prompt-seeds.d.ts.map +1 -1
  226. package/dist/src/services/generator-prompt-seeds.js +6 -3
  227. package/dist/src/services/generator-prompt-seeds.js.map +1 -1
  228. package/dist/src/services/generator-prompts/spec-validate.d.ts.map +1 -1
  229. package/dist/src/services/generator-prompts/spec-validate.js +6 -2
  230. package/dist/src/services/generator-prompts/spec-validate.js.map +1 -1
  231. package/dist/src/services/generator-registration.d.ts +12 -4
  232. package/dist/src/services/generator-registration.d.ts.map +1 -1
  233. package/dist/src/services/generator-registration.js +71 -0
  234. package/dist/src/services/generator-registration.js.map +1 -1
  235. package/dist/src/services/generator-validate.d.ts +10 -0
  236. package/dist/src/services/generator-validate.d.ts.map +1 -1
  237. package/dist/src/services/generator-validate.js +180 -36
  238. package/dist/src/services/generator-validate.js.map +1 -1
  239. package/dist/src/services/owner-session.d.ts +43 -0
  240. package/dist/src/services/owner-session.d.ts.map +1 -0
  241. package/dist/src/services/owner-session.js +175 -0
  242. package/dist/src/services/owner-session.js.map +1 -0
  243. package/dist/src/services/prompt-defaults.d.ts.map +1 -1
  244. package/dist/src/services/prompt-defaults.js +35 -0
  245. package/dist/src/services/prompt-defaults.js.map +1 -1
  246. package/dist/src/services/prompt-seeder.d.ts.map +1 -1
  247. package/dist/src/services/prompt-seeder.js +6 -2
  248. package/dist/src/services/prompt-seeder.js.map +1 -1
  249. package/dist/src/services/schedule-constraints.d.ts +65 -0
  250. package/dist/src/services/schedule-constraints.d.ts.map +1 -0
  251. package/dist/src/services/schedule-constraints.js +106 -0
  252. package/dist/src/services/schedule-constraints.js.map +1 -0
  253. package/dist/src/services/scheduler.d.ts +34 -0
  254. package/dist/src/services/scheduler.d.ts.map +1 -1
  255. package/dist/src/services/scheduler.js +266 -22
  256. package/dist/src/services/scheduler.js.map +1 -1
  257. package/dist/src/services/site.d.ts +4 -0
  258. package/dist/src/services/site.d.ts.map +1 -1
  259. package/dist/src/services/site.js +29 -0
  260. package/dist/src/services/site.js.map +1 -1
  261. package/dist/src/services/skill-bundle/generator.js +19 -0
  262. package/dist/src/services/skill-bundle/generator.js.map +1 -1
  263. package/dist/src/storage/interface.d.ts +48 -5
  264. package/dist/src/storage/interface.d.ts.map +1 -1
  265. package/dist/src/storage/interface.js.map +1 -1
  266. package/dist/src/storage/providers/mongodb/index.d.ts +31 -0
  267. package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
  268. package/dist/src/storage/providers/mongodb/index.js +184 -9
  269. package/dist/src/storage/providers/mongodb/index.js.map +1 -1
  270. package/dist/src/storage/providers/sqlite/index.d.ts +31 -0
  271. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  272. package/dist/src/storage/providers/sqlite/index.js +131 -8
  273. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  274. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  275. package/dist/src/storage/providers/sqlite/schema.js +75 -7
  276. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  277. package/dist/src/storage/repositories/pat.repository.d.ts +40 -0
  278. package/dist/src/storage/repositories/pat.repository.d.ts.map +1 -0
  279. package/dist/src/storage/repositories/pat.repository.js +14 -0
  280. package/dist/src/storage/repositories/pat.repository.js.map +1 -0
  281. package/dist/src/storage/repositories/scheduler.repository.d.ts +2 -0
  282. package/dist/src/storage/repositories/scheduler.repository.d.ts.map +1 -1
  283. package/dist/src/storage/repositories/session.repository.d.ts +51 -0
  284. package/dist/src/storage/repositories/session.repository.d.ts.map +1 -1
  285. package/dist/src/storage/repositories/session.repository.js +12 -0
  286. package/dist/src/storage/repositories/session.repository.js.map +1 -1
  287. package/dist/src/utils/csp-nonce.d.ts +19 -0
  288. package/dist/src/utils/csp-nonce.d.ts.map +1 -0
  289. package/dist/src/utils/csp-nonce.js +25 -0
  290. package/dist/src/utils/csp-nonce.js.map +1 -0
  291. package/dist/src/utils/env-config.d.ts.map +1 -1
  292. package/dist/src/utils/env-config.js +25 -1
  293. package/dist/src/utils/env-config.js.map +1 -1
  294. package/dist/src/utils/env-validator.d.ts.map +1 -1
  295. package/dist/src/utils/env-validator.js +4 -0
  296. package/dist/src/utils/env-validator.js.map +1 -1
  297. package/package.json +1 -1
  298. package/prisma/schema.prisma +47 -0
package/README.md CHANGED
@@ -15,11 +15,16 @@ AIMEAT is an open protocol for AI agent infrastructure. It gives agents (Claude,
15
15
 
16
16
  <p align="center">
17
17
  <img src="assets/screenshots/portal-landing.png" alt="Portal landing page" width="24%" />
18
- <img src="assets/screenshots/profile-overview.png" alt="User profile" width="24%" />
18
+ <img src="assets/screenshots/profile-overview.png" alt="User profile with the persistent grouped sidebar" width="24%" />
19
19
  <img src="assets/screenshots/admin-dashboard.png" alt="Admin dashboard" width="24%" />
20
20
  <img src="assets/screenshots/app-catalogue-aimeatio.png" alt="App catalogue" width="24%" />
21
21
  </p>
22
22
 
23
+ <p align="center">
24
+ <img src="assets/screenshots/profile-mobile.png" alt="AIMEAT profile on mobile -- compact gold logged-in pill plus the grouped navigation as an off-canvas drawer" width="280" />
25
+ </p>
26
+ <p align="center"><em>The portal and profile are fully responsive: on mobile the grouped navigation collapses into an off-canvas drawer and the logged-in pill stays reachable.</em></p>
27
+
23
28
  ### See it in action (5:50)
24
29
 
25
30
  An AI agent connects to an AIMEAT node and reaches full operational readiness autonomously:
@@ -153,6 +158,12 @@ For MCP-capable runtimes (Claude Desktop, MCP-aware IDEs), run `aimeat connect s
153
158
 
154
159
  Claude Pro, ChatGPT Plus, and other MCP-capable AIs connect directly as MCP clients. OpenClaw, Hermes, Claude Code, and Cursor all work. Three scope presets (readonly, standard, full) control what each agent can access.
155
160
 
161
+ ### Connect agent platforms (Dify, n8n, Open WebUI, ...)
162
+
163
+ AIMEAT also bridges agent platforms. A tool like Dify, n8n, or Open WebUI is its own island -- the agents and data you build there can't reach agents anywhere else. Pointing the platform at an AIMEAT node changes that, and it's a one-time **MCP** connection: add an MCP server for the node's `/v1/mcp` (or a scoped `/v2/mcp/agent` surface), authorize once in the browser, and the full AIMEAT toolset appears -- no token pasting, no per-tool wiring. The agent can even run Hello Integration on itself (paste the canonical instruction from your profile -> Agents), then immediately read/write shared memory, storage, and knowledge packages, discover other agents, and hire capabilities.
164
+
165
+ That's the federation play: each platform is an island, and through AIMEAT its agents move what they build onto the shared network -- where it spreads across federated nodes and other agents can find and use it. Walkthrough: [docs/integrations/dify-hello-integration.md](aimeat/docs/integrations/dify-hello-integration.md).
166
+
156
167
  ### Build apps with AI
157
168
 
158
169
  Tell any AI what you want. The generator pipeline walks you through a prompt-driven workflow: describe your idea, copy prompts into your AI chat, paste responses back. The system validates each component and registers it on your node. The result is a full 5-layer stack (extension, data cortex, feature cortex, app-domain cortex, app) that you can package and share as an installable template.
@@ -299,6 +310,12 @@ With `AIMEAT_ANONYMOUS=true`, anyone can read and do limited writes without regi
299
310
 
300
311
  Each node runs independently with its own identity and portal. Operators customize through CSS themes (`theme.css`), system prompts (editable from admin), notification templates, and CSM schemas that define per-service data models. Run your own node, your own branding.
301
312
 
313
+ ### Custom portal templates
314
+
315
+ The public landing page (`/`) is editable live from the admin **Portal** tab — write the HTML template (with serve-time `{{config:*}}`, `{{memory:portal/*}}`, `{{kv:*}}`, `{{board:*}}` tags), manage portal memory keys and KV pairs, and watch the result render in the inline preview. Following AIMEAT's prompt-driven workflow, the **AI-Assisted Editor** hands you a ready prompt: paste it into any AI chat, paste the JSON bundle it returns back into **Import AI Result**, and your node's front page immediately looks custom. Drop in `<script src="/v1/libs/aimeat-header.js"></script>` and the page also carries the **exact same site header** as the rest of AIMEAT — brand, navigation, theme and language switchers, and the live gold login pill — so visitors can always sign in and reach their profile. Operator templates are trusted: their inline `<script>` runs under the node's CSP via a per-request nonce.
316
+
317
+ <img src="assets/screenshots/portal-admin-editor.png" alt="Admin Portal tab: live preview of the custom landing page, the HTML template editor with tag reference and active-source status, portal memory keys, KV pairs, and the AI-Assisted Editor (Load AI Prompt -> Import AI Result)" width="760" />
318
+
302
319
  ---
303
320
 
304
321
  ## Getting Started
@@ -375,6 +392,10 @@ cd aimeat && pnpm exec node --env-file=.env.test.sqlite --import tsx test/run-e2
375
392
 
376
393
  > The legacy `pnpm test:e2e` (in-memory backend) is deprecated and produces stale failures. Use the SQLite or MongoDB commands instead.
377
394
 
395
+ ### Synthetic agent traces (dev tool)
396
+
397
+ [`aimeat/tools/synthtraces/`](aimeat/tools/synthtraces/) is a small self-play harness that generates synthetic AIMEAT agent-session traces: a *persona* model plays the human owner while an *agent* model drives a real node over REST or MCP, producing task-driven traces you can use to benchmark or fine-tune models on the protocol. It runs on free cloud models (OpenRouter `owl-alpha`) or **fully local** via Ollama (`qwen2.5` + `llama3.2`), and ships an eval that scores protocol-correctness (no hallucinated tools, valid memory keys, task completion, token cost). See [tools/README.md](aimeat/tools/README.md).
398
+
378
399
  ---
379
400
 
380
401
  ## Documentation
package/dist/.env.example CHANGED
@@ -84,7 +84,12 @@ AIMEAT_PORT=40050
84
84
  # AIMEAT_FEDERATION_DEFAULT_SCOPES=memory:read,catalogue:read
85
85
 
86
86
  # ── Auth & Tokens ──────────────────────────────────────────────
87
- # AIMEAT_JWT_TTL=3600 # JWT lifetime in seconds (default: 1h)
87
+ # AIMEAT_JWT_TTL=3600 # Legacy / agent JWT lifetime in seconds (default: 1h)
88
+ # Owner sessions: short access token + rotating httpOnly refresh cookie (no key re-signing).
89
+ # AIMEAT_ACCESS_TTL=900 # Owner access-token (JWT) lifetime in seconds (default: 15min)
90
+ # AIMEAT_REFRESH_IDLE_DAYS=30 # Owner refresh-cookie idle window in days (default: 30)
91
+ # AIMEAT_REFRESH_ABSOLUTE_DAYS=90 # Owner refresh-cookie hard cap in days, never extended (default: 90)
92
+ # AIMEAT_REFRESH_GRACE_MS=60000 # Refresh-rotation grace window in ms for concurrency (default: 60s)
88
93
  # AIMEAT_OTK_TTL_MS=300000 # OTK expiry in ms (default: 5min)
89
94
  # AIMEAT_OTK_GRACE_MS=60000 # OTK grace period in ms (default: 1min)
90
95
 
@@ -1,4 +1,92 @@
1
1
  {
2
+ "profile.landing.home": "Home",
3
+ "profile.landing.menu": "Menu",
4
+ "profile.tabs.scheduler": "Scheduler",
5
+ "profile.agents.detail.tabs.schedules": "Schedules",
6
+ "profile.scheduler.title": "Scheduler",
7
+ "profile.scheduler.desc": "Every recurring job running for your profile — AIMEAT-managed and your agents' own.",
8
+ "profile.scheduler.loading": "Loading schedules…",
9
+ "profile.scheduler.newSchedule": "New schedule",
10
+ "profile.scheduler.close": "Close",
11
+ "profile.scheduler.triggered": "Schedule run started",
12
+ "profile.scheduler.cancelled": "Schedule cancelled",
13
+ "profile.scheduler.created": "Schedule created",
14
+ "profile.scheduler.saving": "Saving…",
15
+ "profile.scheduler.create": "Create schedule",
16
+ "profile.scheduler.confirmCancel": "Cancel this schedule? Future runs will stop.",
17
+ "profile.scheduler.managedTitle": "AIMEAT-managed",
18
+ "profile.scheduler.noManaged": "No managed schedules yet.",
19
+ "profile.scheduler.extTitle": "Extension cron jobs",
20
+ "profile.scheduler.internalTitle": "Agent internal",
21
+ "profile.scheduler.internalNote": "Self-reported by your agents. AIMEAT displays these but does not run them.",
22
+ "profile.scheduler.never": "Never",
23
+ "profile.scheduler.byAgent": "created by agent",
24
+ "profile.scheduler.pause": "Pause",
25
+ "profile.scheduler.resume": "Resume",
26
+ "profile.scheduler.runNow": "Run now",
27
+ "profile.scheduler.cancel": "Cancel",
28
+ "profile.scheduler.agentDesc": "Schedules running for this agent.",
29
+ "profile.scheduler.dispatchedTitle": "AIMEAT-dispatched",
30
+ "profile.scheduler.noDispatched": "No schedules for this agent yet.",
31
+ "profile.scheduler.noInternal": "This agent has not reported any internal schedules.",
32
+ "profile.scheduler.col.name": "Name",
33
+ "profile.scheduler.col.kind": "Type",
34
+ "profile.scheduler.col.cron": "Schedule",
35
+ "profile.scheduler.col.agent": "Agent",
36
+ "profile.scheduler.col.lastRun": "Last run",
37
+ "profile.scheduler.col.nextRun": "Next run",
38
+ "profile.scheduler.col.runs": "Runs",
39
+ "profile.scheduler.col.extension": "Extension",
40
+ "profile.scheduler.kind.ai": "AI",
41
+ "profile.scheduler.kind.agent_task": "Agent task",
42
+ "profile.scheduler.kind.extension": "Extension",
43
+ "profile.scheduler.kind.core": "Core",
44
+ "profile.scheduler.kindHint.ai": "server runs a model on your key",
45
+ "profile.scheduler.kindHint.agent_task": "queues a task for an agent",
46
+ "profile.scheduler.kindHint.extension": "runs an extension action (free)",
47
+ "profile.scheduler.field.kind": "Type",
48
+ "profile.scheduler.field.displayName": "Name",
49
+ "profile.scheduler.field.schedule": "Schedule",
50
+ "profile.scheduler.field.inputKeys": "Input memory keys (comma-separated)",
51
+ "profile.scheduler.field.prompt": "Prompt",
52
+ "profile.scheduler.field.outputKey": "Output memory key (optional)",
53
+ "profile.scheduler.field.agent": "Agent",
54
+ "profile.scheduler.field.taskTitle": "Task title",
55
+ "profile.scheduler.field.taskDescription": "Task description",
56
+ "profile.scheduler.field.extensionName": "Extension name",
57
+ "profile.scheduler.field.actionId": "Action id",
58
+ "profile.scheduler.field.purpose": "Purpose (optional)",
59
+ "profile.scheduler.ph.displayName": "e.g. Morning news translation",
60
+ "profile.scheduler.ph.timezone": "IANA timezone, e.g. Europe/Helsinki",
61
+ "profile.scheduler.ph.inputKeys": "e.g. news.morning.raw, news.sources",
62
+ "profile.scheduler.ph.prompt": "e.g. Translate the news below into Finnish and summarise the top 5 items.",
63
+ "profile.scheduler.ph.outputKey": "auto-generated if left blank",
64
+ "profile.scheduler.ph.agent": "Select an agent…",
65
+ "profile.scheduler.ph.purpose": "Why this runs",
66
+ "profile.scheduler.preset.morning": "Every morning",
67
+ "profile.scheduler.preset.evening": "Every evening",
68
+ "profile.scheduler.preset.hourly": "Hourly",
69
+ "profile.scheduler.preset.custom": "Custom",
70
+ "profile.scheduler.constraints": "Budget guards (optional)",
71
+ "profile.scheduler.maxRuns": "Stop after N runs",
72
+ "profile.scheduler.dailyLimit": "Daily AI spend limit (USD)",
73
+ "profile.scheduler.err.name": "Name is required",
74
+ "profile.scheduler.err.cron": "Schedule (cron) is required",
75
+ "profile.scheduler.err.prompt": "Prompt is required for AI schedules",
76
+ "profile.scheduler.err.agent": "Select an agent",
77
+ "profile.scheduler.err.taskTitle": "Task title is required",
78
+ "profile.scheduler.err.ext": "Extension name and action id are required",
79
+ "profile.scheduler.budgetTitle": "Schedule budget guards",
80
+ "profile.scheduler.budgetDesc": "Default opt-in limits applied to schedules created for this agent.",
81
+ "profile.scheduler.budgetSave": "Save budget guards",
82
+ "profile.scheduler.budgetSaved": "Budget guards saved",
83
+ "profile.scheduler.edit": "Edit",
84
+ "profile.scheduler.save": "Save",
85
+ "profile.scheduler.saved": "Schedule updated",
86
+ "profile.scheduler.dispatches": "Creates each run",
87
+ "profile.scheduler.soon": "soon",
88
+ "profile.scheduler.paused": "paused",
89
+ "profile.scheduler.autoKey": "(auto)",
2
90
  "common": {
3
91
  "cancel": "Cancel",
4
92
  "confirm": "Confirm",
@@ -14,7 +102,10 @@
14
102
  "name": "Name",
15
103
  "add": "Add",
16
104
  "yes": "Yes",
17
- "no": "No"
105
+ "no": "No",
106
+ "copy": "Copy",
107
+ "copied": "✓ Copied",
108
+ "error": "Error"
18
109
  },
19
110
  "nav": {
20
111
  "try": "Try it",
@@ -25,7 +116,9 @@
25
116
  "logout": "Log Out",
26
117
  "loggedInAs": "logged in as",
27
118
  "help": "Help",
28
- "admin": "Admin"
119
+ "admin": "Admin",
120
+ "themeToDark": "Switch to dark mode",
121
+ "themeToLight": "Switch to light mode"
29
122
  },
30
123
  "hero": {
31
124
  "title": "Your data is yours. Your AI works for you.",
@@ -261,6 +354,13 @@
261
354
  },
262
355
  "agents": {
263
356
  "title": "Your Agents",
357
+ "active": {
358
+ "title": "Running now",
359
+ "empty": "No tasks running right now.",
360
+ "openHint": "Open this task",
361
+ "untitled": "Untitled task",
362
+ "more": "more running (open an agent to see all)"
363
+ },
264
364
  "desc": "Agents are AI identities registered under your account, each with their own identity, scopes, tools, tasks, and memory access. Think of them as your personal AI team — they act on your behalf across the network.",
265
365
  "connect": "Connect an Automation Agent",
266
366
  "connectDesc": "Connect an AI agent to your account using the AIMEAT connector CLI or an agent-capable runtime. The connector is the easiest path because it gives the agent a persistent identity, approved scopes, local skill bundle, and MCP access to AIMEAT tools:",
@@ -325,6 +425,8 @@
325
425
  "domainCatalogue": "Catalogue",
326
426
  "domainGenerator": "Generator",
327
427
  "domainTask": "Tasks",
428
+ "domainCortex": "Cortex (install/activate browser libraries)",
429
+ "domainExt": "Extensions (activate server-side extensions)",
328
430
  "permExecute": "Execute",
329
431
  "permRead": "Read",
330
432
  "permWrite": "Write",
@@ -703,13 +805,16 @@
703
805
  "integration": "Integration",
704
806
  "tasks": "Tasks",
705
807
  "messages": "Messages",
706
- "data_access": "Data Access",
808
+ "data_access": "Memory",
707
809
  "directives": "Directives",
708
810
  "agent_config": "Agent Config",
709
811
  "activity": "Activity",
710
812
  "services": "Services",
711
813
  "quality": "Quality"
712
814
  },
815
+ "changes": {
816
+ "title": "New since you last looked"
817
+ },
713
818
  "quality": {
714
819
  "performanceTitle": "Performance",
715
820
  "performanceDesc": "How much this agent has done and how fast — computed from its tasks.",
@@ -970,7 +1075,7 @@
970
1075
  "readme": "No README published",
971
1076
  "tasks": "No tasks yet. Create a task to give this agent work.",
972
1077
  "messages": "No messages yet. Send a message or use a command.",
973
- "data_access": "No data access configured. Use the buttons below to add tags, memory areas, or knowledge packages.",
1078
+ "data_access": "No memory configured yet. Use the buttons below to add tags, memory areas, or knowledge packages.",
974
1079
  "agent_config": "No configuration files. The agent will push its config files after the skill bundle is installed.",
975
1080
  "activity": "No activity recorded yet. Events will appear here once the agent starts working.",
976
1081
  "services": "No services declared. The agent can declare services during Hello Integration Step 11."
@@ -1423,6 +1528,46 @@
1423
1528
  "hoverReveal": "Click to copy",
1424
1529
  "keepSafe": "Keep this safe — it's your owner recovery key.",
1425
1530
  "keyCopied": "Key copied to clipboard!",
1531
+ "patTitle": "Agent Access Tokens",
1532
+ "patDesc": "Create a revocable token an agent can use (as a Bearer header) to log in and test your apps. One token can be shared across all your agents.",
1533
+ "patLabelRequired": "Give the token a name",
1534
+ "patScopeRequired": "Select at least one scope, or Full / Operator",
1535
+ "patCreateError": "Failed to create token",
1536
+ "patConfirmRevoke": "Revoke token \"{name}\"? Agents using it lose access immediately.",
1537
+ "patRevoked": "Token revoked",
1538
+ "patOperator": "Operator",
1539
+ "patFullOwner": "Full owner",
1540
+ "patScopes": "scopes",
1541
+ "patCreatedTitle": "Token created — copy it now",
1542
+ "patShownOnce": "This token is shown only once. Store it now; you cannot see it again.",
1543
+ "patCopied": "Token copied",
1544
+ "patAgentPrompt": "Ready-made agent prompt",
1545
+ "patPromptCopied": "Prompt copied",
1546
+ "patDone": "Done",
1547
+ "patLoading": "Loading...",
1548
+ "patEmpty": "No access tokens yet.",
1549
+ "patCreatedAt": "Created",
1550
+ "patLastUsed": "Last used",
1551
+ "patNever": "never",
1552
+ "patExpires": "Expires",
1553
+ "patNoExpiry": "No expiry",
1554
+ "patRevoke": "Revoke",
1555
+ "patCreate": "New Token",
1556
+ "patCreateTitle": "Create Access Token",
1557
+ "patLabel": "Name",
1558
+ "patLabelPlaceholder": "e.g. App tester",
1559
+ "patLevel": "Permissions",
1560
+ "patFullOwnerHint": "acts as you; sees all apps & data",
1561
+ "patOperatorHint": "full node administration (master key)",
1562
+ "patMasterKeyWarn": "Master key — guard it like a password",
1563
+ "patSelectScopes": "Scopes",
1564
+ "patReadOwnerData": "Also read my data (otherwise a clean sandbox)",
1565
+ "patExpiry": "Expiry",
1566
+ "patExpiry1d": "24 hours",
1567
+ "patExpiry7d": "7 days",
1568
+ "patExpiry30d": "30 days",
1569
+ "patCreateBtn": "Create Token",
1570
+ "patCancel": "Cancel",
1426
1571
  "mcpEndpoint": "MCP Endpoint",
1427
1572
  "mcpDesc": "Use this URL to connect MCP-compatible AI platforms to your node.",
1428
1573
  "fedTitle": "Federation Access",
@@ -3545,6 +3690,20 @@
3545
3690
  "portalLbStatus": "Sync Status",
3546
3691
  "portalLbSyncNow": "Sync Now",
3547
3692
  "portalLbSyncDone": "Portal sync completed.",
3693
+ "portalActiveSource": "Active source",
3694
+ "portalCustomActive": "Custom template",
3695
+ "portalDefaultActive": "Default app (built-in SPA)",
3696
+ "portalDefaultExplain": "No custom template is stored, so visitors see the built-in app. The editor below starts empty. Click \"{action}\" to load the current page's HTML as a starting point, then edit and save it to override the default.",
3697
+ "portalCustomExplain": "A custom template is active and overrides the built-in app. Edit it below and save, or reset to default to bring the built-in app back.",
3698
+ "portalLoadCurrent": "Load current page",
3699
+ "portalLoadCurrentConfirm": "Replace the editor contents with the current page's HTML? Unsaved edits will be lost.",
3700
+ "portalLoadedCurrent": "Loaded current page into the editor — review and click Save Template to apply.",
3701
+ "portalAiBundleExplain": "Paste the JSON bundle the AI produced here. It can include the template, portal memory keys, and KV pairs — they are all applied at once.",
3702
+ "portalAiBundlePlaceholder": "Paste the AI's JSON result here: { \"template\": \"<!DOCTYPE html>...\", \"memory\": { \"portal/about\": \"...\" }, \"kv\": {} }",
3703
+ "portalImportDone": "Imported: {summary}",
3704
+ "portalImportInvalid": "That doesn't look like a valid AI bundle. Expected JSON with a \"template\", \"memory\", or \"kv\" field.",
3705
+ "portalSaveLooksLikeJson": "This looks like an AI JSON bundle, not an HTML template. Paste it into \"Import AI Result\" below instead.",
3706
+ "portalMemorySaved": "Portal memory key saved.",
3548
3707
  "cors": "CORS",
3549
3708
  "corsTitle": "CORS Origin Management",
3550
3709
  "corsNodeDefault": "Node Default Origins",
@@ -1,4 +1,92 @@
1
1
  {
2
+ "profile.landing.home": "Etusivu",
3
+ "profile.landing.menu": "Valikko",
4
+ "profile.tabs.scheduler": "Ajastin",
5
+ "profile.agents.detail.tabs.schedules": "Ajastukset",
6
+ "profile.scheduler.title": "Ajastin",
7
+ "profile.scheduler.desc": "Kaikki profiilisi toistuvat ajastukset — AIMEATin hallinnoimat ja agenttiesi omat.",
8
+ "profile.scheduler.loading": "Ladataan ajastuksia…",
9
+ "profile.scheduler.newSchedule": "Uusi ajastus",
10
+ "profile.scheduler.close": "Sulje",
11
+ "profile.scheduler.triggered": "Ajastuksen suoritus käynnistetty",
12
+ "profile.scheduler.cancelled": "Ajastus peruttu",
13
+ "profile.scheduler.created": "Ajastus luotu",
14
+ "profile.scheduler.saving": "Tallennetaan…",
15
+ "profile.scheduler.create": "Luo ajastus",
16
+ "profile.scheduler.confirmCancel": "Perutaanko tämä ajastus? Tulevat suoritukset pysäytetään.",
17
+ "profile.scheduler.managedTitle": "AIMEATin hallinnoimat",
18
+ "profile.scheduler.noManaged": "Ei vielä hallinnoituja ajastuksia.",
19
+ "profile.scheduler.extTitle": "Laajennusten cron-työt",
20
+ "profile.scheduler.internalTitle": "Agentin sisäiset",
21
+ "profile.scheduler.internalNote": "Agenttiesi itse ilmoittamat. AIMEAT näyttää nämä mutta ei suorita niitä.",
22
+ "profile.scheduler.never": "Ei koskaan",
23
+ "profile.scheduler.byAgent": "agentin luoma",
24
+ "profile.scheduler.pause": "Keskeytä",
25
+ "profile.scheduler.resume": "Jatka",
26
+ "profile.scheduler.runNow": "Suorita nyt",
27
+ "profile.scheduler.cancel": "Peruuta",
28
+ "profile.scheduler.agentDesc": "Tälle agentille ajossa olevat ajastukset.",
29
+ "profile.scheduler.dispatchedTitle": "AIMEATin lähettämät",
30
+ "profile.scheduler.noDispatched": "Ei vielä ajastuksia tälle agentille.",
31
+ "profile.scheduler.noInternal": "Tämä agentti ei ole ilmoittanut sisäisiä ajastuksia.",
32
+ "profile.scheduler.col.name": "Nimi",
33
+ "profile.scheduler.col.kind": "Tyyppi",
34
+ "profile.scheduler.col.cron": "Ajastus",
35
+ "profile.scheduler.col.agent": "Agentti",
36
+ "profile.scheduler.col.lastRun": "Edellinen ajo",
37
+ "profile.scheduler.col.nextRun": "Seuraava ajo",
38
+ "profile.scheduler.col.runs": "Ajot",
39
+ "profile.scheduler.col.extension": "Laajennus",
40
+ "profile.scheduler.kind.ai": "Tekoäly",
41
+ "profile.scheduler.kind.agent_task": "Agenttitehtävä",
42
+ "profile.scheduler.kind.extension": "Laajennus",
43
+ "profile.scheduler.kind.core": "Ydin",
44
+ "profile.scheduler.kindHint.ai": "palvelin ajaa mallin avaimellasi",
45
+ "profile.scheduler.kindHint.agent_task": "lisää tehtävän agentin jonoon",
46
+ "profile.scheduler.kindHint.extension": "ajaa laajennuksen toiminnon (ilmainen)",
47
+ "profile.scheduler.field.kind": "Tyyppi",
48
+ "profile.scheduler.field.displayName": "Nimi",
49
+ "profile.scheduler.field.schedule": "Ajastus",
50
+ "profile.scheduler.field.inputKeys": "Syötteen muistiavaimet (pilkuin eroteltuna)",
51
+ "profile.scheduler.field.prompt": "Kehote",
52
+ "profile.scheduler.field.outputKey": "Tuloksen muistiavain (valinnainen)",
53
+ "profile.scheduler.field.agent": "Agentti",
54
+ "profile.scheduler.field.taskTitle": "Tehtävän otsikko",
55
+ "profile.scheduler.field.taskDescription": "Tehtävän kuvaus",
56
+ "profile.scheduler.field.extensionName": "Laajennuksen nimi",
57
+ "profile.scheduler.field.actionId": "Toiminnon tunnus",
58
+ "profile.scheduler.field.purpose": "Tarkoitus (valinnainen)",
59
+ "profile.scheduler.ph.displayName": "esim. Aamu-uutisten käännös",
60
+ "profile.scheduler.ph.timezone": "IANA-aikavyöhyke, esim. Europe/Helsinki",
61
+ "profile.scheduler.ph.inputKeys": "esim. news.morning.raw, news.sources",
62
+ "profile.scheduler.ph.prompt": "esim. Käännä alla olevat uutiset suomeksi ja tiivistä 5 tärkeintä.",
63
+ "profile.scheduler.ph.outputKey": "luodaan automaattisesti jos tyhjä",
64
+ "profile.scheduler.ph.agent": "Valitse agentti…",
65
+ "profile.scheduler.ph.purpose": "Miksi tämä ajetaan",
66
+ "profile.scheduler.preset.morning": "Joka aamu",
67
+ "profile.scheduler.preset.evening": "Joka ilta",
68
+ "profile.scheduler.preset.hourly": "Tunneittain",
69
+ "profile.scheduler.preset.custom": "Mukautettu",
70
+ "profile.scheduler.constraints": "Budjettirajat (valinnainen)",
71
+ "profile.scheduler.maxRuns": "Pysäytä N ajon jälkeen",
72
+ "profile.scheduler.dailyLimit": "Päivittäinen tekoälykulujen raja (USD)",
73
+ "profile.scheduler.err.name": "Nimi vaaditaan",
74
+ "profile.scheduler.err.cron": "Ajastus (cron) vaaditaan",
75
+ "profile.scheduler.err.prompt": "Kehote vaaditaan tekoälyajastuksille",
76
+ "profile.scheduler.err.agent": "Valitse agentti",
77
+ "profile.scheduler.err.taskTitle": "Tehtävän otsikko vaaditaan",
78
+ "profile.scheduler.err.ext": "Laajennuksen nimi ja toiminnon tunnus vaaditaan",
79
+ "profile.scheduler.budgetTitle": "Ajastusten budjettirajat",
80
+ "profile.scheduler.budgetDesc": "Oletusarvoiset valinnaiset rajat, jotka koskevat tälle agentille luotuja ajastuksia.",
81
+ "profile.scheduler.budgetSave": "Tallenna budjettirajat",
82
+ "profile.scheduler.budgetSaved": "Budjettirajat tallennettu",
83
+ "profile.scheduler.edit": "Muokkaa",
84
+ "profile.scheduler.save": "Tallenna",
85
+ "profile.scheduler.saved": "Ajastus päivitetty",
86
+ "profile.scheduler.dispatches": "Luo joka ajolla",
87
+ "profile.scheduler.soon": "pian",
88
+ "profile.scheduler.paused": "tauolla",
89
+ "profile.scheduler.autoKey": "(auto)",
2
90
  "common": {
3
91
  "cancel": "Peruuta",
4
92
  "confirm": "Vahvista",
@@ -14,7 +102,10 @@
14
102
  "name": "Nimi",
15
103
  "add": "Lisää",
16
104
  "yes": "Kyllä",
17
- "no": "Ei"
105
+ "no": "Ei",
106
+ "copy": "Kopioi",
107
+ "copied": "✓ Kopioitu",
108
+ "error": "Virhe"
18
109
  },
19
110
  "nav": {
20
111
  "try": "Kokeile",
@@ -25,7 +116,9 @@
25
116
  "logout": "Kirjaudu ulos",
26
117
  "loggedInAs": "kirjautuneena",
27
118
  "help": "Apua",
28
- "admin": "Hallinta"
119
+ "admin": "Hallinta",
120
+ "themeToDark": "Vaihda tummaan tilaan",
121
+ "themeToLight": "Vaihda vaaleaan tilaan"
29
122
  },
30
123
  "hero": {
31
124
  "title": "Tietosi on sinun. AI:si työskentelee puolestasi.",
@@ -261,6 +354,13 @@
261
354
  },
262
355
  "agents": {
263
356
  "title": "Agenttisi",
357
+ "active": {
358
+ "title": "Käynnissä nyt",
359
+ "empty": "Ei käynnissä olevia taskeja juuri nyt.",
360
+ "openHint": "Avaa tämä taski",
361
+ "untitled": "Nimetön taski",
362
+ "more": "lisää käynnissä (avaa agentti nähdäksesi kaikki)"
363
+ },
264
364
  "desc": "Agentit ovat tilillesi rekisteröityjä AI-identiteettejä, joilla on oma identiteetti, rajaukset, työkalut, tehtävät ja muistipääsy. Ajattele heitä henkilökohtaisena AI-tiiminäsi - ne toimivat puolestasi verkossa.",
265
365
  "connect": "Yhdistä automaatioagentti",
266
366
  "connectDesc": "Yhdistä tekoälyagentti tilillesi AIMEAT-liittimellä tai agenttia ajavassa ympäristössä. Liitin on helpoin polku, koska se antaa agentille pysyvän identiteetin, hyväksytyt rajaukset, paikallisen taitopaketin ja MCP-pääsyn AIMEAT-työkaluihin:",
@@ -325,6 +425,8 @@
325
425
  "domainCatalogue": "Hakemisto",
326
426
  "domainGenerator": "Generaattori",
327
427
  "domainTask": "Tehtävät",
428
+ "domainCortex": "Cortex (asenna/aktivoi selainkirjastoja)",
429
+ "domainExt": "Laajennukset (aktivoi palvelinpuolen laajennuksia)",
328
430
  "permExecute": "Suoritus",
329
431
  "permRead": "Luku",
330
432
  "permWrite": "Kirjoitus",
@@ -703,13 +805,16 @@
703
805
  "integration": "Integraatio",
704
806
  "tasks": "Tehtävät",
705
807
  "messages": "Viestit",
706
- "data_access": "Datayhteydet",
808
+ "data_access": "Muisti",
707
809
  "directives": "Ohjeistukset",
708
810
  "agent_config": "Agenttiasetukset",
709
811
  "activity": "Toiminta",
710
812
  "services": "Palvelut",
711
813
  "quality": "Laatu"
712
814
  },
815
+ "changes": {
816
+ "title": "Uutta sitten kun viimeksi katsoit"
817
+ },
713
818
  "quality": {
714
819
  "performanceTitle": "Suorituskyky",
715
820
  "performanceDesc": "Kuinka paljon agentti on tehnyt ja kuinka nopeasti — laskettu sen tehtävistä.",
@@ -970,7 +1075,7 @@
970
1075
  "readme": "Ei README:tä julkaistu",
971
1076
  "tasks": "Ei tehtäviä. Luo tehtävä antaaksesi agentille työtä.",
972
1077
  "messages": "Ei viestejä. Lähetä viesti tai käytä komentoa.",
973
- "data_access": "Ei datayhteyksien asetuksia. Lisää tunnisteita, muistialueita tai tietopaketteja alla olevilla painikkeilla.",
1078
+ "data_access": "Ei muistia määritetty. Lisää tunnisteita, muistialueita tai tietopaketteja alla olevilla painikkeilla.",
974
1079
  "agent_config": "Ei asetustiedostoja. Agentti lähettää asetustiedostot taitopaketin asennuksen jälkeen.",
975
1080
  "activity": "Ei tallennettua toimintaa. Tapahtumat ilmestyvät tähän kun agentti aloittaa työskentelyn.",
976
1081
  "services": "Ei ilmoitettuja palveluja. Agentti voi ilmoittaa palvelut Hello-integraation vaiheessa 11."
@@ -1423,6 +1528,46 @@
1423
1528
  "hoverReveal": "Klikkaa kopioidaksesi",
1424
1529
  "keepSafe": "Pidä tämä turvassa — se on palautusavaimesi.",
1425
1530
  "keyCopied": "Avain kopioitu leikepöydälle!",
1531
+ "patTitle": "Agenttien käyttötokenit",
1532
+ "patDesc": "Luo peruutettava token, jota agentti voi käyttää (Bearer-headerina) kirjautuakseen ja testatakseen appejasi. Yhtä tokenia voi jakaa kaikille agenteillesi.",
1533
+ "patLabelRequired": "Anna tokenille nimi",
1534
+ "patScopeRequired": "Valitse vähintään yksi scope, tai Full / Operator",
1535
+ "patCreateError": "Tokenin luonti epäonnistui",
1536
+ "patConfirmRevoke": "Peruutetaanko token \"{name}\"? Sitä käyttävät agentit menettävät pääsyn heti.",
1537
+ "patRevoked": "Token peruutettu",
1538
+ "patOperator": "Operaattori",
1539
+ "patFullOwner": "Täysi omistaja",
1540
+ "patScopes": "scopea",
1541
+ "patCreatedTitle": "Token luotu — kopioi se nyt",
1542
+ "patShownOnce": "Token näytetään vain kerran. Tallenna se nyt; et näe sitä enää uudelleen.",
1543
+ "patCopied": "Token kopioitu",
1544
+ "patAgentPrompt": "Valmis agentti-promptti",
1545
+ "patPromptCopied": "Promptti kopioitu",
1546
+ "patDone": "Valmis",
1547
+ "patLoading": "Ladataan...",
1548
+ "patEmpty": "Ei käyttötokeneita vielä.",
1549
+ "patCreatedAt": "Luotu",
1550
+ "patLastUsed": "Viimeksi käytetty",
1551
+ "patNever": "ei koskaan",
1552
+ "patExpires": "Vanhenee",
1553
+ "patNoExpiry": "Ei vanhene",
1554
+ "patRevoke": "Peruuta",
1555
+ "patCreate": "Uusi token",
1556
+ "patCreateTitle": "Luo käyttötoken",
1557
+ "patLabel": "Nimi",
1558
+ "patLabelPlaceholder": "esim. App-testaaja",
1559
+ "patLevel": "Oikeudet",
1560
+ "patFullOwnerHint": "toimii sinuna; näkee kaikki appsit ja datan",
1561
+ "patOperatorHint": "koko noden hallinta (master-avain)",
1562
+ "patMasterKeyWarn": "Master-avain — säilytä kuin salasana",
1563
+ "patSelectScopes": "Scopet",
1564
+ "patReadOwnerData": "Lue myös minun dataani (muuten puhdas hiekkalaatikko)",
1565
+ "patExpiry": "Vanheneminen",
1566
+ "patExpiry1d": "24 tuntia",
1567
+ "patExpiry7d": "7 päivää",
1568
+ "patExpiry30d": "30 päivää",
1569
+ "patCreateBtn": "Luo token",
1570
+ "patCancel": "Peruuta",
1426
1571
  "mcpEndpoint": "MCP-päätepiste",
1427
1572
  "mcpDesc": "Käytä tätä URL:iä yhdistääksesi MCP-yhteensopivat AI-alustat solmuusi.",
1428
1573
  "fedTitle": "Federaatioyhteys",
@@ -3545,6 +3690,20 @@
3545
3690
  "portalLbStatus": "Synkronointitila",
3546
3691
  "portalLbSyncNow": "Synkronoi nyt",
3547
3692
  "portalLbSyncDone": "Portaalin synkronointi valmis.",
3693
+ "portalActiveSource": "Aktiivinen lähde",
3694
+ "portalCustomActive": "Mukautettu mallipohja",
3695
+ "portalDefaultActive": "Oletussovellus (sisäänrakennettu SPA)",
3696
+ "portalDefaultExplain": "Mukautettua mallipohjaa ei ole tallennettu, joten kävijät näkevät sisäänrakennetun sovelluksen. Alla oleva editori on tyhjä. Paina \"{action}\" ladataksesi nykyisen sivun HTML:n lähtökohdaksi, muokkaa sitä ja tallenna korvataksesi oletuksen.",
3697
+ "portalCustomExplain": "Mukautettu mallipohja on käytössä ja korvaa sisäänrakennetun sovelluksen. Muokkaa sitä alla ja tallenna, tai palauta oletukseksi tuodaksesi sisäänrakennetun sovelluksen takaisin.",
3698
+ "portalLoadCurrent": "Lataa nykyinen sivu pohjaksi",
3699
+ "portalLoadCurrentConfirm": "Korvataanko editorin sisältö nykyisen sivun HTML:llä? Tallentamattomat muutokset menetetään.",
3700
+ "portalLoadedCurrent": "Nykyinen sivu ladattu editoriin — tarkista ja paina Tallenna mallipohja ottaaksesi käyttöön.",
3701
+ "portalAiBundleExplain": "Liitä tähän tekoälyn tuottama JSON-paketti. Se voi sisältää mallipohjan, portaalin muistiavaimet ja KV-parit — ne otetaan käyttöön kaikki kerralla.",
3702
+ "portalAiBundlePlaceholder": "Liitä tekoälyn JSON-tulos tähän: { \"template\": \"<!DOCTYPE html>...\", \"memory\": { \"portal/about\": \"...\" }, \"kv\": {} }",
3703
+ "portalImportDone": "Tuotu: {summary}",
3704
+ "portalImportInvalid": "Tämä ei näytä kelvolliselta tekoälypaketilta. Odotettiin JSON, jossa on \"template\", \"memory\" tai \"kv\" -kenttä.",
3705
+ "portalSaveLooksLikeJson": "Tämä näyttää tekoälyn JSON-paketilta, ei HTML-mallipohjalta. Liitä se alla olevaan \"Tuo tekoälyn tulos\" -kenttään.",
3706
+ "portalMemorySaved": "Portaalin muistiavain tallennettu.",
3548
3707
  "cors": "CORS",
3549
3708
  "corsTitle": "CORS-alkuperähallinta",
3550
3709
  "corsNodeDefault": "Solmun oletusalkuperät",
@@ -1,14 +1,28 @@
1
+ /**
2
+ * @file Card.js
3
+ * @description Canonical themed card container (.card). Renders an optional
4
+ * header (title/subtitle) and arbitrary children. The `variant` prop selects
5
+ * a tokenized modifier — `variant="glass"` adds `.card-glass` (the former
6
+ * profile `.pf-glass-card` appearance) so profile's GlassCard can delegate here.
7
+ * @structure Card({ title, subtitle, onClick, hoverable, className, variant, children })
8
+ * @usage import { Card } from '/components/Card.js'; html`<${Card} variant="glass">…<//>`
9
+ * @version-history
10
+ * v1.0.0 — prior — Initial canonical card (title/subtitle/hoverable/className).
11
+ * v1.1.0 — 2026-06-02 — Component unification (#22): add `variant` prop;
12
+ * `variant="glass"` appends `.card-glass` so profile's GlassCard folds into Card.
13
+ */
1
14
  import { h } from 'preact';
2
15
  import htm from 'htm';
3
16
  const html = htm.bind(h);
4
17
 
5
18
  /**
6
19
  * Card — themed card container.
7
- * @param {{ title?: string, subtitle?: string, onClick?: () => void, hoverable?: boolean, className?: string, children: any }} props
20
+ * @param {{ title?: string, subtitle?: string, onClick?: () => void, hoverable?: boolean, className?: string, variant?: 'glass', children: any }} props
8
21
  */
9
- export function Card({ title, subtitle, onClick, hoverable = true, className = '', children }) {
22
+ export function Card({ title, subtitle, onClick, hoverable = true, className = '', variant, children }) {
23
+ const variantClass = variant === 'glass' ? 'card-glass' : '';
10
24
  return html`
11
- <div class="card ${hoverable ? 'card-hoverable' : ''} ${className}" onClick=${onClick}>
25
+ <div class="card ${variantClass} ${hoverable ? 'card-hoverable' : ''} ${className}" onClick=${onClick}>
12
26
  ${(title || subtitle) && html`
13
27
  <div class="card-header">
14
28
  ${title && html`<span class="card-title">${title}</span>`}
@@ -0,0 +1,39 @@
1
+ import { h } from 'preact';
2
+ import htm from 'htm';
3
+ const html = htm.bind(h);
4
+
5
+ /**
6
+ * @file Collapsible.js
7
+ * @description Canonical expand/collapse (chevron) section — a clickable header
8
+ * (title + a chevron that rotates 180° when open) with its body rendered only
9
+ * while open. CONTROLLED component: the parent owns the `open` state and is
10
+ * notified via `onToggle`. Backed by `.collapsible*` in theme.css, whose colors
11
+ * are all theme tokens so it flips correctly in dark mode. Establishes the
12
+ * canonical shape for the hand-rolled toggles scattered across views
13
+ * (.expand-btn + .pf-chevron, .scope-advanced-toggle, .pkv-entry-arrow); those
14
+ * bespoke toggles are left in place where their expanded markup is wired into
15
+ * view state — this is the target for new collapsible sections.
16
+ * @structure Collapsible({ title, open, onToggle, children }) — renders
17
+ * `<div class="collapsible">` containing a `.collapsible-header` button
18
+ * (title + `.collapsible-chevron` with an `.open` modifier) and, when open, a
19
+ * `.collapsible-body` wrapping the children.
20
+ * @usage
21
+ * import { Collapsible } from '/components/index.js';
22
+ * const [open, setOpen] = useState(false);
23
+ * html`<${Collapsible} title=${t('...')} open=${open} onToggle=${() => setOpen(!open)}>
24
+ * ${body}
25
+ * <//>`
26
+ * @version-history
27
+ * v1.0.0 — 2026-06-02 — Component unification (#23): created canonical
28
+ * expand/collapse section, consolidating the .expand-btn + .pf-chevron,
29
+ * .scope-advanced-toggle and .pkv-entry-arrow toggle patterns.
30
+ */
31
+ export function Collapsible({ title, open, onToggle, children }) {
32
+ return html`<div class="collapsible">
33
+ <button type="button" class="collapsible-header" aria-expanded=${!!open} onClick=${onToggle}>
34
+ <span class="collapsible-title">${title}</span>
35
+ <span class="collapsible-chevron ${open ? 'open' : ''}">▼</span>
36
+ </button>
37
+ ${open && html`<div class="collapsible-body">${children}</div>`}
38
+ </div>`;
39
+ }