groove-dev 0.27.92 → 0.27.94

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 (501) hide show
  1. package/moe-training/package.json +2 -1
  2. package/node_modules/@groove-dev/cli/package.json +1 -1
  3. package/node_modules/@groove-dev/daemon/package.json +1 -1
  4. package/node_modules/@groove-dev/daemon/src/api.js +17 -9
  5. package/node_modules/@groove-dev/daemon/src/process.js +2 -0
  6. package/node_modules/@groove-dev/gui/dist/assets/{codemirror-BBL3i_JW.js → codemirror-CFF1Lrnz.js} +10 -10
  7. package/{packages/gui/dist/assets/index-DWv32qyJ.js → node_modules/@groove-dev/gui/dist/assets/index-B3GUKInH.js} +1740 -1740
  8. package/{packages/gui/dist/assets/index-Bo6AeNmM.css → node_modules/@groove-dev/gui/dist/assets/index-C1k-GuDg.css} +1 -1
  9. package/node_modules/@groove-dev/gui/dist/index.html +3 -3
  10. package/node_modules/@groove-dev/gui/package.json +1 -1
  11. package/node_modules/@groove-dev/gui/src/components/agents/agent-panel.jsx +2 -0
  12. package/node_modules/@groove-dev/gui/src/components/editor/code-editor.jsx +3 -3
  13. package/node_modules/@groove-dev/gui/src/stores/groove.js +23 -16
  14. package/node_modules/@groove-dev/gui/src/views/agents.jsx +44 -113
  15. package/node_modules/base64-js/LICENSE +21 -0
  16. package/node_modules/base64-js/README.md +34 -0
  17. package/node_modules/base64-js/base64js.min.js +1 -0
  18. package/node_modules/base64-js/index.d.ts +3 -0
  19. package/node_modules/base64-js/index.js +150 -0
  20. package/node_modules/base64-js/package.json +47 -0
  21. package/node_modules/better-sqlite3/LICENSE +21 -0
  22. package/node_modules/better-sqlite3/README.md +99 -0
  23. package/node_modules/better-sqlite3/binding.gyp +38 -0
  24. package/node_modules/better-sqlite3/deps/common.gypi +68 -0
  25. package/node_modules/better-sqlite3/deps/copy.js +31 -0
  26. package/node_modules/better-sqlite3/deps/defines.gypi +41 -0
  27. package/node_modules/better-sqlite3/deps/download.sh +122 -0
  28. package/node_modules/better-sqlite3/deps/patches/1208.patch +15 -0
  29. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c +268845 -0
  30. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.h +14335 -0
  31. package/node_modules/better-sqlite3/deps/sqlite3/sqlite3ext.h +739 -0
  32. package/node_modules/better-sqlite3/deps/sqlite3.gyp +80 -0
  33. package/node_modules/better-sqlite3/deps/test_extension.c +21 -0
  34. package/node_modules/better-sqlite3/lib/database.js +90 -0
  35. package/node_modules/better-sqlite3/lib/index.js +3 -0
  36. package/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
  37. package/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
  38. package/node_modules/better-sqlite3/lib/methods/function.js +31 -0
  39. package/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
  40. package/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
  41. package/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
  42. package/node_modules/better-sqlite3/lib/methods/table.js +189 -0
  43. package/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
  44. package/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
  45. package/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
  46. package/node_modules/better-sqlite3/lib/util.js +12 -0
  47. package/node_modules/better-sqlite3/package.json +59 -0
  48. package/node_modules/better-sqlite3/src/addon.cpp +47 -0
  49. package/node_modules/better-sqlite3/src/better_sqlite3.cpp +74 -0
  50. package/node_modules/better-sqlite3/src/objects/backup.cpp +120 -0
  51. package/node_modules/better-sqlite3/src/objects/backup.hpp +36 -0
  52. package/node_modules/better-sqlite3/src/objects/database.cpp +417 -0
  53. package/node_modules/better-sqlite3/src/objects/database.hpp +103 -0
  54. package/node_modules/better-sqlite3/src/objects/statement-iterator.cpp +113 -0
  55. package/node_modules/better-sqlite3/src/objects/statement-iterator.hpp +50 -0
  56. package/node_modules/better-sqlite3/src/objects/statement.cpp +383 -0
  57. package/node_modules/better-sqlite3/src/objects/statement.hpp +58 -0
  58. package/node_modules/better-sqlite3/src/util/bind-map.cpp +73 -0
  59. package/node_modules/better-sqlite3/src/util/binder.cpp +193 -0
  60. package/node_modules/better-sqlite3/src/util/constants.cpp +172 -0
  61. package/node_modules/better-sqlite3/src/util/custom-aggregate.cpp +121 -0
  62. package/node_modules/better-sqlite3/src/util/custom-function.cpp +59 -0
  63. package/node_modules/better-sqlite3/src/util/custom-table.cpp +409 -0
  64. package/node_modules/better-sqlite3/src/util/data-converter.cpp +17 -0
  65. package/node_modules/better-sqlite3/src/util/data.cpp +194 -0
  66. package/node_modules/better-sqlite3/src/util/helpers.cpp +109 -0
  67. package/node_modules/better-sqlite3/src/util/macros.cpp +83 -0
  68. package/node_modules/better-sqlite3/src/util/query-macros.cpp +71 -0
  69. package/node_modules/better-sqlite3/src/util/row-builder.cpp +49 -0
  70. package/node_modules/bindings/LICENSE.md +22 -0
  71. package/node_modules/bindings/README.md +98 -0
  72. package/node_modules/bindings/bindings.js +221 -0
  73. package/node_modules/bindings/package.json +28 -0
  74. package/node_modules/bl/.travis.yml +17 -0
  75. package/node_modules/bl/BufferList.js +396 -0
  76. package/node_modules/bl/LICENSE.md +13 -0
  77. package/node_modules/bl/README.md +247 -0
  78. package/node_modules/bl/bl.js +84 -0
  79. package/node_modules/bl/package.json +37 -0
  80. package/node_modules/bl/test/convert.js +21 -0
  81. package/node_modules/bl/test/indexOf.js +492 -0
  82. package/node_modules/bl/test/isBufferList.js +32 -0
  83. package/node_modules/bl/test/test.js +869 -0
  84. package/node_modules/buffer/AUTHORS.md +70 -0
  85. package/node_modules/buffer/LICENSE +21 -0
  86. package/node_modules/buffer/README.md +410 -0
  87. package/node_modules/buffer/index.d.ts +186 -0
  88. package/node_modules/buffer/index.js +1817 -0
  89. package/node_modules/buffer/package.json +96 -0
  90. package/node_modules/decompress-response/index.d.ts +22 -0
  91. package/node_modules/decompress-response/index.js +58 -0
  92. package/node_modules/decompress-response/license +9 -0
  93. package/node_modules/decompress-response/node_modules/mimic-response/index.d.ts +17 -0
  94. package/node_modules/decompress-response/node_modules/mimic-response/index.js +77 -0
  95. package/node_modules/decompress-response/node_modules/mimic-response/license +9 -0
  96. package/node_modules/decompress-response/node_modules/mimic-response/package.json +42 -0
  97. package/node_modules/decompress-response/node_modules/mimic-response/readme.md +78 -0
  98. package/node_modules/decompress-response/package.json +56 -0
  99. package/node_modules/decompress-response/readme.md +48 -0
  100. package/node_modules/deep-extend/LICENSE +20 -0
  101. package/node_modules/deep-extend/README.md +91 -0
  102. package/node_modules/deep-extend/index.js +1 -0
  103. package/node_modules/deep-extend/lib/deep-extend.js +150 -0
  104. package/node_modules/deep-extend/package.json +62 -0
  105. package/node_modules/end-of-stream/LICENSE +21 -0
  106. package/node_modules/end-of-stream/README.md +54 -0
  107. package/node_modules/end-of-stream/index.js +96 -0
  108. package/node_modules/end-of-stream/package.json +37 -0
  109. package/node_modules/expand-template/.travis.yml +6 -0
  110. package/node_modules/expand-template/LICENSE +21 -0
  111. package/node_modules/expand-template/README.md +43 -0
  112. package/node_modules/expand-template/index.js +26 -0
  113. package/node_modules/expand-template/package.json +29 -0
  114. package/node_modules/expand-template/test.js +67 -0
  115. package/node_modules/file-uri-to-path/.npmignore +1 -0
  116. package/node_modules/file-uri-to-path/.travis.yml +30 -0
  117. package/node_modules/file-uri-to-path/History.md +21 -0
  118. package/node_modules/file-uri-to-path/LICENSE +20 -0
  119. package/node_modules/file-uri-to-path/README.md +74 -0
  120. package/node_modules/file-uri-to-path/index.d.ts +2 -0
  121. package/node_modules/file-uri-to-path/index.js +66 -0
  122. package/node_modules/file-uri-to-path/package.json +32 -0
  123. package/node_modules/file-uri-to-path/test/test.js +24 -0
  124. package/node_modules/file-uri-to-path/test/tests.json +13 -0
  125. package/node_modules/fs-constants/LICENSE +21 -0
  126. package/node_modules/fs-constants/README.md +26 -0
  127. package/node_modules/fs-constants/browser.js +1 -0
  128. package/node_modules/fs-constants/index.js +1 -0
  129. package/node_modules/fs-constants/package.json +19 -0
  130. package/node_modules/github-from-package/.travis.yml +4 -0
  131. package/node_modules/github-from-package/LICENSE +18 -0
  132. package/node_modules/github-from-package/example/package.json +8 -0
  133. package/node_modules/github-from-package/example/url.js +3 -0
  134. package/node_modules/github-from-package/index.js +17 -0
  135. package/node_modules/github-from-package/package.json +30 -0
  136. package/node_modules/github-from-package/readme.markdown +53 -0
  137. package/node_modules/github-from-package/test/a.json +8 -0
  138. package/node_modules/github-from-package/test/b.json +5 -0
  139. package/node_modules/github-from-package/test/c.json +5 -0
  140. package/node_modules/github-from-package/test/d.json +7 -0
  141. package/node_modules/github-from-package/test/e.json +5 -0
  142. package/node_modules/github-from-package/test/url.js +19 -0
  143. package/node_modules/ieee754/LICENSE +11 -0
  144. package/node_modules/ieee754/README.md +51 -0
  145. package/node_modules/ieee754/index.d.ts +10 -0
  146. package/node_modules/ieee754/index.js +85 -0
  147. package/node_modules/ieee754/package.json +52 -0
  148. package/node_modules/ini/LICENSE +15 -0
  149. package/node_modules/ini/README.md +102 -0
  150. package/node_modules/ini/ini.js +206 -0
  151. package/node_modules/ini/package.json +33 -0
  152. package/node_modules/minimist/.eslintrc +29 -0
  153. package/node_modules/minimist/.github/FUNDING.yml +12 -0
  154. package/node_modules/minimist/.nycrc +14 -0
  155. package/node_modules/minimist/CHANGELOG.md +298 -0
  156. package/node_modules/minimist/LICENSE +18 -0
  157. package/node_modules/minimist/README.md +121 -0
  158. package/node_modules/minimist/example/parse.js +4 -0
  159. package/node_modules/minimist/index.js +263 -0
  160. package/node_modules/minimist/package.json +75 -0
  161. package/node_modules/minimist/test/all_bool.js +34 -0
  162. package/node_modules/minimist/test/bool.js +177 -0
  163. package/node_modules/minimist/test/dash.js +43 -0
  164. package/node_modules/minimist/test/default_bool.js +37 -0
  165. package/node_modules/minimist/test/dotted.js +24 -0
  166. package/node_modules/minimist/test/kv_short.js +32 -0
  167. package/node_modules/minimist/test/long.js +33 -0
  168. package/node_modules/minimist/test/num.js +38 -0
  169. package/node_modules/minimist/test/parse.js +209 -0
  170. package/node_modules/minimist/test/parse_modified.js +11 -0
  171. package/node_modules/minimist/test/proto.js +64 -0
  172. package/node_modules/minimist/test/short.js +69 -0
  173. package/node_modules/minimist/test/stop_early.js +17 -0
  174. package/node_modules/minimist/test/unknown.js +104 -0
  175. package/node_modules/minimist/test/whitespace.js +10 -0
  176. package/node_modules/mkdirp-classic/LICENSE +21 -0
  177. package/node_modules/mkdirp-classic/README.md +18 -0
  178. package/node_modules/mkdirp-classic/index.js +98 -0
  179. package/node_modules/mkdirp-classic/package.json +18 -0
  180. package/node_modules/moe-training/DEPLOY_CENTRAL_COMMAND.md +413 -0
  181. package/node_modules/moe-training/client/consent.js +96 -0
  182. package/node_modules/moe-training/client/envelope-builder.js +56 -0
  183. package/node_modules/moe-training/client/index.js +10 -0
  184. package/node_modules/moe-training/client/parsers/claude-code.js +108 -0
  185. package/node_modules/moe-training/client/parsers/codex.js +80 -0
  186. package/node_modules/moe-training/client/parsers/gemini.js +80 -0
  187. package/node_modules/moe-training/client/parsers/grok.js +16 -0
  188. package/node_modules/moe-training/client/parsers/index.js +20 -0
  189. package/node_modules/moe-training/client/scrubber.js +128 -0
  190. package/node_modules/moe-training/client/session-attestation.js +115 -0
  191. package/node_modules/moe-training/client/step-classifier.js +68 -0
  192. package/node_modules/moe-training/client/trajectory-capture.js +307 -0
  193. package/node_modules/moe-training/client/transmission-queue.js +104 -0
  194. package/node_modules/moe-training/package.json +21 -0
  195. package/node_modules/moe-training/server/enrichment.js +24 -0
  196. package/node_modules/moe-training/server/index.js +119 -0
  197. package/node_modules/moe-training/server/ledger.js +110 -0
  198. package/node_modules/moe-training/server/routes/ingest.js +96 -0
  199. package/node_modules/moe-training/server/routes/sessions.js +43 -0
  200. package/node_modules/moe-training/server/routes/stats.js +31 -0
  201. package/node_modules/moe-training/server/scoring.js +63 -0
  202. package/node_modules/moe-training/server/session-registry.js +156 -0
  203. package/node_modules/moe-training/server/stats.js +129 -0
  204. package/node_modules/moe-training/server/stitcher.js +69 -0
  205. package/node_modules/moe-training/server/storage.js +147 -0
  206. package/node_modules/moe-training/server/verifier.js +102 -0
  207. package/node_modules/moe-training/shared/constants.js +30 -0
  208. package/node_modules/moe-training/shared/crypto.js +45 -0
  209. package/node_modules/moe-training/shared/envelope-schema.js +220 -0
  210. package/node_modules/moe-training/test/client/consent.test.js +121 -0
  211. package/node_modules/moe-training/test/client/envelope-builder.test.js +107 -0
  212. package/node_modules/moe-training/test/client/parsers/claude-code.test.js +119 -0
  213. package/node_modules/moe-training/test/client/parsers/codex.test.js +83 -0
  214. package/node_modules/moe-training/test/client/parsers/gemini.test.js +99 -0
  215. package/node_modules/moe-training/test/client/scrubber.test.js +143 -0
  216. package/node_modules/moe-training/test/client/session-attestation-security.test.js +95 -0
  217. package/node_modules/moe-training/test/client/step-classifier.test.js +135 -0
  218. package/node_modules/moe-training/test/client/transmission-queue.test.js +33 -0
  219. package/node_modules/moe-training/test/integration/handshake.test.js +260 -0
  220. package/node_modules/moe-training/test/server/ingest-security.test.js +166 -0
  221. package/node_modules/moe-training/test/server/ledger.test.js +131 -0
  222. package/node_modules/moe-training/test/server/scoring.test.js +242 -0
  223. package/node_modules/moe-training/test/server/session-registry.test.js +125 -0
  224. package/node_modules/moe-training/test/server/stitcher.test.js +157 -0
  225. package/node_modules/moe-training/test/server/verifier.test.js +232 -0
  226. package/node_modules/moe-training/test/shared/crypto.test.js +87 -0
  227. package/node_modules/moe-training/test/shared/envelope-schema.test.js +351 -0
  228. package/node_modules/napi-build-utils/.github/workflows/run-npm-tests.yml +31 -0
  229. package/node_modules/napi-build-utils/LICENSE +21 -0
  230. package/node_modules/napi-build-utils/README.md +52 -0
  231. package/node_modules/napi-build-utils/index.js +214 -0
  232. package/node_modules/napi-build-utils/index.md +0 -0
  233. package/node_modules/napi-build-utils/package.json +42 -0
  234. package/node_modules/prebuild-install/CHANGELOG.md +131 -0
  235. package/node_modules/prebuild-install/CONTRIBUTING.md +6 -0
  236. package/node_modules/prebuild-install/LICENSE +21 -0
  237. package/node_modules/prebuild-install/README.md +163 -0
  238. package/node_modules/prebuild-install/asset.js +44 -0
  239. package/node_modules/prebuild-install/bin.js +78 -0
  240. package/node_modules/prebuild-install/download.js +142 -0
  241. package/node_modules/prebuild-install/error.js +14 -0
  242. package/node_modules/prebuild-install/help.txt +16 -0
  243. package/node_modules/prebuild-install/index.js +1 -0
  244. package/node_modules/prebuild-install/log.js +33 -0
  245. package/node_modules/prebuild-install/node_modules/node-abi/LICENSE +21 -0
  246. package/node_modules/prebuild-install/node_modules/node-abi/README.md +54 -0
  247. package/node_modules/prebuild-install/node_modules/node-abi/abi_registry.json +439 -0
  248. package/node_modules/prebuild-install/node_modules/node-abi/index.js +179 -0
  249. package/node_modules/prebuild-install/node_modules/node-abi/package.json +45 -0
  250. package/node_modules/prebuild-install/node_modules/semver/LICENSE +15 -0
  251. package/node_modules/prebuild-install/node_modules/semver/README.md +665 -0
  252. package/node_modules/prebuild-install/node_modules/semver/bin/semver.js +191 -0
  253. package/node_modules/prebuild-install/node_modules/semver/classes/comparator.js +143 -0
  254. package/node_modules/prebuild-install/node_modules/semver/classes/index.js +7 -0
  255. package/node_modules/prebuild-install/node_modules/semver/classes/range.js +557 -0
  256. package/node_modules/prebuild-install/node_modules/semver/classes/semver.js +333 -0
  257. package/node_modules/prebuild-install/node_modules/semver/functions/clean.js +8 -0
  258. package/node_modules/prebuild-install/node_modules/semver/functions/cmp.js +54 -0
  259. package/node_modules/prebuild-install/node_modules/semver/functions/coerce.js +62 -0
  260. package/node_modules/prebuild-install/node_modules/semver/functions/compare-build.js +9 -0
  261. package/node_modules/prebuild-install/node_modules/semver/functions/compare-loose.js +5 -0
  262. package/node_modules/prebuild-install/node_modules/semver/functions/compare.js +7 -0
  263. package/node_modules/prebuild-install/node_modules/semver/functions/diff.js +60 -0
  264. package/node_modules/prebuild-install/node_modules/semver/functions/eq.js +5 -0
  265. package/node_modules/prebuild-install/node_modules/semver/functions/gt.js +5 -0
  266. package/node_modules/prebuild-install/node_modules/semver/functions/gte.js +5 -0
  267. package/node_modules/prebuild-install/node_modules/semver/functions/inc.js +21 -0
  268. package/node_modules/prebuild-install/node_modules/semver/functions/lt.js +5 -0
  269. package/node_modules/prebuild-install/node_modules/semver/functions/lte.js +5 -0
  270. package/node_modules/prebuild-install/node_modules/semver/functions/major.js +5 -0
  271. package/node_modules/prebuild-install/node_modules/semver/functions/minor.js +5 -0
  272. package/node_modules/prebuild-install/node_modules/semver/functions/neq.js +5 -0
  273. package/node_modules/prebuild-install/node_modules/semver/functions/parse.js +18 -0
  274. package/node_modules/prebuild-install/node_modules/semver/functions/patch.js +5 -0
  275. package/node_modules/prebuild-install/node_modules/semver/functions/prerelease.js +8 -0
  276. package/node_modules/prebuild-install/node_modules/semver/functions/rcompare.js +5 -0
  277. package/node_modules/prebuild-install/node_modules/semver/functions/rsort.js +5 -0
  278. package/node_modules/prebuild-install/node_modules/semver/functions/satisfies.js +12 -0
  279. package/node_modules/prebuild-install/node_modules/semver/functions/sort.js +5 -0
  280. package/node_modules/prebuild-install/node_modules/semver/functions/valid.js +8 -0
  281. package/node_modules/prebuild-install/node_modules/semver/index.js +91 -0
  282. package/node_modules/prebuild-install/node_modules/semver/internal/constants.js +37 -0
  283. package/node_modules/prebuild-install/node_modules/semver/internal/debug.js +11 -0
  284. package/node_modules/prebuild-install/node_modules/semver/internal/identifiers.js +29 -0
  285. package/node_modules/prebuild-install/node_modules/semver/internal/lrucache.js +42 -0
  286. package/node_modules/prebuild-install/node_modules/semver/internal/parse-options.js +17 -0
  287. package/node_modules/prebuild-install/node_modules/semver/internal/re.js +223 -0
  288. package/node_modules/prebuild-install/node_modules/semver/package.json +78 -0
  289. package/node_modules/prebuild-install/node_modules/semver/preload.js +4 -0
  290. package/node_modules/prebuild-install/node_modules/semver/range.bnf +16 -0
  291. package/node_modules/prebuild-install/node_modules/semver/ranges/gtr.js +6 -0
  292. package/node_modules/prebuild-install/node_modules/semver/ranges/intersects.js +9 -0
  293. package/node_modules/prebuild-install/node_modules/semver/ranges/ltr.js +6 -0
  294. package/node_modules/prebuild-install/node_modules/semver/ranges/max-satisfying.js +27 -0
  295. package/node_modules/prebuild-install/node_modules/semver/ranges/min-satisfying.js +26 -0
  296. package/node_modules/prebuild-install/node_modules/semver/ranges/min-version.js +63 -0
  297. package/node_modules/prebuild-install/node_modules/semver/ranges/outside.js +82 -0
  298. package/node_modules/prebuild-install/node_modules/semver/ranges/simplify.js +49 -0
  299. package/node_modules/prebuild-install/node_modules/semver/ranges/subset.js +249 -0
  300. package/node_modules/prebuild-install/node_modules/semver/ranges/to-comparators.js +10 -0
  301. package/node_modules/prebuild-install/node_modules/semver/ranges/valid.js +13 -0
  302. package/node_modules/prebuild-install/package.json +67 -0
  303. package/node_modules/prebuild-install/proxy.js +35 -0
  304. package/node_modules/prebuild-install/rc.js +64 -0
  305. package/node_modules/prebuild-install/util.js +143 -0
  306. package/node_modules/pump/.github/FUNDING.yml +2 -0
  307. package/node_modules/pump/.travis.yml +5 -0
  308. package/node_modules/pump/LICENSE +21 -0
  309. package/node_modules/pump/README.md +74 -0
  310. package/node_modules/pump/SECURITY.md +5 -0
  311. package/node_modules/pump/empty.js +1 -0
  312. package/node_modules/pump/index.js +86 -0
  313. package/node_modules/pump/package.json +30 -0
  314. package/node_modules/pump/test-browser.js +66 -0
  315. package/node_modules/pump/test-node.js +53 -0
  316. package/node_modules/rc/LICENSE.APACHE2 +15 -0
  317. package/node_modules/rc/LICENSE.BSD +26 -0
  318. package/node_modules/rc/LICENSE.MIT +24 -0
  319. package/node_modules/rc/README.md +227 -0
  320. package/node_modules/rc/browser.js +7 -0
  321. package/node_modules/rc/cli.js +4 -0
  322. package/node_modules/rc/index.js +53 -0
  323. package/node_modules/rc/lib/utils.js +104 -0
  324. package/node_modules/rc/package.json +29 -0
  325. package/node_modules/rc/test/ini.js +16 -0
  326. package/node_modules/rc/test/nested-env-vars.js +50 -0
  327. package/node_modules/rc/test/test.js +59 -0
  328. package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
  329. package/node_modules/readable-stream/GOVERNANCE.md +136 -0
  330. package/node_modules/readable-stream/LICENSE +47 -0
  331. package/node_modules/readable-stream/README.md +106 -0
  332. package/node_modules/readable-stream/errors-browser.js +127 -0
  333. package/node_modules/readable-stream/errors.js +116 -0
  334. package/node_modules/readable-stream/experimentalWarning.js +17 -0
  335. package/node_modules/readable-stream/lib/_stream_duplex.js +126 -0
  336. package/node_modules/readable-stream/lib/_stream_passthrough.js +37 -0
  337. package/node_modules/readable-stream/lib/_stream_readable.js +1027 -0
  338. package/node_modules/readable-stream/lib/_stream_transform.js +190 -0
  339. package/node_modules/readable-stream/lib/_stream_writable.js +641 -0
  340. package/node_modules/readable-stream/lib/internal/streams/async_iterator.js +180 -0
  341. package/node_modules/readable-stream/lib/internal/streams/buffer_list.js +183 -0
  342. package/node_modules/readable-stream/lib/internal/streams/destroy.js +96 -0
  343. package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +86 -0
  344. package/node_modules/readable-stream/lib/internal/streams/from-browser.js +3 -0
  345. package/node_modules/readable-stream/lib/internal/streams/from.js +52 -0
  346. package/node_modules/readable-stream/lib/internal/streams/pipeline.js +86 -0
  347. package/node_modules/readable-stream/lib/internal/streams/state.js +22 -0
  348. package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
  349. package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
  350. package/node_modules/readable-stream/package.json +68 -0
  351. package/node_modules/readable-stream/readable-browser.js +9 -0
  352. package/node_modules/readable-stream/readable.js +16 -0
  353. package/node_modules/simple-concat/.travis.yml +3 -0
  354. package/node_modules/simple-concat/LICENSE +20 -0
  355. package/node_modules/simple-concat/README.md +44 -0
  356. package/node_modules/simple-concat/index.js +15 -0
  357. package/node_modules/simple-concat/package.json +47 -0
  358. package/node_modules/simple-concat/test/basic.js +41 -0
  359. package/node_modules/simple-get/.github/dependabot.yml +15 -0
  360. package/node_modules/simple-get/.github/workflows/ci.yml +23 -0
  361. package/node_modules/simple-get/LICENSE +20 -0
  362. package/node_modules/simple-get/README.md +333 -0
  363. package/node_modules/simple-get/index.js +108 -0
  364. package/node_modules/simple-get/package.json +67 -0
  365. package/node_modules/string_decoder/LICENSE +48 -0
  366. package/node_modules/string_decoder/README.md +47 -0
  367. package/node_modules/string_decoder/lib/string_decoder.js +296 -0
  368. package/node_modules/string_decoder/package.json +34 -0
  369. package/node_modules/strip-json-comments/index.js +70 -0
  370. package/node_modules/strip-json-comments/license +21 -0
  371. package/node_modules/strip-json-comments/package.json +42 -0
  372. package/node_modules/strip-json-comments/readme.md +64 -0
  373. package/node_modules/tar-fs/.travis.yml +6 -0
  374. package/node_modules/tar-fs/LICENSE +21 -0
  375. package/node_modules/tar-fs/README.md +165 -0
  376. package/node_modules/tar-fs/index.js +363 -0
  377. package/node_modules/tar-fs/node_modules/chownr/LICENSE +15 -0
  378. package/node_modules/tar-fs/node_modules/chownr/README.md +3 -0
  379. package/node_modules/tar-fs/node_modules/chownr/chownr.js +167 -0
  380. package/node_modules/tar-fs/node_modules/chownr/package.json +29 -0
  381. package/node_modules/tar-fs/package.json +41 -0
  382. package/node_modules/tar-fs/test/fixtures/a/hello.txt +1 -0
  383. package/node_modules/tar-fs/test/fixtures/b/a/test.txt +1 -0
  384. package/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
  385. package/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
  386. package/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
  387. package/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
  388. package/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
  389. package/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
  390. package/node_modules/tar-fs/test/fixtures/e/file +0 -0
  391. package/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
  392. package/node_modules/tar-fs/test/index.js +346 -0
  393. package/node_modules/tar-stream/LICENSE +21 -0
  394. package/node_modules/tar-stream/README.md +168 -0
  395. package/node_modules/tar-stream/extract.js +257 -0
  396. package/node_modules/tar-stream/headers.js +295 -0
  397. package/node_modules/tar-stream/index.js +2 -0
  398. package/node_modules/tar-stream/pack.js +255 -0
  399. package/node_modules/tar-stream/package.json +58 -0
  400. package/node_modules/tar-stream/sandbox.js +11 -0
  401. package/node_modules/tunnel-agent/LICENSE +55 -0
  402. package/node_modules/tunnel-agent/README.md +4 -0
  403. package/node_modules/tunnel-agent/index.js +244 -0
  404. package/node_modules/tunnel-agent/package.json +22 -0
  405. package/node_modules/util-deprecate/History.md +16 -0
  406. package/node_modules/util-deprecate/LICENSE +24 -0
  407. package/node_modules/util-deprecate/README.md +53 -0
  408. package/node_modules/util-deprecate/browser.js +67 -0
  409. package/node_modules/util-deprecate/node.js +6 -0
  410. package/node_modules/util-deprecate/package.json +27 -0
  411. package/node_modules/uuid/CHANGELOG.md +274 -0
  412. package/node_modules/uuid/CONTRIBUTING.md +18 -0
  413. package/node_modules/uuid/LICENSE.md +9 -0
  414. package/node_modules/uuid/README.md +466 -0
  415. package/node_modules/uuid/dist/bin/uuid +2 -0
  416. package/node_modules/uuid/dist/commonjs-browser/index.js +79 -0
  417. package/node_modules/uuid/dist/commonjs-browser/md5.js +223 -0
  418. package/node_modules/uuid/dist/commonjs-browser/native.js +11 -0
  419. package/node_modules/uuid/dist/commonjs-browser/nil.js +8 -0
  420. package/node_modules/uuid/dist/commonjs-browser/parse.js +45 -0
  421. package/node_modules/uuid/dist/commonjs-browser/regex.js +8 -0
  422. package/node_modules/uuid/dist/commonjs-browser/rng.js +25 -0
  423. package/node_modules/uuid/dist/commonjs-browser/sha1.js +104 -0
  424. package/node_modules/uuid/dist/commonjs-browser/stringify.js +44 -0
  425. package/node_modules/uuid/dist/commonjs-browser/v1.js +107 -0
  426. package/node_modules/uuid/dist/commonjs-browser/v3.js +16 -0
  427. package/node_modules/uuid/dist/commonjs-browser/v35.js +80 -0
  428. package/node_modules/uuid/dist/commonjs-browser/v4.js +43 -0
  429. package/node_modules/uuid/dist/commonjs-browser/v5.js +16 -0
  430. package/node_modules/uuid/dist/commonjs-browser/validate.js +17 -0
  431. package/node_modules/uuid/dist/commonjs-browser/version.js +21 -0
  432. package/node_modules/uuid/dist/esm-browser/index.js +9 -0
  433. package/node_modules/uuid/dist/esm-browser/md5.js +215 -0
  434. package/node_modules/uuid/dist/esm-browser/native.js +4 -0
  435. package/node_modules/uuid/dist/esm-browser/nil.js +1 -0
  436. package/node_modules/uuid/dist/esm-browser/parse.js +35 -0
  437. package/node_modules/uuid/dist/esm-browser/regex.js +1 -0
  438. package/node_modules/uuid/dist/esm-browser/rng.js +18 -0
  439. package/node_modules/uuid/dist/esm-browser/sha1.js +96 -0
  440. package/node_modules/uuid/dist/esm-browser/stringify.js +33 -0
  441. package/node_modules/uuid/dist/esm-browser/v1.js +95 -0
  442. package/node_modules/uuid/dist/esm-browser/v3.js +4 -0
  443. package/node_modules/uuid/dist/esm-browser/v35.js +66 -0
  444. package/node_modules/uuid/dist/esm-browser/v4.js +29 -0
  445. package/node_modules/uuid/dist/esm-browser/v5.js +4 -0
  446. package/node_modules/uuid/dist/esm-browser/validate.js +7 -0
  447. package/node_modules/uuid/dist/esm-browser/version.js +11 -0
  448. package/node_modules/uuid/dist/esm-node/index.js +9 -0
  449. package/node_modules/uuid/dist/esm-node/md5.js +13 -0
  450. package/node_modules/uuid/dist/esm-node/native.js +4 -0
  451. package/node_modules/uuid/dist/esm-node/nil.js +1 -0
  452. package/node_modules/uuid/dist/esm-node/parse.js +35 -0
  453. package/node_modules/uuid/dist/esm-node/regex.js +1 -0
  454. package/node_modules/uuid/dist/esm-node/rng.js +12 -0
  455. package/node_modules/uuid/dist/esm-node/sha1.js +13 -0
  456. package/node_modules/uuid/dist/esm-node/stringify.js +33 -0
  457. package/node_modules/uuid/dist/esm-node/v1.js +95 -0
  458. package/node_modules/uuid/dist/esm-node/v3.js +4 -0
  459. package/node_modules/uuid/dist/esm-node/v35.js +66 -0
  460. package/node_modules/uuid/dist/esm-node/v4.js +29 -0
  461. package/node_modules/uuid/dist/esm-node/v5.js +4 -0
  462. package/node_modules/uuid/dist/esm-node/validate.js +7 -0
  463. package/node_modules/uuid/dist/esm-node/version.js +11 -0
  464. package/node_modules/uuid/dist/index.js +79 -0
  465. package/node_modules/uuid/dist/md5-browser.js +223 -0
  466. package/node_modules/uuid/dist/md5.js +23 -0
  467. package/node_modules/uuid/dist/native-browser.js +11 -0
  468. package/node_modules/uuid/dist/native.js +15 -0
  469. package/node_modules/uuid/dist/nil.js +8 -0
  470. package/node_modules/uuid/dist/parse.js +45 -0
  471. package/node_modules/uuid/dist/regex.js +8 -0
  472. package/node_modules/uuid/dist/rng-browser.js +25 -0
  473. package/node_modules/uuid/dist/rng.js +24 -0
  474. package/node_modules/uuid/dist/sha1-browser.js +104 -0
  475. package/node_modules/uuid/dist/sha1.js +23 -0
  476. package/node_modules/uuid/dist/stringify.js +44 -0
  477. package/node_modules/uuid/dist/uuid-bin.js +85 -0
  478. package/node_modules/uuid/dist/v1.js +107 -0
  479. package/node_modules/uuid/dist/v3.js +16 -0
  480. package/node_modules/uuid/dist/v35.js +80 -0
  481. package/node_modules/uuid/dist/v4.js +43 -0
  482. package/node_modules/uuid/dist/v5.js +16 -0
  483. package/node_modules/uuid/dist/validate.js +17 -0
  484. package/node_modules/uuid/dist/version.js +21 -0
  485. package/node_modules/uuid/package.json +135 -0
  486. package/node_modules/uuid/wrapper.mjs +10 -0
  487. package/package.json +5 -3
  488. package/packages/cli/package.json +1 -1
  489. package/packages/daemon/package.json +1 -1
  490. package/packages/daemon/src/api.js +17 -9
  491. package/packages/daemon/src/process.js +2 -0
  492. package/packages/gui/dist/assets/{codemirror-BBL3i_JW.js → codemirror-CFF1Lrnz.js} +10 -10
  493. package/{node_modules/@groove-dev/gui/dist/assets/index-DWv32qyJ.js → packages/gui/dist/assets/index-B3GUKInH.js} +1740 -1740
  494. package/{node_modules/@groove-dev/gui/dist/assets/index-Bo6AeNmM.css → packages/gui/dist/assets/index-C1k-GuDg.css} +1 -1
  495. package/packages/gui/dist/index.html +3 -3
  496. package/packages/gui/package.json +1 -1
  497. package/packages/gui/src/components/agents/agent-panel.jsx +2 -0
  498. package/packages/gui/src/components/editor/code-editor.jsx +3 -3
  499. package/packages/gui/src/stores/groove.js +23 -16
  500. package/packages/gui/src/views/agents.jsx +44 -113
  501. package/workspace.png +0 -0
