trident-git 0.2.0 → 0.2.2

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 (311) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-path-routes-manifest.json +23 -0
  3. package/.next/build-manifest.json +20 -0
  4. package/.next/export-marker.json +6 -0
  5. package/.next/images-manifest.json +73 -0
  6. package/.next/next-minimal-server.js.nft.json +1 -0
  7. package/.next/next-server.js.nft.json +1 -0
  8. package/.next/package.json +1 -0
  9. package/.next/prerender-manifest.json +282 -0
  10. package/.next/react-loadable-manifest.json +1 -0
  11. package/.next/required-server-files.js +330 -0
  12. package/.next/required-server-files.json +330 -0
  13. package/.next/routes-manifest.json +170 -0
  14. package/.next/server/app/_global-error/page.js +3 -0
  15. package/.next/server/app/_global-error/page.js.nft.json +1 -0
  16. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
  17. package/.next/server/app/_global-error.html +2 -0
  18. package/.next/server/app/_global-error.meta +16 -0
  19. package/.next/server/app/_global-error.rsc +12 -0
  20. package/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
  21. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
  22. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +4 -0
  23. package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
  24. package/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
  25. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
  26. package/.next/server/app/_not-found/page.js +2 -0
  27. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  28. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  29. package/.next/server/app/_not-found.html +1 -0
  30. package/.next/server/app/_not-found.meta +16 -0
  31. package/.next/server/app/_not-found.rsc +19 -0
  32. package/.next/server/app/_not-found.segments/_full.segment.rsc +19 -0
  33. package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
  34. package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -0
  35. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
  36. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
  37. package/.next/server/app/_not-found.segments/_tree.segment.rsc +6 -0
  38. package/.next/server/app/api/credentials/route.js +1 -0
  39. package/.next/server/app/api/credentials/route.js.nft.json +1 -0
  40. package/.next/server/app/api/credentials/route_client-reference-manifest.js +1 -0
  41. package/.next/server/app/api/custom-scripts/route.js +3 -0
  42. package/.next/server/app/api/custom-scripts/route.js.nft.json +1 -0
  43. package/.next/server/app/api/custom-scripts/route_client-reference-manifest.js +1 -0
  44. package/.next/server/app/api/fs/route.js +1 -0
  45. package/.next/server/app/api/fs/route.js.nft.json +1 -0
  46. package/.next/server/app/api/fs/route_client-reference-manifest.js +1 -0
  47. package/.next/server/app/api/git/action/route.js +1 -0
  48. package/.next/server/app/api/git/action/route.js.nft.json +1 -0
  49. package/.next/server/app/api/git/action/route_client-reference-manifest.js +1 -0
  50. package/.next/server/app/api/git/branches/route.js +1 -0
  51. package/.next/server/app/api/git/branches/route.js.nft.json +1 -0
  52. package/.next/server/app/api/git/branches/route_client-reference-manifest.js +1 -0
  53. package/.next/server/app/api/git/diff/route.js +1 -0
  54. package/.next/server/app/api/git/diff/route.js.nft.json +1 -0
  55. package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -0
  56. package/.next/server/app/api/git/log/route.js +1 -0
  57. package/.next/server/app/api/git/log/route.js.nft.json +1 -0
  58. package/.next/server/app/api/git/log/route_client-reference-manifest.js +1 -0
  59. package/.next/server/app/api/git/status/route.js +1 -0
  60. package/.next/server/app/api/git/status/route.js.nft.json +1 -0
  61. package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -0
  62. package/.next/server/app/api/repos/route.js +1 -0
  63. package/.next/server/app/api/repos/route.js.nft.json +1 -0
  64. package/.next/server/app/api/repos/route_client-reference-manifest.js +1 -0
  65. package/.next/server/app/api/settings/route.js +1 -0
  66. package/.next/server/app/api/settings/route.js.nft.json +1 -0
  67. package/.next/server/app/api/settings/route_client-reference-manifest.js +1 -0
  68. package/.next/server/app/credentials/page.js +4 -0
  69. package/.next/server/app/credentials/page.js.nft.json +1 -0
  70. package/.next/server/app/credentials/page_client-reference-manifest.js +1 -0
  71. package/.next/server/app/credentials.html +1 -0
  72. package/.next/server/app/credentials.meta +15 -0
  73. package/.next/server/app/credentials.rsc +23 -0
  74. package/.next/server/app/credentials.segments/_full.segment.rsc +23 -0
  75. package/.next/server/app/credentials.segments/_head.segment.rsc +6 -0
  76. package/.next/server/app/credentials.segments/_index.segment.rsc +8 -0
  77. package/.next/server/app/credentials.segments/_tree.segment.rsc +6 -0
  78. package/.next/server/app/credentials.segments/credentials/__PAGE__.segment.rsc +9 -0
  79. package/.next/server/app/credentials.segments/credentials.segment.rsc +4 -0
  80. package/.next/server/app/icon.png/route.js +1 -0
  81. package/.next/server/app/icon.png/route.js.nft.json +1 -0
  82. package/.next/server/app/icon.png.meta +1 -0
  83. package/.next/server/app/index.html +1 -0
  84. package/.next/server/app/index.meta +14 -0
  85. package/.next/server/app/index.rsc +20 -0
  86. package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -0
  87. package/.next/server/app/index.segments/_full.segment.rsc +20 -0
  88. package/.next/server/app/index.segments/_head.segment.rsc +6 -0
  89. package/.next/server/app/index.segments/_index.segment.rsc +8 -0
  90. package/.next/server/app/index.segments/_tree.segment.rsc +6 -0
  91. package/.next/server/app/page.js +2 -0
  92. package/.next/server/app/page.js.nft.json +1 -0
  93. package/.next/server/app/page_client-reference-manifest.js +1 -0
  94. package/.next/server/app/workspace/changes/page.js +4 -0
  95. package/.next/server/app/workspace/changes/page.js.nft.json +1 -0
  96. package/.next/server/app/workspace/changes/page_client-reference-manifest.js +1 -0
  97. package/.next/server/app/workspace/changes.html +1 -0
  98. package/.next/server/app/workspace/changes.meta +16 -0
  99. package/.next/server/app/workspace/changes.rsc +26 -0
  100. package/.next/server/app/workspace/changes.segments/_full.segment.rsc +26 -0
  101. package/.next/server/app/workspace/changes.segments/_head.segment.rsc +6 -0
  102. package/.next/server/app/workspace/changes.segments/_index.segment.rsc +8 -0
  103. package/.next/server/app/workspace/changes.segments/_tree.segment.rsc +7 -0
  104. package/.next/server/app/workspace/changes.segments/workspace/changes/__PAGE__.segment.rsc +10 -0
  105. package/.next/server/app/workspace/changes.segments/workspace/changes.segment.rsc +4 -0
  106. package/.next/server/app/workspace/changes.segments/workspace.segment.rsc +7 -0
  107. package/.next/server/app/workspace/custom-scripts/page.js +2 -0
  108. package/.next/server/app/workspace/custom-scripts/page.js.nft.json +1 -0
  109. package/.next/server/app/workspace/custom-scripts/page_client-reference-manifest.js +1 -0
  110. package/.next/server/app/workspace/custom-scripts.html +1 -0
  111. package/.next/server/app/workspace/custom-scripts.meta +16 -0
  112. package/.next/server/app/workspace/custom-scripts.rsc +25 -0
  113. package/.next/server/app/workspace/custom-scripts.segments/_full.segment.rsc +25 -0
  114. package/.next/server/app/workspace/custom-scripts.segments/_head.segment.rsc +6 -0
  115. package/.next/server/app/workspace/custom-scripts.segments/_index.segment.rsc +8 -0
  116. package/.next/server/app/workspace/custom-scripts.segments/_tree.segment.rsc +6 -0
  117. package/.next/server/app/workspace/custom-scripts.segments/workspace/custom-scripts/__PAGE__.segment.rsc +9 -0
  118. package/.next/server/app/workspace/custom-scripts.segments/workspace/custom-scripts.segment.rsc +4 -0
  119. package/.next/server/app/workspace/custom-scripts.segments/workspace.segment.rsc +7 -0
  120. package/.next/server/app/workspace/history/page.js +2 -0
  121. package/.next/server/app/workspace/history/page.js.nft.json +1 -0
  122. package/.next/server/app/workspace/history/page_client-reference-manifest.js +1 -0
  123. package/.next/server/app/workspace/history.html +1 -0
  124. package/.next/server/app/workspace/history.meta +16 -0
  125. package/.next/server/app/workspace/history.rsc +26 -0
  126. package/.next/server/app/workspace/history.segments/_full.segment.rsc +26 -0
  127. package/.next/server/app/workspace/history.segments/_head.segment.rsc +6 -0
  128. package/.next/server/app/workspace/history.segments/_index.segment.rsc +8 -0
  129. package/.next/server/app/workspace/history.segments/_tree.segment.rsc +7 -0
  130. package/.next/server/app/workspace/history.segments/workspace/history/__PAGE__.segment.rsc +10 -0
  131. package/.next/server/app/workspace/history.segments/workspace/history.segment.rsc +4 -0
  132. package/.next/server/app/workspace/history.segments/workspace.segment.rsc +7 -0
  133. package/.next/server/app/workspace/page.js +2 -0
  134. package/.next/server/app/workspace/page.js.nft.json +1 -0
  135. package/.next/server/app/workspace/page_client-reference-manifest.js +1 -0
  136. package/.next/server/app/workspace/settings/page.js +2 -0
  137. package/.next/server/app/workspace/settings/page.js.nft.json +1 -0
  138. package/.next/server/app/workspace/settings/page_client-reference-manifest.js +1 -0
  139. package/.next/server/app/workspace/settings.html +1 -0
  140. package/.next/server/app/workspace/settings.meta +16 -0
  141. package/.next/server/app/workspace/settings.rsc +25 -0
  142. package/.next/server/app/workspace/settings.segments/_full.segment.rsc +25 -0
  143. package/.next/server/app/workspace/settings.segments/_head.segment.rsc +6 -0
  144. package/.next/server/app/workspace/settings.segments/_index.segment.rsc +8 -0
  145. package/.next/server/app/workspace/settings.segments/_tree.segment.rsc +6 -0
  146. package/.next/server/app/workspace/settings.segments/workspace/settings/__PAGE__.segment.rsc +9 -0
  147. package/.next/server/app/workspace/settings.segments/workspace/settings.segment.rsc +4 -0
  148. package/.next/server/app/workspace/settings.segments/workspace.segment.rsc +7 -0
  149. package/.next/server/app/workspace/stashes/page.js +2 -0
  150. package/.next/server/app/workspace/stashes/page.js.nft.json +1 -0
  151. package/.next/server/app/workspace/stashes/page_client-reference-manifest.js +1 -0
  152. package/.next/server/app/workspace/stashes.html +1 -0
  153. package/.next/server/app/workspace/stashes.meta +16 -0
  154. package/.next/server/app/workspace/stashes.rsc +26 -0
  155. package/.next/server/app/workspace/stashes.segments/_full.segment.rsc +26 -0
  156. package/.next/server/app/workspace/stashes.segments/_head.segment.rsc +6 -0
  157. package/.next/server/app/workspace/stashes.segments/_index.segment.rsc +8 -0
  158. package/.next/server/app/workspace/stashes.segments/_tree.segment.rsc +7 -0
  159. package/.next/server/app/workspace/stashes.segments/workspace/stashes/__PAGE__.segment.rsc +10 -0
  160. package/.next/server/app/workspace/stashes.segments/workspace/stashes.segment.rsc +4 -0
  161. package/.next/server/app/workspace/stashes.segments/workspace.segment.rsc +7 -0
  162. package/.next/server/app/workspace.html +1 -0
  163. package/.next/server/app/workspace.meta +15 -0
  164. package/.next/server/app/workspace.rsc +26 -0
  165. package/.next/server/app/workspace.segments/_full.segment.rsc +26 -0
  166. package/.next/server/app/workspace.segments/_head.segment.rsc +6 -0
  167. package/.next/server/app/workspace.segments/_index.segment.rsc +8 -0
  168. package/.next/server/app/workspace.segments/_tree.segment.rsc +7 -0
  169. package/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +10 -0
  170. package/.next/server/app/workspace.segments/workspace.segment.rsc +7 -0
  171. package/.next/server/app-paths-manifest.json +23 -0
  172. package/.next/server/chunks/116.js +1 -0
  173. package/.next/server/chunks/170.js +1 -0
  174. package/.next/server/chunks/309.js +6 -0
  175. package/.next/server/chunks/356.js +1 -0
  176. package/.next/server/chunks/392.js +1 -0
  177. package/.next/server/chunks/443.js +37 -0
  178. package/.next/server/chunks/445.js +22 -0
  179. package/.next/server/chunks/471.js +13 -0
  180. package/.next/server/chunks/557.js +5 -0
  181. package/.next/server/chunks/680.js +1 -0
  182. package/.next/server/chunks/739.js +5 -0
  183. package/.next/server/chunks/781.js +1 -0
  184. package/.next/server/chunks/813.js +1 -0
  185. package/.next/server/chunks/816.js +13 -0
  186. package/.next/server/functions-config-manifest.json +6 -0
  187. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  188. package/.next/server/middleware-build-manifest.js +1 -0
  189. package/.next/server/middleware-manifest.json +6 -0
  190. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  191. package/.next/server/next-font-manifest.js +1 -0
  192. package/.next/server/next-font-manifest.json +1 -0
  193. package/.next/server/pages/404.html +1 -0
  194. package/.next/server/pages/500.html +2 -0
  195. package/.next/server/pages-manifest.json +4 -0
  196. package/.next/server/server-reference-manifest.js +1 -0
  197. package/.next/server/server-reference-manifest.json +1 -0
  198. package/.next/server/webpack-runtime.js +1 -0
  199. package/.next/static/VTWJwhFJd5VcC6GP5bbli/_buildManifest.js +1 -0
  200. package/.next/static/VTWJwhFJd5VcC6GP5bbli/_ssgManifest.js +1 -0
  201. package/.next/static/chunks/131-6237c77d708182b1.js +1 -0
  202. package/.next/static/chunks/147-d4cb3e03218d75df.js +6 -0
  203. package/.next/static/chunks/176-b068120641913226.js +1 -0
  204. package/.next/static/chunks/200-3664e65687e716a2.js +1 -0
  205. package/.next/static/chunks/26-d93e82c9c09ff972.js +1 -0
  206. package/.next/static/chunks/4bd1b696-096d35a2bd1da3af.js +1 -0
  207. package/.next/static/chunks/500-5d45efbf86b8d36e.js +1 -0
  208. package/.next/static/chunks/772-b39107b40c31b6b6.js +3 -0
  209. package/.next/static/chunks/785-e6d755147ff87934.js +1 -0
  210. package/.next/static/chunks/790-3e8fa6e595d97940.js +6 -0
  211. package/.next/static/chunks/794-37dad9bbc14b04b8.js +2 -0
  212. package/.next/static/chunks/841-4d865378216d36eb.js +13 -0
  213. package/.next/static/chunks/app/_global-error/page-9eb8a19109bbd711.js +1 -0
  214. package/.next/static/chunks/app/_not-found/page-5bea07380837254f.js +1 -0
  215. package/.next/static/chunks/app/api/credentials/route-9eb8a19109bbd711.js +1 -0
  216. package/.next/static/chunks/app/api/custom-scripts/route-9eb8a19109bbd711.js +1 -0
  217. package/.next/static/chunks/app/api/fs/route-9eb8a19109bbd711.js +1 -0
  218. package/.next/static/chunks/app/api/git/action/route-9eb8a19109bbd711.js +1 -0
  219. package/.next/static/chunks/app/api/git/branches/route-9eb8a19109bbd711.js +1 -0
  220. package/.next/static/chunks/app/api/git/diff/route-9eb8a19109bbd711.js +1 -0
  221. package/.next/static/chunks/app/api/git/log/route-9eb8a19109bbd711.js +1 -0
  222. package/.next/static/chunks/app/api/git/status/route-9eb8a19109bbd711.js +1 -0
  223. package/.next/static/chunks/app/api/repos/route-9eb8a19109bbd711.js +1 -0
  224. package/.next/static/chunks/app/api/settings/route-9eb8a19109bbd711.js +1 -0
  225. package/.next/static/chunks/app/credentials/page-23c1807ad9f68a40.js +1 -0
  226. package/.next/static/chunks/app/layout-a06241c385e50ae0.js +1 -0
  227. package/.next/static/chunks/app/page-c8404790f5191fd7.js +1 -0
  228. package/.next/static/chunks/app/workspace/changes/page-8cca17f80e66f534.js +3 -0
  229. package/.next/static/chunks/app/workspace/custom-scripts/page-ee24b9dd7779244f.js +1 -0
  230. package/.next/static/chunks/app/workspace/history/page-b7017fea285c804c.js +1 -0
  231. package/.next/static/chunks/app/workspace/layout-cb86c00fdcd8db08.js +1 -0
  232. package/.next/static/chunks/app/workspace/page-21211acc90c08509.js +1 -0
  233. package/.next/static/chunks/app/workspace/settings/page-7ccb58ece31492e9.js +1 -0
  234. package/.next/static/chunks/app/workspace/stashes/page-0e1b8304c4b0f4f3.js +1 -0
  235. package/.next/static/chunks/framework-75892d61b920805f.js +1 -0
  236. package/.next/static/chunks/main-app-221e1b945693a142.js +1 -0
  237. package/.next/static/chunks/main-f1d55fffd3cc9809.js +5 -0
  238. package/.next/static/chunks/next/dist/client/components/builtin/app-error-9eb8a19109bbd711.js +1 -0
  239. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-9eb8a19109bbd711.js +1 -0
  240. package/.next/static/chunks/next/dist/client/components/builtin/global-error-f2a2c324f3740ed8.js +1 -0
  241. package/.next/static/chunks/next/dist/client/components/builtin/not-found-9eb8a19109bbd711.js +1 -0
  242. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9eb8a19109bbd711.js +1 -0
  243. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  244. package/.next/static/chunks/webpack-7dec27dc3bfe207a.js +1 -0
  245. package/.next/static/css/36968b90b2339533.css +1 -0
  246. package/.next/static/css/c56c0e57397a3a60.css +1 -0
  247. package/.next/static/css/de70bee13400563f.css +1 -0
  248. package/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  249. package/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  250. package/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  251. package/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  252. package/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  253. package/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  254. package/README.md +2 -0
  255. package/bin/trident-git.mjs +9 -11
  256. package/{next.config.ts → next.config.mjs} +7 -8
  257. package/package.json +8 -6
  258. package/eslint.config.mjs +0 -18
  259. package/postcss.config.mjs +0 -7
  260. package/src/app/api/credentials/route.ts +0 -113
  261. package/src/app/api/custom-scripts/route.ts +0 -203
  262. package/src/app/api/fs/route.ts +0 -75
  263. package/src/app/api/git/action/route.ts +0 -383
  264. package/src/app/api/git/branches/route.ts +0 -20
  265. package/src/app/api/git/diff/route.ts +0 -104
  266. package/src/app/api/git/log/route.ts +0 -28
  267. package/src/app/api/git/status/route.ts +0 -28
  268. package/src/app/api/repos/route.ts +0 -84
  269. package/src/app/api/settings/route.ts +0 -37
  270. package/src/app/credentials/page.tsx +0 -408
  271. package/src/app/globals.css +0 -109
  272. package/src/app/layout.tsx +0 -38
  273. package/src/app/page.tsx +0 -10
  274. package/src/app/providers.tsx +0 -21
  275. package/src/app/workspace/changes/page.tsx +0 -27
  276. package/src/app/workspace/custom-scripts/page.tsx +0 -247
  277. package/src/app/workspace/history/page.tsx +0 -27
  278. package/src/app/workspace/layout.tsx +0 -26
  279. package/src/app/workspace/page.tsx +0 -27
  280. package/src/app/workspace/settings/page.tsx +0 -233
  281. package/src/app/workspace/stashes/page.tsx +0 -395
  282. package/src/components/command-palette.tsx +0 -178
  283. package/src/components/context-menu.tsx +0 -200
  284. package/src/components/fs-browser.tsx +0 -154
  285. package/src/components/git/diff-view.tsx +0 -137
  286. package/src/components/git/git-graph.tsx +0 -489
  287. package/src/components/git/grouped-diff-viewer.tsx +0 -332
  288. package/src/components/git/history-view.tsx +0 -4862
  289. package/src/components/git/image-diff-view.tsx +0 -342
  290. package/src/components/git/status-view.tsx +0 -597
  291. package/src/components/home-settings-modal.tsx +0 -192
  292. package/src/components/layout/sidebar.tsx +0 -256
  293. package/src/components/repo-list.tsx +0 -206
  294. package/src/components/theme-toggle.tsx +0 -37
  295. package/src/components/toaster.tsx +0 -36
  296. package/src/components/workspace-repo-open-tracker.tsx +0 -39
  297. package/src/hooks/use-credentials.ts +0 -123
  298. package/src/hooks/use-escape-dismiss.ts +0 -72
  299. package/src/hooks/use-git.ts +0 -448
  300. package/src/hooks/use-toast.ts +0 -280
  301. package/src/hooks/use-workspace-title.ts +0 -23
  302. package/src/lib/api-utils.ts +0 -24
  303. package/src/lib/branch-colors.ts +0 -98
  304. package/src/lib/credentials.ts +0 -404
  305. package/src/lib/git.ts +0 -1510
  306. package/src/lib/graph-utils.ts +0 -253
  307. package/src/lib/store.ts +0 -145
  308. package/src/lib/types.ts +0 -95
  309. package/src/lib/utils.ts +0 -266
  310. package/tsconfig.json +0 -34
  311. /package/{src/app/icon.png → .next/server/app/icon.png.body} +0 -0
