@jlongo78/agent-spaces 0.5.3 → 0.5.4

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 (320) hide show
  1. package/.next/standalone/.claude/settings.local.json +16 -0
  2. package/.next/standalone/.next/BUILD_ID +1 -1
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +19 -19
  6. package/.next/standalone/.next/server/app/(desktop)/admin/analytics/page_client-reference-manifest.js +1 -1
  7. package/.next/standalone/.next/server/app/(desktop)/admin/users/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/(desktop)/analytics/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/(desktop)/network/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(desktop)/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/(desktop)/projects/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(desktop)/sessions/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(desktop)/settings/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(desktop)/terminal/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(desktop)/workspaces/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  20. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  28. package/.next/standalone/.next/server/app/_not-found.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  30. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  32. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  33. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  34. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  35. package/.next/standalone/.next/server/app/admin/analytics.html +1 -1
  36. package/.next/standalone/.next/server/app/admin/analytics.rsc +5 -5
  37. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics/__PAGE__.segment.rsc +2 -2
  38. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics.segment.rsc +1 -1
  39. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/admin/analytics.segments/_full.segment.rsc +5 -5
  42. package/.next/standalone/.next/server/app/admin/analytics.segments/_head.segment.rsc +1 -1
  43. package/.next/standalone/.next/server/app/admin/analytics.segments/_index.segment.rsc +3 -3
  44. package/.next/standalone/.next/server/app/admin/analytics.segments/_tree.segment.rsc +2 -2
  45. package/.next/standalone/.next/server/app/admin/users.html +1 -1
  46. package/.next/standalone/.next/server/app/admin/users.rsc +5 -5
  47. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users/__PAGE__.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users.segment.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  50. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  51. package/.next/standalone/.next/server/app/admin/users.segments/_full.segment.rsc +5 -5
  52. package/.next/standalone/.next/server/app/admin/users.segments/_head.segment.rsc +1 -1
  53. package/.next/standalone/.next/server/app/admin/users.segments/_index.segment.rsc +3 -3
  54. package/.next/standalone/.next/server/app/admin/users.segments/_tree.segment.rsc +2 -2
  55. package/.next/standalone/.next/server/app/analytics.html +1 -1
  56. package/.next/standalone/.next/server/app/analytics.rsc +5 -5
  57. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics/__PAGE__.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics.segment.rsc +1 -1
  59. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  60. package/.next/standalone/.next/server/app/analytics.segments/_full.segment.rsc +5 -5
  61. package/.next/standalone/.next/server/app/analytics.segments/_head.segment.rsc +1 -1
  62. package/.next/standalone/.next/server/app/analytics.segments/_index.segment.rsc +3 -3
  63. package/.next/standalone/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  64. package/.next/standalone/.next/server/app/api/analytics/overview/route.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/api/bulk/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/chat/route.js +1 -1
  67. package/.next/standalone/.next/server/app/api/chat/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/config/route.js.nft.json +1 -1
  69. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/folders/route.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/api/network/handshake/route.js +1 -1
  72. package/.next/standalone/.next/server/app/api/network/handshake/route.js.nft.json +1 -1
  73. package/.next/standalone/.next/server/app/api/network/projects/route.js +2 -1
  74. package/.next/standalone/.next/server/app/api/network/projects/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/api/network/search/route.js +2 -1
  76. package/.next/standalone/.next/server/app/api/network/search/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js +2 -1
  78. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js +2 -1
  80. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/api/network/sessions/route.js +2 -1
  82. package/.next/standalone/.next/server/app/api/network/sessions/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js +2 -1
  84. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js.nft.json +1 -1
  85. package/.next/standalone/.next/server/app/api/network/workspaces/route.js +2 -1
  86. package/.next/standalone/.next/server/app/api/network/workspaces/route.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/api/panes/[id]/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/panes/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/search/route.js +1 -1
  91. package/.next/standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/sessions/route.js +1 -1
  96. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/sync/route.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/api/tags/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/tier/route.js +1 -1
  100. package/.next/standalone/.next/server/app/api/tier/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js.nft.json +1 -1
  102. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js.nft.json +1 -1
  104. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js.nft.json +1 -1
  105. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js.nft.json +1 -1
  106. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js.nft.json +1 -1
  107. package/.next/standalone/.next/server/app/api/workspaces/route.js +1 -1
  108. package/.next/standalone/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  109. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/login.html +1 -1
  111. package/.next/standalone/.next/server/app/login.rsc +4 -4
  112. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +4 -4
  113. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  114. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +3 -3
  115. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  116. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  117. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  118. package/.next/standalone/.next/server/app/m/page_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/m/projects/page_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/m/projects.html +1 -1
  121. package/.next/standalone/.next/server/app/m/projects.rsc +5 -5
  122. package/.next/standalone/.next/server/app/m/projects.segments/_full.segment.rsc +5 -5
  123. package/.next/standalone/.next/server/app/m/projects.segments/_head.segment.rsc +1 -1
  124. package/.next/standalone/.next/server/app/m/projects.segments/_index.segment.rsc +3 -3
  125. package/.next/standalone/.next/server/app/m/projects.segments/_tree.segment.rsc +2 -2
  126. package/.next/standalone/.next/server/app/m/projects.segments/m/projects/__PAGE__.segment.rsc +2 -2
  127. package/.next/standalone/.next/server/app/m/projects.segments/m/projects.segment.rsc +1 -1
  128. package/.next/standalone/.next/server/app/m/projects.segments/m.segment.rsc +2 -2
  129. package/.next/standalone/.next/server/app/m/sessions/[id]/page_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/m/sessions/page_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/m/sessions.html +1 -1
  132. package/.next/standalone/.next/server/app/m/sessions.rsc +5 -5
  133. package/.next/standalone/.next/server/app/m/sessions.segments/_full.segment.rsc +5 -5
  134. package/.next/standalone/.next/server/app/m/sessions.segments/_head.segment.rsc +1 -1
  135. package/.next/standalone/.next/server/app/m/sessions.segments/_index.segment.rsc +3 -3
  136. package/.next/standalone/.next/server/app/m/sessions.segments/_tree.segment.rsc +2 -2
  137. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions/__PAGE__.segment.rsc +2 -2
  138. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions.segment.rsc +1 -1
  139. package/.next/standalone/.next/server/app/m/sessions.segments/m.segment.rsc +2 -2
  140. package/.next/standalone/.next/server/app/m/settings/page_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/m/settings.html +1 -1
  142. package/.next/standalone/.next/server/app/m/settings.rsc +5 -5
  143. package/.next/standalone/.next/server/app/m/settings.segments/_full.segment.rsc +5 -5
  144. package/.next/standalone/.next/server/app/m/settings.segments/_head.segment.rsc +1 -1
  145. package/.next/standalone/.next/server/app/m/settings.segments/_index.segment.rsc +3 -3
  146. package/.next/standalone/.next/server/app/m/settings.segments/_tree.segment.rsc +2 -2
  147. package/.next/standalone/.next/server/app/m/settings.segments/m/settings/__PAGE__.segment.rsc +2 -2
  148. package/.next/standalone/.next/server/app/m/settings.segments/m/settings.segment.rsc +1 -1
  149. package/.next/standalone/.next/server/app/m/settings.segments/m.segment.rsc +2 -2
  150. package/.next/standalone/.next/server/app/m/terminal/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/m/terminal.html +1 -1
  152. package/.next/standalone/.next/server/app/m/terminal.rsc +5 -5
  153. package/.next/standalone/.next/server/app/m/terminal.segments/_full.segment.rsc +5 -5
  154. package/.next/standalone/.next/server/app/m/terminal.segments/_head.segment.rsc +1 -1
  155. package/.next/standalone/.next/server/app/m/terminal.segments/_index.segment.rsc +3 -3
  156. package/.next/standalone/.next/server/app/m/terminal.segments/_tree.segment.rsc +2 -2
  157. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal/__PAGE__.segment.rsc +2 -2
  158. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal.segment.rsc +1 -1
  159. package/.next/standalone/.next/server/app/m/terminal.segments/m.segment.rsc +2 -2
  160. package/.next/standalone/.next/server/app/m.html +1 -1
  161. package/.next/standalone/.next/server/app/m.rsc +5 -5
  162. package/.next/standalone/.next/server/app/m.segments/_full.segment.rsc +5 -5
  163. package/.next/standalone/.next/server/app/m.segments/_head.segment.rsc +1 -1
  164. package/.next/standalone/.next/server/app/m.segments/_index.segment.rsc +3 -3
  165. package/.next/standalone/.next/server/app/m.segments/_tree.segment.rsc +2 -2
  166. package/.next/standalone/.next/server/app/m.segments/m/__PAGE__.segment.rsc +2 -2
  167. package/.next/standalone/.next/server/app/m.segments/m.segment.rsc +2 -2
  168. package/.next/standalone/.next/server/app/network.html +1 -1
  169. package/.next/standalone/.next/server/app/network.rsc +5 -5
  170. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network/__PAGE__.segment.rsc +2 -2
  171. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network.segment.rsc +1 -1
  172. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  173. package/.next/standalone/.next/server/app/network.segments/_full.segment.rsc +5 -5
  174. package/.next/standalone/.next/server/app/network.segments/_head.segment.rsc +1 -1
  175. package/.next/standalone/.next/server/app/network.segments/_index.segment.rsc +3 -3
  176. package/.next/standalone/.next/server/app/network.segments/_tree.segment.rsc +2 -2
  177. package/.next/standalone/.next/server/app/projects.html +1 -1
  178. package/.next/standalone/.next/server/app/projects.rsc +5 -5
  179. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects/__PAGE__.segment.rsc +2 -2
  180. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects.segment.rsc +1 -1
  181. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  182. package/.next/standalone/.next/server/app/projects.segments/_full.segment.rsc +5 -5
  183. package/.next/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  184. package/.next/standalone/.next/server/app/projects.segments/_index.segment.rsc +3 -3
  185. package/.next/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  186. package/.next/standalone/.next/server/app/sessions.html +1 -1
  187. package/.next/standalone/.next/server/app/sessions.rsc +5 -5
  188. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions/__PAGE__.segment.rsc +2 -2
  189. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions.segment.rsc +1 -1
  190. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  191. package/.next/standalone/.next/server/app/sessions.segments/_full.segment.rsc +5 -5
  192. package/.next/standalone/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  193. package/.next/standalone/.next/server/app/sessions.segments/_index.segment.rsc +3 -3
  194. package/.next/standalone/.next/server/app/sessions.segments/_tree.segment.rsc +2 -2
  195. package/.next/standalone/.next/server/app/settings.html +1 -1
  196. package/.next/standalone/.next/server/app/settings.rsc +5 -5
  197. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings/__PAGE__.segment.rsc +2 -2
  198. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings.segment.rsc +1 -1
  199. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  200. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +5 -5
  201. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  202. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +3 -3
  203. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  204. package/.next/standalone/.next/server/app/terminal.html +1 -1
  205. package/.next/standalone/.next/server/app/terminal.rsc +5 -5
  206. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal/__PAGE__.segment.rsc +2 -2
  207. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal.segment.rsc +1 -1
  208. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  209. package/.next/standalone/.next/server/app/terminal.segments/_full.segment.rsc +5 -5
  210. package/.next/standalone/.next/server/app/terminal.segments/_head.segment.rsc +1 -1
  211. package/.next/standalone/.next/server/app/terminal.segments/_index.segment.rsc +3 -3
  212. package/.next/standalone/.next/server/app/terminal.segments/_tree.segment.rsc +2 -2
  213. package/.next/standalone/.next/server/app/workspaces.html +1 -1
  214. package/.next/standalone/.next/server/app/workspaces.rsc +5 -5
  215. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces/__PAGE__.segment.rsc +2 -2
  216. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces.segment.rsc +1 -1
  217. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap.segment.rsc +2 -2
  218. package/.next/standalone/.next/server/app/workspaces.segments/_full.segment.rsc +5 -5
  219. package/.next/standalone/.next/server/app/workspaces.segments/_head.segment.rsc +1 -1
  220. package/.next/standalone/.next/server/app/workspaces.segments/_index.segment.rsc +3 -3
  221. package/.next/standalone/.next/server/app/workspaces.segments/_tree.segment.rsc +2 -2
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d038fdf._.js +106 -0
  223. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0e4c2d35._.js → [root-of-the-server]__12673e47._.js} +2 -2
  224. package/.next/standalone/.next/server/chunks/[root-of-the-server]__130dee4b._.js +2 -2
  225. package/.next/standalone/.next/server/chunks/[root-of-the-server]__142c2f41._.js +2 -2
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2861e096._.js +1 -1
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2d3d8d52._.js +2 -2
  228. package/.next/standalone/.next/server/chunks/[root-of-the-server]__45205e47._.js +98 -0
  229. package/.next/standalone/.next/server/chunks/[root-of-the-server]__46b7da42._.js +98 -0
  230. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__8765f2fc._.js → [root-of-the-server]__4cf845f6._.js} +3 -3
  231. package/.next/standalone/.next/server/chunks/[root-of-the-server]__57b966d5._.js +2 -2
  232. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5a0020ba._.js +3 -3
  233. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5bd0f118._.js +2 -2
  234. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5bf8f2c0._.js +98 -0
  235. package/.next/standalone/.next/server/chunks/[root-of-the-server]__69eb20b1._.js +98 -0
  236. package/.next/standalone/.next/server/chunks/[root-of-the-server]__74c48d65._.js +2 -2
  237. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7d6610c4._.js +2 -2
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__84f3af14._.js +2 -2
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a38f7af1._.js +98 -0
  240. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a6eb742d._.js +3 -3
  241. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b4c83e91._.js +3 -3
  242. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b7c8a7dd._.js +98 -0
  243. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__cae0486f._.js → [root-of-the-server]__c1d7faa6._.js} +4 -4
  244. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c546cf71._.js +1 -1
  245. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__a2ee9884._.js → [root-of-the-server]__c977bf2f._.js} +2 -2
  246. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d2f9be33._.js +98 -0
  247. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5615808._.js +2 -2
  248. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d877df12._.js +1 -1
  249. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e9d6e526._.js +98 -0
  250. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f66ceeb8._.js +2 -2
  251. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f893957c._.js +3 -3
  252. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fcd26315._.js +2 -2
  253. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fd505913._.js +2 -2
  254. package/.next/standalone/.next/server/chunks/[root-of-the-server]__feff7b91._.js +3 -3
  255. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__66aca5d4._.js +1 -1
  256. package/.next/standalone/.next/server/chunks/ssr/_1f12caba._.js +1 -1
  257. package/.next/standalone/.next/server/chunks/ssr/_43e7e611._.js +1 -1
  258. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_network_page_tsx_27f035db._.js +1 -1
  259. package/.next/standalone/.next/server/chunks/ssr/src_lib_telemetry_ts_d7f80cd0._.js +1 -1
  260. package/.next/standalone/.next/server/edge/chunks/_d73df637._.js +1 -1
  261. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  262. package/.next/standalone/.next/server/pages/404.html +1 -1
  263. package/.next/standalone/.next/server/pages/500.html +2 -2
  264. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  266. package/.next/standalone/.next/static/chunks/{10c6424526b53431.js → 483bf086feba6531.js} +1 -1
  267. package/.next/standalone/.next/static/chunks/{f8d7a4a58f712ecd.js → 56ddb2d75f5beb1a.js} +1 -1
  268. package/.next/standalone/.next/static/chunks/7c4cfb3160fa8dd4.js +5 -0
  269. package/.next/standalone/.next/static/chunks/{3434c5b2c9958276.js → ae3a695e671c8d31.js} +1 -1
  270. package/.next/standalone/.next/static/chunks/e972ec0d23b19896.js +5 -0
  271. package/.next/standalone/.next/static/chunks/ff5fac1bd7b518dd.css +3 -0
  272. package/.next/standalone/node_modules/@img/sharp-win32-x64/lib/sharp-win32-x64.node +0 -0
  273. package/.next/standalone/node_modules/@img/{sharp-linux-x64 → sharp-win32-x64}/package.json +39 -46
  274. package/.next/standalone/package.json +89 -89
  275. package/.next/standalone/server.js +1 -1
  276. package/.next/standalone/tsconfig.json +34 -34
  277. package/LICENSE +661 -661
  278. package/README.md +131 -131
  279. package/bin/fix-standalone-externals.js +79 -79
  280. package/bin/lib/auto-setup.js +110 -101
  281. package/bin/mdns-service.js +171 -171
  282. package/bin/postinstall.js +35 -35
  283. package/bin/setup-admin.js +195 -189
  284. package/bin/spaces-dev.js +208 -208
  285. package/bin/spaces-install.js +572 -483
  286. package/bin/spaces-service.js +881 -0
  287. package/bin/spaces-setup.js +253 -247
  288. package/bin/spaces.js +500 -466
  289. package/bin/terminal-server.js +1252 -1117
  290. package/package.json +89 -89
  291. package/.next/standalone/.next/server/chunks/[root-of-the-server]__18a58c5f._.js +0 -3
  292. package/.next/standalone/.next/server/chunks/[root-of-the-server]__41e589ee._.js +0 -3
  293. package/.next/standalone/.next/server/chunks/[root-of-the-server]__464db440._.js +0 -3
  294. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4ad64489._.js +0 -3
  295. package/.next/standalone/.next/server/chunks/[root-of-the-server]__64f5810e._.js +0 -98
  296. package/.next/standalone/.next/server/chunks/[root-of-the-server]__95b7f18e._.js +0 -3
  297. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a6ce192e._.js +0 -3
  298. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e2b78951._.js +0 -3
  299. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f84e3cf3._.js +0 -98
  300. package/.next/standalone/.next/static/chunks/302ce212c690bec4.js +0 -5
  301. package/.next/standalone/.next/static/chunks/67c7bf5024309fca.css +0 -3
  302. package/.next/standalone/.next/static/chunks/cb442c50eecb758d.js +0 -5
  303. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/README.md +0 -46
  304. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  305. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +0 -1
  306. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  307. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/package.json +0 -42
  308. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
  309. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  310. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
  311. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  312. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
  313. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
  314. package/.next/standalone/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
  315. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
  316. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
  317. /package/.next/standalone/.next/static/{nbYSIjUtkSwSvTgyR5p00 → 5J530rtIR_FsG4E9MLLpB}/_buildManifest.js +0 -0
  318. /package/.next/standalone/.next/static/{nbYSIjUtkSwSvTgyR5p00 → 5J530rtIR_FsG4E9MLLpB}/_clientMiddlewareManifest.json +0 -0
  319. /package/.next/standalone/.next/static/{nbYSIjUtkSwSvTgyR5p00 → 5J530rtIR_FsG4E9MLLpB}/_ssgManifest.js +0 -0
  320. /package/.next/standalone/node_modules/@img/{sharp-libvips-linux-x64 → sharp-win32-x64}/versions.json +0 -0
