kynjal-cli 3.1.4 → 4.0.1

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 (344) hide show
  1. package/.claude/agents/core/coder.md +1 -1
  2. package/.claude/agents/core/planner.md +2 -2
  3. package/.claude/agents/core/researcher.md +1 -1
  4. package/.claude/agents/core/reviewer.md +1 -1
  5. package/.claude/agents/core/tester.md +1 -1
  6. package/.claude/agents/data/data-ml-model.md +4 -4
  7. package/.claude/agents/development/dev-backend-api.md +4 -4
  8. package/.claude/agents/documentation/docs-api-openapi.md +4 -4
  9. package/.claude/agents/github/code-review-swarm.md +2 -2
  10. package/.claude/agents/github/issue-tracker.md +2 -2
  11. package/.claude/agents/github/pr-manager.md +2 -2
  12. package/.claude/agents/github/release-manager.md +2 -2
  13. package/.claude/agents/github/workflow-automation.md +2 -2
  14. package/.claude/agents/sparc/architecture.md +3 -3
  15. package/.claude/agents/sparc/pseudocode.md +2 -2
  16. package/.claude/agents/sparc/refinement.md +3 -3
  17. package/.claude/agents/sparc/specification.md +2 -2
  18. package/.claude/agents/swarm/adaptive-coordinator.md +1 -1
  19. package/.claude/agents/swarm/hierarchical-coordinator.md +1 -1
  20. package/.claude/agents/swarm/mesh-coordinator.md +1 -1
  21. package/.claude/agents/templates/base-template-generator.md +25 -4
  22. package/.claude/agents/templates/sparc-coordinator.md +3 -3
  23. package/.claude/helpers/auto-commit.sh +1 -1
  24. package/.claude/helpers/auto-memory-hook.mjs +27 -9
  25. package/.claude/helpers/hook-handler.cjs +58 -18
  26. package/.claude/helpers/statusline.cjs +420 -613
  27. package/.claude/helpers/statusline.js +3 -3
  28. package/.claude/settings.json +9 -9
  29. package/.claude/skills/reasoningbank-intelligence/SKILL.md +2 -2
  30. package/.claude/skills/swarm-orchestration/SKILL.md +1 -1
  31. package/README.md +383 -170
  32. package/bin/cli.js +6 -6
  33. package/bin/mcp-server.js +1 -1
  34. package/bin/preinstall.cjs +2 -0
  35. package/dist/src/appliance/gguf-engine.d.ts +91 -0
  36. package/dist/src/appliance/gguf-engine.d.ts.map +1 -0
  37. package/dist/src/appliance/gguf-engine.js +425 -0
  38. package/dist/src/appliance/gguf-engine.js.map +1 -0
  39. package/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
  40. package/dist/src/appliance/ruvllm-bridge.d.ts.map +1 -0
  41. package/dist/src/appliance/ruvllm-bridge.js +292 -0
  42. package/dist/src/appliance/ruvllm-bridge.js.map +1 -0
  43. package/dist/src/appliance/rvfa-builder.d.ts +44 -0
  44. package/dist/src/appliance/rvfa-builder.d.ts.map +1 -0
  45. package/dist/src/appliance/rvfa-builder.js +329 -0
  46. package/dist/src/appliance/rvfa-builder.js.map +1 -0
  47. package/dist/src/appliance/rvfa-distribution.d.ts +97 -0
  48. package/dist/src/appliance/rvfa-distribution.d.ts.map +1 -0
  49. package/dist/src/appliance/rvfa-distribution.js +370 -0
  50. package/dist/src/appliance/rvfa-distribution.js.map +1 -0
  51. package/dist/src/appliance/rvfa-format.d.ts +111 -0
  52. package/dist/src/appliance/rvfa-format.d.ts.map +1 -0
  53. package/dist/src/appliance/rvfa-format.js +393 -0
  54. package/dist/src/appliance/rvfa-format.js.map +1 -0
  55. package/dist/src/appliance/rvfa-runner.d.ts +69 -0
  56. package/dist/src/appliance/rvfa-runner.d.ts.map +1 -0
  57. package/dist/src/appliance/rvfa-runner.js +237 -0
  58. package/dist/src/appliance/rvfa-runner.js.map +1 -0
  59. package/dist/src/appliance/rvfa-signing.d.ts +123 -0
  60. package/dist/src/appliance/rvfa-signing.d.ts.map +1 -0
  61. package/dist/src/appliance/rvfa-signing.js +347 -0
  62. package/dist/src/appliance/rvfa-signing.js.map +1 -0
  63. package/dist/src/commands/agent.d.ts.map +1 -1
  64. package/dist/src/commands/agent.js +121 -21
  65. package/dist/src/commands/agent.js.map +1 -1
  66. package/dist/src/commands/appliance-advanced.d.ts +9 -0
  67. package/dist/src/commands/appliance-advanced.d.ts.map +1 -0
  68. package/dist/src/commands/appliance-advanced.js +215 -0
  69. package/dist/src/commands/appliance-advanced.js.map +1 -0
  70. package/dist/src/commands/appliance.d.ts +8 -0
  71. package/dist/src/commands/appliance.d.ts.map +1 -0
  72. package/dist/src/commands/appliance.js +406 -0
  73. package/dist/src/commands/appliance.js.map +1 -0
  74. package/dist/src/commands/benchmark.js +2 -2
  75. package/dist/src/commands/benchmark.js.map +1 -1
  76. package/dist/src/commands/claims.js +1 -1
  77. package/dist/src/commands/claims.js.map +1 -1
  78. package/dist/src/commands/cleanup.d.ts +13 -0
  79. package/dist/src/commands/cleanup.d.ts.map +1 -0
  80. package/dist/src/commands/cleanup.js +218 -0
  81. package/dist/src/commands/cleanup.js.map +1 -0
  82. package/dist/src/commands/config.js +1 -1
  83. package/dist/src/commands/config.js.map +1 -1
  84. package/dist/src/commands/daemon.d.ts.map +1 -1
  85. package/dist/src/commands/daemon.js +81 -18
  86. package/dist/src/commands/daemon.js.map +1 -1
  87. package/dist/src/commands/deployment.js +1 -1
  88. package/dist/src/commands/deployment.js.map +1 -1
  89. package/dist/src/commands/doctor.d.ts.map +1 -1
  90. package/dist/src/commands/doctor.js +99 -51
  91. package/dist/src/commands/doctor.js.map +1 -1
  92. package/dist/src/commands/embeddings.js +1 -1
  93. package/dist/src/commands/embeddings.js.map +1 -1
  94. package/dist/src/commands/hive-mind.js +26 -26
  95. package/dist/src/commands/hive-mind.js.map +1 -1
  96. package/dist/src/commands/hooks.d.ts.map +1 -1
  97. package/dist/src/commands/hooks.js +800 -100
  98. package/dist/src/commands/hooks.js.map +1 -1
  99. package/dist/src/commands/index.d.ts +9 -2
  100. package/dist/src/commands/index.d.ts.map +1 -1
  101. package/dist/src/commands/index.js +20 -2
  102. package/dist/src/commands/index.js.map +1 -1
  103. package/dist/src/commands/init.d.ts +1 -1
  104. package/dist/src/commands/init.d.ts.map +1 -1
  105. package/dist/src/commands/init.js +22 -18
  106. package/dist/src/commands/init.js.map +1 -1
  107. package/dist/src/commands/mcp.d.ts.map +1 -1
  108. package/dist/src/commands/mcp.js +23 -5
  109. package/dist/src/commands/mcp.js.map +1 -1
  110. package/dist/src/commands/memory.d.ts.map +1 -1
  111. package/dist/src/commands/memory.js +24 -0
  112. package/dist/src/commands/memory.js.map +1 -1
  113. package/dist/src/commands/neural.d.ts.map +1 -1
  114. package/dist/src/commands/neural.js +13 -7
  115. package/dist/src/commands/neural.js.map +1 -1
  116. package/dist/src/commands/performance.js +1 -1
  117. package/dist/src/commands/performance.js.map +1 -1
  118. package/dist/src/commands/plugins.js +1 -1
  119. package/dist/src/commands/plugins.js.map +1 -1
  120. package/dist/src/commands/providers.js +1 -1
  121. package/dist/src/commands/providers.js.map +1 -1
  122. package/dist/src/commands/ruvector/import.js +2 -2
  123. package/dist/src/commands/ruvector/import.js.map +1 -1
  124. package/dist/src/commands/ruvector/index.js +1 -1
  125. package/dist/src/commands/ruvector/index.js.map +1 -1
  126. package/dist/src/commands/ruvector/setup.js +6 -6
  127. package/dist/src/commands/security.d.ts.map +1 -1
  128. package/dist/src/commands/security.js +47 -16
  129. package/dist/src/commands/security.js.map +1 -1
  130. package/dist/src/commands/session.d.ts +1 -1
  131. package/dist/src/commands/session.js +1 -1
  132. package/dist/src/commands/start.d.ts +1 -1
  133. package/dist/src/commands/start.js +12 -12
  134. package/dist/src/commands/start.js.map +1 -1
  135. package/dist/src/commands/status.d.ts +1 -1
  136. package/dist/src/commands/status.d.ts.map +1 -1
  137. package/dist/src/commands/status.js +13 -6
  138. package/dist/src/commands/status.js.map +1 -1
  139. package/dist/src/commands/swarm.js +2 -2
  140. package/dist/src/commands/swarm.js.map +1 -1
  141. package/dist/src/commands/task.d.ts +1 -1
  142. package/dist/src/commands/task.js +1 -1
  143. package/dist/src/commands/transfer-store.js +1 -1
  144. package/dist/src/commands/transfer-store.js.map +1 -1
  145. package/dist/src/config-adapter.js +1 -1
  146. package/dist/src/config-adapter.js.map +1 -1
  147. package/dist/src/index.d.ts +4 -3
  148. package/dist/src/index.d.ts.map +1 -1
  149. package/dist/src/index.js +5 -3
  150. package/dist/src/index.js.map +1 -1
  151. package/dist/src/init/claudemd-generator.js +30 -30
  152. package/dist/src/init/claudemd-generator.js.map +1 -1
  153. package/dist/src/init/executor.d.ts.map +1 -1
  154. package/dist/src/init/executor.js +86 -101
  155. package/dist/src/init/executor.js.map +1 -1
  156. package/dist/src/init/helpers-generator.d.ts.map +1 -1
  157. package/dist/src/init/helpers-generator.js +96 -26
  158. package/dist/src/init/helpers-generator.js.map +1 -1
  159. package/dist/src/init/mcp-generator.d.ts +0 -1
  160. package/dist/src/init/mcp-generator.d.ts.map +1 -1
  161. package/dist/src/init/mcp-generator.js +34 -18
  162. package/dist/src/init/mcp-generator.js.map +1 -1
  163. package/dist/src/init/settings-generator.d.ts.map +1 -1
  164. package/dist/src/init/settings-generator.js +107 -41
  165. package/dist/src/init/settings-generator.js.map +1 -1
  166. package/dist/src/init/statusline-generator.d.ts +16 -8
  167. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  168. package/dist/src/init/statusline-generator.js +537 -1019
  169. package/dist/src/init/statusline-generator.js.map +1 -1
  170. package/dist/src/init/types.d.ts +14 -4
  171. package/dist/src/init/types.d.ts.map +1 -1
  172. package/dist/src/init/types.js +9 -2
  173. package/dist/src/init/types.js.map +1 -1
  174. package/dist/src/mcp-client.d.ts.map +1 -1
  175. package/dist/src/mcp-client.js +10 -0
  176. package/dist/src/mcp-client.js.map +1 -1
  177. package/dist/src/mcp-server.d.ts.map +1 -1
  178. package/dist/src/mcp-server.js +30 -4
  179. package/dist/src/mcp-server.js.map +1 -1
  180. package/dist/src/mcp-tools/agentdb-tools.d.ts +30 -0
  181. package/dist/src/mcp-tools/agentdb-tools.d.ts.map +1 -0
  182. package/dist/src/mcp-tools/agentdb-tools.js +557 -0
  183. package/dist/src/mcp-tools/agentdb-tools.js.map +1 -0
  184. package/dist/src/mcp-tools/browser-tools.js +2 -2
  185. package/dist/src/mcp-tools/browser-tools.js.map +1 -1
  186. package/dist/src/mcp-tools/config-tools.d.ts.map +1 -1
  187. package/dist/src/mcp-tools/config-tools.js +21 -2
  188. package/dist/src/mcp-tools/config-tools.js.map +1 -1
  189. package/dist/src/mcp-tools/coordination-tools.d.ts.map +1 -1
  190. package/dist/src/mcp-tools/coordination-tools.js +192 -13
  191. package/dist/src/mcp-tools/coordination-tools.js.map +1 -1
  192. package/dist/src/mcp-tools/daa-tools.js +5 -5
  193. package/dist/src/mcp-tools/daa-tools.js.map +1 -1
  194. package/dist/src/mcp-tools/github-tools.js +2 -2
  195. package/dist/src/mcp-tools/github-tools.js.map +1 -1
  196. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
  197. package/dist/src/mcp-tools/hive-mind-tools.js +263 -35
  198. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
  199. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  200. package/dist/src/mcp-tools/hooks-tools.js +355 -40
  201. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  202. package/dist/src/mcp-tools/index.d.ts +2 -0
  203. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  204. package/dist/src/mcp-tools/index.js +2 -0
  205. package/dist/src/mcp-tools/index.js.map +1 -1
  206. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  207. package/dist/src/mcp-tools/memory-tools.js +31 -1
  208. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  209. package/dist/src/mcp-tools/neural-tools.d.ts.map +1 -1
  210. package/dist/src/mcp-tools/neural-tools.js +32 -27
  211. package/dist/src/mcp-tools/neural-tools.js.map +1 -1
  212. package/dist/src/mcp-tools/performance-tools.js +1 -1
  213. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  214. package/dist/src/mcp-tools/ruvllm-tools.d.ts +9 -0
  215. package/dist/src/mcp-tools/ruvllm-tools.d.ts.map +1 -0
  216. package/dist/src/mcp-tools/ruvllm-tools.js +283 -0
  217. package/dist/src/mcp-tools/ruvllm-tools.js.map +1 -0
  218. package/dist/src/mcp-tools/swarm-tools.d.ts +2 -1
  219. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  220. package/dist/src/mcp-tools/swarm-tools.js +216 -30
  221. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  222. package/dist/src/mcp-tools/system-tools.d.ts.map +1 -1
  223. package/dist/src/mcp-tools/system-tools.js +109 -6
  224. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  225. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
  226. package/dist/src/mcp-tools/task-tools.js +102 -0
  227. package/dist/src/mcp-tools/task-tools.js.map +1 -1
  228. package/dist/src/mcp-tools/wasm-agent-tools.d.ts +9 -0
  229. package/dist/src/mcp-tools/wasm-agent-tools.d.ts.map +1 -0
  230. package/dist/src/mcp-tools/wasm-agent-tools.js +230 -0
  231. package/dist/src/mcp-tools/wasm-agent-tools.js.map +1 -0
  232. package/dist/src/mcp-tools/workflow-tools.d.ts.map +1 -1
  233. package/dist/src/mcp-tools/workflow-tools.js +91 -0
  234. package/dist/src/mcp-tools/workflow-tools.js.map +1 -1
  235. package/dist/src/memory/ewc-consolidation.d.ts +24 -0
  236. package/dist/src/memory/ewc-consolidation.d.ts.map +1 -1
  237. package/dist/src/memory/ewc-consolidation.js +59 -0
  238. package/dist/src/memory/ewc-consolidation.js.map +1 -1
  239. package/dist/src/memory/intelligence.d.ts +53 -0
  240. package/dist/src/memory/intelligence.d.ts.map +1 -1
  241. package/dist/src/memory/intelligence.js +264 -7
  242. package/dist/src/memory/intelligence.js.map +1 -1
  243. package/dist/src/memory/memory-bridge.d.ts +407 -0
  244. package/dist/src/memory/memory-bridge.d.ts.map +1 -0
  245. package/dist/src/memory/memory-bridge.js +1494 -0
  246. package/dist/src/memory/memory-bridge.js.map +1 -0
  247. package/dist/src/memory/memory-initializer.d.ts +17 -1
  248. package/dist/src/memory/memory-initializer.d.ts.map +1 -1
  249. package/dist/src/memory/memory-initializer.js +320 -42
  250. package/dist/src/memory/memory-initializer.js.map +1 -1
  251. package/dist/src/output.d.ts.map +1 -1
  252. package/dist/src/output.js +1 -0
  253. package/dist/src/output.js.map +1 -1
  254. package/dist/src/parser.d.ts +10 -0
  255. package/dist/src/parser.d.ts.map +1 -1
  256. package/dist/src/parser.js +49 -3
  257. package/dist/src/parser.js.map +1 -1
  258. package/dist/src/plugins/manager.d.ts.map +1 -1
  259. package/dist/src/plugins/manager.js +31 -14
  260. package/dist/src/plugins/manager.js.map +1 -1
  261. package/dist/src/plugins/store/discovery.js +5 -5
  262. package/dist/src/plugins/store/discovery.js.map +1 -1
  263. package/dist/src/plugins/tests/standalone-test.js +4 -4
  264. package/dist/src/plugins/tests/standalone-test.js.map +1 -1
  265. package/dist/src/production/error-handler.js +1 -1
  266. package/dist/src/production/error-handler.js.map +1 -1
  267. package/dist/src/runtime/headless.d.ts +3 -3
  268. package/dist/src/runtime/headless.js +6 -6
  269. package/dist/src/runtime/headless.js.map +1 -1
  270. package/dist/src/ruvector/agent-wasm.d.ts +182 -0
  271. package/dist/src/ruvector/agent-wasm.d.ts.map +1 -0
  272. package/dist/src/ruvector/agent-wasm.js +316 -0
  273. package/dist/src/ruvector/agent-wasm.js.map +1 -0
  274. package/dist/src/ruvector/enhanced-model-router.d.ts.map +1 -1
  275. package/dist/src/ruvector/enhanced-model-router.js +25 -15
  276. package/dist/src/ruvector/enhanced-model-router.js.map +1 -1
  277. package/dist/src/ruvector/index.d.ts +7 -1
  278. package/dist/src/ruvector/index.d.ts.map +1 -1
  279. package/dist/src/ruvector/index.js +17 -1
  280. package/dist/src/ruvector/index.js.map +1 -1
  281. package/dist/src/ruvector/ruvllm-wasm.d.ts +179 -0
  282. package/dist/src/ruvector/ruvllm-wasm.d.ts.map +1 -0
  283. package/dist/src/ruvector/ruvllm-wasm.js +363 -0
  284. package/dist/src/ruvector/ruvllm-wasm.js.map +1 -0
  285. package/dist/src/services/agentic-flow-bridge.d.ts +50 -0
  286. package/dist/src/services/agentic-flow-bridge.d.ts.map +1 -0
  287. package/dist/src/services/agentic-flow-bridge.js +95 -0
  288. package/dist/src/services/agentic-flow-bridge.js.map +1 -0
  289. package/dist/src/services/claim-service.js +1 -1
  290. package/dist/src/services/claim-service.js.map +1 -1
  291. package/dist/src/services/container-worker-pool.d.ts.map +1 -1
  292. package/dist/src/services/container-worker-pool.js +3 -1
  293. package/dist/src/services/container-worker-pool.js.map +1 -1
  294. package/dist/src/services/index.d.ts +1 -1
  295. package/dist/src/services/index.d.ts.map +1 -1
  296. package/dist/src/services/registry-api.d.ts +1 -1
  297. package/dist/src/services/registry-api.js +1 -1
  298. package/dist/src/services/ruvector-training.d.ts +11 -2
  299. package/dist/src/services/ruvector-training.d.ts.map +1 -1
  300. package/dist/src/services/ruvector-training.js +233 -43
  301. package/dist/src/services/ruvector-training.js.map +1 -1
  302. package/dist/src/services/worker-daemon.d.ts +28 -3
  303. package/dist/src/services/worker-daemon.d.ts.map +1 -1
  304. package/dist/src/services/worker-daemon.js +156 -17
  305. package/dist/src/services/worker-daemon.js.map +1 -1
  306. package/dist/src/services/worker-queue.d.ts.map +1 -1
  307. package/dist/src/services/worker-queue.js +2 -0
  308. package/dist/src/services/worker-queue.js.map +1 -1
  309. package/dist/src/transfer/deploy-seraphine.d.ts +1 -1
  310. package/dist/src/transfer/deploy-seraphine.js +4 -4
  311. package/dist/src/transfer/deploy-seraphine.js.map +1 -1
  312. package/dist/src/transfer/ipfs/client.d.ts.map +1 -1
  313. package/dist/src/transfer/ipfs/client.js +8 -0
  314. package/dist/src/transfer/ipfs/client.js.map +1 -1
  315. package/dist/src/transfer/ipfs/upload.d.ts.map +1 -1
  316. package/dist/src/transfer/ipfs/upload.js +0 -2
  317. package/dist/src/transfer/ipfs/upload.js.map +1 -1
  318. package/dist/src/transfer/models/seraphine.d.ts +1 -1
  319. package/dist/src/transfer/models/seraphine.js +5 -5
  320. package/dist/src/transfer/models/seraphine.js.map +1 -1
  321. package/dist/src/transfer/serialization/cfp.d.ts +1 -1
  322. package/dist/src/transfer/serialization/cfp.d.ts.map +1 -1
  323. package/dist/src/transfer/serialization/cfp.js +9 -6
  324. package/dist/src/transfer/serialization/cfp.js.map +1 -1
  325. package/dist/src/transfer/storage/gcs.d.ts.map +1 -1
  326. package/dist/src/transfer/storage/gcs.js +71 -29
  327. package/dist/src/transfer/storage/gcs.js.map +1 -1
  328. package/dist/src/transfer/store/discovery.js +4 -4
  329. package/dist/src/transfer/store/discovery.js.map +1 -1
  330. package/dist/src/transfer/store/registry.js +1 -1
  331. package/dist/src/transfer/store/registry.js.map +1 -1
  332. package/dist/src/transfer/store/tests/standalone-test.js +4 -4
  333. package/dist/src/transfer/store/tests/standalone-test.js.map +1 -1
  334. package/dist/src/transfer/types.d.ts +1 -1
  335. package/dist/src/types.d.ts +1 -1
  336. package/dist/src/types.js +1 -1
  337. package/dist/src/update/validator.js +1 -1
  338. package/dist/src/update/validator.js.map +1 -1
  339. package/dist/tsconfig.tsbuildinfo +1 -1
  340. package/package.json +13 -10
  341. package/.claude/agents/custom/accessibility-auditor.yaml +0 -56
  342. package/.claude/agents/custom/design-architect.yaml +0 -48
  343. package/.claude/agents/custom/ui-developer.yaml +0 -46
  344. package/.claude/agents/custom/ux-researcher.yaml +0 -60
