conductor-oss 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1214) hide show
  1. package/README.md +225 -201
  2. package/dist/commands/setup.d.ts.map +1 -1
  3. package/dist/commands/setup.js +28 -3
  4. package/dist/commands/setup.js.map +1 -1
  5. package/dist/commands/start.d.ts +14 -2
  6. package/dist/commands/start.d.ts.map +1 -1
  7. package/dist/commands/start.js +351 -180
  8. package/dist/commands/start.js.map +1 -1
  9. package/node_modules/@conductor-oss/core/dist/board-watcher.d.ts.map +1 -1
  10. package/node_modules/@conductor-oss/core/dist/board-watcher.js +11 -8
  11. package/node_modules/@conductor-oss/core/dist/board-watcher.js.map +1 -1
  12. package/node_modules/@conductor-oss/core/dist/config-sync.d.ts.map +1 -1
  13. package/node_modules/@conductor-oss/core/dist/config-sync.js +23 -2
  14. package/node_modules/@conductor-oss/core/dist/config-sync.js.map +1 -1
  15. package/node_modules/@conductor-oss/core/dist/config.d.ts.map +1 -1
  16. package/node_modules/@conductor-oss/core/dist/config.js +87 -4
  17. package/node_modules/@conductor-oss/core/dist/config.js.map +1 -1
  18. package/node_modules/@conductor-oss/core/dist/metadata.d.ts.map +1 -1
  19. package/node_modules/@conductor-oss/core/dist/metadata.js +4 -0
  20. package/node_modules/@conductor-oss/core/dist/metadata.js.map +1 -1
  21. package/node_modules/@conductor-oss/core/dist/prompt-builder.d.ts +1 -1
  22. package/node_modules/@conductor-oss/core/dist/prompt-builder.d.ts.map +1 -1
  23. package/node_modules/@conductor-oss/core/dist/prompt-builder.js +5 -0
  24. package/node_modules/@conductor-oss/core/dist/prompt-builder.js.map +1 -1
  25. package/node_modules/@conductor-oss/core/dist/scaffold.d.ts +20 -2
  26. package/node_modules/@conductor-oss/core/dist/scaffold.d.ts.map +1 -1
  27. package/node_modules/@conductor-oss/core/dist/scaffold.js +39 -5
  28. package/node_modules/@conductor-oss/core/dist/scaffold.js.map +1 -1
  29. package/node_modules/@conductor-oss/core/dist/session-manager.d.ts.map +1 -1
  30. package/node_modules/@conductor-oss/core/dist/session-manager.js +82 -9
  31. package/node_modules/@conductor-oss/core/dist/session-manager.js.map +1 -1
  32. package/node_modules/@conductor-oss/core/dist/types.d.ts +33 -7
  33. package/node_modules/@conductor-oss/core/dist/types.d.ts.map +1 -1
  34. package/node_modules/@conductor-oss/core/dist/types.js +151 -0
  35. package/node_modules/@conductor-oss/core/dist/types.js.map +1 -1
  36. package/node_modules/@conductor-oss/plugin-agent-amp/package.json +1 -1
  37. package/node_modules/@conductor-oss/plugin-agent-ccr/package.json +1 -1
  38. package/node_modules/@conductor-oss/plugin-agent-claude-code/package.json +1 -1
  39. package/node_modules/@conductor-oss/plugin-agent-codex/package.json +1 -1
  40. package/node_modules/@conductor-oss/plugin-agent-cursor-cli/package.json +1 -1
  41. package/node_modules/@conductor-oss/plugin-agent-droid/package.json +1 -1
  42. package/node_modules/@conductor-oss/plugin-agent-gemini/package.json +1 -1
  43. package/node_modules/@conductor-oss/plugin-agent-github-copilot/package.json +1 -1
  44. package/node_modules/@conductor-oss/plugin-agent-opencode/package.json +1 -1
  45. package/node_modules/@conductor-oss/plugin-agent-qwen-code/package.json +1 -1
  46. package/node_modules/@conductor-oss/plugin-mcp-server/package.json +1 -1
  47. package/node_modules/@conductor-oss/plugin-notifier-desktop/package.json +1 -1
  48. package/node_modules/@conductor-oss/plugin-notifier-discord/package.json +1 -1
  49. package/node_modules/@conductor-oss/plugin-runtime-tmux/package.json +1 -1
  50. package/node_modules/@conductor-oss/plugin-scm-github/package.json +1 -1
  51. package/node_modules/@conductor-oss/plugin-terminal-web/package.json +1 -1
  52. package/node_modules/@conductor-oss/plugin-tracker-github/package.json +1 -1
  53. package/node_modules/@conductor-oss/plugin-workspace-worktree/package.json +1 -1
  54. package/package.json +24 -23
  55. package/web/.next/standalone/node_modules/@babel/code-frame/lib/index.js +217 -0
  56. package/web/.next/standalone/node_modules/@babel/code-frame/package.json +32 -0
  57. package/web/.next/standalone/node_modules/@babel/helper-validator-identifier/lib/identifier.js +70 -0
  58. package/web/.next/standalone/node_modules/@babel/helper-validator-identifier/lib/index.js +57 -0
  59. package/web/.next/standalone/node_modules/@babel/helper-validator-identifier/lib/keyword.js +35 -0
  60. package/web/.next/standalone/node_modules/@babel/helper-validator-identifier/package.json +31 -0
  61. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/CLI.js +338 -0
  62. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/Cache.js +208 -0
  63. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/DefaultProvider.js +35 -0
  64. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/DefaultProvider.spec.js +75 -0
  65. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/browser-data.js +235 -0
  66. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome-headless-shell.js +47 -0
  67. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome.js +296 -0
  68. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/chromedriver.js +43 -0
  69. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/chromium.js +63 -0
  70. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/firefox.js +374 -0
  71. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/browser-data/types.js +63 -0
  72. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/debug.js +8 -0
  73. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/detectPlatform.js +47 -0
  74. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/fileUtil.js +156 -0
  75. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/httpUtil.js +132 -0
  76. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/install.js +351 -0
  77. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/launch.js +426 -0
  78. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/main-cli.js +9 -0
  79. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/main.js +15 -0
  80. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/package.json +1 -0
  81. package/web/.next/standalone/node_modules/@puppeteer/browsers/lib/esm/provider.js +13 -0
  82. package/web/.next/standalone/node_modules/@puppeteer/browsers/package.json +125 -0
  83. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/asyncify-helpers.js +53 -0
  84. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/context-asyncify.js +58 -0
  85. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/context.js +691 -0
  86. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/debug.js +6 -0
  87. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/deferred-promise.js +96 -0
  88. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/errors.js +58 -0
  89. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/esmHelpers.js +19 -0
  90. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js +387 -0
  91. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/generated/ffi.WASM_RELEASE_SYNC.js +71 -0
  92. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/index.js +128 -0
  93. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/lifetime.js +227 -0
  94. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/memory.js +41 -0
  95. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/module-asyncify.js +97 -0
  96. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/module-test.js +77 -0
  97. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/module.js +302 -0
  98. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/runtime-asyncify.js +49 -0
  99. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/runtime.js +300 -0
  100. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/types-ffi.js +38 -0
  101. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/types.js +58 -0
  102. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/variants.js +169 -0
  103. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/dist/vm-interface.js +12 -0
  104. package/web/.next/standalone/node_modules/@tootallnate/quickjs-emscripten/package.json +60 -0
  105. package/web/.next/standalone/node_modules/agent-base/dist/helpers.js +66 -0
  106. package/web/.next/standalone/node_modules/agent-base/dist/index.js +178 -0
  107. package/web/.next/standalone/node_modules/agent-base/package.json +46 -0
  108. package/web/.next/standalone/node_modules/ast-types/def/babel-core.js +256 -0
  109. package/web/.next/standalone/node_modules/ast-types/def/babel.js +11 -0
  110. package/web/.next/standalone/node_modules/ast-types/def/core.js +298 -0
  111. package/web/.next/standalone/node_modules/ast-types/def/es-proposals.js +33 -0
  112. package/web/.next/standalone/node_modules/ast-types/def/es2020.js +16 -0
  113. package/web/.next/standalone/node_modules/ast-types/def/es6.js +210 -0
  114. package/web/.next/standalone/node_modules/ast-types/def/es7.js +34 -0
  115. package/web/.next/standalone/node_modules/ast-types/def/esprima.js +49 -0
  116. package/web/.next/standalone/node_modules/ast-types/def/flow.js +292 -0
  117. package/web/.next/standalone/node_modules/ast-types/def/jsx.js +103 -0
  118. package/web/.next/standalone/node_modules/ast-types/def/type-annotations.js +40 -0
  119. package/web/.next/standalone/node_modules/ast-types/def/typescript.js +344 -0
  120. package/web/.next/standalone/node_modules/ast-types/fork.js +52 -0
  121. package/web/.next/standalone/node_modules/ast-types/gen/namedTypes.js +6 -0
  122. package/web/.next/standalone/node_modules/ast-types/lib/equiv.js +154 -0
  123. package/web/.next/standalone/node_modules/ast-types/lib/node-path.js +411 -0
  124. package/web/.next/standalone/node_modules/ast-types/lib/path-visitor.js +343 -0
  125. package/web/.next/standalone/node_modules/ast-types/lib/path.js +331 -0
  126. package/web/.next/standalone/node_modules/ast-types/lib/scope.js +318 -0
  127. package/web/.next/standalone/node_modules/ast-types/lib/shared.js +47 -0
  128. package/web/.next/standalone/node_modules/ast-types/lib/types.js +780 -0
  129. package/web/.next/standalone/node_modules/ast-types/main.js +53 -0
  130. package/web/.next/standalone/node_modules/ast-types/package.json +65 -0
  131. package/web/.next/standalone/node_modules/b4a/index.js +188 -0
  132. package/web/.next/standalone/node_modules/b4a/package.json +49 -0
  133. package/web/.next/standalone/node_modules/basic-ftp/dist/Client.js +782 -0
  134. package/web/.next/standalone/node_modules/basic-ftp/dist/FileInfo.js +92 -0
  135. package/web/.next/standalone/node_modules/basic-ftp/dist/FtpContext.js +365 -0
  136. package/web/.next/standalone/node_modules/basic-ftp/dist/ProgressTracker.js +72 -0
  137. package/web/.next/standalone/node_modules/basic-ftp/dist/StringEncoding.js +2 -0
  138. package/web/.next/standalone/node_modules/basic-ftp/dist/StringWriter.js +23 -0
  139. package/web/.next/standalone/node_modules/basic-ftp/dist/index.js +28 -0
  140. package/web/.next/standalone/node_modules/basic-ftp/dist/netUtils.js +66 -0
  141. package/web/.next/standalone/node_modules/basic-ftp/dist/parseControlResponse.js +66 -0
  142. package/web/.next/standalone/node_modules/basic-ftp/dist/parseList.js +79 -0
  143. package/web/.next/standalone/node_modules/basic-ftp/dist/parseListDOS.js +52 -0
  144. package/web/.next/standalone/node_modules/basic-ftp/dist/parseListMLSD.js +187 -0
  145. package/web/.next/standalone/node_modules/basic-ftp/dist/parseListUnix.js +155 -0
  146. package/web/.next/standalone/node_modules/basic-ftp/dist/transfer.js +318 -0
  147. package/web/.next/standalone/node_modules/basic-ftp/package.json +52 -0
  148. package/web/.next/standalone/node_modules/buffer-crc32/index.js +111 -0
  149. package/web/.next/standalone/node_modules/buffer-crc32/package.json +39 -0
  150. package/web/.next/standalone/node_modules/callsites/index.js +13 -0
  151. package/web/.next/standalone/node_modules/callsites/package.json +39 -0
  152. package/web/.next/standalone/node_modules/cliui/build/lib/index.js +287 -0
  153. package/web/.next/standalone/node_modules/cliui/build/lib/string-utils.js +27 -0
  154. package/web/.next/standalone/node_modules/cliui/index.mjs +13 -0
  155. package/web/.next/standalone/node_modules/cliui/package.json +83 -0
  156. package/web/.next/standalone/node_modules/cosmiconfig/dist/Explorer.js +170 -0
  157. package/web/.next/standalone/node_modules/cosmiconfig/dist/ExplorerBase.js +126 -0
  158. package/web/.next/standalone/node_modules/cosmiconfig/dist/ExplorerSync.js +184 -0
  159. package/web/.next/standalone/node_modules/cosmiconfig/dist/cacheWrapper.js +32 -0
  160. package/web/.next/standalone/node_modules/cosmiconfig/dist/canUseDynamicImport.js +23 -0
  161. package/web/.next/standalone/node_modules/cosmiconfig/dist/defaults.js +105 -0
  162. package/web/.next/standalone/node_modules/cosmiconfig/dist/getDirectory.js +38 -0
  163. package/web/.next/standalone/node_modules/cosmiconfig/dist/getPropertyByPath.js +28 -0
  164. package/web/.next/standalone/node_modules/cosmiconfig/dist/index.js +148 -0
  165. package/web/.next/standalone/node_modules/cosmiconfig/dist/loaders.js +150 -0
  166. package/web/.next/standalone/node_modules/cosmiconfig/dist/merge.js +40 -0
  167. package/web/.next/standalone/node_modules/cosmiconfig/dist/readFile.js +56 -0
  168. package/web/.next/standalone/node_modules/cosmiconfig/dist/types.js +3 -0
  169. package/web/.next/standalone/node_modules/cosmiconfig/dist/util.js +99 -0
  170. package/web/.next/standalone/node_modules/cosmiconfig/package.json +103 -0
  171. package/web/.next/standalone/node_modules/data-uri-to-buffer/dist/common.js +54 -0
  172. package/web/.next/standalone/node_modules/data-uri-to-buffer/dist/node.js +26 -0
  173. package/web/.next/standalone/node_modules/data-uri-to-buffer/package.json +48 -0
  174. package/web/.next/standalone/node_modules/debug/package.json +64 -0
  175. package/web/.next/standalone/node_modules/debug/src/browser.js +272 -0
  176. package/web/.next/standalone/node_modules/debug/src/common.js +292 -0
  177. package/web/.next/standalone/node_modules/debug/src/index.js +10 -0
  178. package/web/.next/standalone/node_modules/debug/src/node.js +263 -0
  179. package/web/.next/standalone/node_modules/degenerator/dist/compile.js +107 -0
  180. package/web/.next/standalone/node_modules/degenerator/dist/degenerator.js +156 -0
  181. package/web/.next/standalone/node_modules/degenerator/dist/index.js +19 -0
  182. package/web/.next/standalone/node_modules/degenerator/package.json +42 -0
  183. package/web/.next/standalone/node_modules/end-of-stream/index.js +96 -0
  184. package/web/.next/standalone/node_modules/end-of-stream/package.json +37 -0
  185. package/web/.next/standalone/node_modules/env-paths/index.js +74 -0
  186. package/web/.next/standalone/node_modules/env-paths/license +9 -0
  187. package/web/.next/standalone/node_modules/env-paths/package.json +45 -0
  188. package/web/.next/standalone/node_modules/env-paths/readme.md +115 -0
  189. package/web/.next/standalone/node_modules/error-ex/index.js +141 -0
  190. package/web/.next/standalone/node_modules/error-ex/package.json +46 -0
  191. package/web/.next/standalone/node_modules/escalade/package.json +74 -0
  192. package/web/.next/standalone/node_modules/escalade/sync/index.d.mts +9 -0
  193. package/web/.next/standalone/node_modules/escalade/sync/index.js +18 -0
  194. package/web/.next/standalone/node_modules/escalade/sync/index.mjs +18 -0
  195. package/web/.next/standalone/node_modules/escodegen/escodegen.js +2667 -0
  196. package/web/.next/standalone/node_modules/escodegen/package.json +63 -0
  197. package/web/.next/standalone/node_modules/esprima/dist/esprima.js +6709 -0
  198. package/web/.next/standalone/node_modules/esprima/package.json +112 -0
  199. package/web/.next/standalone/node_modules/estraverse/estraverse.js +805 -0
  200. package/web/.next/standalone/node_modules/estraverse/package.json +40 -0
  201. package/web/.next/standalone/node_modules/esutils/lib/ast.js +144 -0
  202. package/web/.next/standalone/node_modules/esutils/lib/code.js +135 -0
  203. package/web/.next/standalone/node_modules/esutils/lib/keyword.js +165 -0
  204. package/web/.next/standalone/node_modules/esutils/lib/utils.js +33 -0
  205. package/web/.next/standalone/node_modules/esutils/package.json +44 -0
  206. package/web/.next/standalone/node_modules/events-universal/default.js +1 -0
  207. package/web/.next/standalone/node_modules/events-universal/package.json +39 -0
  208. package/web/.next/standalone/node_modules/extract-zip/LICENSE +23 -0
  209. package/web/.next/standalone/node_modules/extract-zip/cli.js +19 -0
  210. package/web/.next/standalone/node_modules/extract-zip/index.js +173 -0
  211. package/web/.next/standalone/node_modules/extract-zip/package.json +80 -0
  212. package/web/.next/standalone/node_modules/extract-zip/readme.md +57 -0
  213. package/web/.next/standalone/node_modules/fast-fifo/fixed-size.js +39 -0
  214. package/web/.next/standalone/node_modules/fast-fifo/index.js +48 -0
  215. package/web/.next/standalone/node_modules/fast-fifo/package.json +28 -0
  216. package/web/.next/standalone/node_modules/fd-slicer/index.js +296 -0
  217. package/web/.next/standalone/node_modules/fd-slicer/package.json +36 -0
  218. package/web/.next/standalone/node_modules/get-stream/buffer-stream.js +52 -0
  219. package/web/.next/standalone/node_modules/get-stream/index.js +60 -0
  220. package/web/.next/standalone/node_modules/get-stream/package.json +50 -0
  221. package/web/.next/standalone/node_modules/get-uri/dist/data.js +43 -0
  222. package/web/.next/standalone/node_modules/get-uri/dist/file.js +57 -0
  223. package/web/.next/standalone/node_modules/get-uri/dist/ftp.js +93 -0
  224. package/web/.next/standalone/node_modules/get-uri/dist/http-error.js +15 -0
  225. package/web/.next/standalone/node_modules/get-uri/dist/http.js +191 -0
  226. package/web/.next/standalone/node_modules/get-uri/dist/https.js +16 -0
  227. package/web/.next/standalone/node_modules/get-uri/dist/index.js +57 -0
  228. package/web/.next/standalone/node_modules/get-uri/dist/notfound.js +16 -0
  229. package/web/.next/standalone/node_modules/get-uri/dist/notmodified.js +17 -0
  230. package/web/.next/standalone/node_modules/get-uri/package.json +58 -0
  231. package/web/.next/standalone/node_modules/http-proxy-agent/dist/index.js +148 -0
  232. package/web/.next/standalone/node_modules/http-proxy-agent/package.json +47 -0
  233. package/web/.next/standalone/node_modules/https-proxy-agent/dist/index.js +180 -0
  234. package/web/.next/standalone/node_modules/https-proxy-agent/dist/parse-proxy-response.js +101 -0
  235. package/web/.next/standalone/node_modules/https-proxy-agent/package.json +50 -0
  236. package/web/.next/standalone/node_modules/import-fresh/index.js +34 -0
  237. package/web/.next/standalone/node_modules/import-fresh/node_modules/resolve-from/index.js +47 -0
  238. package/web/.next/standalone/node_modules/import-fresh/node_modules/resolve-from/license +9 -0
  239. package/web/.next/standalone/node_modules/import-fresh/node_modules/resolve-from/package.json +34 -0
  240. package/web/.next/standalone/node_modules/import-fresh/node_modules/resolve-from/readme.md +72 -0
  241. package/web/.next/standalone/node_modules/import-fresh/package.json +48 -0
  242. package/web/.next/standalone/node_modules/ip-address/dist/address-error.js +12 -0
  243. package/web/.next/standalone/node_modules/ip-address/dist/common.js +46 -0
  244. package/web/.next/standalone/node_modules/ip-address/dist/ip-address.js +35 -0
  245. package/web/.next/standalone/node_modules/ip-address/dist/ipv4.js +360 -0
  246. package/web/.next/standalone/node_modules/ip-address/dist/ipv6.js +1003 -0
  247. package/web/.next/standalone/node_modules/ip-address/dist/v4/constants.js +8 -0
  248. package/web/.next/standalone/node_modules/ip-address/dist/v6/constants.js +76 -0
  249. package/web/.next/standalone/node_modules/ip-address/dist/v6/helpers.js +45 -0
  250. package/web/.next/standalone/node_modules/ip-address/dist/v6/regular-expressions.js +95 -0
  251. package/web/.next/standalone/node_modules/ip-address/package.json +78 -0
  252. package/web/.next/standalone/node_modules/is-arrayish/index.js +10 -0
  253. package/web/.next/standalone/node_modules/is-arrayish/package.json +34 -0
  254. package/web/.next/standalone/node_modules/js-tokens/index.js +23 -0
  255. package/web/.next/standalone/node_modules/js-tokens/package.json +30 -0
  256. package/web/.next/standalone/node_modules/js-yaml/index.js +47 -0
  257. package/web/.next/standalone/node_modules/js-yaml/lib/common.js +59 -0
  258. package/web/.next/standalone/node_modules/js-yaml/lib/dumper.js +965 -0
  259. package/web/.next/standalone/node_modules/js-yaml/lib/exception.js +55 -0
  260. package/web/.next/standalone/node_modules/js-yaml/lib/loader.js +1733 -0
  261. package/web/.next/standalone/node_modules/js-yaml/lib/schema/core.js +11 -0
  262. package/web/.next/standalone/node_modules/js-yaml/lib/schema/default.js +22 -0
  263. package/web/.next/standalone/node_modules/js-yaml/lib/schema/failsafe.js +17 -0
  264. package/web/.next/standalone/node_modules/js-yaml/lib/schema/json.js +19 -0
  265. package/web/.next/standalone/node_modules/js-yaml/lib/schema.js +121 -0
  266. package/web/.next/standalone/node_modules/js-yaml/lib/snippet.js +101 -0
  267. package/web/.next/standalone/node_modules/js-yaml/lib/type/binary.js +125 -0
  268. package/web/.next/standalone/node_modules/js-yaml/lib/type/bool.js +35 -0
  269. package/web/.next/standalone/node_modules/js-yaml/lib/type/float.js +97 -0
  270. package/web/.next/standalone/node_modules/js-yaml/lib/type/int.js +156 -0
  271. package/web/.next/standalone/node_modules/js-yaml/lib/type/map.js +8 -0
  272. package/web/.next/standalone/node_modules/js-yaml/lib/type/merge.js +12 -0
  273. package/web/.next/standalone/node_modules/js-yaml/lib/type/null.js +35 -0
  274. package/web/.next/standalone/node_modules/js-yaml/lib/type/omap.js +44 -0
  275. package/web/.next/standalone/node_modules/js-yaml/lib/type/pairs.js +53 -0
  276. package/web/.next/standalone/node_modules/js-yaml/lib/type/seq.js +8 -0
  277. package/web/.next/standalone/node_modules/js-yaml/lib/type/set.js +29 -0
  278. package/web/.next/standalone/node_modules/js-yaml/lib/type/str.js +8 -0
  279. package/web/.next/standalone/node_modules/js-yaml/lib/type/timestamp.js +88 -0
  280. package/web/.next/standalone/node_modules/js-yaml/lib/type.js +66 -0
  281. package/web/.next/standalone/node_modules/js-yaml/package.json +66 -0
  282. package/web/.next/standalone/node_modules/json-parse-even-better-errors/index.js +121 -0
  283. package/web/.next/standalone/node_modules/json-parse-even-better-errors/package.json +33 -0
  284. package/web/.next/standalone/node_modules/lines-and-columns/build/index.js +62 -0
  285. package/web/.next/standalone/node_modules/lines-and-columns/package.json +49 -0
  286. package/web/.next/standalone/node_modules/lru-cache/index.js +1227 -0
  287. package/web/.next/standalone/node_modules/lru-cache/package.json +96 -0
  288. package/web/.next/standalone/node_modules/ms/index.js +162 -0
  289. package/web/.next/standalone/node_modules/ms/package.json +38 -0
  290. package/web/.next/standalone/node_modules/netmask/lib/netmask.js +208 -0
  291. package/web/.next/standalone/node_modules/netmask/package.json +36 -0
  292. package/web/.next/standalone/node_modules/once/once.js +42 -0
  293. package/web/.next/standalone/node_modules/once/package.json +33 -0
  294. package/web/.next/standalone/node_modules/pac-proxy-agent/dist/index.js +238 -0
  295. package/web/.next/standalone/node_modules/pac-proxy-agent/package.json +58 -0
  296. package/web/.next/standalone/node_modules/pac-resolver/dist/dateRange.js +73 -0
  297. package/web/.next/standalone/node_modules/pac-resolver/dist/dnsDomainIs.js +30 -0
  298. package/web/.next/standalone/node_modules/pac-resolver/dist/dnsDomainLevels.js +28 -0
  299. package/web/.next/standalone/node_modules/pac-resolver/dist/dnsResolve.js +32 -0
  300. package/web/.next/standalone/node_modules/pac-resolver/dist/index.js +87 -0
  301. package/web/.next/standalone/node_modules/pac-resolver/dist/ip.js +50 -0
  302. package/web/.next/standalone/node_modules/pac-resolver/dist/isInNet.js +42 -0
  303. package/web/.next/standalone/node_modules/pac-resolver/dist/isPlainHostName.js +23 -0
  304. package/web/.next/standalone/node_modules/pac-resolver/dist/isResolvable.js +23 -0
  305. package/web/.next/standalone/node_modules/pac-resolver/dist/localHostOrDomainIs.js +40 -0
  306. package/web/.next/standalone/node_modules/pac-resolver/dist/myIpAddress.js +50 -0
  307. package/web/.next/standalone/node_modules/pac-resolver/dist/shExpMatch.js +41 -0
  308. package/web/.next/standalone/node_modules/pac-resolver/dist/timeRange.js +92 -0
  309. package/web/.next/standalone/node_modules/pac-resolver/dist/util.js +22 -0
  310. package/web/.next/standalone/node_modules/pac-resolver/dist/weekdayRange.js +91 -0
  311. package/web/.next/standalone/node_modules/pac-resolver/package.json +47 -0
  312. package/web/.next/standalone/node_modules/parent-module/index.js +37 -0
  313. package/web/.next/standalone/node_modules/parent-module/package.json +46 -0
  314. package/web/.next/standalone/node_modules/parse-json/index.js +54 -0
  315. package/web/.next/standalone/node_modules/parse-json/package.json +45 -0
  316. package/web/.next/standalone/node_modules/pend/index.js +55 -0
  317. package/web/.next/standalone/node_modules/pend/package.json +18 -0
  318. package/web/.next/standalone/node_modules/picocolors/package.json +25 -0
  319. package/web/.next/standalone/node_modules/picocolors/picocolors.js +75 -0
  320. package/web/.next/standalone/node_modules/progress/index.js +1 -0
  321. package/web/.next/standalone/node_modules/progress/lib/node-progress.js +236 -0
  322. package/web/.next/standalone/node_modules/progress/package.json +26 -0
  323. package/web/.next/standalone/node_modules/proxy-agent/dist/index.js +138 -0
  324. package/web/.next/standalone/node_modules/proxy-agent/package.json +60 -0
  325. package/web/.next/standalone/node_modules/proxy-from-env/index.js +108 -0
  326. package/web/.next/standalone/node_modules/proxy-from-env/package.json +34 -0
  327. package/web/.next/standalone/node_modules/pump/index.js +86 -0
  328. package/web/.next/standalone/node_modules/pump/package.json +30 -0
  329. package/web/.next/standalone/node_modules/puppeteer/lib/esm/package.json +1 -0
  330. package/web/.next/standalone/node_modules/puppeteer/lib/esm/puppeteer/getConfiguration.js +122 -0
  331. package/web/.next/standalone/node_modules/puppeteer/lib/esm/puppeteer/puppeteer.js +40 -0
  332. package/web/.next/standalone/node_modules/puppeteer/package.json +145 -0
  333. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/package.json +1 -0
  334. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Browser.js +204 -0
  335. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/BrowserContext.js +182 -0
  336. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/CDPSession.js +68 -0
  337. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/DeviceRequestPrompt.js +34 -0
  338. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Dialog.js +90 -0
  339. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/ElementHandle.js +1406 -0
  340. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/ElementHandleSymbol.js +10 -0
  341. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Frame.js +904 -0
  342. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/HTTPRequest.js +461 -0
  343. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/HTTPResponse.js +56 -0
  344. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Input.js +211 -0
  345. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/JSHandle.js +227 -0
  346. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Page.js +1511 -0
  347. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Realm.js +44 -0
  348. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/Target.js +49 -0
  349. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/WebWorker.js +106 -0
  350. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/api.js +22 -0
  351. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/api/locators/locators.js +769 -0
  352. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/bidi/BrowserConnector.js +83 -0
  353. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Accessibility.js +591 -0
  354. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Binding.js +162 -0
  355. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/BluetoothEmulation.js +26 -0
  356. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Browser.js +321 -0
  357. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/BrowserConnector.js +26 -0
  358. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/BrowserContext.js +192 -0
  359. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/CdpPreloadScript.js +39 -0
  360. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/CdpSession.js +129 -0
  361. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Connection.js +244 -0
  362. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Coverage.js +372 -0
  363. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js +151 -0
  364. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Dialog.js +23 -0
  365. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/ElementHandle.js +206 -0
  366. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/EmulationManager.js +458 -0
  367. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/ExecutionContext.js +457 -0
  368. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/ExtensionTransport.js +175 -0
  369. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Frame.js +358 -0
  370. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/FrameManager.js +455 -0
  371. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/FrameManagerEvents.js +24 -0
  372. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/FrameTree.js +91 -0
  373. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/HTTPRequest.js +195 -0
  374. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/HTTPResponse.js +126 -0
  375. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Input.js +499 -0
  376. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/IsolatedWorld.js +157 -0
  377. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/IsolatedWorlds.js +20 -0
  378. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/JSHandle.js +101 -0
  379. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/LifecycleWatcher.js +174 -0
  380. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/NetworkEventManager.js +162 -0
  381. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/NetworkManager.js +601 -0
  382. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Page.js +1006 -0
  383. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/PredefinedNetworkConditions.js +69 -0
  384. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Target.js +243 -0
  385. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/TargetManageEvents.js +7 -0
  386. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/TargetManager.js +320 -0
  387. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/Tracing.js +110 -0
  388. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/WebWorker.js +73 -0
  389. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/cdp.js +43 -0
  390. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/cdp/utils.js +216 -0
  391. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/AriaQueryHandler.js +54 -0
  392. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserConnector.js +129 -0
  393. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js +39 -0
  394. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/CSSQueryHandler.js +18 -0
  395. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/CallbackRegistry.js +133 -0
  396. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/ConsoleMessage.js +78 -0
  397. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/CustomQueryHandler.js +114 -0
  398. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/Debug.js +109 -0
  399. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/Device.js +1604 -0
  400. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/Errors.js +94 -0
  401. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/EventEmitter.js +128 -0
  402. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/FileChooser.js +75 -0
  403. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/GetQueryHandler.js +70 -0
  404. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/HandleIterator.js +142 -0
  405. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/LazyArg.js +23 -0
  406. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/NetworkManagerEvents.js +21 -0
  407. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/PDFOptions.js +58 -0
  408. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/PQueryHandler.js +18 -0
  409. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/PSelectorParser.js +100 -0
  410. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/PierceQueryHandler.js +18 -0
  411. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/Puppeteer.js +98 -0
  412. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/QueryHandler.js +225 -0
  413. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/ScriptInjector.js +51 -0
  414. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/SecurityDetails.js +69 -0
  415. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/TaskQueue.js +24 -0
  416. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/TextQueryHandler.js +15 -0
  417. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/TimeoutSettings.js +39 -0
  418. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/USKeyboardLayout.js +394 -0
  419. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/WaitTask.js +197 -0
  420. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/XPathQueryHandler.js +21 -0
  421. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/common.js +35 -0
  422. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/common/util.js +375 -0
  423. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/environment.js +24 -0
  424. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/generated/injected.js +9 -0
  425. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/index-browser.js +11 -0
  426. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/index.js +8 -0
  427. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/BrowserLauncher.js +312 -0
  428. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/ChromeLauncher.js +258 -0
  429. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/FirefoxLauncher.js +166 -0
  430. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/LaunchOptions.js +22 -0
  431. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/NodeWebSocketTransport.js +55 -0
  432. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/PipeTransport.js +72 -0
  433. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/PuppeteerNode.js +281 -0
  434. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/ScreenRecorder.js +279 -0
  435. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/node.js +12 -0
  436. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/node/util/fs.js +24 -0
  437. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/puppeteer-core.js +41 -0
  438. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/revisions.js +14 -0
  439. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/AsyncIterableUtil.js +29 -0
  440. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/Deferred.js +105 -0
  441. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/ErrorLike.js +41 -0
  442. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/Function.js +70 -0
  443. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/Mutex.js +46 -0
  444. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/assert.js +18 -0
  445. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/decorators.js +232 -0
  446. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/disposable.js +342 -0
  447. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/encoding.js +63 -0
  448. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/incremental-id-generator.js +18 -0
  449. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/util.js +13 -0
  450. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/puppeteer/util/version.js +10 -0
  451. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/third_party/mitt/mitt.js +44 -0
  452. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/third_party/parsel-js/parsel-js.js +196 -0
  453. package/web/.next/standalone/node_modules/puppeteer-core/lib/esm/third_party/rxjs/rxjs.js +2887 -0
  454. package/web/.next/standalone/node_modules/puppeteer-core/package.json +169 -0
  455. package/web/.next/standalone/node_modules/semver/functions/clean.js +8 -0
  456. package/web/.next/standalone/node_modules/semver/functions/compare-build.js +9 -0
  457. package/web/.next/standalone/node_modules/semver/functions/compare-loose.js +5 -0
  458. package/web/.next/standalone/node_modules/semver/functions/diff.js +60 -0
  459. package/web/.next/standalone/node_modules/semver/functions/inc.js +21 -0
  460. package/web/.next/standalone/node_modules/semver/functions/major.js +5 -0
  461. package/web/.next/standalone/node_modules/semver/functions/minor.js +5 -0
  462. package/web/.next/standalone/node_modules/semver/functions/patch.js +5 -0
  463. package/web/.next/standalone/node_modules/semver/functions/prerelease.js +8 -0
  464. package/web/.next/standalone/node_modules/semver/functions/rcompare.js +5 -0
  465. package/web/.next/standalone/node_modules/semver/functions/rsort.js +5 -0
  466. package/web/.next/standalone/node_modules/semver/functions/sort.js +5 -0
  467. package/web/.next/standalone/node_modules/semver/functions/valid.js +8 -0
  468. package/web/.next/standalone/node_modules/semver/index.js +91 -0
  469. package/web/.next/standalone/node_modules/semver/ranges/gtr.js +6 -0
  470. package/web/.next/standalone/node_modules/semver/ranges/intersects.js +9 -0
  471. package/web/.next/standalone/node_modules/semver/ranges/ltr.js +6 -0
  472. package/web/.next/standalone/node_modules/semver/ranges/max-satisfying.js +27 -0
  473. package/web/.next/standalone/node_modules/semver/ranges/min-satisfying.js +26 -0
  474. package/web/.next/standalone/node_modules/semver/ranges/min-version.js +63 -0
  475. package/web/.next/standalone/node_modules/semver/ranges/outside.js +82 -0
  476. package/web/.next/standalone/node_modules/semver/ranges/simplify.js +49 -0
  477. package/web/.next/standalone/node_modules/semver/ranges/subset.js +249 -0
  478. package/web/.next/standalone/node_modules/semver/ranges/to-comparators.js +10 -0
  479. package/web/.next/standalone/node_modules/semver/ranges/valid.js +13 -0
  480. package/web/.next/standalone/node_modules/smart-buffer/build/smartbuffer.js +1233 -0
  481. package/web/.next/standalone/node_modules/smart-buffer/build/utils.js +108 -0
  482. package/web/.next/standalone/node_modules/smart-buffer/package.json +79 -0
  483. package/web/.next/standalone/node_modules/socks/build/client/socksclient.js +793 -0
  484. package/web/.next/standalone/node_modules/socks/build/common/constants.js +108 -0
  485. package/web/.next/standalone/node_modules/socks/build/common/helpers.js +167 -0
  486. package/web/.next/standalone/node_modules/socks/build/common/receivebuffer.js +43 -0
  487. package/web/.next/standalone/node_modules/socks/build/common/util.js +25 -0
  488. package/web/.next/standalone/node_modules/socks/build/index.js +18 -0
  489. package/web/.next/standalone/node_modules/socks/package.json +58 -0
  490. package/web/.next/standalone/node_modules/socks-proxy-agent/dist/index.js +195 -0
  491. package/web/.next/standalone/node_modules/socks-proxy-agent/package.json +142 -0
  492. package/web/.next/standalone/node_modules/source-map/lib/array-set.js +121 -0
  493. package/web/.next/standalone/node_modules/source-map/lib/base64-vlq.js +140 -0
  494. package/web/.next/standalone/node_modules/source-map/lib/base64.js +67 -0
  495. package/web/.next/standalone/node_modules/source-map/lib/binary-search.js +111 -0
  496. package/web/.next/standalone/node_modules/source-map/lib/mapping-list.js +79 -0
  497. package/web/.next/standalone/node_modules/source-map/lib/quick-sort.js +114 -0
  498. package/web/.next/standalone/node_modules/source-map/lib/source-map-consumer.js +1145 -0
  499. package/web/.next/standalone/node_modules/source-map/lib/source-map-generator.js +425 -0
  500. package/web/.next/standalone/node_modules/source-map/lib/source-node.js +413 -0
  501. package/web/.next/standalone/node_modules/source-map/lib/util.js +488 -0
  502. package/web/.next/standalone/node_modules/source-map/package.json +73 -0
  503. package/web/.next/standalone/node_modules/source-map/source-map.js +8 -0
  504. package/web/.next/standalone/node_modules/streamx/index.js +1184 -0
  505. package/web/.next/standalone/node_modules/streamx/package.json +34 -0
  506. package/web/.next/standalone/node_modules/tar-fs/LICENSE +21 -0
  507. package/web/.next/standalone/node_modules/tar-fs/README.md +154 -0
  508. package/web/.next/standalone/node_modules/tar-fs/index.js +400 -0
  509. package/web/.next/standalone/node_modules/tar-fs/package.json +61 -0
  510. package/web/.next/standalone/node_modules/tar-stream/constants.js +14 -0
  511. package/web/.next/standalone/node_modules/tar-stream/extract.js +406 -0
  512. package/web/.next/standalone/node_modules/tar-stream/headers.js +321 -0
  513. package/web/.next/standalone/node_modules/tar-stream/index.js +2 -0
  514. package/web/.next/standalone/node_modules/tar-stream/pack.js +287 -0
  515. package/web/.next/standalone/node_modules/tar-stream/package.json +42 -0
  516. package/web/.next/standalone/node_modules/text-decoder/index.js +64 -0
  517. package/web/.next/standalone/node_modules/text-decoder/lib/pass-through-decoder.js +19 -0
  518. package/web/.next/standalone/node_modules/text-decoder/lib/utf8-decoder.js +185 -0
  519. package/web/.next/standalone/node_modules/text-decoder/package.json +39 -0
  520. package/web/.next/standalone/node_modules/tslib/package.json +47 -0
  521. package/web/.next/standalone/node_modules/tslib/tslib.js +484 -0
  522. package/web/.next/standalone/node_modules/wrappy/package.json +29 -0
  523. package/web/.next/standalone/node_modules/wrappy/wrappy.js +33 -0
  524. package/web/.next/standalone/node_modules/ws/lib/buffer-util.js +131 -0
  525. package/web/.next/standalone/node_modules/ws/lib/constants.js +19 -0
  526. package/web/.next/standalone/node_modules/ws/lib/event-target.js +292 -0
  527. package/web/.next/standalone/node_modules/ws/lib/extension.js +203 -0
  528. package/web/.next/standalone/node_modules/ws/lib/limiter.js +55 -0
  529. package/web/.next/standalone/node_modules/ws/lib/permessage-deflate.js +528 -0
  530. package/web/.next/standalone/node_modules/ws/lib/receiver.js +706 -0
  531. package/web/.next/standalone/node_modules/ws/lib/sender.js +602 -0
  532. package/web/.next/standalone/node_modules/ws/lib/stream.js +161 -0
  533. package/web/.next/standalone/node_modules/ws/lib/subprotocol.js +62 -0
  534. package/web/.next/standalone/node_modules/ws/lib/validation.js +152 -0
  535. package/web/.next/standalone/node_modules/ws/lib/websocket-server.js +554 -0
  536. package/web/.next/standalone/node_modules/ws/lib/websocket.js +1393 -0
  537. package/web/.next/standalone/node_modules/ws/package.json +69 -0
  538. package/web/.next/standalone/node_modules/ws/wrapper.mjs +8 -0
  539. package/web/.next/standalone/node_modules/y18n/build/lib/index.js +174 -0
  540. package/web/.next/standalone/node_modules/y18n/build/lib/platform-shims/node.js +19 -0
  541. package/web/.next/standalone/node_modules/y18n/index.mjs +8 -0
  542. package/web/.next/standalone/node_modules/y18n/package.json +70 -0
  543. package/web/.next/standalone/node_modules/yargs/build/lib/argsert.js +62 -0
  544. package/web/.next/standalone/node_modules/yargs/build/lib/command.js +449 -0
  545. package/web/.next/standalone/node_modules/yargs/build/lib/completion-templates.js +48 -0
  546. package/web/.next/standalone/node_modules/yargs/build/lib/completion.js +243 -0
  547. package/web/.next/standalone/node_modules/yargs/build/lib/middleware.js +88 -0
  548. package/web/.next/standalone/node_modules/yargs/build/lib/parse-command.js +32 -0
  549. package/web/.next/standalone/node_modules/yargs/build/lib/typings/common-types.js +9 -0
  550. package/web/.next/standalone/node_modules/yargs/build/lib/usage.js +584 -0
  551. package/web/.next/standalone/node_modules/yargs/build/lib/utils/apply-extends.js +59 -0
  552. package/web/.next/standalone/node_modules/yargs/build/lib/utils/is-promise.js +5 -0
  553. package/web/.next/standalone/node_modules/yargs/build/lib/utils/levenshtein.js +34 -0
  554. package/web/.next/standalone/node_modules/yargs/build/lib/utils/maybe-async-result.js +17 -0
  555. package/web/.next/standalone/node_modules/yargs/build/lib/utils/obj-filter.js +10 -0
  556. package/web/.next/standalone/node_modules/yargs/build/lib/utils/process-argv.js +17 -0
  557. package/web/.next/standalone/node_modules/yargs/build/lib/utils/set-blocking.js +12 -0
  558. package/web/.next/standalone/node_modules/yargs/build/lib/utils/which-module.js +10 -0
  559. package/web/.next/standalone/node_modules/yargs/build/lib/validation.js +305 -0
  560. package/web/.next/standalone/node_modules/yargs/build/lib/yargs-factory.js +1512 -0
  561. package/web/.next/standalone/node_modules/yargs/build/lib/yerror.js +9 -0
  562. package/web/.next/standalone/node_modules/yargs/helpers/helpers.mjs +10 -0
  563. package/web/.next/standalone/node_modules/yargs/index.mjs +8 -0
  564. package/web/.next/standalone/node_modules/yargs/lib/platform-shims/esm.mjs +73 -0
  565. package/web/.next/standalone/node_modules/yargs/package.json +123 -0
  566. package/web/.next/standalone/node_modules/yargs-parser/build/lib/index.js +62 -0
  567. package/web/.next/standalone/node_modules/yargs-parser/build/lib/string-utils.js +65 -0
  568. package/web/.next/standalone/node_modules/yargs-parser/build/lib/tokenize-arg-string.js +40 -0
  569. package/web/.next/standalone/node_modules/yargs-parser/build/lib/yargs-parser-types.js +12 -0
  570. package/web/.next/standalone/node_modules/yargs-parser/build/lib/yargs-parser.js +1045 -0
  571. package/web/.next/standalone/node_modules/yargs-parser/package.json +92 -0
  572. package/web/.next/standalone/node_modules/yauzl/LICENSE +21 -0
  573. package/web/.next/standalone/node_modules/yauzl/README.md +658 -0
  574. package/web/.next/standalone/node_modules/yauzl/index.js +796 -0
  575. package/web/.next/standalone/node_modules/yauzl/package.json +40 -0
  576. package/web/.next/standalone/packages/web/.next/BUILD_ID +1 -1
  577. package/web/.next/standalone/packages/web/.next/app-path-routes-manifest.json +10 -0
  578. package/web/.next/standalone/packages/web/.next/build-manifest.json +6 -6
  579. package/web/.next/standalone/packages/web/.next/node_modules/puppeteer-582bc9288a971b4a/lib/esm/package.json +1 -0
  580. package/web/.next/standalone/packages/web/.next/node_modules/puppeteer-582bc9288a971b4a/lib/esm/puppeteer/getConfiguration.js +122 -0
  581. package/web/.next/standalone/packages/web/.next/node_modules/puppeteer-582bc9288a971b4a/lib/esm/puppeteer/puppeteer.js +40 -0
  582. package/web/.next/standalone/packages/web/.next/node_modules/puppeteer-582bc9288a971b4a/package.json +145 -0
  583. package/web/.next/standalone/packages/web/.next/prerender-manifest.json +3 -27
  584. package/web/.next/standalone/packages/web/.next/routes-manifest.json +70 -0
  585. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page/build-manifest.json +4 -4
  586. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page.js +1 -1
  587. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  588. package/web/.next/standalone/packages/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  589. package/web/.next/standalone/packages/web/.next/server/app/_global-error.html +2 -2
  590. package/web/.next/standalone/packages/web/.next/server/app/_global-error.rsc +1 -1
  591. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  592. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  593. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  594. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  595. package/web/.next/standalone/packages/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  596. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page/build-manifest.json +4 -4
  597. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page/server-reference-manifest.json +7 -7
  598. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page.js +10 -7
  599. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  600. package/web/.next/standalone/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  601. package/web/.next/standalone/packages/web/.next/server/app/_not-found.html +1 -1
  602. package/web/.next/standalone/packages/web/.next/server/app/_not-found.rsc +15 -14
  603. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_full.segment.rsc +15 -14
  604. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  605. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_index.segment.rsc +6 -5
  606. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  607. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  608. package/web/.next/standalone/packages/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  609. package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js +3 -3
  610. package/web/.next/standalone/packages/web/.next/server/app/api/access/route.js.nft.json +1 -1
  611. package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js +5 -4
  612. package/web/.next/standalone/packages/web/.next/server/app/api/agents/route.js.nft.json +1 -1
  613. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route/app-paths-manifest.json +3 -0
  614. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route/build-manifest.json +11 -0
  615. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route/server-reference-manifest.json +4 -0
  616. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route.js +10 -0
  617. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route.js.map +5 -0
  618. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route.js.nft.json +1 -0
  619. package/web/.next/standalone/packages/web/.next/server/app/api/app-update/route_client-reference-manifest.js +2 -0
  620. package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js +3 -3
  621. package/web/.next/standalone/packages/web/.next/server/app/api/attachments/route.js.nft.json +1 -1
  622. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js +3 -3
  623. package/web/.next/standalone/packages/web/.next/server/app/api/auth/session/route.js.nft.json +1 -1
  624. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route/app-paths-manifest.json +3 -0
  625. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route/build-manifest.json +11 -0
  626. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route/server-reference-manifest.json +4 -0
  627. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route.js +10 -0
  628. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route.js.map +5 -0
  629. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route.js.nft.json +1 -0
  630. package/web/.next/standalone/packages/web/.next/server/app/api/boards/comments/route_client-reference-manifest.js +2 -0
  631. package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js +3 -3
  632. package/web/.next/standalone/packages/web/.next/server/app/api/boards/route.js.nft.json +1 -1
  633. package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js +3 -3
  634. package/web/.next/standalone/packages/web/.next/server/app/api/config/route.js.nft.json +1 -1
  635. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route/app-paths-manifest.json +3 -0
  636. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route/build-manifest.json +11 -0
  637. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route/server-reference-manifest.json +4 -0
  638. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route.js +10 -0
  639. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route.js.map +5 -0
  640. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route.js.nft.json +1 -0
  641. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/open/route_client-reference-manifest.js +2 -0
  642. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js +3 -3
  643. package/web/.next/standalone/packages/web/.next/server/app/api/context-files/route.js.nft.json +1 -1
  644. package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js +3 -3
  645. package/web/.next/standalone/packages/web/.next/server/app/api/events/route.js.nft.json +1 -1
  646. package/web/.next/standalone/packages/web/.next/server/app/api/executor/health/route.js +3 -3
  647. package/web/.next/standalone/packages/web/.next/server/app/api/executor/health/route.js.nft.json +1 -1
  648. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js +3 -3
  649. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/directory/route.js.nft.json +1 -1
  650. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/pick-directory/route.js +3 -3
  651. package/web/.next/standalone/packages/web/.next/server/app/api/filesystem/pick-directory/route.js.nft.json +1 -1
  652. package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js +3 -3
  653. package/web/.next/standalone/packages/web/.next/server/app/api/github/repos/route.js.nft.json +1 -1
  654. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route/app-paths-manifest.json +3 -0
  655. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route/build-manifest.json +11 -0
  656. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route/server-reference-manifest.json +4 -0
  657. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route.js +10 -0
  658. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route.js.map +5 -0
  659. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route.js.nft.json +1 -0
  660. package/web/.next/standalone/packages/web/.next/server/app/api/github/webhook/route_client-reference-manifest.js +2 -0
  661. package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js +3 -3
  662. package/web/.next/standalone/packages/web/.next/server/app/api/health/boards/route.js.nft.json +1 -1
  663. package/web/.next/standalone/packages/web/.next/server/app/api/health/sessions/route.js +3 -3
  664. package/web/.next/standalone/packages/web/.next/server/app/api/health/sessions/route.js.nft.json +1 -1
  665. package/web/.next/standalone/packages/web/.next/server/app/api/notifications/route.js +3 -3
  666. package/web/.next/standalone/packages/web/.next/server/app/api/notifications/route.js.nft.json +1 -1
  667. package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js +3 -3
  668. package/web/.next/standalone/packages/web/.next/server/app/api/preferences/route.js.nft.json +1 -1
  669. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route/app-paths-manifest.json +3 -0
  670. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route/build-manifest.json +11 -0
  671. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route/server-reference-manifest.json +4 -0
  672. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route.js +11 -0
  673. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route.js.map +5 -0
  674. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route.js.nft.json +1 -0
  675. package/web/.next/standalone/packages/web/.next/server/app/api/remote-access/route_client-reference-manifest.js +2 -0
  676. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/[id]/route.js +3 -3
  677. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
  678. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js +3 -3
  679. package/web/.next/standalone/packages/web/.next/server/app/api/repositories/route.js.nft.json +1 -1
  680. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/actions/route.js +3 -3
  681. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/actions/route.js.nft.json +1 -1
  682. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/archive/route.js +3 -3
  683. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  684. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js +3 -3
  685. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/checks/route.js.nft.json +1 -1
  686. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js +3 -3
  687. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/diff/route.js.nft.json +1 -1
  688. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/route.js +3 -3
  689. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/route.js.nft.json +1 -1
  690. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route/app-paths-manifest.json +3 -0
  691. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route/build-manifest.json +11 -0
  692. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route/server-reference-manifest.json +4 -0
  693. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route.js +10 -0
  694. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route.js.map +5 -0
  695. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route.js.nft.json +1 -0
  696. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feed/stream/route_client-reference-manifest.js +2 -0
  697. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js +3 -3
  698. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/feedback/route.js.nft.json +1 -1
  699. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js +3 -3
  700. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/files/route.js.nft.json +1 -1
  701. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route/app-paths-manifest.json +3 -0
  702. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route/build-manifest.json +11 -0
  703. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route/server-reference-manifest.json +4 -0
  704. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route.js +10 -0
  705. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route.js.map +5 -0
  706. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route.js.nft.json +1 -0
  707. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/interrupt/route_client-reference-manifest.js +2 -0
  708. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/keys/route.js +3 -3
  709. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/keys/route.js.nft.json +1 -1
  710. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js +3 -3
  711. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -1
  712. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js +3 -3
  713. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/route.js.nft.json +1 -1
  714. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/stream/route.js +3 -3
  715. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/output/stream/route.js.nft.json +1 -1
  716. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route/app-paths-manifest.json +3 -0
  717. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route/build-manifest.json +11 -0
  718. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route/server-reference-manifest.json +4 -0
  719. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route.js +10 -0
  720. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route.js.map +5 -0
  721. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route.js.nft.json +1 -0
  722. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/dom/route_client-reference-manifest.js +2 -0
  723. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route/app-paths-manifest.json +3 -0
  724. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route/build-manifest.json +11 -0
  725. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route/server-reference-manifest.json +4 -0
  726. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route.js +10 -0
  727. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route.js.map +5 -0
  728. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route.js.nft.json +1 -0
  729. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/route_client-reference-manifest.js +2 -0
  730. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route/app-paths-manifest.json +3 -0
  731. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route/build-manifest.json +11 -0
  732. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route/server-reference-manifest.json +4 -0
  733. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route.js +10 -0
  734. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route.js.map +5 -0
  735. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route.js.nft.json +1 -0
  736. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/preview/screenshot/route_client-reference-manifest.js +2 -0
  737. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js +3 -3
  738. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -1
  739. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js +3 -3
  740. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  741. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/send/route.js +3 -3
  742. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/[id]/send/route.js.nft.json +1 -1
  743. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js +3 -3
  744. package/web/.next/standalone/packages/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  745. package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js +3 -3
  746. package/web/.next/standalone/packages/web/.next/server/app/api/spawn/route.js.nft.json +1 -1
  747. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js +3 -3
  748. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/branches/route.js.nft.json +1 -1
  749. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js +3 -3
  750. package/web/.next/standalone/packages/web/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  751. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route.js +1 -1
  752. package/web/.next/standalone/packages/web/.next/server/app/auth/grant/route.js.nft.json +1 -1
  753. package/web/.next/standalone/packages/web/.next/server/app/icon.svg/route.js +1 -1
  754. package/web/.next/standalone/packages/web/.next/server/app/icon.svg/route.js.nft.json +1 -1
  755. package/web/.next/standalone/packages/web/.next/server/app/page/build-manifest.json +4 -4
  756. package/web/.next/standalone/packages/web/.next/server/app/page/react-loadable-manifest.json +4 -3
  757. package/web/.next/standalone/packages/web/.next/server/app/page/server-reference-manifest.json +7 -7
  758. package/web/.next/standalone/packages/web/.next/server/app/page.js +13 -9
  759. package/web/.next/standalone/packages/web/.next/server/app/page.js.nft.json +1 -1
  760. package/web/.next/standalone/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
  761. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page/build-manifest.json +4 -4
  762. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page/server-reference-manifest.json +7 -7
  763. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page.js +13 -9
  764. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  765. package/web/.next/standalone/packages/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  766. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page/build-manifest.json +4 -4
  767. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page/server-reference-manifest.json +7 -7
  768. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page.js +10 -7
  769. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page.js.nft.json +1 -1
  770. package/web/.next/standalone/packages/web/.next/server/app/sign-in/[[...sign-in]]/page_client-reference-manifest.js +1 -1
  771. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/build-manifest.json +4 -4
  772. package/web/.next/standalone/packages/web/.next/server/app/unlock/page/server-reference-manifest.json +7 -7
  773. package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js +11 -8
  774. package/web/.next/standalone/packages/web/.next/server/app/unlock/page.js.nft.json +1 -1
  775. package/web/.next/standalone/packages/web/.next/server/app/unlock/page_client-reference-manifest.js +1 -1
  776. package/web/.next/standalone/packages/web/.next/server/app-paths-manifest.json +10 -0
  777. package/web/.next/standalone/packages/web/.next/server/chunks/26076_server_app_api_sessions_[id]_preview_screenshot_route_actions_dcbbcaf6.js +3 -0
  778. package/web/.next/standalone/packages/web/.next/server/chunks/29f24__next-internal_server_app_api_sessions_[id]_feed_stream_route_actions_1262f517.js +3 -0
  779. package/web/.next/standalone/packages/web/.next/server/chunks/29f24__next-internal_server_app_api_sessions_[id]_interrupt_route_actions_89990829.js +3 -0
  780. package/web/.next/standalone/packages/web/.next/server/chunks/29f24__next-internal_server_app_api_sessions_[id]_preview_dom_route_actions_fb81dadb.js +3 -0
  781. package/web/.next/standalone/packages/web/.next/server/chunks/730ea_web__next-internal_server_app_api_boards_comments_route_actions_7acfa960.js +3 -0
  782. package/web/.next/standalone/packages/web/.next/server/chunks/730ea_web__next-internal_server_app_api_context-files_open_route_actions_ffa7eab4.js +3 -0
  783. package/web/.next/standalone/packages/web/.next/server/chunks/730ea_web__next-internal_server_app_api_sessions_[id]_preview_route_actions_9f632c66.js +3 -0
  784. package/web/.next/standalone/packages/web/.next/server/chunks/[externals]__06cd15c5._.js +3 -0
  785. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__0c7f79b1._.js → [root-of-the-server]__025155ac._.js} +1 -1
  786. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__144e8e60._.js → [root-of-the-server]__03277e82._.js} +1 -1
  787. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__16d4a78f._.js → [root-of-the-server]__03d02e36._.js} +1 -1
  788. package/web/.next/standalone/packages/web/.next/server/chunks/{[root-of-the-server]__095ffdaa._.js → [root-of-the-server]__06d0fa23._.js} +1 -1
  789. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__07d320fc._.js +3 -0
  790. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__09d81126._.js +3 -0
  791. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0a4bdecd._.js +3 -0
  792. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0d3270b2._.js +3 -0
  793. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0f87f848._.js +3 -0
  794. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__120e7cdf._.js +3 -0
  795. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__186317eb._.js +3 -0
  796. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1888a793._.js +3 -0
  797. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1ae07be2._.js +3 -0
  798. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1b995ded._.js +3 -0
  799. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1c1c0e68._.js +3 -0
  800. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1ce34a21._.js +3 -0
  801. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__228603ec._.js +3 -0
  802. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__256d4deb._.js +3 -0
  803. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2a02fc49._.js +3 -0
  804. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2ce39d51._.js +1 -1
  805. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2d6ad93c._.js +3 -0
  806. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__31703e2b._.js +3 -0
  807. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__394943dc._.js +3 -0
  808. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3bab2cf7._.js +3 -0
  809. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3f48e8a2._.js +3 -0
  810. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__405fc5bc._.js +3 -0
  811. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__412dec17._.js +3 -0
  812. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__428f1837._.js +3 -0
  813. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__446f586e._.js +3 -0
  814. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__46ba5636._.js +3 -0
  815. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__49e358a8._.js +3 -0
  816. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4a3e9ddd._.js +3 -0
  817. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4d8a3fa3._.js +3 -0
  818. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5dc7cf0d._.js +3 -0
  819. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5fd67791._.js +3 -0
  820. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__61a55b93._.js +3 -0
  821. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__621d9bca._.js +3 -0
  822. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6313c91e._.js +28 -0
  823. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__65fcccc8._.js +3 -0
  824. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__668ff2cd._.js +3 -0
  825. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__66e8ccce._.js +3 -0
  826. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6b163dd7._.js +3 -0
  827. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6c5a5852._.js +3 -0
  828. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__73601621._.js +3 -0
  829. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__747ac51a._.js +3 -0
  830. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__78d6e137._.js +3 -0
  831. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7dac9015._.js +3 -0
  832. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7e929085._.js +3 -0
  833. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7fcfdb86._.js +3 -0
  834. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__80fb443b._.js +3 -0
  835. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__85538066._.js +3 -0
  836. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__85b114a2._.js +3 -0
  837. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__865615a6._.js +3 -0
  838. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__893cfe3c._.js +3 -0
  839. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__90d02df4._.js +3 -0
  840. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__925bed49._.js +3 -0
  841. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__95440fe8._.js +3 -0
  842. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__968aabbd._.js +3 -0
  843. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__97658502._.js +3 -0
  844. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9b2f424f._.js +3 -0
  845. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9ca51739._.js +3 -0
  846. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a45d3a1d._.js +3 -0
  847. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b5c89bad._.js +3 -0
  848. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b73a3118._.js +3 -0
  849. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c06cb06b._.js +3 -0
  850. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c624410f._.js +3 -0
  851. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c6ecf2e6._.js +3 -0
  852. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c9626ece._.js +3 -0
  853. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c9b787f4._.js +3 -0
  854. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cb1e2942._.js +3 -0
  855. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cb29be7d._.js +3 -0
  856. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cc4964a5._.js +3 -0
  857. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cdcdbbe3._.js +3 -0
  858. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ce529f57._.js +3 -0
  859. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cfaae401._.js +3 -0
  860. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d2afbd4e._.js +3 -0
  861. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d62bf196._.js +3 -0
  862. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d8cd86c9._.js +3 -0
  863. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__de098ee1._.js +3 -0
  864. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e0d759be._.js +3 -0
  865. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e6181b22._.js +3 -0
  866. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__e633102f._.js +3 -0
  867. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ea845f9f._.js +7 -0
  868. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__eabdec9e._.js +3 -0
  869. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__eb0c88b2._.js +3 -0
  870. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ececfccf._.js +3 -0
  871. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ed83cdf3._.js +3 -0
  872. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__eda7b9ea._.js +3 -0
  873. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ef38eeb2._.js +3 -0
  874. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__efbfac9f._.js +3 -0
  875. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__efd26bfc._.js +3 -0
  876. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f12a3bd3._.js +3 -0
  877. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f4786ce9._.js +3 -0
  878. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f4d63c18._.js +3 -0
  879. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f8ebc9db._.js +3 -0
  880. package/web/.next/standalone/packages/web/.next/server/chunks/_2c837d66._.js +80 -0
  881. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_5eb57175.js +6 -0
  882. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_eaad1f33.js +3 -0
  883. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_api_app-update_route_actions_67fa9ca7.js +3 -0
  884. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_api_github_webhook_route_actions_16ed82df.js +3 -0
  885. package/web/.next/standalone/packages/web/.next/server/chunks/packages_web__next-internal_server_app_api_remote-access_route_actions_5ebfaea6.js +3 -0
  886. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[externals]_node:async_hooks_b485b2a4._.js +3 -0
  887. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__000b8c99._.js +4 -0
  888. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__009ce29c._.js +3 -0
  889. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__010700d3._.js +3 -0
  890. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__0aa08967._.js +3 -0
  891. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__11ca851a._.js +3 -0
  892. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__29091976._.js +3 -0
  893. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__29d8d063._.js +4 -0
  894. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__4168e031._.js +3 -0
  895. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__5fccda2c._.js +3 -0
  896. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{[root-of-the-server]__525ee5d4._.js → [root-of-the-server]__85aece6a._.js} +2 -2
  897. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__8a6b25f0._.js +3 -0
  898. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__8bcf983b._.js +1 -1
  899. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__a3c8291e._.js +3 -0
  900. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__b388693f._.js +1 -1
  901. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__d1efcbf0._.js +3 -0
  902. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__d800fc87._.js +3 -0
  903. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__e6f079d9._.js +3 -0
  904. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_0e1412de._.js +1 -1
  905. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_1f2460d5._.js +3 -0
  906. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_230c0c14._.js +80 -0
  907. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_27fe5f5d._.js +1 -1
  908. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_69e05fca._.js +1 -1
  909. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_6cfd06c2._.js +3 -0
  910. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_7321b77f._.js +1 -1
  911. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_80efe193._.js +1 -1
  912. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_8982bbf3._.js +3 -0
  913. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_9f3d31e1._.js +1 -1
  914. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_b214b154._.js +3 -0
  915. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_b6d31783._.js +1 -1
  916. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_c0f0e227._.js +1 -1
  917. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_c9612a3a._.js +1 -1
  918. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_e1c18705._.js +3 -0
  919. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_f36ddaa9._.js +1 -1
  920. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_270cb834._.js +1 -1
  921. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_8d94411c._.js +3 -0
  922. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_3d65ee57._.js +24 -0
  923. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_902120fe._.js +31 -0
  924. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{node_modules_@clerk_nextjs_dist_esm_app-router_57153687._.js → node_modules_@clerk_nextjs_dist_esm_app-router_0a811c5a._.js} +2 -2
  925. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_2c78c2f3._.js +3 -0
  926. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_server_index_a054612e.js +3 -0
  927. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@radix-ui_02f0d3f0._.js +3 -0
  928. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_message-square_2e76b8d9.js +3 -0
  929. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_a9871523._.js +14 -0
  930. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_ae5d7b42._.js +3 -0
  931. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/{node_modules_next_2a43e292._.js → node_modules_next_c73d6895._.js} +2 -2
  932. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_08570d7f._.js +1 -1
  933. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_65e60196._.js +1 -1
  934. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_891f7b49._.js +6 -0
  935. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_cd51dad4.js +1 -1
  936. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_esm_eedfc1fd._.js +1 -1
  937. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_components_board_WorkspaceKanban_tsx_735b7999._.js +1 -1
  938. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_components_ui_Tooltip_tsx_6becc8ca._.js +3 -0
  939. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_features_dashboard_DashboardClient_tsx_81ae42b0._.js +3 -0
  940. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_lib_cn_ts_d08d265f._.js +3 -0
  941. package/web/.next/standalone/packages/web/.next/server/functions-config-manifest.json +7 -5
  942. package/web/.next/standalone/packages/web/.next/server/middleware-build-manifest.js +4 -4
  943. package/web/.next/standalone/packages/web/.next/server/middleware.js +2 -4
  944. package/web/.next/standalone/packages/web/.next/server/pages/404.html +1 -1
  945. package/web/.next/standalone/packages/web/.next/server/pages/500.html +2 -2
  946. package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.js +1 -1
  947. package/web/.next/standalone/packages/web/.next/server/server-reference-manifest.json +8 -8
  948. package/web/.next/standalone/packages/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_clientMiddlewareManifest.json +0 -4
  949. package/web/.next/standalone/packages/web/.next/static/chunks/006a91a252482204.js +1 -0
  950. package/web/.next/standalone/packages/web/.next/static/chunks/07f3b9a104ce0ff4.js +1 -0
  951. package/web/.next/standalone/packages/web/.next/static/chunks/1004422d31074d62.js +1 -0
  952. package/web/.next/standalone/packages/web/.next/static/chunks/{12d9b4273416fe9b.js → 28eac764d6544827.js} +1 -1
  953. package/web/.next/standalone/packages/web/.next/static/chunks/2e2e8fd2ceca47dc.js +6 -0
  954. package/web/.next/standalone/packages/web/.next/static/chunks/30ababddac1b82dc.js +1 -0
  955. package/web/.next/standalone/packages/web/.next/static/chunks/3349bdab17ed1183.js +1 -0
  956. package/web/.next/standalone/packages/web/.next/static/chunks/3770166bed1577ce.js +4 -0
  957. package/web/.next/standalone/packages/web/.next/static/chunks/4c3afea55dd8bc93.js +1 -0
  958. package/web/.next/standalone/packages/web/.next/static/chunks/57858ac28cbf124d.js +1 -0
  959. package/web/.next/standalone/packages/web/.next/static/chunks/7fd2a83e9e74f215.js +1 -0
  960. package/web/.next/standalone/packages/web/.next/static/chunks/91e9e111a2536f92.js +1 -0
  961. package/web/.next/standalone/packages/web/.next/static/chunks/aabc80195233b4da.js +1 -0
  962. package/web/.next/standalone/packages/web/.next/static/chunks/bf82908a598c6de5.css +3 -0
  963. package/web/.next/standalone/packages/web/.next/static/chunks/d6a81d2f8b98b4be.js +1 -0
  964. package/web/.next/standalone/packages/web/.next/static/chunks/e9d0e95bbaa0f4fb.js +1 -0
  965. package/web/.next/standalone/packages/web/.next/static/chunks/ebaa0c535c4135f1.js +1 -0
  966. package/web/.next/standalone/packages/web/.next/static/chunks/{turbopack-57373a2ee9f56180.js → turbopack-49f4119854e8206e.js} +1 -1
  967. package/web/.next/standalone/packages/web/package.json +2 -1
  968. package/web/.next/standalone/packages/web/src/app/api/agents/route.ts +196 -2
  969. package/web/.next/standalone/packages/web/src/app/api/app-update/route.ts +6 -0
  970. package/web/.next/standalone/packages/web/src/app/api/auth/session/route.ts +38 -3
  971. package/web/.next/standalone/packages/web/src/app/api/boards/comments/route.ts +8 -0
  972. package/web/.next/standalone/packages/web/src/app/api/boards/route.ts +1 -0
  973. package/web/.next/standalone/packages/web/src/app/api/context-files/open/route.ts +8 -0
  974. package/web/.next/standalone/packages/web/src/app/api/github/webhook/route.ts +5 -0
  975. package/web/.next/standalone/packages/web/src/app/api/remote-access/route.ts +115 -0
  976. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/feed/stream/route.ts +8 -0
  977. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/interrupt/route.ts +8 -0
  978. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/preview/dom/route.ts +37 -0
  979. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/preview/route.test.ts +141 -0
  980. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/preview/route.ts +90 -0
  981. package/web/.next/standalone/packages/web/src/app/api/sessions/[id]/preview/screenshot/route.ts +43 -0
  982. package/web/.next/standalone/packages/web/src/app/auth/grant/route.ts +3 -28
  983. package/web/.next/standalone/packages/web/src/app/layout.tsx +4 -2
  984. package/web/.next/standalone/packages/web/src/app/page.tsx +32 -3
  985. package/web/.next/standalone/packages/web/src/app/sessions/[id]/page.tsx +36 -3
  986. package/web/.next/standalone/packages/web/src/app/sign-in/[[...sign-in]]/page.tsx +20 -2
  987. package/web/.next/standalone/packages/web/src/app/unlock/page.tsx +29 -7
  988. package/web/.next/standalone/packages/web/src/components/Dashboard.tsx +8 -4
  989. package/web/.next/standalone/packages/web/src/components/board/WorkspaceKanban.tsx +1524 -213
  990. package/web/.next/standalone/packages/web/src/components/layout/AppShell.tsx +30 -14
  991. package/web/.next/standalone/packages/web/src/components/layout/AppUpdateNotice.tsx +345 -0
  992. package/web/.next/standalone/packages/web/src/components/layout/WorkspaceSidebarPanel.tsx +1 -1
  993. package/web/.next/standalone/packages/web/src/components/sessions/ChatPanel.tsx +614 -130
  994. package/web/.next/standalone/packages/web/src/components/sessions/SessionDetail.tsx +33 -6
  995. package/web/.next/standalone/packages/web/src/components/sessions/SessionOverview.tsx +0 -57
  996. package/web/.next/standalone/packages/web/src/components/sessions/SessionPreview.tsx +1143 -0
  997. package/web/.next/standalone/packages/web/src/components/sessions/SessionRuntimeStatusBar.tsx +215 -0
  998. package/web/.next/standalone/packages/web/src/features/dashboard/DashboardClient.tsx +1049 -329
  999. package/web/.next/standalone/packages/web/src/features/sessions/SessionPageClient.tsx +9 -17
  1000. package/web/.next/standalone/packages/web/src/hooks/useAgents.ts +5 -0
  1001. package/web/.next/standalone/packages/web/src/hooks/usePreferences.ts +4 -8
  1002. package/web/.next/standalone/packages/web/src/hooks/useResponsiveSidebarState.ts +46 -0
  1003. package/web/.next/standalone/packages/web/src/hooks/useSessionFeed.ts +57 -3
  1004. package/web/.next/standalone/packages/web/src/lib/auth.test.ts +98 -0
  1005. package/web/.next/standalone/packages/web/src/lib/auth.ts +88 -54
  1006. package/web/.next/standalone/packages/web/src/lib/chatFeed.ts +4 -4
  1007. package/web/.next/standalone/packages/web/src/lib/devPreviewBrowser.ts +608 -0
  1008. package/web/.next/standalone/packages/web/src/lib/edgeAuth.test.ts +14 -25
  1009. package/web/.next/standalone/packages/web/src/lib/edgeAuth.ts +39 -52
  1010. package/web/.next/standalone/packages/web/src/lib/guardedRustProxy.ts +30 -2
  1011. package/web/.next/standalone/packages/web/src/lib/knownAgents.ts +125 -0
  1012. package/web/.next/standalone/packages/web/src/lib/liveEvents.ts +50 -3
  1013. package/web/.next/standalone/packages/web/src/lib/modelAccess.ts +7 -0
  1014. package/web/.next/standalone/packages/web/src/lib/previewSession.test.ts +109 -0
  1015. package/web/.next/standalone/packages/web/src/lib/previewSession.ts +216 -0
  1016. package/web/.next/standalone/packages/web/src/lib/previewTypes.ts +75 -0
  1017. package/web/.next/standalone/packages/web/src/lib/projectConfigSync.ts +13 -2
  1018. package/web/.next/standalone/packages/web/src/lib/proxyRoutes.ts +1 -1
  1019. package/web/.next/standalone/packages/web/src/lib/remoteAccess.test.ts +118 -0
  1020. package/web/.next/standalone/packages/web/src/lib/remoteAccess.ts +245 -0
  1021. package/web/.next/standalone/packages/web/src/lib/remoteAccessManager.ts +513 -0
  1022. package/web/.next/standalone/packages/web/src/lib/remoteAccessRuntime.ts +117 -0
  1023. package/web/.next/standalone/packages/web/src/lib/remoteAuth.test.ts +15 -0
  1024. package/web/.next/standalone/packages/web/src/lib/remoteAuth.ts +8 -65
  1025. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/amp.ts +42 -0
  1026. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/ccr.ts +47 -0
  1027. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/claude.ts +179 -0
  1028. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/codex.ts +211 -0
  1029. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/copilot.ts +136 -0
  1030. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/cursor.ts +39 -0
  1031. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/droid.ts +103 -0
  1032. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/gemini.ts +65 -0
  1033. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/helpers.ts +409 -0
  1034. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/index.ts +127 -0
  1035. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/opencode.ts +138 -0
  1036. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/qwen.ts +50 -0
  1037. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels/types.ts +78 -0
  1038. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModelsShared.ts +9 -0
  1039. package/web/.next/standalone/packages/web/src/lib/rustBackendProxy.ts +29 -3
  1040. package/web/.next/standalone/packages/web/src/lib/sessionModelCatalog.ts +56 -0
  1041. package/web/.next/standalone/packages/web/src/lib/sessionRuntimeStatus.ts +152 -0
  1042. package/web/.next/standalone/packages/web/src/lib/types.ts +32 -0
  1043. package/web/.next/standalone/packages/web/src/proxy.ts +2 -98
  1044. package/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_clientMiddlewareManifest.json +0 -4
  1045. package/web/.next/static/chunks/006a91a252482204.js +1 -0
  1046. package/web/.next/static/chunks/07f3b9a104ce0ff4.js +1 -0
  1047. package/web/.next/static/chunks/1004422d31074d62.js +1 -0
  1048. package/web/.next/static/chunks/{12d9b4273416fe9b.js → 28eac764d6544827.js} +1 -1
  1049. package/web/.next/static/chunks/2e2e8fd2ceca47dc.js +6 -0
  1050. package/web/.next/static/chunks/30ababddac1b82dc.js +1 -0
  1051. package/web/.next/static/chunks/3349bdab17ed1183.js +1 -0
  1052. package/web/.next/static/chunks/3770166bed1577ce.js +4 -0
  1053. package/web/.next/static/chunks/4c3afea55dd8bc93.js +1 -0
  1054. package/web/.next/static/chunks/57858ac28cbf124d.js +1 -0
  1055. package/web/.next/static/chunks/7fd2a83e9e74f215.js +1 -0
  1056. package/web/.next/static/chunks/91e9e111a2536f92.js +1 -0
  1057. package/web/.next/static/chunks/aabc80195233b4da.js +1 -0
  1058. package/web/.next/static/chunks/bf82908a598c6de5.css +3 -0
  1059. package/web/.next/static/chunks/d6a81d2f8b98b4be.js +1 -0
  1060. package/web/.next/static/chunks/e9d0e95bbaa0f4fb.js +1 -0
  1061. package/web/.next/static/chunks/ebaa0c535c4135f1.js +1 -0
  1062. package/web/.next/static/chunks/{turbopack-57373a2ee9f56180.js → turbopack-49f4119854e8206e.js} +1 -1
  1063. package/web/.next/standalone/packages/web/.next/server/app/index.html +0 -1
  1064. package/web/.next/standalone/packages/web/.next/server/app/index.meta +0 -14
  1065. package/web/.next/standalone/packages/web/.next/server/app/index.rsc +0 -24
  1066. package/web/.next/standalone/packages/web/.next/server/app/index.segments/__PAGE__.segment.rsc +0 -9
  1067. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_full.segment.rsc +0 -24
  1068. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_head.segment.rsc +0 -6
  1069. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_index.segment.rsc +0 -6
  1070. package/web/.next/standalone/packages/web/.next/server/app/index.segments/_tree.segment.rsc +0 -7
  1071. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__0074ebac._.js +0 -3
  1072. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__03a6b3e6._.js +0 -3
  1073. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__049daed6._.js +0 -3
  1074. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__09c3bdaf._.js +0 -7
  1075. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__137c9740._.js +0 -3
  1076. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__14949257._.js +0 -80
  1077. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__15594e11._.js +0 -3
  1078. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__159ecc1b._.js +0 -3
  1079. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__171dd44e._.js +0 -3
  1080. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__177505ca._.js +0 -3
  1081. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__18aa1fa3._.js +0 -3
  1082. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1c3521a3._.js +0 -3
  1083. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__1c793b78._.js +0 -3
  1084. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__22fbbc7b._.js +0 -3
  1085. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__25bbe81a._.js +0 -3
  1086. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__2d10de49._.js +0 -3
  1087. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__30442998._.js +0 -3
  1088. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__31d22800._.js +0 -3
  1089. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3d6b30a3._.js +0 -14
  1090. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__3d7ad620._.js +0 -3
  1091. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__44892736._.js +0 -3
  1092. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__495221b1._.js +0 -3
  1093. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__4ff9e8b0._.js +0 -3
  1094. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__54eb1ef0._.js +0 -3
  1095. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__5c375e13._.js +0 -3
  1096. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6362697f._.js +0 -3
  1097. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__69b36e36._.js +0 -3
  1098. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6badbf4e._.js +0 -3
  1099. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6c4cd852._.js +0 -3
  1100. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__6f7b329b._.js +0 -3
  1101. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__70b7af90._.js +0 -3
  1102. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__71077192._.js +0 -3
  1103. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__758687ca._.js +0 -3
  1104. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__7604e43b._.js +0 -3
  1105. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__77b23eae._.js +0 -3
  1106. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__78650ac9._.js +0 -3
  1107. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__789107eb._.js +0 -3
  1108. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__78c062a8._.js +0 -3
  1109. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__78c4bb1e._.js +0 -3
  1110. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__790d1d4b._.js +0 -3
  1111. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__8132442f._.js +0 -3
  1112. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__833a2cd9._.js +0 -3
  1113. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__85d6ae4c._.js +0 -3
  1114. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__8d933120._.js +0 -3
  1115. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__90ac5665._.js +0 -3
  1116. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__92a4f9bf._.js +0 -3
  1117. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__93d550e2._.js +0 -3
  1118. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__96e59c1f._.js +0 -3
  1119. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9c1d09aa._.js +0 -3
  1120. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9d98fee2._.js +0 -3
  1121. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__9fcf6265._.js +0 -3
  1122. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a5b78741._.js +0 -3
  1123. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a8a4b101._.js +0 -3
  1124. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__a8d11727._.js +0 -3
  1125. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__b2e0e81c._.js +0 -3
  1126. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__bf756716._.js +0 -3
  1127. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c09452b3._.js +0 -3
  1128. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c3c6a7bf._.js +0 -3
  1129. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c43dcff1._.js +0 -3
  1130. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__c923cbdc._.js +0 -3
  1131. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ce993e7b._.js +0 -3
  1132. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__cfbdd2bf._.js +0 -3
  1133. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d1d8bfb5._.js +0 -3
  1134. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d4d1744d._.js +0 -3
  1135. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__d8852803._.js +0 -3
  1136. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ea1961bd._.js +0 -3
  1137. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ee8a3221._.js +0 -3
  1138. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ef8c815b._.js +0 -3
  1139. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__ef918d06._.js +0 -3
  1140. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f3693403._.js +0 -3
  1141. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f62cac3a._.js +0 -3
  1142. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f73117e9._.js +0 -3
  1143. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__f7651519._.js +0 -3
  1144. package/web/.next/standalone/packages/web/.next/server/chunks/[root-of-the-server]__fc6ffe6c._.js +0 -3
  1145. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_c59ce641._.js +0 -52
  1146. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_next_3f8eedde._.js +0 -3
  1147. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_next_9a15df2c._.js +0 -14
  1148. package/web/.next/standalone/packages/web/.next/server/chunks/node_modules_next_dist_2175c4f5._.js +0 -6
  1149. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__09178ceb._.js +0 -3
  1150. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__404c1aeb._.js +0 -3
  1151. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__4c215c94._.js +0 -3
  1152. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__504277b5._.js +0 -3
  1153. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__6622b514._.js +0 -4
  1154. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__869d9ac0._.js +0 -4
  1155. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__9dc23e5a._.js +0 -3
  1156. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__b3463b25._.js +0 -3
  1157. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__d6c32514._.js +0 -3
  1158. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__dd8d1ff5._.js +0 -3
  1159. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__e93a8bf2._.js +0 -3
  1160. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__f3a0805b._.js +0 -26
  1161. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/[root-of-the-server]__f9e4d8f6._.js +0 -3
  1162. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_3acfb388._.js +0 -3
  1163. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_54e5c07e._.js +0 -3
  1164. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_5edc4d99._.js +0 -3
  1165. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/_668c9201._.js +0 -3
  1166. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_5c577fb4._.js +0 -22
  1167. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_@clerk_nextjs_dist_esm_app-router_a719fbda._.js +0 -3
  1168. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_f2ebd7a9._.js +0 -3
  1169. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_06f89723._.js +0 -6
  1170. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/node_modules_next_dist_aa203534._.js +0 -3
  1171. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_79316445._.js +0 -3
  1172. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_a078c137._.js +0 -3
  1173. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_app_page_tsx_cd282e82._.js +0 -3
  1174. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_app_unlock_UnlockForm_tsx_ce3149a7._.js +0 -3
  1175. package/web/.next/standalone/packages/web/.next/server/chunks/ssr/packages_web_src_components_556f498f._.js +0 -3
  1176. package/web/.next/standalone/packages/web/.next/static/chunks/25438e9094804f85.js +0 -1
  1177. package/web/.next/standalone/packages/web/.next/static/chunks/38c2e6a114505dfb.js +0 -1
  1178. package/web/.next/standalone/packages/web/.next/static/chunks/42170782dc03a5a6.js +0 -1
  1179. package/web/.next/standalone/packages/web/.next/static/chunks/4f46b791ea244c81.js +0 -6
  1180. package/web/.next/standalone/packages/web/.next/static/chunks/524a7c2a8e85ea2f.js +0 -1
  1181. package/web/.next/standalone/packages/web/.next/static/chunks/5672ef74a562c5dd.js +0 -1
  1182. package/web/.next/standalone/packages/web/.next/static/chunks/710591a828e2bb9d.js +0 -1
  1183. package/web/.next/standalone/packages/web/.next/static/chunks/72c822cfe5b6f4f2.js +0 -4
  1184. package/web/.next/standalone/packages/web/.next/static/chunks/870a993d28314a90.js +0 -1
  1185. package/web/.next/standalone/packages/web/.next/static/chunks/8c120e4e5b844646.js +0 -1
  1186. package/web/.next/standalone/packages/web/.next/static/chunks/8ec81b945f12169b.js +0 -1
  1187. package/web/.next/standalone/packages/web/.next/static/chunks/aa158726d4a10331.js +0 -1
  1188. package/web/.next/standalone/packages/web/.next/static/chunks/adf48bd54f32b061.js +0 -1
  1189. package/web/.next/standalone/packages/web/.next/static/chunks/c5caacf383990e7b.js +0 -1
  1190. package/web/.next/standalone/packages/web/.next/static/chunks/d3cd3cf58c908ec9.js +0 -1
  1191. package/web/.next/standalone/packages/web/.next/static/chunks/df9658182f4f7d54.css +0 -3
  1192. package/web/.next/standalone/packages/web/src/app/unlock/UnlockForm.tsx +0 -98
  1193. package/web/.next/standalone/packages/web/src/lib/editorLinks.ts +0 -51
  1194. package/web/.next/standalone/packages/web/src/lib/runtimeAgentModels.ts +0 -788
  1195. package/web/.next/static/chunks/25438e9094804f85.js +0 -1
  1196. package/web/.next/static/chunks/38c2e6a114505dfb.js +0 -1
  1197. package/web/.next/static/chunks/42170782dc03a5a6.js +0 -1
  1198. package/web/.next/static/chunks/4f46b791ea244c81.js +0 -6
  1199. package/web/.next/static/chunks/524a7c2a8e85ea2f.js +0 -1
  1200. package/web/.next/static/chunks/5672ef74a562c5dd.js +0 -1
  1201. package/web/.next/static/chunks/710591a828e2bb9d.js +0 -1
  1202. package/web/.next/static/chunks/72c822cfe5b6f4f2.js +0 -4
  1203. package/web/.next/static/chunks/870a993d28314a90.js +0 -1
  1204. package/web/.next/static/chunks/8c120e4e5b844646.js +0 -1
  1205. package/web/.next/static/chunks/8ec81b945f12169b.js +0 -1
  1206. package/web/.next/static/chunks/aa158726d4a10331.js +0 -1
  1207. package/web/.next/static/chunks/adf48bd54f32b061.js +0 -1
  1208. package/web/.next/static/chunks/c5caacf383990e7b.js +0 -1
  1209. package/web/.next/static/chunks/d3cd3cf58c908ec9.js +0 -1
  1210. package/web/.next/static/chunks/df9658182f4f7d54.css +0 -3
  1211. /package/web/.next/standalone/packages/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_buildManifest.js +0 -0
  1212. /package/web/.next/standalone/packages/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_ssgManifest.js +0 -0
  1213. /package/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_buildManifest.js +0 -0
  1214. /package/web/.next/static/{8a_zZln8ezVAo0jAilwbF → E4-NvSai1Ps20r9dtdpps}/_ssgManifest.js +0 -0
