conductor-oss 0.2.5 → 0.2.6

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 (492) hide show
  1. package/README.md +29 -6
  2. package/dist/commands/init.d.ts +2 -0
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +3 -0
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/setup.d.ts +30 -0
  7. package/dist/commands/setup.d.ts.map +1 -1
  8. package/dist/commands/setup.js +131 -29
  9. package/dist/commands/setup.js.map +1 -1
  10. package/dist/commands/start.d.ts +3 -0
  11. package/dist/commands/start.d.ts.map +1 -1
  12. package/dist/commands/start.js +209 -15
  13. package/dist/commands/start.js.map +1 -1
  14. package/dist/index.js +1 -1
  15. package/node_modules/@conductor-oss/core/dist/config.d.ts +1 -1
  16. package/node_modules/@conductor-oss/core/dist/config.d.ts.map +1 -1
  17. package/node_modules/@conductor-oss/core/dist/config.js +34 -0
  18. package/node_modules/@conductor-oss/core/dist/config.js.map +1 -1
  19. package/node_modules/@conductor-oss/core/dist/scaffold.d.ts +14 -0
  20. package/node_modules/@conductor-oss/core/dist/scaffold.d.ts.map +1 -1
  21. package/node_modules/@conductor-oss/core/dist/scaffold.js +27 -4
  22. package/node_modules/@conductor-oss/core/dist/scaffold.js.map +1 -1
  23. package/node_modules/@conductor-oss/core/dist/types.d.ts +71 -0
  24. package/node_modules/@conductor-oss/core/dist/types.d.ts.map +1 -1
  25. package/node_modules/@conductor-oss/core/dist/types.js +244 -0
  26. package/node_modules/@conductor-oss/core/dist/types.js.map +1 -1
  27. package/node_modules/@conductor-oss/core/package.json +1 -1
  28. package/node_modules/@conductor-oss/plugin-agent-amp/dist/index.js +1 -1
  29. package/node_modules/@conductor-oss/plugin-agent-amp/package.json +2 -2
  30. package/node_modules/@conductor-oss/plugin-agent-ccr/dist/index.js +1 -1
  31. package/node_modules/@conductor-oss/plugin-agent-ccr/package.json +2 -2
  32. package/node_modules/@conductor-oss/plugin-agent-claude-code/dist/index.js +1 -1
  33. package/node_modules/@conductor-oss/plugin-agent-claude-code/package.json +2 -2
  34. package/node_modules/@conductor-oss/plugin-agent-codex/dist/index.js +1 -1
  35. package/node_modules/@conductor-oss/plugin-agent-codex/package.json +2 -2
  36. package/node_modules/@conductor-oss/plugin-agent-cursor-cli/dist/index.js +1 -1
  37. package/node_modules/@conductor-oss/plugin-agent-cursor-cli/package.json +2 -2
  38. package/node_modules/@conductor-oss/plugin-agent-droid/dist/index.js +1 -1
  39. package/node_modules/@conductor-oss/plugin-agent-droid/package.json +2 -2
  40. package/node_modules/@conductor-oss/plugin-agent-gemini/dist/index.js +1 -1
  41. package/node_modules/@conductor-oss/plugin-agent-gemini/package.json +2 -2
  42. package/node_modules/@conductor-oss/plugin-agent-github-copilot/dist/index.js +1 -1
  43. package/node_modules/@conductor-oss/plugin-agent-github-copilot/package.json +2 -2
  44. package/node_modules/@conductor-oss/plugin-agent-opencode/dist/index.js +1 -1
  45. package/node_modules/@conductor-oss/plugin-agent-opencode/package.json +2 -2
  46. package/node_modules/@conductor-oss/plugin-agent-qwen-code/dist/index.js +10 -6
  47. package/node_modules/@conductor-oss/plugin-agent-qwen-code/package.json +2 -2
  48. package/node_modules/@conductor-oss/plugin-mcp-server/dist/index.js +1 -1
  49. package/node_modules/@conductor-oss/plugin-mcp-server/package.json +2 -2
  50. package/node_modules/@conductor-oss/plugin-notifier-desktop/dist/index.js +1 -1
  51. package/node_modules/@conductor-oss/plugin-notifier-desktop/package.json +2 -2
  52. package/node_modules/@conductor-oss/plugin-notifier-discord/dist/index.js +1 -1
  53. package/node_modules/@conductor-oss/plugin-notifier-discord/package.json +2 -2
  54. package/node_modules/@conductor-oss/plugin-runtime-tmux/dist/index.js +1 -1
  55. package/node_modules/@conductor-oss/plugin-runtime-tmux/package.json +2 -2
  56. package/node_modules/@conductor-oss/plugin-scm-github/dist/index.js +1 -1
  57. package/node_modules/@conductor-oss/plugin-scm-github/package.json +2 -2
  58. package/node_modules/@conductor-oss/plugin-terminal-web/dist/index.js +1 -1
  59. package/node_modules/@conductor-oss/plugin-terminal-web/package.json +2 -2
  60. package/node_modules/@conductor-oss/plugin-tracker-github/dist/index.js +1 -1
  61. package/node_modules/@conductor-oss/plugin-tracker-github/package.json +2 -2
  62. package/node_modules/@conductor-oss/plugin-webhook/package.json +2 -2
  63. package/node_modules/@conductor-oss/plugin-workspace-worktree/dist/index.js +1 -1
  64. package/node_modules/@conductor-oss/plugin-workspace-worktree/package.json +2 -2
  65. package/package.json +22 -21
  66. package/web/.next/standalone/packages/web/.next/BUILD_ID +1 -1
  67. package/web/.next/standalone/packages/web/.next/app-path-routes-manifest.json +5 -1
  68. package/web/.next/standalone/packages/web/.next/build-manifest.json +4 -4
  69. package/web/.next/standalone/packages/web/.next/routes-manifest.json +24 -0
  70. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  71. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  72. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  73. package/web/.next/standalone/packages/web/.next/server/app/_global-error.html +2 -2
  74. package/web/.next/standalone/packages/web/.next/server/app/_global-error.rsc +1 -1
  75. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  76. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  77. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  78. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  79. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  80. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  81. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  82. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  83. package/web/.next/standalone/packages/web/.next/server/app/_not-found.html +1 -1
  84. package/web/.next/standalone/packages/web/.next/server/app/_not-found.rsc +9 -9
  85. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_full.segment.rsc +9 -9
  86. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  87. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -5
  88. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  89. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  90. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  91. package/web/.next/standalone/packages/web/.next/server/app/api/access/route/app-paths-manifest.json +3 -0
  92. package/web/.next/standalone/packages/web/.next/server/app/api/access/route/build-manifest.json +11 -0
  93. package/web/.next/standalone/packages/web/.next/server/app/api/access/route/server-reference-manifest.json +4 -0
  94. package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js +11 -0
  95. package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js.map +5 -0
  96. package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js.nft.json +1 -0
  97. package/web/.next/standalone/packages/web/.next/server/app/api/access/route_client-reference-manifest.js +2 -0
  98. package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js +5 -3
  99. package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js.nft.json +1 -1
  100. package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js +4 -2
  101. package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js.nft.json +1 -1
  102. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route/app-paths-manifest.json +3 -0
  103. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route/build-manifest.json +11 -0
  104. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route/server-reference-manifest.json +4 -0
  105. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js +8 -0
  106. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js.map +5 -0
  107. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js.nft.json +1 -0
  108. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route_client-reference-manifest.js +2 -0
  109. package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js +5 -3
  110. package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js.nft.json +1 -1
  111. package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js +4 -2
  112. package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js.nft.json +1 -1
  113. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js +3 -1
  114. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js.nft.json +1 -1
  115. package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js +4 -2
  116. package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js.nft.json +1 -1
  117. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js +3 -1
  118. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js.nft.json +1 -1
  119. package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js +4 -2
  120. package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js.nft.json +1 -1
  121. package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js +3 -1
  122. package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js.nft.json +1 -1
  123. package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js +5 -3
  124. package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js.nft.json +1 -1
  125. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js +5 -3
  126. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js.nft.json +1 -1
  127. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js +4 -2
  128. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js.nft.json +1 -1
  129. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js +4 -2
  130. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js.nft.json +1 -1
  131. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js +4 -2
  132. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js.nft.json +1 -1
  133. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js +3 -1
  134. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js.nft.json +1 -1
  135. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/keys/route.js +3 -1
  136. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/keys/route.js.nft.json +1 -1
  137. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js +4 -2
  138. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -1
  139. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js +4 -2
  140. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js.nft.json +1 -1
  141. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/stream/route.js +4 -2
  142. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/stream/route.js.nft.json +1 -1
  143. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js +4 -2
  144. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -1
  145. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js +3 -1
  146. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  147. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/send/route.js +4 -2
  148. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/send/route.js.nft.json +1 -1
  149. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js +3 -1
  150. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  151. package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js +5 -3
  152. package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js.nft.json +1 -1
  153. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js +3 -1
  154. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js.nft.json +1 -1
  155. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js +5 -3
  156. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  157. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route/app-paths-manifest.json +3 -0
  158. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route/build-manifest.json +11 -0
  159. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route/server-reference-manifest.json +4 -0
  160. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route.js +8 -0
  161. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route.js.map +5 -0
  162. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route.js.nft.json +1 -0
  163. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route_client-reference-manifest.js +2 -0
  164. package/web/.next/standalone/packages/web/.next/server/app/index.html +1 -1
  165. package/web/.next/standalone/packages/web/.next/server/app/index.rsc +4 -4
  166. package/web/.next/standalone/packages/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  167. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  168. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  169. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_index.segment.rsc +3 -3
  170. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  171. package/web/.next/standalone/packages/web/.next/server/app/page/build-manifest.json +2 -2
  172. package/web/.next/standalone/packages/web/.next/server/app/page.js.nft.json +1 -1
  173. package/web/.next/standalone/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
  174. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page/build-manifest.json +2 -2
  175. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  176. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  177. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page/build-manifest.json +2 -2
  178. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page.js.nft.json +1 -1
  179. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page_client-reference-manifest.js +1 -1
  180. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/app-paths-manifest.json +3 -0
  181. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/build-manifest.json +18 -0
  182. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/next-font-manifest.json +14 -0
  183. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/react-loadable-manifest.json +1 -0
  184. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/server-reference-manifest.json +110 -0
  185. package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js +19 -0
  186. package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js.map +5 -0
  187. package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js.nft.json +1 -0
  188. package/web/.next/standalone/packages/web/.next/server/app/unlock/page_client-reference-manifest.js +2 -0
  189. package/web/.next/standalone/packages/web/.next/server/app-paths-manifest.json +5 -1
  190. package/web/.next/standalone/packages/web/.next/server/chunks/1bc17_next_dist_esm_build_templates_app-route_1651710d.js +1 -1
  191. package/web/.next/standalone/packages/web/.next/server/chunks/1bc17_next_dist_esm_build_templates_app-route_34b04c2b.js +1 -1
  192. package/web/.next/standalone/packages/web/.next/server/chunks/1bc17_next_dist_esm_build_templates_app-route_9c655a1d.js +3 -3
  193. package/web/.next/standalone/packages/web/.next/server/chunks/1bc17_next_dist_esm_build_templates_app-route_b41c4976.js +1 -1
  194. package/web/.next/standalone/packages/web/.next/server/chunks/1bc17_next_dist_esm_build_templates_app-route_f4104ae4.js +1 -1
  195. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__005aa909._.js +1 -1
  196. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__03ff76ee._.js +1 -1
  197. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__07ec6d5c._.js +1 -1
  198. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0a0f0f01._.js +1 -1
  199. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0ad3545b._.js +5 -5
  200. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__04d7f8e9._.js → [root-of-the-server]__0c65150d._.js} +2 -2
  201. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__39e2947e._.js → [root-of-the-server]__0d615ef4._.js} +2 -2
  202. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__13ad088c._.js +1 -1
  203. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__14b1d4a3._.js +1 -1
  204. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__000a39bb._.js → [root-of-the-server]__14d277b3._.js} +2 -2
  205. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1741fb8a._.js +1 -1
  206. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__17d81825._.js +3 -0
  207. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__4266ed21._.js → [root-of-the-server]__1b7c6a55._.js} +2 -2
  208. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1e288076._.js +3 -0
  209. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1f626a16._.js +1 -1
  210. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1f712b77._.js +3 -0
  211. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2062aaab._.js +1 -1
  212. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__206c3d8a._.js +1 -1
  213. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__9469f247._.js → [root-of-the-server]__230d54da._.js} +2 -2
  214. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__24d8e6fc._.js +3 -0
  215. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2556a816._.js +1 -1
  216. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2af6c2e0._.js +3 -0
  217. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2d57abda._.js +3 -0
  218. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__30b0f109._.js +3 -0
  219. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__30c75561._.js +3 -0
  220. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__31c39bd9._.js +3 -0
  221. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__7e505454._.js → [root-of-the-server]__341657dd._.js} +2 -2
  222. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__34a19860._.js +3 -0
  223. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3fde7043._.js +1 -1
  224. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__40c8037e._.js +2 -2
  225. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__41ee872a._.js +3 -0
  226. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__44606e04._.js +1 -1
  227. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__44d59fd0._.js +1 -1
  228. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__459839a6._.js +3 -0
  229. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__46a8e776._.js +3 -0
  230. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__48875cbb._.js +1 -1
  231. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__b3f4ff98._.js → [root-of-the-server]__488ab4b2._.js} +2 -2
  232. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4ac9d639._.js +1 -1
  233. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4c3fb752._.js +1 -1
  234. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4dab6a6a._.js +1 -1
  235. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__544326ac._.js +1 -1
  236. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5494c5a2._.js +3 -0
  237. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__54a218f0._.js +3 -3
  238. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__54a76cd2._.js +1 -1
  239. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5661ca72._.js +1 -1
  240. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__568f0a6e._.js +3 -0
  241. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5cd49624._.js +1 -1
  242. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5d76c5af._.js +3 -0
  243. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5e0533de._.js +1 -1
  244. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5f628cf2._.js +3 -0
  245. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__62608541._.js +1 -1
  246. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6d62709d._.js +5 -5
  247. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6e4e09be._.js +3 -0
  248. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__70258e45._.js +3 -0
  249. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__917adaec._.js → [root-of-the-server]__711dc459._.js} +2 -2
  250. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__720136dd._.js +3 -0
  251. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__749331b0._.js +3 -3
  252. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__755c7e10._.js +3 -0
  253. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__778e46a1._.js +5 -5
  254. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7e6ea46e._.js +1 -1
  255. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7f023a04._.js +4 -4
  256. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7f2ed2cd._.js +3 -0
  257. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7fa52da6._.js +1 -1
  258. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__82171aa3._.js +9 -0
  259. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__84362910._.js +1 -1
  260. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__848eb266._.js +1 -1
  261. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__8596d782._.js +1 -1
  262. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__85c5cb36._.js +3 -0
  263. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__878fbacc._.js +3 -0
  264. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__881858fa._.js +1 -1
  265. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__885e3a00._.js +3 -3
  266. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__893f6b3b._.js +1 -1
  267. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__8ac30f97._.js +3 -0
  268. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__8c519453._.js +1 -1
  269. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__919845e0._.js +3 -0
  270. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__9b62b450._.js → [root-of-the-server]__927b9bce._.js} +2 -2
  271. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__93b3582e._.js +3 -0
  272. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__964f4e89._.js +3 -0
  273. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__96633022._.js +1 -1
  274. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__98697e45._.js +1 -1
  275. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__997ebfca._.js +3 -0
  276. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9c930222._.js +3 -0
  277. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9f36b7ec._.js +5 -5
  278. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a44f91a4._.js +3 -3
  279. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__1bc4f8f5._.js → [root-of-the-server]__a5d13971._.js} +2 -2
  280. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a6c7bd91._.js +3 -0
  281. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ae580a1a._.js +3 -0
  282. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__af533b5e._.js +3 -0
  283. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__afa79f55._.js +1 -1
  284. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b057f7b2._.js +1 -1
  285. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b59abfbd._.js +1 -1
  286. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__bd8ace80._.js +3 -0
  287. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__be0f2c29._.js +3 -0
  288. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__bea07e07._.js +1 -1
  289. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c8618cb1._.js +1 -1
  290. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__caf8e7cb._.js +1 -1
  291. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cb112606._.js +1 -1
  292. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cb51f2e3._.js +3 -0
  293. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cba32afb._.js +3 -0
  294. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cc74ea40._.js +1 -1
  295. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cd3692a0._.js +1 -1
  296. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cf3cdecd._.js +1 -1
  297. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d09e7a99._.js +1 -1
  298. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d538c110._.js +1 -1
  299. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d93447b9._.js +1 -1
  300. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d9c80b18._.js +3 -0
  301. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__dc0959da._.js +3 -0
  302. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__dda8eac1._.js +1 -1
  303. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__df2c6efe._.js +3 -0
  304. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e113f6df._.js +1 -1
  305. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e2573a77._.js +1 -1
  306. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e2d60274._.js +3 -0
  307. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e308bb89._.js +1 -1
  308. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e345a443._.js +3 -0
  309. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e80a520f._.js +3 -0
  310. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ea0bb124._.js +3 -0
  311. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ef773ea6._.js +1 -1
  312. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f0d15920._.js +1 -1
  313. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__b029d2c1._.js → [root-of-the-server]__f2f30c04._.js} +2 -2
  314. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f47a2a9e._.js +1 -1
  315. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f48eb2d4._.js +1 -1
  316. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f6a8bbd9._.js +12 -12
  317. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__faceea9b._.js +1 -1
  318. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__fb6ab669._.js +1 -1
  319. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__fcf96768._.js +3 -0
  320. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__fdaa8058._.js +7 -0
  321. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ff2b205d._.js +3 -0
  322. package/web/.next/standalone/packages/web/.next/server/chunks/packages_core_dist_index_cdd30418.js +1 -1
  323. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-amp_dist_index_bf3d8239.js +1 -1
  324. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-ccr_dist_index_69cbf726.js +1 -1
  325. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-claude-code_dist_index_31314e43.js +1 -1
  326. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-cursor-cli_dist_index_8d5cc426.js +1 -1
  327. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-droid_dist_index_f731227a.js +1 -1
  328. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-gemini_dist_index_b2d219e8.js +1 -1
  329. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-github-copilot_dist_index_9f80cb45.js +1 -1
  330. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-opencode_dist_index_7c7015da.js +1 -1
  331. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_agent-qwen-code_dist_index_46dd8653.js +1 -1
  332. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_notifier-desktop_dist_index_ef3473f0.js +1 -1
  333. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_notifier-discord_dist_index_34257226.js +1 -1
  334. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_scm-github_dist_index_3b5a621e.js +1 -1
  335. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_terminal-web_dist_index_1e0706d3.js +1 -1
  336. package/web/.next/standalone/packages/web/.next/server/chunks/packages_plugins_tracker-github_dist_index_2d7af62f.js +1 -1
  337. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_api_access_route_actions_06740e99.js +3 -0
  338. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_api_auth_session_route_actions_078c0ee4.js +3 -0
  339. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_auth_grant_route_actions_13ba4421.js +3 -0
  340. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web_src_lib_13fee5eb._.js +3 -0
  341. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web_src_lib_d64596cc._.js +3 -0
  342. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__1ddf22db._.js → [root-of-the-server]__1012a4c8._.js} +2 -2
  343. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__ed81e796._.js → [root-of-the-server]__81affb12._.js} +2 -2
  344. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__95e85d3d._.js +3 -0
  345. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__f577d85a._.js → [root-of-the-server]__9d698773._.js} +2 -2
  346. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__a38f483b._.js +1 -1
  347. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__3bf3fbfb._.js → [root-of-the-server]__c09a0c60._.js} +2 -2
  348. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__d9dde485._.js +1 -1
  349. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__d5970f3e._.js → [root-of-the-server]__dd435d80._.js} +2 -2
  350. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__469db3c3._.js → [root-of-the-server]__e78955d0._.js} +2 -2
  351. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_14a33487._.js +3 -0
  352. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_34d55bf1._.js +4 -0
  353. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{node_modules__pnpm_c636dc22._.js → node_modules__pnpm_597c265e._.js} +1 -1
  354. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_app_page_tsx_cd282e82._.js +1 -1
  355. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_app_unlock_UnlockForm_tsx_ce3149a7._.js +3 -0
  356. package/web/.next/standalone/packages/web/.next/server/middleware-build-manifest.js +2 -2
  357. package/web/.next/standalone/packages/web/.next/server/middleware.js +1 -1
  358. package/web/.next/standalone/packages/web/.next/server/next-font-manifest.js +1 -1
  359. package/web/.next/standalone/packages/web/.next/server/next-font-manifest.json +7 -0
  360. package/web/.next/standalone/packages/web/.next/server/pages/404.html +1 -1
  361. package/web/.next/standalone/packages/web/.next/server/pages/500.html +2 -2
  362. package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.js +1 -1
  363. package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.json +56 -7
  364. package/web/.next/{static/chunks/9b799cd7eb9a34ff.js → standalone/packages/web/.next/static/chunks/1c4c14af475ada00.js} +1 -1
  365. package/web/.next/standalone/packages/web/.next/static/chunks/ba68284a3401d670.css +3 -0
  366. package/web/.next/standalone/packages/web/.next/static/chunks/{4372fb4d7779cd64.js → d00ddc86d1af3b6d.js} +1 -1
  367. package/web/.next/standalone/packages/web/.next/static/chunks/d8f4bf59132f70fd.js +1 -0
  368. package/web/.next/standalone/packages/web/.next/static/chunks/f355d4d60f0ec80e.js +1 -0
  369. package/web/.next/standalone/packages/web/.next/static/chunks/{turbopack-c3449aaab622f98c.js → turbopack-dc658d17ee981623.js} +1 -1
  370. package/web/.next/standalone/packages/web/package.json +1 -0
  371. package/web/.next/standalone/packages/web/src/app/api/access/route.ts +214 -0
  372. package/web/.next/standalone/packages/web/src/app/api/agents/route.ts +2 -2
  373. package/web/.next/standalone/packages/web/src/app/api/attachments/route.ts +1 -1
  374. package/web/.next/standalone/packages/web/src/app/api/auth/session/route.ts +54 -0
  375. package/web/.next/standalone/packages/web/src/app/api/boards/route.ts +2 -2
  376. package/web/.next/standalone/packages/web/src/app/api/config/route.ts +2 -1
  377. package/web/.next/standalone/packages/web/src/app/api/context-files/route.ts +1 -1
  378. package/web/.next/standalone/packages/web/src/app/api/events/route.ts +1 -1
  379. package/web/.next/standalone/packages/web/src/app/api/filesystem/directory/route.ts +1 -1
  380. package/web/.next/standalone/packages/web/src/app/api/github/repos/route.ts +1 -1
  381. package/web/.next/standalone/packages/web/src/app/api/health/boards/route.ts +1 -1
  382. package/web/.next/standalone/packages/web/src/app/api/preferences/route.ts +9 -2
  383. package/web/.next/standalone/packages/web/src/app/api/repositories/route.ts +19 -2
  384. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/checks/route.ts +1 -1
  385. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/diff/route.ts +1 -1
  386. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/feedback/route.ts +1 -1
  387. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/files/route.ts +1 -1
  388. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/keys/route.ts +1 -1
  389. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/kill/route.ts +1 -1
  390. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/output/route.ts +1 -1
  391. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/output/stream/route.ts +1 -1
  392. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/restore/route.ts +1 -1
  393. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/route.ts +1 -1
  394. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/send/route.ts +1 -1
  395. package/web/.next/standalone/packages/web/src/app/api/sessions/route.ts +1 -1
  396. package/web/.next/standalone/packages/web/src/app/api/spawn/route.ts +1 -1
  397. package/web/.next/standalone/packages/web/src/app/api/workspaces/branches/route.ts +1 -1
  398. package/web/.next/standalone/packages/web/src/app/api/workspaces/route.ts +9 -2
  399. package/web/.next/standalone/packages/web/src/app/auth/grant/route.ts +37 -0
  400. package/web/.next/standalone/packages/web/src/app/page.tsx +763 -9
  401. package/web/.next/standalone/packages/web/src/app/unlock/UnlockForm.tsx +77 -0
  402. package/web/.next/standalone/packages/web/src/app/unlock/page.tsx +41 -0
  403. package/web/.next/standalone/packages/web/src/components/Dashboard.tsx +11 -125
  404. package/web/.next/standalone/packages/web/src/hooks/useConfig.ts +4 -0
  405. package/web/.next/standalone/packages/web/src/lib/accessControl.test.ts +46 -0
  406. package/web/.next/standalone/packages/web/src/lib/accessControl.ts +115 -0
  407. package/web/.next/standalone/packages/web/src/lib/auth.ts +294 -53
  408. package/web/.next/standalone/packages/web/src/lib/edgeAuth.test.ts +91 -0
  409. package/web/.next/standalone/packages/web/src/lib/edgeAuth.ts +205 -0
  410. package/web/.next/standalone/packages/web/src/lib/modelAccess.ts +40 -0
  411. package/web/.next/standalone/packages/web/src/lib/projectConfigSync.ts +2 -0
  412. package/web/.next/standalone/packages/web/src/lib/remoteAuth.ts +104 -0
  413. package/web/.next/standalone/packages/web/src/proxy.ts +64 -0
  414. package/web/.next/standalone/packages/web/tsconfig.tsbuildinfo +1 -1
  415. package/web/.next/{standalone/packages/web/.next/static/chunks/9b799cd7eb9a34ff.js → static/chunks/1c4c14af475ada00.js} +1 -1
  416. package/web/.next/static/chunks/ba68284a3401d670.css +3 -0
  417. package/web/.next/static/chunks/{4372fb4d7779cd64.js → d00ddc86d1af3b6d.js} +1 -1
  418. package/web/.next/static/chunks/d8f4bf59132f70fd.js +1 -0
  419. package/web/.next/static/chunks/f355d4d60f0ec80e.js +1 -0
  420. package/web/.next/static/chunks/{turbopack-c3449aaab622f98c.js → turbopack-dc658d17ee981623.js} +1 -1
  421. package/node_modules/@conductor-oss/core/dist/__tests__/board-parser.test.d.ts +0 -2
  422. package/node_modules/@conductor-oss/core/dist/__tests__/board-parser.test.d.ts.map +0 -1
  423. package/node_modules/@conductor-oss/core/dist/__tests__/board-parser.test.js +0 -67
  424. package/node_modules/@conductor-oss/core/dist/__tests__/board-parser.test.js.map +0 -1
  425. package/node_modules/@conductor-oss/core/dist/__tests__/board-watcher-support-files.test.d.ts +0 -2
  426. package/node_modules/@conductor-oss/core/dist/__tests__/board-watcher-support-files.test.d.ts.map +0 -1
  427. package/node_modules/@conductor-oss/core/dist/__tests__/board-watcher-support-files.test.js +0 -122
  428. package/node_modules/@conductor-oss/core/dist/__tests__/board-watcher-support-files.test.js.map +0 -1
  429. package/node_modules/@conductor-oss/core/dist/__tests__/project-paths.test.d.ts +0 -2
  430. package/node_modules/@conductor-oss/core/dist/__tests__/project-paths.test.d.ts.map +0 -1
  431. package/node_modules/@conductor-oss/core/dist/__tests__/project-paths.test.js +0 -48
  432. package/node_modules/@conductor-oss/core/dist/__tests__/project-paths.test.js.map +0 -1
  433. package/node_modules/@conductor-oss/core/dist/agent-cli-runtime.d.ts +0 -20
  434. package/node_modules/@conductor-oss/core/dist/agent-cli-runtime.d.ts.map +0 -1
  435. package/node_modules/@conductor-oss/core/dist/agent-cli-runtime.js +0 -192
  436. package/node_modules/@conductor-oss/core/dist/agent-cli-runtime.js.map +0 -1
  437. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__019d9c90._.js +0 -3
  438. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__08a3e108._.js +0 -3
  439. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0b0ab434._.js +0 -3
  440. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0e59a166._.js +0 -3
  441. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__16fb4c3e._.js +0 -9
  442. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2ff87bed._.js +0 -3
  443. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3c1772ab._.js +0 -3
  444. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5093c7e0._.js +0 -3
  445. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__53970b23._.js +0 -3
  446. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5a67f1f9._.js +0 -3
  447. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5cf55740._.js +0 -3
  448. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5d124f64._.js +0 -3
  449. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6cad94c3._.js +0 -3
  450. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6d28affc._.js +0 -3
  451. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6f6826fa._.js +0 -3
  452. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6f84fa49._.js +0 -3
  453. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__70c9c405._.js +0 -3
  454. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__711294a3._.js +0 -3
  455. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7791414d._.js +0 -3
  456. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7fb2ee11._.js +0 -7
  457. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__86646048._.js +0 -3
  458. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a15b5527._.js +0 -3
  459. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a4a89ac9._.js +0 -3
  460. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a8a53d4a._.js +0 -3
  461. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a93c59df._.js +0 -3
  462. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__abf6274f._.js +0 -3
  463. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b091b8bc._.js +0 -3
  464. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b87de88e._.js +0 -3
  465. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__bc304d71._.js +0 -3
  466. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__be52402d._.js +0 -3
  467. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__be74f171._.js +0 -3
  468. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c03aa571._.js +0 -3
  469. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c2850420._.js +0 -3
  470. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c82b8934._.js +0 -3
  471. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__deafbc7a._.js +0 -3
  472. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e18c8e77._.js +0 -3
  473. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e1f610fb._.js +0 -3
  474. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e4976f6d._.js +0 -3
  475. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ec21c9a4._.js +0 -3
  476. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ec256a62._.js +0 -3
  477. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__edc8e5a5._.js +0 -3
  478. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f2c28004._.js +0 -3
  479. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f7c743c0._.js +0 -3
  480. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f95f5172._.js +0 -3
  481. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__fc292e1c._.js +0 -3
  482. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ffbf3faf._.js +0 -3
  483. package/web/.next/standalone/packages/web/.next/static/chunks/687bc713618f6993.js +0 -1
  484. package/web/.next/standalone/packages/web/.next/static/chunks/e7bb96d7efad8e32.css +0 -3
  485. package/web/.next/static/chunks/687bc713618f6993.js +0 -1
  486. package/web/.next/static/chunks/e7bb96d7efad8e32.css +0 -3
  487. /package/web/.next/standalone/packages/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_buildManifest.js +0 -0
  488. /package/web/.next/standalone/packages/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_clientMiddlewareManifest.json +0 -0
  489. /package/web/.next/standalone/packages/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_ssgManifest.js +0 -0
  490. /package/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_buildManifest.js +0 -0
  491. /package/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_clientMiddlewareManifest.json +0 -0
  492. /package/web/.next/static/{2lp61OU9Asm88Hx_JCL5e → tV9IvZT_f540bpw2KonCu}/_ssgManifest.js +0 -0
