@soleri/core 2.1.0 → 2.5.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 (377) hide show
  1. package/dist/brain/brain.d.ts +10 -1
  2. package/dist/brain/brain.d.ts.map +1 -1
  3. package/dist/brain/brain.js +116 -13
  4. package/dist/brain/brain.js.map +1 -1
  5. package/dist/brain/intelligence.d.ts +36 -1
  6. package/dist/brain/intelligence.d.ts.map +1 -1
  7. package/dist/brain/intelligence.js +119 -14
  8. package/dist/brain/intelligence.js.map +1 -1
  9. package/dist/brain/types.d.ts +34 -2
  10. package/dist/brain/types.d.ts.map +1 -1
  11. package/dist/cognee/client.d.ts +3 -0
  12. package/dist/cognee/client.d.ts.map +1 -1
  13. package/dist/cognee/client.js +17 -0
  14. package/dist/cognee/client.js.map +1 -1
  15. package/dist/cognee/sync-manager.d.ts +94 -0
  16. package/dist/cognee/sync-manager.d.ts.map +1 -0
  17. package/dist/cognee/sync-manager.js +293 -0
  18. package/dist/cognee/sync-manager.js.map +1 -0
  19. package/dist/control/identity-manager.d.ts +22 -0
  20. package/dist/control/identity-manager.d.ts.map +1 -0
  21. package/dist/control/identity-manager.js +233 -0
  22. package/dist/control/identity-manager.js.map +1 -0
  23. package/dist/control/intent-router.d.ts +32 -0
  24. package/dist/control/intent-router.d.ts.map +1 -0
  25. package/dist/control/intent-router.js +242 -0
  26. package/dist/control/intent-router.js.map +1 -0
  27. package/dist/control/types.d.ts +68 -0
  28. package/dist/control/types.d.ts.map +1 -0
  29. package/dist/control/types.js +9 -0
  30. package/dist/control/types.js.map +1 -0
  31. package/dist/curator/curator.d.ts +37 -1
  32. package/dist/curator/curator.d.ts.map +1 -1
  33. package/dist/curator/curator.js +199 -1
  34. package/dist/curator/curator.js.map +1 -1
  35. package/dist/errors/classify.d.ts +13 -0
  36. package/dist/errors/classify.d.ts.map +1 -0
  37. package/dist/errors/classify.js +97 -0
  38. package/dist/errors/classify.js.map +1 -0
  39. package/dist/errors/index.d.ts +6 -0
  40. package/dist/errors/index.d.ts.map +1 -0
  41. package/dist/errors/index.js +4 -0
  42. package/dist/errors/index.js.map +1 -0
  43. package/dist/errors/retry.d.ts +40 -0
  44. package/dist/errors/retry.d.ts.map +1 -0
  45. package/dist/errors/retry.js +97 -0
  46. package/dist/errors/retry.js.map +1 -0
  47. package/dist/errors/types.d.ts +48 -0
  48. package/dist/errors/types.d.ts.map +1 -0
  49. package/dist/errors/types.js +59 -0
  50. package/dist/errors/types.js.map +1 -0
  51. package/dist/facades/types.d.ts +1 -1
  52. package/dist/governance/governance.d.ts +42 -0
  53. package/dist/governance/governance.d.ts.map +1 -0
  54. package/dist/governance/governance.js +488 -0
  55. package/dist/governance/governance.js.map +1 -0
  56. package/dist/governance/index.d.ts +3 -0
  57. package/dist/governance/index.d.ts.map +1 -0
  58. package/dist/governance/index.js +2 -0
  59. package/dist/governance/index.js.map +1 -0
  60. package/dist/governance/types.d.ts +102 -0
  61. package/dist/governance/types.d.ts.map +1 -0
  62. package/dist/governance/types.js +3 -0
  63. package/dist/governance/types.js.map +1 -0
  64. package/dist/index.d.ts +52 -3
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +47 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/intake/content-classifier.d.ts +14 -0
  69. package/dist/intake/content-classifier.d.ts.map +1 -0
  70. package/dist/intake/content-classifier.js +125 -0
  71. package/dist/intake/content-classifier.js.map +1 -0
  72. package/dist/intake/dedup-gate.d.ts +17 -0
  73. package/dist/intake/dedup-gate.d.ts.map +1 -0
  74. package/dist/intake/dedup-gate.js +66 -0
  75. package/dist/intake/dedup-gate.js.map +1 -0
  76. package/dist/intake/intake-pipeline.d.ts +63 -0
  77. package/dist/intake/intake-pipeline.d.ts.map +1 -0
  78. package/dist/intake/intake-pipeline.js +373 -0
  79. package/dist/intake/intake-pipeline.js.map +1 -0
  80. package/dist/intake/types.d.ts +65 -0
  81. package/dist/intake/types.d.ts.map +1 -0
  82. package/dist/intake/types.js +3 -0
  83. package/dist/intake/types.js.map +1 -0
  84. package/dist/intelligence/loader.js +1 -1
  85. package/dist/intelligence/loader.js.map +1 -1
  86. package/dist/intelligence/types.d.ts +3 -1
  87. package/dist/intelligence/types.d.ts.map +1 -1
  88. package/dist/logging/logger.d.ts +37 -0
  89. package/dist/logging/logger.d.ts.map +1 -0
  90. package/dist/logging/logger.js +145 -0
  91. package/dist/logging/logger.js.map +1 -0
  92. package/dist/logging/types.d.ts +19 -0
  93. package/dist/logging/types.d.ts.map +1 -0
  94. package/dist/logging/types.js +2 -0
  95. package/dist/logging/types.js.map +1 -0
  96. package/dist/loop/loop-manager.d.ts +100 -0
  97. package/dist/loop/loop-manager.d.ts.map +1 -0
  98. package/dist/loop/loop-manager.js +379 -0
  99. package/dist/loop/loop-manager.js.map +1 -0
  100. package/dist/loop/types.d.ts +103 -0
  101. package/dist/loop/types.d.ts.map +1 -0
  102. package/dist/loop/types.js +11 -0
  103. package/dist/loop/types.js.map +1 -0
  104. package/dist/persistence/index.d.ts +3 -0
  105. package/dist/persistence/index.d.ts.map +1 -0
  106. package/dist/persistence/index.js +2 -0
  107. package/dist/persistence/index.js.map +1 -0
  108. package/dist/persistence/sqlite-provider.d.ts +25 -0
  109. package/dist/persistence/sqlite-provider.d.ts.map +1 -0
  110. package/dist/persistence/sqlite-provider.js +59 -0
  111. package/dist/persistence/sqlite-provider.js.map +1 -0
  112. package/dist/persistence/types.d.ts +36 -0
  113. package/dist/persistence/types.d.ts.map +1 -0
  114. package/dist/persistence/types.js +8 -0
  115. package/dist/persistence/types.js.map +1 -0
  116. package/dist/planning/gap-analysis.d.ts +72 -0
  117. package/dist/planning/gap-analysis.d.ts.map +1 -0
  118. package/dist/planning/gap-analysis.js +442 -0
  119. package/dist/planning/gap-analysis.js.map +1 -0
  120. package/dist/planning/gap-types.d.ts +29 -0
  121. package/dist/planning/gap-types.d.ts.map +1 -0
  122. package/dist/planning/gap-types.js +28 -0
  123. package/dist/planning/gap-types.js.map +1 -0
  124. package/dist/planning/planner.d.ts +421 -4
  125. package/dist/planning/planner.d.ts.map +1 -1
  126. package/dist/planning/planner.js +949 -21
  127. package/dist/planning/planner.js.map +1 -1
  128. package/dist/playbooks/generic/brainstorming.d.ts +9 -0
  129. package/dist/playbooks/generic/brainstorming.d.ts.map +1 -0
  130. package/dist/playbooks/generic/brainstorming.js +105 -0
  131. package/dist/playbooks/generic/brainstorming.js.map +1 -0
  132. package/dist/playbooks/generic/code-review.d.ts +11 -0
  133. package/dist/playbooks/generic/code-review.d.ts.map +1 -0
  134. package/dist/playbooks/generic/code-review.js +176 -0
  135. package/dist/playbooks/generic/code-review.js.map +1 -0
  136. package/dist/playbooks/generic/subagent-execution.d.ts +9 -0
  137. package/dist/playbooks/generic/subagent-execution.d.ts.map +1 -0
  138. package/dist/playbooks/generic/subagent-execution.js +68 -0
  139. package/dist/playbooks/generic/subagent-execution.js.map +1 -0
  140. package/dist/playbooks/generic/systematic-debugging.d.ts +9 -0
  141. package/dist/playbooks/generic/systematic-debugging.d.ts.map +1 -0
  142. package/dist/playbooks/generic/systematic-debugging.js +87 -0
  143. package/dist/playbooks/generic/systematic-debugging.js.map +1 -0
  144. package/dist/playbooks/generic/tdd.d.ts +9 -0
  145. package/dist/playbooks/generic/tdd.d.ts.map +1 -0
  146. package/dist/playbooks/generic/tdd.js +70 -0
  147. package/dist/playbooks/generic/tdd.js.map +1 -0
  148. package/dist/playbooks/generic/verification.d.ts +9 -0
  149. package/dist/playbooks/generic/verification.d.ts.map +1 -0
  150. package/dist/playbooks/generic/verification.js +74 -0
  151. package/dist/playbooks/generic/verification.js.map +1 -0
  152. package/dist/playbooks/index.d.ts +4 -0
  153. package/dist/playbooks/index.d.ts.map +1 -0
  154. package/dist/playbooks/index.js +5 -0
  155. package/dist/playbooks/index.js.map +1 -0
  156. package/dist/playbooks/playbook-registry.d.ts +42 -0
  157. package/dist/playbooks/playbook-registry.d.ts.map +1 -0
  158. package/dist/playbooks/playbook-registry.js +227 -0
  159. package/dist/playbooks/playbook-registry.js.map +1 -0
  160. package/dist/playbooks/playbook-seeder.d.ts +47 -0
  161. package/dist/playbooks/playbook-seeder.d.ts.map +1 -0
  162. package/dist/playbooks/playbook-seeder.js +104 -0
  163. package/dist/playbooks/playbook-seeder.js.map +1 -0
  164. package/dist/playbooks/playbook-types.d.ts +132 -0
  165. package/dist/playbooks/playbook-types.d.ts.map +1 -0
  166. package/dist/playbooks/playbook-types.js +12 -0
  167. package/dist/playbooks/playbook-types.js.map +1 -0
  168. package/dist/project/project-registry.d.ts +79 -0
  169. package/dist/project/project-registry.d.ts.map +1 -0
  170. package/dist/project/project-registry.js +274 -0
  171. package/dist/project/project-registry.js.map +1 -0
  172. package/dist/project/types.d.ts +28 -0
  173. package/dist/project/types.d.ts.map +1 -0
  174. package/dist/project/types.js +5 -0
  175. package/dist/project/types.js.map +1 -0
  176. package/dist/prompts/index.d.ts +4 -0
  177. package/dist/prompts/index.d.ts.map +1 -0
  178. package/dist/prompts/index.js +3 -0
  179. package/dist/prompts/index.js.map +1 -0
  180. package/dist/prompts/parser.d.ts +17 -0
  181. package/dist/prompts/parser.d.ts.map +1 -0
  182. package/dist/prompts/parser.js +47 -0
  183. package/dist/prompts/parser.js.map +1 -0
  184. package/dist/prompts/template-manager.d.ts +25 -0
  185. package/dist/prompts/template-manager.d.ts.map +1 -0
  186. package/dist/prompts/template-manager.js +71 -0
  187. package/dist/prompts/template-manager.js.map +1 -0
  188. package/dist/prompts/types.d.ts +26 -0
  189. package/dist/prompts/types.d.ts.map +1 -0
  190. package/dist/prompts/types.js +5 -0
  191. package/dist/prompts/types.js.map +1 -0
  192. package/dist/runtime/admin-extra-ops.d.ts +15 -0
  193. package/dist/runtime/admin-extra-ops.d.ts.map +1 -0
  194. package/dist/runtime/admin-extra-ops.js +595 -0
  195. package/dist/runtime/admin-extra-ops.js.map +1 -0
  196. package/dist/runtime/admin-ops.d.ts +15 -0
  197. package/dist/runtime/admin-ops.d.ts.map +1 -0
  198. package/dist/runtime/admin-ops.js +329 -0
  199. package/dist/runtime/admin-ops.js.map +1 -0
  200. package/dist/runtime/capture-ops.d.ts +15 -0
  201. package/dist/runtime/capture-ops.d.ts.map +1 -0
  202. package/dist/runtime/capture-ops.js +363 -0
  203. package/dist/runtime/capture-ops.js.map +1 -0
  204. package/dist/runtime/cognee-sync-ops.d.ts +12 -0
  205. package/dist/runtime/cognee-sync-ops.d.ts.map +1 -0
  206. package/dist/runtime/cognee-sync-ops.js +55 -0
  207. package/dist/runtime/cognee-sync-ops.js.map +1 -0
  208. package/dist/runtime/core-ops.d.ts +9 -3
  209. package/dist/runtime/core-ops.d.ts.map +1 -1
  210. package/dist/runtime/core-ops.js +693 -10
  211. package/dist/runtime/core-ops.js.map +1 -1
  212. package/dist/runtime/curator-extra-ops.d.ts +9 -0
  213. package/dist/runtime/curator-extra-ops.d.ts.map +1 -0
  214. package/dist/runtime/curator-extra-ops.js +71 -0
  215. package/dist/runtime/curator-extra-ops.js.map +1 -0
  216. package/dist/runtime/domain-ops.d.ts.map +1 -1
  217. package/dist/runtime/domain-ops.js +61 -15
  218. package/dist/runtime/domain-ops.js.map +1 -1
  219. package/dist/runtime/grading-ops.d.ts +14 -0
  220. package/dist/runtime/grading-ops.d.ts.map +1 -0
  221. package/dist/runtime/grading-ops.js +105 -0
  222. package/dist/runtime/grading-ops.js.map +1 -0
  223. package/dist/runtime/intake-ops.d.ts +14 -0
  224. package/dist/runtime/intake-ops.d.ts.map +1 -0
  225. package/dist/runtime/intake-ops.js +110 -0
  226. package/dist/runtime/intake-ops.js.map +1 -0
  227. package/dist/runtime/loop-ops.d.ts +14 -0
  228. package/dist/runtime/loop-ops.d.ts.map +1 -0
  229. package/dist/runtime/loop-ops.js +251 -0
  230. package/dist/runtime/loop-ops.js.map +1 -0
  231. package/dist/runtime/memory-cross-project-ops.d.ts +12 -0
  232. package/dist/runtime/memory-cross-project-ops.d.ts.map +1 -0
  233. package/dist/runtime/memory-cross-project-ops.js +165 -0
  234. package/dist/runtime/memory-cross-project-ops.js.map +1 -0
  235. package/dist/runtime/memory-extra-ops.d.ts +13 -0
  236. package/dist/runtime/memory-extra-ops.d.ts.map +1 -0
  237. package/dist/runtime/memory-extra-ops.js +173 -0
  238. package/dist/runtime/memory-extra-ops.js.map +1 -0
  239. package/dist/runtime/orchestrate-ops.d.ts +17 -0
  240. package/dist/runtime/orchestrate-ops.d.ts.map +1 -0
  241. package/dist/runtime/orchestrate-ops.js +246 -0
  242. package/dist/runtime/orchestrate-ops.js.map +1 -0
  243. package/dist/runtime/planning-extra-ops.d.ts +25 -0
  244. package/dist/runtime/planning-extra-ops.d.ts.map +1 -0
  245. package/dist/runtime/planning-extra-ops.js +663 -0
  246. package/dist/runtime/planning-extra-ops.js.map +1 -0
  247. package/dist/runtime/playbook-ops.d.ts +14 -0
  248. package/dist/runtime/playbook-ops.d.ts.map +1 -0
  249. package/dist/runtime/playbook-ops.js +141 -0
  250. package/dist/runtime/playbook-ops.js.map +1 -0
  251. package/dist/runtime/project-ops.d.ts +15 -0
  252. package/dist/runtime/project-ops.d.ts.map +1 -0
  253. package/dist/runtime/project-ops.js +186 -0
  254. package/dist/runtime/project-ops.js.map +1 -0
  255. package/dist/runtime/runtime.d.ts.map +1 -1
  256. package/dist/runtime/runtime.js +65 -3
  257. package/dist/runtime/runtime.js.map +1 -1
  258. package/dist/runtime/types.d.ts +29 -0
  259. package/dist/runtime/types.d.ts.map +1 -1
  260. package/dist/runtime/vault-extra-ops.d.ts +10 -0
  261. package/dist/runtime/vault-extra-ops.d.ts.map +1 -0
  262. package/dist/runtime/vault-extra-ops.js +536 -0
  263. package/dist/runtime/vault-extra-ops.js.map +1 -0
  264. package/dist/telemetry/telemetry.d.ts +48 -0
  265. package/dist/telemetry/telemetry.d.ts.map +1 -0
  266. package/dist/telemetry/telemetry.js +87 -0
  267. package/dist/telemetry/telemetry.js.map +1 -0
  268. package/dist/vault/playbook.d.ts +34 -0
  269. package/dist/vault/playbook.d.ts.map +1 -0
  270. package/dist/vault/playbook.js +60 -0
  271. package/dist/vault/playbook.js.map +1 -0
  272. package/dist/vault/vault.d.ts +97 -4
  273. package/dist/vault/vault.d.ts.map +1 -1
  274. package/dist/vault/vault.js +424 -65
  275. package/dist/vault/vault.js.map +1 -1
  276. package/package.json +7 -3
  277. package/src/__tests__/admin-extra-ops.test.ts +467 -0
  278. package/src/__tests__/admin-ops.test.ts +271 -0
  279. package/src/__tests__/brain-intelligence.test.ts +205 -0
  280. package/src/__tests__/brain.test.ts +134 -3
  281. package/src/__tests__/capture-ops.test.ts +509 -0
  282. package/src/__tests__/cognee-integration.test.ts +80 -0
  283. package/src/__tests__/cognee-sync-manager.test.ts +103 -0
  284. package/src/__tests__/core-ops.test.ts +292 -2
  285. package/src/__tests__/curator-extra-ops.test.ts +381 -0
  286. package/src/__tests__/domain-ops.test.ts +66 -0
  287. package/src/__tests__/errors.test.ts +388 -0
  288. package/src/__tests__/governance.test.ts +522 -0
  289. package/src/__tests__/grading-ops.test.ts +361 -0
  290. package/src/__tests__/identity-manager.test.ts +243 -0
  291. package/src/__tests__/intake-pipeline.test.ts +162 -0
  292. package/src/__tests__/intent-router.test.ts +222 -0
  293. package/src/__tests__/logger.test.ts +200 -0
  294. package/src/__tests__/loop-ops.test.ts +469 -0
  295. package/src/__tests__/memory-cross-project-ops.test.ts +248 -0
  296. package/src/__tests__/memory-extra-ops.test.ts +352 -0
  297. package/src/__tests__/orchestrate-ops.test.ts +289 -0
  298. package/src/__tests__/persistence.test.ts +225 -0
  299. package/src/__tests__/planner.test.ts +416 -7
  300. package/src/__tests__/planning-extra-ops.test.ts +706 -0
  301. package/src/__tests__/playbook-registry.test.ts +326 -0
  302. package/src/__tests__/playbook-seeder.test.ts +163 -0
  303. package/src/__tests__/playbook.test.ts +389 -0
  304. package/src/__tests__/project-ops.test.ts +381 -0
  305. package/src/__tests__/template-manager.test.ts +222 -0
  306. package/src/__tests__/vault-extra-ops.test.ts +482 -0
  307. package/src/brain/brain.ts +185 -16
  308. package/src/brain/intelligence.ts +179 -10
  309. package/src/brain/types.ts +40 -2
  310. package/src/cognee/client.ts +18 -0
  311. package/src/cognee/sync-manager.ts +389 -0
  312. package/src/control/identity-manager.ts +354 -0
  313. package/src/control/intent-router.ts +326 -0
  314. package/src/control/types.ts +102 -0
  315. package/src/curator/curator.ts +295 -1
  316. package/src/errors/classify.ts +102 -0
  317. package/src/errors/index.ts +5 -0
  318. package/src/errors/retry.ts +132 -0
  319. package/src/errors/types.ts +81 -0
  320. package/src/governance/governance.ts +698 -0
  321. package/src/governance/index.ts +18 -0
  322. package/src/governance/types.ts +111 -0
  323. package/src/index.ts +213 -2
  324. package/src/intake/content-classifier.ts +146 -0
  325. package/src/intake/dedup-gate.ts +92 -0
  326. package/src/intake/intake-pipeline.ts +503 -0
  327. package/src/intake/types.ts +69 -0
  328. package/src/intelligence/loader.ts +1 -1
  329. package/src/intelligence/types.ts +3 -1
  330. package/src/logging/logger.ts +154 -0
  331. package/src/logging/types.ts +21 -0
  332. package/src/loop/loop-manager.ts +448 -0
  333. package/src/loop/types.ts +115 -0
  334. package/src/persistence/index.ts +7 -0
  335. package/src/persistence/sqlite-provider.ts +62 -0
  336. package/src/persistence/types.ts +44 -0
  337. package/src/planning/gap-analysis.ts +775 -0
  338. package/src/planning/gap-types.ts +61 -0
  339. package/src/planning/planner.ts +1273 -24
  340. package/src/playbooks/generic/brainstorming.ts +110 -0
  341. package/src/playbooks/generic/code-review.ts +181 -0
  342. package/src/playbooks/generic/subagent-execution.ts +74 -0
  343. package/src/playbooks/generic/systematic-debugging.ts +92 -0
  344. package/src/playbooks/generic/tdd.ts +75 -0
  345. package/src/playbooks/generic/verification.ts +79 -0
  346. package/src/playbooks/index.ts +27 -0
  347. package/src/playbooks/playbook-registry.ts +284 -0
  348. package/src/playbooks/playbook-seeder.ts +119 -0
  349. package/src/playbooks/playbook-types.ts +162 -0
  350. package/src/project/project-registry.ts +370 -0
  351. package/src/project/types.ts +31 -0
  352. package/src/prompts/index.ts +3 -0
  353. package/src/prompts/parser.ts +59 -0
  354. package/src/prompts/template-manager.ts +77 -0
  355. package/src/prompts/types.ts +28 -0
  356. package/src/runtime/admin-extra-ops.ts +652 -0
  357. package/src/runtime/admin-ops.ts +340 -0
  358. package/src/runtime/capture-ops.ts +404 -0
  359. package/src/runtime/cognee-sync-ops.ts +63 -0
  360. package/src/runtime/core-ops.ts +787 -9
  361. package/src/runtime/curator-extra-ops.ts +85 -0
  362. package/src/runtime/domain-ops.ts +67 -15
  363. package/src/runtime/grading-ops.ts +130 -0
  364. package/src/runtime/intake-ops.ts +126 -0
  365. package/src/runtime/loop-ops.ts +277 -0
  366. package/src/runtime/memory-cross-project-ops.ts +191 -0
  367. package/src/runtime/memory-extra-ops.ts +186 -0
  368. package/src/runtime/orchestrate-ops.ts +278 -0
  369. package/src/runtime/planning-extra-ops.ts +718 -0
  370. package/src/runtime/playbook-ops.ts +169 -0
  371. package/src/runtime/project-ops.ts +202 -0
  372. package/src/runtime/runtime.ts +77 -3
  373. package/src/runtime/types.ts +29 -0
  374. package/src/runtime/vault-extra-ops.ts +606 -0
  375. package/src/telemetry/telemetry.ts +118 -0
  376. package/src/vault/playbook.ts +87 -0
  377. package/src/vault/vault.ts +575 -98