@@ -2,9 +2,19 @@
2
2
 
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { useRouter } from "next/navigation";
5
- import { ExternalLink, Loader2, Pencil, Plus, Search } from "lucide-react";
5
+ import {
6
+ ExternalLink,
7
+ Loader2,
8
+ MessageSquare,
9
+ Pencil,
10
+ Plus,
11
+ RefreshCw,
12
+ Search,
13
+ } from "lucide-react";
6
14
  import { AgentTileIcon } from "@/components/AgentTileIcon";
15
+ import { usePreferences } from "@/hooks/usePreferences";
7
16
  import { cn } from "@/lib/cn";
17
+ import { subscribeToSnapshotEvents } from "@/lib/liveEvents";
8
18
 
9
19
  type BoardRole =
10
20
  | "intake"
@@ -29,6 +39,12 @@ type BoardTask = {
29
39
  priority: string | null;
30
40
  taskRef: string | null;
31
41
  attemptRef: string | null;
42
+ issueId: string | null;
43
+ githubItemId: string | null;
44
+ attachments: string[];
45
+ notes: string | null;
46
+ commentCount: number;
47
+ comments: BoardComment[];
32
48
  };
33
49
 
34
50
  type BoardColumn = {
@@ -37,15 +53,65 @@ type BoardColumn = {
37
53
  tasks: BoardTask[];
38
54
  };
39
55
 
56
+ type GitHubProjectLink = {
57
+ id?: string | null;
58
+ ownerLogin?: string | null;
59
+ number?: number | null;
60
+ title?: string | null;
61
+ url?: string | null;
62
+ statusFieldId?: string | null;
63
+ statusFieldName?: string | null;
64
+ };
65
+
66
+ type BoardActivity = {
67
+ id: string;
68
+ source: string;
69
+ action: string;
70
+ detail: string;
71
+ timestamp: string;
72
+ };
73
+
74
+ type BoardComment = {
75
+ id: string;
76
+ taskId: string;
77
+ author: string;
78
+ authorEmail?: string | null;
79
+ provider?: string | null;
80
+ body: string;
81
+ timestamp: string;
82
+ };
83
+
84
+ type WebhookDelivery = {
85
+ id: string;
86
+ event: string;
87
+ action: string;
88
+ status: string;
89
+ detail: string;
90
+ repository?: string | null;
91
+ timestamp: string;
92
+ };
93
+
40
94
  type BoardResponse = {
41
95
  projectId: string;
96
+ repository?: string | null;
42
97
  boardPath: string;
43
98
  workspacePath: string;
44
99
  columns: BoardColumn[];
45
100
  primaryRoles: BoardRole[];
101
+ githubProject?: GitHubProjectLink | null;
102
+ recentActions?: BoardActivity[];
103
+ recentWebhookDeliveries?: WebhookDelivery[];
46
104
  watcherHint?: string;
47
105
  };
48
106
 
107
+ type GitHubProjectsResponse = {
108
+ projectId: string;
109
+ repository?: string | null;
110
+ ownerLogin?: string | null;
111
+ linkedProject?: GitHubProjectLink | null;
112
+ projects: GitHubProjectLink[];
113
+ };
114
+
49
115
  type ContextFile = {
50
116
  path: string;
51
117
  name: string;
@@ -74,6 +140,8 @@ interface WorkspaceKanbanProps {
74
140
  agentOptions: string[];
75
141
  }
76
142
 
143
+ type BoardViewFilter = "active" | "all" | "backlog" | "cancelled";
144
+
77
145
  const ROLE_COLOR: Record<BoardRole, string> = {
78
146
  intake: "#3c83f6",
79
147
  ready: "#f59f0a",
@@ -103,9 +171,29 @@ const ROLE_LABEL: Record<BoardRole, string> = {
103
171
  };
104
172
  const ACTIVE_BOARD_REFRESH_MS = 10_000;
105
173
  const HIDDEN_BOARD_REFRESH_MS = 30_000;
174
+ const MARKDOWN_EDITOR_LABELS: Record<string, string> = {
175
+ obsidian: "Obsidian",
176
+ vscode: "VS Code",
177
+ notion: "Notion",
178
+ typora: "Typora",
179
+ logseq: "Logseq",
180
+ custom: "your editor",
181
+ };
106
182
 
107
183
  function toRole(value: string): BoardRole {
108
- const roles: BoardRole[] = ["intake", "ready", "dispatching", "inProgress", "needsInput", "blocked", "errored", "review", "merge", "done", "cancelled"];
184
+ const roles: BoardRole[] = [
185
+ "intake",
186
+ "ready",
187
+ "dispatching",
188
+ "inProgress",
189
+ "needsInput",
190
+ "blocked",
191
+ "errored",
192
+ "review",
193
+ "merge",
194
+ "done",
195
+ "cancelled",
196
+ ];
109
197
  return roles.includes(value as BoardRole) ? (value as BoardRole) : "intake";
110
198
  }
111
199
 
@@ -132,10 +220,53 @@ function formatFileSize(value: number | null | undefined): string {
132
220
  return `${(value / (1024 * 1024)).toFixed(1)} MB`;
133
221
  }
134
222
 
135
- function boardsEqual(left: BoardResponse | null, right: BoardResponse): boolean {
223
+ function getMarkdownEditorLabel(editorId: string): string {
224
+ return MARKDOWN_EDITOR_LABELS[editorId] ?? "your editor";
225
+ }
226
+
227
+ function getContextOpenLabel(editorId: string): string {
228
+ if (editorId === "obsidian" || editorId === "vscode" || editorId === "typora" || editorId === "logseq") {
229
+ return `Open in ${getMarkdownEditorLabel(editorId)}`;
230
+ }
231
+ return "Open file";
232
+ }
233
+
234
+ function ContextAttachmentChip({
235
+ attachment,
236
+ onOpen,
237
+ opening = false,
238
+ }: {
239
+ attachment: string;
240
+ onOpen: () => void;
241
+ opening?: boolean;
242
+ }) {
243
+ return (
244
+ <button
245
+ type="button"
246
+ onClick={onOpen}
247
+ disabled={opening}
248
+ className="inline-flex max-w-full items-center gap-1 rounded-[3px] bg-[color:#292929] px-2 py-1 text-[11px] text-[var(--vk-text-muted)] hover:bg-[var(--vk-bg-hover)] hover:text-[var(--vk-text-normal)] disabled:opacity-60"
249
+ title={attachment}
250
+ aria-label={`Open ${attachment}`}
251
+ >
252
+ {opening ? (
253
+ <Loader2 className="h-3 w-3 shrink-0 animate-spin" />
254
+ ) : (
255
+ <ExternalLink className="h-3 w-3 shrink-0" />
256
+ )}
257
+ <span className="truncate">{attachment}</span>
258
+ </button>
259
+ );
260
+ }
261
+
262
+ function boardsEqual(
263
+ left: BoardResponse | null,
264
+ right: BoardResponse
265
+ ): boolean {
136
266
  if (!left) return false;
137
267
  if (
138
268
  left.projectId !== right.projectId ||
269
+ left.repository !== right.repository ||
139
270
  left.boardPath !== right.boardPath ||
140
271
  left.workspacePath !== right.workspacePath ||
141
272
  left.watcherHint !== right.watcherHint ||
@@ -151,7 +282,11 @@ function boardsEqual(left: BoardResponse | null, right: BoardResponse): boolean
151
282
  }
152
283
  }
153
284
 
154
- for (let columnIndex = 0; columnIndex < left.columns.length; columnIndex += 1) {
285
+ for (
286
+ let columnIndex = 0;
287
+ columnIndex < left.columns.length;
288
+ columnIndex += 1
289
+ ) {
155
290
  const leftColumn = left.columns[columnIndex];
156
291
  const rightColumn = right.columns[columnIndex];
157
292
  if (
@@ -162,7 +297,11 @@ function boardsEqual(left: BoardResponse | null, right: BoardResponse): boolean
162
297
  return false;
163
298
  }
164
299
 
165
- for (let taskIndex = 0; taskIndex < leftColumn.tasks.length; taskIndex += 1) {
300
+ for (
301
+ let taskIndex = 0;
302
+ taskIndex < leftColumn.tasks.length;
303
+ taskIndex += 1
304
+ ) {
166
305
  const leftTask = leftColumn.tasks[taskIndex];
167
306
  const rightTask = rightColumn.tasks[taskIndex];
168
307
  if (
@@ -174,27 +313,135 @@ function boardsEqual(left: BoardResponse | null, right: BoardResponse): boolean
174
313
  leftTask.type !== rightTask.type ||
175
314
  leftTask.priority !== rightTask.priority ||
176
315
  leftTask.taskRef !== rightTask.taskRef ||
177
- leftTask.attemptRef !== rightTask.attemptRef
316
+ leftTask.attemptRef !== rightTask.attemptRef ||
317
+ leftTask.issueId !== rightTask.issueId ||
318
+ leftTask.githubItemId !== rightTask.githubItemId ||
319
+ leftTask.notes !== rightTask.notes ||
320
+ leftTask.commentCount !== rightTask.commentCount ||
321
+ leftTask.comments.length !== rightTask.comments.length ||
322
+ leftTask.attachments.length !== rightTask.attachments.length
178
323
  ) {
179
324
  return false;
180
325
  }
326
+
327
+ for (
328
+ let attachmentIndex = 0;
329
+ attachmentIndex < leftTask.attachments.length;
330
+ attachmentIndex += 1
331
+ ) {
332
+ if (
333
+ leftTask.attachments[attachmentIndex] !==
334
+ rightTask.attachments[attachmentIndex]
335
+ ) {
336
+ return false;
337
+ }
338
+ }
339
+
340
+ for (
341
+ let commentIndex = 0;
342
+ commentIndex < leftTask.comments.length;
343
+ commentIndex += 1
344
+ ) {
345
+ if (
346
+ JSON.stringify(leftTask.comments[commentIndex]) !==
347
+ JSON.stringify(rightTask.comments[commentIndex])
348
+ ) {
349
+ return false;
350
+ }
351
+ }
352
+ }
353
+ }
354
+
355
+ const leftGitHubProject = left.githubProject ?? null;
356
+ const rightGitHubProject = right.githubProject ?? null;
357
+ if (
358
+ JSON.stringify(leftGitHubProject) !== JSON.stringify(rightGitHubProject)
359
+ ) {
360
+ return false;
361
+ }
362
+
363
+ const leftActions = left.recentActions ?? [];
364
+ const rightActions = right.recentActions ?? [];
365
+ if (leftActions.length !== rightActions.length) {
366
+ return false;
367
+ }
368
+ for (let index = 0; index < leftActions.length; index += 1) {
369
+ if (
370
+ JSON.stringify(leftActions[index]) !== JSON.stringify(rightActions[index])
371
+ ) {
372
+ return false;
373
+ }
374
+ }
375
+
376
+ const leftDeliveries = left.recentWebhookDeliveries ?? [];
377
+ const rightDeliveries = right.recentWebhookDeliveries ?? [];
378
+ if (leftDeliveries.length !== rightDeliveries.length) {
379
+ return false;
380
+ }
381
+ for (let index = 0; index < leftDeliveries.length; index += 1) {
382
+ if (
383
+ JSON.stringify(leftDeliveries[index]) !==
384
+ JSON.stringify(rightDeliveries[index])
385
+ ) {
386
+ return false;
181
387
  }
182
388
  }
183
389
 
184
390
  return true;
185
391
  }
186
392
 
393
+ function normalizeBoardResponse(value: BoardResponse): BoardResponse {
394
+ return {
395
+ ...value,
396
+ repository: value.repository ?? null,
397
+ githubProject: value.githubProject ?? null,
398
+ recentActions: Array.isArray(value.recentActions)
399
+ ? value.recentActions
400
+ : [],
401
+ recentWebhookDeliveries: Array.isArray(value.recentWebhookDeliveries)
402
+ ? value.recentWebhookDeliveries
403
+ : [],
404
+ columns: Array.isArray(value.columns)
405
+ ? value.columns.map((column) => ({
406
+ ...column,
407
+ tasks: Array.isArray(column.tasks)
408
+ ? column.tasks.map((task) => ({
409
+ ...task,
410
+ issueId: task.issueId ?? null,
411
+ githubItemId: task.githubItemId ?? null,
412
+ attachments: Array.isArray(task.attachments)
413
+ ? task.attachments
414
+ : [],
415
+ notes: task.notes ?? null,
416
+ commentCount:
417
+ typeof task.commentCount === "number"
418
+ ? task.commentCount
419
+ : Array.isArray(task.comments)
420
+ ? task.comments.length
421
+ : 0,
422
+ comments: Array.isArray(task.comments) ? task.comments : [],
423
+ }))
424
+ : [],
425
+ }))
426
+ : [],
427
+ };
428
+ }
429
+
187
430
  function formatLinkedSessionLabel(session: ProjectSession): string {
188
- return session.branch?.trim() || session.summary?.trim() || session.id.slice(0, 8);
431
+ return (
432
+ session.branch?.trim() || session.summary?.trim() || session.id.slice(0, 8)
433
+ );
189
434
  }
190
435
 
191
436
  function getTaskLinkKey(task: BoardTask): string {
192
- return task.taskRef?.trim() || task.id;
437
+ return task.issueId?.trim() || task.taskRef?.trim() || task.id;
193
438
  }
194
439
 
195
440
  function getSessionAgent(session: ProjectSession): string | null {
196
441
  const candidate = session.metadata?.agent;
197
- return typeof candidate === "string" && candidate.trim().length > 0 ? candidate.trim() : null;
442
+ return typeof candidate === "string" && candidate.trim().length > 0
443
+ ? candidate.trim()
444
+ : null;
198
445
  }
199
446
 
200
447
  function formatSessionStatus(status: string): string {
@@ -228,7 +475,83 @@ function sessionStatusPillClass(status: string): string {
228
475
  return "border-[var(--vk-border)] bg-[rgba(255,255,255,0.03)] text-[var(--vk-text-muted)]";
229
476
  }
230
477
 
231
- function compareProjectSessions(left: ProjectSession, right: ProjectSession, primaryId: string | null): number {
478
+ function buildGitHubIssueUrl(
479
+ repository: string | null | undefined,
480
+ issueId: string | null | undefined
481
+ ): string | null {
482
+ const normalizedIssue = issueId?.trim();
483
+ if (!repository || !normalizedIssue || !/^\d+$/.test(normalizedIssue))
484
+ return null;
485
+ const normalizedRepo = repository
486
+ .trim()
487
+ .replace(/^https?:\/\/github\.com\//, "")
488
+ .replace(/^git@github\.com:/, "")
489
+ .replace(/^ssh:\/\/git@github\.com\//, "")
490
+ .replace(/\.git$/, "")
491
+ .replace(/\/+$/, "");
492
+ const [owner, repo] = normalizedRepo.split("/");
493
+ if (!owner || !repo) return null;
494
+ return `https://github.com/${owner}/${repo}/issues/${normalizedIssue}`;
495
+ }
496
+
497
+ function formatGitHubProjectLabel(
498
+ project: GitHubProjectLink | null | undefined
499
+ ): string {
500
+ if (!project?.id) return "No GitHub Project linked";
501
+ const number =
502
+ typeof project.number === "number" ? `#${project.number}` : "Project";
503
+ return `${number} ${project.title?.trim() || "Untitled"}`.trim();
504
+ }
505
+
506
+ function formatActivityTime(timestamp: string): string {
507
+ const parsed = Date.parse(timestamp);
508
+ if (Number.isNaN(parsed)) return timestamp;
509
+ return new Intl.DateTimeFormat("en-US", {
510
+ month: "short",
511
+ day: "numeric",
512
+ hour: "numeric",
513
+ minute: "2-digit",
514
+ }).format(new Date(parsed));
515
+ }
516
+
517
+ function formatWebhookStatus(status: string): string {
518
+ const normalized = status.trim().toLowerCase();
519
+ if (normalized === "synced") return "Synced";
520
+ if (normalized === "failed") return "Failed";
521
+ if (normalized === "skipped") return "Skipped";
522
+ return status;
523
+ }
524
+
525
+ function webhookStatusClass(status: string): string {
526
+ const normalized = status.trim().toLowerCase();
527
+ if (normalized === "synced") {
528
+ return "border-[rgba(84,176,79,0.35)] bg-[rgba(84,176,79,0.12)] text-[var(--vk-green)]";
529
+ }
530
+ if (normalized === "failed") {
531
+ return "border-[rgba(210,81,81,0.35)] bg-[rgba(210,81,81,0.12)] text-[var(--vk-red)]";
532
+ }
533
+ return "border-[var(--vk-border)] bg-[rgba(255,255,255,0.03)] text-[var(--vk-text-muted)]";
534
+ }
535
+
536
+ function findBoardTask(
537
+ board: BoardResponse | null,
538
+ taskId: string
539
+ ): { task: BoardTask; role: BoardRole } | null {
540
+ if (!board) return null;
541
+ for (const column of board.columns) {
542
+ const task = column.tasks.find((item) => item.id === taskId);
543
+ if (task) {
544
+ return { task, role: column.role };
545
+ }
546
+ }
547
+ return null;
548
+ }
549
+
550
+ function compareProjectSessions(
551
+ left: ProjectSession,
552
+ right: ProjectSession,
553
+ primaryId: string | null
554
+ ): number {
232
555
  if (primaryId) {
233
556
  if (left.id === primaryId && right.id !== primaryId) return -1;
234
557
  if (right.id === primaryId && left.id !== primaryId) return 1;
@@ -238,12 +561,18 @@ function compareProjectSessions(left: ProjectSession, right: ProjectSession, pri
238
561
  return rightTime - leftTime;
239
562
  }
240
563
 
241
- export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: WorkspaceKanbanProps) {
564
+ export function WorkspaceKanban({
565
+ projectId,
566
+ defaultAgent,
567
+ agentOptions,
568
+ }: WorkspaceKanbanProps) {
242
569
  const router = useRouter();
570
+ const { preferences } = usePreferences();
243
571
  const [board, setBoard] = useState<BoardResponse | null>(null);
244
572
  const [loading, setLoading] = useState(false);
245
573
  const [error, setError] = useState<string | null>(null);
246
574
  const [search, setSearch] = useState("");
575
+ const [viewFilter, setViewFilter] = useState<BoardViewFilter>("active");
247
576
 
248
577
  const [composerOpen, setComposerOpen] = useState(false);
249
578
  const [composerRole, setComposerRole] = useState<BoardRole>("intake");
@@ -253,28 +582,51 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
253
582
  const [taskType, setTaskType] = useState("feature");
254
583
  const [priority, setPriority] = useState("normal");
255
584
  const [contextNotes, setContextNotes] = useState("");
256
- const [selectedContextPaths, setSelectedContextPaths] = useState<string[]>([]);
585
+ const [selectedContextPaths, setSelectedContextPaths] = useState<string[]>(
586
+ []
587
+ );
257
588
  const [contextSearch, setContextSearch] = useState("");
258
589
  const [contextFiles, setContextFiles] = useState<ContextFile[]>([]);
259
590
  const [contextLoading, setContextLoading] = useState(false);
260
591
  const [contextError, setContextError] = useState<string | null>(null);
592
+ const [openingContextPath, setOpeningContextPath] = useState<string | null>(null);
261
593
  const [uploadFiles, setUploadFiles] = useState<File[]>([]);
262
594
  const [submitting, setSubmitting] = useState(false);
263
595
  const [submitError, setSubmitError] = useState<string | null>(null);
264
596
  const [projectSessions, setProjectSessions] = useState<ProjectSession[]>([]);
265
- const [editingTask, setEditingTask] = useState<{ task: BoardTask; role: BoardRole } | null>(null);
597
+ const [editingTask, setEditingTask] = useState<{
598
+ task: BoardTask;
599
+ role: BoardRole;
600
+ } | null>(null);
266
601
  const [editRole, setEditRole] = useState<BoardRole>("intake");
267
602
  const [editTitle, setEditTitle] = useState("");
268
603
  const [editDescription, setEditDescription] = useState("");
269
604
  const [editAgent, setEditAgent] = useState(defaultAgent);
270
605
  const [editTaskType, setEditTaskType] = useState("feature");
271
606
  const [editPriority, setEditPriority] = useState("normal");
607
+ const [editIssueId, setEditIssueId] = useState("");
608
+ const [editNotes, setEditNotes] = useState("");
272
609
  const [editLinkedSession, setEditLinkedSession] = useState("");
273
610
  const [editingBusy, setEditingBusy] = useState(false);
274
611
  const [editingError, setEditingError] = useState<string | null>(null);
275
- const [draggingTask, setDraggingTask] = useState<{ taskId: string; role: BoardRole } | null>(null);
612
+ const [commentDraft, setCommentDraft] = useState("");
613
+ const [commentBusy, setCommentBusy] = useState(false);
614
+ const [commentError, setCommentError] = useState<string | null>(null);
615
+ const [draggingTask, setDraggingTask] = useState<{
616
+ taskId: string;
617
+ role: BoardRole;
618
+ } | null>(null);
619
+ const [projectSyncOpen, setProjectSyncOpen] = useState(false);
620
+ const [projectSyncLoading, setProjectSyncLoading] = useState(false);
621
+ const [projectSyncSaving, setProjectSyncSaving] = useState(false);
622
+ const [projectSyncError, setProjectSyncError] = useState<string | null>(null);
623
+ const [projectSyncData, setProjectSyncData] =
624
+ useState<GitHubProjectsResponse | null>(null);
625
+ const [selectedGitHubProjectId, setSelectedGitHubProjectId] = useState("");
276
626
  const hasLoadedBoardRef = useRef(false);
277
627
  const boardRequestInFlightRef = useRef(false);
628
+ const preferredMarkdownEditor = preferences?.markdownEditor?.trim() || "obsidian";
629
+ const contextOpenLabel = getContextOpenLabel(preferredMarkdownEditor);
278
630
 
279
631
  const orderedAgentOptions = useMemo(() => {
280
632
  const normalized = [...new Set(agentOptions.filter(Boolean))];
@@ -297,30 +649,39 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
297
649
  }, [defaultAgent, editAgent, orderedAgentOptions]);
298
650
 
299
651
  useEffect(() => {
300
- if (!composerOpen || !projectId) return;
652
+ if ((!composerOpen && !editingTask) || !projectId) return;
301
653
  let cancelled = false;
302
654
 
303
655
  const loadContextFiles = async () => {
304
656
  setContextLoading(true);
305
657
  setContextError(null);
306
658
  try {
307
- const res = await fetch(`/api/context-files?projectId=${encodeURIComponent(projectId)}`);
659
+ const res = await fetch(
660
+ `/api/context-files?projectId=${encodeURIComponent(projectId)}`
661
+ );
308
662
  const payload = (await res.json().catch(() => null)) as
309
663
  | ContextFilesResponse
310
664
  | { error?: string }
311
665
  | null;
312
666
  if (!res.ok) {
313
- throw new Error((payload as { error?: string } | null)?.error ?? `Failed to load context files: ${res.status}`);
667
+ throw new Error(
668
+ (payload as { error?: string } | null)?.error ??
669
+ `Failed to load context files: ${res.status}`
670
+ );
314
671
  }
315
672
  if (cancelled) return;
316
- const files = Array.isArray((payload as ContextFilesResponse | null)?.files)
673
+ const files = Array.isArray(
674
+ (payload as ContextFilesResponse | null)?.files
675
+ )
317
676
  ? (payload as ContextFilesResponse).files
318
677
  : [];
319
678
  setContextFiles(files);
320
679
  } catch (err) {
321
680
  if (cancelled) return;
322
681
  setContextFiles([]);
323
- setContextError(err instanceof Error ? err.message : "Failed to load context files");
682
+ setContextError(
683
+ err instanceof Error ? err.message : "Failed to load context files"
684
+ );
324
685
  } finally {
325
686
  if (!cancelled) setContextLoading(false);
326
687
  }
@@ -330,7 +691,7 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
330
691
  return () => {
331
692
  cancelled = true;
332
693
  };
333
- }, [composerOpen, projectId]);
694
+ }, [composerOpen, editingTask, projectId]);
334
695
 
335
696
  useEffect(() => {
336
697
  if (!projectId || (!composerOpen && !editingTask)) return;
@@ -338,7 +699,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
338
699
 
339
700
  const loadProjectSessions = async () => {
340
701
  try {
341
- const res = await fetch(`/api/sessions?project=${encodeURIComponent(projectId)}`);
702
+ const res = await fetch(
703
+ `/api/sessions?project=${encodeURIComponent(projectId)}`
704
+ );
342
705
  const payload = (await res.json().catch(() => null)) as
343
706
  | { sessions?: ProjectSession[] }
344
707
  | ProjectSession[]
@@ -350,8 +713,8 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
350
713
  const sessions = Array.isArray(payload)
351
714
  ? payload
352
715
  : Array.isArray(payload?.sessions)
353
- ? payload.sessions
354
- : [];
716
+ ? payload.sessions
717
+ : [];
355
718
  setProjectSessions(sessions);
356
719
  } catch {
357
720
  if (!cancelled) {
@@ -368,58 +731,123 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
368
731
 
369
732
  useEffect(() => {
370
733
  hasLoadedBoardRef.current = false;
734
+ setProjectSyncOpen(false);
735
+ setProjectSyncError(null);
736
+ setProjectSyncData(null);
737
+ setSelectedGitHubProjectId("");
371
738
  }, [projectId]);
372
739
 
373
- const loadBoard = useCallback(async (options?: { silent?: boolean }) => {
740
+ const loadBoard = useCallback(
741
+ async (options?: { silent?: boolean }) => {
742
+ if (!projectId) {
743
+ setBoard(null);
744
+ setError(null);
745
+ setLoading(false);
746
+ hasLoadedBoardRef.current = false;
747
+ return;
748
+ }
749
+ if (boardRequestInFlightRef.current) {
750
+ return;
751
+ }
752
+
753
+ boardRequestInFlightRef.current = true;
754
+
755
+ if (!options?.silent) {
756
+ setLoading(true);
757
+ }
758
+ try {
759
+ const res = await fetch(
760
+ `/api/boards?projectId=${encodeURIComponent(projectId)}`
761
+ );
762
+ const data = (await res.json().catch(() => null)) as
763
+ | BoardResponse
764
+ | { error?: string }
765
+ | null;
766
+ if (!res.ok) {
767
+ throw new Error(
768
+ (data as { error?: string } | null)?.error ??
769
+ `Failed to load board: ${res.status}`
770
+ );
771
+ }
772
+
773
+ const nextBoard = normalizeBoardResponse(data as BoardResponse);
774
+ hasLoadedBoardRef.current = true;
775
+ setBoard((current) =>
776
+ boardsEqual(current, nextBoard) ? current : nextBoard
777
+ );
778
+ setError(null);
779
+ } catch (err) {
780
+ if (!options?.silent || !hasLoadedBoardRef.current) {
781
+ setBoard(null);
782
+ setError(err instanceof Error ? err.message : "Failed to load board");
783
+ }
784
+ } finally {
785
+ if (!options?.silent) {
786
+ setLoading(false);
787
+ }
788
+ boardRequestInFlightRef.current = false;
789
+ }
790
+ },
791
+ [projectId]
792
+ );
793
+
794
+ useEffect(() => {
795
+ void loadBoard({ silent: false });
796
+ }, [loadBoard]);
797
+
798
+ const loadGitHubProjects = useCallback(async () => {
374
799
  if (!projectId) {
375
- setBoard(null);
376
- setError(null);
377
- setLoading(false);
378
- hasLoadedBoardRef.current = false;
379
- return;
380
- }
381
- if (boardRequestInFlightRef.current) {
800
+ setProjectSyncData(null);
801
+ setProjectSyncError(null);
382
802
  return;
383
803
  }
384
804
 
385
- boardRequestInFlightRef.current = true;
386
-
387
- if (!options?.silent) {
388
- setLoading(true);
389
- }
805
+ setProjectSyncLoading(true);
806
+ setProjectSyncError(null);
390
807
  try {
391
- const res = await fetch(`/api/boards?projectId=${encodeURIComponent(projectId)}`);
392
- const data = (await res.json().catch(() => null)) as BoardResponse | { error?: string } | null;
808
+ const res = await fetch(
809
+ `/api/github/projects?projectId=${encodeURIComponent(projectId)}`
810
+ );
811
+ const payload = (await res.json().catch(() => null)) as
812
+ | GitHubProjectsResponse
813
+ | { error?: string }
814
+ | null;
393
815
  if (!res.ok) {
394
- throw new Error((data as { error?: string } | null)?.error ?? `Failed to load board: ${res.status}`);
816
+ throw new Error(
817
+ (payload as { error?: string } | null)?.error ??
818
+ `Failed to load GitHub Projects (${res.status})`
819
+ );
395
820
  }
396
821
 
397
- const nextBoard = data as BoardResponse;
398
- hasLoadedBoardRef.current = true;
399
- setBoard((current) => (boardsEqual(current, nextBoard) ? current : nextBoard));
400
- setError(null);
822
+ const next = {
823
+ ...(payload as GitHubProjectsResponse),
824
+ projects: Array.isArray((payload as GitHubProjectsResponse).projects)
825
+ ? (payload as GitHubProjectsResponse).projects
826
+ : [],
827
+ };
828
+ setProjectSyncData(next);
829
+ setSelectedGitHubProjectId(
830
+ next.linkedProject?.id?.trim() || next.projects[0]?.id?.trim() || ""
831
+ );
401
832
  } catch (err) {
402
- if (!options?.silent || !hasLoadedBoardRef.current) {
403
- setBoard(null);
404
- setError(err instanceof Error ? err.message : "Failed to load board");
405
- }
833
+ setProjectSyncError(
834
+ err instanceof Error ? err.message : "Failed to load GitHub Projects"
835
+ );
836
+ setProjectSyncData(null);
837
+ setSelectedGitHubProjectId("");
406
838
  } finally {
407
- if (!options?.silent) {
408
- setLoading(false);
409
- }
410
- boardRequestInFlightRef.current = false;
839
+ setProjectSyncLoading(false);
411
840
  }
412
841
  }, [projectId]);
413
842
 
414
- useEffect(() => {
415
- void loadBoard({ silent: false });
416
- }, [loadBoard]);
417
-
418
843
  useEffect(() => {
419
844
  if (!projectId) return;
420
845
 
421
846
  const refresh = () => {
422
- if (typeof document !== "undefined" && document.visibilityState === "hidden") {
847
+ if (
848
+ typeof document !== "undefined" &&
849
+ document.visibilityState === "hidden"
850
+ ) {
423
851
  return;
424
852
  }
425
853
  void loadBoard({ silent: true });
@@ -427,9 +855,10 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
427
855
 
428
856
  let timeoutId: number | null = null;
429
857
  const scheduleRefresh = () => {
430
- const delay = document.visibilityState === "visible"
431
- ? ACTIVE_BOARD_REFRESH_MS
432
- : HIDDEN_BOARD_REFRESH_MS;
858
+ const delay =
859
+ document.visibilityState === "visible"
860
+ ? ACTIVE_BOARD_REFRESH_MS
861
+ : HIDDEN_BOARD_REFRESH_MS;
433
862
  timeoutId = window.setTimeout(() => {
434
863
  refresh();
435
864
  scheduleRefresh();
@@ -454,41 +883,91 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
454
883
  };
455
884
  }, [loadBoard, projectId]);
456
885
 
886
+ useEffect(() => {
887
+ if (!projectId) return;
888
+ return subscribeToSnapshotEvents(() => {
889
+ void loadBoard({ silent: true });
890
+ });
891
+ }, [loadBoard, projectId]);
892
+
893
+ useEffect(() => {
894
+ if (!projectSyncOpen || !projectId) return;
895
+ void loadGitHubProjects();
896
+ }, [loadGitHubProjects, projectId, projectSyncOpen]);
897
+
457
898
  const visibleColumns = useMemo(() => {
458
899
  const query = search.trim().toLowerCase();
459
900
  const source = board?.columns ?? [];
901
+ const allowedRoles =
902
+ viewFilter === "all"
903
+ ? null
904
+ : viewFilter === "backlog"
905
+ ? new Set<BoardRole>(["intake", "ready"])
906
+ : viewFilter === "cancelled"
907
+ ? new Set<BoardRole>(["cancelled"])
908
+ : new Set<BoardRole>([
909
+ "intake",
910
+ "ready",
911
+ "dispatching",
912
+ "inProgress",
913
+ "needsInput",
914
+ "blocked",
915
+ "errored",
916
+ "review",
917
+ "merge",
918
+ ]);
460
919
 
461
920
  return source
921
+ .filter((column) => !allowedRoles || allowedRoles.has(column.role))
462
922
  .map((column) => {
463
923
  if (!query) return column;
464
924
  return {
465
925
  ...column,
466
926
  tasks: column.tasks.filter((task) => {
467
- const haystack = `${task.text} ${task.agent ?? ""} ${task.type ?? ""} ${task.priority ?? ""}`.toLowerCase();
927
+ const commentText = task.comments
928
+ .map((comment) => `${comment.author} ${comment.body}`)
929
+ .join(" ");
930
+ const haystack = `${task.text} ${task.agent ?? ""} ${
931
+ task.type ?? ""
932
+ } ${task.priority ?? ""} ${task.issueId ?? ""} ${
933
+ task.notes ?? ""
934
+ } ${task.attachments.join(" ")} ${commentText}`.toLowerCase();
468
935
  return haystack.includes(query);
469
936
  }),
470
937
  };
471
938
  });
472
- }, [board?.columns, search]);
939
+ }, [board?.columns, search, viewFilter]);
473
940
 
474
941
  const filteredContextFiles = useMemo(() => {
475
942
  const query = contextSearch.trim().toLowerCase();
476
943
  if (!query) return contextFiles;
477
944
  return contextFiles.filter((file) => {
478
- const haystack = `${file.path} ${file.name} ${file.source ?? ""}`.toLowerCase();
945
+ const haystack = `${file.path} ${file.name} ${
946
+ file.source ?? ""
947
+ }`.toLowerCase();
479
948
  return haystack.includes(query);
480
949
  });
481
950
  }, [contextFiles, contextSearch]);
482
951
  const editLinkedSessionOptions = useMemo(() => {
483
952
  if (!editingTask) return projectSessions;
484
- const taskKey = getTaskLinkKey(editingTask.task);
953
+ const activeTask = findBoardTask(board, editingTask.task.id) ?? editingTask;
954
+ const taskKey = getTaskLinkKey(activeTask.task);
485
955
  return [...projectSessions].sort((left, right) => {
486
- const leftRelated = left.id === editingTask.task.attemptRef || left.issueId?.trim() === taskKey;
487
- const rightRelated = right.id === editingTask.task.attemptRef || right.issueId?.trim() === taskKey;
956
+ const leftRelated =
957
+ left.id === activeTask.task.attemptRef ||
958
+ left.issueId?.trim() === taskKey;
959
+ const rightRelated =
960
+ right.id === activeTask.task.attemptRef ||
961
+ right.issueId?.trim() === taskKey;
488
962
  if (leftRelated !== rightRelated) return leftRelated ? -1 : 1;
489
- return compareProjectSessions(left, right, editingTask.task.attemptRef);
963
+ return compareProjectSessions(left, right, activeTask.task.attemptRef);
490
964
  });
491
- }, [editingTask, projectSessions]);
965
+ }, [board, editingTask, projectSessions]);
966
+
967
+ const activeEditingTask = useMemo(() => {
968
+ if (!editingTask) return null;
969
+ return findBoardTask(board, editingTask.task.id) ?? editingTask;
970
+ }, [board, editingTask]);
492
971
 
493
972
  function openComposer(role: BoardRole) {
494
973
  setComposerRole(role);
@@ -500,18 +979,79 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
500
979
  setUploadFiles([]);
501
980
  }
502
981
 
982
+ function clearContextOpenError() {
983
+ if (editingTask) {
984
+ setEditingError(null);
985
+ return;
986
+ }
987
+ if (composerOpen) {
988
+ setSubmitError(null);
989
+ return;
990
+ }
991
+ setError(null);
992
+ }
993
+
994
+ function reportContextOpenError(message: string) {
995
+ if (editingTask) {
996
+ setEditingError(message);
997
+ return;
998
+ }
999
+ if (composerOpen) {
1000
+ setSubmitError(message);
1001
+ return;
1002
+ }
1003
+ setError(message);
1004
+ }
1005
+
1006
+ const openContextAttachment = useCallback(
1007
+ async (path: string) => {
1008
+ if (!projectId) return;
1009
+ setOpeningContextPath(path);
1010
+ clearContextOpenError();
1011
+ try {
1012
+ const response = await fetch("/api/context-files/open", {
1013
+ method: "POST",
1014
+ headers: { "Content-Type": "application/json" },
1015
+ body: JSON.stringify({ projectId, path }),
1016
+ });
1017
+ const payload = (await response.json().catch(() => null)) as
1018
+ | { opened?: boolean; error?: string }
1019
+ | null;
1020
+ if (!response.ok) {
1021
+ throw new Error(
1022
+ payload?.error ?? `Failed to open context file: ${response.status}`
1023
+ );
1024
+ }
1025
+ } catch (err) {
1026
+ reportContextOpenError(
1027
+ err instanceof Error ? err.message : "Failed to open context file"
1028
+ );
1029
+ } finally {
1030
+ setOpeningContextPath((current) =>
1031
+ current === path ? null : current
1032
+ );
1033
+ }
1034
+ },
1035
+ [composerOpen, editingTask, projectId]
1036
+ );
1037
+
503
1038
  function toggleContextPath(path: string) {
504
- setSelectedContextPaths((current) => (
1039
+ setSelectedContextPaths((current) =>
505
1040
  current.includes(path)
506
1041
  ? current.filter((item) => item !== path)
507
1042
  : [...current, path]
508
- ));
1043
+ );
509
1044
  }
510
1045
 
511
1046
  function removeUploadFile(file: File) {
512
- setUploadFiles((current) => current.filter((entry) => (
513
- entry.name !== file.name || entry.size !== file.size || entry.lastModified !== file.lastModified
514
- )));
1047
+ setUploadFiles((current) =>
1048
+ current.filter(
1049
+ (entry) =>
1050
+ entry.name !== file.name ||
1051
+ entry.size !== file.size ||
1052
+ entry.lastModified !== file.lastModified
1053
+ )
1054
+ );
515
1055
  }
516
1056
 
517
1057
  async function handleCreateTask() {
@@ -531,18 +1071,23 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
531
1071
  method: "POST",
532
1072
  body: formData,
533
1073
  });
534
- const uploadPayload = (await uploadRes.json().catch(() => null)) as
535
- | { files?: Array<{ path?: string }>; error?: string }
536
- | null;
1074
+ const uploadPayload = (await uploadRes.json().catch(() => null)) as {
1075
+ files?: Array<{ path?: string }>;
1076
+ error?: string;
1077
+ } | null;
537
1078
  if (!uploadRes.ok) {
538
- throw new Error(uploadPayload?.error ?? `Upload failed: ${uploadRes.status}`);
1079
+ throw new Error(
1080
+ uploadPayload?.error ?? `Upload failed: ${uploadRes.status}`
1081
+ );
539
1082
  }
540
1083
  uploadedPaths = (uploadPayload?.files ?? [])
541
1084
  .map((entry) => entry.path?.trim())
542
1085
  .filter((value): value is string => Boolean(value));
543
1086
  }
544
1087
 
545
- const attachments = [...new Set([...selectedContextPaths, ...uploadedPaths])];
1088
+ const attachments = [
1089
+ ...new Set([...selectedContextPaths, ...uploadedPaths]),
1090
+ ];
546
1091
  const res = await fetch("/api/boards", {
547
1092
  method: "POST",
548
1093
  headers: { "Content-Type": "application/json" },
@@ -565,12 +1110,15 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
565
1110
  | null;
566
1111
 
567
1112
  if (!res.ok) {
568
- throw new Error((payload as { error?: string } | null)?.error ?? `Failed to create task: ${res.status}`);
1113
+ throw new Error(
1114
+ (payload as { error?: string } | null)?.error ??
1115
+ `Failed to create task: ${res.status}`
1116
+ );
569
1117
  }
570
1118
 
571
1119
  setBoard((current) => {
572
1120
  if (!payload || !("columns" in payload)) return current;
573
- const next = payload as BoardResponse;
1121
+ const next = normalizeBoardResponse(payload as BoardResponse);
574
1122
  return {
575
1123
  ...(current ?? next),
576
1124
  ...next,
@@ -587,7 +1135,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
587
1135
  setUploadFiles([]);
588
1136
  setComposerOpen(false);
589
1137
  } catch (err) {
590
- setSubmitError(err instanceof Error ? err.message : "Failed to create task");
1138
+ setSubmitError(
1139
+ err instanceof Error ? err.message : "Failed to create task"
1140
+ );
591
1141
  } finally {
592
1142
  setSubmitting(false);
593
1143
  }
@@ -599,28 +1149,119 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
599
1149
  if (!projectId || mutatingRef.current) return;
600
1150
  mutatingRef.current = true;
601
1151
  try {
602
- const res = await fetch("/api/boards", {
603
- method: "PATCH",
604
- headers: { "Content-Type": "application/json" },
605
- body: JSON.stringify({
606
- projectId,
607
- ...payload,
608
- }),
609
- });
610
- const data = (await res.json().catch(() => null)) as BoardResponse | { error?: string } | null;
611
- if (!res.ok) {
612
- throw new Error((data as { error?: string } | null)?.error ?? `Failed to update board: ${res.status}`);
613
- }
614
- const nextBoard = data as BoardResponse;
615
- setBoard((current) => (boardsEqual(current, nextBoard) ? current : nextBoard));
616
- setError(null);
1152
+ const res = await fetch("/api/boards", {
1153
+ method: "PATCH",
1154
+ headers: { "Content-Type": "application/json" },
1155
+ body: JSON.stringify({
1156
+ projectId,
1157
+ ...payload,
1158
+ }),
1159
+ });
1160
+ const data = (await res.json().catch(() => null)) as
1161
+ | BoardResponse
1162
+ | { error?: string }
1163
+ | null;
1164
+ if (!res.ok) {
1165
+ throw new Error(
1166
+ (data as { error?: string } | null)?.error ??
1167
+ `Failed to update board: ${res.status}`
1168
+ );
1169
+ }
1170
+ const nextBoard = normalizeBoardResponse(data as BoardResponse);
1171
+ setBoard((current) =>
1172
+ boardsEqual(current, nextBoard) ? current : nextBoard
1173
+ );
1174
+ setError(null);
617
1175
  } finally {
618
1176
  mutatingRef.current = false;
619
1177
  }
620
1178
  }
621
1179
 
1180
+ async function handleSaveGitHubProjectLink(link: GitHubProjectLink | null) {
1181
+ if (!projectId || projectSyncSaving) return;
1182
+ setProjectSyncSaving(true);
1183
+ setProjectSyncError(null);
1184
+ try {
1185
+ const res = await fetch("/api/github/projects", {
1186
+ method: "PUT",
1187
+ headers: { "Content-Type": "application/json" },
1188
+ body: JSON.stringify({
1189
+ projectId,
1190
+ link: link?.id ? link : null,
1191
+ }),
1192
+ });
1193
+ const payload = (await res.json().catch(() => null)) as {
1194
+ githubProject?: GitHubProjectLink | null;
1195
+ error?: string;
1196
+ } | null;
1197
+ if (!res.ok) {
1198
+ throw new Error(
1199
+ payload?.error ??
1200
+ `Failed to update GitHub Project link (${res.status})`
1201
+ );
1202
+ }
1203
+
1204
+ setBoard((current) =>
1205
+ current
1206
+ ? { ...current, githubProject: payload?.githubProject ?? null }
1207
+ : current
1208
+ );
1209
+ await loadGitHubProjects();
1210
+ } catch (err) {
1211
+ setProjectSyncError(
1212
+ err instanceof Error
1213
+ ? err.message
1214
+ : "Failed to update GitHub Project link"
1215
+ );
1216
+ } finally {
1217
+ setProjectSyncSaving(false);
1218
+ }
1219
+ }
1220
+
1221
+ async function handleGitHubProjectSync(direction: "pull" | "push") {
1222
+ if (!projectId || projectSyncSaving) return;
1223
+ setProjectSyncSaving(true);
1224
+ setProjectSyncError(null);
1225
+ try {
1226
+ const res = await fetch("/api/github/projects/sync", {
1227
+ method: "POST",
1228
+ headers: { "Content-Type": "application/json" },
1229
+ body: JSON.stringify({ projectId, direction }),
1230
+ });
1231
+ const payload = (await res.json().catch(() => null)) as {
1232
+ board?: BoardResponse;
1233
+ error?: string;
1234
+ } | null;
1235
+ if (!res.ok) {
1236
+ throw new Error(
1237
+ payload?.error ??
1238
+ `Failed to ${direction} GitHub Project (${res.status})`
1239
+ );
1240
+ }
1241
+ if (payload?.board) {
1242
+ const nextBoard = normalizeBoardResponse(payload.board);
1243
+ setBoard((current) =>
1244
+ boardsEqual(current, nextBoard) ? current : nextBoard
1245
+ );
1246
+ } else {
1247
+ await loadBoard({ silent: true });
1248
+ }
1249
+ await loadGitHubProjects();
1250
+ } catch (err) {
1251
+ setProjectSyncError(
1252
+ err instanceof Error
1253
+ ? err.message
1254
+ : `Failed to ${direction} GitHub Project`
1255
+ );
1256
+ } finally {
1257
+ setProjectSyncSaving(false);
1258
+ }
1259
+ }
1260
+
622
1261
  function openEditor(task: BoardTask, role: BoardRole) {
623
- const { title: nextTitle, description: nextDescription } = splitTaskText(task.text);
1262
+ const { title: nextTitle, description: nextDescription } = splitTaskText(
1263
+ task.text
1264
+ );
624
1265
  setEditingTask({ task, role });
625
1266
  setEditRole(role);
626
1267
  setEditTitle(nextTitle);
@@ -628,42 +1269,90 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
628
1269
  setEditAgent(task.agent ?? orderedAgentOptions[0] ?? defaultAgent);
629
1270
  setEditTaskType(task.type ?? "feature");
630
1271
  setEditPriority(task.priority ?? "normal");
1272
+ setEditIssueId(task.issueId ?? "");
1273
+ setEditNotes(task.notes ?? "");
631
1274
  setEditLinkedSession(task.attemptRef ?? "");
632
1275
  setEditingError(null);
1276
+ setCommentDraft("");
1277
+ setCommentError(null);
633
1278
  }
634
1279
 
635
1280
  function closeEditor() {
636
- if (editingBusy) return;
1281
+ if (editingBusy || commentBusy) return;
637
1282
  setEditingTask(null);
638
1283
  setEditingError(null);
1284
+ setCommentDraft("");
1285
+ setCommentError(null);
639
1286
  }
640
1287
 
641
1288
  async function handleSaveEdit() {
642
- if (!editingTask || !editTitle.trim()) return;
1289
+ if (!activeEditingTask || !editTitle.trim()) return;
643
1290
  setEditingBusy(true);
644
1291
  setEditingError(null);
645
1292
  try {
646
1293
  await handleBoardMutation({
647
- taskId: editingTask.task.id,
1294
+ taskId: activeEditingTask.task.id,
648
1295
  role: editRole,
649
1296
  title: editTitle.trim(),
650
1297
  description: editDescription,
1298
+ contextNotes: editNotes.trim() || "",
1299
+ issueId: editIssueId.trim() || "",
651
1300
  agent: editAgent,
652
1301
  type: editTaskType,
653
1302
  priority: editPriority,
654
1303
  attemptRef: editLinkedSession,
655
1304
  taskRef: editLinkedSession
656
- ? (editingTask.task.taskRef ?? editingTask.task.id)
657
- : (editingTask.task.taskRef ?? ""),
1305
+ ? activeEditingTask.task.taskRef ?? activeEditingTask.task.id
1306
+ : activeEditingTask.task.taskRef ?? "",
658
1307
  });
659
1308
  setEditingTask(null);
660
1309
  } catch (err) {
661
- setEditingError(err instanceof Error ? err.message : "Failed to update task");
1310
+ setEditingError(
1311
+ err instanceof Error ? err.message : "Failed to update task"
1312
+ );
662
1313
  } finally {
663
1314
  setEditingBusy(false);
664
1315
  }
665
1316
  }
666
1317
 
1318
+ async function handleAddComment() {
1319
+ if (!projectId || !activeEditingTask || !commentDraft.trim()) return;
1320
+ setCommentBusy(true);
1321
+ setCommentError(null);
1322
+ try {
1323
+ const res = await fetch("/api/boards/comments", {
1324
+ method: "POST",
1325
+ headers: { "Content-Type": "application/json" },
1326
+ body: JSON.stringify({
1327
+ projectId,
1328
+ taskId: activeEditingTask.task.id,
1329
+ body: commentDraft.trim(),
1330
+ }),
1331
+ });
1332
+ const payload = (await res.json().catch(() => null)) as
1333
+ | BoardResponse
1334
+ | { error?: string }
1335
+ | null;
1336
+ if (!res.ok) {
1337
+ throw new Error(
1338
+ (payload as { error?: string } | null)?.error ??
1339
+ `Failed to add comment: ${res.status}`
1340
+ );
1341
+ }
1342
+ const nextBoard = normalizeBoardResponse(payload as BoardResponse);
1343
+ setBoard((current) =>
1344
+ boardsEqual(current, nextBoard) ? current : nextBoard
1345
+ );
1346
+ setCommentDraft("");
1347
+ } catch (err) {
1348
+ setCommentError(
1349
+ err instanceof Error ? err.message : "Failed to add comment"
1350
+ );
1351
+ } finally {
1352
+ setCommentBusy(false);
1353
+ }
1354
+ }
1355
+
667
1356
  if (!projectId) {
668
1357
  return (
669
1358
  <div className="flex h-full items-center justify-center text-[14px] text-[var(--vk-text-muted)]">
@@ -677,10 +1366,28 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
677
1366
  <header className="border-b border-[var(--vk-border)] px-4 py-3">
678
1367
  <div className="flex flex-wrap items-center gap-2">
679
1368
  <div className="inline-flex rounded-[3px] border border-[var(--vk-border)] p-px">
680
- <span className="rounded-[2px] bg-[var(--vk-bg-active)] px-3 py-1 text-[13px] text-[var(--vk-text-strong)]">Active</span>
681
- <span className="px-3 py-1 text-[13px] text-[var(--vk-text-muted)]">All</span>
682
- <span className="px-3 py-1 text-[13px] text-[var(--vk-text-muted)]">Backlog</span>
683
- <span className="px-3 py-1 text-[13px] text-[var(--vk-text-muted)]">Cancelled</span>
1369
+ {(
1370
+ [
1371
+ ["active", "Active"],
1372
+ ["all", "All"],
1373
+ ["backlog", "Backlog"],
1374
+ ["cancelled", "Cancelled"],
1375
+ ] as const
1376
+ ).map(([value, label]) => (
1377
+ <button
1378
+ key={value}
1379
+ type="button"
1380
+ onClick={() => setViewFilter(value)}
1381
+ className={cn(
1382
+ "px-3 py-1 text-[13px]",
1383
+ viewFilter === value
1384
+ ? "rounded-[2px] bg-[var(--vk-bg-active)] text-[var(--vk-text-strong)]"
1385
+ : "text-[var(--vk-text-muted)] hover:bg-[var(--vk-bg-hover)]"
1386
+ )}
1387
+ >
1388
+ {label}
1389
+ </button>
1390
+ ))}
684
1391
  </div>
685
1392
 
686
1393
  <div className="ml-auto flex w-full min-w-0 flex-wrap items-center gap-2 sm:w-auto sm:min-w-[220px] sm:flex-nowrap sm:flex-none">
@@ -705,8 +1412,231 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
705
1412
  </div>
706
1413
  </div>
707
1414
 
1415
+ <div className="mt-3 flex flex-wrap items-center gap-2">
1416
+ <button
1417
+ type="button"
1418
+ onClick={() => setProjectSyncOpen((current) => !current)}
1419
+ className="inline-flex h-[31px] items-center gap-2 rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)]"
1420
+ >
1421
+ <span>GitHub Project</span>
1422
+ <span className="text-[var(--vk-text-muted)]">
1423
+ {board?.githubProject?.id
1424
+ ? formatGitHubProjectLabel(board.githubProject)
1425
+ : "Connect"}
1426
+ </span>
1427
+ </button>
1428
+
1429
+ {board?.githubProject?.url ? (
1430
+ <a
1431
+ href={board.githubProject.url}
1432
+ target="_blank"
1433
+ rel="noreferrer"
1434
+ className="inline-flex h-[31px] items-center gap-1 rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)]"
1435
+ >
1436
+ <span>Open Project</span>
1437
+ <ExternalLink className="h-3.5 w-3.5" />
1438
+ </a>
1439
+ ) : null}
1440
+ </div>
1441
+
1442
+ {projectSyncOpen && (
1443
+ <div className="mt-3 rounded-[6px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] p-3">
1444
+ <div className="flex flex-wrap items-center gap-2">
1445
+ <label className="min-w-0 flex-1">
1446
+ <span className="mb-1 block text-[11px] uppercase tracking-[0.08em] text-[var(--vk-text-muted)]">
1447
+ Linked project
1448
+ </span>
1449
+ <select
1450
+ value={selectedGitHubProjectId}
1451
+ onChange={(event) =>
1452
+ setSelectedGitHubProjectId(event.target.value)
1453
+ }
1454
+ disabled={projectSyncLoading || projectSyncSaving}
1455
+ className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
1456
+ >
1457
+ <option value="">
1458
+ {projectSyncLoading
1459
+ ? "Loading GitHub Projects..."
1460
+ : "Select a GitHub Project"}
1461
+ </option>
1462
+ {(projectSyncData?.projects ?? []).map((project) => (
1463
+ <option
1464
+ key={project.id ?? "unknown"}
1465
+ value={project.id ?? ""}
1466
+ >
1467
+ {formatGitHubProjectLabel(project)}
1468
+ </option>
1469
+ ))}
1470
+ </select>
1471
+ </label>
1472
+
1473
+ <button
1474
+ type="button"
1475
+ disabled={
1476
+ !selectedGitHubProjectId ||
1477
+ projectSyncLoading ||
1478
+ projectSyncSaving
1479
+ }
1480
+ onClick={() => {
1481
+ const project =
1482
+ projectSyncData?.projects.find(
1483
+ (item) => item.id === selectedGitHubProjectId
1484
+ ) ?? null;
1485
+ void handleSaveGitHubProjectLink(project);
1486
+ }}
1487
+ className="inline-flex h-9 items-center rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1488
+ >
1489
+ {projectSyncSaving ? (
1490
+ <Loader2 className="h-4 w-4 animate-spin" />
1491
+ ) : (
1492
+ "Connect"
1493
+ )}
1494
+ </button>
1495
+
1496
+ <button
1497
+ type="button"
1498
+ disabled={!board?.githubProject?.id || projectSyncSaving}
1499
+ onClick={() => void handleSaveGitHubProjectLink(null)}
1500
+ className="inline-flex h-9 items-center rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1501
+ >
1502
+ Disconnect
1503
+ </button>
1504
+
1505
+ <button
1506
+ type="button"
1507
+ disabled={!board?.githubProject?.id || projectSyncSaving}
1508
+ onClick={() => void handleGitHubProjectSync("pull")}
1509
+ className="inline-flex h-9 items-center gap-2 rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1510
+ >
1511
+ {projectSyncSaving ? (
1512
+ <Loader2 className="h-4 w-4 animate-spin" />
1513
+ ) : (
1514
+ <RefreshCw className="h-4 w-4" />
1515
+ )}
1516
+ Pull
1517
+ </button>
1518
+
1519
+ <button
1520
+ type="button"
1521
+ disabled={!board?.githubProject?.id || projectSyncSaving}
1522
+ onClick={() => void handleGitHubProjectSync("push")}
1523
+ className="inline-flex h-9 items-center rounded-[3px] bg-[var(--vk-bg-active)] px-3 text-[13px] text-[var(--vk-text-strong)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1524
+ >
1525
+ Push
1526
+ </button>
1527
+ </div>
1528
+
1529
+ <div className="mt-2 flex flex-wrap items-center gap-3 text-[12px] text-[var(--vk-text-muted)]">
1530
+ <span>
1531
+ Repository:{" "}
1532
+ {board?.repository?.trim() ||
1533
+ projectSyncData?.repository?.trim() ||
1534
+ "Not configured"}
1535
+ </span>
1536
+ {projectSyncData?.ownerLogin ? (
1537
+ <span>Owner: {projectSyncData.ownerLogin}</span>
1538
+ ) : null}
1539
+ </div>
1540
+
1541
+ {projectSyncError && (
1542
+ <p className="mt-2 text-[12px] text-[var(--vk-red)]">
1543
+ {projectSyncError}
1544
+ </p>
1545
+ )}
1546
+
1547
+ {(board?.recentWebhookDeliveries?.length ?? 0) > 0 && (
1548
+ <div className="mt-3 rounded-[6px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] p-3">
1549
+ <div className="mb-2 flex items-center justify-between gap-2">
1550
+ <h3 className="text-[12px] uppercase tracking-[0.08em] text-[var(--vk-text-muted)]">
1551
+ Webhook diagnostics
1552
+ </h3>
1553
+ <span className="text-[11px] text-[var(--vk-text-muted)]">
1554
+ {(board?.recentWebhookDeliveries ?? []).length}
1555
+ </span>
1556
+ </div>
1557
+
1558
+ <div className="space-y-2">
1559
+ {(board?.recentWebhookDeliveries ?? [])
1560
+ .slice(0, 6)
1561
+ .map((delivery) => (
1562
+ <div
1563
+ key={delivery.id}
1564
+ className="rounded-[4px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] p-2"
1565
+ >
1566
+ <div className="flex flex-wrap items-center gap-2">
1567
+ <span
1568
+ className={`inline-flex h-5 items-center rounded-[3px] border px-2 text-[10px] ${webhookStatusClass(
1569
+ delivery.status
1570
+ )}`}
1571
+ >
1572
+ {formatWebhookStatus(delivery.status)}
1573
+ </span>
1574
+ <span className="text-[12px] text-[var(--vk-text-normal)]">
1575
+ {delivery.event}
1576
+ {delivery.action ? ` / ${delivery.action}` : ""}
1577
+ </span>
1578
+ <span className="ml-auto text-[11px] text-[var(--vk-text-muted)]">
1579
+ {formatActivityTime(delivery.timestamp)}
1580
+ </span>
1581
+ </div>
1582
+ <p className="mt-1 text-[12px] text-[var(--vk-text-muted)]">
1583
+ {delivery.detail}
1584
+ </p>
1585
+ {delivery.repository ? (
1586
+ <p className="mt-1 text-[11px] text-[var(--vk-text-muted)]">
1587
+ Repo: {delivery.repository}
1588
+ </p>
1589
+ ) : null}
1590
+ </div>
1591
+ ))}
1592
+ </div>
1593
+ </div>
1594
+ )}
1595
+ </div>
1596
+ )}
1597
+
708
1598
  {board?.watcherHint && (
709
- <p className="pt-2 text-[12px] text-[var(--vk-text-muted)]">{board.watcherHint}</p>
1599
+ <p className="pt-2 text-[12px] text-[var(--vk-text-muted)]">
1600
+ {board.watcherHint}
1601
+ </p>
1602
+ )}
1603
+
1604
+ {(board?.recentActions?.length ?? 0) > 0 && (
1605
+ <div className="mt-3 rounded-[6px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] p-3">
1606
+ <div className="mb-2 flex items-center justify-between gap-2">
1607
+ <h3 className="text-[12px] uppercase tracking-[0.08em] text-[var(--vk-text-muted)]">
1608
+ Recent activity
1609
+ </h3>
1610
+ <span className="text-[11px] text-[var(--vk-text-muted)]">
1611
+ {(board?.recentActions ?? []).length}
1612
+ </span>
1613
+ </div>
1614
+
1615
+ <div className="space-y-2">
1616
+ {(board?.recentActions ?? []).slice(0, 6).map((activity) => (
1617
+ <div
1618
+ key={activity.id}
1619
+ className="flex flex-wrap items-center gap-x-2 gap-y-1 text-[12px]"
1620
+ >
1621
+ <span className="rounded-[3px] bg-[color:#292929] px-2 py-0.5 text-[11px] text-[var(--vk-text-muted)]">
1622
+ {activity.source}
1623
+ </span>
1624
+ <span className="text-[var(--vk-text-normal)]">
1625
+ {activity.action}
1626
+ </span>
1627
+ <span
1628
+ className="min-w-0 flex-1 truncate text-[var(--vk-text-muted)]"
1629
+ title={activity.detail}
1630
+ >
1631
+ {activity.detail}
1632
+ </span>
1633
+ <span className="text-[11px] text-[var(--vk-text-muted)]">
1634
+ {formatActivityTime(activity.timestamp)}
1635
+ </span>
1636
+ </div>
1637
+ ))}
1638
+ </div>
1639
+ </div>
710
1640
  )}
711
1641
  </header>
712
1642
 
@@ -723,18 +1653,27 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
723
1653
  ) : (
724
1654
  <div
725
1655
  className="flex min-w-0 flex-col gap-3 rounded-[4px] border border-[var(--vk-border)] lg:grid lg:gap-0"
726
- style={{ gridTemplateColumns: `repeat(${Math.max(visibleColumns.length, 1)}, minmax(240px, 1fr))` }}
1656
+ style={{
1657
+ gridTemplateColumns: `repeat(${Math.max(
1658
+ visibleColumns.length,
1659
+ 1
1660
+ )}, minmax(240px, 1fr))`,
1661
+ }}
727
1662
  >
728
1663
  {visibleColumns.map((column, columnIndex) => (
729
1664
  <article
730
1665
  key={column.role}
731
1666
  className={cn(
732
1667
  "flex min-h-[320px] flex-col border-b border-[var(--vk-border)] bg-[var(--vk-bg-panel)] lg:min-h-[540px] lg:border-b-0 lg:border-r",
733
- columnIndex === visibleColumns.length - 1 && "border-b-0 lg:border-r-0",
1668
+ columnIndex === visibleColumns.length - 1 &&
1669
+ "border-b-0 lg:border-r-0"
734
1670
  )}
735
1671
  >
736
1672
  <header className="flex h-[41px] items-center border-b border-[var(--vk-border)] px-2">
737
- <span className="h-2 w-2 rounded-full" style={{ backgroundColor: ROLE_COLOR[column.role] }} />
1673
+ <span
1674
+ className="h-2 w-2 rounded-full"
1675
+ style={{ backgroundColor: ROLE_COLOR[column.role] }}
1676
+ />
738
1677
  <span className="ml-2 text-[14px] text-[var(--vk-text-normal)]">
739
1678
  {column.heading || ROLE_LABEL[column.role]}
740
1679
  </span>
@@ -751,7 +1690,8 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
751
1690
  <div
752
1691
  className={cn(
753
1692
  "flex-1 space-y-2 overflow-y-auto p-2",
754
- draggingTask?.role === column.role && "bg-[rgba(255,255,255,0.02)]",
1693
+ draggingTask?.role === column.role &&
1694
+ "bg-[rgba(255,255,255,0.02)]"
755
1695
  )}
756
1696
  onDragOver={(event) => {
757
1697
  if (!draggingTask) return;
@@ -759,12 +1699,17 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
759
1699
  }}
760
1700
  onDrop={(event) => {
761
1701
  event.preventDefault();
762
- if (!draggingTask || draggingTask.role === column.role) return;
1702
+ if (!draggingTask || draggingTask.role === column.role)
1703
+ return;
763
1704
  void handleBoardMutation({
764
1705
  taskId: draggingTask.taskId,
765
1706
  role: column.role,
766
1707
  }).catch((err) => {
767
- setError(err instanceof Error ? err.message : "Failed to move task");
1708
+ setError(
1709
+ err instanceof Error
1710
+ ? err.message
1711
+ : "Failed to move task"
1712
+ );
768
1713
  });
769
1714
  setDraggingTask(null);
770
1715
  }}
@@ -775,35 +1720,63 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
775
1720
  </div>
776
1721
  )}
777
1722
 
778
- {column.tasks.slice(0, 50).map((task) => {
779
- const { title: taskTitle, description: taskDescription } = splitTaskText(task.text);
1723
+ {column.tasks.map((task) => {
1724
+ const { title: taskTitle, description: taskDescription } =
1725
+ splitTaskText(task.text);
780
1726
  const taskLinkKey = getTaskLinkKey(task);
1727
+ const issueUrl = buildGitHubIssueUrl(
1728
+ board?.repository,
1729
+ task.issueId
1730
+ );
781
1731
  const linkedSessions = projectSessions
782
- .filter((session) => session.id === task.attemptRef || session.issueId?.trim() === taskLinkKey)
783
- .sort((left, right) => compareProjectSessions(left, right, task.attemptRef ?? null));
1732
+ .filter(
1733
+ (session) =>
1734
+ session.id === task.attemptRef ||
1735
+ session.issueId?.trim() === taskLinkKey
1736
+ )
1737
+ .sort((left, right) =>
1738
+ compareProjectSessions(
1739
+ left,
1740
+ right,
1741
+ task.attemptRef ?? null
1742
+ )
1743
+ );
784
1744
  const primaryLinkedSession = task.attemptRef
785
- ? linkedSessions.find((session) => session.id === task.attemptRef) ?? null
786
- : (linkedSessions[0] ?? null);
787
- const unresolvedPrimaryLink = task.attemptRef
788
- && !linkedSessions.some((session) => session.id === task.attemptRef)
789
- ? task.attemptRef
790
- : null;
1745
+ ? linkedSessions.find(
1746
+ (session) => session.id === task.attemptRef
1747
+ ) ?? null
1748
+ : linkedSessions[0] ?? null;
1749
+ const unresolvedPrimaryLink =
1750
+ task.attemptRef &&
1751
+ !linkedSessions.some(
1752
+ (session) => session.id === task.attemptRef
1753
+ )
1754
+ ? task.attemptRef
1755
+ : null;
791
1756
  return (
792
1757
  <div
793
1758
  key={`${column.role}-${task.id}`}
794
1759
  draggable
795
- onDragStart={() => setDraggingTask({ taskId: task.id, role: column.role })}
1760
+ onDragStart={() =>
1761
+ setDraggingTask({
1762
+ taskId: task.id,
1763
+ role: column.role,
1764
+ })
1765
+ }
796
1766
  onDragEnd={() => setDraggingTask(null)}
797
1767
  className={cn(
798
1768
  "rounded-[3px] border border-[var(--vk-border)] bg-[color:#212121] p-2",
799
- draggingTask?.taskId === task.id && "opacity-60",
1769
+ draggingTask?.taskId === task.id && "opacity-60"
800
1770
  )}
801
1771
  >
802
1772
  <div className="flex items-start gap-2">
803
1773
  <p className="min-w-0 flex-1 font-mono text-[12px] text-[var(--vk-text-muted)]">
804
- {task.taskRef?.trim()
805
- || (task.id.length > 12
806
- ? `TASK-${task.id.split("-")[0]?.toUpperCase() ?? task.id.toUpperCase()}`
1774
+ {task.taskRef?.trim() ||
1775
+ (task.id.length > 12
1776
+ ? `TASK-${
1777
+ task.id.split("-")[0]?.toUpperCase() ??
1778
+ task.id.toUpperCase()
1779
+ }`
807
1780
  : task.id)}
808
1781
  </p>
809
1782
  <button
@@ -816,19 +1789,71 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
816
1789
  <Pencil className="h-3.5 w-3.5" />
817
1790
  </button>
818
1791
  </div>
819
- <p className="pt-1 text-[15px] leading-[22px] text-[var(--vk-text-normal)]">{taskTitle}</p>
1792
+ <p className="pt-1 text-[15px] leading-[22px] text-[var(--vk-text-normal)]">
1793
+ {taskTitle}
1794
+ </p>
820
1795
  {taskDescription && (
821
- <p className="pt-1 text-[13px] leading-[20px] text-[var(--vk-text-muted)]">{taskDescription}</p>
1796
+ <p className="pt-1 text-[13px] leading-[20px] text-[var(--vk-text-muted)]">
1797
+ {taskDescription}
1798
+ </p>
1799
+ )}
1800
+ {task.notes && (
1801
+ <p className="pt-2 text-[12px] leading-[18px] text-[var(--vk-text-muted)]">
1802
+ {task.notes}
1803
+ </p>
1804
+ )}
1805
+
1806
+ {task.commentCount > 0 && (
1807
+ <div className="mt-2 flex items-center gap-1 text-[11px] text-[var(--vk-text-muted)]">
1808
+ <MessageSquare className="h-3.5 w-3.5" />
1809
+ <span>
1810
+ {task.commentCount} comment
1811
+ {task.commentCount === 1 ? "" : "s"}
1812
+ </span>
1813
+ </div>
1814
+ )}
1815
+
1816
+ {(task.issueId || task.attachments.length > 0) && (
1817
+ <div className="mt-2 flex flex-wrap items-center gap-1.5">
1818
+ {task.issueId ? (
1819
+ issueUrl ? (
1820
+ <a
1821
+ href={issueUrl}
1822
+ target="_blank"
1823
+ rel="noreferrer"
1824
+ className="inline-flex h-5 items-center gap-1 rounded-[3px] border border-[var(--vk-border)] px-2 text-[11px] text-[var(--vk-text-muted)] hover:bg-[var(--vk-bg-hover)]"
1825
+ >
1826
+ <span>Issue #{task.issueId}</span>
1827
+ <ExternalLink className="h-3 w-3" />
1828
+ </a>
1829
+ ) : (
1830
+ <span className="inline-flex h-5 items-center rounded-[3px] border border-[var(--vk-border)] px-2 text-[11px] text-[var(--vk-text-muted)]">
1831
+ Issue {task.issueId}
1832
+ </span>
1833
+ )
1834
+ ) : null}
1835
+
1836
+ {task.attachments.map((attachment) => (
1837
+ <ContextAttachmentChip
1838
+ key={`${task.id}-${attachment}`}
1839
+ attachment={attachment}
1840
+ opening={openingContextPath === attachment}
1841
+ onOpen={() => void openContextAttachment(attachment)}
1842
+ />
1843
+ ))}
1844
+ </div>
822
1845
  )}
823
1846
 
824
- {(linkedSessions.length > 0 || unresolvedPrimaryLink) && (
1847
+ {(linkedSessions.length > 0 ||
1848
+ unresolvedPrimaryLink) && (
825
1849
  <div className="mt-3 rounded-[4px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] p-2">
826
1850
  <div className="flex items-center justify-between gap-2">
827
1851
  <span className="text-[11px] uppercase tracking-[0.08em] text-[var(--vk-text-muted)]">
828
1852
  Runs
829
1853
  </span>
830
1854
  <span className="text-[11px] text-[var(--vk-text-muted)]">
831
- {linkedSessions.length + (unresolvedPrimaryLink ? 1 : 0)}
1855
+ {linkedSessions.length +
1856
+ (unresolvedPrimaryLink ? 1 : 0)}
832
1857
  </span>
833
1858
  </div>
834
1859
 
@@ -836,17 +1861,32 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
836
1861
  {primaryLinkedSession ? (
837
1862
  <button
838
1863
  type="button"
839
- onClick={() => router.push(`/sessions/${encodeURIComponent(primaryLinkedSession.id)}?tab=chat`)}
1864
+ onClick={() =>
1865
+ router.push(
1866
+ `/sessions/${encodeURIComponent(
1867
+ primaryLinkedSession.id
1868
+ )}?tab=chat`
1869
+ )
1870
+ }
840
1871
  className="flex w-full items-center justify-between gap-2 rounded-[3px] border border-[rgba(255,255,255,0.05)] bg-[rgba(255,255,255,0.03)] px-2 py-1.5 text-left hover:bg-[var(--vk-bg-hover)]"
841
1872
  title={primaryLinkedSession.id}
842
1873
  >
843
1874
  <div className="flex min-w-0 items-center gap-2">
844
1875
  {getSessionAgent(primaryLinkedSession) ? (
845
- <AgentTileIcon seed={{ label: getSessionAgent(primaryLinkedSession) as string }} className="h-5 w-5" />
1876
+ <AgentTileIcon
1877
+ seed={{
1878
+ label: getSessionAgent(
1879
+ primaryLinkedSession
1880
+ ) as string,
1881
+ }}
1882
+ className="h-5 w-5"
1883
+ />
846
1884
  ) : null}
847
1885
  <div className="min-w-0">
848
1886
  <div className="truncate text-[12px] text-[var(--vk-text-normal)]">
849
- {formatLinkedSessionLabel(primaryLinkedSession)}
1887
+ {formatLinkedSessionLabel(
1888
+ primaryLinkedSession
1889
+ )}
850
1890
  </div>
851
1891
  <div className="truncate text-[11px] text-[var(--vk-text-muted)]">
852
1892
  Primary run
@@ -854,8 +1894,14 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
854
1894
  </div>
855
1895
  </div>
856
1896
  <div className="flex shrink-0 items-center gap-2">
857
- <span className={`inline-flex h-5 items-center rounded-[3px] border px-2 text-[10px] ${sessionStatusPillClass(primaryLinkedSession.status)}`}>
858
- {formatSessionStatus(primaryLinkedSession.status)}
1897
+ <span
1898
+ className={`inline-flex h-5 items-center rounded-[3px] border px-2 text-[10px] ${sessionStatusPillClass(
1899
+ primaryLinkedSession.status
1900
+ )}`}
1901
+ >
1902
+ {formatSessionStatus(
1903
+ primaryLinkedSession.status
1904
+ )}
859
1905
  </span>
860
1906
  <ExternalLink className="h-3 w-3 text-[var(--vk-text-muted)]" />
861
1907
  </div>
@@ -863,25 +1909,45 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
863
1909
  ) : null}
864
1910
 
865
1911
  {linkedSessions
866
- .filter((session) => session.id !== primaryLinkedSession?.id)
1912
+ .filter(
1913
+ (session) =>
1914
+ session.id !== primaryLinkedSession?.id
1915
+ )
867
1916
  .map((session) => (
868
1917
  <button
869
1918
  key={session.id}
870
1919
  type="button"
871
- onClick={() => router.push(`/sessions/${encodeURIComponent(session.id)}?tab=chat`)}
1920
+ onClick={() =>
1921
+ router.push(
1922
+ `/sessions/${encodeURIComponent(
1923
+ session.id
1924
+ )}?tab=chat`
1925
+ )
1926
+ }
872
1927
  className="flex w-full items-center justify-between gap-2 rounded-[3px] px-2 py-1.5 text-left hover:bg-[var(--vk-bg-hover)]"
873
1928
  title={session.id}
874
1929
  >
875
1930
  <div className="flex min-w-0 items-center gap-2">
876
1931
  {getSessionAgent(session) ? (
877
- <AgentTileIcon seed={{ label: getSessionAgent(session) as string }} className="h-5 w-5" />
1932
+ <AgentTileIcon
1933
+ seed={{
1934
+ label: getSessionAgent(
1935
+ session
1936
+ ) as string,
1937
+ }}
1938
+ className="h-5 w-5"
1939
+ />
878
1940
  ) : null}
879
1941
  <span className="truncate text-[12px] text-[var(--vk-text-normal)]">
880
1942
  {formatLinkedSessionLabel(session)}
881
1943
  </span>
882
1944
  </div>
883
1945
  <div className="flex shrink-0 items-center gap-2">
884
- <span className={`inline-flex h-5 items-center rounded-[3px] border px-2 text-[10px] ${sessionStatusPillClass(session.status)}`}>
1946
+ <span
1947
+ className={`inline-flex h-5 items-center rounded-[3px] border px-2 text-[10px] ${sessionStatusPillClass(
1948
+ session.status
1949
+ )}`}
1950
+ >
885
1951
  {formatSessionStatus(session.status)}
886
1952
  </span>
887
1953
  <ExternalLink className="h-3 w-3 text-[var(--vk-text-muted)]" />
@@ -892,13 +1958,23 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
892
1958
  {unresolvedPrimaryLink ? (
893
1959
  <button
894
1960
  type="button"
895
- onClick={() => router.push(`/sessions/${encodeURIComponent(unresolvedPrimaryLink)}?tab=chat`)}
1961
+ onClick={() =>
1962
+ router.push(
1963
+ `/sessions/${encodeURIComponent(
1964
+ unresolvedPrimaryLink
1965
+ )}?tab=chat`
1966
+ )
1967
+ }
896
1968
  className="flex w-full items-center justify-between gap-2 rounded-[3px] px-2 py-1.5 text-left hover:bg-[var(--vk-bg-hover)]"
897
1969
  title={unresolvedPrimaryLink}
898
1970
  >
899
1971
  <div className="min-w-0">
900
- <div className="truncate text-[12px] text-[var(--vk-text-normal)]">{unresolvedPrimaryLink}</div>
901
- <div className="truncate text-[11px] text-[var(--vk-text-muted)]">Primary run</div>
1972
+ <div className="truncate text-[12px] text-[var(--vk-text-normal)]">
1973
+ {unresolvedPrimaryLink}
1974
+ </div>
1975
+ <div className="truncate text-[11px] text-[var(--vk-text-muted)]">
1976
+ Primary run
1977
+ </div>
902
1978
  </div>
903
1979
  <ExternalLink className="h-3 w-3 shrink-0 text-[var(--vk-text-muted)]" />
904
1980
  </button>
@@ -911,11 +1987,18 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
911
1987
  <div className="flex min-w-0 items-center gap-1.5">
912
1988
  {task.agent ? (
913
1989
  <>
914
- <AgentTileIcon seed={{ label: task.agent }} className="h-6 w-6" />
915
- <span className="truncate text-[12px] text-[var(--vk-text-muted)]">{formatAgentLabel(task.agent)}</span>
1990
+ <AgentTileIcon
1991
+ seed={{ label: task.agent }}
1992
+ className="h-6 w-6"
1993
+ />
1994
+ <span className="truncate text-[12px] text-[var(--vk-text-muted)]">
1995
+ {formatAgentLabel(task.agent)}
1996
+ </span>
916
1997
  </>
917
1998
  ) : (
918
- <span className="text-[12px] text-[var(--vk-text-muted)]">No agent</span>
1999
+ <span className="text-[12px] text-[var(--vk-text-muted)]">
2000
+ No agent
2001
+ </span>
919
2002
  )}
920
2003
  </div>
921
2004
 
@@ -935,11 +2018,6 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
935
2018
  </div>
936
2019
  );
937
2020
  })}
938
- {column.tasks.length > 50 && (
939
- <div className="rounded-[3px] border border-dashed border-[var(--vk-border)] px-2 py-2 text-center text-[12px] text-[var(--vk-text-muted)]">
940
- +{column.tasks.length - 50} more tasks
941
- </div>
942
- )}
943
2021
  </div>
944
2022
  </article>
945
2023
  ))}
@@ -947,8 +2025,11 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
947
2025
  )}
948
2026
  </div>
949
2027
 
950
- {editingTask && (
951
- <div className="fixed inset-0 z-[75] flex items-start justify-center overflow-y-auto bg-black/60 px-3 py-3 sm:items-center sm:py-0" onClick={closeEditor}>
2028
+ {activeEditingTask && (
2029
+ <div
2030
+ className="fixed inset-0 z-[75] flex items-start justify-center overflow-y-auto bg-black/60 px-3 py-3 sm:items-center sm:py-0"
2031
+ onClick={closeEditor}
2032
+ >
952
2033
  <div
953
2034
  className="flex max-h-[calc(100dvh-1.5rem)] w-full max-w-[560px] flex-col overflow-hidden rounded-[6px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)]"
954
2035
  onClick={(event) => event.stopPropagation()}
@@ -956,7 +2037,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
956
2037
  aria-modal="true"
957
2038
  >
958
2039
  <header className="border-b border-[var(--vk-border)] px-4 py-3">
959
- <h2 className="text-[18px] text-[var(--vk-text-strong)]">Edit Board Task</h2>
2040
+ <h2 className="text-[18px] text-[var(--vk-text-strong)]">
2041
+ Edit Board Task
2042
+ </h2>
960
2043
  <p className="pt-1 text-[12px] text-[var(--vk-text-muted)]">
961
2044
  Move the card, update the task, and link the latest session run.
962
2045
  </p>
@@ -964,7 +2047,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
964
2047
 
965
2048
  <div className="min-h-0 flex-1 space-y-3 overflow-y-auto px-4 py-4">
966
2049
  <label className="block">
967
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Title</span>
2050
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2051
+ Title
2052
+ </span>
968
2053
  <input
969
2054
  value={editTitle}
970
2055
  onChange={(event) => setEditTitle(event.target.value)}
@@ -973,7 +2058,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
973
2058
  </label>
974
2059
 
975
2060
  <label className="block">
976
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Description</span>
2061
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2062
+ Description
2063
+ </span>
977
2064
  <textarea
978
2065
  value={editDescription}
979
2066
  onChange={(event) => setEditDescription(event.target.value)}
@@ -984,14 +2071,22 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
984
2071
 
985
2072
  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
986
2073
  <label className="block">
987
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Column</span>
2074
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2075
+ Column
2076
+ </span>
988
2077
  <select
989
2078
  value={editRole}
990
- onChange={(event) => setEditRole(toRole(event.target.value))}
2079
+ onChange={(event) =>
2080
+ setEditRole(toRole(event.target.value))
2081
+ }
991
2082
  className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
992
2083
  >
993
2084
  {board?.columns.map((column) => (
994
- <option key={column.role} value={column.role} className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">
2085
+ <option
2086
+ key={column.role}
2087
+ value={column.role}
2088
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2089
+ >
995
2090
  {column.heading || ROLE_LABEL[column.role]}
996
2091
  </option>
997
2092
  ))}
@@ -999,14 +2094,20 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
999
2094
  </label>
1000
2095
 
1001
2096
  <label className="block">
1002
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Agent</span>
2097
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2098
+ Agent
2099
+ </span>
1003
2100
  <select
1004
2101
  value={editAgent}
1005
2102
  onChange={(event) => setEditAgent(event.target.value)}
1006
2103
  className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
1007
2104
  >
1008
2105
  {orderedAgentOptions.map((item) => (
1009
- <option key={item} value={item} className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">
2106
+ <option
2107
+ key={item}
2108
+ value={item}
2109
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2110
+ >
1010
2111
  {formatAgentLabel(item)}
1011
2112
  </option>
1012
2113
  ))}
@@ -1016,7 +2117,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1016
2117
 
1017
2118
  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
1018
2119
  <label className="block">
1019
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Type</span>
2120
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2121
+ Type
2122
+ </span>
1020
2123
  <input
1021
2124
  value={editTaskType}
1022
2125
  onChange={(event) => setEditTaskType(event.target.value)}
@@ -1025,7 +2128,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1025
2128
  </label>
1026
2129
 
1027
2130
  <label className="block">
1028
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Priority</span>
2131
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2132
+ Priority
2133
+ </span>
1029
2134
  <input
1030
2135
  value={editPriority}
1031
2136
  onChange={(event) => setEditPriority(event.target.value)}
@@ -1035,15 +2140,141 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1035
2140
  </div>
1036
2141
 
1037
2142
  <label className="block">
1038
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Primary linked run</span>
2143
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2144
+ GitHub issue id (optional)
2145
+ </span>
2146
+ <input
2147
+ value={editIssueId}
2148
+ onChange={(event) => setEditIssueId(event.target.value)}
2149
+ placeholder="123"
2150
+ className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-transparent px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
2151
+ />
2152
+ </label>
2153
+
2154
+ <label className="block">
2155
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2156
+ Notes
2157
+ </span>
2158
+ <textarea
2159
+ value={editNotes}
2160
+ onChange={(event) => setEditNotes(event.target.value)}
2161
+ rows={3}
2162
+ className="w-full rounded-[3px] border border-[var(--vk-border)] bg-transparent px-2 py-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
2163
+ />
2164
+ </label>
2165
+
2166
+ {activeEditingTask.task.attachments.length > 0 && (
2167
+ <div>
2168
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2169
+ Attachments
2170
+ </span>
2171
+ <div className="flex flex-wrap gap-1.5">
2172
+ {activeEditingTask.task.attachments.map((attachment) => (
2173
+ <ContextAttachmentChip
2174
+ key={attachment}
2175
+ attachment={attachment}
2176
+ opening={openingContextPath === attachment}
2177
+ onOpen={() => void openContextAttachment(attachment)}
2178
+ />
2179
+ ))}
2180
+ </div>
2181
+ </div>
2182
+ )}
2183
+
2184
+ <div className="rounded-[4px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] p-3">
2185
+ <div className="mb-2 flex items-center justify-between gap-2">
2186
+ <span className="text-[12px] uppercase tracking-[0.08em] text-[var(--vk-text-muted)]">
2187
+ Comments
2188
+ </span>
2189
+ <span className="text-[11px] text-[var(--vk-text-muted)]">
2190
+ {activeEditingTask.task.commentCount}
2191
+ </span>
2192
+ </div>
2193
+
2194
+ <div className="space-y-2">
2195
+ {activeEditingTask.task.comments.length > 0 ? (
2196
+ activeEditingTask.task.comments.map((comment) => (
2197
+ <div
2198
+ key={comment.id}
2199
+ className="rounded-[4px] border border-[var(--vk-border)] bg-[rgba(255,255,255,0.02)] px-3 py-2"
2200
+ >
2201
+ <div className="flex flex-wrap items-center gap-2">
2202
+ <span className="text-[12px] text-[var(--vk-text-normal)]">
2203
+ {comment.author}
2204
+ </span>
2205
+ <span className="text-[11px] text-[var(--vk-text-muted)]">
2206
+ {formatActivityTime(comment.timestamp)}
2207
+ </span>
2208
+ </div>
2209
+ <p className="pt-1 whitespace-pre-wrap text-[13px] leading-[20px] text-[var(--vk-text-muted)]">
2210
+ {comment.body}
2211
+ </p>
2212
+ </div>
2213
+ ))
2214
+ ) : (
2215
+ <p className="text-[12px] text-[var(--vk-text-muted)]">
2216
+ No comments yet.
2217
+ </p>
2218
+ )}
2219
+ </div>
2220
+
2221
+ <label className="mt-3 block">
2222
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2223
+ Add comment
2224
+ </span>
2225
+ <textarea
2226
+ value={commentDraft}
2227
+ onChange={(event) => setCommentDraft(event.target.value)}
2228
+ rows={3}
2229
+ placeholder="Share status, request input, or leave implementation notes."
2230
+ className="w-full rounded-[3px] border border-[var(--vk-border)] bg-transparent px-2 py-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
2231
+ />
2232
+ </label>
2233
+
2234
+ {commentError && (
2235
+ <p className="mt-2 text-[12px] text-[var(--vk-red)]">
2236
+ {commentError}
2237
+ </p>
2238
+ )}
2239
+
2240
+ <div className="mt-3 flex justify-end">
2241
+ <button
2242
+ type="button"
2243
+ onClick={() => void handleAddComment()}
2244
+ disabled={!commentDraft.trim() || commentBusy}
2245
+ className="inline-flex h-9 items-center gap-2 rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
2246
+ >
2247
+ {commentBusy ? (
2248
+ <Loader2 className="h-4 w-4 animate-spin" />
2249
+ ) : (
2250
+ <MessageSquare className="h-4 w-4" />
2251
+ )}
2252
+ Post comment
2253
+ </button>
2254
+ </div>
2255
+ </div>
2256
+
2257
+ <label className="block">
2258
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2259
+ Primary linked run
2260
+ </span>
1039
2261
  <select
1040
2262
  value={editLinkedSession}
1041
2263
  onChange={(event) => setEditLinkedSession(event.target.value)}
1042
2264
  className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
1043
2265
  >
1044
- <option value="" className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">No linked session</option>
2266
+ <option
2267
+ value=""
2268
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2269
+ >
2270
+ No linked session
2271
+ </option>
1045
2272
  {editLinkedSessionOptions.map((session) => (
1046
- <option key={session.id} value={session.id} className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">
2273
+ <option
2274
+ key={session.id}
2275
+ value={session.id}
2276
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2277
+ >
1047
2278
  {formatLinkedSessionLabel(session)} · {session.status}
1048
2279
  </option>
1049
2280
  ))}
@@ -1051,7 +2282,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1051
2282
  </label>
1052
2283
 
1053
2284
  {editingError && (
1054
- <p className="text-[12px] text-[var(--vk-red)]">{editingError}</p>
2285
+ <p className="text-[12px] text-[var(--vk-red)]">
2286
+ {editingError}
2287
+ </p>
1055
2288
  )}
1056
2289
  </div>
1057
2290
 
@@ -1059,7 +2292,7 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1059
2292
  <button
1060
2293
  type="button"
1061
2294
  onClick={closeEditor}
1062
- disabled={editingBusy}
2295
+ disabled={editingBusy || commentBusy}
1063
2296
  className="inline-flex h-9 items-center rounded-[3px] border border-[var(--vk-border)] px-3 text-[13px] text-[var(--vk-text-normal)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1064
2297
  >
1065
2298
  Cancel
@@ -1070,7 +2303,11 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1070
2303
  disabled={!editTitle.trim() || editingBusy}
1071
2304
  className="inline-flex h-9 items-center rounded-[3px] bg-[var(--vk-bg-active)] px-3 text-[13px] text-[var(--vk-text-strong)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1072
2305
  >
1073
- {editingBusy ? <Loader2 className="h-4 w-4 animate-spin" /> : "Save Task"}
2306
+ {editingBusy ? (
2307
+ <Loader2 className="h-4 w-4 animate-spin" />
2308
+ ) : (
2309
+ "Save Task"
2310
+ )}
1074
2311
  </button>
1075
2312
  </footer>
1076
2313
  </div>
@@ -1078,7 +2315,10 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1078
2315
  )}
1079
2316
 
1080
2317
  {composerOpen && (
1081
- <div className="fixed inset-0 z-[75] flex items-start justify-center overflow-y-auto bg-black/60 px-3 py-3 sm:items-center sm:py-0" onClick={() => !submitting && setComposerOpen(false)}>
2318
+ <div
2319
+ className="fixed inset-0 z-[75] flex items-start justify-center overflow-y-auto bg-black/60 px-3 py-3 sm:items-center sm:py-0"
2320
+ onClick={() => !submitting && setComposerOpen(false)}
2321
+ >
1082
2322
  <div
1083
2323
  className="flex max-h-[calc(100dvh-1.5rem)] w-full max-w-[560px] flex-col overflow-hidden rounded-[6px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)]"
1084
2324
  onClick={(event) => event.stopPropagation()}
@@ -1086,15 +2326,20 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1086
2326
  aria-modal="true"
1087
2327
  >
1088
2328
  <header className="border-b border-[var(--vk-border)] px-4 py-3">
1089
- <h2 className="text-[18px] text-[var(--vk-text-strong)]">Create Board Task</h2>
2329
+ <h2 className="text-[18px] text-[var(--vk-text-strong)]">
2330
+ Create Board Task
2331
+ </h2>
1090
2332
  <p className="pt-1 text-[12px] text-[var(--vk-text-muted)]">
1091
- Add a task card with project and agent tags for Obsidian + conductor watcher.
2333
+ Add a task card with project and agent tags for Obsidian +
2334
+ conductor watcher.
1092
2335
  </p>
1093
2336
  </header>
1094
2337
 
1095
2338
  <div className="min-h-0 flex-1 space-y-3 overflow-y-auto px-4 py-4">
1096
2339
  <label className="block">
1097
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Title</span>
2340
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2341
+ Title
2342
+ </span>
1098
2343
  <input
1099
2344
  value={title}
1100
2345
  onChange={(event) => setTitle(event.target.value)}
@@ -1104,7 +2349,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1104
2349
  </label>
1105
2350
 
1106
2351
  <label className="block">
1107
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Description (optional)</span>
2352
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2353
+ Description (optional)
2354
+ </span>
1108
2355
  <textarea
1109
2356
  value={description}
1110
2357
  onChange={(event) => setDescription(event.target.value)}
@@ -1115,7 +2362,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1115
2362
  </label>
1116
2363
 
1117
2364
  <label className="block">
1118
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Context notes (optional)</span>
2365
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2366
+ Context notes (optional)
2367
+ </span>
1119
2368
  <textarea
1120
2369
  value={contextNotes}
1121
2370
  onChange={(event) => setContextNotes(event.target.value)}
@@ -1127,14 +2376,20 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1127
2376
 
1128
2377
  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
1129
2378
  <label className="block">
1130
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Agent</span>
2379
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2380
+ Agent
2381
+ </span>
1131
2382
  <select
1132
2383
  value={agent}
1133
2384
  onChange={(event) => setAgent(event.target.value)}
1134
2385
  className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
1135
2386
  >
1136
2387
  {orderedAgentOptions.map((item) => (
1137
- <option key={item} value={item} className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">
2388
+ <option
2389
+ key={item}
2390
+ value={item}
2391
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2392
+ >
1138
2393
  {formatAgentLabel(item)}
1139
2394
  </option>
1140
2395
  ))}
@@ -1142,14 +2397,22 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1142
2397
  </label>
1143
2398
 
1144
2399
  <label className="block">
1145
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Column</span>
2400
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2401
+ Column
2402
+ </span>
1146
2403
  <select
1147
2404
  value={composerRole}
1148
- onChange={(event) => setComposerRole(toRole(event.target.value))}
2405
+ onChange={(event) =>
2406
+ setComposerRole(toRole(event.target.value))
2407
+ }
1149
2408
  className="h-9 w-full rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-panel)] px-2 text-[14px] text-[var(--vk-text-normal)] outline-none focus:border-[var(--vk-orange)]"
1150
2409
  >
1151
2410
  {visibleColumns.map((column) => (
1152
- <option key={column.role} value={column.role} className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]">
2411
+ <option
2412
+ key={column.role}
2413
+ value={column.role}
2414
+ className="bg-[var(--vk-bg-panel)] text-[var(--vk-text-normal)]"
2415
+ >
1153
2416
  {column.heading || ROLE_LABEL[column.role]}
1154
2417
  </option>
1155
2418
  ))}
@@ -1159,7 +2422,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1159
2422
 
1160
2423
  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
1161
2424
  <label className="block">
1162
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Type</span>
2425
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2426
+ Type
2427
+ </span>
1163
2428
  <input
1164
2429
  value={taskType}
1165
2430
  onChange={(event) => setTaskType(event.target.value)}
@@ -1169,7 +2434,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1169
2434
  </label>
1170
2435
 
1171
2436
  <label className="block">
1172
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Priority</span>
2437
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2438
+ Priority
2439
+ </span>
1173
2440
  <input
1174
2441
  value={priority}
1175
2442
  onChange={(event) => setPriority(event.target.value)}
@@ -1181,10 +2448,14 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1181
2448
 
1182
2449
  <div className="rounded-[4px] border border-[var(--vk-border)] p-3">
1183
2450
  <div className="flex flex-wrap items-center justify-between gap-2">
1184
- <p className="text-[12px] text-[var(--vk-text-muted)]">Context attachments</p>
2451
+ <p className="text-[12px] text-[var(--vk-text-muted)]">
2452
+ Context attachments
2453
+ </p>
1185
2454
  <p className="text-[12px] text-[var(--vk-text-muted)]">
1186
2455
  {selectedContextPaths.length} selected
1187
- {uploadFiles.length > 0 ? ` · ${uploadFiles.length} upload(s)` : ""}
2456
+ {uploadFiles.length > 0
2457
+ ? ` · ${uploadFiles.length} upload(s)`
2458
+ : ""}
1188
2459
  </p>
1189
2460
  </div>
1190
2461
 
@@ -1200,11 +2471,12 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1200
2471
  setUploadFiles((current) => {
1201
2472
  const merged = [...current];
1202
2473
  for (const file of next) {
1203
- const exists = merged.some((entry) => (
1204
- entry.name === file.name
1205
- && entry.size === file.size
1206
- && entry.lastModified === file.lastModified
1207
- ));
2474
+ const exists = merged.some(
2475
+ (entry) =>
2476
+ entry.name === file.name &&
2477
+ entry.size === file.size &&
2478
+ entry.lastModified === file.lastModified
2479
+ );
1208
2480
  if (!exists) merged.push(file);
1209
2481
  }
1210
2482
  return merged;
@@ -1226,7 +2498,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1226
2498
  className="inline-flex items-center gap-1 rounded-[3px] border border-[var(--vk-border)] bg-[var(--vk-bg-hover)] px-2 py-1 text-[11px] text-[var(--vk-text-normal)]"
1227
2499
  title="Remove upload"
1228
2500
  >
1229
- <span className="truncate max-w-[220px]">{file.name}</span>
2501
+ <span className="truncate max-w-[220px]">
2502
+ {file.name}
2503
+ </span>
1230
2504
  <span className="text-[var(--vk-text-muted)]">×</span>
1231
2505
  </button>
1232
2506
  ))}
@@ -1234,7 +2508,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1234
2508
  )}
1235
2509
 
1236
2510
  <label className="mt-3 block">
1237
- <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">Select existing context</span>
2511
+ <span className="mb-1 block text-[12px] text-[var(--vk-text-muted)]">
2512
+ Select existing context
2513
+ </span>
1238
2514
  <input
1239
2515
  value={contextSearch}
1240
2516
  onChange={(event) => setContextSearch(event.target.value)}
@@ -1250,33 +2526,62 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1250
2526
  <span>Loading context files...</span>
1251
2527
  </div>
1252
2528
  ) : contextError ? (
1253
- <p className="px-2 py-2 text-[12px] text-[var(--vk-red)]">{contextError}</p>
2529
+ <p className="px-2 py-2 text-[12px] text-[var(--vk-red)]">
2530
+ {contextError}
2531
+ </p>
1254
2532
  ) : filteredContextFiles.length === 0 ? (
1255
- <p className="px-2 py-2 text-[12px] text-[var(--vk-text-muted)]">No context files found.</p>
2533
+ <p className="px-2 py-2 text-[12px] text-[var(--vk-text-muted)]">
2534
+ No context files found.
2535
+ </p>
1256
2536
  ) : (
1257
2537
  <ul className="divide-y divide-[var(--vk-border)]">
1258
2538
  {filteredContextFiles.map((file) => {
1259
- const checked = selectedContextPaths.includes(file.path);
2539
+ const checked = selectedContextPaths.includes(
2540
+ file.path
2541
+ );
1260
2542
  return (
1261
2543
  <li key={file.path} className="px-2 py-1.5">
1262
- <label className="flex cursor-pointer items-start gap-2 text-[12px] text-[var(--vk-text-normal)]">
1263
- <input
1264
- type="checkbox"
1265
- checked={checked}
1266
- onChange={() => toggleContextPath(file.path)}
1267
- className="mt-0.5 h-3.5 w-3.5 rounded border-[var(--vk-border)] bg-transparent"
1268
- />
1269
- <span className="min-w-0">
1270
- <span className="block truncate">
1271
- {file.path}
2544
+ <div className="flex items-start gap-2">
2545
+ <label className="flex min-w-0 flex-1 cursor-pointer items-start gap-2 text-[12px] text-[var(--vk-text-normal)]">
2546
+ <input
2547
+ type="checkbox"
2548
+ checked={checked}
2549
+ onChange={() => toggleContextPath(file.path)}
2550
+ className="mt-0.5 h-3.5 w-3.5 rounded border-[var(--vk-border)] bg-transparent"
2551
+ />
2552
+ <span className="min-w-0">
2553
+ <span className="block truncate">
2554
+ {file.path}
2555
+ </span>
2556
+ <span className="block text-[11px] text-[var(--vk-text-muted)]">
2557
+ {file.kind}
2558
+ {file.source ? ` · ${file.source}` : ""}
2559
+ {file.sizeBytes
2560
+ ? ` · ${formatFileSize(file.sizeBytes)}`
2561
+ : ""}
2562
+ </span>
1272
2563
  </span>
1273
- <span className="block text-[11px] text-[var(--vk-text-muted)]">
1274
- {file.kind}
1275
- {file.source ? ` · ${file.source}` : ""}
1276
- {file.sizeBytes ? ` · ${formatFileSize(file.sizeBytes)}` : ""}
2564
+ </label>
2565
+ <button
2566
+ type="button"
2567
+ onClick={() =>
2568
+ void openContextAttachment(file.path)
2569
+ }
2570
+ disabled={openingContextPath === file.path}
2571
+ className="inline-flex h-7 shrink-0 items-center gap-1 rounded-[3px] border border-[var(--vk-border)] px-2 text-[11px] text-[var(--vk-text-muted)] hover:bg-[var(--vk-bg-hover)] hover:text-[var(--vk-text-normal)] disabled:opacity-60"
2572
+ title={`${contextOpenLabel}: ${file.path}`}
2573
+ aria-label={`${contextOpenLabel}: ${file.path}`}
2574
+ >
2575
+ {openingContextPath === file.path ? (
2576
+ <Loader2 className="h-3 w-3 animate-spin" />
2577
+ ) : (
2578
+ <ExternalLink className="h-3 w-3" />
2579
+ )}
2580
+ <span className="hidden sm:inline">
2581
+ {contextOpenLabel}
1277
2582
  </span>
1278
- </span>
1279
- </label>
2583
+ </button>
2584
+ </div>
1280
2585
  </li>
1281
2586
  );
1282
2587
  })}
@@ -1286,7 +2591,9 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1286
2591
  </div>
1287
2592
 
1288
2593
  {submitError && (
1289
- <p className="text-[12px] text-[var(--vk-red)]">{submitError}</p>
2594
+ <p className="text-[12px] text-[var(--vk-red)]">
2595
+ {submitError}
2596
+ </p>
1290
2597
  )}
1291
2598
  </div>
1292
2599
 
@@ -1305,7 +2612,11 @@ export function WorkspaceKanban({ projectId, defaultAgent, agentOptions }: Works
1305
2612
  disabled={!title.trim() || submitting}
1306
2613
  className="inline-flex h-9 items-center rounded-[3px] bg-[var(--vk-bg-active)] px-3 text-[13px] text-[var(--vk-text-strong)] hover:bg-[var(--vk-bg-hover)] disabled:opacity-50"
1307
2614
  >
1308
- {submitting ? <Loader2 className="h-4 w-4 animate-spin" /> : "Create Task"}
2615
+ {submitting ? (
2616
+ <Loader2 className="h-4 w-4 animate-spin" />
2617
+ ) : (
2618
+ "Create Task"
2619
+ )}
1309
2620
  </button>
1310
2621
  </footer>
1311
2622
  </div>