create-claudeportal 0.2.2 → 0.2.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.
@@ -129,4 +129,4 @@ ${e}</tr>
129
129
  `}tablecell(e){let i=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+i+`</${n}>
130
130
  `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${Ai(e,!0)}</code>`}br(e){return"<br>"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:i,tokens:n}){let l=this.parser.parseInline(n),o=vm(e);if(o===null)return l;e=o;let h='<a href="'+e+'"';return i&&(h+=' title="'+Ai(i)+'"'),h+=">"+l+"</a>",h}image({href:e,title:i,text:n,tokens:l}){l&&(n=this.parser.parseInline(l,this.parser.textRenderer));let o=vm(e);if(o===null)return Ai(n);e=o;let h=`<img src="${e}" alt="${Ai(n)}"`;return i&&(h+=` title="${Ai(i)}"`),h+=">",h}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:Ai(e.text)}},ad=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}checkbox({raw:e}){return e}},xi=class Wu{options;renderer;textRenderer;constructor(i){this.options=i||ur,this.options.renderer=this.options.renderer||new ao,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new ad}static parse(i,n){return new Wu(n).parse(i)}static parseInline(i,n){return new Wu(n).parseInline(i)}parse(i){let n="";for(let l=0;l<i.length;l++){let o=i[l];if(this.options.extensions?.renderers?.[o.type]){let d=o,_=this.options.extensions.renderers[d.type].call({parser:this},d);if(_!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(d.type)){n+=_||"";continue}}let h=o;switch(h.type){case"space":{n+=this.renderer.space(h);break}case"hr":{n+=this.renderer.hr(h);break}case"heading":{n+=this.renderer.heading(h);break}case"code":{n+=this.renderer.code(h);break}case"table":{n+=this.renderer.table(h);break}case"blockquote":{n+=this.renderer.blockquote(h);break}case"list":{n+=this.renderer.list(h);break}case"checkbox":{n+=this.renderer.checkbox(h);break}case"html":{n+=this.renderer.html(h);break}case"def":{n+=this.renderer.def(h);break}case"paragraph":{n+=this.renderer.paragraph(h);break}case"text":{n+=this.renderer.text(h);break}default:{let d='Token with "'+h.type+'" type was not found.';if(this.options.silent)return console.error(d),"";throw new Error(d)}}}return n}parseInline(i,n=this.renderer){let l="";for(let o=0;o<i.length;o++){let h=i[o];if(this.options.extensions?.renderers?.[h.type]){let _=this.options.extensions.renderers[h.type].call({parser:this},h);if(_!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(h.type)){l+=_||"";continue}}let d=h;switch(d.type){case"escape":{l+=n.text(d);break}case"html":{l+=n.html(d);break}case"link":{l+=n.link(d);break}case"image":{l+=n.image(d);break}case"checkbox":{l+=n.checkbox(d);break}case"strong":{l+=n.strong(d);break}case"em":{l+=n.em(d);break}case"codespan":{l+=n.codespan(d);break}case"br":{l+=n.br(d);break}case"del":{l+=n.del(d);break}case"text":{l+=n.text(d);break}default:{let _='Token with "'+d.type+'" type was not found.';if(this.options.silent)return console.error(_),"";throw new Error(_)}}}return l}},dl=class{options;block;constructor(e){this.options=e||ur}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?bi.lex:bi.lexInline}provideParser(){return this.block?xi.parse:xi.parseInline}},xC=class{defaults=Ju();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=xi;Renderer=ao;TextRenderer=ad;Lexer=bi;Tokenizer=lo;Hooks=dl;constructor(...e){this.use(...e)}walkTokens(e,i){let n=[];for(let l of e)switch(n=n.concat(i.call(this,l)),l.type){case"table":{let o=l;for(let h of o.header)n=n.concat(this.walkTokens(h.tokens,i));for(let h of o.rows)for(let d of h)n=n.concat(this.walkTokens(d.tokens,i));break}case"list":{let o=l;n=n.concat(this.walkTokens(o.items,i));break}default:{let o=l;this.defaults.extensions?.childTokens?.[o.type]?this.defaults.extensions.childTokens[o.type].forEach(h=>{let d=o[h].flat(1/0);n=n.concat(this.walkTokens(d,i))}):o.tokens&&(n=n.concat(this.walkTokens(o.tokens,i)))}}return n}use(...e){let i=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let l={...n};if(l.async=this.defaults.async||l.async||!1,n.extensions&&(n.extensions.forEach(o=>{if(!o.name)throw new Error("extension name required");if("renderer"in o){let h=i.renderers[o.name];h?i.renderers[o.name]=function(...d){let _=o.renderer.apply(this,d);return _===!1&&(_=h.apply(this,d)),_}:i.renderers[o.name]=o.renderer}if("tokenizer"in o){if(!o.level||o.level!=="block"&&o.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let h=i[o.level];h?h.unshift(o.tokenizer):i[o.level]=[o.tokenizer],o.start&&(o.level==="block"?i.startBlock?i.startBlock.push(o.start):i.startBlock=[o.start]:o.level==="inline"&&(i.startInline?i.startInline.push(o.start):i.startInline=[o.start]))}"childTokens"in o&&o.childTokens&&(i.childTokens[o.name]=o.childTokens)}),l.extensions=i),n.renderer){let o=this.defaults.renderer||new ao(this.defaults);for(let h in n.renderer){if(!(h in o))throw new Error(`renderer '${h}' does not exist`);if(["options","parser"].includes(h))continue;let d=h,_=n.renderer[d],p=o[d];o[d]=(...f)=>{let y=_.apply(o,f);return y===!1&&(y=p.apply(o,f)),y||""}}l.renderer=o}if(n.tokenizer){let o=this.defaults.tokenizer||new lo(this.defaults);for(let h in n.tokenizer){if(!(h in o))throw new Error(`tokenizer '${h}' does not exist`);if(["options","rules","lexer"].includes(h))continue;let d=h,_=n.tokenizer[d],p=o[d];o[d]=(...f)=>{let y=_.apply(o,f);return y===!1&&(y=p.apply(o,f)),y}}l.tokenizer=o}if(n.hooks){let o=this.defaults.hooks||new dl;for(let h in n.hooks){if(!(h in o))throw new Error(`hook '${h}' does not exist`);if(["options","block"].includes(h))continue;let d=h,_=n.hooks[d],p=o[d];dl.passThroughHooks.has(h)?o[d]=f=>{if(this.defaults.async&&dl.passThroughHooksRespectAsync.has(h))return(async()=>{let S=await _.call(o,f);return p.call(o,S)})();let y=_.call(o,f);return p.call(o,y)}:o[d]=(...f)=>{if(this.defaults.async)return(async()=>{let S=await _.apply(o,f);return S===!1&&(S=await p.apply(o,f)),S})();let y=_.apply(o,f);return y===!1&&(y=p.apply(o,f)),y}}l.hooks=o}if(n.walkTokens){let o=this.defaults.walkTokens,h=n.walkTokens;l.walkTokens=function(d){let _=[];return _.push(h.call(this,d)),o&&(_=_.concat(o.call(this,d))),_}}this.defaults={...this.defaults,...l}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,i){return bi.lex(e,i??this.defaults)}parser(e,i){return xi.parse(e,i??this.defaults)}parseMarkdown(e){return(i,n)=>{let l={...n},o={...this.defaults,...l},h=this.onError(!!o.silent,!!o.async);if(this.defaults.async===!0&&l.async===!1)return h(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof i>"u"||i===null)return h(new Error("marked(): input parameter is undefined or null"));if(typeof i!="string")return h(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(i)+", string expected"));if(o.hooks&&(o.hooks.options=o,o.hooks.block=e),o.async)return(async()=>{let d=o.hooks?await o.hooks.preprocess(i):i,_=await(o.hooks?await o.hooks.provideLexer():e?bi.lex:bi.lexInline)(d,o),p=o.hooks?await o.hooks.processAllTokens(_):_;o.walkTokens&&await Promise.all(this.walkTokens(p,o.walkTokens));let f=await(o.hooks?await o.hooks.provideParser():e?xi.parse:xi.parseInline)(p,o);return o.hooks?await o.hooks.postprocess(f):f})().catch(h);try{o.hooks&&(i=o.hooks.preprocess(i));let d=(o.hooks?o.hooks.provideLexer():e?bi.lex:bi.lexInline)(i,o);o.hooks&&(d=o.hooks.processAllTokens(d)),o.walkTokens&&this.walkTokens(d,o.walkTokens);let _=(o.hooks?o.hooks.provideParser():e?xi.parse:xi.parseInline)(d,o);return o.hooks&&(_=o.hooks.postprocess(_)),_}catch(d){return h(d)}}}onError(e,i){return n=>{if(n.message+=`
131
131
  Please report this to https://github.com/markedjs/marked.`,e){let l="<p>An error occurred:</p><pre>"+Ai(n.message+"",!0)+"</pre>";return i?Promise.resolve(l):l}if(i)return Promise.reject(n);throw n}}},cr=new xC;function Le(e,i){return cr.parse(e,i)}Le.options=Le.setOptions=function(e){return cr.setOptions(e),Le.defaults=cr.defaults,kv(Le.defaults),Le};Le.getDefaults=Ju;Le.defaults=ur;Le.use=function(...e){return cr.use(...e),Le.defaults=cr.defaults,kv(Le.defaults),Le};Le.walkTokens=function(e,i){return cr.walkTokens(e,i)};Le.parseInline=cr.parseInline;Le.Parser=xi;Le.parser=xi.parse;Le.Renderer=ao;Le.TextRenderer=ad;Le.Lexer=bi;Le.lexer=bi.lex;Le.Tokenizer=lo;Le.Hooks=dl;Le.parse=Le;Le.options;Le.setOptions;Le.use;Le.walkTokens;Le.parseInline;xi.parse;bi.lex;function wC(e){return e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/\bon\w+\s*=\s*"[^"]*"/gi,"").replace(/\bon\w+\s*=\s*'[^']*'/gi,"").replace(/javascript\s*:/gi,"")}function bm(e){const i=[];let n="",l=!1;for(const o of e){if(o==='"'){l=!l;continue}if(o===","&&!l){i.push(n.trim()),n="";continue}n+=o}return i.push(n.trim()),i}function CC({content:e}){const i=e.trim().split(`
