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,136 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { f as getProjectStorageDir, h as getRepoRoot } from "./git-BGj31GX-.mjs";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
4
|
import { join } from "node:path";
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { getCookie } from "hono/cookie";
|
|
7
|
+
//#region src/lib/server-auth.ts
|
|
8
|
+
/** Header, HttpOnly cookie, or legacy query param carrying the per-session review API token. */
|
|
9
|
+
const SESSION_TOKEN_HEADER = "x-diffing-token";
|
|
10
|
+
const SESSION_TOKEN_QUERY = "token";
|
|
11
|
+
const SESSION_TOKEN_COOKIE = "diffing-token";
|
|
12
|
+
function generateSessionToken() {
|
|
13
|
+
return randomBytes(32).toString("hex");
|
|
14
|
+
}
|
|
15
|
+
function isLoopbackHost(host) {
|
|
16
|
+
const normalized = host.toLowerCase();
|
|
17
|
+
if (normalized === "localhost" || normalized === "::1" || normalized === "[::1]") return true;
|
|
18
|
+
const octets = normalized.split(".");
|
|
19
|
+
return octets.length === 4 && octets[0] === "127" && octets.every((part) => {
|
|
20
|
+
if (!/^\d{1,3}$/.test(part)) return false;
|
|
21
|
+
const value = Number(part);
|
|
22
|
+
return value >= 0 && value <= 255;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function isWildcardBindHost(host) {
|
|
26
|
+
const normalized = host.toLowerCase();
|
|
27
|
+
return normalized === "0.0.0.0" || normalized === "::";
|
|
28
|
+
}
|
|
29
|
+
function requestHostHeader(hostHeader) {
|
|
30
|
+
if (!hostHeader) return null;
|
|
31
|
+
const trimmed = hostHeader.trim();
|
|
32
|
+
if (!trimmed) return null;
|
|
33
|
+
if (trimmed.startsWith("[")) {
|
|
34
|
+
const end = trimmed.indexOf("]");
|
|
35
|
+
return end === -1 ? trimmed.toLowerCase() : trimmed.slice(1, end).toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
return trimmed.split(":")[0].toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
/** Reject non-loopback Host headers when the server binds loopback (DNS rebinding guard). */
|
|
40
|
+
function isAllowedRequestHost(hostHeader, bindHost) {
|
|
41
|
+
if (!isLoopbackHost(bindHost)) return true;
|
|
42
|
+
const host = requestHostHeader(hostHeader);
|
|
43
|
+
if (!host) return true;
|
|
44
|
+
return isLoopbackHost(host);
|
|
45
|
+
}
|
|
46
|
+
function readSessionToken(c) {
|
|
47
|
+
const header = c.req.header(SESSION_TOKEN_HEADER);
|
|
48
|
+
if (header) return header;
|
|
49
|
+
const cookie = getCookie(c, SESSION_TOKEN_COOKIE);
|
|
50
|
+
if (cookie) return cookie;
|
|
51
|
+
return c.req.query("token") || null;
|
|
52
|
+
}
|
|
53
|
+
/** `Set-Cookie` value for the review session token (loopback http — no Secure). */
|
|
54
|
+
function buildSessionTokenSetCookieValue(token) {
|
|
55
|
+
return `${SESSION_TOKEN_COOKIE}=${encodeURIComponent(token)}; Path=/; SameSite=Strict; HttpOnly`;
|
|
56
|
+
}
|
|
57
|
+
/** Escape a session token for embedding in a double-quoted JS string literal. */
|
|
58
|
+
function escapeTokenForJsString(token) {
|
|
59
|
+
return token.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
60
|
+
}
|
|
61
|
+
/** Inject `window.__DIFFING_SESSION_TOKEN__` into served HTML so deep links work without `?token=`. */
|
|
62
|
+
function injectSessionTokenIntoHtml(html, authToken) {
|
|
63
|
+
if (!authToken) return html;
|
|
64
|
+
const script = `<script>window.__DIFFING_SESSION_TOKEN__="${escapeTokenForJsString(authToken)}";<\/script>`;
|
|
65
|
+
if (html.includes("</head>")) return html.replace("</head>", `${script}</head>`);
|
|
66
|
+
return `${script}${html}`;
|
|
67
|
+
}
|
|
68
|
+
function createServerAuthMiddleware(config) {
|
|
69
|
+
return async (c, next) => {
|
|
70
|
+
if (!c.req.path.startsWith("/api/")) {
|
|
71
|
+
await next();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (!isAllowedRequestHost(c.req.header("host"), config.bindHost)) return c.json({ error: "request Host header is not allowed for this bind address" }, 403);
|
|
75
|
+
if (!config.insecureNoAuth && config.authToken) {
|
|
76
|
+
if (readSessionToken(c) !== config.authToken) return c.json({ error: "invalid or missing review session token" }, 401);
|
|
77
|
+
}
|
|
78
|
+
await next();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/lib/lock-probe.ts
|
|
83
|
+
/** Map wildcard bind hosts to loopback for local probes. */
|
|
84
|
+
function loopbackProbeHost(host) {
|
|
85
|
+
if (host === "0.0.0.0") return "127.0.0.1";
|
|
86
|
+
return host;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Synchronous loopback probe: GET `/api/review/status` and expect a JSON body
|
|
90
|
+
* with a numeric `round` field. Used to detect stale locks after PID reuse.
|
|
91
|
+
*/
|
|
92
|
+
function probeLockServerSync(lock) {
|
|
93
|
+
if (lock.port <= 0) return true;
|
|
94
|
+
const host = loopbackProbeHost(lock.host);
|
|
95
|
+
const headers = {};
|
|
96
|
+
if (lock.capability) headers["X-Diffing-Capability"] = lock.capability;
|
|
97
|
+
if (lock.authToken) headers[SESSION_TOKEN_HEADER] = lock.authToken;
|
|
98
|
+
const script = `
|
|
99
|
+
import http from 'node:http';
|
|
100
|
+
const host = ${JSON.stringify(host)};
|
|
101
|
+
const port = ${lock.port};
|
|
102
|
+
const headers = ${JSON.stringify(headers)};
|
|
103
|
+
const req = http.request({
|
|
104
|
+
hostname: host,
|
|
105
|
+
port,
|
|
106
|
+
path: '/api/review/status',
|
|
107
|
+
method: 'GET',
|
|
108
|
+
headers,
|
|
109
|
+
}, (res) => {
|
|
110
|
+
let data = '';
|
|
111
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
112
|
+
res.on('end', () => { process.stdout.write(data); });
|
|
113
|
+
});
|
|
114
|
+
req.on('error', () => process.exit(2));
|
|
115
|
+
req.setTimeout(400, () => { req.destroy(); process.exit(2); });
|
|
116
|
+
req.end();
|
|
117
|
+
`;
|
|
118
|
+
const result = spawnSync(process.execPath, [
|
|
119
|
+
"--input-type=module",
|
|
120
|
+
"-e",
|
|
121
|
+
script
|
|
122
|
+
], {
|
|
123
|
+
timeout: 900,
|
|
124
|
+
encoding: "utf8"
|
|
125
|
+
});
|
|
126
|
+
if (result.status !== 0) return false;
|
|
127
|
+
try {
|
|
128
|
+
return typeof JSON.parse(result.stdout.trim()).round === "number";
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
5
134
|
//#region src/lib/server-lock.ts
|
|
6
135
|
const STARTUP_LEASE_STALE_MS = 3e4;
|
|
7
136
|
/**
|
|
@@ -10,7 +139,7 @@ const STARTUP_LEASE_STALE_MS = 3e4;
|
|
|
10
139
|
* mismatches between a user-started session and an MCP request.
|
|
11
140
|
*/
|
|
12
141
|
function diffScopeKey(options) {
|
|
13
|
-
const { port: _port, host: _host, noOpen: _noOpen, reuseSession: _reuseSession, replaceSession: _replaceSession, help: _help, version: _version, outputMode: _outputMode, tui: _tui, gpu: _gpu, noExtDiff: _noExtDiff, ...scope } = options;
|
|
142
|
+
const { port: _port, host: _host, noOpen: _noOpen, insecureNoAuth: _insecureNoAuth, reuseSession: _reuseSession, replaceSession: _replaceSession, help: _help, version: _version, outputMode: _outputMode, tui: _tui, gpu: _gpu, noExtDiff: _noExtDiff, ...scope } = options;
|
|
14
143
|
return JSON.stringify(scope);
|
|
15
144
|
}
|
|
16
145
|
function lockPath(repoRoot) {
|
|
@@ -31,10 +160,23 @@ function sessionPath(lock) {
|
|
|
31
160
|
return join(sessionsPath(lock.repoRoot), `${encodeURIComponent(serverSessionId(lock))}.json`);
|
|
32
161
|
}
|
|
33
162
|
function writeJsonAtomically(path, value) {
|
|
34
|
-
|
|
163
|
+
const parent = join(path, "..");
|
|
164
|
+
mkdirSync(parent, {
|
|
165
|
+
recursive: true,
|
|
166
|
+
mode: 448
|
|
167
|
+
});
|
|
168
|
+
try {
|
|
169
|
+
chmodSync(parent, 448);
|
|
170
|
+
} catch {}
|
|
35
171
|
const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
36
|
-
writeFileSync(temporary, JSON.stringify(value, null, 2),
|
|
172
|
+
writeFileSync(temporary, JSON.stringify(value, null, 2), {
|
|
173
|
+
encoding: "utf-8",
|
|
174
|
+
mode: 384
|
|
175
|
+
});
|
|
37
176
|
renameSync(temporary, path);
|
|
177
|
+
try {
|
|
178
|
+
chmodSync(path, 384);
|
|
179
|
+
} catch {}
|
|
38
180
|
}
|
|
39
181
|
function normalizedLock(lock) {
|
|
40
182
|
return lock.sessionId ? lock : {
|
|
@@ -139,21 +281,24 @@ function activateServerLock(lock) {
|
|
|
139
281
|
writeJsonAtomically(lockPath(lock.repoRoot), normalized);
|
|
140
282
|
return normalized;
|
|
141
283
|
}
|
|
284
|
+
function isPidAlive(pid) {
|
|
285
|
+
try {
|
|
286
|
+
process.kill(pid, 0);
|
|
287
|
+
return true;
|
|
288
|
+
} catch (error) {
|
|
289
|
+
return (error && typeof error === "object" && "code" in error ? error.code : void 0) === "EPERM";
|
|
290
|
+
}
|
|
291
|
+
}
|
|
142
292
|
/**
|
|
143
|
-
* True
|
|
144
|
-
*
|
|
293
|
+
* True when the lock pid is alive, belongs to this repo, and the loopback port
|
|
294
|
+
* still serves a diffing review status endpoint (detects PID reuse).
|
|
145
295
|
*/
|
|
146
296
|
function isLockAlive(lock, expectedRepoRoot) {
|
|
297
|
+
if (!isPidAlive(lock.pid)) return false;
|
|
147
298
|
try {
|
|
148
|
-
|
|
149
|
-
} catch {
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
try {
|
|
153
|
-
return lock.repoRoot === (expectedRepoRoot ?? getRepoRoot());
|
|
154
|
-
} catch {
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
299
|
+
if (lock.repoRoot !== (expectedRepoRoot ?? getRepoRoot())) return false;
|
|
300
|
+
} catch {}
|
|
301
|
+
return probeLockServerSync(lock);
|
|
157
302
|
}
|
|
158
303
|
function removeServerLock(repoRoot) {
|
|
159
304
|
try {
|
|
@@ -249,11 +394,18 @@ function acquireServerStartupLease(repoRoot, ownerId, now = Date.now()) {
|
|
|
249
394
|
}
|
|
250
395
|
if (reclaim && !acquiredAfterRace) {
|
|
251
396
|
const stalePath = `${path}.stale-${process.pid}-${now}`;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
397
|
+
try {
|
|
398
|
+
renameSync(path, stalePath);
|
|
399
|
+
rmSync(stalePath, {
|
|
400
|
+
recursive: true,
|
|
401
|
+
force: true
|
|
402
|
+
});
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (error?.code === "ENOENT") {
|
|
405
|
+
if (!tryCreate()) return null;
|
|
406
|
+
acquiredAfterRace = true;
|
|
407
|
+
} else return null;
|
|
408
|
+
}
|
|
257
409
|
}
|
|
258
410
|
if (!acquiredAfterRace && !tryCreate()) return null;
|
|
259
411
|
}
|
|
@@ -272,4 +424,4 @@ function acquireServerStartupLease(repoRoot, ownerId, now = Date.now()) {
|
|
|
272
424
|
};
|
|
273
425
|
}
|
|
274
426
|
//#endregion
|
|
275
|
-
export { listServerLocks as a, removeServerLockIfOwned as c, sameServerSession as d, serverSessionId as f, isLockAlive as i, removeServerSession as l, activateServerLock as n, readServerLock as o, writeServerLock as p, diffScopeKey as r, removeServerLock as s, acquireServerStartupLease as t, resolveActiveServerLock as u };
|
|
427
|
+
export { isWildcardBindHost as S, buildSessionTokenSetCookieValue as _, listServerLocks as a, injectSessionTokenIntoHtml as b, removeServerLockIfOwned as c, sameServerSession as d, serverSessionId as f, SESSION_TOKEN_QUERY as g, SESSION_TOKEN_HEADER as h, isLockAlive as i, removeServerSession as l, probeLockServerSync as m, activateServerLock as n, readServerLock as o, writeServerLock as p, diffScopeKey as r, removeServerLock as s, acquireServerStartupLease as t, resolveActiveServerLock as u, createServerAuthMiddleware as v, isLoopbackHost as x, generateSessionToken as y };
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { l as removeServerSession } from "./server-lock-
|
|
1
|
+
import { a as loadSettings, i as reviewSessionUrl } from "./session-url-sr7lXXVc.mjs";
|
|
2
|
+
import { l as removeServerSession, m as probeLockServerSync } from "./server-lock-BNI8FKV1.mjs";
|
|
3
3
|
//#region src/lib/session-conflict.ts
|
|
4
4
|
function sleepMs(ms) {
|
|
5
5
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
6
6
|
}
|
|
7
7
|
/** Loopback-safe review URL for web / gh-pr locks; null for TUI or invalid ports. */
|
|
8
8
|
function existingSessionUrl(lock) {
|
|
9
|
-
|
|
10
|
-
if (mode === "tui" || !(lock.port > 0)) return null;
|
|
11
|
-
const host = lock.host === "0.0.0.0" ? "127.0.0.1" : lock.host;
|
|
12
|
-
const path = mode === "gh-pr" ? "/gh/pr" : "";
|
|
13
|
-
return `http://${host}:${lock.port}${path}`;
|
|
9
|
+
return reviewSessionUrl(lock);
|
|
14
10
|
}
|
|
15
11
|
function defaultClearLock(lock) {
|
|
16
12
|
removeServerSession(lock);
|
|
@@ -36,6 +32,10 @@ async function stopLockOwner(lock, options = {}) {
|
|
|
36
32
|
const now = options.now ?? Date.now;
|
|
37
33
|
const isAlive = options.isAlive ?? ((candidate) => pidAlive(candidate.pid, kill));
|
|
38
34
|
const clearLock = options.clearLock ?? defaultClearLock;
|
|
35
|
+
if (!await (options.lockMatches ?? ((candidate) => probeLockServerSync(candidate)))(lock)) {
|
|
36
|
+
clearLock(lock);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
39
|
if (!isAlive(lock)) {
|
|
40
40
|
clearLock(lock);
|
|
41
41
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as listServerLocks, d as sameServerSession, f as serverSessionId, n as activateServerLock, u as resolveActiveServerLock } from "./server-lock-
|
|
2
|
-
import { n as openExistingSession, r as stopLockOwner, t as existingSessionUrl } from "./session-conflict-
|
|
1
|
+
import { a as listServerLocks, d as sameServerSession, f as serverSessionId, n as activateServerLock, u as resolveActiveServerLock } from "./server-lock-BNI8FKV1.mjs";
|
|
2
|
+
import { n as openExistingSession, r as stopLockOwner, t as existingSessionUrl } from "./session-conflict-Bqt1M4Mp.mjs";
|
|
3
3
|
//#region src/lib/session-manager.ts
|
|
4
4
|
const EXIT_OK = 0;
|
|
5
5
|
const EXIT_NOT_FOUND = 4;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { g as SESSION_TOKEN_QUERY, x as isLoopbackHost } from "./server-lock-BNI8FKV1.mjs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
//#region src/lib/json-atomic.ts
|
|
7
|
+
/** Write JSON via a temp file and rename so readers never see a partial file. */
|
|
8
|
+
function writeJsonAtomically(path, value) {
|
|
9
|
+
mkdirSync(join(path, ".."), { recursive: true });
|
|
10
|
+
const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
11
|
+
writeFileSync(temporary, JSON.stringify(value, null, 2), "utf-8");
|
|
12
|
+
renameSync(temporary, path);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/lib/settings.ts
|
|
16
|
+
const SETTINGS_FILE = join(join(homedir(), ".config", "diffing"), "settings.json");
|
|
17
|
+
const DEFAULTS = {
|
|
18
|
+
defaultMode: "web",
|
|
19
|
+
staged: true,
|
|
20
|
+
untracked: true,
|
|
21
|
+
diffStyle: "split",
|
|
22
|
+
defaultTabSize: 4,
|
|
23
|
+
theme: "rose-pine",
|
|
24
|
+
editorIDE: "default",
|
|
25
|
+
lineDiffType: "word",
|
|
26
|
+
lineWrap: false,
|
|
27
|
+
diffIndicators: "classic",
|
|
28
|
+
showLineNumbers: true,
|
|
29
|
+
hunkSeparators: "line-info",
|
|
30
|
+
lineHoverHighlight: "both",
|
|
31
|
+
fontSize: 13,
|
|
32
|
+
expandContextByDefault: false,
|
|
33
|
+
collapsedContextThreshold: 10,
|
|
34
|
+
expansionLineCount: 20,
|
|
35
|
+
haptics: true,
|
|
36
|
+
sounds: true,
|
|
37
|
+
uiFont: null,
|
|
38
|
+
monoFont: null,
|
|
39
|
+
density: "comfortable",
|
|
40
|
+
autoCollapseLineThreshold: 400,
|
|
41
|
+
requireViewAllBeforeSend: false,
|
|
42
|
+
showStatusBar: true,
|
|
43
|
+
savedReplies: [],
|
|
44
|
+
ignoreSpaceChange: false,
|
|
45
|
+
ignoreAllSpace: false
|
|
46
|
+
};
|
|
47
|
+
function loadSettings() {
|
|
48
|
+
try {
|
|
49
|
+
const data = readFileSync(SETTINGS_FILE, "utf-8");
|
|
50
|
+
const settings = {
|
|
51
|
+
...DEFAULTS,
|
|
52
|
+
...JSON.parse(data)
|
|
53
|
+
};
|
|
54
|
+
if (settings.defaultMode !== "web" && settings.defaultMode !== "tui") settings.defaultMode = DEFAULTS.defaultMode;
|
|
55
|
+
return settings;
|
|
56
|
+
} catch {
|
|
57
|
+
return { ...DEFAULTS };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function saveSettings(settings) {
|
|
61
|
+
const merged = {
|
|
62
|
+
...loadSettings(),
|
|
63
|
+
...settings
|
|
64
|
+
};
|
|
65
|
+
writeJsonAtomically(SETTINGS_FILE, merged);
|
|
66
|
+
return merged;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/lib/session-url.ts
|
|
70
|
+
/** Loopback-safe review URL for web / gh-pr locks; null for TUI or invalid ports. */
|
|
71
|
+
function reviewSessionBaseUrl(lock) {
|
|
72
|
+
if ((lock.mode ?? "web") === "tui" || !(lock.port > 0)) return null;
|
|
73
|
+
if (!isLoopbackHost(lock.host) && lock.host !== "0.0.0.0" && lock.host !== "::") return null;
|
|
74
|
+
const host = lock.host === "0.0.0.0" || lock.host === "::" ? "127.0.0.1" : lock.host;
|
|
75
|
+
const path = lock.mode === "gh-pr" ? "/gh/pr" : "";
|
|
76
|
+
return `http://${host}:${lock.port}${path}`;
|
|
77
|
+
}
|
|
78
|
+
/** Browseable review URL without auth query params (auth uses cookie + header). */
|
|
79
|
+
function appendSessionToken(url, _token) {
|
|
80
|
+
try {
|
|
81
|
+
const parsed = new URL(url);
|
|
82
|
+
parsed.searchParams.delete(SESSION_TOKEN_QUERY);
|
|
83
|
+
const search = parsed.searchParams.toString();
|
|
84
|
+
return `${parsed.origin}${parsed.pathname}${search ? `?${search}` : ""}${parsed.hash}`;
|
|
85
|
+
} catch {
|
|
86
|
+
return url;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Public review URL for humans (no `?token=` — session cookie is set when HTML is served). */
|
|
90
|
+
function reviewSessionUrl(lock) {
|
|
91
|
+
const base = reviewSessionBaseUrl(lock);
|
|
92
|
+
if (!base) return null;
|
|
93
|
+
return base;
|
|
94
|
+
}
|
|
95
|
+
/** Join an API path to a session base URL (origin only; strips any legacy `?token=`). */
|
|
96
|
+
function joinSessionApiUrl(base, path) {
|
|
97
|
+
return `${new URL(base).origin}${path.startsWith("/") ? path : `/${path}`}`;
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { loadSettings as a, reviewSessionUrl as i, joinSessionApiUrl as n, saveSettings as o, reviewSessionBaseUrl as r, appendSessionToken as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { s as getFileContent } from "./git-BGj31GX-.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { createServer } from "node:http";
|
|
4
4
|
//#region src/lib/tui-search-bridge.ts
|
|
@@ -26,7 +26,7 @@ async function readJson(request) {
|
|
|
26
26
|
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
27
27
|
}
|
|
28
28
|
async function runSearch(body) {
|
|
29
|
-
const { searchAll, searchContent, searchFiles, searchSymbols } = await import("./search-
|
|
29
|
+
const { searchAll, searchContent, searchFiles, searchSymbols } = await import("./search-CQ4nsjBX.mjs");
|
|
30
30
|
const scope = body.scope ?? "all";
|
|
31
31
|
const query = typeof body.query === "string" ? body.query : "";
|
|
32
32
|
const limit = typeof body.limit === "number" ? body.limit : void 0;
|
|
@@ -100,7 +100,7 @@ async function startTuiSearchBridge() {
|
|
|
100
100
|
if (request.method === "POST" && request.url === "/track") {
|
|
101
101
|
const body = await readJson(request);
|
|
102
102
|
if (typeof body.path === "string") {
|
|
103
|
-
const { trackSelection } = await import("./search-
|
|
103
|
+
const { trackSelection } = await import("./search-CQ4nsjBX.mjs");
|
|
104
104
|
await trackSelection(typeof body.query === "string" ? body.query : "", body.path);
|
|
105
105
|
}
|
|
106
106
|
sendJson(response, 200, { ok: true });
|
|
@@ -32,15 +32,18 @@ async function checkForUpdates(currentVersion) {
|
|
|
32
32
|
try {
|
|
33
33
|
const controller = new AbortController();
|
|
34
34
|
const id = setTimeout(() => controller.abort(), 1e3);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch("https://registry.npmjs.org/diffing/latest", { signal: controller.signal });
|
|
37
|
+
if (!res.ok) return null;
|
|
38
|
+
const data = await res.json();
|
|
39
|
+
if (!data.version) return null;
|
|
40
|
+
return {
|
|
41
|
+
hasUpdate: isNewerVersion(currentVersion, data.version),
|
|
42
|
+
latestVersion: data.version
|
|
43
|
+
};
|
|
44
|
+
} finally {
|
|
45
|
+
clearTimeout(id);
|
|
46
|
+
}
|
|
44
47
|
} catch {
|
|
45
48
|
return null;
|
|
46
49
|
}
|
|
@@ -106,10 +109,7 @@ async function runUpdateCommand() {
|
|
|
106
109
|
} catch {}
|
|
107
110
|
console.log(`Running: ${cmd} ${args.join(" ")}\n`);
|
|
108
111
|
const exitCode = await new Promise((res) => {
|
|
109
|
-
const child = spawn(cmd, args, {
|
|
110
|
-
stdio: "inherit",
|
|
111
|
-
shell: true
|
|
112
|
-
});
|
|
112
|
+
const child = spawn(cmd, args, { stdio: "inherit" });
|
|
113
113
|
child.on("close", (code) => {
|
|
114
114
|
res(code ?? 0);
|
|
115
115
|
});
|
|
@@ -120,8 +120,9 @@ async function runUpdateCommand() {
|
|
|
120
120
|
});
|
|
121
121
|
if (exitCode === 0) console.log(`\n\x1b[38;5;82mSuccessfully updated diffing to v${latest}!\x1b[0m\n`);
|
|
122
122
|
else {
|
|
123
|
-
console.error(`\n\x1b[38;5;196mFailed to update diffing.
|
|
124
|
-
console.error(`
|
|
123
|
+
console.error(`\n\x1b[38;5;196mFailed to update diffing. Install into your user prefix instead of using sudo:\x1b[0m`);
|
|
124
|
+
console.error(` npm config get prefix # e.g. ~/.npm-global or ~/.local`);
|
|
125
|
+
console.error(` ${cmd} ${args.join(" ")}\n`);
|
|
125
126
|
}
|
|
126
127
|
return exitCode;
|
|
127
128
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diffing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "local-first CLI for reviewing, navigating, and discussing git diffs with AI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
7
10
|
"packageManager": "pnpm@11.6.0",
|
|
8
11
|
"homepage": "https://github.com/ahmedragab20/diffing",
|
|
9
12
|
"repository": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{at as e,ot as t}from"./chunk-CSCIHK7Q-tcgA8jR0.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-9MKexpFu.js";var t=class{constructor(e){this.init=e,this.records=this.init()}static{e(this,`ImperativeState`)}reset(){this.records=this.init()}};export{t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e,p as t}from"./src-9MKexpFu.js";import{x as n}from"./chunk-CSCIHK7Q-tcgA8jR0.js";var r=e(e=>{let{securityLevel:r}=n(),i=t(`body`);return r===`sandbox`&&(i=t((t(`#i${e}`).node()?.contentDocument??document).body)),i.select(`#${e}`)},`selectSvgElement`);export{r as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-9MKexpFu.js";import"./chunk-CSCIHK7Q-tcgA8jR0.js";import"./chunk-5ZQYHXKU-DZ5cvCDV.js";import"./chunk-O5CBEL6O-CbNGK3Te.js";import"./chunk-FMBD7UC4-DlpmhBYg.js";import"./chunk-BSJP7CBP-CP_f908b.js";import"./chunk-L5ZTLDWV-BjVXSZnt.js";import"./chunk-ND2GUHAM-kWh41zUn.js";import"./chunk-55IACEB6-yXpL8wjV.js";import"./chunk-2J33WTMH-tvuzKhdK.js";import"./chunk-NZK2D7GU-CDrIi44_.js";import"./chunk-3OPIFGDE-D_nBoD9w.js";import"./chunk-KSCS5N6A-BkfieXpV.js";import"./chunk-LZXEDZCA-CaAWmy4Q.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-CJjgOWmY.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-9MKexpFu.js";import"./chunk-CSCIHK7Q-tcgA8jR0.js";import"./chunk-5ZQYHXKU-DZ5cvCDV.js";import"./chunk-O5CBEL6O-CbNGK3Te.js";import"./chunk-FMBD7UC4-DlpmhBYg.js";import"./chunk-BSJP7CBP-CP_f908b.js";import"./chunk-L5ZTLDWV-BjVXSZnt.js";import"./chunk-ND2GUHAM-kWh41zUn.js";import"./chunk-55IACEB6-yXpL8wjV.js";import"./chunk-2J33WTMH-tvuzKhdK.js";import"./chunk-NZK2D7GU-CDrIi44_.js";import"./chunk-3OPIFGDE-D_nBoD9w.js";import"./chunk-KSCS5N6A-BkfieXpV.js";import"./chunk-LZXEDZCA-CaAWmy4Q.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-CJjgOWmY.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-9MKexpFu.js";import"./chunk-CSCIHK7Q-tcgA8jR0.js";import"./chunk-5ZQYHXKU-DZ5cvCDV.js";import"./chunk-O5CBEL6O-CbNGK3Te.js";import"./chunk-BSJP7CBP-CP_f908b.js";import"./chunk-L5ZTLDWV-BjVXSZnt.js";import"./chunk-55IACEB6-yXpL8wjV.js";import"./chunk-2J33WTMH-tvuzKhdK.js";import"./chunk-NZK2D7GU-CDrIi44_.js";import"./chunk-3OPIFGDE-D_nBoD9w.js";import"./chunk-KSCS5N6A-BkfieXpV.js";import"./chunk-LZXEDZCA-CaAWmy4Q.js";import{i as t,n,r,t as i}from"./chunk-AQP2D5EJ-CQYQKXSE.js";var a={parser:n,get db(){return new i(2)},renderer:r,styles:t,init:e(e=>{e.state||={},e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
package/dist/git-DaP_1rVy.mjs
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
|
-
//#region src/lib/settings.ts
|
|
5
|
-
const CONFIG_DIR = join(homedir(), ".config", "diffing");
|
|
6
|
-
const SETTINGS_FILE = join(CONFIG_DIR, "settings.json");
|
|
7
|
-
const DEFAULTS = {
|
|
8
|
-
defaultMode: "web",
|
|
9
|
-
staged: true,
|
|
10
|
-
untracked: true,
|
|
11
|
-
diffStyle: "split",
|
|
12
|
-
defaultTabSize: 4,
|
|
13
|
-
theme: "rose-pine",
|
|
14
|
-
editorIDE: "default",
|
|
15
|
-
lineDiffType: "word",
|
|
16
|
-
lineWrap: false,
|
|
17
|
-
diffIndicators: "classic",
|
|
18
|
-
showLineNumbers: true,
|
|
19
|
-
hunkSeparators: "line-info",
|
|
20
|
-
lineHoverHighlight: "both",
|
|
21
|
-
fontSize: 13,
|
|
22
|
-
expandContextByDefault: false,
|
|
23
|
-
collapsedContextThreshold: 10,
|
|
24
|
-
expansionLineCount: 20,
|
|
25
|
-
haptics: true,
|
|
26
|
-
sounds: true,
|
|
27
|
-
uiFont: null,
|
|
28
|
-
monoFont: null,
|
|
29
|
-
density: "comfortable",
|
|
30
|
-
autoCollapseLineThreshold: 400,
|
|
31
|
-
requireViewAllBeforeSend: false,
|
|
32
|
-
showStatusBar: true,
|
|
33
|
-
savedReplies: [],
|
|
34
|
-
ignoreSpaceChange: false,
|
|
35
|
-
ignoreAllSpace: false
|
|
36
|
-
};
|
|
37
|
-
function loadSettings() {
|
|
38
|
-
try {
|
|
39
|
-
const data = readFileSync(SETTINGS_FILE, "utf-8");
|
|
40
|
-
const settings = {
|
|
41
|
-
...DEFAULTS,
|
|
42
|
-
...JSON.parse(data)
|
|
43
|
-
};
|
|
44
|
-
if (settings.defaultMode !== "web" && settings.defaultMode !== "tui") settings.defaultMode = DEFAULTS.defaultMode;
|
|
45
|
-
return settings;
|
|
46
|
-
} catch {
|
|
47
|
-
return { ...DEFAULTS };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function saveSettings(settings) {
|
|
51
|
-
const merged = {
|
|
52
|
-
...loadSettings(),
|
|
53
|
-
...settings
|
|
54
|
-
};
|
|
55
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
56
|
-
writeFileSync(SETTINGS_FILE, JSON.stringify(merged, null, 2));
|
|
57
|
-
return merged;
|
|
58
|
-
}
|
|
59
|
-
//#endregion
|
|
60
|
-
export { saveSettings as n, loadSettings as t };
|