@@ -0,0 +1,347 @@
1
+ /**
2
+ * RVFA Ed25519 Code Signing -- Digital signatures for RVFA appliance files.
3
+ *
4
+ * Provides tamper detection and publisher identity verification using
5
+ * Ed25519 (RFC 8032) via Node.js native crypto. Zero external dependencies.
6
+ *
7
+ * @module @claude-flow/cli/appliance/rvfa-signing
8
+ */
9
+ import { generateKeyPairSync, createHash, sign, verify, createPublicKey, createPrivateKey, } from 'node:crypto';
10
+ import { readFile, writeFile, stat, chmod, mkdir } from 'node:fs/promises';
11
+ // ── Constants ────────────────────────────────────────────────
12
+ const PREAMBLE_SIZE = 12; // 4B magic + 4B version + 4B header_len
13
+ const SHA256_SIZE = 32;
14
+ const KEY_FILE_MODE = 0o600;
15
+ // ── Key Management ───────────────────────────────────────────
16
+ /** Compute the fingerprint of a public key: first 16 hex chars of its SHA256. */
17
+ function computeFingerprint(publicKeyPem) {
18
+ return createHash('sha256')
19
+ .update(publicKeyPem, 'utf-8')
20
+ .digest('hex')
21
+ .slice(0, 16);
22
+ }
23
+ /**
24
+ * Generate a new Ed25519 key pair for RVFA signing.
25
+ */
26
+ export async function generateKeyPair() {
27
+ const { publicKey, privateKey } = generateKeyPairSync('ed25519', {
28
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
29
+ privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
30
+ });
31
+ const pubBuf = Buffer.from(publicKey, 'utf-8');
32
+ const privBuf = Buffer.from(privateKey, 'utf-8');
33
+ const fingerprint = computeFingerprint(publicKey);
34
+ return { publicKey: pubBuf, privateKey: privBuf, fingerprint };
35
+ }
36
+ /**
37
+ * Save a key pair to disk as PEM files.
38
+ *
39
+ * @param keyPair The key pair to persist.
40
+ * @param dir Directory to write files into.
41
+ * @param name Base name for the key files (default: 'rvfa-signing').
42
+ * @returns Paths to the written public and private key files.
43
+ */
44
+ export async function saveKeyPair(keyPair, dir, name = 'rvfa-signing') {
45
+ await mkdir(dir, { recursive: true });
46
+ const pubPath = `${dir}/${name}.pub`;
47
+ const privPath = `${dir}/${name}.key`;
48
+ await writeFile(pubPath, keyPair.publicKey);
49
+ await writeFile(privPath, keyPair.privateKey, { mode: KEY_FILE_MODE });
50
+ // Ensure private key has restrictive permissions even on existing files
51
+ await chmod(privPath, KEY_FILE_MODE);
52
+ return { publicKeyPath: pubPath, privateKeyPath: privPath };
53
+ }
54
+ /**
55
+ * Load a key pair from PEM files on disk.
56
+ *
57
+ * @param dir Directory containing the key files.
58
+ * @param name Base name for the key files (default: 'rvfa-signing').
59
+ */
60
+ export async function loadKeyPair(dir, name = 'rvfa-signing') {
61
+ const pubPath = `${dir}/${name}.pub`;
62
+ const privPath = `${dir}/${name}.key`;
63
+ const publicKey = await readFile(pubPath);
64
+ const privateKey = await readFile(privPath);
65
+ // Warn if private key permissions are too open
66
+ const privStat = await stat(privPath);
67
+ const mode = privStat.mode & 0o777;
68
+ if (mode & 0o077) {
69
+ console.warn(`[rvfa-signing] WARNING: Private key ${privPath} has open permissions ` +
70
+ `(${mode.toString(8)}). Consider running: chmod 600 ${privPath}`);
71
+ }
72
+ const fingerprint = computeFingerprint(publicKey.toString('utf-8'));
73
+ return { publicKey, privateKey, fingerprint };
74
+ }
75
+ /**
76
+ * Load a public key from a single PEM file.
77
+ */
78
+ export async function loadPublicKey(path) {
79
+ return readFile(path);
80
+ }
81
+ // ── Internal Helpers ─────────────────────────────────────────
82
+ /**
83
+ * Recursively sort object keys for canonical JSON serialization.
84
+ * Produces deterministic output regardless of insertion order.
85
+ */
86
+ function canonicalJson(value) {
87
+ return JSON.stringify(value, (_key, val) => {
88
+ if (val !== null && typeof val === 'object' && !Array.isArray(val) && !Buffer.isBuffer(val)) {
89
+ const sorted = {};
90
+ for (const k of Object.keys(val).sort()) {
91
+ sorted[k] = val[k];
92
+ }
93
+ return sorted;
94
+ }
95
+ return val;
96
+ });
97
+ }
98
+ /**
99
+ * Parse an RVFA binary into its components without full validation.
100
+ * Returns the header object, header JSON bytes, section data region, and footer.
101
+ */
102
+ function parseRvfaBinary(buf) {
103
+ if (buf.length < PREAMBLE_SIZE + SHA256_SIZE) {
104
+ throw new Error('Buffer too small to be a valid RVFA file');
105
+ }
106
+ const magic = buf.subarray(0, 4).toString('ascii');
107
+ if (magic !== 'RVFA') {
108
+ throw new Error(`Invalid RVFA magic: expected "RVFA", got "${magic}"`);
109
+ }
110
+ const headerLen = buf.readUInt32LE(8);
111
+ const headerStart = PREAMBLE_SIZE;
112
+ const headerEnd = headerStart + headerLen;
113
+ if (headerEnd > buf.length - SHA256_SIZE) {
114
+ throw new Error('Header length extends beyond buffer');
115
+ }
116
+ const headerJson = buf.subarray(headerStart, headerEnd).toString('utf-8');
117
+ let header;
118
+ try {
119
+ header = JSON.parse(headerJson);
120
+ }
121
+ catch {
122
+ throw new Error('Failed to parse RVFA header JSON');
123
+ }
124
+ const footer = buf.subarray(buf.length - SHA256_SIZE);
125
+ const sectionData = buf.subarray(headerEnd, buf.length - SHA256_SIZE);
126
+ return { header, headerStart, headerEnd, sectionData, footer };
127
+ }
128
+ /**
129
+ * Compute the signing digest for an RVFA file.
130
+ *
131
+ * The digest is SHA256 of: canonical_header_json (without signature field)
132
+ * + section_data_bytes
133
+ * + footer_32_bytes
134
+ */
135
+ function computeSigningDigest(header, sectionData, footer) {
136
+ // Strip signature field from header for digest computation
137
+ const stripped = { ...header };
138
+ delete stripped.signature;
139
+ const canonical = Buffer.from(canonicalJson(stripped), 'utf-8');
140
+ return createHash('sha256')
141
+ .update(canonical)
142
+ .update(sectionData)
143
+ .update(footer)
144
+ .digest();
145
+ }
146
+ /** Convert a Buffer or PEM string into a KeyObject. */
147
+ function toPrivateKeyObject(key) {
148
+ const pem = Buffer.isBuffer(key) ? key.toString('utf-8') : key;
149
+ return createPrivateKey(pem);
150
+ }
151
+ /** Convert a Buffer or PEM string into a KeyObject. */
152
+ function toPublicKeyObject(key) {
153
+ const pem = Buffer.isBuffer(key) ? key.toString('utf-8') : key;
154
+ return createPublicKey(pem);
155
+ }
156
+ /**
157
+ * Rebuild the RVFA binary with an updated header.
158
+ *
159
+ * Preserves the original preamble version, recalculates header length,
160
+ * and keeps section data and footer intact.
161
+ */
162
+ function rebuildRvfa(originalBuf, newHeader, sectionData, footer) {
163
+ const headerJson = Buffer.from(JSON.stringify(newHeader), 'utf-8');
164
+ // Preamble: magic + version + new header length
165
+ const preamble = Buffer.alloc(PREAMBLE_SIZE);
166
+ originalBuf.copy(preamble, 0, 0, 8); // magic + version unchanged
167
+ preamble.writeUInt32LE(headerJson.length, 8);
168
+ return Buffer.concat([preamble, headerJson, sectionData, footer]);
169
+ }
170
+ // ── RvfaSigner ───────────────────────────────────────────────
171
+ /**
172
+ * Signs RVFA appliance files and data with Ed25519.
173
+ */
174
+ export class RvfaSigner {
175
+ keyObj;
176
+ fingerprint;
177
+ constructor(privateKey) {
178
+ this.keyObj = toPrivateKeyObject(privateKey);
179
+ // Derive public key to compute fingerprint
180
+ const pubPem = createPublicKey(this.keyObj)
181
+ .export({ type: 'spki', format: 'pem' });
182
+ this.fingerprint = computeFingerprint(pubPem);
183
+ }
184
+ /**
185
+ * Sign an RVFA appliance file in-place.
186
+ *
187
+ * Algorithm:
188
+ * 1. Read and parse the RVFA binary
189
+ * 2. Strip any existing signature from the header
190
+ * 3. Compute SHA256 of [canonical_header + section_data + footer]
191
+ * 4. Sign the digest with Ed25519
192
+ * 5. Embed signature metadata into the header
193
+ * 6. Write the updated binary back to the file
194
+ *
195
+ * @param rvfaPath Path to the .rvf appliance file.
196
+ * @param signedBy Optional publisher name.
197
+ * @returns The signature metadata that was embedded.
198
+ */
199
+ async signAppliance(rvfaPath, signedBy) {
200
+ const buf = await readFile(rvfaPath);
201
+ const { header, sectionData, footer } = parseRvfaBinary(buf);
202
+ // Compute digest over header (without signature) + sections + footer
203
+ const digest = computeSigningDigest(header, sectionData, footer);
204
+ // Ed25519 sign
205
+ const sig = sign(null, digest, this.keyObj);
206
+ const metadata = {
207
+ algorithm: 'ed25519',
208
+ publicKeyFingerprint: this.fingerprint,
209
+ signature: sig.toString('hex'),
210
+ signedAt: new Date().toISOString(),
211
+ signedBy,
212
+ scope: 'full',
213
+ };
214
+ // Embed signature in header and rebuild
215
+ header.signature = metadata;
216
+ const rebuilt = rebuildRvfa(buf, header, sectionData, footer);
217
+ await writeFile(rvfaPath, rebuilt);
218
+ return metadata;
219
+ }
220
+ /**
221
+ * Sign a section footer hash (detached signature).
222
+ *
223
+ * @param footerHash The 32-byte SHA256 footer hash from an RVFA file.
224
+ * @returns Hex-encoded Ed25519 signature.
225
+ */
226
+ async signSections(footerHash) {
227
+ if (footerHash.length !== SHA256_SIZE) {
228
+ throw new Error(`Footer hash must be ${SHA256_SIZE} bytes, got ${footerHash.length}`);
229
+ }
230
+ const sig = sign(null, footerHash, this.keyObj);
231
+ return sig.toString('hex');
232
+ }
233
+ /**
234
+ * Sign an RVFP patch file (detached signature).
235
+ *
236
+ * @param patchData The raw patch binary data.
237
+ * @returns Hex-encoded Ed25519 signature.
238
+ */
239
+ async signPatch(patchData) {
240
+ const digest = createHash('sha256').update(patchData).digest();
241
+ const sig = sign(null, digest, this.keyObj);
242
+ return sig.toString('hex');
243
+ }
244
+ }
245
+ // ── RvfaVerifier ─────────────────────────────────────────────
246
+ /**
247
+ * Verifies Ed25519 signatures on RVFA appliance files and data.
248
+ */
249
+ export class RvfaVerifier {
250
+ keyObj;
251
+ fingerprint;
252
+ constructor(publicKey) {
253
+ this.keyObj = toPublicKeyObject(publicKey);
254
+ const pem = Buffer.isBuffer(publicKey) ? publicKey.toString('utf-8') : publicKey;
255
+ this.fingerprint = computeFingerprint(pem);
256
+ }
257
+ /**
258
+ * Verify the Ed25519 signature embedded in an RVFA appliance file.
259
+ *
260
+ * @param rvfaPath Path to the .rvf appliance file.
261
+ * @returns Verification result with details and any errors.
262
+ */
263
+ async verifyAppliance(rvfaPath) {
264
+ const errors = [];
265
+ let buf;
266
+ try {
267
+ buf = await readFile(rvfaPath);
268
+ }
269
+ catch (err) {
270
+ return { valid: false, errors: [`Failed to read file: ${err.message}`] };
271
+ }
272
+ let parsed;
273
+ try {
274
+ parsed = parseRvfaBinary(buf);
275
+ }
276
+ catch (err) {
277
+ return { valid: false, errors: [`Invalid RVFA file: ${err.message}`] };
278
+ }
279
+ const { header, sectionData, footer } = parsed;
280
+ // Extract signature metadata from header
281
+ const sigRaw = header.signature;
282
+ if (!sigRaw || typeof sigRaw !== 'object') {
283
+ return { valid: false, errors: ['No signature found in RVFA header'] };
284
+ }
285
+ const sigMeta = sigRaw;
286
+ if (sigMeta.algorithm !== 'ed25519') {
287
+ errors.push(`Unsupported algorithm: ${String(sigMeta.algorithm)}`);
288
+ return { valid: false, errors };
289
+ }
290
+ if (typeof sigMeta.signature !== 'string' || !sigMeta.signature) {
291
+ errors.push('Signature field is missing or empty');
292
+ return { valid: false, errors };
293
+ }
294
+ // Recompute the digest the same way the signer did
295
+ const digest = computeSigningDigest(header, sectionData, footer);
296
+ // Verify
297
+ let sigBuf;
298
+ try {
299
+ sigBuf = Buffer.from(sigMeta.signature, 'hex');
300
+ }
301
+ catch {
302
+ errors.push('Signature is not valid hex');
303
+ return { valid: false, errors };
304
+ }
305
+ let valid;
306
+ try {
307
+ valid = verify(null, digest, this.keyObj, sigBuf);
308
+ }
309
+ catch (err) {
310
+ errors.push(`Verification error: ${err.message}`);
311
+ return { valid: false, errors };
312
+ }
313
+ if (!valid) {
314
+ errors.push('Ed25519 signature verification failed: data may be tampered');
315
+ }
316
+ return {
317
+ valid,
318
+ signerFingerprint: sigMeta.publicKeyFingerprint,
319
+ signedAt: sigMeta.signedAt,
320
+ signedBy: sigMeta.signedBy,
321
+ errors,
322
+ };
323
+ }
324
+ /**
325
+ * Verify a detached Ed25519 signature over arbitrary data.
326
+ *
327
+ * @param data The data that was signed.
328
+ * @param signature Hex-encoded Ed25519 signature.
329
+ */
330
+ async verifyDetached(data, signature) {
331
+ const digest = createHash('sha256').update(data).digest();
332
+ const sigBuf = Buffer.from(signature, 'hex');
333
+ return verify(null, digest, this.keyObj, sigBuf);
334
+ }
335
+ /**
336
+ * Verify an RVFP patch file signature.
337
+ *
338
+ * @param patchData The raw patch binary data.
339
+ * @param signature Hex-encoded Ed25519 signature.
340
+ */
341
+ async verifyPatch(patchData, signature) {
342
+ const digest = createHash('sha256').update(patchData).digest();
343
+ const sigBuf = Buffer.from(signature, 'hex');
344
+ return verify(null, digest, this.keyObj, sigBuf);
345
+ }
346
+ }
347
+ //# sourceMappingURL=rvfa-signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rvfa-signing.js","sourceRoot":"","sources":["../../../src/appliance/rvfa-signing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/commands/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAiC,MAAM,aAAa,CAAC;AAm3B1E,eAAO,MAAM,YAAY,EAAE,OA8B1B,CAAC;AAoCF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/commands/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAiC,MAAM,aAAa,CAAC;AA49B1E,eAAO,MAAM,YAAY,EAAE,OA8B1B,CAAC;AAoCF,eAAe,YAAY,CAAC"}
@@ -5,6 +5,40 @@
5
5
  import { output } from '../output.js';
