groove-dev 0.27.86 → 0.27.88

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 (538) hide show
  1. package/CLAUDE.md +11 -0
  2. package/moe-training/client/scrubber.js +4 -2
  3. package/moe-training/client/step-classifier.js +17 -0
  4. package/moe-training/client/trajectory-capture.js +80 -6
  5. package/moe-training/client/transmission-queue.js +11 -0
  6. package/moe-training/test/client/scrubber.test.js +14 -4
  7. package/moe-training/test/client/step-classifier.test.js +47 -0
  8. package/moe-training/test/client/transmission-queue.test.js +33 -0
  9. package/node_modules/@groove-dev/cli/bin/groove.js +10 -1
  10. package/node_modules/@groove-dev/cli/package.json +1 -1
  11. package/node_modules/@groove-dev/cli/src/commands/connect.js +116 -205
  12. package/node_modules/@groove-dev/cli/src/commands/disconnect.js +38 -62
  13. package/node_modules/@groove-dev/cli/src/commands/remotes.js +75 -0
  14. package/node_modules/@groove-dev/daemon/package.json +1 -1
  15. package/node_modules/@groove-dev/daemon/src/api.js +115 -7
  16. package/node_modules/@groove-dev/daemon/src/conversations.js +29 -3
  17. package/node_modules/@groove-dev/daemon/src/process.js +56 -1
  18. package/node_modules/@groove-dev/daemon/src/providers/codex.js +28 -10
  19. package/node_modules/@groove-dev/daemon/src/registry.js +30 -0
  20. package/node_modules/@groove-dev/daemon/src/validate.js +23 -0
  21. package/node_modules/@groove-dev/gui/dist/assets/index-BSqk8cbI.css +1 -0
  22. package/node_modules/@groove-dev/gui/dist/assets/index-B_igwWvq.js +8642 -0
  23. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  24. package/node_modules/@groove-dev/gui/package.json +2 -1
  25. package/node_modules/@groove-dev/gui/src/components/agents/agent-file-tree.jsx +254 -0
  26. package/node_modules/@groove-dev/gui/src/components/agents/code-review.jsx +177 -0
  27. package/node_modules/@groove-dev/gui/src/components/agents/diff-viewer.jsx +148 -0
  28. package/node_modules/@groove-dev/gui/src/components/agents/workspace-mode.jsx +377 -0
  29. package/node_modules/@groove-dev/gui/src/components/chat/chat-input.jsx +117 -40
  30. package/node_modules/@groove-dev/gui/src/components/chat/chat-messages.jsx +10 -13
  31. package/node_modules/@groove-dev/gui/src/components/chat/chat-view.jsx +26 -1
  32. package/node_modules/@groove-dev/gui/src/components/chat/conversation-list.jsx +14 -14
  33. package/node_modules/@groove-dev/gui/src/components/chat/model-picker.jsx +5 -0
  34. package/node_modules/@groove-dev/gui/src/components/preview/preview-workspace.jsx +6 -5
  35. package/node_modules/@groove-dev/gui/src/components/preview/screenshot-overlay.jsx +41 -29
  36. package/node_modules/@groove-dev/gui/src/stores/groove.js +138 -3
  37. package/node_modules/@groove-dev/gui/src/views/agents.jsx +36 -3
  38. package/node_modules/@groove-dev/gui/src/views/settings.jsx +104 -26
  39. package/node_modules/base64-arraybuffer/CHANGELOG.md +28 -0
  40. package/node_modules/base64-arraybuffer/LICENSE +22 -0
  41. package/node_modules/base64-arraybuffer/README.md +27 -0
  42. package/node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js +50 -0
  43. package/node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js.map +1 -0
  44. package/node_modules/base64-arraybuffer/dist/base64-arraybuffer.umd.js +61 -0
  45. package/node_modules/base64-arraybuffer/dist/base64-arraybuffer.umd.js.map +1 -0
  46. package/node_modules/base64-arraybuffer/dist/lib/index.js +48 -0
  47. package/node_modules/base64-arraybuffer/dist/lib/index.js.map +1 -0
  48. package/node_modules/base64-arraybuffer/dist/types/index.d.ts +2 -0
  49. package/node_modules/base64-arraybuffer/package.json +54 -0
  50. package/node_modules/base64-arraybuffer/rollup.config.ts +40 -0
  51. package/node_modules/css-line-break/CHANGELOG.md +58 -0
  52. package/node_modules/css-line-break/LICENSE +22 -0
  53. package/node_modules/css-line-break/README.md +66 -0
  54. package/node_modules/css-line-break/dist/css-line-break.es5.js +706 -0
  55. package/node_modules/css-line-break/dist/css-line-break.es5.js.map +1 -0
  56. package/node_modules/css-line-break/dist/css-line-break.umd.js +718 -0
  57. package/node_modules/css-line-break/dist/css-line-break.umd.js.map +1 -0
  58. package/node_modules/css-line-break/dist/lib/LineBreak.js +516 -0
  59. package/node_modules/css-line-break/dist/lib/LineBreak.js.map +1 -0
  60. package/node_modules/css-line-break/dist/lib/Util.js +109 -0
  61. package/node_modules/css-line-break/dist/lib/Util.js.map +1 -0
  62. package/node_modules/css-line-break/dist/lib/index.js +9 -0
  63. package/node_modules/css-line-break/dist/lib/index.js.map +1 -0
  64. package/node_modules/css-line-break/dist/lib/linebreak-trie.js +6 -0
  65. package/node_modules/css-line-break/dist/lib/linebreak-trie.js.map +1 -0
  66. package/node_modules/css-line-break/dist/types/LineBreak.d.ts +38 -0
  67. package/node_modules/css-line-break/dist/types/Util.d.ts +5 -0
  68. package/node_modules/css-line-break/dist/types/index.d.ts +2 -0
  69. package/node_modules/css-line-break/dist/types/linebreak-trie.d.ts +2 -0
  70. package/node_modules/css-line-break/package.json +61 -0
  71. package/node_modules/css-line-break/rollup.config.ts +40 -0
  72. package/node_modules/html2canvas/CHANGELOG.md +566 -0
  73. package/node_modules/html2canvas/LICENSE +22 -0
  74. package/node_modules/html2canvas/README.md +73 -0
  75. package/node_modules/html2canvas/dist/html2canvas.esm.js +7822 -0
  76. package/node_modules/html2canvas/dist/html2canvas.esm.js.map +1 -0
  77. package/node_modules/html2canvas/dist/html2canvas.js +7830 -0
  78. package/node_modules/html2canvas/dist/html2canvas.js.map +1 -0
  79. package/node_modules/html2canvas/dist/html2canvas.min.js +20 -0
  80. package/node_modules/html2canvas/dist/lib/__tests__/index.js +144 -0
  81. package/node_modules/html2canvas/dist/lib/__tests__/index.js.map +1 -0
  82. package/node_modules/html2canvas/dist/lib/core/__mocks__/cache-storage.js +10 -0
  83. package/node_modules/html2canvas/dist/lib/core/__mocks__/cache-storage.js.map +1 -0
  84. package/node_modules/html2canvas/dist/lib/core/__mocks__/context.js +22 -0
  85. package/node_modules/html2canvas/dist/lib/core/__mocks__/context.js.map +1 -0
  86. package/node_modules/html2canvas/dist/lib/core/__mocks__/features.js +12 -0
  87. package/node_modules/html2canvas/dist/lib/core/__mocks__/features.js.map +1 -0
  88. package/node_modules/html2canvas/dist/lib/core/__mocks__/logger.js +24 -0
  89. package/node_modules/html2canvas/dist/lib/core/__mocks__/logger.js.map +1 -0
  90. package/node_modules/html2canvas/dist/lib/core/__tests__/cache-storage.js +420 -0
  91. package/node_modules/html2canvas/dist/lib/core/__tests__/cache-storage.js.map +1 -0
  92. package/node_modules/html2canvas/dist/lib/core/__tests__/logger.js +28 -0
  93. package/node_modules/html2canvas/dist/lib/core/__tests__/logger.js.map +1 -0
  94. package/node_modules/html2canvas/dist/lib/core/bitwise.js +6 -0
  95. package/node_modules/html2canvas/dist/lib/core/bitwise.js.map +1 -0
  96. package/node_modules/html2canvas/dist/lib/core/cache-storage.js +198 -0
  97. package/node_modules/html2canvas/dist/lib/core/cache-storage.js.map +1 -0
  98. package/node_modules/html2canvas/dist/lib/core/context.js +18 -0
  99. package/node_modules/html2canvas/dist/lib/core/context.js.map +1 -0
  100. package/node_modules/html2canvas/dist/lib/core/debugger.js +25 -0
  101. package/node_modules/html2canvas/dist/lib/core/debugger.js.map +1 -0
  102. package/node_modules/html2canvas/dist/lib/core/features.js +193 -0
  103. package/node_modules/html2canvas/dist/lib/core/features.js.map +1 -0
  104. package/node_modules/html2canvas/dist/lib/core/logger.js +88 -0
  105. package/node_modules/html2canvas/dist/lib/core/logger.js.map +1 -0
  106. package/node_modules/html2canvas/dist/lib/core/util.js +5 -0
  107. package/node_modules/html2canvas/dist/lib/core/util.js.map +1 -0
  108. package/node_modules/html2canvas/dist/lib/css/IPropertyDescriptor.js +3 -0
  109. package/node_modules/html2canvas/dist/lib/css/IPropertyDescriptor.js.map +1 -0
  110. package/node_modules/html2canvas/dist/lib/css/ITypeDescriptor.js +3 -0
  111. package/node_modules/html2canvas/dist/lib/css/ITypeDescriptor.js.map +1 -0
  112. package/node_modules/html2canvas/dist/lib/css/index.js +216 -0
  113. package/node_modules/html2canvas/dist/lib/css/index.js.map +1 -0
  114. package/node_modules/html2canvas/dist/lib/css/layout/__mocks__/bounds.js +9 -0
  115. package/node_modules/html2canvas/dist/lib/css/layout/__mocks__/bounds.js.map +1 -0
  116. package/node_modules/html2canvas/dist/lib/css/layout/bounds.js +42 -0
  117. package/node_modules/html2canvas/dist/lib/css/layout/bounds.js.map +1 -0
  118. package/node_modules/html2canvas/dist/lib/css/layout/text.js +137 -0
  119. package/node_modules/html2canvas/dist/lib/css/layout/text.js.map +1 -0
  120. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/background-tests.js +48 -0
  121. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/background-tests.js.map +1 -0
  122. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/font-family.js +25 -0
  123. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/font-family.js.map +1 -0
  124. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/paint-order.js +88 -0
  125. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/paint-order.js.map +1 -0
  126. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/text-shadow.js +94 -0
  127. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/text-shadow.js.map +1 -0
  128. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/transform-tests.js +18 -0
  129. package/node_modules/html2canvas/dist/lib/css/property-descriptors/__tests__/transform-tests.js.map +1 -0
  130. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-clip.js +24 -0
  131. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-clip.js.map +1 -0
  132. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-color.js +11 -0
  133. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-color.js.map +1 -0
  134. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-image.js +24 -0
  135. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-image.js.map +1 -0
  136. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-origin.js +24 -0
  137. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-origin.js.map +1 -0
  138. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-position.js +17 -0
  139. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-position.js.map +1 -0
  140. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-repeat.js +36 -0
  141. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-repeat.js.map +1 -0
  142. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-size.js +24 -0
  143. package/node_modules/html2canvas/dist/lib/css/property-descriptors/background-size.js.map +1 -0
  144. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-color.js +15 -0
  145. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-color.js.map +1 -0
  146. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-radius.js +18 -0
  147. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-radius.js.map +1 -0
  148. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-style.js +27 -0
  149. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-style.js.map +1 -0
  150. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-width.js +21 -0
  151. package/node_modules/html2canvas/dist/lib/css/property-descriptors/border-width.js.map +1 -0
  152. package/node_modules/html2canvas/dist/lib/css/property-descriptors/box-shadow.js +55 -0
  153. package/node_modules/html2canvas/dist/lib/css/property-descriptors/box-shadow.js.map +1 -0
  154. package/node_modules/html2canvas/dist/lib/css/property-descriptors/color.js +11 -0
  155. package/node_modules/html2canvas/dist/lib/css/property-descriptors/color.js.map +1 -0
  156. package/node_modules/html2canvas/dist/lib/css/property-descriptors/content.js +20 -0
  157. package/node_modules/html2canvas/dist/lib/css/property-descriptors/content.js.map +1 -0
  158. package/node_modules/html2canvas/dist/lib/css/property-descriptors/counter-increment.js +31 -0
  159. package/node_modules/html2canvas/dist/lib/css/property-descriptors/counter-increment.js.map +1 -0
  160. package/node_modules/html2canvas/dist/lib/css/property-descriptors/counter-reset.js +27 -0
  161. package/node_modules/html2canvas/dist/lib/css/property-descriptors/counter-reset.js.map +1 -0
  162. package/node_modules/html2canvas/dist/lib/css/property-descriptors/direction.js +19 -0
  163. package/node_modules/html2canvas/dist/lib/css/property-descriptors/direction.js.map +1 -0
  164. package/node_modules/html2canvas/dist/lib/css/property-descriptors/display.js +82 -0
  165. package/node_modules/html2canvas/dist/lib/css/property-descriptors/display.js.map +1 -0
  166. package/node_modules/html2canvas/dist/lib/css/property-descriptors/duration.js +15 -0
  167. package/node_modules/html2canvas/dist/lib/css/property-descriptors/duration.js.map +1 -0
  168. package/node_modules/html2canvas/dist/lib/css/property-descriptors/float.js +23 -0
  169. package/node_modules/html2canvas/dist/lib/css/property-descriptors/float.js.map +1 -0
  170. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-family.js +33 -0
  171. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-family.js.map +1 -0
  172. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-size.js +11 -0
  173. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-size.js.map +1 -0
  174. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-style.js +21 -0
  175. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-style.js.map +1 -0
  176. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-variant.js +14 -0
  177. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-variant.js.map +1 -0
  178. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-weight.js +26 -0
  179. package/node_modules/html2canvas/dist/lib/css/property-descriptors/font-weight.js.map +1 -0
  180. package/node_modules/html2canvas/dist/lib/css/property-descriptors/letter-spacing.js +22 -0
  181. package/node_modules/html2canvas/dist/lib/css/property-descriptors/letter-spacing.js.map +1 -0
  182. package/node_modules/html2canvas/dist/lib/css/property-descriptors/line-break.js +24 -0
  183. package/node_modules/html2canvas/dist/lib/css/property-descriptors/line-break.js.map +1 -0
  184. package/node_modules/html2canvas/dist/lib/css/property-descriptors/line-height.js +25 -0
  185. package/node_modules/html2canvas/dist/lib/css/property-descriptors/line-height.js.map +1 -0
  186. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-image.js +17 -0
  187. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-image.js.map +1 -0
  188. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-position.js +19 -0
  189. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-position.js.map +1 -0
  190. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-type.js +123 -0
  191. package/node_modules/html2canvas/dist/lib/css/property-descriptors/list-style-type.js.map +1 -0
  192. package/node_modules/html2canvas/dist/lib/css/property-descriptors/margin.js +14 -0
  193. package/node_modules/html2canvas/dist/lib/css/property-descriptors/margin.js.map +1 -0
  194. package/node_modules/html2canvas/dist/lib/css/property-descriptors/opacity.js +17 -0
  195. package/node_modules/html2canvas/dist/lib/css/property-descriptors/opacity.js.map +1 -0
  196. package/node_modules/html2canvas/dist/lib/css/property-descriptors/overflow-wrap.js +19 -0
  197. package/node_modules/html2canvas/dist/lib/css/property-descriptors/overflow-wrap.js.map +1 -0
  198. package/node_modules/html2canvas/dist/lib/css/property-descriptors/overflow.js +28 -0
  199. package/node_modules/html2canvas/dist/lib/css/property-descriptors/overflow.js.map +1 -0
  200. package/node_modules/html2canvas/dist/lib/css/property-descriptors/padding.js +15 -0
  201. package/node_modules/html2canvas/dist/lib/css/property-descriptors/padding.js.map +1 -0
  202. package/node_modules/html2canvas/dist/lib/css/property-descriptors/paint-order.js +34 -0
  203. package/node_modules/html2canvas/dist/lib/css/property-descriptors/paint-order.js.map +1 -0
  204. package/node_modules/html2canvas/dist/lib/css/property-descriptors/position.js +23 -0
  205. package/node_modules/html2canvas/dist/lib/css/property-descriptors/position.js.map +1 -0
  206. package/node_modules/html2canvas/dist/lib/css/property-descriptors/quotes.js +42 -0
  207. package/node_modules/html2canvas/dist/lib/css/property-descriptors/quotes.js.map +1 -0
  208. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-align.js +22 -0
  209. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-align.js.map +1 -0
  210. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-decoration-color.js +11 -0
  211. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-decoration-color.js.map +1 -0
  212. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-decoration-line.js +29 -0
  213. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-decoration-line.js.map +1 -0
  214. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-shadow.js +47 -0
  215. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-shadow.js.map +1 -0
  216. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-transform.js +21 -0
  217. package/node_modules/html2canvas/dist/lib/css/property-descriptors/text-transform.js.map +1 -0
  218. package/node_modules/html2canvas/dist/lib/css/property-descriptors/transform-origin.js +25 -0
  219. package/node_modules/html2canvas/dist/lib/css/property-descriptors/transform-origin.js.map +1 -0
  220. package/node_modules/html2canvas/dist/lib/css/property-descriptors/transform.js +37 -0
  221. package/node_modules/html2canvas/dist/lib/css/property-descriptors/transform.js.map +1 -0
  222. package/node_modules/html2canvas/dist/lib/css/property-descriptors/visibility.js +21 -0
  223. package/node_modules/html2canvas/dist/lib/css/property-descriptors/visibility.js.map +1 -0
  224. package/node_modules/html2canvas/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +11 -0
  225. package/node_modules/html2canvas/dist/lib/css/property-descriptors/webkit-text-stroke-color.js.map +1 -0
  226. package/node_modules/html2canvas/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +17 -0
  227. package/node_modules/html2canvas/dist/lib/css/property-descriptors/webkit-text-stroke-width.js.map +1 -0
  228. package/node_modules/html2canvas/dist/lib/css/property-descriptors/word-break.js +27 -0
  229. package/node_modules/html2canvas/dist/lib/css/property-descriptors/word-break.js.map +1 -0
  230. package/node_modules/html2canvas/dist/lib/css/property-descriptors/z-index.js +20 -0
  231. package/node_modules/html2canvas/dist/lib/css/property-descriptors/z-index.js.map +1 -0
  232. package/node_modules/html2canvas/dist/lib/css/syntax/__tests__/tokernizer-tests.js +34 -0
  233. package/node_modules/html2canvas/dist/lib/css/syntax/__tests__/tokernizer-tests.js.map +1 -0
  234. package/node_modules/html2canvas/dist/lib/css/syntax/parser.js +147 -0
  235. package/node_modules/html2canvas/dist/lib/css/syntax/parser.js.map +1 -0
  236. package/node_modules/html2canvas/dist/lib/css/syntax/tokenizer.js +630 -0
  237. package/node_modules/html2canvas/dist/lib/css/syntax/tokenizer.js.map +1 -0
  238. package/node_modules/html2canvas/dist/lib/css/types/__tests__/color-tests.js +66 -0
  239. package/node_modules/html2canvas/dist/lib/css/types/__tests__/color-tests.js.map +1 -0
  240. package/node_modules/html2canvas/dist/lib/css/types/__tests__/image-tests.js +233 -0
  241. package/node_modules/html2canvas/dist/lib/css/types/__tests__/image-tests.js.map +1 -0
  242. package/node_modules/html2canvas/dist/lib/css/types/angle.js +81 -0
  243. package/node_modules/html2canvas/dist/lib/css/types/angle.js.map +1 -0
  244. package/node_modules/html2canvas/dist/lib/css/types/color.js +288 -0
  245. package/node_modules/html2canvas/dist/lib/css/types/color.js.map +1 -0
  246. package/node_modules/html2canvas/dist/lib/css/types/functions/-prefix-linear-gradient.js +33 -0
  247. package/node_modules/html2canvas/dist/lib/css/types/functions/-prefix-linear-gradient.js.map +1 -0
  248. package/node_modules/html2canvas/dist/lib/css/types/functions/-prefix-radial-gradient.js +84 -0
  249. package/node_modules/html2canvas/dist/lib/css/types/functions/-prefix-radial-gradient.js.map +1 -0
  250. package/node_modules/html2canvas/dist/lib/css/types/functions/-webkit-gradient.js +60 -0
  251. package/node_modules/html2canvas/dist/lib/css/types/functions/-webkit-gradient.js.map +1 -0
  252. package/node_modules/html2canvas/dist/lib/css/types/functions/__tests__/radial-gradient.js +68 -0
  253. package/node_modules/html2canvas/dist/lib/css/types/functions/__tests__/radial-gradient.js.map +1 -0
  254. package/node_modules/html2canvas/dist/lib/css/types/functions/counter.js +374 -0
  255. package/node_modules/html2canvas/dist/lib/css/types/functions/counter.js.map +1 -0
  256. package/node_modules/html2canvas/dist/lib/css/types/functions/gradient.js +165 -0
  257. package/node_modules/html2canvas/dist/lib/css/types/functions/gradient.js.map +1 -0
  258. package/node_modules/html2canvas/dist/lib/css/types/functions/linear-gradient.js +28 -0
  259. package/node_modules/html2canvas/dist/lib/css/types/functions/linear-gradient.js.map +1 -0
  260. package/node_modules/html2canvas/dist/lib/css/types/functions/radial-gradient.js +91 -0
  261. package/node_modules/html2canvas/dist/lib/css/types/functions/radial-gradient.js.map +1 -0
  262. package/node_modules/html2canvas/dist/lib/css/types/image.js +53 -0
  263. package/node_modules/html2canvas/dist/lib/css/types/image.js.map +1 -0
  264. package/node_modules/html2canvas/dist/lib/css/types/index.js +3 -0
  265. package/node_modules/html2canvas/dist/lib/css/types/index.js.map +1 -0
  266. package/node_modules/html2canvas/dist/lib/css/types/length-percentage.js +52 -0
  267. package/node_modules/html2canvas/dist/lib/css/types/length-percentage.js.map +1 -0
  268. package/node_modules/html2canvas/dist/lib/css/types/length.js +8 -0
  269. package/node_modules/html2canvas/dist/lib/css/types/length.js.map +1 -0
  270. package/node_modules/html2canvas/dist/lib/css/types/time.js +18 -0
  271. package/node_modules/html2canvas/dist/lib/css/types/time.js.map +1 -0
  272. package/node_modules/html2canvas/dist/lib/dom/__mocks__/document-cloner.js +24 -0
  273. package/node_modules/html2canvas/dist/lib/dom/__mocks__/document-cloner.js.map +1 -0
  274. package/node_modules/html2canvas/dist/lib/dom/document-cloner.js +530 -0
  275. package/node_modules/html2canvas/dist/lib/dom/document-cloner.js.map +1 -0
  276. package/node_modules/html2canvas/dist/lib/dom/element-container.js +35 -0
  277. package/node_modules/html2canvas/dist/lib/dom/element-container.js.map +1 -0
  278. package/node_modules/html2canvas/dist/lib/dom/elements/li-element-container.js +30 -0
  279. package/node_modules/html2canvas/dist/lib/dom/elements/li-element-container.js.map +1 -0
  280. package/node_modules/html2canvas/dist/lib/dom/elements/ol-element-container.js +31 -0
  281. package/node_modules/html2canvas/dist/lib/dom/elements/ol-element-container.js.map +1 -0
  282. package/node_modules/html2canvas/dist/lib/dom/elements/select-element-container.js +31 -0
  283. package/node_modules/html2canvas/dist/lib/dom/elements/select-element-container.js.map +1 -0
  284. package/node_modules/html2canvas/dist/lib/dom/elements/textarea-element-container.js +30 -0
  285. package/node_modules/html2canvas/dist/lib/dom/elements/textarea-element-container.js.map +1 -0
  286. package/node_modules/html2canvas/dist/lib/dom/node-parser.js +142 -0
  287. package/node_modules/html2canvas/dist/lib/dom/node-parser.js.map +1 -0
  288. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/canvas-element-container.js +32 -0
  289. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/canvas-element-container.js.map +1 -0
  290. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/iframe-element-container.js +55 -0
  291. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/iframe-element-container.js.map +1 -0
  292. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/image-element-container.js +33 -0
  293. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/image-element-container.js.map +1 -0
  294. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/index.js +3 -0
  295. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/index.js.map +1 -0
  296. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/input-element-container.js +102 -0
  297. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/input-element-container.js.map +1 -0
  298. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/pseudo-elements.js +1 -0
  299. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/pseudo-elements.js.map +1 -0
  300. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/svg-element-container.js +38 -0
  301. package/node_modules/html2canvas/dist/lib/dom/replaced-elements/svg-element-container.js.map +1 -0
  302. package/node_modules/html2canvas/dist/lib/dom/text-container.js +32 -0
  303. package/node_modules/html2canvas/dist/lib/dom/text-container.js.map +1 -0
  304. package/node_modules/html2canvas/dist/lib/index.js +181 -0
  305. package/node_modules/html2canvas/dist/lib/index.js.map +1 -0
  306. package/node_modules/html2canvas/dist/lib/invariant.js +10 -0
  307. package/node_modules/html2canvas/dist/lib/invariant.js.map +1 -0
  308. package/node_modules/html2canvas/dist/lib/render/background.js +187 -0
  309. package/node_modules/html2canvas/dist/lib/render/background.js.map +1 -0
  310. package/node_modules/html2canvas/dist/lib/render/bezier-curve.js +36 -0
  311. package/node_modules/html2canvas/dist/lib/render/bezier-curve.js.map +1 -0
  312. package/node_modules/html2canvas/dist/lib/render/border.js +105 -0
  313. package/node_modules/html2canvas/dist/lib/render/border.js.map +1 -0
  314. package/node_modules/html2canvas/dist/lib/render/bound-curves.js +190 -0
  315. package/node_modules/html2canvas/dist/lib/render/bound-curves.js.map +1 -0
  316. package/node_modules/html2canvas/dist/lib/render/box-sizing.js +21 -0
  317. package/node_modules/html2canvas/dist/lib/render/box-sizing.js.map +1 -0
  318. package/node_modules/html2canvas/dist/lib/render/canvas/canvas-renderer.js +1030 -0
  319. package/node_modules/html2canvas/dist/lib/render/canvas/canvas-renderer.js.map +1 -0
  320. package/node_modules/html2canvas/dist/lib/render/canvas/foreignobject-renderer.js +108 -0
  321. package/node_modules/html2canvas/dist/lib/render/canvas/foreignobject-renderer.js.map +1 -0
  322. package/node_modules/html2canvas/dist/lib/render/effects.js +41 -0
  323. package/node_modules/html2canvas/dist/lib/render/effects.js.map +1 -0
  324. package/node_modules/html2canvas/dist/lib/render/font-metrics.js +55 -0
  325. package/node_modules/html2canvas/dist/lib/render/font-metrics.js.map +1 -0
  326. package/node_modules/html2canvas/dist/lib/render/path.js +27 -0
  327. package/node_modules/html2canvas/dist/lib/render/path.js.map +1 -0
  328. package/node_modules/html2canvas/dist/lib/render/renderer.js +12 -0
  329. package/node_modules/html2canvas/dist/lib/render/renderer.js.map +1 -0
  330. package/node_modules/html2canvas/dist/lib/render/stacking-context.js +172 -0
  331. package/node_modules/html2canvas/dist/lib/render/stacking-context.js.map +1 -0
  332. package/node_modules/html2canvas/dist/lib/render/vector.js +18 -0
  333. package/node_modules/html2canvas/dist/lib/render/vector.js.map +1 -0
  334. package/node_modules/html2canvas/dist/types/__tests__/index.d.ts +1 -0
  335. package/node_modules/html2canvas/dist/types/core/__mocks__/cache-storage.d.ts +2 -0
  336. package/node_modules/html2canvas/dist/types/core/__mocks__/context.d.ts +9 -0
  337. package/node_modules/html2canvas/dist/types/core/__mocks__/features.d.ts +8 -0
  338. package/node_modules/html2canvas/dist/types/core/__mocks__/logger.d.ts +9 -0
  339. package/node_modules/html2canvas/dist/types/core/__tests__/cache-storage.d.ts +1 -0
  340. package/node_modules/html2canvas/dist/types/core/__tests__/logger.d.ts +1 -0
  341. package/node_modules/html2canvas/dist/types/core/bitwise.d.ts +1 -0
  342. package/node_modules/html2canvas/dist/types/core/cache-storage.d.ts +26 -0
  343. package/node_modules/html2canvas/dist/types/core/context.d.ts +15 -0
  344. package/node_modules/html2canvas/dist/types/core/debugger.d.ts +8 -0
  345. package/node_modules/html2canvas/dist/types/core/features.d.ts +12 -0
  346. package/node_modules/html2canvas/dist/types/core/logger.d.ts +18 -0
  347. package/node_modules/html2canvas/dist/types/core/util.d.ts +1 -0
  348. package/node_modules/html2canvas/dist/types/css/IPropertyDescriptor.d.ts +36 -0
  349. package/node_modules/html2canvas/dist/types/css/ITypeDescriptor.d.ts +6 -0
  350. package/node_modules/html2canvas/dist/types/css/index.d.ts +132 -0
  351. package/node_modules/html2canvas/dist/types/css/layout/__mocks__/bounds.d.ts +2 -0
  352. package/node_modules/html2canvas/dist/types/css/layout/bounds.d.ts +14 -0
  353. package/node_modules/html2canvas/dist/types/css/layout/text.d.ts +10 -0
  354. package/node_modules/html2canvas/dist/types/css/property-descriptors/__tests__/background-tests.d.ts +1 -0
  355. package/node_modules/html2canvas/dist/types/css/property-descriptors/__tests__/font-family.d.ts +1 -0
  356. package/node_modules/html2canvas/dist/types/css/property-descriptors/__tests__/paint-order.d.ts +1 -0
  357. package/node_modules/html2canvas/dist/types/css/property-descriptors/__tests__/text-shadow.d.ts +1 -0
  358. package/node_modules/html2canvas/dist/types/css/property-descriptors/__tests__/transform-tests.d.ts +1 -0
  359. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-clip.d.ts +8 -0
  360. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-color.d.ts +2 -0
  361. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-image.d.ts +3 -0
  362. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-origin.d.ts +8 -0
  363. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-position.d.ts +5 -0
  364. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-repeat.d.ts +9 -0
  365. package/node_modules/html2canvas/dist/types/css/property-descriptors/background-size.d.ts +11 -0
  366. package/node_modules/html2canvas/dist/types/css/property-descriptors/border-color.d.ts +5 -0
  367. package/node_modules/html2canvas/dist/types/css/property-descriptors/border-radius.d.ts +7 -0
  368. package/node_modules/html2canvas/dist/types/css/property-descriptors/border-style.d.ts +12 -0
  369. package/node_modules/html2canvas/dist/types/css/property-descriptors/border-width.d.ts +5 -0
  370. package/node_modules/html2canvas/dist/types/css/property-descriptors/box-shadow.d.ts +14 -0
  371. package/node_modules/html2canvas/dist/types/css/property-descriptors/color.d.ts +2 -0
  372. package/node_modules/html2canvas/dist/types/css/property-descriptors/content.d.ts +4 -0
  373. package/node_modules/html2canvas/dist/types/css/property-descriptors/counter-increment.d.ts +7 -0
  374. package/node_modules/html2canvas/dist/types/css/property-descriptors/counter-reset.d.ts +7 -0
  375. package/node_modules/html2canvas/dist/types/css/property-descriptors/direction.d.ts +6 -0
  376. package/node_modules/html2canvas/dist/types/css/property-descriptors/display.d.ts +35 -0
  377. package/node_modules/html2canvas/dist/types/css/property-descriptors/duration.d.ts +2 -0
  378. package/node_modules/html2canvas/dist/types/css/property-descriptors/float.d.ts +9 -0
  379. package/node_modules/html2canvas/dist/types/css/property-descriptors/font-family.d.ts +4 -0
  380. package/node_modules/html2canvas/dist/types/css/property-descriptors/font-size.d.ts +2 -0
  381. package/node_modules/html2canvas/dist/types/css/property-descriptors/font-style.d.ts +7 -0
  382. package/node_modules/html2canvas/dist/types/css/property-descriptors/font-variant.d.ts +2 -0
  383. package/node_modules/html2canvas/dist/types/css/property-descriptors/font-weight.d.ts +2 -0
  384. package/node_modules/html2canvas/dist/types/css/property-descriptors/letter-spacing.d.ts +2 -0
  385. package/node_modules/html2canvas/dist/types/css/property-descriptors/line-break.d.ts +6 -0
  386. package/node_modules/html2canvas/dist/types/css/property-descriptors/line-height.d.ts +4 -0
  387. package/node_modules/html2canvas/dist/types/css/property-descriptors/list-style-image.d.ts +3 -0
  388. package/node_modules/html2canvas/dist/types/css/property-descriptors/list-style-position.d.ts +6 -0
  389. package/node_modules/html2canvas/dist/types/css/property-descriptors/list-style-type.d.ts +58 -0
  390. package/node_modules/html2canvas/dist/types/css/property-descriptors/margin.d.ts +5 -0
  391. package/node_modules/html2canvas/dist/types/css/property-descriptors/opacity.d.ts +2 -0
  392. package/node_modules/html2canvas/dist/types/css/property-descriptors/overflow-wrap.d.ts +6 -0
  393. package/node_modules/html2canvas/dist/types/css/property-descriptors/overflow.d.ts +9 -0
  394. package/node_modules/html2canvas/dist/types/css/property-descriptors/padding.d.ts +5 -0
  395. package/node_modules/html2canvas/dist/types/css/property-descriptors/paint-order.d.ts +8 -0
  396. package/node_modules/html2canvas/dist/types/css/property-descriptors/position.d.ts +9 -0
  397. package/node_modules/html2canvas/dist/types/css/property-descriptors/quotes.d.ts +8 -0
  398. package/node_modules/html2canvas/dist/types/css/property-descriptors/text-align.d.ts +7 -0
  399. package/node_modules/html2canvas/dist/types/css/property-descriptors/text-decoration-color.d.ts +2 -0
  400. package/node_modules/html2canvas/dist/types/css/property-descriptors/text-decoration-line.d.ts +10 -0
  401. package/node_modules/html2canvas/dist/types/css/property-descriptors/text-shadow.d.ts +12 -0
  402. package/node_modules/html2canvas/dist/types/css/property-descriptors/text-transform.d.ts +8 -0
  403. package/node_modules/html2canvas/dist/types/css/property-descriptors/transform-origin.d.ts +4 -0
  404. package/node_modules/html2canvas/dist/types/css/property-descriptors/transform.d.ts +4 -0
  405. package/node_modules/html2canvas/dist/types/css/property-descriptors/visibility.d.ts +7 -0
  406. package/node_modules/html2canvas/dist/types/css/property-descriptors/webkit-text-stroke-color.d.ts +2 -0
  407. package/node_modules/html2canvas/dist/types/css/property-descriptors/webkit-text-stroke-width.d.ts +2 -0
  408. package/node_modules/html2canvas/dist/types/css/property-descriptors/word-break.d.ts +7 -0
  409. package/node_modules/html2canvas/dist/types/css/property-descriptors/z-index.d.ts +7 -0
  410. package/node_modules/html2canvas/dist/types/css/syntax/__tests__/tokernizer-tests.d.ts +1 -0
  411. package/node_modules/html2canvas/dist/types/css/syntax/parser.d.ts +34 -0
  412. package/node_modules/html2canvas/dist/types/css/syntax/tokenizer.d.ts +94 -0
  413. package/node_modules/html2canvas/dist/types/css/types/__tests__/color-tests.d.ts +1 -0
  414. package/node_modules/html2canvas/dist/types/css/types/__tests__/image-tests.d.ts +1 -0
  415. package/node_modules/html2canvas/dist/types/css/types/angle.d.ts +7 -0
  416. package/node_modules/html2canvas/dist/types/css/types/color.d.ts +11 -0
  417. package/node_modules/html2canvas/dist/types/css/types/functions/-prefix-linear-gradient.d.ts +4 -0
  418. package/node_modules/html2canvas/dist/types/css/types/functions/-prefix-radial-gradient.d.ts +4 -0
  419. package/node_modules/html2canvas/dist/types/css/types/functions/-webkit-gradient.d.ts +4 -0
  420. package/node_modules/html2canvas/dist/types/css/types/functions/__tests__/radial-gradient.d.ts +1 -0
  421. package/node_modules/html2canvas/dist/types/css/types/functions/counter.d.ts +10 -0
  422. package/node_modules/html2canvas/dist/types/css/types/functions/gradient.d.ts +7 -0
  423. package/node_modules/html2canvas/dist/types/css/types/functions/linear-gradient.d.ts +4 -0
  424. package/node_modules/html2canvas/dist/types/css/types/functions/radial-gradient.d.ts +12 -0
  425. package/node_modules/html2canvas/dist/types/css/types/image.d.ts +54 -0
  426. package/node_modules/html2canvas/dist/types/css/types/index.d.ts +1 -0
  427. package/node_modules/html2canvas/dist/types/css/types/length-percentage.d.ts +11 -0
  428. package/node_modules/html2canvas/dist/types/css/types/length.d.ts +4 -0
  429. package/node_modules/html2canvas/dist/types/css/types/time.d.ts +2 -0
  430. package/node_modules/html2canvas/dist/types/dom/__mocks__/document-cloner.d.ts +6 -0
  431. package/node_modules/html2canvas/dist/types/dom/document-cloner.d.ts +45 -0
  432. package/node_modules/html2canvas/dist/types/dom/element-container.d.ts +19 -0
  433. package/node_modules/html2canvas/dist/types/dom/elements/li-element-container.d.ts +6 -0
  434. package/node_modules/html2canvas/dist/types/dom/elements/ol-element-container.d.ts +7 -0
  435. package/node_modules/html2canvas/dist/types/dom/elements/select-element-container.d.ts +6 -0
  436. package/node_modules/html2canvas/dist/types/dom/elements/textarea-element-container.d.ts +6 -0
  437. package/node_modules/html2canvas/dist/types/dom/node-parser.d.ts +23 -0
  438. package/node_modules/html2canvas/dist/types/dom/replaced-elements/canvas-element-container.d.ts +8 -0
  439. package/node_modules/html2canvas/dist/types/dom/replaced-elements/iframe-element-container.d.ts +11 -0
  440. package/node_modules/html2canvas/dist/types/dom/replaced-elements/image-element-container.d.ts +8 -0
  441. package/node_modules/html2canvas/dist/types/dom/replaced-elements/index.d.ts +4 -0
  442. package/node_modules/html2canvas/dist/types/dom/replaced-elements/input-element-container.d.ts +12 -0
  443. package/node_modules/html2canvas/dist/types/dom/replaced-elements/pseudo-elements.d.ts +0 -0
  444. package/node_modules/html2canvas/dist/types/dom/replaced-elements/svg-element-container.d.ts +8 -0
  445. package/node_modules/html2canvas/dist/types/dom/text-container.d.ts +8 -0
  446. package/node_modules/html2canvas/dist/types/index.d.ts +10 -0
  447. package/node_modules/html2canvas/dist/types/invariant.d.ts +1 -0
  448. package/node_modules/html2canvas/dist/types/render/background.d.ts +16 -0
  449. package/node_modules/html2canvas/dist/types/render/bezier-curve.d.ts +14 -0
  450. package/node_modules/html2canvas/dist/types/render/border.d.ts +6 -0
  451. package/node_modules/html2canvas/dist/types/render/bound-curves.d.ts +32 -0
  452. package/node_modules/html2canvas/dist/types/render/box-sizing.d.ts +4 -0
  453. package/node_modules/html2canvas/dist/types/render/canvas/canvas-renderer.d.ts +53 -0
  454. package/node_modules/html2canvas/dist/types/render/canvas/foreignobject-renderer.d.ts +11 -0
  455. package/node_modules/html2canvas/dist/types/render/effects.d.ts +38 -0
  456. package/node_modules/html2canvas/dist/types/render/font-metrics.d.ts +11 -0
  457. package/node_modules/html2canvas/dist/types/render/path.d.ts +13 -0
  458. package/node_modules/html2canvas/dist/types/render/renderer.d.ts +7 -0
  459. package/node_modules/html2canvas/dist/types/render/stacking-context.d.ts +24 -0
  460. package/node_modules/html2canvas/dist/types/render/vector.d.ts +9 -0
  461. package/node_modules/html2canvas/package.json +124 -0
  462. package/node_modules/html2canvas/tsconfig.json +21 -0
  463. package/node_modules/text-segmentation/CHANGELOG.md +43 -0
  464. package/node_modules/text-segmentation/LICENSE +22 -0
  465. package/node_modules/text-segmentation/README.md +27 -0
  466. package/node_modules/text-segmentation/dist/lib/GraphemeBreak.js +218 -0
  467. package/node_modules/text-segmentation/dist/lib/GraphemeBreak.js.map +1 -0
  468. package/node_modules/text-segmentation/dist/lib/grapheme-break-trie.js +6 -0
  469. package/node_modules/text-segmentation/dist/lib/grapheme-break-trie.js.map +1 -0
  470. package/node_modules/text-segmentation/dist/lib/index.js +9 -0
  471. package/node_modules/text-segmentation/dist/lib/index.js.map +1 -0
  472. package/node_modules/text-segmentation/dist/text-segmentation.es5.js +384 -0
  473. package/node_modules/text-segmentation/dist/text-segmentation.es5.js.map +1 -0
  474. package/node_modules/text-segmentation/dist/text-segmentation.umd.js +397 -0
  475. package/node_modules/text-segmentation/dist/text-segmentation.umd.js.map +1 -0
  476. package/node_modules/text-segmentation/dist/types/GraphemeBreak.d.ts +21 -0
  477. package/node_modules/text-segmentation/dist/types/grapheme-break-trie.d.ts +2 -0
  478. package/node_modules/text-segmentation/dist/types/index.d.ts +1 -0
  479. package/node_modules/text-segmentation/package.json +55 -0
  480. package/node_modules/text-segmentation/rollup.config.ts +40 -0
  481. package/node_modules/utrie/CHANGELOG.md +32 -0
  482. package/node_modules/utrie/LICENSE +22 -0
  483. package/node_modules/utrie/dist/lib/Trie.js +143 -0
  484. package/node_modules/utrie/dist/lib/Trie.js.map +1 -0
  485. package/node_modules/utrie/dist/lib/TrieBuilder.js +888 -0
  486. package/node_modules/utrie/dist/lib/TrieBuilder.js.map +1 -0
  487. package/node_modules/utrie/dist/lib/Util.js +54 -0
  488. package/node_modules/utrie/dist/lib/Util.js.map +1 -0
  489. package/node_modules/utrie/dist/lib/index.js +10 -0
  490. package/node_modules/utrie/dist/lib/index.js.map +1 -0
  491. package/node_modules/utrie/dist/types/Trie.d.ts +76 -0
  492. package/node_modules/utrie/dist/types/TrieBuilder.d.ts +65 -0
  493. package/node_modules/utrie/dist/types/Util.d.ts +3 -0
  494. package/node_modules/utrie/dist/types/index.d.ts +2 -0
  495. package/node_modules/utrie/dist/utrie.es5.js +1101 -0
  496. package/node_modules/utrie/dist/utrie.es5.js.map +1 -0
  497. package/node_modules/utrie/dist/utrie.umd.js +1114 -0
  498. package/node_modules/utrie/dist/utrie.umd.js.map +1 -0
  499. package/node_modules/utrie/package.json +53 -0
  500. package/node_modules/utrie/rollup.config.ts +40 -0
  501. package/package.json +1 -1
  502. package/packages/cli/bin/groove.js +10 -1
  503. package/packages/cli/package.json +1 -1
  504. package/packages/cli/src/commands/connect.js +116 -205
  505. package/packages/cli/src/commands/disconnect.js +38 -62
  506. package/packages/cli/src/commands/remotes.js +75 -0
  507. package/packages/daemon/package.json +1 -1
  508. package/packages/daemon/src/api.js +115 -7
  509. package/packages/daemon/src/conversations.js +29 -3
  510. package/packages/daemon/src/process.js +56 -1
  511. package/packages/daemon/src/providers/codex.js +28 -10
  512. package/packages/daemon/src/registry.js +30 -0
  513. package/packages/daemon/src/validate.js +23 -0
  514. package/packages/gui/dist/assets/index-BSqk8cbI.css +1 -0
  515. package/packages/gui/dist/assets/index-B_igwWvq.js +8642 -0
  516. package/packages/gui/dist/index.html +2 -2
  517. package/packages/gui/package.json +2 -1
  518. package/packages/gui/src/components/agents/agent-file-tree.jsx +254 -0
  519. package/packages/gui/src/components/agents/code-review.jsx +177 -0
  520. package/packages/gui/src/components/agents/diff-viewer.jsx +148 -0
  521. package/packages/gui/src/components/agents/workspace-mode.jsx +377 -0
  522. package/packages/gui/src/components/chat/chat-input.jsx +117 -40
  523. package/packages/gui/src/components/chat/chat-messages.jsx +10 -13
  524. package/packages/gui/src/components/chat/chat-view.jsx +26 -1
  525. package/packages/gui/src/components/chat/conversation-list.jsx +14 -14
  526. package/packages/gui/src/components/chat/model-picker.jsx +5 -0
  527. package/packages/gui/src/components/preview/preview-workspace.jsx +6 -5
  528. package/packages/gui/src/components/preview/screenshot-overlay.jsx +41 -29
  529. package/packages/gui/src/stores/groove.js +138 -3
  530. package/packages/gui/src/views/agents.jsx +36 -3
  531. package/packages/gui/src/views/settings.jsx +104 -26
  532. package/test/doomsday-clock/index.html +55 -0
  533. package/test/doomsday-clock/script.js +66 -0
  534. package/test/doomsday-clock/style.css +315 -0
  535. package/node_modules/@groove-dev/gui/dist/assets/index-BbDDgazC.js +0 -8616
  536. package/node_modules/@groove-dev/gui/dist/assets/index-fhMxiPGp.css +0 -1
  537. package/packages/gui/dist/assets/index-BbDDgazC.js +0 -8616
  538. package/packages/gui/dist/assets/index-fhMxiPGp.css +0 -1