@@ -0,0 +1,232 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ import { describe, it, beforeEach, afterEach } from 'node:test';
4
+ import assert from 'node:assert/strict';
5
+ import { mkdtempSync, rmSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { tmpdir } from 'node:os';
8
+ import { generateECDHKeypair, deriveSharedSecret, signEnvelope } from '../../shared/crypto.js';
9
+ import { SessionRegistry } from '../../server/session-registry.js';
10
+ import { EnvelopeVerifier } from '../../server/verifier.js';
11
+
12
+ const VALID_CONTRIBUTOR = 'c'.repeat(32);
13
+ const VALID_APP_HASH = 'b'.repeat(64);
14
+
15
+ function makeSignedEnvelope(sessionId, sequence, sharedSecret, extra = {}) {
16
+ const envelope = {
17
+ envelope_id: `env_test_${sequence}`,
18
+ session_id: sessionId,
19
+ chunk_sequence: sequence,
20
+ contributor_id: VALID_CONTRIBUTOR,
21
+ metadata: { model_engine: 'claude-opus-4-6', provider: 'claude-code', agent_role: 'frontend', agent_id: 'frontend-1' },
22
+ trajectory_log: [{ step: 1, type: 'thought', timestamp: Date.now() / 1000, content: 'test', token_count: 10 }],
23
+ ...extra,
24
+ };
25
+
26
+ const forHmac = { ...envelope };
27
+ const envelopeBytes = JSON.stringify(forHmac);
28
+ const hmac = signEnvelope(sharedSecret, envelopeBytes, sequence);
29
+
30
+ envelope.attestation = {
31
+ session_hmac: hmac,
32
+ sequence,
33
+ app_version_hash: VALID_APP_HASH,
34
+ };
35
+
36
+ return envelope;
37
+ }
38
+
39
+ function makeSignedCloseEnvelope(sessionId, sequence, sharedSecret) {
40
+ const envelope = {
41
+ envelope_id: `env_close_${sequence}`,
42
+ session_id: sessionId,
43
+ type: 'SESSION_CLOSE',
44
+ outcome: {
45
+ status: 'SUCCESS',
46
+ total_steps: 10,
47
+ total_chunks: 1,
48
+ user_interventions: 0,
49
+ total_tokens: 500,
50
+ duration_seconds: 60,
51
+ files_modified: 1,
52
+ errors_encountered: 0,
53
+ errors_recovered: 0,
54
+ coordination_events: 0,
55
+ },
56
+ };
57
+
58
+ const forHmac = { ...envelope };
59
+ const envelopeBytes = JSON.stringify(forHmac);
60
+ const hmac = signEnvelope(sharedSecret, envelopeBytes, sequence);
61
+
62
+ envelope.attestation = {
63
+ session_hmac: hmac,
64
+ sequence,
65
+ app_version_hash: VALID_APP_HASH,
66
+ };
67
+
68
+ return envelope;
69
+ }
70
+
71
+ describe('EnvelopeVerifier', () => {
72
+ let registry;
73
+ let verifier;
74
+ let tmpDir;
75
+ let sharedSecret;
76
+ const sessionId = 'sess_verify_001';
77
+
78
+ beforeEach(() => {
79
+ tmpDir = mkdtempSync(join(tmpdir(), 'verify-test-'));
80
+ registry = new SessionRegistry(join(tmpDir, 'sessions.db'));
81
+ verifier = new EnvelopeVerifier(registry);
82
+
83
+ const clientKeypair = generateECDHKeypair();
84
+ const result = registry.openSession(
85
+ sessionId, clientKeypair.publicKey, 'claude-code', 'claude-opus-4-6',
86
+ 'fp_verify', 'hash_verify', '0.27.77'
87
+ );
88
+
89
+ const session = registry.getSession(sessionId);
90
+ sharedSecret = session.shared_secret;
91
+ });
92
+
93
+ afterEach(() => {
94
+ registry.close();
95
+ rmSync(tmpDir, { recursive: true, force: true });
96
+ });
97
+
98
+ it('accepts a valid envelope with correct HMAC', () => {
99
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
100
+ const result = verifier.verify(envelope);
101
+ assert.equal(result.valid, true);
102
+ });
103
+
104
+ it('rejects a tampered envelope (HMAC fails)', () => {
105
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
106
+ envelope.trajectory_log.push({ step: 2, type: 'action', content: 'injected' });
107
+ const result = verifier.verify(envelope);
108
+ assert.equal(result.valid, false);
109
+ assert.ok(result.reason.includes('HMAC'));
110
+ });
111
+
112
+ it('rejects wrong sequence number', () => {
113
+ const envelope = makeSignedEnvelope(sessionId, 5, sharedSecret);
114
+ const result = verifier.verify(envelope);
115
+ assert.equal(result.valid, false);
116
+ assert.ok(result.reason.includes('sequence'));
117
+ });
118
+
119
+ it('rejects unknown session_id', () => {
120
+ const envelope = makeSignedEnvelope('sess_nonexistent', 0, sharedSecret);
121
+ const result = verifier.verify(envelope);
122
+ assert.equal(result.valid, false);
123
+ assert.ok(result.reason.includes('unknown session_id'));
124
+ });
125
+
126
+ it('rejects envelope for closed session', () => {
127
+ registry.closeSession(sessionId);
128
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
129
+ const result = verifier.verify(envelope);
130
+ assert.equal(result.valid, false);
131
+ assert.ok(result.reason.includes('closed'));
132
+ });
133
+
134
+ it('rejects envelope missing attestation', () => {
135
+ const envelope = {
136
+ session_id: sessionId,
137
+ envelope_id: 'env_no_att',
138
+ trajectory_log: [],
139
+ };
140
+ const result = verifier.verify(envelope);
141
+ assert.equal(result.valid, false);
142
+ assert.ok(result.reason.includes('attestation'));
143
+ });
144
+
145
+ it('increments sequence after successful verification', () => {
146
+ const env0 = makeSignedEnvelope(sessionId, 0, sharedSecret);
147
+ const r0 = verifier.verify(env0);
148
+ assert.equal(r0.valid, true);
149
+
150
+ const env1 = makeSignedEnvelope(sessionId, 1, sharedSecret);
151
+ const r1 = verifier.verify(env1);
152
+ assert.equal(r1.valid, true);
153
+
154
+ const session = registry.getSession(sessionId);
155
+ assert.equal(session.expected_sequence, 2);
156
+ });
157
+
158
+ // --- New security tests ---
159
+
160
+ it('rejects empty HMAC string', () => {
161
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
162
+ envelope.attestation.session_hmac = '';
163
+ const result = verifier.verify(envelope);
164
+ assert.equal(result.valid, false);
165
+ assert.ok(result.reason.includes('HMAC'));
166
+ });
167
+
168
+ it('rejects missing HMAC field', () => {
169
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
170
+ delete envelope.attestation.session_hmac;
171
+ const result = verifier.verify(envelope);
172
+ assert.equal(result.valid, false);
173
+ assert.ok(result.reason.includes('HMAC'));
174
+ });
175
+
176
+ it('atomic sequence prevents duplicate sequence acceptance', () => {
177
+ const env0 = makeSignedEnvelope(sessionId, 0, sharedSecret);
178
+ const r0 = verifier.verify(env0);
179
+ assert.equal(r0.valid, true);
180
+
181
+ // Re-sign with sequence 0 again (replay attempt)
182
+ const env0replay = makeSignedEnvelope(sessionId, 0, sharedSecret);
183
+ const rReplay = verifier.verify(env0replay);
184
+ assert.equal(rReplay.valid, false);
185
+ assert.ok(rReplay.reason.includes('sequence'));
186
+ });
187
+
188
+ it('verifyClose checks sequence number', () => {
189
+ // Send one regular envelope first (sequence 0)
190
+ const env0 = makeSignedEnvelope(sessionId, 0, sharedSecret);
191
+ verifier.verify(env0);
192
+
193
+ // Close with wrong sequence
194
+ const closeWrong = makeSignedCloseEnvelope(sessionId, 0, sharedSecret);
195
+ const resultWrong = verifyClose(verifier, closeWrong);
196
+ assert.equal(resultWrong.valid, false);
197
+ assert.ok(resultWrong.reason.includes('sequence'));
198
+
199
+ // Close with correct sequence
200
+ const closeRight = makeSignedCloseEnvelope(sessionId, 1, sharedSecret);
201
+ const resultRight = verifyClose(verifier, closeRight);
202
+ assert.equal(resultRight.valid, true);
203
+ });
204
+
205
+ it('verifyClose rejects empty HMAC', () => {
206
+ const closeEnv = makeSignedCloseEnvelope(sessionId, 0, sharedSecret);
207
+ closeEnv.attestation.session_hmac = '';
208
+ const result = verifier.verifyClose(closeEnv);
209
+ assert.equal(result.valid, false);
210
+ assert.ok(result.reason.includes('HMAC'));
211
+ });
212
+
213
+ it('rejects OFFLINE HMAC marker from offline client', () => {
214
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
215
+ envelope.attestation.session_hmac = 'OFFLINE';
216
+ const result = verifier.verify(envelope);
217
+ assert.equal(result.valid, false);
218
+ assert.ok(result.reason.includes('HMAC'));
219
+ });
220
+
221
+ it('rejects mega-length HMAC string', () => {
222
+ const envelope = makeSignedEnvelope(sessionId, 0, sharedSecret);
223
+ envelope.attestation.session_hmac = 'a'.repeat(1_000_000);
224
+ const result = verifier.verify(envelope);
225
+ assert.equal(result.valid, false);
226
+ assert.ok(result.reason.includes('HMAC'));
227
+ });
228
+ });
229
+
230
+ function verifyClose(verifier, envelope) {
231
+ return verifier.verifyClose(envelope);
232
+ }
@@ -0,0 +1,87 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ import { describe, it } from 'node:test';
4
+ import assert from 'node:assert/strict';
5
+ import { writeFileSync, mkdtempSync, rmSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { tmpdir } from 'node:os';
8
+ import {
9
+ generateECDHKeypair,
10
+ deriveSharedSecret,
11
+ signEnvelope,
12
+ verifyEnvelope,
13
+ computeAppHash,
14
+ } from '../../shared/crypto.js';
15
+
16
+ describe('crypto', () => {
17
+ it('generates ECDH keypairs with base64 encoded keys', () => {
18
+ const kp = generateECDHKeypair();
19
+ assert.ok(kp.publicKey);
20
+ assert.ok(kp.privateKey);
21
+ assert.ok(Buffer.from(kp.publicKey, 'base64').length > 0);
22
+ assert.ok(Buffer.from(kp.privateKey, 'base64').length > 0);
23
+ });
24
+
25
+ it('derives the same shared secret from both sides', () => {
26
+ const alice = generateECDHKeypair();
27
+ const bob = generateECDHKeypair();
28
+
29
+ const secretA = deriveSharedSecret(alice.privateKey, bob.publicKey);
30
+ const secretB = deriveSharedSecret(bob.privateKey, alice.publicKey);
31
+
32
+ assert.equal(secretA, secretB);
33
+ assert.ok(Buffer.from(secretA, 'base64').length > 0);
34
+ });
35
+
36
+ it('HMAC sign and verify round-trip', () => {
37
+ const alice = generateECDHKeypair();
38
+ const bob = generateECDHKeypair();
39
+ const secret = deriveSharedSecret(alice.privateKey, bob.publicKey);
40
+
41
+ const payload = JSON.stringify({ data: 'test envelope content' });
42
+ const seq = 1;
43
+ const hmac = signEnvelope(secret, payload, seq);
44
+
45
+ assert.ok(typeof hmac === 'string');
46
+ assert.ok(hmac.length > 0);
47
+ assert.ok(verifyEnvelope(secret, payload, seq, hmac));
48
+ });
49
+
50
+ it('verification fails with tampered payload', () => {
51
+ const alice = generateECDHKeypair();
52
+ const bob = generateECDHKeypair();
53
+ const secret = deriveSharedSecret(alice.privateKey, bob.publicKey);
54
+
55
+ const payload = JSON.stringify({ data: 'original' });
56
+ const hmac = signEnvelope(secret, payload, 1);
57
+
58
+ const tampered = JSON.stringify({ data: 'tampered' });
59
+ assert.equal(verifyEnvelope(secret, tampered, 1, hmac), false);
60
+ });
61
+
62
+ it('verification fails with wrong sequence number', () => {
63
+ const alice = generateECDHKeypair();
64
+ const bob = generateECDHKeypair();
65
+ const secret = deriveSharedSecret(alice.privateKey, bob.publicKey);
66
+
67
+ const payload = JSON.stringify({ data: 'test' });
68
+ const hmac = signEnvelope(secret, payload, 1);
69
+
70
+ assert.equal(verifyEnvelope(secret, payload, 2, hmac), false);
71
+ });
72
+
73
+ it('computeAppHash returns SHA256 of file contents', () => {
74
+ const dir = mkdtempSync(join(tmpdir(), 'crypto-test-'));
75
+ const filePath = join(dir, 'test-file.txt');
76
+ writeFileSync(filePath, 'hello world');
77
+
78
+ const hash = computeAppHash(filePath);
79
+ assert.ok(typeof hash === 'string');
80
+ assert.equal(hash.length, 64);
81
+
82
+ const hash2 = computeAppHash(filePath);
83
+ assert.equal(hash, hash2);
84
+
85
+ rmSync(dir, { recursive: true });
86
+ });
87
+ });
@@ -0,0 +1,351 @@
1
+ // FSL-1.1-Apache-2.0 — see LICENSE
2
+
3
+ import { describe, it } from 'node:test';
4
+ import assert from 'node:assert/strict';
5
+ import { validateEnvelope, STEP_TYPES } from '../../shared/envelope-schema.js';
6
+
7
+ const VALID_HMAC = 'a'.repeat(64);
8
+ const VALID_APP_HASH = 'b'.repeat(64);
9
+ const VALID_CONTRIBUTOR = 'c'.repeat(32);
10
+
11
+ function validEnvelope() {
12
+ return {
13
+ envelope_id: 'env_test-123',
14
+ session_id: 'sess_test-456',
15
+ chunk_sequence: 0,
16
+ contributor_id: VALID_CONTRIBUTOR,
17
+ attestation: { session_hmac: VALID_HMAC, sequence: 0, app_version_hash: VALID_APP_HASH },
18
+ metadata: {
19
+ model_engine: 'claude-opus-4-6',
20
+ provider: 'claude-code',
21
+ agent_role: 'backend',
22
+ agent_id: 'backend-1',
23
+ task_complexity: 'medium',
24
+ team_size: 2,
25
+ groove_version: '0.27.0',
26
+ },
27
+ trajectory_log: [
28
+ { step: 1, type: 'thought', timestamp: Date.now() / 1000, content: 'thinking...', token_count: 10 },
29
+ { step: 2, type: 'action', timestamp: Date.now() / 1000, tool: 'Read', content: 'reading file' },
30
+ ],
31
+ };
32
+ }
33
+
34
+ describe('envelope-schema', () => {
35
+ it('valid envelope passes validation', () => {
36
+ const result = validateEnvelope(validEnvelope());
37
+ assert.equal(result.valid, true);
38
+ assert.equal(result.errors.length, 0);
39
+ });
40
+
41
+ it('null envelope fails', () => {
42
+ const result = validateEnvelope(null);
43
+ assert.equal(result.valid, false);
44
+ });
45
+
46
+ it('missing session_id fails', () => {
47
+ const env = validEnvelope();
48
+ delete env.session_id;
49
+ const result = validateEnvelope(env);
50
+ assert.equal(result.valid, false);
51
+ });
52
+
53
+ it('missing metadata.provider fails', () => {
54
+ const env = validEnvelope();
55
+ delete env.metadata.provider;
56
+ const result = validateEnvelope(env);
57
+ assert.equal(result.valid, false);
58
+ assert.ok(result.errors.some((e) => e.includes('provider')));
59
+ });
60
+
61
+ it('invalid step type fails', () => {
62
+ const env = validEnvelope();
63
+ env.trajectory_log[0].type = 'invalid_type';
64
+ const result = validateEnvelope(env);
65
+ assert.equal(result.valid, false);
66
+ assert.ok(result.errors.some((e) => e.includes('invalid_type')));
67
+ });
68
+
69
+ it('missing step number fails', () => {
70
+ const env = validEnvelope();
71
+ delete env.trajectory_log[0].step;
72
+ const result = validateEnvelope(env);
73
+ assert.equal(result.valid, false);
74
+ });
75
+
76
+ it('missing timestamp fails', () => {
77
+ const env = validEnvelope();
78
+ delete env.trajectory_log[0].timestamp;
79
+ const result = validateEnvelope(env);
80
+ assert.equal(result.valid, false);
81
+ });
82
+
83
+ it('all STEP_TYPES are valid', () => {
84
+ for (const type of STEP_TYPES) {
85
+ const env = validEnvelope();
86
+ env.trajectory_log = [{ step: 1, type, timestamp: Date.now() / 1000 }];
87
+ const result = validateEnvelope(env);
88
+ assert.equal(result.valid, true, `Type "${type}" should be valid`);
89
+ }
90
+ });
91
+
92
+ // --- New security tests ---
93
+
94
+ it('rejects trajectory_log with > 500 steps', () => {
95
+ const env = validEnvelope();
96
+ env.trajectory_log = Array.from({ length: 501 }, (_, i) => ({
97
+ step: i, type: 'thought', timestamp: Date.now() / 1000,
98
+ }));
99
+ const result = validateEnvelope(env);
100
+ assert.equal(result.valid, false);
101
+ assert.ok(result.errors.some(e => e.includes('500')));
102
+ });
103
+
104
+ it('rejects step with content > 10KB', () => {
105
+ const env = validEnvelope();
106
+ env.trajectory_log[0].content = 'x'.repeat(10_001);
107
+ const result = validateEnvelope(env);
108
+ assert.equal(result.valid, false);
109
+ assert.ok(result.errors.some(e => e.includes('10000')));
110
+ });
111
+
112
+ it('rejects step with token_count > 100,000', () => {
113
+ const env = validEnvelope();
114
+ env.trajectory_log[0].token_count = 100_001;
115
+ const result = validateEnvelope(env);
116
+ assert.equal(result.valid, false);
117
+ assert.ok(result.errors.some(e => e.includes('token_count')));
118
+ });
119
+
120
+ it('rejects step with negative token_count', () => {
121
+ const env = validEnvelope();
122
+ env.trajectory_log[0].token_count = -1;
123
+ const result = validateEnvelope(env);
124
+ assert.equal(result.valid, false);
125
+ assert.ok(result.errors.some(e => e.includes('token_count')));
126
+ });
127
+
128
+ it('rejects step with step number > 50,000', () => {
129
+ const env = validEnvelope();
130
+ env.trajectory_log[0].step = 50_001;
131
+ const result = validateEnvelope(env);
132
+ assert.equal(result.valid, false);
133
+ });
134
+
135
+ it('rejects step with negative step number', () => {
136
+ const env = validEnvelope();
137
+ env.trajectory_log[0].step = -1;
138
+ const result = validateEnvelope(env);
139
+ assert.equal(result.valid, false);
140
+ });
141
+
142
+ it('rejects invalid provider', () => {
143
+ const env = validEnvelope();
144
+ env.metadata.provider = 'fake-provider';
145
+ const result = validateEnvelope(env);
146
+ assert.equal(result.valid, false);
147
+ assert.ok(result.errors.some(e => e.includes('provider')));
148
+ });
149
+
150
+ it('rejects invalid model_engine', () => {
151
+ const env = validEnvelope();
152
+ env.metadata.model_engine = 'gpt-5-turbo';
153
+ const result = validateEnvelope(env);
154
+ assert.equal(result.valid, false);
155
+ assert.ok(result.errors.some(e => e.includes('model_engine')));
156
+ });
157
+
158
+ it('rejects contributor_id that is not 32-char hex', () => {
159
+ const env = validEnvelope();
160
+ env.contributor_id = 'user_abc';
161
+ const result = validateEnvelope(env);
162
+ assert.equal(result.valid, false);
163
+ assert.ok(result.errors.some(e => e.includes('contributor_id')));
164
+ });
165
+
166
+ it('rejects contributor_id with uppercase hex', () => {
167
+ const env = validEnvelope();
168
+ env.contributor_id = 'A'.repeat(32);
169
+ const result = validateEnvelope(env);
170
+ assert.equal(result.valid, false);
171
+ assert.ok(result.errors.some(e => e.includes('contributor_id')));
172
+ });
173
+
174
+ it('rejects attestation.session_hmac that is not 64-char hex', () => {
175
+ const env = validEnvelope();
176
+ env.attestation.session_hmac = 'abc';
177
+ const result = validateEnvelope(env);
178
+ assert.equal(result.valid, false);
179
+ assert.ok(result.errors.some(e => e.includes('session_hmac')));
180
+ });
181
+
182
+ it('rejects attestation.app_version_hash that is not 64-char hex', () => {
183
+ const env = validEnvelope();
184
+ env.attestation.app_version_hash = 'def';
185
+ const result = validateEnvelope(env);
186
+ assert.equal(result.valid, false);
187
+ assert.ok(result.errors.some(e => e.includes('app_version_hash')));
188
+ });
189
+
190
+ it('rejects future timestamps beyond 1 hour', () => {
191
+ const env = validEnvelope();
192
+ env.trajectory_log[0].timestamp = (Date.now() + 2 * 60 * 60 * 1000) / 1000;
193
+ const result = validateEnvelope(env);
194
+ assert.equal(result.valid, false);
195
+ assert.ok(result.errors.some(e => e.includes('Timestamp out of range')));
196
+ });
197
+
198
+ it('rejects timestamps older than 7 days', () => {
199
+ const env = validEnvelope();
200
+ env.trajectory_log[0].timestamp = (Date.now() - 8 * 24 * 60 * 60 * 1000) / 1000;
201
+ const result = validateEnvelope(env);
202
+ assert.equal(result.valid, false);
203
+ assert.ok(result.errors.some(e => e.includes('Timestamp out of range')));
204
+ });
205
+
206
+ it('rejects team_size outside 1-50', () => {
207
+ const env = validEnvelope();
208
+ env.metadata.team_size = 0;
209
+ let result = validateEnvelope(env);
210
+ assert.equal(result.valid, false);
211
+
212
+ env.metadata.team_size = 51;
213
+ result = validateEnvelope(env);
214
+ assert.equal(result.valid, false);
215
+ });
216
+
217
+ it('rejects invalid task_complexity', () => {
218
+ const env = validEnvelope();
219
+ env.metadata.task_complexity = 'extreme';
220
+ const result = validateEnvelope(env);
221
+ assert.equal(result.valid, false);
222
+ assert.ok(result.errors.some(e => e.includes('task_complexity')));
223
+ });
224
+
225
+ it('accepts absent optional metadata fields', () => {
226
+ const env = validEnvelope();
227
+ delete env.metadata.team_size;
228
+ delete env.metadata.task_complexity;
229
+ delete env.metadata.groove_version;
230
+ const result = validateEnvelope(env);
231
+ assert.equal(result.valid, true);
232
+ });
233
+
234
+ it('valid SESSION_CLOSE passes', () => {
235
+ const close = {
236
+ envelope_id: 'env_close-1',
237
+ session_id: 'sess_test-1',
238
+ type: 'SESSION_CLOSE',
239
+ attestation: { session_hmac: VALID_HMAC, sequence: 5, app_version_hash: VALID_APP_HASH },
240
+ outcome: {
241
+ status: 'SUCCESS',
242
+ user_interventions: 1,
243
+ total_steps: 100,
244
+ total_chunks: 2,
245
+ total_tokens: 5000,
246
+ duration_seconds: 300,
247
+ files_modified: 3,
248
+ errors_encountered: 1,
249
+ errors_recovered: 1,
250
+ coordination_events: 0,
251
+ },
252
+ };
253
+ const result = validateEnvelope(close);
254
+ assert.equal(result.valid, true);
255
+ });
256
+
257
+ it('SESSION_CLOSE missing outcome fails', () => {
258
+ const close = {
259
+ envelope_id: 'env_close-1',
260
+ session_id: 'sess_test-1',
261
+ type: 'SESSION_CLOSE',
262
+ attestation: { session_hmac: VALID_HMAC, sequence: 5, app_version_hash: VALID_APP_HASH },
263
+ };
264
+ const result = validateEnvelope(close);
265
+ assert.equal(result.valid, false);
266
+ assert.ok(result.errors.some((e) => e.includes('outcome')));
267
+ });
268
+
269
+ it('SESSION_CLOSE missing status fails', () => {
270
+ const close = {
271
+ envelope_id: 'env_close-1',
272
+ session_id: 'sess_test-1',
273
+ type: 'SESSION_CLOSE',
274
+ attestation: { session_hmac: VALID_HMAC, sequence: 0, app_version_hash: VALID_APP_HASH },
275
+ outcome: { total_steps: 10, total_chunks: 1 },
276
+ };
277
+ const result = validateEnvelope(close);
278
+ assert.equal(result.valid, false);
279
+ assert.ok(result.errors.some((e) => e.includes('status')));
280
+ });
281
+
282
+ it('SESSION_CLOSE rejects invalid outcome status', () => {
283
+ const close = {
284
+ envelope_id: 'env_close-1',
285
+ session_id: 'sess_test-1',
286
+ type: 'SESSION_CLOSE',
287
+ attestation: { session_hmac: VALID_HMAC, sequence: 0, app_version_hash: VALID_APP_HASH },
288
+ outcome: { status: 'TIMEOUT', total_steps: 10, total_chunks: 1 },
289
+ };
290
+ const result = validateEnvelope(close);
291
+ assert.equal(result.valid, false);
292
+ assert.ok(result.errors.some(e => e.includes('status')));
293
+ });
294
+
295
+ it('SESSION_CLOSE rejects negative outcome numerics', () => {
296
+ const close = {
297
+ envelope_id: 'env_close-1',
298
+ session_id: 'sess_test-1',
299
+ type: 'SESSION_CLOSE',
300
+ attestation: { session_hmac: VALID_HMAC, sequence: 0, app_version_hash: VALID_APP_HASH },
301
+ outcome: { status: 'SUCCESS', total_steps: 10, total_chunks: 1, user_interventions: -5 },
302
+ };
303
+ const result = validateEnvelope(close);
304
+ assert.equal(result.valid, false);
305
+ assert.ok(result.errors.some(e => e.includes('user_interventions')));
306
+ });
307
+
308
+ it('SESSION_CLOSE rejects outcome numerics > 50,000', () => {
309
+ const close = {
310
+ envelope_id: 'env_close-1',
311
+ session_id: 'sess_test-1',
312
+ type: 'SESSION_CLOSE',
313
+ attestation: { session_hmac: VALID_HMAC, sequence: 0, app_version_hash: VALID_APP_HASH },
314
+ outcome: { status: 'SUCCESS', total_steps: 50_001, total_chunks: 1 },
315
+ };
316
+ const result = validateEnvelope(close);
317
+ assert.equal(result.valid, false);
318
+ });
319
+
320
+ it('rejects token_count = 999999', () => {
321
+ const env = validEnvelope();
322
+ env.trajectory_log[0].token_count = 999_999;
323
+ const result = validateEnvelope(env);
324
+ assert.equal(result.valid, false);
325
+ assert.ok(result.errors.some(e => e.includes('token_count')));
326
+ });
327
+
328
+ it('rejects SQL injection in contributor_id', () => {
329
+ const env = validEnvelope();
330
+ env.contributor_id = "'; DROP TABLE balances; --";
331
+ const result = validateEnvelope(env);
332
+ assert.equal(result.valid, false);
333
+ assert.ok(result.errors.some(e => e.includes('contributor_id')));
334
+ });
335
+
336
+ it('rejects attestation.session_hmac = giant string', () => {
337
+ const env = validEnvelope();
338
+ env.attestation.session_hmac = 'x'.repeat(1_000_000);
339
+ const result = validateEnvelope(env);
340
+ assert.equal(result.valid, false);
341
+ assert.ok(result.errors.some(e => e.includes('session_hmac')));
342
+ });
343
+
344
+ it('rejects empty attestation.session_hmac', () => {
345
+ const env = validEnvelope();
346
+ env.attestation.session_hmac = '';
347
+ const result = validateEnvelope(env);
348
+ assert.equal(result.valid, false);
349
+ assert.ok(result.errors.some(e => e.includes('session_hmac')));
350
+ });
351
+ });
@@ -0,0 +1,31 @@
1
+ name: Run npm Tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [ "main" ]
7
+ pull_request:
8
+ branches: [ "main" ]
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+
14
+ strategy:
15
+ matrix:
16
+ node-version: [22, 23]
17
+
18
+ steps:
19
+ - name: Checkout repository
20
+ uses: actions/checkout@v2
21
+
22
+ - name: Set up Node.js ${{ matrix.node-version }}
23
+ uses: actions/setup-node@v3
24
+ with:
25
+ node-version: ${{ matrix.node-version }}
26
+
27
+ - name: Install dependencies
28
+ run: npm install
29
+
30
+ - name: Run tests
31
+ run: npm test