6
6
  import { select, confirm, input } from '../prompt.js';
7
7
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ /**
11
+ * Update swarm-activity.json metrics after agent count changes.
12
+ * The statusline reads this file to display the swarm agent count.
13
+ */
14
+ function updateSwarmActivityMetrics(agentCountDelta) {
15
+ try {
16
+ const metricsDir = path.join(process.cwd(), '.claude-flow', 'metrics');
17
+ const activityPath = path.join(metricsDir, 'swarm-activity.json');
18
+ let data = {
19
+ timestamp: new Date().toISOString(),
20
+ swarm: { active: false, agent_count: 0, coordination_active: false },
21
+ };
22
+ if (fs.existsSync(activityPath)) {
23
+ data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
24
+ }
25
+ else {
26
+ fs.mkdirSync(metricsDir, { recursive: true });
27
+ }
28
+ const swarm = data.swarm ?? {};
29
+ const currentCount = Math.max(0, swarm.agent_count || 0);
30
+ const newCount = Math.max(0, currentCount + agentCountDelta);
31
+ swarm.agent_count = newCount;
32
+ swarm.active = newCount > 0;
33
+ swarm.coordination_active = newCount > 0;
34
+ data.swarm = swarm;
35
+ data.timestamp = new Date().toISOString();
36
+ fs.writeFileSync(activityPath, JSON.stringify(data, null, 2));
37
+ }
38
+ catch {
39
+ // Non-critical — don't fail the command if metrics update fails
40
+ }
41
+ }
8
42
  // Available agent types with descriptions
