magicpath-ai 2.3.2 → 3.0.0-experimental.0
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/dist/cli.js +39 -85
- package/package.json +7 -4
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readFileSync as pr}from"fs";import{dirname as gr,join as ur}from"path";import{fileURLToPath as fr}from"url";import{program as N}from"commander";import Ge from"axios";var p=class extends Error{code;suggestion;constructor(n,t){super(n),this.code=t==null?void 0:t.code,this.suggestion=t==null?void 0:t.suggestion}};function bt(e){if(!(!e||typeof e!="object"))return e}function H(e){var n,t,o;if(e instanceof p)return e;if(Ge.isAxiosError(e)){let r=bt((n=e.response)==null?void 0:n.data),s=typeof(r==null?void 0:r.message)=="string"?r.message:e.response?`API error: ${e.response.status} ${e.response.statusText}`:e.message,i=typeof(r==null?void 0:r.code)=="string"?r.code:void 0,c=typeof((t=r==null?void 0:r.details)==null?void 0:t.billing_url)=="string"?r.details.billing_url:typeof((o=r==null?void 0:r.details)==null?void 0:o.billingUrl)=="string"?r.details.billingUrl:void 0,a=typeof(r==null?void 0:r.suggestion)=="string"?r.suggestion:c?"Upgrade to Pro from billing to keep using external agents.":void 0;return new p(s,{code:i,...a?{suggestion:a}:{}})}return e instanceof Error?new p(e.message):new p(String(e))}function vt(){Ge.interceptors.response.use(e=>e,e=>{var n;if(Ge.isAxiosError(e)){let t=bt((n=e.response)==null?void 0:n.data);if(typeof(t==null?void 0:t.code)=="string")return Promise.reject(H(e))}return Promise.reject(e)})}var xt=!1;function $t(e){xt=e}function x(){return xt}function v(e){console.log(JSON.stringify(e,null,2)),process.exit(0)}function A(e){let t={error:e instanceof Error?e.message:String(e)};e instanceof p&&(e.code&&(t.code=e.code),e.suggestion&&(t.suggestion=e.suggestion)),console.error(JSON.stringify(t,null,2)),process.exit(1)}var J="0.0.0-dev";function Ct(e){J=e}import ne from"chalk";import ge from"fs-extra";import Ht from"path";import cn from"os";import Gt from"axios";var S=process.env.MAGICPATH_API_URL??"https://api.magicpath.ai";function $e(e,n){return`${S}/${e}/${n}`}function jt(e){return`${S}/v1/registry/${e}`}var rn=process.env.MAGICPATH_WEB_URL??"https://www.magicpath.ai";function Ve(e){return`${rn}${e}`}function Et(e){return Ve(`/files/${e}`)}function ze(e){return`${S}/auth/${e}`}function Je(){return`${S}/v1/external-agent/components`}function Be(e){return`${S}/v1/external-agent/components/${e}/context`}function At(e){return`${S}/v1/external-agent/components/${e}/start`}function Pt(e){return`${S}/v1/external-agent/components/${e}/revisions`}function Ke(e,n){return`${S}/v1/external-agent/components/${e}/revisions/${n}/files`}function Xe(e){return`${S}/v1/external-agent/jobs/${e}`}function Y(){return`${S}/users/me`}function qe(){return`${S}/users/me/projects`}function Tt(){return`${S}/users/me/assets/upload-url`}function St(){return`${S}/projects`}function Nt(e){return`${S}/projects/${e}`}function Rt(e){return`${S}/projects/${e}/components`}function Ze(e){return`${S}/projects/${e}/images`}function Ce(){return`${S}/users/me/design-systems`}function kt(e){return`${S}/design-systems/${e}`}function oe(){return`${S}/users/me/socket-rooms`}function Ot(){return`${S}/liveblocks/auth`}function Mt(e){return`${S}/components/${e}`}function Ut(){return`${S}/components/search`}function Ft(e){return`${S}/organizations/${e}`}function Ye(e){return`${S}/organizations/${e}/projects`}function je(e){return`${S}/organizations/${e}/design-systems`}var sn=[{type:"claude-code",envVar:"CLAUDECODE"},{type:"cursor",envVar:"CURSOR_TRACE_ID"},{type:"cursor",envVar:"CURSOR_AGENT"},{type:"codex",envVar:"CODEX_SANDBOX"},{type:"codex",envVar:"CODEX_THREAD_ID"},{type:"codex",envVar:"CODEX_CI"},{type:"gemini",envVar:"GEMINI_CLI"},{type:"antigravity",envVar:"ANTIGRAVITY_AGENT"},{type:"augment",envVar:"AUGMENT_AGENT"},{type:"opencode",envVar:"OPENCODE_CLIENT"},{type:"copilot",envVar:"COPILOT_MODEL"},{type:"cline",envVar:"CLINE_ACTIVE"},{type:"replit",envVar:"REPL_ID"},{type:"goose",envVar:"GOOSE_TERMINAL"}],Ee={"claude-code":"claude-code",claude:"claude-code",cursor:"cursor","cursor-agent":"cursor",codex:"codex","codex-cli":"codex",gemini:"gemini","gemini-cli":"gemini",antigravity:"antigravity",augment:"augment",opencode:"opencode",copilot:"copilot","github-copilot":"copilot","github-copilot-cli":"copilot",cline:"cline",replit:"replit",v0:"v0",devin:"devin",aider:"aider",goose:"goose",amp:"amp"};function Dt(e){let n=e.trim();if(!n)return null;let t=n.indexOf("@");if(t===-1)return{slug:n.toLowerCase()};let o=n.slice(0,t).trim().toLowerCase(),r=n.slice(t+1).trim()||void 0;return o?{slug:o,version:r}:null}function _t(e){if(e in Ee)return Ee[e];for(let n of Object.keys(Ee))if(e.startsWith(`${n}_`)||e.startsWith(`${n}-`))return Ee[n];return e}var Ae;function Lt(){return Ae||(Ae=an(),Ae)}function an(){let e=process.env.MAGICPATH_AGENT;if(e){let t=Dt(e);if(t)return{kind:"known-agent",slug:_t(t.slug),version:t.version}}for(let t of sn){let o=process.env[t.envVar];if(o&&o!=="0"&&o.toLowerCase()!=="false")return{kind:"known-agent",slug:t.type}}let n=process.env.AI_AGENT;if(n){let t=Dt(n);if(t)return{kind:"known-agent",slug:_t(t.slug),version:t.version}}return process.stdin.isTTY?{kind:"interactive-human"}:{kind:"unknown-agent"}}function Wt(e){switch(e.kind){case"known-agent":return{type:e.slug,version:e.version};case"interactive-human":return{type:"interactive"};case"unknown-agent":return{}}}var Vt=Ht.join(cn.homedir(),".magicpath"),Pe=Ht.join(Vt,"session.json");function Te(){try{if(!ge.existsSync(Pe))return null;let e=ge.readJsonSync(Pe);return e.accessToken&&e.refreshToken?e:null}catch{return null}}function zt(e){ge.ensureDirSync(Vt),ge.writeJsonSync(Pe,e)}function Qe(e,n){let t=Te();zt({accessToken:e,refreshToken:n,user:t==null?void 0:t.user})}function Q(){let e=Te();return e?{accessToken:e.accessToken,refreshToken:e.refreshToken}:null}function Jt(){try{ge.removeSync(Pe)}catch{}}function ln(e){try{let n=Te();n&&(n.user=e,zt(n))}catch{}}function Bt(){let e=Te();return(e==null?void 0:e.user)??null}function E(){let{type:e,version:n}=Wt(Lt()),t={"X-Client-Type":"cli","X-Client-Version":J};e&&(t["X-Agent-Type"]=e),n&&(t["X-Agent-Version"]=n);let o=process.env.MAGICPATH_TOKEN;if(o)return t.Authorization=`Bearer ${o}`,t;let r=Q();if(!r)throw new Error("Not logged in. Run `magicpath-ai login` first.");return t.Authorization=`Bearer ${r.accessToken}`,t}function ue(e){var o,r;let n=(o=e.subscription)!=null&&o.active?(r=e.subscription.type)!=null&&r.startsWith("PRO")?"Pro":"Creator":"Free",t={name:e.name||e.firstName||e.displayName,email:e.email,plan:n};return ln(t),t}async function et(){let e=E(),n=await Gt.get(Y(),{headers:e}),t=n.data.user??n.data;return ue(t)}async function fe(e){let n=await Gt.get(Y(),{headers:e});return((n.data.user??n.data).organizationUsers??[]).map(r=>({id:String(r.organization.id),name:r.organization.name,role:r.role}))}async function G(e,n){let t=await fe(n),o=t.find(i=>i.id===e);if(o)return{id:o.id,name:o.name};let r=e.toLowerCase(),s=t.find(i=>i.name.toLowerCase()===r);if(s)return{id:s.id,name:s.name};throw new p(`Team "${e}" not found.`,{code:"TEAM_NOT_FOUND",suggestion:"Run `magicpath-ai list-teams` to see your teams."})}var Kt=["#95D5B2","#74C69D","#52B788","#40916C","#2D6A4F","#1B4332"];function mn(e){return ne.hex(Kt[Math.min(e,Kt.length-1)])}var tt=ne.hex("#2D6A4F"),dn=ne.hex("#1B4332"),pn=ne.hex("#E8F5E9"),ot=ne.hex("#888888"),gn=["\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D","\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 ","\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 ","\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D"],un=["\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551","\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551","\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551","\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D"],fn=gn.map((e,n)=>e+" "+un[n]);function hn(e){return e.map((n,t)=>{let o=mn(t),r="";for(let s of n)r+=s===" "?s:o(s);return r})}function Xt(e){let n=!!Q(),t=n?Bt():null;console.log();for(let s of hn(fn))console.log(s);if(console.log(),n&&t){let s=t.plan?` \xB7 ${t.plan}`:"";console.log(" "+tt("\u25CF")+" "+ne.bold(pn(t.name??"MagicPath User"))+dn(" "+(t.email??"")+s))}else console.log(" "+ot("\u25CB Not logged in \xB7 run")+" "+tt("magicpath-ai login"));console.log();let o=20,r=[["search <query>","Search components"],["add <name>","Add to project"],["list-projects","Your projects"],["setup-skills","Set up AI agents"]];for(let[s,i]of r)console.log(" "+tt(s.padEnd(o))+ot(i));console.log(),console.log(" "+ot(`v${e} \u2500 magicpath-ai --help`)),console.log()}import Ne from"prompts";import lo from"ora";import{z as ie}from"zod";import ae from"path";import En from"os";import st from"fs-extra";import{pino as qt}from"pino";var re=qt();function se(){re=qt({level:"debug"}),re.debug({message:"DEBUG logger enabled. "})}var k={info:e=>{re.info(e)},debug:e=>{re.debug(e)},warn:e=>{re.warn(e)},error:e=>{re.error(e)}};import Zt from"axios";import Se from"path";import yn from"os";import{Readable as In}from"stream";import he from"fs-extra";import bn from"adm-zip";import{v4 as vn}from"uuid";async function xn(e){if(!(e instanceof In))return;let n=[];return new Promise((t,o)=>{e.on("data",r=>{n.push(Buffer.isBuffer(r)?r:Buffer.from(r))}),e.on("error",o),e.on("end",()=>t(Buffer.concat(n).toString("utf8")))})}async function $n(e){var n;if(e instanceof p)return e;if(Zt.isAxiosError(e)){let t=await xn((n=e.response)==null?void 0:n.data);if(t)try{let o=JSON.parse(t);return H({...e,response:{...e.response,data:o},isAxiosError:!0})}catch{}return H(e)}return new p("Failed to download project. Make sure your key is valid.")}async function Yt(e){let n=$e("v1","components/repository"),t=`${vn()}.zip`,o=Se.join(yn.tmpdir(),t);try{let r=await Zt({url:n,params:{key:e},method:"GET",responseType:"stream"});return await he.ensureDir(Se.dirname(o)),await new Promise(async(s,i)=>{try{r.data.pipe(he.createWriteStream(o)).on("error",i).once("close",()=>s(o))}catch(c){i(c)}}),o}catch(r){throw await $n(r)}}function nt(e){try{he.removeSync(e)}catch{}}function Qt(e,n,t){try{let o=Se.join(t,n),r=1;for(;he.existsSync(o);)r++,o=Se.join(t,`${n}-${r}`);return he.mkdirSync(o,{recursive:!0}),new bn(e).extractAllTo(o,!0),nt(e),o}catch{throw new p("Failed to extract project. Please try again.")}}import{execSync as rt}from"child_process";import to from"ora";import eo from"fs-extra";import Cn from"path";function oo(){try{return rt("yarn --version",{stdio:"ignore"}),"yarn"}catch{return"npm"}}function no(e){let n=oo(),t=to(`\u{1F4E6} Installing dependencies using ${n}...`).start();try{rt(n==="yarn"?"yarn install":"npm install",{cwd:e,stdio:"ignore"}),t.succeed("Dependencies installed successfully!")}catch{throw t.fail("Failed to install dependencies"),new p("Failed to install dependencies. Please check your internet connection and try again.")}}function jn(e){let n=Cn.join(e,"package.json");if(!eo.existsSync(n))return new Set;try{let t=eo.readJsonSync(n),o=new Set;return t.dependencies&&Object.keys(t.dependencies).forEach(r=>o.add(r)),t.devDependencies&&Object.keys(t.devDependencies).forEach(r=>o.add(r)),o}catch{return new Set}}function ro(e,n){if(e.length===0)return{installed:[],skipped:[]};let t=jn(n),o=e.filter(c=>!t.has(c)),r=e.filter(c=>t.has(c));if(o.length===0)return k.debug("All dependencies already installed"),{installed:[],skipped:r};let s=oo(),i=to(`\u{1F4E6} Installing ${o.length} package${o.length>1?"s":""} using ${s}...`).start();try{let c=o.join(" "),a=s==="yarn"?`yarn add ${c}`:`npm install ${c}`;return k.debug({command:a}),rt(a,{cwd:n,stdio:"ignore"}),i.succeed(`Installed ${o.length} package${o.length>1?"s":""}`),{installed:o,skipped:r}}catch{throw i.fail("Failed to install packages"),new p(`Failed to install packages: ${o.join(", ")}. Please install them manually.`)}}import{execSync as so}from"child_process";import io from"ora";function ao(e,n){let t={cursor:"Cursor",antigravity:"Antigravity",vscode:"VS Code",webstorm:"WebStorm"},o={cursor:["cursor","code"],antigravity:["agy","antigravity"],vscode:["code"],webstorm:["webstorm","web"]},r=io(`\u{1F680} Opening project in ${t[n]}...`).start(),s=!1;try{for(let i of o[n]){if(s)break;try{so(`${i} .`,{cwd:e,stdio:"ignore"}),s=!0}catch{s=!1}}if(!s)throw new Error("Failed to open with command.");r.succeed(`Project opened in ${t[n]}!`)}catch{r.fail(`Failed to open ${t[n]}`);let i={cursor:`\u274C Cursor command not found!
|
|
2
|
+
import{readFileSync as yi}from"fs";import{dirname as wi,join as Ii}from"path";import{fileURLToPath as vi}from"url";var G="0.0.0-dev";function $t(e){G=e}import rt from"axios";var d=class extends Error{code;suggestion;constructor(t,n){super(t),this.code=n==null?void 0:n.code,this.suggestion=n==null?void 0:n.suggestion}};function Ot(e){if(!(!e||typeof e!="object"))return e}function dr(e){switch(e){case 401:return"AUTH_REQUIRED";case 403:return"FORBIDDEN";case 404:return"NOT_FOUND";case 409:return"CONFLICT";case 426:return"CLI_UPGRADE_REQUIRED";case 429:return"QUOTA_EXCEEDED";default:return e?"API_ERROR":void 0}}function D(e){var t,n,o,s;if(e instanceof d)return e;if(rt.isAxiosError(e)){let r=Ot((t=e.response)==null?void 0:t.data),i=typeof(r==null?void 0:r.message)=="string"?r.message:e.response?`API error: ${e.response.status} ${e.response.statusText}`:e.message,c=typeof(r==null?void 0:r.code)=="string"?r.code:dr((n=e.response)==null?void 0:n.status),a=typeof((o=r==null?void 0:r.details)==null?void 0:o.billing_url)=="string"?r.details.billing_url:typeof((s=r==null?void 0:r.details)==null?void 0:s.billingUrl)=="string"?r.details.billingUrl:void 0,m=typeof(r==null?void 0:r.suggestion)=="string"?r.suggestion:a?"Upgrade to Pro from billing to keep using external agents.":void 0;return new d(i,{code:c,...m?{suggestion:m}:{}})}return e instanceof Error?new d(e.message):new d(String(e))}function Dt(){rt.interceptors.response.use(e=>e,e=>{var t;if(rt.isAxiosError(e)){let n=Ot((t=e.response)==null?void 0:t.data);if(typeof(n==null?void 0:n.code)=="string")return Promise.reject(D(e))}return Promise.reject(e)})}import{Command as fi,Option as hi}from"commander";var pr=[{type:"claude-code",envVar:"CLAUDECODE"},{type:"cursor",envVar:"CURSOR_TRACE_ID"},{type:"cursor",envVar:"CURSOR_AGENT"},{type:"codex",envVar:"CODEX_SANDBOX"},{type:"codex",envVar:"CODEX_THREAD_ID"},{type:"codex",envVar:"CODEX_CI"},{type:"gemini",envVar:"GEMINI_CLI"},{type:"antigravity",envVar:"ANTIGRAVITY_AGENT"},{type:"augment",envVar:"AUGMENT_AGENT"},{type:"opencode",envVar:"OPENCODE_CLIENT"},{type:"copilot",envVar:"COPILOT_MODEL"},{type:"cline",envVar:"CLINE_ACTIVE"},{type:"replit",envVar:"REPL_ID"},{type:"goose",envVar:"GOOSE_TERMINAL"}],xe={"claude-code":"claude-code",claude:"claude-code",cursor:"cursor","cursor-agent":"cursor",codex:"codex","codex-cli":"codex",gemini:"gemini","gemini-cli":"gemini",antigravity:"antigravity",augment:"augment",opencode:"opencode",copilot:"copilot","github-copilot":"copilot","github-copilot-cli":"copilot",cline:"cline",replit:"replit",v0:"v0",devin:"devin",aider:"aider",goose:"goose",amp:"amp"};function Mt(e){let t=e.trim();if(!t)return null;let n=t.indexOf("@");if(n===-1)return{slug:t.toLowerCase()};let o=t.slice(0,n).trim().toLowerCase(),s=t.slice(n+1).trim()||void 0;return o?{slug:o,version:s}:null}function Ft(e){if(e in xe)return xe[e];for(let t of Object.keys(xe))if(e.startsWith(`${t}_`)||e.startsWith(`${t}-`))return xe[t];return e}var Ee;function Te(){return Ee||(Ee=lr(),Ee)}function lr(){let e=process.env.MAGICPATH_AGENT;if(e){let n=Mt(e);if(n)return{kind:"known-agent",slug:Ft(n.slug),version:n.version}}for(let n of pr){let o=process.env[n.envVar];if(o&&o!=="0"&&o.toLowerCase()!=="false")return{kind:"known-agent",slug:n.type}}let t=process.env.AI_AGENT;if(t){let n=Mt(t);if(n)return{kind:"known-agent",slug:Ft(n.slug),version:n.version}}return process.stdin.isTTY?{kind:"interactive-human"}:{kind:"unknown-agent"}}function _t(e){switch(e.kind){case"known-agent":return{type:e.slug,version:e.version};case"interactive-human":return{type:"interactive"};case"unknown-agent":return{}}}var st=null;function it(e){let t=Te();return st={interactive:!((e==null?void 0:e.output)==="json")&&t.kind==="interactive-human"&&!!process.stdout.isTTY,caller:t},st}function Lt(){return st??it()}import ut from"axios";import{Command as Xt,Option as hr}from"commander";import yr from"ora";import{z as j}from"zod";var gr=j.object({nextCursor:j.string().nullable(),hasMore:j.boolean()}),Ui=j.object({ok:j.literal(!0),data:j.unknown(),meta:j.object({command:j.string().min(1),cliVersion:j.string().min(1),page:gr.optional(),warnings:j.array(j.string()).optional()})}),$i=j.object({ok:j.literal(!1),error:j.object({code:j.string().min(1),message:j.string().min(1),suggestion:j.string().optional()})});function ur(e,t,n){var o;return{ok:!0,data:t,meta:{command:e,cliVersion:G,...n!=null&&n.page?{page:n.page}:{},...(o=n==null?void 0:n.warnings)!=null&&o.length?{warnings:n.warnings}:{}}}}function fr(e){let t=D(e);return{ok:!1,error:{code:t.code??"ERROR",message:t.message,...t.suggestion?{suggestion:t.suggestion}:{}}}}function Vt(e,t,n){console.log(JSON.stringify(ur(e,t,n),null,2)),process.exit(0)}function Ne(e){console.error(JSON.stringify(fr(e),null,2)),process.exit(1)}var ke=50;function Gt(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64url")}function Ht(e){if(!e)return{};try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));if(!t||typeof t!="object")throw new Error("not an object");return t}catch{throw new d("Invalid --cursor token.",{code:"INVALID_CURSOR",suggestion:"Pass the meta.page.nextCursor value from the previous page unchanged."})}}function Wt(e){let t=typeof e=="string"?Number(e):typeof e=="number"?e:NaN;if(!Number.isInteger(t)||t<1||t>100)throw new d("Invalid --limit value (must be an integer between 1 and 100).",{code:"INVALID_LIMIT"});return t}function zt(e,t,n){return{nextCursor:n?Gt({offset:e+t}):null,hasMore:n}}function Ue(e,t){return{nextCursor:t&&e?Gt({after:e}):null,hasMore:t&&e!==null}}var Jt=null;function Bt(e){Jt=e}function qt(){return Jt}function wr(){let e={start:()=>e,stop:()=>e,succeed:()=>e,fail:()=>e,text:""};return e}function Ir(e){return t=>e.interactive?yr(t).start():wr()}function vr(e){let t=e.variadic?`${e.name}...`:e.name;return e.required===!1?`[${t}]`:`<${t}>`}function Cr(e,t){return e.parent?`${e.name()} ${t}`:t}function g(e,t){let n=new Xt(t.name);n.summary(t.summary),n.description(t.description??t.summary);for(let s of t.aliases??[])n.alias(s);for(let s of t.args??[])n.argument(vr(s),s.description);for(let s of t.flags??[])s.hidden?n.addOption(new hr(s.flags,s.description).hideHelp()):s.default!==void 0?n.option(s.flags,s.description,s.default):n.option(s.flags,s.description);t.paginated&&(n.option("--limit <n>","Maximum results per page (1-100)",String(ke)),n.option("--cursor <token>","Opaque cursor from meta.page.nextCursor"));let o=Cr(e,t.name);return n.action(async(...s)=>{let r=s.slice(0,-2),i=n.optsWithGlobals(),c=Lt();Bt(o);try{let a=t.paginated?{limit:Wt(i.limit??String(ke)),cursor:Ht(i.cursor)}:{limit:ke,cursor:{}},m=await t.run({args:r,opts:i,mode:c,command:o,page:a,progress:Ir(c)});Vt(o,m.data,{page:m.page,warnings:m.warnings})}catch(a){Ne(a)}}),e.addCommand(n,t.hidden?{hidden:!0}:void 0),n}function E(e,t,n,o){let s=new Xt(t);s.summary(n),s.description(n);for(let r of(o==null?void 0:o.aliases)??[])s.alias(r);return e.addCommand(s,o!=null&&o.hidden?{hidden:!0}:void 0),s}import{Command as Sr}from"commander";function I(e,t,n,o){return g(e,{...n,...o,name:t,hidden:!0,aliases:[]})}function Yt(e,t,n){let o=new Sr(t);o.allowUnknownOption(!0),o.allowExcessArguments(!0),o.action(()=>{Ne(new d(`The "${t}" command was removed in v3.`,{code:"REMOVED_COMMAND",suggestion:n}))}),e.addCommand(o,{hidden:!0})}import ge from"fs-extra";import Cn from"path";import Pr from"os";import Sn from"axios";var w=process.env.MAGICPATH_API_URL??"https://api.magicpath.ai";function T(e,t){return`${w}/${e}/${t}`}function Zt(e){return`${w}/v1/registry/${e}`}var br=process.env.MAGICPATH_WEB_URL??"https://www.magicpath.ai";function K(e){return`${br}${e}`}function J(e){return K(`/files/${e}`)}function Kt(e){return`${w}/auth/${e}`}function Qt(){return`${w}/v1/external-agent/components`}function at(e){return`${w}/v1/external-agent/components/${e}/context`}function en(e){return`${w}/v1/external-agent/components/${e}/start`}function tn(e){return`${w}/v1/external-agent/components/${e}/revisions`}function nn(e,t){return`${w}/v1/external-agent/components/${e}/revisions/${t}/files`}function $e(e){return`${w}/v1/external-agent/jobs/${e}`}function pe(){return`${w}/users/me`}function ct(){return`${w}/users/me/projects`}function on(){return`${w}/users/me/assets/upload-url`}function rn(){return`${w}/projects`}function le(e){return`${w}/projects/${e}`}function sn(e){return`${w}/projects/${e}/components`}function mt(e){return`${w}/projects/${e}/images`}function an(){return`${w}/users/me/design-systems`}function Oe(e){return`${w}/design-systems/${e}`}function De(){return`${w}/users/me/socket-rooms`}function cn(){return`${w}/liveblocks/auth`}function Me(e){return`${w}/components/${e}`}function Fe(){return`${w}/components/search`}function dt(){return`${w}/components/batch`}function pt(e){return`${w}/components/${e}/revisions`}function mn(e){return`${w}/components/${e}/copy`}function dn(e){return`${w}/components/${e}/copy-to-project`}function pn(e,t){return`${w}/components/${e}/revision/${t}/screenshot`}function ln(e){return`${w}/projects/${e}/canvas`}function gn(e){return`${w}/projects/${e}/copy`}function un(e){return`${w}/projects/${e}/move-to-organization`}function _e(e){return`${w}/projects/${e}/share`}function fn(){return`${w}/images/batch`}function hn(e){return`${w}/images/${e}/copy`}function yn(e){return`${w}/images/${e}/url`}function wn(){return`${w}/design-systems`}function In(e){return`${w}/organizations/${e}`}function lt(e){return`${w}/organizations/${e}/projects`}function vn(e){return`${w}/organizations/${e}/design-systems`}var bn=Cn.join(Pr.homedir(),".magicpath"),Le=Cn.join(bn,"session.json");function Ve(){try{if(!ge.existsSync(Le))return null;let e=ge.readJsonSync(Le);return e.accessToken&&e.refreshToken?e:null}catch{return null}}function Pn(e){ge.ensureDirSync(bn),ge.writeJsonSync(Le,e)}function jn(e,t){let n=Ve();Pn({accessToken:e,refreshToken:t,user:n==null?void 0:n.user})}function ue(){let e=Ve();return e?{accessToken:e.accessToken,refreshToken:e.refreshToken}:null}function An(){try{ge.removeSync(Le)}catch{}}function jr(e){try{let t=Ve();t&&(t.user=e,Pn(t))}catch{}}function Rn(){let e=Ve();return(e==null?void 0:e.user)??null}function u(){let{type:e,version:t}=_t(Te()),n={"X-Client-Type":"cli","X-Client-Version":G};e&&(n["X-Agent-Type"]=e),t&&(n["X-Agent-Version"]=t);let o=qt();o&&(n["X-Cli-Command"]=o);let s=process.env.MAGICPATH_TOKEN;if(s)return n.Authorization=`Bearer ${s}`,n;let r=ue();if(!r)throw new d("Not logged in.",{code:"AUTH_REQUIRED",suggestion:"Run: magicpath-ai auth login"});return n.Authorization=`Bearer ${r.accessToken}`,n}function gt(e){var o,s;let t=(o=e.subscription)!=null&&o.active?(s=e.subscription.type)!=null&&s.startsWith("PRO")?"Pro":"Creator":"Free",n={name:e.name||e.firstName||e.displayName,email:e.email,plan:t};return jr(n),n}async function xn(){let e=u(),t=await Sn.get(pe(),{headers:e}),n=t.data.user??t.data;return gt(n)}async function Q(e){let t=await Sn.get(pe(),{headers:e});return((t.data.user??t.data).organizationUsers??[]).map(s=>({id:String(s.organization.id),name:s.organization.name,role:s.role}))}async function M(e,t){let n=await Q(t),o=n.find(i=>i.id===e);if(o)return{id:o.id,name:o.name};let s=e.toLowerCase(),r=n.find(i=>i.name.toLowerCase()===s);if(r)return{id:r.id,name:r.name};throw new d(`Team "${e}" not found.`,{code:"TEAM_NOT_FOUND",suggestion:"Run `magicpath-ai list-teams` to see your teams."})}import Ge from"axios";function He(e){var n;let t=((n=e.data.data)==null?void 0:n.projects)??e.data.projects??e.data;return Array.isArray(t)?t:[]}async function We(e,t){if(t!=null&&t.personal){let c=await Ge.get(`${ct()}`,{headers:e});return He(c).map(a=>{var m;return{...a,ownerType:"personal",ownerName:((m=a.owner)==null?void 0:m.email)??""}})}if(t!=null&&t.orgId){let c=await Ge.get(`${lt(t.orgId)}`,{headers:{...e,"X-Organization-ID":t.orgId}});return He(c).map(a=>({...a,ownerType:"team",ownerName:t.orgName??""}))}let n=await Q(e),o=[Ge.get(`${ct()}`,{headers:e}).then(c=>He(c).map(a=>{var m;return{...a,ownerType:"personal",ownerName:((m=a.owner)==null?void 0:m.email)??""}})),...n.map(c=>Ge.get(`${lt(c.id)}`,{headers:{...e,"X-Organization-ID":c.id}}).then(a=>He(a).map(m=>({...m,ownerType:"team",ownerName:c.name}))).catch(()=>[]))],r=(await Promise.all(o)).flat(),i=new Set;return r.filter(c=>{let a=String(c.id);return i.has(a)?!1:(i.add(a),!0)})}import{createClient as Ar}from"@liveblocks/client";import Rr from"ws";function ze(e){let t=cn();return Ar({polyfills:{fetch,WebSocket:Rr},authEndpoint:async n=>await(await fetch(t,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify({room:n})})).json()})}async function Je(e,t,n=1e4){let{room:o,leave:s}=e.enterRoom(t,{initialPresence:{}});return await new Promise((r,i)=>{let c=setTimeout(()=>{i(new Error(`Timed out connecting to room ${t}`))},n),a=o.subscribe("status",m=>{m==="connected"&&(clearTimeout(c),a(),r())});o.getStatus()==="connected"&&(clearTimeout(c),a(),r())}),await new Promise(r=>{if(o.getOthers().length>0){r();return}let c=setTimeout(()=>{a(),r()},3e3),a=o.subscribe("others",m=>{m.length>0&&(clearTimeout(c),a(),r())})}),{room:o,leave:s}}function Be(e){var o,s;let t=e.getOthers(),n=[];for(let r of t){let i=(o=r.presence)==null?void 0:o.presence;(s=i==null?void 0:i.selectedShapeIds)!=null&&s.length&&n.push(...i.selectedShapeIds)}return[...new Set(n)]}async function En(e,t){let{root:n}=await e.getStorage(),o=n.get("records");if(!o)return[];let s=[];for(let r of t){let i=o.get(r);if(!i)continue;let c=typeof i.toObject=="function"?i.toObject():i;if(c.type==="mp-component"&&c.props){let a=typeof c.props.toObject=="function"?c.props.toObject():c.props;a.serverId&&s.push({serverId:a.serverId,clientId:a.clientId??r.replace("shape:",""),name:a.name??"Unknown",selectedRevisionId:typeof a.selectedRevisionId=="string"&&a.selectedRevisionId.length>0?a.selectedRevisionId:null})}}return s}function ee(e){return e&&typeof e.toObject=="function"?e.toObject():e}function F(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function xr(e,t){let n=ee(t),o=ee(n==null?void 0:n.meta);return F(o==null?void 0:o.imageId)??(e.startsWith("asset:")?e.slice(6):void 0)}function Er(e){return e.startsWith("shape:")?e.slice(6):e}async function qe(e,t){let{root:n}=await e.getStorage(),o=n.get("records");if(!o)return[];let s=[];for(let r of t){let i=o.get(r);if(!i)continue;let c=ee(i);if(c.type!=="image"&&c.type!=="mp-image")continue;let a=ee(c.props)??{},m=F(a.assetId),p=m?o.get(m):null,l=ee(p),y=ee(l==null?void 0:l.props)??{},h=(m?xr(m,p):void 0)??F(a.imageId)??F(a.serverId)??(r.startsWith("shape:")?r.slice(6):r);h&&s.push({imageId:h,shapeId:Er(r),...F(y.name)||F(a.name)||F(a.altText)?{name:F(y.name)??F(a.name)??F(a.altText)}:{},...typeof a.w=="number"?{width:a.w}:{},...typeof a.h=="number"?{height:a.h}:{}})}return s}function Tr(e){let t=typeof e=="string"?Number(e):typeof e=="number"?e:NaN;if(!Number.isInteger(t)||t<1)throw new d("Invalid --timeout value (must be a positive integer in milliseconds).",{code:"INVALID_TIMEOUT"});return t}async function Nr(e,t){var p,l;let n=await ut.get(De(),{headers:e}),o=((p=n.data.data)==null?void 0:p.socket_rooms)??n.data.socket_rooms,s=(o==null?void 0:o.projectRooms)??[];if(s.length===0)return{activeProjects:[],selection:{components:[],images:[]}};let r=new Map;try{let y=await We(e);r=new Map(y.map(h=>[String(h.id),h.name??""]))}catch{}let i=s.map(y=>{let h=String(y.id);return{id:h,name:r.get(h)??null,url:J(h)}}),c=ze(e),a=[],m=[];for(let y of s){let h=String(y.id),f=r.get(h)??"",v=null;try{let A=await Je(c,y.room,t);v=A.leave;let x=Be(A.room);if(x.length===0)continue;let[R,L]=await Promise.all([En(A.room,x),qe(A.room,x)]);m.push(...L.map(b=>({id:b.imageId,shapeId:b.shapeId,name:b.name??null,projectId:h,projectName:f,...b.width?{width:b.width}:{},...b.height?{height:b.height}:{}})));for(let b of R){let C=null,N=b.name;try{let z=await ut.get(Me(b.serverId),{headers:e}),V=((l=z.data.data)==null?void 0:l.component)??z.data.component;C=(V==null?void 0:V.generatedName)??null,N=(V==null?void 0:V.name)??b.name}catch{}a.push({id:b.serverId,generatedName:C,name:N,selectedRevisionId:b.selectedRevisionId,url:C?T("v1",C):null})}}finally{v&&v()}}return{activeProjects:i,selection:{components:a,images:m}}}var fe={name:"context",summary:"Show auth, teams, active canvas projects, and current selection",description:"One-call context for agents: who is authenticated, their teams, the project(s) open on the MagicPath canvas, and any selected components or images.",flags:[{flags:"--no-selection",description:"Skip reading the live canvas selection"},{flags:"--timeout <ms>",description:"Canvas connect timeout in milliseconds",default:"10000"}],run:async e=>{let t=[],n=null;process.env.MAGICPATH_TOKEN?n="environment":ue()&&(n="stored");let o=n!==null,s=e.mode.caller,r={version:G,agent:s.kind==="known-agent"?s.slug:null};if(!o)return t.push("Not authenticated \u2014 run: magicpath-ai auth login"),{data:{auth:{authenticated:!1,method:null,user:null},teams:[],activeProjects:[],selection:null,cli:r},warnings:t};let i=u(),c=e.progress("Gathering context\u2026");try{let a=await ut.get(pe(),{headers:i}),m=a.data.user??a.data;gt(m);let p={id:String(m.id),email:m.email??null,displayName:m.displayName??m.name??null},l=await Q(i),y=[],h=null;if(e.opts.selection!==!1){let f=Tr(e.opts.timeout);try{let v=await Nr(i,f);y=v.activeProjects,h=v.selection}catch(v){let A=v instanceof Error?v.message:String(v);t.push(`Canvas selection unavailable: ${A}`)}}return c.succeed(),{data:{auth:{authenticated:!0,method:n,user:p},teams:l,activeProjects:y,selection:h,cli:r},warnings:t}}catch(a){throw c.fail(),a}}};function Tn(e){g(e,fe),I(e,"whoami",fe),I(e,"info",fe),I(e,"selection",fe),I(e,"active-project",fe)}import kr from"http";import $n from"axios";import{exec as Ur}from"child_process";var $r=12e4,On=`
|
|
3
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
4
|
+
body{font-family:Geist,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#fff;color:#1a1a1a;padding:1rem}
|
|
5
|
+
.card{position:relative;width:100%;max-width:32rem;background:#fff;border-radius:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,.1),0 8px 10px -1px rgba(0,0,0,.1);overflow:hidden}
|
|
6
|
+
.gradient{position:absolute;top:0;left:0;right:0;height:12rem;background:radial-gradient(circle at center top,#DCF1E3 0%,#fff 80%);opacity:.2;pointer-events:none}
|
|
7
|
+
.content{position:relative;z-index:1;padding:2rem;display:flex;flex-direction:column;align-items:center}
|
|
8
|
+
.icon-box{width:4rem;height:4rem;border-radius:1rem;background:rgba(220,241,227,.1);display:flex;align-items:center;justify-content:center;margin-bottom:1rem}
|
|
9
|
+
.icon-box svg{width:2rem;height:2rem}
|
|
10
|
+
h1{font-size:1.5rem;font-weight:600;margin-bottom:.5rem;text-align:center}
|
|
11
|
+
p{color:#999;font-size:.9rem;text-align:center;max-width:24rem;line-height:1.5}
|
|
12
|
+
`,Or='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="#085C34"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>',Dr='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="#dc2626"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"/></svg>',Mr=`<!DOCTYPE html>
|
|
13
|
+
<html><head><meta charset="utf-8"><title>MagicPath CLI</title>
|
|
14
|
+
<style>${On}</style>
|
|
15
|
+
</head><body><div class="card"><div class="gradient"></div><div class="content">
|
|
16
|
+
<div class="icon-box">${Or}</div>
|
|
17
|
+
<h1>Logged in!</h1>
|
|
18
|
+
<p>You can close this tab and return to your terminal.</p>
|
|
19
|
+
</div></div></body></html>`,Nn=e=>`<!DOCTYPE html>
|
|
20
|
+
<html><head><meta charset="utf-8"><title>MagicPath CLI</title>
|
|
21
|
+
<style>${On}</style>
|
|
22
|
+
</head><body><div class="card"><div class="gradient"></div><div class="content">
|
|
23
|
+
<div class="icon-box">${Dr}</div>
|
|
24
|
+
<h1>Login failed</h1>
|
|
25
|
+
<p>${e}</p>
|
|
26
|
+
</div></div></body></html>`;async function Dn(e){let t=await $n.post(Kt("extension/tokens"),{token:e}),{access_token:n,refresh_token:o}=t.data;jn(n,o);try{return await xn()}catch{return null}}async function ft(e){return new Promise((t,n)=>{let o=!1,s,r=e.progress("Waiting for browser login\u2026");function i(){clearTimeout(s),c.close()}let c=kr.createServer(async(a,m)=>{var y;let p=new URL(a.url||"/","http://localhost");if(p.pathname!=="/callback"){m.writeHead(404,{"Content-Type":"text/plain"}),m.end("Not found");return}let l=p.searchParams.get("code");if(!l){m.writeHead(400,{"Content-Type":"text/html"}),m.end(Nn("No authorization code received."));return}try{let h=await Dn(l);m.writeHead(200,{"Content-Type":"text/html"}),m.end(Mr),i(),r.succeed("Logged in successfully!"),o=!0,t(h)}catch(h){let f=$n.isAxiosError(h)&&((y=h.response)==null?void 0:y.status)===400?"Invalid or expired authorization code. Please try again.":"Failed to exchange code. Please try again.";m.writeHead(400,{"Content-Type":"text/html"}),m.end(Nn(f)),i(),r.fail("Login failed"),o=!0,n(new d(f,{code:"AUTH_FAILED"}))}});c.listen(0,"127.0.0.1",()=>{let a=c.address();if(!a||typeof a=="string"){o=!0,n(new d("Failed to start local auth server."));return}let m=K(`/auth/cli?port=${a.port}`);r.text=`Waiting for browser login\u2026 If the browser doesn't open, visit: ${m}`;let p=process.platform;Ur(`${p==="darwin"?"open":p==="win32"?"start":"xdg-open"} "${m}"`)}),s=setTimeout(()=>{o||(i(),r.fail("Login timed out"),o=!0,n(new d("Login timed out.",{code:"LOGIN_TIMEOUT",suggestion:"Run `magicpath-ai auth login --code <code>` with a code from "+K("/auth/cli")})))},$r)})}var kn={name:"login",summary:"Log in to your MagicPath account",flags:[{flags:"--code <code>",description:"Exchange an authorization code non-interactively"}],run:async e=>{if(e.opts.code)return{data:{authenticated:!0,user:await Dn(e.opts.code)}};if(!e.mode.interactive)throw new d("Interactive login is not available in agent contexts.",{code:"AUTH_REQUIRED",suggestion:`Ask the user to run \`npx -y magicpath-ai auth login\` in their terminal, or supply --code <code> from ${K("/auth/cli")}`});return{data:{authenticated:!0,user:await ft(e)}}}},Un={name:"logout",summary:"Log out of your MagicPath account",run:async()=>(An(),{data:{loggedOut:!0}})},Fr={name:"status",summary:"Show local auth status without a network call",run:async()=>{let e=null;return process.env.MAGICPATH_TOKEN?e="environment":ue()&&(e="stored"),{data:{authenticated:e!==null,method:e,user:Rn()}}}};function Mn(e){let t=E(e,"auth","Authentication: log in, log out, and check status");g(t,kn),g(t,Un),g(t,Fr),I(e,"login",kn),I(e,"logout",Un)}import O from"axios";function ne(e){var t;return((t=e==null?void 0:e.data)==null?void 0:t.project)??(e==null?void 0:e.project)??e}function oe(e){let t=String(e.id);return{id:t,name:e.name??null,isLibrary:e.isLibrary??!1,...e.componentCount!==void 0?{componentCount:e.componentCount}:Array.isArray(e.components)?{componentCount:e.components.length}:{},...e.visibility!==void 0?{visibility:e.visibility}:{},...e.organizationId!==void 0?{organizationId:e.organizationId===null?null:String(e.organizationId)}:{},createdAt:e.createdAt??null,updatedAt:e.updatedAt??null,url:J(t)}}function _r(e){return{type:e.ownerType??"personal",name:e.ownerName??""}}var Fn={name:"list",summary:"List projects you can access (personal and team)",paginated:!0,flags:[{flags:"--team <nameOrId>",description:"Only projects in this team"},{flags:"--personal",description:"Only personal projects"},{flags:"--offset <n>",description:"Number of results to skip",hidden:!0}],run:async e=>{if(e.opts.team&&e.opts.personal)throw new d("Cannot use --team and --personal together.",{code:"INVALID_OPTIONS",suggestion:"Use --team to filter by team, or --personal for personal projects only."});let t=u(),n=e.progress("Fetching projects\u2026");try{let o;if(e.opts.personal)o={personal:!0};else if(e.opts.team){let a=await M(e.opts.team,t);o={orgId:a.id,orgName:a.name}}let s=await We(t,o),r=e.opts.offset!==void 0?Number(e.opts.offset)||0:e.page.cursor.offset??0,i=e.page.limit,c=s.slice(r,r+i);return n.succeed(),{data:{projects:c.map(a=>({...oe(a),workspace:_r(a)})),total:s.length},page:zt(r,i,r+c.length<s.length)}}catch(o){throw n.fail(),o}}},Lr={name:"get",summary:"Get a project by id",args:[{name:"id",description:"Project id"}],run:async e=>{let t=u(),n=await O.get(le(e.args[0]),{headers:t}),o=ne(n.data);return{data:{project:{...oe(o),...Array.isArray(o.images)?{imageCount:o.images.length}:{},isSharingEnabled:o.isSharingEnabled??!1}}}}},_n={name:"create",summary:"Create a project (personal or in a team)",flags:[{flags:"--name <name>",description:"Project name (defaults to an auto-generated name)"},{flags:"--team <nameOrId>",description:"Create the project in this team"}],run:async e=>{var o;let t=u(),n=e.progress("Creating project\u2026");try{let s={...t},r=null;e.opts.team&&(r=await M(e.opts.team,t),s["X-Organization-ID"]=r.id);let i=await O.post(rn(),{},{headers:s}),c=ne(i.data);if(e.opts.name){let a=await O.patch(le(String(c.id)),{data:{name:e.opts.name}},{headers:s});c=ne(a.data)}return n.succeed(),{data:{project:{...oe(c),workspace:r?{type:"team",name:r.name}:{type:"personal",name:((o=c.owner)==null?void 0:o.email)??""}}}}}catch(s){throw n.fail(),s}}},Vr={name:"rename",summary:"Rename a project",args:[{name:"id",description:"Project id"}],flags:[{flags:"--name <name>",description:"New project name"}],run:async e=>{if(!e.opts.name)throw new d("Missing --name.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai project rename <id> --name <name>"});let t=u(),n=await O.patch(le(e.args[0]),{data:{name:e.opts.name}},{headers:t});return{data:{project:oe(ne(n.data))}}}},Gr={name:"delete",summary:"Delete a project",args:[{name:"id",description:"Project id"}],run:async e=>{let t=u();return await O.delete(le(e.args[0]),{headers:t}),{data:{deleted:!0,id:e.args[0]}}}},Hr={name:"duplicate",summary:"Duplicate a project, including its components",args:[{name:"id",description:"Project id to copy"}],run:async e=>{let t=u(),n=e.progress("Duplicating project\u2026");try{let o=await O.post(gn(e.args[0]),{},{headers:t});return n.succeed(),{data:{project:oe(ne(o.data))}}}catch(o){throw n.fail(),o}}},Wr={name:"move",summary:"Move a project into a team workspace",args:[{name:"id",description:"Project id"}],flags:[{flags:"--team <nameOrId>",description:"Destination team"}],run:async e=>{if(!e.opts.team)throw new d("Missing --team.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai project move <id> --team <nameOrId>"});let t=u(),n=await M(e.opts.team,t),o=await O.post(un(e.args[0]),{organizationId:n.id},{headers:t});return{data:{project:oe(ne(o.data)),team:{id:n.id,name:n.name}}}}},zr={name:"canvas",summary:"Snapshot of a project canvas: components and images with positions",args:[{name:"id",description:"Project id"}],run:async e=>{var o;let t=u(),n=e.progress("Fetching canvas\u2026");try{let r=((o=(await O.get(ln(e.args[0]),{headers:t})).data)==null?void 0:o.data)??{};return n.succeed(),{data:{canvas:{...r,components:(r.components??[]).map(i=>({...i,id:String(i.id),...i.selectedRevisionId!==void 0&&i.selectedRevisionId!==null?{selectedRevisionId:String(i.selectedRevisionId)}:{},url:T("v1",i.generatedName)})),images:(r.images??[]).map(i=>({...i,id:String(i.id)}))}}}}catch(s){throw n.fail(),s}}},Jr={name:"share-link",summary:"Get (or create) a public share link for a project",args:[{name:"id",description:"Project id"}],flags:[{flags:"--revoke",description:"Revoke all share links and disable sharing"}],run:async e=>{var r,i,c,a,m;let t=e.args[0],n=u();if(e.opts.revoke)return await O.delete(_e(t),{headers:n}),{data:{revoked:!0,projectId:t}};let s=((c=(i=(r=(await O.get(_e(t),{headers:n})).data)==null?void 0:r.data)==null?void 0:i.share_tokens)==null?void 0:c[0])??null;return s||(s=(m=(a=(await O.post(_e(t),{},{headers:n})).data)==null?void 0:a.data)==null?void 0:m.share_token),{data:{shareUrl:K(`/projects/${t}?token=${s.token}`),token:s.token,projectId:t}}}};function Ln(e){let t=E(e,"project","Projects: list, create, rename, duplicate, move, share, and inspect canvases");g(t,Fn),g(t,Lr),g(t,_n),g(t,Vr),g(t,Gr),g(t,Hr),g(t,Wr),g(t,zr),g(t,Jr),I(e,"list-projects",Fn),I(e,"create-project",_n)}import _ from"axios";import Br from"path";import qr from"fs-extra";var Vn=20,Hn=1280,Wn=832;function zn(e){return e.generatedName?{...e,url:T("v1",e.generatedName)}:e}function ht(e){return zn({...e,id:String(e.id),...e.projectId!=null?{projectId:String(e.projectId)}:{},selectedRevisionId:e.selectedRevisionId!=null?String(e.selectedRevisionId):null})}async function B(e,t){return(await _.get(Me(e),{headers:t})).data.data.component}async function q(e,t){var r;if(/^\d+$/.test(e))return e;let s=(((r=(await _.get(Fe(),{headers:t,params:{q:e,limit:5}})).data.data)==null?void 0:r.components)??[]).find(i=>i.generatedName===e);if(!s)throw new d(`Component "${e}" not found.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai component list <projectId>` to see components."});return String(s.id)}function Jn(e,t){if(t)return t;if(e.selectedRevisionId!=null)return String(e.selectedRevisionId);let n=(e.revisions??[]).find(o=>o.status==="COMPLETED");if(n)return String(n.id);throw new d(`Component ${e.id} has no completed revision.`,{code:"NO_COMPLETED_REVISION",suggestion:"Pass --revision explicitly or wait for a revision to complete."})}async function Bn(e,t){return(await _.patch(dt(),{operations:e.map(o=>({...o,type:"update"}))},{headers:t})).data.results??[]}function qn(e){let t=e.find(n=>!n.success);if(t)throw new d(`Failed to update component ${t.componentId}: ${t.error??"unknown error"}.`,{code:"API_ERROR"})}var Gn={name:"list",summary:"List components in a project",args:[{name:"projectId",description:"The project ID"}],flags:[{flags:"--name <substr>",description:"Filter by name (case-insensitive substring)"},{flags:"--created-by <userId>",description:"Filter to components created or edited by this user ID"},{flags:"--sort-by <field>",description:"Sort by field (name, createdAt)",default:"name"},{flags:"--order <dir>",description:"Sort direction (asc, desc)",default:"asc"},{flags:"--status <status>",description:"Revision status filter (COMPLETED, PENDING, FAILED)",default:"COMPLETED"},{flags:"--after <id>",description:"Legacy cursor: fetch components after this ID",hidden:!0}],paginated:!0,run:async e=>{var o,s;let t=u(),n=e.progress("Fetching components\u2026");try{let r=new URLSearchParams({limit:String(e.page.limit),revisionStatus:e.opts.status??"COMPLETED",sortBy:e.opts.sortBy??"name",order:e.opts.order??"asc"}),i=e.opts.after??e.page.cursor.after;i&&r.set("after",String(i)),e.opts.name&&r.set("name",e.opts.name),e.opts.createdBy&&r.set("createdBy",e.opts.createdBy);let c=await _.get(`${sn(e.args[0])}?${r}`,{headers:t}),a=((o=c.data.data)==null?void 0:o.components)??[],m=((s=c.data.data)==null?void 0:s.pagination)??{hasNext:!1,lastId:null};return n.succeed(),{data:{components:a.map(p=>zn({...p,id:String(p.id)}))},page:Ue(m.lastId!=null?String(m.lastId):null,!!m.hasNext)}}catch(r){throw n.fail(),r}}},Xr={name:"get",summary:"Get a component by ID or generatedName",args:[{name:"idOrGeneratedName",description:"Component ID (numeric) or generatedName (e.g. wispy-river-5234)"}],run:async e=>{let t=u(),n=e.progress("Fetching component\u2026");try{let o=await q(e.args[0],t),s=await B(o,t);return n.succeed(),{data:{component:ht(s)}}}catch(o){throw n.fail(),o}}},Yr={name:"rename",summary:"Rename a component",args:[{name:"id",description:"Component ID"}],flags:[{flags:"--name <name>",description:"New component name"}],run:async e=>{if(!e.opts.name)throw new d("Missing --name.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai component rename <id> --name <name>"});let t=u(),n=e.progress("Renaming component\u2026");try{let o=await q(e.args[0],t),s=await B(o,t),r=await Bn([{componentId:o,data:{projectId:String(s.projectId),name:e.opts.name}}],t);return qn(r),n.succeed(),{data:{component:{id:o,name:e.opts.name,projectId:String(s.projectId)}}}}catch(o){throw n.fail(),o}}},Zr={name:"delete",summary:"Delete one or more components",args:[{name:"id",description:"Component ID(s)",variadic:!0}],run:async e=>{let t=u(),n=e.args.flat(),o=e.progress("Deleting components\u2026");try{let s=new Map;for(let i of n){let c=await q(i,t),a=await B(c,t),m=String(a.projectId);s.set(m,[...s.get(m)??[],c])}let r=[];for(let[i,c]of s)for(let a=0;a<c.length;a+=Vn){let m=c.slice(a,a+Vn),p=await _.delete(dt(),{headers:t,data:{operations:m.map(l=>({componentId:l,type:"delete",data:{projectId:i}}))}});for(let l of p.data.results??[])r.push({id:String(l.componentId),success:!!l.success,...l.error?{error:l.error}:{}})}return o.succeed(),{data:{deleted:r.filter(i=>i.success).map(i=>i.id),results:r}}}catch(s){throw o.fail(),s}}},Kr={name:"duplicate",summary:"Duplicate a component within its project",args:[{name:"id",description:"Component ID"}],run:async e=>{var o,s,r,i,c;let t=u(),n=e.progress("Duplicating component\u2026");try{let a=await q(e.args[0],t),m=await B(a,t),p={x:Number(((o=m.position)==null?void 0:o.x)??0),y:Number(((s=m.position)==null?void 0:s.y)??0),z:Number(((r=m.position)==null?void 0:r.z)??0),width:Number(((i=m.position)==null?void 0:i.width)??Hn),height:Number(((c=m.position)==null?void 0:c.height)??Wn)};p.x=p.x+p.width+200;let l=await _.post(mn(a),{position:p},{headers:t});return n.succeed(),{data:{component:ht(l.data.data.component)}}}catch(a){throw n.fail(),a}}},Qr={name:"copy-to",summary:"Copy a component to another project",args:[{name:"id",description:"Component ID"}],flags:[{flags:"--project <targetProjectId>",description:"Target project ID"},{flags:"--revision <revisionId>",description:"Revision to copy (defaults to the selected revision)"}],run:async e=>{if(!e.opts.project)throw new d("Missing --project.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai component copy-to <id> --project <targetProjectId>"});let t=u(),n=e.progress("Copying component\u2026");try{let o=await q(e.args[0],t),s=e.opts.revision;if(!s){let a=await B(o,t);s=Jn(a)}let r=await _.post(dn(o),{targetProjectId:String(e.opts.project),revisionId:s},{headers:t}),{component:i,revision:c}=r.data.data;return n.succeed(),{data:{component:ht(i),revision:c?{id:String(c.id),status:c.status,previewImageUrl:c.previewImageUrl??null}:null}}}catch(o){throw n.fail(),o}}},es={name:"revisions",summary:"List a component's revision history (newest first)",args:[{name:"id",description:"Component ID"}],run:async e=>{var o;let t=u(),n=e.progress("Fetching revisions\u2026");try{let s=await q(e.args[0],t),[r,i]=await Promise.all([_.get(pt(s),{headers:t}),B(s,t)]),c=i.selectedRevisionId!=null?String(i.selectedRevisionId):null,a=(((o=r.data.data)==null?void 0:o.revisions)??[]).map(m=>({id:String(m.id),status:m.status,createdAt:m.createdAt,previewImageUrl:m.previewImageUrl??null,isSelected:String(m.id)===c}));return n.succeed(),{data:{revisions:a,selectedRevisionId:c}}}catch(s){throw n.fail(),s}}},ts={name:"select-revision",summary:"Set a component's selected revision (reverts the canvas to that revision)",args:[{name:"id",description:"Component ID"}],flags:[{flags:"--revision <revisionId>",description:"Revision ID to select"}],run:async e=>{var o;if(!e.opts.revision)throw new d("Missing --revision.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai component select-revision <id> --revision <revisionId>"});let t=u(),n=e.progress("Selecting revision\u2026");try{let s=await q(e.args[0],t),r=String(e.opts.revision),[i,c]=await Promise.all([B(s,t),_.get(pt(s),{headers:t})]),a=(((o=c.data.data)==null?void 0:o.revisions)??[]).find(p=>String(p.id)===r);if(!a)throw new d(`Revision ${r} not found on component ${s}.`,{code:"NOT_FOUND",suggestion:`Run \`magicpath-ai component revisions ${s}\` to see revisions.`});let m=await Bn([{componentId:s,data:{projectId:String(i.projectId),selectedRevisionId:r}}],t);return qn(m),n.succeed(),{data:{component:{id:s,selectedRevisionId:r},revision:{id:r,previewImageUrl:a.previewImageUrl??null}}}}catch(s){throw n.fail(),s}}},ns={name:"screenshot",summary:"Render a PNG screenshot of a component revision",args:[{name:"id",description:"Component ID"}],flags:[{flags:"--revision <revisionId>",description:"Revision to render (defaults to the selected revision)"},{flags:"--width <px>",description:"Viewport width in pixels (100-4000)",default:String(Hn)},{flags:"--height <px>",description:"Viewport height in pixels (100-4000)",default:String(Wn)},{flags:"--scale <n>",description:"Device scale factor (1-4)"},{flags:"--out <path>",description:"Output file path (default: magicpath-screenshot-<id>.png)"}],run:async e=>{let t=u(),n=e.progress("Taking screenshot\u2026");try{let o=await q(e.args[0],t),s=e.opts.revision;if(!s){let p=await B(o,t);s=Jn(p)}let r=Number(e.opts.width),i=Number(e.opts.height),c={width:r,height:i};e.opts.scale&&(c.scale=Number(e.opts.scale));let a=await _.post(pn(o,s),c,{headers:t,responseType:"arraybuffer"}),m=Br.resolve(e.opts.out??`magicpath-screenshot-${o}.png`);return await qr.outputFile(m,Buffer.from(a.data)),n.succeed(),{data:{path:m,componentId:o,revisionId:s,width:r,height:i}}}catch(o){throw n.fail(),o}}};function Xn(e){let t=E(e,"component","Components: list, get, rename, delete, duplicate, copy, revisions, screenshots",{aliases:["design"]});g(t,Gn),g(t,Xr),g(t,Yr),g(t,Zr),g(t,Kr),g(t,Qr),g(t,es),g(t,ts),g(t,ns),I(e,"list-components",Gn)}import he from"axios";import os from"fs-extra";async function Kn(e,t){var i;let n=an(),o=t;if(e){let c=await M(e,t);n=vn(c.id),o={...t,"X-Organization-ID":c.id}}let s=await he.get(n,{headers:o}),r=((i=s.data.data)==null?void 0:i.design_systems)??s.data.design_systems??s.data;return Array.isArray(r)?r:[]}async function Qn(e){if(e.file&&e.json)throw new d("Cannot use --file and --json together.",{code:"INVALID_ARGUMENTS",suggestion:"Pass the theme data either as a JSON file or inline, not both."});let t;if(e.file)try{t=await os.readJson(e.file)}catch{throw new d(`Could not read JSON from "${e.file}".`,{code:"INVALID_ARGUMENTS",suggestion:"Check that the file exists and contains valid JSON."})}else try{t=JSON.parse(e.json)}catch{throw new d("Invalid --json value.",{code:"INVALID_ARGUMENTS",suggestion:`Pass a valid JSON object string, e.g. --json '{"theme":{...}}'.`})}if(!t||typeof t!="object"||Array.isArray(t))throw new d("Theme payload must be a JSON object.",{code:"INVALID_ARGUMENTS"});return t}function rs(e){let t=typeof e.type=="string"?e.type:"tailwind",n=e.data&&typeof e.data=="object"?e.data:e;return t==="tailwind"&&n.version===void 0&&(n={...n,version:1}),{type:t,data:n}}function yt(e){return{id:String(e.id),name:e.name,...e.type!==void 0?{type:e.type}:{},...e.isPublic!==void 0?{isPublic:e.isPublic}:{},...e.createdAt!==void 0?{createdAt:e.createdAt}:{},...e.updatedAt!==void 0?{updatedAt:e.updatedAt}:{}}}var Yn={name:"list",summary:"List themes (design systems)",flags:[{flags:"--team <nameOrId>",description:"List themes for a specific team"}],run:async e=>{let t=u(),n=e.progress("Fetching themes\u2026");try{let o=await Kn(e.opts.team,t);return n.succeed(),{data:{themes:o.map(yt)}}}catch(o){throw n.fail(),o}}},Zn={name:"get",summary:"Get a theme definition (CSS variables, fonts, styling prompt)",args:[{name:"idOrName",description:"Theme ID (numeric) or name (case-insensitive match)"}],flags:[{flags:"--team <nameOrId>",description:"Look up theme within a specific team"}],run:async e=>{var o;let t=u(),n=e.progress("Fetching theme\u2026");try{let s=e.args[0],r;if(!/^\d+$/.test(s)){let m=await Kn(e.opts.team,t),p=s.toLowerCase(),l=m.find(y=>(y.name||"").toLowerCase()===p);if(!l)throw new d(`Theme "${e.args[0]}" not found.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai theme list` to see available themes."});s=String(l.id),r=l.name}let i=await he.get(Oe(s),{headers:t}),c=((o=i.data.data)==null?void 0:o.design_system)??i.data.design_system,a=c.data??{};return n.succeed(),{data:{id:String(c.id??s),name:c.name??r??s,...c.type!==void 0?{type:c.type}:{},theme:a.theme,defaultTheme:a.defaultTheme,prompt:a.prompt??a.markdown,fonts:a.fonts,version:a.version}}}catch(s){throw n.fail(),s}}},ss={name:"create",summary:"Create a theme (design system)",flags:[{flags:"--name <name>",description:"Theme name"},{flags:"--file <path>",description:"Path to a JSON file with the theme data"},{flags:"--json <inline>",description:"Inline JSON string with the theme data"}],run:async e=>{var i;if(!e.opts.name)throw new d("Missing --name.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai theme create --name <name> --file <path.json>"});if(!e.opts.file&&!e.opts.json)throw new d("Missing theme data.",{code:"INVALID_ARGUMENTS",suggestion:"Pass the theme data with --file <path.json> or --json <inline>."});let t=u(),n=await Qn(e.opts),{type:o,data:s}=rs(n),r=e.progress("Creating theme\u2026");try{let c=await he.post(wn(),{name:e.opts.name,type:o,data:s},{headers:t}),a=((i=c.data.data)==null?void 0:i.design_system)??c.data.design_system;return r.succeed(),{data:{theme:yt(a)}}}catch(c){throw r.fail(),c}}},is={name:"update",summary:"Update a theme name and/or data",args:[{name:"id",description:"Theme ID"}],flags:[{flags:"--name <name>",description:"New theme name"},{flags:"--file <path>",description:"Path to a JSON file with the new theme data"},{flags:"--json <inline>",description:"Inline JSON string with the new theme data"}],run:async e=>{var s;if(!e.opts.name&&!e.opts.file&&!e.opts.json)throw new d("Nothing to update.",{code:"INVALID_ARGUMENTS",suggestion:"Pass --name, --file, or --json."});let t=u(),n={};if(e.opts.name&&(n.name=e.opts.name),e.opts.file||e.opts.json){let r=await Qn(e.opts);n.data=r.data&&typeof r.data=="object"?r.data:r}let o=e.progress("Updating theme\u2026");try{let r=await he.patch(Oe(e.args[0]),n,{headers:t}),i=((s=r.data.data)==null?void 0:s.design_system)??r.data.design_system;return o.succeed(),{data:{theme:yt(i)}}}catch(r){throw o.fail(),r}}},as={name:"delete",summary:"Delete a theme",args:[{name:"id",description:"Theme ID"}],run:async e=>{let t=u(),n=e.progress("Deleting theme\u2026");try{return await he.delete(Oe(e.args[0]),{headers:t}),n.succeed(),{data:{deleted:!0,id:e.args[0]}}}catch(o){throw n.fail(),o}}};function eo(e){let t=E(e,"theme","Themes (design systems): list, get, create, update, delete");g(t,Yn),g(t,Zn),g(t,ss),g(t,is),g(t,as),I(e,"list-themes",Yn),I(e,"get-theme",Zn)}import cs from"axios";var wt={name:"list",summary:"List teams the authenticated user belongs to",run:async()=>{let e=u();return{data:{teams:await Q(e)}}}};async function no(e,t){var s;let n=u(),o=t.progress("Fetching members\u2026");try{let r=await M(e,n),i=await cs.get(In(r.id),{headers:{...n,"X-Organization-ID":r.id}}),a=(((s=i.data.data)==null?void 0:s.organization)??i.data.organization??i.data).users??[];return o.succeed(),{data:{team:{id:r.id,name:r.name},members:a.map(m=>{var p,l,y;return{id:String(((p=m.user)==null?void 0:p.id)??m.userId),displayName:((l=m.user)==null?void 0:l.displayName)??null,email:((y=m.user)==null?void 0:y.email)??null,role:m.role}})}}}catch(r){throw o.fail(),r}}var to={name:"members",summary:"List members of a team",args:[{name:"team",description:"Team name or ID"}],run:async e=>no(e.args[0],e)};function oo(e){let t=E(e,"team","Teams (read-only): list teams and their members");g(t,wt),g(t,to),I(e,"list-teams",wt),I(e,"list-orgs",wt),I(e,"list-members",{...to,args:[],flags:[{flags:"--team <nameOrId>",description:"Team name or ID"}],run:async n=>{if(!n.opts.team)throw new d("Missing --team.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai team members <nameOrId>"});return no(n.opts.team,n)}})}import X from"axios";import ro from"fs";import It from"path";import{imageSize as ms}from"image-size";var so=512;async function ds(e){if(/^https?:\/\//i.test(e)){let n=await X.get(e,{responseType:"arraybuffer"}),o=It.basename(new URL(e).pathname)||"image";return{buffer:Buffer.from(n.data),fileName:o}}let t=It.resolve(e);if(!ro.existsSync(t))throw new d(`Image file not found: ${t}`,{code:"FILE_NOT_FOUND",suggestion:"Pass a local image file path or an http(s) URL."});return{buffer:ro.readFileSync(t),fileName:It.basename(t)}}function Xe(e){if(e===void 0)return;let t=Number(e);if(!Number.isFinite(t))throw new d(`Invalid number: ${e}`,{code:"INVALID_ARGUMENTS"});return t}function vt(e){return{id:String(e.id),name:e.name??null,url:e.url??null,position:e.position??null}}var ps={name:"add",summary:"Add an image to a project canvas from a local file path or a URL",args:[{name:"projectId",description:"The id of the project to add the image to"},{name:"pathOrUrl",description:"A local image file path or an http(s) URL"}],flags:[{flags:"--name <name>",description:"Display name for the image (defaults to the file name)"},{flags:"--x <x>",description:"Canvas x position (default 0)"},{flags:"--y <y>",description:"Canvas y position (default 0)"},{flags:"--width <width>",description:"Width in canvas units (defaults to the intrinsic width)"},{flags:"--height <height>",description:"Height in canvas units (defaults to the intrinsic height)"}],run:async e=>{var s,r;let[t,n]=e.args,o=e.progress("Adding image to project\u2026");try{let i=u(),{buffer:c,fileName:a}=await ds(n),m=Xe(e.opts.width),p=Xe(e.opts.height);if(m===void 0||p===void 0)try{let R=ms(c);m=m??R.width,p=p??R.height}catch{}m=m??so,p=p??so;let l={x:Xe(e.opts.x)??0,y:Xe(e.opts.y)??0,z:0,width:m,height:p},y=e.opts.name??(a.replace(/\.[^/.]+$/,"")||a),h=await X.get(on(),{headers:i,params:{filename:a,content_type:"image/*",make_public:"true"}}),{upload_url:f,upload_token:v}=h.data;await X.put(f,c,{headers:{"Content-Type":"image/*","x-goog-acl":"public-read"}});let x=(r=(s=(await X.post(mt(t),{name:y,position:l,upload_token:v},{headers:i})).data)==null?void 0:s.data)==null?void 0:r.image;return o.succeed(),{data:{image:vt(x)}}}catch(i){throw o.fail(),i}}},ls={name:"list",summary:"List the images on a project canvas",args:[{name:"projectId",description:"The id of the project"}],run:async e=>{var s,r;let t=u();return{data:{images:(((r=(s=(await X.get(mt(e.args[0]),{headers:t})).data)==null?void 0:s.data)==null?void 0:r.images)??[]).map(vt)}}}},gs={name:"delete",summary:"Delete one or more images from a project canvas",args:[{name:"id",description:"Image id(s) to delete",variadic:!0}],flags:[{flags:"--project <projectId>",description:"The project the images belong to"}],run:async e=>{var i;let t=e.args[0]??[];if(!e.opts.project)throw new d("Missing --project.",{code:"INVALID_ARGUMENTS",suggestion:"Use: magicpath-ai image delete <id...> --project <projectId>"});let n=u(),o={operations:t.map(c=>({imageId:c,type:"delete",data:{projectId:e.opts.project}}))};return{data:{results:(((i=(await X.delete(fn(),{headers:n,data:o})).data)==null?void 0:i.results)??[]).map(c=>({id:String(c.imageId),deleted:c.success===!0}))}}}},us={name:"duplicate",summary:"Duplicate an image on its project canvas",args:[{name:"id",description:"Image id to copy"}],run:async e=>{var o,s;let t=u(),n=await X.post(hn(e.args[0]),{},{headers:t});return{data:{image:vt((s=(o=n.data)==null?void 0:o.data)==null?void 0:s.image)}}}},fs={name:"url",summary:"Get a fresh, viewable URL for an image",args:[{name:"id",description:"Image id"}],run:async e=>{var o,s;let t=u(),n=await X.get(yn(e.args[0]),{headers:t});return{data:{id:e.args[0],url:((s=(o=n.data)==null?void 0:o.data)==null?void 0:s.url)??null}}}};function io(e){let t=E(e,"image","Project canvas images: add, list, delete, duplicate, and resolve URLs");g(t,ps),g(t,ls),g(t,gs),g(t,us),g(t,fs)}import hs from"axios";var ys=50,ws={name:"search",summary:"Search components by name across all accessible projects",description:"Server-side search over component name and generatedName in every project the user can access. Filter with --team, --personal, or --project.",args:[{name:"query",description:"Search text (case-insensitive)"}],flags:[{flags:"--team <nameOrId>",description:"Search only within a specific team"},{flags:"--personal",description:"Search only personal projects"},{flags:"--project <projectId>",description:"Search only within a specific project"}],paginated:!0,run:async e=>{if(e.opts.team&&e.opts.personal)throw new d("Cannot use --team and --personal together.",{code:"INVALID_OPTIONS",suggestion:"Use --team to filter by team, or --personal for personal projects only."});let t=u(),n=Math.min(e.page.limit,ys),o={q:e.args[0],limit:String(n)};if(e.page.cursor.after&&(o.after=e.page.cursor.after),e.opts.personal)o.personal="true";else if(e.opts.team){let r=await M(e.opts.team,t);o.organizationId=r.id}e.opts.project&&(o.projectId=e.opts.project);let s=e.progress("Searching components\u2026");try{let i=(await hs.get(Fe(),{headers:t,params:o})).data.data,c=(i.components??[]).map(p=>({...p,url:T("v1",p.generatedName)})),{hasNext:a,lastId:m}=i.pagination;return s.succeed(),{data:{components:c},page:Ue(m===null?null:String(m),a)}}catch(r){throw s.fail(),r}}};function ao(e){g(e,ws)}import vo from"axios";import Co from"fs-extra";import As from"path";import mo from"crypto";import $ from"fs-extra";import k from"path";var Is=new Set(["src/App.tsx","src/index.css"]),co="This component uses Tailwind v4. Replace @tailwind base/components/utilities; with @import 'tailwindcss';. Preserve the existing src/index.css Tailwind setup and append custom CSS below it.",vs=/@tailwind\s+(base|components|utilities)\s*;/i,Cs=/@import\s+(?:url\(\s*)?['"]tailwindcss['"]\s*\)?\s*;/i;function Y(e){return mo.createHash("sha256").update(e).digest("hex")}function Ss(e){return mo.createHash("sha256").update(e).digest("hex")}function Ye(e){return k.posix.normalize(e)!==e?!1:Is.has(e)||e.startsWith("src/components/generated/")&&!e.endsWith("/")||e.startsWith("assets/")&&!e.endsWith("/")}function Ze(e){return e.startsWith("assets/")&&!e.endsWith("/")}function bs(e){let t=k.extname(e).toLowerCase();return{".avif":"image/avif",".gif":"image/gif",".jpeg":"image/jpeg",".jpg":"image/jpeg",".png":"image/png",".svg":"image/svg+xml",".webp":"image/webp"}[t]}function Ct(e){let t=[];for(let n of $.readdirSync(e,{withFileTypes:!0})){let o=k.join(e,n.name);n.isDirectory()?t.push(...Ct(o)):n.isFile()&&t.push(o)}return t}function we(e,t){if(!Ye(t.path))throw new d(`Refusing to write disallowed path from API: ${t.path}`,{code:"DISALLOWED_PATH"});let n=k.join(e,t.path);$.ensureDirSync(k.dirname(n)),t.encoding==="base64"?$.writeFileSync(n,Buffer.from(t.content.replace(/\s/g,""),"base64")):$.writeFileSync(n,t.content,"utf8")}function ye(e){let t=[],n=["src/App.tsx","src/index.css"],o=k.join(e,"src/components/generated");if($.existsSync(o))for(let r of Ct(o))n.push(k.relative(e,r).split(k.sep).join("/"));let s=k.join(e,"assets");if($.existsSync(s))for(let r of Ct(s))n.push(k.relative(e,r).split(k.sep).join("/"));for(let r of Array.from(new Set(n)).sort()){if(!Ye(r))continue;let i=k.join(e,r);if(!(!$.existsSync(i)||!$.statSync(i).isFile()))if(Ze(r)){let c=$.readFileSync(i);t.push({path:r,content:c.toString("base64"),encoding:"base64",mimeType:bs(r),sha256:Ss(c)})}else{let c=$.readFileSync(i,"utf8");t.push({path:r,content:c,encoding:"utf8",sha256:Y(c)})}}return t}function po(e){let t=k.join(e,"src/index.css");if(!$.existsSync(t))throw new d(co,{code:"TAILWIND_V4_REQUIRED"});let n=$.readFileSync(t,"utf8");if(vs.test(n)||!Cs.test(n))throw new d(co,{code:"TAILWIND_V4_REQUIRED"})}function lo(e,t){if(t.mode==="create")return ye(e);let n=new Map(t.editableFiles.map(o=>[o.path,o.sha256]));return ye(e).map(o=>({...o,baseSha256:n.get(o.path)})).filter(o=>o.sha256!==o.baseSha256)}function go(e,t){if(t.mode==="create")return[];let n=new Set(ye(e).map(o=>o.path));return t.editableFiles.map(o=>o.path).filter(o=>!Ze(o)).filter(o=>!n.has(o))}import ho from"axios";import uo from"fs-extra";import fo from"path";function Ps(e){let t=new Map;for(let n of e)t.has(n.imageId)||t.set(n.imageId,n);return Array.from(t.values())}async function St(e){var n;let t;try{t=u()}catch{return[]}try{let o=await ho.get(De(),{headers:t}),s=((n=o.data.data)==null?void 0:n.socket_rooms)??o.data.socket_rooms,r=(s==null?void 0:s.projectRooms)??[],i=e?r.filter(m=>String(m.id)===String(e)):r;if(i.length===0)return[];let c=ze(t),a=[];for(let m of i){let p=null;try{let l=await Je(c,m.room);p=l.leave;let y=Be(l.room);if(y.length===0)continue;let h=await qe(l.room,y);a.push(...h.filter(f=>/^\d+$/.test(f.imageId)).map(f=>({imageId:f.imageId,...f.shapeId?{shapeId:f.shapeId}:{}})))}catch{}finally{p&&p()}}return Ps(a)}catch{return[]}}async function bt(e,t){if(!(t!=null&&t.length))return[];let n=[];for(let o of t){if(!Ye(o.assetPath)||!Ze(o.assetPath))throw new d(`Refusing to download selected image outside assets/: ${o.assetPath}`,{code:"DISALLOWED_PATH"});let s=await ho.get(o.accessUrl,{responseType:"arraybuffer"}),r=fo.join(e,o.assetPath);uo.ensureDirSync(fo.dirname(r)),uo.writeFileSync(r,Buffer.from(s.data)),n.push({...o,downloadedPath:r})}return n}import Ke from"fs-extra";import js from"path";var wo="magicpath-code.json";function Ie(e){return js.join(e,wo)}function Io(e){let t=Ie(e);if(!Ke.existsSync(t))throw new d(`No ${wo} found.`,{code:"NO_MANIFEST",suggestion:"Run `magicpath-ai code start --project <projectId>` or `magicpath-ai code start --component <componentId>` first."});return Ke.readJsonSync(t)}function ve(e,t){Ke.ensureDirSync(e),Ke.writeJsonSync(Ie(e),t,{spaces:2})}function yo(e,t){if(e===void 0)return;let n=Number(e);if(!Number.isFinite(n)||n<=0)throw new d(`${t} must be a positive number.`,{code:"INVALID_ARGUMENTS"});return n}function Ce(e){let t=yo(e.width,"--width"),n=yo(e.height,"--height");if(t===void 0!=(n===void 0))throw new d("Pass both --width and --height, or neither.",{code:"INVALID_ARGUMENTS"});return t===void 0||n===void 0?void 0:{width:t,height:n}}async function Rs(e,t){let n=t.progress("Starting edit session\u2026");try{let o=await St(),r=(await vo.post(en(t.opts.component),{...t.opts.revision?{revisionId:t.opts.revision}:{},...o.length>0?{selectedImages:o}:{}},{headers:u()})).data.data;Co.ensureDirSync(e);for(let a of r.editableFiles)we(e,a);let i=await bt(e,r.selectedImages),c={mode:"edit",componentId:r.component.id,projectId:r.component.projectId,selectedRevisionId:r.component.selectedRevisionId,baseRevisionId:r.component.baseRevisionId,jobId:r.jobId,generatedName:r.component.generatedName,name:r.component.name,selectedImages:i,editableFiles:r.editableFiles.map(a=>({path:a.path,sha256:Y(a.content)}))};return ve(e,c),n.succeed(),{data:{dir:e,manifestPath:Ie(e),...c,status:"pending",scaffoldedPaths:r.editableFiles.map(a=>a.path),selectedImages:i}}}catch(o){throw n.fail(),o}}async function xs(e,t,n){let o=Ce(n.opts),s=n.progress("Starting create session\u2026");try{let r=await St(t),c=(await vo.post(Qt(),{projectId:t,...n.opts.name?{name:n.opts.name}:{},...o?{dimensions:o}:{},...r.length>0?{selectedImages:r}:{}},{headers:u()})).data.data,a=c.editableFiles??[];Co.ensureDirSync(e);for(let l of a)we(e,l);let m=await bt(e,c.selectedImages),p={mode:"create",componentId:c.componentId,projectId:t,selectedRevisionId:c.revisionId,jobId:c.jobId,generatedName:c.generatedName,name:n.opts.name,dimensions:o,selectedImages:m,editableFiles:a.map(l=>({path:l.path,sha256:Y(l.content)}))};return ve(e,p),s.succeed(),{data:{dir:e,manifestPath:Ie(e),...p,status:"pending",scaffoldedPaths:a.map(l=>l.path),selectedImages:m}}}catch(r){throw s.fail(),r}}var So={name:"start",summary:"Start a pending create or edit session before writing code",flags:[{flags:"--project <projectId>",description:"Target MagicPath project ID for create"},{flags:"--component <componentId>",description:"Existing MagicPath component ID for edit"},{flags:"--revision <revisionId>",description:"Start editing this revision. Defaults to the component's currently selected revision."},{flags:"--dir <dir>",description:"Working directory to initialize",default:"."},{flags:"--name <name>",description:"Component name"},{flags:"--width <px>",description:"Canvas component width for create"},{flags:"--height <px>",description:"Canvas component height for create"}],run:async e=>{let t=As.resolve(e.opts.dir);if(!!e.opts.project==!!e.opts.component)throw new d("Run code start with exactly one of --project for create or --component for edit.",{code:"INVALID_ARGUMENTS"});if(e.opts.component){if(Ce(e.opts))throw new d("Use --width and --height with code submit when resizing an existing component.",{code:"INVALID_ARGUMENTS"});return Rs(t,e)}return xs(t,e.opts.project,e)}};import Es from"axios";import Ts from"fs-extra";import Ns from"path";var Pt={name:"read",summary:"Fetch read-only editable files for an existing MagicPath component",description:"Fetches the editable source files of a component into a working directory without starting an edit session. Run `code start --component <componentId>` before submitting edits.",args:[{name:"componentId",description:"MagicPath component ID"}],flags:[{flags:"--dir <dir>",description:"Working directory to write",default:"."},{flags:"--revision <revisionId>",description:"Pull this revision of the component. Defaults to the component's currently selected revision."}],run:async e=>{let t=e.args[0],n=Ns.resolve(e.opts.dir),o=e.progress("Fetching component source\u2026");try{Ts.ensureDirSync(n);let s=e.opts.revision?`${at(t)}?revisionId=${encodeURIComponent(e.opts.revision)}`:at(t),i=(await Es.get(s,{headers:u()})).data.data;for(let c of i.editableFiles)we(n,c);return o.succeed(),{data:{dir:n,readOnly:!0,component:i.component,editableFiles:i.editableFiles.map(c=>({path:c.path,sha256:Y(c.content)}))}}}catch(s){throw o.fail(),s}}};import jt from"axios";import ks from"path";var Us=3,$s=2e3;function bo(e){return new Promise(t=>setTimeout(t,e))}async function Po(e){return(await jt.get($e(e),{headers:u()})).data.data}async function Os(e,t){for(;;){let n=await Po(e);if(n.status==="completed"||n.status==="failed"||n.status==="cancelled")return n;await bo(t)}}async function Ds(e,t){let n=t;for(let o=0;o<Us;o++){if(n.previewImageUrl)return n;await bo($s),n=await Po(e)}return n}function Ms(e){return e.generatedName?T("v1",e.generatedName):J(e.projectId)}var jo={name:"submit",summary:"Submit changed editable files for the component in this working directory",flags:[{flags:"--dir <dir>",description:"Working directory containing magicpath-code.json",default:"."},{flags:"--no-wait",description:"Return immediately instead of waiting for the build job to finish"},{flags:"--interval <ms>",description:"Polling interval while waiting",default:"2000"},{flags:"--width <px>",description:"Updated canvas component width"},{flags:"--height <px>",description:"Updated canvas component height"}],run:async e=>{let t=ks.resolve(e.opts.dir),n=Io(t),o=Ce(e.opts);po(t);let s=lo(t,n),r=go(t,n);if(n.mode==="create"&&!s.some(p=>p.path==="src/App.tsx"))throw new d("Create submit requires src/App.tsx in the working directory.",{code:"MISSING_APP_TSX"});if(s.length===0&&r.length===0&&!o)return{data:{status:"unchanged",componentId:n.componentId,revisionId:n.selectedRevisionId}};let i=n.mode==="create"||!!n.baseRevisionId&&n.selectedRevisionId!==n.baseRevisionId,c=e.progress("Submitting files\u2026"),a;try{a=(i?await jt.post(nn(n.componentId,n.selectedRevisionId),{files:s.map(l=>({path:l.path,content:l.content,encoding:l.encoding,mimeType:l.mimeType})),contextJobId:n.jobId,...o?{dimensions:o}:{},...n.mode==="edit"?{deletedPaths:r}:{}},{headers:u()}):await jt.post(tn(n.componentId),{baseRevisionId:n.baseRevisionId??n.selectedRevisionId,files:s.map(l=>({path:l.path,content:l.content,encoding:l.encoding,mimeType:l.mimeType,baseSha256:l.baseSha256})),deletedPaths:r,...o?{dimensions:o}:{}},{headers:u()})).data.data,c.succeed()}catch(p){throw c.fail(),p}let m=a;if(e.opts.wait!==!1){let p=e.progress("Waiting for build job\u2026");try{m=await Os(a.jobId,Number(e.opts.interval)),m.status==="completed"&&!m.previewImageUrl&&(m=await Ds(a.jobId,m)),p.succeed()}catch(l){throw p.fail(),l}}if(m.status==="completed"){let p=ye(t),l={...n,mode:"edit",jobId:a.jobId,selectedRevisionId:m.revisionId,baseRevisionId:m.revisionId,...o?{dimensions:o}:{},editableFiles:p.map(y=>({path:y.path,sha256:y.sha256??Y(y.content)}))};ve(t,l)}return{data:{job:{...m,jobId:a.jobId,deletedPaths:r,...o?{dimensions:o}:{}},revision:{id:m.revisionId,previewImageUrl:m.previewImageUrl??null},component:{id:n.componentId,url:Ms(n)}}}}};import Fs from"axios";var Ao={name:"status",summary:"Fetch external-agent build job status",args:[{name:"jobId",description:"External agent job ID"}],run:async e=>({data:(await Fs.get($e(e.args[0]),{headers:u()})).data.data})};function Ro(e){let t=E(e,"code","Create and edit canvas components from local code");t.addHelpText("after",`
|
|
27
|
+
Tailwind v4:
|
|
28
|
+
src/index.css must keep @import 'tailwindcss';.
|
|
29
|
+
Do not use @tailwind base/components/utilities; and do not replace the
|
|
30
|
+
template @theme inline, :root, or .dark token blocks. Append custom CSS below
|
|
31
|
+
the existing setup.
|
|
32
|
+
`),g(t,So),g(t,Pt),g(t,jo),g(t,Ao),g(t,{...Pt,name:"context",hidden:!0}),Yt(t,"create","Use code start followed by code submit.")}import Rt from"prompts";import je from"path";import Js from"fs-extra";import{pino as xo}from"pino";var re=xo();function se(){re=xo({level:"debug"}),re.debug({message:"DEBUG logger enabled. "})}var S={info:e=>{re.info(e)},debug:e=>{re.debug(e)},warn:e=>{re.warn(e)},error:e=>{re.error(e)}};var H=class extends d{constructor(){super("You must be logged in to install components.")}};import Eo from"axios";import W from"fs-extra";import Z from"path";import{z as U}from"zod";var _s=U.object({name:U.string(),path:U.string(),content:U.string()}),Ls=U.object({data:U.object({name:U.string(),generatedName:U.string(),files:U.array(_s),utils:U.object({content:U.string()}),dependencies:U.array(U.string())})});function ie(e){let t=e.match(/export\s+default\s+function\s+([A-Z][a-zA-Z0-9]*)/),n=e.match(/export\s+default\s+([A-Z][a-zA-Z0-9]*)\s*[;\n]/),o=e.match(/export\s+function\s+([A-Z][a-zA-Z0-9]*)/),s=e.match(/export\s+const\s+([A-Z][a-zA-Z0-9]*)\s*[=:]/),r=null,i=!1;if(t?(r=t[1],i=!0):n?(r=n[1],i=!0):o?r=o[1]:s&&(r=s[1]),!r)return null;let c=`${r}Props`,a=new RegExp(`(?:interface|type)\\s+${c}\\s*(?:=\\s*)?\\{([^}]*)\\}`,"s"),m=e.match(a),p=[],l=[];if(m){let h=m[1].split(/[;\n]/).filter(f=>f.trim());for(let f of h){let v=f.trim();if(!v||v.startsWith("//")||v.startsWith("/*"))continue;let A=v.match(/^(\w+)(\?)?:/);if(A){let x=A[1],R=!!A[2];if(x==="children")continue;R?l.push(x):p.push(x)}}}return{name:r,isDefault:i,propsType:m?c:void 0,requiredProps:p,optionalProps:l}}function Se(e,t){return e.isDefault?`import ${e.name} from '${t}';`:`import { ${e.name} } from '${t}';`}function be(e){let{name:t,requiredProps:n,optionalProps:o}=e;if(n.length===0&&o.length===0)return`<${t} />`;let s=n.map(r=>`${r}={/* TODO */}`).join(" ");return s?`<${t} ${s} />`:`<${t} />`}function Vs(e){let{componentName:t,importPath:n,exportInfo:o,fileName:s}=e,r=[`# ${t}`,"","## Import","","```tsx"];if(o){if(r.push(Se(o,n)),r.push("```"),r.push(""),r.push("## Usage"),r.push(""),r.push("```tsx"),r.push(be(o)),r.push("```"),o.requiredProps.length>0){r.push(""),r.push("## Required Props"),r.push("");for(let i of o.requiredProps)r.push(`- \`${i}\``)}if(o.optionalProps.length>0){r.push(""),r.push("## Optional Props"),r.push("");for(let i of o.optionalProps)r.push(`- \`${i}\``)}}else r.push(`import { ${s} } from '${n}';`),r.push("```");return r.push(""),r.join(`
|
|
33
|
+
`)}function To(e,t){let n=Vs(t),o=Z.join(e,"usage.md");W.writeFileSync(o,n,"utf8"),S.debug({message:"Wrote usage file",usagePath:o})}async function Pe(e){var o,s,r;let t=Zt(e);S.debug({message:"Fetching component from registry",url:t});let n;try{n=u()}catch{throw new H}try{let i=await Eo.get(t,{headers:n});return Ls.parse(i.data).data}catch(i){throw i instanceof d?i:Eo.isAxiosError(i)?((o=i.response)==null?void 0:o.status)===401?new H:((s=i.response)==null?void 0:s.status)===403?new d("A Pro subscription is required to install components. Visit https://www.magicpath.ai/documentation/help/plans to see the plans available.",{code:"FORBIDDEN",suggestion:"Upgrade to a Pro subscription at https://www.magicpath.ai/documentation/help/plans"}):((r=i.response)==null?void 0:r.status)===404?new d(`Component "${e}" not found. Please check the name and try again.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai search <query>` to find available components."}):D(i):new d("Failed to fetch component. Please check your internet connection and try again.")}}function No(e,t){let n=[];for(let o of e){let s=Z.join(t,o.path);W.existsSync(s)&&n.push(o.path)}return n}function Gs(e,t=1){let n="../".repeat(t),o=e;return o=o.replace(/((?:import|export)(?:\s+type)?\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)(?:\s*,\s*(?:\{[^}]*\}|\*\s+as\s+\w+|\w+))*\s+from\s+)?['"])(\.\.\/)([^'"]+['"])/g,(s,r,i,c)=>`${r}${n}${i}${c}`),o=o.replace(/(import\s*\(\s*['"])(\.\.\/)([^'"]+['"]\s*\))/g,(s,r,i,c)=>`${r}${n}${i}${c}`),o=o.replace(/(require\s*\(\s*['"])(\.\.\/)([^'"]+['"]\s*\))/g,(s,r,i,c)=>`${r}${n}${i}${c}`),o}function ko(e,t,n=!1){W.ensureDirSync(t);for(let o of e){let s=Z.join(t,o.path),r=Z.dirname(s);W.ensureDirSync(r);let i=n?Gs(o.content):o.content;W.writeFileSync(s,i,"utf8"),S.debug({message:"Wrote file",filePath:s})}}function Uo(e){let t=Z.join(e,"utils.ts");if(!W.existsSync(t))return!1;try{return W.readFileSync(t,"utf8").includes("export function cn")}catch{return!1}}function $o(e,t){W.ensureDirSync(t);let n=Z.join(t,"utils.ts");W.writeFileSync(n,e,"utf8"),S.debug({message:"Wrote utils file",utilsPath:n})}var ae="src/components/magicpath",Hs="src/lib";function Qe(e){return e.trim().replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase().replace(/[\s_]+/g,"-").replace(/[^a-z0-9-]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"component"}function et(e,t=process.cwd()){let n=e||ae;return Z.join(t,n)}function Oo(e=process.cwd()){return Z.join(e,Hs)}import{execSync as At}from"child_process";import Mo from"ora";import Do from"fs-extra";import Ws from"path";function Fo(){try{return At("yarn --version",{stdio:"ignore"}),"yarn"}catch{return"npm"}}function _o(e){let t=Fo(),n=Mo(`\u{1F4E6} Installing dependencies using ${t}...`).start();try{At(t==="yarn"?"yarn install":"npm install",{cwd:e,stdio:"ignore"}),n.succeed("Dependencies installed successfully!")}catch{throw n.fail("Failed to install dependencies"),new d("Failed to install dependencies. Please check your internet connection and try again.")}}function zs(e){let t=Ws.join(e,"package.json");if(!Do.existsSync(t))return new Set;try{let n=Do.readJsonSync(t),o=new Set;return n.dependencies&&Object.keys(n.dependencies).forEach(s=>o.add(s)),n.devDependencies&&Object.keys(n.devDependencies).forEach(s=>o.add(s)),o}catch{return new Set}}function Lo(e,t){if(e.length===0)return{installed:[],skipped:[]};let n=zs(t),o=e.filter(c=>!n.has(c)),s=e.filter(c=>n.has(c));if(o.length===0)return S.debug("All dependencies already installed"),{installed:[],skipped:s};let r=Fo(),i=Mo(`\u{1F4E6} Installing ${o.length} package${o.length>1?"s":""} using ${r}...`).start();try{let c=o.join(" "),a=r==="yarn"?`yarn add ${c}`:`npm install ${c}`;return S.debug({command:a}),At(a,{cwd:t,stdio:"ignore"}),i.succeed(`Installed ${o.length} package${o.length>1?"s":""}`),{installed:o,skipped:s}}catch{throw i.fail("Failed to install packages"),new d(`Failed to install packages: ${o.join(", ")}. Please install them manually.`)}}var Bs=new d("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."});async function qs(e,t){let{ctx:n,isBatch:o}=t,s=n.progress(`Fetching component "${e}"\u2026`);try{let r=await Pe(e);return s.succeed(`Found component: ${r.name}`),r}catch(r){if(s.fail(),!(r instanceof H))throw r instanceof d?r:new d("Something went wrong!");if(!n.mode.interactive||o)throw Bs;let{shouldLogin:i}=await Rt({type:"confirm",name:"shouldLogin",message:"You need to be logged in to install components. Log in now?",initial:!0});if(!i)return"cancelled";try{await ft(n)}catch{return"cancelled"}let c=n.progress(`Fetching component "${e}"\u2026`);try{let a=await Pe(e);return c.succeed(`Found component: ${a.name}`),a}catch(a){throw c.fail(),a instanceof d?a:new d("Something went wrong!")}}}async function Xs(e,t){let{ctx:n,cwd:o,force:s,dryRun:r,autoYes:i,isBatch:c,pathOverride:a,warnings:m}=t,p=await qs(e,t);if(p==="cancelled")return"cancelled";let l=p,y=et(a,o),h=Qe(l.name),f=je.join(y,h),v=Oo(o);S.debug({basePath:y,componentFolderName:h,componentsPath:f,utilsPath:v});let A=No(l.files,f);if(A.length>0&&!s){if(i)throw new d(`Files already exist: ${A.join(", ")}. Use --force to replace.`,{code:"FILES_EXIST",suggestion:"Pass `--force` to replace existing files."});{let{shouldOverwrite:P}=await Rt({type:"confirm",name:"shouldOverwrite",message:"Do you want to overwrite these files?",initial:!1});if(!P)return"cancelled"}}if(!i&&A.length===0){let{shouldProceed:P}=await Rt({type:"confirm",name:"shouldProceed",message:"Proceed with installation?",initial:!0});if(!P)return"cancelled"}let x=l.files.map(P=>je.relative(o,je.join(f,P.path))),R=l.files[0],L,b,C=null,N,z;if(R&&(N=R.name.replace(/\.tsx?$/,""),z=a?`@/${a}/${h}/${N}`:`@/components/magicpath/${h}/${N}`,C=ie(R.content),C?(L=Se(C,z),b=be(C)):L=`import { ${N} } from '${z}';`),r)return{component:l.name,generatedName:l.generatedName,filesWritten:x,...c?{}:{files:l.files.map(P=>({path:P.path,name:P.name,content:P.content}))},dependenciesInstalled:l.dependencies,importStatement:L,usage:b,dryRun:!0};let V=n.progress("Writing component files\u2026");try{ko(l.files,f,!0),V.succeed(`Wrote ${l.files.length} file(s) to ${je.relative(o,f)||"."}`)}catch{throw V.fail(),new d("Failed to write component files. Please check permissions and try again.")}if(!Uo(v)&&l.utils.content)try{$o(l.utils.content,v)}catch(P){S.debug({err:P}),m.push("Could not write utils.ts. You may need to create it manually.")}let kt=[];if(l.dependencies.length>0)try{let{installed:P,skipped:Ut}=Lo(l.dependencies,o);kt.push(...P),Ut.length>0&&S.debug({message:"Skipped already installed packages",skipped:Ut})}catch(P){P instanceof d&&m.push(P.message)}if(R&&N&&z)try{To(f,{componentName:l.name,importPath:z,exportInfo:C,fileName:N})}catch(P){S.debug({err:P})}return{component:l.name,generatedName:l.generatedName,filesWritten:x,dependenciesInstalled:kt,importStatement:L,usage:b,dryRun:!1}}var Vo={name:"install",summary:"Install MagicPath components into your project",description:`Fetches one or more components from the MagicPath registry, writes their files to ${ae}, and installs missing dependencies.`,args:[{name:"generatedNames",description:"One or more generated names of components (e.g., wispy-river-5234 bold-moon-2031)",variadic:!0}],flags:[{flags:"--dir <dir>",description:`Custom path for components (default: ${ae})`},{flags:"--force",description:"Overwrite existing files"},{flags:"--dry-run",description:"Show what would happen without writing files"},{flags:"--overwrite",description:"Overwrite existing files",hidden:!0},{flags:"-p, --path <path>",description:"Custom path for components",hidden:!0},{flags:"-y, --yes",description:"Skip confirmation prompts",hidden:!0},{flags:"-d, --debug",description:"Enable debug logging",hidden:!0}],run:async e=>{let t=e.args[0];e.opts.debug&&se();let n=process.cwd();if(!Js.existsSync(je.join(n,"package.json")))throw new d("No package.json found. Please run this command from the root of your React project.",{code:"MISSING_PACKAGE_JSON",suggestion:"Run this command from the root of your project where package.json is located."});let o=t.length>1,s=[],r={ctx:e,cwd:n,force:!!(e.opts.force||e.opts.overwrite),dryRun:!!e.opts.dryRun,autoYes:!e.mode.interactive||!!e.opts.yes||o,isBatch:o,pathOverride:e.opts.dir??e.opts.path,warnings:s};S.debug({generatedNames:t,options:e.opts});let i=[];for(let c of t)try{let a=await Xs(c,r);if(a==="cancelled")return{data:{cancelled:!0}};i.push(a)}catch(a){if(!o)throw a;i.push({component:c,generatedName:c,filesWritten:[],dependenciesInstalled:[],dryRun:r.dryRun,error:a instanceof Error?a.message:String(a)})}return o?{data:{results:i,total:i.length,succeeded:i.filter(c=>!c.error).length,failed:i.filter(c=>c.error).length},warnings:s}:{data:i[0],warnings:s}}};function Go(e){g(e,Vo),I(e,"add",Vo)}var Ys={name:"inspect",summary:"Inspect a MagicPath component's source code without installing",args:[{name:"generatedName",description:"Generated name of the component (e.g., wispy-river-5234)"}],flags:[{flags:"-d, --debug",description:"Enable debug logging",hidden:!0}],run:async e=>{let t=e.args[0];e.opts.debug&&se(),S.debug({generatedName:t,options:e.opts});let n=e.progress(`Fetching component "${t}"\u2026`),o;try{o=await Pe(t),n.succeed(`Found component: ${o.name}`)}catch(a){throw n.fail(),a instanceof H?new d("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."}):a instanceof d?a:new d("Something went wrong!")}let s=Qe(o.name),r=o.files[0],i,c;if(r){let a=r.name.replace(/\.tsx?$/,""),m=`@/components/magicpath/${s}/${a}`,p=ie(r.content);p?(i=Se(p,m),c=be(p)):i=`import { ${a} } from '${m}';`}return{data:{component:o.name,generatedName:o.generatedName,files:o.files.map(a=>({path:a.path,name:a.name,content:a.content})),dependencies:o.dependencies,importStatement:i,usage:c}}}};function Ho(e){g(e,Ys)}import Ae from"path";import ce from"fs-extra";function Zs(e,t){if(!ce.existsSync(e))return[];let n=ce.readdirSync(e,{withFileTypes:!0}),o=[];for(let s of n){if(!s.isDirectory())continue;let r=Ae.join(e,s.name),i=ce.readdirSync(r).filter(p=>!ce.statSync(Ae.join(r,p)).isDirectory()),c=i.find(p=>(p.endsWith(".tsx")||p.endsWith(".ts"))&&p!=="usage.md"&&!p.includes(".test.")&&!p.includes(".spec.")),a=null,m=null;if(c)try{let p=ce.readFileSync(Ae.join(r,c),"utf8"),l=ie(p);if(l){a=l.name;let y=c.replace(/\.tsx?$/,""),h=`@/components/magicpath/${s.name}/${y}`;m=l.isDefault?`import ${l.name} from '${h}';`:`import { ${l.name} } from '${h}';`}}catch{}o.push({name:a||s.name,folder:s.name,path:Ae.relative(t,r),files:i.filter(p=>p!=="usage.md"),exportName:a,importStatement:m})}return o}var Wo={name:"installed",summary:"List MagicPath components installed in the current project",flags:[{flags:"--dir <dir>",description:`Custom components path (default: ${ae})`},{flags:"-p, --path <path>",description:"Custom components path",hidden:!0}],run:async e=>{let t=process.cwd(),n=et(e.opts.dir??e.opts.path,t);if(!ce.existsSync(n))return{data:{components:[],total:0}};let o=Zs(n,t);return{data:{components:o,total:o.length,componentsPath:Ae.relative(t,n)}}}};function zo(e){g(e,Wo),I(e,"list-installed",Wo)}import{exec as Ks}from"child_process";function Jo(e){return/^\d+$/.test(e)?{type:"project",url:J(e),projectId:e}:{type:"component",url:T("v1",e),generatedName:e}}var tt={name:"open",summary:"Open a project or component in the browser (or return its URL)",description:"Resolves a project id or component generatedName to its MagicPath URL. Opens the OS browser only for an interactive human or with --browser; agents receive the URL in the result instead.",args:[{name:"target",description:"A project id or a component generatedName (e.g. wispy-river-5234)"}],flags:[{flags:"--browser",description:"Force-open the OS browser"}],run:async e=>{let t=Jo(e.args[0]),n=e.mode.interactive||e.opts.browser===!0;if(n){let o=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";Ks(`${o} ${t.url}`)}return{data:{...t,opened:n}}}};function Bo(e){g(e,tt),I(e,"view",tt),I(e,"view-component",tt),I(e,"share",tt)}import{Command as ii}from"commander";import ot from"prompts";import nr from"ora";import{z as me}from"zod";import de from"path";import ai from"os";import Nt from"fs-extra";var Qs=!1;function xt(){return Qs}function qo(e){console.log(JSON.stringify(e,null,2)),process.exit(0)}function Et(e){let n={error:e instanceof Error?e.message:String(e)};e instanceof d&&(e.code&&(n.code=e.code),e.suggestion&&(n.suggestion=e.suggestion)),console.error(JSON.stringify(n,null,2)),process.exit(1)}import Xo from"axios";import nt from"path";import ei from"os";import{Readable as ti}from"stream";import Re from"fs-extra";import ni from"adm-zip";import{v4 as oi}from"uuid";async function ri(e){if(!(e instanceof ti))return;let t=[];return new Promise((n,o)=>{e.on("data",s=>{t.push(Buffer.isBuffer(s)?s:Buffer.from(s))}),e.on("error",o),e.on("end",()=>n(Buffer.concat(t).toString("utf8")))})}async function si(e){var t;if(e instanceof d)return e;if(Xo.isAxiosError(e)){let n=await ri((t=e.response)==null?void 0:t.data);if(n)try{let o=JSON.parse(n);return D({...e,response:{...e.response,data:o},isAxiosError:!0})}catch{}return D(e)}return new d("Failed to download project. Make sure your key is valid.")}async function Yo(e){let t=T("v1","components/repository"),n=`${oi()}.zip`,o=nt.join(ei.tmpdir(),n);try{let s=await Xo({url:t,params:{key:e},method:"GET",responseType:"stream"});return await Re.ensureDir(nt.dirname(o)),await new Promise(async(r,i)=>{try{s.data.pipe(Re.createWriteStream(o)).on("error",i).once("close",()=>r(o))}catch(c){i(c)}}),o}catch(s){throw await si(s)}}function Tt(e){try{Re.removeSync(e)}catch{}}function Zo(e,t,n){try{let o=nt.join(n,t),s=1;for(;Re.existsSync(o);)s++,o=nt.join(n,`${t}-${s}`);return Re.mkdirSync(o,{recursive:!0}),new ni(e).extractAllTo(o,!0),Tt(e),o}catch{throw new d("Failed to extract project. Please try again.")}}import{execSync as Ko}from"child_process";import Qo from"ora";function er(e,t){let n={cursor:"Cursor",antigravity:"Antigravity",vscode:"VS Code",webstorm:"WebStorm"},o={cursor:["cursor","code"],antigravity:["agy","antigravity"],vscode:["code"],webstorm:["webstorm","web"]},s=Qo(`\u{1F680} Opening project in ${n[t]}...`).start(),r=!1;try{for(let i of o[t]){if(r)break;try{Ko(`${i} .`,{cwd:e,stdio:"ignore"}),r=!0}catch{r=!1}}if(!r)throw new Error("Failed to open with command.");s.succeed(`Project opened in ${n[t]}!`)}catch{s.fail(`Failed to open ${n[t]}`);let i={cursor:`\u274C Cursor command not found!
|
|
3
34
|
|
|
4
35
|
\u{1F527} To fix this, you need to install the Cursor command line tools:
|
|
5
36
|
|
|
@@ -62,87 +93,10 @@ import{readFileSync as pr}from"fs";import{dirname as gr,join as ur}from"path";im
|
|
|
62
93
|
export PATH="/Applications/WebStorm.app/Contents/MacOS:$PATH"
|
|
63
94
|
- Or create an alias: alias webstorm="open -na 'WebStorm.app'"
|
|
64
95
|
|
|
65
|
-
\u{1F4D6} More help: https://www.jetbrains.com/help/webstorm/working-with-the-ide-features-from-command-line.html`};throw new
|
|
66
|
-
${
|
|
67
|
-
\u{1F389} Done! Your project is ready to go at: ${
|
|
68
|
-
`)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.
|
|
72
|
-
.gradient{position:absolute;top:0;left:0;right:0;height:12rem;background:radial-gradient(circle at center top,#DCF1E3 0%,#fff 80%);opacity:.2;pointer-events:none}
|
|
73
|
-
.content{position:relative;z-index:1;padding:2rem;display:flex;flex-direction:column;align-items:center}
|
|
74
|
-
.icon-box{width:4rem;height:4rem;border-radius:1rem;background:rgba(220,241,227,.1);display:flex;align-items:center;justify-content:center;margin-bottom:1rem}
|
|
75
|
-
.icon-box svg{width:2rem;height:2rem}
|
|
76
|
-
h1{font-size:1.5rem;font-weight:600;margin-bottom:.5rem;text-align:center}
|
|
77
|
-
p{color:#999;font-size:.9rem;text-align:center;max-width:24rem;line-height:1.5}
|
|
78
|
-
`,Hn='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="#085C34"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>',Gn='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="#dc2626"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"/></svg>',Vn=`<!DOCTYPE html>
|
|
79
|
-
<html><head><meta charset="utf-8"><title>MagicPath CLI</title>
|
|
80
|
-
<style>${bo}</style>
|
|
81
|
-
</head><body><div class="card"><div class="gradient"></div><div class="content">
|
|
82
|
-
<div class="icon-box">${Hn}</div>
|
|
83
|
-
<h1>Logged in!</h1>
|
|
84
|
-
<p>You can close this tab and return to your terminal.</p>
|
|
85
|
-
</div></div></body></html>`,Io=e=>`<!DOCTYPE html>
|
|
86
|
-
<html><head><meta charset="utf-8"><title>MagicPath CLI</title>
|
|
87
|
-
<style>${bo}</style>
|
|
88
|
-
</head><body><div class="card"><div class="gradient"></div><div class="content">
|
|
89
|
-
<div class="icon-box">${Gn}</div>
|
|
90
|
-
<h1>Login failed</h1>
|
|
91
|
-
<p>${e}</p>
|
|
92
|
-
</div></div></body></html>`;async function at(){return new Promise((e,n)=>{let t=!1,o,r=Dn.createServer(async(c,a)=>{var m;let l=new URL(c.url||"/","http://localhost");if(l.pathname!=="/callback"){a.writeHead(404,{"Content-Type":"text/plain"}),a.end("Not found");return}let g=l.searchParams.get("code");if(!g){a.writeHead(400,{"Content-Type":"text/html"}),a.end(Io("No authorization code received."));return}try{let f=await it.post(ze("extension/tokens"),{token:g}),{access_token:d,refresh_token:b}=f.data;Qe(d,b);try{await et()}catch{}a.writeHead(200,{"Content-Type":"text/html"}),a.end(Vn),s(),i.succeed("Logged in successfully!"),t=!0,e(!0)}catch(f){console.error(f);let d=it.isAxiosError(f)&&((m=f.response)==null?void 0:m.status)===400?"Invalid or expired authorization code. Please try again.":"Failed to exchange code. Please try again.";a.writeHead(400,{"Content-Type":"text/html"}),a.end(Io(d)),s(),i.fail("Login failed"),t=!0,n(new p(d))}});function s(){clearTimeout(o),r.close()}r.listen(0,"127.0.0.1",()=>{let c=r.address();if(!c||typeof c=="string"){t=!0,n(new p("Failed to start local auth server."));return}let a=c.port,l=Ve(`/auth/cli?port=${a}`);console.log(`
|
|
93
|
-
Opening your browser to log in...
|
|
94
|
-
`),console.log(`If the browser doesn't open, visit: ${l}
|
|
95
|
-
`);let g=process.platform;Ln(`${g==="darwin"?"open":g==="win32"?"start":"xdg-open"} "${l}"`)});let i=_n("Waiting for browser login...").start();o=setTimeout(()=>{t||(s(),i.fail("Login timed out"),console.log("\nTip: You can also log in with `magicpath-ai login --code <code>`."),t=!0,e(!1))},Wn)})}function vo(e){e.command("login").description("Log in to your MagicPath account").option("--code <code>","Exchange an authorization code non-interactively").action(async n=>{try{if(n.code){let o=await it.post(ze("extension/tokens"),{token:n.code}),{access_token:r,refresh_token:s}=o.data;Qe(r,s);try{await et()}catch{}x()&&v({authenticated:!0,method:"code"}),console.log("Logged in successfully!");return}x()&&(process.env.MAGICPATH_TOKEN&&v({authenticated:!0,method:"environment"}),Q()&&v({authenticated:!0,method:"stored"}),A(new Error("Not authenticated. Set MAGICPATH_TOKEN environment variable or run login interactively."))),await at()||console.log("Login cancelled.")}catch(t){throw x()&&A(t),t instanceof p&&(console.error(`
|
|
96
|
-
${t.message}`),process.exit(1)),t}}),e.command("logout").description("Log out of your MagicPath account").action(()=>{Jt(),x()&&v({loggedOut:!0}),console.log("Logged out successfully.")})}var Jn=F.object({yes:F.boolean().default(!1),overwrite:F.boolean().default(!1),path:F.string().optional(),debug:F.boolean().default(!1),dryRun:F.boolean().default(!1)}),ti=F.object({component:F.string(),generatedName:F.string(),filesWritten:F.array(F.string()),dependenciesInstalled:F.array(F.string()),importStatement:F.string().optional(),usage:F.string().optional(),dryRun:F.boolean()});function xo(e){e.command("add").description("Add a MagicPath component to your project").argument("<generatedNames...>","One or more generated names of components (e.g., wispy-river-5234 bold-moon-2031)").option("-y, --yes","Skip confirmation prompts",!1).option("--overwrite","Overwrite existing files",!1).option("-p, --path <path>",`Custom path for components (default: ${ye})`).option("-d, --debug","Enable debug logging",!1).option("--dry-run","Show what would happen without writing files",!1).action(async(n,t)=>{try{let o;try{o=Jn.parse(t)}catch{throw new Error("Invalid CLI options for add command.")}o.debug&&se();let r=x();r&&(o.yes=!0);let s=n.length>1;s&&(o.yes=!0),k.debug({generatedNames:n,options:o});let i=process.cwd(),c=X.join(i,"package.json");if(!zn.existsSync(c))throw new p("No package.json found. Please run this command from the root of your React project.",{code:"MISSING_PACKAGE_JSON",suggestion:"Run this command from the root of your project where package.json is located."});let a=[];s&&!r&&console.log(`
|
|
97
|
-
Adding ${n.length} components...
|
|
98
|
-
`);for(let l of n)try{let g=r?null:T(`Fetching component "${l}"...`).start(),m;try{m=await we(l),g==null||g.succeed(`Found component: ${m.name}`)}catch(C){if(C instanceof B){if(g==null||g.fail("Not logged in"),r||s)throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."});let{shouldLogin:j}=await ct({type:"confirm",name:"shouldLogin",message:"You need to be logged in to install components. Log in now?",initial:!0});if(!j){console.log("Installation cancelled.");return}if(!await at()){console.log("Installation cancelled.");return}let L=T(`Fetching component "${l}"...`).start();try{m=await we(l),L.succeed(`Found component: ${m.name}`)}catch(It){throw L.fail("Failed to fetch component"),It instanceof p?It:new p("Something went wrong!")}}else{if(g==null||g.fail("Failed to fetch component"),s){let j=C instanceof p?C.message:"Something went wrong!";a.push({component:l,generatedName:l,filesWritten:[],dependenciesInstalled:[],dryRun:o.dryRun,error:j}),r||console.log(` \u26A0\uFE0F Skipping "${l}": ${j}`);continue}throw C instanceof p?C:new p("Something went wrong!")}}let f=ke(o.path,i),d=Re(m.name),b=X.join(f,d),I=yo(i);k.debug({basePath:f,componentFolderName:d,componentsPath:b,utilsPath:I});let $=uo(m.files,b);if($.length>0&&!o.overwrite)if(r||(console.log(`
|
|
99
|
-
The following files already exist:`),$.forEach(C=>console.log(` - ${C}`))),o.yes){if(s){r||console.log(` \u26A0\uFE0F Skipping "${m.name}": files already exist. Use --overwrite.`),a.push({component:m.name,generatedName:m.generatedName,filesWritten:[],dependenciesInstalled:[],dryRun:o.dryRun,error:"Files already exist. Use --overwrite to replace."});continue}if(r)throw new p(`Files already exist: ${$.join(", ")}. Use --overwrite to replace.`,{code:"FILES_EXIST",suggestion:"Pass `--overwrite` to replace existing files."});console.log("Use --overwrite to replace existing files.");return}else{let{shouldOverwrite:C}=await ct({type:"confirm",name:"shouldOverwrite",message:"Do you want to overwrite these files?",initial:!1});if(!C){console.log("Installation cancelled.");return}}if(!o.yes&&$.length===0){console.log(`
|
|
100
|
-
This will install:`),console.log(` Component: ${m.name}`),console.log(` Files: ${m.files.length} file(s) to ${X.relative(i,b)||"."}`),console.log(` Dependencies: ${m.dependencies.length} package(s)`);let{shouldProceed:C}=await ct({type:"confirm",name:"shouldProceed",message:"Proceed with installation?",initial:!0});if(!C){console.log("Installation cancelled.");return}}let w=m.files.map(C=>X.relative(i,X.join(b,C.path))),u=m.files[0],h,y;if(u){let C=u.name.replace(/\.tsx?$/,""),j=o.path?`@/${o.path}/${d}/${C}`:`@/components/magicpath/${d}/${C}`,R=ee(u.content);R?(h=ce(R,j),y=le(R)):h=`import { ${C} } from '${j}';`}if(o.dryRun){let C=r?m.files.map(j=>({path:j.path,name:j.name,content:j.content})):void 0;!s&&r&&v({component:m.name,generatedName:m.generatedName,filesWritten:w,files:C,dependenciesInstalled:m.dependencies,importStatement:h,usage:y,dryRun:!0}),a.push({component:m.name,generatedName:m.generatedName,filesWritten:w,dependenciesInstalled:m.dependencies,importStatement:h,usage:y,dryRun:!0}),r||(console.log(`
|
|
101
|
-
[Dry run] Would install:`),console.log(` Component: ${m.name}`),console.log(` Files: ${w.join(", ")}`),console.log(` Dependencies: ${m.dependencies.join(", ")||"none"}`),h&&console.log(` Import: ${h}`));continue}let P=r?null:T("Writing component files...").start();try{fo(m.files,b,!0),P==null||P.succeed(`Wrote ${m.files.length} file(s) to ${X.relative(i,b)||"."}`)}catch{if(P==null||P.fail("Failed to write component files"),s){a.push({component:m.name,generatedName:m.generatedName,filesWritten:[],dependenciesInstalled:[],dryRun:!1,error:"Failed to write component files."});continue}throw new p("Failed to write component files. Please check permissions and try again.")}if(!ho(I)&&m.utils.content){let C=r?null:T("Installing utilities...").start();try{wo(m.utils.content,I),C==null||C.succeed(`Wrote utils.ts to ${X.relative(i,I)||"."}`)}catch(j){C==null||C.fail("Failed to write utils file"),k.debug({err:j}),r||console.log(" Warning: Could not write utils.ts. You may need to create it manually.")}}let _=[];if(m.dependencies.length>0)try{let{installed:C,skipped:j}=ro(m.dependencies,i);_.push(...C),j.length>0&&k.debug({message:"Skipped already installed packages",skipped:j})}catch(C){C instanceof p&&(r||console.log(`
|
|
102
|
-
\u26A0\uFE0F ${C.message}`))}if(a.push({component:m.name,generatedName:m.generatedName,filesWritten:w,dependenciesInstalled:_,importStatement:h,usage:y,dryRun:!1}),!s&&r&&v({component:m.name,generatedName:m.generatedName,filesWritten:w,dependenciesInstalled:_,importStatement:h,usage:y,dryRun:!1}),r||(console.log(`
|
|
103
|
-
\u2705 Successfully added "${m.name}" to your project!`),s||console.log(`
|
|
104
|
-
Usage:`)),u){let C=u.name.replace(/\.tsx?$/,""),j=o.path?`@/${o.path}/${d}/${C}`:`@/components/magicpath/${d}/${C}`,R=ee(u.content);!s&&!r&&(R?(console.log(` ${ce(R,j)}`),console.log(""),console.log(` ${le(R)}`),R.requiredProps.length>0&&(console.log(""),console.log(` Required props: ${R.requiredProps.join(", ")}`))):console.log(` import { ${C} } from '${j}';`));try{go(b,{componentName:m.name,importPath:j,exportInfo:R,fileName:C}),!s&&!r&&console.log(`
|
|
105
|
-
\u{1F4C4} Usage documentation written to ${X.relative(i,X.join(b,"usage.md"))}`)}catch(L){k.debug({err:L})}}}catch(g){if(s){let m=g instanceof Error?g.message:String(g);a.push({component:l,generatedName:l,filesWritten:[],dependenciesInstalled:[],dryRun:o.dryRun,error:m}),r||console.log(` \u26A0\uFE0F Failed "${l}": ${m}`);continue}throw g}if(s){r&&v({results:a,total:a.length,succeeded:a.filter(m=>!m.error).length,failed:a.filter(m=>m.error).length});let l=a.filter(m=>!m.error),g=a.filter(m=>m.error);console.log(`
|
|
106
|
-
${l.length} of ${a.length} component(s) added successfully.`),g.length>0&&console.log(` ${g.length} failed: ${g.map(m=>m.generatedName).join(", ")}`)}}catch(o){throw x()&&A(o),o instanceof p&&(console.error(`
|
|
107
|
-
${o.message}`),process.exit(1)),o}})}import $o from"axios";function Co(e){e.command("whoami").description("Show the currently authenticated user").action(async()=>{var t;let n=x();try{let o;try{o=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let r=n?null:T("Fetching user info...").start();try{let s=await $o.get(Y(),{headers:o}),i=s.data.user??s.data;r==null||r.succeed("Authenticated");let c=ue(i);n&&v(i),console.log(`
|
|
108
|
-
Name: ${c.name||"N/A"}`),console.log(` Email: ${c.email||"N/A"}`),i.id&&console.log(` ID: ${i.id}`),console.log(` Plan: ${c.plan}`)}catch(s){throw r==null||r.fail("Failed to fetch user info"),$o.isAxiosError(s)?((t=s.response)==null?void 0:t.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login` to re-authenticate.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):H(s):s}}catch(o){throw n&&A(o),o instanceof p&&(console.error(`
|
|
109
|
-
${o.message}`),process.exit(1)),o}})}import lt from"axios";import Oe from"axios";function Me(e){var t;let n=((t=e.data.data)==null?void 0:t.projects)??e.data.projects??e.data;return Array.isArray(n)?n:[]}async function Z(e,n){if(n!=null&&n.personal){let c=await Oe.get(`${qe()}`,{headers:e});return Me(c).map(a=>{var l;return{...a,ownerType:"personal",ownerName:((l=a.owner)==null?void 0:l.email)??""}})}if(n!=null&&n.orgId){let c=await Oe.get(`${Ye(n.orgId)}`,{headers:{...e,"X-Organization-ID":n.orgId}});return Me(c).map(a=>({...a,ownerType:"team",ownerName:n.orgName??""}))}let t=await fe(e),o=[Oe.get(`${qe()}`,{headers:e}).then(c=>Me(c).map(a=>{var l;return{...a,ownerType:"personal",ownerName:((l=a.owner)==null?void 0:l.email)??""}})),...t.map(c=>Oe.get(`${Ye(c.id)}`,{headers:{...e,"X-Organization-ID":c.id}}).then(a=>Me(a).map(l=>({...l,ownerType:"team",ownerName:c.name}))).catch(()=>[]))],s=(await Promise.all(o)).flat(),i=new Set;return s.filter(c=>{let a=String(c.id);return i.has(a)?!1:(i.add(a),!0)})}function jo(e){e.command("list-projects").description("List all projects (personal and team)").option("--limit <n>","Maximum number of results").option("--offset <n>","Number of results to skip","0").option("--team <nameOrId>","Filter to a specific team").option("--personal","Show only personal projects").action(async n=>{var s,i,c;let t=x(),o=n.limit?parseInt(n.limit,10):void 0,r=parseInt(n.offset,10)||0;try{if(n.team&&n.personal)throw new p("Cannot use --team and --personal together.",{code:"INVALID_OPTIONS",suggestion:"Use --team to filter by team, or --personal for personal projects only."});let a;try{a=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let l=t?null:T("Fetching projects...").start();try{let g;if(n.personal)g={personal:!0};else if(n.team){let h=await G(n.team,a);g={orgId:h.id,orgName:h.name}}let m=await Z(a,g),f=m.length,d=m;if(r>0&&(d=d.slice(r)),o!==void 0&&(d=d.slice(0,o)),l==null||l.succeed(`Found ${f} project(s)`),t&&v({projects:d,pagination:{total:f,limit:o??f,offset:r,hasMore:r+d.length<f}}),d.length===0){console.log(`
|
|
110
|
-
No projects found.`);return}console.log("");let b=Math.max(4,...d.map(h=>(h.name||"").length)),I=Math.max(9,...d.map(h=>h.ownerType==="personal"?8:(h.ownerName||"").length)),$=7,w=10,u=10;console.log(` ${"Name".padEnd(b)} ${"Type".padEnd($)} ${"Components".padEnd(w)} ${"Workspace".padEnd(I)} Updated`),console.log(` ${"\u2500".repeat(b)} ${"\u2500".repeat($)} ${"\u2500".repeat(w)} ${"\u2500".repeat(I)} ${"\u2500".repeat(u)}`);for(let h of d){let y=(h.name||"").padEnd(b),P=(h.isLibrary?"library":"project").padEnd($),U=String(h.componentCount??((s=h._count)==null?void 0:s.components)??"?").padEnd(w),_=(h.ownerType==="personal"?"Personal":h.ownerName||"").padEnd(I),C=h.updatedAt?new Date(h.updatedAt).toISOString().slice(0,10):"";console.log(` ${y} ${P} ${U} ${_} ${C}`)}o!==void 0&&r+d.length<f&&console.log(`
|
|
111
|
-
Showing ${d.length} of ${f}. Use --offset ${r+d.length} to see more.`)}catch(g){throw l==null||l.fail("Failed to fetch projects"),g instanceof p?g:lt.isAxiosError(g)?((i=g.response)==null?void 0:i.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):new p(`API error: ${(c=g.response)==null?void 0:c.status}`):g}}catch(a){throw t&&A(a),a instanceof p&&(console.error(`
|
|
112
|
-
${a.message}`),process.exit(1)),a}}),e.command("list-components").description("List components in a project").argument("<projectId>","The project ID").option("--limit <n>","Maximum number of results","100").option("--after <id>","Cursor: fetch components after this ID (for pagination)").option("--sort-by <field>","Sort by field (name, createdAt)","name").option("--order <dir>","Sort direction (asc, desc)","asc").option("--created-by <userId>","Filter to components created or edited by this user ID").action(async(n,t)=>{var s,i,c,a,l;let o=x(),r=parseInt(t.limit,10)||100;try{let g;try{g=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let m=o?null:T("Fetching components...").start();try{let f=new URLSearchParams({limit:String(r),revisionStatus:"COMPLETED",sortBy:t.sortBy,order:t.order});t.after&&f.set("after",t.after),t.createdBy&&f.set("createdBy",t.createdBy);let d=`${Rt(n)}?${f}`,b=await lt.get(d,{headers:g}),I=((s=b.data.data)==null?void 0:s.components)??b.data.components??b.data,$=((i=b.data.data)==null?void 0:i.pagination)??b.data.pagination,w=Array.isArray(I)?I.length:0;if(m==null||m.succeed(`Found ${w} component(s)`),o&&v({components:I,pagination:$??{limit:r,hasNext:!1,lastId:null}}),!Array.isArray(I)||I.length===0){console.log(`
|
|
113
|
-
No components found.`);return}console.log("");let u=Math.max(4,...I.map(y=>(y.name||"").length)),h=Math.max(14,...I.map(y=>(y.generatedName||"").length));console.log(` ${"Name".padEnd(u)} ${"Generated Name".padEnd(h)} ${"Rev".padEnd(4)} ${"Views".padEnd(6)} ${"Likes".padEnd(6)} ${"Remixes".padEnd(7)} ${"Updated".padEnd(10)} ID`),console.log(` ${"\u2500".repeat(u)} ${"\u2500".repeat(h)} ${"\u2500".repeat(4)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(7)} ${"\u2500".repeat(10)} ${"\u2500".repeat(20)}`);for(let y of I){let P=(y.name||"").padEnd(u),U=(y.generatedName||"").padEnd(h),_=String(y.revisionCount??"?").padEnd(4),C=String(y.viewCount??0).padEnd(6),j=String(y.likeCount??0).padEnd(6),R=String(y.remixCount??0).padEnd(7),L=y.updatedAt?new Date(y.updatedAt).toISOString().slice(0,10):"";console.log(` ${P} ${U} ${_} ${C} ${j} ${R} ${L.padEnd(10)} ${y.id||""}`)}$!=null&&$.hasNext&&console.log(`
|
|
114
|
-
More results available. Use --after ${$.lastId} to see the next page.`)}catch(f){throw m==null||m.fail("Failed to fetch components"),lt.isAxiosError(f)?((c=f.response)==null?void 0:c.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):((a=f.response)==null?void 0:a.status)===404?new p(`Project "${n}" not found.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai list-projects` to see available projects."}):new p(`API error: ${(l=f.response)==null?void 0:l.status}`):f}}catch(g){throw o&&A(g),g instanceof p&&(console.error(`
|
|
115
|
-
${g.message}`),process.exit(1)),g}})}import{execSync as Bn}from"child_process";function Eo(e){e.command("setup-skills").description("Set up MagicPath for AI agents").action(async()=>{console.log("Installing MagicPath skills..."),Bn("npx skills add https://github.com/MagicPathAI/agent-skills --skill magicpath -y",{stdio:"inherit"})})}import{exec as Kn}from"child_process";function Ue(e){return/^\d+$/.test(e)?{type:"project",url:Et(e),projectId:e}:{type:"component",url:$e("v1",e),generatedName:e}}function Ao(e){e.command("view").alias("view-component").description("Open a component preview or a project in the browser").argument("<identifier>","A component generatedName (e.g., wispy-river-5234) or a project id").action(n=>{let t=Ue(n);x()&&v(t);let o=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";Kn(`${o} ${t.url}`),console.log(`Opening ${t.url}`)})}function Po(e){e.command("share").description("Get a shareable URL for a component or a project").argument("<identifier>","A component generatedName (e.g., wispy-river-5234) or a project id").action(n=>{let t=Ue(n);if(x()){v(t);return}console.log(t.url)})}import Xn from"axios";function To(e){e.command("info").description("Show project and auth status (useful for agent context injection)").action(async()=>{let n=x();try{let t=null,o=!1,r=null;process.env.MAGICPATH_TOKEN?(t="environment",o=!0,r=E()):Q()&&(t="stored",o=!0,r=E());let s=null,i=null;if(o&&r)try{let l=await Xn.get(Y(),{headers:r}),g=l.data.user??l.data,m=ue(g);s={id:g.id,name:m.name??"Unknown",email:m.email??""},i=(g.organizationUsers??[]).map(d=>({id:String(d.organization.id),name:d.organization.name,role:d.role}))}catch{}let c=null;if(o&&r)try{c=(await Z(r)).map(g=>{var m;return{id:g.id,name:g.name,componentCount:g.componentCount??((m=g._count)==null?void 0:m.components)??0,ownerType:g.ownerType,ownerName:g.ownerName}})}catch{}if(n&&v({auth:{authenticated:o,method:t,user:s},teams:i,projects:c,cli:{version:J,commands:["add","view","share","search","inspect","list-projects","list-components","list-teams","list-members","list-themes","get-theme","list-installed","selection","active-project","code","image","login","logout","whoami","info","clone","setup-skills"]}}),console.log(""),console.log(` MagicPath CLI v${J}`),console.log(""),o&&s?(console.log(` Authenticated: yes (${t})`),console.log(` User: ${s.name} <${s.email}>`)):o?(console.log(` Authenticated: yes (${t})`),console.log(" User: (could not fetch)")):(console.log(" Authenticated: no"),console.log(" Run `magicpath-ai login` to authenticate.")),i&&i.length>0){console.log(""),console.log(` Teams: ${i.length}`);for(let l of i)console.log(` - ${l.name} (${l.role.toLowerCase()})`)}if(console.log(""),c&&c.length>0){console.log(` Projects: ${c.length}`);for(let l of c){let g=l.ownerType==="personal"?"":` [${l.ownerName}]`;console.log(` - ${l.name} (${l.componentCount} components)${g}`)}}else o&&console.log(" Projects: none");console.log("")}catch(t){n&&A(t),console.error(`Error: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}})}import So from"axios";function No(e){e.command("search").description("Search component names across all projects").argument("<query>","Search query (case-insensitive substring match)").option("--limit <n>","Maximum number of results","20").option("--team <nameOrId>","Search only within a specific team").option("--personal","Search only personal projects").action(async(n,t)=>{var s,i;let o=x(),r=parseInt(t.limit,10)||20;try{if(t.team&&t.personal)throw new p("Cannot use --team and --personal together.",{code:"INVALID_OPTIONS",suggestion:"Use --team to filter by team, or --personal for personal projects only."});let c;try{c=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let a=o?null:T("Searching components...").start();try{let l=new URLSearchParams({q:n,limit:String(Math.min(Math.max(r,1),50))});if(t.personal)l.set("personal","true");else if(t.team){let u=await G(t.team,c);l.set("organizationId",u.id)}let g=await So.get(`${Ut()}?${l.toString()}`,{headers:c}),m=g.data.data??g.data,d=(Array.isArray(m==null?void 0:m.components)?m.components:[]).map(u=>{var h,y,P,U;return{name:u.name,generatedName:u.generatedName,id:String(u.id),projectName:((h=u.project)==null?void 0:h.name)??"",projectId:String(((y=u.project)==null?void 0:y.id)??""),previewImageUrl:u.previewImageUrl??null,ownerType:((P=u.project)==null?void 0:P.ownerType)==="team"?"team":"personal",ownerName:((U=u.project)==null?void 0:U.ownerName)??""}});if(a==null||a.succeed(`Found ${d.length} match(es) for "${n}"`),o&&v(d),d.length===0){console.log(`
|
|
116
|
-
No components matching "${n}".`);return}console.log("");let b=Math.max(4,...d.map(u=>u.name.length)),I=Math.max(13,...d.map(u=>u.generatedName.length)),$=Math.max(7,...d.map(u=>u.projectName.length)),w=Math.max(9,...d.map(u=>u.ownerType==="personal"?8:u.ownerName.length));console.log(` ${"Name".padEnd(b)} ${"Generated Name".padEnd(I)} ${"Project".padEnd($)} ${"Workspace".padEnd(w)}`),console.log(` ${"\u2500".repeat(b)} ${"\u2500".repeat(I)} ${"\u2500".repeat($)} ${"\u2500".repeat(w)}`);for(let u of d){let h=u.ownerType==="personal"?"Personal":u.ownerName;console.log(` ${u.name.padEnd(b)} ${u.generatedName.padEnd(I)} ${u.projectName.padEnd($)} ${h.padEnd(w)}`)}}catch(l){throw a==null||a.fail("Search failed"),l instanceof p?l:So.isAxiosError(l)?((s=l.response)==null?void 0:s.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`."):new p(`API error: ${(i=l.response)==null?void 0:i.status}`):l}}catch(c){throw o&&A(c),c instanceof p&&(console.error(`
|
|
117
|
-
${c.message}`),process.exit(1)),c}})}import{z as D}from"zod";var ea=D.object({generatedName:D.string().describe("The generated name of the component (e.g., wispy-river-5234)")}),ta=D.object({component:D.string().describe("Component display name"),generatedName:D.string().describe("Component generated name"),files:D.array(D.object({path:D.string(),name:D.string(),content:D.string()})).describe("Component source files"),dependencies:D.array(D.string()).describe("Required packages"),importStatement:D.string().optional().describe("Import statement for the component"),usage:D.string().optional().describe("JSX usage example")});function Ro(e){e.command("inspect").description("Inspect a MagicPath component's source code without installing").argument("<generatedName>","Generated name of the component (e.g., wispy-river-5234)").option("-d, --debug","Enable debug logging",!1).action(async(n,t)=>{try{t.debug&&se();let o=x();k.debug({generatedName:n,options:t});let r=o?null:T(`Fetching component "${n}"...`).start(),s;try{s=await we(n),r==null||r.succeed(`Found component: ${s.name}`)}catch(m){throw r==null||r.fail("Failed to fetch component"),m instanceof B?new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."}):m instanceof p?m:new p("Something went wrong!")}let i=Re(s.name),c=s.files[0],a,l;if(c){let m=c.name.replace(/\.tsx?$/,""),f=`@/components/magicpath/${i}/${m}`,d=ee(c.content);d?(a=ce(d,f),l=le(d)):a=`import { ${m} } from '${f}';`}let g=s.files.map(m=>({path:m.path,name:m.name,content:m.content}));if(o){v({component:s.name,generatedName:s.generatedName,files:g,dependencies:s.dependencies,importStatement:a,usage:l});return}console.log(`
|
|
118
|
-
Component: ${s.name}`),console.log(` Files: ${s.files.map(m=>m.path).join(", ")}`),console.log(` Dependencies: ${s.dependencies.join(", ")||"none"}`),a&&console.log(` Import: ${a}`);for(let m of s.files)console.log(`
|
|
119
|
-
${"\u2500".repeat(60)}`),console.log(` ${m.path}`),console.log(`${"\u2500".repeat(60)}`),console.log(m.content)}catch(o){throw x()&&A(o),o instanceof p&&(console.error(`
|
|
120
|
-
${o.message}`),process.exit(1)),o}})}import te from"path";import me from"fs-extra";function qn(e,n){if(!me.existsSync(e))return[];let t=me.readdirSync(e,{withFileTypes:!0}),o=[];for(let r of t){if(!r.isDirectory())continue;let s=te.join(e,r.name),i=me.readdirSync(s).filter(g=>!me.statSync(te.join(s,g)).isDirectory()),c=i.find(g=>(g.endsWith(".tsx")||g.endsWith(".ts"))&&g!=="usage.md"&&!g.includes(".test.")&&!g.includes(".spec.")),a=null,l=null;if(c)try{let g=me.readFileSync(te.join(s,c),"utf8"),m=ee(g);if(m){a=m.name;let f=c.replace(/\.tsx?$/,""),d=`@/components/magicpath/${r.name}/${f}`;m.isDefault?l=`import ${m.name} from '${d}';`:l=`import { ${m.name} } from '${d}';`}}catch{}o.push({name:a||r.name,folder:r.name,path:te.relative(n,s),files:i.filter(g=>g!=="usage.md"),exportName:a,importStatement:l})}return o}function ko(e){e.command("list-installed").description("List MagicPath components installed in the current project").option("-p, --path <path>",`Custom components path (default: ${ye})`).action(async n=>{let t=x();try{let o=process.cwd(),r=ke(n.path,o);if(!me.existsSync(r)){t&&v({components:[],total:0}),console.log(`
|
|
121
|
-
No MagicPath components found at ${te.relative(o,r)||r}`);return}let s=qn(r,o);if(t&&v({components:s,total:s.length,componentsPath:te.relative(o,r)}),s.length===0){console.log(`
|
|
122
|
-
No MagicPath components installed.`);return}console.log(`
|
|
123
|
-
${s.length} component(s) installed in ${te.relative(o,r)}:
|
|
124
|
-
`);let i=Math.max(9,...s.map(l=>l.name.length)),c=Math.max(6,...s.map(l=>l.folder.length)),a=5;console.log(` ${"Component".padEnd(i)} ${"Folder".padEnd(c)} ${"Files".padEnd(a)}`),console.log(` ${"\u2500".repeat(i)} ${"\u2500".repeat(c)} ${"\u2500".repeat(a)}`);for(let l of s)console.log(` ${l.name.padEnd(i)} ${l.folder.padEnd(c)} ${String(l.files.length).padEnd(a)}`)}catch(o){throw t&&A(o),o instanceof p&&(console.error(`
|
|
125
|
-
${o.message}`),process.exit(1)),o}})}import Oo from"axios";function Mo(e){e.command("list-themes").description("List all themes (design systems)").option("--team <nameOrId>","List themes for a specific team").action(async n=>{var o,r,s;let t=x();try{let i;try{i=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let c=t?null:T("Fetching themes...").start();try{let a=Ce(),l=i;if(n.team){let w=await G(n.team,i);a=je(w.id),l={...i,"X-Organization-ID":w.id}}let g=await Oo.get(a,{headers:l}),m=((o=g.data.data)==null?void 0:o.design_systems)??g.data.design_systems??g.data,f=Array.isArray(m)?m:[];if(c==null||c.succeed(`Found ${f.length} theme(s)`),t&&v({themes:f.map(w=>({id:String(w.id),name:w.name,isPublic:w.isPublic,createdAt:w.createdAt,updatedAt:w.updatedAt}))}),f.length===0){console.log(`
|
|
126
|
-
No themes found.`);return}console.log("");let d=Math.max(4,...f.map(w=>(w.name||"").length)),b=Math.max(2,...f.map(w=>String(w.id).length)),I=6,$=10;console.log(` ${"Name".padEnd(d)} ${"ID".padEnd(b)} ${"Public".padEnd(I)} Updated`),console.log(` ${"\u2500".repeat(d)} ${"\u2500".repeat(b)} ${"\u2500".repeat(I)} ${"\u2500".repeat($)}`);for(let w of f){let u=(w.name||"").padEnd(d),h=String(w.id).padEnd(b),y=(w.isPublic?"yes":"no").padEnd(I),P=w.updatedAt?new Date(w.updatedAt).toISOString().slice(0,10):"";console.log(` ${u} ${h} ${y} ${P}`)}}catch(a){throw c==null||c.fail("Failed to fetch themes"),Oo.isAxiosError(a)?((r=a.response)==null?void 0:r.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):new p(`API error: ${(s=a.response)==null?void 0:s.status}`):a}}catch(i){throw t&&A(i),i instanceof p&&(console.error(`
|
|
127
|
-
${i.message}`),process.exit(1)),i}})}import mt from"axios";function Uo(e){e.command("get-theme").description("Get a theme definition (CSS variables, fonts, styling prompt)").argument("<themeIdOrName>","Theme ID (numeric) or name (case-insensitive match)").option("--team <nameOrId>","Look up theme within a specific team").action(async(n,t)=>{var r,s,i,c,a,l,g;let o=x();try{let m;try{m=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let f=o?null:T("Fetching theme...").start();try{let d=n,b;if(!/^\d+$/.test(n)){let h=Ce(),y=m;if(t.team){let R=await G(t.team,m);h=je(R.id),y={...m,"X-Organization-ID":R.id}}let P=await mt.get(h,{headers:y}),U=((r=P.data.data)==null?void 0:r.design_systems)??P.data.design_systems??P.data,_=Array.isArray(U)?U:[],C=n.toLowerCase(),j=_.find(R=>(R.name||"").toLowerCase()===C);if(!j)throw new p(`Theme "${n}" not found.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai list-themes` to see available themes."});d=String(j.id),b=j.name}let I=await mt.get(kt(d),{headers:m}),$=((s=I.data.data)==null?void 0:s.design_system)??I.data.design_system,w=$.name??b??d,u=$.data;f==null||f.succeed(`Theme: ${w}`),o&&v({id:String($.id??d),name:w,theme:u.theme,defaultTheme:u.defaultTheme,prompt:u.prompt,fonts:u.fonts,version:u.version}),console.log(""),console.log(` Name: ${w}`),console.log(` ID: ${$.id??d}`),console.log(` Default Theme: ${u.defaultTheme??"light"}`),u.prompt&&console.log(` Prompt: ${u.prompt}`);for(let h of["light","dark"]){let y=(i=u.theme)==null?void 0:i[h];if(y&&Object.keys(y).length>0){console.log(`
|
|
128
|
-
${h.charAt(0).toUpperCase()+h.slice(1)} Theme Variables:`);let P=Math.max(8,...Object.keys(y).map(U=>U.length));console.log(` ${"Variable".padEnd(P)} Value`),console.log(` ${"\u2500".repeat(P)} ${"\u2500".repeat(30)}`);for(let[U,_]of Object.entries(y))console.log(` ${U.padEnd(P)} ${_}`)}}if(u.fonts&&Object.keys(u.fonts).length>0){console.log(`
|
|
129
|
-
Fonts:`);for(let[h,y]of Object.entries(u.fonts)){let P=y.weights?Object.keys(y.weights).join(", "):"default";console.log(` ${h} (${y.source}, weights: ${P})`)}}}catch(d){throw f==null||f.fail("Failed to fetch theme"),mt.isAxiosError(d)?((c=d.response)==null?void 0:c.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):((a=d.response)==null?void 0:a.status)===404||((l=d.response)==null?void 0:l.status)===403?new p(`Theme "${n}" not found or not accessible.`,{code:"NOT_FOUND",suggestion:"Run `magicpath-ai list-themes` to see available themes."}):new p(`API error: ${(g=d.response)==null?void 0:g.status}`):(d instanceof p,d)}}catch(m){throw o&&A(m),m instanceof p&&(console.error(`
|
|
130
|
-
${m.message}`),process.exit(1)),m}})}import dt from"axios";import{createClient as Zn}from"@liveblocks/client";import Yn from"ws";function Fe(e){let n=Ot();return Zn({polyfills:{fetch,WebSocket:Yn},authEndpoint:async t=>await(await fetch(n,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify({room:t})})).json()})}async function De(e,n,t=1e4){let{room:o,leave:r}=e.enterRoom(n,{initialPresence:{}});return await new Promise((s,i)=>{let c=setTimeout(()=>{i(new Error(`Timed out connecting to room ${n}`))},t),a=o.subscribe("status",l=>{l==="connected"&&(clearTimeout(c),a(),s())});o.getStatus()==="connected"&&(clearTimeout(c),a(),s())}),await new Promise(s=>{if(o.getOthers().length>0){s();return}let c=setTimeout(()=>{a(),s()},3e3),a=o.subscribe("others",l=>{l.length>0&&(clearTimeout(c),a(),s())})}),{room:o,leave:r}}function _e(e){var o,r;let n=e.getOthers(),t=[];for(let s of n){let i=(o=s.presence)==null?void 0:o.presence;(r=i==null?void 0:i.selectedShapeIds)!=null&&r.length&&t.push(...i.selectedShapeIds)}return[...new Set(t)]}async function Fo(e,n){let{root:t}=await e.getStorage(),o=t.get("records");if(!o)return[];let r=[];for(let s of n){let i=o.get(s);if(!i)continue;let c=typeof i.toObject=="function"?i.toObject():i;if(c.type==="mp-component"&&c.props){let a=typeof c.props.toObject=="function"?c.props.toObject():c.props;a.serverId&&r.push({serverId:a.serverId,clientId:a.clientId??s.replace("shape:",""),name:a.name??"Unknown",selectedRevisionId:typeof a.selectedRevisionId=="string"&&a.selectedRevisionId.length>0?a.selectedRevisionId:null})}}return r}function de(e){return e&&typeof e.toObject=="function"?e.toObject():e}function z(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function Qn(e,n){let t=de(n),o=de(t==null?void 0:t.meta);return z(o==null?void 0:o.imageId)??(e.startsWith("asset:")?e.slice(6):void 0)}function er(e){return e.startsWith("shape:")?e.slice(6):e}async function Le(e,n){let{root:t}=await e.getStorage(),o=t.get("records");if(!o)return[];let r=[];for(let s of n){let i=o.get(s);if(!i)continue;let c=de(i);if(c.type!=="image"&&c.type!=="mp-image")continue;let a=de(c.props)??{},l=z(a.assetId),g=l?o.get(l):null,m=de(g),f=de(m==null?void 0:m.props)??{},d=(l?Qn(l,g):void 0)??z(a.imageId)??z(a.serverId)??(s.startsWith("shape:")?s.slice(6):s);d&&r.push({imageId:d,shapeId:er(s),...z(f.name)||z(a.name)||z(a.altText)?{name:z(f.name)??z(a.name)??z(a.altText)}:{},...typeof a.w=="number"?{width:a.w}:{},...typeof a.h=="number"?{height:a.h}:{}})}return r}function Do(e){e.command("selection").description("Get the currently selected component(s) from the web app canvas").action(async()=>{var t,o,r,s;let n=x();try{let i;try{i=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let c=n?null:T("Checking canvas selection...").start();try{let a=await dt.get(oe(),{headers:i}),l=((t=a.data.data)==null?void 0:t.socket_rooms)??a.data.socket_rooms,g=(l==null?void 0:l.projectRooms)??[];if(g.length===0){c==null||c.succeed("No active canvas session"),n&&v({projects:[],components:[],images:[]}),console.log(`
|
|
131
|
-
No active canvas session found.`);return}let m=new Map;try{let u=await Z(i);m=new Map(u.map(h=>[String(h.id),{name:h.name??"",ownerType:h.ownerType,ownerName:h.ownerName}]))}catch{}let f=g.map(u=>{let h=m.get(String(u.id));return h?{id:String(u.id),name:h.name,ownerType:h.ownerType,ownerName:h.ownerName}:{id:String(u.id),name:null,ownerType:null,ownerName:null}}),d=g.map(u=>{var h;return{projectId:u.id,projectName:((h=m.get(String(u.id)))==null?void 0:h.name)??"",roomId:u.room}}),b=Fe(i),I=[],$=[];for(let u of d){let h=null;try{let y=await De(b,u.roomId);h=y.leave;let P=y.room,U=_e(P);if(U.length===0)continue;let[_,C]=await Promise.all([Fo(P,U),Le(P,U)]);$.push(...C.map(j=>({id:j.imageId,shapeId:j.shapeId,name:j.name??null,projectId:u.projectId,projectName:u.projectName,...j.width?{width:j.width}:{},...j.height?{height:j.height}:{}})));for(let j of _)try{let R=await dt.get(Mt(j.serverId),{headers:i}),L=((o=R.data.data)==null?void 0:o.component)??R.data.component;I.push({id:j.serverId,name:(L==null?void 0:L.name)??j.name,generatedName:(L==null?void 0:L.generatedName)??null,clientId:j.clientId,projectId:u.projectId,projectName:u.projectName,selectedRevisionId:j.selectedRevisionId})}catch{I.push({id:j.serverId,name:j.name,generatedName:null,clientId:j.clientId,projectId:u.projectId,projectName:u.projectName,selectedRevisionId:j.selectedRevisionId})}}catch{}finally{h&&h()}}if(I.length===0){if(c==null||c.succeed($.length>0?`Found ${$.length} selected image(s)`:"No components selected"),n&&v({projects:f,components:[],images:$}),$.length>0){console.log(`
|
|
132
|
-
Selected image(s):`);for(let u of $)console.log(` ${u.name??"Image"} (${u.id})`)}else console.log(`
|
|
133
|
-
No active selection.`);if(f.length>0){console.log(" Active project(s):");for(let u of f){let h=u.ownerType==="team"&&u.ownerName?` [${u.ownerName}]`:"",y=u.name??`(unresolved project ${u.id})`;console.log(` ${y}${h}`)}}return}c==null||c.succeed(`Found ${I.length} selected component(s)`),n&&v({projects:f,components:I,images:$});let w=new Map;for(let u of I){let h=u.projectId;w.has(h)||w.set(h,[]),w.get(h).push(u)}console.log("");for(let[,u]of w){console.log(` Selected in "${u[0].projectName}":`);for(let h of u){let y=h.generatedName?` (${h.generatedName})`:"";console.log(` ${h.name}${y}`)}}if($.length>0){console.log(`
|
|
134
|
-
Selected image(s):`);for(let u of $)console.log(` ${u.name??"Image"} (${u.id})`)}}catch(a){throw c==null||c.fail("Failed to check selection"),dt.isAxiosError(a)?((r=a.response)==null?void 0:r.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):new p(`API error: ${(s=a.response)==null?void 0:s.status}`):a}}catch(i){throw n&&A(i),i instanceof p&&(console.error(`
|
|
135
|
-
${i.message}`),process.exit(1)),i}})}import _o from"axios";function Lo(e){e.command("active-project").description("Get the project(s) the user currently has open in the MagicPath web app").action(async()=>{var t,o,r;let n=x();try{let s;try{s=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let i=n?null:T("Checking active project...").start();try{let c=await _o.get(oe(),{headers:s}),a=((t=c.data.data)==null?void 0:t.socket_rooms)??c.data.socket_rooms,l=(a==null?void 0:a.projectRooms)??[];if(l.length===0){i==null||i.succeed("No active canvas session"),n&&v({projects:[]}),console.log(`
|
|
136
|
-
No active canvas session found.`);return}let g=await Z(s),m=new Map;for(let d of g)m.set(String(d.id),d);let f=[];for(let d of l){let b=String(d.id),I=m.get(b);I?f.push({id:b,name:I.name??null,ownerType:I.ownerType,ownerName:I.ownerName}):f.push({id:b,name:null,ownerType:null,ownerName:null})}i==null||i.succeed(`Found ${f.length} active project${f.length===1?"":"s"}`),n&&v({projects:f}),console.log("");for(let d of f){let b=d.ownerType==="team"&&d.ownerName?` [${d.ownerName}]`:"",I=d.name??`(unresolved project ${d.id})`;console.log(` ${I}${b}`)}}catch(c){throw i==null||i.fail("Failed to check active project"),_o.isAxiosError(c)?((o=c.response)==null?void 0:o.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):new p(`API error: ${(r=c.response)==null?void 0:r.status}`):c}}catch(s){throw n&&A(s),s instanceof p&&(console.error(`
|
|
137
|
-
${s.message}`),process.exit(1)),s}})}function Wo(e){e.command("list-teams").description("List teams you belong to").action(async()=>{let n=x();try{let t;try{t=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let o=n?null:T("Fetching teams...").start();try{let r=await fe(t);if(o==null||o.succeed(`Found ${r.length} team(s)`),n&&v({teams:r}),r.length===0){console.log(`
|
|
138
|
-
No teams found.`);return}console.log("");let s=Math.max(4,...r.map(a=>a.name.length)),i=Math.max(2,...r.map(a=>a.id.length)),c=Math.max(4,...r.map(a=>a.role.length));console.log(` ${"Name".padEnd(s)} ${"ID".padEnd(i)} Role`),console.log(` ${"\u2500".repeat(s)} ${"\u2500".repeat(i)} ${"\u2500".repeat(c)}`);for(let a of r)console.log(` ${a.name.padEnd(s)} ${a.id.padEnd(i)} ${a.role}`)}catch(r){throw o==null||o.fail("Failed to fetch teams"),r instanceof p,r}}catch(t){throw n&&A(t),t instanceof p&&(console.error(`
|
|
139
|
-
${t.message}`),process.exit(1)),t}})}import Ho from"axios";function Go(e){e.command("list-members").description("List members of a team").requiredOption("--team <nameOrId>","Team name or ID").action(async n=>{var o,r,s;let t=x();try{let i;try{i=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let c=t?null:T("Fetching members...").start();try{let a=await G(n.team,i),l=await Ho.get(Ft(a.id),{headers:{...i,"X-Organization-ID":a.id}}),f=((((o=l.data.data)==null?void 0:o.organization)??l.data.organization??l.data).users??[]).map(w=>{var u,h,y;return{id:String(((u=w.user)==null?void 0:u.id)??w.userId),displayName:((h=w.user)==null?void 0:h.displayName)??null,email:((y=w.user)==null?void 0:y.email)??null,role:w.role}});if(c==null||c.succeed(`${a.name}: ${f.length} member(s)`),t&&v({team:{id:a.id,name:a.name},members:f}),f.length===0){console.log(`
|
|
140
|
-
No members found.`);return}console.log("");let d=Math.max(4,...f.map(w=>(w.displayName||"").length)),b=Math.max(5,...f.map(w=>(w.email||"").length)),I=Math.max(2,...f.map(w=>w.id.length)),$=Math.max(4,...f.map(w=>w.role.length));console.log(` ${"Name".padEnd(d)} ${"Email".padEnd(b)} ${"ID".padEnd(I)} Role`),console.log(` ${"\u2500".repeat(d)} ${"\u2500".repeat(b)} ${"\u2500".repeat(I)} ${"\u2500".repeat($)}`);for(let w of f)console.log(` ${(w.displayName||"").padEnd(d)} ${(w.email||"").padEnd(b)} ${w.id.padEnd(I)} ${w.role}`)}catch(a){throw c==null||c.fail("Failed to fetch members"),a instanceof p?a:Ho.isAxiosError(a)?((r=a.response)==null?void 0:r.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):new p(`API error: ${(s=a.response)==null?void 0:s.status}`):a}}catch(i){throw t&&A(i),i instanceof p&&(console.error(`
|
|
141
|
-
${i.message}`),process.exit(1)),i}})}import V from"axios";import qo from"crypto";import O from"fs-extra";import M from"path";var Zo="magicpath-code.json",tr=new Set(["src/App.tsx","src/index.css"]),Vo="This component uses Tailwind v4. Replace @tailwind base/components/utilities; with @import 'tailwindcss';. Preserve the existing src/index.css Tailwind setup and append custom CSS below it.",or=/@tailwind\s+(base|components|utilities)\s*;/i,nr=/@import\s+(?:url\(\s*)?['"]tailwindcss['"]\s*\)?\s*;/i;function pe(e){return qo.createHash("sha256").update(e).digest("hex")}function rr(e){return qo.createHash("sha256").update(e).digest("hex")}function ft(e){return tr.has(e)||e.startsWith("src/components/generated/")&&!e.endsWith("/")||e.startsWith("assets/")&&!e.endsWith("/")}function ht(e){return e.startsWith("assets/")&&!e.endsWith("/")}function sr(e){let n=M.extname(e).toLowerCase();return{".avif":"image/avif",".gif":"image/gif",".jpeg":"image/jpeg",".jpg":"image/jpeg",".png":"image/png",".svg":"image/svg+xml",".webp":"image/webp"}[n]}function We(e){return M.join(e,Zo)}function ir(e){let n=We(e);if(!O.existsSync(n))throw new p(`No ${Zo} found. Run \`magicpath-ai code context <componentId>\` or \`magicpath-ai code start --project <projectId>\` first.`);return O.readJsonSync(n)}function Ie(e,n){O.ensureDirSync(e),O.writeJsonSync(We(e),n,{spaces:2})}function pt(e,n){if(!ft(n.path))throw new p(`Refusing to write disallowed path from API: ${n.path}`);let t=M.join(e,n.path);O.ensureDirSync(M.dirname(t)),n.encoding==="base64"?O.writeFileSync(t,Buffer.from(n.content.replace(/\s/g,""),"base64")):O.writeFileSync(t,n.content,"utf8")}function ve(e){let n=[],t=["src/App.tsx","src/index.css"],o=M.join(e,"src/components/generated");if(O.existsSync(o))for(let s of ut(o))t.push(M.relative(e,s).split(M.sep).join("/"));let r=M.join(e,"assets");if(O.existsSync(r))for(let s of ut(r))t.push(M.relative(e,s).split(M.sep).join("/"));for(let s of Array.from(new Set(t)).sort()){if(!ft(s))continue;let i=M.join(e,s);if(!(!O.existsSync(i)||!O.statSync(i).isFile()))if(ht(s)){let c=O.readFileSync(i);n.push({path:s,content:c.toString("base64"),encoding:"base64",mimeType:sr(s),sha256:rr(c)})}else{let c=O.readFileSync(i,"utf8");n.push({path:s,content:c,encoding:"utf8",sha256:pe(c)})}}return n}function zo(e){let n=M.join(e,"src/index.css");if(!O.existsSync(n))throw new p(Vo);let t=O.readFileSync(n,"utf8");if(or.test(t)||!nr.test(t))throw new p(Vo)}function ut(e){let n=[];for(let t of O.readdirSync(e,{withFileTypes:!0})){let o=M.join(e,t.name);t.isDirectory()?n.push(...ut(o)):t.isFile()&&n.push(o)}return n}function ar(e,n){if(n.mode==="create")return ve(e);let t=new Map(n.editableFiles.map(o=>[o.path,o.sha256]));return ve(e).map(o=>({...o,baseSha256:t.get(o.path)})).filter(o=>o.sha256!==o.baseSha256)}function cr(e,n){if(n.mode==="create")return[];let t=new Set(ve(e).map(o=>o.path));return n.editableFiles.map(o=>o.path).filter(o=>!ht(o)).filter(o=>!t.has(o))}async function Jo(e,n){let t=E();for(;;){let r=(await V.get(Xe(e),{headers:t})).data.data;if(r.status==="completed"||r.status==="failed"||r.status==="cancelled")return r;await new Promise(s=>setTimeout(s,n))}}function be(e){let n=H(e);throw x()&&A(n),n}function Bo(e,n){if(e===void 0)return;let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new p(`${n} must be a positive number.`);return t}function gt(e){let n=Bo(e.width,"--width"),t=Bo(e.height,"--height");if(n===void 0!=(t===void 0))throw new p("Pass both --width and --height, or neither.");return n===void 0||t===void 0?void 0:{width:n,height:t}}function lr(e){let n=new Map;for(let t of e)n.has(t.imageId)||n.set(t.imageId,t);return Array.from(n.values())}async function Ko(e){var t;let n;try{n=E()}catch{return[]}try{let o=await V.get(oe(),{headers:n}),r=((t=o.data.data)==null?void 0:t.socket_rooms)??o.data.socket_rooms,s=(r==null?void 0:r.projectRooms)??[],i=e?s.filter(l=>String(l.id)===String(e)):s;if(i.length===0)return[];let c=Fe(n),a=[];for(let l of i){let g=null;try{let m=await De(c,l.room);g=m.leave;let f=_e(m.room);if(f.length===0)continue;let d=await Le(m.room,f);a.push(...d.filter(b=>/^\d+$/.test(b.imageId)).map(b=>({imageId:b.imageId,...b.shapeId?{shapeId:b.shapeId}:{}})))}catch{}finally{g&&g()}}return lr(a)}catch{return[]}}async function Xo(e,n){if(!(n!=null&&n.length))return[];let t=[];for(let o of n){if(!ft(o.assetPath)||!ht(o.assetPath))throw new p(`Refusing to download selected image outside assets/: ${o.assetPath}`);let r=await V.get(o.accessUrl,{responseType:"arraybuffer"}),s=M.join(e,o.assetPath);O.ensureDirSync(M.dirname(s)),O.writeFileSync(s,Buffer.from(r.data)),t.push({...o,downloadedPath:s})}return t}function Yo(e){let n=e.command("code").description("Create and edit canvas components from local code").addHelpText("after",`
|
|
142
|
-
Tailwind v4:
|
|
143
|
-
src/index.css must keep @import 'tailwindcss';.
|
|
144
|
-
Do not use @tailwind base/components/utilities; and do not replace the
|
|
145
|
-
template @theme inline, :root, or .dark token blocks. Append custom CSS below
|
|
146
|
-
the existing setup.
|
|
147
|
-
`);n.command("start").description("Start a pending create or edit session before writing code").option("--project <projectId>","Target MagicPath project ID for create").option("--component <componentId>","Existing MagicPath component ID for edit").option("--revision <revisionId>","Start editing this revision. Defaults to the component's currently selected revision.").option("--dir <dir>","Working directory to initialize",".").option("--name <name>","Component name").option("--width <px>","Canvas component width for create").option("--height <px>","Canvas component height for create").action(async t=>{try{let o=M.resolve(t.dir),r=gt(t);if(!!t.project==!!t.component)throw new p("Run code start with exactly one of --project for create or --component for edit.");if(t.component){if(r)throw new p("Use --width and --height with code submit when resizing an existing component.");let d=await Ko(),I=(await V.post(At(t.component),{...t.revision?{revisionId:t.revision}:{},...d.length>0?{selectedImages:d}:{}},{headers:E()})).data.data;O.ensureDirSync(o);for(let h of I.editableFiles)pt(o,h);let $=await Xo(o,I.selectedImages),w={mode:"edit",componentId:I.component.id,projectId:I.component.projectId,selectedRevisionId:I.component.selectedRevisionId,baseRevisionId:I.component.baseRevisionId,jobId:I.jobId,generatedName:I.component.generatedName,name:I.component.name,selectedImages:$,editableFiles:I.editableFiles.map(h=>({path:h.path,sha256:pe(h.content)}))};Ie(o,w);let u={dir:o,manifestPath:We(o),...w,status:"pending",scaffoldedPaths:I.editableFiles.map(h=>h.path),selectedImages:$};x()&&v(u),console.log(`Started pending edit ${w.selectedRevisionId} for component ${w.componentId} in ${o}`);return}let s=t.project;if(!s)throw new p("Create sessions require --project.");let i=await Ko(s),a=(await V.post(Je(),{projectId:s,...t.name?{name:t.name}:{},...r?{dimensions:r}:{},...i.length>0?{selectedImages:i}:{}},{headers:E()})).data.data,l=a.editableFiles??[];O.ensureDirSync(o);for(let d of l)pt(o,d);let g=await Xo(o,a.selectedImages),m={mode:"create",componentId:a.componentId,projectId:s,selectedRevisionId:a.revisionId,jobId:a.jobId,generatedName:a.generatedName,name:t.name,dimensions:r,selectedImages:g,editableFiles:l.map(d=>({path:d.path,sha256:pe(d.content)}))};Ie(o,m);let f={dir:o,manifestPath:We(o),...m,status:"pending",scaffoldedPaths:l.map(d=>d.path),selectedImages:g};x()&&v(f),console.log(`Started pending component ${m.componentId} in ${o}`+(l.length>0?` (scaffolded ${l.length} file${l.length===1?"":"s"})`:""))}catch(o){be(o)}}),n.command("context").description("Fetch editable files for an existing MagicPath component").argument("<componentId>","MagicPath component ID").option("--dir <dir>","Working directory to write",".").option("--revision <revisionId>","Pull this revision of the component. Defaults to the component's currently selected revision.").action(async(t,o)=>{try{let r=M.resolve(o.dir);O.ensureDirSync(r);let s=o.revision?`${Be(t)}?revisionId=${encodeURIComponent(o.revision)}`:Be(t),c=(await V.get(s,{headers:E()})).data.data;for(let l of c.editableFiles)pt(r,l);let a={dir:r,readOnly:!0,component:c.component,editableFiles:c.editableFiles.map(l=>({path:l.path,sha256:pe(l.content)}))};x()&&v(a),console.log(`Fetched ${c.editableFiles.length} read-only editable file(s) into ${r}. Run \`magicpath-ai code start --component ${t} --dir ${r}\` before submitting edits.`)}catch(r){be(r)}}),n.command("submit").description("Submit changed editable files for the component in this working directory").option("--dir <dir>","Working directory containing magicpath-code.json",".").option("--wait","Wait for the build job to finish",!1).option("--interval <ms>","Polling interval when --wait is set","2000").option("--width <px>","Updated canvas component width").option("--height <px>","Updated canvas component height").action(async t=>{try{let o=M.resolve(t.dir),r=ir(o),s=gt(t);zo(o);let i=ar(o,r),c=cr(o,r);if(r.mode==="create"&&!i.some(m=>m.path==="src/App.tsx"))throw new p("Create submit requires src/App.tsx in the working directory.");if(i.length===0&&c.length===0&&!s){let m={status:"unchanged",componentId:r.componentId,revisionId:r.selectedRevisionId};x()&&v(m),console.log("No editable file changes to submit.");return}let l=r.mode==="create"||!!r.baseRevisionId&&r.selectedRevisionId!==r.baseRevisionId?await V.post(Ke(r.componentId,r.selectedRevisionId),{files:i.map(m=>({path:m.path,content:m.content,encoding:m.encoding,mimeType:m.mimeType})),contextJobId:r.jobId,...s?{dimensions:s}:{},...r.mode==="edit"?{deletedPaths:c}:{}},{headers:E()}):await V.post(Pt(r.componentId),{baseRevisionId:r.baseRevisionId??r.selectedRevisionId,files:i.map(m=>({path:m.path,content:m.content,encoding:m.encoding,mimeType:m.mimeType,baseSha256:m.baseSha256})),deletedPaths:c,...s?{dimensions:s}:{}},{headers:E()}),g=l.data.data;if(t.wait&&(g=await Jo(l.data.data.jobId,Number(t.interval))),g.status==="completed"){let m=ve(o),f={...r,mode:"edit",jobId:l.data.data.jobId,selectedRevisionId:g.revisionId,baseRevisionId:g.revisionId,...s?{dimensions:s}:{},editableFiles:m.map(d=>({path:d.path,sha256:d.sha256??pe(d.content)}))};Ie(o,f)}x()&&v({...g,jobId:l.data.data.jobId,deletedPaths:c,...s?{dimensions:s}:{}}),console.log(`Submitted ${i.length} file(s)`+(c.length>0?` and ${c.length} deletion(s)`:"")+`. Job ${l.data.data.jobId}: ${g.status}`)}catch(o){be(o)}}),n.command("create").description("Create a new MagicPath component from local editable files").requiredOption("--project <projectId>","Target MagicPath project ID").option("--dir <dir>","Working directory containing src/App.tsx",".").option("--name <name>","Component name").option("--wait","Wait for the build job to finish",!1).option("--width <px>","Canvas component width").option("--height <px>","Canvas component height").action(async t=>{try{let o=M.resolve(t.dir),r=gt(t);zo(o);let s=ve(o);if(!s.some(g=>g.path==="src/App.tsx"))throw new p("Create requires src/App.tsx in the working directory.");let i=await V.post(Je(),{projectId:t.project,...t.name?{name:t.name}:{},...r?{dimensions:r}:{}},{headers:E()}),c={mode:"create",componentId:i.data.data.componentId,projectId:t.project,selectedRevisionId:i.data.data.revisionId,jobId:i.data.data.jobId,generatedName:i.data.data.generatedName,name:t.name,dimensions:r,editableFiles:[]};Ie(o,c);let a=await V.post(Ke(c.componentId,c.selectedRevisionId),{files:s.map(g=>({path:g.path,content:g.content,encoding:g.encoding,mimeType:g.mimeType})),contextJobId:c.jobId,...r?{dimensions:r}:{}},{headers:E()}),l=a.data.data;t.wait&&(l=await Jo(a.data.data.jobId,2e3)),l.status==="completed"&&Ie(o,{...c,mode:"edit",jobId:a.data.data.jobId,selectedRevisionId:l.revisionId,...r?{dimensions:r}:{},editableFiles:s.map(g=>({path:g.path,sha256:g.sha256??pe(g.content)}))}),x()&&v({...l,jobId:a.data.data.jobId,...r?{dimensions:r}:{}}),console.log(`Created component ${a.data.data.componentId}. Job ${a.data.data.jobId}: ${l.status}`)}catch(o){be(o)}}),n.command("status").description("Fetch external-agent build job status").argument("<jobId>","External agent job ID").action(async t=>{try{let o=await V.get(Xe(t),{headers:E()});x()&&v(o.data.data),console.log(`${t}: ${o.data.data.status}`)}catch(o){be(o)}})}import xe from"axios";import Qo from"fs";import wt from"path";import{imageSize as mr}from"image-size";var en=512;async function dr(e){if(/^https?:\/\//i.test(e)){let t=await xe.get(e,{responseType:"arraybuffer"}),o=wt.basename(new URL(e).pathname)||"image";return{buffer:Buffer.from(t.data),fileName:o}}let n=wt.resolve(e);if(!Qo.existsSync(n))throw new Error(`Image file not found: ${n}`);return{buffer:Qo.readFileSync(n),fileName:wt.basename(n)}}function He(e){if(e===void 0)return;let n=Number(e);if(!Number.isFinite(n))throw new Error(`Invalid number: ${e}`);return n}function tn(e){let n=e.command("image").description("Add and list images on a project canvas");n.command("add").description("Add an image to a project canvas from a local file path or a URL").argument("<projectId>","The id of the project to add the image to").argument("<pathOrUrl>","A local image file path or an http(s) URL").option("--name <name>","Display name for the image (defaults to the file name)").option("--x <x>","Canvas x position (default 0)").option("--y <y>","Canvas y position (default 0)").option("--width <width>","Width in canvas units (defaults to the intrinsic width)").option("--height <height>","Height in canvas units (defaults to the intrinsic height)").action(async(t,o,r)=>{var c,a;let s=x(),i=s?null:T("Adding image to project...").start();try{let l=E(),{buffer:g,fileName:m}=await dr(o),f=He(r.width),d=He(r.height);if(f===void 0||d===void 0)try{let P=mr(g);f=f??P.width,d=d??P.height}catch{}f=f??en,d=d??en;let b={x:He(r.x)??0,y:He(r.y)??0,z:0,width:f,height:d},I=r.name??(m.replace(/\.[^/.]+$/,"")||m),$=await xe.get(Tt(),{headers:l,params:{filename:m,content_type:"image/*",make_public:"true"}}),{upload_url:w,upload_token:u}=$.data;await xe.put(w,g,{headers:{"Content-Type":"image/*","x-goog-acl":"public-read"}});let y=(a=(c=(await xe.post(Ze(t),{name:I,position:b,upload_token:u},{headers:l})).data)==null?void 0:c.data)==null?void 0:a.image;i==null||i.succeed("Image added to project"),s&&v({image:y}),console.log(`Added "${(y==null?void 0:y.name)??I}" (${(y==null?void 0:y.id)??"unknown id"})`),y!=null&&y.url&&console.log(y.url)}catch(l){i==null||i.fail("Failed to add image"),s&&A(l),console.error(l instanceof Error?l.message:String(l)),process.exit(1)}}),n.command("list").description("List the images on a project canvas").argument("<projectId>","The id of the project").action(async t=>{var s,i;let o=x(),r=o?null:T("Fetching images...").start();try{let c=E(),l=((i=(s=(await xe.get(Ze(t),{headers:c})).data)==null?void 0:s.data)==null?void 0:i.images)??[];if(r==null||r.succeed(`Found ${l.length} image(s)`),o&&v({images:l}),l.length===0){console.log("No images in this project.");return}for(let g of l)console.log(`- ${g.name} (${g.id})${g.url?` \u2014 ${g.url}`:""}`)}catch(c){r==null||r.fail("Failed to list images"),o&&A(c),console.error(c instanceof Error?c.message:String(c)),process.exit(1)}})}import yt from"axios";function on(e){var n;return((n=e==null?void 0:e.data)==null?void 0:n.project)??(e==null?void 0:e.project)??e}function nn(e){e.command("create-project").description("Create a new project (personal or in a team)").option("--name <name>","Project name (defaults to an auto-generated name)").option("--team <nameOrId>","Create the project in this team").action(async n=>{var o,r,s,i;let t=x();try{let c;try{c=E()}catch{throw new p("Not authenticated. Set MAGICPATH_TOKEN or run `magicpath-ai login`.",{code:"NOT_AUTHENTICATED",suggestion:"Run `magicpath-ai login` or set the MAGICPATH_TOKEN environment variable."})}let a=t?null:T("Creating project...").start();try{let l={...c},g=null;n.team&&(g=await G(n.team,c),l["X-Organization-ID"]=g.id);let m=await yt.post(St(),{},{headers:l}),f=on(m.data);if(n.name){let b=await yt.patch(Nt(String(f.id)),{data:{name:n.name}},{headers:l});f=on(b.data)}let d=g?{...f,ownerType:"team",ownerName:g.name}:{...f,ownerType:"personal",ownerName:((o=f.owner)==null?void 0:o.email)??""};a==null||a.succeed(`Created project "${d.name}"${g?` in ${g.name}`:""}`),t&&v({project:d}),console.log(""),console.log(` ID: ${d.id}`),console.log(` Name: ${d.name}`),console.log(` Workspace: ${g?g.name+" (team)":"personal"}`)}catch(l){throw a==null||a.fail("Failed to create project"),l instanceof p?l:yt.isAxiosError(l)?((r=l.response)==null?void 0:r.status)===401?new p("Token is invalid or expired. Run `magicpath-ai login`.",{code:"TOKEN_EXPIRED",suggestion:"Run `magicpath-ai login` to re-authenticate."}):((s=l.response)==null?void 0:s.status)===403?new p("Not allowed to create a project in this workspace.",{code:"FORBIDDEN",suggestion:"Verify you are a member of the team and have permission to create projects."}):new p(`API error: ${(i=l.response)==null?void 0:i.status}`):l}}catch(c){throw t&&A(c),c instanceof p&&(console.error(`
|
|
148
|
-
${c.message}`),process.exit(1)),c}})}var hr=gr(fr(import.meta.url)),wr=JSON.parse(pr(ur(hr,"..","package.json"),"utf8"));Ct(wr.version);vt();process.argv.length<=2&&(Xt(J),process.exit(0));N.name("magicpath").description("").version(J).option("-o, --output <format>","Output format: json").hook("preAction",e=>{e.optsWithGlobals().output==="json"&&$t(!0)});mo(N);xo(N);vo(N);Co(N);jo(N);Eo(N);Ao(N);Po(N);To(N);No(N);ko(N);Ro(N);Mo(N);Uo(N);Do(N);Lo(N);Wo(N);Go(N);Yo(N);tn(N);nn(N);N.parse();
|
|
96
|
+
\u{1F4D6} More help: https://www.jetbrains.com/help/webstorm/working-with-the-ide-features-from-command-line.html`};throw new d(i[t])}}function tr(e){let t=process.platform,n;switch(t){case"darwin":n="open";break;case"win32":n="explorer";break;default:n="xdg-open";break}let s={darwin:"Finder",win32:"File Explorer",linux:"File Manager"}[t]||"File Manager",r=Qo(`\u{1F4C1} Opening project in ${s}...`).start();try{Ko(`${n} "${e}"`,{stdio:"ignore"}),r.succeed(`Project opened in ${s}!`)}catch{throw r.fail(`Failed to open ${s}`),new d(`Failed to open project in ${s}. The file manager may not be available.`)}}var ci=me.object({key:me.string(),debug:me.boolean().default(!1),ide:me.enum(["cursor","antigravity","vscode","webstorm"]).optional(),dir:me.string().optional(),name:me.string().optional()});function mi(e){let t=D(e);xt()&&Et(t),console.error(`
|
|
97
|
+
${t.message}`),process.exit(1)}function or(e){let t=new ii("clone");t.description("\u2728 Instantly bring your MagicPath project to your local playground. Edit, remix, and create in your own vibe.").requiredOption("-k, --key <accessKey>","\u{1F511} One-time magic access key to unlock and download your project").option("-d, --debug","Get verbose debug logs in the CLI").option("-i, --ide <ide>","Pre-select IDE to open project in (cursor, antigravity, vscode, webstorm)").option("--dir <directory>","Target directory for non-interactive use").option("--name <projectName>","Project name for non-interactive use").action(async n=>{try{let o;try{o=ci.parse(n)}catch{throw new d("Invalid CLI options for clone command.")}o.debug&&se();let s=xt();s&&(!o.dir||!o.name)&&Et(new Error("In JSON mode, --dir and --name are required for clone.")),S.debug({options:n}),S.debug({options:o});let r,i;if(o.dir&&o.name)r=de.resolve(o.dir),i=o.name,await Nt.ensureDir(r);else{let f=ai.homedir(),v=[{name:"Documents",path:de.join(f,"Documents")},{name:"Desktop",path:de.join(f,"Desktop")},{name:"Downloads",path:de.join(f,"Downloads")}],x=(await Promise.all(v.map(async C=>{try{return await Nt.pathExists(C.path)?C:null}catch{return null}}))).filter(C=>C!==null),R=[{title:`Right here (current folder: ${process.cwd()})`,value:process.cwd()},{title:`Home directory (${f})`,value:f}];x.forEach(C=>{R.push({title:C.name,value:C.path})}),R.push({title:"Other (specify custom path)",value:"custom"});let{targetDir:L}=await ot({type:"select",name:"targetDir",message:"Where should we put your code?",choices:R,initial:0});if(r=L,L==="custom"){let{customPath:C}=await ot({type:"text",name:"customPath",message:"Enter the full path where you want to create your project:",initial:f,validate:N=>{if(!N)return"Please enter a path";try{return de.resolve(N),!0}catch{return"Please enter a valid path"}}});if(!C)throw new d("Project creation cancelled");r=de.resolve(C);try{await Nt.ensureDir(r)}catch{throw new d(`Failed to create or access directory: ${r}`)}}if(!r)throw new d("Download cancelled");if(i=(await ot({type:"text",name:"projectName",message:"What would you like to name your project?",initial:"magicpath-project"})).projectName,!i)throw new d("Project creation cancelled")}let c,a=s?null:nr("\u{1F4E5} Downloading project...").start();try{c=await Yo(o.key),S.debug({filename:c}),a==null||a.succeed("Project downloaded")}catch(f){throw a==null||a.fail("Download failed"),f instanceof d?f:new d("Something went wrong!")}let m=s?null:nr("\u{1F4E6} Unpacking project...").start(),p;try{p=Zo(c,i,r),m==null||m.succeed(`Project unpacked to ${i}`)}catch(f){throw m==null||m.fail("Failed to unpack project"),Tt(c),f instanceof d?f:new d("Something went wrong!")}try{_o(p)}catch(f){throw f instanceof d?f:new d("Something went wrong!")}s&&qo({projectDir:p});let l=[{title:"Cursor",value:"cursor"},{title:"Antigravity",value:"antigravity"},{title:"VS Code",value:"vscode"},{title:"WebStorm",value:"webstorm"},{title:"Open in file manager",value:"filemanager"},{title:"None (just finish)",value:"none"}],y=0;if(o.ide){let f=l.findIndex(v=>v.value===o.ide);f!==-1&&(y=f)}let h=await ot({type:"select",name:"ide",message:"Which IDE would you like to open the project in?",choices:l,initial:y});if(h.ide&&h.ide!=="none")try{h.ide==="filemanager"?tr(p):er(p,h.ide)}catch(f){S.debug({err:f}),f instanceof d?console.log(f.message):console.log("\u26A0\uFE0F Opening failed, but your project is ready!")}console.log(`
|
|
98
|
+
\u{1F389} Done! Your project is ready to go at: ${p}`)}catch(o){mi(o)}}),e.addCommand(t,{hidden:!0})}import{Command as di}from"commander";import{execSync as pi}from"child_process";function rr(e){let t=new di("setup-skills");t.description("Set up MagicPath for AI agents").action(async()=>{console.log("Installing MagicPath skills..."),pi("npx skills add https://github.com/MagicPathAI/agent-skills --skill magicpath -y",{stdio:"inherit"})}),e.addCommand(t,{hidden:!0})}import{Command as li}from"commander";function sr(e){return!!e._hidden}function gi(e){return e.options.filter(t=>!t.hidden)}function ir(e,t){let n=[...t,e.name()].join(" "),o=[],s=e.commands.filter(r=>!sr(r));if(s.length===0){let i=(e.registeredArguments??[]).map(a=>a.required?`<${a.name()}>`:`[${a.name()}]`);o.push(`### \`${[n,...i].join(" ")}\``),o.push(""),o.push(e.description()||e.summary()||"");let c=gi(e);if(c.length>0){o.push("");for(let a of c)o.push(`- \`${a.flags}\` \u2014 ${a.description}`)}return o.push(""),o}o.push(`## \`${n}\``),o.push(""),o.push(e.summary()||e.description()||""),o.push("");for(let r of s)o.push(...ir(r,[...t,e.name()]));return o}function ui(e){let t=["# magicpath-ai CLI Reference","","<!-- Generated by `magicpath-ai docs --format md`. Do not edit by hand. -->","",e.description(),"","All commands emit a JSON envelope: `{ok: true, data, meta}` on stdout (exit 0) or","`{ok: false, error: {code, message, suggestion?}}` on stderr (exit 1). Paginated","commands accept `--limit <n>` and `--cursor <token>` and return `meta.page.nextCursor`.",""];for(let n of e.commands.filter(o=>!sr(o)))t.push(...ir(n,[]));return t.join(`
|
|
99
|
+
`).replace(/\n{3,}/g,`
|
|
100
|
+
|
|
101
|
+
`)}function ar(e){let t=new li("docs");t.description("Print CLI reference documentation"),t.option("--format <format>","Output format (md)","md"),t.action(()=>{process.stdout.write(ui(e)+`
|
|
102
|
+
`),process.exit(0)}),e.addCommand(t,{hidden:!0})}function cr(){let e=new fi;return e.name("magicpath-ai").description('MagicPath CLI \u2014 agent-first interface to MagicPath. Search, inspect, and install UI components ("designs") into apps; create and edit designs on the MagicPath canvas from code; manage projects, themes (design systems), revisions, images, and teams. Every command emits a JSON envelope: {ok: true, data, meta} on stdout, {ok: false, error: {code, message, suggestion}} on stderr. Start with `context` to see auth, teams, open projects, and the current canvas selection.').version(G).addOption(new hi("-o, --output <format>","Deprecated: output is always JSON").hideHelp()).hook("preAction",()=>{it(e.opts())}),Tn(e),Mn(e),Ln(e),Xn(e),eo(e),oo(e),io(e),ao(e),Ro(e),Go(e),Ho(e),zo(e),Bo(e),or(e),rr(e),ar(e),e}var Ci=wi(vi(import.meta.url)),Si=JSON.parse(yi(Ii(Ci,"..","package.json"),"utf8"));$t(Si.version);Dt();var mr=cr();process.argv.length<=2&&(mr.outputHelp(),process.exit(0));mr.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magicpath-ai",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-experimental.0",
|
|
4
4
|
"description": "Node CLI for MagicPath",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"magicpath-ai": "./dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": ">=
|
|
12
|
+
"node": ">=20.0.0"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "rm -rf dist && esbuild src/cli.ts --bundle --minify --platform=node --format=esm --target=node16 --outfile=dist/cli.js --packages=external && chmod +x dist/cli.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"prepublishOnly": "npm run lint",
|
|
21
21
|
"preversion": "npm run lint",
|
|
22
22
|
"version": "npm run format && git add -A src",
|
|
23
|
-
"postversion": "git push && git push --tags"
|
|
23
|
+
"postversion": "git push && git push --tags",
|
|
24
|
+
"test": "vitest run"
|
|
24
25
|
},
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
@@ -47,9 +48,11 @@
|
|
|
47
48
|
"@types/uuid": "^9.0.8",
|
|
48
49
|
"@types/ws": "^8.18.1",
|
|
49
50
|
"esbuild": "^0.28.0",
|
|
51
|
+
"msw": "^2.14.6",
|
|
50
52
|
"prettier": "^3.2.5",
|
|
51
53
|
"typescript": "^5.8.3",
|
|
52
|
-
"typescript-eslint": "^8.32.1"
|
|
54
|
+
"typescript-eslint": "^8.32.1",
|
|
55
|
+
"vitest": "^4.1.8"
|
|
53
56
|
},
|
|
54
57
|
"files": [
|
|
55
58
|
"dist"
|