diffing 0.11.0 → 0.12.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.
- package/README.md +2 -12
- package/dist/{cli-agent-DkwGxuy2.mjs → cli-agent-CWsOHN-j.mjs} +165 -53
- package/dist/{cli-gh-D0NfKpOp.mjs → cli-gh-DI69gJGo.mjs} +24 -14
- package/dist/cli.mjs +53 -22
- package/dist/client/assets/{angular-html-Dl53kkiy.js → angular-html-PLPuQo0k.js} +1 -1
- package/dist/client/assets/{angular-ts-wNJFFkey.js → angular-ts-CE02Ij4b.js} +1 -1
- package/dist/client/assets/{apl-BxtQST-h.js → apl-CsuUKZoi.js} +1 -1
- package/dist/client/assets/{arc-CBmZuzPB.js → arc-CgL5kFe-.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-CEci_K9f.js → architectureDiagram-3BPJPVTR-DxZQWGnx.js} +1 -1
- package/dist/client/assets/{astro-BpADD5rh.js → astro-DkFc7sbz.js} +1 -1
- package/dist/client/assets/{blade-B4I5SQmP.js → blade-BkY07kcC.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-DcKhDtnE.js → blockDiagram-GPEHLZMM-D5a2KZV2.js} +1 -1
- package/dist/client/assets/{c-C3VtOgg8.js → c-T1BrPfJ6.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CaHozoxF.js → c4Diagram-AAUBKEIU-mpMH4kFC.js} +1 -1
- package/dist/client/assets/channel-D3niKhl0.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-tvuzKhdK.js → chunk-2J33WTMH-vMtgRLFH.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-D_nBoD9w.js → chunk-3OPIFGDE-Dx-FqyO2.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-yHPdy1G8.js → chunk-4BX2VUAB-CUrPd8Kv.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-yXpL8wjV.js → chunk-55IACEB6-DHg3Nr8A.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-DZ5cvCDV.js → chunk-5ZQYHXKU-CpDPvbGs.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CJjgOWmY.js → chunk-727SXJPM-3VOGMxwk.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CQYQKXSE.js → chunk-AQP2D5EJ-4dbfbIS6.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CP_f908b.js → chunk-BSJP7CBP-Dfyn0Uwp.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-tcgA8jR0.js → chunk-CSCIHK7Q-VTpSKo0F.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DlpmhBYg.js → chunk-FMBD7UC4-kXD1MyOL.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BkfieXpV.js → chunk-KSCS5N6A-BrVoWOAb.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-BjVXSZnt.js → chunk-L5ZTLDWV-wZEQDPsa.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CaAWmy4Q.js → chunk-LZXEDZCA-D3i0B0eg.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-kWh41zUn.js → chunk-ND2GUHAM-hDVHT0bN.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-CDrIi44_.js → chunk-NZK2D7GU-jQUfhp9h.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-CbNGK3Te.js → chunk-O5CBEL6O-CX_vPWhk.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-CZLFuGpt.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-BhcpjkaB.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-Cca0fTtG.js → chunk-XPW4576I-Co_-vDB4.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DK5KJNIt.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-y5K9t6Se.js +1 -0
- package/dist/client/assets/{cobol-j-6eG2UQ.js → cobol-8-qBLs-a.js} +1 -1
- package/dist/client/assets/{coffee-CZLH0dtt.js → coffee-Bjz5lkyW.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DlxESVex.js → cose-bilkent-S5V4N54A-BljJ0FSA.js} +1 -1
- package/dist/client/assets/{cpp-j6Bp24RI.js → cpp-5BVQCBXT.js} +1 -1
- package/dist/client/assets/{crystal-DW7wcFUs.js → crystal-CCkY93GS.js} +1 -1
- package/dist/client/assets/{css-C43BDU2i.js → css-BTM7Tp2a.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-BaemEJFh.js → dagre-BM42HDAG-BSynd_2D.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BaM-bkJ3.js → diagram-2AECGRRQ-K3E2CVdy.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BOH04DJO.js → diagram-5GNKFQAL-BQHIrfKc.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BP5MyqDZ.js → diagram-KO2AKTUF-Bqs8sNN4.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-Dt4gKMYF.js → diagram-LMA3HP47-C9K4bpQe.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-DoT1VshN.js → diagram-OG6HWLK6-DK6wIXY2.js} +1 -1
- package/dist/client/assets/{dist-DEAxvC4F.js → dist-1nkZYMRy.js} +1 -1
- package/dist/client/assets/{edge-D9ySFlnD.js → edge-DqN2FJce.js} +1 -1
- package/dist/client/assets/{elixir-CoJz_LQ5.js → elixir-BiAgRUFF.js} +1 -1
- package/dist/client/assets/{elm-CvedWh_e.js → elm-N1IbY8sz.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CMP78FsQ.js → erDiagram-TEJ5UH35-jsHCiP02.js} +1 -1
- package/dist/client/assets/{erb-lD_yYZsm.js → erb-B-yYlWAZ.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-Dp0s5BFj.js → flowDiagram-I6XJVG4X-DOB1dAWG.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-GmSG31U-.js → ganttDiagram-6RSMTGT7-BYIewcY5.js} +1 -1
- package/dist/client/assets/{git-rebase-DwZABzof.js → git-rebase-CVkPxOAF.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C1SXShag.js → gitGraphDiagram-PVQCEYII-VNQzbpv2.js} +1 -1
- package/dist/client/assets/{glimmer-js-CWcs3w1Z.js → glimmer-js-BmG1xm72.js} +1 -1
- package/dist/client/assets/{glimmer-ts-CrzGN4lJ.js → glimmer-ts-CvTgwZsg.js} +1 -1
- package/dist/client/assets/{glsl-DRCtwX7h.js → glsl-DwjNNCbW.js} +1 -1
- package/dist/client/assets/{graphql-rpmrismS.js → graphql-BvgkyF8E.js} +1 -1
- package/dist/client/assets/{hack-Ba02RnuQ.js → hack-DH3188x2.js} +1 -1
- package/dist/client/assets/{haml-BHBACStm.js → haml-B0GTfMhX.js} +1 -1
- package/dist/client/assets/{handlebars-BtlQ1SCa.js → handlebars-he7hLDd9.js} +1 -1
- package/dist/client/assets/{html-BkVU3Dge.js → html-DIYgdTBq.js} +1 -1
- package/dist/client/assets/{html-derivative-DoK92vwi.js → html-derivative-2s6MXlci.js} +1 -1
- package/dist/client/assets/{http-CJAwKSPH.js → http-COS23XJP.js} +1 -1
- package/dist/client/assets/{hurl-kaX5jwuN.js → hurl-BlZPjeJt.js} +1 -1
- package/dist/client/assets/{index-BHeNiC07.js → index-BrEVVQOB.js} +154 -154
- package/dist/client/assets/{index-D8hOoJCg.css → index-BsuX6HVI.css} +1 -1
- package/dist/client/assets/{infoDiagram-5YYISTIA-B0i3BlNR.js → infoDiagram-5YYISTIA-DQRqk24I.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BN8sEei4.js → ishikawaDiagram-YF4QCWOH-DU1rqrLx.js} +1 -1
- package/dist/client/assets/{java-BvrigIoq.js → java-BAa5w-Qd.js} +1 -1
- package/dist/client/assets/{javascript-DZkPTYAi.js → javascript-C9e02ssI.js} +1 -1
- package/dist/client/assets/{jinja-Ceg7ui1S.js → jinja-Bx37xXwq.js} +1 -1
- package/dist/client/assets/{jison-iE1GaOyN.js → jison-m_DEf8Jo.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CE6O3NhU.js → journeyDiagram-JHISSGLW-CoHlfevf.js} +1 -1
- package/dist/client/assets/{json-C0j8rEcg.js → json-DtN5AWRW.js} +1 -1
- package/dist/client/assets/{jsx-B7eXljgz.js → jsx-BlPpu8bR.js} +1 -1
- package/dist/client/assets/{julia-DMDw0aMP.js → julia-BAOmCbHl.js} +1 -1
- package/dist/client/assets/{just-BryMKRJ_.js → just-C_bvVjwE.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-j-aU6Yzp.js → kanban-definition-UN3LZRKU-BiqYI7_m.js} +1 -1
- package/dist/client/assets/{latex-BNC9-sjr.js → latex-81pMfNMt.js} +1 -1
- package/dist/client/assets/{line-CyEqpEDp.js → line-DCovs9My.js} +1 -1
- package/dist/client/assets/{linear-CXeaA9km.js → linear-cJF5XHE7.js} +1 -1
- package/dist/client/assets/{liquid-D-fQw-oJ.js → liquid-sKRTk6dT.js} +1 -1
- package/dist/client/assets/{lua-CD2aJ_rS.js → lua-C1uZL4IF.js} +1 -1
- package/dist/client/assets/{marko-BQ37hu6z.js → marko-BKEzP1CL.js} +1 -1
- package/dist/client/assets/{mdc-B5NUi3zZ.js → mdc-CLkfm94H.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BxHF_XbX.js → mermaid-parser.core-CTsTbvb2.js} +1 -1
- package/dist/client/assets/{mermaid.core-BUtaf4P1.js → mermaid.core-D86HJEwL.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-D13tPu2o.js → mindmap-definition-RKZ34NQL-CL3heUmL.js} +1 -1
- package/dist/client/assets/{nginx-1W1E03Rg.js → nginx-eDGm66pc.js} +1 -1
- package/dist/client/assets/{nim-C5A88bFP.js → nim-CoWZPv8-.js} +1 -1
- package/dist/client/assets/{perl-BYoP0wNt.js → perl-MoMqtMVr.js} +1 -1
- package/dist/client/assets/{php-CFxna09e.js → php-DXXVMAtN.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-CHL7Ml5w.js → pieDiagram-4H26LBE5-CWV3TMu4.js} +1 -1
- package/dist/client/assets/{pug-BR4JgWAk.js → pug-CPWaB94J.js} +1 -1
- package/dist/client/assets/{qml-D1U1EFEe.js → qml-lhvpx8vk.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-BnYtv-HY.js → quadrantDiagram-W4KKPZXB-QV25BYos.js} +1 -1
- package/dist/client/assets/{r-ChE6X060.js → r-DYbUnmmK.js} +1 -1
- package/dist/client/assets/{razor-B5iVfQMe.js → razor-DcyOLv96.js} +1 -1
- package/dist/client/assets/{regexp-Dz2drUIf.js → regexp-BdY10jm0.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-D8QEGLKB.js → requirementDiagram-4Y6WPE33-BPMsmU6J.js} +1 -1
- package/dist/client/assets/{review-export-CvFFbCAB.js → review-export-CMwjJURs.js} +1 -1
- package/dist/client/assets/{rst-DZM3RGRs.js → rst-6ShFOzgH.js} +1 -1
- package/dist/client/assets/{ruby-DkXnm-J8.js → ruby-B04DeVbi.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-wVaks6lB.js → sankeyDiagram-5OEKKPKP-DQJeroPp.js} +1 -1
- package/dist/client/assets/{sas-DMbpc71c.js → sas-Dj26ftNa.js} +1 -1
- package/dist/client/assets/{scss-IwVMMp22.js → scss-BOHpBkgl.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Cg31TB-R.js → sequenceDiagram-3UESZ5HK-DdV0Y6Sz.js} +1 -1
- package/dist/client/assets/{shellscript-CIStAKx3.js → shellscript-CpHwjRcU.js} +1 -1
- package/dist/client/assets/{shellsession-uLtzHhlo.js → shellsession-BJAvf4GN.js} +1 -1
- package/dist/client/assets/{soy-BkxBYigm.js → soy-B67bZJnL.js} +1 -1
- package/dist/client/assets/{sql-Ba9y9EvJ.js → sql-8MzOqSsK.js} +1 -1
- package/dist/client/assets/{src-9MKexpFu.js → src-AaoRSmFl.js} +1 -1
- package/dist/client/assets/{stata-CrPCbiIZ.js → stata-aCME945h.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-BbvNjVF6.js → stateDiagram-AJRCARHV-CMD_Xj2M.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-vLl7D4ue.js +1 -0
- package/dist/client/assets/{surrealql-Dvip5u_o.js → surrealql-B_V_HxAi.js} +1 -1
- package/dist/client/assets/{svelte-xBLD60Zd.js → svelte-BcQvTlqz.js} +1 -1
- package/dist/client/assets/{templ-CWv68xbP.js → templ-DZCQ2blz.js} +1 -1
- package/dist/client/assets/{tex-CHqz-fYs.js → tex-BfeQ5Wuu.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CWKkJ3QZ.js → timeline-definition-PNZ67QCA-CyIS7Zoe.js} +1 -1
- package/dist/client/assets/{ts-tags-DS82EDuE.js → ts-tags-DVWE0E87.js} +1 -1
- package/dist/client/assets/{tsx-B2GBjp2F.js → tsx-DdJ7Sfqf.js} +1 -1
- package/dist/client/assets/{twig-CC8x9pG0.js → twig-_gVgaha5.js} +1 -1
- package/dist/client/assets/{typescript-g7i13lnC.js → typescript-Bj0_LzZV.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-OLItKWeg.js → vennDiagram-CIIHVFJN-C-J2kWyk.js} +1 -1
- package/dist/client/assets/{vue-rFbe7luB.js → vue-Dnt_GBRb.js} +1 -1
- package/dist/client/assets/{vue-html-D9GQtYub.js → vue-html-ClVA5__5.js} +1 -1
- package/dist/client/assets/{vue-vine-mrNtQtY5.js → vue-vine-BCcz4SVP.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Dy1yfeb4.js → wardleyDiagram-YWT4CUSO-Dzt4EPh8.js} +1 -1
- package/dist/client/assets/{xml-CHfMjyAM.js → xml-BYeUHEti.js} +1 -1
- package/dist/client/assets/{xsl-BFkNSogJ.js → xsl-Vsx0SZEV.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DfSnfjVL.js → xychartDiagram-2RQKCTM6-BAWZKvwP.js} +1 -1
- package/dist/client/assets/{yaml-BfSgHc04.js → yaml-C6L1khMK.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/{completions-BO2DUM-8.mjs → completions-DvyV49HY.mjs} +1 -0
- package/dist/{doctor-D0Y3kOY7.mjs → doctor-Bz9VHuBI.mjs} +7 -7
- package/dist/{find-tui-binary-B71xiwWu.mjs → find-tui-binary-DVQADOSF.mjs} +56 -25
- package/dist/{git-Czo96ymM.mjs → git-BGj31GX-.mjs} +71 -7
- package/dist/git-CfDSkUcE.mjs +2 -0
- package/dist/{github-CErBub2y.mjs → github-DXiEeHzk.mjs} +1 -1
- package/dist/{github-DBsZ0h_l.mjs → github-DpzqNrUh.mjs} +3 -3
- package/dist/{github-attachments-plDeB0iE.mjs → github-attachments-DgOf7BhP.mjs} +2 -2
- package/dist/{mcp-DtVrMR2S.mjs → mcp-zDVzU1vl.mjs} +32 -29
- package/dist/native/tui-darwin-arm64/diffing-tui +0 -0
- package/dist/native/tui-darwin-x64/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-musl/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-musl/diffing-tui +0 -0
- package/dist/native/tui-win32-x64-msvc/diffing-tui.exe +0 -0
- package/dist/{search-BMPY_ZW8.mjs → search-3R2E5xxr.mjs} +16 -1
- package/dist/{search-BO9Im7eu.mjs → search-CQ4nsjBX.mjs} +1 -1
- package/dist/{server-j0PnTVX1.mjs → server-Dw3lkQ5q.mjs} +157 -42
- package/dist/{server-lock-CY0_1mcS.mjs → server-lock-BNI8FKV1.mjs} +175 -23
- package/dist/{session-conflict-C6V9ZKo7.mjs → session-conflict-Bqt1M4Mp.mjs} +7 -7
- package/dist/{session-manager-CYNchhVA.mjs → session-manager-BKSZQqDJ.mjs} +2 -2
- package/dist/session-url-sr7lXXVc.mjs +100 -0
- package/dist/{tui-search-bridge-Bfb2ktdA.mjs → tui-search-bridge-BGgLCwMF.mjs} +3 -3
- package/dist/{update-check-Copcz9eb.mjs → update-check-BUfh4Y6c.mjs} +16 -15
- package/package.json +4 -1
- package/dist/client/assets/channel-Ct4-oSQN.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-BXhKFVX7.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-_EwuC51_.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-C8bdx9R4.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B26wrQuH.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-B5BbZkU5.js +0 -1
- package/dist/git-DaP_1rVy.mjs +0 -2
- package/dist/settings-yK0GYpbn.mjs +0 -60
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { i as buildGitDiffArgs, s as parseDiffOptions, t as startServer } from "./server-
|
|
1
|
+
import { i as buildGitDiffArgs, s as parseDiffOptions, t as startServer } from "./server-Dw3lkQ5q.mjs";
|
|
2
|
+
import { i as reviewSessionUrl, n as joinSessionApiUrl, r as reviewSessionBaseUrl, t as appendSessionToken } from "./session-url-sr7lXXVc.mjs";
|
|
2
3
|
import { t as formatComments } from "./comment-format-B85NHZnG.mjs";
|
|
3
4
|
import { n as formatPlanReview } from "./plan-format-BwJh5JSE.mjs";
|
|
4
|
-
import { c as removeServerLockIfOwned, i as isLockAlive, p as writeServerLock, r as diffScopeKey, s as removeServerLock, t as acquireServerStartupLease, u as resolveActiveServerLock } from "./server-lock-
|
|
5
|
+
import { c as removeServerLockIfOwned, h as SESSION_TOKEN_HEADER, i as isLockAlive, p as writeServerLock, r as diffScopeKey, s as removeServerLock, t as acquireServerStartupLease, u as resolveActiveServerLock, x as isLoopbackHost, y as generateSessionToken } from "./server-lock-BNI8FKV1.mjs";
|
|
5
6
|
import { n as AWAIT_REVIEW_TIMEOUT_NEXT_ACTION, r as AWAIT_TOOL_DESCRIPTION_SUFFIX, s as PLAN_SUBMIT_NEXT_ACTION, t as AWAIT_PLAN_TIMEOUT_NEXT_ACTION } from "./handoff-LAFtmnHf.mjs";
|
|
6
7
|
import { execFileSync } from "node:child_process";
|
|
7
8
|
import { randomUUID } from "node:crypto";
|
|
@@ -105,25 +106,18 @@ function resolveMcpRepository(repoPath = process.cwd(), explicit = false) {
|
|
|
105
106
|
throw new Error(`diffing mcp: path is not inside a Git repository: ${candidate}`);
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
|
-
function isLoopbackHost(host) {
|
|
109
|
-
const normalized = host.toLowerCase();
|
|
110
|
-
if (normalized === "localhost" || normalized === "::1" || normalized === "[::1]") return true;
|
|
111
|
-
const octets = normalized.split(".");
|
|
112
|
-
return octets.length === 4 && octets[0] === "127" && octets.every((part) => {
|
|
113
|
-
if (!/^\d{1,3}$/.test(part)) return false;
|
|
114
|
-
const value = Number(part);
|
|
115
|
-
return value >= 0 && value <= 255;
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
109
|
function lockUrl(lock) {
|
|
119
|
-
|
|
120
|
-
if (!isLoopbackHost(lock.host)) return null;
|
|
121
|
-
return `http://${lock.host === "::1" ? "[::1]" : lock.host}:${lock.port}`;
|
|
110
|
+
return reviewSessionUrl(lock);
|
|
122
111
|
}
|
|
123
|
-
async function requestJson(base, path, init) {
|
|
112
|
+
async function requestJson(base, path, init, authToken) {
|
|
124
113
|
let response;
|
|
125
114
|
try {
|
|
126
|
-
|
|
115
|
+
const headers = new Headers(init?.headers);
|
|
116
|
+
if (authToken) headers.set(SESSION_TOKEN_HEADER, authToken);
|
|
117
|
+
response = await fetch(joinSessionApiUrl(base, path), {
|
|
118
|
+
...init,
|
|
119
|
+
headers
|
|
120
|
+
});
|
|
127
121
|
} catch (error) {
|
|
128
122
|
if (error instanceof Error && error.name === "AbortError") throw new Error(`Request to ${path} was cancelled. Retry the MCP tool when ready.`);
|
|
129
123
|
const detail = error instanceof Error ? error.message : String(error);
|
|
@@ -368,11 +362,11 @@ function createMcpServer(options) {
|
|
|
368
362
|
const lock = liveLock();
|
|
369
363
|
if (!lock) throw new Error(`No diffing review session is running for ${repoRoot}. Start one with start_review_session, \`diffing --web\`, or \`diffing "gh pr <ref>"\`, then retry.`);
|
|
370
364
|
ensureReusableLock(lock);
|
|
371
|
-
const
|
|
372
|
-
if (!
|
|
365
|
+
const apiOrigin = reviewSessionBaseUrl(lock);
|
|
366
|
+
if (!apiOrigin) throw new Error("The active diffing session does not expose a reachable loopback API.");
|
|
373
367
|
return {
|
|
374
368
|
lock,
|
|
375
|
-
|
|
369
|
+
apiOrigin,
|
|
376
370
|
identity: `${lock.pid}:${lock.startedAt}:${lock.port}:${lock.ownerId ?? ""}`
|
|
377
371
|
};
|
|
378
372
|
}
|
|
@@ -391,11 +385,11 @@ function createMcpServer(options) {
|
|
|
391
385
|
if (session.lock.mode === "tui") {
|
|
392
386
|
if (!session.lock.capability) throw new Error("The TUI lock is missing its API capability.");
|
|
393
387
|
headers.set("X-Diffing-Capability", session.lock.capability);
|
|
394
|
-
}
|
|
395
|
-
return requestJson(session.
|
|
388
|
+
} else if (session.lock.authToken) headers.set(SESSION_TOKEN_HEADER, session.lock.authToken);
|
|
389
|
+
return requestJson(session.apiOrigin, path, {
|
|
396
390
|
...init,
|
|
397
391
|
headers
|
|
398
|
-
});
|
|
392
|
+
}, session.lock.authToken);
|
|
399
393
|
}
|
|
400
394
|
function requestBaseJson(path, init) {
|
|
401
395
|
return requestSessionJson(requireWebSession(), path, init);
|
|
@@ -530,12 +524,17 @@ function createMcpServer(options) {
|
|
|
530
524
|
try {
|
|
531
525
|
const afterLease = liveLock();
|
|
532
526
|
if (afterLease) return reuse(afterLease);
|
|
527
|
+
const authToken = generateSessionToken();
|
|
533
528
|
const lock = {
|
|
534
529
|
port: (await startServerFn({
|
|
535
530
|
port: 0,
|
|
536
531
|
host: "127.0.0.1",
|
|
537
532
|
clientDir,
|
|
538
|
-
diffOpts: parsed
|
|
533
|
+
diffOpts: parsed,
|
|
534
|
+
security: {
|
|
535
|
+
bindHost: "127.0.0.1",
|
|
536
|
+
authToken
|
|
537
|
+
}
|
|
539
538
|
})).port,
|
|
540
539
|
host: "127.0.0.1",
|
|
541
540
|
pid: process.pid,
|
|
@@ -547,7 +546,8 @@ function createMcpServer(options) {
|
|
|
547
546
|
diffArgs: [...diffArgs],
|
|
548
547
|
owner: "mcp",
|
|
549
548
|
ownerId,
|
|
550
|
-
sessionId: ownerId
|
|
549
|
+
sessionId: ownerId,
|
|
550
|
+
authToken
|
|
551
551
|
};
|
|
552
552
|
try {
|
|
553
553
|
writeLock(lock);
|
|
@@ -749,7 +749,9 @@ function createMcpServer(options) {
|
|
|
749
749
|
if (author) params.set("author", author);
|
|
750
750
|
if (fullBody) params.set("fullBody", "true");
|
|
751
751
|
if (format === "xml") {
|
|
752
|
-
const
|
|
752
|
+
const headers = new Headers();
|
|
753
|
+
if (session.lock.authToken) headers.set(SESSION_TOKEN_HEADER, session.lock.authToken);
|
|
754
|
+
const res = await fetch(joinSessionApiUrl(session.apiOrigin, `/api/gh/threads?${params}`), { headers });
|
|
753
755
|
const text = await res.text();
|
|
754
756
|
if (!res.ok) throw new Error(text || res.statusText);
|
|
755
757
|
return textResult(text, { result: {
|
|
@@ -784,7 +786,9 @@ function createMcpServer(options) {
|
|
|
784
786
|
if (fullBody) params.set("fullBody", "true");
|
|
785
787
|
if (state) params.set("state", state);
|
|
786
788
|
if (format === "xml") {
|
|
787
|
-
const
|
|
789
|
+
const headers = new Headers();
|
|
790
|
+
if (session.lock.authToken) headers.set(SESSION_TOKEN_HEADER, session.lock.authToken);
|
|
791
|
+
const res = await fetch(joinSessionApiUrl(session.apiOrigin, `/api/gh/reviews?${params}`), { headers });
|
|
788
792
|
const text = await res.text();
|
|
789
793
|
if (!res.ok) throw new Error(text || res.statusText);
|
|
790
794
|
return textResult(text, { result: {
|
|
@@ -1253,7 +1257,6 @@ function createMcpServer(options) {
|
|
|
1253
1257
|
annotations: MUTATING
|
|
1254
1258
|
}, async ({ title, body, source, model, planId }) => {
|
|
1255
1259
|
const session = requireWebSession();
|
|
1256
|
-
const base = session.url;
|
|
1257
1260
|
await seedPlanCursor(session, void 0, true);
|
|
1258
1261
|
const plan = await requestSessionJson(session, "/api/plans", {
|
|
1259
1262
|
method: "POST",
|
|
@@ -1266,7 +1269,7 @@ function createMcpServer(options) {
|
|
|
1266
1269
|
model
|
|
1267
1270
|
})
|
|
1268
1271
|
});
|
|
1269
|
-
const url = `${
|
|
1272
|
+
const url = appendSessionToken(`${session.apiOrigin}/plan/${plan.id}`, session.lock.authToken);
|
|
1270
1273
|
return textResult(`Submitted plan ${plan.id} (v${plan.version}) at ${url}. ${PLAN_SUBMIT_NEXT_ACTION}`, {
|
|
1271
1274
|
status: "submitted",
|
|
1272
1275
|
planId: plan.id,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as getProjectStorageDir, h as getRepoRoot } from "./git-BGj31GX-.mjs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { mkdirSync } from "node:fs";
|
|
4
4
|
//#region src/lib/symbols.ts
|
|
@@ -38,6 +38,11 @@ const SYMBOL_PATTERNS = [
|
|
|
38
38
|
kind: "enum",
|
|
39
39
|
nameGroup: 1
|
|
40
40
|
},
|
|
41
|
+
{
|
|
42
|
+
pattern: /^\s*namespace\s+((?:\w[\w$]*(?:\\\w[\w$]*)*)+)\s*;/i,
|
|
43
|
+
kind: "namespace",
|
|
44
|
+
nameGroup: 1
|
|
45
|
+
},
|
|
41
46
|
{
|
|
42
47
|
pattern: /^\s*(?:(?:export|declare)\s+)*namespace\s+(\w[\w$]*)/i,
|
|
43
48
|
kind: "namespace",
|
|
@@ -48,6 +53,16 @@ const SYMBOL_PATTERNS = [
|
|
|
48
53
|
kind: "variable",
|
|
49
54
|
nameGroup: 1
|
|
50
55
|
},
|
|
56
|
+
{
|
|
57
|
+
pattern: /^\s*(?:(?:public|private|protected|static|abstract|final)\s+)+function\s+(\w[\w$]*)\s*\(/i,
|
|
58
|
+
kind: "function",
|
|
59
|
+
nameGroup: 1
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
pattern: /^\s*(?:(?:abstract|final|readonly)\s+)+class\s+(\w[\w$]*)/i,
|
|
63
|
+
kind: "class",
|
|
64
|
+
nameGroup: 1
|
|
65
|
+
},
|
|
51
66
|
{
|
|
52
67
|
pattern: /^\s*(?!(?:if|for|while|switch|catch)\b)(?:(?:public|private|protected|static|async|abstract|readonly|override|get|set)\s+)*(\w[\w$]*)\s*(?:<[^>]+>)?\s*\([^)]*\)\s*(?:\{|:[^={]+[;{])/i,
|
|
53
68
|
kind: "method",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as searchFiles, i as searchContent, o as searchSymbols, r as searchAll, s as trackSelection } from "./search-
|
|
1
|
+
import { a as searchFiles, i as searchContent, o as searchSymbols, r as searchAll, s as trackSelection } from "./search-3R2E5xxr.mjs";
|
|
2
2
|
export { searchAll, searchContent, searchFiles, searchSymbols, trackSelection };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
import { a as searchFiles, i as searchContent, o as searchSymbols, r as searchAll, s as trackSelection, t as getSearchStatus } from "./search-
|
|
3
|
-
import {
|
|
1
|
+
import { C as listRepoFiles, D as toSafeRelativePath, E as isSafePath, S as isGitRepo, T as revertHunk, _ as getShowDiff, a as getCommitSeriesSummary, b as getUntrackedFilePathsAsync, d as getMergeStatus, f as getProjectStorageDir, h as getRepoRoot, l as getGitDiffAsync, m as getRepoMetadataAsync, o as getCustomGitDiffAsync, s as getFileContent, u as getHunkHistory, x as gitAddFile, y as getTabSizeForFilesAsync } from "./git-BGj31GX-.mjs";
|
|
2
|
+
import { a as searchFiles, i as searchContent, o as searchSymbols, r as searchAll, s as trackSelection, t as getSearchStatus } from "./search-3R2E5xxr.mjs";
|
|
3
|
+
import { a as loadSettings, o as saveSettings } from "./session-url-sr7lXXVc.mjs";
|
|
4
4
|
import { t as formatComments } from "./comment-format-B85NHZnG.mjs";
|
|
5
5
|
import { n as formatPlanReview, r as sectionTitleForLine, t as extractPlanLines } from "./plan-format-BwJh5JSE.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { _ as buildSessionTokenSetCookieValue, b as injectSessionTokenIntoHtml, v as createServerAuthMiddleware } from "./server-lock-BNI8FKV1.mjs";
|
|
7
|
+
import { D as updatePrReviewComment, E as submitReview, S as refreshPrSession, T as setPrReviewThreadResolved, a as detectCwdRepo, b as parsePrRef, f as fetchPrFileContentViaGh, i as deletePrReviewComment, l as fetchExistingCommentsViaGh, t as buildPrSession, u as fetchExistingReviewsViaGh, w as resolvedFromSession } from "./github-DpzqNrUh.mjs";
|
|
7
8
|
import { execFileSync } from "node:child_process";
|
|
8
9
|
import { createHash } from "node:crypto";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
@@ -53,6 +54,7 @@ const DEFAULTS = {
|
|
|
53
54
|
outputMode: "auto",
|
|
54
55
|
host: "127.0.0.1",
|
|
55
56
|
noOpen: false,
|
|
57
|
+
insecureNoAuth: false,
|
|
56
58
|
reuseSession: false,
|
|
57
59
|
replaceSession: false,
|
|
58
60
|
help: false,
|
|
@@ -184,6 +186,10 @@ const DIFFING_OPTIONS = {
|
|
|
184
186
|
type: "boolean",
|
|
185
187
|
default: false
|
|
186
188
|
},
|
|
189
|
+
"insecure-no-auth": {
|
|
190
|
+
type: "boolean",
|
|
191
|
+
default: false
|
|
192
|
+
},
|
|
187
193
|
"reuse-session": {
|
|
188
194
|
type: "boolean",
|
|
189
195
|
default: false
|
|
@@ -241,8 +247,12 @@ Git Diff Options (drop-in replacement for git diff):`);
|
|
|
241
247
|
console.log(`
|
|
242
248
|
Diffing Server Options:
|
|
243
249
|
--port <port> Port to run the server on (default: random available port)
|
|
244
|
-
--host <host> Host address to bind to (default: 127.0.0.1).
|
|
245
|
-
|
|
250
|
+
--host <host> Host address to bind to (default: 127.0.0.1). Loopback
|
|
251
|
+
binds require a per-session API token. To expose the
|
|
252
|
+
review UI on your LAN, pass 0.0.0.0 together with
|
|
253
|
+
--insecure-no-auth (disables API authentication).
|
|
254
|
+
--insecure-no-auth Allow binding to 0.0.0.0 without API tokens (unsafe on
|
|
255
|
+
shared networks). Ignored on loopback binds.
|
|
246
256
|
--no-open Don't open the browser automatically
|
|
247
257
|
--reuse-session Open the active review instead of starting another
|
|
248
258
|
--replace-session Stop the active review and start a replacement
|
|
@@ -300,7 +310,8 @@ Examples:
|
|
|
300
310
|
diffing -U10 Diff with 10 context lines
|
|
301
311
|
diffing --word-diff=color Word-level diff in color
|
|
302
312
|
diffing -b -w Ignore whitespace changes
|
|
303
|
-
diffing --host 0.0.0.0
|
|
313
|
+
diffing --host 0.0.0.0 --insecure-no-auth
|
|
314
|
+
Expose the review UI on the LAN without API tokens
|
|
304
315
|
diffing view Browse the working-tree diff in the TUI
|
|
305
316
|
diffing view --staged Browse staged changes
|
|
306
317
|
diffing --view main..feature Browse a branch comparison
|
|
@@ -454,6 +465,15 @@ function preprocessOptionalValueArgs(rawArgs) {
|
|
|
454
465
|
"find-renames",
|
|
455
466
|
"break-rewrites"
|
|
456
467
|
]);
|
|
468
|
+
/** Git accepts values only as `--flag=value` for these; never `--flag value`. */
|
|
469
|
+
const ATTACHED_ONLY_LONGS = new Set([
|
|
470
|
+
"stat",
|
|
471
|
+
"dirstat",
|
|
472
|
+
"relative",
|
|
473
|
+
"word-diff",
|
|
474
|
+
"color-moved",
|
|
475
|
+
"submodule"
|
|
476
|
+
]);
|
|
457
477
|
const startsWithDigit = (s) => typeof s === "string" && /^[0-9]/.test(s);
|
|
458
478
|
const out = [];
|
|
459
479
|
for (let i = 0; i < rawArgs.length; i++) {
|
|
@@ -482,6 +502,13 @@ function preprocessOptionalValueArgs(rawArgs) {
|
|
|
482
502
|
}
|
|
483
503
|
continue;
|
|
484
504
|
}
|
|
505
|
+
const attachedOnlyMatch = /^--(stat|dirstat|relative|word-diff|color-moved|submodule)$/.exec(arg);
|
|
506
|
+
if (attachedOnlyMatch) {
|
|
507
|
+
const name = attachedOnlyMatch[1];
|
|
508
|
+
if (ATTACHED_ONLY_LONGS.has(name)) out.push(`--${name}=`);
|
|
509
|
+
else out.push(arg);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
485
512
|
out.push(arg);
|
|
486
513
|
}
|
|
487
514
|
return out;
|
|
@@ -517,6 +544,7 @@ function parseDiffOptions(rawArgs, defaultInteractiveMode = "web") {
|
|
|
517
544
|
if (values.port) opts.port = parseInt(values.port, 10);
|
|
518
545
|
if (values.host) opts.host = values.host;
|
|
519
546
|
if (values["no-open"]) opts.noOpen = true;
|
|
547
|
+
if (values["insecure-no-auth"]) opts.insecureNoAuth = true;
|
|
520
548
|
if (values["reuse-session"]) opts.reuseSession = true;
|
|
521
549
|
if (values["replace-session"]) opts.replaceSession = true;
|
|
522
550
|
if (values["gh-pr"]) opts.ghPr = String(values["gh-pr"]);
|
|
@@ -594,7 +622,11 @@ function parseDiffOptions(rawArgs, defaultInteractiveMode = "web") {
|
|
|
594
622
|
if (values.raw) opts.outputFormat = "raw";
|
|
595
623
|
if (values.numstat) opts.outputFormat = "numstat";
|
|
596
624
|
if (values.shortstat) opts.outputFormat = "shortstat";
|
|
597
|
-
if (values.stat !== void 0)
|
|
625
|
+
if (values.stat !== void 0) {
|
|
626
|
+
opts.outputFormat = "stat";
|
|
627
|
+
const statVal = values.stat;
|
|
628
|
+
if (statVal) opts.statParam = statVal;
|
|
629
|
+
}
|
|
598
630
|
if (values.summary) opts.outputFormat = "summary";
|
|
599
631
|
if (values["name-only"]) opts.outputFormat = "name-only";
|
|
600
632
|
if (values["name-status"]) opts.outputFormat = "name-status";
|
|
@@ -654,11 +686,9 @@ function parseDiffOptions(rawArgs, defaultInteractiveMode = "web") {
|
|
|
654
686
|
}
|
|
655
687
|
const dashDashIdx = rawArgs.indexOf("--");
|
|
656
688
|
if (dashDashIdx >= 0) {
|
|
657
|
-
for (let i = 0; i < dashDashIdx; i++) {
|
|
658
|
-
const arg = rawArgs[i];
|
|
659
|
-
if (!arg.startsWith("-")) opts.revisions.push(arg);
|
|
660
|
-
}
|
|
661
689
|
for (let i = dashDashIdx + 1; i < rawArgs.length; i++) opts.pathspecs.push(rawArgs[i]);
|
|
690
|
+
const pathspecSet = new Set(opts.pathspecs);
|
|
691
|
+
for (const p of positionals) if (!pathspecSet.has(p)) opts.revisions.push(p);
|
|
662
692
|
} else for (const p of positionals) opts.revisions.push(p);
|
|
663
693
|
if (values.view) opts.outputMode = "tui";
|
|
664
694
|
else if (values.tui) opts.outputMode = "tui";
|
|
@@ -707,7 +737,7 @@ function buildGitDiffArgs(opts) {
|
|
|
707
737
|
if (opts.outputFormat === "raw") args.push("--raw");
|
|
708
738
|
if (opts.outputFormat === "numstat") args.push("--numstat");
|
|
709
739
|
if (opts.outputFormat === "shortstat") args.push("--shortstat");
|
|
710
|
-
if (opts.outputFormat === "stat") args.push("--stat");
|
|
740
|
+
if (opts.outputFormat === "stat") args.push(opts.statParam ? `--stat=${opts.statParam}` : "--stat");
|
|
711
741
|
if (opts.outputFormat === "summary") args.push("--summary");
|
|
712
742
|
if (opts.outputFormat === "name-only") args.push("--name-only");
|
|
713
743
|
if (opts.outputFormat === "name-status") args.push("--name-status");
|
|
@@ -781,6 +811,88 @@ function intoShowMode(opts) {
|
|
|
781
811
|
return opts;
|
|
782
812
|
}
|
|
783
813
|
//#endregion
|
|
814
|
+
//#region src/lib/git-path.ts
|
|
815
|
+
/** Decode Git `core.quotePath` C-quoted pathnames from diff headers. */
|
|
816
|
+
function decodeGitPath$1(raw) {
|
|
817
|
+
const input = raw.trim();
|
|
818
|
+
if (!(input.startsWith("\"") && input.endsWith("\""))) return input;
|
|
819
|
+
const bytes = [];
|
|
820
|
+
const pushText = (value) => bytes.push(...Buffer.from(value, "utf8"));
|
|
821
|
+
for (let i = 1; i < input.length - 1; i++) {
|
|
822
|
+
if (input[i] !== "\\") {
|
|
823
|
+
const codePoint = input.codePointAt(i);
|
|
824
|
+
pushText(String.fromCodePoint(codePoint));
|
|
825
|
+
if (codePoint > 65535) i++;
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
const escaped = input[++i];
|
|
829
|
+
if (escaped == null) break;
|
|
830
|
+
const simple = {
|
|
831
|
+
a: 7,
|
|
832
|
+
b: 8,
|
|
833
|
+
t: 9,
|
|
834
|
+
n: 10,
|
|
835
|
+
v: 11,
|
|
836
|
+
f: 12,
|
|
837
|
+
r: 13,
|
|
838
|
+
"\"": 34,
|
|
839
|
+
"\\": 92
|
|
840
|
+
};
|
|
841
|
+
if (escaped in simple) {
|
|
842
|
+
bytes.push(simple[escaped]);
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
if (/[0-7]/.test(escaped)) {
|
|
846
|
+
let octal = escaped;
|
|
847
|
+
while (octal.length < 3 && i + 1 < input.length - 1 && /[0-7]/.test(input[i + 1])) octal += input[++i];
|
|
848
|
+
bytes.push(Number.parseInt(octal, 8));
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
pushText(escaped);
|
|
852
|
+
}
|
|
853
|
+
return Buffer.from(bytes).toString("utf8");
|
|
854
|
+
}
|
|
855
|
+
function stripSidePrefix$1(path, prefix) {
|
|
856
|
+
return path.startsWith(prefix) ? path.slice(prefix.length) : path;
|
|
857
|
+
}
|
|
858
|
+
function consumeGitToken$1(input, start) {
|
|
859
|
+
if (input[start] !== "\"") {
|
|
860
|
+
const end = input.indexOf(" ", start);
|
|
861
|
+
return {
|
|
862
|
+
token: input.slice(start, end < 0 ? input.length : end),
|
|
863
|
+
next: end < 0 ? input.length : end
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
let escaped = false;
|
|
867
|
+
for (let i = start + 1; i < input.length; i++) {
|
|
868
|
+
const char = input[i];
|
|
869
|
+
if (!escaped && char === "\"") return {
|
|
870
|
+
token: input.slice(start, i + 1),
|
|
871
|
+
next: i + 1
|
|
872
|
+
};
|
|
873
|
+
if (!escaped && char === "\\") escaped = true;
|
|
874
|
+
else escaped = false;
|
|
875
|
+
}
|
|
876
|
+
return null;
|
|
877
|
+
}
|
|
878
|
+
/** Parse `diff --git` header paths, including quoted paths and spaces in names. */
|
|
879
|
+
function parseGitDiffHeaderPaths(line) {
|
|
880
|
+
if (!line.startsWith("diff --git ")) return null;
|
|
881
|
+
const rest = line.slice(11);
|
|
882
|
+
if (rest.startsWith("\"")) {
|
|
883
|
+
const first = consumeGitToken$1(rest, 0);
|
|
884
|
+
if (!first) return null;
|
|
885
|
+
let cursor = first.next;
|
|
886
|
+
while (cursor < rest.length && /\s/.test(rest[cursor])) cursor++;
|
|
887
|
+
const second = consumeGitToken$1(rest, cursor);
|
|
888
|
+
if (!second) return null;
|
|
889
|
+
return [stripSidePrefix$1(decodeGitPath$1(first.token), "a/"), stripSidePrefix$1(decodeGitPath$1(second.token), "b/")];
|
|
890
|
+
}
|
|
891
|
+
const separator = rest.lastIndexOf(" b/");
|
|
892
|
+
if (separator < 0) return null;
|
|
893
|
+
return [stripSidePrefix$1(rest.slice(0, separator), "a/"), stripSidePrefix$1(rest.slice(separator + 1), "b/")];
|
|
894
|
+
}
|
|
895
|
+
//#endregion
|
|
784
896
|
//#region src/lib/diff-overview.ts
|
|
785
897
|
/**
|
|
786
898
|
* Compose the working-tree banner. Used by the default `git diff` (unstaged +
|
|
@@ -973,7 +1085,6 @@ function summariseCommitSeries(series, rows) {
|
|
|
973
1085
|
}
|
|
974
1086
|
//#endregion
|
|
975
1087
|
//#region src/lib/diff-engine.ts
|
|
976
|
-
const MAX_BUFFER = 50 * 1024 * 1024;
|
|
977
1088
|
/**
|
|
978
1089
|
* Determine whether to use the "standard" web mode (unstaged+staged+untracked)
|
|
979
1090
|
* or a "custom" mode (specific revisions / pathspecs).
|
|
@@ -988,8 +1099,8 @@ function isCustomMode$1(opts) {
|
|
|
988
1099
|
function parseFilePaths(patch) {
|
|
989
1100
|
const paths = /* @__PURE__ */ new Set();
|
|
990
1101
|
for (const line of patch.split("\n")) {
|
|
991
|
-
const
|
|
992
|
-
if (
|
|
1102
|
+
const parsed = parseGitDiffHeaderPaths(line);
|
|
1103
|
+
if (parsed) paths.add(parsed[1]);
|
|
993
1104
|
}
|
|
994
1105
|
return [...paths];
|
|
995
1106
|
}
|
|
@@ -1001,9 +1112,9 @@ function parseBinaryFiles(patch, untrackedFiles) {
|
|
|
1001
1112
|
if (!line.startsWith("Binary files ") || !line.includes(" differ")) continue;
|
|
1002
1113
|
let filePath = "";
|
|
1003
1114
|
for (let j = i - 1; j >= 0; j--) {
|
|
1004
|
-
const
|
|
1005
|
-
if (
|
|
1006
|
-
filePath =
|
|
1115
|
+
const parsed = parseGitDiffHeaderPaths(lines[j]);
|
|
1116
|
+
if (parsed) {
|
|
1117
|
+
filePath = parsed[1];
|
|
1007
1118
|
break;
|
|
1008
1119
|
}
|
|
1009
1120
|
}
|
|
@@ -1068,12 +1179,10 @@ async function executeDiffAsync(opts) {
|
|
|
1068
1179
|
*/
|
|
1069
1180
|
async function executeDiffWithMeta(opts) {
|
|
1070
1181
|
const { patch, commits, truncated } = await executeDiffAsync(opts);
|
|
1071
|
-
const repoName =
|
|
1072
|
-
const branch = getBranchName();
|
|
1073
|
-
const untrackedFiles = opts.includeUntracked && !opts.showMode ? await getUntrackedFilePathsAsync() : [];
|
|
1182
|
+
const [{ repoName, branch }, untrackedFiles] = await Promise.all([getRepoMetadataAsync(), opts.includeUntracked && !opts.showMode ? getUntrackedFilePathsAsync() : Promise.resolve([])]);
|
|
1074
1183
|
const binaryFiles = parseBinaryFiles(patch, new Set(untrackedFiles));
|
|
1075
1184
|
const filePaths = parseFilePaths(patch);
|
|
1076
|
-
const tabSizeMap =
|
|
1185
|
+
const tabSizeMap = await getTabSizeForFilesAsync(filePaths);
|
|
1077
1186
|
let overview;
|
|
1078
1187
|
if (opts.showMode && commits && commits.length > 0) overview = buildCommitOverview({
|
|
1079
1188
|
commits: commits.map((c) => ({
|
|
@@ -1150,11 +1259,7 @@ function runTerminalDiff(opts) {
|
|
|
1150
1259
|
}
|
|
1151
1260
|
finalArgs.push(...args);
|
|
1152
1261
|
try {
|
|
1153
|
-
execFileSync("git", ["diff", ...finalArgs], {
|
|
1154
|
-
encoding: "utf-8",
|
|
1155
|
-
maxBuffer: MAX_BUFFER,
|
|
1156
|
-
stdio: "inherit"
|
|
1157
|
-
});
|
|
1262
|
+
execFileSync("git", ["diff", ...finalArgs], { stdio: "inherit" });
|
|
1158
1263
|
return 0;
|
|
1159
1264
|
} catch (err) {
|
|
1160
1265
|
if (err.status === 1 && opts.exitCode) return 1;
|
|
@@ -1175,11 +1280,7 @@ function runTerminalShow(opts) {
|
|
|
1175
1280
|
];
|
|
1176
1281
|
if (opts.pathspecs.length > 0) args.push("--", ...opts.pathspecs);
|
|
1177
1282
|
try {
|
|
1178
|
-
execFileSync("git", args, {
|
|
1179
|
-
encoding: "utf-8",
|
|
1180
|
-
maxBuffer: MAX_BUFFER,
|
|
1181
|
-
stdio: "inherit"
|
|
1182
|
-
});
|
|
1283
|
+
execFileSync("git", args, { stdio: "inherit" });
|
|
1183
1284
|
return 0;
|
|
1184
1285
|
} catch (err) {
|
|
1185
1286
|
return err.status ?? 1;
|
|
@@ -1683,7 +1784,7 @@ function guiEditorCommand(bin, absolutePath, platform) {
|
|
|
1683
1784
|
function terminalEditorCommand(bin, absolutePath, platform, env) {
|
|
1684
1785
|
if (platform === "darwin") return {
|
|
1685
1786
|
cmd: "osascript",
|
|
1686
|
-
args: ["-e", `tell application "Terminal" to do script "${bin}
|
|
1787
|
+
args: ["-e", `tell application "Terminal" to do script ("${bin} " & quoted form of "${absolutePath.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}")`]
|
|
1687
1788
|
};
|
|
1688
1789
|
if (platform === "win32") return {
|
|
1689
1790
|
cmd: "cmd.exe",
|
|
@@ -2835,8 +2936,13 @@ function collectPrAvatarUrls(session) {
|
|
|
2835
2936
|
function isCustomMode(opts) {
|
|
2836
2937
|
return opts.revisions.length > 0 || opts.pathspecs.length > 0 || opts.showMode;
|
|
2837
2938
|
}
|
|
2838
|
-
function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore, prSessionStore, prMode = false
|
|
2939
|
+
function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore, prSessionStore, prMode = false, security = {
|
|
2940
|
+
bindHost: "127.0.0.1",
|
|
2941
|
+
authToken: null,
|
|
2942
|
+
insecureNoAuth: true
|
|
2943
|
+
}) {
|
|
2839
2944
|
const app = new Hono();
|
|
2945
|
+
app.use("*", createServerAuthMiddleware(security));
|
|
2840
2946
|
let diffOpts = { ...diffOptsInput };
|
|
2841
2947
|
const customMode = isCustomMode(diffOpts);
|
|
2842
2948
|
const store = commentStore ?? new FileCommentStore();
|
|
@@ -3733,7 +3839,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3733
3839
|
const session = await prStore.get();
|
|
3734
3840
|
if (!session) return notInPrMode(c);
|
|
3735
3841
|
try {
|
|
3736
|
-
const { fetchPrChecks } = await import("./github-
|
|
3842
|
+
const { fetchPrChecks } = await import("./github-DXiEeHzk.mjs");
|
|
3737
3843
|
const checks = await fetchPrChecks(resolvedFromSession(session), session.headSha);
|
|
3738
3844
|
const summary = {
|
|
3739
3845
|
total: checks.length,
|
|
@@ -3765,7 +3871,7 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3765
3871
|
const text = typeof body.body === "string" ? body.body.trim() : "";
|
|
3766
3872
|
if (!text) return c.json({ error: "body is required" }, 400);
|
|
3767
3873
|
try {
|
|
3768
|
-
const { replyToPrComment } = await import("./github-
|
|
3874
|
+
const { replyToPrComment } = await import("./github-DXiEeHzk.mjs");
|
|
3769
3875
|
const result = await replyToPrComment({
|
|
3770
3876
|
resolved: resolvedFromSession(session),
|
|
3771
3877
|
inReplyTo: id,
|
|
@@ -3979,8 +4085,8 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3979
4085
|
if (decision !== "approve" && decision !== "comment" && decision !== "request-changes" && decision !== "draft") return c.json({ error: "decision must be one of: approve, comment, request-changes, draft" }, 400);
|
|
3980
4086
|
const generalBody = typeof body.body === "string" ? body.body : "";
|
|
3981
4087
|
if (body.dryRun === true) {
|
|
3982
|
-
const { buildReviewPayload, resolvedFromSession } = await import("./github-
|
|
3983
|
-
const { rewriteLocalAttachmentsInBodies } = await import("./github-attachments-
|
|
4088
|
+
const { buildReviewPayload, resolvedFromSession } = await import("./github-DXiEeHzk.mjs");
|
|
4089
|
+
const { rewriteLocalAttachmentsInBodies } = await import("./github-attachments-DgOf7BhP.mjs");
|
|
3984
4090
|
const resolved = resolvedFromSession(session);
|
|
3985
4091
|
const comments = session.comments ?? [];
|
|
3986
4092
|
const rewritten = await rewriteLocalAttachmentsInBodies(resolved, [generalBody, ...comments.map((c) => c.body ?? "")], { dryRun: true });
|
|
@@ -4370,10 +4476,19 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
4370
4476
|
try {
|
|
4371
4477
|
const content = await readFile(fullPath);
|
|
4372
4478
|
const contentType = MIME_TYPES[extname(fullPath)] || "application/octet-stream";
|
|
4479
|
+
if (contentType === "text/html" && security.authToken) {
|
|
4480
|
+
const html = injectSessionTokenIntoHtml(content.toString("utf-8"), security.authToken);
|
|
4481
|
+
return new Response(html, { headers: {
|
|
4482
|
+
"Content-Type": contentType,
|
|
4483
|
+
"Set-Cookie": buildSessionTokenSetCookieValue(security.authToken)
|
|
4484
|
+
} });
|
|
4485
|
+
}
|
|
4373
4486
|
return new Response(content, { headers: { "Content-Type": contentType } });
|
|
4374
4487
|
} catch {
|
|
4375
|
-
const
|
|
4376
|
-
|
|
4488
|
+
const html = injectSessionTokenIntoHtml((await readFile(join(clientDir, "index.html"))).toString("utf-8"), security.authToken);
|
|
4489
|
+
const spaHeaders = { "Content-Type": "text/html" };
|
|
4490
|
+
if (security.authToken) spaHeaders["Set-Cookie"] = buildSessionTokenSetCookieValue(security.authToken);
|
|
4491
|
+
return new Response(html, { headers: spaHeaders });
|
|
4377
4492
|
}
|
|
4378
4493
|
});
|
|
4379
4494
|
return app;
|
|
@@ -4464,7 +4579,7 @@ async function startServer(options) {
|
|
|
4464
4579
|
throw new Error(`Failed to build PR session for ${options.prRef}: ${detail}`);
|
|
4465
4580
|
}
|
|
4466
4581
|
}
|
|
4467
|
-
const app = createApp(options.clientDir, options.diffOpts, void 0, void 0, void 0, prMode);
|
|
4582
|
+
const app = createApp(options.clientDir, options.diffOpts, void 0, void 0, void 0, prMode, options.security);
|
|
4468
4583
|
return new Promise((resolve) => {
|
|
4469
4584
|
serve({
|
|
4470
4585
|
fetch: app.fetch,
|