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,242 @@
1
+ /**
2
+ * @file agents-activity-subtab.js
3
+ * @description Activity sub-tab for agent detail view.
4
+ * Shows stats summary cards (tasks completed, tokens used, success rate),
5
+ * daily activity chart with time range selector, scheduled jobs list,
6
+ * and recent event log with pagination.
7
+ * @structure
8
+ * - AgentActivitySubtab (default export) -- main component
9
+ * - StatsCards -- summary stat cards row
10
+ * - ActivityChart -- text-based daily activity display
11
+ * - ScheduledJobs -- cron job list with source badges
12
+ * - EventLog -- scrollable recent event entries
13
+ * @version-history
14
+ * v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 2
15
+ */
16
+ import { h } from 'preact';
17
+ import { useState, useEffect, useRef } from 'preact/hooks';
18
+ import htm from 'htm';
19
+ const html = htm.bind(h);
20
+ import { t } from '/js/i18n.js';
21
+ import { timeAgo } from '/js/utils.js';
22
+ import { getActivity, getActivityLog } from '/js/services/agent-activity.js';
23
+
24
+ const RANGE_OPTIONS = [
25
+ { days: 7, label: '7d' },
26
+ { days: 30, label: '30d' },
27
+ { days: 90, label: '90d' },
28
+ ];
29
+
30
+ function StatsCards({ stats }) {
31
+ const cards = [
32
+ { key: 'tasksCompleted', value: stats?.tasksCompleted ?? 0 },
33
+ { key: 'tokensUsed', value: stats?.tokensUsed30d ?? 0 },
34
+ { key: 'successRate', value: stats?.successRate != null ? `${Math.round(stats.successRate)}%` : '-' },
35
+ ];
36
+
37
+ return html`
38
+ <div class="agd-stats-grid">
39
+ ${cards.map(c => html`
40
+ <div class="agd-stat-card" key=${c.key}>
41
+ <div class="agd-stat-value">${c.value}</div>
42
+ <div class="agd-stat-label">${t(`profile.agents.activity.${c.key}`)}</div>
43
+ </div>
44
+ `)}
45
+ </div>
46
+ `;
47
+ }
48
+
49
+ function ActivityChart({ history, selectedDays, onRangeChange }) {
50
+ if (!history || history.length === 0) {
51
+ return html`
52
+ <div class="agd-chart-container">
53
+ <div class="agd-range-bar">
54
+ ${RANGE_OPTIONS.map(opt => html`
55
+ <button key=${opt.days}
56
+ class="agd-range-btn ${selectedDays === opt.days ? 'active' : ''}"
57
+ onClick=${() => onRangeChange(opt.days)}>
58
+ ${opt.label}
59
+ </button>
60
+ `)}
61
+ </div>
62
+ <div class="agd-empty">${t('profile.agents.activity.noActivity')}</div>
63
+ </div>
64
+ `;
65
+ }
66
+
67
+ // API returns { date, metric, value } rows -- aggregate tasks_completed per date
68
+ const dailyTotals = {};
69
+ for (const row of history) {
70
+ if (row.metric === 'tasks_completed' || row.metric === 'tasks_started') {
71
+ dailyTotals[row.date] = (dailyTotals[row.date] || 0) + (row.value || 0);
72
+ }
73
+ }
74
+ const dates = Object.keys(dailyTotals).sort();
75
+ const maxTasks = Math.max(...Object.values(dailyTotals), 1);
76
+
77
+ return html`
78
+ <div class="agd-chart-container">
79
+ <div class="agd-range-bar">
80
+ ${RANGE_OPTIONS.map(opt => html`
81
+ <button key=${opt.days}
82
+ class="agd-range-btn ${selectedDays === opt.days ? 'active' : ''}"
83
+ onClick=${() => onRangeChange(opt.days)}>
84
+ ${opt.label}
85
+ </button>
86
+ `)}
87
+ </div>
88
+ <div class="agd-chart-rows">
89
+ ${dates.map(date => {
90
+ const count = dailyTotals[date] || 0;
91
+ const pct = Math.round((count / maxTasks) * 100);
92
+ const dateStr = new Date(date + 'T00:00:00').toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
93
+ return html`
94
+ <div class="agd-chart-row" key=${date}>
95
+ <span class="agd-chart-date">${dateStr}</span>
96
+ <div class="agd-chart-bar-track">
97
+ <div class="agd-chart-bar-fill" style="width:${pct}%"></div>
98
+ </div>
99
+ <span class="agd-chart-count">${count}</span>
100
+ </div>
101
+ `;
102
+ })}
103
+ </div>
104
+ </div>
105
+ `;
106
+ }
107
+
108
+ function ScheduledJobs({ jobs }) {
109
+ if (!jobs || jobs.length === 0) return null;
110
+
111
+ return html`
112
+ <div>
113
+ <div class="agd-section-header">
114
+ <span class="agd-section-title">${t('profile.agents.activity.scheduledJobs')}</span>
115
+ </div>
116
+ ${jobs.map((job, i) => html`
117
+ <div class="agd-log-entry" key=${job.id || i}>
118
+ <span class="${job.type === 'aimeat' ? 'agd-job-badge-aimeat' : 'agd-job-badge-agent'}">
119
+ ${job.type === 'aimeat' ? t('profile.agents.activity.aimeatJob') : t('profile.agents.activity.agentJob')}
120
+ </span>
121
+ <span class="agd-log-type">${job.name || job.id || '-'}</span>
122
+ <span class="agd-log-msg">${job.cron || ''}</span>
123
+ <span class="agd-log-time">
124
+ ${job.enabled === false ? 'disabled' : ''}
125
+ ${job.lastRunAt ? timeAgo(job.lastRunAt) : ''}
126
+ </span>
127
+ </div>
128
+ `)}
129
+ </div>
130
+ `;
131
+ }
132
+
133
+ function EventLog({ events, onViewMore }) {
134
+ if (!events || events.length === 0) return null;
135
+
136
+ return html`
137
+ <div>
138
+ <div class="agd-section-header">
139
+ <span class="agd-section-title">${t('profile.agents.activity.recentLog')}</span>
140
+ </div>
141
+ <div class="agd-event-log-scroll">
142
+ ${events.map((ev, i) => html`
143
+ <div class="agd-log-entry" key=${ev.id || i}>
144
+ <span class="agd-log-time">${ev.timestamp ? timeAgo(ev.timestamp) : '-'}</span>
145
+ <span class="agd-log-type">${ev.type || ev.event || '-'}</span>
146
+ <span class="agd-log-msg">${ev.message || ''}</span>
147
+ </div>
148
+ `)}
149
+ </div>
150
+ ${onViewMore && html`
151
+ <button class="btn-ghost btn-sm" onClick=${onViewMore}>
152
+ ${t('profile.agents.activity.viewFullLog')}
153
+ </button>
154
+ `}
155
+ </div>
156
+ `;
157
+ }
158
+
159
+ export default function AgentActivitySubtab({ agentName, session, showToast }) {
160
+ const [loading, setLoading] = useState(true);
161
+ const [stats, setStats] = useState(null);
162
+ const [history, setHistory] = useState([]);
163
+ const [jobs, setJobs] = useState([]);
164
+ const [events, setEvents] = useState([]);
165
+ const [selectedDays, setSelectedDays] = useState(30);
166
+ const [logPage, setLogPage] = useState(1);
167
+ const [hasMoreLog, setHasMoreLog] = useState(false);
168
+
169
+ async function loadData(days) {
170
+ const daysToUse = days ?? selectedDays;
171
+ try {
172
+ const [actResp, logResp] = await Promise.all([
173
+ getActivity(agentName, daysToUse),
174
+ getActivityLog(agentName, 1, 20),
175
+ ]);
176
+ setStats(actResp?.data?.activity_stats || null);
177
+ setHistory(actResp?.data?.history || []);
178
+ setJobs(actResp?.data?.scheduled_jobs || []);
179
+ setEvents(logResp?.data?.events || []);
180
+ setHasMoreLog((logResp?.data?.events || []).length >= 20);
181
+ setLogPage(1);
182
+ } catch {
183
+ setStats(null);
184
+ setHistory([]);
185
+ setJobs([]);
186
+ setEvents([]);
187
+ }
188
+ setLoading(false);
189
+ }
190
+
191
+ useEffect(() => {
192
+ setLoading(true);
193
+ loadData();
194
+ }, [agentName]);
195
+
196
+ // Live update listener
197
+ const loadRef = useRef(loadData);
198
+ loadRef.current = loadData;
199
+ useEffect(() => {
200
+ const handler = () => loadRef.current();
201
+ window.addEventListener('aimeat-live-update', handler);
202
+ return () => window.removeEventListener('aimeat-live-update', handler);
203
+ }, []);
204
+
205
+ function handleRangeChange(days) {
206
+ setSelectedDays(days);
207
+ setLoading(true);
208
+ loadData(days);
209
+ }
210
+
211
+ async function handleViewMore() {
212
+ const nextPage = logPage + 1;
213
+ try {
214
+ const resp = await getActivityLog(agentName, nextPage, 20);
215
+ const newEvents = resp?.data?.events || [];
216
+ setEvents(prev => [...prev, ...newEvents]);
217
+ setLogPage(nextPage);
218
+ setHasMoreLog(newEvents.length >= 20);
219
+ } catch {
220
+ // silent
221
+ }
222
+ }
223
+
224
+ if (loading) {
225
+ return html`<div class="agd-empty">${t('profile.loading')}</div>`;
226
+ }
227
+
228
+ const hasAnyData = stats || history.length > 0 || jobs.length > 0 || events.length > 0;
229
+
230
+ if (!hasAnyData) {
231
+ return html`<div class="agd-empty">${t('profile.agents.activity.noActivity')}</div>`;
232
+ }
233
+
234
+ return html`
235
+ <div>
236
+ <${StatsCards} stats=${stats} />
237
+ <${ActivityChart} history=${history} selectedDays=${selectedDays} onRangeChange=${handleRangeChange} />
238
+ <${ScheduledJobs} jobs=${jobs} />
239
+ <${EventLog} events=${events} onViewMore=${hasMoreLog ? handleViewMore : null} />
240
+ </div>
241
+ `;
242
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * @file agents-capabilities-subtab.js
3
+ * @description Capabilities sub-tab for agent detail view.
4
+ * Shows technical skills with type/verification badges,
5
+ * domain knowledge with language tags, and action queue support
6
+ * derived from the agent's scopes.
7
+ * @structure
8
+ * - AgentCapabilitiesSubtab (default export) -- main component
9
+ * - TechnicalSkills -- badge list of technical capabilities
10
+ * - DomainKnowledge -- domain expertise + language tags
11
+ * - ActionQueueSupport -- scope-derived work accept/deliver indicators
12
+ * @version-history
13
+ * v1.0.0 -- 2026-05-22 -- Initial creation for Agent Dashboard Phase 2
14
+ */
15
+ import { h } from 'preact';
16
+ import { useState, useEffect } from 'preact/hooks';
17
+ import htm from 'htm';
18
+ const html = htm.bind(h);
19
+ import { t } from '/js/i18n.js';
20
+ import { getCapabilities } from '/js/services/agent-capabilities.js';
21
+
22
+ function tFallback(key, fallback) {
23
+ const val = t(key);
24
+ return val !== key ? val : fallback;
25
+ }
26
+
27
+ function TechnicalSkills({ capabilities }) {
28
+ if (!capabilities || capabilities.length === 0) return null;
29
+
30
+ return html`
31
+ <div class="agd-directive-section">
32
+ <h4>${tFallback('profile.agents.capabilities.technical', 'Technical Skills')}</h4>
33
+ <div class="agd-cap-list">
34
+ ${capabilities.map(cap => html`
35
+ <span class="agd-cap-badge">
36
+ <span class="agd-cap-name">${cap.name}</span>
37
+ <span class="agd-cap-type agd-cap-type-${cap.type}">${cap.type}</span>
38
+ ${cap.verified
39
+ ? html`<span class="agd-cap-verified">${tFallback('profile.agents.capabilities.verified', 'verified')}</span>`
40
+ : html`<span class="agd-cap-unverified">${tFallback('profile.agents.capabilities.selfReported', 'self-reported')}</span>`
41
+ }
42
+ </span>
43
+ `)}
44
+ </div>
45
+ </div>
46
+ `;
47
+ }
48
+
49
+ function DomainKnowledge({ domains }) {
50
+ if (!domains || domains.length === 0) return null;
51
+
52
+ const languages = domains.filter(d => d.startsWith('Language: '));
53
+ const otherDomains = domains.filter(d => !d.startsWith('Language: '));
54
+
55
+ return html`
56
+ <div class="agd-directive-section">
57
+ <h4>${tFallback('profile.agents.capabilities.domain', 'Domain Knowledge')}</h4>
58
+ ${otherDomains.length > 0 && html`
59
+ <div class="agd-cap-list">
60
+ ${otherDomains.map(d => html`
61
+ <span class="agd-cap-badge agd-cap-domain">${d}</span>
62
+ `)}
63
+ </div>
64
+ `}
65
+ ${languages.length > 0 && html`
66
+ <div class="agd-cap-langs">
67
+ <span class="agd-cap-lang-label">${tFallback('profile.agents.capabilities.languages', 'Languages')}:</span>
68
+ ${languages.map(l => html`
69
+ <span class="agd-cap-badge agd-cap-lang">${l.replace('Language: ', '')}</span>
70
+ `)}
71
+ </div>
72
+ `}
73
+ </div>
74
+ `;
75
+ }
76
+
77
+ function ActionQueueSupport({ scopes }) {
78
+ const scopeList = scopes ?? [];
79
+ const hasAll = scopeList.includes('*');
80
+ const canAccept = hasAll || scopeList.includes('work:accept');
81
+ const canDeliver = hasAll || scopeList.includes('work:deliver');
82
+
83
+ if (!canAccept && !canDeliver) return null;
84
+
85
+ return html`
86
+ <div class="agd-directive-section">
87
+ <h4>${tFallback('profile.agents.capabilities.actionQueue', 'Action Queue Support')}</h4>
88
+ <div class="agd-cap-queue-list">
89
+ ${canAccept && html`
90
+ <div class="agd-cap-queue-item">
91
+ <span class="agd-cap-check">✓</span>
92
+ <span>${tFallback('profile.agents.capabilities.canAccept', 'Can accept work')}</span>
93
+ </div>
94
+ `}
95
+ ${canDeliver && html`
96
+ <div class="agd-cap-queue-item">
97
+ <span class="agd-cap-check">✓</span>
98
+ <span>${tFallback('profile.agents.capabilities.canDeliver', 'Can deliver work')}</span>
99
+ </div>
100
+ `}
101
+ </div>
102
+ </div>
103
+ `;
104
+ }
105
+
106
+ export default function AgentCapabilitiesSubtab({ agentName, session, showToast, agent }) {
107
+ const [techCaps, setTechCaps] = useState(null);
108
+ const [domainCaps, setDomainCaps] = useState(null);
109
+ const [loading, setLoading] = useState(true);
110
+
111
+ useEffect(() => {
112
+ let cancelled = false;
113
+ async function load() {
114
+ setLoading(true);
115
+ try {
116
+ const resp = await getCapabilities(agentName);
117
+ if (cancelled) return;
118
+ setTechCaps(resp?.data?.technical_capabilities ?? []);
119
+ setDomainCaps(resp?.data?.domain_capabilities ?? []);
120
+ } catch {
121
+ if (!cancelled) {
122
+ setTechCaps([]);
123
+ setDomainCaps([]);
124
+ }
125
+ }
126
+ if (!cancelled) setLoading(false);
127
+ }
128
+ load();
129
+ return () => { cancelled = true; };
130
+ }, [agentName]);
131
+
132
+ // Listen for live updates
133
+ useEffect(() => {
134
+ const handler = async () => {
135
+ try {
136
+ const resp = await getCapabilities(agentName);
137
+ setTechCaps(resp?.data?.technical_capabilities ?? []);
138
+ setDomainCaps(resp?.data?.domain_capabilities ?? []);
139
+ } catch { /* ignore */ }
140
+ };
141
+ window.addEventListener('aimeat-live-update', handler);
142
+ return () => window.removeEventListener('aimeat-live-update', handler);
143
+ }, [agentName]);
144
+
145
+ if (loading) {
146
+ return html`<div class="agd-empty">⏳</div>`;
147
+ }
148
+
149
+ const scopes = agent?.default_scopes ?? [];
150
+ const hasTech = techCaps && techCaps.length > 0;
151
+ const hasDomain = domainCaps && domainCaps.length > 0;
152
+ const hasQueue = scopes.includes('*') || scopes.includes('work:accept') || scopes.includes('work:deliver');
153
+
154
+ if (!hasTech && !hasDomain && !hasQueue) {
155
+ return html`<div class="agd-empty">${tFallback('profile.agents.capabilities.empty', 'No capabilities reported yet')}</div>`;
156
+ }
157
+
158
+ return html`
159
+ <div>
160
+ <${TechnicalSkills} capabilities=${techCaps} />
161
+ <${DomainKnowledge} domains=${domainCaps} />
162
+ <${ActionQueueSupport} scopes=${scopes} />
163
+ </div>
164
+ `;
165
+ }
@@ -0,0 +1,292 @@
1
+ /**
2
+ * @file agents-directives-subtab.js
3
+ * @description Directives sub-tab for agent detail view.
4
+ * Shows merged directives with source badges (system/owner/agent),
5
+ * editable agent-level rules, and read-only memory areas and resources.
6
+ * @structure
7
+ * - AgentDirectivesSubtab (default export) -- main component
8
+ * - RulesList -- displays rules with source badges
9
+ * - EditableRules -- editable agent-level rules in edit mode
10
+ * @version-history
11
+ * v1.0.0 -- 2026-05-21 -- Initial creation for Agent Dashboard Phase 1
12
+ */
13
+ import { h } from 'preact';
14
+ import { useState, useEffect, useRef } from 'preact/hooks';
15
+ import htm from 'htm';
16
+ const html = htm.bind(h);
17
+ import { t } from '/js/i18n.js';
18
+ import { getDirectives, upsertDirectives, deleteDirectives } from '/js/services/agent-directives.js';
19
+
20
+ function tFallback(key, fallback) {
21
+ const val = t(key);
22
+ return val !== key ? val : fallback;
23
+ }
24
+
25
+ function sourceLabel(source) {
26
+ return tFallback(`profile.agents.directives.source.${source}`, source.charAt(0).toUpperCase() + source.slice(1));
27
+ }
28
+
29
+ function sourceClass(source) {
30
+ if (source === 'system') return 'agd-source-system';
31
+ if (source === 'owner') return 'agd-source-owner';
32
+ if (source === 'agent') return 'agd-source-agent';
33
+ return 'agd-source-system';
34
+ }
35
+
36
+ function RulesList({ rules }) {
37
+ if (!rules || rules.length === 0) {
38
+ return html`<div class="agd-empty">${tFallback('profile.agents.directives.noRules', 'No rules defined')}</div>`;
39
+ }
40
+ return html`
41
+ <div>
42
+ ${rules.map((rule, i) => html`
43
+ <div class="agd-rule-item" key=${i}>
44
+ <span class="agd-rule-source ${sourceClass(rule.source || 'system')}">${sourceLabel(rule.source || 'system')}</span>
45
+ <span class="agd-rule-text">${rule.text || rule.rule || rule}</span>
46
+ </div>
47
+ `)}
48
+ </div>
49
+ `;
50
+ }
51
+
52
+ function EditableRules({ rules, onChange }) {
53
+ function handleChange(index, value) {
54
+ const updated = [...rules];
55
+ updated[index] = value;
56
+ onChange(updated);
57
+ }
58
+
59
+ function handleRemove(index) {
60
+ const updated = rules.filter((_, i) => i !== index);
61
+ onChange(updated);
62
+ }
63
+
64
+ function handleAdd() {
65
+ onChange([...rules, '']);
66
+ }
67
+
68
+ return html`
69
+ <div>
70
+ ${rules.map((rule, i) => html`
71
+ <div class="agd-rule-edit-row" key=${i}>
72
+ <input type="text" value=${rule} onInput=${(e) => handleChange(i, e.target.value)}
73
+ placeholder=${tFallback('profile.agents.directives.rulePlaceholder', 'Enter a rule or guideline...')} />
74
+ <button class="agd-remove-btn" onClick=${() => handleRemove(i)} title=${tFallback('profile.agents.directives.removeRule', 'Remove')}>
75
+ ×
76
+ </button>
77
+ </div>
78
+ `)}
79
+ <button class="agd-add-btn" onClick=${handleAdd}>
80
+ + ${tFallback('profile.agents.directives.addRule', 'Add rule')}
81
+ </button>
82
+ </div>
83
+ `;
84
+ }
85
+
86
+ export default function AgentDirectivesSubtab({ agentName, session, showToast }) {
87
+ const [directives, setDirectives] = useState(null);
88
+ const [editing, setEditing] = useState(false);
89
+ const [editPurpose, setEditPurpose] = useState('');
90
+ const [editRules, setEditRules] = useState([]);
91
+ const [saving, setSaving] = useState(false);
92
+ const [error, setError] = useState(null);
93
+
94
+ async function loadDirectives() {
95
+ try {
96
+ const resp = await getDirectives(agentName);
97
+ setDirectives(resp?.data || null);
98
+ setError(null);
99
+ } catch (err) {
100
+ // 404 means no directives set yet -- that is fine
101
+ if (err.status === 404) {
102
+ setDirectives({ purpose: '', rules: [], memory_areas: [], resources: [] });
103
+ setError(null);
104
+ } else {
105
+ setError(err.message);
106
+ setDirectives(null);
107
+ }
108
+ }
109
+ }
110
+
111
+ useEffect(() => {
112
+ loadDirectives();
113
+ }, [agentName]);
114
+
115
+ // Live update listener
116
+ const loadRef = useRef(loadDirectives);
117
+ loadRef.current = loadDirectives;
118
+ useEffect(() => {
119
+ const handler = () => loadRef.current();
120
+ window.addEventListener('aimeat-live-update', handler);
121
+ return () => window.removeEventListener('aimeat-live-update', handler);
122
+ }, []);
123
+
124
+ function startEditing() {
125
+ // Extract agent-level rules for editing
126
+ const agentRules = (directives?.rules || [])
127
+ .filter(r => (r.source || 'agent') === 'agent')
128
+ .map(r => r.text || r.rule || r);
129
+ setEditPurpose(directives?.agent_purpose || directives?.purpose || '');
130
+ setEditRules(agentRules.length > 0 ? agentRules : ['']);
131
+ setEditing(true);
132
+ }
133
+
134
+ function cancelEditing() {
135
+ setEditing(false);
136
+ setEditPurpose('');
137
+ setEditRules([]);
138
+ }
139
+
140
+ async function handleSave() {
141
+ setSaving(true);
142
+ try {
143
+ const cleanRules = editRules.filter(r => r.trim());
144
+ await upsertDirectives(agentName, {
145
+ purpose: editPurpose.trim() || undefined,
146
+ rules: cleanRules.length > 0 ? cleanRules : undefined,
147
+ });
148
+ showToast(tFallback('profile.agents.directives.saved', 'Directives saved'));
149
+ setEditing(false);
150
+ await loadDirectives();
151
+ } catch (err) {
152
+ showToast(err.message || tFallback('profile.agents.directives.saveError', 'Failed to save'), true);
153
+ }
154
+ setSaving(false);
155
+ }
156
+
157
+ async function handleReset() {
158
+ setSaving(true);
159
+ try {
160
+ await deleteDirectives(agentName);
161
+ showToast(tFallback('profile.agents.directives.reset', 'Directives reset to defaults'));
162
+ setEditing(false);
163
+ await loadDirectives();
164
+ } catch (err) {
165
+ showToast(err.message || tFallback('profile.agents.directives.resetError', 'Failed to reset'), true);
166
+ }
167
+ setSaving(false);
168
+ }
169
+
170
+ if (directives === null && !error) {
171
+ return html`<div class="agd-empty">${t('profile.loading')}</div>`;
172
+ }
173
+
174
+ if (error) {
175
+ return html`<div class="agd-empty">${error}</div>`;
176
+ }
177
+
178
+ const purpose = directives?.purpose || '';
179
+ const rules = directives?.rules || [];
180
+ const memoryAreas = directives?.memory_areas || [];
181
+ const resources = directives?.resources || [];
182
+
183
+ // Separate rules by source for display
184
+ const systemRules = rules.filter(r => r.source === 'system');
185
+ const ownerRules = rules.filter(r => r.source === 'owner');
186
+ const agentRules = rules.filter(r => r.source === 'agent' || (!r.source && typeof r === 'string'));
187
+
188
+ return html`
189
+ <div>
190
+ ${!editing ? html`
191
+ <!-- View mode -->
192
+ <div class="agd-section-header">
193
+ <span class="agd-section-title">${tFallback('profile.agents.directives.title', 'Directives')}</span>
194
+ <div>
195
+ <button class="btn-outline btn-sm" onClick=${(e) => { e.stopPropagation(); startEditing(); }}>
196
+ ${tFallback('profile.agents.directives.edit', 'Edit')}
197
+ </button>
198
+ </div>
199
+ </div>
200
+
201
+ ${purpose && html`
202
+ <div class="agd-directive-section">
203
+ <h4>${tFallback('profile.agents.directives.purpose', 'Purpose')}</h4>
204
+ <div class="agd-purpose-text">${purpose}</div>
205
+ </div>
206
+ `}
207
+
208
+ <div class="agd-directive-section">
209
+ <h4>${tFallback('profile.agents.directives.rules', 'Rules')}</h4>
210
+ ${rules.length > 0 ? html`<${RulesList} rules=${rules} />` : html`
211
+ <div class="agd-empty">${tFallback('profile.agents.directives.noRules', 'No rules defined')}</div>
212
+ `}
213
+ </div>
214
+
215
+ ${memoryAreas.length > 0 && html`
216
+ <div class="agd-directive-section">
217
+ <h4>${tFallback('profile.agents.directives.memoryAreas', 'Memory Areas')}</h4>
218
+ ${memoryAreas.map(area => html`
219
+ <div class="agd-list-item" key=${area.key || area}>
220
+ <code>${area.key || area}</code>
221
+ ${area.access && html` -- ${area.access}`}
222
+ ${area.description && html` -- ${area.description}`}
223
+ </div>
224
+ `)}
225
+ </div>
226
+ `}
227
+
228
+ ${resources.length > 0 && html`
229
+ <div class="agd-directive-section">
230
+ <h4>${tFallback('profile.agents.directives.resources', 'Resources')}</h4>
231
+ ${resources.map(res => html`
232
+ <div class="agd-list-item" key=${res.url || res}>
233
+ <code>${res.url || res}</code>
234
+ ${res.description && html` -- ${res.description}`}
235
+ </div>
236
+ `)}
237
+ </div>
238
+ `}
239
+
240
+ ${!purpose && rules.length === 0 && memoryAreas.length === 0 && resources.length === 0 && html`
241
+ <div class="agd-empty">
242
+ ${tFallback('profile.agents.directives.empty', 'No directives configured for this agent. Click Edit to add rules and purpose.')}
243
+ </div>
244
+ `}
245
+ ` : html`
246
+ <!-- Edit mode -->
247
+ <div class="agd-section-header">
248
+ <span class="agd-section-title">${tFallback('profile.agents.directives.editing', 'Editing Directives')}</span>
249
+ </div>
250
+
251
+ <div class="agd-directive-section">
252
+ <h4>${tFallback('profile.agents.directives.purpose', 'Purpose')}</h4>
253
+ <div class="agd-form-field">
254
+ <textarea value=${editPurpose} onInput=${(e) => setEditPurpose(e.target.value)}
255
+ placeholder=${tFallback('profile.agents.directives.purposePlaceholder', 'What is this agent for?')}></textarea>
256
+ </div>
257
+ </div>
258
+
259
+ ${systemRules.length > 0 && html`
260
+ <div class="agd-directive-section">
261
+ <h4>${tFallback('profile.agents.directives.systemRules', 'System Rules')} (${tFallback('profile.agents.directives.readOnly', 'read-only')})</h4>
262
+ <${RulesList} rules=${systemRules} />
263
+ </div>
264
+ `}
265
+
266
+ ${ownerRules.length > 0 && html`
267
+ <div class="agd-directive-section">
268
+ <h4>${tFallback('profile.agents.directives.ownerRules', 'Owner Rules')} (${tFallback('profile.agents.directives.readOnly', 'read-only')})</h4>
269
+ <${RulesList} rules=${ownerRules} />
270
+ </div>
271
+ `}
272
+
273
+ <div class="agd-directive-section">
274
+ <h4>${tFallback('profile.agents.directives.agentRules', 'Agent Rules')}</h4>
275
+ <${EditableRules} rules=${editRules} onChange=${setEditRules} />
276
+ </div>
277
+
278
+ <div class="agd-form-actions">
279
+ <button class="btn-primary btn-sm" onClick=${(e) => { e.stopPropagation(); handleSave(); }} disabled=${saving}>
280
+ ${saving ? tFallback('profile.agents.directives.saving', 'Saving...') : tFallback('profile.agents.directives.save', 'Save')}
281
+ </button>
282
+ <button class="btn-outline btn-sm" onClick=${(e) => { e.stopPropagation(); cancelEditing(); }}>
283
+ ${t('profile.agents.scopeUi.cancel')}
284
+ </button>
285
+ <button class="btn-danger btn-sm" onClick=${(e) => { e.stopPropagation(); handleReset(); }} disabled=${saving}>
286
+ ${tFallback('profile.agents.directives.resetDefaults', 'Reset to Defaults')}
287
+ </button>
288
+ </div>
289
+ `}
290
+ </div>
291
+ `;
292
+ }