@@ -1,483 +1,572 @@
1
- #!/usr/bin/env node
2
-
3
- 'use strict';
4
-
5
- const { execFileSync } = require('child_process');
6
- const path = require('path');
7
- const os = require('os');
8
- const fs = require('fs');
9
-
10
- const PACKAGES_DIR = path.join(os.homedir(), '.spaces', 'packages');
11
- const NODE_MODULES_DIR = path.join(PACKAGES_DIR, 'node_modules', '@spaces');
12
-
13
- // ─── Package definitions ─────────────────────────────────────
14
- const PACKAGES = {
15
- teams: {
16
- name: '@spaces/teams',
17
- dir: path.join(PACKAGES_DIR, 'teams'),
18
- repo: 'jlongo78/spaces-teams',
19
- private: false,
20
- verify: (dir) => fs.existsSync(path.join(dir, 'dist', 'index.js')),
21
- verifyLabel: 'dist/index.js',
22
- },
23
- pro: {
24
- name: '@spaces/pro',
25
- dir: path.join(PACKAGES_DIR, 'pro'),
26
- repo: 'jlongo78/spaces-pro',
27
- private: true,
28
- verify: (dir) => fs.existsSync(path.join(dir, 'dist', 'index.js')),
29
- verifyLabel: 'dist/index.js',
30
- },
31
- };
32
-
33
- // ─── Helpers ──────────────────────────────────────────────────
34
- function log(msg) { console.log(` ${msg}`); }
35
- function logOk(msg) { console.log(` ✓ ${msg}`); }
36
- function logErr(msg) { console.error(` ✗ ${msg}`); }
37
- function logWarn(msg) { console.log(` ! ${msg}`); }
38
-
39
- function run(cmd, args, opts = {}) {
40
- const isWin = process.platform === 'win32';
41
- const safeArgs = isWin
42
- ? args.map(a => (a.includes(' ') ? '"' + a + '"' : a))
43
- : args;
44
- return execFileSync(cmd, safeArgs, {
45
- encoding: 'utf-8',
46
- stdio: opts.quiet ? ['pipe', 'pipe', 'pipe'] : 'inherit',
47
- shell: isWin,
48
- ...opts,
49
- });
50
- }
51
-
52
- /**
53
- * Clone a repo, trying SSH first then HTTPS (with optional PAT).
54
- */
55
- function gitClone(repo, dest, isPrivate) {
56
- const sshUrl = `git@github.com:${repo}.git`;
57
- const httpsUrl = `https://github.com/${repo}.git`;
58
-
59
- // Try SSH first
60
- try {
61
- log(`Cloning ${repo} (SSH)...`);
62
- run('git', ['clone', '--depth', '1', sshUrl, dest]);
63
- return;
64
- } catch {
65
- // SSH failed, try HTTPS
66
- }
67
-
68
- // HTTPS check for PAT if private
69
- if (isPrivate) {
70
- const pat = process.env.GH_PAT || process.env.GITHUB_TOKEN || '';
71
- if (pat) {
72
- log(`Cloning ${repo} (HTTPS + token)...`);
73
- const authedUrl = `https://${pat}@github.com/${repo}.git`;
74
- run('git', ['clone', '--depth', '1', authedUrl, dest]);
75
- return;
76
- }
77
- }
78
-
79
- log(`Cloning ${repo} (HTTPS)...`);
80
- run('git', ['clone', '--depth', '1', httpsUrl, dest]);
81
- }
82
-
83
- /**
84
- * Pull latest changes in a repo directory.
85
- */
86
- function gitPull(dir) {
87
- log('Pulling latest...');
88
- run('git', ['pull', '--ff-only'], { cwd: dir });
89
- }
90
-
91
- /**
92
- * Create the symlink from node_modules/@spaces/<name> -> ../../<name>
93
- */
94
- function createSymlink(pkgKey) {
95
- const linkPath = path.join(NODE_MODULES_DIR, pkgKey);
96
- const targetPath = path.join('..', '..', pkgKey); // relative symlink
97
-
98
- fs.mkdirSync(NODE_MODULES_DIR, { recursive: true });
99
-
100
- // Remove existing link/dir
101
- try {
102
- const stat = fs.lstatSync(linkPath);
103
- if (stat.isSymbolicLink() || stat.isFile()) {
104
- fs.unlinkSync(linkPath);
105
- } else if (stat.isDirectory()) {
106
- fs.rmSync(linkPath, { recursive: true });
107
- }
108
- } catch {}
109
-
110
- fs.symlinkSync(targetPath, linkPath, process.platform === 'win32' ? 'junction' : 'dir');
111
- logOk(`Symlink: @spaces/${pkgKey} -> packages/${pkgKey}`);
112
- }
113
-
114
- /**
115
- * Check if a native module loads correctly from a package directory.
116
- */
117
- function checkNativeModule(moduleName, searchDir) {
118
- try {
119
- const nodePath = path.join(searchDir, 'node_modules');
120
- const result = run(process.execPath, [
121
- '-e',
122
- `try { require('${moduleName}'); console.log('ok'); } catch(e) { console.log(e.message); }`,
123
- ], {
124
- quiet: true,
125
- cwd: searchDir,
126
- env: { ...process.env, NODE_PATH: nodePath },
127
- });
128
- return result.trim() === 'ok';
129
- } catch {
130
- return false;
131
- }
132
- }
133
-
134
- // ─── Install command ──────────────────────────────────────────
135
- function installPackage(pkgKey) {
136
- const pkg = PACKAGES[pkgKey];
137
- if (!pkg) {
138
- logErr(`Unknown package: ${pkgKey}`);
139
- log(`Available: ${Object.keys(PACKAGES).join(', ')}`);
140
- process.exit(1);
141
- }
142
-
143
- console.log(`\n Installing ${pkg.name}...\n`);
144
-
145
- // Pro requires teams as a prerequisite
146
- if (pkgKey === "pro") {
147
- const teamsDir = PACKAGES.teams.dir;
148
- if (!fs.existsSync(path.join(teamsDir, "dist", "index.js"))) {
149
- log("@spaces/pro requires @spaces/teams -- installing teams first...");
150
- console.log("");
151
- installPackage("teams");
152
- console.log("");
153
- }
154
- }
155
-
156
- // 1. Clone or pull
157
- if (fs.existsSync(path.join(pkg.dir, '.git'))) {
158
- gitPull(pkg.dir);
159
- } else {
160
- fs.mkdirSync(PACKAGES_DIR, { recursive: true });
161
- gitClone(pkg.repo, pkg.dir, pkg.private);
162
- }
163
-
164
- // 2. Install dependencies
165
- // Both teams and pro need TypeScript build
166
- log('Installing dependencies...');
167
- run('npm', ['install'], { cwd: pkg.dir });
168
-
169
- log('Building TypeScript...');
170
- run('npm', ['run', 'build'], { cwd: pkg.dir });
171
-
172
- log('Pruning dev dependencies...');
173
- run('npm', ['prune', '--omit=dev'], { cwd: pkg.dir });
174
-
175
- // 5. Create symlink
176
- createSymlink(pkgKey);
177
-
178
- // 6. Verify
179
- if (pkg.verify(pkg.dir)) {
180
- logOk(`${pkg.name} installed successfully`);
181
- } else {
182
- logErr(`${pkg.name} installed but ${pkg.verifyLabel} not found`);
183
- process.exit(1);
184
- }
185
-
186
- // 7. Update tier in server.json
187
- const configPath = path.join(os.homedir(), '.spaces', 'server.json');
188
- try {
189
- const config = fs.existsSync(configPath)
190
- ? JSON.parse(fs.readFileSync(configPath, 'utf-8'))
191
- : { port: 3457, basePath: '' };
192
- // teams → team tier, pro → federation tier (upgrade only, don't downgrade)
193
- const tierMap = { teams: 'team', pro: 'federation' };
194
- const tierRank = { community: 0, team: 1, federation: 2 };
195
- const newTier = tierMap[pkgKey] || config.tier || 'community';
196
- if ((tierRank[newTier] || 0) >= (tierRank[config.tier] || 0)) {
197
- config.tier = newTier;
198
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
199
- logOk(`Tier set to ${newTier}`);
200
- }
201
- } catch {}
202
-
203
- // 8. Verify require() works
204
- try {
205
- const result = run(process.execPath, [
206
- '-e',
207
- `const p = require.resolve('${pkg.name}'); console.log('resolved: ' + p);`,
208
- ], {
209
- quiet: true,
210
- env: { ...process.env, NODE_PATH: path.join(PACKAGES_DIR, 'node_modules') },
211
- });
212
- logOk(`require('${pkg.name}') -> ${result.trim().replace('resolved: ', '')}`);
213
- } catch {
214
- logWarn(`require('${pkg.name}') failed — this may be OK if peer deps aren't available yet`);
215
- }
216
-
217
- console.log('');
218
- }
219
-
220
- // ─── Verify command ───────────────────────────────────────────
221
- function verifyAll() {
222
- console.log('\n Spaces Package Verification\n');
223
-
224
- let allOk = true;
225
-
226
- for (const [key, pkg] of Object.entries(PACKAGES)) {
227
- log(`─── ${pkg.name} ───`);
228
-
229
- // Check if installed
230
- if (!fs.existsSync(pkg.dir)) {
231
- logWarn('Not installed');
232
- log('');
233
- continue;
234
- }
235
-
236
- // Check git status
237
- try {
238
- const branch = run('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: pkg.dir, quiet: true }).trim();
239
- const hash = run('git', ['rev-parse', '--short', 'HEAD'], { cwd: pkg.dir, quiet: true }).trim();
240
- logOk(`Git: ${branch} @ ${hash}`);
241
- } catch {
242
- logErr('Git status check failed');
243
- allOk = false;
244
- }
245
-
246
- // Check entry point
247
- if (pkg.verify(pkg.dir)) {
248
- logOk(`Entry: ${pkg.verifyLabel} exists`);
249
- } else {
250
- logErr(`Entry: ${pkg.verifyLabel} missing`);
251
- allOk = false;
252
- }
253
-
254
- // Check node_modules
255
- if (fs.existsSync(path.join(pkg.dir, 'node_modules'))) {
256
- logOk('Dependencies: node_modules present');
257
- } else {
258
- logErr('Dependencies: node_modules missing');
259
- allOk = false;
260
- }
261
-
262
- // Check symlink
263
- const linkPath = path.join(NODE_MODULES_DIR, key);
264
- try {
265
- const stat = fs.lstatSync(linkPath);
266
- if (stat.isSymbolicLink()) {
267
- const target = fs.readlinkSync(linkPath);
268
- logOk(`Symlink: @spaces/${key} -> ${target}`);
269
- } else {
270
- logWarn(`@spaces/${key} exists but is not a symlink`);
271
- }
272
- } catch {
273
- logErr(`Symlink: @spaces/${key} missing`);
274
- allOk = false;
275
- }
276
-
277
- // Check native modules
278
- const nativeOk = checkNativeModule('better-sqlite3', pkg.dir);
279
- if (nativeOk) {
280
- logOk('Native: better-sqlite3 loads OK');
281
- } else {
282
- logErr('Native: better-sqlite3 failed (ABI mismatch? Run: spaces upgrade)');
283
- allOk = false;
284
- }
285
-
286
- // Check require() resolution
287
- try {
288
- run(process.execPath, [
289
- '-e',
290
- `require.resolve('${pkg.name}')`,
291
- ], {
292
- quiet: true,
293
- env: { ...process.env, NODE_PATH: path.join(PACKAGES_DIR, 'node_modules') },
294
- });
295
- logOk(`require('${pkg.name}') resolves OK`);
296
- } catch {
297
- logErr(`require('${pkg.name}') fails`);
298
- allOk = false;
299
- }
300
-
301
- log('');
302
- }
303
-
304
- if (allOk) {
305
- logOk('All checks passed');
306
- } else {
307
- logErr('Some checks failed run "spaces upgrade" to fix');
308
- }
309
- console.log('');
310
- }
311
-
312
- // ─── Upgrade command ──────────────────────────────────────────
313
- function upgradePackage(pkgKey) {
314
- if (pkgKey) {
315
- // Upgrade specific package
316
- const pkg = PACKAGES[pkgKey];
317
- if (!pkg) {
318
- logErr(`Unknown package: ${pkgKey}`);
319
- process.exit(1);
320
- }
321
- if (!fs.existsSync(pkg.dir)) {
322
- log(`${pkg.name} not installed — running install instead`);
323
- installPackage(pkgKey);
324
- return;
325
- }
326
- console.log(`\n Upgrading ${pkg.name}...\n`);
327
- doUpgrade(pkgKey, pkg);
328
- } else {
329
- // Upgrade all installed packages
330
- console.log('\n Upgrading all installed packages...\n');
331
- for (const [key, pkg] of Object.entries(PACKAGES)) {
332
- if (fs.existsSync(pkg.dir)) {
333
- log(`─── ${pkg.name} ───`);
334
- doUpgrade(key, pkg);
335
- log('');
336
- }
337
- }
338
- }
339
- console.log('');
340
- }
341
-
342
- function doUpgrade(pkgKey, pkg) {
343
- // Pull latest
344
- gitPull(pkg.dir);
345
-
346
- run('npm', ['install'], { cwd: pkg.dir });
347
- log('Building TypeScript...');
348
- run('npm', ['run', 'build'], { cwd: pkg.dir });
349
- run('npm', ['prune', '--omit=dev'], { cwd: pkg.dir });
350
-
351
- // Re-create symlink
352
- createSymlink(pkgKey);
353
-
354
- if (pkg.verify(pkg.dir)) {
355
- logOk(`${pkg.name} upgraded successfully`);
356
- } else {
357
- logErr(`${pkg.name} upgrade failed ${pkg.verifyLabel} not found`);
358
- }
359
- }
360
-
361
- // ─── Uninstall command ────────────────────────────────────────
362
- function uninstallOne(pkgKey) {
363
- const pkg = PACKAGES[pkgKey];
364
-
365
- // Remove symlink
366
- const linkPath = path.join(NODE_MODULES_DIR, pkgKey);
367
- try {
368
- const stat = fs.lstatSync(linkPath);
369
- if (stat.isSymbolicLink() || stat.isFile()) {
370
- fs.unlinkSync(linkPath);
371
- } else if (stat.isDirectory()) {
372
- fs.rmSync(linkPath, { recursive: true });
373
- }
374
- logOk(`Removed symlink @spaces/${pkgKey}`);
375
- } catch {
376
- logWarn(`Symlink @spaces/${pkgKey} not found`);
377
- }
378
-
379
- // Remove package directory
380
- if (fs.existsSync(pkg.dir)) {
381
- fs.rmSync(pkg.dir, { recursive: true });
382
- logOk(`Removed ${pkg.dir}`);
383
- } else {
384
- logWarn(`${pkg.dir} not found`);
385
- }
386
- }
387
-
388
- function uninstallPackage(pkgKey) {
389
- if (pkgKey) {
390
- const pkg = PACKAGES[pkgKey];
391
- if (!pkg) {
392
- logErr(`Unknown package: ${pkgKey}`);
393
- log(`Available: ${Object.keys(PACKAGES).join(', ')}`);
394
- process.exit(1);
395
- }
396
- console.log(`\n Uninstalling ${pkg.name}...\n`);
397
- uninstallOne(pkgKey);
398
- // Reset tier to community if removing a tier package
399
- const configPath = path.join(os.homedir(), '.spaces', 'server.json');
400
- try {
401
- if (fs.existsSync(configPath)) {
402
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
403
- if (config.tier && config.tier !== 'community') {
404
- config.tier = 'community';
405
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
406
- logOk('Reset tier to community');
407
- }
408
- }
409
- } catch {}
410
- logOk(`${pkg.name} uninstalled`);
411
- } else {
412
- console.log('\n Uninstalling everything...\n');
413
-
414
- // Remove tier packages
415
- for (const [key, pkg] of Object.entries(PACKAGES)) {
416
- if (fs.existsSync(pkg.dir) || fs.existsSync(path.join(NODE_MODULES_DIR, key))) {
417
- log(`─── ${pkg.name} ───`);
418
- uninstallOne(key);
419
- }
420
- }
421
- // Clean up packages dir
422
- try { fs.rmdirSync(NODE_MODULES_DIR); } catch {}
423
- try { fs.rmdirSync(path.join(PACKAGES_DIR, 'node_modules')); } catch {}
424
- try { fs.rmdirSync(PACKAGES_DIR); } catch {}
425
-
426
- // Remove the global spaces CLI
427
- log('─── @jlongo78/agent-spaces ───');
428
- try {
429
- run('npm', ['uninstall', '-g', '@jlongo78/agent-spaces'], { quiet: true });
430
- logOk('Removed global spaces CLI');
431
- } catch {
432
- logWarn('Global spaces CLI not found or already removed');
433
- }
434
-
435
- // Reset tier to community in server.json
436
- const configPath = path.join(os.homedir(), '.spaces', 'server.json');
437
- try {
438
- if (fs.existsSync(configPath)) {
439
- const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
440
- if (config.tier && config.tier !== 'community') {
441
- config.tier = 'community';
442
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
443
- logOk('Reset tier to community');
444
- }
445
- }
446
- } catch {}
447
-
448
- logOk('Spaces fully uninstalled');
449
- log('User data remains at ~/.spaces/ — remove manually if desired');
450
- }
451
- console.log('');
452
- }
453
-
454
- // ─── CLI ──────────────────────────────────────────────────────
455
- const command = process.argv[2];
456
- const target = process.argv[3];
457
-
458
- switch (command) {
459
- case 'install':
460
- if (!target) {
461
- logErr('Usage: spaces install <teams|pro>');
462
- process.exit(1);
463
- }
464
- installPackage(target);
465
- break;
466
-
467
- case 'uninstall':
468
- uninstallPackage(target || null);
469
- break;
470
-
471
- case 'verify':
472
- verifyAll();
473
- break;
474
-
475
- case 'upgrade':
476
- upgradePackage(target || null);
477
- break;
478
-
479
- default:
480
- logErr(`Unknown command: ${command}`);
481
- log('Usage: spaces <install|uninstall|verify|upgrade> [package]');
482
- process.exit(1);
483
- }
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const { execFileSync } = require('child_process');
6
+ const path = require('path');
7
+ const os = require('os');
8
+ const fs = require('fs');
9
+
10
+ // Resolve the target user's home directory.
11
+ // On Windows, if running from a separate admin account, find the user
12
+ // who actually has Claude Code data (.claude/ directory).
13
+ function resolveTargetHome() {
14
+ const currentHome = os.homedir();
15
+ if (process.platform !== 'win32') return currentHome;
16
+ // Check if the current user has .claude — if so, they're the target
17
+ if (fs.existsSync(path.join(currentHome, '.claude'))) return currentHome;
18
+ // Scan for users with .claude
19
+ const usersDir = path.dirname(currentHome);
20
+ const skip = new Set(['Public', 'Default', 'Default User', 'All Users']);
21
+ try {
22
+ const claudeUsers = fs.readdirSync(usersDir)
23
+ .filter(name => !skip.has(name) && !name.startsWith('.'))
24
+ .filter(name => fs.existsSync(path.join(usersDir, name, '.claude')));
25
+ if (claudeUsers.length === 1) return path.join(usersDir, claudeUsers[0]);
26
+ } catch {}
27
+ return currentHome;
28
+ }
29
+
30
+ const TARGET_HOME = resolveTargetHome();
31
+ const SPACES_DIR = path.join(TARGET_HOME, '.spaces');
32
+ const PACKAGES_DIR = path.join(SPACES_DIR, 'packages');
33
+ const NODE_MODULES_DIR = path.join(PACKAGES_DIR, 'node_modules', '@spaces');
34
+
35
+ // ─── Package definitions ─────────────────────────────────────
36
+ const PACKAGES = {
37
+ teams: {
38
+ name: '@spaces/teams',
39
+ dir: path.join(PACKAGES_DIR, 'teams'),
40
+ repo: 'jlongo78/spaces-teams',
41
+ private: false,
42
+ verify: (dir) => fs.existsSync(path.join(dir, 'dist', 'index.js')),
43
+ verifyLabel: 'dist/index.js',
44
+ },
45
+ pro: {
46
+ name: '@spaces/pro',
47
+ dir: path.join(PACKAGES_DIR, 'pro'),
48
+ repo: 'jlongo78/spaces-pro',
49
+ private: true,
50
+ verify: (dir) => fs.existsSync(path.join(dir, 'dist', 'index.js')),
51
+ verifyLabel: 'dist/index.js',
52
+ },
53
+ };
54
+
55
+ // ─── Helpers ──────────────────────────────────────────────────
56
+ function log(msg) { console.log(` ${msg}`); }
57
+ function logOk(msg) { console.log(` ✓ ${msg}`); }
58
+ function logErr(msg) { console.error(` ✗ ${msg}`); }
59
+ function logWarn(msg) { console.log(` ! ${msg}`); }
60
+
61
+ // On Windows, ensure Git is in PATH (admin accounts may not inherit user PATH)
62
+ function ensureGitInPath() {
63
+ if (process.platform !== 'win32') return;
64
+ try {
65
+ execFileSync('git', ['--version'], { stdio: 'pipe', shell: true });
66
+ return; // git already available
67
+ } catch {}
68
+ // Try common Git install locations (system-wide and per-user)
69
+ const candidates = [
70
+ path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Git', 'cmd'),
71
+ path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Git', 'cmd'),
72
+ // Per-user installs (check target user and all profiles)
73
+ path.join(TARGET_HOME, 'AppData', 'Local', 'Programs', 'Git', 'cmd'),
74
+ path.join(TARGET_HOME, 'AppData', 'Local', 'Programs', 'Git', 'mingw64', 'bin'),
75
+ ];
76
+ // Also check all user profiles in case Git is installed by a different user
77
+ try {
78
+ const usersDir = path.dirname(os.homedir());
79
+ for (const name of fs.readdirSync(usersDir)) {
80
+ candidates.push(path.join(usersDir, name, 'AppData', 'Local', 'Programs', 'Git', 'cmd'));
81
+ candidates.push(path.join(usersDir, name, 'AppData', 'Local', 'Programs', 'Git', 'mingw64', 'bin'));
82
+ }
83
+ } catch {}
84
+ for (const dir of candidates) {
85
+ if (fs.existsSync(path.join(dir, 'git.exe'))) {
86
+ process.env.PATH = process.env.PATH + ';' + dir;
87
+ return;
88
+ }
89
+ }
90
+ }
91
+ ensureGitInPath();
92
+
93
+ function run(cmd, args, opts = {}) {
94
+ const isWin = process.platform === 'win32';
95
+ const safeArgs = isWin
96
+ ? args.map(a => (a.includes(' ') ? '"' + a + '"' : a))
97
+ : args;
98
+ return execFileSync(cmd, safeArgs, {
99
+ encoding: 'utf-8',
100
+ stdio: opts.quiet ? ['pipe', 'pipe', 'pipe'] : 'inherit',
101
+ shell: isWin,
102
+ ...opts,
103
+ });
104
+ }
105
+
106
+ // Git args prefix: allow operating on repos owned by a different user
107
+ // (e.g. admin account managing packages in the target user's home)
108
+ const GIT_SAFE = ['-c', 'safe.directory=*'];
109
+
110
+ /**
111
+ * Clone a repo, trying SSH first then HTTPS (with optional PAT).
112
+ */
113
+ function gitClone(repo, dest, isPrivate) {
114
+ const sshUrl = `git@github.com:${repo}.git`;
115
+ const httpsUrl = `https://github.com/${repo}.git`;
116
+
117
+ // Try SSH first
118
+ try {
119
+ log(`Cloning ${repo} (SSH)...`);
120
+ run('git', [...GIT_SAFE, 'clone', '--depth', '1', sshUrl, dest]);
121
+ return;
122
+ } catch {
123
+ // SSH failed, try HTTPS
124
+ }
125
+
126
+ // HTTPS check for PAT if private
127
+ if (isPrivate) {
128
+ const pat = process.env.GH_PAT || process.env.GITHUB_TOKEN || '';
129
+ if (pat) {
130
+ log(`Cloning ${repo} (HTTPS + token)...`);
131
+ const authedUrl = `https://${pat}@github.com/${repo}.git`;
132
+ run('git', [...GIT_SAFE, 'clone', '--depth', '1', authedUrl, dest]);
133
+ return;
134
+ }
135
+ }
136
+
137
+ log(`Cloning ${repo} (HTTPS)...`);
138
+ run('git', [...GIT_SAFE, 'clone', '--depth', '1', httpsUrl, dest]);
139
+ }
140
+
141
+ /**
142
+ * Pull latest changes in a repo directory.
143
+ */
144
+ function gitPull(dir) {
145
+ log('Pulling latest...');
146
+ run('git', [...GIT_SAFE, 'pull', '--ff-only'], { cwd: dir });
147
+ }
148
+
149
+ /**
150
+ * Create the symlink from node_modules/@spaces/<name> -> ../../<name>
151
+ */
152
+ function createSymlink(pkgKey) {
153
+ const linkPath = path.join(NODE_MODULES_DIR, pkgKey);
154
+ const targetPath = path.join('..', '..', pkgKey); // relative symlink
155
+
156
+ fs.mkdirSync(NODE_MODULES_DIR, { recursive: true });
157
+
158
+ // Remove existing link/dir
159
+ try {
160
+ const stat = fs.lstatSync(linkPath);
161
+ if (stat.isSymbolicLink() || stat.isFile()) {
162
+ fs.unlinkSync(linkPath);
163
+ } else if (stat.isDirectory()) {
164
+ fs.rmSync(linkPath, { recursive: true });
165
+ }
166
+ } catch {}
167
+
168
+ fs.symlinkSync(targetPath, linkPath, process.platform === 'win32' ? 'junction' : 'dir');
169
+ logOk(`Symlink: @spaces/${pkgKey} -> packages/${pkgKey}`);
170
+ }
171
+
172
+ /**
173
+ * Check if a native module loads correctly from a package directory.
174
+ */
175
+ function checkNativeModule(moduleName, searchDir) {
176
+ try {
177
+ const nodePath = path.join(searchDir, 'node_modules');
178
+ // Use execFileSync directly (no shell) so quotes aren't mangled on Windows
179
+ const result = execFileSync(process.execPath, [
180
+ '-e',
181
+ `try { require('${moduleName}'); console.log('ok'); } catch(e) { console.log(e.message); }`,
182
+ ], {
183
+ encoding: 'utf-8',
184
+ stdio: ['pipe', 'pipe', 'pipe'],
185
+ cwd: searchDir,
186
+ env: { ...process.env, NODE_PATH: nodePath },
187
+ });
188
+ return result.trim() === 'ok';
189
+ } catch {
190
+ return false;
191
+ }
192
+ }
193
+
194
+ // ─── Install command ──────────────────────────────────────────
195
+ function installPackage(pkgKey) {
196
+ const pkg = PACKAGES[pkgKey];
197
+ if (!pkg) {
198
+ logErr(`Unknown package: ${pkgKey}`);
199
+ log(`Available: ${Object.keys(PACKAGES).join(', ')}`);
200
+ process.exit(1);
201
+ }
202
+
203
+ console.log(`\n Installing ${pkg.name}...\n`);
204
+
205
+ // Pro requires teams as a prerequisite
206
+ if (pkgKey === "pro") {
207
+ const teamsDir = PACKAGES.teams.dir;
208
+ if (!fs.existsSync(path.join(teamsDir, "dist", "index.js"))) {
209
+ log("@spaces/pro requires @spaces/teams -- installing teams first...");
210
+ console.log("");
211
+ installPackage("teams");
212
+ console.log("");
213
+ }
214
+ }
215
+
216
+ // 1. Clone or pull
217
+ if (fs.existsSync(path.join(pkg.dir, '.git'))) {
218
+ gitPull(pkg.dir);
219
+ } else {
220
+ fs.mkdirSync(PACKAGES_DIR, { recursive: true });
221
+ gitClone(pkg.repo, pkg.dir, pkg.private);
222
+ }
223
+
224
+ // 2. Install dependencies
225
+ // Both teams and pro need TypeScript build
226
+ log('Installing dependencies...');
227
+ run('npm', ['install'], { cwd: pkg.dir });
228
+
229
+ // Rebuild native modules for the current platform/ABI
230
+ log('Rebuilding native modules...');
231
+ run('npm', ['rebuild'], { cwd: pkg.dir });
232
+
233
+ log('Building TypeScript...');
234
+ run('npm', ['run', 'build'], { cwd: pkg.dir });
235
+
236
+ log('Pruning dev dependencies...');
237
+ run('npm', ['prune', '--omit=dev'], { cwd: pkg.dir });
238
+
239
+ // 5. Create symlink
240
+ createSymlink(pkgKey);
241
+
242
+ // 6. Verify
243
+ if (pkg.verify(pkg.dir)) {
244
+ logOk(`${pkg.name} installed successfully`);
245
+ } else {
246
+ logErr(`${pkg.name} installed but ${pkg.verifyLabel} not found`);
247
+ process.exit(1);
248
+ }
249
+
250
+ // 7. Verify native modules
251
+ if (!checkNativeModule('better-sqlite3', pkg.dir)) {
252
+ logWarn('better-sqlite3 native module not loading — attempting rebuild...');
253
+ run('npm', ['rebuild', 'better-sqlite3'], { cwd: pkg.dir });
254
+ if (checkNativeModule('better-sqlite3', pkg.dir)) {
255
+ logOk('better-sqlite3 rebuilt successfully');
256
+ } else {
257
+ logErr('better-sqlite3 still failing — you may need to install build tools');
258
+ }
259
+ } else {
260
+ logOk('Native modules OK');
261
+ }
262
+
263
+ // 8. Update tier in server.json
264
+ const configPath = path.join(SPACES_DIR, 'server.json');
265
+ try {
266
+ const config = fs.existsSync(configPath)
267
+ ? JSON.parse(fs.readFileSync(configPath, 'utf-8'))
268
+ : { port: 3457, basePath: '' };
269
+ // teams → team tier, pro → federation tier
270
+ // Add-on packages set their tier; base package resets to community
271
+ // only if no add-on package is currently installed
272
+ const tierMap = { teams: 'team', pro: 'federation' };
273
+ if (tierMap[pkgKey]) {
274
+ // Installing an add-on — set its tier
275
+ config.tier = tierMap[pkgKey];
276
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
277
+ logOk(`Tier set to ${tierMap[pkgKey]}`);
278
+ } else if (!config.tier || config.tier === 'community') {
279
+ // Base package install, no add-on tier — ensure community
280
+ config.tier = 'community';
281
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
282
+ logOk(`Tier set to community`);
283
+ } else {
284
+ // Base package install but an add-on tier exists — preserve it
285
+ logOk(`Tier unchanged (${config.tier})`);
286
+ }
287
+ } catch {}
288
+
289
+ // 9. Verify require() works
290
+ try {
291
+ const result = execFileSync(process.execPath, [
292
+ '-e',
293
+ `const p = require.resolve('${pkg.name}'); console.log('resolved: ' + p);`,
294
+ ], {
295
+ encoding: 'utf-8',
296
+ stdio: ['pipe', 'pipe', 'pipe'],
297
+ env: { ...process.env, NODE_PATH: path.join(PACKAGES_DIR, 'node_modules') },
298
+ });
299
+ logOk(`require('${pkg.name}') -> ${result.trim().replace('resolved: ', '')}`);
300
+ } catch {
301
+ logWarn(`require('${pkg.name}') failed — this may be OK if peer deps aren't available yet`);
302
+ }
303
+
304
+ console.log('');
305
+ }
306
+
307
+ // ─── Verify command ───────────────────────────────────────────
308
+ function verifyAll() {
309
+ console.log('\n Spaces Package Verification\n');
310
+
311
+ let allOk = true;
312
+
313
+ for (const [key, pkg] of Object.entries(PACKAGES)) {
314
+ log(`─── ${pkg.name} ───`);
315
+
316
+ // Check if installed
317
+ if (!fs.existsSync(pkg.dir)) {
318
+ logWarn('Not installed');
319
+ log('');
320
+ continue;
321
+ }
322
+
323
+ // Check git status
324
+ try {
325
+ const branch = run('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: pkg.dir, quiet: true }).trim();
326
+ const hash = run('git', ['rev-parse', '--short', 'HEAD'], { cwd: pkg.dir, quiet: true }).trim();
327
+ logOk(`Git: ${branch} @ ${hash}`);
328
+ } catch {
329
+ logErr('Git status check failed');
330
+ allOk = false;
331
+ }
332
+
333
+ // Check entry point
334
+ if (pkg.verify(pkg.dir)) {
335
+ logOk(`Entry: ${pkg.verifyLabel} exists`);
336
+ } else {
337
+ logErr(`Entry: ${pkg.verifyLabel} missing`);
338
+ allOk = false;
339
+ }
340
+
341
+ // Check node_modules
342
+ if (fs.existsSync(path.join(pkg.dir, 'node_modules'))) {
343
+ logOk('Dependencies: node_modules present');
344
+ } else {
345
+ logErr('Dependencies: node_modules missing');
346
+ allOk = false;
347
+ }
348
+
349
+ // Check symlink
350
+ const linkPath = path.join(NODE_MODULES_DIR, key);
351
+ try {
352
+ const stat = fs.lstatSync(linkPath);
353
+ if (stat.isSymbolicLink()) {
354
+ const target = fs.readlinkSync(linkPath);
355
+ logOk(`Symlink: @spaces/${key} -> ${target}`);
356
+ } else {
357
+ logWarn(`@spaces/${key} exists but is not a symlink`);
358
+ }
359
+ } catch {
360
+ logErr(`Symlink: @spaces/${key} missing`);
361
+ allOk = false;
362
+ }
363
+
364
+ // Check native modules
365
+ const nativeOk = checkNativeModule('better-sqlite3', pkg.dir);
366
+ if (nativeOk) {
367
+ logOk('Native: better-sqlite3 loads OK');
368
+ } else {
369
+ logErr('Native: better-sqlite3 failed (ABI mismatch? Run: spaces upgrade)');
370
+ allOk = false;
371
+ }
372
+
373
+ // Check require() resolution
374
+ try {
375
+ execFileSync(process.execPath, [
376
+ '-e',
377
+ `require.resolve('${pkg.name}')`,
378
+ ], {
379
+ encoding: 'utf-8',
380
+ stdio: ['pipe', 'pipe', 'pipe'],
381
+ env: { ...process.env, NODE_PATH: path.join(PACKAGES_DIR, 'node_modules') },
382
+ });
383
+ logOk(`require('${pkg.name}') resolves OK`);
384
+ } catch {
385
+ logErr(`require('${pkg.name}') fails`);
386
+ allOk = false;
387
+ }
388
+
389
+ log('');
390
+ }
391
+
392
+ if (allOk) {
393
+ logOk('All checks passed');
394
+ } else {
395
+ logErr('Some checks failed — run "spaces upgrade" to fix');
396
+ }
397
+ console.log('');
398
+ }
399
+
400
+ // ─── Upgrade command ──────────────────────────────────────────
401
+ function upgradePackage(pkgKey) {
402
+ if (pkgKey) {
403
+ // Upgrade specific package
404
+ const pkg = PACKAGES[pkgKey];
405
+ if (!pkg) {
406
+ logErr(`Unknown package: ${pkgKey}`);
407
+ process.exit(1);
408
+ }
409
+ if (!fs.existsSync(pkg.dir)) {
410
+ log(`${pkg.name} not installed — running install instead`);
411
+ installPackage(pkgKey);
412
+ return;
413
+ }
414
+ console.log(`\n Upgrading ${pkg.name}...\n`);
415
+ doUpgrade(pkgKey, pkg);
416
+ } else {
417
+ // Upgrade all installed packages
418
+ console.log('\n Upgrading all installed packages...\n');
419
+ for (const [key, pkg] of Object.entries(PACKAGES)) {
420
+ if (fs.existsSync(pkg.dir)) {
421
+ log(`─── ${pkg.name} ───`);
422
+ doUpgrade(key, pkg);
423
+ log('');
424
+ }
425
+ }
426
+ }
427
+ console.log('');
428
+ }
429
+
430
+ function doUpgrade(pkgKey, pkg) {
431
+ // Pull latest
432
+ gitPull(pkg.dir);
433
+
434
+ run('npm', ['install'], { cwd: pkg.dir });
435
+ run('npm', ['rebuild'], { cwd: pkg.dir });
436
+ log('Building TypeScript...');
437
+ run('npm', ['run', 'build'], { cwd: pkg.dir });
438
+ run('npm', ['prune', '--omit=dev'], { cwd: pkg.dir });
439
+
440
+ // Re-create symlink
441
+ createSymlink(pkgKey);
442
+
443
+ if (pkg.verify(pkg.dir)) {
444
+ logOk(`${pkg.name} upgraded successfully`);
445
+ } else {
446
+ logErr(`${pkg.name} upgrade failed — ${pkg.verifyLabel} not found`);
447
+ }
448
+ }
449
+
450
+ // ─── Uninstall command ────────────────────────────────────────
451
+ function uninstallOne(pkgKey) {
452
+ const pkg = PACKAGES[pkgKey];
453
+
454
+ // Remove symlink
455
+ const linkPath = path.join(NODE_MODULES_DIR, pkgKey);
456
+ try {
457
+ const stat = fs.lstatSync(linkPath);
458
+ if (stat.isSymbolicLink() || stat.isFile()) {
459
+ fs.unlinkSync(linkPath);
460
+ } else if (stat.isDirectory()) {
461
+ fs.rmSync(linkPath, { recursive: true });
462
+ }
463
+ logOk(`Removed symlink @spaces/${pkgKey}`);
464
+ } catch {
465
+ logWarn(`Symlink @spaces/${pkgKey} not found`);
466
+ }
467
+
468
+ // Remove package directory
469
+ if (fs.existsSync(pkg.dir)) {
470
+ fs.rmSync(pkg.dir, { recursive: true });
471
+ logOk(`Removed ${pkg.dir}`);
472
+ } else {
473
+ logWarn(`${pkg.dir} not found`);
474
+ }
475
+ }
476
+
477
+ function uninstallPackage(pkgKey) {
478
+ if (pkgKey) {
479
+ const pkg = PACKAGES[pkgKey];
480
+ if (!pkg) {
481
+ logErr(`Unknown package: ${pkgKey}`);
482
+ log(`Available: ${Object.keys(PACKAGES).join(', ')}`);
483
+ process.exit(1);
484
+ }
485
+ console.log(`\n Uninstalling ${pkg.name}...\n`);
486
+ uninstallOne(pkgKey);
487
+ // Reset tier to community if removing a tier package
488
+ const configPath = path.join(SPACES_DIR, 'server.json');
489
+ try {
490
+ if (fs.existsSync(configPath)) {
491
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
492
+ if (config.tier && config.tier !== 'community') {
493
+ config.tier = 'community';
494
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
495
+ logOk('Reset tier to community');
496
+ }
497
+ }
498
+ } catch {}
499
+ logOk(`${pkg.name} uninstalled`);
500
+ } else {
501
+ console.log('\n Uninstalling everything...\n');
502
+
503
+ // Remove tier packages
504
+ for (const [key, pkg] of Object.entries(PACKAGES)) {
505
+ if (fs.existsSync(pkg.dir) || fs.existsSync(path.join(NODE_MODULES_DIR, key))) {
506
+ log(`─── ${pkg.name} ───`);
507
+ uninstallOne(key);
508
+ }
509
+ }
510
+ // Clean up packages dir
511
+ try { fs.rmdirSync(NODE_MODULES_DIR); } catch {}
512
+ try { fs.rmdirSync(path.join(PACKAGES_DIR, 'node_modules')); } catch {}
513
+ try { fs.rmdirSync(PACKAGES_DIR); } catch {}
514
+
515
+ // Remove the global spaces CLI
516
+ log('─── @jlongo78/agent-spaces ───');
517
+ try {
518
+ run('npm', ['uninstall', '-g', '@jlongo78/agent-spaces'], { quiet: true });
519
+ logOk('Removed global spaces CLI');
520
+ } catch {
521
+ logWarn('Global spaces CLI not found or already removed');
522
+ }
523
+
524
+ // Reset tier to community in server.json
525
+ const configPath = path.join(SPACES_DIR, 'server.json');
526
+ try {
527
+ if (fs.existsSync(configPath)) {
528
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
529
+ if (config.tier && config.tier !== 'community') {
530
+ config.tier = 'community';
531
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
532
+ logOk('Reset tier to community');
533
+ }
534
+ }
535
+ } catch {}
536
+
537
+ logOk('Spaces fully uninstalled');
538
+ log('User data remains at ~/.spaces/ — remove manually if desired');
539
+ }
540
+ console.log('');
541
+ }
542
+
543
+ // ─── CLI ──────────────────────────────────────────────────────
544
+ const command = process.argv[2];
545
+ const target = process.argv[3];
546
+
547
+ switch (command) {
548
+ case 'install':
549
+ if (!target) {
550
+ logErr('Usage: spaces install <teams|pro>');
551
+ process.exit(1);
552
+ }
553
+ installPackage(target);
554
+ break;
555
+
556
+ case 'uninstall':
557
+ uninstallPackage(target || null);
558
+ break;
559
+
560
+ case 'verify':
561
+ verifyAll();
562
+ break;
563
+
564
+ case 'upgrade':
565
+ upgradePackage(target || null);
566
+ break;
567
+
568
+ default:
569
+ logErr(`Unknown command: ${command}`);
570
+ log('Usage: spaces <install|uninstall|verify|upgrade> [package]');
571
+ process.exit(1);
572
+ }