9
43
  const AGENT_TYPES = [
10
44
  { value: 'coder', label: 'Coder', hint: 'Code development with neural patterns' },
@@ -130,6 +164,8 @@ const spawnCommand = {
130
164
  });
131
165
  output.writeln();
132
166
  output.printSuccess(`Agent ${agentName} spawned successfully`);
167
+ // Update swarm-activity.json so statusline reflects the new agent count
168
+ updateSwarmActivityMetrics(1);
133
169
  if (ctx.flags.format === 'json') {
134
170
  output.printJson(result);
135
171
  }
@@ -350,6 +386,8 @@ const stopCommand = {
350
386
  output.writeln(output.dim(' Releasing resources...'));
351
387
  }
352
388
  output.printSuccess(`Agent ${agentId} stopped successfully`);
389
+ // Update swarm-activity.json so statusline reflects the reduced agent count
390
+ updateSwarmActivityMetrics(-1);
353
391
  if (ctx.flags.format === 'json') {
354
392
  output.printJson(result);
355
393
  }
@@ -382,26 +420,86 @@ const metricsCommand = {
382
420
  action: async (ctx) => {
383
421
  const agentId = ctx.args[0];
384
422
  const period = ctx.flags.period;
385
- // Default metrics (updated by MCP agent/metrics when available)
423
+ // Collect real metrics from .swarm/ state
424
+ const { existsSync, readFileSync, readdirSync, statSync } = await import('fs');
425
+ const { join } = await import('path');
426
+ let totalAgents = 0;
427
+ let activeAgents = 0;
428
+ let tasksCompleted = 0;
429
+ const typeCounts = {};
430
+ // Read swarm agent state
431
+ const swarmDir = join(process.cwd(), '.swarm');
432
+ const agentsDir = join(swarmDir, 'agents');
433
+ if (existsSync(agentsDir)) {
434
+ try {
435
+ const files = readdirSync(agentsDir).filter(f => f.endsWith('.json'));
436
+ for (const file of files) {
437
+ try {
438
+ const data = JSON.parse(readFileSync(join(agentsDir, file), 'utf-8'));
439
+ totalAgents++;
440
+ const agType = data.type || 'unknown';
441
+ if (!typeCounts[agType])
442
+ typeCounts[agType] = { count: 0, tasks: 0, success: 0 };
443
+ typeCounts[agType].count++;
444
+ if (data.status === 'active' || data.status === 'running')
445
+ activeAgents++;
446
+ if (data.tasksCompleted) {
447
+ typeCounts[agType].tasks += data.tasksCompleted;
448
+ tasksCompleted += data.tasksCompleted;
449
+ }
450
+ if (data.successCount)
451
+ typeCounts[agType].success += data.successCount;
452
+ }
453
+ catch { /* skip malformed */ }
454
+ }
455
+ }
456
+ catch { /* no agents dir */ }
457
+ }
458
+ // Read swarm activity for additional state
459
+ const activityFile = join(swarmDir, 'swarm-activity.json');
460
+ if (existsSync(activityFile)) {
461
+ try {
462
+ const activity = JSON.parse(readFileSync(activityFile, 'utf-8'));
463
+ if (activity.totalAgents && totalAgents === 0)
464
+ totalAgents = activity.totalAgents;
465
+ if (activity.activeAgents && activeAgents === 0)
466
+ activeAgents = activity.activeAgents;
467
+ }
468
+ catch { /* ignore */ }
469
+ }
470
+ // Read memory.db stats
471
+ let vectorCount = 0;
472
+ const dbPath = join(swarmDir, 'memory.db');
473
+ if (existsSync(dbPath)) {
474
+ try {
475
+ const dbSize = statSync(dbPath).size;
476
+ vectorCount = Math.floor(dbSize / 2048);
477
+ }
478
+ catch { /* ignore */ }
479
+ }
480
+ const byType = Object.entries(typeCounts).map(([type, data]) => ({
481
+ type,
482
+ count: data.count,
483
+ tasks: data.tasks,
484
+ successRate: data.tasks > 0 ? `${Math.round((data.success / data.tasks) * 100)}%` : 'N/A'
485
+ }));
486
+ const avgSuccessRate = tasksCompleted > 0
487
+ ? `${Math.round(Object.values(typeCounts).reduce((a, d) => a + d.success, 0) / tasksCompleted * 100)}%`
488
+ : 'N/A';
386
489
  const metrics = {
387
490
  period,
388
491
  summary: {
389
- totalAgents: 4,
390
- activeAgents: 3,
391
- tasksCompleted: 127,
392
- avgSuccessRate: '96.2%',
393
- totalTokens: 1234567,
394
- avgResponseTime: '1.45s'
492
+ totalAgents,
493
+ activeAgents,
494
+ tasksCompleted,
495
+ avgSuccessRate,
496
+ vectorCount,
497
+ note: totalAgents === 0 ? 'No agents spawned yet. Use: agent spawn -t coder' : undefined
395
498
  },
396
- byType: [
397
- { type: 'coder', count: 2, tasks: 45, successRate: '97%' },
398
- { type: 'researcher', count: 1, tasks: 32, successRate: '95%' },
399
- { type: 'tester', count: 1, tasks: 50, successRate: '98%' }
400
- ],
499
+ byType,
401
500
  performance: {
402
- flashAttention: '2.8x speedup',
403
- memoryReduction: '52%',
404
- searchImprovement: '150x faster'
501
+ memoryVectors: `${vectorCount} vectors`,
502
+ searchBackend: vectorCount > 0 ? 'HNSW-indexed' : 'none'
405
503
  }
406
504
  };
407
505
  if (ctx.flags.format === 'json') {
@@ -421,8 +519,7 @@ const metricsCommand = {
421
519
  { metric: 'Active Agents', value: metrics.summary.activeAgents },
422
520
  { metric: 'Tasks Completed', value: metrics.summary.tasksCompleted },
423
521
  { metric: 'Success Rate', value: metrics.summary.avgSuccessRate },
424
- { metric: 'Total Tokens', value: metrics.summary.totalTokens.toLocaleString() },
425
- { metric: 'Avg Response Time', value: metrics.summary.avgResponseTime }
522
+ { metric: 'Memory Vectors', value: metrics.summary.vectorCount }
426
523
  ]
427
524
  });
428
525
  output.writeln();
@@ -436,12 +533,15 @@ const metricsCommand = {
436
533
  ],
437
534
  data: metrics.byType
438
535
  });
536
+ if (metrics.summary.note) {
537
+ output.writeln();
538
+ output.writeln(output.dim(metrics.summary.note));
539
+ }
439
540
  output.writeln();
440
- output.writeln(output.bold('V3 Performance Gains'));
541
+ output.writeln(output.bold('Memory'));
441
542
  output.printList([
442
- `Flash Attention: ${output.success(metrics.performance.flashAttention)}`,
443
- `Memory Reduction: ${output.success(metrics.performance.memoryReduction)}`,
444
- `Search: ${output.success(metrics.performance.searchImprovement)}`
543
+ `Vectors: ${output.success(metrics.performance.memoryVectors)}`,
544
+ `Backend: ${output.success(metrics.performance.searchBackend)}`
445
545
  ]);
446
546
  return { success: true, data: metrics };
447
547
  }