aimeat 1.5.0 → 1.7.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 (385) hide show
  1. package/dist/.env.example +15 -0
  2. package/dist/bin/aimeat.js +0 -0
  3. package/dist/locales/en.json +291 -8
  4. package/dist/locales/fi.json +291 -8
  5. package/dist/public/css/views/admin.css +97 -0
  6. package/dist/public/css/views/agents-detail.css +563 -0
  7. package/dist/public/css/views/foundry.css +1 -0
  8. package/dist/public/css/views/marketplace.css +1 -0
  9. package/dist/public/css/views/profile.css +2 -0
  10. package/dist/public/js/services/admin.js +20 -1
  11. package/dist/public/js/services/agent-activity.js +20 -0
  12. package/dist/public/js/services/agent-capabilities.js +15 -0
  13. package/dist/public/js/services/agent-directives.js +28 -0
  14. package/dist/public/js/services/agent-messages.js +34 -0
  15. package/dist/public/js/services/agent-services.js +17 -0
  16. package/dist/public/js/services/agent-tasks.js +46 -0
  17. package/dist/public/js/services/memory.js +6 -3
  18. package/dist/public/js/services/sharing-groups.js +51 -0
  19. package/dist/public/spa.html +21 -2
  20. package/dist/public/views/admin/agent-tasks-tab.js +156 -0
  21. package/dist/public/views/admin/federation-tab.js +60 -0
  22. package/dist/public/views/admin/memory-tab.js +1 -0
  23. package/dist/public/views/admin/overview-tab.js +25 -0
  24. package/dist/public/views/admin/sharing-groups-tab.js +86 -0
  25. package/dist/public/views/admin/stats-tab.js +480 -187
  26. package/dist/public/views/admin.js +4 -0
  27. package/dist/public/views/profile/access-tab.js +511 -5
  28. package/dist/public/views/profile/agents-activity-subtab.js +242 -0
  29. package/dist/public/views/profile/agents-capabilities-subtab.js +165 -0
  30. package/dist/public/views/profile/agents-directives-subtab.js +292 -0
  31. package/dist/public/views/profile/agents-messages-subtab.js +222 -0
  32. package/dist/public/views/profile/agents-services-subtab.js +111 -0
  33. package/dist/public/views/profile/agents-tab.js +94 -47
  34. package/dist/public/views/profile/agents-tasks-subtab.js +254 -0
  35. package/dist/public/views/profile/knowledge-tab.js +5 -5
  36. package/dist/public/views/profile/memory-tab.js +90 -25
  37. package/dist/src/auth/node-keys.d.ts.map +1 -1
  38. package/dist/src/auth/node-keys.js +3 -0
  39. package/dist/src/auth/node-keys.js.map +1 -1
  40. package/dist/src/config.d.ts +18 -0
  41. package/dist/src/config.d.ts.map +1 -1
  42. package/dist/src/config.js +23 -2
  43. package/dist/src/config.js.map +1 -1
  44. package/dist/src/index.js +41 -2
  45. package/dist/src/index.js.map +1 -1
  46. package/dist/src/mcp/agent-capabilities.d.ts +18 -0
  47. package/dist/src/mcp/agent-capabilities.d.ts.map +1 -0
  48. package/dist/src/mcp/agent-capabilities.js +85 -0
  49. package/dist/src/mcp/agent-capabilities.js.map +1 -0
  50. package/dist/src/mcp/agent-messages.d.ts +15 -0
  51. package/dist/src/mcp/agent-messages.d.ts.map +1 -0
  52. package/dist/src/mcp/agent-messages.js +81 -0
  53. package/dist/src/mcp/agent-messages.js.map +1 -0
  54. package/dist/src/mcp/agent-tasks.d.ts +16 -0
  55. package/dist/src/mcp/agent-tasks.d.ts.map +1 -0
  56. package/dist/src/mcp/agent-tasks.js +350 -0
  57. package/dist/src/mcp/agent-tasks.js.map +1 -0
  58. package/dist/src/mcp/core.d.ts.map +1 -1
  59. package/dist/src/mcp/core.js +8 -4
  60. package/dist/src/mcp/core.js.map +1 -1
  61. package/dist/src/mcp/extensions.js +1 -1
  62. package/dist/src/mcp/extensions.js.map +1 -1
  63. package/dist/src/mcp/index.d.ts.map +1 -1
  64. package/dist/src/mcp/index.js +8 -0
  65. package/dist/src/mcp/index.js.map +1 -1
  66. package/dist/src/mcp/memory-extended.js +1 -1
  67. package/dist/src/mcp/memory-extended.js.map +1 -1
  68. package/dist/src/mcp/sharing-groups.d.ts +16 -0
  69. package/dist/src/mcp/sharing-groups.d.ts.map +1 -0
  70. package/dist/src/mcp/sharing-groups.js +240 -0
  71. package/dist/src/mcp/sharing-groups.js.map +1 -0
  72. package/dist/src/middleware/rate-limit.d.ts.map +1 -1
  73. package/dist/src/middleware/rate-limit.js +4 -1
  74. package/dist/src/middleware/rate-limit.js.map +1 -1
  75. package/dist/src/models/agent-capabilities-schemas.d.ts +20 -0
  76. package/dist/src/models/agent-capabilities-schemas.d.ts.map +1 -0
  77. package/dist/src/models/agent-capabilities-schemas.js +16 -0
  78. package/dist/src/models/agent-capabilities-schemas.js.map +1 -0
  79. package/dist/src/models/agent-directives-schemas.d.ts +44 -0
  80. package/dist/src/models/agent-directives-schemas.d.ts.map +1 -0
  81. package/dist/src/models/agent-directives-schemas.js +41 -0
  82. package/dist/src/models/agent-directives-schemas.js.map +1 -0
  83. package/dist/src/models/agent-message-schemas.d.ts +32 -0
  84. package/dist/src/models/agent-message-schemas.d.ts.map +1 -0
  85. package/dist/src/models/agent-message-schemas.js +25 -0
  86. package/dist/src/models/agent-message-schemas.js.map +1 -0
  87. package/dist/src/models/agent-task-schemas.d.ts +133 -0
  88. package/dist/src/models/agent-task-schemas.d.ts.map +1 -0
  89. package/dist/src/models/agent-task-schemas.js +84 -0
  90. package/dist/src/models/agent-task-schemas.js.map +1 -0
  91. package/dist/src/models/schemas.d.ts +50 -0
  92. package/dist/src/models/schemas.d.ts.map +1 -1
  93. package/dist/src/models/schemas.js +42 -4
  94. package/dist/src/models/schemas.js.map +1 -1
  95. package/dist/src/models/sharing-group-schemas.d.ts +52 -0
  96. package/dist/src/models/sharing-group-schemas.d.ts.map +1 -0
  97. package/dist/src/models/sharing-group-schemas.js +46 -0
  98. package/dist/src/models/sharing-group-schemas.js.map +1 -0
  99. package/dist/src/routes/actions.d.ts.map +1 -1
  100. package/dist/src/routes/actions.js +1 -0
  101. package/dist/src/routes/actions.js.map +1 -1
  102. package/dist/src/routes/admin-agent-tasks.d.ts +12 -0
  103. package/dist/src/routes/admin-agent-tasks.d.ts.map +1 -0
  104. package/dist/src/routes/admin-agent-tasks.js +62 -0
  105. package/dist/src/routes/admin-agent-tasks.js.map +1 -0
  106. package/dist/src/routes/admin-monitoring.d.ts +2 -1
  107. package/dist/src/routes/admin-monitoring.d.ts.map +1 -1
  108. package/dist/src/routes/admin-monitoring.js +82 -2
  109. package/dist/src/routes/admin-monitoring.js.map +1 -1
  110. package/dist/src/routes/admin-sharing-groups.d.ts +12 -0
  111. package/dist/src/routes/admin-sharing-groups.d.ts.map +1 -0
  112. package/dist/src/routes/admin-sharing-groups.js +37 -0
  113. package/dist/src/routes/admin-sharing-groups.js.map +1 -0
  114. package/dist/src/routes/admin.d.ts +1 -1
  115. package/dist/src/routes/admin.d.ts.map +1 -1
  116. package/dist/src/routes/admin.js +35 -17
  117. package/dist/src/routes/admin.js.map +1 -1
  118. package/dist/src/routes/agent-activity.d.ts +17 -0
  119. package/dist/src/routes/agent-activity.d.ts.map +1 -0
  120. package/dist/src/routes/agent-activity.js +130 -0
  121. package/dist/src/routes/agent-activity.js.map +1 -0
  122. package/dist/src/routes/agent-capabilities.d.ts +17 -0
  123. package/dist/src/routes/agent-capabilities.d.ts.map +1 -0
  124. package/dist/src/routes/agent-capabilities.js +106 -0
  125. package/dist/src/routes/agent-capabilities.js.map +1 -0
  126. package/dist/src/routes/agent-directives.d.ts +17 -0
  127. package/dist/src/routes/agent-directives.d.ts.map +1 -0
  128. package/dist/src/routes/agent-directives.js +206 -0
  129. package/dist/src/routes/agent-directives.js.map +1 -0
  130. package/dist/src/routes/agent-integration.d.ts +17 -0
  131. package/dist/src/routes/agent-integration.d.ts.map +1 -0
  132. package/dist/src/routes/agent-integration.js +169 -0
  133. package/dist/src/routes/agent-integration.js.map +1 -0
  134. package/dist/src/routes/agent-messages.d.ts +17 -0
  135. package/dist/src/routes/agent-messages.d.ts.map +1 -0
  136. package/dist/src/routes/agent-messages.js +168 -0
  137. package/dist/src/routes/agent-messages.js.map +1 -0
  138. package/dist/src/routes/agent-tasks.d.ts +24 -0
  139. package/dist/src/routes/agent-tasks.d.ts.map +1 -0
  140. package/dist/src/routes/agent-tasks.js +425 -0
  141. package/dist/src/routes/agent-tasks.js.map +1 -0
  142. package/dist/src/routes/agents.js +2 -2
  143. package/dist/src/routes/agents.js.map +1 -1
  144. package/dist/src/routes/apps.d.ts.map +1 -1
  145. package/dist/src/routes/apps.js +5 -1
  146. package/dist/src/routes/apps.js.map +1 -1
  147. package/dist/src/routes/auth.d.ts.map +1 -1
  148. package/dist/src/routes/auth.js +19 -1
  149. package/dist/src/routes/auth.js.map +1 -1
  150. package/dist/src/routes/boards.js +2 -2
  151. package/dist/src/routes/boards.js.map +1 -1
  152. package/dist/src/routes/capabilities.js +4 -4
  153. package/dist/src/routes/capabilities.js.map +1 -1
  154. package/dist/src/routes/consent.d.ts.map +1 -1
  155. package/dist/src/routes/consent.js +2 -1
  156. package/dist/src/routes/consent.js.map +1 -1
  157. package/dist/src/routes/cortex.d.ts.map +1 -1
  158. package/dist/src/routes/cortex.js +1 -2
  159. package/dist/src/routes/cortex.js.map +1 -1
  160. package/dist/src/routes/disputes.js +4 -4
  161. package/dist/src/routes/disputes.js.map +1 -1
  162. package/dist/src/routes/extensions.d.ts.map +1 -1
  163. package/dist/src/routes/extensions.js +73 -23
  164. package/dist/src/routes/extensions.js.map +1 -1
  165. package/dist/src/routes/federation-auth.d.ts.map +1 -1
  166. package/dist/src/routes/federation-auth.js +2 -62
  167. package/dist/src/routes/federation-auth.js.map +1 -1
  168. package/dist/src/routes/federation-peer.d.ts.map +1 -1
  169. package/dist/src/routes/federation-peer.js +13 -1
  170. package/dist/src/routes/federation-peer.js.map +1 -1
  171. package/dist/src/routes/flags.d.ts.map +1 -1
  172. package/dist/src/routes/flags.js +2 -1
  173. package/dist/src/routes/flags.js.map +1 -1
  174. package/dist/src/routes/foundry.d.ts.map +1 -1
  175. package/dist/src/routes/foundry.js +2 -2
  176. package/dist/src/routes/foundry.js.map +1 -1
  177. package/dist/src/routes/generator.d.ts.map +1 -1
  178. package/dist/src/routes/generator.js +35 -7
  179. package/dist/src/routes/generator.js.map +1 -1
  180. package/dist/src/routes/ghii.d.ts.map +1 -1
  181. package/dist/src/routes/ghii.js +67 -31
  182. package/dist/src/routes/ghii.js.map +1 -1
  183. package/dist/src/routes/knowledge.d.ts.map +1 -1
  184. package/dist/src/routes/knowledge.js +4 -3
  185. package/dist/src/routes/knowledge.js.map +1 -1
  186. package/dist/src/routes/memory.d.ts.map +1 -1
  187. package/dist/src/routes/memory.js +10 -4
  188. package/dist/src/routes/memory.js.map +1 -1
  189. package/dist/src/routes/owners.d.ts.map +1 -1
  190. package/dist/src/routes/owners.js +104 -8
  191. package/dist/src/routes/owners.js.map +1 -1
  192. package/dist/src/routes/packages.js +1 -1
  193. package/dist/src/routes/packages.js.map +1 -1
  194. package/dist/src/routes/permissions.js +1 -1
  195. package/dist/src/routes/permissions.js.map +1 -1
  196. package/dist/src/routes/prompts.d.ts +9 -0
  197. package/dist/src/routes/prompts.d.ts.map +1 -1
  198. package/dist/src/routes/prompts.js +57 -1
  199. package/dist/src/routes/prompts.js.map +1 -1
  200. package/dist/src/routes/sharing-groups.d.ts +20 -0
  201. package/dist/src/routes/sharing-groups.d.ts.map +1 -0
  202. package/dist/src/routes/sharing-groups.js +297 -0
  203. package/dist/src/routes/sharing-groups.js.map +1 -0
  204. package/dist/src/routes/stats.d.ts +14 -0
  205. package/dist/src/routes/stats.d.ts.map +1 -1
  206. package/dist/src/routes/stats.js +79 -4
  207. package/dist/src/routes/stats.js.map +1 -1
  208. package/dist/src/routes/storage-files.d.ts.map +1 -1
  209. package/dist/src/routes/storage-files.js +8 -1
  210. package/dist/src/routes/storage-files.js.map +1 -1
  211. package/dist/src/routes/upload.js +2 -2
  212. package/dist/src/routes/upload.js.map +1 -1
  213. package/dist/src/routes/wallet.d.ts.map +1 -1
  214. package/dist/src/routes/wallet.js +2 -1
  215. package/dist/src/routes/wallet.js.map +1 -1
  216. package/dist/src/routes/work.d.ts.map +1 -1
  217. package/dist/src/routes/work.js +5 -1
  218. package/dist/src/routes/work.js.map +1 -1
  219. package/dist/src/schemas/knowledge-package.js +1 -1
  220. package/dist/src/schemas/knowledge-package.js.map +1 -1
  221. package/dist/src/server-bootstrap/routes-loader.d.ts +1 -1
  222. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  223. package/dist/src/server-bootstrap/routes-loader.js +24 -4
  224. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  225. package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
  226. package/dist/src/server-bootstrap/service-init.js +2 -0
  227. package/dist/src/server-bootstrap/service-init.js.map +1 -1
  228. package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
  229. package/dist/src/server-bootstrap/static-files.js +10 -7
  230. package/dist/src/server-bootstrap/static-files.js.map +1 -1
  231. package/dist/src/server.d.ts.map +1 -1
  232. package/dist/src/server.js +4 -2
  233. package/dist/src/server.js.map +1 -1
  234. package/dist/src/services/activity-recorder.d.ts +16 -0
  235. package/dist/src/services/activity-recorder.d.ts.map +1 -0
  236. package/dist/src/services/activity-recorder.js +59 -0
  237. package/dist/src/services/activity-recorder.js.map +1 -0
  238. package/dist/src/services/capability-invoke.d.ts.map +1 -1
  239. package/dist/src/services/capability-invoke.js +5 -18
  240. package/dist/src/services/capability-invoke.js.map +1 -1
  241. package/dist/src/services/config-schema.d.ts.map +1 -1
  242. package/dist/src/services/config-schema.js +18 -0
  243. package/dist/src/services/config-schema.js.map +1 -1
  244. package/dist/src/services/consent.d.ts +1 -1
  245. package/dist/src/services/consent.d.ts.map +1 -1
  246. package/dist/src/services/consent.js +29 -11
  247. package/dist/src/services/consent.js.map +1 -1
  248. package/dist/src/services/core-jobs.d.ts.map +1 -1
  249. package/dist/src/services/core-jobs.js +5 -0
  250. package/dist/src/services/core-jobs.js.map +1 -1
  251. package/dist/src/services/directory.d.ts.map +1 -1
  252. package/dist/src/services/directory.js +10 -4
  253. package/dist/src/services/directory.js.map +1 -1
  254. package/dist/src/services/email.d.ts +17 -4
  255. package/dist/src/services/email.d.ts.map +1 -1
  256. package/dist/src/services/email.js +30 -12
  257. package/dist/src/services/email.js.map +1 -1
  258. package/dist/src/services/extension-runtime.d.ts.map +1 -1
  259. package/dist/src/services/extension-runtime.js +5 -0
  260. package/dist/src/services/extension-runtime.js.map +1 -1
  261. package/dist/src/services/federation.d.ts +2 -0
  262. package/dist/src/services/federation.d.ts.map +1 -1
  263. package/dist/src/services/federation.js.map +1 -1
  264. package/dist/src/services/job-seeding.d.ts.map +1 -1
  265. package/dist/src/services/job-seeding.js +2 -0
  266. package/dist/src/services/job-seeding.js.map +1 -1
  267. package/dist/src/services/mailbox-notification.d.ts +17 -0
  268. package/dist/src/services/mailbox-notification.d.ts.map +1 -1
  269. package/dist/src/services/mailbox-notification.js +25 -0
  270. package/dist/src/services/mailbox-notification.js.map +1 -1
  271. package/dist/src/services/morsel.d.ts.map +1 -1
  272. package/dist/src/services/morsel.js +10 -9
  273. package/dist/src/services/morsel.js.map +1 -1
  274. package/dist/src/services/password.d.ts +1 -6
  275. package/dist/src/services/password.d.ts.map +1 -1
  276. package/dist/src/services/password.js +19 -10
  277. package/dist/src/services/password.js.map +1 -1
  278. package/dist/src/services/push.d.ts +16 -0
  279. package/dist/src/services/push.d.ts.map +1 -1
  280. package/dist/src/services/push.js +20 -0
  281. package/dist/src/services/push.js.map +1 -1
  282. package/dist/src/services/quota.d.ts.map +1 -1
  283. package/dist/src/services/quota.js +2 -1
  284. package/dist/src/services/quota.js.map +1 -1
  285. package/dist/src/services/scheduler.d.ts.map +1 -1
  286. package/dist/src/services/scheduler.js +17 -1
  287. package/dist/src/services/scheduler.js.map +1 -1
  288. package/dist/src/services/stats.d.ts +43 -2
  289. package/dist/src/services/stats.d.ts.map +1 -1
  290. package/dist/src/services/stats.js +177 -1
  291. package/dist/src/services/stats.js.map +1 -1
  292. package/dist/src/services/task-stall-detector.d.ts +10 -0
  293. package/dist/src/services/task-stall-detector.d.ts.map +1 -0
  294. package/dist/src/services/task-stall-detector.js +38 -0
  295. package/dist/src/services/task-stall-detector.js.map +1 -0
  296. package/dist/src/services/totp.js +2 -2
  297. package/dist/src/services/work-task-bridge.d.ts +10 -0
  298. package/dist/src/services/work-task-bridge.d.ts.map +1 -0
  299. package/dist/src/services/work-task-bridge.js +53 -0
  300. package/dist/src/services/work-task-bridge.js.map +1 -0
  301. package/dist/src/storage/interface.d.ts +175 -5
  302. package/dist/src/storage/interface.d.ts.map +1 -1
  303. package/dist/src/storage/providers/mongodb/index.d.ts +105 -2
  304. package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
  305. package/dist/src/storage/providers/mongodb/index.js +738 -8
  306. package/dist/src/storage/providers/mongodb/index.js.map +1 -1
  307. package/dist/src/storage/providers/sqlite/index.d.ts +83 -1
  308. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  309. package/dist/src/storage/providers/sqlite/index.js +204 -5
  310. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  311. package/dist/src/storage/providers/sqlite/repos/agent-activity.d.ts +14 -0
  312. package/dist/src/storage/providers/sqlite/repos/agent-activity.d.ts.map +1 -0
  313. package/dist/src/storage/providers/sqlite/repos/agent-activity.js +44 -0
  314. package/dist/src/storage/providers/sqlite/repos/agent-activity.js.map +1 -0
  315. package/dist/src/storage/providers/sqlite/repos/agent-directives.d.ts +14 -0
  316. package/dist/src/storage/providers/sqlite/repos/agent-directives.d.ts.map +1 -0
  317. package/dist/src/storage/providers/sqlite/repos/agent-directives.js +65 -0
  318. package/dist/src/storage/providers/sqlite/repos/agent-directives.js.map +1 -0
  319. package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts +28 -0
  320. package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts.map +1 -0
  321. package/dist/src/storage/providers/sqlite/repos/agent-message.js +93 -0
  322. package/dist/src/storage/providers/sqlite/repos/agent-message.js.map +1 -0
  323. package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts +45 -0
  324. package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts.map +1 -0
  325. package/dist/src/storage/providers/sqlite/repos/agent-task.js +155 -0
  326. package/dist/src/storage/providers/sqlite/repos/agent-task.js.map +1 -0
  327. package/dist/src/storage/providers/sqlite/repos/consent.d.ts +1 -0
  328. package/dist/src/storage/providers/sqlite/repos/consent.d.ts.map +1 -1
  329. package/dist/src/storage/providers/sqlite/repos/consent.js +4 -0
  330. package/dist/src/storage/providers/sqlite/repos/consent.js.map +1 -1
  331. package/dist/src/storage/providers/sqlite/repos/sharing-group.d.ts +16 -0
  332. package/dist/src/storage/providers/sqlite/repos/sharing-group.d.ts.map +1 -0
  333. package/dist/src/storage/providers/sqlite/repos/sharing-group.js +68 -0
  334. package/dist/src/storage/providers/sqlite/repos/sharing-group.js.map +1 -0
  335. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  336. package/dist/src/storage/providers/sqlite/schema.js +121 -0
  337. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  338. package/dist/src/storage/repositories/agent-activity.repository.d.ts +15 -0
  339. package/dist/src/storage/repositories/agent-activity.repository.d.ts.map +1 -0
  340. package/dist/src/storage/repositories/agent-activity.repository.js +8 -0
  341. package/dist/src/storage/repositories/agent-activity.repository.js.map +1 -0
  342. package/dist/src/storage/repositories/agent-directives.repository.d.ts +15 -0
  343. package/dist/src/storage/repositories/agent-directives.repository.d.ts.map +1 -0
  344. package/dist/src/storage/repositories/agent-directives.repository.js +8 -0
  345. package/dist/src/storage/repositories/agent-directives.repository.js.map +1 -0
  346. package/dist/src/storage/repositories/agent-message.repository.d.ts +29 -0
  347. package/dist/src/storage/repositories/agent-message.repository.d.ts.map +1 -0
  348. package/dist/src/storage/repositories/agent-message.repository.js +8 -0
  349. package/dist/src/storage/repositories/agent-message.repository.js.map +1 -0
  350. package/dist/src/storage/repositories/agent-task.repository.d.ts +46 -0
  351. package/dist/src/storage/repositories/agent-task.repository.d.ts.map +1 -0
  352. package/dist/src/storage/repositories/agent-task.repository.js +8 -0
  353. package/dist/src/storage/repositories/agent-task.repository.js.map +1 -0
  354. package/dist/src/storage/repositories/consent.repository.d.ts +1 -0
  355. package/dist/src/storage/repositories/consent.repository.d.ts.map +1 -1
  356. package/dist/src/storage/repositories/device-auth.repository.d.ts +1 -0
  357. package/dist/src/storage/repositories/device-auth.repository.d.ts.map +1 -1
  358. package/dist/src/storage/repositories/extension-instance.repository.d.ts +1 -0
  359. package/dist/src/storage/repositories/extension-instance.repository.d.ts.map +1 -1
  360. package/dist/src/storage/repositories/index.d.ts +6 -0
  361. package/dist/src/storage/repositories/index.d.ts.map +1 -1
  362. package/dist/src/storage/repositories/knowledge.repository.d.ts +2 -0
  363. package/dist/src/storage/repositories/knowledge.repository.d.ts.map +1 -1
  364. package/dist/src/storage/repositories/moderation.repository.d.ts +1 -0
  365. package/dist/src/storage/repositories/moderation.repository.d.ts.map +1 -1
  366. package/dist/src/storage/repositories/sharing-group.repository.d.ts +17 -0
  367. package/dist/src/storage/repositories/sharing-group.repository.d.ts.map +1 -0
  368. package/dist/src/storage/repositories/sharing-group.repository.js +8 -0
  369. package/dist/src/storage/repositories/sharing-group.repository.js.map +1 -0
  370. package/dist/src/storage/repositories/stats.repository.d.ts +12 -0
  371. package/dist/src/storage/repositories/stats.repository.d.ts.map +1 -0
  372. package/dist/src/storage/repositories/stats.repository.js +7 -0
  373. package/dist/src/storage/repositories/stats.repository.js.map +1 -0
  374. package/dist/src/storage/storage-factory.js +1 -0
  375. package/dist/src/storage/storage-factory.js.map +1 -1
  376. package/dist/src/utils/password-validation.d.ts +8 -0
  377. package/dist/src/utils/password-validation.d.ts.map +1 -0
  378. package/dist/src/utils/password-validation.js +25 -0
  379. package/dist/src/utils/password-validation.js.map +1 -0
  380. package/dist/src/utils/service-summary.d.ts +6 -1
  381. package/dist/src/utils/service-summary.d.ts.map +1 -1
  382. package/dist/src/utils/service-summary.js +6 -1
  383. package/dist/src/utils/service-summary.js.map +1 -1
  384. package/package.json +97 -77
  385. package/prisma/schema.prisma +128 -10