@@ -0,0 +1,652 @@
1
+ /**
2
+ * Extended admin operations — 23 ops for production readiness.
3
+ *
4
+ * Groups: telemetry (3), permissions (1), vault analytics (1),
5
+ * search insights (1), module status (1), env (1), gc (1), export config (1),
6
+ * key pool (4), profiles (5), plugins (2), instruction validation (1),
7
+ * hot reload (1).
8
+ */
9
+
10
+ import { z } from 'zod';
11
+ import { readFileSync, existsSync } from 'node:fs';
12
+ import type { OpDefinition } from '../facades/types.js';
13
+ import type { AgentRuntime } from './types.js';
14
+
15
+ type PermissionLevel = 'strict' | 'moderate' | 'permissive';
16
+
17
+ interface ApiToken {
18
+ name: string;
19
+ role: string;
20
+ createdAt: number;
21
+ }
22
+ interface AccountProfile {
23
+ name: string;
24
+ provider: string;
25
+ active: boolean;
26
+ addedAt: number;
27
+ }
28
+ interface PluginInfo {
29
+ id: string;
30
+ name: string;
31
+ status: 'active' | 'inactive' | 'error';
32
+ opsCount: number;
33
+ }
34
+
35
+ /**
36
+ * Create 23 extended admin operations for production observability.
37
+ */
38
+ export function createAdminExtraOps(runtime: AgentRuntime): OpDefinition[] {
39
+ const { vault, brain, cognee, telemetry } = runtime;
40
+
41
+ // In-memory permission level — default 'moderate'
42
+ let permissionLevel: PermissionLevel = 'moderate';
43
+
44
+ return [
45
+ // ─── Telemetry ──────────────────────────────────────────────────
46
+ {
47
+ name: 'admin_telemetry',
48
+ description: 'Get telemetry stats — call counts, success rate, durations, slowest ops.',
49
+ auth: 'read',
50
+ handler: async () => {
51
+ return telemetry.getStats();
52
+ },
53
+ },
54
+ {
55
+ name: 'admin_telemetry_recent',
56
+ description: 'Get recent facade calls — newest first.',
57
+ auth: 'read',
58
+ schema: z.object({
59
+ limit: z.number().optional().default(50),
60
+ }),
61
+ handler: async (params) => {
62
+ const limit = (params.limit as number) ?? 50;
63
+ return telemetry.getRecent(limit);
64
+ },
65
+ },
66
+ {
67
+ name: 'admin_telemetry_reset',
68
+ description: 'Reset telemetry counters — clears all recorded calls.',
69
+ auth: 'write',
70
+ handler: async () => {
71
+ telemetry.reset();
72
+ return { reset: true, message: 'Telemetry counters cleared.' };
73
+ },
74
+ },
75
+
76
+ // ─── Permissions ────────────────────────────────────────────────
77
+ {
78
+ name: 'admin_permissions',
79
+ description: 'Get or set auth enforcement policy (strict, moderate, permissive).',
80
+ auth: 'write',
81
+ schema: z.object({
82
+ action: z.enum(['get', 'set']),
83
+ level: z.enum(['strict', 'moderate', 'permissive']).optional(),
84
+ }),
85
+ handler: async (params) => {
86
+ const action = params.action as string;
87
+ if (action === 'set') {
88
+ const level = params.level as PermissionLevel | undefined;
89
+ if (level) {
90
+ permissionLevel = level;
91
+ }
92
+ }
93
+ return { level: permissionLevel };
94
+ },
95
+ },
96
+
97
+ // ─── Vault Analytics ────────────────────────────────────────────
98
+ {
99
+ name: 'admin_vault_analytics',
100
+ description: 'Vault usage analytics — entries by domain, type, age, tag coverage.',
101
+ auth: 'read',
102
+ handler: async () => {
103
+ try {
104
+ const db = vault.getDb();
105
+ const now = Math.floor(Date.now() / 1000);
106
+ const DAY = 86400;
107
+
108
+ // Entries by domain
109
+ const byDomain = db
110
+ .prepare('SELECT domain, COUNT(*) as count FROM entries GROUP BY domain')
111
+ .all() as Array<{ domain: string; count: number }>;
112
+
113
+ // Entries by type
114
+ const byType = db
115
+ .prepare('SELECT type, COUNT(*) as count FROM entries GROUP BY type')
116
+ .all() as Array<{ type: string; count: number }>;
117
+
118
+ // Entries by age bucket
119
+ const ageBuckets = {
120
+ '0-7d': 0,
121
+ '7-30d': 0,
122
+ '30-90d': 0,
123
+ '90d+': 0,
124
+ };
125
+
126
+ const rows = db.prepare('SELECT created_at FROM entries').all() as Array<{
127
+ created_at: number;
128
+ }>;
129
+
130
+ for (const row of rows) {
131
+ const ageSeconds = now - row.created_at;
132
+ if (ageSeconds <= 7 * DAY) ageBuckets['0-7d']++;
133
+ else if (ageSeconds <= 30 * DAY) ageBuckets['7-30d']++;
134
+ else if (ageSeconds <= 90 * DAY) ageBuckets['30-90d']++;
135
+ else ageBuckets['90d+']++;
136
+ }
137
+
138
+ // Average tags per entry
139
+ const tagRows = db.prepare('SELECT tags FROM entries').all() as Array<{ tags: string }>;
140
+
141
+ let totalTags = 0;
142
+ let noTags = 0;
143
+ let noDescription = 0;
144
+
145
+ for (const row of tagRows) {
146
+ try {
147
+ const tags = JSON.parse(row.tags) as string[];
148
+ totalTags += tags.length;
149
+ if (tags.length === 0) noTags++;
150
+ } catch {
151
+ noTags++;
152
+ }
153
+ }
154
+
155
+ // Entries without descriptions
156
+ const noDescResult = db
157
+ .prepare(
158
+ "SELECT COUNT(*) as count FROM entries WHERE description IS NULL OR description = ''",
159
+ )
160
+ .get() as { count: number } | undefined;
161
+ noDescription = noDescResult?.count ?? 0;
162
+
163
+ const totalEntries = tagRows.length;
164
+
165
+ return {
166
+ totalEntries,
167
+ byDomain: Object.fromEntries(byDomain.map((r) => [r.domain, r.count])),
168
+ byType: Object.fromEntries(byType.map((r) => [r.type, r.count])),
169
+ byAge: ageBuckets,
170
+ avgTagsPerEntry:
171
+ totalEntries > 0 ? Math.round((totalTags / totalEntries) * 10) / 10 : 0,
172
+ entriesWithoutTags: noTags,
173
+ entriesWithoutDescription: noDescription,
174
+ };
175
+ } catch (err) {
176
+ return {
177
+ error: 'Failed to compute vault analytics',
178
+ detail: err instanceof Error ? err.message : String(err),
179
+ };
180
+ }
181
+ },
182
+ },
183
+
184
+ // ─── Search Insights ────────────────────────────────────────────
185
+ {
186
+ name: 'admin_search_insights',
187
+ description: 'Search miss tracking — feedback stats, miss rate, top missed queries.',
188
+ auth: 'read',
189
+ handler: async () => {
190
+ try {
191
+ const feedbackStats = brain.getFeedbackStats();
192
+ const total = feedbackStats.total;
193
+ const rejected = feedbackStats.byAction.dismissed ?? 0;
194
+ const failed = feedbackStats.byAction.failed ?? 0;
195
+ const missCount = rejected + failed;
196
+ const missRate = total > 0 ? Math.round((missCount / total) * 1000) / 1000 : 0;
197
+
198
+ // Top missed queries — get recent feedback with 'dismissed' or 'failed' action
199
+ const db = vault.getDb();
200
+ const missedQueries = db
201
+ .prepare(
202
+ "SELECT query, COUNT(*) as count FROM brain_feedback WHERE action IN ('dismissed', 'failed') GROUP BY query ORDER BY count DESC LIMIT 10",
203
+ )
204
+ .all() as Array<{ query: string; count: number }>;
205
+
206
+ return {
207
+ totalFeedback: total,
208
+ missRate,
209
+ missCount,
210
+ topMissedQueries: missedQueries,
211
+ byAction: feedbackStats.byAction,
212
+ };
213
+ } catch {
214
+ return {
215
+ totalFeedback: 0,
216
+ missRate: 0,
217
+ missCount: 0,
218
+ topMissedQueries: [],
219
+ byAction: {},
220
+ note: 'No feedback data available',
221
+ };
222
+ }
223
+ },
224
+ },
225
+
226
+ // ─── Module Status ──────────────────────────────────────────────
227
+ {
228
+ name: 'admin_module_status',
229
+ description: 'Status of all runtime modules — check each is initialized.',
230
+ auth: 'read',
231
+ handler: async () => {
232
+ const cogneeStatus = cognee.getStatus();
233
+ const llmAvailable = runtime.llmClient.isAvailable();
234
+ const loopStatus = runtime.loop.getStatus();
235
+
236
+ return {
237
+ vault: true,
238
+ brain: true,
239
+ planner: true,
240
+ curator: runtime.curator.getStatus().initialized,
241
+ governance: true,
242
+ cognee: { available: cogneeStatus?.available ?? false },
243
+ loop: { active: loopStatus !== null },
244
+ llm: {
245
+ openai: llmAvailable.openai,
246
+ anthropic: llmAvailable.anthropic,
247
+ },
248
+ };
249
+ },
250
+ },
251
+
252
+ // ─── Environment ────────────────────────────────────────────────
253
+ {
254
+ name: 'admin_env',
255
+ description: 'Safe environment info — node version, platform, memory usage. No secrets.',
256
+ auth: 'read',
257
+ handler: async () => {
258
+ return {
259
+ nodeVersion: process.version,
260
+ platform: process.platform,
261
+ arch: process.arch,
262
+ pid: process.pid,
263
+ memoryUsage: process.memoryUsage(),
264
+ cwd: process.cwd(),
265
+ };
266
+ },
267
+ },
268
+
269
+ // ─── Garbage Collection ─────────────────────────────────────────
270
+ {
271
+ name: 'admin_gc',
272
+ description: 'Trigger garbage collection on in-memory caches — brain, cognee, telemetry.',
273
+ auth: 'write',
274
+ handler: async () => {
275
+ const cleared: string[] = [];
276
+
277
+ try {
278
+ brain.rebuildVocabulary();
279
+ cleared.push('brain');
280
+ } catch {
281
+ // Brain rebuild failed — graceful degradation
282
+ }
283
+
284
+ try {
285
+ cognee.resetPendingCognify();
286
+ cleared.push('cognee');
287
+ } catch {
288
+ // Cognee reset failed — graceful degradation
289
+ }
290
+
291
+ try {
292
+ telemetry.reset();
293
+ cleared.push('telemetry');
294
+ } catch {
295
+ // Telemetry reset failed — graceful degradation
296
+ }
297
+
298
+ return { cleared };
299
+ },
300
+ },
301
+
302
+ // ─── Export Config ──────────────────────────────────────────────
303
+ {
304
+ name: 'admin_export_config',
305
+ description: 'Export full runtime config — agent ID, paths, log level. No secrets.',
306
+ auth: 'read',
307
+ handler: async () => {
308
+ const { agentId, vaultPath, plansPath, logLevel } = runtime.config;
309
+ return {
310
+ agentId,
311
+ vaultPath: vaultPath ?? null,
312
+ plansPath: plansPath ?? null,
313
+ logLevel: logLevel ?? 'info',
314
+ modules: [
315
+ 'vault',
316
+ 'brain',
317
+ 'brainIntelligence',
318
+ 'planner',
319
+ 'curator',
320
+ 'governance',
321
+ 'cognee',
322
+ 'loop',
323
+ 'identityManager',
324
+ 'intentRouter',
325
+ 'llmClient',
326
+ 'telemetry',
327
+ ],
328
+ };
329
+ },
330
+ },
331
+
332
+ // ─── Key Pool (#157) ──────────────────────────────────────────
333
+ {
334
+ name: 'admin_key_pool_status',
335
+ description:
336
+ 'LLM key pool status — pool size, active key index, per-key circuit breaker state (open/closed/half-open).',
337
+ auth: 'read',
338
+ handler: async () => {
339
+ const available = runtime.llmClient.isAvailable();
340
+ return {
341
+ openai: {
342
+ available: available.openai,
343
+ },
344
+ anthropic: {
345
+ available: available.anthropic,
346
+ },
347
+ };
348
+ },
349
+ },
350
+ {
351
+ name: 'admin_create_token',
352
+ description: 'Create a named API token with role-based access.',
353
+ auth: 'admin',
354
+ schema: z.object({
355
+ name: z.string().describe('Token name (unique identifier)'),
356
+ role: z.enum(['read', 'write', 'admin']).describe('Access role'),
357
+ }),
358
+ handler: async (params) => {
359
+ const token: ApiToken = {
360
+ name: params.name as string,
361
+ role: params.role as string,
362
+ createdAt: Date.now(),
363
+ };
364
+ // Store in vault metadata
365
+ vault.add({
366
+ id: `api-token-${token.name}`,
367
+ type: 'rule',
368
+ domain: 'admin',
369
+ title: `API Token: ${token.name}`,
370
+ severity: 'suggestion',
371
+ description: `API token with ${token.role} access`,
372
+ tags: ['api-token', token.role],
373
+ });
374
+ return { created: true, name: token.name, role: token.role };
375
+ },
376
+ },
377
+ {
378
+ name: 'admin_revoke_token',
379
+ description: 'Revoke (delete) a named API token.',
380
+ auth: 'admin',
381
+ schema: z.object({
382
+ name: z.string().describe('Token name to revoke'),
383
+ }),
384
+ handler: async (params) => {
385
+ const removed = vault.remove(`api-token-${params.name}`);
386
+ return { revoked: removed, name: params.name };
387
+ },
388
+ },
389
+ {
390
+ name: 'admin_list_tokens',
391
+ description: 'List all API tokens (names and roles only, no secrets).',
392
+ auth: 'read',
393
+ handler: async () => {
394
+ const entries = vault.list({ domain: 'admin' });
395
+ const tokens = entries
396
+ .filter((e) => e.id.startsWith('api-token-'))
397
+ .map((e) => ({
398
+ name: e.id.replace('api-token-', ''),
399
+ role: e.tags?.find((t) => ['read', 'write', 'admin'].includes(t)) ?? 'unknown',
400
+ }));
401
+ return { tokens, count: tokens.length };
402
+ },
403
+ },
404
+
405
+ // ─── Account Profiles (#158) ─────────────────────────────────
406
+ {
407
+ name: 'admin_add_account',
408
+ description: 'Add an API account profile. Keys are stored in vault, never exposed.',
409
+ auth: 'admin',
410
+ schema: z.object({
411
+ name: z.string().describe('Profile name'),
412
+ provider: z.enum(['openai', 'anthropic']).describe('API provider'),
413
+ }),
414
+ handler: async (params) => {
415
+ const profile: AccountProfile = {
416
+ name: params.name as string,
417
+ provider: params.provider as string,
418
+ active: false,
419
+ addedAt: Date.now(),
420
+ };
421
+ vault.add({
422
+ id: `account-profile-${profile.name}`,
423
+ type: 'rule',
424
+ domain: 'admin',
425
+ title: `Account: ${profile.name} (${profile.provider})`,
426
+ severity: 'suggestion',
427
+ description: `API account profile for ${profile.provider}`,
428
+ tags: ['account-profile', profile.provider],
429
+ });
430
+ return { added: true, name: profile.name, provider: profile.provider };
431
+ },
432
+ },
433
+ {
434
+ name: 'admin_remove_account',
435
+ description: 'Remove an API account profile.',
436
+ auth: 'admin',
437
+ schema: z.object({
438
+ name: z.string().describe('Profile name to remove'),
439
+ }),
440
+ handler: async (params) => {
441
+ const removed = vault.remove(`account-profile-${params.name}`);
442
+ return { removed, name: params.name };
443
+ },
444
+ },
445
+ {
446
+ name: 'admin_rotate_account',
447
+ description: 'Rotate to a different API account profile.',
448
+ auth: 'admin',
449
+ schema: z.object({
450
+ name: z.string().describe('Profile name to activate'),
451
+ }),
452
+ handler: async (params) => {
453
+ const entry = vault.get(`account-profile-${params.name}`);
454
+ if (!entry) return { error: `Account profile not found: ${params.name}` };
455
+ return {
456
+ rotated: true,
457
+ name: params.name,
458
+ note: 'Profile activated (key rotation requires restart)',
459
+ };
460
+ },
461
+ },
462
+ {
463
+ name: 'admin_list_accounts',
464
+ description: 'List all account profiles (names and providers only, no keys).',
465
+ auth: 'read',
466
+ handler: async () => {
467
+ const entries = vault.list({ domain: 'admin' });
468
+ const accounts = entries
469
+ .filter((e) => e.id.startsWith('account-profile-'))
470
+ .map((e) => ({
471
+ name: e.id.replace('account-profile-', ''),
472
+ provider: e.tags?.find((t) => ['openai', 'anthropic'].includes(t)) ?? 'unknown',
473
+ }));
474
+ return { accounts, count: accounts.length };
475
+ },
476
+ },
477
+ {
478
+ name: 'admin_account_status',
479
+ description: 'Get current active account profile status.',
480
+ auth: 'read',
481
+ handler: async () => {
482
+ const available = runtime.llmClient.isAvailable();
483
+ return {
484
+ openai: { available: available.openai },
485
+ anthropic: { available: available.anthropic },
486
+ };
487
+ },
488
+ },
489
+
490
+ // ─── Plugins (#159) ──────────────────────────────────────────
491
+ {
492
+ name: 'admin_list_plugins',
493
+ description: 'List all registered domain plugins and their status.',
494
+ auth: 'read',
495
+ handler: async () => {
496
+ // Plugins are domain facades — discover via vault domains
497
+ const domains = vault.getDomains();
498
+ const plugins: PluginInfo[] = domains
499
+ .filter((d) => d.domain !== 'admin' && d.domain !== 'planning')
500
+ .map((d) => ({
501
+ id: d.domain,
502
+ name: d.domain,
503
+ status: 'active' as const,
504
+ opsCount: 5, // standard domain ops: get_patterns, search, get_entry, capture, remove
505
+ }));
506
+ return { plugins, count: plugins.length };
507
+ },
508
+ },
509
+ {
510
+ name: 'admin_plugin_status',
511
+ description: 'Get detailed status of a specific plugin (domain facade).',
512
+ auth: 'read',
513
+ schema: z.object({
514
+ pluginId: z.string().describe('Plugin/domain ID'),
515
+ }),
516
+ handler: async (params) => {
517
+ const domainId = params.pluginId as string;
518
+ const domainEntries = vault.list({ domain: domainId });
519
+ if (domainEntries.length === 0) {
520
+ return { error: `Plugin not found or empty: ${domainId}` };
521
+ }
522
+ return {
523
+ id: domainId,
524
+ status: 'active',
525
+ entryCount: domainEntries.length,
526
+ opsCount: 5,
527
+ ops: ['get_patterns', 'search', 'get_entry', 'capture', 'remove'],
528
+ };
529
+ },
530
+ },
531
+
532
+ // ─── Hot Reload (#63) ──────────────────────────────────────
533
+ {
534
+ name: 'admin_hot_reload',
535
+ description:
536
+ 'Hot-reload runtime caches — rebuilds brain vocabulary, vault FTS index, and prompt templates. Use after bulk vault changes.',
537
+ auth: 'write',
538
+ handler: async () => {
539
+ const reloaded: string[] = [];
540
+ let brainTerms = 0;
541
+ let templateCount = 0;
542
+
543
+ try {
544
+ brain.rebuildVocabulary();
545
+ brainTerms = brain.getStats().vocabularySize;
546
+ reloaded.push('brain');
547
+ } catch {
548
+ // Graceful degradation
549
+ }
550
+
551
+ try {
552
+ vault.rebuildFtsIndex();
553
+ reloaded.push('vault_fts');
554
+ } catch {
555
+ // Graceful degradation
556
+ }
557
+
558
+ try {
559
+ runtime.templateManager.load();
560
+ templateCount = runtime.templateManager.listTemplates().length;
561
+ reloaded.push('templates');
562
+ } catch {
563
+ // Graceful degradation
564
+ }
565
+
566
+ return { reloaded, brainTerms, templateCount };
567
+ },
568
+ },
569
+
570
+ // ─── Instruction Validation (#160) ───────────────────────────
571
+ {
572
+ name: 'admin_validate_instructions',
573
+ description:
574
+ 'Validate instruction files (CLAUDE.md, SKILL.md) for governance and quality — checks structure, required fields, formatting.',
575
+ auth: 'read',
576
+ schema: z.object({
577
+ filePath: z.string().describe('Path to the instruction file to validate'),
578
+ }),
579
+ handler: async (params) => {
580
+ try {
581
+ const filePath = params.filePath as string;
582
+ if (!existsSync(filePath)) {
583
+ return { valid: false, errors: [{ line: 0, issue: 'File not found' }] };
584
+ }
585
+
586
+ const content = readFileSync(filePath, 'utf-8');
587
+ const errors: Array<{ line: number; issue: string }> = [];
588
+ const warnings: Array<{ line: number; issue: string }> = [];
589
+
590
+ // Check for YAML frontmatter (SKILL.md files)
591
+ if (filePath.endsWith('SKILL.md') || filePath.includes('/skills/')) {
592
+ if (!content.startsWith('---')) {
593
+ errors.push({ line: 1, issue: 'SKILL.md must start with YAML frontmatter (---)' });
594
+ } else {
595
+ const fmEnd = content.indexOf('---', 3);
596
+ if (fmEnd === -1) {
597
+ errors.push({
598
+ line: 1,
599
+ issue: 'YAML frontmatter not closed (missing closing ---)',
600
+ });
601
+ } else {
602
+ const fm = new Set(content.slice(3, fmEnd));
603
+ if (!fm.has('name:'))
604
+ errors.push({ line: 1, issue: 'Missing required field: name' });
605
+ if (!fm.has('description:'))
606
+ errors.push({ line: 1, issue: 'Missing required field: description' });
607
+ }
608
+ }
609
+ }
610
+
611
+ // General checks for any instruction file
612
+ const lines = content.split('\n');
613
+ for (let i = 0; i < lines.length; i++) {
614
+ const line = lines[i];
615
+ // Check for extremely long lines
616
+ if (line.length > 500) {
617
+ warnings.push({ line: i + 1, issue: `Line too long (${line.length} chars)` });
618
+ }
619
+ }
620
+
621
+ // Check for conflicting instructions
622
+ if (content.includes('ALWAYS') && content.includes('NEVER')) {
623
+ const alwaysLines = lines.filter((l) => l.includes('ALWAYS'));
624
+ const neverLines = lines.filter((l) => l.includes('NEVER'));
625
+ if (alwaysLines.length > 5 && neverLines.length > 5) {
626
+ warnings.push({
627
+ line: 0,
628
+ issue: 'Many ALWAYS/NEVER directives — check for contradictions',
629
+ });
630
+ }
631
+ }
632
+
633
+ // Check for empty content
634
+ if (content.trim().length < 10) {
635
+ errors.push({ line: 1, issue: 'File is essentially empty' });
636
+ }
637
+
638
+ return {
639
+ valid: errors.length === 0,
640
+ filePath,
641
+ errors,
642
+ warnings,
643
+ lineCount: lines.length,
644
+ charCount: content.length,
645
+ };
646
+ } catch (err) {
647
+ return { error: (err as Error).message };
648
+ }
649
+ },
650
+ },
651
+ ];
652
+ }