@jlongo78/agent-spaces 0.9.8 → 0.9.10

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 (381) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +3 -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/routes-manifest.json +23 -0
  6. package/.next/standalone/.next/server/app/(desktop)/admin/analytics/page.js.nft.json +1 -1
  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_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/(desktop)/network/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(desktop)/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(desktop)/projects/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(desktop)/sessions/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(desktop)/settings/page_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/(desktop)/terminal/page.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/(desktop)/terminal/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/(desktop)/workspaces/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  23. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  24. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  27. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  28. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  29. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  31. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  32. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  33. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  34. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  35. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  36. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  38. package/.next/standalone/.next/server/app/admin/analytics.html +1 -1
  39. package/.next/standalone/.next/server/app/admin/analytics.rsc +3 -3
  40. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics/__PAGE__.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics.segment.rsc +1 -1
  42. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  43. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/admin/analytics.segments/_full.segment.rsc +3 -3
  45. package/.next/standalone/.next/server/app/admin/analytics.segments/_head.segment.rsc +1 -1
  46. package/.next/standalone/.next/server/app/admin/analytics.segments/_index.segment.rsc +2 -2
  47. package/.next/standalone/.next/server/app/admin/analytics.segments/_tree.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/admin/users.html +1 -1
  49. package/.next/standalone/.next/server/app/admin/users.rsc +2 -2
  50. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users/__PAGE__.segment.rsc +1 -1
  51. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users.segment.rsc +1 -1
  52. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  53. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  54. package/.next/standalone/.next/server/app/admin/users.segments/_full.segment.rsc +2 -2
  55. package/.next/standalone/.next/server/app/admin/users.segments/_head.segment.rsc +1 -1
  56. package/.next/standalone/.next/server/app/admin/users.segments/_index.segment.rsc +2 -2
  57. package/.next/standalone/.next/server/app/admin/users.segments/_tree.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/analytics.html +1 -1
  59. package/.next/standalone/.next/server/app/analytics.rsc +2 -2
  60. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics/__PAGE__.segment.rsc +1 -1
  61. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics.segment.rsc +1 -1
  62. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  63. package/.next/standalone/.next/server/app/analytics.segments/_full.segment.rsc +2 -2
  64. package/.next/standalone/.next/server/app/analytics.segments/_head.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/analytics.segments/_index.segment.rsc +2 -2
  66. package/.next/standalone/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  67. package/.next/standalone/.next/server/app/api/chat/route.js +1 -1
  68. package/.next/standalone/.next/server/app/api/chat/route.js.nft.json +1 -1
  69. package/.next/standalone/.next/server/app/api/claude/usage/route/app-paths-manifest.json +3 -0
  70. package/.next/standalone/.next/server/app/api/claude/usage/route/build-manifest.json +11 -0
  71. package/.next/standalone/.next/server/app/api/claude/usage/route/server-reference-manifest.json +4 -0
  72. package/.next/standalone/.next/server/app/api/claude/usage/route.js +8 -0
  73. package/.next/standalone/.next/server/app/api/claude/usage/route.js.map +5 -0
  74. package/.next/standalone/.next/server/app/api/claude/usage/route.js.nft.json +1 -0
  75. package/.next/standalone/.next/server/app/api/claude/usage/route_client-reference-manifest.js +2 -0
  76. package/.next/standalone/.next/server/app/api/cortex/status/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js +1 -1
  78. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/whisper/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route/app-paths-manifest.json +3 -0
  81. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route/build-manifest.json +11 -0
  82. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route/server-reference-manifest.json +4 -0
  83. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route.js +8 -0
  84. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route.js.map +5 -0
  85. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route.js.nft.json +1 -0
  86. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/[todoId]/route_client-reference-manifest.js +2 -0
  87. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route/app-paths-manifest.json +3 -0
  88. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route/build-manifest.json +11 -0
  89. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route/server-reference-manifest.json +4 -0
  90. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route.js +8 -0
  91. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route.js.map +5 -0
  92. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route.js.nft.json +1 -0
  93. package/.next/standalone/.next/server/app/api/workspaces/[id]/todos/route_client-reference-manifest.js +2 -0
  94. package/.next/standalone/.next/server/app/cortex.html +1 -1
  95. package/.next/standalone/.next/server/app/cortex.rsc +2 -2
  96. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex/__PAGE__.segment.rsc +1 -1
  97. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex.segment.rsc +1 -1
  98. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  99. package/.next/standalone/.next/server/app/cortex.segments/_full.segment.rsc +2 -2
  100. package/.next/standalone/.next/server/app/cortex.segments/_head.segment.rsc +1 -1
  101. package/.next/standalone/.next/server/app/cortex.segments/_index.segment.rsc +2 -2
  102. package/.next/standalone/.next/server/app/cortex.segments/_tree.segment.rsc +2 -2
  103. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/login.html +1 -1
  105. package/.next/standalone/.next/server/app/login.rsc +2 -2
  106. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +2 -2
  107. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  108. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +2 -2
  109. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  110. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  111. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  112. package/.next/standalone/.next/server/app/m/page_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/m/projects/page_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/m/projects.html +1 -1
  115. package/.next/standalone/.next/server/app/m/projects.rsc +2 -2
  116. package/.next/standalone/.next/server/app/m/projects.segments/_full.segment.rsc +2 -2
  117. package/.next/standalone/.next/server/app/m/projects.segments/_head.segment.rsc +1 -1
  118. package/.next/standalone/.next/server/app/m/projects.segments/_index.segment.rsc +2 -2
  119. package/.next/standalone/.next/server/app/m/projects.segments/_tree.segment.rsc +2 -2
  120. package/.next/standalone/.next/server/app/m/projects.segments/m/projects/__PAGE__.segment.rsc +1 -1
  121. package/.next/standalone/.next/server/app/m/projects.segments/m/projects.segment.rsc +1 -1
  122. package/.next/standalone/.next/server/app/m/projects.segments/m.segment.rsc +1 -1
  123. package/.next/standalone/.next/server/app/m/sessions/[id]/page_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/m/sessions/page_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/m/sessions.html +1 -1
  126. package/.next/standalone/.next/server/app/m/sessions.rsc +2 -2
  127. package/.next/standalone/.next/server/app/m/sessions.segments/_full.segment.rsc +2 -2
  128. package/.next/standalone/.next/server/app/m/sessions.segments/_head.segment.rsc +1 -1
  129. package/.next/standalone/.next/server/app/m/sessions.segments/_index.segment.rsc +2 -2
  130. package/.next/standalone/.next/server/app/m/sessions.segments/_tree.segment.rsc +2 -2
  131. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions/__PAGE__.segment.rsc +1 -1
  132. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions.segment.rsc +1 -1
  133. package/.next/standalone/.next/server/app/m/sessions.segments/m.segment.rsc +1 -1
  134. package/.next/standalone/.next/server/app/m/settings/page_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/m/settings.html +1 -1
  136. package/.next/standalone/.next/server/app/m/settings.rsc +2 -2
  137. package/.next/standalone/.next/server/app/m/settings.segments/_full.segment.rsc +2 -2
  138. package/.next/standalone/.next/server/app/m/settings.segments/_head.segment.rsc +1 -1
  139. package/.next/standalone/.next/server/app/m/settings.segments/_index.segment.rsc +2 -2
  140. package/.next/standalone/.next/server/app/m/settings.segments/_tree.segment.rsc +2 -2
  141. package/.next/standalone/.next/server/app/m/settings.segments/m/settings/__PAGE__.segment.rsc +1 -1
  142. package/.next/standalone/.next/server/app/m/settings.segments/m/settings.segment.rsc +1 -1
  143. package/.next/standalone/.next/server/app/m/settings.segments/m.segment.rsc +1 -1
  144. package/.next/standalone/.next/server/app/m/terminal/page_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/m/terminal.html +1 -1
  146. package/.next/standalone/.next/server/app/m/terminal.rsc +2 -2
  147. package/.next/standalone/.next/server/app/m/terminal.segments/_full.segment.rsc +2 -2
  148. package/.next/standalone/.next/server/app/m/terminal.segments/_head.segment.rsc +1 -1
  149. package/.next/standalone/.next/server/app/m/terminal.segments/_index.segment.rsc +2 -2
  150. package/.next/standalone/.next/server/app/m/terminal.segments/_tree.segment.rsc +2 -2
  151. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal/__PAGE__.segment.rsc +1 -1
  152. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal.segment.rsc +1 -1
  153. package/.next/standalone/.next/server/app/m/terminal.segments/m.segment.rsc +1 -1
  154. package/.next/standalone/.next/server/app/m.html +1 -1
  155. package/.next/standalone/.next/server/app/m.rsc +2 -2
  156. package/.next/standalone/.next/server/app/m.segments/_full.segment.rsc +2 -2
  157. package/.next/standalone/.next/server/app/m.segments/_head.segment.rsc +1 -1
  158. package/.next/standalone/.next/server/app/m.segments/_index.segment.rsc +2 -2
  159. package/.next/standalone/.next/server/app/m.segments/_tree.segment.rsc +2 -2
  160. package/.next/standalone/.next/server/app/m.segments/m/__PAGE__.segment.rsc +1 -1
  161. package/.next/standalone/.next/server/app/m.segments/m.segment.rsc +1 -1
  162. package/.next/standalone/.next/server/app/network.html +1 -1
  163. package/.next/standalone/.next/server/app/network.rsc +2 -2
  164. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network/__PAGE__.segment.rsc +1 -1
  165. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network.segment.rsc +1 -1
  166. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  167. package/.next/standalone/.next/server/app/network.segments/_full.segment.rsc +2 -2
  168. package/.next/standalone/.next/server/app/network.segments/_head.segment.rsc +1 -1
  169. package/.next/standalone/.next/server/app/network.segments/_index.segment.rsc +2 -2
  170. package/.next/standalone/.next/server/app/network.segments/_tree.segment.rsc +2 -2
  171. package/.next/standalone/.next/server/app/projects.html +1 -1
  172. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  173. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects/__PAGE__.segment.rsc +1 -1
  174. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects.segment.rsc +1 -1
  175. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  176. package/.next/standalone/.next/server/app/projects.segments/_full.segment.rsc +2 -2
  177. package/.next/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  178. package/.next/standalone/.next/server/app/projects.segments/_index.segment.rsc +2 -2
  179. package/.next/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  180. package/.next/standalone/.next/server/app/sessions.html +1 -1
  181. package/.next/standalone/.next/server/app/sessions.rsc +2 -2
  182. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions/__PAGE__.segment.rsc +1 -1
  183. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions.segment.rsc +1 -1
  184. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  185. package/.next/standalone/.next/server/app/sessions.segments/_full.segment.rsc +2 -2
  186. package/.next/standalone/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  187. package/.next/standalone/.next/server/app/sessions.segments/_index.segment.rsc +2 -2
  188. package/.next/standalone/.next/server/app/sessions.segments/_tree.segment.rsc +2 -2
  189. package/.next/standalone/.next/server/app/settings.html +1 -1
  190. package/.next/standalone/.next/server/app/settings.rsc +3 -3
  191. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings/__PAGE__.segment.rsc +2 -2
  192. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings.segment.rsc +1 -1
  193. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  194. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +3 -3
  195. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  196. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  197. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  198. package/.next/standalone/.next/server/app/terminal.html +1 -1
  199. package/.next/standalone/.next/server/app/terminal.rsc +3 -3
  200. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal/__PAGE__.segment.rsc +2 -2
  201. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal.segment.rsc +1 -1
  202. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  203. package/.next/standalone/.next/server/app/terminal.segments/_full.segment.rsc +3 -3
  204. package/.next/standalone/.next/server/app/terminal.segments/_head.segment.rsc +1 -1
  205. package/.next/standalone/.next/server/app/terminal.segments/_index.segment.rsc +2 -2
  206. package/.next/standalone/.next/server/app/terminal.segments/_tree.segment.rsc +2 -2
  207. package/.next/standalone/.next/server/app/vr/page_client-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/app/vr.html +1 -1
  209. package/.next/standalone/.next/server/app/vr.rsc +2 -2
  210. package/.next/standalone/.next/server/app/vr.segments/_full.segment.rsc +2 -2
  211. package/.next/standalone/.next/server/app/vr.segments/_head.segment.rsc +1 -1
  212. package/.next/standalone/.next/server/app/vr.segments/_index.segment.rsc +2 -2
  213. package/.next/standalone/.next/server/app/vr.segments/_tree.segment.rsc +2 -2
  214. package/.next/standalone/.next/server/app/vr.segments/vr/__PAGE__.segment.rsc +1 -1
  215. package/.next/standalone/.next/server/app/vr.segments/vr.segment.rsc +1 -1
  216. package/.next/standalone/.next/server/app/workspaces.html +1 -1
  217. package/.next/standalone/.next/server/app/workspaces.rsc +2 -2
  218. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces/__PAGE__.segment.rsc +1 -1
  219. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces.segment.rsc +1 -1
  220. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  221. package/.next/standalone/.next/server/app/workspaces.segments/_full.segment.rsc +2 -2
  222. package/.next/standalone/.next/server/app/workspaces.segments/_head.segment.rsc +1 -1
  223. package/.next/standalone/.next/server/app/workspaces.segments/_index.segment.rsc +2 -2
  224. package/.next/standalone/.next/server/app/workspaces.segments/_tree.segment.rsc +2 -2
  225. package/.next/standalone/.next/server/app-paths-manifest.json +3 -0
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00e90fc6._.js +15 -2
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01ab8675._.js +15 -2
  228. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03974f05._.js +15 -2
  229. package/.next/standalone/.next/server/chunks/[root-of-the-server]__046c9b91._.js +16 -3
  230. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04ae6bf0._.js +15 -2
  231. package/.next/standalone/.next/server/chunks/[root-of-the-server]__056fa416._.js +1 -1
  232. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ac4ea3f._.js +1 -1
  233. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b8e64cb._.js +15 -2
  234. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0facd39e._.js +15 -2
  235. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10bc76a3._.js +1 -1
  236. package/.next/standalone/.next/server/chunks/[root-of-the-server]__115f3934._.js +15 -2
  237. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11f155f1._.js +1 -1
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__160e7c73._.js +52 -24
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17a3b966._.js +15 -2
  240. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17d3a2b2._.js +15 -2
  241. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a86c055._.js +15 -2
  242. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fe0f452._.js +127 -0
  243. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20b5e9c4._.js +1 -1
  244. package/.next/standalone/.next/server/chunks/[root-of-the-server]__28d6fbd8._.js +15 -2
  245. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2a3f866b._.js +16 -3
  246. package/.next/standalone/.next/server/chunks/[root-of-the-server]__316617e7._.js +3 -3
  247. package/.next/standalone/.next/server/chunks/[root-of-the-server]__32ad8f71._.js +15 -2
  248. package/.next/standalone/.next/server/chunks/[root-of-the-server]__35457394._.js +15 -2
  249. package/.next/standalone/.next/server/chunks/[root-of-the-server]__35de78e6._.js +15 -2
  250. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3685ffcb._.js +15 -2
  251. package/.next/standalone/.next/server/chunks/[root-of-the-server]__38954988._.js +15 -2
  252. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3a32b624._.js +111 -0
  253. package/.next/standalone/.next/server/chunks/[root-of-the-server]__426ad936._.js +17 -4
  254. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4985c034._.js +15 -2
  255. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c6ce9ed._.js +16 -3
  256. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5cebe58a._.js +15 -2
  257. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5d5e4789._.js +15 -2
  258. package/.next/standalone/.next/server/chunks/[root-of-the-server]__65676930._.js +1 -1
  259. package/.next/standalone/.next/server/chunks/[root-of-the-server]__67cab326._.js +2 -2
  260. package/.next/standalone/.next/server/chunks/[root-of-the-server]__698c6f01._.js +16 -3
  261. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c64af29._.js +22 -9
  262. package/.next/standalone/.next/server/chunks/[root-of-the-server]__73aed9f5._.js +15 -2
  263. package/.next/standalone/.next/server/chunks/[root-of-the-server]__79b6a9bb._.js +15 -2
  264. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7db704c6._.js +17 -4
  265. package/.next/standalone/.next/server/chunks/[root-of-the-server]__812ca02b._.js +15 -2
  266. package/.next/standalone/.next/server/chunks/[root-of-the-server]__821f50fa._.js +15 -2
  267. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8716b86e._.js +15 -2
  268. package/.next/standalone/.next/server/chunks/[root-of-the-server]__884ef754._.js +15 -2
  269. package/.next/standalone/.next/server/chunks/[root-of-the-server]__88cdbd68._.js +15 -2
  270. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89d9aba9._.js +15 -2
  271. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8c2e1260._.js +111 -0
  272. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8d536cb5._.js +15 -2
  273. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8df8c5d1._.js +15 -2
  274. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8f2ccc41._.js +15 -2
  275. package/.next/standalone/.next/server/chunks/[root-of-the-server]__95c9d682._.js +15 -2
  276. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9e5d7774._.js +15 -2
  277. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9edcff87._.js +15 -2
  278. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a049dfc2._.js +15 -2
  279. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a5b4bb9a._.js +15 -2
  280. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a83262a1._.js +15 -2
  281. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9cd1240._.js +15 -2
  282. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9d7f822._.js +15 -2
  283. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad08c221._.js +15 -2
  284. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad585f2f._.js +15 -2
  285. package/.next/standalone/.next/server/chunks/[root-of-the-server]__afcb8f7d._.js +15 -2
  286. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bc250d43._.js +15 -2
  287. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bce2a6e7._.js +15 -2
  288. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bfcd7fd4._.js +13 -0
  289. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c011bf91._.js +15 -2
  290. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c37d6380._.js +1 -1
  291. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cae392eb._.js +15 -2
  292. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cc2616bb._.js +16 -3
  293. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d501fa9b._.js +15 -2
  294. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d59c6c15._.js +15 -2
  295. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5c1db32._.js +15 -2
  296. package/.next/standalone/.next/server/chunks/[root-of-the-server]__dba60c86._.js +15 -2
  297. package/.next/standalone/.next/server/chunks/[root-of-the-server]__de14b9ae._.js +15 -2
  298. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e10643d1._.js +15 -2
  299. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e3477417._.js +15 -2
  300. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e4db362e._.js +1 -1
  301. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e4e70b86._.js +15 -2
  302. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e54925af._.js +15 -2
  303. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e8cbeaca._.js +111 -0
  304. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e8edc5b0._.js +15 -2
  305. package/.next/standalone/.next/server/chunks/[root-of-the-server]__eab4d83b._.js +15 -2
  306. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f056fd83._.js +15 -2
  307. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f0e99572._.js +15 -2
  308. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fe1e16d0._.js +15 -2
  309. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ff9cd277._.js +15 -2
  310. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ffaea2ce._.js +15 -2
  311. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_claude_usage_route_actions_fe002ec1.js +3 -0
  312. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_workspaces_[id]_todos_route_actions_0d4ffac5.js +3 -0
  313. package/.next/standalone/.next/server/chunks/ce889_server_app_api_workspaces_[id]_todos_[todoId]_route_actions_754fe6b9.js +3 -0
  314. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__66aca5d4._.js +1 -1
  315. package/.next/standalone/.next/server/chunks/ssr/{_17b946fd._.js → _20c2cf3a._.js} +2 -2
  316. package/.next/standalone/.next/server/chunks/ssr/_5f55bf8f._.js +3 -0
  317. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_settings_page_tsx_f74824b3._.js +1 -1
  318. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_terminal_page_tsx_de5e8d85._.js +1 -1
  319. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__90eeddae._.js +1 -1
  320. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__ca3f649e._.js +2 -2
  321. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  322. package/.next/standalone/.next/server/pages/404.html +1 -1
  323. package/.next/standalone/.next/server/pages/500.html +2 -2
  324. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  325. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  326. package/.next/standalone/.next/static/chunks/14216197f9dcbe5b.css +3 -0
  327. package/.next/standalone/.next/static/chunks/{0852575eb90c1e8d.js → 4c9fb0a38f041a3d.js} +2 -2
  328. package/.next/standalone/.next/static/chunks/8f6f93ab45a5ff5b.js +1 -0
  329. package/.next/standalone/.next/static/chunks/{e62bb488d02db247.js → d2566c2dcf53fef3.js} +1 -1
  330. package/.next/standalone/.next/static/chunks/{7f6a14f1849fa94d.js → ff7d85dade44d1f3.js} +1 -1
  331. package/.next/standalone/bin/cortex-hook.js +8 -3
  332. package/.next/standalone/bin/cortex-learn-hook.js +7 -2
  333. package/.next/standalone/bin/scrub-standalone.js +89 -0
  334. package/.next/standalone/bin/terminal-server.js +44 -16
  335. package/.next/standalone/docs/features/claude-usage.md +105 -0
  336. package/.next/standalone/docs/features/workspace-todos.md +127 -0
  337. package/.next/standalone/docs/superpowers/plans/2026-04-21-workspace-todos.md +1097 -0
  338. package/.next/standalone/docs/superpowers/plans/2026-04-22-claude-usage-display.md +749 -0
  339. package/.next/standalone/docs/superpowers/specs/2026-04-21-workspace-todos-design.md +180 -0
  340. package/.next/standalone/docs/superpowers/specs/2026-04-22-claude-usage-display-design.md +183 -0
  341. package/.next/standalone/package-lock.json +2 -2
  342. package/.next/standalone/package.json +2 -2
  343. package/.next/standalone/src/app/(desktop)/settings/page.tsx +40 -1
  344. package/.next/standalone/src/app/(desktop)/terminal/page.tsx +54 -2
  345. package/.next/standalone/src/app/api/chat/route.ts +56 -53
  346. package/.next/standalone/src/app/api/claude/usage/route.ts +33 -0
  347. package/.next/standalone/src/app/api/config/route.ts +3 -0
  348. package/.next/standalone/src/app/api/sessions/[id]/chat/route.ts +2 -1
  349. package/.next/standalone/src/app/api/workspaces/[id]/todos/[todoId]/route.ts +55 -0
  350. package/.next/standalone/src/app/api/workspaces/[id]/todos/route.ts +43 -0
  351. package/.next/standalone/src/components/claude/claude-usage-strip.tsx +175 -0
  352. package/.next/standalone/src/components/workspace/workspace-todos.tsx +265 -0
  353. package/.next/standalone/src/hooks/use-claude-usage.ts +66 -0
  354. package/.next/standalone/src/lib/claude/credentials.ts +36 -0
  355. package/.next/standalone/src/lib/claude/usage.ts +69 -0
  356. package/.next/standalone/src/lib/config.ts +3 -0
  357. package/.next/standalone/src/lib/db/queries.ts +103 -1
  358. package/.next/standalone/src/lib/db/schema.ts +18 -0
  359. package/.next/standalone/src/lib/spawn-env.ts +32 -0
  360. package/.next/standalone/src/lib/terminal/server.ts +3 -3
  361. package/.next/standalone/src/middleware.ts +23 -5
  362. package/.next/standalone/src/types/claude.ts +39 -0
  363. package/.next/standalone/tests/db/workspace-todos.test.ts +156 -0
  364. package/bin/cortex-hook.js +8 -3
  365. package/bin/cortex-learn-hook.js +7 -2
  366. package/bin/scrub-standalone.js +89 -0
  367. package/bin/terminal-server.js +44 -16
  368. package/package.json +2 -2
  369. package/.next/standalone/.claude/settings.local.json +0 -68
  370. package/.next/standalone/.claude/spaces-env.json +0 -1
  371. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e2a996e5._.js +0 -114
  372. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ead29015._.js +0 -13
  373. package/.next/standalone/.next/server/chunks/ssr/_3ba93bdd._.js +0 -3
  374. package/.next/standalone/.next/static/chunks/074df89a63b6a854.js +0 -1
  375. package/.next/standalone/.next/static/chunks/2b769d1597e4fc1c.css +0 -3
  376. package/.next/standalone/.spaces/cortex-context.md +0 -51
  377. package/.next/standalone/cortex-hook-debug.log +0 -57
  378. package/.next/standalone/docs/plans/2026-03-02-security-audit.md +0 -229
  379. /package/.next/standalone/.next/static/{u1pHON3drz1mBi7owkbBP → HNrWymrkgOP9Z4WIaYeOj}/_buildManifest.js +0 -0
  380. /package/.next/standalone/.next/static/{u1pHON3drz1mBi7owkbBP → HNrWymrkgOP9Z4WIaYeOj}/_clientMiddlewareManifest.json +0 -0
  381. /package/.next/standalone/.next/static/{u1pHON3drz1mBi7owkbBP → HNrWymrkgOP9Z4WIaYeOj}/_ssgManifest.js +0 -0