@@ -0,0 +1,77 @@
1
+ "use client";
2
+
3
+ import { type FormEvent, useState } from "react";
4
+ import { useRouter } from "next/navigation";
5
+
6
+ type UnlockFormProps = {
7
+ initialError: string | null;
8
+ nextPath: string;
9
+ };
10
+
11
+ export function UnlockForm({ initialError, nextPath }: UnlockFormProps) {
12
+ const router = useRouter();
13
+ const [token, setToken] = useState("");
14
+ const [submitting, setSubmitting] = useState(false);
15
+ const [error, setError] = useState<string | null>(initialError);
16
+
17
+ async function handleSubmit(event: FormEvent<HTMLFormElement>): Promise<void> {
18
+ event.preventDefault();
19
+ setSubmitting(true);
20
+ setError(null);
21
+
22
+ try {
23
+ const response = await fetch("/api/auth/session", {
24
+ method: "POST",
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ },
28
+ body: JSON.stringify({ token }),
29
+ });
30
+
31
+ if (!response.ok) {
32
+ const payload = await response.json().catch(() => null) as { error?: string } | null;
33
+ setError(payload?.error ?? "Unable to unlock this Conductor session.");
34
+ return;
35
+ }
36
+
37
+ router.replace(nextPath);
38
+ router.refresh();
39
+ } finally {
40
+ setSubmitting(false);
41
+ }
42
+ }
43
+
44
+ return (
45
+ <form className="mt-6 space-y-4" onSubmit={(event) => void handleSubmit(event)}>
46
+ <label className="block space-y-2">
47
+ <span className="text-sm font-medium text-[var(--text-strong)]">Access token</span>
48
+ <input
49
+ autoCapitalize="none"
50
+ autoComplete="one-time-code"
51
+ autoCorrect="off"
52
+ className="w-full rounded-[var(--radius-md)] border bg-[var(--bg-elevated)] px-3 py-2 text-sm text-[var(--text-strong)] outline-none transition focus:border-[var(--accent-primary)]"
53
+ inputMode="text"
54
+ onChange={(event) => setToken(event.target.value)}
55
+ placeholder="Paste the Conductor access token"
56
+ spellCheck={false}
57
+ type="password"
58
+ value={token}
59
+ />
60
+ </label>
61
+
62
+ {error ? (
63
+ <p className="rounded-[var(--radius-md)] border border-red-500/40 bg-red-500/10 px-3 py-2 text-sm text-red-200">
64
+ {error}
65
+ </p>
66
+ ) : null}
67
+
68
+ <button
69
+ className="inline-flex w-full items-center justify-center rounded-[var(--radius-md)] bg-[var(--accent-primary)] px-4 py-2 text-sm font-medium text-[var(--accent-contrast)] transition hover:opacity-95 disabled:cursor-not-allowed disabled:opacity-60"
70
+ disabled={submitting || token.trim().length === 0}
71
+ type="submit"
72
+ >
73
+ {submitting ? "Unlocking..." : "Unlock"}
74
+ </button>
75
+ </form>
76
+ );
77
+ }
@@ -0,0 +1,41 @@
1
+ import { sanitizeRedirectTarget } from "@/lib/remoteAuth";
2
+ import { UnlockForm } from "./UnlockForm";
3
+
4
+ function getErrorMessage(code: string | null | undefined): string | null {
5
+ if (code === "invalid") return "That access link or token is invalid.";
6
+ if (code === "unavailable") return "Remote sign-in is not available for this session.";
7
+ return null;
8
+ }
9
+
10
+ type UnlockPageProps = {
11
+ searchParams?: Promise<Record<string, string | string[] | undefined>>;
12
+ };
13
+
14
+ export default async function UnlockPage({ searchParams }: UnlockPageProps) {
15
+ const resolved = searchParams ? await searchParams : {};
16
+ const rawNext = resolved.next;
17
+ const nextValue = Array.isArray(rawNext) ? rawNext[0] : rawNext;
18
+ const rawError = resolved.error;
19
+ const errorValue = Array.isArray(rawError) ? rawError[0] : rawError;
20
+
21
+ return (
22
+ <main className="flex min-h-screen items-center justify-center px-4 py-10">
23
+ <section className="surface-card w-full max-w-md rounded-[var(--radius-lg)] border p-6 shadow-[var(--shadow-card)]">
24
+ <div className="space-y-2">
25
+ <p className="text-xs font-semibold uppercase tracking-[0.28em] text-[var(--text-muted)]">
26
+ Secure Remote Access
27
+ </p>
28
+ <h1 className="text-2xl font-semibold text-[var(--text-strong)]">Unlock Conductor</h1>
29
+ <p className="text-sm leading-6 text-[var(--text-muted)]">
30
+ Use the secure unlock link from the terminal that started this session, or paste the access token below.
31
+ </p>
32
+ </div>
33
+
34
+ <UnlockForm
35
+ initialError={getErrorMessage(errorValue)}
36
+ nextPath={sanitizeRedirectTarget(nextValue)}
37
+ />
38
+ </section>
39
+ </main>
40
+ );
41
+ }
@@ -19,6 +19,7 @@ import type {
19
19
  SSESnapshotEvent,
20
20
  } from "@/lib/types";