@@ -1,278 +1,189 @@
1
- // GROOVE CLI — connect command (SSH tunnel to remote daemon)
1
+ // GROOVE CLI — connect command (SSH tunnel via daemon TunnelManager)
2
2
  // FSL-1.1-Apache-2.0 — see LICENSE
3
3
 
4
- import { execFileSync, spawn } from 'child_process';
5
- import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
6
- import { resolve } from 'path';
7
- import { createConnection } from 'net';
4
+ import { execFileSync } from 'child_process';
8
5
  import chalk from 'chalk';
9
6
 
10
- const REMOTE_PORT = 31415;
11
- const DEFAULT_LOCAL_PORT = 31416;
12
- const MAX_PORT_ATTEMPTS = 10;
7
+ const API = 'http://localhost:31415/api';
13
8
 
14
- // Allow user@host OR plain hostname (SSH config aliases like "groove-ai")
15
- const SSH_TARGET_PATTERN = /^([a-zA-Z0-9._-]+@)?[a-zA-Z0-9._-]+$/;
16
-
17
- function validateTarget(target) {
9
+ function parseTarget(target) {
18
10
  if (!target || typeof target !== 'string') {
19
- throw new Error('SSH target is required (e.g., user@host or ssh-config-alias)');
11
+ throw new Error('SSH target is required (e.g., user@host)');
20
12
  }
21
- // Block injection characters
22
13
  if (/[;|&`$(){}[\]<>!#\n\r\\]/.test(target)) {
23
14
  throw new Error('Invalid characters in SSH target');
24
15
  }
25
- if (!SSH_TARGET_PATTERN.test(target)) {
26
- throw new Error('Invalid SSH target format. Expected: user@hostname or ssh-config-alias');
27
- }
28
16
  if (target.length > 253) {
29
17
  throw new Error('SSH target too long');
30
18
  }
31
- }
32
-
33
- function grooveDir() {
34
- const dir = resolve(process.cwd(), '.groove');
35
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
36
- return dir;
37
- }
38
-
39
- function pidFile() {
40
- return resolve(grooveDir(), 'tunnel.pid');
41
- }
42
-
43
- function tunnelInfoFile() {
44
- return resolve(grooveDir(), 'tunnel.json');
45
- }
46
-
47
- function isPortInUse(port) {
48
- return new Promise((resolve) => {
49
- const conn = createConnection({ host: '127.0.0.1', port });
50
- conn.setTimeout(3000);
51
- conn.on('connect', () => { conn.destroy(); resolve(true); });
52
- conn.on('error', () => resolve(false));
53
- conn.on('timeout', () => { conn.destroy(); resolve(false); });
54
- });
55
- }
56
-
57
- async function findAvailablePort() {
58
- for (let port = DEFAULT_LOCAL_PORT; port < DEFAULT_LOCAL_PORT + MAX_PORT_ATTEMPTS; port++) {
59
- if (!(await isPortInUse(port))) return port;
60
- }
61
- throw new Error(`No available local port found (tried ${DEFAULT_LOCAL_PORT}-${DEFAULT_LOCAL_PORT + MAX_PORT_ATTEMPTS - 1})`);
62
- }
63
-
64
- function preflight(target, keyFile) {
65
- // SSH in and check if daemon is listening on remote
66
- // Use curl to health endpoint — works on both Linux and macOS
67
- const args = [
68
- ...(keyFile ? ['-i', keyFile] : []),
69
- '-o', 'ConnectTimeout=10',
70
- '-o', 'StrictHostKeyChecking=accept-new',
71
- '-o', 'BatchMode=yes',
72
- target,
73
- `curl -sf http://localhost:${REMOTE_PORT}/api/health >/dev/null 2>&1 || echo __GROOVE_NOT_RUNNING__`,
74
- ];
75
-
76
- try {
77
- const result = execFileSync('ssh', args, {
78
- encoding: 'utf8',
79
- timeout: 15000,
80
- stdio: ['pipe', 'pipe', 'pipe'],
81
- });
82
-
83
- if (result.includes('__GROOVE_NOT_RUNNING__')) {
84
- return { running: false };
85
- }
86
- return { running: true };
87
- } catch (err) {
88
- const stderr = err.stderr?.toString() || '';
89
- if (stderr.includes('Permission denied')) {
90
- throw new Error('SSH authentication failed. Check your key or credentials.');
91
- }
92
- if (stderr.includes('Connection refused') || stderr.includes('Connection timed out') || stderr.includes('No route to host')) {
93
- throw new Error(`Cannot reach ${target}. Check the hostname and that SSH is running.`);
94
- }
95
- throw new Error(`SSH preflight failed: ${stderr.trim() || err.message}`);
19
+ const atIdx = target.indexOf('@');
20
+ if (atIdx === -1) {
21
+ return { user: null, host: target };
96
22
  }
23
+ return { user: target.slice(0, atIdx), host: target.slice(atIdx + 1) };
97
24
  }
98
25
 
99
- function isSshProcess(pid) {
100
- // Verify the PID belongs to an SSH process (not a random reused PID)
26
+ async function daemonRunning() {
101
27
  try {
102
- const cmd = execFileSync('ps', ['-p', String(pid), '-o', 'command='], {
103
- encoding: 'utf8',
104
- timeout: 3000,
105
- }).trim();
106
- return cmd.includes('ssh');
28
+ const res = await fetch(`${API}/health`, { signal: AbortSignal.timeout(3000) });
29
+ return res.ok;
107
30
  } catch {
108
31
  return false;
109
32
  }
110
33
  }
111
34
 
112
- function existingTunnel() {
113
- const pf = pidFile();
114
- if (!existsSync(pf)) return null;
115
- const pid = parseInt(readFileSync(pf, 'utf8').trim(), 10);
116
- if (isNaN(pid)) return null;
117
- // Check if process is still alive AND is an SSH process
118
- try {
119
- process.kill(pid, 0);
120
- if (!isSshProcess(pid)) {
121
- // PID was reused by a different process — stale tunnel files
122
- return null;
123
- }
124
- // Read tunnel info if available
125
- const infoPath = tunnelInfoFile();
126
- if (existsSync(infoPath)) {
127
- const info = JSON.parse(readFileSync(infoPath, 'utf8'));
128
- return { pid, ...info };
129
- }
130
- return { pid };
131
- } catch {
132
- return null;
133
- }
134
- }
135
-
136
35
  function openBrowser(url) {
137
- const platform = process.platform;
138
36
  try {
139
- if (platform === 'darwin') {
37
+ if (process.platform === 'darwin') {
140
38
  execFileSync('open', [url], { stdio: 'ignore' });
141
- } else if (platform === 'win32') {
39
+ } else if (process.platform === 'win32') {
142
40
  execFileSync('cmd', ['/c', 'start', '', url], { stdio: 'ignore' });
143
41
  } else {
144
42
  execFileSync('xdg-open', [url], { stdio: 'ignore' });
145
43
  }
146
44
  } catch {
147
- // Browser open is best-effort
45
+ // best-effort
148
46
  }
149
47
  }
150
48
 
49
+ function sleep(ms) {
50
+ return new Promise(r => setTimeout(r, ms));
51
+ }
52
+
151
53
  export async function connect(target, options) {
152
54
  console.log('');
153
55
 
154
- // Validate SSH target
56
+ let user, host;
155
57
  try {
156
- validateTarget(target);
58
+ ({ user, host } = parseTarget(target));
157
59
  } catch (err) {
158
60
  console.log(chalk.red(' Error: ') + err.message);
159
61
  console.log('');
160
62
  return;
161
63
  }
162
64
 
163
- // Check for existing tunnel
164
- const existing = existingTunnel();
165
- if (existing) {
166
- console.log(chalk.yellow(' Tunnel already active') + ` (PID ${existing.pid})`);
167
- if (existing.target) {
168
- console.log(` Target: ${existing.target}`);
169
- }
170
- if (existing.localPort) {
171
- console.log(` GUI: ${chalk.cyan(`http://localhost:${existing.localPort}`)}`);
172
- }
173
- console.log('');
174
- console.log(` Run ${chalk.bold('groove disconnect')} first to close it.`);
65
+ if (!(await daemonRunning())) {
66
+ console.log(chalk.red(' Local daemon is not running.'));
67
+ console.log(` Run ${chalk.bold('groove start')} first.`);
175
68
  console.log('');
176
69
  return;
177
70
  }
178
71
 
179
- // Preflight check daemon is running on remote
180
- console.log(chalk.dim(' Checking remote daemon...'));
72
+ // Check for existing saved remote matching this host+user
73
+ let tunnelId;
74
+ let tunnels;
181
75
  try {
182
- const check = preflight(target, options.identity);
183
- if (!check.running) {
184
- console.log(chalk.red(' Daemon not running on remote.'));
185
- console.log(` SSH into ${chalk.bold(target)} and run ${chalk.bold('groove start')} first.`);
186
- console.log('');
187
- return;
188
- }
76
+ const res = await fetch(`${API}/tunnels`);
77
+ tunnels = await res.json();
189
78
  } catch (err) {
190
- console.log(chalk.red(' ' + err.message));
79
+ console.log(chalk.red(' Failed to query tunnels: ') + err.message);
191
80
  console.log('');
192
81
  return;
193
82
  }
194
83
 
195
- console.log(chalk.dim(' Remote daemon is running.'));
84
+ const match = tunnels.find(t =>
85
+ t.host === host && (user ? t.user === user : true)
86
+ );
196
87
 
197
- // Find available local port
198
- let localPort;
199
- try {
200
- localPort = await findAvailablePort();
201
- } catch (err) {
202
- console.log(chalk.red(' ' + err.message));
203
- console.log('');
204
- return;
205
- }
206
-
207
- if (localPort !== DEFAULT_LOCAL_PORT) {
208
- console.log(chalk.yellow(` Port ${DEFAULT_LOCAL_PORT} in use, using ${localPort} instead.`));
88
+ if (match) {
89
+ if (match.active) {
90
+ console.log(chalk.yellow(' Tunnel already active') + ` to ${match.name}`);
91
+ if (match.localPort) {
92
+ console.log(` GUI: ${chalk.cyan(`http://localhost:${match.localPort}`)}`);
93
+ }
94
+ console.log('');
95
+ console.log(` Run ${chalk.bold('groove disconnect')} first to close it.`);
96
+ console.log('');
97
+ return;
98
+ }
99
+ tunnelId = match.id;
100
+ console.log(chalk.dim(` Using saved remote: ${match.name}`));
101
+ }
102
+
103
+ // Save new tunnel config if none found
104
+ if (!tunnelId) {
105
+ try {
106
+ const body = {
107
+ name: target,
108
+ host,
109
+ user: user || process.env.USER || 'root',
110
+ port: options.port ? parseInt(options.port, 10) : 22,
111
+ sshKeyPath: options.identity || null,
112
+ autoConnect: options.autoConnect || false,
113
+ projectDir: options.projectDir || null,
114
+ };
115
+ const res = await fetch(`${API}/tunnels`, {
116
+ method: 'POST',
117
+ headers: { 'Content-Type': 'application/json' },
118
+ body: JSON.stringify(body),
119
+ });
120
+ const data = await res.json();
121
+ if (!res.ok) throw new Error(data.error || 'Failed to save tunnel');
122
+ tunnelId = data.id;
123
+ console.log(chalk.dim(` Saved remote: ${data.name} (${data.id})`));
124
+ } catch (err) {
125
+ console.log(chalk.red(' ' + err.message));
126
+ console.log('');
127
+ return;
128
+ }
209
129
  }
210
130
 
211
- // Spawn SSH tunnel
212
- const sshArgs = [
213
- '-N', // No remote command
214
- '-L', `127.0.0.1:${localPort}:localhost:${REMOTE_PORT}`, // Local bind to 127.0.0.1 only
215
- '-o', 'ServerAliveInterval=30', // Keepalive every 30s
216
- '-o', 'ServerAliveCountMax=3', // Die after 3 missed keepalives
217
- '-o', 'ExitOnForwardFailure=yes', // Fail if port forward fails
218
- '-o', 'StrictHostKeyChecking=accept-new',
219
- ...(options.identity ? ['-i', options.identity] : []),
220
- target,
221
- ];
222
-
223
- const tunnel = spawn('ssh', sshArgs, {
224
- stdio: ['ignore', 'ignore', 'pipe'],
225
- detached: true,
226
- });
227
-
228
- // Capture stderr for early errors
229
- let stderrBuf = '';
230
- tunnel.stderr.on('data', (chunk) => { stderrBuf += chunk.toString(); });
231
-
232
- // Wait a moment to catch immediate failures (bad key, connection refused)
233
- await new Promise((resolve) => setTimeout(resolve, 2000));
234
-
235
- // Check if tunnel is still alive
236
- if (tunnel.exitCode !== null) {
237
- console.log(chalk.red(' Tunnel failed to start.'));
238
- if (stderrBuf.trim()) {
239
- console.log(chalk.dim(' ' + stderrBuf.trim()));
131
+ // Fire connect — the daemon handles test, install, upgrade, start, port-forward
132
+ console.log(chalk.dim(' Connecting...'));
133
+
134
+ let connectDone = false;
135
+ let connectResult = null;
136
+ let connectError = null;
137
+
138
+ const connectPromise = fetch(`${API}/tunnels/${tunnelId}/connect`, {
139
+ method: 'POST',
140
+ headers: { 'Content-Type': 'application/json' },
141
+ body: JSON.stringify({}),
142
+ }).then(async r => {
143
+ const data = await r.json();
144
+ if (!r.ok) throw new Error(data.error || 'Connection failed');
145
+ return data;
146
+ }).then(data => { connectResult = data; })
147
+ .catch(err => { connectError = err; })
148
+ .finally(() => { connectDone = true; });
149
+
150
+ // Poll status every 2s while connect is in progress
151
+ let dots = 0;
152
+ while (!connectDone) {
153
+ await sleep(2000);
154
+ if (connectDone) break;
155
+ try {
156
+ const res = await fetch(`${API}/tunnels/${tunnelId}/status`, {
157
+ signal: AbortSignal.timeout(2000),
158
+ });
159
+ const status = await res.json();
160
+ if (status.active) break;
161
+ } catch {
162
+ // status poll failure is non-fatal
240
163
  }
241
- console.log('');
242
- return;
164
+ dots++;
165
+ process.stdout.write(`\r ${chalk.dim('Connecting' + '.'.repeat((dots % 3) + 1).padEnd(3))} `);
243
166
  }
244
167
 
245
- // Verify the tunnel is actually forwarding
246
- const tunnelUp = await isPortInUse(localPort);
247
- if (!tunnelUp) {
248
- console.log(chalk.red(' Tunnel started but port forward not active.'));
249
- try { process.kill(tunnel.pid); } catch { /* ignore */ }
168
+ // Ensure connect promise resolves
169
+ await connectPromise;
170
+ process.stdout.write('\r' + ' '.repeat(40) + '\r');
171
+
172
+ if (connectError) {
173
+ console.log(chalk.red(' Connection failed: ') + connectError.message);
250
174
  console.log('');
251
175
  return;
252
176
  }
253
177
 
254
- // Detach and save PID
255
- tunnel.unref();
256
- writeFileSync(pidFile(), String(tunnel.pid), { mode: 0o600 });
257
- writeFileSync(tunnelInfoFile(), JSON.stringify({
258
- target,
259
- localPort,
260
- remotePort: REMOTE_PORT,
261
- startedAt: new Date().toISOString(),
262
- }), { mode: 0o600 });
263
-
264
- const url = `http://localhost:${localPort}`;
178
+ const url = connectResult.url || `http://localhost:${connectResult.localPort}`;
265
179
 
266
- console.log('');
267
180
  console.log(chalk.green(' Connected!'));
268
181
  console.log('');
269
182
  console.log(` Target: ${chalk.bold(target)}`);
270
- console.log(` Tunnel: localhost:${localPort} → ${target}:${REMOTE_PORT}`);
183
+ console.log(` Tunnel: localhost:${connectResult.localPort} → ${target}:31415`);
271
184
  console.log(` GUI: ${chalk.cyan(url)}`);
272
- console.log(` PID: ${tunnel.pid}`);
273
185
  console.log('');
274
186
 
275
- // Open browser (Commander: --no-browser sets options.browser = false)
276
187
  if (options.browser !== false) {
277
188
  openBrowser(url);
278
189
  }
@@ -1,91 +1,67 @@
1
- // GROOVE CLI — disconnect command (kill SSH tunnel)
1
+ // GROOVE CLI — disconnect command (close SSH tunnel via daemon)
2
2
  // FSL-1.1-Apache-2.0 — see LICENSE
3
3
 
4
- import { execFileSync } from 'child_process';
5
- import { existsSync, readFileSync, unlinkSync } from 'fs';
6
- import { resolve } from 'path';
7
4
  import chalk from 'chalk';
8
5
 
9
- function pidFile() {
10
- return resolve(process.cwd(), '.groove', 'tunnel.pid');
11
- }
12
-
13
- function tunnelInfoFile() {
14
- return resolve(process.cwd(), '.groove', 'tunnel.json');
15
- }
6
+ const API = 'http://localhost:31415/api';
16
7
 
17
- function cleanup() {
18
- try { if (existsSync(pidFile())) unlinkSync(pidFile()); } catch { /* ignore */ }
19
- try { if (existsSync(tunnelInfoFile())) unlinkSync(tunnelInfoFile()); } catch { /* ignore */ }
8
+ async function daemonRunning() {
9
+ try {
10
+ const res = await fetch(`${API}/health`, { signal: AbortSignal.timeout(3000) });
11
+ return res.ok;
12
+ } catch {
13
+ return false;
14
+ }
20
15
  }
21
16
 
22
- export async function disconnect() {
17
+ export async function disconnect(target) {
23
18
  console.log('');
24
19
 
25
- const pf = pidFile();
26
- if (!existsSync(pf)) {
27
- console.log(chalk.yellow(' No active tunnel found.'));
20
+ if (!(await daemonRunning())) {
21
+ console.log(chalk.yellow(' No daemon running.'));
28
22
  console.log('');
29
23
  return;
30
24
  }
31
25
 
32
- const pid = parseInt(readFileSync(pf, 'utf8').trim(), 10);
33
- if (isNaN(pid)) {
34
- console.log(chalk.yellow(' Invalid tunnel PID file. Cleaning up.'));
35
- cleanup();
36
- console.log('');
37
- return;
38
- }
39
-
40
- // Read tunnel info for display
41
- let info = {};
42
- try {
43
- const infoPath = tunnelInfoFile();
44
- if (existsSync(infoPath)) {
45
- info = JSON.parse(readFileSync(infoPath, 'utf8'));
46
- }
47
- } catch { /* ignore */ }
48
-
49
- // Check if process is alive
26
+ let tunnels;
50
27
  try {
51
- process.kill(pid, 0);
52
- } catch {
53
- console.log(chalk.yellow(' Tunnel process already dead. Cleaning up.'));
54
- cleanup();
28
+ const res = await fetch(`${API}/tunnels`);
29
+ tunnels = await res.json();
30
+ } catch (err) {
31
+ console.log(chalk.red(' Failed to query tunnels: ') + err.message);
55
32
  console.log('');
56
33
  return;
57
34
  }
58
35
 
59
- // Verify the PID belongs to an SSH process (not a random reused PID after reboot)
60
- try {
61
- const cmd = execFileSync('ps', ['-p', String(pid), '-o', 'command='], {
62
- encoding: 'utf8', timeout: 3000,
63
- }).trim();
64
- if (!cmd.includes('ssh')) {
65
- console.log(chalk.yellow(' PID no longer belongs to an SSH tunnel. Cleaning up stale files.'));
66
- cleanup();
36
+ // Find the tunnel to disconnect
37
+ let tunnel;
38
+ if (target) {
39
+ tunnel = tunnels.find(t => t.active && (t.name === target || t.host === target || t.id === target));
40
+ if (!tunnel) {
41
+ console.log(chalk.yellow(` No active tunnel matching "${target}".`));
42
+ console.log('');
43
+ return;
44
+ }
45
+ } else {
46
+ tunnel = tunnels.find(t => t.active);
47
+ if (!tunnel) {
48
+ console.log(chalk.yellow(' No active tunnel found.'));
67
49
  console.log('');
68
50
  return;
69
51
  }
70
- } catch {
71
- // ps failed — proceed cautiously, don't kill
72
- console.log(chalk.yellow(' Cannot verify tunnel process. Cleaning up stale files.'));
73
- cleanup();
74
- console.log('');
75
- return;
76
52
  }
77
53
 
78
- // Kill the tunnel
79
54
  try {
80
- process.kill(pid, 'SIGTERM');
81
- console.log(chalk.green(' Tunnel disconnected.'));
82
- if (info.target) {
83
- console.log(` Was connected to: ${chalk.dim(info.target)}`);
84
- }
55
+ const res = await fetch(`${API}/tunnels/${tunnel.id}/disconnect`, { method: 'POST' });
56
+ const data = await res.json();
57
+ if (!res.ok) throw new Error(data.error || 'Disconnect failed');
85
58
  } catch (err) {
86
- console.log(chalk.red(' Failed to kill tunnel: ') + err.message);
59
+ console.log(chalk.red(' Disconnect failed: ') + err.message);
60
+ console.log('');
61
+ return;
87
62
  }
88
63
 
89
- cleanup();
64
+ console.log(chalk.green(' Tunnel disconnected.'));
65
+ console.log(` Was connected to: ${chalk.dim(tunnel.name)}`);
90
66
  console.log('');
91
67
  }
@@ -0,0 +1,75 @@
1
+ // GROOVE CLI — remotes command (list saved SSH tunnels)
2
+ // FSL-1.1-Apache-2.0 — see LICENSE
3
+
4
+ import chalk from 'chalk';
5
+
6
+ const API = 'http://localhost:31415/api';
7
+
8
+ async function daemonRunning() {
9
+ try {
10
+ const res = await fetch(`${API}/health`, { signal: AbortSignal.timeout(3000) });
11
+ return res.ok;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ export async function remotes() {
18
+ console.log('');
19
+
20
+ if (!(await daemonRunning())) {
21
+ console.log(chalk.yellow(' Daemon is not running.'));
22
+ console.log(` Run ${chalk.bold('groove start')} first.`);
23
+ console.log('');
24
+ return;
25
+ }
26
+
27
+ let tunnels;
28
+ try {
29
+ const res = await fetch(`${API}/tunnels`);
30
+ tunnels = await res.json();
31
+ } catch (err) {
32
+ console.log(chalk.red(' Failed to query tunnels: ') + err.message);
33
+ console.log('');
34
+ return;
35
+ }
36
+
37
+ if (!tunnels.length) {
38
+ console.log(chalk.dim(' No saved remotes.'));
39
+ console.log(` Use ${chalk.bold('groove connect user@host')} to add one.`);
40
+ console.log('');
41
+ return;
42
+ }
43
+
44
+ // Column headers
45
+ const nameW = Math.max(6, ...tunnels.map(t => t.name.length)) + 2;
46
+ const hostW = Math.max(6, ...tunnels.map(t => t.host.length)) + 2;
47
+ const userW = Math.max(6, ...tunnels.map(t => t.user.length)) + 2;
48
+
49
+ const header =
50
+ chalk.dim(' ' +
51
+ 'NAME'.padEnd(nameW) +
52
+ 'HOST'.padEnd(hostW) +
53
+ 'USER'.padEnd(userW) +
54
+ 'STATUS'.padEnd(12) +
55
+ 'PORT');
56
+ console.log(header);
57
+ console.log(chalk.dim(' ' + '─'.repeat(nameW + hostW + userW + 12 + 6)));
58
+
59
+ for (const t of tunnels) {
60
+ const statusRaw = t.active ? 'active' : 'inactive';
61
+ const statusCol = t.active ? chalk.green(statusRaw) : chalk.dim(statusRaw);
62
+ const portRaw = t.active && t.localPort ? String(t.localPort) : '—';
63
+ const portCol = t.active && t.localPort ? chalk.cyan(portRaw) : chalk.dim(portRaw);
64
+ console.log(
65
+ ' ' +
66
+ t.name.padEnd(nameW) +
67
+ t.host.padEnd(hostW) +
68
+ t.user.padEnd(userW) +
69
+ statusCol + ' '.repeat(Math.max(1, 12 - statusRaw.length)) +
70
+ portCol
71
+ );
72
+ }
73
+
74
+ console.log('');
75
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groove-dev/daemon",
3
- "version": "0.27.86",
3
+ "version": "0.27.88",
4
4
  "description": "GROOVE daemon — agent orchestration engine",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",