@@ -1,6 +1,15 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
  import { HAS_AUTH } from '@/lib/tier';
3
3
 
4
+ function timingSafeEqualStr(a: string, b: string): boolean {
5
+ const aBytes = new TextEncoder().encode(a);
6
+ const bBytes = new TextEncoder().encode(b);
7
+ if (aBytes.length !== bBytes.length) return false;
8
+ let result = 0;
9
+ for (let i = 0; i < aBytes.length; i++) result |= aBytes[i] ^ bBytes[i];
10
+ return result === 0;
11
+ }
12
+
4
13
  async function verifyToken(token: string, secretHex: string): Promise<{ sub: string; role: string } | null> {
5
14
  if (!token) return null;
6
15
  const parts = token.split('.');
@@ -20,7 +29,7 @@ async function verifyToken(token: string, secretHex: string): Promise<{ sub: str
20
29
  const expectedSig = btoa(String.fromCharCode(...new Uint8Array(sigBytes)))
21
30
  .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
22
31
 
23
- if (expectedSig !== sig) return null;
32
+ if (!timingSafeEqualStr(expectedSig, sig)) return null;
24
33
 
25
34
  try {
26
35
  const payloadStr = atob(payloadB64.replace(/-/g, '+').replace(/_/g, '/'));
@@ -58,9 +67,17 @@ export async function middleware(request: NextRequest) {
58
67
  return NextResponse.next();
59
68
  }
60
69
 
61
- // Federation API routes authenticate via Bearer token
62
- if (pathname.startsWith('/api/network/') && request.headers.get('authorization')?.startsWith('Bearer ')) {
63
- return NextResponse.next();
70
+ // Federation API routes authenticate via Bearer token. Middleware can't validate
71
+ // the token against network.db in Edge runtime, so we only let through requests
72
+ // that carry a well-formed API-key bearer (shape: "spk_" + base36-ish). The route
73
+ // handler is still responsible for calling requireNetworkAuth() — this bypass is
74
+ // purely a shape check to reject arbitrary strings like "Bearer anything".
75
+ const authHeader = request.headers.get('authorization');
76
+ if (pathname.startsWith('/api/network/') && authHeader?.startsWith('Bearer ')) {
77
+ const bearer = authHeader.slice(7);
78
+ if (/^spk_[A-Za-z0-9_-]{8,}$/.test(bearer)) {
79
+ return NextResponse.next();
80
+ }
64
81
  }
65
82
 
66
83
  // Connection request/callback endpoints are unauthenticated (verified by token in body)
@@ -73,7 +90,8 @@ export async function middleware(request: NextRequest) {
73
90
 
74
91
  // Internal API requests from MCP servers / agent processes / VR client (local network)
75
92
  const internalToken = request.headers.get('x-spaces-internal') || request.nextUrl.searchParams.get('_internal');
76
- if (internalToken === (process.env.SPACES_SESSION_SECRET || '').slice(0, 16) &&
93
+ const expectedInternalToken = (process.env.SPACES_SESSION_SECRET || '').slice(0, 16);
94
+ if (internalToken && expectedInternalToken && timingSafeEqualStr(internalToken, expectedInternalToken) &&
77
95
  (request.headers.get('host')?.startsWith('localhost') || request.headers.get('host')?.startsWith('127.0.0.1') || request.headers.get('host')?.startsWith('192.168.'))) {
78
96
  return NextResponse.next();
79
97
  }
@@ -206,3 +206,42 @@ export interface AnalyticsOverview {
206
206
  dailyActivity: DailyActivity[];
207
207
  dailyModelTokens: DailyModelTokens[];
208
208
  }
209
+
210
+ export interface WorkspaceTodo {
211
+ id: number;
212
+ workspaceId: number;
213
+ text: string;
214
+ completed: boolean;
215
+ sortOrder: number;
216
+ created: string;
217
+ completedAt: string | null;
218
+ }
219
+
220
+ // ─── Claude plan-usage (mirrors /usage in Claude Code) ───────
221
+
222
+ export interface RateLimit {
223
+ utilization: number | null; // 0-100
224
+ resets_at: string | null; // ISO 8601
225
+ }
226
+
227
+ export interface ExtraUsage {
228
+ is_enabled: boolean;
229
+ monthly_limit: number | null;
230
+ used_credits: number | null;
231
+ utilization: number | null;
232
+ }
233
+
234
+ export interface Utilization {
235
+ five_hour?: RateLimit | null;
236
+ seven_day?: RateLimit | null;
237
+ seven_day_oauth_apps?: RateLimit | null;
238
+ seven_day_opus?: RateLimit | null;
239
+ seven_day_sonnet?: RateLimit | null;
240
+ extra_usage?: ExtraUsage | null;
241
+ }
242
+
243
+ export type UsageResponse =
244
+ | { status: 'ok'; data: Utilization }
245
+ | { status: 'unauthenticated' }
246
+ | { status: 'expired' }
247
+ | { status: 'upstream_error' };
@@ -0,0 +1,156 @@
1
+ import fs from 'fs';
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import Database from 'better-sqlite3';
6
+
7
+ import { __testing } from '@/lib/db/schema';
8
+ import {
9
+ getWorkspaceTodos,
10
+ addWorkspaceTodo,
11
+ updateWorkspaceTodo,
12
+ deleteWorkspaceTodo,
13
+ } from '@/lib/db/queries';
14
+
15
+ const TEST_USER = 'test-user'; // matches tests/setup.ts auth mock
16
+ let db: Database.Database;
17
+ let tempDir: string;
18
+
19
+ beforeEach(() => {
20
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'spaces-todos-test-'));
21
+ const dbPath = path.join(tempDir, 'test.db');
22
+ db = new Database(dbPath);
23
+ db.pragma('journal_mode = WAL');
24
+ db.pragma('foreign_keys = ON');
25
+
26
+ const ddl = [
27
+ `CREATE TABLE workspaces (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ name TEXT NOT NULL,
30
+ color TEXT DEFAULT '#6366f1',
31
+ created TEXT DEFAULT (datetime('now'))
32
+ )`,
33
+ `CREATE TABLE workspace_todos (
34
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
35
+ workspace_id INTEGER NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
36
+ text TEXT NOT NULL,
37
+ completed INTEGER NOT NULL DEFAULT 0,
38
+ sort_order INTEGER NOT NULL DEFAULT 0,
39
+ created TEXT NOT NULL DEFAULT (datetime('now')),
40
+ completed_at TEXT
41
+ )`,
42
+ `CREATE INDEX idx_workspace_todos_workspace ON workspace_todos(workspace_id)`,
43
+ ];
44
+ for (const stmt of ddl) {
45
+ db.prepare(stmt).run();
46
+ }
47
+
48
+ __testing.dbs.set(TEST_USER, db);
49
+
50
+ db.prepare("INSERT INTO workspaces (id, name) VALUES (1, 'Test WS')").run();
51
+ });
52
+
53
+ afterEach(() => {
54
+ try { db.close(); } catch {}
55
+ __testing.dbs.delete(TEST_USER);
56
+ fs.rmSync(tempDir, { recursive: true, force: true });
57
+ });
58
+
59
+ describe('workspace todos query helpers', () => {
60
+ it('adds a todo with incrementing sort_order among uncompleted rows', () => {
61
+ const a = addWorkspaceTodo(1, 'first');
62
+ const b = addWorkspaceTodo(1, 'second');
63
+ const c = addWorkspaceTodo(1, 'third');
64
+
65
+ expect(a.sortOrder).toBe(0);
66
+ expect(b.sortOrder).toBe(1);
67
+ expect(c.sortOrder).toBe(2);
68
+ expect(a.completed).toBe(false);
69
+ expect(a.text).toBe('first');
70
+ });
71
+
72
+ it('trims text and rejects empty', () => {
73
+ const t = addWorkspaceTodo(1, ' hello ');
74
+ expect(t.text).toBe('hello');
75
+
76
+ expect(() => addWorkspaceTodo(1, ' ')).toThrow();
77
+ expect(() => addWorkspaceTodo(1, '')).toThrow();
78
+ });
79
+
80
+ it('toggles completed and sets/clears completed_at', () => {
81
+ const t = addWorkspaceTodo(1, 'toggle me');
82
+ expect(t.completedAt).toBeNull();
83
+
84
+ const done = updateWorkspaceTodo(1, t.id, { completed: true });
85
+ expect(done?.completed).toBe(true);
86
+ expect(done?.completedAt).not.toBeNull();
87
+
88
+ const undone = updateWorkspaceTodo(1, t.id, { completed: false });
89
+ expect(undone?.completed).toBe(false);
90
+ expect(undone?.completedAt).toBeNull();
91
+ });
92
+
93
+ it('updates text, trims, rejects empty', () => {
94
+ const t = addWorkspaceTodo(1, 'original');
95
+ const upd = updateWorkspaceTodo(1, t.id, { text: ' edited ' });
96
+ expect(upd?.text).toBe('edited');
97
+
98
+ expect(() => updateWorkspaceTodo(1, t.id, { text: ' ' })).toThrow();
99
+ });
100
+
101
+ it('lists todos: uncompleted first by sort_order, completed last by completed_at desc', () => {
102
+ const a = addWorkspaceTodo(1, 'a');
103
+ const b = addWorkspaceTodo(1, 'b');
104
+ const c = addWorkspaceTodo(1, 'c');
105
+
106
+ updateWorkspaceTodo(1, b.id, { completed: true });
107
+ updateWorkspaceTodo(1, a.id, { completed: true });
108
+
109
+ const list = getWorkspaceTodos(1);
110
+ expect(list.map(t => t.text)).toEqual(['c', 'a', 'b']);
111
+ });
112
+
113
+ it('deletes a todo', () => {
114
+ const t = addWorkspaceTodo(1, 'doomed');
115
+ deleteWorkspaceTodo(1, t.id);
116
+ expect(getWorkspaceTodos(1)).toHaveLength(0);
117
+ });
118
+
119
+ it('cascades when the workspace is deleted', () => {
120
+ addWorkspaceTodo(1, 'x');
121
+ addWorkspaceTodo(1, 'y');
122
+ db.prepare('DELETE FROM workspaces WHERE id = 1').run();
123
+ const rows = db.prepare('SELECT COUNT(*) AS n FROM workspace_todos').get() as { n: number };
124
+ expect(rows.n).toBe(0);
125
+ });
126
+
127
+ it('scopes listing by workspace', () => {
128
+ db.prepare("INSERT INTO workspaces (id, name) VALUES (2, 'Other')").run();
129
+ addWorkspaceTodo(1, 'ws-1-a');
130
+ addWorkspaceTodo(2, 'ws-2-a');
131
+ addWorkspaceTodo(1, 'ws-1-b');
132
+
133
+ const ws1 = getWorkspaceTodos(1);
134
+ const ws2 = getWorkspaceTodos(2);
135
+ expect(ws1.map(t => t.text).sort()).toEqual(['ws-1-a', 'ws-1-b']);
136
+ expect(ws2.map(t => t.text)).toEqual(['ws-2-a']);
137
+ });
138
+
139
+ it('refuses to update or delete a todo from a different workspace', () => {
140
+ db.prepare("INSERT INTO workspaces (id, name) VALUES (2, 'Other')").run();
141
+ const t = addWorkspaceTodo(1, 'belongs to ws 1');
142
+
143
+ // Update with the wrong workspace id → returns null, leaves row untouched.
144
+ const update = updateWorkspaceTodo(2, t.id, { text: 'hijacked' });
145
+ expect(update).toBeNull();
146
+ expect(getWorkspaceTodos(1)[0].text).toBe('belongs to ws 1');
147
+
148
+ // Delete with the wrong workspace id → row survives.
149
+ deleteWorkspaceTodo(2, t.id);
150
+ expect(getWorkspaceTodos(1)).toHaveLength(1);
151
+
152
+ // Correct workspace → works.
153
+ deleteWorkspaceTodo(1, t.id);
154
+ expect(getWorkspaceTodos(1)).toHaveLength(0);
155
+ });
156
+ });
@@ -2,11 +2,16 @@
2
2
  'use strict';
3
3
  const http = require('http');
4
4
  const fs = require('fs');
5
+ const os = require('os');
5
6
  const path = require('path');
6
7
 
7
- const LOG_FILE = path.join(process.cwd(), 'cortex-hook-debug.log');
8
+ const LOG_DIR = path.join(os.homedir(), '.spaces', 'logs');
9
+ const LOG_FILE = path.join(LOG_DIR, 'cortex-hook-debug.log');
8
10
  function log(msg) {
9
- try { fs.appendFileSync(LOG_FILE, "[" + new Date().toISOString() + "] " + msg + "\n"); } catch(e) {}
11
+ try {
12
+ fs.mkdirSync(LOG_DIR, { recursive: true });
13
+ fs.appendFileSync(LOG_FILE, "[" + new Date().toISOString() + "] " + msg + "\n");
14
+ } catch(e) {}
10
15
  }
11
16
 
12
17
  function readSpacesEnv() {
@@ -49,7 +54,7 @@ async function main() {
49
54
 
50
55
  const query = encodeURIComponent(prompt);
51
56
  const url = "http://localhost:" + port + "/api/cortex/context/?q=" + query + "&limit=5" + (wsId ? "&workspace_id=" + wsId : "");
52
- log('Querying: ' + url + ' (event: ' + eventName + ')');
57
+ log('Querying cortex (prompt length: ' + prompt.length + ', event: ' + eventName + ')');
53
58
 
54
59
  try {
55
60
  const body = await new Promise((resolve, reject) => {
@@ -2,11 +2,16 @@
2
2
  'use strict';
3
3
  const http = require('http');
4
4
  const fs = require('fs');
5
+ const os = require('os');
5
6
  const path = require('path');
6
7
 
7
- const LOG_FILE = path.join(process.cwd(), 'cortex-hook-debug.log');
8
+ const LOG_DIR = path.join(os.homedir(), '.spaces', 'logs');
9
+ const LOG_FILE = path.join(LOG_DIR, 'cortex-hook-debug.log');
8
10
  function log(msg) {
9
- try { fs.appendFileSync(LOG_FILE, "[" + new Date().toISOString() + "] [LEARN] " + msg + "\n"); } catch(e) {}
11
+ try {
12
+ fs.mkdirSync(LOG_DIR, { recursive: true });
13
+ fs.appendFileSync(LOG_FILE, "[" + new Date().toISOString() + "] [LEARN] " + msg + "\n");
14
+ } catch(e) {}
10
15
  }
11
16
 
12
17
  function readSpacesEnv() {
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Remove runtime-generated files from .next/standalone/ before publishing to npm.
4
+ // Historical incident: cortex-hook-debug.log containing user prompts (and npm tokens)
5
+ // leaked into versions 0.9.6-0.9.9 because the hook wrote to process.cwd() which
6
+ // at runtime was .next/standalone/. Hooks now log to ~/.spaces/logs/, but this
7
+ // belt-and-suspenders scrub runs on every publish to catch any other accidents.
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const STANDALONE = path.join(process.cwd(), '.next', 'standalone');
13
+
14
+ const DENY_FILES = [
15
+ 'cortex-hook-debug.log',
16
+ ];
17
+
18
+ const DENY_DIRS = [
19
+ '.spaces',
20
+ '.claude',
21
+ '.codex',
22
+ '.gemini',
23
+ '.pi',
24
+ 'logs',
25
+ ];
26
+
27
+ const DENY_PATTERNS = [
28
+ /\.log$/i,
29
+ /^\.env(\..+)?$/i,
30
+ /^\.npmrc$/i,
31
+ ];
32
+
33
+ function walk(dir, cb) {
34
+ let entries;
35
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
36
+ catch { return; }
37
+ for (const e of entries) {
38
+ const full = path.join(dir, e.name);
39
+ if (e.isDirectory()) {
40
+ if (DENY_DIRS.includes(e.name)) {
41
+ fs.rmSync(full, { recursive: true, force: true });
42
+ console.log('[scrub] removed dir: ' + path.relative(STANDALONE, full));
43
+ continue;
44
+ }
45
+ walk(full, cb);
46
+ } else if (e.isFile()) {
47
+ cb(full, e.name);
48
+ }
49
+ }
50
+ }
51
+
52
+ if (!fs.existsSync(STANDALONE)) {
53
+ console.log('[scrub] no .next/standalone to scrub');
54
+ process.exit(0);
55
+ }
56
+
57
+ walk(STANDALONE, (full, name) => {
58
+ if (DENY_FILES.includes(name) || DENY_PATTERNS.some(p => p.test(name))) {
59
+ fs.rmSync(full, { force: true });
60
+ console.log('[scrub] removed file: ' + path.relative(STANDALONE, full));
61
+ }
62
+ });
63
+
64
+ // Final scan: refuse to publish if any obvious secrets remain in text files
65
+ const SECRET_PATTERNS = [
66
+ /npm_[A-Za-z0-9]{30,}/,
67
+ /sk-ant-[A-Za-z0-9_-]{20,}/,
68
+ /ghp_[A-Za-z0-9]{30,}/,
69
+ ];
70
+ let leaked = false;
71
+ walk(STANDALONE, (full, name) => {
72
+ if (!/\.(js|json|md|txt|log|ts|tsx|mjs|cjs)$/i.test(name)) return;
73
+ let content;
74
+ try { content = fs.readFileSync(full, 'utf-8'); } catch { return; }
75
+ for (const p of SECRET_PATTERNS) {
76
+ const m = content.match(p);
77
+ if (m) {
78
+ console.error('[scrub] SECRET DETECTED in ' + path.relative(STANDALONE, full) + ': ' + m[0].slice(0, 12) + '...');
79
+ leaked = true;
80
+ }
81
+ }
82
+ });
83
+
84
+ if (leaked) {
85
+ console.error('[scrub] aborting publish — secrets found in build output');
86
+ process.exit(1);
87
+ }
88
+
89
+ console.log('[scrub] done — standalone clean');
@@ -1334,8 +1334,11 @@ function handleConnection(wss, ws, req) {
1334
1334
  const rawAgentSession = url.searchParams.get('agentSession') || '';
1335
1335
  const agentSession = (rawAgentSession === 'new' || SESSION_ID_RE.test(rawAgentSession)) ? rawAgentSession : '';
1336
1336
  const rawCustomCommand = url.searchParams.get('customCommand') || '';
1337
- // Sanitize: reject shell metacharacters that enable injection (;, |, &, $, `, etc.)
1338
- const customCommand = /[;&|`$(){}]/.test(rawCustomCommand) ? '' : rawCustomCommand;
1337
+ // Sanitize via allowlist. Any character outside [A-Za-z0-9 . _ - /] is rejected.
1338
+ // Earlier blocklist (/[;&|`$(){}]/) missed newlines, redirects (<,>), and
1339
+ // backslashes — a payload like "legit\nmalicious" would inject a second command
1340
+ // when the PTY wrote it with a trailing \r.
1341
+ const customCommand = /^[A-Za-z0-9._\-/ ]+$/.test(rawCustomCommand) ? rawCustomCommand : '';
1339
1342
  const cols = parseInt(url.searchParams.get('cols') || '120', 10);
1340
1343
  const rows = parseInt(url.searchParams.get('rows') || '30', 10);
1341
1344
 
@@ -1554,8 +1557,25 @@ function handleConnection(wss, ws, req) {
1554
1557
  // Detect bash-on-Windows so cd commands use bash syntax, not cmd.exe `cd /d`
1555
1558
  const isBashOnWindows = isWindows && shell && (shell.endsWith('bash.exe') || shell.endsWith('bash'));
1556
1559
 
1557
- const env = { ...process.env };
1558
- delete env.CLAUDECODE;
1560
+ // Build a minimal env for the user-facing PTY — never inherit the server's
1561
+ // secrets (SPACES_SESSION_SECRET, GH_PAT, NPM_TOKEN, ANTHROPIC_API_KEY, etc).
1562
+ // Only forward identity/shell/locale/terminal basics from the server env.
1563
+ const PTY_ENV_ALLOW = [
1564
+ 'HOME', 'USER', 'LOGNAME', 'SHELL', 'PATH', 'PWD', 'OLDPWD', 'HOSTNAME',
1565
+ 'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', 'LC_COLLATE', 'LC_TIME',
1566
+ 'LC_NUMERIC', 'LC_MONETARY', 'TZ',
1567
+ 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_RUNTIME_DIR',
1568
+ 'XDG_STATE_HOME',
1569
+ 'TERM', 'TERM_PROGRAM', 'TERM_PROGRAM_VERSION', 'COLORTERM', 'COLUMNS', 'LINES',
1570
+ 'NODE_ENV', 'NVM_DIR', 'NVM_BIN',
1571
+ // Windows basics
1572
+ 'SYSTEMROOT', 'WINDIR', 'APPDATA', 'LOCALAPPDATA', 'USERPROFILE', 'COMSPEC',
1573
+ 'PATHEXT', 'PROGRAMFILES', 'PROGRAMFILES(X86)', 'PROGRAMDATA',
1574
+ ];
1575
+ const env = {};
1576
+ for (const k of PTY_ENV_ALLOW) {
1577
+ if (process.env[k] !== undefined) env[k] = process.env[k];
1578
+ }
1559
1579
  // Enable prompt suggestions in spawned Claude Code sessions
1560
1580
  env.CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION = 'true';
1561
1581
  // Tell Claude Code where git-bash is so it doesn't fail the bash detection
@@ -2208,19 +2228,30 @@ async function handleProxyConnection(clientWs, nodeId, opts) {
2208
2228
  return;
2209
2229
  }
2210
2230
 
2211
- // Get the remote WebSocket URL via the terminal token endpoint
2212
- // Only skip TLS verification if explicitly opted in (e.g., self-signed certs)
2231
+ // Get the remote WebSocket URL via the terminal token endpoint.
2232
+ // If the user opted into skipping TLS verification (for self-signed federation
2233
+ // certs), scope it to JUST this request via an undici Agent rather than the
2234
+ // process-global NODE_TLS_REJECT_UNAUTHORIZED env var, which would disable
2235
+ // cert verification for every outbound TLS connection in the process and
2236
+ // race with concurrent requests.
2213
2237
  const skipTls = process.env.SPACES_SKIP_TLS_VERIFY === '1';
2214
- const prevTls = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
2215
- if (skipTls) process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
2238
+ let fetchOptions = {
2239
+ method: 'POST',
2240
+ headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
2241
+ signal: AbortSignal.timeout(10000),
2242
+ };
2243
+ if (skipTls) {
2244
+ try {
2245
+ const { Agent } = require('undici');
2246
+ fetchOptions.dispatcher = new Agent({ connect: { rejectUnauthorized: false } });
2247
+ } catch (e) {
2248
+ console.warn('[Proxy] undici unavailable for per-request TLS opt-out; refusing to fall back to global flag');
2249
+ }
2250
+ }
2216
2251
  let remoteWsUrl;
2217
2252
  try {
2218
2253
  const tokenUrl = `${node.url}/api/network/terminal/token/`;
2219
- const res = await fetch(tokenUrl, {
2220
- method: 'POST',
2221
- headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
2222
- signal: AbortSignal.timeout(10000),
2223
- });
2254
+ const res = await fetch(tokenUrl, fetchOptions);
2224
2255
 
2225
2256
  if (!res.ok) {
2226
2257
  let detail = '';
@@ -2236,9 +2267,6 @@ async function handleProxyConnection(clientWs, nodeId, opts) {
2236
2267
  clientWs.send(JSON.stringify({ type: 'error', data: `Cannot reach remote node: ${err.message}` }));
2237
2268
  clientWs.close();
2238
2269
  return;
2239
- } finally {
2240
- if (prevTls === undefined) delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
2241
- else process.env.NODE_TLS_REJECT_UNAUTHORIZED = prevTls;
2242
2270
  }
2243
2271
 
2244
2272
  // Connect to remote terminal server using the API key directly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jlongo78/agent-spaces",
3
- "version": "0.9.8",
3
+ "version": "0.9.10",
4
4
  "description": "Agent workspace manager for Claude, Codex, Gemini, and more",
5
5
  "bin": {
6
6
  "spaces": "./bin/spaces.js"
@@ -32,7 +32,7 @@
32
32
  "dev": "node bin/spaces-dev.js",
33
33
  "build": "cross-env STANDALONE=1 next build && node -e \"const fs=require('fs');fs.cpSync('.next/static','.next/standalone/.next/static',{recursive:true});fs.cpSync('public','.next/standalone/public',{recursive:true})\" && node bin/fix-standalone-externals.js",
34
34
  "postinstall": "node bin/spaces-postinstall.js || true",
35
- "prepublishOnly": "npm run build",
35
+ "prepublishOnly": "npm run build && node bin/scrub-standalone.js",
36
36
  "setup": "node bin/spaces-setup.js",
37
37
  "setup-admin": "node bin/setup-admin.js",
38
38
  "server:build": "next build",
@@ -1,68 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm view:*)",
5
- "Bash(npm publish:*)",
6
- "Bash(where spaces:*)",
7
- "Bash(node:*)",
8
- "Bash(npm run:*)",
9
- "Bash(curl:*)",
10
- "Bash(powershell:*)",
11
- "Bash(spaces service:*)",
12
- "Bash(git:*)",
13
- "Bash(npm whoami:*)",
14
- "Read(//c/Users/johns/.spaces/packages/pro/**)",
15
- "Bash(npx tsc)",
16
- "Bash(node -e \"console.log\\(require\\('./package.json'\\).version\\)\")",
17
- "Bash(find /d/projects/spaces/src -type f \\\\\\( -name \"*.tsx\" -o -name \"*.ts\" \\\\\\) -exec grep -l \"template\\\\|Template\" {} \\\\;)",
18
- "Bash(npx next:*)"
19
- ]
20
- },
21
- "hooks": {
22
- "UserPromptSubmit": [
23
- {
24
- "hooks": [
25
- {
26
- "type": "command",
27
- "command": "node \"D:\\projects\\spaces\\bin\\cortex-hook.js\"",
28
- "timeout": 15
29
- }
30
- ]
31
- }
32
- ],
33
- "Stop": [
34
- {
35
- "hooks": [
36
- {
37
- "type": "command",
38
- "command": "node \"D:\\projects\\spaces\\bin\\cortex-learn-hook.js\"",
39
- "timeout": 10
40
- }
41
- ]
42
- }
43
- ],
44
- "SessionStart": [
45
- {
46
- "hooks": [
47
- {
48
- "type": "command",
49
- "command": "node \"C:\\Users\\johns\\.spaces\\packages\\teams\\bin\\spaces-hook.js\" a64f4c8c-f9de-4f51-98ed-b100ebcc7638",
50
- "timeout": 10000
51
- }
52
- ]
53
- }
54
- ]
55
- },
56
- "mcpServers": {
57
- "cortex": {
58
- "command": "node",
59
- "args": [
60
- "D:\\projects\\spaces\\bin\\cortex-mcp.js"
61
- ],
62
- "env": {
63
- "SPACES_URL": "http://localhost:3457",
64
- "SPACES_INTERNAL_TOKEN": "5a6d378a74905803"
65
- }
66
- }
67
- }
68
- }
@@ -1 +0,0 @@
1
- {"workspaceId":"2","port":3457}