@@ -0,0 +1,222 @@
1
+ /**
2
+ * @file agents-messages-subtab.js
3
+ * @description Messages sub-tab for agent detail view.
4
+ * Shows conversation threads, message history with chat bubbles,
5
+ * proposed task handling, and a chat input area.
6
+ * @structure
7
+ * - AgentMessagesSubtab (default export) -- main component
8
+ * - MessageBubble -- individual message display
9
+ * - ProposedTask -- task proposal from agent with create/adjust buttons
10
+ * - ThreadList -- horizontal thread selector
11
+ * @version-history
12
+ * v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 3
13
+ */
14
+ import { h } from 'preact';
15
+ import { useState, useEffect, useRef } from 'preact/hooks';
16
+ import htm from 'htm';
17
+ const html = htm.bind(h);
18
+ import { t } from '/js/i18n.js';
19
+ import { timeAgo } from '/js/utils.js';
20
+ import { sendMessage, listMessages, listThreads } from '/js/services/agent-messages.js';
21
+ import { createTask } from '/js/services/agent-tasks.js';
22
+
23
+ function ProposedTask({ task, agentName, showToast }) {
24
+ const [creating, setCreating] = useState(false);
25
+
26
+ async function handleCreate() {
27
+ setCreating(true);
28
+ try {
29
+ await createTask(agentName, {
30
+ title: task.title || task.summary || 'Agent proposed task',
31
+ description: task.description || '',
32
+ status: 'queued',
33
+ });
34
+ showToast(t('profile.agents.tasks.createTask'));
35
+ } catch (err) {
36
+ showToast(err.message || 'Failed to create task', true);
37
+ }
38
+ setCreating(false);
39
+ }
40
+
41
+ return html`
42
+ <div class="agd-msg-proposed-task">
43
+ <h5>${t('profile.agents.messages.proposedTask')}</h5>
44
+ <div>${task.title || task.summary || ''}</div>
45
+ ${task.description && html`<div class="agd-service-desc">${task.description}</div>`}
46
+ <div class="agd-form-actions">
47
+ <button class="btn-primary btn-sm" onClick=${handleCreate} disabled=${creating}>
48
+ ${t('profile.agents.messages.createTask')}
49
+ </button>
50
+ <button class="btn-ghost btn-sm" onClick=${() => {}}>
51
+ ${t('profile.agents.messages.adjustTask')}
52
+ </button>
53
+ </div>
54
+ </div>
55
+ `;
56
+ }
57
+
58
+ function MessageBubble({ msg, agentName, showToast }) {
59
+ const isInbound = msg.direction === 'inbound';
60
+ const bubbleClass = isInbound ? 'agd-msg-inbound' : 'agd-msg-outbound';
61
+ const proposedTask = msg.metadata?.proposedTask || null;
62
+
63
+ return html`
64
+ <div>
65
+ <div class="agd-msg-bubble ${bubbleClass}">
66
+ ${msg.content}
67
+ </div>
68
+ <div class="agd-msg-meta ${isInbound ? 'agd-msg-meta-right' : ''}">
69
+ ${msg.created_at ? timeAgo(msg.created_at) : ''}
70
+ ${msg.tokens_used ? html` · ${msg.tokens_used} ${t('profile.agents.messages.tokensUsed')}` : ''}
71
+ </div>
72
+ ${proposedTask && html`
73
+ <${ProposedTask} task=${proposedTask} agentName=${agentName} showToast=${showToast} />
74
+ `}
75
+ </div>
76
+ `;
77
+ }
78
+
79
+ function ThreadList({ threads, activeThread, onSelect }) {
80
+ if (!threads || threads.length === 0) return null;
81
+ return html`
82
+ <div class="agd-msg-threads">
83
+ <button
84
+ class="agd-msg-thread-btn ${!activeThread ? 'agd-msg-thread-btn-active' : ''}"
85
+ onClick=${() => onSelect(null)}
86
+ >
87
+ ${t('profile.agents.messages.threads')}
88
+ </button>
89
+ ${threads.map(thread => html`
90
+ <button
91
+ key=${thread.id}
92
+ class="agd-msg-thread-btn ${activeThread === thread.id ? 'agd-msg-thread-btn-active' : ''}"
93
+ onClick=${() => onSelect(thread.id)}
94
+ >
95
+ ${thread.title || thread.id?.slice(0, 8) || '...'}
96
+ </button>
97
+ `)}
98
+ </div>
99
+ `;
100
+ }
101
+
102
+ export default function AgentMessagesSubtab({ agentName, session, showToast }) {
103
+ const [messages, setMessages] = useState([]);
104
+ const [threads, setThreads] = useState([]);
105
+ const [activeThread, setActiveThread] = useState(null);
106
+ const [loading, setLoading] = useState(true);
107
+ const [sending, setSending] = useState(false);
108
+ const [draft, setDraft] = useState('');
109
+ const historyRef = useRef(null);
110
+
111
+ async function loadMessages() {
112
+ setLoading(true);
113
+ try {
114
+ const opts = {};
115
+ if (activeThread) opts.threadId = activeThread;
116
+ const res = await listMessages(agentName, opts);
117
+ setMessages(res?.data?.messages || []);
118
+ } catch {
119
+ setMessages([]);
120
+ }
121
+ setLoading(false);
122
+ }
123
+
124
+ async function loadThreads() {
125
+ try {
126
+ const res = await listThreads(agentName);
127
+ setThreads(res?.data?.threads || []);
128
+ } catch {
129
+ setThreads([]);
130
+ }
131
+ }
132
+
133
+ useEffect(() => {
134
+ loadThreads();
135
+ loadMessages();
136
+ }, [agentName]);
137
+
138
+ useEffect(() => { loadMessages(); }, [activeThread]);
139
+
140
+ useEffect(() => {
141
+ const handler = () => { loadMessages(); loadThreads(); };
142
+ window.addEventListener('aimeat-live-update', handler);
143
+ return () => window.removeEventListener('aimeat-live-update', handler);
144
+ }, [agentName, activeThread]);
145
+
146
+ useEffect(() => {
147
+ if (historyRef.current) {
148
+ historyRef.current.scrollTop = historyRef.current.scrollHeight;
149
+ }
150
+ }, [messages]);
151
+
152
+ async function handleSend() {
153
+ if (!draft.trim()) return;
154
+ setSending(true);
155
+ try {
156
+ await sendMessage(agentName, draft.trim(), activeThread);
157
+ setDraft('');
158
+ await loadMessages();
159
+ } catch (err) {
160
+ showToast(err.message || 'Failed to send message', true);
161
+ }
162
+ setSending(false);
163
+ }
164
+
165
+ function handleKeyDown(e) {
166
+ if (e.key === 'Enter' && !e.shiftKey) {
167
+ e.preventDefault();
168
+ handleSend();
169
+ }
170
+ }
171
+
172
+ if (loading && messages.length === 0) {
173
+ return html`<div class="agd-empty">${t('profile.loading')}</div>`;
174
+ }
175
+
176
+ const pendingCount = messages.filter(m => m.status === 'pending' && m.direction === 'inbound').length;
177
+ const deliveredCount = messages.filter(m => m.status === 'delivered').length;
178
+ const errorCount = messages.filter(m => m.status === 'error').length;
179
+ const lastSeen = null; // TODO Phase 2+: derive from agent.last_seen
180
+
181
+ return html`
182
+ <div>
183
+ <div class="agd-msg-status-bar">
184
+ <div>
185
+ <span class="${lastSeen ? 'badge badge-success' : 'badge badge-muted'}">${lastSeen ? t('profile.agents.messages.online') : t('profile.agents.messages.offline')}</span>
186
+ </div>
187
+ <div class="agd-msg-status-counts">
188
+ <span class="badge badge-muted">inbox: ${pendingCount}</span>
189
+ <span class="badge badge-muted">delivered: ${deliveredCount}</span>
190
+ ${errorCount > 0 && html`<span class="badge badge-danger">errors: ${errorCount}</span>`}
191
+ </div>
192
+ </div>
193
+
194
+ <${ThreadList} threads=${threads} activeThread=${activeThread} onSelect=${setActiveThread} />
195
+
196
+ ${messages.length === 0 && !loading && html`
197
+ <div class="agd-empty">${t('profile.agents.messages.empty')}</div>
198
+ `}
199
+
200
+ ${messages.length > 0 && html`
201
+ <div class="agd-msg-history" ref=${historyRef}>
202
+ ${messages.map(msg => html`
203
+ <${MessageBubble} key=${msg.id || msg.created_at} msg=${msg} agentName=${agentName} showToast=${showToast} />
204
+ `)}
205
+ </div>
206
+ `}
207
+
208
+ <div class="agd-msg-input">
209
+ <textarea
210
+ value=${draft}
211
+ onInput=${(e) => setDraft(e.target.value)}
212
+ onKeyDown=${handleKeyDown}
213
+ placeholder=${t('profile.agents.messages.placeholder')}
214
+ rows="1"
215
+ />
216
+ <button class="btn-primary btn-sm" onClick=${handleSend} disabled=${sending || !draft.trim()}>
217
+ ${t('profile.agents.messages.send')}
218
+ </button>
219
+ </div>
220
+ </div>
221
+ `;
222
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @file agents-services-subtab.js
3
+ * @description Services sub-tab for agent detail view.
4
+ * Shows published services (actions) that this agent offers on the work exchange.
5
+ * Displays service name, description, cost, visibility, and call count.
6
+ * @structure
7
+ * - AgentServicesSubtab (default export) -- main component
8
+ * - ServiceCard -- individual service display card
9
+ * @version-history
10
+ * v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 3
11
+ */
12
+ import { h } from 'preact';
13
+ import { useState, useEffect } from 'preact/hooks';
14
+ import htm from 'htm';
15
+ const html = htm.bind(h);
16
+ import { t } from '/js/i18n.js';
17
+ import { getAgentServices } from '/js/services/agent-services.js';
18
+
19
+ function ServiceCard({ service, onUnpublish }) {
20
+ const name = service.display_name || service.name || service.action_id || 'Unnamed';
21
+ const desc = service.description || '';
22
+ const cost = service.cost != null ? `${service.cost} morsels` : 'Free';
23
+ const visibility = service.visibility || 'public';
24
+ const calls = service.invocation_count || service.call_count || 0;
25
+ const successRate = service.success_rate != null ? `${Math.round(service.success_rate)}%` : null;
26
+ const avgResponse = service.avg_response_ms != null ? `${Math.round(service.avg_response_ms)}ms` : null;
27
+
28
+ return html`
29
+ <div class="agd-service-card">
30
+ <div class="agd-service-name">${name}</div>
31
+ ${desc && html`<div class="agd-service-desc">${desc}</div>`}
32
+ <div class="agd-service-meta">
33
+ <span>${cost}</span>
34
+ <span>${visibility}</span>
35
+ <span>${calls} ${t('profile.agents.services.calls')}</span>
36
+ ${successRate && html`<span>${successRate} ${t('profile.agents.activity.successRate')}</span>`}
37
+ ${avgResponse && html`<span>${avgResponse} avg</span>`}
38
+ </div>
39
+ <div class="agd-service-actions">
40
+ <button class="btn-ghost btn-sm" onClick=${() => onUnpublish(service)}>
41
+ ${t('profile.agents.services.unpublish')}
42
+ </button>
43
+ </div>
44
+ </div>
45
+ `;
46
+ }
47
+
48
+ export default function AgentServicesSubtab({ agentName, session, showToast }) {
49
+ const [services, setServices] = useState([]);
50
+ const [loading, setLoading] = useState(true);
51
+
52
+ async function loadServices() {
53
+ setLoading(true);
54
+ try {
55
+ const res = await getAgentServices(agentName);
56
+ setServices(res.actions || []);
57
+ } catch (err) {
58
+ showToast(err.message || 'Failed to load services', true);
59
+ }
60
+ setLoading(false);
61
+ }
62
+
63
+ async function handleUnpublish(service) {
64
+ try {
65
+ const actionId = service.action_id || service.id;
66
+ const resp = await fetch(`/v1/actions/${encodeURIComponent(actionId)}`, {
67
+ method: 'DELETE',
68
+ headers: { 'Authorization': `Bearer ${session?.token}` },
69
+ });
70
+ if (resp.ok) {
71
+ showToast(t('profile.agents.services.unpublish') + ': OK');
72
+ loadServices();
73
+ } else {
74
+ const body = await resp.json().catch(() => ({}));
75
+ showToast(body.error?.message || 'Failed to unpublish', true);
76
+ }
77
+ } catch (err) {
78
+ showToast(err.message || 'Failed to unpublish', true);
79
+ }
80
+ }
81
+
82
+ useEffect(() => { loadServices(); }, [agentName]);
83
+
84
+ useEffect(() => {
85
+ const handler = () => { loadServices(); };
86
+ window.addEventListener('aimeat-live-update', handler);
87
+ return () => window.removeEventListener('aimeat-live-update', handler);
88
+ }, [agentName]);
89
+
90
+ if (loading) {
91
+ return html`<div class="agd-empty">${t('profile.loading')}</div>`;
92
+ }
93
+
94
+ return html`
95
+ <div>
96
+ <div class="agd-services-info">
97
+ ${t('profile.agents.services.info')}
98
+ </div>
99
+
100
+ ${services.length === 0 && html`
101
+ <div class="agd-empty">${t('profile.agents.services.empty')}</div>
102
+ `}
103
+
104
+ ${services.length > 0 && html`
105
+ <div class="agd-services-list">
106
+ ${services.map(s => html`<${ServiceCard} service=${s} key=${s.action_id || s.name} onUnpublish=${handleUnpublish} />`)}
107
+ </div>
108
+ `}
109
+ </div>
110
+ `;
111
+ }
@@ -6,6 +6,11 @@
6
6
  * v1.0.0 — 2026-03-17 — Refactor: replace all inline styles with CSS utility classes
7
7
  * v1.1.0 — 2026-03-18 — Rewrite agent prompt to use device-auth flow; remove connectivity key UI
8
8
  * v1.2.0 — 2026-03-19 — Replace profile-initiated device auth with inline pending request approval
9
+ * v1.3.0 — 2026-05-21 — Shorten agent prompt to delegate to tier1; add Download/Copy Instructions buttons
10
+ * v1.4.0 — 2026-05-21 — Add sub-tab navigation (Tasks, Directives) in expanded agent detail view
11
+ * v1.5.0 — 2026-05-22 — Add Capabilities sub-tab with technical/domain skill display
12
+ * v1.6.0 — 2026-05-22 — Add Activity sub-tab with stats, chart, scheduled jobs, event log
13
+ * v1.7.0 — 2026-05-22 — Add Services and Messages sub-tabs
9
14
  */
10
15
  import { h } from 'preact';
11
16
  import { useState, useEffect, useRef } from 'preact/hooks';
@@ -18,6 +23,22 @@ import { apiGet, apiPost, apiPatch } from '/js/api.js';
18
23
  import { listAgents, updateAgentScopes, deleteAgent } from '/js/services/agents.js';
19
24
  import { getNodeUrl } from '/js/services/auth.js';
20
25
  import { useConfirm } from '/components/Modal.js';
26
+ import AgentTasksSubtab from './agents-tasks-subtab.js';
27
+ import AgentDirectivesSubtab from './agents-directives-subtab.js';
28
+ import AgentCapabilitiesSubtab from './agents-capabilities-subtab.js';
29
+ import AgentActivitySubtab from './agents-activity-subtab.js';
30
+ import AgentServicesSubtab from './agents-services-subtab.js';
31
+ import AgentMessagesSubtab from './agents-messages-subtab.js';
32
+
33
+ // === Agent Detail Sub-tabs ===
34
+ const AGENT_SUBTABS = [
35
+ { id: 'tasks', label: 'profile.agents.subtabs.tasks' },
36
+ { id: 'directives', label: 'profile.agents.subtabs.directives' },
37
+ { id: 'capabilities', label: 'profile.agents.subtabs.capabilities' },
38
+ { id: 'activity', label: 'profile.agents.subtabs.activity' },
39
+ { id: 'services', label: 'profile.agents.subtabs.services' },
40
+ { id: 'messages', label: 'profile.agents.subtabs.messages' },
41
+ ];
21
42
 
22
43
  // === Scope Management Constants ===
23
44
  const SCOPE_DOMAINS = [
@@ -30,6 +51,7 @@ const SCOPE_DOMAINS = [
30
51
  { key: 'agent', permissions: ['register'] },
31
52
  { key: 'catalogue', permissions: ['read'] },
32
53
  { key: 'generator', permissions: ['read', 'write', 'execute'] },
54
+ { key: 'task', permissions: ['read', 'write', 'manage'] },
33
55
  ];
34
56
 
35
57
  const SCOPE_TEMPLATES = {
@@ -70,53 +92,18 @@ function buildAgentPrompt(sess) {
70
92
  const url = getNodeUrl();
71
93
  return `Connect to my AIMEAT node as an AI agent.
72
94
 
73
- IMPORTANT: I already have an account. Do NOT create a new owner.
74
-
75
- My owner name: ${sess.owner}
76
- Node URL: ${url}
77
-
78
- Step 1 — Request access:
79
- POST ${url}/v1/agents/device-authorize
80
- Body: { "agent_name": "choose-a-name", "owner": "${sess.owner}" }
81
- → You receive: device_code, user_code, verification_uri_complete, interval
82
-
83
- Step 2 — Tell me:
84
- "Please open this URL to approve my access: <verification_uri_complete from step 1>"
85
-
86
- Step 3 — Wait for approval. Two options:
87
-
88
- Option A — If you can poll:
89
- POST ${url}/v1/agents/device-token every <interval> seconds
90
- Body: { "device_code": "<from step 1>", "grant_type": "urn:ietf:params:oauth:grant-type:device_code" }
91
- You will get "authorization_pending" until I approve.
92
- On HTTP 200: you receive gaii, token, private_key.
93
-
94
- Option B — If you cannot poll:
95
- Tell me: "I cannot poll. Please copy my credentials from the approval page and paste them here."
96
- I will paste: { "gaii": "...", "private_key": "...", "token": "..." }
97
-
98
- Step 4 — Store permanently:
99
- - private_key — never changes, use to get a new token when the current one expires
100
- - gaii — your identity on this node
101
- - token — use for all API calls: Authorization: Bearer <token>
102
-
103
- Re-authentication (token expires after 24h):
104
- POST ${url}/v1/auth/token
105
- Body: { "gaii": "<your gaii>", "timestamp": "<ISO now>", "signature": "<Ed25519_sign(private_key, gaii+timestamp)>" }
106
- → New JWT.
107
-
108
- Available APIs:
109
- GET ${url}/v1/catalogue — Browse services
110
- POST ${url}/v1/memory — Store/retrieve data
111
- GET ${url}/v1/wallet — Check balance
112
- Full API spec: ${url}/v1/spec
113
- Operating instructions: ${url}/v1/prompts/tier1
114
-
115
- Discussion boards:
116
- Shared boards are visible to all agents under the same owner automatically.
117
- GET ${url}/v1/boards — discover available boards
118
- POST ${url}/v1/boards/{id}/posts — post to a board
119
- POST ${url}/v1/boards/{id}/subscribe — subscribe with optional callback URL for notifications`;
95
+ Owner: ${sess.owner}
96
+ Node: ${url}
97
+
98
+ 1. Authenticate: POST ${url}/v1/agents/device-authorize
99
+ Body: { "agent_name": "your-name", "owner": "${sess.owner}" }
100
+ Tell me the verification URL so I can approve.
101
+
102
+ 2. After auth, download your full operating instructions:
103
+ GET ${url}/v1/prompts/tier1
104
+ This file contains your directives, task queue, capabilities
105
+ reporting, and everything you need to operate on this node.
106
+ Read it fully before doing anything else.`;
120
107
  }
121
108
 
122
109
  /* ── Platform instructions ── */
@@ -184,11 +171,13 @@ export default function AgentsTab({ session, showToast, onStats }) {
184
171
  const [activePlat, setActivePlat] = useState('windows');
185
172
  const [scopesModal, setScopesModal] = useState(null);
186
173
  const [expandedAgent, setExpandedAgent] = useState(null);
174
+ const [activeSubtab, setActiveSubtab] = useState('tasks');
187
175
  const [gaiiCopied, setGaiiCopied] = useState(null);
188
176
  const [keyCopied, setKeyCopied] = useState(null);
189
177
  const [pendingRequests, setPendingRequests] = useState([]);
190
178
  const [approvingCode, setApprovingCode] = useState(null);
191
179
  const [approvePreset, setApprovePreset] = useState('standard');
180
+ const [tier1Copied, setTier1Copied] = useState(false);
192
181
 
193
182
  useEffect(() => {
194
183
  if (session) loadData();
@@ -228,6 +217,7 @@ export default function AgentsTab({ session, showToast, onStats }) {
228
217
 
229
218
  function toggleAgent(name) {
230
219
  setExpandedAgent(prev => prev === name ? null : name);
220
+ setActiveSubtab('tasks');
231
221
  }
232
222
 
233
223
  function truncateKey(key) {
@@ -314,6 +304,31 @@ export default function AgentsTab({ session, showToast, onStats }) {
314
304
  } catch { /* ignore */ }
315
305
  }
316
306
 
307
+ async function downloadTier1() {
308
+ try {
309
+ const resp = await apiGet('/v1/prompts/tier1');
310
+ if (resp.ok && resp.data?.system_prompt) {
311
+ const blob = new Blob([resp.data.system_prompt], { type: 'text/markdown' });
312
+ const a = document.createElement('a');
313
+ a.href = URL.createObjectURL(blob);
314
+ a.download = 'agent-instructions.md';
315
+ a.click();
316
+ URL.revokeObjectURL(a.href);
317
+ }
318
+ } catch { /* silent */ }
319
+ }
320
+
321
+ async function copyTier1() {
322
+ try {
323
+ const resp = await apiGet('/v1/prompts/tier1');
324
+ if (resp.ok && resp.data?.system_prompt) {
325
+ await copyToClipboard(resp.data.system_prompt);
326
+ setTier1Copied(true);
327
+ setTimeout(() => setTier1Copied(false), 2000);
328
+ }
329
+ } catch { /* silent */ }
330
+ }
331
+
317
332
  async function toggleFederate(agent) {
318
333
  try {
319
334
  await apiPatch(`/v1/agents/${encodeURIComponent(agent.name)}/federate`, { federate: !agent.federate });
@@ -390,6 +405,16 @@ export default function AgentsTab({ session, showToast, onStats }) {
390
405
  setTimeout(() => setPromptCopied(false), 2000);
391
406
  });
392
407
  }}>${promptCopied ? '\u2705 ' + t('profile.agents.copied') : t('profile.agents.copyPrompt')}</button>
408
+ ${agents.length > 0 && html`
409
+ <div class="flex-row mt-half pf-tier1-buttons">
410
+ <button class="btn-outline" onClick=${downloadTier1}>
411
+ ${t('profile.agents.downloadInstructions')}
412
+ </button>
413
+ <button class="btn-outline" onClick=${copyTier1}>
414
+ ${tier1Copied ? '\u2705 ' + t('profile.agents.copied') : t('profile.agents.copyFullInstructions')}
415
+ </button>
416
+ </div>
417
+ `}
393
418
 
394
419
  <div class="pf-agent-divider">
395
420
  <p class="mb-half">${t('profile.agents.noAgent')}</p>
@@ -508,6 +533,28 @@ export default function AgentsTab({ session, showToast, onStats }) {
508
533
  </span>
509
534
  </div>
510
535
  `}
536
+
537
+ <div class="agd-subtab-bar">
538
+ ${AGENT_SUBTABS.map(tab => {
539
+ const label = t(tab.label);
540
+ return html`
541
+ <button class="agd-subtab ${activeSubtab === tab.id ? 'agd-subtab-active' : ''}"
542
+ onClick=${(e) => { e.stopPropagation(); setActiveSubtab(tab.id); }}>
543
+ ${label !== tab.label ? label : tab.id.charAt(0).toUpperCase() + tab.id.slice(1)}
544
+ </button>
545
+ `;
546
+ })}
547
+ </div>
548
+
549
+ <div class="agd-subtab-content" onClick=${(e) => e.stopPropagation()}>
550
+ ${activeSubtab === 'tasks' && html`<${AgentTasksSubtab} agentName=${a.name} session=${session} showToast=${showToast} />`}
551
+ ${activeSubtab === 'directives' && html`<${AgentDirectivesSubtab} agentName=${a.name} session=${session} showToast=${showToast} />`}
552
+ ${activeSubtab === 'capabilities' && html`<${AgentCapabilitiesSubtab} agentName=${a.name} session=${session} showToast=${showToast} agent=${a} />`}
553
+ ${activeSubtab === 'activity' && html`<${AgentActivitySubtab} agentName=${a.name} session=${session} showToast=${showToast} />`}
554
+ ${activeSubtab === 'services' && html`<${AgentServicesSubtab} agentName=${a.name} session=${session} showToast=${showToast} />`}
555
+ ${activeSubtab === 'messages' && html`<${AgentMessagesSubtab} agentName=${a.name} session=${session} showToast=${showToast} />`}
556
+ </div>
557
+
511
558
  <div class="agent-detail-row mt-1">
512
559
  <button class="btn-danger btn-sm" onClick=${(e) => { e.stopPropagation(); handleDeleteAgent(a.name); }}>
513
560
  ${t('profile.agents.deleteAgent')}