difit 4.0.5 → 4.0.6
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.ja.md +1 -0
- package/README.ko.md +1 -0
- package/README.md +1 -0
- package/README.zh.md +1 -0
- package/dist/cli/comment.d.ts +2 -0
- package/dist/cli/comment.js +91 -0
- package/dist/cli/comment.test.d.ts +1 -0
- package/dist/cli/comment.test.js +164 -0
- package/dist/cli/index.js +103 -12
- package/dist/cli/utils.d.ts +1 -0
- package/dist/cli/utils.js +7 -0
- package/dist/client/assets/{_baseFor-DKyA49xd.js → _baseFor-Dq1lbcoh.js} +1 -1
- package/dist/client/assets/{arc-COOp7iVe.js → arc-1g1LrDb3.js} +1 -1
- package/dist/client/assets/architecture-YZFGNWBL-MZfdAdY6.js +1 -0
- package/dist/client/assets/architectureDiagram-Q4EWVU46-D87-Rmwy.js +36 -0
- package/dist/client/assets/{blockDiagram-DXYQGD6D-CtNJnEWN.js → blockDiagram-DXYQGD6D-Cep-MIFv.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-BqG-1m6C.js → c4Diagram-AHTNJAMY-BQuH9Txx.js} +1 -1
- package/dist/client/assets/channel-CJqLEVLU.js +1 -0
- package/dist/client/assets/{chunk-2KRD3SAO-DqP2NJNd.js → chunk-2KRD3SAO-CpQQpmvx.js} +1 -1
- package/dist/client/assets/chunk-336JU56O-Ddk9EzgO.js +2 -0
- package/dist/client/assets/chunk-426QAEUC-2xhUznDE.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-BT78EnQ6.js → chunk-4BX2VUAB-Ca-N0Wd9.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-C4w_Bwzw.js → chunk-4TB4RGXK-ZTWP_Onw.js} +2 -2
- package/dist/client/assets/{chunk-55IACEB6-z3MQSTaj.js → chunk-55IACEB6-Dub40zHG.js} +1 -1
- package/dist/client/assets/{chunk-5FUZZQ4R-Chei69aj.js → chunk-5FUZZQ4R-Cgda0gtZ.js} +1 -1
- package/dist/client/assets/{chunk-5PVQY5BW-HgRiIs0X.js → chunk-5PVQY5BW-D8JPH_tm.js} +1 -1
- package/dist/client/assets/{chunk-67CJDMHE-B2q10-fp.js → chunk-67CJDMHE-U1KyLHzG.js} +1 -1
- package/dist/client/assets/{chunk-7N4EOEYR-DPgxysWq.js → chunk-7N4EOEYR-WzOy51nD.js} +1 -1
- package/dist/client/assets/{chunk-AA7GKIK3-BqmVmKLq.js → chunk-AA7GKIK3-DlWOj4lr.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-CaIgleFn.js → chunk-BSJP7CBP-CcZ0op08.js} +1 -1
- package/dist/client/assets/{chunk-CIAEETIT-ByD-tlNF.js → chunk-CIAEETIT-qVSphnw5.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-d3RUKKAj.js → chunk-EDXVE4YY-76SPH4sf.js} +1 -1
- package/dist/client/assets/{chunk-ENJZ2VHE-CNq5Qmg9.js → chunk-ENJZ2VHE-CKULNIzL.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DYfHJ6MV.js → chunk-FMBD7UC4-CvDPP3mb.js} +1 -1
- package/dist/client/assets/{chunk-FOC6F5B3-BRpSWlZj.js → chunk-FOC6F5B3-DceW0hWA.js} +1 -1
- package/dist/client/assets/{chunk-ICPOFSXX-B_MThwG6.js → chunk-ICPOFSXX-ChGBNZMk.js} +2 -2
- package/dist/client/assets/{chunk-K5T4RW27-DmamW1Ds.js → chunk-K5T4RW27-DBHdC4ln.js} +10 -10
- package/dist/client/assets/{chunk-KGLVRYIC-CRbg4c4z.js → chunk-KGLVRYIC-DRS7yiGQ.js} +1 -1
- package/dist/client/assets/{chunk-LIHQZDEY-CHQPSdB3.js → chunk-LIHQZDEY-KsE8dyJP.js} +1 -1
- package/dist/client/assets/{chunk-ORNJ4GCN-CIsQ4Zi4.js → chunk-ORNJ4GCN-Dnp4oHRD.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-Cxi0kdGg.js → chunk-OYMX7WX6-CciaotDu.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-BiVE5u_E.js +1 -0
- package/dist/client/assets/{chunk-U2HBQHQK-V_hneCfR.js → chunk-U2HBQHQK-nbp7CjBP.js} +1 -1
- package/dist/client/assets/{chunk-X2U36JSP-De4pvO-I.js → chunk-X2U36JSP-Chs85loT.js} +1 -1
- package/dist/client/assets/{chunk-XPW4576I-B_osXKp6.js → chunk-XPW4576I-VtI9b561.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-C_kqXssD.js → chunk-YZCP3GAM-sBsewSoO.js} +1 -1
- package/dist/client/assets/{chunk-ZZ45TVLE-B_xtlma5.js → chunk-ZZ45TVLE-TMgeW_px.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-CfyHazmg.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-D7Rb-bnu.js +1 -0
- package/dist/client/assets/clone-8xC1huEg.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-5TzM3w9g.js +1 -0
- package/dist/client/assets/{cytoscape.esm-DRReFUEO.js → cytoscape.esm-DdcHPZAZ.js} +2 -2
- package/dist/client/assets/{dagre-KV5264BT-BWYGReXF.js → dagre-KV5264BT-xvyFOxd3.js} +1 -1
- package/dist/client/assets/{dagre-DU-XBdcU.js → dagre-sb6WtN4K.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DpUUhvWz.js → diagram-5BDNPKRD-ChRpAe5p.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-BJoTrUAx.js → diagram-G4DWMVQ6-C_8BED4A.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-CAk1GW5g.js → diagram-MMDJMWI5-BMwXEou2.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-Cct6g7FA.js → diagram-TYMM5635-CeAkx82D.js} +1 -1
- package/dist/client/assets/{dist-61sCfOmN.js → dist-CwC9dd2Z.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-DHs2bXUj.js → erDiagram-SMLLAGMA-yGCTeXGt.js} +1 -1
- package/dist/client/assets/{flatten-mnWyE-RB.js → flatten-SRIRKgqP.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-DLu-6dfC.js → flowDiagram-DWJPFMVM-CugkvbmM.js} +1 -1
- package/dist/client/assets/ganttDiagram-T4ZO3ILL-BXnlBFgK.js +292 -0
- package/dist/client/assets/gitGraph-7Q5UKJZL-BeTWkPrd.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-Bc_rL3_k.js → gitGraphDiagram-UUTBAWPF-B61aCwwu.js} +1 -1
- package/dist/client/assets/{graphlib-BVMK0xYE.js → graphlib-BMWKz3zT.js} +1 -1
- package/dist/client/assets/index-D2Y8-unG.css +2 -0
- package/dist/client/assets/index-D9v_eYzS.js +79 -0
- package/dist/client/assets/info-OMHHGYJF-MUNR2tTt.js +1 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-Cf8u4jgP.js → infoDiagram-42DDH7IO-Bkh6nTL2.js} +1 -1
- package/dist/client/assets/{isEmpty-CiiIHfXR.js → isEmpty-CStpjy4G.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-7n7DvfEb.js → ishikawaDiagram-UXIWVN3A-D_fdVT6_.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-BMkeQqJb.js → journeyDiagram-VCZTEJTY-DkXVokNF.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-B8KkeZLS.js → kanban-definition-6JOO6SKY-y8qq7qvL.js} +1 -1
- package/dist/client/assets/{line-CVpcI6kj.js → line-B0LcTqNY.js} +1 -1
- package/dist/client/assets/{linear-DmhiOOKU.js → linear-CqIjr2qp.js} +1 -1
- package/dist/client/assets/mermaid-parser.core-Du6QzpZO.js +4 -0
- package/dist/client/assets/{mermaid.core-R7nXpPx-.js → mermaid.core-CZBu-oKJ.js} +3 -3
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-CwcHocMZ.js → mindmap-definition-QFDTVHPH-BJrRxSkM.js} +1 -1
- package/dist/client/assets/{ordinal-k--hYEme.js → ordinal-DIg8h6NI.js} +1 -1
- package/dist/client/assets/packet-4T2RLAQJ-Ci-Uu57s.js +1 -0
- package/dist/client/assets/pie-ZZUOXDRM-pm57XGIg.js +1 -0
- package/dist/client/assets/{pieDiagram-DEJITSTG-BVAn8Lmr.js → pieDiagram-DEJITSTG-Debmhc0u.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-C2XZ_zxa.js → quadrantDiagram-34T5L4WZ-SE3g2BC9.js} +1 -1
- package/dist/client/assets/radar-PYXPWWZC-CH-AuSDw.js +1 -0
- package/dist/client/assets/{reduce-BTlHjXna.js → reduce-CG4cgj93.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-CfO16pkI.js → requirementDiagram-MS252O5E-1mv41puC.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-D_4_234M.js → sankeyDiagram-XADWPNL6-CLjPRtOP.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-B-yHKMuK.js → sequenceDiagram-FGHM5R23-Cs-P3AtR.js} +1 -1
- package/dist/client/assets/src-5XpQHeIJ.js +1 -0
- package/dist/client/assets/{stateDiagram-FHFEXIEX-BeG2di4I.js → stateDiagram-FHFEXIEX-CmB1fohY.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-D6jsrR-f.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-DhtnMGcE.js → timeline-definition-GMOUNBTQ-BMUafJOI.js} +1 -1
- package/dist/client/assets/treeView-SZITEDCU-BGsVMAdJ.js +1 -0
- package/dist/client/assets/treemap-W4RFUUIX-DXnhegXy.js +1 -0
- package/dist/client/assets/{vennDiagram-DHZGUBPP-CBn69TcQ.js → vennDiagram-DHZGUBPP-CpZ1Qhjz.js} +1 -1
- package/dist/client/assets/wardley-RL74JXVD-COd5nWj-.js +1 -0
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-CEoSJmN1.js → wardleyDiagram-NUSXRM2D-C-zH0lsd.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-BZ_X9tkn.js → xychartDiagram-5P7HB3ND-SkLFuEHZ.js} +1 -1
- package/dist/client/index.html +2 -4
- package/dist/client/site-data/blobs/080c0e6/cHVibGljL3NpdGUtZGF0YS9vZy1pbWFnZS5wbmc.png +0 -0
- package/dist/client/site-data/blobs/55f23a1/bGFuZGluZy9wdWJsaWMvZGlmaXQvbG9nby5wbmc.png +0 -0
- package/dist/client/site-data/blobs/66ff7c6/cHVibGljL2xvZ28ucG5n.png +0 -0
- package/dist/client/site-data/blobs/e6977fe/cHVibGljL2xvZ28ucG5n.png +0 -0
- package/dist/client/site-data/og-image.png +0 -0
- package/dist/server/file-watcher.d.ts +2 -1
- package/dist/server/file-watcher.js +9 -3
- package/dist/server/git-diff.d.ts +5 -0
- package/dist/server/git-diff.js +65 -1
- package/dist/server/git-diff.test.js +50 -0
- package/dist/server/server.js +265 -68
- package/dist/server/server.test.js +228 -0
- package/dist/tui/App.js +0 -1
- package/dist/types/diff.d.ts +4 -4
- package/dist/types/watch.d.ts +30 -1
- package/dist/utils/commentImports.d.ts +2 -0
- package/dist/utils/commentImports.js +119 -1
- package/dist/utils/editorOptions.d.ts +58 -35
- package/dist/utils/editorOptions.js +150 -24
- package/dist/utils/editorOptions.test.js +201 -9
- package/package.json +7 -4
- package/dist/client/assets/architecture-YZFGNWBL-Cs2Q6RQP.js +0 -1
- package/dist/client/assets/architectureDiagram-Q4EWVU46-BO4dVPUA.js +0 -36
- package/dist/client/assets/channel-_xDT1u3-.js +0 -1
- package/dist/client/assets/chunk-336JU56O-D1qa7Qzb.js +0 -2
- package/dist/client/assets/chunk-426QAEUC-6J_A_wvD.js +0 -1
- package/dist/client/assets/chunk-CFjPhJqf.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-C0QzfgZ8.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-5XrS-DAQ.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-Covl2vKy.js +0 -1
- package/dist/client/assets/clone-rhRH8pyW.js +0 -1
- package/dist/client/assets/cose-bilkent-S5V4N54A-BvXFc7Rr.js +0 -1
- package/dist/client/assets/ganttDiagram-T4ZO3ILL-CMIzlKAR.js +0 -292
- package/dist/client/assets/gitGraph-7Q5UKJZL-A_wWsXju.js +0 -1
- package/dist/client/assets/index-BPoqJmrs.js +0 -79
- package/dist/client/assets/index-Cq_APK7Y.css +0 -2
- package/dist/client/assets/info-OMHHGYJF-Bv3kK2Bb.js +0 -1
- package/dist/client/assets/mermaid-parser.core-CnJ9Tv8l.js +0 -4
- package/dist/client/assets/packet-4T2RLAQJ-D2q3-9ae.js +0 -1
- package/dist/client/assets/pie-ZZUOXDRM-GivlQcUF.js +0 -1
- package/dist/client/assets/preload-helper-DSXbuxSR.js +0 -1
- package/dist/client/assets/radar-PYXPWWZC-C9pD6VNR.js +0 -1
- package/dist/client/assets/src-CjDs0_Ij.js +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DvcSq7KE.js +0 -1
- package/dist/client/assets/treeView-SZITEDCU-BSNk8_yV.js +0 -1
- package/dist/client/assets/treemap-W4RFUUIX-ym4zQztE.js +0 -1
- package/dist/client/assets/wardley-RL74JXVD-B02H6ReJ.js +0 -1
- /package/dist/client/assets/{array-BNor45A1.js → array-DOVTz2Mq.js} +0 -0
- /package/dist/client/assets/{defaultLocale-DPzUsThw.js → defaultLocale-Ck2Xxk-C.js} +0 -0
- /package/dist/client/assets/{init-C0L3woqb.js → init-Bft5Ffpj.js} +0 -0
- /package/dist/client/assets/{katex-FOM3xZj7.js → katex-CeIlAR55.js} +0 -0
- /package/dist/client/assets/{path-sMK4d_s9.js → path-DfRbCp9y.js} +0 -0
- /package/dist/client/assets/{prism-bash-iQBez6et.js → prism-bash-CPkZUJMA.js} +0 -0
- /package/dist/client/assets/{prism-clojure-CTkJ-FW_.js → prism-clojure-BpoF2XhX.js} +0 -0
- /package/dist/client/assets/{prism-csharp-DAAROvjt.js → prism-csharp-BEk8D1-3.js} +0 -0
- /package/dist/client/assets/{prism-dart-CMjMHaBW.js → prism-dart-ByLYrdQB.js} +0 -0
- /package/dist/client/assets/{prism-elixir-B9cwzXs0.js → prism-elixir-BZtyIEab.js} +0 -0
- /package/dist/client/assets/{prism-haskell-Vgx7BCAm.js → prism-haskell-NAsbeo3V.js} +0 -0
- /package/dist/client/assets/{prism-hcl-Du4YC80h.js → prism-hcl-crnGqmVp.js} +0 -0
- /package/dist/client/assets/{prism-java-CWuFbfVD.js → prism-java-BovStacA.js} +0 -0
- /package/dist/client/assets/{prism-markup-templating-h9TC-ifW.js → prism-markup-templating-Cl8NiLjy.js} +0 -0
- /package/dist/client/assets/{prism-nix-CqauNIYa.js → prism-nix-BS_cm_1n.js} +0 -0
- /package/dist/client/assets/{prism-perl-DhcRwJzx.js → prism-perl-DGLVMq5H.js} +0 -0
- /package/dist/client/assets/{prism-php-DcBIrISj.js → prism-php-BskSwJN8.js} +0 -0
- /package/dist/client/assets/{prism-protobuf-DuPg7Jbg.js → prism-protobuf-DfbIYpO7.js} +0 -0
- /package/dist/client/assets/{prism-ruby-lhDmuasn.js → prism-ruby-FBVh1PRE.js} +0 -0
- /package/dist/client/assets/{prism-scala-YlPat9I4.js → prism-scala--9AfMHPY.js} +0 -0
- /package/dist/client/assets/{prism-solidity-C3nR0EVH.js → prism-solidity-BgJNkj1z.js} +0 -0
- /package/dist/client/assets/{prism-sql-Cz-8DmQS.js → prism-sql-C9Czmpov.js} +0 -0
- /package/dist/client/assets/{prism-vim-C3oukvmk.js → prism-vim-CzUNf0WQ.js} +0 -0
- /package/dist/client/assets/{rough.esm-DeLgKbOI.js → rough.esm-Bbn_-PMU.js} +0 -0
package/dist/types/diff.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export interface ParsedDiff {
|
|
|
32
32
|
chunks: DiffChunk[];
|
|
33
33
|
}
|
|
34
34
|
export type DiffViewMode = 'split' | 'unified';
|
|
35
|
-
|
|
35
|
+
type LegacyDiffViewMode = 'side-by-side' | 'inline';
|
|
36
36
|
export type DiffSide = 'old' | 'new';
|
|
37
37
|
export type DiffLineRange = number | {
|
|
38
38
|
start: number;
|
|
@@ -168,11 +168,11 @@ export interface CommentThread {
|
|
|
168
168
|
codeContent?: string;
|
|
169
169
|
messages: DiffCommentMessage[];
|
|
170
170
|
}
|
|
171
|
-
|
|
171
|
+
interface RevisionOption {
|
|
172
172
|
value: string;
|
|
173
173
|
label: string;
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
interface BranchInfo {
|
|
176
176
|
name: string;
|
|
177
177
|
current: boolean;
|
|
178
178
|
}
|
|
@@ -199,7 +199,7 @@ export interface FileExpandedState {
|
|
|
199
199
|
oldTotalLines?: number;
|
|
200
200
|
newTotalLines?: number;
|
|
201
201
|
}
|
|
202
|
-
|
|
202
|
+
interface ExpandedRange {
|
|
203
203
|
chunkIndex: number;
|
|
204
204
|
direction: 'up' | 'down';
|
|
205
205
|
count: number;
|
package/dist/types/watch.d.ts
CHANGED
|
@@ -5,12 +5,41 @@ export declare enum DiffMode {
|
|
|
5
5
|
DOT = "dot",// HEAD vs working (all changes)
|
|
6
6
|
SPECIFIC = "specific"
|
|
7
7
|
}
|
|
8
|
+
type WatchChangeType = 'file' | 'commit' | 'staging';
|
|
9
|
+
interface ConnectedWatchEvent {
|
|
10
|
+
type: 'connected';
|
|
11
|
+
diffMode: DiffMode;
|
|
12
|
+
changeType: WatchChangeType;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
message?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ReloadWatchEvent {
|
|
17
|
+
type: 'reload';
|
|
18
|
+
diffMode: DiffMode;
|
|
19
|
+
changeType: WatchChangeType;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
}
|
|
23
|
+
interface ErrorWatchEvent {
|
|
24
|
+
type: 'error';
|
|
25
|
+
diffMode: DiffMode;
|
|
26
|
+
changeType: WatchChangeType;
|
|
27
|
+
timestamp: string;
|
|
28
|
+
message?: string;
|
|
29
|
+
}
|
|
30
|
+
interface CommentsChangedWatchEvent {
|
|
31
|
+
type: 'commentsChanged';
|
|
32
|
+
version: number;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
}
|
|
35
|
+
export type WatchEvent = ConnectedWatchEvent | ReloadWatchEvent | ErrorWatchEvent | CommentsChangedWatchEvent;
|
|
8
36
|
export interface ClientWatchState {
|
|
9
37
|
isWatchEnabled: boolean;
|
|
10
38
|
diffMode: DiffMode;
|
|
11
39
|
shouldReload: boolean;
|
|
12
40
|
isReloading: boolean;
|
|
13
41
|
lastChangeTime: Date | null;
|
|
14
|
-
lastChangeType:
|
|
42
|
+
lastChangeType: WatchChangeType | null;
|
|
15
43
|
connectionStatus: 'connected' | 'disconnected' | 'reconnecting';
|
|
16
44
|
}
|
|
45
|
+
export {};
|
|
@@ -3,7 +3,9 @@ interface MergeCommentImportsResult {
|
|
|
3
3
|
threads: DiffCommentThread[];
|
|
4
4
|
warnings: string[];
|
|
5
5
|
}
|
|
6
|
+
export declare function normalizeCommentImports(input: unknown): CommentImport[];
|
|
6
7
|
export declare function parseCommentImportValue(value: string): CommentImport[];
|
|
8
|
+
export declare function mergeCommentThreads(existingThreads: DiffCommentThread[], incomingThreads: DiffCommentThread[]): MergeCommentImportsResult;
|
|
7
9
|
export declare function serializeCommentImports(commentImports: CommentImport[]): string;
|
|
8
10
|
export declare function mergeCommentImports(existingThreads: DiffCommentThread[], commentImports: CommentImport[]): MergeCommentImportsResult;
|
|
9
11
|
export {};
|
|
@@ -105,7 +105,7 @@ function normalizeCommentImportEntry(value) {
|
|
|
105
105
|
};
|
|
106
106
|
return normalized;
|
|
107
107
|
}
|
|
108
|
-
function normalizeCommentImports(input) {
|
|
108
|
+
export function normalizeCommentImports(input) {
|
|
109
109
|
if (Array.isArray(input)) {
|
|
110
110
|
return input.map((entry) => normalizeCommentImportEntry(entry));
|
|
111
111
|
}
|
|
@@ -204,6 +204,124 @@ function createImportedReply(commentImport, now) {
|
|
|
204
204
|
updatedAt,
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
|
+
function cloneLineRange(line) {
|
|
208
|
+
if (typeof line === 'number') {
|
|
209
|
+
return line;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
start: line.start,
|
|
213
|
+
end: line.end,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function clonePosition(position) {
|
|
217
|
+
return {
|
|
218
|
+
side: position.side,
|
|
219
|
+
line: cloneLineRange(position.line),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function cloneCodeSnapshot(snapshot) {
|
|
223
|
+
if (!snapshot) {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
content: snapshot.content,
|
|
228
|
+
language: snapshot.language,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function cloneMessage(message) {
|
|
232
|
+
return {
|
|
233
|
+
id: message.id,
|
|
234
|
+
body: message.body,
|
|
235
|
+
author: message.author,
|
|
236
|
+
createdAt: message.createdAt,
|
|
237
|
+
updatedAt: message.updatedAt,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function cloneThread(thread) {
|
|
241
|
+
return {
|
|
242
|
+
id: thread.id,
|
|
243
|
+
filePath: thread.filePath,
|
|
244
|
+
createdAt: thread.createdAt,
|
|
245
|
+
updatedAt: thread.updatedAt,
|
|
246
|
+
position: clonePosition(thread.position),
|
|
247
|
+
codeSnapshot: cloneCodeSnapshot(thread.codeSnapshot),
|
|
248
|
+
messages: thread.messages.map(cloneMessage),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function messagesMatch(left, right) {
|
|
252
|
+
if (left.id === right.id) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
if (normalizeAuthor(left.author) !== normalizeAuthor(right.author)) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
return left.body === right.body && left.createdAt === right.createdAt;
|
|
259
|
+
}
|
|
260
|
+
function threadsMatch(left, right) {
|
|
261
|
+
if (left.id === right.id) {
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
if (left.filePath !== right.filePath || !positionsMatch(left.position, right.position)) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
const leftRoot = left.messages[0];
|
|
268
|
+
const rightRoot = right.messages[0];
|
|
269
|
+
if (!leftRoot || !rightRoot) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
return messagesMatch(leftRoot, rightRoot);
|
|
273
|
+
}
|
|
274
|
+
function sortReplies(left, right) {
|
|
275
|
+
const createdAtOrder = left.createdAt.localeCompare(right.createdAt);
|
|
276
|
+
if (createdAtOrder !== 0) {
|
|
277
|
+
return createdAtOrder;
|
|
278
|
+
}
|
|
279
|
+
return left.id.localeCompare(right.id);
|
|
280
|
+
}
|
|
281
|
+
function pickNewerMessage(existingMessage, incomingMessage) {
|
|
282
|
+
if (incomingMessage.updatedAt.localeCompare(existingMessage.updatedAt) >= 0) {
|
|
283
|
+
return cloneMessage(incomingMessage);
|
|
284
|
+
}
|
|
285
|
+
return cloneMessage(existingMessage);
|
|
286
|
+
}
|
|
287
|
+
function mergeThread(existingThread, incomingThread) {
|
|
288
|
+
const mergedMessages = existingThread.messages.map(cloneMessage);
|
|
289
|
+
for (const incomingMessage of incomingThread.messages) {
|
|
290
|
+
const matchIndex = mergedMessages.findIndex((message) => messagesMatch(message, incomingMessage));
|
|
291
|
+
if (matchIndex >= 0) {
|
|
292
|
+
mergedMessages[matchIndex] = pickNewerMessage(mergedMessages[matchIndex], incomingMessage);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
mergedMessages.push(cloneMessage(incomingMessage));
|
|
296
|
+
}
|
|
297
|
+
const [rootMessage, ...replyMessages] = mergedMessages;
|
|
298
|
+
const orderedMessages = rootMessage
|
|
299
|
+
? [rootMessage, ...replyMessages.sort(sortReplies)]
|
|
300
|
+
: replyMessages.sort(sortReplies);
|
|
301
|
+
const updatedAt = orderedMessages.reduce((latest, message) => maxIsoTimestamp(latest, message.updatedAt), maxIsoTimestamp(existingThread.updatedAt, incomingThread.updatedAt));
|
|
302
|
+
return {
|
|
303
|
+
...cloneThread(existingThread),
|
|
304
|
+
createdAt: existingThread.createdAt.localeCompare(incomingThread.createdAt) <= 0
|
|
305
|
+
? existingThread.createdAt
|
|
306
|
+
: incomingThread.createdAt,
|
|
307
|
+
updatedAt,
|
|
308
|
+
position: clonePosition(existingThread.position),
|
|
309
|
+
codeSnapshot: cloneCodeSnapshot(incomingThread.codeSnapshot ?? existingThread.codeSnapshot),
|
|
310
|
+
messages: orderedMessages,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
export function mergeCommentThreads(existingThreads, incomingThreads) {
|
|
314
|
+
const threads = existingThreads.map(cloneThread);
|
|
315
|
+
for (const incomingThread of incomingThreads) {
|
|
316
|
+
const existingIndex = threads.findIndex((thread) => threadsMatch(thread, incomingThread));
|
|
317
|
+
if (existingIndex < 0) {
|
|
318
|
+
threads.push(cloneThread(incomingThread));
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
threads[existingIndex] = mergeThread(threads[existingIndex], incomingThread);
|
|
322
|
+
}
|
|
323
|
+
return { threads, warnings: [] };
|
|
324
|
+
}
|
|
207
325
|
function serializeLineRange(line) {
|
|
208
326
|
if (typeof line === 'number') {
|
|
209
327
|
return line;
|
|
@@ -1,37 +1,60 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
readonly
|
|
4
|
-
readonly
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
readonly
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
readonly label: "Zed";
|
|
20
|
-
readonly protocol: "zed";
|
|
21
|
-
readonly cliCommand: "zed";
|
|
22
|
-
readonly cliArgs: readonly [];
|
|
23
|
-
readonly lineFormat: "path-suffix";
|
|
24
|
-
readonly aliases: readonly ["zed"];
|
|
25
|
-
}, {
|
|
26
|
-
readonly id: "none";
|
|
27
|
-
readonly label: "Hide “Open in editor” button";
|
|
28
|
-
readonly protocol: null;
|
|
29
|
-
readonly cliCommand: null;
|
|
30
|
-
readonly cliArgs: readonly [];
|
|
31
|
-
readonly lineFormat: "goto-flag";
|
|
32
|
-
readonly aliases: readonly ["none", "disabled", "off"];
|
|
33
|
-
}];
|
|
34
|
-
export type EditorOption = (typeof EDITOR_OPTIONS)[number];
|
|
35
|
-
export type EditorOptionId = EditorOption['id'];
|
|
1
|
+
export type EditorOptionId = 'vscode' | 'cursor' | 'zed' | 'textmate' | 'bbedit' | 'emacs' | 'macvim' | 'sublime' | 'nova' | 'custom' | 'none';
|
|
2
|
+
interface EditorOption {
|
|
3
|
+
readonly id: EditorOptionId;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
/**
|
|
6
|
+
* Executable to run. Empty string for the `custom` placeholder (filled in by
|
|
7
|
+
* the user) and for `none` (open-in-editor disabled).
|
|
8
|
+
*/
|
|
9
|
+
readonly command: string;
|
|
10
|
+
/**
|
|
11
|
+
* Whitespace-separated argument template. Supports the `%file` and `%line`
|
|
12
|
+
* placeholders. Parsed just before spawning so quoted segments survive:
|
|
13
|
+
* e.g. `'-l %line "%file"'`.
|
|
14
|
+
*/
|
|
15
|
+
readonly argsTemplate: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const CUSTOM_EDITOR_ID: EditorOptionId;
|
|
18
|
+
export declare const NONE_EDITOR_ID: EditorOptionId;
|
|
36
19
|
export declare const DEFAULT_EDITOR_ID: EditorOptionId;
|
|
20
|
+
export declare const EDITOR_OPTIONS: readonly [EditorOption, ...EditorOption[]];
|
|
21
|
+
export declare const DEFAULT_EDITOR_OPTION: EditorOption;
|
|
22
|
+
/**
|
|
23
|
+
* Case-insensitive lookup by id. Used mostly for the `DIFIT_EDITOR` / `EDITOR`
|
|
24
|
+
* environment-variable fallback on the server; the browser UI passes the full
|
|
25
|
+
* `{id, command, argsTemplate}` shape so it does not rely on this helper.
|
|
26
|
+
*/
|
|
37
27
|
export declare const resolveEditorOption: (input?: string) => EditorOption;
|
|
28
|
+
/**
|
|
29
|
+
* Tokenise a user-supplied arguments template string into individual CLI
|
|
30
|
+
* arguments. Supports single and double quoted segments so paths and flags
|
|
31
|
+
* containing spaces can be preserved.
|
|
32
|
+
*
|
|
33
|
+
* Inside double-quoted segments `\"` decodes to a literal `"` and `\\` to a
|
|
34
|
+
* literal `\`, mirroring common shell intuition. Other `\x` sequences pass
|
|
35
|
+
* through untouched so Lisp/regex fragments like `\s` or `\$` stay intact.
|
|
36
|
+
* Single-quoted segments are fully literal. The template is handed to
|
|
37
|
+
* `spawn` as argv directly – no shell is involved.
|
|
38
|
+
*/
|
|
39
|
+
export declare const parseEditorArgsTemplate: (template: string | undefined | null) => string[];
|
|
40
|
+
interface EditorSpawnSpec {
|
|
41
|
+
readonly command: string;
|
|
42
|
+
readonly args: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
interface BuildEditorSpawnSpecInput {
|
|
45
|
+
readonly command: string;
|
|
46
|
+
readonly argsTemplate: string;
|
|
47
|
+
readonly filePath: string;
|
|
48
|
+
readonly lineNumber: number | null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the final `{ command, args }` tuple to hand to `child_process.spawn`.
|
|
52
|
+
* Returns `null` when the command is empty so callers can surface a clear
|
|
53
|
+
* "not configured" error instead of spawning an empty process.
|
|
54
|
+
*
|
|
55
|
+
* `%file` and `%line` are substituted as-is inside each token, so composite
|
|
56
|
+
* tokens such as `"%file:%line"` become `"/abs/file.ts:42"`. When no line
|
|
57
|
+
* number is available the substitution falls back to `1`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const buildEditorSpawnSpec: (input: BuildEditorSpawnSpecInput) => EditorSpawnSpec | null;
|
|
60
|
+
export {};
|
|
@@ -1,45 +1,171 @@
|
|
|
1
|
+
export const CUSTOM_EDITOR_ID = 'custom';
|
|
2
|
+
export const NONE_EDITOR_ID = 'none';
|
|
3
|
+
export const DEFAULT_EDITOR_ID = 'vscode';
|
|
1
4
|
export const EDITOR_OPTIONS = [
|
|
2
5
|
{
|
|
3
6
|
id: 'vscode',
|
|
4
7
|
label: 'VS Code',
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
cliArgs: [],
|
|
8
|
-
lineFormat: 'goto-flag',
|
|
9
|
-
aliases: ['vscode', 'code'],
|
|
8
|
+
command: 'code',
|
|
9
|
+
argsTemplate: '-g %file:%line',
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
id: 'cursor',
|
|
13
13
|
label: 'Cursor',
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
cliArgs: [],
|
|
17
|
-
lineFormat: 'goto-flag',
|
|
18
|
-
aliases: ['cursor'],
|
|
14
|
+
command: 'cursor',
|
|
15
|
+
argsTemplate: '-g %file:%line',
|
|
19
16
|
},
|
|
20
17
|
{
|
|
21
18
|
id: 'zed',
|
|
22
19
|
label: 'Zed',
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
command: 'zed',
|
|
21
|
+
argsTemplate: '%file:%line',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'textmate',
|
|
25
|
+
label: 'TextMate',
|
|
26
|
+
command: 'mate',
|
|
27
|
+
argsTemplate: '-l %line %file',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'bbedit',
|
|
31
|
+
label: 'BBEdit',
|
|
32
|
+
command: 'bbedit',
|
|
33
|
+
argsTemplate: '+%line %file',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'emacs',
|
|
37
|
+
label: 'Emacs',
|
|
38
|
+
command: 'emacsclient',
|
|
39
|
+
argsTemplate: '--no-wait +%line %file',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'macvim',
|
|
43
|
+
label: 'MacVim',
|
|
44
|
+
command: 'mvim',
|
|
45
|
+
argsTemplate: '--remote-silent +%line %file',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'sublime',
|
|
49
|
+
label: 'Sublime Text',
|
|
50
|
+
command: 'subl',
|
|
51
|
+
argsTemplate: '%file:%line',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'nova',
|
|
55
|
+
label: 'Nova',
|
|
56
|
+
command: 'nova',
|
|
57
|
+
argsTemplate: 'open %file -l %line',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'custom',
|
|
61
|
+
label: 'Custom…',
|
|
62
|
+
command: '',
|
|
63
|
+
argsTemplate: '',
|
|
28
64
|
},
|
|
29
65
|
{
|
|
30
66
|
id: 'none',
|
|
31
67
|
label: 'Hide “Open in editor” button',
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
cliArgs: [],
|
|
35
|
-
lineFormat: 'goto-flag',
|
|
36
|
-
aliases: ['none', 'disabled', 'off'],
|
|
68
|
+
command: '',
|
|
69
|
+
argsTemplate: '',
|
|
37
70
|
},
|
|
38
71
|
];
|
|
39
|
-
export const
|
|
72
|
+
export const DEFAULT_EDITOR_OPTION = EDITOR_OPTIONS.find((option) => option.id === DEFAULT_EDITOR_ID) ?? EDITOR_OPTIONS[0];
|
|
73
|
+
/**
|
|
74
|
+
* Case-insensitive lookup by id. Used mostly for the `DIFIT_EDITOR` / `EDITOR`
|
|
75
|
+
* environment-variable fallback on the server; the browser UI passes the full
|
|
76
|
+
* `{id, command, argsTemplate}` shape so it does not rely on this helper.
|
|
77
|
+
*/
|
|
40
78
|
export const resolveEditorOption = (input) => {
|
|
41
79
|
const normalized = (input ?? DEFAULT_EDITOR_ID).toLowerCase();
|
|
42
|
-
const matched = EDITOR_OPTIONS.find((option) => option.id === normalized
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
const matched = EDITOR_OPTIONS.find((option) => option.id === normalized);
|
|
81
|
+
return matched ?? DEFAULT_EDITOR_OPTION;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Tokenise a user-supplied arguments template string into individual CLI
|
|
85
|
+
* arguments. Supports single and double quoted segments so paths and flags
|
|
86
|
+
* containing spaces can be preserved.
|
|
87
|
+
*
|
|
88
|
+
* Inside double-quoted segments `\"` decodes to a literal `"` and `\\` to a
|
|
89
|
+
* literal `\`, mirroring common shell intuition. Other `\x` sequences pass
|
|
90
|
+
* through untouched so Lisp/regex fragments like `\s` or `\$` stay intact.
|
|
91
|
+
* Single-quoted segments are fully literal. The template is handed to
|
|
92
|
+
* `spawn` as argv directly – no shell is involved.
|
|
93
|
+
*/
|
|
94
|
+
export const parseEditorArgsTemplate = (template) => {
|
|
95
|
+
const input = template ?? '';
|
|
96
|
+
const tokens = [];
|
|
97
|
+
const n = input.length;
|
|
98
|
+
let i = 0;
|
|
99
|
+
while (i < n) {
|
|
100
|
+
while (i < n && /\s/.test(input[i] ?? ''))
|
|
101
|
+
i++;
|
|
102
|
+
if (i >= n)
|
|
103
|
+
break;
|
|
104
|
+
let token = '';
|
|
105
|
+
let inQuote = null;
|
|
106
|
+
while (i < n) {
|
|
107
|
+
const ch = input[i];
|
|
108
|
+
if (ch === undefined)
|
|
109
|
+
break;
|
|
110
|
+
if (inQuote === '"') {
|
|
111
|
+
if (ch === '\\' && i + 1 < n) {
|
|
112
|
+
const next = input[i + 1];
|
|
113
|
+
if (next === '"' || next === '\\') {
|
|
114
|
+
token += next;
|
|
115
|
+
i += 2;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (ch === inQuote) {
|
|
120
|
+
inQuote = null;
|
|
121
|
+
i++;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
token += ch;
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (inQuote === "'") {
|
|
130
|
+
if (ch === inQuote) {
|
|
131
|
+
inQuote = null;
|
|
132
|
+
i++;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
token += ch;
|
|
136
|
+
i++;
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (ch === '"' || ch === "'") {
|
|
141
|
+
inQuote = ch;
|
|
142
|
+
i++;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (/\s/.test(ch))
|
|
146
|
+
break;
|
|
147
|
+
token += ch;
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
tokens.push(token);
|
|
151
|
+
}
|
|
152
|
+
return tokens;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Build the final `{ command, args }` tuple to hand to `child_process.spawn`.
|
|
156
|
+
* Returns `null` when the command is empty so callers can surface a clear
|
|
157
|
+
* "not configured" error instead of spawning an empty process.
|
|
158
|
+
*
|
|
159
|
+
* `%file` and `%line` are substituted as-is inside each token, so composite
|
|
160
|
+
* tokens such as `"%file:%line"` become `"/abs/file.ts:42"`. When no line
|
|
161
|
+
* number is available the substitution falls back to `1`.
|
|
162
|
+
*/
|
|
163
|
+
export const buildEditorSpawnSpec = (input) => {
|
|
164
|
+
const command = input.command.trim();
|
|
165
|
+
if (!command)
|
|
166
|
+
return null;
|
|
167
|
+
const tokens = parseEditorArgsTemplate(input.argsTemplate);
|
|
168
|
+
const lineValue = String(input.lineNumber ?? 1);
|
|
169
|
+
const args = tokens.map((piece) => piece.replaceAll('%file', input.filePath).replaceAll('%line', lineValue));
|
|
170
|
+
return { command, args };
|
|
45
171
|
};
|