@plannotator/opencode 0.5.2 → 0.5.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
@@ -30,10 +30,11 @@ Add to your `opencode.json`:
30
30
 
31
31
  Restart OpenCode. The `submit_plan` tool is now available.
32
32
 
33
- > **Existing users:** If you're stuck on an old version, clear both caches and restart:
33
+ > **Slash commands:** Run the install script to get `/plannotator-review`:
34
34
  > ```bash
35
- > rm -rf ~/.cache/opencode/node_modules/@plannotator ~/.bun/install/cache/@plannotator
35
+ > curl -fsSL https://plannotator.ai/install.sh | bash
36
36
  > ```
37
+ > This also clears any cached plugin versions.
37
38
 
38
39
  ## How It Works
39
40
 
package/dist/index.js CHANGED
@@ -860,7 +860,7 @@ https://github.com/highlightjs/highlight.js/issues/2277\`),Tt=de,$e=Oe),Ue===voi
860
860
  created: \${new Date().toISOString().slice(0,19)}Z
861
861
  source: plannotator
862
862
  tags: [plan, ...]
863
- ---\`})]})]})]}),p.jsx("div",{className:"border-t border-border"}),p.jsxs("div",{className:"flex items-center justify-between",children:[p.jsxs("div",{children:[p.jsx("div",{className:"text-sm font-medium",children:"Bear Notes"}),p.jsx("div",{className:"text-xs text-muted-foreground",children:"Auto-save approved plans to Bear"})]}),p.jsx("button",{role:"switch","aria-checked":I.enabled,onClick:()=>z(!I.enabled),className:\`relative inline-flex h-6 w-11 items-center rounded-full transition-colors \${I.enabled?"bg-primary":"bg-muted"}\`,children:p.jsx("span",{className:\`inline-block h-4 w-4 transform rounded-full bg-white shadow-sm transition-transform \${I.enabled?"translate-x-6":"translate-x-1"}\`})})]})]})]})]})}),document.body)]})};async function _A(r){const i=JSON.stringify(r),c=new TextEncoder().encode(i),s=new CompressionStream("deflate-raw"),u=s.writable.getWriter();u.write(c),u.close();const d=await new Response(s.readable).arrayBuffer(),b=new Uint8Array(d);return btoa(String.fromCharCode(...b)).replace(/\\+/g,"-").replace(/\\//g,"_").replace(/=/g,"")}async function $A(r){const i=r.replace(/-/g,"+").replace(/_/g,"/"),c=atob(i),s=Uint8Array.from(c,f=>f.charCodeAt(0)),u=new DecompressionStream("deflate-raw"),d=u.writable.getWriter();d.write(s),d.close();const b=await new Response(u.readable).arrayBuffer(),E=new TextDecoder().decode(b);return JSON.parse(E)}function ex(r){return r.map(i=>{const c=i.author||null,s=i.imagePaths?.length?i.imagePaths:void 0;if(i.type===st.GLOBAL_COMMENT)return["G",i.text||"",c,s];const u=i.type[0];return u==="D"?["D",i.originalText,c,s]:[u,i.originalText,i.text||"",c,s]})}function tx(r){const i={D:st.DELETION,R:st.REPLACEMENT,C:st.COMMENT,I:st.INSERTION,G:st.GLOBAL_COMMENT};return r.map((c,s)=>{const u=c[0];if(u==="G"){const m=c[1],S=c[2],v=c[3];return{id:\`shared-\${s}-\${Date.now()}\`,blockId:"",startOffset:0,endOffset:0,type:st.GLOBAL_COMMENT,text:m||void 0,originalText:"",createdA:Date.now()+s,author:S||void 0,imagePaths:v?.length?v:void 0}}const d=c[1],b=u==="D"?void 0:c[2],E=u==="D"?c[2]:c[3],f=u==="D"?c[3]:c[4];return{id:\`shared-\${s}-\${Date.now()}\`,blockId:"",startOffset:0,endOffset:0,type:i[u],text:b||void 0,originalText:d,createdA:Date.now()+s,author:E||void 0,imagePaths:f?.length?f:void 0}})}const nx="https://share.plannotator.ai";async function ax(r,i,c){const s={p:r,a:ex(i),g:c?.length?c:void 0},u=await _A(s);return\`\${nx}/#\${u}\`}async function ix(){const r=window.location.hash.slice(1);if(!r)return null;try{return await $A(r)}catch(i){return console.warn("Failed to parse share hash:",i),null}}function rx(r){const i=new Blob([r]).size;return i<1024?\`\${i} B\`:\`\${(i/1024).toFixed(1)} KB\`}function ox(r,i,c,s,u,d,b){const[E,f]=_.useState(!1),[m,S]=_.useState(!0),[v,h]=_.useState(""),[O,T]=_.useState(""),[I,y]=_.useState(null),[C,A]=_.useState(null),D=_.useCallback(()=>{y(null),A(null)},[]),j=_.useCallback(async()=>{try{const z=await ix();if(z){s(z.p);const Y=tx(z.a);return u(Y),z.g?.length&&(d(z.g),A(z.g)),y(Y),f(!0),b?.(),window.history.replaceState({},"",window.location.pathname),!0}return!1}catch(z){return console.error("Failed to load from share hash:",z),!1}},[s,u,d,b]);_.useEffect(()=>{j().finally(()=>S(!1))},[]),_.useEffect(()=>{const z=()=>{window.location.hash.length>1&&j()};return window.addEventListener("hashchange",z),()=>window.removeEventListener("hashchange",z)},[j]);const F=_.useCallback(async()=>{try{const z=await ax(r,i,c);h(z),T(rx(z))}catch(z){console.error("Failed to generate share URL:",z),h(""),T("")}},[r,i,c]);return _.useEffect(()=>{F()},[F]),{isSharedSession:E,isLoadingShared:m,shareUrl:v,shareUrlSize:O,pendingSharedAnnotations:I,sharedGlobalAttachments:C,clearPendingSharedAnnotations:D,refreshShareUrl:F}}const sx="https://api.github.com/repos/backnotprop/plannotator/releases/latest",sT={"0.5.0":{title:"Code Review is here!",description:"Review git diffs with inline annotations. Run /plannotator-review to try it."}};function lx(r,i){const c=d=>d.replace(/^v/,""),s=c(r).split(".").map(Number),u=c(i).split(".").map(Number);for(let d=0;d<Math.max(s.length,u.length);d++){const b=s[d]||0,E=u[d]||0;if(E>b)return!0;if(E<b)return!1}return!1}function cx(){const[r,i]=_.useState(null);return _.useEffect(()=>{(async()=>{try{const s="0.5.1",d=new URLSearchParams(window.location.search).get("preview-update");if(d){const h=d.replace(/^v/,"");i({currentVersion:s,latestVersion:d,updateAvailable:!0,releaseUrl:\`https://github.com/backnotprop/plannotator/releases/tag/v\${h}\`,featureHighlight:sT[h]});return}const b=await fetch(sx);if(!b.ok)return;const E=await b.json(),f=E.tag_name,m=lx(s,f),S=f.replace(/^v/,""),v=sT[S];i({currentVersion:s,latestVersion:f,updateAvailable:m,releaseUrl:E.html_url,featureHighlight:v})}catch(s){console.debug("Update check failed:",s)}})()},[]),r}const dx="curl -fsSL https://plannotator.ai/install.sh | bash",lp="rm -rf ~/.cache/opencode/node_modules/@plannotator ~/.bun/install/cache/@plannotator",ux=({origin:r})=>{const i=cx(),[c,s]=_.useState(!1),[u,d]=_.useState(!1),[b,E]=_.useState(!1),v=(new URLSearchParams(window.location.search).get("preview-origin")||r)==="opencode";if(!i?.updateAvailable||b)return null;const h=async()=>{try{await navigator.clipboard.writeText(v?lp:dx),s(!0),setTimeout(()=>s(!1),2e3)}catch(I){console.error("Failed to copy:",I)}},O=async()=>{try{await navigator.clipboard.writeText(lp),d(!0),setTimeout(()=>d(!1),2e3)}catch(I){console.error("Failed to copy:",I)}};return i.featureHighlight?p.jsx("div",{className:"fixed bottom-4 right-4 z-50 max-w-md animate-in slide-in-from-bottom-2 fade-in duration-300",children:p.jsxs("div",{className:"bg-card border border-primary/30 rounded-xl shadow-2xl overflow-hidden",children:[p.jsx("div",{className:"bg-gradient-to-r from-primary/20 to-primary/5 px-5 py-4 border-b border-border/50",children:p.jsxs("div",{className:"flex items-start justify-between gap-3",children:[p.jsxs("div",{className:"flex items-center gap-3",children:[p.jsx("div",{className:"flex-shrink-0 w-10 h-10 rounded-lg bg-primary/20 flex items-center justify-center",children:p.jsx("svg",{className:"w-5 h-5 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})})}),p.jsxs("div",{children:[p.jsx("h4",{className:"text-base font-semibold text-foreground",children:i.featureHighlight.title}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:["New in ",i.latestVersion]})]})]}),p.jsx("button",{onClick:()=>E(!0),className:"text-muted-foreground hover:text-foreground transition-colors p-1",children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})}),p.jsxs("div",{className:"px-5 py-4",children:[p.jsx("p",{className:"text-sm text-foreground/80 leading-relaxed",children:i.featureHighlight.description}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-3",children:["You have ",i.currentVersion]}),v&&p.jsxs("div",{className:"mt-3 p-3 bg-muted/50 rounded-lg",children:[p.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:"Clear cache to update:"}),p.jsxs("div",{className:"flex items-center gap-2",children:[p.jsx("code",{className:"flex-1 text-[10px] font-mono text-foreground/70 bg-background/50 px-2 py-1 rounded truncate",children:lp}),p.jsx("button",{onClick:O,className:"px-2 py-1 text-xs font-medium text-muted-foreground hover:text-foreground border border-border rounded hover:bg-muted transition-colors",children:u?"Copied!":"Copy"})]})]}),p.jsxs("div",{className:"mt-4 flex items-center gap-2",children:[!v&&p.jsx("button",{onClick:h,className:"flex-1 px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity",children:c?"Copied!":"Copy install command"}),p.jsx("a",{href:i.releaseUrl,target:"_blank",rel:"noopener noreferrer",className:\`px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground border border-border rounded-lg hover:bg-muted transition-colors \${v?"flex-1 text-center":""}\`,children:"Release notes"})]})]})]})}):p.jsx("div",{className:"fixed bottom-4 right-4 z-50 max-w-sm animate-in slide-in-from-bottom-2 fade-in duration-300",children:p.jsx("div",{className:"bg-card border border-border rounded-lg shadow-xl p-4",children:p.jsxs("div",{className:"flex items-start gap-3",children:[p.jsx("div",{className:"flex-shrink-0 w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center",children:p.jsx("svg",{className:"w-4 h-4 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"})})}),p.jsxs("div",{className:"flex-1 min-w-0",children:[p.jsxs("div",{className:"flex items-center justify-between gap-2",children:[p.jsx("h4",{className:"text-sm font-medium text-foreground",children:"Update available"}),p.jsx("button",{onClick:()=>E(!0),className:"text-muted-foreground hover:text-foreground transition-colors",children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:[i.latestVersion," is available (you have ",i.currentVersion,")"]}),p.jsxs("div",{className:"mt-3 flex items-center gap-2",children:[p.jsx("button",{onClick:h,className:"flex-1 px-3 py-1.5 text-xs font-medium bg-primary text-primary-foreground rounded-md hover:opacity-90 transition-opacity",children:c?"Copied!":"Copy install command"}),p.jsx("a",{href:i.releaseUrl,target:"_blank",rel:"noopener noreferrer",className:"px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground border border-border rounded-md hover:bg-muted transition-colors",children:"Notes"})]})]})]})})})},mx=\`# Implementation Plan: Real-time Collaboration
863
+ ---\`})]})]})]}),p.jsx("div",{className:"border-t border-border"}),p.jsxs("div",{className:"flex items-center justify-between",children:[p.jsxs("div",{children:[p.jsx("div",{className:"text-sm font-medium",children:"Bear Notes"}),p.jsx("div",{className:"text-xs text-muted-foreground",children:"Auto-save approved plans to Bear"})]}),p.jsx("button",{role:"switch","aria-checked":I.enabled,onClick:()=>z(!I.enabled),className:\`relative inline-flex h-6 w-11 items-center rounded-full transition-colors \${I.enabled?"bg-primary":"bg-muted"}\`,children:p.jsx("span",{className:\`inline-block h-4 w-4 transform rounded-full bg-white shadow-sm transition-transform \${I.enabled?"translate-x-6":"translate-x-1"}\`})})]})]})]})]})}),document.body)]})};async function _A(r){const i=JSON.stringify(r),c=new TextEncoder().encode(i),s=new CompressionStream("deflate-raw"),u=s.writable.getWriter();u.write(c),u.close();const d=await new Response(s.readable).arrayBuffer(),b=new Uint8Array(d);return btoa(String.fromCharCode(...b)).replace(/\\+/g,"-").replace(/\\//g,"_").replace(/=/g,"")}async function $A(r){const i=r.replace(/-/g,"+").replace(/_/g,"/"),c=atob(i),s=Uint8Array.from(c,f=>f.charCodeAt(0)),u=new DecompressionStream("deflate-raw"),d=u.writable.getWriter();d.write(s),d.close();const b=await new Response(u.readable).arrayBuffer(),E=new TextDecoder().decode(b);return JSON.parse(E)}function ex(r){return r.map(i=>{const c=i.author||null,s=i.imagePaths?.length?i.imagePaths:void 0;if(i.type===st.GLOBAL_COMMENT)return["G",i.text||"",c,s];const u=i.type[0];return u==="D"?["D",i.originalText,c,s]:[u,i.originalText,i.text||"",c,s]})}function tx(r){const i={D:st.DELETION,R:st.REPLACEMENT,C:st.COMMENT,I:st.INSERTION,G:st.GLOBAL_COMMENT};return r.map((c,s)=>{const u=c[0];if(u==="G"){const m=c[1],S=c[2],v=c[3];return{id:\`shared-\${s}-\${Date.now()}\`,blockId:"",startOffset:0,endOffset:0,type:st.GLOBAL_COMMENT,text:m||void 0,originalText:"",createdA:Date.now()+s,author:S||void 0,imagePaths:v?.length?v:void 0}}const d=c[1],b=u==="D"?void 0:c[2],E=u==="D"?c[2]:c[3],f=u==="D"?c[3]:c[4];return{id:\`shared-\${s}-\${Date.now()}\`,blockId:"",startOffset:0,endOffset:0,type:i[u],text:b||void 0,originalText:d,createdA:Date.now()+s,author:E||void 0,imagePaths:f?.length?f:void 0}})}const nx="https://share.plannotator.ai";async function ax(r,i,c){const s={p:r,a:ex(i),g:c?.length?c:void 0},u=await _A(s);return\`\${nx}/#\${u}\`}async function ix(){const r=window.location.hash.slice(1);if(!r)return null;try{return await $A(r)}catch(i){return console.warn("Failed to parse share hash:",i),null}}function rx(r){const i=new Blob([r]).size;return i<1024?\`\${i} B\`:\`\${(i/1024).toFixed(1)} KB\`}function ox(r,i,c,s,u,d,b){const[E,f]=_.useState(!1),[m,S]=_.useState(!0),[v,h]=_.useState(""),[O,T]=_.useState(""),[I,y]=_.useState(null),[C,A]=_.useState(null),D=_.useCallback(()=>{y(null),A(null)},[]),j=_.useCallback(async()=>{try{const z=await ix();if(z){s(z.p);const Y=tx(z.a);return u(Y),z.g?.length&&(d(z.g),A(z.g)),y(Y),f(!0),b?.(),window.history.replaceState({},"",window.location.pathname),!0}return!1}catch(z){return console.error("Failed to load from share hash:",z),!1}},[s,u,d,b]);_.useEffect(()=>{j().finally(()=>S(!1))},[]),_.useEffect(()=>{const z=()=>{window.location.hash.length>1&&j()};return window.addEventListener("hashchange",z),()=>window.removeEventListener("hashchange",z)},[j]);const F=_.useCallback(async()=>{try{const z=await ax(r,i,c);h(z),T(rx(z))}catch(z){console.error("Failed to generate share URL:",z),h(""),T("")}},[r,i,c]);return _.useEffect(()=>{F()},[F]),{isSharedSession:E,isLoadingShared:m,shareUrl:v,shareUrlSize:O,pendingSharedAnnotations:I,sharedGlobalAttachments:C,clearPendingSharedAnnotations:D,refreshShareUrl:F}}const sx="https://api.github.com/repos/backnotprop/plannotator/releases/latest",sT={"0.5.0":{title:"Code Review is here!",description:"Review git diffs with inline annotations. Run /plannotator-review to try it."}};function lx(r,i){const c=d=>d.replace(/^v/,""),s=c(r).split(".").map(Number),u=c(i).split(".").map(Number);for(let d=0;d<Math.max(s.length,u.length);d++){const b=s[d]||0,E=u[d]||0;if(E>b)return!0;if(E<b)return!1}return!1}function cx(){const[r,i]=_.useState(null);return _.useEffect(()=>{(async()=>{try{const s="0.5.2",d=new URLSearchParams(window.location.search).get("preview-update");if(d){const h=d.replace(/^v/,"");i({currentVersion:s,latestVersion:d,updateAvailable:!0,releaseUrl:\`https://github.com/backnotprop/plannotator/releases/tag/v\${h}\`,featureHighlight:sT[h]});return}const b=await fetch(sx);if(!b.ok)return;const E=await b.json(),f=E.tag_name,m=lx(s,f),S=f.replace(/^v/,""),v=sT[S];i({currentVersion:s,latestVersion:f,updateAvailable:m,releaseUrl:E.html_url,featureHighlight:v})}catch(s){console.debug("Update check failed:",s)}})()},[]),r}const dx="curl -fsSL https://plannotator.ai/install.sh | bash",lp="rm -rf ~/.cache/opencode/node_modules/@plannotator ~/.bun/install/cache/@plannotator",ux=({origin:r})=>{const i=cx(),[c,s]=_.useState(!1),[u,d]=_.useState(!1),[b,E]=_.useState(!1),v=(new URLSearchParams(window.location.search).get("preview-origin")||r)==="opencode";if(!i?.updateAvailable||b)return null;const h=async()=>{try{await navigator.clipboard.writeText(v?lp:dx),s(!0),setTimeout(()=>s(!1),2e3)}catch(I){console.error("Failed to copy:",I)}},O=async()=>{try{await navigator.clipboard.writeText(lp),d(!0),setTimeout(()=>d(!1),2e3)}catch(I){console.error("Failed to copy:",I)}};return i.featureHighlight?p.jsx("div",{className:"fixed bottom-4 right-4 z-50 max-w-md animate-in slide-in-from-bottom-2 fade-in duration-300",children:p.jsxs("div",{className:"bg-card border border-primary/30 rounded-xl shadow-2xl overflow-hidden",children:[p.jsx("div",{className:"bg-gradient-to-r from-primary/20 to-primary/5 px-5 py-4 border-b border-border/50",children:p.jsxs("div",{className:"flex items-start justify-between gap-3",children:[p.jsxs("div",{className:"flex items-center gap-3",children:[p.jsx("div",{className:"flex-shrink-0 w-10 h-10 rounded-lg bg-primary/20 flex items-center justify-center",children:p.jsx("svg",{className:"w-5 h-5 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})})}),p.jsxs("div",{children:[p.jsx("h4",{className:"text-base font-semibold text-foreground",children:i.featureHighlight.title}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:["New in ",i.latestVersion]})]})]}),p.jsx("button",{onClick:()=>E(!0),className:"text-muted-foreground hover:text-foreground transition-colors p-1",children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})}),p.jsxs("div",{className:"px-5 py-4",children:[p.jsx("p",{className:"text-sm text-foreground/80 leading-relaxed",children:i.featureHighlight.description}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-3",children:["You have ",i.currentVersion]}),v&&p.jsxs("div",{className:"mt-3 p-3 bg-muted/50 rounded-lg",children:[p.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:"Clear cache to update:"}),p.jsxs("div",{className:"flex items-center gap-2",children:[p.jsx("code",{className:"flex-1 text-[10px] font-mono text-foreground/70 bg-background/50 px-2 py-1 rounded truncate",children:lp}),p.jsx("button",{onClick:O,className:"px-2 py-1 text-xs font-medium text-muted-foreground hover:text-foreground border border-border rounded hover:bg-muted transition-colors",children:u?"Copied!":"Copy"})]})]}),p.jsxs("div",{className:"mt-4 flex items-center gap-2",children:[!v&&p.jsx("button",{onClick:h,className:"flex-1 px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-lg hover:opacity-90 transition-opacity",children:c?"Copied!":"Copy install command"}),p.jsx("a",{href:i.releaseUrl,target:"_blank",rel:"noopener noreferrer",className:\`px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground border border-border rounded-lg hover:bg-muted transition-colors \${v?"flex-1 text-center":""}\`,children:"Release notes"})]})]})]})}):p.jsx("div",{className:"fixed bottom-4 right-4 z-50 max-w-sm animate-in slide-in-from-bottom-2 fade-in duration-300",children:p.jsx("div",{className:"bg-card border border-border rounded-lg shadow-xl p-4",children:p.jsxs("div",{className:"flex items-start gap-3",children:[p.jsx("div",{className:"flex-shrink-0 w-8 h-8 rounded-full bg-primary/20 flex items-center justify-center",children:p.jsx("svg",{className:"w-4 h-4 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"})})}),p.jsxs("div",{className:"flex-1 min-w-0",children:[p.jsxs("div",{className:"flex items-center justify-between gap-2",children:[p.jsx("h4",{className:"text-sm font-medium text-foreground",children:"Update available"}),p.jsx("button",{onClick:()=>E(!0),className:"text-muted-foreground hover:text-foreground transition-colors",children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),p.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:[i.latestVersion," is available (you have ",i.currentVersion,")"]}),p.jsxs("div",{className:"mt-3 flex items-center gap-2",children:[p.jsx("button",{onClick:h,className:"flex-1 px-3 py-1.5 text-xs font-medium bg-primary text-primary-foreground rounded-md hover:opacity-90 transition-opacity",children:c?"Copied!":"Copy install command"}),p.jsx("a",{href:i.releaseUrl,target:"_blank",rel:"noopener noreferrer",className:"px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground border border-border rounded-md hover:bg-muted transition-colors",children:"Notes"})]})]})]})})})},mx=\`# Implementation Plan: Real-time Collaboration
864
864
 
865
865
  ## Overview
866
866
  Add real-time collaboration features to the editor using WebSocket connections and operational transforms.
@@ -1134,7 +1134,7 @@ export const CursorOverlay: React.FC<CursorOverlayProps> = ({
1134
1134
  ---
1135
1135
 
1136
1136
  **Target:** Ship MVP in next sprint
1137
- \`,px=()=>{const[r,i]=_.useState(mx),[c,s]=_.useState([]),[u,d]=_.useState(null),[b,E]=_.useState([]),[f,m]=_.useState(null),[S,v]=_.useState(!1),[h,O]=_.useState(!1),[T,I]=_.useState(!1),[y,C]=_.useState(!0),[A,D]=_.useState("selection"),[j,F]=_.useState(()=>bt.getItem("plannotator-tater-mode")==="true"),[z,Y]=_.useState(!1),[N,G]=_.useState(null),[w,M]=_.useState([]),[q,W]=_.useState(!0),[ae,ce]=_.useState(!1),[P,K]=_.useState(null),[Z,se]=_.useState(null),ue=_.useRef(null),{isSharedSession:x,isLoadingShared:X,shareUrl:re,shareUrlSize:me,pendingSharedAnnotations:Ee,clearPendingSharedAnnotations:ee}=ox(r,c,w,i,s,M,()=>{W(!1)});_.useEffect(()=>{if(Ee&&Ee.length>0){const Re=setTimeout(()=>{ue.current?.clearAllHighlights(),ue.current?.applySharedAnnotations(Ee),ee()},100);return()=>clearTimeout(Re)}},[Ee,ee]);const le=Re=>{F(Re),bt.setItem("plannotator-tater-mode",String(Re))};_.useEffect(()=>{X||x||fetch("/api/plan").then(Re=>{if(!Re.ok)throw new Error("Not in API mode");return Re.json()}).then(Re=>{i(Re.plan),Y(!0),Re.origin&&G(Re.origin)}).catch(()=>{Y(!1)}).finally(()=>W(!1))},[X,x]),_.useEffect(()=>{const{frontmatter:Re}=cT(r);m(Re),E(WO(r))},[r]),_.useEffect(()=>{const Re=Be=>{const ft=Be.clipboardData?.items;if(ft){for(const kt of ft)if(kt.type.startsWith("image/")){Be.preventDefault();const yt=kt.getAsFile();if(yt){const Ze=URL.createObjectURL(yt);se({file:yt,blobUrl:Ze})}break}}};return document.addEventListener("paste",Re),()=>document.removeEventListener("paste",Re)},[]);const oe=async(Re,Be)=>{if(Z)try{const ft=new FormData,kt=Be?new File([Re],"annotated.png",{type:"image/png"}):Z.file;ft.append("file",kt);const yt=await fetch("/api/upload",{method:"POST",body:ft});if(yt.ok){const{path:Ze}=await yt.json();M(bn=>[...bn,Ze])}}catch{}finally{URL.revokeObjectURL(Z.blobUrl),se(null)}},fe=()=>{Z&&(URL.revokeObjectURL(Z.blobUrl),se(null))},Ce=async()=>{ce(!0);try{const Re=NT(),Be=xT(),ft=LT(),kt=gp(),yt={},Ze=XA(ft);Ze&&(yt.agentSwitch=Ze),yt.planSave={enabled:kt.enabled,...kt.customPath&&{customPath:kt.customPath}},Re.enabled&&Re.vaultPath&&(yt.obsidian={vaultPath:Re.vaultPath,folder:Re.folder||"plannotator",plan:r}),Be.enabled&&(yt.bear={plan:r}),(c.length>0||w.length>0)&&(yt.feedback=xt),await fetch("/api/approve",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(yt)}),K("approved")}catch{ce(!1)}},Ne=async()=>{ce(!0);try{const Re=gp();await fetch("/api/deny",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({feedback:xt,planSave:{enabled:Re.enabled,...Re.customPath&&{customPath:Re.customPath}}})}),K("denied")}catch{ce(!1)}},Le=Re=>{s(Be=>[...Be,Re]),d(Re.id),C(!0)},je=Re=>{ue.current?.removeHighlight(Re),s(Be=>Be.filter(ft=>ft.id!==Re)),u===Re&&d(null)},Fe=(Re,Be)=>{s(ft=>ft.map(kt=>kt.author===Re?{...kt,author:Be}:kt))},Et=Re=>{M(Be=>[...Be,Re])},Qe=Re=>{M(Be=>Be.filter(ft=>ft!==Re))},xt=_.useMemo(()=>XO(b,c,w),[b,c,w]),nt=_.useMemo(()=>N==="opencode"?"OpenCode":N==="claude-code"?"Claude Code":"Coding Agent",[N]);return p.jsx(LA,{defaultTheme:"dark",children:p.jsxs("div",{className:"h-screen flex flex-col bg-background overflow-hidden",children:[j&&p.jsx(qA,{}),p.jsxs("header",{className:"h-12 flex items-center justify-between px-2 md:px-4 border-b border-border/50 bg-card/50 backdrop-blur-xl z-50",children:[p.jsxs("div",{className:"flex items-center gap-2 md:gap-3",children:[p.jsx("a",{href:"https://plannotator.ai",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-1.5 md:gap-2 hover:opacity-80 transition-opacity",children:p.jsx("span",{className:"text-sm font-semibold tracking-tight",children:"Plannotator"})}),p.jsxs("a",{href:"https://github.com/backnotprop/plannotator/releases",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-muted-foreground font-mono opacity-60 hidden md:inline hover:opacity-100 transition-opacity",children:["v","0.5.1"]}),N&&p.jsx("span",{className:\`text-[10px] px-1.5 py-0.5 rounded font-medium hidden md:inline \${N==="claude-code"?"bg-orange-500/15 text-orange-400":"bg-zinc-500/20 text-zinc-400"}\`,children:nt})]}),p.jsxs("div",{className:"flex items-center gap-1 md:gap-2",children:[z&&p.jsxs(p.Fragment,{children:[p.jsxs("button",{onClick:()=>{c.length===0?O(!0):Ne()},disabled:ae,className:\`p-1.5 md:px-2.5 md:py-1 rounded-md text-xs font-medium transition-all \${ae?"opacity-50 cursor-not-allowed bg-muted text-muted-foreground":"bg-accent/15 text-accent hover:bg-accent/25 border border-accent/30"}\`,title:"Send Feedback",children:[p.jsx("svg",{className:"w-4 h-4 md:hidden",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})}),p.jsx("span",{className:"hidden md:inline",children:ae?"Sending...":"Send Feedback"})]}),p.jsxs("div",{className:"relative group/approve",children:[p.jsxs("button",{onClick:()=>{N==="claude-code"&&c.length>0?I(!0):Ce()},disabled:ae,className:\`px-2 py-1 md:px-2.5 rounded-md text-xs font-medium transition-all \${ae?"opacity-50 cursor-not-allowed bg-muted text-muted-foreground":N==="claude-code"&&c.length>0?"bg-success/50 text-success-foreground/70 hover:bg-success hover:text-success-foreground":"bg-success text-success-foreground hover:opacity-90"}\`,children:[p.jsx("span",{className:"md:hidden",children:ae?"...":"OK"}),p.jsx("span",{className:"hidden md:inline",children:ae?"Approving...":"Approve"})]}),N==="claude-code"&&c.length>0&&p.jsxs("div",{className:"absolute top-full right-0 mt-2 px-3 py-2 bg-popover border border-border rounded-lg shadow-xl text-xs text-foreground w-56 text-center opacity-0 invisible group-hover/approve:opacity-100 group-hover/approve:visible transition-all pointer-events-none z-50",children:[p.jsx("div",{className:"absolute bottom-full right-4 border-4 border-transparent border-b-border"}),p.jsx("div",{className:"absolute bottom-full right-4 mt-px border-4 border-transparent border-b-popover"}),nt," doesn't support feedback on approval. Your annotations won't be seen."]})]}),p.jsx("div",{className:"w-px h-5 bg-border/50 mx-1 hidden md:block"})]}),p.jsx(kA,{}),p.jsx(ZA,{taterMode:j,onTaterModeChange:le,onIdentityChange:Fe,origin:N}),p.jsx("button",{onClick:()=>C(!y),className:\`p-1.5 rounded-md text-xs font-medium transition-all \${y?"bg-primary/15 text-primary":"text-muted-foreground hover:text-foreground hover:bg-muted"}\`,children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"})})}),p.jsxs("button",{onClick:()=>v(!0),className:"p-1.5 md:px-2.5 md:py-1 rounded-md text-xs font-medium bg-muted hover:bg-muted/80 transition-colors",title:"Export",children:[p.jsx("svg",{className:"w-4 h-4 md:hidden",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"})}),p.jsx("span",{className:"hidden md:inline",children:"Export"})]})]})]}),p.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[p.jsx("main",{className:"flex-1 overflow-y-auto bg-grid",children:p.jsxs("div",{className:"min-h-full flex flex-col items-center px-4 py-3 md:px-10 md:py-8 xl:px-16",children:[p.jsx("div",{className:"w-full max-w-[832px] 2xl:max-w-5xl mb-3 md:mb-4 flex justify-start",children:p.jsx(FA,{mode:A,onChange:D,taterMode:j})}),p.jsx(yA,{ref:ue,blocks:b,markdown:r,frontmatter:f,annotations:c,onAddAnnotation:Le,onSelectAnnotation:d,selectedAnnotationId:u,mode:A,taterMode:j,globalAttachments:w,onAddGlobalAttachment:Et,onRemoveGlobalAttachment:Qe})]})}),p.jsx(AA,{isOpen:y,blocks:b,annotations:c,selectedId:u,onSelect:d,onDelete:je,shareUrl:re})]}),p.jsx(MA,{isOpen:S,onClose:()=>v(!1),shareUrl:re,shareUrlSize:me,diffOutput:xt,annotationCount:c.length,taterSprite:j?p.jsx(Sp,{}):void 0}),p.jsx(nT,{isOpen:h,onClose:()=>O(!1),title:"Add Annotations First",message:\`To provide feedback, select text in the plan and add annotations. \${nt} will use your annotations to revise the plan.\`,variant:"info"}),p.jsx(nT,{isOpen:T,onClose:()=>I(!1),onConfirm:()=>{I(!1),Ce()},title:"Annotations Won't Be Sent",message:p.jsxs(p.Fragment,{children:[nt," doesn't yet support feedback on approval. Your ",c.length," annotation",c.length!==1?"s":""," will be lost."]}),subMessage:p.jsxs(p.Fragment,{children:["To send feedback, use ",p.jsx("strong",{children:"Send Feedback"})," instead.",p.jsx("br",{}),p.jsx("br",{}),"Want this feature? Upvote these issues:",p.jsx("br",{}),p.jsx("a",{href:"https://github.com/anthropics/claude-code/issues/16001",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"#16001"})," \xB7 ",p.jsx("a",{href:"https://github.com/anthropics/claude-code/issues/15755",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"#15755"})]}),confirmText:"Approve Anyway",cancelText:"Cancel",variant:"warning",showCancel:!0}),P&&p.jsx("div",{className:"fixed inset-0 z-[100] bg-background flex items-center justify-center",children:p.jsxs("div",{className:"text-center space-y-6 max-w-md px-8",children:[p.jsx("div",{className:\`mx-auto w-16 h-16 rounded-full flex items-center justify-center \${P==="approved"?"bg-success/20 text-success":"bg-accent/20 text-accent"}\`,children:P==="approved"?p.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):p.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})})}),p.jsxs("div",{className:"space-y-2",children:[p.jsx("h2",{className:"text-xl font-semibold text-foreground",children:P==="approved"?"Plan Approved":"Feedback Sent"}),p.jsx("p",{className:"text-muted-foreground",children:P==="approved"?\`\${nt} will proceed with the implementation.\`:\`\${nt} will revise the plan based on your annotations.\`})]}),p.jsxs("div",{className:"pt-4 border-t border-border space-y-2",children:[p.jsxs("p",{className:"text-sm text-muted-foreground",children:["You can close this tab and return to ",p.jsx("span",{className:"text-foreground font-medium",children:nt}),"."]}),p.jsx("p",{className:"text-xs text-muted-foreground/60",children:"Your response has been sent."})]})]})}),p.jsx(ux,{origin:N}),p.jsx(pT,{isOpen:!!Z,imageSrc:Z?.blobUrl??"",onAccept:oe,onClose:fe})]})})},kT=document.getElementById("root");if(!kT)throw new Error("Could not find root element to mount to");const gx=jO.createRoot(kT);gx.render(p.jsx(GO.StrictMode,{children:p.jsx(px,{})}));</script>
1137
+ \`,px=()=>{const[r,i]=_.useState(mx),[c,s]=_.useState([]),[u,d]=_.useState(null),[b,E]=_.useState([]),[f,m]=_.useState(null),[S,v]=_.useState(!1),[h,O]=_.useState(!1),[T,I]=_.useState(!1),[y,C]=_.useState(!0),[A,D]=_.useState("selection"),[j,F]=_.useState(()=>bt.getItem("plannotator-tater-mode")==="true"),[z,Y]=_.useState(!1),[N,G]=_.useState(null),[w,M]=_.useState([]),[q,W]=_.useState(!0),[ae,ce]=_.useState(!1),[P,K]=_.useState(null),[Z,se]=_.useState(null),ue=_.useRef(null),{isSharedSession:x,isLoadingShared:X,shareUrl:re,shareUrlSize:me,pendingSharedAnnotations:Ee,clearPendingSharedAnnotations:ee}=ox(r,c,w,i,s,M,()=>{W(!1)});_.useEffect(()=>{if(Ee&&Ee.length>0){const Re=setTimeout(()=>{ue.current?.clearAllHighlights(),ue.current?.applySharedAnnotations(Ee),ee()},100);return()=>clearTimeout(Re)}},[Ee,ee]);const le=Re=>{F(Re),bt.setItem("plannotator-tater-mode",String(Re))};_.useEffect(()=>{X||x||fetch("/api/plan").then(Re=>{if(!Re.ok)throw new Error("Not in API mode");return Re.json()}).then(Re=>{i(Re.plan),Y(!0),Re.origin&&G(Re.origin)}).catch(()=>{Y(!1)}).finally(()=>W(!1))},[X,x]),_.useEffect(()=>{const{frontmatter:Re}=cT(r);m(Re),E(WO(r))},[r]),_.useEffect(()=>{const Re=Be=>{const ft=Be.clipboardData?.items;if(ft){for(const kt of ft)if(kt.type.startsWith("image/")){Be.preventDefault();const yt=kt.getAsFile();if(yt){const Ze=URL.createObjectURL(yt);se({file:yt,blobUrl:Ze})}break}}};return document.addEventListener("paste",Re),()=>document.removeEventListener("paste",Re)},[]);const oe=async(Re,Be)=>{if(Z)try{const ft=new FormData,kt=Be?new File([Re],"annotated.png",{type:"image/png"}):Z.file;ft.append("file",kt);const yt=await fetch("/api/upload",{method:"POST",body:ft});if(yt.ok){const{path:Ze}=await yt.json();M(bn=>[...bn,Ze])}}catch{}finally{URL.revokeObjectURL(Z.blobUrl),se(null)}},fe=()=>{Z&&(URL.revokeObjectURL(Z.blobUrl),se(null))},Ce=async()=>{ce(!0);try{const Re=NT(),Be=xT(),ft=LT(),kt=gp(),yt={},Ze=XA(ft);Ze&&(yt.agentSwitch=Ze),yt.planSave={enabled:kt.enabled,...kt.customPath&&{customPath:kt.customPath}},Re.enabled&&Re.vaultPath&&(yt.obsidian={vaultPath:Re.vaultPath,folder:Re.folder||"plannotator",plan:r}),Be.enabled&&(yt.bear={plan:r}),(c.length>0||w.length>0)&&(yt.feedback=xt),await fetch("/api/approve",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(yt)}),K("approved")}catch{ce(!1)}},Ne=async()=>{ce(!0);try{const Re=gp();await fetch("/api/deny",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({feedback:xt,planSave:{enabled:Re.enabled,...Re.customPath&&{customPath:Re.customPath}}})}),K("denied")}catch{ce(!1)}},Le=Re=>{s(Be=>[...Be,Re]),d(Re.id),C(!0)},je=Re=>{ue.current?.removeHighlight(Re),s(Be=>Be.filter(ft=>ft.id!==Re)),u===Re&&d(null)},Fe=(Re,Be)=>{s(ft=>ft.map(kt=>kt.author===Re?{...kt,author:Be}:kt))},Et=Re=>{M(Be=>[...Be,Re])},Qe=Re=>{M(Be=>Be.filter(ft=>ft!==Re))},xt=_.useMemo(()=>XO(b,c,w),[b,c,w]),nt=_.useMemo(()=>N==="opencode"?"OpenCode":N==="claude-code"?"Claude Code":"Coding Agent",[N]);return p.jsx(LA,{defaultTheme:"dark",children:p.jsxs("div",{className:"h-screen flex flex-col bg-background overflow-hidden",children:[j&&p.jsx(qA,{}),p.jsxs("header",{className:"h-12 flex items-center justify-between px-2 md:px-4 border-b border-border/50 bg-card/50 backdrop-blur-xl z-50",children:[p.jsxs("div",{className:"flex items-center gap-2 md:gap-3",children:[p.jsx("a",{href:"https://plannotator.ai",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-1.5 md:gap-2 hover:opacity-80 transition-opacity",children:p.jsx("span",{className:"text-sm font-semibold tracking-tight",children:"Plannotator"})}),p.jsxs("a",{href:"https://github.com/backnotprop/plannotator/releases",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-muted-foreground font-mono opacity-60 hidden md:inline hover:opacity-100 transition-opacity",children:["v","0.5.2"]}),N&&p.jsx("span",{className:\`text-[10px] px-1.5 py-0.5 rounded font-medium hidden md:inline \${N==="claude-code"?"bg-orange-500/15 text-orange-400":"bg-zinc-500/20 text-zinc-400"}\`,children:nt})]}),p.jsxs("div",{className:"flex items-center gap-1 md:gap-2",children:[z&&p.jsxs(p.Fragment,{children:[p.jsxs("button",{onClick:()=>{c.length===0?O(!0):Ne()},disabled:ae,className:\`p-1.5 md:px-2.5 md:py-1 rounded-md text-xs font-medium transition-all \${ae?"opacity-50 cursor-not-allowed bg-muted text-muted-foreground":"bg-accent/15 text-accent hover:bg-accent/25 border border-accent/30"}\`,title:"Send Feedback",children:[p.jsx("svg",{className:"w-4 h-4 md:hidden",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})}),p.jsx("span",{className:"hidden md:inline",children:ae?"Sending...":"Send Feedback"})]}),p.jsxs("div",{className:"relative group/approve",children:[p.jsxs("button",{onClick:()=>{N==="claude-code"&&c.length>0?I(!0):Ce()},disabled:ae,className:\`px-2 py-1 md:px-2.5 rounded-md text-xs font-medium transition-all \${ae?"opacity-50 cursor-not-allowed bg-muted text-muted-foreground":N==="claude-code"&&c.length>0?"bg-success/50 text-success-foreground/70 hover:bg-success hover:text-success-foreground":"bg-success text-success-foreground hover:opacity-90"}\`,children:[p.jsx("span",{className:"md:hidden",children:ae?"...":"OK"}),p.jsx("span",{className:"hidden md:inline",children:ae?"Approving...":"Approve"})]}),N==="claude-code"&&c.length>0&&p.jsxs("div",{className:"absolute top-full right-0 mt-2 px-3 py-2 bg-popover border border-border rounded-lg shadow-xl text-xs text-foreground w-56 text-center opacity-0 invisible group-hover/approve:opacity-100 group-hover/approve:visible transition-all pointer-events-none z-50",children:[p.jsx("div",{className:"absolute bottom-full right-4 border-4 border-transparent border-b-border"}),p.jsx("div",{className:"absolute bottom-full right-4 mt-px border-4 border-transparent border-b-popover"}),nt," doesn't support feedback on approval. Your annotations won't be seen."]})]}),p.jsx("div",{className:"w-px h-5 bg-border/50 mx-1 hidden md:block"})]}),p.jsx(kA,{}),p.jsx(ZA,{taterMode:j,onTaterModeChange:le,onIdentityChange:Fe,origin:N}),p.jsx("button",{onClick:()=>C(!y),className:\`p-1.5 rounded-md text-xs font-medium transition-all \${y?"bg-primary/15 text-primary":"text-muted-foreground hover:text-foreground hover:bg-muted"}\`,children:p.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"})})}),p.jsxs("button",{onClick:()=>v(!0),className:"p-1.5 md:px-2.5 md:py-1 rounded-md text-xs font-medium bg-muted hover:bg-muted/80 transition-colors",title:"Export",children:[p.jsx("svg",{className:"w-4 h-4 md:hidden",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"})}),p.jsx("span",{className:"hidden md:inline",children:"Export"})]})]})]}),p.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[p.jsx("main",{className:"flex-1 overflow-y-auto bg-grid",children:p.jsxs("div",{className:"min-h-full flex flex-col items-center px-4 py-3 md:px-10 md:py-8 xl:px-16",children:[p.jsx("div",{className:"w-full max-w-[832px] 2xl:max-w-5xl mb-3 md:mb-4 flex justify-start",children:p.jsx(FA,{mode:A,onChange:D,taterMode:j})}),p.jsx(yA,{ref:ue,blocks:b,markdown:r,frontmatter:f,annotations:c,onAddAnnotation:Le,onSelectAnnotation:d,selectedAnnotationId:u,mode:A,taterMode:j,globalAttachments:w,onAddGlobalAttachment:Et,onRemoveGlobalAttachment:Qe})]})}),p.jsx(AA,{isOpen:y,blocks:b,annotations:c,selectedId:u,onSelect:d,onDelete:je,shareUrl:re})]}),p.jsx(MA,{isOpen:S,onClose:()=>v(!1),shareUrl:re,shareUrlSize:me,diffOutput:xt,annotationCount:c.length,taterSprite:j?p.jsx(Sp,{}):void 0}),p.jsx(nT,{isOpen:h,onClose:()=>O(!1),title:"Add Annotations First",message:\`To provide feedback, select text in the plan and add annotations. \${nt} will use your annotations to revise the plan.\`,variant:"info"}),p.jsx(nT,{isOpen:T,onClose:()=>I(!1),onConfirm:()=>{I(!1),Ce()},title:"Annotations Won't Be Sent",message:p.jsxs(p.Fragment,{children:[nt," doesn't yet support feedback on approval. Your ",c.length," annotation",c.length!==1?"s":""," will be lost."]}),subMessage:p.jsxs(p.Fragment,{children:["To send feedback, use ",p.jsx("strong",{children:"Send Feedback"})," instead.",p.jsx("br",{}),p.jsx("br",{}),"Want this feature? Upvote these issues:",p.jsx("br",{}),p.jsx("a",{href:"https://github.com/anthropics/claude-code/issues/16001",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"#16001"})," \xB7 ",p.jsx("a",{href:"https://github.com/anthropics/claude-code/issues/15755",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"#15755"})]}),confirmText:"Approve Anyway",cancelText:"Cancel",variant:"warning",showCancel:!0}),P&&p.jsx("div",{className:"fixed inset-0 z-[100] bg-background flex items-center justify-center",children:p.jsxs("div",{className:"text-center space-y-6 max-w-md px-8",children:[p.jsx("div",{className:\`mx-auto w-16 h-16 rounded-full flex items-center justify-center \${P==="approved"?"bg-success/20 text-success":"bg-accent/20 text-accent"}\`,children:P==="approved"?p.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):p.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,children:p.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})})}),p.jsxs("div",{className:"space-y-2",children:[p.jsx("h2",{className:"text-xl font-semibold text-foreground",children:P==="approved"?"Plan Approved":"Feedback Sent"}),p.jsx("p",{className:"text-muted-foreground",children:P==="approved"?\`\${nt} will proceed with the implementation.\`:\`\${nt} will revise the plan based on your annotations.\`})]}),p.jsxs("div",{className:"pt-4 border-t border-border space-y-2",children:[p.jsxs("p",{className:"text-sm text-muted-foreground",children:["You can close this tab and return to ",p.jsx("span",{className:"text-foreground font-medium",children:nt}),"."]}),p.jsx("p",{className:"text-xs text-muted-foreground/60",children:"Your response has been sent."})]})]})}),p.jsx(ux,{origin:N}),p.jsx(pT,{isOpen:!!Z,imageSrc:Z?.blobUrl??"",onAccept:oe,onClose:fe})]})})},kT=document.getElementById("root");if(!kT)throw new Error("Could not find root element to mount to");const gx=jO.createRoot(kT);gx.render(p.jsx(GO.StrictMode,{children:p.jsx(px,{})}));</script>
1138
1138
  <style rel="stylesheet" crossorigin>pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
1139
1139
  Theme: GitHub Dark
1140
1140
  Description: Dark theme as seen on github.com
@@ -2788,13 +2788,6 @@ Do NOT proceed with implementation until your plan is approved.
2788
2788
  });
2789
2789
  const gitContext = await getGitContext();
2790
2790
  const { patch: rawPatch, label: gitRef } = await runGitDiff("uncommitted", gitContext.defaultBranch);
2791
- if (!rawPatch.trim()) {
2792
- ctx.client.app.log({
2793
- level: "warn",
2794
- message: "No changes to review"
2795
- });
2796
- return;
2797
- }
2798
2791
  const server = await startReviewServer({
2799
2792
  rawPatch,
2800
2793
  gitRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plannotator/opencode",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Plannotator plugin for OpenCode - interactive plan review with visual annotation",
5
5
  "author": "backnotprop",
6
6
  "license": "BSL-1.1",