diffing 0.16.0 → 0.17.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/dist/{cli-agent-Dk0yRtrA.mjs → cli-agent-qNwkSjxK.mjs} +22 -7
- package/dist/cli.mjs +3 -3
- package/dist/client/assets/{angular-html-JZN5kc0L.js → angular-html-ByeJB0rh.js} +1 -1
- package/dist/client/assets/{angular-ts-CJtfwtPm.js → angular-ts-CiwZGajG.js} +1 -1
- package/dist/client/assets/{apl-BW-LdBEV.js → apl-C8k5a5fk.js} +1 -1
- package/dist/client/assets/{arc-CxBp7uj_.js → arc-B8VMoqVr.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DWRcM6V_.js → architectureDiagram-3BPJPVTR-C-ng2xNL.js} +1 -1
- package/dist/client/assets/{astro-gYWZxO_0.js → astro-BE-h-qpp.js} +1 -1
- package/dist/client/assets/{blade-Dhwn6-nM.js → blade-D-0BV1wW.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-C5RclE5o.js → blockDiagram-GPEHLZMM-DyAQuONU.js} +1 -1
- package/dist/client/assets/{c-DStVJ8gV.js → c-Dg_Gx29H.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BGUA_e0K.js → c4Diagram-AAUBKEIU-k5uKTHvm.js} +1 -1
- package/dist/client/assets/channel-DsuXeLi4.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-B7n4bw-R.js → chunk-2J33WTMH-Dod_VwYj.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-w01g5zoV.js → chunk-3OPIFGDE-B8HMjry-.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-DxqZfswb.js → chunk-4BX2VUAB-TvkJVIZw.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CbDClk6A.js → chunk-55IACEB6-BsXuKAKc.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-CnsO6rSw.js → chunk-5ZQYHXKU-BI1cj2cZ.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-BtcRYmEV.js → chunk-727SXJPM-yWQ27Wk0.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CGhb3Sth.js → chunk-AQP2D5EJ-B2BBCtTr.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-DeuRDOb1.js → chunk-BSJP7CBP-CXXvPXhK.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-B9E4vQNj.js → chunk-CSCIHK7Q-jYiloqyi.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Bq9LG2aQ.js → chunk-FMBD7UC4-DZzqIT32.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BVlK-NC4.js → chunk-KSCS5N6A-krdCf8iG.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-DcdQquQQ.js → chunk-L5ZTLDWV-0uuTmeZV.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-D3hLMWf5.js → chunk-LZXEDZCA-BBfUgD06.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-0nxCj3q_.js → chunk-ND2GUHAM-jkir4ZKE.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-C_Wkgas6.js → chunk-NZK2D7GU-DMWZNibJ.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-BjWUWCBx.js → chunk-O5CBEL6O-B1e1HGaX.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-D5b3mBJ2.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-C1Pa4Y04.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-BoIL-UAf.js → chunk-XPW4576I-AvbCAUav.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DCnVfYt-.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BPa1Jkt-.js +1 -0
- package/dist/client/assets/{cobol-BhFBbthm.js → cobol-DQnGB_GV.js} +1 -1
- package/dist/client/assets/{coffee-CIJ9uq8T.js → coffee-CDV5a89x.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-CbiOjhru.js → cose-bilkent-S5V4N54A-t-mDNRF2.js} +1 -1
- package/dist/client/assets/{cpp-DtSSrq00.js → cpp-8G6b-siI.js} +1 -1
- package/dist/client/assets/{crystal-CukkuPMH.js → crystal-CGYCC6FM.js} +1 -1
- package/dist/client/assets/{css-B1khiVXh.js → css-nez4R8_Z.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DV-L1RXR.js → dagre-BM42HDAG--azesYIg.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BIS3Tcy4.js → diagram-2AECGRRQ-4WJ7nKhA.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BT7ScWHB.js → diagram-5GNKFQAL-C7ZGhLXn.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-DhEvzqhQ.js → diagram-KO2AKTUF-BobK_rbl.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DIh9QR2k.js → diagram-LMA3HP47-BOc-OkIS.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-V6xtTYuU.js → diagram-OG6HWLK6-BEtLgm86.js} +1 -1
- package/dist/client/assets/{dist--CAI-jgr.js → dist-DPuBwToc.js} +1 -1
- package/dist/client/assets/{edge-CuCj0fvA.js → edge-Z5RMbJQv.js} +1 -1
- package/dist/client/assets/{edit-BMeAI0Sj.js → edit-CFxbgVPV.js} +1 -1
- package/dist/client/assets/{elixir-CakheKmu.js → elixir-d3C79FQc.js} +1 -1
- package/dist/client/assets/{elm-C1NdUKtL.js → elm-CDAf6Uyn.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DLJ0CCH3.js → erDiagram-TEJ5UH35-D-pR2GY9.js} +1 -1
- package/dist/client/assets/{erb-CetH6rlA.js → erb-CTJk9FKH.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-aIYTauNq.js → flowDiagram-I6XJVG4X-BwMCy2QV.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DRQE_4dV.js → ganttDiagram-6RSMTGT7-BI1WLJDi.js} +1 -1
- package/dist/client/assets/{git-rebase-sKnthHnf.js → git-rebase-Dr0-MVoW.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DbSrYZsG.js → gitGraphDiagram-PVQCEYII-CUfW0k1f.js} +1 -1
- package/dist/client/assets/{glimmer-js-Bt7nvyGa.js → glimmer-js-CXhLhyW-.js} +1 -1
- package/dist/client/assets/{glimmer-ts-YO9zmz82.js → glimmer-ts-BFAFT-VD.js} +1 -1
- package/dist/client/assets/{glsl-DsvRozYb.js → glsl-D7yanhgY.js} +1 -1
- package/dist/client/assets/{graphql-sXzHf_gb.js → graphql-CpoDxrok.js} +1 -1
- package/dist/client/assets/{hack-C3UDBYU5.js → hack-BL5fmC4q.js} +1 -1
- package/dist/client/assets/{haml-Bfx2v9ts.js → haml-ClAE6RVM.js} +1 -1
- package/dist/client/assets/{handlebars-D7y9m08n.js → handlebars-nHw91uOv.js} +1 -1
- package/dist/client/assets/{html-LJt8Nrzd.js → html-BIiOKqgG.js} +1 -1
- package/dist/client/assets/{html-derivative-GRYtRNx6.js → html-derivative-D1nPnuOK.js} +1 -1
- package/dist/client/assets/{http-CFcGSNWA.js → http-B_QcRZjt.js} +1 -1
- package/dist/client/assets/{hurl-EaOExxlv.js → hurl-CZE0DsD3.js} +1 -1
- package/dist/client/assets/{index-DIOUI027.js → index-Erqhm7rW.js} +7 -7
- package/dist/client/assets/{infoDiagram-5YYISTIA-CT2k1ZKR.js → infoDiagram-5YYISTIA-w2M_OHua.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-D9ZWerXw.js → ishikawaDiagram-YF4QCWOH-CW_l9PGx.js} +1 -1
- package/dist/client/assets/{java-QdNEgqNn.js → java-CXTqX09w.js} +1 -1
- package/dist/client/assets/{javascript-C0TUIalv.js → javascript-9z9ABBep.js} +1 -1
- package/dist/client/assets/{jinja-CHXCs943.js → jinja-Cluf_5Bk.js} +1 -1
- package/dist/client/assets/{jison-Cu1JVrPL.js → jison-CqCEUtc4.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CS0prGm3.js → journeyDiagram-JHISSGLW-D-YwusBa.js} +1 -1
- package/dist/client/assets/{json-DbuC832p.js → json-BMq_bPP8.js} +1 -1
- package/dist/client/assets/{jsx-D2ojEfVP.js → jsx-Djij59b9.js} +1 -1
- package/dist/client/assets/{julia-DBG4gf9M.js → julia-DybzCMnh.js} +1 -1
- package/dist/client/assets/{just-cnG6iJYR.js → just-4ChcAr9-.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-B5_nyCCN.js → kanban-definition-UN3LZRKU-Brvoukmm.js} +1 -1
- package/dist/client/assets/{latex-C-t8YHXx.js → latex-CS2TtFXG.js} +1 -1
- package/dist/client/assets/{line-PhY2p9yO.js → line-CqxM-stA.js} +1 -1
- package/dist/client/assets/{linear-DZfj4bbh.js → linear-C7T82059.js} +1 -1
- package/dist/client/assets/{liquid-BXKFGxIR.js → liquid-84AtYenm.js} +1 -1
- package/dist/client/assets/{lua-BNuqYfRm.js → lua-DJzFx3Cf.js} +1 -1
- package/dist/client/assets/{marko-DSC8kwzM.js → marko-BLw9BV9E.js} +1 -1
- package/dist/client/assets/{mdc-BwB9Dj6D.js → mdc-BjZejN3b.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BrVg46EN.js → mermaid-parser.core-BdiEBAsd.js} +1 -1
- package/dist/client/assets/{mermaid.core-Bnf5T6PT.js → mermaid.core-BsnKhnrM.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-CAomoDK8.js → mindmap-definition-RKZ34NQL-CBaIFnbc.js} +1 -1
- package/dist/client/assets/{nginx-BrQvZxpD.js → nginx-DuamCwvX.js} +1 -1
- package/dist/client/assets/{nim-tVYcrqi1.js → nim-Bt8c9-ge.js} +1 -1
- package/dist/client/assets/{perl-B-60oGLc.js → perl-D52AfmwC.js} +1 -1
- package/dist/client/assets/{php-DJJABwVz.js → php-BBMlJg0_.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BOtZhQH4.js → pieDiagram-4H26LBE5-BlmPajcA.js} +1 -1
- package/dist/client/assets/{pug-KJGvmNqp.js → pug-DFHmDqEE.js} +1 -1
- package/dist/client/assets/{qml-6M7QCkVi.js → qml-C0333o-g.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Pcpz6-BU.js → quadrantDiagram-W4KKPZXB-Bqlm_zZk.js} +1 -1
- package/dist/client/assets/{r-CJX_7SfZ.js → r-DZFmvIgR.js} +1 -1
- package/dist/client/assets/{razor-DYZH4-tY.js → razor-BIGLkWzR.js} +1 -1
- package/dist/client/assets/{regexp-DWtQcg88.js → regexp-BW6jpgf9.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-Cruba0r2.js → requirementDiagram-4Y6WPE33-B1PrtUeD.js} +1 -1
- package/dist/client/assets/{review-export-DUMpiyN2.js → review-export-BlgD3bdw.js} +1 -1
- package/dist/client/assets/{rst-idvXY1TW.js → rst-Cj51ZJaa.js} +1 -1
- package/dist/client/assets/{ruby-CBUdU1Jx.js → ruby-lMhGjwpf.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DpLjNHX_.js → sankeyDiagram-5OEKKPKP-D2HtUNVF.js} +1 -1
- package/dist/client/assets/{sas-CD7-yPwf.js → sas-BWSQku7l.js} +1 -1
- package/dist/client/assets/{scss-CcmN3LNf.js → scss-CdRPuhLN.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Dxvk3OQI.js → sequenceDiagram-3UESZ5HK-D9SQy0XI.js} +1 -1
- package/dist/client/assets/{shellscript-BxkDFxdN.js → shellscript-DOfOBXcj.js} +1 -1
- package/dist/client/assets/{shellsession-Bz5EKpQO.js → shellsession-7XAOCVni.js} +1 -1
- package/dist/client/assets/{soy-DMVQQ2W2.js → soy-DDnzVRIw.js} +1 -1
- package/dist/client/assets/{sql-B-oK6O9W.js → sql-Ba34agKe.js} +1 -1
- package/dist/client/assets/{src-BNoZKBH3.js → src-BO-qT_v_.js} +1 -1
- package/dist/client/assets/{stata-CUZrRD4_.js → stata-BQlYGHQU.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-DcGkjwzF.js → stateDiagram-AJRCARHV-7IEYjFRo.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DP6swlL9.js +1 -0
- package/dist/client/assets/{surrealql-TyxgDynf.js → surrealql-BET1l7SW.js} +1 -1
- package/dist/client/assets/{svelte-nYNHcaCO.js → svelte-Bd7ZOeQI.js} +1 -1
- package/dist/client/assets/{templ-DfKxw_Rl.js → templ-BYvRQdOw.js} +1 -1
- package/dist/client/assets/{tex-CNwID2CI.js → tex-CT8DpKxX.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CluiloeV.js → timeline-definition-PNZ67QCA-CurQYWmi.js} +1 -1
- package/dist/client/assets/{ts-tags-DgUARkAi.js → ts-tags-D4iPPwau.js} +1 -1
- package/dist/client/assets/{tsx-2yb3iicd.js → tsx-Dgk_Aw-B.js} +1 -1
- package/dist/client/assets/{twig-l1ft8ReI.js → twig-abRNWeh3.js} +1 -1
- package/dist/client/assets/{typescript-BZqXFlL1.js → typescript-BgR1JqdC.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DHRoQg07.js → vennDiagram-CIIHVFJN-DbrRBL5S.js} +1 -1
- package/dist/client/assets/{vue-BgXkMZZj.js → vue-DSkhKq4Q.js} +1 -1
- package/dist/client/assets/{vue-html-Byxl7Gyw.js → vue-html-J0jWoD9X.js} +1 -1
- package/dist/client/assets/{vue-vine-Bzpp44S9.js → vue-vine-BgX5MC8-.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DQ_ujF1q.js → wardleyDiagram-YWT4CUSO-DIFXQsoP.js} +1 -1
- package/dist/client/assets/{xml-CpwLtzxK.js → xml-Ca53xGLB.js} +1 -1
- package/dist/client/assets/{xsl-VlCQyM4_.js → xsl-CNnXclYV.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DjG2u0Gz.js → xychartDiagram-2RQKCTM6-CmfInPqa.js} +1 -1
- package/dist/client/assets/{yaml-BypQObHK.js → yaml-CjjyUhfg.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/{mcp-C9HpAFs0.mjs → mcp-DhynPewa.mjs} +35 -19
- 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/{server-BmQqrWy4.mjs → server-CEbp7K-k.mjs} +289 -29
- package/extensions/pi/index.ts +283 -86
- package/extensions/pi/pi-modules.d.ts +70 -0
- package/extensions/pi/tsconfig.json +14 -0
- package/package.json +2 -1
- package/dist/client/assets/channel-BqKSU-HY.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-BE1tL2Nx.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-DP73Gify.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK--5lgckcu.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CCQu7EQ7.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DVv3yrP9.js +0 -1
|
@@ -1784,6 +1784,7 @@ function resolveEditorCommand(editor, absolutePath, platform = process.platform,
|
|
|
1784
1784
|
case "zed": return guiEditorCommand("zed", absolutePath, platform);
|
|
1785
1785
|
case "vim": return terminalEditorCommand("vim", absolutePath, platform, env);
|
|
1786
1786
|
case "neovim": return terminalEditorCommand("nvim", absolutePath, platform, env);
|
|
1787
|
+
case "ghostty": return ghosttyEditorCommand(absolutePath, platform);
|
|
1787
1788
|
default: return null;
|
|
1788
1789
|
}
|
|
1789
1790
|
}
|
|
@@ -1797,6 +1798,28 @@ function guiEditorCommand(bin, absolutePath, platform) {
|
|
|
1797
1798
|
args: [absolutePath]
|
|
1798
1799
|
};
|
|
1799
1800
|
}
|
|
1801
|
+
function ghosttyEditorCommand(absolutePath, platform) {
|
|
1802
|
+
if (platform === "darwin") return {
|
|
1803
|
+
cmd: "open",
|
|
1804
|
+
args: [
|
|
1805
|
+
"-na",
|
|
1806
|
+
"Ghostty",
|
|
1807
|
+
"--args",
|
|
1808
|
+
"-e",
|
|
1809
|
+
"nvim",
|
|
1810
|
+
absolutePath
|
|
1811
|
+
]
|
|
1812
|
+
};
|
|
1813
|
+
if (platform === "linux") return {
|
|
1814
|
+
cmd: "ghostty",
|
|
1815
|
+
args: [
|
|
1816
|
+
"-e",
|
|
1817
|
+
"nvim",
|
|
1818
|
+
absolutePath
|
|
1819
|
+
]
|
|
1820
|
+
};
|
|
1821
|
+
return null;
|
|
1822
|
+
}
|
|
1800
1823
|
function terminalEditorCommand(bin, absolutePath, platform, env) {
|
|
1801
1824
|
if (platform === "darwin") return {
|
|
1802
1825
|
cmd: "osascript",
|
|
@@ -2178,6 +2201,113 @@ var FilePrSessionStore = class {
|
|
|
2178
2201
|
} catch {}
|
|
2179
2202
|
}
|
|
2180
2203
|
};
|
|
2204
|
+
const PATH_MATCH_CAP = 20;
|
|
2205
|
+
function compilePathspecGlob(pattern) {
|
|
2206
|
+
const source = pattern.trim();
|
|
2207
|
+
if (!source) return {
|
|
2208
|
+
error: "invalid path glob: empty pattern",
|
|
2209
|
+
status: 400,
|
|
2210
|
+
path: pattern
|
|
2211
|
+
};
|
|
2212
|
+
try {
|
|
2213
|
+
return {
|
|
2214
|
+
source,
|
|
2215
|
+
test: compileGlobTester(source)
|
|
2216
|
+
};
|
|
2217
|
+
} catch (error) {
|
|
2218
|
+
return {
|
|
2219
|
+
error: error instanceof Error ? error.message : "invalid path glob",
|
|
2220
|
+
status: 400,
|
|
2221
|
+
path: pattern
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
function fileMatchesPath(matcher, oldPath, newPath) {
|
|
2226
|
+
if (newPath && matcher.test(newPath)) return true;
|
|
2227
|
+
if (oldPath && matcher.test(oldPath)) return true;
|
|
2228
|
+
return false;
|
|
2229
|
+
}
|
|
2230
|
+
function parseExcludeList(raw) {
|
|
2231
|
+
if (raw == null) return [];
|
|
2232
|
+
const values = (Array.isArray(raw) ? raw : raw.split(",")).map((value) => value.trim()).filter(Boolean);
|
|
2233
|
+
for (const value of values) if (value !== "lockfiles") return {
|
|
2234
|
+
error: `unknown exclude: ${value}`,
|
|
2235
|
+
status: 400
|
|
2236
|
+
};
|
|
2237
|
+
return [...new Set(values)];
|
|
2238
|
+
}
|
|
2239
|
+
function isLockfileNoise(path) {
|
|
2240
|
+
const base = path.split("/").pop() ?? path;
|
|
2241
|
+
if (base === "package-lock.json" || base === "pnpm-lock.yaml") return true;
|
|
2242
|
+
if (base.endsWith(".lock")) return true;
|
|
2243
|
+
if (base.endsWith(".min.js")) return true;
|
|
2244
|
+
return false;
|
|
2245
|
+
}
|
|
2246
|
+
function displayPath(oldPath, newPath) {
|
|
2247
|
+
return newPath ?? oldPath ?? "";
|
|
2248
|
+
}
|
|
2249
|
+
function capPathMatches(matches) {
|
|
2250
|
+
return matches.slice(0, PATH_MATCH_CAP);
|
|
2251
|
+
}
|
|
2252
|
+
function compileGlobTester(pattern) {
|
|
2253
|
+
const parts = (pattern.includes("/") ? pattern : `**/${pattern}`).split("/");
|
|
2254
|
+
for (const part of parts) {
|
|
2255
|
+
if (part !== "**" && part.includes("**")) throw new Error(`invalid path glob: ${pattern}`);
|
|
2256
|
+
validateGlobSegment(part, pattern);
|
|
2257
|
+
}
|
|
2258
|
+
return (path) => matchParts(parts, path.split("/"));
|
|
2259
|
+
}
|
|
2260
|
+
function matchParts(pat, path) {
|
|
2261
|
+
if (pat.length === 0) return path.length === 0;
|
|
2262
|
+
if (pat[0] === "**") return matchParts(pat.slice(1), path) || path.length > 0 && matchParts(pat, path.slice(1));
|
|
2263
|
+
if (path.length === 0) return false;
|
|
2264
|
+
return globSegment(pat[0], path[0]) && matchParts(pat.slice(1), path.slice(1));
|
|
2265
|
+
}
|
|
2266
|
+
function validateGlobSegment(segment, pattern) {
|
|
2267
|
+
for (let i = 0; i < segment.length; i++) {
|
|
2268
|
+
if (segment[i] === "[") {
|
|
2269
|
+
const close = segment.indexOf("]", i + 1);
|
|
2270
|
+
if (close < 0 || close === i + 1) throw new Error(`invalid path glob: ${pattern}`);
|
|
2271
|
+
i = close;
|
|
2272
|
+
continue;
|
|
2273
|
+
}
|
|
2274
|
+
if (segment[i] === "\\") {
|
|
2275
|
+
if (segment[i + 1] == null) throw new Error(`invalid path glob: ${pattern}`);
|
|
2276
|
+
i++;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
function globSegment(pattern, value) {
|
|
2281
|
+
return globChars([...pattern], [...value]);
|
|
2282
|
+
}
|
|
2283
|
+
function globChars(pattern, value) {
|
|
2284
|
+
if (pattern.length === 0) return value.length === 0;
|
|
2285
|
+
const [head, ...rest] = pattern;
|
|
2286
|
+
if (head === "*") return globChars(rest, value) || value.length > 0 && globChars(pattern, value.slice(1));
|
|
2287
|
+
if (head === "?") return value.length > 0 && globChars(rest, value.slice(1));
|
|
2288
|
+
if (head === "[") {
|
|
2289
|
+
const close = rest.indexOf("]");
|
|
2290
|
+
if (close < 0 || value.length === 0) return false;
|
|
2291
|
+
const classBody = rest.slice(0, close);
|
|
2292
|
+
const negated = classBody[0] === "!" || classBody[0] === "^";
|
|
2293
|
+
if (classMatches(negated ? classBody.slice(1) : classBody, value[0]) === negated) return false;
|
|
2294
|
+
return globChars(rest.slice(close + 1), value.slice(1));
|
|
2295
|
+
}
|
|
2296
|
+
if (head === "\\") return rest.length > 0 && value.length > 0 && rest[0] === value[0] && globChars(rest.slice(1), value.slice(1));
|
|
2297
|
+
return value.length > 0 && head === value[0] && globChars(rest, value.slice(1));
|
|
2298
|
+
}
|
|
2299
|
+
function classMatches(body, value) {
|
|
2300
|
+
for (let i = 0; i < body.length;) {
|
|
2301
|
+
if (i + 2 < body.length && body[i + 1] === "-") {
|
|
2302
|
+
if (body[i] <= value && value <= body[i + 2]) return true;
|
|
2303
|
+
i += 3;
|
|
2304
|
+
continue;
|
|
2305
|
+
}
|
|
2306
|
+
if (body[i] === value) return true;
|
|
2307
|
+
i++;
|
|
2308
|
+
}
|
|
2309
|
+
return false;
|
|
2310
|
+
}
|
|
2181
2311
|
//#endregion
|
|
2182
2312
|
//#region src/lib/agent-diff-index.ts
|
|
2183
2313
|
/**
|
|
@@ -2406,33 +2536,140 @@ function buildAgentDiffIndex(patch, generation = nextGeneration++) {
|
|
|
2406
2536
|
patchBytes
|
|
2407
2537
|
};
|
|
2408
2538
|
}
|
|
2409
|
-
|
|
2539
|
+
const DIRECTORY_CAP = 20;
|
|
2540
|
+
function indexSummary(index, excludeRaw) {
|
|
2541
|
+
const exclude = parseExcludeList(excludeRaw);
|
|
2542
|
+
if ("error" in exclude) return exclude;
|
|
2543
|
+
const counted = exclude.includes("lockfiles") ? index.files.filter((file) => !isLockfileNoise(displayPath(file.oldPath, file.newPath))) : index.files;
|
|
2410
2544
|
const changes = {};
|
|
2411
|
-
|
|
2412
|
-
|
|
2545
|
+
let hunks = 0;
|
|
2546
|
+
let rows = 0;
|
|
2547
|
+
let additions = 0;
|
|
2548
|
+
let deletions = 0;
|
|
2549
|
+
for (const file of counted) {
|
|
2550
|
+
changes[file.kind] = (changes[file.kind] ?? 0) + 1;
|
|
2551
|
+
hunks += file.hunks.length;
|
|
2552
|
+
rows += file.rowCount;
|
|
2553
|
+
additions += file.additions;
|
|
2554
|
+
deletions += file.deletions;
|
|
2555
|
+
}
|
|
2556
|
+
const summary = {
|
|
2413
2557
|
generation: index.generation,
|
|
2414
2558
|
complete: index.complete,
|
|
2415
|
-
files:
|
|
2416
|
-
hunks
|
|
2417
|
-
rows
|
|
2418
|
-
additions
|
|
2419
|
-
deletions
|
|
2559
|
+
files: counted.length,
|
|
2560
|
+
hunks,
|
|
2561
|
+
rows,
|
|
2562
|
+
additions,
|
|
2563
|
+
deletions,
|
|
2420
2564
|
patchBytes: index.patchBytes,
|
|
2421
2565
|
changes,
|
|
2566
|
+
directories: summarizeDirectories(counted),
|
|
2422
2567
|
next: [
|
|
2423
2568
|
"diff_files",
|
|
2424
2569
|
"diff_search",
|
|
2425
2570
|
"diff_slice"
|
|
2426
2571
|
]
|
|
2427
2572
|
};
|
|
2573
|
+
if (exclude.length > 0) summary.exclude = exclude;
|
|
2574
|
+
return summary;
|
|
2575
|
+
}
|
|
2576
|
+
function summarizeDirectories(files) {
|
|
2577
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
2578
|
+
for (const file of files) {
|
|
2579
|
+
const path = displayPath(file.oldPath, file.newPath);
|
|
2580
|
+
const slash = path.indexOf("/");
|
|
2581
|
+
const dir = slash < 0 ? "." : path.slice(0, slash);
|
|
2582
|
+
const bucket = buckets.get(dir) ?? {
|
|
2583
|
+
path: dir,
|
|
2584
|
+
files: 0,
|
|
2585
|
+
hunks: 0,
|
|
2586
|
+
additions: 0,
|
|
2587
|
+
deletions: 0
|
|
2588
|
+
};
|
|
2589
|
+
bucket.files += 1;
|
|
2590
|
+
bucket.hunks += file.hunks.length;
|
|
2591
|
+
bucket.additions += file.additions;
|
|
2592
|
+
bucket.deletions += file.deletions;
|
|
2593
|
+
buckets.set(dir, bucket);
|
|
2594
|
+
}
|
|
2595
|
+
const ranked = [...buckets.values()].sort((a, b) => {
|
|
2596
|
+
if (b.files !== a.files) return b.files - a.files;
|
|
2597
|
+
return b.additions + b.deletions - (a.additions + a.deletions);
|
|
2598
|
+
});
|
|
2599
|
+
if (ranked.length <= DIRECTORY_CAP) return ranked;
|
|
2600
|
+
const head = ranked.slice(0, DIRECTORY_CAP);
|
|
2601
|
+
const rest = ranked.slice(DIRECTORY_CAP);
|
|
2602
|
+
const other = {
|
|
2603
|
+
path: "+other",
|
|
2604
|
+
files: 0,
|
|
2605
|
+
hunks: 0,
|
|
2606
|
+
additions: 0,
|
|
2607
|
+
deletions: 0
|
|
2608
|
+
};
|
|
2609
|
+
for (const bucket of rest) {
|
|
2610
|
+
other.files += bucket.files;
|
|
2611
|
+
other.hunks += bucket.hunks;
|
|
2612
|
+
other.additions += bucket.additions;
|
|
2613
|
+
other.deletions += bucket.deletions;
|
|
2614
|
+
}
|
|
2615
|
+
head.push(other);
|
|
2616
|
+
return head;
|
|
2617
|
+
}
|
|
2618
|
+
function scopedFiles(index, path) {
|
|
2619
|
+
if (path == null || path === "") return { entries: index.files.map((file, i) => ({
|
|
2620
|
+
index: i,
|
|
2621
|
+
file
|
|
2622
|
+
})) };
|
|
2623
|
+
const matcher = compilePathspecGlob(path);
|
|
2624
|
+
if ("error" in matcher) return matcher;
|
|
2625
|
+
return {
|
|
2626
|
+
matcher,
|
|
2627
|
+
entries: index.files.flatMap((file, i) => fileMatchesPath(matcher, file.oldPath, file.newPath) ? [{
|
|
2628
|
+
index: i,
|
|
2629
|
+
file
|
|
2630
|
+
}] : [])
|
|
2631
|
+
};
|
|
2428
2632
|
}
|
|
2429
|
-
function
|
|
2633
|
+
function resolveInspectFile(index, file, path) {
|
|
2634
|
+
const hasFile = file != null;
|
|
2635
|
+
const hasPath = path != null && path !== "";
|
|
2636
|
+
if (hasFile && hasPath) return {
|
|
2637
|
+
error: "path and file are mutually exclusive",
|
|
2638
|
+
status: 400,
|
|
2639
|
+
path
|
|
2640
|
+
};
|
|
2641
|
+
if (!hasFile && !hasPath) return {
|
|
2642
|
+
error: "file or path is required",
|
|
2643
|
+
status: 400
|
|
2644
|
+
};
|
|
2645
|
+
if (hasFile) return { fileIndex: file };
|
|
2646
|
+
const scoped = scopedFiles(index, path);
|
|
2647
|
+
if ("error" in scoped) return scoped;
|
|
2648
|
+
if (scoped.entries.length === 0) return {
|
|
2649
|
+
error: "path matched no files",
|
|
2650
|
+
status: 404,
|
|
2651
|
+
path
|
|
2652
|
+
};
|
|
2653
|
+
if (scoped.entries.length > 1) return {
|
|
2654
|
+
error: "path matched multiple files; narrow the glob or pass file",
|
|
2655
|
+
status: 409,
|
|
2656
|
+
path,
|
|
2657
|
+
matches: capPathMatches(scoped.entries.map(({ index, file }) => ({
|
|
2658
|
+
index,
|
|
2659
|
+
path: displayPath(file.oldPath, file.newPath)
|
|
2660
|
+
})))
|
|
2661
|
+
};
|
|
2662
|
+
return { fileIndex: scoped.entries[0].index };
|
|
2663
|
+
}
|
|
2664
|
+
function indexFiles(index, cursor = 0, limit = 100, path) {
|
|
2665
|
+
const scoped = scopedFiles(index, path);
|
|
2666
|
+
if ("error" in scoped) return scoped;
|
|
2430
2667
|
const safeLimit = clamp(limit, 1, MAX_PAGE_LINES);
|
|
2431
2668
|
const start = Math.max(0, cursor);
|
|
2432
|
-
const end = Math.min(
|
|
2433
|
-
const files =
|
|
2434
|
-
index
|
|
2435
|
-
path: file.
|
|
2669
|
+
const end = Math.min(scoped.entries.length, start + safeLimit);
|
|
2670
|
+
const files = scoped.entries.slice(start, end).map(({ index, file }) => ({
|
|
2671
|
+
index,
|
|
2672
|
+
path: displayPath(file.oldPath, file.newPath),
|
|
2436
2673
|
oldPath: file.oldPath,
|
|
2437
2674
|
newPath: file.newPath,
|
|
2438
2675
|
kind: file.kind,
|
|
@@ -2442,13 +2679,16 @@ function indexFiles(index, cursor = 0, limit = 100) {
|
|
|
2442
2679
|
additions: file.additions,
|
|
2443
2680
|
deletions: file.deletions
|
|
2444
2681
|
}));
|
|
2445
|
-
|
|
2682
|
+
const page = {
|
|
2446
2683
|
generation: index.generation,
|
|
2447
2684
|
returned: files.length,
|
|
2448
2685
|
total: index.files.length,
|
|
2449
|
-
|
|
2686
|
+
matched: scoped.entries.length,
|
|
2687
|
+
nextCursor: end < scoped.entries.length ? end : null,
|
|
2450
2688
|
files
|
|
2451
2689
|
};
|
|
2690
|
+
if (path) page.path = path;
|
|
2691
|
+
return page;
|
|
2452
2692
|
}
|
|
2453
2693
|
function indexHunks(index, fileIndex, cursor = 0, limit = 100, generation) {
|
|
2454
2694
|
if (generation !== void 0 && generation !== index.generation) return {
|
|
@@ -2519,11 +2759,17 @@ function indexSlice(index, fileIndex, startRow = 0, maxLines = DEFAULT_SLICE_LIN
|
|
|
2519
2759
|
rows
|
|
2520
2760
|
};
|
|
2521
2761
|
}
|
|
2522
|
-
function indexSearch(index, query, fileStart = 0, rowStart = 0, limit = 100, maxBytes = DEFAULT_MAX_BYTES, generation) {
|
|
2762
|
+
function indexSearch(index, query, fileStart = 0, rowStart = 0, limit = 100, maxBytes = DEFAULT_MAX_BYTES, generation, path) {
|
|
2523
2763
|
if (generation !== void 0 && generation !== index.generation) return {
|
|
2524
2764
|
error: `stale generation ${generation}; current generation is ${index.generation}`,
|
|
2525
2765
|
status: 409
|
|
2526
2766
|
};
|
|
2767
|
+
let matcher;
|
|
2768
|
+
if (path) {
|
|
2769
|
+
const compiled = compilePathspecGlob(path);
|
|
2770
|
+
if ("error" in compiled) return compiled;
|
|
2771
|
+
matcher = compiled;
|
|
2772
|
+
}
|
|
2527
2773
|
const q = query.toLowerCase();
|
|
2528
2774
|
if (!q) return {
|
|
2529
2775
|
generation: index.generation,
|
|
@@ -2542,6 +2788,7 @@ function indexSearch(index, query, fileStart = 0, rowStart = 0, limit = 100, max
|
|
|
2542
2788
|
let nextRow = null;
|
|
2543
2789
|
outer: for (let fi = Math.max(0, fileStart); fi < index.files.length; fi++) {
|
|
2544
2790
|
const file = index.files[fi];
|
|
2791
|
+
if (matcher && !fileMatchesPath(matcher, file.oldPath, file.newPath)) continue;
|
|
2545
2792
|
const path = file.newPath ?? file.oldPath ?? "";
|
|
2546
2793
|
const pathMatch = path.toLowerCase().includes(q);
|
|
2547
2794
|
const rowBegin = fi === fileStart ? Math.max(0, rowStart) : 0;
|
|
@@ -3146,9 +3393,21 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3146
3393
|
const n = Number(value);
|
|
3147
3394
|
return Number.isFinite(n) && n >= 0 ? Math.trunc(n) : fallback;
|
|
3148
3395
|
}
|
|
3396
|
+
function optionalUInt(value) {
|
|
3397
|
+
if (value == null || value === "") return void 0;
|
|
3398
|
+
const n = Number(value);
|
|
3399
|
+
return Number.isFinite(n) && n >= 0 ? Math.trunc(n) : void 0;
|
|
3400
|
+
}
|
|
3401
|
+
function inspectError(c, result) {
|
|
3402
|
+
const body = { error: result.error };
|
|
3403
|
+
if (result.path != null) body.path = result.path;
|
|
3404
|
+
if (result.matches != null) body.matches = result.matches;
|
|
3405
|
+
return c.json(body, result.status);
|
|
3406
|
+
}
|
|
3149
3407
|
app.get("/api/diff/summary", async (c) => {
|
|
3150
3408
|
const patch = await resolveAgentPatch();
|
|
3151
|
-
const summary = indexSummary(agentDiffCache.getOrBuild(patch));
|
|
3409
|
+
const summary = indexSummary(agentDiffCache.getOrBuild(patch), c.req.query("exclude"));
|
|
3410
|
+
if ("status" in summary) return inspectError(c, summary);
|
|
3152
3411
|
if (!prMode) return c.json(summary);
|
|
3153
3412
|
const session = await prStore.get();
|
|
3154
3413
|
if (!session) return c.json(summary);
|
|
@@ -3166,32 +3425,33 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3166
3425
|
});
|
|
3167
3426
|
app.get("/api/diff/files", async (c) => {
|
|
3168
3427
|
const patch = await resolveAgentPatch();
|
|
3169
|
-
const
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
return c.json(indexFiles(index, cursor, limit));
|
|
3428
|
+
const result = indexFiles(agentDiffCache.getOrBuild(patch), parseUInt(c.req.query("cursor"), 0), parseUInt(c.req.query("limit"), 100), c.req.query("path"));
|
|
3429
|
+
if ("status" in result) return inspectError(c, result);
|
|
3430
|
+
return c.json(result);
|
|
3173
3431
|
});
|
|
3174
3432
|
app.get("/api/diff/hunks", async (c) => {
|
|
3175
3433
|
const patch = await resolveAgentPatch();
|
|
3176
3434
|
const index = agentDiffCache.getOrBuild(patch);
|
|
3177
|
-
const
|
|
3435
|
+
const resolved = resolveInspectFile(index, optionalUInt(c.req.query("file")), c.req.query("path"));
|
|
3436
|
+
if ("status" in resolved) return inspectError(c, resolved);
|
|
3178
3437
|
const cursor = parseUInt(c.req.query("cursor"), 0);
|
|
3179
3438
|
const limit = parseUInt(c.req.query("limit"), 100);
|
|
3180
3439
|
const generationRaw = c.req.query("generation");
|
|
3181
|
-
const result = indexHunks(index,
|
|
3182
|
-
if ("status" in result) return c
|
|
3440
|
+
const result = indexHunks(index, resolved.fileIndex, cursor, limit, generationRaw != null && generationRaw !== "" ? parseUInt(generationRaw, 0) : void 0);
|
|
3441
|
+
if ("status" in result) return inspectError(c, result);
|
|
3183
3442
|
return c.json(result);
|
|
3184
3443
|
});
|
|
3185
3444
|
app.get("/api/diff/slice", async (c) => {
|
|
3186
3445
|
const patch = await resolveAgentPatch();
|
|
3187
3446
|
const index = agentDiffCache.getOrBuild(patch);
|
|
3188
|
-
const
|
|
3447
|
+
const resolved = resolveInspectFile(index, optionalUInt(c.req.query("file")), c.req.query("path"));
|
|
3448
|
+
if ("status" in resolved) return inspectError(c, resolved);
|
|
3189
3449
|
const start = parseUInt(c.req.query("start"), 0);
|
|
3190
3450
|
const maxLines = parseUInt(c.req.query("maxLines"), 120);
|
|
3191
3451
|
const maxBytes = parseUInt(c.req.query("maxBytes"), 256 * 1024);
|
|
3192
3452
|
const generationRaw = c.req.query("generation");
|
|
3193
|
-
const result = indexSlice(index,
|
|
3194
|
-
if ("status" in result) return c
|
|
3453
|
+
const result = indexSlice(index, resolved.fileIndex, start, maxLines, maxBytes, generationRaw != null && generationRaw !== "" ? parseUInt(generationRaw, 0) : void 0);
|
|
3454
|
+
if ("status" in result) return inspectError(c, result);
|
|
3195
3455
|
return c.json(result);
|
|
3196
3456
|
});
|
|
3197
3457
|
app.get("/api/diff/search", async (c) => {
|
|
@@ -3203,8 +3463,8 @@ function createApp(clientDir, diffOptsInput = DEFAULTS, commentStore, planStore,
|
|
|
3203
3463
|
const limit = parseUInt(c.req.query("limit"), 100);
|
|
3204
3464
|
const maxBytes = parseUInt(c.req.query("maxBytes"), 256 * 1024);
|
|
3205
3465
|
const generationRaw = c.req.query("generation");
|
|
3206
|
-
const result = indexSearch(index, q, file, row, limit, maxBytes, generationRaw != null && generationRaw !== "" ? parseUInt(generationRaw, 0) : void 0);
|
|
3207
|
-
if ("status" in result) return c
|
|
3466
|
+
const result = indexSearch(index, q, file, row, limit, maxBytes, generationRaw != null && generationRaw !== "" ? parseUInt(generationRaw, 0) : void 0, c.req.query("path"));
|
|
3467
|
+
if ("status" in result) return inspectError(c, result);
|
|
3208
3468
|
return c.json(result);
|
|
3209
3469
|
});
|
|
3210
3470
|
const resolveFileVersion = async (path, version) => {
|