difit 1.1.1 ā 1.1.3
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 +1 -2
- package/dist/cli/index.js +15 -2
- package/dist/cli/utils.d.ts +1 -0
- package/dist/cli/utils.js +3 -0
- package/dist/client/assets/index-BKXkeB0O.css +1 -0
- package/dist/client/assets/index-Blx_E2fr.js +187 -0
- package/dist/client/assets/prism-java-BWsdaGwD.js +1 -0
- package/dist/client/assets/prism-php-Cv8baymX.js +1 -0
- package/dist/client/assets/prism-ruby-X0-wafPq.js +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/git-diff-tui.js +10 -3
- package/dist/server/git-diff.js +3 -2
- package/dist/server/server.js +57 -3
- package/package.json +25 -25
- package/dist/client/assets/index-B67TY4_1.js +0 -178
- package/dist/client/assets/index-BHrhjAlZ.css +0 -1
- package/dist/client/assets/prism-java-Bz0cy7o8.js +0 -1
- package/dist/client/assets/prism-php-Y_bwvUTe.js +0 -1
- package/dist/client/assets/prism-ruby-pgU1Zfy6.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as u}from"./index-Blx_E2fr.js";function p(t,a){for(var r=0;r<a.length;r++){const e=a[r];if(typeof e!="string"&&!Array.isArray(e)){for(const s in e)if(s!=="default"&&!(s in t)){const n=Object.getOwnPropertyDescriptor(e,s);n&&Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:()=>e[s]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var o={},i;function d(){return i||(i=1,function(t){var a=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,r=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,e={pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};t.languages.java=t.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[e,{pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:e.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+r+/[A-Z]\w*\b/.source),lookbehind:!0,inside:e.inside}],keyword:a,function:[t.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),t.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),t.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":e,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+r+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:e.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+r+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:e.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(/<keyword>/g,function(){return a.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)),o}var c=d();const l=u(c),w=p({__proto__:null,default:l},[c]);export{w as p};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as c}from"./index-Blx_E2fr.js";function f(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const a in t)if(a!=="default"&&!(a in e)){const i=Object.getOwnPropertyDescriptor(t,a);i&&Object.defineProperty(e,a,i.get?i:{enumerable:!0,get:()=>t[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var u={},d;function g(){return d||(d=1,function(e){var r=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],t=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,a=/<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,i=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:r,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:t,operator:a,punctuation:i};var l={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:r,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:t,operator:a,punctuation:i}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",function(s){if(/<\?/.test(s.code)){var p=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;e.languages["markup-templating"].buildPlaceholders(s,"php",p)}}),e.hooks.add("after-tokenize",function(s){e.languages["markup-templating"].tokenizePlaceholders(s,"php")})}(Prism)),u}var b=g();const y=c(b),m=f({__proto__:null,default:y},[b]);export{m as p};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g as l}from"./index-Blx_E2fr.js";function d(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const i in t)if(i!=="default"&&!(i in e)){const s=Object.getOwnPropertyDescriptor(t,i);s&&Object.defineProperty(e,i,s.get?s:{enumerable:!0,get:()=>t[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var a={},o;function g(){return o||(o=1,function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var r={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",t=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+t),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+t+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism)),a}var u=g();const p=l(u),b=d({__proto__:null,default:p},[u]);export{b as p};
|
package/dist/client/index.html
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
<link rel="icon" type="image/png" sizes="512x512" href="/icon-512x512.png" />
|
|
11
11
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
12
12
|
<title>ReviewIt - Git Diff Viewer</title>
|
|
13
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/assets/index-Blx_E2fr.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BKXkeB0O.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import simpleGit from 'simple-git';
|
|
2
|
-
import { validateDiffArguments } from '../cli/utils.js';
|
|
2
|
+
import { validateDiffArguments, createCommitRangeString } from '../cli/utils.js';
|
|
3
3
|
export async function loadGitDiff(targetCommitish, baseCommitish) {
|
|
4
4
|
// Validate arguments
|
|
5
5
|
const validation = validateDiffArguments(targetCommitish, baseCommitish);
|
|
@@ -23,7 +23,10 @@ export async function loadGitDiff(targetCommitish, baseCommitish) {
|
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
25
|
// Both are regular commits: standard commit-to-commit comparison
|
|
26
|
-
diff = await git.diff([
|
|
26
|
+
diff = await git.diff([
|
|
27
|
+
createCommitRangeString(baseCommitish, targetCommitish),
|
|
28
|
+
'--name-status',
|
|
29
|
+
]);
|
|
27
30
|
if (!diff.trim()) {
|
|
28
31
|
// Try without parent (for initial commit)
|
|
29
32
|
const diffInitial = await git.diff([targetCommitish, '--name-status']);
|
|
@@ -60,7 +63,11 @@ export async function loadGitDiff(targetCommitish, baseCommitish) {
|
|
|
60
63
|
else {
|
|
61
64
|
try {
|
|
62
65
|
// Both are regular commits: standard commit-to-commit comparison
|
|
63
|
-
fileDiff = await git.diff([
|
|
66
|
+
fileDiff = await git.diff([
|
|
67
|
+
createCommitRangeString(baseCommitish, targetCommitish),
|
|
68
|
+
'--',
|
|
69
|
+
path,
|
|
70
|
+
]);
|
|
64
71
|
}
|
|
65
72
|
catch {
|
|
66
73
|
// For new files or if parent doesn't exist
|
package/dist/server/git-diff.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { simpleGit } from 'simple-git';
|
|
2
|
-
import { validateDiffArguments, shortHash } from '../cli/utils.js';
|
|
2
|
+
import { validateDiffArguments, shortHash, createCommitRangeString } from '../cli/utils.js';
|
|
3
3
|
export class GitDiffParser {
|
|
4
|
+
git;
|
|
4
5
|
constructor(repoPath = process.cwd()) {
|
|
5
6
|
this.git = simpleGit(repoPath);
|
|
6
7
|
}
|
|
@@ -35,7 +36,7 @@ export class GitDiffParser {
|
|
|
35
36
|
// Both are regular commits: standard commit-to-commit comparison
|
|
36
37
|
const targetHash = await this.git.revparse([targetCommitish]);
|
|
37
38
|
const baseHash = await this.git.revparse([baseCommitish]);
|
|
38
|
-
resolvedCommit =
|
|
39
|
+
resolvedCommit = createCommitRangeString(shortHash(baseHash), shortHash(targetHash));
|
|
39
40
|
diffArgs = [baseCommitish, targetCommitish];
|
|
40
41
|
}
|
|
41
42
|
if (ignoreWhitespace) {
|
package/dist/server/server.js
CHANGED
|
@@ -11,6 +11,7 @@ export async function startServer(options) {
|
|
|
11
11
|
let diffData = null;
|
|
12
12
|
let currentIgnoreWhitespace = options.ignoreWhitespace || false;
|
|
13
13
|
app.use(express.json());
|
|
14
|
+
app.use(express.text()); // For sendBeacon text/plain requests
|
|
14
15
|
app.use((_req, res, next) => {
|
|
15
16
|
res.header('Access-Control-Allow-Origin', 'http://localhost:*');
|
|
16
17
|
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
@@ -30,6 +31,58 @@ export async function startServer(options) {
|
|
|
30
31
|
}
|
|
31
32
|
res.json({ ...diffData, ignoreWhitespace });
|
|
32
33
|
});
|
|
34
|
+
// Store comments for final output
|
|
35
|
+
let finalComments = [];
|
|
36
|
+
app.post('/api/comments', (req, res) => {
|
|
37
|
+
try {
|
|
38
|
+
// Handle both JSON and text/plain content types (sendBeacon sends as text/plain)
|
|
39
|
+
let comments = [];
|
|
40
|
+
if (req.headers['content-type']?.includes('application/json')) {
|
|
41
|
+
comments = req.body.comments || [];
|
|
42
|
+
}
|
|
43
|
+
else if (typeof req.body === 'string') {
|
|
44
|
+
const parsed = JSON.parse(req.body);
|
|
45
|
+
comments = parsed.comments || [];
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
comments = req.body.comments || [];
|
|
49
|
+
}
|
|
50
|
+
finalComments = comments;
|
|
51
|
+
res.json({ success: true });
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error('Error parsing comments:', error);
|
|
55
|
+
res.status(400).json({ error: 'Invalid comment data' });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
app.get('/api/comments-output', (_req, res) => {
|
|
59
|
+
if (finalComments.length > 0) {
|
|
60
|
+
const output = formatCommentsOutput(finalComments);
|
|
61
|
+
res.send(output);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
res.send('');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Function to format comments for output
|
|
68
|
+
function formatCommentsOutput(comments) {
|
|
69
|
+
const prompts = comments.map((comment) => {
|
|
70
|
+
return `${comment.file}:${comment.line}\n${comment.body}`;
|
|
71
|
+
});
|
|
72
|
+
return [
|
|
73
|
+
'\nš Comments from review session:',
|
|
74
|
+
'='.repeat(50),
|
|
75
|
+
prompts.join('\n=====\n'),
|
|
76
|
+
'='.repeat(50),
|
|
77
|
+
`Total comments: ${comments.length}\n`,
|
|
78
|
+
].join('\n');
|
|
79
|
+
}
|
|
80
|
+
// Function to output comments when server shuts down
|
|
81
|
+
function outputFinalComments() {
|
|
82
|
+
if (finalComments.length > 0) {
|
|
83
|
+
console.log(formatCommentsOutput(finalComments));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
33
86
|
// SSE endpoint to detect when tab is closed
|
|
34
87
|
app.get('/api/heartbeat', (req, res) => {
|
|
35
88
|
res.writeHead(200, {
|
|
@@ -48,6 +101,7 @@ export async function startServer(options) {
|
|
|
48
101
|
req.on('close', () => {
|
|
49
102
|
clearInterval(heartbeatInterval);
|
|
50
103
|
console.log('Client disconnected, shutting down server...');
|
|
104
|
+
outputFinalComments();
|
|
51
105
|
process.exit(0);
|
|
52
106
|
});
|
|
53
107
|
});
|
|
@@ -57,7 +111,7 @@ export async function startServer(options) {
|
|
|
57
111
|
// Find client files relative to the CLI executable location
|
|
58
112
|
const distPath = join(__dirname, '..', 'client');
|
|
59
113
|
app.use(express.static(distPath));
|
|
60
|
-
app.get('*', (_req, res) => {
|
|
114
|
+
app.get('/{*splat}', (_req, res) => {
|
|
61
115
|
res.sendFile(join(distPath, 'index.html'));
|
|
62
116
|
});
|
|
63
117
|
}
|
|
@@ -85,7 +139,7 @@ export async function startServer(options) {
|
|
|
85
139
|
try {
|
|
86
140
|
await open(url);
|
|
87
141
|
}
|
|
88
|
-
catch
|
|
142
|
+
catch {
|
|
89
143
|
console.warn('Failed to open browser automatically');
|
|
90
144
|
}
|
|
91
145
|
}
|
|
@@ -106,7 +160,7 @@ async function startServerWithFallback(app, preferredPort) {
|
|
|
106
160
|
.catch(reject);
|
|
107
161
|
}
|
|
108
162
|
else {
|
|
109
|
-
reject(err);
|
|
163
|
+
reject(new Error(`Server error: ${err instanceof Error ? err.message : String(err)}`));
|
|
110
164
|
}
|
|
111
165
|
});
|
|
112
166
|
});
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "difit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "A lightweight command-line tool that spins up a local web server to display Git commit diffs in a GitHub-like Files changed view",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=21.0.0"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
10
|
"difit": "./dist/cli/index.js"
|
|
@@ -34,17 +34,17 @@
|
|
|
34
34
|
"prepublishOnly": "NODE_ENV=production pnpm run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"commander": "^
|
|
38
|
-
"express": "^
|
|
39
|
-
"ink": "^
|
|
37
|
+
"commander": "^14.0.0",
|
|
38
|
+
"express": "^5.1.0",
|
|
39
|
+
"ink": "^6.0.1",
|
|
40
40
|
"lucide-react": "^0.525.0",
|
|
41
|
-
"open": "^10.
|
|
41
|
+
"open": "^10.1.2",
|
|
42
42
|
"prism-react-renderer": "^2.4.1",
|
|
43
43
|
"prismjs": "^1.30.0",
|
|
44
|
-
"react": "^
|
|
45
|
-
"react-dom": "^
|
|
46
|
-
"shiki": "^
|
|
47
|
-
"simple-git": "^3.
|
|
44
|
+
"react": "^19.1.0",
|
|
45
|
+
"react-dom": "^19.1.0",
|
|
46
|
+
"shiki": "^3.7.0",
|
|
47
|
+
"simple-git": "^3.28.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@eslint/eslintrc": "^3.3.1",
|
|
@@ -52,28 +52,28 @@
|
|
|
52
52
|
"@tailwindcss/postcss": "^4.1.11",
|
|
53
53
|
"@tailwindcss/typography": "^0.5.16",
|
|
54
54
|
"@tsconfig/strictest": "^2.0.5",
|
|
55
|
-
"@types/express": "^
|
|
56
|
-
"@types/node": "^
|
|
55
|
+
"@types/express": "^5.0.3",
|
|
56
|
+
"@types/node": "^24.0.8",
|
|
57
57
|
"@types/prismjs": "^1.26.5",
|
|
58
|
-
"@types/react": "^
|
|
59
|
-
"@types/react-dom": "^
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
61
|
-
"@typescript-eslint/parser": "^
|
|
62
|
-
"@vitejs/plugin-react": "^4.
|
|
58
|
+
"@types/react": "^19.1.8",
|
|
59
|
+
"@types/react-dom": "^19.1.6",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.35.1",
|
|
61
|
+
"@typescript-eslint/parser": "^8.35.1",
|
|
62
|
+
"@vitejs/plugin-react": "^4.6.0",
|
|
63
63
|
"autoprefixer": "^10.4.21",
|
|
64
|
-
"eslint": "^
|
|
64
|
+
"eslint": "^9.30.0",
|
|
65
65
|
"eslint-config-prettier": "^10.1.5",
|
|
66
66
|
"eslint-plugin-import": "^2.32.0",
|
|
67
|
-
"eslint-plugin-react": "^7.
|
|
68
|
-
"eslint-plugin-react-hooks": "^
|
|
67
|
+
"eslint-plugin-react": "^7.37.5",
|
|
68
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
69
69
|
"eslint-plugin-unused-imports": "^4.1.4",
|
|
70
|
-
"lefthook": "^1.
|
|
70
|
+
"lefthook": "^1.11.14",
|
|
71
71
|
"postcss": "^8.5.6",
|
|
72
|
-
"prettier": "^3.
|
|
72
|
+
"prettier": "^3.6.2",
|
|
73
73
|
"tailwindcss": "^4.1.11",
|
|
74
|
-
"typescript": "^5.
|
|
75
|
-
"vite": "^
|
|
76
|
-
"vitest": "^
|
|
74
|
+
"typescript": "^5.8.3",
|
|
75
|
+
"vite": "^7.0.0",
|
|
76
|
+
"vitest": "^3.2.4"
|
|
77
77
|
},
|
|
78
78
|
"files": [
|
|
79
79
|
"dist",
|