difit 0.0.2 → 0.0.4

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 CHANGED
@@ -54,7 +54,9 @@ pnpm install
54
54
 
55
55
  # Start development server (with hot reload)
56
56
  # This runs both Vite dev server and CLI with NODE_ENV=development
57
- pnpm run dev
57
+ pnpm run dev # defaults to HEAD
58
+ pnpm run dev HEAD~3 # review HEAD~3
59
+ pnpm run dev main # review main branch
58
60
 
59
61
  # For development CLI only (connects to separate Vite server)
60
62
  pnpm run dev:cli <commit-ish>
@@ -98,7 +100,7 @@ ReviewIt includes an inline commenting system that integrates with Claude Code:
98
100
  + onClick();
99
101
  + };
100
102
  ----
101
- コメント: 「この関数名はもっと具体的にした方がいいかも」
103
+ Comment: "This function name should probably be more specific"
102
104
  ```
103
105
 
104
106
  ## 🏗️ Architecture
@@ -50,4 +50,4 @@ prismjs/prism.js:
50
50
  * @namespace
51
51
  * @public
52
52
  *)
53
- */function cg(){B.useEffect(()=>{globalThis.Prism=S,eo(()=>import("./prism-typescript-B2PMeEx1.js"),[]),eo(()=>import("./prism-json-xwnKirkR.js"),[]),eo(()=>import("./prism-css-Bpx-unsJ.js"),[])},[])}function dg(e){var r;const t=(r=e.split(".").pop())==null?void 0:r.toLowerCase();return{ts:"typescript",tsx:"tsx",js:"javascript",jsx:"jsx",json:"json",css:"css",scss:"css",html:"html"}[t||""]||"text"}let Nc="";function pg(e){Nc=e}function Zo({code:e,language:t,className:n}){cg();const r=t||dg(Nc);return k.jsx(ug,{code:e,language:r,theme:Ec.nightOwl,children:({style:l,tokens:o,getLineProps:i,getTokenProps:s})=>k.jsx("span",{className:n,style:{...l,background:"transparent"},children:o.map((a,d)=>k.jsx("span",{...i({line:a}),children:a.map((h,f)=>k.jsx("span",{...s({token:h})},f))},d))})})}function fg({chunk:e,comments:t,onAddComment:n}){const[r,l]=B.useState(null),o=f=>{l(f)},i=()=>{l(null)},s=async f=>{r!==null&&(await n(r,f),l(null))},a=f=>t.filter(m=>m.line===f),h=(f=>{const m=[];let x=e.oldStart,g=e.newStart,y=0;for(;y<f.length;){const w=f[y];if(w.type==="normal")m.push({oldLine:w,newLine:{...w},oldLineNumber:x,newLineNumber:g}),x++,g++,y++;else if(w.type==="delete"){let c=y+1;for(;c<f.length&&f[c].type==="delete";)c++;const u=f.slice(y,c),p=[];for(;c<f.length&&f[c].type==="add";)p.push(f[c]),c++;const v=Math.max(u.length,p.length);for(let b=0;b<v;b++){const N=u[b],_=p[b];m.push({oldLine:N,newLine:_,oldLineNumber:N?x+b:void 0,newLineNumber:_?g+b:void 0})}x+=u.length,g+=p.length,y=c}else w.type==="add"&&(m.push({newLine:w,newLineNumber:g}),g++,y++)}return m})(e.lines);return k.jsx("div",{className:"bg-github-bg-primary border border-github-border rounded-md overflow-hidden",children:k.jsx("table",{className:"w-full border-collapse font-mono text-xs leading-5",children:k.jsx("tbody",{children:h.map((f,m)=>{var w,c,u,p;const x=f.oldLineNumber?a(f.oldLineNumber):[],g=f.newLineNumber?a(f.newLineNumber):[],y=Array.from(new Map([...x,...g].map(v=>[v.id,v])).values());return k.jsxs(ei.Fragment,{children:[k.jsxs("tr",{className:"transition-colors duration-200 hover:bg-github-bg-secondary group",children:[k.jsx("td",{className:"w-[60px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:f.oldLineNumber||""}),k.jsx("td",{className:`w-1/2 p-0 align-top border-r border-github-border relative ${((w=f.oldLine)==null?void 0:w.type)==="delete"?"bg-diff-deletion-bg":((c=f.oldLine)==null?void 0:c.type)==="normal"?"bg-transparent":"bg-github-bg-secondary"}`,children:f.oldLine&&k.jsxs("div",{className:"flex items-center relative min-h-[20px] px-3",children:[k.jsx(Zo,{code:f.oldLine.content,className:"flex-1 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),f.oldLineNumber&&k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>o(f.oldLineNumber),title:"Add comment",children:"💬"})]})}),k.jsx("td",{className:"w-[60px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:f.newLineNumber||""}),k.jsx("td",{className:`w-1/2 p-0 align-top relative ${((u=f.newLine)==null?void 0:u.type)==="add"?"bg-diff-addition-bg":((p=f.newLine)==null?void 0:p.type)==="normal"?"bg-transparent":"bg-github-bg-secondary"}`,children:f.newLine&&k.jsxs("div",{className:"flex items-center relative min-h-[20px] px-3",children:[k.jsx(Zo,{code:f.newLine.content,className:"flex-1 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),f.newLineNumber&&k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>o(f.newLineNumber),title:"Add comment",children:"💬"})]})})]}),y.length>0&&k.jsx("tr",{className:"bg-github-bg-secondary",children:k.jsx("td",{colSpan:4,className:"p-0 border-t border-github-border",children:y.map(v=>k.jsxs("div",{className:"m-2 mx-3 p-2 bg-github-bg-tertiary border border-github-border rounded-md",children:[k.jsx("div",{className:"flex items-center justify-between mb-1",children:k.jsxs("span",{className:"text-[11px] text-github-text-muted",children:["Line ",v.line," • ",new Date(v.timestamp).toLocaleString()]})}),k.jsx("div",{className:"text-github-text-primary text-[13px] leading-6 whitespace-pre-wrap",children:v.body})]},v.id))})}),(r===f.oldLineNumber||r===f.newLineNumber)&&k.jsx("tr",{className:"bg-github-bg-secondary",children:k.jsx("td",{colSpan:4,className:"p-0 border-t border-github-border",children:k.jsx(vc,{onSubmit:s,onCancel:i})})})]},m)})})})})}function gg({chunk:e,comments:t,onAddComment:n,mode:r="inline"}){const[l,o]=B.useState(null),i=m=>{switch(m.type){case"add":return"bg-diff-addition-bg";case"delete":return"bg-diff-deletion-bg";default:return"bg-transparent"}},s=m=>{switch(m.type){case"add":return"+";case"delete":return"-";default:return" "}},a=m=>{o(m)},d=()=>{o(null)},h=async m=>{l!==null&&(await n(l,m),o(null))},f=m=>t.filter(x=>x.line===m);return r==="side-by-side"?k.jsx(fg,{chunk:e,comments:t,onAddComment:n}):k.jsx("div",{className:"bg-github-bg-primary",children:k.jsx("table",{className:"w-full border-collapse font-mono text-xs leading-5",children:k.jsx("tbody",{children:e.lines.map((m,x)=>{const g=f(m.newLineNumber||m.oldLineNumber||0);return k.jsxs(ei.Fragment,{children:[k.jsxs("tr",{className:`transition-colors duration-200 hover:bg-[var(--bg-tertiary)] group ${i(m)}`,children:[k.jsx("td",{className:"w-[50px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:m.oldLineNumber||""}),k.jsx("td",{className:"w-[50px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:m.newLineNumber||""}),k.jsx("td",{className:"p-0 w-full relative align-top",children:k.jsxs("div",{className:"flex items-center relative min-h-[20px]",children:[k.jsx("span",{className:`w-5 text-center text-github-text-muted flex-shrink-0 bg-github-bg-secondary border-r border-github-border ${m.type==="add"?"text-github-accent bg-diff-addition-bg":m.type==="delete"?"text-github-danger bg-diff-deletion-bg":""}`,children:s(m)}),k.jsx(Zo,{code:m.content,className:"flex-1 px-3 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>a(m.newLineNumber||m.oldLineNumber||0),title:"Add comment",children:"💬"})]})})]}),g.map(y=>k.jsx("tr",{className:"bg-[var(--bg-secondary)]",children:k.jsx("td",{colSpan:3,className:"p-0 border-t border-[var(--border-muted)]",children:k.jsxs("div",{className:"m-2 mx-3 p-2 bg-[var(--bg-tertiary)] border border-[var(--border)] rounded-md",children:[k.jsx("div",{className:"flex items-center justify-between mb-1",children:k.jsxs("span",{className:"text-[11px] text-[var(--text-muted)]",children:["Line ",y.line," • ",new Date(y.timestamp).toLocaleString()]})}),k.jsx("div",{className:"text-[var(--text-primary)] text-[13px] leading-6 whitespace-pre-wrap",children:y.body})]})})},y.id)),l===(m.newLineNumber||m.oldLineNumber)&&k.jsx("tr",{className:"bg-[var(--bg-secondary)]",children:k.jsx("td",{colSpan:3,className:"p-0 border-t border-[var(--border-muted)]",children:k.jsx(vc,{onSubmit:h,onCancel:d})})})]},x)})})})})}const Cc=B.createContext(void 0);function yg({children:e,comments:t,onAddComment:n,onGeneratePrompt:r}){return k.jsx(Cc.Provider,{value:{comments:t,onAddComment:n,onGeneratePrompt:r},children:e})}function mg(){const e=B.useContext(Cc);if(e===void 0)throw new Error("useComments must be used within a CommentProvider");return e}function hg({file:e,comments:t,diffMode:n,reviewedFiles:r,onToggleReviewed:l}){const[o,i]=B.useState(new Set([0])),{onAddComment:s}=mg();B.useEffect(()=>{pg(e.path)},[e.path]);const a=x=>{i(g=>{const y=new Set(g);return y.has(x)?y.delete(x):y.add(x),y})},d=()=>{i(new Set(e.chunks.map((x,g)=>g)))},h=()=>{i(new Set)},f=x=>{switch(x){case"added":return"🆕";case"deleted":return"🗑️";case"renamed":return"📝";default:return"📄"}},m=async(x,g)=>{try{await s(e.path,x,g)}catch(y){console.error("Failed to add comment:",y)}};return k.jsxs("div",{className:"h-full flex flex-col bg-github-bg-primary",children:[k.jsxs("div",{className:"bg-github-bg-secondary border-b border-github-border px-5 py-4 flex items-center justify-between flex-wrap gap-3",children:[k.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[k.jsx("span",{className:"text-base",children:f(e.status)}),k.jsx("h2",{className:"text-base font-semibold text-github-text-primary m-0 overflow-hidden text-ellipsis whitespace-nowrap",children:e.path}),e.oldPath&&e.oldPath!==e.path&&k.jsxs("span",{className:"text-xs text-github-text-muted italic",children:["(renamed from ",e.oldPath,")"]})]}),k.jsxs("div",{className:"flex items-center gap-3",children:[k.jsx("input",{type:"checkbox",className:"w-4 h-4 cursor-pointer accent-github-accent",checked:r.has(e.path),onChange:()=>l(e.path),title:r.has(e.path)?"Mark as not reviewed":"Mark as reviewed"}),k.jsx("span",{className:"text-sm text-github-text-secondary",children:"Viewed"}),k.jsx("button",{className:"bg-transparent border-none cursor-pointer px-1.5 py-1 rounded text-sm text-github-text-secondary transition-all hover:bg-github-bg-tertiary hover:text-github-text-primary",onClick:()=>{navigator.clipboard.writeText(e.path).then(()=>{console.log("File path copied to clipboard:",e.path)}).catch(x=>{console.error("Failed to copy file path:",x)})},title:"Copy file path",children:"📋"}),k.jsx("button",{className:"bg-transparent border-none cursor-pointer px-1.5 py-1 rounded text-base text-github-text-secondary transition-all hover:bg-github-bg-tertiary hover:text-github-text-primary",title:"More options",children:"⋯"})]})]}),k.jsx("div",{className:"flex items-center gap-4",children:k.jsxs("div",{className:"flex gap-2",children:[k.jsx("button",{onClick:d,className:"px-3 py-1.5 text-xs font-medium rounded border bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80 transition-all",children:"Expand All"}),k.jsx("button",{onClick:h,className:"px-3 py-1.5 text-xs font-medium rounded border bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80 transition-all",children:"Collapse All"})]})}),k.jsx("div",{className:"flex-1 overflow-y-auto",children:e.chunks.map((x,g)=>k.jsxs("div",{className:"border-b border-github-border",children:[k.jsxs("div",{className:"bg-github-bg-tertiary px-3 py-2 cursor-pointer flex items-center gap-2 border-b border-github-border transition-colors hover:bg-github-bg-secondary",onClick:()=>a(g),children:[k.jsx("span",{className:"text-github-text-muted text-xs w-3 text-center",children:o.has(g)?"▼":"▶"}),k.jsx("code",{className:"text-github-text-secondary text-xs font-mono",children:x.header})]}),o.has(g)&&k.jsx(gg,{chunk:x,comments:t,onAddComment:m,mode:n})]},g))})]})}function vg(){const[e,t]=B.useState(null),[n,r]=B.useState([]),[l,o]=B.useState(new Set),[i,s]=B.useState("side-by-side"),[a,d]=B.useState(!0),[h,f]=B.useState(null);B.useEffect(()=>{m(),x()},[]);const m=async()=>{try{const c=await fetch("/api/diff");if(!c.ok)throw new Error("Failed to fetch diff data");const u=await c.json();t(u)}catch(c){f(c instanceof Error?c.message:"Unknown error")}finally{d(!1)}},x=async()=>{try{const c=await fetch("/api/comments");if(c.ok){const u=await c.json();r(u)}}catch(c){console.warn("Failed to fetch comments:",c)}},g=async(c,u,p)=>{try{const v=await fetch("/api/comments",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({file:c,line:u,body:p})});if(!v.ok)throw new Error("Failed to add comment");const b=await v.json();return r(N=>[...N,b]),b}catch(v){throw console.error("Failed to add comment:",v),v}},y=async c=>{try{const u=await fetch(`/api/comments/${c}/prompt`,{method:"POST"});if(!u.ok)throw new Error("Failed to generate prompt");const{prompt:p}=await u.json();return p}catch(u){throw console.error("Failed to generate prompt:",u),u}},w=c=>{o(u=>{const p=new Set(u);return p.has(c)?p.delete(c):p.add(c),p})};return a?k.jsx("div",{className:"flex items-center justify-center h-screen bg-github-bg-primary",children:k.jsx("div",{className:"text-github-text-secondary text-base",children:"Loading diff..."})}):h?k.jsxs("div",{className:"flex flex-col items-center justify-center h-screen bg-github-bg-primary text-center gap-2",children:[k.jsx("h2",{className:"text-github-danger text-2xl mb-2",children:"Error"}),k.jsx("p",{className:"text-github-text-secondary text-base",children:h})]}):e?k.jsx(yg,{comments:n,onAddComment:g,onGeneratePrompt:y,children:k.jsxs("div",{className:"h-screen flex flex-col",children:[k.jsxs("header",{className:"bg-github-bg-secondary border-b border-github-border px-4 py-3 flex items-center justify-between gap-4",children:[k.jsx("h1",{className:"text-lg font-semibold text-github-text-primary m-0",children:"📋 ReviewIt"}),k.jsxs("div",{className:"flex items-center gap-4 text-sm text-github-text-secondary",children:[k.jsxs("span",{children:["Reviewing:"," ",k.jsx("code",{className:"bg-github-bg-tertiary px-1.5 py-0.5 rounded text-xs text-github-text-primary",children:e.commit})]}),k.jsxs("span",{children:[e.files.length," file",e.files.length!==1?"s":""," changed"]})]}),k.jsxs("div",{className:"flex gap-1",children:[k.jsx("button",{onClick:()=>s("side-by-side"),className:`px-3 py-1.5 text-xs font-medium rounded border transition-all duration-200 ${i==="side-by-side"?"bg-blue-600 text-white border-blue-600":"bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80"}`,children:"📋 Side by Side"}),k.jsx("button",{onClick:()=>s("inline"),className:`px-3 py-1.5 text-xs font-medium rounded border transition-all duration-200 ${i==="inline"?"bg-blue-600 text-white border-blue-600":"bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80"}`,children:"📝 Inline"})]})]}),k.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[k.jsx("aside",{className:"w-80 min-w-80 bg-github-bg-secondary border-r border-github-border overflow-y-auto",children:k.jsx(nf,{files:e.files,onScrollToFile:c=>{const u=document.getElementById(`file-${c.replace(/[^a-zA-Z0-9]/g,"-")}`);u&&u.scrollIntoView({behavior:"smooth",block:"start"})},comments:n,reviewedFiles:l,onToggleReviewed:w})}),k.jsx("main",{className:"flex-1 overflow-y-auto",children:e.files.map(c=>k.jsx("div",{id:`file-${c.path.replace(/[^a-zA-Z0-9]/g,"-")}`,className:"mb-6",children:k.jsx(hg,{file:c,comments:n.filter(u=>u.file===c.path),diffMode:i,reviewedFiles:l,onToggleReviewed:w})},c.path))})]})]})}):k.jsxs("div",{className:"flex flex-col items-center justify-center h-screen bg-github-bg-primary text-center gap-2",children:[k.jsx("h2",{className:"text-github-danger text-2xl mb-2",children:"No data"}),k.jsx("p",{className:"text-github-text-secondary text-base",children:"No diff data available"})]})}to.createRoot(document.getElementById("root")).render(k.jsx(ei.StrictMode,{children:k.jsx(vg,{})}));
53
+ */function cg(){B.useEffect(()=>{globalThis.Prism=S,eo(()=>import("./prism-typescript-B2PMeEx1.js"),[]),eo(()=>import("./prism-json-xwnKirkR.js"),[]),eo(()=>import("./prism-css-Bpx-unsJ.js"),[])},[])}function dg(e){var r;const t=(r=e.split(".").pop())==null?void 0:r.toLowerCase();return{ts:"typescript",tsx:"tsx",js:"javascript",jsx:"jsx",json:"json",css:"css",scss:"css",html:"html"}[t||""]||"text"}let Nc="";function pg(e){Nc=e}function Zo({code:e,language:t,className:n}){cg();const r=t||dg(Nc);return k.jsx(ug,{code:e,language:r,theme:Ec.nightOwl,children:({style:l,tokens:o,getLineProps:i,getTokenProps:s})=>k.jsx("span",{className:n,style:{...l,background:"transparent"},children:o.map((a,d)=>k.jsx("span",{...i({line:a}),children:a.map((h,f)=>k.jsx("span",{...s({token:h})},f))},d))})})}function fg({chunk:e,comments:t,onAddComment:n}){const[r,l]=B.useState(null),o=f=>{l(f)},i=()=>{l(null)},s=async f=>{r!==null&&(await n(r,f),l(null))},a=f=>t.filter(m=>m.line===f),h=(f=>{const m=[];let x=e.oldStart,g=e.newStart,y=0;for(;y<f.length;){const w=f[y];if(w.type==="normal")m.push({oldLine:w,newLine:{...w},oldLineNumber:x,newLineNumber:g}),x++,g++,y++;else if(w.type==="delete"){let c=y+1;for(;c<f.length&&f[c].type==="delete";)c++;const u=f.slice(y,c),p=[];for(;c<f.length&&f[c].type==="add";)p.push(f[c]),c++;const v=Math.max(u.length,p.length);for(let b=0;b<v;b++){const N=u[b],_=p[b];m.push({oldLine:N,newLine:_,oldLineNumber:N?x+b:void 0,newLineNumber:_?g+b:void 0})}x+=u.length,g+=p.length,y=c}else w.type==="add"&&(m.push({newLine:w,newLineNumber:g}),g++,y++)}return m})(e.lines);return k.jsx("div",{className:"bg-github-bg-primary border border-github-border rounded-md overflow-hidden",children:k.jsx("table",{className:"w-full border-collapse font-mono text-xs leading-5",children:k.jsx("tbody",{children:h.map((f,m)=>{var w,c,u,p;const x=f.oldLineNumber?a(f.oldLineNumber):[],g=f.newLineNumber?a(f.newLineNumber):[],y=Array.from(new Map([...x,...g].map(v=>[v.id,v])).values());return k.jsxs(ei.Fragment,{children:[k.jsxs("tr",{className:"transition-colors duration-200 hover:bg-github-bg-secondary group",children:[k.jsx("td",{className:"w-[60px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:f.oldLineNumber||""}),k.jsx("td",{className:`w-1/2 p-0 align-top border-r border-github-border relative ${((w=f.oldLine)==null?void 0:w.type)==="delete"?"bg-diff-deletion-bg":((c=f.oldLine)==null?void 0:c.type)==="normal"?"bg-transparent":"bg-github-bg-secondary"}`,children:f.oldLine&&k.jsxs("div",{className:"flex items-center relative min-h-[20px] px-3",children:[k.jsx(Zo,{code:f.oldLine.content,className:"flex-1 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),f.oldLineNumber&&k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>o(f.oldLineNumber),title:"Add comment",children:"💬"})]})}),k.jsx("td",{className:"w-[60px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:f.newLineNumber||""}),k.jsx("td",{className:`w-1/2 p-0 align-top relative ${((u=f.newLine)==null?void 0:u.type)==="add"?"bg-diff-addition-bg":((p=f.newLine)==null?void 0:p.type)==="normal"?"bg-transparent":"bg-github-bg-secondary"}`,children:f.newLine&&k.jsxs("div",{className:"flex items-center relative min-h-[20px] px-3",children:[k.jsx(Zo,{code:f.newLine.content,className:"flex-1 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),f.newLineNumber&&k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>o(f.newLineNumber),title:"Add comment",children:"💬"})]})})]}),y.length>0&&k.jsx("tr",{className:"bg-github-bg-secondary",children:k.jsx("td",{colSpan:4,className:"p-0 border-t border-github-border",children:y.map(v=>k.jsxs("div",{className:"m-2 mx-3 p-2 bg-github-bg-tertiary border border-github-border rounded-md",children:[k.jsx("div",{className:"flex items-center justify-between mb-1",children:k.jsxs("span",{className:"text-[11px] text-github-text-muted",children:["Line ",v.line," • ",new Date(v.timestamp).toLocaleString()]})}),k.jsx("div",{className:"text-github-text-primary text-[13px] leading-6 whitespace-pre-wrap",children:v.body})]},v.id))})}),(r===f.oldLineNumber||r===f.newLineNumber)&&k.jsx("tr",{className:"bg-github-bg-secondary",children:k.jsx("td",{colSpan:4,className:"p-0 border-t border-github-border",children:k.jsx(vc,{onSubmit:s,onCancel:i})})})]},m)})})})})}function gg({chunk:e,comments:t,onAddComment:n,mode:r="inline"}){const[l,o]=B.useState(null),i=m=>{switch(m.type){case"add":return"bg-diff-addition-bg";case"delete":return"bg-diff-deletion-bg";default:return"bg-transparent"}},s=m=>{switch(m.type){case"add":return"+";case"delete":return"-";default:return" "}},a=m=>{o(m)},d=()=>{o(null)},h=async m=>{l!==null&&(await n(l,m),o(null))},f=m=>t.filter(x=>x.line===m);return r==="side-by-side"?k.jsx(fg,{chunk:e,comments:t,onAddComment:n}):k.jsx("div",{className:"bg-github-bg-primary",children:k.jsx("table",{className:"w-full border-collapse font-mono text-xs leading-5",children:k.jsx("tbody",{children:e.lines.map((m,x)=>{const g=f(m.newLineNumber||m.oldLineNumber||0);return k.jsxs(ei.Fragment,{children:[k.jsxs("tr",{className:`transition-colors duration-200 hover:bg-[var(--bg-tertiary)] group ${i(m)}`,children:[k.jsx("td",{className:"w-[50px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:m.oldLineNumber||""}),k.jsx("td",{className:"w-[50px] px-2 text-right text-github-text-muted bg-github-bg-secondary border-r border-github-border select-none align-top",children:m.newLineNumber||""}),k.jsx("td",{className:"p-0 w-full relative align-top",children:k.jsxs("div",{className:"flex items-center relative min-h-[20px]",children:[k.jsx("span",{className:`w-5 text-center text-github-text-muted flex-shrink-0 bg-github-bg-secondary border-r border-github-border ${m.type==="add"?"text-github-accent bg-diff-addition-bg":m.type==="delete"?"text-github-danger bg-diff-deletion-bg":""}`,children:s(m)}),k.jsx(Zo,{code:m.content,className:"flex-1 px-3 text-github-text-primary whitespace-pre-wrap break-all overflow-wrap-break-word [&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:font-inherit [&_pre]:text-inherit [&_pre]:leading-inherit [&_code]:!bg-transparent [&_code]:font-inherit [&_code]:text-inherit [&_code]:leading-inherit"}),k.jsx("button",{className:"absolute right-2 top-1/2 -translate-y-1/2 bg-github-bg-tertiary border border-github-border rounded w-6 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 text-[10px] cursor-pointer hover:bg-github-bg-secondary",onClick:()=>a(m.newLineNumber||m.oldLineNumber||0),title:"Add comment",children:"💬"})]})})]}),g.map(y=>k.jsx("tr",{className:"bg-[var(--bg-secondary)]",children:k.jsx("td",{colSpan:3,className:"p-0 border-t border-[var(--border-muted)]",children:k.jsxs("div",{className:"m-2 mx-3 p-2 bg-[var(--bg-tertiary)] border border-[var(--border)] rounded-md",children:[k.jsx("div",{className:"flex items-center justify-between mb-1",children:k.jsxs("span",{className:"text-[11px] text-[var(--text-muted)]",children:["Line ",y.line," • ",new Date(y.timestamp).toLocaleString()]})}),k.jsx("div",{className:"text-[var(--text-primary)] text-[13px] leading-6 whitespace-pre-wrap",children:y.body})]})})},y.id)),l===(m.newLineNumber||m.oldLineNumber)&&k.jsx("tr",{className:"bg-[var(--bg-secondary)]",children:k.jsx("td",{colSpan:3,className:"p-0 border-t border-[var(--border-muted)]",children:k.jsx(vc,{onSubmit:h,onCancel:d})})})]},x)})})})})}const Cc=B.createContext(void 0);function yg({children:e,comments:t,onAddComment:n,onGeneratePrompt:r}){return k.jsx(Cc.Provider,{value:{comments:t,onAddComment:n,onGeneratePrompt:r},children:e})}function mg(){const e=B.useContext(Cc);if(e===void 0)throw new Error("useComments must be used within a CommentProvider");return e}function hg({file:e,comments:t,diffMode:n,reviewedFiles:r,onToggleReviewed:l}){const[o,i]=B.useState(new Set(e.chunks.map((x,g)=>g))),{onAddComment:s}=mg();B.useEffect(()=>{pg(e.path)},[e.path]);const a=x=>{i(g=>{const y=new Set(g);return y.has(x)?y.delete(x):y.add(x),y})},d=()=>{i(new Set(e.chunks.map((x,g)=>g)))},h=()=>{i(new Set)},f=x=>{switch(x){case"added":return"🆕";case"deleted":return"🗑️";case"renamed":return"📝";default:return"📄"}},m=async(x,g)=>{try{await s(e.path,x,g)}catch(y){console.error("Failed to add comment:",y)}};return k.jsxs("div",{className:"h-full flex flex-col bg-github-bg-primary",children:[k.jsxs("div",{className:"bg-github-bg-secondary border-b border-github-border px-5 py-4 flex items-center justify-between flex-wrap gap-3",children:[k.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[k.jsx("span",{className:"text-base",children:f(e.status)}),k.jsx("h2",{className:"text-base font-semibold text-github-text-primary m-0 overflow-hidden text-ellipsis whitespace-nowrap",children:e.path}),e.oldPath&&e.oldPath!==e.path&&k.jsxs("span",{className:"text-xs text-github-text-muted italic",children:["(renamed from ",e.oldPath,")"]})]}),k.jsxs("div",{className:"flex items-center gap-3",children:[k.jsx("input",{type:"checkbox",className:"w-4 h-4 cursor-pointer accent-github-accent",checked:r.has(e.path),onChange:()=>l(e.path),title:r.has(e.path)?"Mark as not reviewed":"Mark as reviewed"}),k.jsx("span",{className:"text-sm text-github-text-secondary",children:"Viewed"}),k.jsx("button",{className:"bg-transparent border-none cursor-pointer px-1.5 py-1 rounded text-sm text-github-text-secondary transition-all hover:bg-github-bg-tertiary hover:text-github-text-primary",onClick:()=>{navigator.clipboard.writeText(e.path).then(()=>{console.log("File path copied to clipboard:",e.path)}).catch(x=>{console.error("Failed to copy file path:",x)})},title:"Copy file path",children:"📋"}),k.jsx("button",{className:"bg-transparent border-none cursor-pointer px-1.5 py-1 rounded text-base text-github-text-secondary transition-all hover:bg-github-bg-tertiary hover:text-github-text-primary",title:"More options",children:"⋯"})]})]}),k.jsx("div",{className:"flex items-center gap-4",children:k.jsxs("div",{className:"flex gap-2",children:[k.jsx("button",{onClick:d,className:"px-3 py-1.5 text-xs font-medium rounded border bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80 transition-all",children:"Expand All"}),k.jsx("button",{onClick:h,className:"px-3 py-1.5 text-xs font-medium rounded border bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80 transition-all",children:"Collapse All"})]})}),k.jsx("div",{className:"flex-1 overflow-y-auto",children:e.chunks.map((x,g)=>k.jsxs("div",{className:"border-b border-github-border",children:[k.jsxs("div",{className:"bg-github-bg-tertiary px-3 py-2 cursor-pointer flex items-center gap-2 border-b border-github-border transition-colors hover:bg-github-bg-secondary",onClick:()=>a(g),children:[k.jsx("span",{className:"text-github-text-muted text-xs w-3 text-center",children:o.has(g)?"▼":"▶"}),k.jsx("code",{className:"text-github-text-secondary text-xs font-mono",children:x.header})]}),o.has(g)&&k.jsx(gg,{chunk:x,comments:t,onAddComment:m,mode:n})]},g))})]})}function vg(){const[e,t]=B.useState(null),[n,r]=B.useState([]),[l,o]=B.useState(new Set),[i,s]=B.useState("side-by-side"),[a,d]=B.useState(!0),[h,f]=B.useState(null);B.useEffect(()=>{m(),x()},[]);const m=async()=>{try{const c=await fetch("/api/diff");if(!c.ok)throw new Error("Failed to fetch diff data");const u=await c.json();t(u)}catch(c){f(c instanceof Error?c.message:"Unknown error")}finally{d(!1)}},x=async()=>{try{const c=await fetch("/api/comments");if(c.ok){const u=await c.json();r(u)}}catch(c){console.warn("Failed to fetch comments:",c)}},g=async(c,u,p)=>{try{const v=await fetch("/api/comments",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({file:c,line:u,body:p})});if(!v.ok)throw new Error("Failed to add comment");const b=await v.json();return r(N=>[...N,b]),b}catch(v){throw console.error("Failed to add comment:",v),v}},y=async c=>{try{const u=await fetch(`/api/comments/${c}/prompt`,{method:"POST"});if(!u.ok)throw new Error("Failed to generate prompt");const{prompt:p}=await u.json();return p}catch(u){throw console.error("Failed to generate prompt:",u),u}},w=c=>{o(u=>{const p=new Set(u);return p.has(c)?p.delete(c):p.add(c),p})};return a?k.jsx("div",{className:"flex items-center justify-center h-screen bg-github-bg-primary",children:k.jsx("div",{className:"text-github-text-secondary text-base",children:"Loading diff..."})}):h?k.jsxs("div",{className:"flex flex-col items-center justify-center h-screen bg-github-bg-primary text-center gap-2",children:[k.jsx("h2",{className:"text-github-danger text-2xl mb-2",children:"Error"}),k.jsx("p",{className:"text-github-text-secondary text-base",children:h})]}):e?k.jsx(yg,{comments:n,onAddComment:g,onGeneratePrompt:y,children:k.jsxs("div",{className:"h-screen flex flex-col",children:[k.jsxs("header",{className:"bg-github-bg-secondary border-b border-github-border px-4 py-3 flex items-center justify-between gap-4",children:[k.jsx("h1",{className:"text-lg font-semibold text-github-text-primary m-0",children:"📋 ReviewIt"}),k.jsxs("div",{className:"flex items-center gap-4 text-sm text-github-text-secondary",children:[k.jsxs("span",{children:["Reviewing:"," ",k.jsx("code",{className:"bg-github-bg-tertiary px-1.5 py-0.5 rounded text-xs text-github-text-primary",children:e.commit})]}),k.jsxs("span",{children:[e.files.length," file",e.files.length!==1?"s":""," changed"]})]}),k.jsxs("div",{className:"flex gap-1",children:[k.jsx("button",{onClick:()=>s("side-by-side"),className:`px-3 py-1.5 text-xs font-medium rounded border transition-all duration-200 ${i==="side-by-side"?"bg-blue-600 text-white border-blue-600":"bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80"}`,children:"📋 Side by Side"}),k.jsx("button",{onClick:()=>s("inline"),className:`px-3 py-1.5 text-xs font-medium rounded border transition-all duration-200 ${i==="inline"?"bg-blue-600 text-white border-blue-600":"bg-github-bg-tertiary text-github-text-primary border-github-border hover:opacity-80"}`,children:"📝 Inline"})]})]}),k.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[k.jsx("aside",{className:"w-80 min-w-80 bg-github-bg-secondary border-r border-github-border overflow-y-auto",children:k.jsx(nf,{files:e.files,onScrollToFile:c=>{const u=document.getElementById(`file-${c.replace(/[^a-zA-Z0-9]/g,"-")}`);u&&u.scrollIntoView({behavior:"smooth",block:"start"})},comments:n,reviewedFiles:l,onToggleReviewed:w})}),k.jsx("main",{className:"flex-1 overflow-y-auto",children:e.files.map(c=>k.jsx("div",{id:`file-${c.path.replace(/[^a-zA-Z0-9]/g,"-")}`,className:"mb-6",children:k.jsx(hg,{file:c,comments:n.filter(u=>u.file===c.path),diffMode:i,reviewedFiles:l,onToggleReviewed:w})},c.path))})]})]})}):k.jsxs("div",{className:"flex flex-col items-center justify-center h-screen bg-github-bg-primary text-center gap-2",children:[k.jsx("h2",{className:"text-github-danger text-2xl mb-2",children:"No data"}),k.jsx("p",{className:"text-github-text-secondary text-base",children:"No diff data available"})]})}to.createRoot(document.getElementById("root")).render(k.jsx(ei.StrictMode,{children:k.jsx(vg,{})}));
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>ReviewIt - Git Diff Viewer</title>
8
- <script type="module" crossorigin src="/assets/index-IxkylgHX.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-B79lDGO8.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-CSJzfcU-.css">
10
10
  </head>
11
11
  <body>
@@ -34,7 +34,7 @@ export class CommentStore {
34
34
  '----',
35
35
  context,
36
36
  '----',
37
- `コメント: 「${comment.body}」`,
37
+ `Comment: "${comment.body}"`,
38
38
  ].join('\n');
39
39
  }
40
40
  async saveToFile() {
@@ -70,10 +70,10 @@ export async function startServer(options) {
70
70
  res.status(500).json({ error: 'Failed to generate prompt' });
71
71
  }
72
72
  });
73
- // CLIツールとして配布される場合は常にproductionモードで動作する
73
+ // Always runs in production mode when distributed as a CLI tool
74
74
  const isProduction = process.env.NODE_ENV === 'production' || process.env.NODE_ENV !== 'development';
75
75
  if (isProduction) {
76
- // CLI実行ファイルの場所から相対的にクライアントファイルを探す
76
+ // Find client files relative to the CLI executable location
77
77
  const distPath = join(__dirname, '..', 'client');
78
78
  app.use(express.static(distPath));
79
79
  app.get('*', (_req, res) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "difit",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
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": {
@@ -19,7 +19,7 @@
19
19
  "url": "https://github.com/yoshiko-pg/difit/issues"
20
20
  },
21
21
  "scripts": {
22
- "dev": "concurrently \"pnpm run dev:cli HEAD --no-open\" \"sleep 3 && vite --open\"",
22
+ "dev": "node scripts/dev.js",
23
23
  "dev:cli": "tsc --project tsconfig.cli.json && NODE_ENV=development node dist/cli/index.js",
24
24
  "build": "tsc && vite build",
25
25
  "build:cli": "tsc --project tsconfig.cli.json",
@@ -57,7 +57,6 @@
57
57
  "@typescript-eslint/parser": "^6.15.0",
58
58
  "@vitejs/plugin-react": "^4.2.1",
59
59
  "autoprefixer": "^10.4.21",
60
- "concurrently": "^9.2.0",
61
60
  "eslint": "^8.56.0",
62
61
  "eslint-plugin-react": "^7.33.2",
63
62
  "eslint-plugin-react-hooks": "^4.6.0",