@jlongo78/agent-spaces 0.7.6 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (800) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +6 -0
  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/routes-manifest.json +38 -0
  7. package/.next/standalone/.next/server/app/(desktop)/admin/analytics/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/(desktop)/admin/users/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/(desktop)/analytics/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(desktop)/cortex/page/react-loadable-manifest.json +1 -1
  11. package/.next/standalone/.next/server/app/(desktop)/cortex/page.js.nft.json +1 -1
  12. package/.next/standalone/.next/server/app/(desktop)/cortex/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(desktop)/network/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(desktop)/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(desktop)/projects/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(desktop)/sessions/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(desktop)/settings/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(desktop)/terminal/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/(desktop)/terminal/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/(desktop)/workspaces/page_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  28. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  29. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  30. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  32. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  33. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  34. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  36. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  37. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  38. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  39. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  40. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  41. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  42. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  43. package/.next/standalone/.next/server/app/admin/analytics.html +1 -1
  44. package/.next/standalone/.next/server/app/admin/analytics.rsc +6 -7
  45. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics/__PAGE__.segment.rsc +2 -2
  46. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics.segment.rsc +1 -1
  47. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  48. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/analytics.segments/_full.segment.rsc +6 -7
  50. package/.next/standalone/.next/server/app/admin/analytics.segments/_head.segment.rsc +1 -1
  51. package/.next/standalone/.next/server/app/admin/analytics.segments/_index.segment.rsc +2 -2
  52. package/.next/standalone/.next/server/app/admin/analytics.segments/_tree.segment.rsc +2 -2
  53. package/.next/standalone/.next/server/app/admin/users.html +1 -1
  54. package/.next/standalone/.next/server/app/admin/users.rsc +2 -2
  55. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users/__PAGE__.segment.rsc +1 -1
  56. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users.segment.rsc +1 -1
  57. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  58. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  59. package/.next/standalone/.next/server/app/admin/users.segments/_full.segment.rsc +2 -2
  60. package/.next/standalone/.next/server/app/admin/users.segments/_head.segment.rsc +1 -1
  61. package/.next/standalone/.next/server/app/admin/users.segments/_index.segment.rsc +2 -2
  62. package/.next/standalone/.next/server/app/admin/users.segments/_tree.segment.rsc +2 -2
  63. package/.next/standalone/.next/server/app/analytics.html +1 -1
  64. package/.next/standalone/.next/server/app/analytics.rsc +3 -3
  65. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics/__PAGE__.segment.rsc +2 -2
  66. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics.segment.rsc +1 -1
  67. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/analytics.segments/_full.segment.rsc +3 -3
  69. package/.next/standalone/.next/server/app/analytics.segments/_head.segment.rsc +1 -1
  70. package/.next/standalone/.next/server/app/analytics.segments/_index.segment.rsc +2 -2
  71. package/.next/standalone/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  72. package/.next/standalone/.next/server/app/api/analytics/overview/route.js.nft.json +1 -1
  73. package/.next/standalone/.next/server/app/api/benchmark/lobes/route/app-paths-manifest.json +3 -0
  74. package/.next/standalone/.next/server/app/api/benchmark/lobes/route/build-manifest.json +11 -0
  75. package/.next/standalone/.next/server/app/api/benchmark/lobes/route/server-reference-manifest.json +4 -0
  76. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js +7 -0
  77. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js.map +5 -0
  78. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js.nft.json +1 -0
  79. package/.next/standalone/.next/server/app/api/benchmark/lobes/route_client-reference-manifest.js +2 -0
  80. package/.next/standalone/.next/server/app/api/benchmark/run/route/app-paths-manifest.json +3 -0
  81. package/.next/standalone/.next/server/app/api/benchmark/run/route/build-manifest.json +11 -0
  82. package/.next/standalone/.next/server/app/api/benchmark/run/route/server-reference-manifest.json +4 -0
  83. package/.next/standalone/.next/server/app/api/benchmark/run/route.js +7 -0
  84. package/.next/standalone/.next/server/app/api/benchmark/run/route.js.map +5 -0
  85. package/.next/standalone/.next/server/app/api/benchmark/run/route.js.nft.json +1 -0
  86. package/.next/standalone/.next/server/app/api/benchmark/run/route_client-reference-manifest.js +2 -0
  87. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route/app-paths-manifest.json +3 -0
  88. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route/build-manifest.json +11 -0
  89. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route/server-reference-manifest.json +4 -0
  90. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js +7 -0
  91. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js.map +5 -0
  92. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js.nft.json +1 -0
  93. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route_client-reference-manifest.js +2 -0
  94. package/.next/standalone/.next/server/app/api/benchmark/runs/route/app-paths-manifest.json +3 -0
  95. package/.next/standalone/.next/server/app/api/benchmark/runs/route/build-manifest.json +11 -0
  96. package/.next/standalone/.next/server/app/api/benchmark/runs/route/server-reference-manifest.json +4 -0
  97. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js +7 -0
  98. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js.map +5 -0
  99. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js.nft.json +1 -0
  100. package/.next/standalone/.next/server/app/api/benchmark/runs/route_client-reference-manifest.js +2 -0
  101. package/.next/standalone/.next/server/app/api/benchmark/status/route/app-paths-manifest.json +3 -0
  102. package/.next/standalone/.next/server/app/api/benchmark/status/route/build-manifest.json +11 -0
  103. package/.next/standalone/.next/server/app/api/benchmark/status/route/server-reference-manifest.json +4 -0
  104. package/.next/standalone/.next/server/app/api/benchmark/status/route.js +7 -0
  105. package/.next/standalone/.next/server/app/api/benchmark/status/route.js.map +5 -0
  106. package/.next/standalone/.next/server/app/api/benchmark/status/route.js.nft.json +1 -0
  107. package/.next/standalone/.next/server/app/api/benchmark/status/route_client-reference-manifest.js +2 -0
  108. package/.next/standalone/.next/server/app/api/bulk/route.js.nft.json +1 -1
  109. package/.next/standalone/.next/server/app/api/config/route.js.nft.json +1 -1
  110. package/.next/standalone/.next/server/app/api/cortex/context/route.js.nft.json +1 -1
  111. package/.next/standalone/.next/server/app/api/cortex/curation/assess/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/cortex/curation/publish/route.js.nft.json +1 -1
  113. package/.next/standalone/.next/server/app/api/cortex/curation/refine/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/cortex/curation/review/route.js.nft.json +1 -1
  115. package/.next/standalone/.next/server/app/api/cortex/curation/seed/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/cortex/export/route.js.nft.json +1 -1
  117. package/.next/standalone/.next/server/app/api/cortex/federation/pending/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/cortex/federation/resolve/route.js.nft.json +1 -1
  119. package/.next/standalone/.next/server/app/api/cortex/federation/search/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/cortex/federation/teach/route.js.nft.json +1 -1
  121. package/.next/standalone/.next/server/app/api/cortex/graph/edges/route.js.nft.json +1 -1
  122. package/.next/standalone/.next/server/app/api/cortex/graph/entities/[id]/route.js.nft.json +1 -1
  123. package/.next/standalone/.next/server/app/api/cortex/graph/entities/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/cortex/graph/populate/route.js.nft.json +1 -1
  125. package/.next/standalone/.next/server/app/api/cortex/import/route.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/api/cortex/import/status/route.js.nft.json +1 -1
  127. package/.next/standalone/.next/server/app/api/cortex/ingest/bootstrap/route.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/api/cortex/ingest/status/route.js.nft.json +1 -1
  129. package/.next/standalone/.next/server/app/api/cortex/knowledge/[id]/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/cortex/knowledge/route.js.nft.json +1 -1
  131. package/.next/standalone/.next/server/app/api/cortex/lobes/[id]/route.js.nft.json +1 -1
  132. package/.next/standalone/.next/server/app/api/cortex/lobes/route.js.nft.json +1 -1
  133. package/.next/standalone/.next/server/app/api/cortex/lobes/share/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/cortex/marketplace/browse/route.js.nft.json +1 -1
  135. package/.next/standalone/.next/server/app/api/cortex/marketplace/preview/route.js.nft.json +1 -1
  136. package/.next/standalone/.next/server/app/api/cortex/mcp/call/route.js.nft.json +1 -1
  137. package/.next/standalone/.next/server/app/api/cortex/mcp/tools/route.js.nft.json +1 -1
  138. package/.next/standalone/.next/server/app/api/cortex/search/route.js.nft.json +1 -1
  139. package/.next/standalone/.next/server/app/api/cortex/settings/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/cortex/status/route.js.nft.json +1 -1
  141. package/.next/standalone/.next/server/app/api/cortex/timeline/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/cortex/usage/route.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/api/cortex/workspace/[id]/context/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  145. package/.next/standalone/.next/server/app/api/files/route.js +1 -1
  146. package/.next/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  147. package/.next/standalone/.next/server/app/api/folders/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/network/handshake/route.js.nft.json +1 -1
  149. package/.next/standalone/.next/server/app/api/network/projects/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/network/search/route.js.nft.json +1 -1
  151. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js.nft.json +1 -1
  153. package/.next/standalone/.next/server/app/api/network/sessions/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js.nft.json +1 -1
  155. package/.next/standalone/.next/server/app/api/network/workspaces/route.js.nft.json +1 -1
  156. package/.next/standalone/.next/server/app/api/panes/[id]/route.js.nft.json +1 -1
  157. package/.next/standalone/.next/server/app/api/panes/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  159. package/.next/standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js.nft.json +1 -1
  161. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js.nft.json +1 -1
  162. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  163. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  164. package/.next/standalone/.next/server/app/api/sync/route.js.nft.json +1 -1
  165. package/.next/standalone/.next/server/app/api/tags/route.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/api/tier/route.js.nft.json +1 -1
  167. package/.next/standalone/.next/server/app/api/whisper/route/app-paths-manifest.json +3 -0
  168. package/.next/standalone/.next/server/app/api/whisper/route/build-manifest.json +11 -0
  169. package/.next/standalone/.next/server/app/api/whisper/route/server-reference-manifest.json +4 -0
  170. package/.next/standalone/.next/server/app/api/whisper/route.js +7 -0
  171. package/.next/standalone/.next/server/app/api/whisper/route.js.map +5 -0
  172. package/.next/standalone/.next/server/app/api/whisper/route.js.nft.json +1 -0
  173. package/.next/standalone/.next/server/app/api/whisper/route_client-reference-manifest.js +2 -0
  174. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js.nft.json +1 -1
  175. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js.nft.json +1 -1
  177. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js.nft.json +1 -1
  178. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js.nft.json +1 -1
  179. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js.nft.json +1 -1
  180. package/.next/standalone/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  181. package/.next/standalone/.next/server/app/cortex.html +1 -1
  182. package/.next/standalone/.next/server/app/cortex.rsc +3 -3
  183. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex/__PAGE__.segment.rsc +2 -2
  184. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex.segment.rsc +1 -1
  185. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  186. package/.next/standalone/.next/server/app/cortex.segments/_full.segment.rsc +3 -3
  187. package/.next/standalone/.next/server/app/cortex.segments/_head.segment.rsc +1 -1
  188. package/.next/standalone/.next/server/app/cortex.segments/_index.segment.rsc +2 -2
  189. package/.next/standalone/.next/server/app/cortex.segments/_tree.segment.rsc +2 -2
  190. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/login.html +1 -1
  192. package/.next/standalone/.next/server/app/login.rsc +2 -2
  193. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +2 -2
  194. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  195. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +2 -2
  196. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  197. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  198. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  199. package/.next/standalone/.next/server/app/m/page_client-reference-manifest.js +1 -1
  200. package/.next/standalone/.next/server/app/m/projects/page_client-reference-manifest.js +1 -1
  201. package/.next/standalone/.next/server/app/m/projects.html +1 -1
  202. package/.next/standalone/.next/server/app/m/projects.rsc +2 -2
  203. package/.next/standalone/.next/server/app/m/projects.segments/_full.segment.rsc +2 -2
  204. package/.next/standalone/.next/server/app/m/projects.segments/_head.segment.rsc +1 -1
  205. package/.next/standalone/.next/server/app/m/projects.segments/_index.segment.rsc +2 -2
  206. package/.next/standalone/.next/server/app/m/projects.segments/_tree.segment.rsc +2 -2
  207. package/.next/standalone/.next/server/app/m/projects.segments/m/projects/__PAGE__.segment.rsc +1 -1
  208. package/.next/standalone/.next/server/app/m/projects.segments/m/projects.segment.rsc +1 -1
  209. package/.next/standalone/.next/server/app/m/projects.segments/m.segment.rsc +1 -1
  210. package/.next/standalone/.next/server/app/m/sessions/[id]/page.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/m/sessions/[id]/page_client-reference-manifest.js +1 -1
  212. package/.next/standalone/.next/server/app/m/sessions/page_client-reference-manifest.js +1 -1
  213. package/.next/standalone/.next/server/app/m/sessions.html +1 -1
  214. package/.next/standalone/.next/server/app/m/sessions.rsc +2 -2
  215. package/.next/standalone/.next/server/app/m/sessions.segments/_full.segment.rsc +2 -2
  216. package/.next/standalone/.next/server/app/m/sessions.segments/_head.segment.rsc +1 -1
  217. package/.next/standalone/.next/server/app/m/sessions.segments/_index.segment.rsc +2 -2
  218. package/.next/standalone/.next/server/app/m/sessions.segments/_tree.segment.rsc +2 -2
  219. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions/__PAGE__.segment.rsc +1 -1
  220. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions.segment.rsc +1 -1
  221. package/.next/standalone/.next/server/app/m/sessions.segments/m.segment.rsc +1 -1
  222. package/.next/standalone/.next/server/app/m/settings/page_client-reference-manifest.js +1 -1
  223. package/.next/standalone/.next/server/app/m/settings.html +1 -1
  224. package/.next/standalone/.next/server/app/m/settings.rsc +2 -2
  225. package/.next/standalone/.next/server/app/m/settings.segments/_full.segment.rsc +2 -2
  226. package/.next/standalone/.next/server/app/m/settings.segments/_head.segment.rsc +1 -1
  227. package/.next/standalone/.next/server/app/m/settings.segments/_index.segment.rsc +2 -2
  228. package/.next/standalone/.next/server/app/m/settings.segments/_tree.segment.rsc +2 -2
  229. package/.next/standalone/.next/server/app/m/settings.segments/m/settings/__PAGE__.segment.rsc +1 -1
  230. package/.next/standalone/.next/server/app/m/settings.segments/m/settings.segment.rsc +1 -1
  231. package/.next/standalone/.next/server/app/m/settings.segments/m.segment.rsc +1 -1
  232. package/.next/standalone/.next/server/app/m/terminal/page.js.nft.json +1 -1
  233. package/.next/standalone/.next/server/app/m/terminal/page_client-reference-manifest.js +1 -1
  234. package/.next/standalone/.next/server/app/m/terminal.html +1 -1
  235. package/.next/standalone/.next/server/app/m/terminal.rsc +3 -3
  236. package/.next/standalone/.next/server/app/m/terminal.segments/_full.segment.rsc +3 -3
  237. package/.next/standalone/.next/server/app/m/terminal.segments/_head.segment.rsc +1 -1
  238. package/.next/standalone/.next/server/app/m/terminal.segments/_index.segment.rsc +2 -2
  239. package/.next/standalone/.next/server/app/m/terminal.segments/_tree.segment.rsc +2 -2
  240. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal/__PAGE__.segment.rsc +2 -2
  241. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal.segment.rsc +1 -1
  242. package/.next/standalone/.next/server/app/m/terminal.segments/m.segment.rsc +1 -1
  243. package/.next/standalone/.next/server/app/m.html +1 -1
  244. package/.next/standalone/.next/server/app/m.rsc +2 -2
  245. package/.next/standalone/.next/server/app/m.segments/_full.segment.rsc +2 -2
  246. package/.next/standalone/.next/server/app/m.segments/_head.segment.rsc +1 -1
  247. package/.next/standalone/.next/server/app/m.segments/_index.segment.rsc +2 -2
  248. package/.next/standalone/.next/server/app/m.segments/_tree.segment.rsc +2 -2
  249. package/.next/standalone/.next/server/app/m.segments/m/__PAGE__.segment.rsc +1 -1
  250. package/.next/standalone/.next/server/app/m.segments/m.segment.rsc +1 -1
  251. package/.next/standalone/.next/server/app/network.html +1 -1
  252. package/.next/standalone/.next/server/app/network.rsc +2 -2
  253. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network/__PAGE__.segment.rsc +1 -1
  254. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network.segment.rsc +1 -1
  255. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  256. package/.next/standalone/.next/server/app/network.segments/_full.segment.rsc +2 -2
  257. package/.next/standalone/.next/server/app/network.segments/_head.segment.rsc +1 -1
  258. package/.next/standalone/.next/server/app/network.segments/_index.segment.rsc +2 -2
  259. package/.next/standalone/.next/server/app/network.segments/_tree.segment.rsc +2 -2
  260. package/.next/standalone/.next/server/app/projects.html +1 -1
  261. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  262. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects/__PAGE__.segment.rsc +1 -1
  263. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects.segment.rsc +1 -1
  264. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  265. package/.next/standalone/.next/server/app/projects.segments/_full.segment.rsc +2 -2
  266. package/.next/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  267. package/.next/standalone/.next/server/app/projects.segments/_index.segment.rsc +2 -2
  268. package/.next/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  269. package/.next/standalone/.next/server/app/sessions.html +1 -1
  270. package/.next/standalone/.next/server/app/sessions.rsc +2 -2
  271. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions/__PAGE__.segment.rsc +1 -1
  272. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions.segment.rsc +1 -1
  273. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  274. package/.next/standalone/.next/server/app/sessions.segments/_full.segment.rsc +2 -2
  275. package/.next/standalone/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  276. package/.next/standalone/.next/server/app/sessions.segments/_index.segment.rsc +2 -2
  277. package/.next/standalone/.next/server/app/sessions.segments/_tree.segment.rsc +2 -2
  278. package/.next/standalone/.next/server/app/settings.html +1 -1
  279. package/.next/standalone/.next/server/app/settings.rsc +2 -2
  280. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings/__PAGE__.segment.rsc +1 -1
  281. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings.segment.rsc +1 -1
  282. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  283. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  284. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  285. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  286. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  287. package/.next/standalone/.next/server/app/terminal.html +1 -1
  288. package/.next/standalone/.next/server/app/terminal.rsc +3 -3
  289. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal/__PAGE__.segment.rsc +2 -2
  290. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal.segment.rsc +1 -1
  291. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  292. package/.next/standalone/.next/server/app/terminal.segments/_full.segment.rsc +3 -3
  293. package/.next/standalone/.next/server/app/terminal.segments/_head.segment.rsc +1 -1
  294. package/.next/standalone/.next/server/app/terminal.segments/_index.segment.rsc +2 -2
  295. package/.next/standalone/.next/server/app/terminal.segments/_tree.segment.rsc +2 -2
  296. package/.next/standalone/.next/server/app/vr/page/react-loadable-manifest.json +3 -3
  297. package/.next/standalone/.next/server/app/vr/page_client-reference-manifest.js +1 -1
  298. package/.next/standalone/.next/server/app/vr.html +1 -1
  299. package/.next/standalone/.next/server/app/vr.rsc +3 -3
  300. package/.next/standalone/.next/server/app/vr.segments/_full.segment.rsc +3 -3
  301. package/.next/standalone/.next/server/app/vr.segments/_head.segment.rsc +1 -1
  302. package/.next/standalone/.next/server/app/vr.segments/_index.segment.rsc +2 -2
  303. package/.next/standalone/.next/server/app/vr.segments/_tree.segment.rsc +2 -2
  304. package/.next/standalone/.next/server/app/vr.segments/vr/__PAGE__.segment.rsc +2 -2
  305. package/.next/standalone/.next/server/app/vr.segments/vr.segment.rsc +1 -1
  306. package/.next/standalone/.next/server/app/workspaces.html +1 -1
  307. package/.next/standalone/.next/server/app/workspaces.rsc +2 -2
  308. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces/__PAGE__.segment.rsc +1 -1
  309. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces.segment.rsc +1 -1
  310. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  311. package/.next/standalone/.next/server/app/workspaces.segments/_full.segment.rsc +2 -2
  312. package/.next/standalone/.next/server/app/workspaces.segments/_head.segment.rsc +1 -1
  313. package/.next/standalone/.next/server/app/workspaces.segments/_index.segment.rsc +2 -2
  314. package/.next/standalone/.next/server/app/workspaces.segments/_tree.segment.rsc +2 -2
  315. package/.next/standalone/.next/server/app-paths-manifest.json +6 -0
  316. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0041efe4._.js +2 -2
  317. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00bf0ace._.js +2 -2
  318. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0a837dd9._.js +98 -0
  319. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e71d908._.js +3 -3
  320. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e9142f3._.js +2 -2
  321. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10e47926._.js +1 -1
  322. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1665dc78._.js +2 -2
  323. package/.next/standalone/.next/server/chunks/[root-of-the-server]__175cbabf._.js +2 -2
  324. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1adae357._.js +2 -2
  325. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d359752._.js +2 -2
  326. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1e8fabeb._.js +2 -2
  327. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1f8deca0._.js +8 -8
  328. package/.next/standalone/.next/server/chunks/[root-of-the-server]__253fdda1._.js +2 -2
  329. package/.next/standalone/.next/server/chunks/[root-of-the-server]__28e6434f._.js +2 -2
  330. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2a386564._.js +3 -3
  331. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2c20fb38._.js +2 -2
  332. package/.next/standalone/.next/server/chunks/[root-of-the-server]__309132cd._.js +1 -1
  333. package/.next/standalone/.next/server/chunks/[root-of-the-server]__33fec964._.js +3 -3
  334. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3786d8ae._.js +2 -2
  335. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3ae92407._.js +2 -2
  336. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3beda9fe._.js +2 -2
  337. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4619e9bd._.js +1 -1
  338. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4a051043._.js +2 -2
  339. package/.next/standalone/.next/server/chunks/[root-of-the-server]__508002e4._.js +2 -2
  340. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5086c373._.js +2 -2
  341. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5913e097._.js +2 -2
  342. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5b5f68d2._.js +2 -2
  343. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c1f2459._.js +2 -2
  344. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5ec8c977._.js +2 -2
  345. package/.next/standalone/.next/server/chunks/[root-of-the-server]__63cebc6c._.js +2 -2
  346. package/.next/standalone/.next/server/chunks/[root-of-the-server]__64d30d4d._.js +2 -2
  347. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c54fc2e._.js +2 -2
  348. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6dc1fb7e._.js +2 -2
  349. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6e568102._.js +2 -2
  350. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6faa04c0._.js +2 -2
  351. package/.next/standalone/.next/server/chunks/[root-of-the-server]__74a34dc3._.js +2 -2
  352. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7819e4cf._.js +98 -0
  353. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7e7250a4._.js +2 -2
  354. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8309e0a4._.js +2 -2
  355. package/.next/standalone/.next/server/chunks/[root-of-the-server]__86cc0e2b._.js +6 -6
  356. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89c2565a._.js +2 -2
  357. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8d178ad9._.js +2 -2
  358. package/.next/standalone/.next/server/chunks/[root-of-the-server]__93ee06f3._.js +2 -2
  359. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9e1f0137._.js +98 -0
  360. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9e4c154a._.js +2 -2
  361. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9d2e1d3._.js +2 -2
  362. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ae53d343._.js +2 -2
  363. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b3a04cef._.js +2 -2
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b4270b77._.js +1 -1
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b6b6ce60._.js +3 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c0757773._.js +98 -0
  367. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c24cfa91._.js +3 -0
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c7c47529._.js +3 -0
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c88b63f7._.js +2 -2
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cba5f007._.js +1 -1
  371. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cbf4ceb0._.js +2 -2
  372. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cefdba2f._.js +2 -2
  373. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cf9e82bb._.js +2 -2
  374. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d2897392._.js +2 -2
  375. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d3b2d856._.js +2 -2
  376. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d73273ca._.js +2 -2
  377. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d8417eb6._.js +2 -2
  378. package/.next/standalone/.next/server/chunks/[root-of-the-server]__dc2a55de._.js +2 -2
  379. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e0d4690b._.js +2 -2
  380. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e3ea8547._.js +98 -0
  381. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e678dd53._.js +1 -1
  382. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e9223f55._.js +2 -2
  383. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ea630076._.js +2 -2
  384. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f26ca49d._.js +1 -1
  385. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f33e1101._.js +2 -2
  386. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f515f865._.js +2 -2
  387. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fceb5d60._.js +2 -2
  388. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fed41403._.js +2 -2
  389. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ff2e98c2._.js +2 -2
  390. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_benchmark_lobes_route_actions_ea7beadb.js +3 -0
  391. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_benchmark_run_route_actions_9ed0ba41.js +3 -0
  392. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_benchmark_runs_[id]_route_actions_39f90307.js +3 -0
  393. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_benchmark_runs_route_actions_37cf958b.js +3 -0
  394. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_benchmark_status_route_actions_009e2cba.js +3 -0
  395. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_whisper_route_actions_be9a633d.js +3 -0
  396. package/.next/standalone/.next/server/chunks/ssr/{_c1cfdd09._.js → [root-of-the-server]__16621ac5._.js} +2 -2
  397. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__66aca5d4._.js +1 -1
  398. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__9c81bd86._.js +3 -0
  399. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__e3bf6054._.js +5 -0
  400. package/.next/standalone/.next/server/chunks/ssr/{_81abf587._.js → _31ada310._.js} +2 -2
  401. package/.next/standalone/.next/server/chunks/ssr/_648a8a2d._.js +3 -0
  402. package/.next/standalone/.next/server/chunks/ssr/_999dae61._.js +3 -0
  403. package/.next/standalone/.next/server/chunks/ssr/_c48c91e5._.js +3 -0
  404. package/.next/standalone/.next/server/chunks/ssr/_f8959434._.js +3 -0
  405. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_cortex_page_tsx_0f33d8b3._.js +1 -1
  406. package/.next/standalone/.next/server/chunks/ssr/src_components_terminal_terminal-pane_tsx_803c5e2c._.js +9 -0
  407. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__32a0045c._.js +1 -1
  408. package/.next/standalone/.next/server/edge/chunks/_d73df637._.js +1 -1
  409. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  410. package/.next/standalone/.next/server/pages/404.html +1 -1
  411. package/.next/standalone/.next/server/pages/500.html +2 -2
  412. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  413. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  414. package/.next/standalone/.next/static/chunks/157826a3253f8ccf.js +7 -0
  415. package/.next/standalone/.next/static/chunks/{396eac60f496f178.js → 2f9f09924ff9d447.js} +1 -1
  416. package/.next/standalone/.next/static/chunks/{e23f20b51a75a5bb.js → 4ced66ef12d91b38.js} +35 -12
  417. package/.next/standalone/.next/static/chunks/57d04d161b8a01b3.js +7 -0
  418. package/.next/standalone/.next/static/chunks/709c4608e5b935e8.js +1 -0
  419. package/.next/standalone/.next/static/chunks/{7424664c6ffa94bd.js → 7b14d4e609b55b9b.js} +1 -1
  420. package/.next/standalone/.next/static/chunks/7be37f4a56b8f575.js +1 -0
  421. package/.next/standalone/.next/static/chunks/8021d5a2269ff113.js +1 -0
  422. package/.next/standalone/.next/static/chunks/a3fd93a9dde3cacc.js +1 -0
  423. package/.next/standalone/.next/static/chunks/{412140a02893327a.js → afee31c7399daf2a.js} +1 -1
  424. package/.next/standalone/.next/static/chunks/b92fdbf858aeb0b3.js +1 -0
  425. package/.next/standalone/.next/static/chunks/c17274c2f95d4ba2.js +5 -0
  426. package/.next/standalone/.next/static/chunks/e116953dc83d4eec.js +1 -0
  427. package/.next/standalone/.next/static/chunks/e82f4414650587cf.js +7 -0
  428. package/.next/standalone/.next/static/chunks/f6464729e7aa0da0.css +3 -0
  429. package/.next/standalone/LICENSE +661 -0
  430. package/.next/standalone/NOTICE +5 -0
  431. package/.next/standalone/README.md +131 -0
  432. package/.next/standalone/bin/cortex-hook.sh +62 -62
  433. package/.next/standalone/bin/cortex-mcp.js +60 -60
  434. package/.next/standalone/bin/fix-standalone-externals.js +79 -0
  435. package/.next/standalone/bin/lib/auto-setup.js +110 -0
  436. package/.next/standalone/bin/mdns-service.js +171 -0
  437. package/.next/standalone/bin/postinstall.js +35 -0
  438. package/.next/standalone/bin/setup-admin.js +195 -0
  439. package/.next/standalone/bin/spaces-dev.js +247 -0
  440. package/.next/standalone/bin/spaces-install.js +638 -0
  441. package/.next/standalone/bin/spaces-reset-totp.js +50 -0
  442. package/.next/standalone/bin/spaces-service.js +1020 -0
  443. package/.next/standalone/bin/spaces-setup.js +253 -0
  444. package/.next/standalone/bin/spaces.js +788 -0
  445. package/.next/standalone/bin/ssh-auth-keys.sh +68 -0
  446. package/.next/standalone/bin/terminal-server.js +1807 -0
  447. package/.next/standalone/docker-compose.yml +28 -0
  448. package/.next/standalone/docs/architecture.md +387 -0
  449. package/.next/standalone/docs/cortex.md +293 -0
  450. package/.next/standalone/docs/getting-started.md +96 -0
  451. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-design.md +133 -0
  452. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-plan.md +959 -0
  453. package/.next/standalone/docs/plans/2026-03-07-service-command-design.md +146 -0
  454. package/.next/standalone/docs/plans/2026-03-07-service-command-plan.md +254 -0
  455. package/.next/standalone/docs/server-install.md +564 -0
  456. package/.next/standalone/docs/social-card.html +150 -0
  457. package/.next/standalone/docs/superpowers/plans/2026-03-12-spaces-cortex.md +5270 -0
  458. package/.next/standalone/docs/superpowers/plans/2026-03-13-cortex-wiring.md +1387 -1387
  459. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-entity-graph.md +1923 -1923
  460. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-knowledge-evolution.md +1113 -1113
  461. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-boundary-engine.md +853 -853
  462. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-context-engine.md +1274 -1274
  463. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-signal-ingestion.md +933 -933
  464. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-lobes.md +1080 -1080
  465. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-gravity-system.md +768 -768
  466. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-ui.md +1108 -1108
  467. package/.next/standalone/docs/superpowers/plans/2026-03-18-cortex-ui-integration.md +1846 -1846
  468. package/.next/standalone/docs/superpowers/plans/2026-03-19-vr-phase1-shell.md +1639 -0
  469. package/.next/standalone/docs/superpowers/specs/2026-03-11-universe-view-design.md +320 -0
  470. package/.next/standalone/docs/superpowers/specs/2026-03-12-spaces-brain-design.md +720 -0
  471. package/.next/standalone/docs/superpowers/specs/2026-03-13-cortex-wiring-design.md +268 -268
  472. package/.next/standalone/docs/superpowers/specs/2026-03-14-cortex-v2-design.md +623 -623
  473. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-lobes-design.md +263 -263
  474. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-v2-ui-design.md +240 -240
  475. package/.next/standalone/docs/superpowers/specs/2026-03-16-pane-ux-design.md +77 -0
  476. package/.next/standalone/docs/superpowers/specs/2026-03-18-cortex-ui-integration-design.md +341 -341
  477. package/.next/standalone/docs/superpowers/specs/2026-03-19-vr-phase1-shell-design.md +288 -0
  478. package/.next/standalone/docs/tiers.md +104 -0
  479. package/.next/standalone/eslint.config.mjs +18 -0
  480. package/.next/standalone/next.config.ts +20 -0
  481. package/.next/standalone/nginx.conf +53 -0
  482. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/README.md +46 -0
  483. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +221 -0
  484. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +1 -0
  485. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  486. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/package.json +42 -0
  487. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +46 -0
  488. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +221 -0
  489. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +1 -0
  490. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  491. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +42 -0
  492. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +30 -0
  493. package/.next/standalone/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
  494. package/.next/standalone/node_modules/@img/{sharp-win32-x64 → sharp-linux-x64}/package.json +46 -39
  495. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
  496. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +46 -0
  497. package/.next/standalone/package-lock.json +14154 -0
  498. package/.next/standalone/package.json +104 -103
  499. package/.next/standalone/postcss.config.mjs +7 -0
  500. package/.next/standalone/scripts/rebuild.cmd +65 -0
  501. package/.next/standalone/scripts/rebuild.sh +59 -0
  502. package/.next/standalone/server.js +1 -1
  503. package/.next/standalone/src/app/(desktop)/admin/analytics/page.tsx +266 -0
  504. package/.next/standalone/src/app/(desktop)/admin/users/page.tsx +399 -0
  505. package/.next/standalone/src/app/(desktop)/analytics/page.tsx +166 -0
  506. package/.next/standalone/src/app/(desktop)/cortex/page.tsx +81 -78
  507. package/.next/standalone/src/app/(desktop)/dashboard-client.tsx +56 -0
  508. package/.next/standalone/src/app/(desktop)/layout.tsx +18 -0
  509. package/.next/standalone/src/app/(desktop)/network/page.tsx +137 -0
  510. package/.next/standalone/src/app/(desktop)/page.tsx +17 -0
  511. package/.next/standalone/src/app/(desktop)/projects/page.tsx +68 -0
  512. package/.next/standalone/src/app/(desktop)/sessions/[id]/page.tsx +519 -0
  513. package/.next/standalone/src/app/(desktop)/sessions/page.tsx +145 -0
  514. package/.next/standalone/src/app/(desktop)/settings/page.tsx +446 -0
  515. package/.next/standalone/src/app/(desktop)/terminal/layout.tsx +7 -0
  516. package/.next/standalone/src/app/(desktop)/terminal/page.tsx +1151 -0
  517. package/.next/standalone/src/app/(desktop)/terminal/pane/[id]/page.tsx +211 -0
  518. package/.next/standalone/src/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page.tsx +192 -0
  519. package/.next/standalone/src/app/(desktop)/workspaces/page.tsx +12 -0
  520. package/.next/standalone/src/app/api/admin/analytics/route.ts +10 -0
  521. package/.next/standalone/src/app/api/admin/users/[id]/route.ts +20 -0
  522. package/.next/standalone/src/app/api/admin/users/route.ts +15 -0
  523. package/.next/standalone/src/app/api/analytics/overview/route.ts +80 -0
  524. package/.next/standalone/src/app/api/auth/login/route.ts +10 -0
  525. package/.next/standalone/src/app/api/auth/logout/route.ts +9 -0
  526. package/.next/standalone/src/app/api/auth/me/route.ts +22 -0
  527. package/.next/standalone/src/app/api/auth/totp/setup/route.ts +10 -0
  528. package/.next/standalone/src/app/api/auth/totp/status/route.ts +10 -0
  529. package/.next/standalone/src/app/api/auth/totp/verify/route.ts +10 -0
  530. package/.next/standalone/src/app/api/benchmark/lobes/route.ts +16 -0
  531. package/.next/standalone/src/app/api/benchmark/run/route.ts +92 -0
  532. package/.next/standalone/src/app/api/benchmark/runs/[id]/route.ts +26 -0
  533. package/.next/standalone/src/app/api/benchmark/runs/route.ts +16 -0
  534. package/.next/standalone/src/app/api/benchmark/status/route.ts +35 -0
  535. package/.next/standalone/src/app/api/bulk/route.ts +34 -0
  536. package/.next/standalone/src/app/api/chat/route.ts +85 -0
  537. package/.next/standalone/src/app/api/config/route.ts +30 -0
  538. package/.next/standalone/src/app/api/cortex/context/route.ts +78 -78
  539. package/.next/standalone/src/app/api/cortex/curation/assess/route.ts +27 -27
  540. package/.next/standalone/src/app/api/cortex/curation/publish/route.ts +23 -23
  541. package/.next/standalone/src/app/api/cortex/curation/refine/route.ts +23 -23
  542. package/.next/standalone/src/app/api/cortex/curation/review/route.ts +29 -29
  543. package/.next/standalone/src/app/api/cortex/curation/seed/route.ts +23 -23
  544. package/.next/standalone/src/app/api/cortex/export/route.ts +40 -40
  545. package/.next/standalone/src/app/api/cortex/federation/pending/route.ts +20 -20
  546. package/.next/standalone/src/app/api/cortex/federation/resolve/route.ts +43 -43
  547. package/.next/standalone/src/app/api/cortex/federation/search/route.ts +35 -35
  548. package/.next/standalone/src/app/api/cortex/federation/teach/route.ts +76 -76
  549. package/.next/standalone/src/app/api/cortex/graph/edges/route.ts +112 -112
  550. package/.next/standalone/src/app/api/cortex/graph/entities/[id]/route.ts +73 -73
  551. package/.next/standalone/src/app/api/cortex/graph/entities/route.ts +75 -75
  552. package/.next/standalone/src/app/api/cortex/graph/populate/route.ts +203 -203
  553. package/.next/standalone/src/app/api/cortex/import/route.ts +75 -75
  554. package/.next/standalone/src/app/api/cortex/import/status/route.ts +15 -15
  555. package/.next/standalone/src/app/api/cortex/ingest/bootstrap/route.ts +29 -29
  556. package/.next/standalone/src/app/api/cortex/ingest/status/route.ts +15 -15
  557. package/.next/standalone/src/app/api/cortex/knowledge/[id]/route.ts +91 -91
  558. package/.next/standalone/src/app/api/cortex/knowledge/route.ts +93 -93
  559. package/.next/standalone/src/app/api/cortex/lobes/[id]/route.ts +67 -67
  560. package/.next/standalone/src/app/api/cortex/lobes/route.ts +22 -22
  561. package/.next/standalone/src/app/api/cortex/lobes/share/route.ts +80 -80
  562. package/.next/standalone/src/app/api/cortex/marketplace/browse/route.ts +43 -43
  563. package/.next/standalone/src/app/api/cortex/marketplace/preview/route.ts +46 -46
  564. package/.next/standalone/src/app/api/cortex/mcp/call/route.ts +11 -11
  565. package/.next/standalone/src/app/api/cortex/mcp/tools/route.ts +6 -6
  566. package/.next/standalone/src/app/api/cortex/search/route.ts +43 -43
  567. package/.next/standalone/src/app/api/cortex/settings/route.ts +33 -33
  568. package/.next/standalone/src/app/api/cortex/status/route.ts +169 -169
  569. package/.next/standalone/src/app/api/cortex/timeline/route.ts +42 -42
  570. package/.next/standalone/src/app/api/cortex/usage/route.ts +31 -31
  571. package/.next/standalone/src/app/api/cortex/workspace/[id]/context/route.ts +41 -41
  572. package/.next/standalone/src/app/api/events/route.ts +40 -0
  573. package/.next/standalone/src/app/api/files/route.ts +187 -0
  574. package/.next/standalone/src/app/api/folders/route.ts +97 -0
  575. package/.next/standalone/src/app/api/network/connect-callback/route.ts +11 -0
  576. package/.next/standalone/src/app/api/network/connect-request/[id]/route.ts +11 -0
  577. package/.next/standalone/src/app/api/network/connect-request/route.ts +17 -0
  578. package/.next/standalone/src/app/api/network/discovered/route.ts +9 -0
  579. package/.next/standalone/src/app/api/network/handshake/route.ts +25 -0
  580. package/.next/standalone/src/app/api/network/health/route.ts +10 -0
  581. package/.next/standalone/src/app/api/network/identity/route.ts +15 -0
  582. package/.next/standalone/src/app/api/network/keys/[id]/route.ts +10 -0
  583. package/.next/standalone/src/app/api/network/keys/route.ts +15 -0
  584. package/.next/standalone/src/app/api/network/nodes/[id]/route.ts +15 -0
  585. package/.next/standalone/src/app/api/network/nodes/check/route.ts +9 -0
  586. package/.next/standalone/src/app/api/network/nodes/route.ts +15 -0
  587. package/.next/standalone/src/app/api/network/projects/route.ts +25 -0
  588. package/.next/standalone/src/app/api/network/proxy/[nodeId]/[...path]/route.ts +15 -0
  589. package/.next/standalone/src/app/api/network/search/route.ts +38 -0
  590. package/.next/standalone/src/app/api/network/sessions/[id]/messages/route.ts +36 -0
  591. package/.next/standalone/src/app/api/network/sessions/[id]/route.ts +34 -0
  592. package/.next/standalone/src/app/api/network/sessions/route.ts +43 -0
  593. package/.next/standalone/src/app/api/network/terminal/token/route.ts +10 -0
  594. package/.next/standalone/src/app/api/network/workspaces/[id]/route.ts +34 -0
  595. package/.next/standalone/src/app/api/network/workspaces/route.ts +61 -0
  596. package/.next/standalone/src/app/api/panes/[id]/route.ts +60 -0
  597. package/.next/standalone/src/app/api/panes/route.ts +39 -0
  598. package/.next/standalone/src/app/api/projects/route.ts +13 -0
  599. package/.next/standalone/src/app/api/search/route.ts +47 -0
  600. package/.next/standalone/src/app/api/sessions/[id]/chat/route.ts +120 -0
  601. package/.next/standalone/src/app/api/sessions/[id]/messages/route.ts +28 -0
  602. package/.next/standalone/src/app/api/sessions/[id]/route.ts +73 -0
  603. package/.next/standalone/src/app/api/sessions/route.ts +64 -0
  604. package/.next/standalone/src/app/api/sync/route.ts +24 -0
  605. package/.next/standalone/src/app/api/tags/route.ts +35 -0
  606. package/.next/standalone/src/app/api/tier/route.ts +16 -0
  607. package/.next/standalone/src/app/api/updates/route.ts +53 -0
  608. package/.next/standalone/src/app/api/whisper/route.ts +90 -0
  609. package/.next/standalone/src/app/api/workspaces/[id]/context/[key]/route.ts +39 -0
  610. package/.next/standalone/src/app/api/workspaces/[id]/context/route.ts +28 -0
  611. package/.next/standalone/src/app/api/workspaces/[id]/messages/[msgId]/route.ts +17 -0
  612. package/.next/standalone/src/app/api/workspaces/[id]/messages/route.ts +39 -0
  613. package/.next/standalone/src/app/api/workspaces/[id]/route.ts +47 -0
  614. package/.next/standalone/src/app/api/workspaces/[id]/sessions/route.ts +62 -0
  615. package/.next/standalone/src/app/api/workspaces/route.ts +79 -0
  616. package/.next/standalone/src/app/globals.css +85 -0
  617. package/.next/standalone/src/app/icon.png +0 -0
  618. package/.next/standalone/src/app/layout.tsx +33 -0
  619. package/.next/standalone/src/app/login/layout.tsx +7 -0
  620. package/.next/standalone/src/app/login/page.tsx +315 -0
  621. package/.next/standalone/src/app/m/layout.tsx +16 -0
  622. package/.next/standalone/src/app/m/page.tsx +118 -0
  623. package/.next/standalone/src/app/m/projects/page.tsx +64 -0
  624. package/.next/standalone/src/app/m/sessions/[id]/page.tsx +168 -0
  625. package/.next/standalone/src/app/m/sessions/page.tsx +177 -0
  626. package/.next/standalone/src/app/m/settings/page.tsx +230 -0
  627. package/.next/standalone/src/app/m/terminal/page.tsx +413 -0
  628. package/.next/standalone/src/app/vr/page.tsx +21 -0
  629. package/.next/standalone/src/app/vr/vr-app.tsx +163 -0
  630. package/.next/standalone/src/app/vr/vr-controls.tsx +139 -0
  631. package/.next/standalone/src/app/vr/vr-door.tsx +82 -0
  632. package/.next/standalone/src/app/vr/vr-environment.tsx +71 -0
  633. package/.next/standalone/src/app/vr/vr-gaze.tsx +89 -0
  634. package/.next/standalone/src/app/vr/vr-layout.ts +49 -0
  635. package/.next/standalone/src/app/vr/vr-lobby.tsx +97 -0
  636. package/.next/standalone/src/app/vr/vr-pane.tsx +195 -0
  637. package/.next/standalone/src/app/vr/vr-room.tsx +79 -0
  638. package/.next/standalone/src/app/vr/vr-terminal.tsx +303 -0
  639. package/.next/standalone/src/components/auth/totp-gate.tsx +183 -0
  640. package/.next/standalone/src/components/bus/activity-panel.tsx +261 -0
  641. package/.next/standalone/src/components/common/color-picker.tsx +35 -0
  642. package/.next/standalone/src/components/common/dev-directory-picker.tsx +339 -0
  643. package/.next/standalone/src/components/common/folder-picker.tsx +200 -0
  644. package/.next/standalone/src/components/common/tag-picker.tsx +190 -0
  645. package/.next/standalone/src/components/common/workspace-picker.tsx +113 -0
  646. package/.next/standalone/src/components/cortex/benchmark-tab.tsx +880 -0
  647. package/.next/standalone/src/components/cortex/constants.ts +29 -29
  648. package/.next/standalone/src/components/cortex/cortex-dashboard.tsx +304 -304
  649. package/.next/standalone/src/components/cortex/cortex-indicator.tsx +44 -44
  650. package/.next/standalone/src/components/cortex/cortex-panel.tsx +140 -140
  651. package/.next/standalone/src/components/cortex/cortex-settings.tsx +221 -221
  652. package/.next/standalone/src/components/cortex/curation-tab.tsx +810 -810
  653. package/.next/standalone/src/components/cortex/entity-detail.tsx +101 -101
  654. package/.next/standalone/src/components/cortex/entity-graph.tsx +382 -382
  655. package/.next/standalone/src/components/cortex/import-dialog.tsx +212 -212
  656. package/.next/standalone/src/components/cortex/injection-badge.tsx +72 -72
  657. package/.next/standalone/src/components/cortex/knowledge-card.tsx +109 -109
  658. package/.next/standalone/src/components/cortex/knowledge-tab.tsx +158 -158
  659. package/.next/standalone/src/components/cortex/lobe-settings.tsx +215 -215
  660. package/.next/standalone/src/components/cortex/marketplace-card.tsx +126 -126
  661. package/.next/standalone/src/components/cortex/marketplace-tab.tsx +113 -113
  662. package/.next/standalone/src/components/dashboard/activity-chart.tsx +41 -0
  663. package/.next/standalone/src/components/dashboard/model-usage-chart.tsx +61 -0
  664. package/.next/standalone/src/components/dashboard/recent-sessions.tsx +68 -0
  665. package/.next/standalone/src/components/dashboard/stats-cards.tsx +36 -0
  666. package/.next/standalone/src/components/files/file-explorer.tsx +703 -0
  667. package/.next/standalone/src/components/layout/providers.tsx +38 -0
  668. package/.next/standalone/src/components/layout/sidebar.tsx +170 -0
  669. package/.next/standalone/src/components/layout/tier-provider.tsx +53 -0
  670. package/.next/standalone/src/components/layout/update-banner.tsx +92 -0
  671. package/.next/standalone/src/components/mobile/bottom-nav.tsx +46 -0
  672. package/.next/standalone/src/components/mobile/mobile-chat-input.tsx +244 -0
  673. package/.next/standalone/src/components/mobile/mobile-header.tsx +44 -0
  674. package/.next/standalone/src/components/mobile/mobile-session-card.tsx +56 -0
  675. package/.next/standalone/src/components/mobile/mobile-terminal-input.tsx +71 -0
  676. package/.next/standalone/src/components/mobile/mobile-terminal-pane.tsx +300 -0
  677. package/.next/standalone/src/components/mobile/mobile-terminal-toolbar.tsx +53 -0
  678. package/.next/standalone/src/components/mobile/pull-to-refresh.tsx +82 -0
  679. package/.next/standalone/src/components/mobile/voice-input.tsx +53 -0
  680. package/.next/standalone/src/components/network/api-key-list.tsx +190 -0
  681. package/.next/standalone/src/components/network/connection-requests.tsx +94 -0
  682. package/.next/standalone/src/components/network/node-add-dialog.tsx +131 -0
  683. package/.next/standalone/src/components/network/node-badge.tsx +26 -0
  684. package/.next/standalone/src/components/network/node-list.tsx +207 -0
  685. package/.next/standalone/src/components/network/node-selector.tsx +49 -0
  686. package/.next/standalone/src/components/sessions/session-filters.tsx +116 -0
  687. package/.next/standalone/src/components/sessions/session-list.tsx +485 -0
  688. package/.next/standalone/src/components/terminal/terminal-pane.tsx +874 -0
  689. package/.next/standalone/src/components/viewer/chat-input.tsx +275 -0
  690. package/.next/standalone/src/components/viewer/message-renderer.tsx +551 -0
  691. package/.next/standalone/src/components/workspace/universe-cluster.tsx +131 -0
  692. package/.next/standalone/src/components/workspace/universe-orb.tsx +128 -0
  693. package/.next/standalone/src/components/workspace/universe-types.ts +22 -0
  694. package/.next/standalone/src/components/workspace/universe-utils.ts +11 -0
  695. package/.next/standalone/src/components/workspace/universe-view.tsx +397 -0
  696. package/.next/standalone/src/components/workspace/workspace-chooser.tsx +616 -0
  697. package/.next/standalone/src/hooks/use-benchmark.ts +71 -0
  698. package/.next/standalone/src/hooks/use-bus.ts +147 -0
  699. package/.next/standalone/src/hooks/use-idle-detection.ts +79 -0
  700. package/.next/standalone/src/hooks/use-network.ts +229 -0
  701. package/.next/standalone/src/hooks/use-sessions.ts +437 -0
  702. package/.next/standalone/src/hooks/use-speech-recognition.ts +113 -0
  703. package/.next/standalone/src/hooks/use-sse.ts +35 -0
  704. package/.next/standalone/src/hooks/use-tier.ts +39 -0
  705. package/.next/standalone/src/lib/agents.ts +70 -0
  706. package/.next/standalone/src/lib/aider/parser.ts +111 -0
  707. package/.next/standalone/src/lib/api.ts +19 -0
  708. package/.next/standalone/src/lib/auth.ts +47 -0
  709. package/.next/standalone/src/lib/claude/parser.ts +212 -0
  710. package/.next/standalone/src/lib/claude/stats.ts +204 -0
  711. package/.next/standalone/src/lib/codex/parser.ts +265 -0
  712. package/.next/standalone/src/lib/config.ts +115 -0
  713. package/.next/standalone/src/lib/cortex/benchmark.ts +67 -0
  714. package/.next/standalone/src/lib/cortex/config.ts +40 -40
  715. package/.next/standalone/src/lib/cortex/debug.ts +10 -10
  716. package/.next/standalone/src/lib/cortex/distillation/usage-store.ts +18 -18
  717. package/.next/standalone/src/lib/cortex/graph/resolver.ts +10 -10
  718. package/.next/standalone/src/lib/cortex/graph/types.ts +22 -22
  719. package/.next/standalone/src/lib/cortex/index.ts +56 -56
  720. package/.next/standalone/src/lib/cortex/ingestion/bootstrap.ts +14 -14
  721. package/.next/standalone/src/lib/cortex/knowledge/compat.ts +14 -14
  722. package/.next/standalone/src/lib/cortex/knowledge/contradiction.ts +10 -10
  723. package/.next/standalone/src/lib/cortex/knowledge/types.ts +67 -67
  724. package/.next/standalone/src/lib/cortex/lobes/config.ts +16 -16
  725. package/.next/standalone/src/lib/cortex/lobes/resolver.ts +8 -8
  726. package/.next/standalone/src/lib/cortex/lobes/shares.ts +14 -14
  727. package/.next/standalone/src/lib/cortex/mcp/server.ts +8 -8
  728. package/.next/standalone/src/lib/cortex/portability/exporter.ts +6 -6
  729. package/.next/standalone/src/lib/cortex/portability/importer.ts +10 -10
  730. package/.next/standalone/src/lib/cortex/retrieval/context-engine.ts +10 -10
  731. package/.next/standalone/src/lib/cortex/types.ts +39 -39
  732. package/.next/standalone/src/lib/cost-calculator.ts +48 -0
  733. package/.next/standalone/src/lib/db/init.ts +71 -0
  734. package/.next/standalone/src/lib/db/queries.ts +718 -0
  735. package/.next/standalone/src/lib/db/schema.ts +202 -0
  736. package/.next/standalone/src/lib/events/sse.ts +36 -0
  737. package/.next/standalone/src/lib/gemini/parser.ts +216 -0
  738. package/.next/standalone/src/lib/license.ts +56 -0
  739. package/.next/standalone/src/lib/pro.ts +31 -0
  740. package/.next/standalone/src/lib/sync/indexer.ts +429 -0
  741. package/.next/standalone/src/lib/sync/watcher.ts +64 -0
  742. package/.next/standalone/src/lib/teams.ts +31 -0
  743. package/.next/standalone/src/lib/telemetry.ts +75 -0
  744. package/.next/standalone/src/lib/terminal/server.ts +128 -0
  745. package/.next/standalone/src/lib/tier.ts +38 -0
  746. package/.next/standalone/src/lib/utils.ts +72 -0
  747. package/.next/standalone/src/middleware.ts +133 -0
  748. package/.next/standalone/src/types/claude.ts +208 -0
  749. package/.next/standalone/src/types/network.ts +61 -0
  750. package/.next/standalone/tests/setup.ts +8 -0
  751. package/.next/standalone/tsconfig.json +34 -34
  752. package/.next/standalone/vitest.config.ts +24 -0
  753. package/LICENSE +661 -661
  754. package/README.md +131 -131
  755. package/bin/cortex-hook.sh +62 -62
  756. package/bin/cortex-mcp.js +60 -60
  757. package/bin/fix-standalone-externals.js +79 -79
  758. package/bin/lib/auto-setup.js +110 -110
  759. package/bin/mdns-service.js +171 -171
  760. package/bin/postinstall.js +35 -35
  761. package/bin/setup-admin.js +195 -195
  762. package/bin/spaces-dev.js +247 -208
  763. package/bin/spaces-install.js +638 -599
  764. package/bin/spaces-reset-totp.js +50 -50
  765. package/bin/spaces-service.js +1020 -1020
  766. package/bin/spaces-setup.js +253 -253
  767. package/bin/spaces.js +788 -776
  768. package/bin/ssh-auth-keys.sh +68 -68
  769. package/bin/terminal-server.js +1807 -1683
  770. package/package.json +104 -103
  771. package/.next/standalone/.claude/settings.local.json +0 -55
  772. package/.next/standalone/.claude/spaces-env.json +0 -1
  773. package/.next/standalone/.next/server/chunks/[root-of-the-server]__eb8acb65._.js +0 -3
  774. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__e921fdfc._.js +0 -5
  775. package/.next/standalone/.next/server/chunks/ssr/_2230ad2d._.js +0 -3
  776. package/.next/standalone/.next/server/chunks/ssr/_5cf334fd._.js +0 -3
  777. package/.next/standalone/.next/server/chunks/ssr/_db0abd0a._.js +0 -3
  778. package/.next/standalone/.next/server/chunks/ssr/_db2fec84._.js +0 -3
  779. package/.next/standalone/.next/server/chunks/ssr/_f4e57187._.js +0 -3
  780. package/.next/standalone/.next/server/chunks/ssr/src_40fa36ce._.js +0 -7
  781. package/.next/standalone/.next/static/chunks/003e7aa1adfe577d.js +0 -1
  782. package/.next/standalone/.next/static/chunks/232d8aae4fefab70.js +0 -1
  783. package/.next/standalone/.next/static/chunks/5325351ef49cb65f.js +0 -1
  784. package/.next/standalone/.next/static/chunks/559735e598ca3cbb.js +0 -1
  785. package/.next/standalone/.next/static/chunks/5d5d7b0095dd52ae.js +0 -1
  786. package/.next/standalone/.next/static/chunks/7a7c0d9d875332a3.js +0 -1
  787. package/.next/standalone/.next/static/chunks/898f380eba90427a.js +0 -1
  788. package/.next/standalone/.next/static/chunks/95339e55722bb4ca.js +0 -5
  789. package/.next/standalone/.next/static/chunks/9cd594813c539df9.js +0 -1
  790. package/.next/standalone/.next/static/chunks/aae9e0fa485bd835.js +0 -5
  791. package/.next/standalone/.next/static/chunks/c1a95aebf6725f64.css +0 -3
  792. package/.next/standalone/.next/static/chunks/c515eb77d9410aa0.js +0 -5
  793. package/.next/standalone/.next/static/chunks/d9ae203a7f123546.js +0 -5
  794. package/.next/standalone/.next/static/chunks/f9f2628207848ac2.js +0 -1
  795. package/.next/standalone/.spaces/cortex-context.md +0 -70
  796. package/.next/standalone/node_modules/@img/sharp-win32-x64/lib/sharp-win32-x64.node +0 -0
  797. /package/.next/standalone/.next/static/{ncDe4k4gvD0788HAnq_3G → PcpzUspSK8QDdwzAJz8br}/_buildManifest.js +0 -0
  798. /package/.next/standalone/.next/static/{ncDe4k4gvD0788HAnq_3G → PcpzUspSK8QDdwzAJz8br}/_clientMiddlewareManifest.json +0 -0
  799. /package/.next/standalone/.next/static/{ncDe4k4gvD0788HAnq_3G → PcpzUspSK8QDdwzAJz8br}/_ssgManifest.js +0 -0
  800. /package/.next/standalone/node_modules/@img/{sharp-win32-x64 → sharp-libvips-linux-x64}/versions.json +0 -0