@@ -1,448 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
3
- import { GitStatus, GitLog, Repository, AppSettings, FileDiffPayload, BranchTrackingInfo, GitError } from '@/lib/types';
4
- import { showGitErrorToast } from './use-toast';
5
-
6
- const API_BASE = '/api';
7
-
8
- export function useSettings() {
9
- return useQuery<AppSettings & { resolvedDefaultFolder: string }>({
10
- queryKey: ['settings'],
11
- queryFn: async () => {
12
- const res = await fetch(`${API_BASE}/settings`);
13
- if (!res.ok) throw new Error('Failed to fetch settings');
14
- return res.json();
15
- },
16
- });
17
- }
18
-
19
- export function useUpdateSettings() {
20
- const queryClient = useQueryClient();
21
- return useMutation({
22
- mutationFn: async (updates: Partial<AppSettings>) => {
23
- const res = await fetch(`${API_BASE}/settings`, {
24
- method: 'PUT',
25
- headers: { 'Content-Type': 'application/json' },
26
- body: JSON.stringify(updates),
27
- });
28
- if (!res.ok) throw new Error('Failed to update settings');
29
- return res.json();
30
- },
31
- onSuccess: () => {
32
- queryClient.invalidateQueries({ queryKey: ['settings'] });
33
- },
34
- });
35
- }
36
-
37
- export function useRepositories() {
38
- return useQuery<Repository[]>({
39
- queryKey: ['repos'],
40
- queryFn: async () => {
41
- const res = await fetch(`${API_BASE}/repos`);
42
- if (!res.ok) throw new Error('Failed to fetch repositories');
43
- return res.json();
44
- },
45
- });
46
- }
47
-
48
- export function useRepository(repoPath: string | null) {
49
- const { data: repos } = useRepositories();
50
- return useMemo(() =>
51
- repos?.find(r => r.path === repoPath) || null,
52
- [repos, repoPath]);
53
- }
54
-
55
- export function useAddRepository() {
56
- const queryClient = useQueryClient();
57
- return useMutation({
58
- mutationFn: async ({ path, name }: { path: string; name?: string }) => {
59
- const res = await fetch(`${API_BASE}/repos`, {
60
- method: 'POST',
61
- headers: { 'Content-Type': 'application/json' },
62
- body: JSON.stringify({ path, name }),
63
- });
64
- if (!res.ok) {
65
- const errorData = await res.json().catch(() => ({}));
66
- throw new Error(errorData.error || 'Failed to add repository');
67
- }
68
- return res.json();
69
- },
70
- onSuccess: () => {
71
- queryClient.invalidateQueries({ queryKey: ['repos'] });
72
- },
73
- });
74
- }
75
-
76
- export function useUpdateRepository() {
77
- const queryClient = useQueryClient();
78
- return useMutation({
79
- mutationFn: async ({ path, updates }: { path: string; updates: Partial<Repository> }) => {
80
- const res = await fetch(`${API_BASE}/repos`, {
81
- method: 'PUT',
82
- headers: { 'Content-Type': 'application/json' },
83
- body: JSON.stringify({ path, updates }),
84
- });
85
- if (!res.ok) throw new Error(await res.text());
86
- return res.json();
87
- },
88
- onSuccess: () => {
89
- queryClient.invalidateQueries({ queryKey: ['repos'] });
90
- },
91
- });
92
- }
93
-
94
- export function useDeleteRepository() {
95
- const queryClient = useQueryClient();
96
- return useMutation({
97
- mutationFn: async ({ path }: { path: string }) => {
98
- const res = await fetch(`${API_BASE}/repos`, {
99
- method: 'DELETE',
100
- headers: { 'Content-Type': 'application/json' },
101
- body: JSON.stringify({ path }),
102
- });
103
- if (!res.ok) throw new Error(await res.text());
104
- return res.json();
105
- },
106
- onSuccess: () => {
107
- queryClient.invalidateQueries({ queryKey: ['repos'] });
108
- },
109
- });
110
- }
111
-
112
-
113
- export function useGitStatus(repoPath: string | null) {
114
- return useQuery<GitStatus>({
115
- queryKey: ['git', repoPath, 'status'],
116
- queryFn: async () => {
117
- if (!repoPath) return null;
118
- const res = await fetch(`${API_BASE}/git/status?path=${encodeURIComponent(repoPath)}`);
119
- if (!res.ok) {
120
- const errorData = await res.json().catch(() => ({}));
121
- const err = new Error(errorData.error || 'Failed to fetch status') as GitError;
122
- err.status = res.status;
123
- throw err;
124
- }
125
- return res.json();
126
- },
127
- enabled: !!repoPath,
128
- refetchOnWindowFocus: true,
129
- refetchOnReconnect: true,
130
- retry: (failureCount, error: GitError) => {
131
- // Don't retry for 404 or 400 errors
132
- if (error.status === 404 || error.status === 400) return false;
133
- return failureCount < 3;
134
- },
135
- });
136
- }
137
-
138
- export function useGitLog(repoPath: string | null, limit: number = 50) {
139
- return useQuery<GitLog>({
140
- queryKey: ['git', repoPath, 'log', limit],
141
- queryFn: async () => {
142
- if (!repoPath) return null;
143
- const res = await fetch(`${API_BASE}/git/log?path=${encodeURIComponent(repoPath)}&limit=${limit}`);
144
- if (!res.ok) {
145
- const errorData = await res.json().catch(() => ({}));
146
- const err = new Error(errorData.error || 'Failed to fetch log') as GitError;
147
- err.status = res.status;
148
- throw err;
149
- }
150
- return res.json();
151
- },
152
- enabled: !!repoPath,
153
- placeholderData: (previousData) => previousData,
154
- retry: (failureCount, error: GitError) => {
155
- if (error.status === 404 || error.status === 400) return false;
156
- return failureCount < 3;
157
- },
158
- });
159
- }
160
-
161
- export function useGitBranches(repoPath: string | null) {
162
- return useQuery<{
163
- branches: string[],
164
- current: string,
165
- branchCommits: Record<string, string>,
166
- remotes: Record<string, string[]>,
167
- remoteUrls: Record<string, string>,
168
- trackingInfo: Record<string, BranchTrackingInfo>
169
- }>({
170
- queryKey: ['git', repoPath, 'branches'],
171
- queryFn: async () => {
172
- if (!repoPath) return null;
173
- const res = await fetch(`${API_BASE}/git/branches?path=${encodeURIComponent(repoPath)}`);
174
- if (!res.ok) {
175
- throw new Error('Failed to fetch branches');
176
- }
177
- return res.json();
178
- },
179
- enabled: !!repoPath,
180
- });
181
- }
182
-
183
- export function useGitDiff(repoPath: string | null, filePath: string | null) {
184
- return useQuery<FileDiffPayload>({
185
- queryKey: ['git', repoPath, 'diff', filePath],
186
- queryFn: async () => {
187
- if (!repoPath || !filePath) return null;
188
- const res = await fetch(`${API_BASE}/git/diff?path=${encodeURIComponent(repoPath)}&file=${encodeURIComponent(filePath)}`);
189
- if (!res.ok) {
190
- const errorData = await res.json().catch(() => ({}));
191
- const err = new Error(errorData.error || 'Failed to fetch diff') as GitError;
192
- err.status = res.status;
193
- throw err;
194
- }
195
- return res.json();
196
- },
197
- enabled: !!repoPath && !!filePath,
198
- retry: (failureCount, error: GitError) => {
199
- if (error.status === 404 || error.status === 400) return false;
200
- return failureCount < 3;
201
- },
202
- });
203
- }
204
-
205
- export interface CommitFile {
206
- path: string;
207
- status: string;
208
- additions: number;
209
- deletions: number;
210
- }
211
-
212
- export function useCommitDiff(repoPath: string | null, commitHash: string | null) {
213
- return useQuery<{ files: CommitFile[]; diff: string }>({
214
- queryKey: ['git', repoPath, 'commit-diff', commitHash],
215
- queryFn: async () => {
216
- if (!repoPath || !commitHash) return null;
217
- const res = await fetch(`${API_BASE}/git/diff?path=${encodeURIComponent(repoPath)}&commit=${encodeURIComponent(commitHash)}`);
218
- if (!res.ok) {
219
- const errorData = await res.json().catch(() => ({}));
220
- const err = new Error(errorData.error || 'Failed to fetch commit diff') as GitError;
221
- err.status = res.status;
222
- throw err;
223
- }
224
- return res.json();
225
- },
226
- enabled: !!repoPath && !!commitHash,
227
- retry: (failureCount, error: GitError) => {
228
- if (error.status === 404 || error.status === 400) return false;
229
- return failureCount < 3;
230
- },
231
- });
232
- }
233
-
234
- export function useCommitFileDiff(repoPath: string | null, commitHash: string | null, filePath: string | null) {
235
- return useQuery<FileDiffPayload>({
236
- queryKey: ['git', repoPath, 'commit-file-diff', commitHash, filePath],
237
- queryFn: async () => {
238
- if (!repoPath || !commitHash || !filePath) return null;
239
- const res = await fetch(`${API_BASE}/git/diff?path=${encodeURIComponent(repoPath)}&commit=${encodeURIComponent(commitHash)}&file=${encodeURIComponent(filePath)}`);
240
- if (!res.ok) {
241
- const errorData = await res.json().catch(() => ({}));
242
- const err = new Error(errorData.error || 'Failed to fetch file diff') as GitError;
243
- err.status = res.status;
244
- throw err;
245
- }
246
- return res.json();
247
- },
248
- enabled: !!repoPath && !!commitHash && !!filePath,
249
- retry: (failureCount, error: GitError) => {
250
- if (error.status === 404 || error.status === 400) return false;
251
- return failureCount < 3;
252
- },
253
- });
254
- }
255
-
256
- // Stash types
257
- export interface GitStash {
258
- index: number;
259
- message: string;
260
- date: string;
261
- hash: string;
262
- }
263
-
264
- export function useGitStashes(repoPath: string | null) {
265
- return useQuery<GitStash[]>({
266
- queryKey: ['git', repoPath, 'stashes'],
267
- queryFn: async () => {
268
- if (!repoPath) return [];
269
- const res = await fetch(`${API_BASE}/git/action`, {
270
- method: 'POST',
271
- headers: { 'Content-Type': 'application/json' },
272
- body: JSON.stringify({ repoPath, action: 'stash-list' }),
273
- });
274
- if (!res.ok) {
275
- throw new Error('Failed to fetch stashes');
276
- }
277
- const data = await res.json();
278
- return data.stashes || [];
279
- },
280
- enabled: !!repoPath,
281
- });
282
- }
283
-
284
- export interface StashFile {
285
- path: string;
286
- status: string;
287
- }
288
-
289
- export function useStashFiles(repoPath: string | null, stashIndex: number | null) {
290
- return useQuery<StashFile[]>({
291
- queryKey: ['git', repoPath, 'stash-files', stashIndex],
292
- queryFn: async () => {
293
- if (!repoPath || stashIndex === null) return [];
294
- const res = await fetch(`${API_BASE}/git/action`, {
295
- method: 'POST',
296
- headers: { 'Content-Type': 'application/json' },
297
- body: JSON.stringify({ repoPath, action: 'stash-files', data: { index: stashIndex } }),
298
- });
299
- if (!res.ok) {
300
- throw new Error('Failed to fetch stash files');
301
- }
302
- const data = await res.json();
303
- return data.files || [];
304
- },
305
- enabled: !!repoPath && stashIndex !== null,
306
- });
307
- }
308
-
309
- export function useStashFileDiff(repoPath: string | null, stashIndex: number | null, filePath: string | null) {
310
- return useQuery<FileDiffPayload>({
311
- queryKey: ['git', repoPath, 'stash-file-diff', stashIndex, filePath],
312
- queryFn: async () => {
313
- if (!repoPath || stashIndex === null || !filePath) return { left: '', right: '', diff: '' };
314
- const res = await fetch(`${API_BASE}/git/action`, {
315
- method: 'POST',
316
- headers: { 'Content-Type': 'application/json' },
317
- body: JSON.stringify({ repoPath, action: 'stash-file-diff', data: { index: stashIndex, file: filePath } }),
318
- });
319
- if (!res.ok) {
320
- throw new Error('Failed to fetch stash file diff');
321
- }
322
- return res.json();
323
- },
324
- enabled: !!repoPath && stashIndex !== null && !!filePath,
325
- });
326
- }
327
-
328
- // Actions
329
- export type GitActionType = 'commit' | 'push' | 'pull' | 'fetch' | 'stage' | 'unstage' | 'checkout' | 'checkout-to-local' | 'branch' | 'create-tag' | 'delete-branch' | 'delete-remote-branch' | 'delete-remote' | 'delete-tag' | 'delete-remote-tag' | 'rename-branch' | 'rename-remote-branch' | 'rename-remote' | 'add-remote' | 'reset' | 'revert' | 'cherry-pick' | 'cherry-pick-multiple' | 'cherry-pick-abort' | 'rebase' | 'merge' | 'check-merge-conflicts' | 'check-rebase-conflicts' | 'get-remotes' | 'get-remote-branches' | 'get-tracking-branch' | 'get-latest-commit-message' | 'push-to-remote' | 'pull-from-remote' | 'stash' | 'stash-apply' | 'stash-drop' | 'stash-pop' | 'reword' | 'discard' | 'cleanup-lock-file';
330
-
331
- // Map action types to human-readable operation names
332
- const actionOperationNames: Record<GitActionType, string> = {
333
- 'commit': 'Commit',
334
- 'push': 'Push',
335
- 'pull': 'Pull',
336
- 'fetch': 'Fetch',
337
- 'stage': 'Stage',
338
- 'unstage': 'Unstage',
339
- 'checkout': 'Checkout',
340
- 'checkout-to-local': 'Checkout',
341
- 'branch': 'Create Branch',
342
- 'create-tag': 'Create Tag',
343
- 'delete-branch': 'Delete Branch',
344
- 'delete-remote-branch': 'Delete Remote Branch',
345
- 'delete-remote': 'Delete Remote',
346
- 'delete-tag': 'Delete Tag',
347
- 'delete-remote-tag': 'Delete Remote Tag',
348
- 'rename-branch': 'Rename Branch',
349
- 'rename-remote-branch': 'Rename Remote Branch',
350
- 'rename-remote': 'Rename Remote',
351
- 'add-remote': 'Add Remote',
352
- 'reset': 'Reset',
353
- 'revert': 'Revert Commit',
354
- 'cherry-pick': 'Cherry Pick',
355
- 'cherry-pick-multiple': 'Cherry Pick',
356
- 'cherry-pick-abort': 'Cherry Pick',
357
- 'rebase': 'Rebase',
358
- 'merge': 'Merge',
359
- 'check-merge-conflicts': 'Check Merge Conflicts',
360
- 'check-rebase-conflicts': 'Check Rebase Conflicts',
361
- 'get-remotes': 'Get Remotes',
362
- 'get-remote-branches': 'Get Remote Branches',
363
- 'get-tracking-branch': 'Get Tracking Branch',
364
- 'get-latest-commit-message': 'Get Latest Commit Message',
365
- 'push-to-remote': 'Push',
366
- 'pull-from-remote': 'Pull',
367
- 'stash': 'Stash',
368
- 'stash-apply': 'Apply Stash',
369
- 'stash-drop': 'Drop Stash',
370
- 'stash-pop': 'Pop Stash',
371
- 'reword': 'Reword Commit',
372
- 'discard': 'Discard Changes',
373
- 'cleanup-lock-file': 'Cleanup Lock File',
374
- };
375
-
376
- const READ_ONLY_ACTIONS: readonly GitActionType[] = [
377
- 'check-merge-conflicts',
378
- 'check-rebase-conflicts',
379
- 'get-remotes',
380
- 'get-remote-branches',
381
- 'get-tracking-branch',
382
- 'get-latest-commit-message'
383
- ];
384
-
385
- interface GitActionPayload {
386
- repoPath: string;
387
- action: GitActionType;
388
- data?: any;
389
- suppressErrorToast?: boolean;
390
- }
391
-
392
- async function cleanupLockFile(repoPath: string) {
393
- const res = await fetch(`${API_BASE}/git/action`, {
394
- method: 'POST',
395
- headers: { 'Content-Type': 'application/json' },
396
- body: JSON.stringify({ repoPath, action: 'cleanup-lock-file' }),
397
- });
398
- if (!res.ok) {
399
- throw new Error('Failed to cleanup lock file');
400
- }
401
- return res.json();
402
- }
403
-
404
- export function useGitAction() {
405
- const queryClient = useQueryClient();
406
- return useMutation({
407
- mutationFn: async ({ repoPath, action, data }: GitActionPayload) => {
408
- const res = await fetch(`${API_BASE}/git/action`, {
409
- method: 'POST',
410
- headers: { 'Content-Type': 'application/json' },
411
- body: JSON.stringify({ repoPath, action, data }),
412
- });
413
- if (!res.ok) {
414
- const error = await res.json();
415
- throw new Error(error.error || 'Failed to execute action');
416
- }
417
- return res.json();
418
- },
419
- onSuccess: (_, variables) => {
420
- // Don't invalidate for read-only actions
421
- if (!READ_ONLY_ACTIONS.includes(variables.action)) {
422
- // Invalidate relevant queries
423
- queryClient.invalidateQueries({ queryKey: ['git', variables.repoPath] });
424
- }
425
- },
426
- onError: (error: Error, variables) => {
427
- // Show error toast for git operations (except read-only actions)
428
- if (!READ_ONLY_ACTIONS.includes(variables.action) && !variables.suppressErrorToast) {
429
- const operationName = actionOperationNames[variables.action] || variables.action;
430
-
431
- // Check for lock file error
432
- if (error.message.includes('Unable to create') && error.message.includes('.git/index.lock')) {
433
- showGitErrorToast(error, {
434
- operation: operationName,
435
- fixLabel: 'Remove Lock File',
436
- onFix: async () => {
437
- await cleanupLockFile(variables.repoPath);
438
- // Invalidate queries to refresh status
439
- queryClient.invalidateQueries({ queryKey: ['git', variables.repoPath] });
440
- }
441
- });
442
- } else {
443
- showGitErrorToast(error, { operation: operationName });
444
- }
445
- }
446
- },
447
- });
448
- }