diffing 0.10.5 → 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 +76 -41
- package/dist/{cli-agent-BJiATn11.mjs → cli-agent-CWsOHN-j.mjs} +198 -57
- package/dist/{cli-gh-_bkDCxhh.mjs → cli-gh-DI69gJGo.mjs} +27 -17
- package/dist/cli.mjs +189 -229
- package/dist/client/assets/{angular-html-CBcwKYDC.js → angular-html-PLPuQo0k.js} +1 -1
- package/dist/client/assets/{angular-ts-DRBYUaJA.js → angular-ts-CE02Ij4b.js} +1 -1
- package/dist/client/assets/{apl-BM0X8jeL.js → apl-CsuUKZoi.js} +1 -1
- package/dist/client/assets/{arc-DTkmmKl3.js → arc-CgL5kFe-.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Cw75ay7q.js → architectureDiagram-3BPJPVTR-DxZQWGnx.js} +1 -1
- package/dist/client/assets/{astro-DKTNkoRZ.js → astro-DkFc7sbz.js} +1 -1
- package/dist/client/assets/{blade-DaM7a9Zp.js → blade-BkY07kcC.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-DAzINMr_.js → blockDiagram-GPEHLZMM-D5a2KZV2.js} +1 -1
- package/dist/client/assets/{c-B3C0Or4o.js → c-T1BrPfJ6.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-C7SsS28g.js → c4Diagram-AAUBKEIU-mpMH4kFC.js} +1 -1
- package/dist/client/assets/channel-D3niKhl0.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-DHOUGWx8.js → chunk-2J33WTMH-vMtgRLFH.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-D8d2scLX.js → chunk-3OPIFGDE-Dx-FqyO2.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-BSC-E5yg.js → chunk-4BX2VUAB-CUrPd8Kv.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-27pC5pKn.js → chunk-55IACEB6-DHg3Nr8A.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-BM60x82y.js → chunk-5ZQYHXKU-CpDPvbGs.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-CHCF96vE.js → chunk-727SXJPM-3VOGMxwk.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-BoVsvmTa.js → chunk-AQP2D5EJ-4dbfbIS6.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-Iip4uSio.js → chunk-BSJP7CBP-Dfyn0Uwp.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-DuIWPyay.js → chunk-CSCIHK7Q-VTpSKo0F.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Du6rtd2k.js → chunk-FMBD7UC4-kXD1MyOL.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BBq105vI.js → chunk-KSCS5N6A-BrVoWOAb.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-0DmB5Qp8.js → chunk-L5ZTLDWV-wZEQDPsa.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CoRsjUfr.js → chunk-LZXEDZCA-D3i0B0eg.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-tX8cKEls.js → chunk-ND2GUHAM-hDVHT0bN.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-BoJGgPic.js → chunk-NZK2D7GU-jQUfhp9h.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-mlwCWs97.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-B5efww8M.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-De9QR_Td.js → cobol-8-qBLs-a.js} +1 -1
- package/dist/client/assets/{coffee-Ct_GvuHP.js → coffee-Bjz5lkyW.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-ATaJZGF7.js → cose-bilkent-S5V4N54A-BljJ0FSA.js} +1 -1
- package/dist/client/assets/{cpp-Dw52w9cj.js → cpp-5BVQCBXT.js} +1 -1
- package/dist/client/assets/{crystal-Dx8ADdsd.js → crystal-CCkY93GS.js} +1 -1
- package/dist/client/assets/{css-CZ13XvDU.js → css-BTM7Tp2a.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-aDltuYut.js → dagre-BM42HDAG-BSynd_2D.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-DGWnHVMJ.js → diagram-2AECGRRQ-K3E2CVdy.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-Dd7eZBKe.js → diagram-5GNKFQAL-BQHIrfKc.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-DWThXREf.js → diagram-KO2AKTUF-Bqs8sNN4.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CXR4Bjtc.js → diagram-LMA3HP47-C9K4bpQe.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-D4Cbf0nW.js → diagram-OG6HWLK6-DK6wIXY2.js} +1 -1
- package/dist/client/assets/{dist-CUDhrHNw.js → dist-1nkZYMRy.js} +1 -1
- package/dist/client/assets/{edge-CQCjdJKj.js → edge-DqN2FJce.js} +1 -1
- package/dist/client/assets/{elixir-bkjwPazA.js → elixir-BiAgRUFF.js} +1 -1
- package/dist/client/assets/{elm-CCweX5Cq.js → elm-N1IbY8sz.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-BmAyt7SU.js → erDiagram-TEJ5UH35-jsHCiP02.js} +1 -1
- package/dist/client/assets/{erb-D-Z-KBLp.js → erb-B-yYlWAZ.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-C6nIFUVc.js → flowDiagram-I6XJVG4X-DOB1dAWG.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DMlxThBf.js → ganttDiagram-6RSMTGT7-BYIewcY5.js} +1 -1
- package/dist/client/assets/{git-rebase-BdoFdenB.js → git-rebase-CVkPxOAF.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-JaIFkAIT.js → gitGraphDiagram-PVQCEYII-VNQzbpv2.js} +1 -1
- package/dist/client/assets/{glimmer-js-CZQrBJKq.js → glimmer-js-BmG1xm72.js} +1 -1
- package/dist/client/assets/{glimmer-ts-CBYW46D4.js → glimmer-ts-CvTgwZsg.js} +1 -1
- package/dist/client/assets/{glsl-wxixKkY_.js → glsl-DwjNNCbW.js} +1 -1
- package/dist/client/assets/{graphql-CqZ0Lo5a.js → graphql-BvgkyF8E.js} +1 -1
- package/dist/client/assets/{hack-rqWymQRV.js → hack-DH3188x2.js} +1 -1
- package/dist/client/assets/{haml-DFw_IoGM.js → haml-B0GTfMhX.js} +1 -1
- package/dist/client/assets/{handlebars-3VmTVMYt.js → handlebars-he7hLDd9.js} +1 -1
- package/dist/client/assets/{html-C0Li76jB.js → html-DIYgdTBq.js} +1 -1
- package/dist/client/assets/{html-derivative-CO-RQW8y.js → html-derivative-2s6MXlci.js} +1 -1
- package/dist/client/assets/{http-sPrZOeBY.js → http-COS23XJP.js} +1 -1
- package/dist/client/assets/{hurl-DUoPe4Lc.js → hurl-BlZPjeJt.js} +1 -1
- package/dist/client/assets/index-BrEVVQOB.js +4021 -0
- package/dist/client/assets/index-BsuX6HVI.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-B6AZ5SCV.js → infoDiagram-5YYISTIA-DQRqk24I.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CytMrpo8.js → ishikawaDiagram-YF4QCWOH-DU1rqrLx.js} +1 -1
- package/dist/client/assets/{java-Cj0G6QRg.js → java-BAa5w-Qd.js} +1 -1
- package/dist/client/assets/{javascript-d5SUuyWD.js → javascript-C9e02ssI.js} +1 -1
- package/dist/client/assets/{jinja-BTw9k0vO.js → jinja-Bx37xXwq.js} +1 -1
- package/dist/client/assets/{jison-9xSVvR1q.js → jison-m_DEf8Jo.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Bd4jZUYI.js → journeyDiagram-JHISSGLW-CoHlfevf.js} +1 -1
- package/dist/client/assets/{json-DjAt53ka.js → json-DtN5AWRW.js} +1 -1
- package/dist/client/assets/{jsx-BX5KmQ7d.js → jsx-BlPpu8bR.js} +1 -1
- package/dist/client/assets/{julia-CLLx1dHC.js → julia-BAOmCbHl.js} +1 -1
- package/dist/client/assets/{just-C0v80bKe.js → just-C_bvVjwE.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-Ds4pXHJa.js → kanban-definition-UN3LZRKU-BiqYI7_m.js} +1 -1
- package/dist/client/assets/{latex-DY-oQfwO.js → latex-81pMfNMt.js} +1 -1
- package/dist/client/assets/{line-BbSLfOl6.js → line-DCovs9My.js} +1 -1
- package/dist/client/assets/{linear-BMIZJAAR.js → linear-cJF5XHE7.js} +1 -1
- package/dist/client/assets/{liquid-DDHDgbZx.js → liquid-sKRTk6dT.js} +1 -1
- package/dist/client/assets/{lua-CXymerKS.js → lua-C1uZL4IF.js} +1 -1
- package/dist/client/assets/{marko-DoPFsptl.js → marko-BKEzP1CL.js} +1 -1
- package/dist/client/assets/{mdc-BxSmTphd.js → mdc-CLkfm94H.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-CcYSvN4q.js → mermaid-parser.core-CTsTbvb2.js} +1 -1
- package/dist/client/assets/{mermaid.core-COTNtqgQ.js → mermaid.core-D86HJEwL.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BTxraRzn.js → mindmap-definition-RKZ34NQL-CL3heUmL.js} +1 -1
- package/dist/client/assets/{nginx-Bma0jNOT.js → nginx-eDGm66pc.js} +1 -1
- package/dist/client/assets/{nim-DMBpjygU.js → nim-CoWZPv8-.js} +1 -1
- package/dist/client/assets/{perl-CrnrV-AJ.js → perl-MoMqtMVr.js} +1 -1
- package/dist/client/assets/{php-CDYxzX6t.js → php-DXXVMAtN.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DglRmzer.js → pieDiagram-4H26LBE5-CWV3TMu4.js} +1 -1
- package/dist/client/assets/{pug-DNewy3GU.js → pug-CPWaB94J.js} +1 -1
- package/dist/client/assets/{qml-COjcnZ-W.js → qml-lhvpx8vk.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-BjSmyES7.js → quadrantDiagram-W4KKPZXB-QV25BYos.js} +1 -1
- package/dist/client/assets/{r-CrCaMxLS.js → r-DYbUnmmK.js} +1 -1
- package/dist/client/assets/{razor-jeuOZIar.js → razor-DcyOLv96.js} +1 -1
- package/dist/client/assets/{regexp-DSHVUX08.js → regexp-BdY10jm0.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-B4f430jS.js → requirementDiagram-4Y6WPE33-BPMsmU6J.js} +1 -1
- package/dist/client/assets/{review-export-Cen1WEcX.js → review-export-CMwjJURs.js} +1 -1
- package/dist/client/assets/{rst-CIDgytzc.js → rst-6ShFOzgH.js} +1 -1
- package/dist/client/assets/{ruby-DtuseoNq.js → ruby-B04DeVbi.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-TQPPlxc6.js → sankeyDiagram-5OEKKPKP-DQJeroPp.js} +1 -1
- package/dist/client/assets/{sas-C72Theia.js → sas-Dj26ftNa.js} +1 -1
- package/dist/client/assets/{scss-ClECtwRk.js → scss-BOHpBkgl.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-D1tx07Wg.js → sequenceDiagram-3UESZ5HK-DdV0Y6Sz.js} +1 -1
- package/dist/client/assets/{shellscript-BCwBsi2k.js → shellscript-CpHwjRcU.js} +1 -1
- package/dist/client/assets/{shellsession-BrOddEl5.js → shellsession-BJAvf4GN.js} +1 -1
- package/dist/client/assets/{soy-Dcs0GWFW.js → soy-B67bZJnL.js} +1 -1
- package/dist/client/assets/{sql-BAjA7Gv7.js → sql-8MzOqSsK.js} +1 -1
- package/dist/client/assets/{src-CYYhkqTK.js → src-AaoRSmFl.js} +1 -1
- package/dist/client/assets/{stata-19ngQtzR.js → stata-aCME945h.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-BZRCEzb5.js → stateDiagram-AJRCARHV-CMD_Xj2M.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-vLl7D4ue.js +1 -0
- package/dist/client/assets/{surrealql-Ce2TBRjE.js → surrealql-B_V_HxAi.js} +1 -1
- package/dist/client/assets/{svelte-DQ_1eGZz.js → svelte-BcQvTlqz.js} +1 -1
- package/dist/client/assets/{templ-Cw2DDxWF.js → templ-DZCQ2blz.js} +1 -1
- package/dist/client/assets/{tex-myDSO2eP.js → tex-BfeQ5Wuu.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CP0OZhBT.js → timeline-definition-PNZ67QCA-CyIS7Zoe.js} +1 -1
- package/dist/client/assets/{ts-tags-rh39ZwVs.js → ts-tags-DVWE0E87.js} +1 -1
- package/dist/client/assets/{tsx-B0-26jrU.js → tsx-DdJ7Sfqf.js} +1 -1
- package/dist/client/assets/{twig-CgasHzPb.js → twig-_gVgaha5.js} +1 -1
- package/dist/client/assets/{typescript-Dq3T0c-m.js → typescript-Bj0_LzZV.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DHaKHj0j.js → vennDiagram-CIIHVFJN-C-J2kWyk.js} +1 -1
- package/dist/client/assets/{vue-CzFVh92-.js → vue-Dnt_GBRb.js} +1 -1
- package/dist/client/assets/{vue-html-Bv2uFkTH.js → vue-html-ClVA5__5.js} +1 -1
- package/dist/client/assets/{vue-vine-DzieBk9Y.js → vue-vine-BCcz4SVP.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Dky7jxlZ.js → wardleyDiagram-YWT4CUSO-Dzt4EPh8.js} +1 -1
- package/dist/client/assets/{xml-wcdHRHN8.js → xml-BYeUHEti.js} +1 -1
- package/dist/client/assets/{xsl-CXrwsLG9.js → xsl-Vsx0SZEV.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-BQ2hG60h.js → xychartDiagram-2RQKCTM6-BAWZKvwP.js} +1 -1
- package/dist/client/assets/{yaml-lO6lK6Xe.js → yaml-C6L1khMK.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/{completions-3UF8uzhx.mjs → completions-DvyV49HY.mjs} +22 -1
- package/dist/{doctor-BGYZNIYP.mjs → doctor-Bz9VHuBI.mjs} +7 -6
- package/dist/find-tui-binary-DVQADOSF.mjs +101 -0
- package/dist/{git-Czo96ymM.mjs → git-BGj31GX-.mjs} +71 -7
- package/dist/git-CfDSkUcE.mjs +2 -0
- package/dist/{github-DKT0lJXv.mjs → github-DXiEeHzk.mjs} +1 -1
- package/dist/{github-CEjtGd41.mjs → github-DpzqNrUh.mjs} +3 -3
- package/dist/{github-attachments-Cf17YWp4.mjs → github-attachments-DgOf7BhP.mjs} +2 -2
- package/dist/{mcp-Dq7J5QOP.mjs → mcp-zDVzU1vl.mjs} +42 -33
- 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/{review-export-BBDWvftT.mjs → review-export-B63eRAVa.mjs} +1 -1
- package/dist/{settings-bwe7yQ8U.mjs → search-3R2E5xxr.mjs} +133 -98
- package/dist/search-CQ4nsjBX.mjs +2 -0
- package/dist/{server-C9i4V36o.mjs → server-Dw3lkQ5q.mjs} +296 -110
- package/dist/server-lock-BNI8FKV1.mjs +427 -0
- package/dist/session-conflict-Bqt1M4Mp.mjs +96 -0
- package/dist/session-manager-BKSZQqDJ.mjs +159 -0
- package/dist/session-url-sr7lXXVc.mjs +100 -0
- package/dist/tui-search-bridge-BGgLCwMF.mjs +133 -0
- package/dist/{update-check-DUuHmPeZ.mjs → update-check-BUfh4Y6c.mjs} +16 -15
- package/package.json +9 -4
- package/dist/client/assets/channel-lsVHTuYR.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-AHUiTM0z.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-D41j4yxb.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-D1Eo3kly.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-bAMsbsfB.js +0 -1
- package/dist/client/assets/index-B42c0TyV.css +0 -1
- package/dist/client/assets/index-BN_-di_r.js +0 -3959
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Da-mGMA2.js +0 -1
- package/dist/find-tui-binary-CRpbYXLC.mjs +0 -52
- package/dist/git-DaP_1rVy.mjs +0 -2
- package/dist/server-lock-Dd_ss_Il.mjs +0 -153
- /package/dist/{apply-suggestion-DNNsC5gx.mjs → apply-suggestion-CHYnw68I.mjs} +0 -0
- /package/dist/{comment-format-B5AcGcR-.mjs → comment-format-B85NHZnG.mjs} +0 -0
- /package/dist/{diff-fingerprint-C8YO3TTE.mjs → diff-fingerprint-BgR0tu1o.mjs} +0 -0
- /package/dist/{handoff-DPoIyeWn.mjs → handoff-LAFtmnHf.mjs} +0 -0
- /package/dist/{plan-format-BQyx--mp.mjs → plan-format-BwJh5JSE.mjs} +0 -0
|
@@ -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 };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { s as getFileContent } from "./git-BGj31GX-.mjs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
//#region src/lib/tui-search-bridge.ts
|
|
5
|
+
const MAX_REQUEST_BYTES = 8 * 1024 * 1024;
|
|
6
|
+
const MAX_PREVIEW_BYTES = 2 * 1024 * 1024;
|
|
7
|
+
function sendJson(response, status, value) {
|
|
8
|
+
const body = JSON.stringify(value);
|
|
9
|
+
response.writeHead(status, {
|
|
10
|
+
"content-type": "application/json; charset=utf-8",
|
|
11
|
+
"content-length": Buffer.byteLength(body),
|
|
12
|
+
connection: "close"
|
|
13
|
+
});
|
|
14
|
+
response.end(body);
|
|
15
|
+
}
|
|
16
|
+
async function readJson(request) {
|
|
17
|
+
const chunks = [];
|
|
18
|
+
let size = 0;
|
|
19
|
+
for await (const chunk of request) {
|
|
20
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
21
|
+
size += buffer.length;
|
|
22
|
+
if (size > MAX_REQUEST_BYTES) throw new Error("request body is too large");
|
|
23
|
+
chunks.push(buffer);
|
|
24
|
+
}
|
|
25
|
+
if (chunks.length === 0) return {};
|
|
26
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
27
|
+
}
|
|
28
|
+
async function runSearch(body) {
|
|
29
|
+
const { searchAll, searchContent, searchFiles, searchSymbols } = await import("./search-CQ4nsjBX.mjs");
|
|
30
|
+
const scope = body.scope ?? "all";
|
|
31
|
+
const query = typeof body.query === "string" ? body.query : "";
|
|
32
|
+
const limit = typeof body.limit === "number" ? body.limit : void 0;
|
|
33
|
+
const paths = Array.isArray(body.changedPaths) ? body.changedPaths.filter((path) => typeof path === "string") : void 0;
|
|
34
|
+
if (scope === "text") return searchContent(query, {
|
|
35
|
+
limit,
|
|
36
|
+
regex: !!body.regex,
|
|
37
|
+
paths
|
|
38
|
+
});
|
|
39
|
+
if (scope === "symbols") return searchSymbols(query, {
|
|
40
|
+
limit,
|
|
41
|
+
paths
|
|
42
|
+
});
|
|
43
|
+
if (scope === "files") return searchFiles(query, {
|
|
44
|
+
limit,
|
|
45
|
+
paths
|
|
46
|
+
});
|
|
47
|
+
return searchAll(query, {
|
|
48
|
+
limit,
|
|
49
|
+
regex: !!body.regex,
|
|
50
|
+
paths
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function loadTuiPreview(body) {
|
|
54
|
+
if (typeof body.path !== "string" || !body.path) throw new Error("preview path is required");
|
|
55
|
+
const buffer = getFileContent(body.path, "new");
|
|
56
|
+
if (!buffer) return {
|
|
57
|
+
path: body.path,
|
|
58
|
+
content: "",
|
|
59
|
+
missing: true,
|
|
60
|
+
binary: false,
|
|
61
|
+
truncated: false
|
|
62
|
+
};
|
|
63
|
+
if (buffer.subarray(0, Math.min(buffer.length, 8192)).includes(0)) return {
|
|
64
|
+
path: body.path,
|
|
65
|
+
content: "",
|
|
66
|
+
missing: false,
|
|
67
|
+
binary: true,
|
|
68
|
+
truncated: false
|
|
69
|
+
};
|
|
70
|
+
const truncated = buffer.length > MAX_PREVIEW_BYTES;
|
|
71
|
+
return {
|
|
72
|
+
path: body.path,
|
|
73
|
+
content: buffer.subarray(0, MAX_PREVIEW_BYTES).toString("utf8"),
|
|
74
|
+
missing: false,
|
|
75
|
+
binary: false,
|
|
76
|
+
truncated
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Exposes the web UI's long-lived fff search engine to the native TUI without
|
|
81
|
+
* duplicating its native binding or its frecency database. The bridge is
|
|
82
|
+
* loopback-only and protected by a per-process capability.
|
|
83
|
+
*/
|
|
84
|
+
async function startTuiSearchBridge() {
|
|
85
|
+
const capability = randomUUID();
|
|
86
|
+
const server = createServer(async (request, response) => {
|
|
87
|
+
if (request.headers["x-diffing-capability"] !== capability) {
|
|
88
|
+
sendJson(response, 401, { error: "invalid TUI search capability" });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
if (request.method === "POST" && request.url === "/search") {
|
|
93
|
+
sendJson(response, 200, await runSearch(await readJson(request)));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (request.method === "POST" && request.url === "/preview") {
|
|
97
|
+
sendJson(response, 200, loadTuiPreview(await readJson(request)));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (request.method === "POST" && request.url === "/track") {
|
|
101
|
+
const body = await readJson(request);
|
|
102
|
+
if (typeof body.path === "string") {
|
|
103
|
+
const { trackSelection } = await import("./search-CQ4nsjBX.mjs");
|
|
104
|
+
await trackSelection(typeof body.query === "string" ? body.query : "", body.path);
|
|
105
|
+
}
|
|
106
|
+
sendJson(response, 200, { ok: true });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
sendJson(response, 404, { error: "not found" });
|
|
110
|
+
} catch (error) {
|
|
111
|
+
sendJson(response, 500, { error: error?.message ?? "TUI search failed" });
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
await new Promise((resolveP, reject) => {
|
|
115
|
+
server.once("error", reject);
|
|
116
|
+
server.listen(0, "127.0.0.1", () => {
|
|
117
|
+
server.off("error", reject);
|
|
118
|
+
resolveP();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
const address = server.address();
|
|
122
|
+
if (!address || typeof address === "string") {
|
|
123
|
+
server.close();
|
|
124
|
+
throw new Error("could not resolve TUI search bridge address");
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
endpoint: `http://127.0.0.1:${address.port}`,
|
|
128
|
+
capability,
|
|
129
|
+
close: () => new Promise((resolveP) => server.close(() => resolveP()))
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { startTuiSearchBridge };
|
|
@@ -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": {
|
|
@@ -26,10 +29,11 @@
|
|
|
26
29
|
"dist"
|
|
27
30
|
],
|
|
28
31
|
"scripts": {
|
|
29
|
-
"build": "
|
|
32
|
+
"build": "pnpm run build:ts && pnpm run build:tui && pnpm run bundle:tui",
|
|
30
33
|
"build:ts": "tsdown && vite build",
|
|
31
34
|
"build:tui": "cargo build --release --manifest-path crates/diffing-tui/Cargo.toml",
|
|
32
35
|
"build:tui:debug": "cargo build --manifest-path crates/diffing-tui/Cargo.toml",
|
|
36
|
+
"bundle:tui": "node scripts/stage-tui-binary.mjs",
|
|
33
37
|
"changeset": "changeset",
|
|
34
38
|
"dev:client": "vite",
|
|
35
39
|
"dev:server": "tsx src/cli.ts --no-open --port 3433",
|
|
@@ -38,8 +42,9 @@
|
|
|
38
42
|
"test:ts": "vitest run",
|
|
39
43
|
"test:tui": "cargo test --manifest-path crates/diffing-tui/Cargo.toml",
|
|
40
44
|
"test:watch": "vitest",
|
|
41
|
-
"
|
|
42
|
-
"release": "
|
|
45
|
+
"verify:tui-bundle": "vitest run src/__tests__/native-bundle.test.ts src/__tests__/find-tui-binary.test.ts",
|
|
46
|
+
"verify:release-bundle": "node scripts/verify-tui-bundle.mjs",
|
|
47
|
+
"prepublishOnly": "pnpm run verify:release-bundle",
|
|
43
48
|
"version-packages": "changeset version"
|
|
44
49
|
},
|
|
45
50
|
"dependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{at as e,ot as t}from"./chunk-CSCIHK7Q-DuIWPyay.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-CYYhkqTK.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-CYYhkqTK.js";import{x as n}from"./chunk-CSCIHK7Q-DuIWPyay.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-CYYhkqTK.js";import"./chunk-CSCIHK7Q-DuIWPyay.js";import"./chunk-5ZQYHXKU-BM60x82y.js";import"./chunk-O5CBEL6O-mlwCWs97.js";import"./chunk-FMBD7UC4-Du6rtd2k.js";import"./chunk-BSJP7CBP-Iip4uSio.js";import"./chunk-L5ZTLDWV-0DmB5Qp8.js";import"./chunk-ND2GUHAM-tX8cKEls.js";import"./chunk-55IACEB6-27pC5pKn.js";import"./chunk-2J33WTMH-DHOUGWx8.js";import"./chunk-NZK2D7GU-BoJGgPic.js";import"./chunk-3OPIFGDE-D8d2scLX.js";import"./chunk-KSCS5N6A-BBq105vI.js";import"./chunk-LZXEDZCA-CoRsjUfr.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-CHCF96vE.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-CYYhkqTK.js";import"./chunk-CSCIHK7Q-DuIWPyay.js";import"./chunk-5ZQYHXKU-BM60x82y.js";import"./chunk-O5CBEL6O-mlwCWs97.js";import"./chunk-FMBD7UC4-Du6rtd2k.js";import"./chunk-BSJP7CBP-Iip4uSio.js";import"./chunk-L5ZTLDWV-0DmB5Qp8.js";import"./chunk-ND2GUHAM-tX8cKEls.js";import"./chunk-55IACEB6-27pC5pKn.js";import"./chunk-2J33WTMH-DHOUGWx8.js";import"./chunk-NZK2D7GU-BoJGgPic.js";import"./chunk-3OPIFGDE-D8d2scLX.js";import"./chunk-KSCS5N6A-BBq105vI.js";import"./chunk-LZXEDZCA-CoRsjUfr.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-CHCF96vE.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};
|