@@ -0,0 +1,1639 @@
1
+ # Spaces VR Phase 1: Shell + Static Rooms — Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Build a native Meta Quest 3 VR app that connects to a running Spaces server and renders workspace rooms with pane placeholders, navigable via eye tracking and hand tracking.
6
+
7
+ **Architecture:** Unity project (`C:\projects\spaces-vr`) with Meta XR SDK. HTTP client polls Spaces server API. Two scenes: Lobby (doors per workspace) and WorkspaceRoom (pane placeholders in semicircle). Eye tracking for gaze focus, hand tracking for grab/move/resize.
8
+
9
+ **Tech Stack:** Unity 2022.3 LTS, C#, Meta XR SDK v68+, Meta Interaction SDK, TextMeshPro, UnityWebRequest
10
+
11
+ **Spec:** `docs/superpowers/specs/2026-03-19-vr-phase1-shell-design.md`
12
+
13
+ **Important:** This is a Unity project. Many steps involve Unity Editor operations (creating scenes, configuring components, building prefabs) that cannot be fully automated via code. The plan provides exact C# scripts and documents which Editor steps are needed.
14
+
15
+ ---
16
+
17
+ ### Task 0: Server-Side — Add workspace_id Filter to Panes API
18
+
19
+ **Context:** The VR client needs to fetch panes for a specific workspace. The current `GET /api/panes` route only returns panes for the active workspace. We need to support `?workspace_id=N`.
20
+
21
+ **Files:**
22
+ - Modify: `C:\projects\spaces\src\app\api\panes\route.ts`
23
+
24
+ - [ ] **Step 1: Update the GET handler to accept workspace_id query param**
25
+
26
+ Replace the GET handler in `src/app/api/panes/route.ts`:
27
+
28
+ ```typescript
29
+ export async function GET(request: NextRequest) {
30
+ const user = getAuthUser(request);
31
+ return withUser(user, async () => {
32
+ await ensureInitialized();
33
+ const url = new URL(request.url);
34
+ const workspaceId = url.searchParams.get('workspace_id');
35
+ if (workspaceId) {
36
+ const { getPanesByWorkspace } = await import('@/lib/db/queries');
37
+ return NextResponse.json(getPanesByWorkspace(parseInt(workspaceId, 10)));
38
+ }
39
+ return NextResponse.json(getActivePanes());
40
+ });
41
+ }
42
+ ```
43
+
44
+ Add `getPanesByWorkspace` to the imports if not already imported:
45
+ ```typescript
46
+ import { getActivePanes, createPane, getPanesByWorkspace } from '@/lib/db/queries';
47
+ ```
48
+
49
+ - [ ] **Step 2: Verify the change**
50
+
51
+ Run: `npx tsc --noEmit 2>&1 | head -5`
52
+ Expected: No errors
53
+
54
+ - [ ] **Step 3: Commit**
55
+
56
+ ```bash
57
+ cd C:\projects\spaces
58
+ git add src/app/api/panes/route.ts
59
+ git commit -m "feat: add workspace_id filter to GET /api/panes for VR client"
60
+ ```
61
+
62
+ ---
63
+
64
+ ### Task 1: Unity Project Setup
65
+
66
+ **Context:** Create the Unity project and configure it for Quest 3 development. This task is mostly Unity Editor work.
67
+
68
+ - [ ] **Step 1: Create the Unity project**
69
+
70
+ Open Unity Hub → New Project → 3D (URP) template → Project name: `spaces-vr` → Location: `C:\projects\` → Create Project
71
+
72
+ - [ ] **Step 2: Initialize git**
73
+
74
+ ```bash
75
+ cd C:\projects\spaces-vr
76
+ git init
77
+ ```
78
+
79
+ Create `.gitignore`:
80
+
81
+ ```
82
+ # Unity
83
+ [Ll]ibrary/
84
+ [Tt]emp/
85
+ [Oo]bj/
86
+ [Bb]uild/
87
+ [Bb]uilds/
88
+ [Ll]ogs/
89
+ [Uu]ser[Ss]ettings/
90
+ *.csproj
91
+ *.unityproj
92
+ *.sln
93
+ *.suo
94
+ *.tmp
95
+ *.user
96
+ *.userprefs
97
+ *.pidb
98
+ *.booproj
99
+ *.svd
100
+ *.pdb
101
+ *.mdb
102
+ *.opendb
103
+ *.VC.db
104
+ *.pidb.meta
105
+ *.pdb.meta
106
+ *.mdb.meta
107
+ crashlytics-buildid.txt
108
+ sysinfo.txt
109
+ *.apk
110
+ *.aab
111
+ *.unitypackage
112
+ *.unitypackage.meta
113
+ ```
114
+
115
+ ```bash
116
+ git add .gitignore
117
+ git commit -m "chore: initialize spaces-vr Unity project"
118
+ ```
119
+
120
+ - [ ] **Step 3: Configure build settings for Quest 3**
121
+
122
+ In Unity Editor:
123
+ 1. File → Build Settings → Switch Platform to **Android**
124
+ 2. Player Settings:
125
+ - Other Settings → Scripting Backend: **IL2CPP**
126
+ - Other Settings → Target Architectures: check **ARM64** only
127
+ - Other Settings → Minimum API Level: **Android 12.0 (API 32)**
128
+ - Other Settings → Graphics APIs: **Vulkan** only (remove OpenGLES)
129
+ - Company Name: `Spaces`
130
+ - Product Name: `Spaces VR`
131
+ - Package Name: `com.spaces.vr`
132
+
133
+ - [ ] **Step 4: Install Meta XR SDK packages**
134
+
135
+ In Unity: Window → Package Manager → + → Add by name:
136
+ - `com.meta.xr.sdk.all` (Meta XR All-in-One SDK)
137
+
138
+ This pulls in OVR, Interaction SDK, and all Quest features.
139
+
140
+ After import, accept any "Fix All" prompts from the Meta Project Setup Tool.
141
+
142
+ - [ ] **Step 5: Configure OVR settings**
143
+
144
+ 1. In Hierarchy, delete the default Main Camera
145
+ 2. Add: right-click → XR → OVR Camera Rig
146
+ 3. On the OVRCameraRig, in OVRManager:
147
+ - Target Devices: Quest 3
148
+ - Tracking Origin Type: Floor Level
149
+ - Hand Tracking Support: Controllers and Hands
150
+ - Eye Tracking Support: Supported (check "Required" = false for fallback)
151
+ 4. Edit → Project Settings → XR Plug-in Management → check **Oculus**
152
+ 5. Edit → Project Settings → Meta XR → check: Eye Tracking, Hand Tracking
153
+
154
+ - [ ] **Step 6: Create folder structure**
155
+
156
+ In Unity Project window, create these folders:
157
+ ```
158
+ Assets/
159
+ ├── Scenes/
160
+ ├── Scripts/
161
+ │ ├── Core/
162
+ │ ├── Lobby/
163
+ │ ├── Room/
164
+ │ ├── Interaction/
165
+ │ └── UI/
166
+ ├── Prefabs/
167
+ ├── Materials/
168
+ └── Shaders/
169
+ ```
170
+
171
+ - [ ] **Step 7: Commit**
172
+
173
+ ```bash
174
+ cd C:\projects\spaces-vr
175
+ git add -A
176
+ git commit -m "feat: configure Unity project for Quest 3 with Meta XR SDK"
177
+ ```
178
+
179
+ ---
180
+
181
+ ### Task 2: Data Models and Server Connection
182
+
183
+ **Files:**
184
+ - Create: `Assets/Scripts/Core/WorkspaceData.cs`
185
+ - Create: `Assets/Scripts/Core/SpacesConnection.cs`
186
+ - Create: `Assets/Scripts/Core/SessionManager.cs`
187
+
188
+ - [ ] **Step 1: Create data models**
189
+
190
+ ```csharp
191
+ // Assets/Scripts/Core/WorkspaceData.cs
192
+ using System;
193
+ using System.Collections.Generic;
194
+
195
+ [Serializable]
196
+ public class WorkspaceData
197
+ {
198
+ public int id;
199
+ public string name;
200
+ public string color;
201
+ public int paneCount;
202
+ }
203
+
204
+ [Serializable]
205
+ public class PaneData
206
+ {
207
+ public string id;
208
+ public string agentType;
209
+ public string title;
210
+ }
211
+
212
+ [Serializable]
213
+ public class WorkspaceListResponse
214
+ {
215
+ public List<WorkspaceData> items;
216
+ }
217
+
218
+ // Helper to deserialize JSON array (Unity's JsonUtility doesn't handle top-level arrays)
219
+ public static class JsonArrayHelper
220
+ {
221
+ public static List<T> FromJson<T>(string json)
222
+ {
223
+ string wrapped = "{\"items\":" + json + "}";
224
+ var wrapper = UnityEngine.JsonUtility.FromJson<Wrapper<T>>(wrapped);
225
+ return wrapper.items;
226
+ }
227
+
228
+ [Serializable]
229
+ private class Wrapper<T>
230
+ {
231
+ public List<T> items;
232
+ }
233
+ }
234
+ ```
235
+
236
+ - [ ] **Step 2: Create session manager**
237
+
238
+ ```csharp
239
+ // Assets/Scripts/Core/SessionManager.cs
240
+ using UnityEngine;
241
+
242
+ public class SessionManager : MonoBehaviour
243
+ {
244
+ public static SessionManager Instance { get; private set; }
245
+
246
+ public string ServerUrl { get; set; } = "http://localhost:3457";
247
+ public string SessionCookie { get; private set; }
248
+ public bool IsAuthenticated => !string.IsNullOrEmpty(SessionCookie);
249
+
250
+ private void Awake()
251
+ {
252
+ if (Instance != null) { Destroy(gameObject); return; }
253
+ Instance = this;
254
+ DontDestroyOnLoad(gameObject);
255
+ }
256
+
257
+ public void SetCookie(string cookie)
258
+ {
259
+ SessionCookie = cookie;
260
+ }
261
+
262
+ public void ClearSession()
263
+ {
264
+ SessionCookie = null;
265
+ }
266
+ }
267
+ ```
268
+
269
+ - [ ] **Step 3: Create HTTP connection client**
270
+
271
+ ```csharp
272
+ // Assets/Scripts/Core/SpacesConnection.cs
273
+ using System;
274
+ using System.Collections;
275
+ using System.Collections.Generic;
276
+ using UnityEngine;
277
+ using UnityEngine.Networking;
278
+
279
+ public class SpacesConnection : MonoBehaviour
280
+ {
281
+ public static SpacesConnection Instance { get; private set; }
282
+
283
+ [SerializeField] private float workspacePollingInterval = 30f;
284
+ [SerializeField] private float panePollingInterval = 10f;
285
+ [SerializeField] private float requestTimeout = 5f;
286
+ [SerializeField] private int maxConsecutiveFailures = 3;
287
+
288
+ public event Action<List<WorkspaceData>> OnWorkspacesUpdated;
289
+ public event Action<List<PaneData>> OnPanesUpdated;
290
+ public event Action<bool> OnConnectionStateChanged;
291
+
292
+ private int consecutiveFailures;
293
+ private bool isConnected;
294
+
295
+ private void Awake()
296
+ {
297
+ if (Instance != null) { Destroy(gameObject); return; }
298
+ Instance = this;
299
+ DontDestroyOnLoad(gameObject);
300
+ }
301
+
302
+ private string BaseUrl => SessionManager.Instance.ServerUrl;
303
+
304
+ public IEnumerator FetchWorkspaces(Action<List<WorkspaceData>> callback)
305
+ {
306
+ using var req = UnityWebRequest.Get($"{BaseUrl}/api/workspaces");
307
+ req.timeout = (int)requestTimeout;
308
+ if (SessionManager.Instance.IsAuthenticated)
309
+ req.SetRequestHeader("Cookie", SessionManager.Instance.SessionCookie);
310
+
311
+ yield return req.SendWebRequest();
312
+
313
+ if (req.result == UnityWebRequest.Result.Success)
314
+ {
315
+ consecutiveFailures = 0;
316
+ if (!isConnected) { isConnected = true; OnConnectionStateChanged?.Invoke(true); }
317
+
318
+ var workspaces = JsonArrayHelper.FromJson<WorkspaceData>(req.downloadHandler.text);
319
+ callback?.Invoke(workspaces);
320
+ OnWorkspacesUpdated?.Invoke(workspaces);
321
+ }
322
+ else
323
+ {
324
+ HandleFailure();
325
+ callback?.Invoke(null);
326
+ }
327
+ }
328
+
329
+ public IEnumerator FetchPanes(int workspaceId, Action<List<PaneData>> callback)
330
+ {
331
+ using var req = UnityWebRequest.Get($"{BaseUrl}/api/panes?workspace_id={workspaceId}");
332
+ req.timeout = (int)requestTimeout;
333
+ if (SessionManager.Instance.IsAuthenticated)
334
+ req.SetRequestHeader("Cookie", SessionManager.Instance.SessionCookie);
335
+
336
+ yield return req.SendWebRequest();
337
+
338
+ if (req.result == UnityWebRequest.Result.Success)
339
+ {
340
+ consecutiveFailures = 0;
341
+ var panes = JsonArrayHelper.FromJson<PaneData>(req.downloadHandler.text);
342
+ callback?.Invoke(panes);
343
+ OnPanesUpdated?.Invoke(panes);
344
+ }
345
+ else
346
+ {
347
+ HandleFailure();
348
+ callback?.Invoke(null);
349
+ }
350
+ }
351
+
352
+ public IEnumerator TryConnect(Action<bool> callback)
353
+ {
354
+ // Try unauthenticated first
355
+ using var req = UnityWebRequest.Get($"{BaseUrl}/api/workspaces");
356
+ req.timeout = (int)requestTimeout;
357
+ yield return req.SendWebRequest();
358
+
359
+ if (req.result == UnityWebRequest.Result.Success)
360
+ {
361
+ isConnected = true;
362
+ OnConnectionStateChanged?.Invoke(true);
363
+ callback?.Invoke(true);
364
+ }
365
+ else if (req.responseCode == 401)
366
+ {
367
+ // Auth required — need login UI (Phase 1: show message)
368
+ Debug.Log("[SpacesVR] Server requires authentication");
369
+ callback?.Invoke(false);
370
+ }
371
+ else
372
+ {
373
+ HandleFailure();
374
+ callback?.Invoke(false);
375
+ }
376
+ }
377
+
378
+ private void HandleFailure()
379
+ {
380
+ consecutiveFailures++;
381
+ if (consecutiveFailures >= maxConsecutiveFailures && isConnected)
382
+ {
383
+ isConnected = false;
384
+ OnConnectionStateChanged?.Invoke(false);
385
+ }
386
+ }
387
+
388
+ // Coroutine-based polling helpers
389
+ public IEnumerator PollWorkspaces()
390
+ {
391
+ while (true)
392
+ {
393
+ yield return FetchWorkspaces(null);
394
+ yield return new WaitForSeconds(workspacePollingInterval);
395
+ }
396
+ }
397
+
398
+ public IEnumerator PollPanes(int workspaceId)
399
+ {
400
+ while (true)
401
+ {
402
+ yield return FetchPanes(workspaceId, null);
403
+ yield return new WaitForSeconds(panePollingInterval);
404
+ }
405
+ }
406
+ }
407
+ ```
408
+
409
+ - [ ] **Step 4: Commit**
410
+
411
+ ```bash
412
+ cd C:\projects\spaces-vr
413
+ git add Assets/Scripts/Core/
414
+ git commit -m "feat: add data models and HTTP connection client"
415
+ ```
416
+
417
+ ---
418
+
419
+ ### Task 3: Gaze Manager (Eye Tracking + Fallback)
420
+
421
+ **Files:**
422
+ - Create: `Assets/Scripts/Interaction/GazeManager.cs`
423
+ - Create: `Assets/Scripts/Interaction/GazeFocusHighlight.cs`
424
+
425
+ - [ ] **Step 1: Create GazeManager**
426
+
427
+ ```csharp
428
+ // Assets/Scripts/Interaction/GazeManager.cs
429
+ using UnityEngine;
430
+
431
+ public class GazeManager : MonoBehaviour
432
+ {
433
+ public static GazeManager Instance { get; private set; }
434
+
435
+ [SerializeField] private float focusDelay = 0.3f; // 300ms sustained gaze
436
+ [SerializeField] private float unfocusDelay = 0.2f;
437
+ [SerializeField] private float maxRayDistance = 20f;
438
+ [SerializeField] private LayerMask gazeLayerMask = ~0;
439
+
440
+ public GameObject FocusedObject { get; private set; }
441
+ public RaycastHit? LastHit { get; private set; }
442
+ public event System.Action<GameObject> OnFocusChanged;
443
+
444
+ private OVREyeGaze leftEyeGaze;
445
+ private OVREyeGaze rightEyeGaze;
446
+ private bool useEyeTracking;
447
+ private Transform centerEye;
448
+
449
+ private GameObject candidateObject;
450
+ private float candidateTime;
451
+ private float unfocusTime;
452
+
453
+ private void Awake()
454
+ {
455
+ if (Instance != null) { Destroy(gameObject); return; }
456
+ Instance = this;
457
+ }
458
+
459
+ private void Start()
460
+ {
461
+ // Try to find eye tracking components
462
+ var eyeGazes = FindObjectsOfType<OVREyeGaze>();
463
+ foreach (var eg in eyeGazes)
464
+ {
465
+ if (eg.Eye == OVREyeGaze.EyeId.Combined || eg.Eye == OVREyeGaze.EyeId.Left)
466
+ leftEyeGaze = eg;
467
+ }
468
+
469
+ // Find center eye anchor for fallback
470
+ var rig = FindObjectOfType<OVRCameraRig>();
471
+ if (rig != null) centerEye = rig.centerEyeAnchor;
472
+
473
+ // Check if eye tracking is available
474
+ useEyeTracking = OVRPlugin.eyeTrackingEnabled;
475
+ if (!useEyeTracking)
476
+ Debug.Log("[GazeManager] Eye tracking unavailable, using head-gaze fallback");
477
+ }
478
+
479
+ private void Update()
480
+ {
481
+ Ray gazeRay = GetGazeRay();
482
+ RaycastHit hit;
483
+ bool didHit = Physics.Raycast(gazeRay, out hit, maxRayDistance, gazeLayerMask);
484
+
485
+ if (didHit)
486
+ {
487
+ LastHit = hit;
488
+ var hitObj = hit.collider.gameObject;
489
+
490
+ if (hitObj == FocusedObject)
491
+ {
492
+ // Still looking at focused object — reset unfocus timer
493
+ unfocusTime = 0f;
494
+ }
495
+ else if (hitObj == candidateObject)
496
+ {
497
+ // Still looking at candidate — accumulate focus time
498
+ candidateTime += Time.deltaTime;
499
+ if (candidateTime >= focusDelay)
500
+ {
501
+ SetFocus(hitObj);
502
+ }
503
+ }
504
+ else
505
+ {
506
+ // New candidate
507
+ candidateObject = hitObj;
508
+ candidateTime = 0f;
509
+ }
510
+ }
511
+ else
512
+ {
513
+ LastHit = null;
514
+ candidateObject = null;
515
+ candidateTime = 0f;
516
+
517
+ if (FocusedObject != null)
518
+ {
519
+ unfocusTime += Time.deltaTime;
520
+ if (unfocusTime >= unfocusDelay)
521
+ {
522
+ SetFocus(null);
523
+ }
524
+ }
525
+ }
526
+ }
527
+
528
+ private Ray GetGazeRay()
529
+ {
530
+ if (useEyeTracking && leftEyeGaze != null)
531
+ {
532
+ return new Ray(leftEyeGaze.transform.position, leftEyeGaze.transform.forward);
533
+ }
534
+
535
+ // Head-gaze fallback
536
+ if (centerEye != null)
537
+ {
538
+ return new Ray(centerEye.position, centerEye.forward);
539
+ }
540
+
541
+ return new Ray(Camera.main.transform.position, Camera.main.transform.forward);
542
+ }
543
+
544
+ private void SetFocus(GameObject obj)
545
+ {
546
+ if (FocusedObject == obj) return;
547
+
548
+ // Notify old object
549
+ if (FocusedObject != null)
550
+ {
551
+ var highlight = FocusedObject.GetComponent<GazeFocusHighlight>();
552
+ if (highlight != null) highlight.OnUnfocus();
553
+ }
554
+
555
+ FocusedObject = obj;
556
+ unfocusTime = 0f;
557
+ candidateObject = null;
558
+ candidateTime = 0f;
559
+
560
+ // Notify new object
561
+ if (FocusedObject != null)
562
+ {
563
+ var highlight = FocusedObject.GetComponent<GazeFocusHighlight>();
564
+ if (highlight != null) highlight.OnFocus();
565
+ }
566
+
567
+ OnFocusChanged?.Invoke(FocusedObject);
568
+ }
569
+ }
570
+ ```
571
+
572
+ - [ ] **Step 2: Create GazeFocusHighlight**
573
+
574
+ ```csharp
575
+ // Assets/Scripts/Interaction/GazeFocusHighlight.cs
576
+ using UnityEngine;
577
+
578
+ public class GazeFocusHighlight : MonoBehaviour
579
+ {
580
+ [SerializeField] private float highlightScale = 1.02f;
581
+ [SerializeField] private float transitionSpeed = 8f;
582
+ [SerializeField] private Color highlightColor = new Color(0.5f, 0.3f, 1f, 0.3f); // purple glow
583
+
584
+ private Vector3 originalScale;
585
+ private bool isFocused;
586
+ private float focusLerp; // 0 = unfocused, 1 = focused
587
+ private Renderer[] renderers;
588
+ private MaterialPropertyBlock propBlock;
589
+
590
+ private void Awake()
591
+ {
592
+ originalScale = transform.localScale;
593
+ renderers = GetComponentsInChildren<Renderer>();
594
+ propBlock = new MaterialPropertyBlock();
595
+ }
596
+
597
+ private void Update()
598
+ {
599
+ float target = isFocused ? 1f : 0f;
600
+ focusLerp = Mathf.MoveTowards(focusLerp, target, Time.deltaTime * transitionSpeed);
601
+
602
+ // Scale
603
+ transform.localScale = Vector3.Lerp(originalScale, originalScale * highlightScale, focusLerp);
604
+
605
+ // Emission glow
606
+ foreach (var r in renderers)
607
+ {
608
+ r.GetPropertyBlock(propBlock);
609
+ propBlock.SetColor("_EmissionColor", highlightColor * focusLerp);
610
+ r.SetPropertyBlock(propBlock);
611
+ }
612
+ }
613
+
614
+ public void OnFocus()
615
+ {
616
+ isFocused = true;
617
+ }
618
+
619
+ public void OnUnfocus()
620
+ {
621
+ isFocused = false;
622
+ }
623
+ }
624
+ ```
625
+
626
+ - [ ] **Step 3: Commit**
627
+
628
+ ```bash
629
+ cd C:\projects\spaces-vr
630
+ git add Assets/Scripts/Interaction/GazeManager.cs Assets/Scripts/Interaction/GazeFocusHighlight.cs
631
+ git commit -m "feat: add gaze manager with eye tracking and head-gaze fallback"
632
+ ```
633
+
634
+ ---
635
+
636
+ ### Task 4: Pane Layout Math and Pane Surface
637
+
638
+ **Files:**
639
+ - Create: `Assets/Scripts/Room/PaneLayout.cs`
640
+ - Create: `Assets/Scripts/Room/PaneSurface.cs`
641
+ - Create: `Assets/Scripts/UI/PaneHeader.cs`
642
+ - Create: `Assets/Scripts/UI/StatusIndicator.cs`
643
+
644
+ - [ ] **Step 1: Create PaneLayout (semicircle positioning)**
645
+
646
+ ```csharp
647
+ // Assets/Scripts/Room/PaneLayout.cs
648
+ using UnityEngine;
649
+
650
+ public static class PaneLayout
651
+ {
652
+ public static Vector3[] ComputePositions(int paneCount, float radius = 2f, float eyeHeight = 1.6f)
653
+ {
654
+ if (paneCount <= 0) return new Vector3[0];
655
+
656
+ var positions = new Vector3[paneCount];
657
+
658
+ if (paneCount == 1)
659
+ {
660
+ positions[0] = new Vector3(0, eyeHeight, radius);
661
+ return positions;
662
+ }
663
+
664
+ // Arc grows with pane count
665
+ float totalArcDeg;
666
+ if (paneCount <= 2) totalArcDeg = 40f;
667
+ else if (paneCount <= 4) totalArcDeg = 80f;
668
+ else if (paneCount <= 6) totalArcDeg = 120f;
669
+ else totalArcDeg = 160f;
670
+
671
+ float startAngle = 90f - totalArcDeg / 2f; // center the arc at 90° (forward)
672
+ float step = totalArcDeg / (paneCount - 1);
673
+
674
+ for (int i = 0; i < paneCount; i++)
675
+ {
676
+ float angleDeg = startAngle + step * i;
677
+ float angleRad = angleDeg * Mathf.Deg2Rad;
678
+ float x = Mathf.Cos(angleRad) * radius;
679
+ float z = Mathf.Sin(angleRad) * radius;
680
+ positions[i] = new Vector3(x, eyeHeight, z);
681
+ }
682
+
683
+ return positions;
684
+ }
685
+
686
+ public static Quaternion ComputeRotation(Vector3 panePosition)
687
+ {
688
+ // Face inward toward room center (Y-axis billboard only)
689
+ Vector3 toCenter = -new Vector3(panePosition.x, 0, panePosition.z).normalized;
690
+ return Quaternion.LookRotation(toCenter, Vector3.up);
691
+ }
692
+ }
693
+ ```
694
+
695
+ - [ ] **Step 2: Create StatusIndicator**
696
+
697
+ ```csharp
698
+ // Assets/Scripts/UI/StatusIndicator.cs
699
+ using UnityEngine;
700
+
701
+ public enum PaneStatus
702
+ {
703
+ Idle, // gray
704
+ Active, // green
705
+ Waiting, // amber
706
+ Error // red
707
+ }
708
+
709
+ public class StatusIndicator : MonoBehaviour
710
+ {
711
+ [SerializeField] private Renderer dotRenderer;
712
+
713
+ private static readonly Color IdleColor = new Color(0.4f, 0.4f, 0.4f);
714
+ private static readonly Color ActiveColor = new Color(0.2f, 0.8f, 0.2f);
715
+ private static readonly Color WaitingColor = new Color(0.9f, 0.7f, 0.1f);
716
+ private static readonly Color ErrorColor = new Color(0.9f, 0.2f, 0.2f);
717
+
718
+ private MaterialPropertyBlock propBlock;
719
+
720
+ private void Awake()
721
+ {
722
+ propBlock = new MaterialPropertyBlock();
723
+ }
724
+
725
+ public void SetStatus(PaneStatus status)
726
+ {
727
+ Color c = status switch
728
+ {
729
+ PaneStatus.Active => ActiveColor,
730
+ PaneStatus.Waiting => WaitingColor,
731
+ PaneStatus.Error => ErrorColor,
732
+ _ => IdleColor,
733
+ };
734
+
735
+ if (dotRenderer != null)
736
+ {
737
+ dotRenderer.GetPropertyBlock(propBlock);
738
+ propBlock.SetColor("_Color", c);
739
+ propBlock.SetColor("_EmissionColor", c * 0.5f);
740
+ dotRenderer.SetPropertyBlock(propBlock);
741
+ }
742
+ }
743
+ }
744
+ ```
745
+
746
+ - [ ] **Step 3: Create PaneHeader**
747
+
748
+ ```csharp
749
+ // Assets/Scripts/UI/PaneHeader.cs
750
+ using TMPro;
751
+ using UnityEngine;
752
+
753
+ public class PaneHeader : MonoBehaviour
754
+ {
755
+ [SerializeField] private TextMeshPro titleText;
756
+ [SerializeField] private TextMeshPro subtitleText;
757
+ [SerializeField] private Renderer accentBar;
758
+
759
+ private MaterialPropertyBlock propBlock;
760
+
761
+ private void Awake()
762
+ {
763
+ propBlock = new MaterialPropertyBlock();
764
+ }
765
+
766
+ public void SetInfo(string agentType, string title, Color workspaceColor)
767
+ {
768
+ if (titleText != null)
769
+ titleText.text = string.IsNullOrEmpty(title) ? agentType : title;
770
+
771
+ if (subtitleText != null)
772
+ subtitleText.text = agentType;
773
+
774
+ if (accentBar != null)
775
+ {
776
+ accentBar.GetPropertyBlock(propBlock);
777
+ propBlock.SetColor("_Color", workspaceColor);
778
+ accentBar.SetPropertyBlock(propBlock);
779
+ }
780
+ }
781
+ }
782
+ ```
783
+
784
+ - [ ] **Step 4: Create PaneSurface**
785
+
786
+ ```csharp
787
+ // Assets/Scripts/Room/PaneSurface.cs
788
+ using TMPro;
789
+ using UnityEngine;
790
+
791
+ [RequireComponent(typeof(BoxCollider))]
792
+ [RequireComponent(typeof(GazeFocusHighlight))]
793
+ public class PaneSurface : MonoBehaviour
794
+ {
795
+ [SerializeField] private TextMeshPro contentText;
796
+ [SerializeField] private PaneHeader header;
797
+ [SerializeField] private StatusIndicator statusIndicator;
798
+
799
+ public string PaneId { get; private set; }
800
+ public PaneData Data { get; private set; }
801
+
802
+ private static readonly Vector3 DefaultSize = new Vector3(1.2f, 0.8f, 0.01f);
803
+ private static readonly Vector3 MinSize = new Vector3(0.6f, 0.4f, 0.01f);
804
+ private static readonly Vector3 MaxSize = new Vector3(2.4f, 1.6f, 0.01f);
805
+
806
+ public void Initialize(PaneData data, Color workspaceColor)
807
+ {
808
+ Data = data;
809
+ PaneId = data.id;
810
+
811
+ header?.SetInfo(data.agentType, data.title, workspaceColor);
812
+ statusIndicator?.SetStatus(PaneStatus.Idle); // Phase 1: always idle
813
+
814
+ if (contentText != null)
815
+ contentText.text = $"<color=#666>{data.agentType}\nConnecting...</color>";
816
+ }
817
+
818
+ public void SetSize(Vector3 newSize)
819
+ {
820
+ newSize.x = Mathf.Clamp(newSize.x, MinSize.x, MaxSize.x);
821
+ newSize.y = Mathf.Clamp(newSize.y, MinSize.y, MaxSize.y);
822
+ newSize.z = DefaultSize.z;
823
+ transform.localScale = newSize;
824
+ }
825
+ }
826
+ ```
827
+
828
+ - [ ] **Step 5: Commit**
829
+
830
+ ```bash
831
+ cd C:\projects\spaces-vr
832
+ git add Assets/Scripts/Room/ Assets/Scripts/UI/
833
+ git commit -m "feat: add pane layout, surface, header, and status indicator"
834
+ ```
835
+
836
+ ---
837
+
838
+ ### Task 5: Hand Tracking — Grab and Resize
839
+
840
+ **Files:**
841
+ - Create: `Assets/Scripts/Interaction/HandGrabHandler.cs`
842
+
843
+ - [ ] **Step 1: Create HandGrabHandler**
844
+
845
+ ```csharp
846
+ // Assets/Scripts/Interaction/HandGrabHandler.cs
847
+ using UnityEngine;
848
+
849
+ public class HandGrabHandler : MonoBehaviour
850
+ {
851
+ [SerializeField] private OVRHand leftHand;
852
+ [SerializeField] private OVRHand rightHand;
853
+ [SerializeField] private float grabDistance = 0.15f;
854
+ [SerializeField] private float smoothing = 15f;
855
+ [SerializeField] private float minDistFromCenter = 1f;
856
+ [SerializeField] private float maxDistFromCenter = 4f;
857
+ [SerializeField] private float minHeight = 0.5f;
858
+ [SerializeField] private float maxHeight = 3f;
859
+
860
+ private PaneSurface grabbedPane;
861
+ private Transform grabbingHand;
862
+ private Vector3 grabOffset;
863
+
864
+ // Two-hand resize state
865
+ private bool isResizing;
866
+ private float initialPinchDistance;
867
+ private Vector3 initialPaneScale;
868
+
869
+ private void Update()
870
+ {
871
+ bool leftPinch = leftHand != null && leftHand.GetFingerIsPinching(OVRHand.HandFinger.Index);
872
+ bool rightPinch = rightHand != null && rightHand.GetFingerIsPinching(OVRHand.HandFinger.Index);
873
+
874
+ // Two-hand resize
875
+ if (leftPinch && rightPinch && grabbedPane != null)
876
+ {
877
+ HandleResize();
878
+ return;
879
+ }
880
+
881
+ if (isResizing)
882
+ {
883
+ isResizing = false;
884
+ }
885
+
886
+ // Single-hand grab
887
+ if (!leftPinch && !rightPinch)
888
+ {
889
+ grabbedPane = null;
890
+ grabbingHand = null;
891
+ return;
892
+ }
893
+
894
+ Transform activeHand = leftPinch ? leftHand.transform : rightHand.transform;
895
+
896
+ if (grabbedPane == null)
897
+ {
898
+ // Try to grab
899
+ TryGrab(activeHand);
900
+ }
901
+ else if (grabbingHand == activeHand)
902
+ {
903
+ // Move grabbed pane
904
+ MoveGrabbedPane();
905
+ }
906
+ }
907
+
908
+ private void TryGrab(Transform hand)
909
+ {
910
+ Collider[] hits = Physics.OverlapSphere(hand.position, grabDistance);
911
+ foreach (var hit in hits)
912
+ {
913
+ var pane = hit.GetComponent<PaneSurface>();
914
+ if (pane != null)
915
+ {
916
+ grabbedPane = pane;
917
+ grabbingHand = hand;
918
+ grabOffset = pane.transform.position - hand.position;
919
+ return;
920
+ }
921
+ }
922
+ }
923
+
924
+ private void MoveGrabbedPane()
925
+ {
926
+ Vector3 targetPos = grabbingHand.position + grabOffset;
927
+
928
+ // Constrain position
929
+ float dist = new Vector2(targetPos.x, targetPos.z).magnitude;
930
+ if (dist < minDistFromCenter || dist > maxDistFromCenter)
931
+ {
932
+ Vector2 dir = new Vector2(targetPos.x, targetPos.z).normalized;
933
+ dist = Mathf.Clamp(dist, minDistFromCenter, maxDistFromCenter);
934
+ targetPos.x = dir.x * dist;
935
+ targetPos.z = dir.y * dist;
936
+ }
937
+ targetPos.y = Mathf.Clamp(targetPos.y, minHeight, maxHeight);
938
+
939
+ grabbedPane.transform.position = Vector3.Lerp(
940
+ grabbedPane.transform.position, targetPos, Time.deltaTime * smoothing);
941
+
942
+ // Re-orient to face center
943
+ grabbedPane.transform.rotation = PaneLayout.ComputeRotation(grabbedPane.transform.position);
944
+ }
945
+
946
+ private void HandleResize()
947
+ {
948
+ float currentDist = Vector3.Distance(leftHand.transform.position, rightHand.transform.position);
949
+
950
+ if (!isResizing)
951
+ {
952
+ isResizing = true;
953
+ initialPinchDistance = currentDist;
954
+ initialPaneScale = grabbedPane.transform.localScale;
955
+ return;
956
+ }
957
+
958
+ float scaleFactor = currentDist / initialPinchDistance;
959
+ Vector3 newScale = initialPaneScale * scaleFactor;
960
+ grabbedPane.SetSize(newScale);
961
+ }
962
+ }
963
+ ```
964
+
965
+ - [ ] **Step 2: Commit**
966
+
967
+ ```bash
968
+ cd C:\projects\spaces-vr
969
+ git add Assets/Scripts/Interaction/HandGrabHandler.cs
970
+ git commit -m "feat: add hand tracking grab-to-move and pinch-to-resize"
971
+ ```
972
+
973
+ ---
974
+
975
+ ### Task 6: Lobby Scene — Door Spawning and Navigation
976
+
977
+ **Files:**
978
+ - Create: `Assets/Scripts/Lobby/LobbyManager.cs`
979
+ - Create: `Assets/Scripts/Lobby/WorkspaceDoor.cs`
980
+ - Create: `Assets/Scripts/Lobby/DoorInteraction.cs`
981
+
982
+ - [ ] **Step 1: Create WorkspaceDoor**
983
+
984
+ ```csharp
985
+ // Assets/Scripts/Lobby/WorkspaceDoor.cs
986
+ using TMPro;
987
+ using UnityEngine;
988
+
989
+ public class WorkspaceDoor : MonoBehaviour
990
+ {
991
+ [SerializeField] private TextMeshPro nameLabel;
992
+ [SerializeField] private TextMeshPro infoLabel;
993
+ [SerializeField] private Renderer frameRenderer;
994
+ [SerializeField] private Renderer glowRenderer;
995
+
996
+ public WorkspaceData Data { get; private set; }
997
+
998
+ private MaterialPropertyBlock propBlock;
999
+
1000
+ private void Awake()
1001
+ {
1002
+ propBlock = new MaterialPropertyBlock();
1003
+ }
1004
+
1005
+ public void Initialize(WorkspaceData data)
1006
+ {
1007
+ Data = data;
1008
+
1009
+ if (nameLabel != null) nameLabel.text = data.name;
1010
+ if (infoLabel != null) infoLabel.text = $"{data.paneCount} pane{(data.paneCount != 1 ? "s" : "")}";
1011
+
1012
+ Color wsColor;
1013
+ if (!ColorUtility.TryParseHtmlString(data.color, out wsColor))
1014
+ wsColor = new Color(0.4f, 0.3f, 0.9f); // default purple
1015
+
1016
+ if (frameRenderer != null)
1017
+ {
1018
+ frameRenderer.GetPropertyBlock(propBlock);
1019
+ propBlock.SetColor("_Color", wsColor);
1020
+ frameRenderer.SetPropertyBlock(propBlock);
1021
+ }
1022
+
1023
+ if (glowRenderer != null)
1024
+ {
1025
+ glowRenderer.GetPropertyBlock(propBlock);
1026
+ propBlock.SetColor("_EmissionColor", wsColor * 0.3f);
1027
+ glowRenderer.SetPropertyBlock(propBlock);
1028
+ }
1029
+ }
1030
+ }
1031
+ ```
1032
+
1033
+ - [ ] **Step 2: Create DoorInteraction (gaze-to-enter)**
1034
+
1035
+ ```csharp
1036
+ // Assets/Scripts/Lobby/DoorInteraction.cs
1037
+ using UnityEngine;
1038
+
1039
+ [RequireComponent(typeof(GazeFocusHighlight))]
1040
+ public class DoorInteraction : MonoBehaviour
1041
+ {
1042
+ [SerializeField] private float confirmTime = 1.5f;
1043
+ [SerializeField] private Renderer confirmRing; // a progress ring UI element
1044
+
1045
+ private float gazeTimer;
1046
+ private bool isGazed;
1047
+ private WorkspaceDoor door;
1048
+ private MaterialPropertyBlock propBlock;
1049
+
1050
+ private void Awake()
1051
+ {
1052
+ door = GetComponent<WorkspaceDoor>();
1053
+ propBlock = new MaterialPropertyBlock();
1054
+ }
1055
+
1056
+ private void OnEnable()
1057
+ {
1058
+ if (GazeManager.Instance != null)
1059
+ GazeManager.Instance.OnFocusChanged += HandleFocusChanged;
1060
+ }
1061
+
1062
+ private void OnDisable()
1063
+ {
1064
+ if (GazeManager.Instance != null)
1065
+ GazeManager.Instance.OnFocusChanged -= HandleFocusChanged;
1066
+ }
1067
+
1068
+ private void HandleFocusChanged(GameObject focused)
1069
+ {
1070
+ isGazed = (focused == gameObject);
1071
+ if (!isGazed)
1072
+ {
1073
+ gazeTimer = 0f;
1074
+ UpdateRing(0f);
1075
+ }
1076
+ }
1077
+
1078
+ private void Update()
1079
+ {
1080
+ if (!isGazed) return;
1081
+
1082
+ gazeTimer += Time.deltaTime;
1083
+ UpdateRing(gazeTimer / confirmTime);
1084
+
1085
+ if (gazeTimer >= confirmTime)
1086
+ {
1087
+ gazeTimer = 0f;
1088
+ EnterWorkspace();
1089
+ }
1090
+ }
1091
+
1092
+ private void UpdateRing(float progress)
1093
+ {
1094
+ if (confirmRing != null)
1095
+ {
1096
+ confirmRing.gameObject.SetActive(progress > 0f);
1097
+ confirmRing.GetPropertyBlock(propBlock);
1098
+ propBlock.SetFloat("_Progress", Mathf.Clamp01(progress));
1099
+ confirmRing.SetPropertyBlock(propBlock);
1100
+ }
1101
+ }
1102
+
1103
+ private void EnterWorkspace()
1104
+ {
1105
+ if (door?.Data != null)
1106
+ {
1107
+ LobbyManager.Instance?.EnterWorkspace(door.Data);
1108
+ }
1109
+ }
1110
+ }
1111
+ ```
1112
+
1113
+ - [ ] **Step 3: Create LobbyManager**
1114
+
1115
+ ```csharp
1116
+ // Assets/Scripts/Lobby/LobbyManager.cs
1117
+ using System.Collections;
1118
+ using System.Collections.Generic;
1119
+ using UnityEngine;
1120
+
1121
+ public class LobbyManager : MonoBehaviour
1122
+ {
1123
+ public static LobbyManager Instance { get; private set; }
1124
+
1125
+ [SerializeField] private GameObject doorPrefab;
1126
+ [SerializeField] private float doorRadius = 4f;
1127
+ [SerializeField] private float doorHeight = 0f;
1128
+ [SerializeField] private GameObject offlinePanel;
1129
+ [SerializeField] private RoomManager roomManager;
1130
+
1131
+ private List<GameObject> spawnedDoors = new List<GameObject>();
1132
+ private Coroutine pollCoroutine;
1133
+
1134
+ private void Awake()
1135
+ {
1136
+ Instance = this;
1137
+ }
1138
+
1139
+ private IEnumerator Start()
1140
+ {
1141
+ // Initial connection attempt
1142
+ bool connected = false;
1143
+ yield return SpacesConnection.Instance.TryConnect(result => connected = result);
1144
+
1145
+ if (connected)
1146
+ {
1147
+ yield return SpacesConnection.Instance.FetchWorkspaces(SpawnDoors);
1148
+ pollCoroutine = StartCoroutine(SpacesConnection.Instance.PollWorkspaces());
1149
+ }
1150
+ else
1151
+ {
1152
+ ShowOffline();
1153
+ }
1154
+
1155
+ SpacesConnection.Instance.OnConnectionStateChanged += OnConnectionChanged;
1156
+ SpacesConnection.Instance.OnWorkspacesUpdated += SpawnDoors;
1157
+ }
1158
+
1159
+ private void OnDestroy()
1160
+ {
1161
+ if (SpacesConnection.Instance != null)
1162
+ {
1163
+ SpacesConnection.Instance.OnConnectionStateChanged -= OnConnectionChanged;
1164
+ SpacesConnection.Instance.OnWorkspacesUpdated -= SpawnDoors;
1165
+ }
1166
+ }
1167
+
1168
+ private void OnConnectionChanged(bool connected)
1169
+ {
1170
+ if (connected)
1171
+ {
1172
+ HideOffline();
1173
+ if (pollCoroutine == null)
1174
+ pollCoroutine = StartCoroutine(SpacesConnection.Instance.PollWorkspaces());
1175
+ }
1176
+ else
1177
+ {
1178
+ ShowOffline();
1179
+ }
1180
+ }
1181
+
1182
+ private void SpawnDoors(List<WorkspaceData> workspaces)
1183
+ {
1184
+ if (workspaces == null) return;
1185
+
1186
+ // Clear existing doors
1187
+ foreach (var d in spawnedDoors) Destroy(d);
1188
+ spawnedDoors.Clear();
1189
+
1190
+ if (workspaces.Count == 0) return;
1191
+
1192
+ float angleStep = 360f / workspaces.Count;
1193
+
1194
+ for (int i = 0; i < workspaces.Count; i++)
1195
+ {
1196
+ float angleDeg = angleStep * i;
1197
+ float angleRad = angleDeg * Mathf.Deg2Rad;
1198
+
1199
+ Vector3 pos = new Vector3(
1200
+ Mathf.Sin(angleRad) * doorRadius,
1201
+ doorHeight,
1202
+ Mathf.Cos(angleRad) * doorRadius
1203
+ );
1204
+
1205
+ Quaternion rot = Quaternion.LookRotation(-pos.normalized, Vector3.up);
1206
+
1207
+ var doorObj = Instantiate(doorPrefab, pos, rot, transform);
1208
+ var door = doorObj.GetComponent<WorkspaceDoor>();
1209
+ door?.Initialize(workspaces[i]);
1210
+
1211
+ spawnedDoors.Add(doorObj);
1212
+ }
1213
+ }
1214
+
1215
+ public void EnterWorkspace(WorkspaceData workspace)
1216
+ {
1217
+ // Stop lobby polling
1218
+ if (pollCoroutine != null)
1219
+ {
1220
+ StopCoroutine(pollCoroutine);
1221
+ pollCoroutine = null;
1222
+ }
1223
+
1224
+ // Hide lobby objects
1225
+ foreach (var d in spawnedDoors) d.SetActive(false);
1226
+
1227
+ // Activate room
1228
+ roomManager?.LoadWorkspace(workspace);
1229
+ }
1230
+
1231
+ public void ReturnToLobby()
1232
+ {
1233
+ roomManager?.UnloadWorkspace();
1234
+ foreach (var d in spawnedDoors) d.SetActive(true);
1235
+ pollCoroutine = StartCoroutine(SpacesConnection.Instance.PollWorkspaces());
1236
+ }
1237
+
1238
+ private void ShowOffline()
1239
+ {
1240
+ if (offlinePanel != null) offlinePanel.SetActive(true);
1241
+ }
1242
+
1243
+ private void HideOffline()
1244
+ {
1245
+ if (offlinePanel != null) offlinePanel.SetActive(false);
1246
+ }
1247
+ }
1248
+ ```
1249
+
1250
+ - [ ] **Step 4: Commit**
1251
+
1252
+ ```bash
1253
+ cd C:\projects\spaces-vr
1254
+ git add Assets/Scripts/Lobby/
1255
+ git commit -m "feat: add lobby with workspace doors and gaze-to-enter navigation"
1256
+ ```
1257
+
1258
+ ---
1259
+
1260
+ ### Task 7: Room Manager — Pane Spawning and Room Scaling
1261
+
1262
+ **Files:**
1263
+ - Create: `Assets/Scripts/Room/RoomManager.cs`
1264
+
1265
+ - [ ] **Step 1: Create RoomManager**
1266
+
1267
+ ```csharp
1268
+ // Assets/Scripts/Room/RoomManager.cs
1269
+ using System.Collections;
1270
+ using System.Collections.Generic;
1271
+ using UnityEngine;
1272
+
1273
+ public class RoomManager : MonoBehaviour
1274
+ {
1275
+ [SerializeField] private GameObject panePrefab;
1276
+ [SerializeField] private Light roomLight;
1277
+ [SerializeField] private Transform roomContainer;
1278
+
1279
+ private List<GameObject> spawnedPanes = new List<GameObject>();
1280
+ private WorkspaceData currentWorkspace;
1281
+ private Coroutine pollCoroutine;
1282
+
1283
+ // Room scaling light presets
1284
+ private static readonly Color WarmLight = new Color(1f, 0.9f, 0.8f);
1285
+ private static readonly Color NeutralLight = new Color(0.9f, 0.9f, 1f);
1286
+ private static readonly Color CoolLight = new Color(0.7f, 0.8f, 1f);
1287
+
1288
+ public void LoadWorkspace(WorkspaceData workspace)
1289
+ {
1290
+ currentWorkspace = workspace;
1291
+ if (roomContainer != null) roomContainer.gameObject.SetActive(true);
1292
+
1293
+ StartCoroutine(FetchAndSpawnPanes());
1294
+ }
1295
+
1296
+ public void UnloadWorkspace()
1297
+ {
1298
+ if (pollCoroutine != null)
1299
+ {
1300
+ StopCoroutine(pollCoroutine);
1301
+ pollCoroutine = null;
1302
+ }
1303
+
1304
+ foreach (var p in spawnedPanes) Destroy(p);
1305
+ spawnedPanes.Clear();
1306
+
1307
+ currentWorkspace = null;
1308
+ if (roomContainer != null) roomContainer.gameObject.SetActive(false);
1309
+ }
1310
+
1311
+ private IEnumerator FetchAndSpawnPanes()
1312
+ {
1313
+ yield return SpacesConnection.Instance.FetchPanes(currentWorkspace.id, SpawnPanes);
1314
+ pollCoroutine = StartCoroutine(SpacesConnection.Instance.PollPanes(currentWorkspace.id));
1315
+ }
1316
+
1317
+ private void SpawnPanes(List<PaneData> panes)
1318
+ {
1319
+ if (panes == null) return;
1320
+
1321
+ // Clear existing
1322
+ foreach (var p in spawnedPanes) Destroy(p);
1323
+ spawnedPanes.Clear();
1324
+
1325
+ // Compute positions
1326
+ var positions = PaneLayout.ComputePositions(panes.Count);
1327
+
1328
+ // Parse workspace color
1329
+ Color wsColor;
1330
+ if (!ColorUtility.TryParseHtmlString(currentWorkspace.color, out wsColor))
1331
+ wsColor = new Color(0.4f, 0.3f, 0.9f);
1332
+
1333
+ // Scale room lighting based on pane count
1334
+ SetRoomLighting(panes.Count);
1335
+
1336
+ // Spawn panes
1337
+ for (int i = 0; i < panes.Count; i++)
1338
+ {
1339
+ Vector3 pos = positions[i];
1340
+ Quaternion rot = PaneLayout.ComputeRotation(pos);
1341
+
1342
+ Transform parent = roomContainer != null ? roomContainer : transform;
1343
+ var paneObj = Instantiate(panePrefab, pos, rot, parent);
1344
+ var surface = paneObj.GetComponent<PaneSurface>();
1345
+ surface?.Initialize(panes[i], wsColor);
1346
+
1347
+ spawnedPanes.Add(paneObj);
1348
+ }
1349
+ }
1350
+
1351
+ private void SetRoomLighting(int paneCount)
1352
+ {
1353
+ if (roomLight == null) return;
1354
+
1355
+ if (paneCount <= 2)
1356
+ {
1357
+ roomLight.color = WarmLight;
1358
+ roomLight.intensity = 0.6f;
1359
+ }
1360
+ else if (paneCount <= 5)
1361
+ {
1362
+ roomLight.color = NeutralLight;
1363
+ roomLight.intensity = 0.8f;
1364
+ }
1365
+ else
1366
+ {
1367
+ roomLight.color = CoolLight;
1368
+ roomLight.intensity = 1.0f;
1369
+ }
1370
+ }
1371
+ }
1372
+ ```
1373
+
1374
+ - [ ] **Step 2: Commit**
1375
+
1376
+ ```bash
1377
+ cd C:\projects\spaces-vr
1378
+ git add Assets/Scripts/Room/RoomManager.cs
1379
+ git commit -m "feat: add room manager with pane spawning and adaptive lighting"
1380
+ ```
1381
+
1382
+ ---
1383
+
1384
+ ### Task 8: Palm Menu (Return to Lobby)
1385
+
1386
+ **Files:**
1387
+ - Create: `Assets/Scripts/Interaction/PalmMenu.cs`
1388
+
1389
+ - [ ] **Step 1: Create PalmMenu**
1390
+
1391
+ ```csharp
1392
+ // Assets/Scripts/Interaction/PalmMenu.cs
1393
+ using UnityEngine;
1394
+
1395
+ public class PalmMenu : MonoBehaviour
1396
+ {
1397
+ [SerializeField] private OVRHand hand; // left hand
1398
+ [SerializeField] private OVRSkeleton skeleton;
1399
+ [SerializeField] private GameObject menuPanel; // small floating UI
1400
+ [SerializeField] private Renderer homeButton;
1401
+ [SerializeField] private float palmUpThreshold = 0.7f; // dot product with up vector
1402
+ [SerializeField] private float gazeConfirmTime = 1.0f;
1403
+
1404
+ private bool menuVisible;
1405
+ private float gazeTimer;
1406
+ private bool isGazingHome;
1407
+ private MaterialPropertyBlock propBlock;
1408
+
1409
+ private void Awake()
1410
+ {
1411
+ propBlock = new MaterialPropertyBlock();
1412
+ if (menuPanel != null) menuPanel.SetActive(false);
1413
+ }
1414
+
1415
+ private void Update()
1416
+ {
1417
+ UpdateMenuVisibility();
1418
+ if (menuVisible) UpdateGazeConfirm();
1419
+ }
1420
+
1421
+ private void UpdateMenuVisibility()
1422
+ {
1423
+ if (hand == null || skeleton == null)
1424
+ {
1425
+ SetMenuVisible(false);
1426
+ return;
1427
+ }
1428
+
1429
+ // Check if palm is facing up
1430
+ if (skeleton.Bones == null || skeleton.Bones.Count == 0)
1431
+ {
1432
+ SetMenuVisible(false);
1433
+ return;
1434
+ }
1435
+
1436
+ // Use wrist bone orientation to determine palm facing
1437
+ Transform wrist = skeleton.Bones[(int)OVRSkeleton.BoneId.Hand_WristRoot]?.Transform;
1438
+ if (wrist == null) { SetMenuVisible(false); return; }
1439
+
1440
+ float palmDot = Vector3.Dot(wrist.up, Vector3.up);
1441
+ bool palmUp = palmDot > palmUpThreshold;
1442
+
1443
+ // Also check if user is looking at their palm
1444
+ bool lookingAtPalm = false;
1445
+ if (GazeManager.Instance?.LastHit != null)
1446
+ {
1447
+ float distToHand = Vector3.Distance(
1448
+ GazeManager.Instance.LastHit.Value.point, wrist.position);
1449
+ lookingAtPalm = distToHand < 0.2f;
1450
+ }
1451
+
1452
+ SetMenuVisible(palmUp && lookingAtPalm);
1453
+ }
1454
+
1455
+ private void SetMenuVisible(bool visible)
1456
+ {
1457
+ if (menuVisible == visible) return;
1458
+ menuVisible = visible;
1459
+ if (menuPanel != null) menuPanel.SetActive(visible);
1460
+ if (!visible) gazeTimer = 0f;
1461
+ }
1462
+
1463
+ private void UpdateGazeConfirm()
1464
+ {
1465
+ // Check if gaze is on the home button
1466
+ var focused = GazeManager.Instance?.FocusedObject;
1467
+ if (focused != null && focused == homeButton?.gameObject)
1468
+ {
1469
+ gazeTimer += Time.deltaTime;
1470
+
1471
+ // Update progress ring
1472
+ if (homeButton != null)
1473
+ {
1474
+ homeButton.GetPropertyBlock(propBlock);
1475
+ propBlock.SetFloat("_Progress", gazeTimer / gazeConfirmTime);
1476
+ homeButton.SetPropertyBlock(propBlock);
1477
+ }
1478
+
1479
+ if (gazeTimer >= gazeConfirmTime)
1480
+ {
1481
+ gazeTimer = 0f;
1482
+ ReturnToLobby();
1483
+ }
1484
+ }
1485
+ else
1486
+ {
1487
+ gazeTimer = 0f;
1488
+ }
1489
+ }
1490
+
1491
+ private void ReturnToLobby()
1492
+ {
1493
+ LobbyManager.Instance?.ReturnToLobby();
1494
+ }
1495
+ }
1496
+ ```
1497
+
1498
+ - [ ] **Step 2: Commit**
1499
+
1500
+ ```bash
1501
+ cd C:\projects\spaces-vr
1502
+ git add Assets/Scripts/Interaction/PalmMenu.cs
1503
+ git commit -m "feat: add palm menu with gaze-confirm return to lobby"
1504
+ ```
1505
+
1506
+ ---
1507
+
1508
+ ### Task 9: Scene Setup and Prefab Assembly (Unity Editor)
1509
+
1510
+ **Context:** This task is done entirely in the Unity Editor. It connects all the scripts to GameObjects and creates the prefabs and scenes.
1511
+
1512
+ - [ ] **Step 1: Create PaneSurface prefab**
1513
+
1514
+ 1. In Scene, create: 3D Object → Quad. Name it `PaneSurface`.
1515
+ 2. Scale: (1.2, 0.8, 1). This is the pane surface.
1516
+ 3. Create a dark material (`PaneSurface.mat`): Shader = URP/Lit, Base Color = `#0a0a0f`, Metallic = 0, Smoothness = 0.1.
1517
+ 4. Add a child: 3D Object → Sphere (scale 0.02) for the status dot. Position top-left corner.
1518
+ 5. Add child TextMeshPro objects for header (top of quad) and content (body).
1519
+ 6. Add components to the root:
1520
+ - `PaneSurface.cs`
1521
+ - `GazeFocusHighlight.cs`
1522
+ - `BoxCollider` (auto-added by PaneSurface RequireComponent)
1523
+ 7. Wire serialized fields: `contentText`, `header`, `statusIndicator` → child objects.
1524
+ 8. Drag to `Assets/Prefabs/PaneSurface.prefab`.
1525
+
1526
+ - [ ] **Step 2: Create WorkspaceDoor prefab**
1527
+
1528
+ 1. Create an empty GameObject named `WorkspaceDoor`.
1529
+ 2. Add child: Cube scaled to (1.2, 2.2, 0.1) — the door frame. Apply `DoorFrame.mat`.
1530
+ 3. Add child: TextMeshPro for name label (above frame).
1531
+ 4. Add child: TextMeshPro for info label (inside frame).
1532
+ 5. Add child: Point Light (range 2, intensity 0.5) for glow.
1533
+ 6. Add components to root:
1534
+ - `WorkspaceDoor.cs`
1535
+ - `DoorInteraction.cs`
1536
+ - `GazeFocusHighlight.cs`
1537
+ - `BoxCollider` (size matching the door frame)
1538
+ 7. Wire serialized fields.
1539
+ 8. Drag to `Assets/Prefabs/WorkspaceDoor.prefab`.
1540
+
1541
+ - [ ] **Step 3: Set up the main scene**
1542
+
1543
+ 1. Open the default scene (or create `Assets/Scenes/Main.unity`).
1544
+ 2. Ensure OVRCameraRig is present (from Task 1).
1545
+ 3. Create empty GameObjects:
1546
+ - `[Managers]` — add `SessionManager.cs`, `SpacesConnection.cs`, `GazeManager.cs`
1547
+ - `[Lobby]` — add `LobbyManager.cs`. Wire `doorPrefab` to the WorkspaceDoor prefab.
1548
+ - `[Room]` — add `RoomManager.cs`. Wire `panePrefab` to the PaneSurface prefab. Add a Directional Light child for room lighting.
1549
+ - `[Interaction]` — add `HandGrabHandler.cs`. Wire `leftHand` and `rightHand` to OVRHandPrefab instances.
1550
+ - `[PalmMenu]` — add `PalmMenu.cs` with a small floating Canvas child for the home button.
1551
+ 4. Add OVRHandPrefab for left and right hands (from Meta XR SDK samples).
1552
+ 5. Set Room container initially inactive.
1553
+ 6. Create an "Offline Panel" — a TextMeshPro world-space canvas at center, initially inactive. Wire to LobbyManager's `offlinePanel` field.
1554
+ 7. Wire cross-references: LobbyManager.roomManager → RoomManager, etc.
1555
+
1556
+ - [ ] **Step 4: Test in editor Play Mode**
1557
+
1558
+ Press Play in Unity Editor. With Meta XR Simulator:
1559
+ 1. Verify lobby spawns — should see "Offline" panel if no server is running.
1560
+ 2. Start Spaces server (`node bin/spaces.js --port 3457`). Hit Play again.
1561
+ 3. Doors should appear for each workspace.
1562
+ 4. Simulated gaze → door → should trigger confirm ring and enter room.
1563
+ 5. Panes should spawn in semicircle with correct names.
1564
+
1565
+ - [ ] **Step 5: Commit**
1566
+
1567
+ ```bash
1568
+ cd C:\projects\spaces-vr
1569
+ git add -A
1570
+ git commit -m "feat: assemble scenes, prefabs, and wire all components"
1571
+ ```
1572
+
1573
+ ---
1574
+
1575
+ ### Task 10: Quest 3 Build and Deploy
1576
+
1577
+ - [ ] **Step 1: Configure Android build**
1578
+
1579
+ In Unity:
1580
+ 1. File → Build Settings → ensure Android platform is selected
1581
+ 2. Player Settings → verify: IL2CPP, ARM64, Vulkan, API 32 (from Task 1)
1582
+ 3. XR Plug-in Management → verify Oculus checked
1583
+ 4. Meta XR → verify Eye Tracking + Hand Tracking enabled
1584
+
1585
+ - [ ] **Step 2: Build APK**
1586
+
1587
+ File → Build Settings → Build → save as `Build/SpacesVR.apk`
1588
+
1589
+ Expected: Build succeeds. First build takes 5-10 minutes.
1590
+
1591
+ - [ ] **Step 3: Deploy to Quest 3 (when you have one)**
1592
+
1593
+ Option A — Quest Link:
1594
+ 1. Connect Quest via USB-C or Air Link
1595
+ 2. In Unity: File → Build and Run (deploys and launches automatically)
1596
+
1597
+ Option B — SideQuest:
1598
+ 1. Install SideQuest on PC
1599
+ 2. Connect Quest via USB
1600
+ 3. Drag `Build/SpacesVR.apk` into SideQuest
1601
+ 4. On Quest: Unknown Sources → Spaces VR
1602
+
1603
+ - [ ] **Step 4: Commit final build config**
1604
+
1605
+ ```bash
1606
+ cd C:\projects\spaces-vr
1607
+ git add -A
1608
+ git commit -m "chore: finalize Quest 3 build configuration"
1609
+ ```
1610
+
1611
+ ---
1612
+
1613
+ ### Summary: File Map
1614
+
1615
+ ```
1616
+ C:\projects\spaces-vr\Assets\Scripts\
1617
+ ├── Core\
1618
+ │ ├── WorkspaceData.cs # Task 2 — data models + JSON helpers
1619
+ │ ├── SpacesConnection.cs # Task 2 — HTTP client + polling
1620
+ │ └── SessionManager.cs # Task 2 — auth token management
1621
+ ├── Interaction\
1622
+ │ ├── GazeManager.cs # Task 3 — eye tracking + head-gaze fallback
1623
+ │ ├── GazeFocusHighlight.cs # Task 3 — visual focus feedback
1624
+ │ ├── HandGrabHandler.cs # Task 5 — grab/move/resize
1625
+ │ └── PalmMenu.cs # Task 8 — palm-up home button
1626
+ ├── Lobby\
1627
+ │ ├── LobbyManager.cs # Task 6 — spawn doors, manage transitions
1628
+ │ ├── WorkspaceDoor.cs # Task 6 — door rendering
1629
+ │ └── DoorInteraction.cs # Task 6 — gaze-to-enter
1630
+ ├── Room\
1631
+ │ ├── RoomManager.cs # Task 7 — spawn panes, room lighting
1632
+ │ ├── PaneSurface.cs # Task 4 — pane placeholder
1633
+ │ └── PaneLayout.cs # Task 4 — semicircle math
1634
+ └── UI\
1635
+ ├── PaneHeader.cs # Task 4 — agent name/type label
1636
+ └── StatusIndicator.cs # Task 4 — colored status dot
1637
+
1638
+ C:\projects\spaces\src\app\api\panes\route.ts # Task 0 — workspace_id filter
1639
+ ```