21
21
  import { getAttentionLevel } from "@/lib/types";
22
+ import { AgentTileIcon } from "./AgentTileIcon";
22
23
  import { TERMINAL_STATUSES } from "@conductor-oss/core/types";
23
24
  import { SessionCard } from "./SessionCard";
24
25
  import { EmptyState } from "./EmptyState";
@@ -254,56 +255,6 @@ function getProjectFaviconUrls(repo?: string | null, iconUrl?: string | null): s
254
255
  }
255
256
  }
256
257
 
257
- function getAgentIconUrls(agent: AgentIconSeed): string[] {
258
- const urls: string[] = [];
259
-
260
- if (agent.iconUrl) {
261
- const direct = agent.iconUrl.trim();
262
- if (direct) {
263
- urls.push(direct);
264
- }
265
- }
266
-
267
- const simpleIconCandidates = [
268
- asSimpleIconSlug(agent.label),
269
- asSimpleIconSlug(agent.launchName),
270
- asSimpleIconSlug(agent.launchName).replace(/-cli$/u, ""),
271
- ].filter((slug) => slug.length > 0);
272
- for (const slug of simpleIconCandidates) {
273
- urls.push(`https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/${slug}.svg`);
274
- }
275
-
276
- if (!agent.homepage) return urls;
277
-
278
- try {
279
- const homepageUrl = new URL(agent.homepage);
280
- const homepageOrigin = `${homepageUrl.origin}`;
281
- urls.push(`https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(homepageOrigin)}`);
282
- urls.push(`https://www.google.com/s2/favicons?sz=64&domain=${encodeURIComponent(homepageUrl.hostname)}`);
283
- const gitHubRepo = parseGithubRepo(agent.homepage);
284
- if (gitHubRepo) {
285
- const owner = encodeURIComponent(gitHubRepo.owner);
286
- const project = encodeURIComponent(gitHubRepo.name);
287
- urls.push(`https://opengraph.githubassets.com/1/${owner}/${project}`);
288
- const repoFiles = [
289
- ".github/logo.png",
290
- ".github/favicon.png",
291
- ".github/logo.svg",
292
- "assets/logo.png",
293
- "assets/favicon.png",
294
- "logo.png",
295
- "favicon.png",
296
- "logo.svg",
297
- ];
298
- urls.push(...repoFiles.map((file) => `https://raw.githubusercontent.com/${owner}/${project}/HEAD/${file}`));
299
- }
300
- } catch {
301
- // Ignore malformed homepages.
302
- }
303
-
304
- return [...new Set(urls)];
305
- }
306
-
307
258
  function getProjectAbbrev(projectId: string): string {
308
259
  const parts = projectId.split(/[-_\s/]+/).filter(Boolean);
309
260
  if (parts.length === 1) {
@@ -329,82 +280,16 @@ function DefaultProjectIcon({ projectId, color }: { projectId: string; color: st
329
280
  );
330
281
  }
331
282
 
332
- function DefaultAgentIcon({
333
- label,
334
- color,
335
- className = "h-5 w-5",
336
- }: {
337
- label: string;
338
- color: string;
339
- className?: string;
340
- }) {
341
- const fallback = getProjectAbbrev(label);
342
- return (
343
- <span
344
- className={`flex ${className} shrink-0 items-center justify-center rounded-sm text-[10px] font-semibold text-white`}
345
- style={{ backgroundColor: color }}
346
- aria-hidden="true"
347
- >
348
- {fallback}
349
- </span>
350
- );
351
- }
352
-
353
- function getSeededColor(seed: string): string {
354
- const FALLBACK_COLORS = [
355
- "#14b8a6",
356
- "#22c55e",
357
- "#84cc16",
358
- "#eab308",
359
- "#f97316",
360
- "#f43f5e",
361
- "#a855f7",
362
- "#ec4899",
363
- "#06b6d4",
364
- "#0ea5e9",
365
- ];
366
- let hash = 0;
367
- for (let i = 0; i < seed.length; i += 1) {
368
- hash = (hash * 31 + seed.charCodeAt(i)) % 360;
369
- }
370
- return FALLBACK_COLORS[hash % FALLBACK_COLORS.length] ?? "#6b7280";
371
- }
372
-
373
283
  function AgentIcon({ agent, className = "h-5 w-5" }: { agent: AgentIconSeed; className?: string }) {
374
- const [iconErrorIndex, setIconErrorIndex] = useState(0);
375
- const [isLoaded, setIsLoaded] = useState(false);
376
- const iconUrls = useMemo(() => getAgentIconUrls(agent), [agent.iconUrl, agent.homepage, agent.label, agent.launchName]);
377
- const color = useMemo(
378
- () => getSeededColor(`${agent.label}-${agent.launchName}`),
379
- [agent.label, agent.launchName],
380
- );
381
-
382
- useEffect(() => {
383
- setIconErrorIndex(0);
384
- setIsLoaded(false);
385
- }, [iconUrls]);
386
- useEffect(() => setIsLoaded(false), [iconErrorIndex]);
387
-
388
- const shouldUseFallback =
389
- !iconUrls.length || iconErrorIndex >= iconUrls.length || !iconUrls[iconErrorIndex];
390
-
391
- if (shouldUseFallback) {
392
- return <DefaultAgentIcon className={className} label={agent.label} color={color} />;
393
- }
394
-
395
284
  return (
396
- <span className="relative inline-flex">
397
- {!isLoaded && <DefaultAgentIcon className={className} label={agent.label} color={color} />}
398
- <img
399
- src={iconUrls[iconErrorIndex]}
400
- alt={`${agent.label} icon`}
401
- className={`${className} shrink-0 rounded-sm border border-[var(--color-border-subtle)] bg-white object-contain ${isLoaded ? "inline-flex" : "hidden"}`}
402
- onError={() => {
403
- setIconErrorIndex((current) => current + 1);
404
- setIsLoaded(false);
285
+ <span className="inline-flex rounded-sm border border-[var(--color-border-subtle)] bg-white p-[1px]">
286
+ <AgentTileIcon
287
+ seed={{
288
+ label: agent.label,
289
+ homepage: agent.homepage,
290
+ iconUrl: agent.iconUrl,
405
291
  }}
406
- onLoad={() => setIsLoaded(true)}
407
- loading="lazy"
292
+ className={className}
408
293
  />
409
294
  </span>
410
295
  );
@@ -450,7 +335,7 @@ const KNOWN_AGENTS: KnownAgent[] = [
450
335
  description: "OpenAI Codex CLI",
451
336
  homepage: "https://github.com/openai/codex",
452
337
  iconUrl: "https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/openai.svg",
453
- installHint: "npm install -g @openai/codex-cli",
338
+ installHint: "npm install -g @openai/codex",
454
339
  launchCommand: "codex",
455
340
  capabilities: ["chat", "review", "terminal"],
456
341
  },
@@ -555,7 +440,8 @@ const KNOWN_AGENTS: KnownAgent[] = [
555
440
  aliases: ["qwen code", "qwen_code", "qwen", "qwen-code", "qwen-code-cli"],
556
441
  description: "Qwen Code CLI",
557
442
  homepage: "https://qwenlm.github.io/announcements/",
558
- launchCommand: "qwen-code",
443
+ installHint: "npm install -g @qwen-code/qwen-code@latest",
444
+ launchCommand: "qwen",
559
445
  capabilities: ["chat", "review", "reasoning", "analysis"],
560
446
  },
561
447
  ];
@@ -10,6 +10,7 @@ export interface ConfigProject {
10
10
  boardFile?: string | null;
11
11
  description: string | null;
12
12
  agent: string;
13
+ agentModel: string | null;
13
14
  }
14
15
 
15
16
  interface UseConfigReturn {
@@ -33,6 +34,9 @@ function normalizeProject(
33
34
  agent: typeof raw?.["agent"] === "string" && raw["agent"].trim().length > 0
34
35
  ? raw["agent"]
35
36
  : "qwen-code",
37
+ agentModel: typeof raw?.["agentModel"] === "string" && raw["agentModel"].trim().length > 0
38
+ ? raw["agentModel"]
39
+ : null,
36
40
  };
37
41
  }
38
42
 
@@ -0,0 +1,46 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { isLoopbackHost, resolveRoleForEmail, roleMeetsRequirement } from "./accessControl";
4
+
5
+ test("resolveRoleForEmail prefers the highest matching bound role", () => {
6
+ const resolution = resolveRoleForEmail("lead@example.com", {
7
+ roles: {
8
+ viewers: ["lead@example.com"],
9
+ admins: ["lead@example.com"],
10
+ },
11
+ });
12
+
13
+ assert.equal(resolution.role, "admin");
14
+ assert.equal(resolution.matchedBinding, true);
15
+ });
16
+
17
+ test("resolveRoleForEmail falls back to the configured default role", () => {
18
+ const resolution = resolveRoleForEmail("member@example.com", {
19
+ defaultRole: "viewer",
20
+ });
21
+
22
+ assert.equal(resolution.role, "viewer");
23
+ assert.equal(resolution.matchedBinding, false);
24
+ });
25
+
26
+ test("resolveRoleForEmail denies unmatched users when explicit bindings exist", () => {
27
+ const resolution = resolveRoleForEmail("outsider@example.com", {
28
+ roles: {
29
+ operators: ["operator@example.com"],
30
+ },
31
+ });
32
+
33
+ assert.equal(resolution.role, null);
34
+ });
35
+
36
+ test("roleMeetsRequirement enforces the viewer/operator/admin hierarchy", () => {
37
+ assert.equal(roleMeetsRequirement("admin", "operator"), true);
38
+ assert.equal(roleMeetsRequirement("operator", "viewer"), true);
39
+ assert.equal(roleMeetsRequirement("viewer", "operator"), false);
40
+ });
41
+
42
+ test("isLoopbackHost recognizes local dashboard hosts", () => {
43
+ assert.equal(isLoopbackHost("localhost"), true);
44
+ assert.equal(isLoopbackHost("127.0.0.1"), true);
45
+ assert.equal(isLoopbackHost("app.example.com"), false);
46
+ });
@@ -0,0 +1,115 @@
1
+ import type {
2
+ DashboardAccessConfig,
3
+ DashboardRole,
4
+ DashboardRoleBindings,
5
+ } from "@conductor-oss/core/types";
6
+
7
+ export type RoleRequirement = DashboardRole;
8
+
9
+ const ROLE_WEIGHT: Record<DashboardRole, number> = {
10
+ viewer: 0,
11
+ operator: 1,
12
+ admin: 2,
13
+ };
14
+
15
+ function normalizeList(values: string[] | undefined): string[] {
16
+ return (values ?? [])
17
+ .map((value) => value.trim().toLowerCase())
18
+ .filter(Boolean);
19
+ }
20
+
21
+ function roleBindingsConfigured(bindings?: DashboardRoleBindings | null): boolean {
22
+ if (!bindings) return false;
23
+ return (
24
+ normalizeList(bindings.viewers).length > 0 ||
25
+ normalizeList(bindings.operators).length > 0 ||
26
+ normalizeList(bindings.admins).length > 0 ||
27
+ normalizeList(bindings.viewerDomains).length > 0 ||
28
+ normalizeList(bindings.operatorDomains).length > 0 ||
29
+ normalizeList(bindings.adminDomains).length > 0
30
+ );
31
+ }
32
+
33
+ function matchesDomain(email: string, domains: string[]): boolean {
34
+ return domains.some((domain) => email.endsWith(`@${domain}`));
35
+ }
36
+
37
+ function matchesEmailOrDomain(email: string, emails: string[], domains: string[]): boolean {
38
+ return emails.includes(email) || matchesDomain(email, domains);
39
+ }
40
+
41
+ export function isLoopbackHost(hostname: string | null | undefined): boolean {
42
+ const normalized = (hostname ?? "").trim().toLowerCase();
43
+ return normalized === "localhost"
44
+ || normalized === "127.0.0.1"
45
+ || normalized === "0.0.0.0"
46
+ || normalized === "::1"
47
+ || normalized === "[::1]";
48
+ }
49
+
50
+ export function roleMeetsRequirement(
51
+ actualRole: DashboardRole,
52
+ requiredRole: RoleRequirement,
53
+ ): boolean {
54
+ return ROLE_WEIGHT[actualRole] >= ROLE_WEIGHT[requiredRole];
55
+ }
56
+
57
+ export function resolveRoleForEmail(
58
+ email: string,
59
+ access: DashboardAccessConfig | null | undefined,
60
+ envFallback?: {
61
+ allowedEmails?: string[];
62
+ allowedDomains?: string[];
63
+ adminEmails?: string[];
64
+ },
65
+ ): {
66
+ role: DashboardRole | null;
67
+ matchedBinding: boolean;
68
+ explicitBindingsConfigured: boolean;
69
+ } {
70
+ const normalizedEmail = email.trim().toLowerCase();
71
+ const bindings = access?.roles;
72
+
73
+ const adminEmails = [
74
+ ...normalizeList(bindings?.admins),
75
+ ...normalizeList(envFallback?.adminEmails),
76
+ ];
77
+ const operatorEmails = [
78
+ ...normalizeList(bindings?.operators),
79
+ ...normalizeList(envFallback?.allowedEmails),
80
+ ];
81
+ const viewerEmails = normalizeList(bindings?.viewers);
82
+
83
+ const adminDomains = normalizeList(bindings?.adminDomains);
84
+ const operatorDomains = [
85
+ ...normalizeList(bindings?.operatorDomains),
86
+ ...normalizeList(envFallback?.allowedDomains),
87
+ ];
88
+ const viewerDomains = normalizeList(bindings?.viewerDomains);
89
+
90
+ const explicitBindingsConfigured =
91
+ roleBindingsConfigured(bindings) ||
92
+ adminEmails.length > 0 ||
93
+ operatorEmails.length > 0 ||
94
+ operatorDomains.length > 0;
95
+
96
+ if (matchesEmailOrDomain(normalizedEmail, adminEmails, adminDomains)) {
97
+ return { role: "admin", matchedBinding: true, explicitBindingsConfigured };
98
+ }
99
+ if (matchesEmailOrDomain(normalizedEmail, operatorEmails, operatorDomains)) {
100
+ return { role: "operator", matchedBinding: true, explicitBindingsConfigured };
101
+ }
102
+ if (matchesEmailOrDomain(normalizedEmail, viewerEmails, viewerDomains)) {
103
+ return { role: "viewer", matchedBinding: true, explicitBindingsConfigured };
104
+ }
105
+
106
+ if (access?.defaultRole) {
107
+ return { role: access.defaultRole, matchedBinding: false, explicitBindingsConfigured };
108
+ }
109
+
110
+ if (explicitBindingsConfigured) {
111
+ return { role: null, matchedBinding: false, explicitBindingsConfigured };
112
+ }
113
+
114
+ return { role: "operator", matchedBinding: false, explicitBindingsConfigured };
115
+ }