132
- `).filter(Boolean);if(i.length===0)return m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Empty CSV"});const n=bm(i[0]),l=i.slice(1).map(o=>bm(o));return m.jsx("div",{className:"overflow-auto",children:m.jsxs("table",{className:"text-sm border-collapse w-full",children:[m.jsx("thead",{children:m.jsx("tr",{children:n.map((o,h)=>m.jsx("th",{className:"border border-[var(--border)] px-3 py-1.5 text-left font-semibold bg-[var(--bg-sidebar)] text-[var(--text-primary)]",children:o.trim()},h))})}),m.jsx("tbody",{children:l.map((o,h)=>m.jsx("tr",{className:"even:bg-[var(--bg-sidebar)]",children:o.map((d,_)=>m.jsx("td",{className:"border border-[var(--border)] px-3 py-1.5 text-[var(--text-primary)]",children:d.trim()},_))},h))})]})})}const go="h-full bg-[var(--bg-secondary)] flex flex-col";function kC({output:e}){return e.status==="empty"?m.jsx(TC,{}):e.status==="processing"?m.jsx(RC,{outcome:e.outcome,fileCount:e.fileCount}):e.status==="error"?m.jsx(DC,{message:e.message}):m.jsx(EC,{output:e})}function EC({output:e}){const{selectedOutcome:i}=Ni(),[n,l]=O.useState(!1),[o,h]=O.useState(""),[d,_]=O.useState(null),p=e.path.split("/").pop()||e.path,f=e.path.endsWith(".csv"),y=()=>{navigator.clipboard.writeText(e.content)},S=()=>{const C=new Blob([e.content],{type:"text/plain"}),b=URL.createObjectURL(C),R=document.createElement("a");R.href=b,R.download=p,R.click(),URL.revokeObjectURL(b)},x=()=>{if(d||!o.trim())return;const C=o.trim();nb({id:crypto.randomUUID(),name:C,outcomeKey:i||"custom",content:e.content,createdAt:Date.now()}),_(C)};return m.jsxs("div",{className:`${go}`,children:[m.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-[var(--border)] shrink-0",children:[m.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)] truncate",children:p}),m.jsxs("div",{className:"flex gap-2 ml-2 shrink-0",children:[m.jsx("button",{onClick:y,"aria-label":"Copy output to clipboard",className:"text-xs px-3 py-1 rounded border border-[var(--border)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-sidebar)] transition-colors",children:"Copy"}),m.jsx("button",{onClick:S,"aria-label":"Download output file",className:"text-xs px-3 py-1 rounded border border-[var(--border)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-sidebar)] transition-colors",children:"Download"})]})]}),m.jsx("div",{className:"flex-1 overflow-auto px-4 py-3 min-h-0",children:f?m.jsx(CC,{content:e.content}):m.jsx("div",{className:"output-prose",dangerouslySetInnerHTML:{__html:wC(Le.parse(e.content,{async:!1}))}})}),m.jsxs("div",{className:"shrink-0 px-4 py-1.5 border-t border-[var(--border)] text-xs text-green-600",children:["✓ Saved to ",e.path]}),m.jsx("div",{className:"shrink-0 px-4 py-2 border-t border-[var(--border)]",children:d?m.jsxs("p",{className:"text-xs text-indigo-600 font-medium",children:["⭐ Saved as ‘",d,"’"]}):n?m.jsxs("div",{className:"flex gap-2",children:[m.jsx("input",{type:"text",value:o,onChange:C=>h(C.target.value),placeholder:"Template name...",className:"flex-1 text-xs px-2 py-1 rounded border border-[var(--border)] bg-[var(--bg-secondary)] text-[var(--text-primary)] outline-none focus:ring-1 focus:ring-indigo-400",autoFocus:!0,onKeyDown:C=>{C.key==="Enter"&&x()}}),m.jsx("button",{onClick:x,className:"text-xs px-3 py-1 rounded bg-indigo-600 text-white font-medium hover:bg-indigo-700 transition-colors",children:"Save"})]}):m.jsx("button",{onClick:()=>l(!0),className:"w-full text-xs py-2 rounded-lg border border-dashed transition-colors hover:border-indigo-400 hover:text-indigo-600",style:{borderColor:"var(--border)",color:"var(--text-secondary)",background:"transparent",cursor:"pointer"},children:"⭐ Like this style? Save it as a template"})})]})}function TC(){const{loadOutput:e}=Ni(),[i,n]=O.useState(!1),l=async()=>{n(!0);try{const h=await(await fetch("/api/pick-file")).json();h?.path&&(await(await fetch(`/api/read-file?path=${encodeURIComponent(h.path)}`)).json())?.content&&await e(h.path)}catch{}n(!1)};return m.jsxs("div",{className:`${go} items-center justify-center gap-3`,children:[m.jsx("span",{className:"text-4xl",children:"📄"}),m.jsx("p",{className:"text-base font-medium text-[var(--text-primary)]",children:"Your output will appear here"}),m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Pick a folder and outcome, then hit Go"}),m.jsx("button",{onClick:l,disabled:i,style:{padding:"8px 20px",borderRadius:"10px",border:"1px solid var(--border)",background:"transparent",color:"var(--text-secondary)",fontSize:"13px",fontWeight:500,cursor:i?"not-allowed":"pointer",marginTop:"8px",transition:"all 0.15s"},children:i?"Opening...":"📂 Open a document"})]})}function RC({outcome:e,fileCount:i}){const{folderPath:n,loadOutput:l}=Ni(),[o,h]=O.useState(!1),d=async()=>{if(n){h(!0);try{const p=await(await fetch(`/api/latest-output?folderPath=${encodeURIComponent(n)}`)).json();p?.path&&await l(p.path)}catch{}h(!1)}};return m.jsxs("div",{className:`${go} items-center justify-center gap-2`,children:[m.jsx("span",{className:"text-4xl animate-pulse",children:"⏳"}),m.jsxs("p",{className:"text-base font-medium text-[var(--text-primary)]",children:[e," — ",i," documents..."]}),m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Claude is working — check the terminal for progress"}),m.jsx("button",{onClick:d,disabled:o,style:{padding:"8px 18px",borderRadius:"8px",border:"1px solid var(--border)",background:"transparent",color:"var(--text-secondary)",fontSize:"12px",fontWeight:500,cursor:o?"not-allowed":"pointer",marginTop:"12px"},children:o?"Checking...":"Check if done"})]})}function DC({message:e}){const{folderPath:i,loadOutput:n}=Ni(),[l,o]=O.useState(!1),[h,d]=O.useState(!1),_=async()=>{if(i){o(!0),d(!1);try{const f=await(await fetch(`/api/latest-output?folderPath=${encodeURIComponent(i)}`)).json();f?.path?await n(f.path):d(!0)}catch{d(!0)}o(!1)}};return m.jsxs("div",{className:`${go} items-center justify-center gap-3`,children:[m.jsx("span",{className:"text-4xl",children:"⚠️"}),m.jsx("p",{style:{fontSize:"13px",color:"#dc2626",textAlign:"center",maxWidth:"300px"},children:e}),m.jsx("button",{onClick:_,disabled:l,style:{padding:"10px 24px",borderRadius:"10px",border:"none",background:"#6366f1",color:"#fff",fontSize:"14px",fontWeight:600,cursor:l?"not-allowed":"pointer",opacity:l?.6:1,marginTop:"8px"},children:l?"Checking...":"Check for output"}),h&&m.jsx("p",{style:{fontSize:"12px",color:"#f59e0b",textAlign:"center"},children:"No output file found yet. Claude may still be working — try again in a moment."}),m.jsx("p",{style:{fontSize:"11px",color:"#9ca3af",textAlign:"center"},children:"Click to check if Claude has finished writing the output file"})]})}function MC(){const[e,i]=O.useState(!0),{mode:n}=Rt(),l=Ni();return Ty(),O.useEffect(()=>(n==="document"?document.documentElement.classList.add("doc-mode"):document.documentElement.classList.remove("doc-mode"),()=>document.documentElement.classList.remove("doc-mode")),[n]),m.jsxs("div",{className:"h-full flex flex-col",style:{background:"#f8fafc"},children:[m.jsx(zy,{}),m.jsx(Oy,{}),m.jsxs("div",{className:"flex-1 flex min-h-0",children:[m.jsx(Ly,{open:e,onToggle:()=>i(!e)}),m.jsx(fb,{open:e}),m.jsxs("div",{className:"flex-1 flex min-w-0",children:[m.jsx("div",{className:"flex-1 min-w-0 flex flex-col",style:{background:"#1a1a2e"},children:m.jsx(Aw,{})}),m.jsx("div",{style:{width:"45%",flexShrink:0,borderLeft:"1px solid #e5e7eb"},children:n==="developer"?m.jsx(zw,{}):m.jsx(kC,{output:l.output})})]})]})]})}function BC(){return m.jsx(Ey,{children:m.jsx(MC,{})})}function AC(){const{path:e,setProjectPath:i}=Rt();return e?m.jsx(BC,{}):m.jsx(Ay,{onProjectSelected:i})}function zC(){return m.jsx(vy,{children:m.jsx(yy,{children:m.jsx(AC,{})})})}_y.createRoot(document.getElementById("root")).render(m.jsx(O.StrictMode,{children:m.jsx(zC,{})}));
132
+ `).filter(Boolean);if(i.length===0)return m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Empty CSV"});const n=bm(i[0]),l=i.slice(1).map(o=>bm(o));return m.jsx("div",{className:"overflow-auto",children:m.jsxs("table",{className:"text-sm border-collapse w-full",children:[m.jsx("thead",{children:m.jsx("tr",{children:n.map((o,h)=>m.jsx("th",{className:"border border-[var(--border)] px-3 py-1.5 text-left font-semibold bg-[var(--bg-sidebar)] text-[var(--text-primary)]",children:o.trim()},h))})}),m.jsx("tbody",{children:l.map((o,h)=>m.jsx("tr",{className:"even:bg-[var(--bg-sidebar)]",children:o.map((d,_)=>m.jsx("td",{className:"border border-[var(--border)] px-3 py-1.5 text-[var(--text-primary)]",children:d.trim()},_))},h))})]})})}const go="h-full bg-[var(--bg-secondary)] flex flex-col";function kC({output:e}){return e.status==="empty"?m.jsx(TC,{}):e.status==="processing"?m.jsx(RC,{outcome:e.outcome,fileCount:e.fileCount}):e.status==="error"?m.jsx(DC,{message:e.message}):m.jsx(EC,{output:e})}function EC({output:e}){const{selectedOutcome:i}=Ni(),[n,l]=O.useState(!1),[o,h]=O.useState(""),[d,_]=O.useState(null),p=e.path.split("/").pop()||e.path,f=e.path.endsWith(".csv"),y=()=>{navigator.clipboard.writeText(e.content)},S=()=>{const C=new Blob([e.content],{type:"text/plain"}),b=URL.createObjectURL(C),R=document.createElement("a");R.href=b,R.download=p,R.click(),URL.revokeObjectURL(b)},x=()=>{if(d||!o.trim())return;const C=o.trim();nb({id:crypto.randomUUID(),name:C,outcomeKey:i||"custom",content:e.content,createdAt:Date.now()}),_(C)};return m.jsxs("div",{className:`${go}`,children:[m.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-[var(--border)] shrink-0",children:[m.jsx("span",{className:"text-sm font-medium text-[var(--text-primary)] truncate",children:p}),m.jsxs("div",{className:"flex gap-2 ml-2 shrink-0",children:[m.jsx("button",{onClick:y,"aria-label":"Copy output to clipboard",className:"text-xs px-3 py-1 rounded border border-[var(--border)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-sidebar)] transition-colors",children:"Copy"}),m.jsx("button",{onClick:S,"aria-label":"Download output file",className:"text-xs px-3 py-1 rounded border border-[var(--border)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-sidebar)] transition-colors",children:"Download"})]})]}),m.jsx("div",{className:"flex-1 overflow-auto px-4 py-3 min-h-0",children:f?m.jsx(CC,{content:e.content}):m.jsx("div",{className:"output-prose",dangerouslySetInnerHTML:{__html:wC(Le.parse(e.content,{async:!1}))}})}),m.jsxs("div",{className:"shrink-0 px-4 py-1.5 border-t border-[var(--border)] text-xs text-green-600",children:["✓ Saved to ",e.path]}),m.jsx("div",{className:"shrink-0 px-4 py-2 border-t border-[var(--border)]",children:d?m.jsxs("p",{className:"text-xs text-indigo-600 font-medium",children:["⭐ Saved as ‘",d,"’"]}):n?m.jsxs("div",{className:"flex gap-2",children:[m.jsx("input",{type:"text",value:o,onChange:C=>h(C.target.value),placeholder:"Template name...",className:"flex-1 text-xs px-2 py-1 rounded border border-[var(--border)] bg-[var(--bg-secondary)] text-[var(--text-primary)] outline-none focus:ring-1 focus:ring-indigo-400",autoFocus:!0,onKeyDown:C=>{C.key==="Enter"&&x()}}),m.jsx("button",{onClick:x,className:"text-xs px-3 py-1 rounded bg-indigo-600 text-white font-medium hover:bg-indigo-700 transition-colors",children:"Save"})]}):m.jsx("button",{onClick:()=>l(!0),className:"w-full text-xs py-2 rounded-lg border border-dashed transition-colors hover:border-indigo-400 hover:text-indigo-600",style:{borderColor:"var(--border)",color:"var(--text-secondary)",background:"transparent",cursor:"pointer"},children:"⭐ Like this style? Save it as a template"})})]})}function TC(){const{loadOutput:e}=Ni(),[i,n]=O.useState(!1),l=async()=>{n(!0);try{const h=await(await fetch("/api/pick-file")).json();if(h?.path){const _=await(await fetch(`/api/read-file?path=${encodeURIComponent(h.path)}`)).json();(_?.content||_?.binary)&&await e(h.path)}}catch{}n(!1)};return m.jsxs("div",{className:`${go} items-center justify-center gap-3`,children:[m.jsx("span",{className:"text-4xl",children:"📄"}),m.jsx("p",{className:"text-base font-medium text-[var(--text-primary)]",children:"Your output will appear here"}),m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Pick a folder and outcome, then hit Go"}),m.jsx("button",{onClick:l,disabled:i,style:{padding:"8px 20px",borderRadius:"10px",border:"1px solid var(--border)",background:"transparent",color:"var(--text-secondary)",fontSize:"13px",fontWeight:500,cursor:i?"not-allowed":"pointer",marginTop:"8px",transition:"all 0.15s"},children:i?"Opening...":"📂 Open a document"})]})}function RC({outcome:e,fileCount:i}){const{folderPath:n,loadOutput:l}=Ni(),[o,h]=O.useState(!1),d=async()=>{if(n){h(!0);try{const p=await(await fetch(`/api/latest-output?folderPath=${encodeURIComponent(n)}`)).json();p?.path&&await l(p.path)}catch{}h(!1)}};return m.jsxs("div",{className:`${go} items-center justify-center gap-2`,children:[m.jsx("span",{className:"text-4xl animate-pulse",children:"⏳"}),m.jsxs("p",{className:"text-base font-medium text-[var(--text-primary)]",children:[e," — ",i," documents..."]}),m.jsx("p",{className:"text-sm text-[var(--text-secondary)]",children:"Claude is working — check the terminal for progress"}),m.jsx("button",{onClick:d,disabled:o,style:{padding:"8px 18px",borderRadius:"8px",border:"1px solid var(--border)",background:"transparent",color:"var(--text-secondary)",fontSize:"12px",fontWeight:500,cursor:o?"not-allowed":"pointer",marginTop:"12px"},children:o?"Checking...":"Check if done"})]})}function DC({message:e}){const{folderPath:i,loadOutput:n}=Ni(),[l,o]=O.useState(!1),[h,d]=O.useState(!1),_=async()=>{if(i){o(!0),d(!1);try{const f=await(await fetch(`/api/latest-output?folderPath=${encodeURIComponent(i)}`)).json();f?.path?await n(f.path):d(!0)}catch{d(!0)}o(!1)}};return m.jsxs("div",{className:`${go} items-center justify-center gap-3`,children:[m.jsx("span",{className:"text-4xl",children:"⚠️"}),m.jsx("p",{style:{fontSize:"13px",color:"#dc2626",textAlign:"center",maxWidth:"300px"},children:e}),m.jsx("button",{onClick:_,disabled:l,style:{padding:"10px 24px",borderRadius:"10px",border:"none",background:"#6366f1",color:"#fff",fontSize:"14px",fontWeight:600,cursor:l?"not-allowed":"pointer",opacity:l?.6:1,marginTop:"8px"},children:l?"Checking...":"Check for output"}),h&&m.jsx("p",{style:{fontSize:"12px",color:"#f59e0b",textAlign:"center"},children:"No output file found yet. Claude may still be working — try again in a moment."}),m.jsx("p",{style:{fontSize:"11px",color:"#9ca3af",textAlign:"center"},children:"Click to check if Claude has finished writing the output file"})]})}function MC(){const[e,i]=O.useState(!0),{mode:n}=Rt(),l=Ni();return Ty(),O.useEffect(()=>(n==="document"?document.documentElement.classList.add("doc-mode"):document.documentElement.classList.remove("doc-mode"),()=>document.documentElement.classList.remove("doc-mode")),[n]),m.jsxs("div",{className:"h-full flex flex-col",style:{background:"#f8fafc"},children:[m.jsx(zy,{}),m.jsx(Oy,{}),m.jsxs("div",{className:"flex-1 flex min-h-0",children:[m.jsx(Ly,{open:e,onToggle:()=>i(!e)}),m.jsx(fb,{open:e}),m.jsxs("div",{className:"flex-1 flex min-w-0",children:[m.jsx("div",{className:"flex-1 min-w-0 flex flex-col",style:{background:"#1a1a2e"},children:m.jsx(Aw,{})}),m.jsx("div",{style:{width:"45%",flexShrink:0,borderLeft:"1px solid #e5e7eb"},children:n==="developer"?m.jsx(zw,{}):m.jsx(kC,{output:l.output})})]})]})]})}function BC(){return m.jsx(Ey,{children:m.jsx(MC,{})})}function AC(){const{path:e,setProjectPath:i}=Rt();return e?m.jsx(BC,{}):m.jsx(Ay,{onProjectSelected:i})}function zC(){return m.jsx(vy,{children:m.jsx(yy,{children:m.jsx(AC,{})})})}_y.createRoot(document.getElementById("root")).render(m.jsx(O.StrictMode,{children:m.jsx(zC,{})}));
package/dist/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Claude Portal</title>
7
- <script type="module" crossorigin src="/assets/index-ChGdxmzn.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-Dk_0f6au.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-BG0yZd9Y.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claudeportal",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Get from npx to a working app in under 5 minutes — Claude Code setup wizard",
5
5
  "bin": {
6
6
  "create-claudeportal": "bin/cli.js"
@@ -88,6 +88,23 @@ const RECOMMENDED_MCPS = [
88
88
  usefulFor: ['draft', 'extract', 'transform'],
89
89
  category: 'automation',
90
90
  },
91
+ {
92
+ id: 'composio',
93
+ name: 'Composio',
94
+ description: '250+ app integrations — CRM, email, social, databases',
95
+ installHint: 'claude mcp add composio -- npx -y composio-core mcp',
96
+ usefulFor: ['draft', 'extract', 'analyse', 'transform', 'summarize'],
97
+ category: 'automation',
98
+ },
99
+ // Social Media
100
+ {
101
+ id: 'postiz',
102
+ name: 'Postiz',
103
+ description: 'Schedule and manage social media posts across platforms',
104
+ installHint: 'claude mcp add postiz -- npx -y @postiz/mcp-server',
105
+ usefulFor: ['draft', 'transform'],
106
+ category: 'social',
107
+ },
91
108
  // Meetings & Notes
92
109
  {
93
110
  id: 'fireflies',
@@ -155,6 +172,7 @@ const CATEGORY_LABELS = {
155
172
  design: 'Design & Build',
156
173
  workspace: 'Workspace',
157
174
  automation: 'Automation',
175
+ social: 'Social Media',
158
176
  meetings: 'Meetings',
159
177
  projects: 'Project Management',
160
178
  data: 'Data',
@@ -96,8 +96,26 @@ router.get('/read-file', (req, res) => {
96
96
  if (stat.size > 10 * 1024 * 1024) {
97
97
  return res.status(413).json({ error: 'File too large (max 10MB)' })
98
98
  }
99
- const content = fs.readFileSync(resolved, 'utf8')
100
- res.json({ content, path: resolved, size: stat.size, modified: stat.mtime.toISOString() })
99
+
100
+ const ext = path.extname(resolved).toLowerCase()
101
+ const binaryTypes = ['.pdf', '.docx', '.doc', '.xlsx', '.xls', '.pptx', '.odt']
102
+
103
+ if (binaryTypes.includes(ext)) {
104
+ // Binary files can't be read as text — return metadata only
105
+ // Claude Code can read these directly via its file reading capability
106
+ res.json({
107
+ content: null,
108
+ binary: true,
109
+ path: resolved,
110
+ size: stat.size,
111
+ type: ext.slice(1),
112
+ modified: stat.mtime.toISOString(),
113
+ message: `${ext.slice(1).toUpperCase()} file — Claude will read this directly`,
114
+ })
115
+ } else {
116
+ const content = fs.readFileSync(resolved, 'utf8')
117
+ res.json({ content, path: resolved, size: stat.size, modified: stat.mtime.toISOString() })
118
+ }
101
119
  } catch (err) {
102
120
  res.status(500).json({ error: err.message })
103
121
  }
@@ -170,12 +188,12 @@ router.get('/pick-file', (req, res) => {
170
188
  let selected
171
189
  if (process.platform === 'darwin') {
172
190
  selected = execSync(
173
- `osascript -e 'POSIX path of (choose file with prompt "Choose a document" of type {"md", "txt", "csv", "json", "html"})'`,
191
+ `osascript -e 'POSIX path of (choose file with prompt "Choose a document" of type {"md", "txt", "csv", "json", "html", "pdf", "docx", "doc", "xlsx", "xls", "pptx", "rtf", "odt", "tsv"})'`,
174
192
  { encoding: 'utf8', timeout: 60000 }
175
193
  ).trim()
176
194
  } else if (process.platform === 'linux') {
177
195
  selected = execSync(
178
- 'zenity --file-selection --title="Choose a document" --file-filter="Documents|*.md *.txt *.csv *.json *.html" 2>/dev/null',
196
+ 'zenity --file-selection --title="Choose a document" --file-filter="Documents|*.md *.txt *.csv *.json *.html *.pdf *.docx *.doc *.xlsx *.xls *.pptx *.rtf *.odt *.tsv" 2>/dev/null',
179
197
  { encoding: 'utf8', timeout: 60000 }
180
198
  ).trim()
181
199
  } else {