@manan_joshi/atelier 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +11 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,15 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{execFileSync as un}from"child_process";import{stdin as C,stdout as F}from"process";import{existsSync as x,mkdirSync as dn,readFileSync as ke,writeFileSync as yn}from"fs";import{homedir as bn,platform as wn}from"os";import{dirname as hn,join as p,resolve as pn}from"path";import{Command as Bn}from"commander";import{execFileSync as te}from"child_process";import{chmodSync as Me,existsSync as ne,mkdirSync as Re,readFileSync as Se,rmSync as Gr,writeFileSync as _e}from"fs";import{homedir as Or,platform as Ir}from"os";import{dirname as me,join as oe}from"path";var Xe=oe(Or(),".config","atelier"),z=oe(Xe,"session.json"),S=oe(Xe,"config.json"),ie="dev.atelier.session",Hr="https://atelier.mananjoshi.me/api",qr="Ov23liiscZlMXcJ2RLnd";function le(){return process.env.ATELIER_API_URL??Hr}function Fr(){return process.env.ATELIER_GITHUB_CLIENT_ID??qr}async function Ye(e){let r=e.apiUrl??le(),t=e.clientId??Fr(),n=await Dr(t);await e.onPrompt({verificationUri:n.verification_uri,userCode:n.user_code,expiresIn:n.expires_in});let i=await jr(t,n,e.onPoll),l=await fetch(`${r}/auth/github/exchange`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({githubAccessToken:i})});if(!l.ok)throw new Error(`Atelier API rejected GitHub login (${l.status})`);let a=await l.json();return Vr({apiUrl:r,user:a.user,token:a.token}),{apiUrl:r,user:a.user}}async function Je(){let e=_();if(!e)return;let r=await fetch(`${e.apiUrl}/me`,{headers:{authorization:`Bearer ${e.token}`}});if(!r.ok)return;return{user:(await r.json()).user,apiUrl:e.apiUrl}}function _(){let e=Le();if(!e)return;let r=Er(e);if(!r)return;return{apiUrl:e.apiUrl,user:e.user,token:r}}function b(){return Qe().activeProfile??"personal"}function ae(e){Pr({...Qe(),activeProfile:e})}function We(){let e=Le();if(e?.tokenStorage==="keychain")tt(e.user.id);if(ne(z))Gr(z)}function Le(){if(!ne(z))return;return JSON.parse(Se(z,"utf-8"))}function Qe(){if(!ne(S))return{};return JSON.parse(Se(S,"utf-8"))}function Pr(e){Re(me(S),{recursive:!0}),_e(S,JSON.stringify(e,null,2)+`
4
- `,"utf-8"),Me(S,384)}function Vr(e){Re(me(z),{recursive:!0});let r=Ir()==="darwin",t={apiUrl:e.apiUrl,user:e.user,tokenStorage:r?"keychain":"file",createdAt:new Date().toISOString()};if(r)et(e.user.id,e.token);else t.token=e.token;_e(z,JSON.stringify(t,null,2)+`
5
- `,"utf-8"),Me(z,384)}function Er(e){if(e.tokenStorage==="file")return e.token;return rt(e.user.id)}async function Dr(e){let r=await fetch("https://github.com/login/device/code",{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:e,scope:"read:user user:email"})});if(!r.ok)throw new Error(`GitHub device-code request failed (${r.status})`);return r.json()}async function jr(e,r,t){let n=r.interval,i=Date.now()+r.expires_in*1000;while(Date.now()<i){await nt(n*1000),await t?.("Waiting for GitHub authorization\u2026");let l=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:e,device_code:r.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})});if(!l.ok)throw new Error(`GitHub token polling failed (${l.status})`);let a=await l.json();if(a.access_token)return a.access_token;if(a.error==="authorization_pending")continue;if(a.error==="slow_down"){n+=5;continue}if(a.error==="access_denied")throw new Error("GitHub login was denied");if(a.error==="expired_token")throw new Error("GitHub login code expired");throw new Error(a.error_description??"GitHub login failed")}throw new Error("GitHub login timed out")}function et(e,r){te("security",["add-generic-password","-a",e,"-s",ie,"-w",r,"-U"],{stdio:"ignore"})}function rt(e){try{return te("security",["find-generic-password","-a",e,"-s",ie,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function tt(e){try{te("security",["delete-generic-password","-a",e,"-s",ie],{stdio:"ignore"})}catch{}}function nt(e){return new Promise((r)=>setTimeout(r,e))}async function Ne(){return(await(await h("/profiles")).json()).profiles}async function Ge(e){return(await(await h("/profiles",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:e})})).json()).profile}async function m(e){let r=await h(`/profiles/${encodeURIComponent(e)}`);if(r.status===404)return;return(await r.json()).profile}async function X(){return await(await h("/vault")).json()}async function Oe(e){await h("/vault",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}async function Ie(e){let r=await h(`/profiles/${encodeURIComponent(e)}/key`);if(r.status===404)return;return(await r.json()).profileKey}async function ce(e,r){return(await(await h(`/profiles/${encodeURIComponent(e)}/key`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(r)})).json()).profileKey}async function He(e){return(await(await h(`/profiles/${encodeURIComponent(e)}/configs`)).json()).configs}async function qe(e,r){let t=await h(`/profiles/${encodeURIComponent(e)}/configs/${encodeURIComponent(r)}`);if(t.status===404)return;return(await t.json()).config}async function Fe(e,r,t){return await(await h(`/profiles/${encodeURIComponent(e)}/configs/${encodeURIComponent(r)}/versions`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})).json()}async function h(e,r={}){let t=_();if(!t)throw new Error("Not logged in. Run `atl login`.");let n=await fetch(`${t.apiUrl}${e}`,{...r,headers:{...r.headers,authorization:`Bearer ${t.token}`}});if(!n.ok&&n.status!==404){let i=await n.json().catch(()=>{return});throw new Error(i?.error??`Atelier API request failed (${n.status})`)}return n}import{createCipheriv as $t,createHash as At,randomBytes as Ct}from"crypto";import{readFile as xt}from"fs/promises";import{execFileSync as ue}from"child_process";import{createCipheriv as ot,createDecipheriv as it,randomBytes as Y,scryptSync as lt}from"crypto";import{chmodSync as at,existsSync as Ve,mkdirSync as ct,readFileSync as ft,rmSync as gt,writeFileSync as st}from"fs";import{homedir as ut,platform as de}from"os";import{dirname as dt,join as Ee}from"path";var ye="dev.atelier.vault",yt=Ee(ut(),".config","atelier"),K=Ee(yt,"vault-key.json"),Pe={N:32768,r:8,p:1},bt=67108864,fe="aes-256-gcm";async function be(){let e=U();return{initialized:(await X()).initialized,unlocked:Boolean(se(e.user.id)),activeProfile:b()}}async function we(e,r=b()){ht(e);let t=U();if((await X()).initialized)throw new Error("Atelier vault already exists. Run `atl vault unlock` if this machine is locked.");let i=await m(r);if(!i)throw new Error(`Profile not found: ${r}`);let l=Y(32),a=Y(32),d=Y(16),ee=tr(e,d,Pe),re=ge(l,ee),R=ge(a,l);return await Oe({kdf:{algorithm:"scrypt",salt:N(d),params:Pe},encryptedVaultKey:re}),await ce(r,{version:1,algorithm:R.algorithm,nonce:R.nonce,encryptedKey:R.ciphertext}),he(t.user.id,l),{profileName:i.name}}async function De(e){let r=U(),t=await X();if(!t.initialized)throw new Error("Atelier vault is not initialized. Run `atl save <id>` or `atl vault init`.");let n=rr(t,e);return he(r.user.id,n),{activeProfile:b()}}function je(){let e=U();pt(e.user.id)}async function wt(e,r=b()){let t=U(),n=se(t.user.id);if(n)return n;if(!e)throw new Error("Vault passphrase is required");let i=await X();if(!i.initialized){await we(e,r);let l=se(t.user.id);if(!l)throw new Error("Vault initialized but local key was not stored");return l}return rr(i,e)}async function er(e,r=b()){let t=await wt(e,r),n=await Ie(r);if(n)return nr(n.encryptedKey,n.nonce,t);let i=Y(32),l=ge(i,t);return await ce(r,{version:1,algorithm:l.algorithm,nonce:l.nonce,encryptedKey:l.ciphertext}),i}function rr(e,r){if(!e.kdf||!e.encryptedVaultKey)throw new Error("Vault payload is incomplete");if(e.kdf.algorithm!=="scrypt")throw new Error(`Unsupported vault KDF: ${e.kdf.algorithm}`);let t=G(e.kdf.salt),n=tr(r,t,e.kdf.params),i=nr(e.encryptedVaultKey.ciphertext,e.encryptedVaultKey.nonce,n);return he(U().user.id,i),i}function tr(e,r,t){return lt(e,r,32,{N:t.N,r:t.r,p:t.p,maxmem:bt})}function ge(e,r){let t=Y(12),n=ot(fe,r,t),i=Buffer.concat([n.update(e),n.final()]),l=n.getAuthTag();return{algorithm:fe,nonce:N(t),ciphertext:N(Buffer.concat([i,l]))}}function nr(e,r,t){let n=Buffer.from(G(e)),i=Buffer.from(G(r)),l=n.subarray(0,-16),a=n.subarray(-16),d=it(fe,t,i);return d.setAuthTag(a),Buffer.concat([d.update(l),d.final()])}function ht(e){if(e.length<12)throw new Error("Vault passphrase must be at least 12 characters.")}function U(){let e=_();if(!e)throw new Error("Not logged in. Run `atl login`.");return e}function he(e,r){let t=N(r);if(de()==="darwin"){ue("security",["add-generic-password","-a",e,"-s",ye,"-w",t,"-U"],{stdio:"ignore"});return}ct(dt(K),{recursive:!0}),st(K,JSON.stringify({userId:e,key:t},null,2)+`
6
- `,"utf-8"),at(K,384)}function se(e){let r=de()==="darwin"?Bt(e):zt(e);return r?Buffer.from(G(r)):void 0}function pt(e){if(de()==="darwin"){try{ue("security",["delete-generic-password","-a",e,"-s",ye],{stdio:"ignore"})}catch{}return}if(Ve(K))gt(K)}function Bt(e){try{return ue("security",["find-generic-password","-a",e,"-s",ye,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function zt(e){if(!Ve(K))return;let r=JSON.parse(ft(K,"utf-8"));return r.userId===e?r.key:void 0}function N(e){return Buffer.from(e).toString("base64url")}function G(e){return new Uint8Array(Buffer.from(e,"base64url"))}function or(e){let r=[];if(!e.exists)r.push("file does not exist");if(e.isDirectory||e.kind==="directory"||e.format==="directory")r.push("directory saving is not supported yet");if(e.kind==="generated")r.push("generated/cache files are not saved");if(e.kind==="private"||e.shareability==="private")r.push("private/auth files are blocked");if(e.secretFindings.length>0)r.push("detected secret material");if(e.size!==void 0&&e.size>1048576)r.push(`file is larger than ${Tt(1048576)}`);if(Kt(e))r.push("binary files are not supported yet");return{ok:r.length===0,reasons:r}}function pe(e){let r=or(e);if(!r.ok)throw new Error(`Cannot save ${e.id}: ${r.reasons.join("; ")}`)}function Kt(e){if(e.previewSuppressedReason?.toLowerCase().includes("binary"))return!0;return["binary","sqlite","db"].includes(e.format.toLowerCase())}function Tt(e){if(e<1024)return`${e} B`;let r=e/1024;if(r<1024)return`${Math.round(r)} KiB`;return`${Math.round(r/1024)} MiB`}var ir="aes-256-gcm";async function cr(e,r={}){pe(e);let t=b(),n=await er(r.passphrase,t),i=await xt(e.path),l=vt(i,n),a=await Fe(t,e.id,{kind:"file",pathHint:e.displayPath,contentSha256:lr(i),ciphertextSha256:lr(l.ciphertextBytes),sizeBytes:i.byteLength,algorithm:l.algorithm,profileKeyVersion:1,nonce:l.nonce,ciphertext:l.ciphertext});return{profileName:t,stableId:e.id,version:a.version,reused:a.reused}}function vt(e,r){let t=Ct(12),n=$t(ir,r,t),i=Buffer.concat([n.update(e),n.final()]),l=n.getAuthTag(),a=Buffer.concat([i,l]);return{algorithm:ir,nonce:ar(t),ciphertext:ar(a),ciphertextBytes:a}}function lr(e){return At("sha256").update(e).digest("hex")}function ar(e){return Buffer.from(e).toString("base64url")}import{execFileSync as wr}from"child_process";import{existsSync as $,lstatSync as Mt,mkdirSync as Rt,readdirSync as Ke,readFileSync as J,statSync as k,writeFileSync as St}from"fs";import{homedir as _t,userInfo as mt}from"os";import{dirname as hr,join as T,relative as pr,resolve as Xt}from"path";var fr=[{domain:"AI Tools",app:"Pi",items:[{id:"pi.dir",path:"~/.pi",kind:"directory",format:"directory",shareability:"machine-specific"}]},{domain:"Shell",app:"Starship",items:[{id:"starship.config",path:"~/.config/starship.toml",kind:"config",format:"toml",shareability:"shareable"}]},{domain:"Editors",app:"Zed",items:[{id:"zed.dir",path:"~/.config/zed",kind:"directory",format:"directory",shareability:"shareable"},{id:"zed.settings",path:"~/.config/zed/settings.json",kind:"config",format:"jsonc",shareability:"shareable"},{id:"zed.themes",path:"~/.config/zed/themes",kind:"config",format:"directory",shareability:"shareable"},{id:"zed.prompts",path:"~/.config/zed/prompts",kind:"generated",format:"directory",shareability:"machine-specific"}]},{domain:"Git",app:"Git",items:[{id:"git.config",path:"~/.gitconfig",kind:"config",format:"gitconfig",shareability:"machine-specific"},{id:"git.config-dir",path:"~/.config/git",kind:"directory",format:"directory",shareability:"machine-specific"},{id:"git.ignore",path:"~/.gitignore",kind:"config",format:"gitignore",shareability:"machine-specific"}]},{domain:"Private/Auth",app:"Credentials",privateByDefault:!0,items:[{id:"auth.ssh",path:"~/.ssh",kind:"private",format:"directory",shareability:"private"},{id:"auth.aws",path:"~/.aws",kind:"private",format:"directory",shareability:"private"},{id:"auth.gh",path:"~/.config/gh",kind:"private",format:"directory",shareability:"private"},{id:"auth.gcloud-adc",path:"~/.config/gcloud/application_default_credentials.json",kind:"private",format:"json",shareability:"private"},{id:"auth.docker",path:"~/.docker/config.json",kind:"private",format:"json",shareability:"private"},{id:"auth.pi",path:"~/.config/pi/auth.json",kind:"private",format:"json",shareability:"private"}]},{domain:"Shell",app:"Zsh",items:[{id:"zsh.home-rc",path:"~/.zshrc",kind:"config",format:"shell",shareability:"shareable"},{id:"zsh.home-env",path:"~/.zshenv",kind:"config",format:"shell",shareability:"private"},{id:"zsh.dir",path:"~/.config/zsh",kind:"directory",format:"directory",shareability:"machine-specific"},{id:"zsh.env",path:"~/.config/zsh/.zshenv",kind:"config",format:"shell",shareability:"private"},{id:"zsh.rc",path:"~/.config/zsh/.zshrc",kind:"config",format:"shell",shareability:"shareable"},{id:"zsh.conf",path:"~/.config/zsh/conf.d",kind:"directory",format:"directory",shareability:"shareable"},{id:"zsh.zcompdump",path:"~/.config/zsh/.zcompdump",kind:"generated",format:"text",shareability:"machine-specific"},{id:"zsh.sessions",path:"~/.config/zsh/.zsh_sessions",kind:"generated",format:"directory",shareability:"machine-specific"}]},{domain:"Terminals",app:"cmux",items:[{id:"cmux.dir",path:"~/.config/cmux",kind:"directory",format:"directory",shareability:"shareable"},{id:"cmux.config",path:"~/.config/cmux/cmux.json",kind:"config",format:"jsonc",shareability:"shareable"},{id:"cmux.ghostty",path:"~/Library/Application Support/com.cmuxterm.app/config.ghostty",kind:"config",format:"ghostty",shareability:"shareable"},{id:"cmux.browser-history",path:"~/Library/Application Support/com.cmuxterm.app/browser_history.json",kind:"generated",format:"json",shareability:"machine-specific"}]}];var Be=[["GitHub token",/gh[pousr]_[A-Za-z0-9_]{20,}/g],["Slack token",/xox[baprs]-[A-Za-z0-9-]{20,}/g],["AWS access key",/AKIA[0-9A-Z]{16}/g],["Private key",/-----BEGIN (?:RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----/g],["Generic token assignment",/(?:token|api[_-]?key|secret|webhook|password)\s*[=:]\s*["']?[^"'\s]{12,}/gi]];function gr(e){let r=[],t=e.split(/\r?\n/);for(let[n,i]of Be)for(let l of e.matchAll(i)){let a=l.index??0,d=e.slice(0,a).split(/\r?\n/).length;r.push({type:n,line:d,preview:O(l[0])})}return t.forEach((n,i)=>{for(let l of n.matchAll(/[A-Za-z0-9_+\/=.-]{32,}/g)){let a=l[0];if(!Ut(a,n)&&ur(a,n))r.push({type:"High-entropy string",line:i+1,preview:O(a)})}}),Zt(r)}function O(e){if(e.length<=8)return"[redacted]";return`${e.slice(0,4)}\u2026${e.slice(-4)}`}function sr(e){let r=e;for(let[,t]of Be)r=r.replace(t,(n)=>O(n));return r=r.replace(/[A-Za-z0-9_+\/=.-]{32,}/g,(t)=>{if(ur(t,e))return O(t);return t}),r}function Ut(e,r){return Be.some(([,t])=>{return t.lastIndex=0,Array.from(r.matchAll(t)).some((n)=>n[0].includes(e)||e.includes(n[0]))})}function ur(e,r){if(e.startsWith("amazon."))return!1;if(e.includes("anthropic.claude"))return!1;if(/^[A-Za-z0-9.-]+@[A-Za-z0-9.-]+$/.test(e))return!1;if(/model/i.test(r)&&/^[A-Za-z0-9_.-]+$/.test(e))return!1;return kt(e)>4.2&&/[A-Za-z]/.test(e)&&/[0-9]/.test(e)}function kt(e){let r=new Map;for(let n of e)r.set(n,(r.get(n)??0)+1);let t=0;for(let n of r.values()){let i=n/e.length;t-=i*Math.log2(i)}return t}function Zt(e){let r=new Set;return e.filter((t)=>{let n=`${t.type}:${t.line}:${t.preview}`;if(r.has(n))return!1;return r.add(n),!0})}function dr(e){let n=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1").replace(/,\s*([}\]])/g,"$1");return JSON.parse(n)}var A=_t(),Yt=new Set([".zsh",".zshrc",".zshenv",".sh",".json",".jsonc",".toml",".md",".yml",".yaml",".gitconfig",".gitignore",".ghostty",""]),Jt=[/cache/i,/history/i,/session/i,/state/i,/\.mdb$/i,/\.sqlite/i,/\.db$/i,/zcompdump/i,/logs?/i],Wt=[/credential/i,/secret/i,/token/i,/auth\.json$/i,/hosts\.yml$/i,/config\.json$/i],H;async function Te(e){H=e.includeLegacyManagers?Et():void 0;let t=Lt(e.repoRoot).flatMap((l)=>l.items.map((a)=>({definition:l,item:a}))),n=new Set,i=[];for(let{definition:l,item:a}of t){let d=ze(a.path);n.add(d),i.push(Qt(l,a,d))}for(let l of Nt()){if(n.has(l.path))continue;n.add(l.path),i.push(yr(l))}for(let l of e.manualPaths??[]){let a=ze(l);if(n.has(a))continue;n.add(a),i.push(yr({path:a,reason:"manual path"}))}return i.sort((l,a)=>`${l.domain}:${l.app}:${l.path}`.localeCompare(`${a.domain}:${a.app}:${a.path}`)),{version:1,generatedAt:new Date().toISOString(),repoRoot:e.repoRoot,home:A,items:i,summary:{total:i.length,existing:i.filter((l)=>l.exists).length,secrets:i.filter((l)=>l.secretFindings.length>0).length,drift:i.filter((l)=>l.mirrors.some((a)=>a.exists&&a.identical===!1)).length,generated:i.filter((l)=>l.kind==="generated").length,private:i.filter((l)=>l.shareability==="private").length}}}function $e(e,r={}){let t=r.path??T(e.repoRoot,".atelier","state","inventory.json");return Rt(hr(t),{recursive:!0}),St(t,JSON.stringify(e,null,2)+`
7
- `,"utf-8"),t}function Lt(e){let r=T(e,"packages","registry","definitions");if(!$(r))return fr;return Ke(r).filter((t)=>t.endsWith(".jsonc")).map((t)=>dr(J(T(r,t),"utf-8")))}function Qt(e,r,t){return Br({path:t,domain:e.domain,app:e.app,kind:r.kind,format:r.format,shareability:r.shareability,reason:"registry match",mirrors:r.mirrors??[],privateByDefault:e.privateByDefault,id:r.id})}function yr(e){let r=jt(e.path),t=rn(e.path),n=tn(e.path,t);return Br({path:e.path,domain:en(e.path),app:r,kind:t,format:nn(e.path),shareability:n,reason:e.reason,mirrors:[],privateByDefault:n==="private"})}function Br(e){let r=$(e.path),t=r?Mt(e.path):void 0,n=r?k(e.path):void 0,i=!!n?.isDirectory(),l=!!t?.isSymbolicLink(),a=r&&!i&&zr(e.path)?gr(J(e.path,"utf-8")):[],d=e.mirrors.map((R)=>Ot(e.path,ze(R))),ee=qt(e.kind,e.shareability,a.length,d),re=Ht(e.path,r,i,e.shareability,e.privateByDefault,e.kind);return{id:e.id??Dt(e.path),domain:e.domain,app:e.app,path:e.path,displayPath:W(e.path),kind:e.kind,format:e.format,shareability:e.shareability,exists:r,isDirectory:i,isSymlink:l,mode:n?`0${(n.mode&511).toString(8)}`:void 0,owner:r?mt().username:void 0,size:n?.size,git:r?Ft(e.path):void 0,legacyManagers:r?Pt(e.path):{},mirrors:d,secretFindings:a,...re,recommendation:ee,reason:e.reason}}function Nt(){let e=[],r=T(A,".config");if(!$(r))return e;for(let t of Ke(r,{withFileTypes:!0})){if(t.name.startsWith("."))continue;let n=T(r,t.name);if(e.push({path:n,reason:"~/.config app directory"}),!t.isDirectory())continue;for(let i of Gt(n).slice(0,80)){let l=T(n,i.name);if(Ae(l)){e.push({path:l,reason:"generated/app-state candidate"});continue}if(i.isFile()&&Ce(i.name))e.push({path:l,reason:"shallow ~/.config config candidate"});if(i.isDirectory()&&["conf.d","themes","snippets","plugins"].includes(i.name))e.push({path:l,reason:"shallow ~/.config config directory"})}}return e}function Gt(e){try{return Ke(e,{withFileTypes:!0})}catch{return[]}}function Ot(e,r){let t=$(r);if(!t||!$(e)||k(e).isDirectory()||k(r).isDirectory())return{path:r,displayPath:W(r),exists:t};let n=J(e,"utf-8"),i=J(r,"utf-8");return{path:r,displayPath:W(r),exists:t,identical:n===i,diff:n===i?void 0:It(i,n)}}function It(e,r){let t=e.split(/\r?\n/),n=r.split(/\r?\n/),i=Math.max(t.length,n.length),l=[];for(let a=0;a<i;a++){if(t[a]===n[a])continue;if(t[a]!==void 0)l.push(`-${t[a]}`);if(n[a]!==void 0)l.push(`+${n[a]}`)}return l.slice(0,200).join(`
8
- `)}function Ht(e,r,t,n,i,l){if(!r)return{previewSuppressedReason:"missing"};if(t)return{previewSuppressedReason:"directory"};if(n==="private"||i||l==="private")return{previewSuppressedReason:"private/auth metadata-only"};if(!zr(e))return{previewSuppressedReason:"binary or unsupported file type"};let a=J(e,"utf-8");return{preview:sr(a).slice(0,20000)}}function qt(e,r,t,n){if(t>0)return"rotate-secret";if(e==="generated")return"ignore-generated";if(r==="private")return"mark-private";if(n.some((i)=>i.exists&&i.identical===!1))return"resolve-drift";if(r==="machine-specific")return"review-machine-specific";if(e==="config"||e==="directory")return"adopt-candidate";return"none"}function Ft(e){let r=k(e).isDirectory()?e:hr(e),t=I(["rev-parse","--show-toplevel"],r);if(!t)return;let n=pr(t,e),i=!!I(["check-ignore","-q",n],t,!0),l=!!I(["ls-files","--error-unmatch",n],t,!0),a=l&&!!I(["status","--porcelain","--",n],t);return{root:t,tracked:l,modified:a,ignored:i}}function Pt(e){if(!H)return{};return{yadm:Vt(e)}}function Vt(e){let r=W(e).replace(/^~\//,"");if(H?.modified.has(r))return"modified";if(H?.tracked.has(r))return"tracked";return"unknown"}function Et(){let e=new Set((br("yadm",["ls-files"])??"").split(`
9
- `).filter(Boolean)),r=new Set((br("yadm",["status","--porcelain"])??"").split(`
10
- `).map((t)=>t.slice(3).trim()).filter(Boolean));return{tracked:e,modified:r}}function I(e,r,t=!1){try{return wr("git",e,{cwd:r,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||(t?"ok":void 0)}catch{return}}function br(e,r){try{return wr(e,r,{cwd:A,encoding:"utf-8",stdio:["ignore","pipe","ignore"]})}catch{return}}function ze(e){return Xt(e.replace(/^~(?=\/|$)/,A))}function W(e){return e.startsWith(A)?`~${e.slice(A.length)}`:e}function Dt(e){return W(e).replace(/[^A-Za-z0-9_.-]+/g,":")}function jt(e){let r=pr(T(A,".config"),e);if(!r.startsWith(".."))return r.split(/[\\/]/)[0]||"Unknown";return"Unknown"}function en(e){if(e.includes("/.config/"))return"~/.config";if(e.includes("/.ssh")||e.includes("/.aws"))return"Private/Auth";return"Unknown"}function rn(e){if(Ae(e))return"generated";if(Wt.some((r)=>r.test(e)))return"private";if($(e)&&k(e).isDirectory())return"directory";if(Ce(e))return"config";return"unknown"}function tn(e,r){if(r==="private")return"private";if(r==="generated")return"machine-specific";if(e.includes("/credentials")||e.includes("/.ssh")||e.includes("/.aws"))return"private";return"machine-specific"}function nn(e){if($(e)&&k(e).isDirectory())return"directory";if(e.endsWith(".jsonc"))return"jsonc";if(e.endsWith(".json"))return"json";if(e.endsWith(".toml"))return"toml";if(e.endsWith(".zsh"))return"shell";if(e.endsWith(".md"))return"markdown";return"text"}function Ae(e){return Jt.some((r)=>r.test(e))}function Ce(e){return/(^config\.|settings\.|rc$|\.rc$|\.zshrc$|\.zshenv$|\.jsonc?$|\.toml$|\.ya?ml$|\.zsh$|\.conf$|\.ini$)/i.test(e)}function zr(e){let r=e.split("/").pop()??"";if(Ae(e))return!1;if(r.includes("lock")||r.endsWith(".mdb")||r.endsWith(".sqlite")||r.endsWith(".db"))return!1;let t=r.includes(".")?r.slice(r.lastIndexOf(".")):"";return Yt.has(t)||Ce(r)}import{Box as f,Text as c,render as on}from"ink";import{jsxDEV as o,Fragment as sn}from"react/jsx-dev-runtime";function g(e){return on(o(sn,{children:e},void 0,!1,void 0,this)).waitUntilExit()}function xe({inventory:e,path:r}){return o(f,{flexDirection:"column",gap:1,children:[o(y,{title:"Scan complete",subtitle:r},void 0,!1,void 0,this),o(f,{gap:2,children:[o(Z,{label:"total",value:e.summary.total,color:"cyan"},void 0,!1,void 0,this),o(Z,{label:"existing",value:e.summary.existing,color:"green"},void 0,!1,void 0,this),o(Z,{label:"private",value:e.summary.private,color:"red"},void 0,!1,void 0,this),o(Z,{label:"generated",value:e.summary.generated,color:"magenta"},void 0,!1,void 0,this),o(Z,{label:"secrets",value:e.summary.secrets,color:"red"},void 0,!1,void 0,this),o(Z,{label:"drift",value:e.summary.drift,color:"blue"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Kr({items:e,title:r}){return o(f,{flexDirection:"column",children:[o(y,{title:r,subtitle:`${e.length} item${e.length===1?"":"s"}`},void 0,!1,void 0,this),o(f,{flexDirection:"column",marginTop:1,children:e.map((t)=>o(f,{gap:1,children:[o(c,{color:t.exists?"white":"gray",children:t.exists?"\u25CF":"\u25CB"},void 0,!1,void 0,this),o(c,{color:_r(t),children:t.domain},void 0,!1,void 0,this),o(c,{color:"gray",children:"/"},void 0,!1,void 0,this),o(c,{color:"cyan",children:t.app},void 0,!1,void 0,this),o(c,{children:t.displayPath},void 0,!1,void 0,this),o(B,{label:t.shareability,color:mr(t.shareability)},void 0,!1,void 0,this),t.secretFindings.length>0?o(B,{label:"secret",color:"red"},void 0,!1,void 0,this):null,t.mirrors.some((n)=>n.exists&&n.identical===!1)?o(B,{label:"drift",color:"blue"},void 0,!1,void 0,this):null]},t.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Tr({item:e}){return o(f,{flexDirection:"column",gap:1,children:[o(y,{title:e.app,subtitle:e.displayPath},void 0,!1,void 0,this),o(f,{gap:1,children:[o(B,{label:e.domain,color:"cyan"},void 0,!1,void 0,this),o(B,{label:e.kind,color:_r(e)},void 0,!1,void 0,this),o(B,{label:e.shareability,color:mr(e.shareability)},void 0,!1,void 0,this),o(B,{label:e.recommendation,color:"yellow"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(ln,{rows:[["reason",e.reason],["exists",String(e.exists)],["mode",e.mode??"\u2014"],["symlink",String(e.isSymlink)],["git",gn(e)],["legacy",fn(e)]]},void 0,!1,void 0,this),e.secretFindings.length>0?o(f,{flexDirection:"column",children:[o(c,{color:"red",bold:!0,children:"Secret warnings"},void 0,!1,void 0,this),e.secretFindings.map((r,t)=>o(c,{color:"red",children:[" ",r.type,r.line?` line ${r.line}`:"",": ",r.preview]},`${r.type}-${t}`,!0,void 0,this))]},void 0,!0,void 0,this):null,e.mirrors.length>0?o(f,{flexDirection:"column",children:[o(c,{color:"blue",bold:!0,children:"Mirrors"},void 0,!1,void 0,this),e.mirrors.map((r)=>o(c,{children:[" ",r.displayPath," \u2014 ",r.exists?r.identical===!1?"differs":"identical":"missing"]},r.path,!0,void 0,this))]},void 0,!0,void 0,this):null,o(f,{flexDirection:"column",children:[o(c,{bold:!0,children:e.preview?"Safe preview":"Preview"},void 0,!1,void 0,this),o(c,{color:e.preview?"white":"gray",children:e.preview?e.preview.slice(0,3000):`Suppressed: ${e.previewSuppressedReason??"not available"}`},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function $r({decisions:e}){return o(f,{flexDirection:"column",children:[o(y,{title:"Decisions",subtitle:`${e.length} saved`},void 0,!1,void 0,this),o(f,{flexDirection:"column",marginTop:1,children:e.length===0?o(c,{color:"gray",children:"No decisions recorded yet."},void 0,!1,void 0,this):e.map((r)=>o(f,{gap:1,children:[o(B,{label:r.status,color:"cyan"},void 0,!1,void 0,this),o(c,{children:r.itemId},void 0,!1,void 0,this),o(c,{color:"gray",children:r.updatedAt},void 0,!1,void 0,this)]},`${r.itemId}-${r.updatedAt}`,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Ar({verificationUri:e,userCode:r,expiresIn:t}){return o(f,{flexDirection:"column",gap:1,children:[o(y,{title:"Login with GitHub",subtitle:`code expires in ${Math.round(t/60)} minutes`},void 0,!1,void 0,this),o(f,{flexDirection:"column",children:[o(c,{children:"Open:"},void 0,!1,void 0,this),o(c,{color:"blue",underline:!0,children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(f,{gap:1,children:[o(c,{children:"Enter code:"},void 0,!1,void 0,this),o(c,{color:"green",bold:!0,children:r},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Cr({login:e,apiUrl:r}){return o(f,{flexDirection:"column",children:[o(y,{title:"Logged in",subtitle:r},void 0,!1,void 0,this),o(c,{color:"green",children:["\u2713 ",e]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function xr({login:e,apiUrl:r}){if(!e)return o(c,{color:"yellow",children:"Not logged in. Run `atl login`."},void 0,!1,void 0,this);return o(f,{flexDirection:"column",children:[o(y,{title:"Current account",subtitle:r},void 0,!1,void 0,this),o(c,{color:"green",children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function vr(){return o(c,{color:"green",children:"\u2713 Logged out"},void 0,!1,void 0,this)}function Ur({profiles:e,activeProfile:r}){return o(f,{flexDirection:"column",children:[o(y,{title:"Profiles",subtitle:`active: ${r}`},void 0,!1,void 0,this),o(f,{flexDirection:"column",marginTop:1,children:e.map((t)=>o(f,{gap:1,children:[o(c,{color:t.name===r?"green":"gray",children:t.name===r?"\u25CF":"\u25CB"},void 0,!1,void 0,this),o(c,{bold:t.name===r,children:t.name},void 0,!1,void 0,this),o(c,{color:"gray",children:t.createdAt},void 0,!1,void 0,this)]},t.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function L({title:e,name:r}){return o(f,{flexDirection:"column",children:[o(y,{title:e},void 0,!1,void 0,this),o(c,{color:"green",children:["\u2713 ",r]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function kr({configs:e,profileName:r}){return o(f,{flexDirection:"column",children:[o(y,{title:"Saved configs",subtitle:r},void 0,!1,void 0,this),e.length===0?o(c,{color:"gray",children:"No saved configs yet."},void 0,!1,void 0,this):e.map((t)=>o(f,{flexDirection:"column",marginTop:1,children:[o(c,{bold:!0,children:t.stableId},void 0,!1,void 0,this),o(c,{color:"gray",children:t.pathHint??"no path hint"},void 0,!1,void 0,this),t.latestVersion?o(c,{color:"green",children:[t.latestVersion.contentSha256.slice(0,12)," \xB7 ",t.latestVersion.sizeBytes," bytes \xB7 ",t.latestVersion.createdAt]},void 0,!0,void 0,this):null]},t.id,!0,void 0,this))]},void 0,!0,void 0,this)}function Zr({config:e,profileName:r}){return o(f,{flexDirection:"column",children:[o(y,{title:e.stableId,subtitle:r},void 0,!1,void 0,this),o(c,{color:"gray",children:e.pathHint??"no path hint"},void 0,!1,void 0,this),o(f,{flexDirection:"column",marginTop:1,children:(e.versions??[]).map((t)=>o(c,{children:[t.contentSha256.slice(0,12)," \xB7 ",t.sizeBytes," bytes \xB7 ",t.createdAt]},t.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Mr({stableId:e,profileName:r,versionHash:t,sizeBytes:n,reused:i}){return o(f,{flexDirection:"column",children:[o(y,{title:i?"Config already saved":"Config saved",subtitle:r},void 0,!1,void 0,this),o(c,{color:"green",children:["\u2713 ",e]},void 0,!0,void 0,this),o(c,{color:"gray",children:["Version ",t.slice(0,12)," \xB7 ",n," bytes \xB7 encrypted"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Rr({item:e,status:r}){return o(f,{flexDirection:"column",children:[o(y,{title:"Decision saved",subtitle:e.displayPath},void 0,!1,void 0,this),o(f,{gap:1,children:[o(c,{children:"Status:"},void 0,!1,void 0,this),o(B,{label:r,color:"green"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Sr({checks:e}){let r=e.filter((n)=>n.status==="fail").length,t=e.filter((n)=>n.status==="warn").length;return o(f,{flexDirection:"column",gap:1,children:[o(y,{title:"Doctor",subtitle:r?`${r} failing`:t?`${t} warning${t===1?"":"s"}`:"all checks passed"},void 0,!1,void 0,this),o(f,{flexDirection:"column",children:e.map((n)=>o(f,{gap:1,children:[o(c,{color:cn(n.status),children:an(n.status)},void 0,!1,void 0,this),o(c,{bold:!0,children:n.label},void 0,!1,void 0,this),o(c,{color:"gray",children:n.detail},void 0,!1,void 0,this)]},n.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function q({query:e}){return o(c,{color:"red",children:["No inventory item matched: ",e]},void 0,!0,void 0,this)}function y({title:e,subtitle:r}){return o(f,{flexDirection:"column",children:[o(c,{bold:!0,color:"cyan",children:"\u25C6 Atelier"},void 0,!1,void 0,this),o(f,{gap:1,children:[o(c,{bold:!0,children:e},void 0,!1,void 0,this),r?o(c,{color:"gray",children:r},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Z({label:e,value:r,color:t}){return o(f,{flexDirection:"column",borderStyle:"round",borderColor:t,paddingX:1,children:[o(c,{color:t,bold:!0,children:r},void 0,!1,void 0,this),o(c,{color:"gray",children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function B({label:e,color:r}){return o(c,{color:r,children:["[",e,"]"]},void 0,!0,void 0,this)}function ln({rows:e}){return o(f,{flexDirection:"column",children:e.map(([r,t])=>o(f,{gap:1,children:[o(c,{color:"gray",children:r.padEnd(10)},void 0,!1,void 0,this),o(c,{children:t},void 0,!1,void 0,this)]},r,!0,void 0,this))},void 0,!1,void 0,this)}function _r(e){let r=typeof e==="string"?e:e.kind;if(r==="private")return"red";if(r==="generated")return"magenta";if(r==="config")return"green";return"yellow"}function mr(e){if(e==="private")return"red";if(e==="shareable")return"green";return"yellow"}function an(e){if(e==="pass")return"\u2713";if(e==="warn")return"!";return"\u2717"}function cn(e){if(e==="pass")return"green";if(e==="warn")return"yellow";return"red"}function fn(e){let r=Object.entries(e.legacyManagers??{});if(r.length===0)return"not scanned";return r.map(([t,n])=>`${t}: ${n}`).join(", ")}function gn(e){if(!e.git)return"not in repo";return`${e.git.tracked?"tracked":"untracked"}${e.git.modified?", modified":""} @ ${e.git.root}`}import{jsxDEV as s}from"react/jsx-dev-runtime";var w=pn(import.meta.dir,"../../.."),Jr=zn(),v=p(Jr,"inventory.json"),V=p(Jr,"decisions.json"),ve=new Set(["undecided","candidate","shareable","machine-specific","private","ignored"]),Xr,u=new Bn;u.name("atl").description("Atelier config inventory cockpit").version("0.1.2");u.command("login").description("Login to Atelier with GitHub device auth").option("--api-url <url>","Atelier API URL",le()).action(async(e)=>{let r=await Ye({apiUrl:e.apiUrl,onPrompt:async(t)=>{await g(s(Ar,{verificationUri:t.verificationUri,userCode:t.userCode,expiresIn:t.expiresIn},void 0,!1,void 0,this))}});await g(s(Cr,{login:r.user.login,apiUrl:r.apiUrl},void 0,!1,void 0,this))});u.command("whoami").description("Show the current Atelier account").action(async()=>{let e=await Je();if(await g(s(xr,{login:e?.user.login,apiUrl:e?.apiUrl},void 0,!1,void 0,this)),!e)process.exitCode=1});u.command("logout").description("Remove the local Atelier session").action(async()=>{We(),await g(s(vr,{},void 0,!1,void 0,this))});u.command("api").description("Run the local Atelier API server for development").option("--port <port>","port to bind","8787").action(async(e)=>{await $n(Number(e.port))});var D=u.command("profile").description("Manage account-backed config profiles");D.command("list").description("List remote profiles").action(async()=>{await g(s(Ur,{profiles:await Ne(),activeProfile:b()},void 0,!1,void 0,this))});D.command("create").description("Create a remote profile").argument("<name>").action(async(e)=>{let r=await Ge(e);await g(s(L,{title:"Profile created",name:r.name},void 0,!1,void 0,this))});D.command("switch").description("Set the active local profile after verifying it exists remotely").argument("<name>").action(async(e)=>{let r=await m(e);if(!r)throw new Error(`Profile not found: ${e}`);ae(r.name),await g(s(L,{title:"Active profile",name:r.name},void 0,!1,void 0,this))});D.command("current").description("Show the active local profile").action(async()=>{await g(s(L,{title:"Active profile",name:b()},void 0,!1,void 0,this))});u.command("checkout").description("Alias for `atl profile switch`").argument("<name>").action(async(e)=>{let r=await m(e);if(!r)throw new Error(`Profile not found: ${e}`);ae(r.name),await g(s(L,{title:"Active profile",name:r.name},void 0,!1,void 0,this))});var j=u.command("vault").description("Advanced vault controls");j.command("status").description("Show vault initialization and local unlock state").action(async()=>{let e=await be();console.log(`Vault: ${e.initialized?"initialized":"not initialized"}`),console.log(`Local state: ${e.unlocked?"unlocked":"locked"}`),console.log(`Active profile: ${e.activeProfile}`)});j.command("init").description("Initialize the encrypted vault now instead of waiting for first save").action(async()=>{let e=await Nr("Create an Atelier vault passphrase: "),r=await we(e);console.log(`Vault initialized for profile ${r.profileName}`)});j.command("unlock").description("Unlock this machine with the vault passphrase").action(async()=>{let e=await E("Vault passphrase: "),r=await De(e);console.log(`Vault unlocked for profile ${r.activeProfile}`)});j.command("lock").description("Remove local unlocked vault material from this machine").action(async()=>{je(),console.log("Vault locked")});u.command("save").description("Save a config snapshot to the active encrypted profile").argument("<id-or-path>").action(async(e)=>{await Qr(e)});u.command("adopt").description("Alias for `atl save`").argument("<id-or-path>").action(async(e)=>{await Qr(e)});var Wr=u.command("saved").description("Inspect encrypted configs saved remotely");Wr.command("list").description("List saved configs for the active profile").action(async()=>{let e=b();await g(s(kr,{configs:await He(e),profileName:e},void 0,!1,void 0,this))});Wr.command("show").description("Show saved metadata and version history").argument("<stable-id>").action(async(e)=>{let r=b(),t=await qe(r,e);if(!t)throw new Error(`Saved config not found: ${e}`);await g(s(Zr,{config:t,profileName:r},void 0,!1,void 0,this))});u.command("scan").description("Scan this machine and write local inventory").option("--path <path...>","additional manual path(s) to scan").option("--legacy","include legacy manager signals like yadm").action(async(e)=>{let r=await Te({repoRoot:w,manualPaths:e.path??[],includeLegacyManagers:e.legacy}),t=$e(r,{path:v});await g(s(xe,{inventory:r,path:t},void 0,!1,void 0,this))});u.command("ui").description("Open the local TanStack Start inventory UI").option("--scan","rescan before opening the UI").option("--path <path...>","additional manual path(s) to scan").option("--legacy","include legacy manager signals like yadm during scan").option("--port <port>","port to bind","4141").action(async(e)=>{if(!x(v)||e.scan){console.log("Atelier: scanning configs\u2026");let r=await Te({repoRoot:w,manualPaths:e.path??[],includeLegacyManagers:e.legacy});$e(r,{path:v}),console.log(`Atelier: scan complete (${r.summary.existing}/${r.summary.total} existing)`)}console.log("Atelier: starting UI\u2026"),await An(Number(e.port))});u.command("list").description("List inventory items with polished terminal output").option("--domain <domain>","filter by domain").option("--app <app>","filter by app").option("--secrets","only items with secret warnings").option("--drift","only items with mirror drift").option("--generated","only generated/app-state items").option("--private","only private items").option("--missing","only missing registry items").option("--json","print JSON instead of Ink output").action(async(e)=>{let r=M(),t=Kn(r.items,e);if(e.json)return Q(t);await g(s(Kr,{items:t,title:"Inventory"},void 0,!1,void 0,this))});u.command("inspect").description("Inspect one inventory item by id or path").argument("<id-or-path>").option("--json","print JSON instead of Ink output").action(async(e,r)=>{let t=M(),n=Ze(t,e);if(r.json)return Q(n??null);await g(n?s(Tr,{item:n},void 0,!1,void 0,this):s(q,{query:e},void 0,!1,void 0,this))});u.command("decisions").description("Show saved item decisions").option("--json","print JSON instead of Ink output").action(async(e)=>{let r=Lr().decisions;if(e.json)return Q(r);await g(s($r,{decisions:r},void 0,!1,void 0,this))});u.command("decide").description("Save a decision for one inventory item").argument("<id-or-path>").argument("<status>",`one of: ${Array.from(ve).join(", ")}`).action(async(e,r)=>{if(!ve.has(r))u.error(`invalid status '${r}'. Valid: ${Array.from(ve).join(", ")}`);let t=M(),n=Ze(t,e);if(!n){await g(s(q,{query:e},void 0,!1,void 0,this)),process.exitCode=1;return}let i=Lr();i.decisions=i.decisions.filter((l)=>l.itemId!==n.id),i.decisions.push({itemId:n.id,status:r,updatedAt:new Date().toISOString()}),dn(hn(V),{recursive:!0}),yn(V,JSON.stringify(i,null,2)+`
11
- `,"utf-8"),await g(s(Rr,{item:n,status:r},void 0,!1,void 0,this))});u.command("summary").description("Print the last scan summary").option("--json","print JSON instead of Ink output").action(async(e)=>{let r=M();if(e.json)return Q(r.summary);await g(s(xe,{inventory:r,path:v},void 0,!1,void 0,this))});u.command("doctor").description("Check Atelier CLI, UI, inventory, and local environment health").option("--json","print JSON instead of Ink output").action(async(e)=>{let r=Tn();if(e.json)Q(r);else await g(s(Sr,{checks:r},void 0,!1,void 0,this));if(r.some((t)=>t.status==="fail"))process.exitCode=1});u.parseAsync(process.argv).catch((e)=>{console.error(e instanceof Error?e.message:e),process.exit(1)});function Q(e){console.log(JSON.stringify(e,null,2))}function M(){if(!x(v))throw new Error("No inventory found. Run `atl scan` first.");return JSON.parse(ke(v,"utf-8"))}function Lr(){if(!x(V))return{version:1,decisions:[]};return JSON.parse(ke(V,"utf-8"))}function zn(){if(process.env.ATELIER_STATE_DIR)return process.env.ATELIER_STATE_DIR;if(process.env.XDG_STATE_HOME)return p(process.env.XDG_STATE_HOME,"atelier");if(wn()==="win32"&&process.env.LOCALAPPDATA)return p(process.env.LOCALAPPDATA,"Atelier");return p(bn(),".local","state","atelier")}async function Qr(e){let r=M(),t=Ze(r,e);if(!t){await g(s(q,{query:e},void 0,!1,void 0,this)),process.exitCode=1;return}let n=await be(),i;if(!n.initialized)i=await Nr("Create an Atelier vault passphrase: ");else if(!n.unlocked)i=await E("Vault passphrase: ");let l=await cr(t,{passphrase:i});await g(s(Mr,{stableId:l.stableId,profileName:l.profileName,versionHash:l.version.contentSha256,sizeBytes:l.version.sizeBytes,reused:l.reused},void 0,!1,void 0,this))}async function Nr(e){let r=await E(e),t=await E("Confirm vault passphrase: ");if(r!==t)throw new Error("Vault passphrases do not match");return r}async function E(e){if(!C.isTTY)return F.write(e),Xr??=ke(0,"utf-8").split(/\r?\n/),Xr.shift()??"";F.write(e),C.setRawMode(!0),C.resume(),C.setEncoding("utf-8");let r="";try{for await(let t of C){let n=String(t);for(let i of n){if(i==="\x03")F.write(`
12
- `),process.exit(130);if(i==="\r"||i===`
13
- `)return F.write(`
14
- `),r;if(i==="\x7F"){r=r.slice(0,-1);continue}r+=i}}}finally{C.setRawMode(!1),C.pause()}return r}function Kn(e,r){return e.filter((t)=>{if(r.domain&&t.domain.toLowerCase()!==r.domain.toLowerCase())return!1;if(r.app&&t.app.toLowerCase()!==r.app.toLowerCase())return!1;if(r.secrets&&t.secretFindings.length===0)return!1;if(r.drift&&!t.mirrors.some((n)=>n.exists&&n.identical===!1))return!1;if(r.generated&&t.kind!=="generated")return!1;if(r.private&&t.shareability!=="private")return!1;if(r.missing&&t.exists)return!1;return!0})}function Ze(e,r){let t=Ue(r);return e.items.find((n)=>n.id===r||Ue(n.path)===t||Ue(n.displayPath)===t)??e.items.find((n)=>n.displayPath.includes(r)||n.path.includes(r))}function Ue(e){return e.replace(/^~(?=\/|$)/,process.env.HOME??"").toLowerCase()}function Tn(){let e=[],r=x(v)?M():void 0,t=P("bun",["--version"]),n=P("node",["--version"]),i=P("which",["atl"]),l=P("git",["status","--porcelain"],w);return e.push({label:"repo",status:x(p(w,"package.json"))?"pass":"fail",detail:w}),e.push({label:"bun",status:t?"pass":"fail",detail:t?`v${t}`:"not found"}),e.push({label:"node for Vite",status:n&&Yr(n)?"pass":"warn",detail:n?`${n}${Yr(n)?"":" \u2014 Vite wants 20.19+ or 22.12+"}`:"not found"}),e.push({label:"global atl",status:i?i.includes(".bun")||i.includes(w)?"pass":"warn":"fail",detail:i??"not linked; run `bun link` from the repo"}),e.push({label:"inventory",status:r?"pass":"warn",detail:r?`${r.summary.existing}/${r.summary.total} existing, generated ${r.generatedAt}`:"missing; run `atl scan`"}),e.push({label:"secret warnings",status:r&&r.summary.secrets>0?"warn":"pass",detail:r?`${r.summary.secrets} item${r.summary.secrets===1?"":"s"} flagged`:"no inventory"}),e.push({label:"ui dependencies",status:x(p(w,"node_modules","@tanstack","react-start"))?"pass":"fail",detail:x(p(w,"node_modules","@tanstack","react-start"))?"installed":"missing; run `bun install`"}),e.push({label:"git state",status:l===void 0?"warn":l.trim()?"warn":"pass",detail:l===void 0?"not a git repo":l.trim()?`${l.trim().split(`
15
- `).length} changed file(s)`:"clean"}),e}function P(e,r,t=w){try{return un(e,r,{cwd:t,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function Yr(e){let r=e.match(/^v?(\d+)\.(\d+)\.(\d+)/);if(!r)return!1;let[,t,n]=r,i=Number(t),l=Number(n);if(i===20)return l>=19;if(i===22)return l>=12;return i>22}async function $n(e){let r=process.env.ATELIER_API_SECRET??crypto.randomUUID(),t=Bun.spawn(["bun","src/index.ts"],{cwd:p(w,"apps","api"),env:{...process.env,PORT:String(e),ATELIER_API_SECRET:r},stdin:"inherit",stdout:"inherit",stderr:"inherit"});console.log(`Atelier API: http://localhost:${e}`);let n=await t.exited;process.exit(n)}async function An(e){let r=Bun.spawn(["bun","--bun","vite","dev","--host","127.0.0.1","--port",String(e)],{cwd:p(w,"apps","ui"),env:{...process.env,ATELIER_REPO_ROOT:w},stdin:"inherit",stdout:"inherit",stderr:"inherit"});console.log(`Atelier UI: http://localhost:${e}`);let t=await r.exited;process.exit(t)}
3
+ import{stdin as w,stdout as G}from"process";import{existsSync as Ct,readFileSync as St}from"fs";import{homedir as rn,platform as nn}from"os";import{join as q,resolve as on}from"path";import{Command as an}from"commander";import{execFileSync as j}from"child_process";import{chmodSync as $e,existsSync as ee,mkdirSync as Ae,readFileSync as me,rmSync as Mt,writeFileSync as ve}from"fs";import{homedir as _t,platform as Xt}from"os";import{dirname as xe,join as te}from"path";var Ce=te(_t(),".config","atelier"),h=te(Ce,"session.json"),C=te(Ce,"config.json"),re="dev.atelier.session",Yt="https://atelier.mananjoshi.me/api",Jt="Ov23liiscZlMXcJ2RLnd";function J(){return process.env.ATELIER_API_URL??Yt}function Wt(){return process.env.ATELIER_GITHUB_CLIENT_ID??Jt}async function Se(e){let t=e.apiUrl??J(),r=e.clientId??Wt(),n=await Qt(r);await e.onPrompt({verificationUri:n.verification_uri,userCode:n.user_code,expiresIn:n.expires_in});let a=await Ot(r,n,e.onPoll),i=await fetch(`${t}/auth/github/exchange`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({githubAccessToken:a})});if(!i.ok)throw new Error(`Atelier API rejected GitHub login (${i.status})`);let c=await i.json();return It({apiUrl:t,user:c.user,token:c.token}),{apiUrl:t,user:c.user}}async function Re(){let e=S();if(!e)return;let t=await fetch(`${e.apiUrl}/me`,{headers:{authorization:`Bearer ${e.token}`}});if(!t.ok)return;return{user:(await t.json()).user,apiUrl:e.apiUrl}}function S(){let e=W();if(!e)return;let t=Nt(e);if(!t)return;return{apiUrl:e.apiUrl,user:e.user,token:t}}function y(){return ke().activeProfile??"personal"}function ne(e){Lt({...ke(),activeProfile:e})}function Ue(){let e=W();if(e?.tokenStorage==="keychain")Ht(e.user.id);if(ee(h))Mt(h)}function W(){if(!ee(h))return;return JSON.parse(me(h,"utf-8"))}function ke(){if(!ee(C))return{};return JSON.parse(me(C,"utf-8"))}function Lt(e){Ae(xe(C),{recursive:!0}),ve(C,JSON.stringify(e,null,2)+`
4
+ `,"utf-8"),$e(C,384)}function It(e){Ae(xe(h),{recursive:!0});let t=Xt()==="darwin",r={apiUrl:e.apiUrl,user:e.user,tokenStorage:t?"keychain":"file",createdAt:new Date().toISOString()};if(t)Gt(e.user.id,e.token);else r.token=e.token;ve(h,JSON.stringify(r,null,2)+`
5
+ `,"utf-8"),$e(h,384)}function Nt(e){if(e.tokenStorage==="file")return e.token;return qt(e.user.id)}async function Qt(e){let t=await fetch("https://github.com/login/device/code",{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:e,scope:"read:user user:email"})});if(!t.ok)throw new Error(`GitHub device-code request failed (${t.status})`);return t.json()}async function Ot(e,t,r){let n=t.interval,a=Date.now()+t.expires_in*1000;while(Date.now()<a){await Ft(n*1000),await r?.("Waiting for GitHub authorization\u2026");let i=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({client_id:e,device_code:t.device_code,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})});if(!i.ok)throw new Error(`GitHub token polling failed (${i.status})`);let c=await i.json();if(c.access_token)return c.access_token;if(c.error==="authorization_pending")continue;if(c.error==="slow_down"){n+=5;continue}if(c.error==="access_denied")throw new Error("GitHub login was denied");if(c.error==="expired_token")throw new Error("GitHub login code expired");throw new Error(c.error_description??"GitHub login failed")}throw new Error("GitHub login timed out")}function Gt(e,t){j("security",["add-generic-password","-a",e,"-s",re,"-w",t,"-U"],{stdio:"ignore"})}function qt(e){try{return j("security",["find-generic-password","-a",e,"-s",re,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function Ht(e){try{j("security",["delete-generic-password","-a",e,"-s",re],{stdio:"ignore"})}catch{}}function Ft(e){return new Promise((t)=>setTimeout(t,e))}async function Ze(){return(await(await p("/profiles")).json()).profiles}async function Me(e){return(await(await p("/profiles",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:e})})).json()).profile}async function R(e){let t=await p(`/profiles/${encodeURIComponent(e)}`);if(t.status===404)return;return(await t.json()).profile}async function U(){return await(await p("/vault")).json()}async function _e(e){await p("/vault",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}async function Xe(e){let t=await p(`/profiles/${encodeURIComponent(e)}/key`);if(t.status===404)return;return(await t.json()).profileKey}async function oe(e,t){return(await(await p(`/profiles/${encodeURIComponent(e)}/key`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(t)})).json()).profileKey}async function Ye(e){return(await(await p(`/profiles/${encodeURIComponent(e)}/configs`)).json()).configs}async function Je(e,t){let r=await p(`/profiles/${encodeURIComponent(e)}/configs/${encodeURIComponent(t)}`);if(r.status===404)return;return(await r.json()).config}async function We(e,t,r){return await(await p(`/profiles/${encodeURIComponent(e)}/configs/${encodeURIComponent(t)}/versions`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})).json()}async function p(e,t={}){let r=S();if(!r)throw new Error("Not logged in. Run `atl login`.");let n=await fetch(`${r.apiUrl}${e}`,{...t,headers:{...t.headers,authorization:`Bearer ${r.token}`}});if(!n.ok&&n.status!==404){let a=await n.json().catch(()=>{return});throw new Error(a?.error??`Atelier API request failed (${n.status})`)}return n}import{createCipheriv as yr,createHash as br,randomBytes as pr}from"crypto";import{readFile as wr}from"fs/promises";import{execFileSync as le}from"child_process";import{createCipheriv as Pt,createDecipheriv as Vt,randomBytes as k,scryptSync as Dt}from"crypto";import{chmodSync as Et,existsSync as Ie,mkdirSync as jt,readFileSync as er,rmSync as tr,writeFileSync as rr}from"fs";import{homedir as nr,platform as se}from"os";import{dirname as or,join as Ne}from"path";var fe="dev.atelier.vault",ir=Ne(nr(),".config","atelier"),B=Ne(ir,"vault-key.json"),Le={N:32768,r:8,p:1},ar=67108864,ie="aes-256-gcm";async function ge(){let e=A();return{initialized:(await U()).initialized,unlocked:Boolean(ce(e.user.id)),activeProfile:y()}}async function ue(e,t=y()){lr(e);let r=A();if((await U()).initialized)throw new Error("Atelier vault already exists. Run `atl vault unlock` if this machine is locked.");let a=await R(t);if(!a)throw new Error(`Profile not found: ${t}`);let i=k(32),c=k(32),f=k(16),D=He(e,f,Le),E=ae(i,D),x=ae(c,i);return await _e({kdf:{algorithm:"scrypt",salt:L(f),params:Le},encryptedVaultKey:E}),await oe(t,{version:1,algorithm:x.algorithm,nonce:x.nonce,encryptedKey:x.ciphertext}),de(r.user.id,i),{profileName:a.name}}async function Qe(e){let t=A(),r=await U();if(!r.initialized)throw new Error("Atelier vault is not initialized. Run `atl save <id>` or `atl vault init`.");let n=qe(r,e);return de(t.user.id,n),{activeProfile:y()}}function Oe(){let e=A();sr(e.user.id)}async function cr(e,t=y()){let r=A(),n=ce(r.user.id);if(n)return n;if(!e)throw new Error("Vault passphrase is required");let a=await U();if(!a.initialized){await ue(e,t);let i=ce(r.user.id);if(!i)throw new Error("Vault initialized but local key was not stored");return i}return qe(a,e)}async function Ge(e,t=y()){let r=await cr(e,t),n=await Xe(t);if(n)return Fe(n.encryptedKey,n.nonce,r);let a=k(32),i=ae(a,r);return await oe(t,{version:1,algorithm:i.algorithm,nonce:i.nonce,encryptedKey:i.ciphertext}),a}function qe(e,t){if(!e.kdf||!e.encryptedVaultKey)throw new Error("Vault payload is incomplete");if(e.kdf.algorithm!=="scrypt")throw new Error(`Unsupported vault KDF: ${e.kdf.algorithm}`);let r=I(e.kdf.salt),n=He(t,r,e.kdf.params),a=Fe(e.encryptedVaultKey.ciphertext,e.encryptedVaultKey.nonce,n);return de(A().user.id,a),a}function He(e,t,r){return Dt(e,t,32,{N:r.N,r:r.r,p:r.p,maxmem:ar})}function ae(e,t){let r=k(12),n=Pt(ie,t,r),a=Buffer.concat([n.update(e),n.final()]),i=n.getAuthTag();return{algorithm:ie,nonce:L(r),ciphertext:L(Buffer.concat([a,i]))}}function Fe(e,t,r){let n=Buffer.from(I(e)),a=Buffer.from(I(t)),i=n.subarray(0,-16),c=n.subarray(-16),f=Vt(ie,r,a);return f.setAuthTag(c),Buffer.concat([f.update(i),f.final()])}function lr(e){if(e.length<12)throw new Error("Vault passphrase must be at least 12 characters.")}function A(){let e=S();if(!e)throw new Error("Not logged in. Run `atl login`.");return e}function de(e,t){let r=L(t);if(se()==="darwin"){le("security",["add-generic-password","-a",e,"-s",fe,"-w",r,"-U"],{stdio:"ignore"});return}jt(or(B),{recursive:!0}),rr(B,JSON.stringify({userId:e,key:r},null,2)+`
6
+ `,"utf-8"),Et(B,384)}function ce(e){let t=se()==="darwin"?fr(e):gr(e);return t?Buffer.from(I(t)):void 0}function sr(e){if(se()==="darwin"){try{le("security",["delete-generic-password","-a",e,"-s",fe],{stdio:"ignore"})}catch{}return}if(Ie(B))tr(B)}function fr(e){try{return le("security",["find-generic-password","-a",e,"-s",fe,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function gr(e){if(!Ie(B))return;let t=JSON.parse(er(B,"utf-8"));return t.userId===e?t.key:void 0}function L(e){return Buffer.from(e).toString("base64url")}function I(e){return new Uint8Array(Buffer.from(e,"base64url"))}function Pe(e){let t=[];if(!e.exists)t.push("file does not exist");if(e.isDirectory||e.kind==="directory"||e.format==="directory")t.push("directory saving is not supported yet");if(e.kind==="generated")t.push("generated/cache files are not saved");if(e.kind==="private"||e.shareability==="private")t.push("private/auth files are blocked");if(e.secretFindings.length>0)t.push("detected secret material");if(e.size!==void 0&&e.size>1048576)t.push(`file is larger than ${dr(1048576)}`);if(ur(e))t.push("binary files are not supported yet");return{ok:t.length===0,reasons:t}}function ye(e){let t=Pe(e);if(!t.ok)throw new Error(`Cannot save ${e.id}: ${t.reasons.join("; ")}`)}function ur(e){if(e.previewSuppressedReason?.toLowerCase().includes("binary"))return!0;return["binary","sqlite","db"].includes(e.format.toLowerCase())}function dr(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${Math.round(t)} KiB`;return`${Math.round(t/1024)} MiB`}var Ve="aes-256-gcm";async function je(e,t={}){ye(e);let r=y(),n=await Ge(t.passphrase,r),a=await wr(e.path),i=hr(a,n),c=await We(r,e.id,{kind:"file",pathHint:e.displayPath,contentSha256:De(a),ciphertextSha256:De(i.ciphertextBytes),sizeBytes:a.byteLength,algorithm:i.algorithm,profileKeyVersion:1,nonce:i.nonce,ciphertext:i.ciphertext});return{profileName:r,stableId:e.id,version:c.version,reused:c.reused}}function hr(e,t){let r=pr(12),n=yr(Ve,t,r),a=Buffer.concat([n.update(e),n.final()]),i=n.getAuthTag(),c=Buffer.concat([a,i]);return{algorithm:Ve,nonce:Ee(r),ciphertext:Ee(c),ciphertextBytes:c}}function De(e){return br("sha256").update(e).digest("hex")}function Ee(e){return Buffer.from(e).toString("base64url")}import{execFileSync as ct}from"child_process";import{existsSync as K,lstatSync as Tr,mkdirSync as $r,readdirSync as we,readFileSync as Z,statSync as m,writeFileSync as Ar}from"fs";import{homedir as mr,userInfo as vr}from"os";import{dirname as lt,join as z,relative as st,resolve as xr}from"path";var et=[{domain:"AI Tools",app:"Pi",items:[{id:"pi.dir",path:"~/.pi",kind:"directory",format:"directory",shareability:"machine-specific"}]},{domain:"Shell",app:"Starship",items:[{id:"starship.config",path:"~/.config/starship.toml",kind:"config",format:"toml",shareability:"shareable"}]},{domain:"Editors",app:"Zed",items:[{id:"zed.dir",path:"~/.config/zed",kind:"directory",format:"directory",shareability:"shareable"},{id:"zed.settings",path:"~/.config/zed/settings.json",kind:"config",format:"jsonc",shareability:"shareable"},{id:"zed.themes",path:"~/.config/zed/themes",kind:"config",format:"directory",shareability:"shareable"},{id:"zed.prompts",path:"~/.config/zed/prompts",kind:"generated",format:"directory",shareability:"machine-specific"}]},{domain:"Git",app:"Git",items:[{id:"git.config",path:"~/.gitconfig",kind:"config",format:"gitconfig",shareability:"machine-specific"},{id:"git.config-dir",path:"~/.config/git",kind:"directory",format:"directory",shareability:"machine-specific"},{id:"git.ignore",path:"~/.gitignore",kind:"config",format:"gitignore",shareability:"machine-specific"}]},{domain:"Private/Auth",app:"Credentials",privateByDefault:!0,items:[{id:"auth.ssh",path:"~/.ssh",kind:"private",format:"directory",shareability:"private"},{id:"auth.aws",path:"~/.aws",kind:"private",format:"directory",shareability:"private"},{id:"auth.gh",path:"~/.config/gh",kind:"private",format:"directory",shareability:"private"},{id:"auth.gcloud-adc",path:"~/.config/gcloud/application_default_credentials.json",kind:"private",format:"json",shareability:"private"},{id:"auth.docker",path:"~/.docker/config.json",kind:"private",format:"json",shareability:"private"},{id:"auth.pi",path:"~/.config/pi/auth.json",kind:"private",format:"json",shareability:"private"}]},{domain:"Shell",app:"Zsh",items:[{id:"zsh.home-rc",path:"~/.zshrc",kind:"config",format:"shell",shareability:"shareable"},{id:"zsh.home-env",path:"~/.zshenv",kind:"config",format:"shell",shareability:"private"},{id:"zsh.dir",path:"~/.config/zsh",kind:"directory",format:"directory",shareability:"machine-specific"},{id:"zsh.env",path:"~/.config/zsh/.zshenv",kind:"config",format:"shell",shareability:"private"},{id:"zsh.rc",path:"~/.config/zsh/.zshrc",kind:"config",format:"shell",shareability:"shareable"},{id:"zsh.conf",path:"~/.config/zsh/conf.d",kind:"directory",format:"directory",shareability:"shareable"},{id:"zsh.zcompdump",path:"~/.config/zsh/.zcompdump",kind:"generated",format:"text",shareability:"machine-specific"},{id:"zsh.sessions",path:"~/.config/zsh/.zsh_sessions",kind:"generated",format:"directory",shareability:"machine-specific"}]},{domain:"Terminals",app:"cmux",items:[{id:"cmux.dir",path:"~/.config/cmux",kind:"directory",format:"directory",shareability:"shareable"},{id:"cmux.config",path:"~/.config/cmux/cmux.json",kind:"config",format:"jsonc",shareability:"shareable"},{id:"cmux.ghostty",path:"~/Library/Application Support/com.cmuxterm.app/config.ghostty",kind:"config",format:"ghostty",shareability:"shareable"},{id:"cmux.browser-history",path:"~/Library/Application Support/com.cmuxterm.app/browser_history.json",kind:"generated",format:"json",shareability:"machine-specific"}]}];var be=[["GitHub token",/gh[pousr]_[A-Za-z0-9_]{20,}/g],["Slack token",/xox[baprs]-[A-Za-z0-9-]{20,}/g],["AWS access key",/AKIA[0-9A-Z]{16}/g],["Private key",/-----BEGIN (?:RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----/g],["Generic token assignment",/(?:token|api[_-]?key|secret|webhook|password)\s*[=:]\s*["']?[^"'\s]{12,}/gi]];function tt(e){let t=[],r=e.split(/\r?\n/);for(let[n,a]of be)for(let i of e.matchAll(a)){let c=i.index??0,f=e.slice(0,c).split(/\r?\n/).length;t.push({type:n,line:f,preview:N(i[0])})}return r.forEach((n,a)=>{for(let i of n.matchAll(/[A-Za-z0-9_+\/=.-]{32,}/g)){let c=i[0];if(!Br(c,n)&&nt(c,n))t.push({type:"High-entropy string",line:a+1,preview:N(c)})}}),Kr(t)}function N(e){if(e.length<=8)return"[redacted]";return`${e.slice(0,4)}\u2026${e.slice(-4)}`}function rt(e){let t=e;for(let[,r]of be)t=t.replace(r,(n)=>N(n));return t=t.replace(/[A-Za-z0-9_+\/=.-]{32,}/g,(r)=>{if(nt(r,e))return N(r);return r}),t}function Br(e,t){return be.some(([,r])=>{return r.lastIndex=0,Array.from(t.matchAll(r)).some((n)=>n[0].includes(e)||e.includes(n[0]))})}function nt(e,t){if(e.startsWith("amazon."))return!1;if(e.includes("anthropic.claude"))return!1;if(/^[A-Za-z0-9.-]+@[A-Za-z0-9.-]+$/.test(e))return!1;if(/model/i.test(t)&&/^[A-Za-z0-9_.-]+$/.test(e))return!1;return zr(e)>4.2&&/[A-Za-z]/.test(e)&&/[0-9]/.test(e)}function zr(e){let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let r=0;for(let n of t.values()){let a=n/e.length;r-=a*Math.log2(a)}return r}function Kr(e){let t=new Set;return e.filter((r)=>{let n=`${r.type}:${r.line}:${r.preview}`;if(t.has(n))return!1;return t.add(n),!0})}function ot(e){let n=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/(^|[^:])\/\/.*$/gm,"$1").replace(/,\s*([}\]])/g,"$1");return JSON.parse(n)}var T=mr(),Cr=new Set([".zsh",".zshrc",".zshenv",".sh",".json",".jsonc",".toml",".md",".yml",".yaml",".gitconfig",".gitignore",".ghostty",""]),Sr=[/cache/i,/history/i,/session/i,/state/i,/\.mdb$/i,/\.sqlite/i,/\.db$/i,/zcompdump/i,/logs?/i],Rr=[/credential/i,/secret/i,/token/i,/auth\.json$/i,/hosts\.yml$/i,/config\.json$/i],O;async function ft(e){O=e.includeLegacyManagers?Nr():void 0;let r=Ur(e.repoRoot).flatMap((i)=>i.items.map((c)=>({definition:i,item:c}))),n=new Set,a=[];for(let{definition:i,item:c}of r){let f=pe(c.path);n.add(f),a.push(kr(i,c,f))}for(let i of Zr()){if(n.has(i.path))continue;n.add(i.path),a.push(it(i))}for(let i of e.manualPaths??[]){let c=pe(i);if(n.has(c))continue;n.add(c),a.push(it({path:c,reason:"manual path"}))}return a.sort((i,c)=>`${i.domain}:${i.app}:${i.path}`.localeCompare(`${c.domain}:${c.app}:${c.path}`)),{version:1,generatedAt:new Date().toISOString(),repoRoot:e.repoRoot,home:T,items:a,summary:{total:a.length,existing:a.filter((i)=>i.exists).length,secrets:a.filter((i)=>i.secretFindings.length>0).length,drift:a.filter((i)=>i.mirrors.some((c)=>c.exists&&c.identical===!1)).length,generated:a.filter((i)=>i.kind==="generated").length,private:a.filter((i)=>i.shareability==="private").length}}}function gt(e,t={}){let r=t.path??z(e.repoRoot,".atelier","state","inventory.json");return $r(lt(r),{recursive:!0}),Ar(r,JSON.stringify(e,null,2)+`
7
+ `,"utf-8"),r}function Ur(e){let t=z(e,"packages","registry","definitions");if(!K(t))return et;return we(t).filter((r)=>r.endsWith(".jsonc")).map((r)=>ot(Z(z(t,r),"utf-8")))}function kr(e,t,r){return ut({path:r,domain:e.domain,app:e.app,kind:t.kind,format:t.format,shareability:t.shareability,reason:"registry match",mirrors:t.mirrors??[],privateByDefault:e.privateByDefault,id:t.id})}function it(e){let t=Or(e.path),r=qr(e.path),n=Hr(e.path,r);return ut({path:e.path,domain:Gr(e.path),app:t,kind:r,format:Fr(e.path),shareability:n,reason:e.reason,mirrors:[],privateByDefault:n==="private"})}function ut(e){let t=K(e.path),r=t?Tr(e.path):void 0,n=t?m(e.path):void 0,a=!!n?.isDirectory(),i=!!r?.isSymbolicLink(),c=t&&!a&&dt(e.path)?tt(Z(e.path,"utf-8")):[],f=e.mirrors.map((x)=>_r(e.path,pe(x))),D=Jr(e.kind,e.shareability,c.length,f),E=Yr(e.path,t,a,e.shareability,e.privateByDefault,e.kind);return{id:e.id??Qr(e.path),domain:e.domain,app:e.app,path:e.path,displayPath:M(e.path),kind:e.kind,format:e.format,shareability:e.shareability,exists:t,isDirectory:a,isSymlink:i,mode:n?`0${(n.mode&511).toString(8)}`:void 0,owner:t?vr().username:void 0,size:n?.size,git:t?Wr(e.path):void 0,legacyManagers:t?Lr(e.path):{},mirrors:f,secretFindings:c,...E,recommendation:D,reason:e.reason}}function Zr(){let e=[],t=z(T,".config");if(!K(t))return e;for(let r of we(t,{withFileTypes:!0})){if(r.name.startsWith("."))continue;let n=z(t,r.name);if(e.push({path:n,reason:"~/.config app directory"}),!r.isDirectory())continue;for(let a of Mr(n).slice(0,80)){let i=z(n,a.name);if(he(i)){e.push({path:i,reason:"generated/app-state candidate"});continue}if(a.isFile()&&Be(a.name))e.push({path:i,reason:"shallow ~/.config config candidate"});if(a.isDirectory()&&["conf.d","themes","snippets","plugins"].includes(a.name))e.push({path:i,reason:"shallow ~/.config config directory"})}}return e}function Mr(e){try{return we(e,{withFileTypes:!0})}catch{return[]}}function _r(e,t){let r=K(t);if(!r||!K(e)||m(e).isDirectory()||m(t).isDirectory())return{path:t,displayPath:M(t),exists:r};let n=Z(e,"utf-8"),a=Z(t,"utf-8");return{path:t,displayPath:M(t),exists:r,identical:n===a,diff:n===a?void 0:Xr(a,n)}}function Xr(e,t){let r=e.split(/\r?\n/),n=t.split(/\r?\n/),a=Math.max(r.length,n.length),i=[];for(let c=0;c<a;c++){if(r[c]===n[c])continue;if(r[c]!==void 0)i.push(`-${r[c]}`);if(n[c]!==void 0)i.push(`+${n[c]}`)}return i.slice(0,200).join(`
8
+ `)}function Yr(e,t,r,n,a,i){if(!t)return{previewSuppressedReason:"missing"};if(r)return{previewSuppressedReason:"directory"};if(n==="private"||a||i==="private")return{previewSuppressedReason:"private/auth metadata-only"};if(!dt(e))return{previewSuppressedReason:"binary or unsupported file type"};let c=Z(e,"utf-8");return{preview:rt(c).slice(0,20000)}}function Jr(e,t,r,n){if(r>0)return"rotate-secret";if(e==="generated")return"ignore-generated";if(t==="private")return"mark-private";if(n.some((a)=>a.exists&&a.identical===!1))return"resolve-drift";if(t==="machine-specific")return"review-machine-specific";if(e==="config"||e==="directory")return"adopt-candidate";return"none"}function Wr(e){let t=m(e).isDirectory()?e:lt(e),r=Q(["rev-parse","--show-toplevel"],t);if(!r)return;let n=st(r,e),a=!!Q(["check-ignore","-q",n],r,!0),i=!!Q(["ls-files","--error-unmatch",n],r,!0),c=i&&!!Q(["status","--porcelain","--",n],r);return{root:r,tracked:i,modified:c,ignored:a}}function Lr(e){if(!O)return{};return{yadm:Ir(e)}}function Ir(e){let t=M(e).replace(/^~\//,"");if(O?.modified.has(t))return"modified";if(O?.tracked.has(t))return"tracked";return"unknown"}function Nr(){let e=new Set((at("yadm",["ls-files"])??"").split(`
9
+ `).filter(Boolean)),t=new Set((at("yadm",["status","--porcelain"])??"").split(`
10
+ `).map((r)=>r.slice(3).trim()).filter(Boolean));return{tracked:e,modified:t}}function Q(e,t,r=!1){try{return ct("git",e,{cwd:t,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||(r?"ok":void 0)}catch{return}}function at(e,t){try{return ct(e,t,{cwd:T,encoding:"utf-8",stdio:["ignore","pipe","ignore"]})}catch{return}}function pe(e){return xr(e.replace(/^~(?=\/|$)/,T))}function M(e){return e.startsWith(T)?`~${e.slice(T.length)}`:e}function Qr(e){return M(e).replace(/[^A-Za-z0-9_.-]+/g,":")}function Or(e){let t=st(z(T,".config"),e);if(!t.startsWith(".."))return t.split(/[\\/]/)[0]||"Unknown";return"Unknown"}function Gr(e){if(e.includes("/.config/"))return"~/.config";if(e.includes("/.ssh")||e.includes("/.aws"))return"Private/Auth";return"Unknown"}function qr(e){if(he(e))return"generated";if(Rr.some((t)=>t.test(e)))return"private";if(K(e)&&m(e).isDirectory())return"directory";if(Be(e))return"config";return"unknown"}function Hr(e,t){if(t==="private")return"private";if(t==="generated")return"machine-specific";if(e.includes("/credentials")||e.includes("/.ssh")||e.includes("/.aws"))return"private";return"machine-specific"}function Fr(e){if(K(e)&&m(e).isDirectory())return"directory";if(e.endsWith(".jsonc"))return"jsonc";if(e.endsWith(".json"))return"json";if(e.endsWith(".toml"))return"toml";if(e.endsWith(".zsh"))return"shell";if(e.endsWith(".md"))return"markdown";return"text"}function he(e){return Sr.some((t)=>t.test(e))}function Be(e){return/(^config\.|settings\.|rc$|\.rc$|\.zshrc$|\.zshenv$|\.jsonc?$|\.toml$|\.ya?ml$|\.zsh$|\.conf$|\.ini$)/i.test(e)}function dt(e){let t=e.split("/").pop()??"";if(he(e))return!1;if(t.includes("lock")||t.endsWith(".mdb")||t.endsWith(".sqlite")||t.endsWith(".db"))return!1;let r=t.includes(".")?t.slice(t.lastIndexOf(".")):"";return Cr.has(r)||Be(t)}import{Box as s,Text as l,render as Pr}from"ink";import{jsxDEV as o,Fragment as tn}from"react/jsx-dev-runtime";function g(e){return Pr(o(tn,{children:e},void 0,!1,void 0,this)).waitUntilExit()}function ze({inventory:e,path:t}){return o(s,{flexDirection:"column",gap:1,children:[o(b,{title:"Scan complete",subtitle:t},void 0,!1,void 0,this),o(s,{gap:2,children:[o(v,{label:"total",value:e.summary.total,color:"cyan"},void 0,!1,void 0,this),o(v,{label:"existing",value:e.summary.existing,color:"green"},void 0,!1,void 0,this),o(v,{label:"private",value:e.summary.private,color:"red"},void 0,!1,void 0,this),o(v,{label:"generated",value:e.summary.generated,color:"magenta"},void 0,!1,void 0,this),o(v,{label:"secrets",value:e.summary.secrets,color:"red"},void 0,!1,void 0,this),o(v,{label:"drift",value:e.summary.drift,color:"blue"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function yt({items:e,title:t}){return o(s,{flexDirection:"column",children:[o(b,{title:t,subtitle:`${e.length} item${e.length===1?"":"s"}`},void 0,!1,void 0,this),o(s,{flexDirection:"column",marginTop:1,children:e.map((r)=>o(s,{gap:1,children:[o(l,{color:r.exists?"white":"gray",children:r.exists?"\u25CF":"\u25CB"},void 0,!1,void 0,this),o(l,{color:mt(r),children:r.domain},void 0,!1,void 0,this),o(l,{color:"gray",children:"/"},void 0,!1,void 0,this),o(l,{color:"cyan",children:r.app},void 0,!1,void 0,this),o(l,{children:r.displayPath},void 0,!1,void 0,this),o($,{label:r.shareability,color:vt(r.shareability)},void 0,!1,void 0,this),r.secretFindings.length>0?o($,{label:"secret",color:"red"},void 0,!1,void 0,this):null,r.mirrors.some((n)=>n.exists&&n.identical===!1)?o($,{label:"drift",color:"blue"},void 0,!1,void 0,this):null]},r.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function bt({item:e}){return o(s,{flexDirection:"column",gap:1,children:[o(b,{title:e.app,subtitle:e.displayPath},void 0,!1,void 0,this),o(s,{gap:1,children:[o($,{label:e.domain,color:"cyan"},void 0,!1,void 0,this),o($,{label:e.kind,color:mt(e)},void 0,!1,void 0,this),o($,{label:e.shareability,color:vt(e.shareability)},void 0,!1,void 0,this),o($,{label:e.recommendation,color:"yellow"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(Vr,{rows:[["reason",e.reason],["exists",String(e.exists)],["mode",e.mode??"\u2014"],["symlink",String(e.isSymlink)],["git",en(e)],["legacy",jr(e)]]},void 0,!1,void 0,this),e.secretFindings.length>0?o(s,{flexDirection:"column",children:[o(l,{color:"red",bold:!0,children:"Secret warnings"},void 0,!1,void 0,this),e.secretFindings.map((t,r)=>o(l,{color:"red",children:[" ",t.type,t.line?` line ${t.line}`:"",": ",t.preview]},`${t.type}-${r}`,!0,void 0,this))]},void 0,!0,void 0,this):null,e.mirrors.length>0?o(s,{flexDirection:"column",children:[o(l,{color:"blue",bold:!0,children:"Mirrors"},void 0,!1,void 0,this),e.mirrors.map((t)=>o(l,{children:[" ",t.displayPath," \u2014 ",t.exists?t.identical===!1?"differs":"identical":"missing"]},t.path,!0,void 0,this))]},void 0,!0,void 0,this):null,o(s,{flexDirection:"column",children:[o(l,{bold:!0,children:e.preview?"Safe preview":"Preview"},void 0,!1,void 0,this),o(l,{color:e.preview?"white":"gray",children:e.preview?e.preview.slice(0,3000):`Suppressed: ${e.previewSuppressedReason??"not available"}`},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function pt({verificationUri:e,userCode:t,expiresIn:r}){return o(s,{flexDirection:"column",gap:1,children:[o(b,{title:"Login with GitHub",subtitle:`code expires in ${Math.round(r/60)} minutes`},void 0,!1,void 0,this),o(s,{flexDirection:"column",children:[o(l,{children:"Open:"},void 0,!1,void 0,this),o(l,{color:"blue",underline:!0,children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(s,{gap:1,children:[o(l,{children:"Enter code:"},void 0,!1,void 0,this),o(l,{color:"green",bold:!0,children:t},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function wt({login:e,apiUrl:t}){return o(s,{flexDirection:"column",children:[o(b,{title:"Logged in",subtitle:t},void 0,!1,void 0,this),o(l,{color:"green",children:["\u2713 ",e]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function ht({login:e,apiUrl:t}){if(!e)return o(l,{color:"yellow",children:"Not logged in. Run `atl login`."},void 0,!1,void 0,this);return o(s,{flexDirection:"column",children:[o(b,{title:"Current account",subtitle:t},void 0,!1,void 0,this),o(l,{color:"green",children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Bt(){return o(l,{color:"green",children:"\u2713 Logged out"},void 0,!1,void 0,this)}function zt({profiles:e,activeProfile:t}){return o(s,{flexDirection:"column",children:[o(b,{title:"Profiles",subtitle:`active: ${t}`},void 0,!1,void 0,this),o(s,{flexDirection:"column",marginTop:1,children:e.map((r)=>o(s,{gap:1,children:[o(l,{color:r.name===t?"green":"gray",children:r.name===t?"\u25CF":"\u25CB"},void 0,!1,void 0,this),o(l,{bold:r.name===t,children:r.name},void 0,!1,void 0,this),o(l,{color:"gray",children:r.createdAt},void 0,!1,void 0,this)]},r.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function _({title:e,name:t}){return o(s,{flexDirection:"column",children:[o(b,{title:e},void 0,!1,void 0,this),o(l,{color:"green",children:["\u2713 ",t]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function Kt({configs:e,profileName:t}){return o(s,{flexDirection:"column",children:[o(b,{title:"Saved configs",subtitle:t},void 0,!1,void 0,this),e.length===0?o(l,{color:"gray",children:"No saved configs yet."},void 0,!1,void 0,this):e.map((r)=>o(s,{flexDirection:"column",marginTop:1,children:[o(l,{bold:!0,children:r.stableId},void 0,!1,void 0,this),o(l,{color:"gray",children:r.pathHint??"no path hint"},void 0,!1,void 0,this),r.latestVersion?o(l,{color:"green",children:[r.latestVersion.contentSha256.slice(0,12)," \xB7 ",r.latestVersion.sizeBytes," bytes \xB7 ",r.latestVersion.createdAt]},void 0,!0,void 0,this):null]},r.id,!0,void 0,this))]},void 0,!0,void 0,this)}function Tt({config:e,profileName:t}){return o(s,{flexDirection:"column",children:[o(b,{title:e.stableId,subtitle:t},void 0,!1,void 0,this),o(l,{color:"gray",children:e.pathHint??"no path hint"},void 0,!1,void 0,this),o(s,{flexDirection:"column",marginTop:1,children:(e.versions??[]).map((r)=>o(l,{children:[r.contentSha256.slice(0,12)," \xB7 ",r.sizeBytes," bytes \xB7 ",r.createdAt]},r.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function $t({stableId:e,profileName:t,versionHash:r,sizeBytes:n,reused:a}){return o(s,{flexDirection:"column",children:[o(b,{title:a?"Config already saved":"Config saved",subtitle:t},void 0,!1,void 0,this),o(l,{color:"green",children:["\u2713 ",e]},void 0,!0,void 0,this),o(l,{color:"gray",children:["Version ",r.slice(0,12)," \xB7 ",n," bytes \xB7 encrypted"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function At({checks:e}){let t=e.filter((n)=>n.status==="fail").length,r=e.filter((n)=>n.status==="warn").length;return o(s,{flexDirection:"column",gap:1,children:[o(b,{title:"Doctor",subtitle:t?`${t} failing`:r?`${r} warning${r===1?"":"s"}`:"all checks passed"},void 0,!1,void 0,this),o(s,{flexDirection:"column",children:e.map((n)=>o(s,{gap:1,children:[o(l,{color:Er(n.status),children:Dr(n.status)},void 0,!1,void 0,this),o(l,{bold:!0,children:n.label},void 0,!1,void 0,this),o(l,{color:"gray",children:n.detail},void 0,!1,void 0,this)]},n.label,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function Ke({query:e}){return o(l,{color:"red",children:["No inventory item matched: ",e]},void 0,!0,void 0,this)}function b({title:e,subtitle:t}){return o(s,{flexDirection:"column",children:[o(l,{bold:!0,color:"cyan",children:"\u25C6 Atelier"},void 0,!1,void 0,this),o(s,{gap:1,children:[o(l,{bold:!0,children:e},void 0,!1,void 0,this),t?o(l,{color:"gray",children:t},void 0,!1,void 0,this):null]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function v({label:e,value:t,color:r}){return o(s,{flexDirection:"column",borderStyle:"round",borderColor:r,paddingX:1,children:[o(l,{color:r,bold:!0,children:t},void 0,!1,void 0,this),o(l,{color:"gray",children:e},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}function $({label:e,color:t}){return o(l,{color:t,children:["[",e,"]"]},void 0,!0,void 0,this)}function Vr({rows:e}){return o(s,{flexDirection:"column",children:e.map(([t,r])=>o(s,{gap:1,children:[o(l,{color:"gray",children:t.padEnd(10)},void 0,!1,void 0,this),o(l,{children:r},void 0,!1,void 0,this)]},t,!0,void 0,this))},void 0,!1,void 0,this)}function mt(e){let t=typeof e==="string"?e:e.kind;if(t==="private")return"red";if(t==="generated")return"magenta";if(t==="config")return"green";return"yellow"}function vt(e){if(e==="private")return"red";if(e==="shareable")return"green";return"yellow"}function Dr(e){if(e==="pass")return"\u2713";if(e==="warn")return"!";return"\u2717"}function Er(e){if(e==="pass")return"green";if(e==="warn")return"yellow";return"red"}function jr(e){let t=Object.entries(e.legacyManagers??{});if(t.length===0)return"not scanned";return t.map(([r,n])=>`${r}: ${n}`).join(", ")}function en(e){if(!e.git)return"not in repo";return`${e.git.tracked?"tracked":"untracked"}${e.git.modified?", modified":""} @ ${e.git.root}`}import{jsxDEV as u}from"react/jsx-dev-runtime";var cn=on(import.meta.dir,"../../.."),Rt=ln(),X=q(Rt,"inventory.json"),xt,d=new an;d.name("atl").description("Atelier config management CLI").version("0.1.4");d.command("login").description("Login to Atelier with GitHub device auth").option("--api-url <url>","Atelier API URL",J()).action(async(e)=>{let t=await Se({apiUrl:e.apiUrl,onPrompt:async(r)=>{await g(u(pt,{verificationUri:r.verificationUri,userCode:r.userCode,expiresIn:r.expiresIn},void 0,!1,void 0,this))}});await g(u(wt,{login:t.user.login,apiUrl:t.apiUrl},void 0,!1,void 0,this))});d.command("whoami").description("Show the current Atelier account").action(async()=>{let e=await Re();if(await g(u(ht,{login:e?.user.login,apiUrl:e?.apiUrl},void 0,!1,void 0,this)),!e)process.exitCode=1});d.command("logout").description("Remove the local Atelier session").action(async()=>{Ue(),await g(u(Bt,{},void 0,!1,void 0,this))});var F=d.command("profile").description("Manage account-backed config profiles");F.command("list").description("List remote profiles").action(async()=>{await g(u(zt,{profiles:await Ze(),activeProfile:y()},void 0,!1,void 0,this))});F.command("create").description("Create a remote profile").argument("<name>").action(async(e)=>{let t=await Me(e);await g(u(_,{title:"Profile created",name:t.name},void 0,!1,void 0,this))});F.command("switch").description("Set the active local profile after verifying it exists remotely").argument("<name>").action(async(e)=>{let t=await R(e);if(!t)throw new Error(`Profile not found: ${e}`);ne(t.name),await g(u(_,{title:"Active profile",name:t.name},void 0,!1,void 0,this))});F.command("current").description("Show the active local profile").action(async()=>{await g(u(_,{title:"Active profile",name:y()},void 0,!1,void 0,this))});d.command("checkout").description("Alias for `atl profile switch`").argument("<name>").action(async(e)=>{let t=await R(e);if(!t)throw new Error(`Profile not found: ${e}`);ne(t.name),await g(u(_,{title:"Active profile",name:t.name},void 0,!1,void 0,this))});var P=d.command("vault").description("Advanced vault controls");P.command("status").description("Show vault initialization and local unlock state").action(async()=>{let e=await ge();console.log(`Vault: ${e.initialized?"initialized":"not initialized"}`),console.log(`Local state: ${e.unlocked?"unlocked":"locked"}`),console.log(`Active profile: ${e.activeProfile}`)});P.command("init").description("Initialize the encrypted vault now instead of waiting for first save").action(async()=>{let e=await kt("Create an Atelier vault passphrase: "),t=await ue(e);console.log(`Vault initialized for profile ${t.profileName}`)});P.command("unlock").description("Unlock this machine with the vault passphrase").action(async()=>{let e=await H("Vault passphrase: "),t=await Qe(e);console.log(`Vault unlocked for profile ${t.activeProfile}`)});P.command("lock").description("Remove local unlocked vault material from this machine").action(async()=>{Oe(),console.log("Vault locked")});d.command("save").description("Save a config snapshot to the active encrypted profile").argument("<id-or-path>").action(async(e)=>{await sn(e)});var Ut=d.command("saved").description("Inspect encrypted configs saved remotely");Ut.command("list").description("List saved configs for the active profile").action(async()=>{let e=y();await g(u(Kt,{configs:await Ye(e),profileName:e},void 0,!1,void 0,this))});Ut.command("show").description("Show saved metadata and version history").argument("<stable-id>").action(async(e)=>{let t=y(),r=await Je(t,e);if(!r)throw new Error(`Saved config not found: ${e}`);await g(u(Tt,{config:r,profileName:t},void 0,!1,void 0,this))});d.command("scan").description("Scan this machine and write local inventory").option("--path <path...>","additional manual path(s) to scan").option("--legacy","include legacy manager signals like yadm").action(async(e)=>{let t=await ft({repoRoot:cn,manualPaths:e.path??[],includeLegacyManagers:e.legacy}),r=gt(t,{path:X});await g(u(ze,{inventory:t,path:r},void 0,!1,void 0,this))});d.command("list").description("List inventory items with polished terminal output").option("--domain <domain>","filter by domain").option("--app <app>","filter by app").option("--secrets","only items with secret warnings").option("--drift","only items with mirror drift").option("--generated","only generated/app-state items").option("--private","only private items").option("--missing","only missing registry items").option("--json","print JSON instead of Ink output").action(async(e)=>{let t=Y(),r=fn(t.items,e);if(e.json)return V(r);await g(u(yt,{items:r,title:"Inventory"},void 0,!1,void 0,this))});d.command("inspect").description("Inspect one inventory item by id or path").argument("<id-or-path>").option("--json","print JSON instead of Ink output").action(async(e,t)=>{let r=Y(),n=Zt(r,e);if(t.json)return V(n??null);await g(n?u(bt,{item:n},void 0,!1,void 0,this):u(Ke,{query:e},void 0,!1,void 0,this))});d.command("summary").description("Print the last scan summary").option("--json","print JSON instead of Ink output").action(async(e)=>{let t=Y();if(e.json)return V(t.summary);await g(u(ze,{inventory:t,path:X},void 0,!1,void 0,this))});d.command("doctor").description("Check Atelier CLI, account, inventory, and local environment health").option("--json","print JSON instead of Ink output").action(async(e)=>{let t=gn();if(e.json)V(t);else await g(u(At,{checks:t},void 0,!1,void 0,this));if(t.some((r)=>r.status==="fail"))process.exitCode=1});d.parseAsync(process.argv).catch((e)=>{console.error(e instanceof Error?e.message:e),process.exit(1)});function V(e){console.log(JSON.stringify(e,null,2))}function Y(){if(!Ct(X))throw new Error("No inventory found. Run `atl scan` first.");return JSON.parse(St(X,"utf-8"))}function ln(){if(process.env.ATELIER_STATE_DIR)return process.env.ATELIER_STATE_DIR;if(process.env.XDG_STATE_HOME)return q(process.env.XDG_STATE_HOME,"atelier");if(nn()==="win32"&&process.env.LOCALAPPDATA)return q(process.env.LOCALAPPDATA,"Atelier");return q(rn(),".local","state","atelier")}async function sn(e){let t=Y(),r=Zt(t,e);if(!r){await g(u(Ke,{query:e},void 0,!1,void 0,this)),process.exitCode=1;return}let n=await ge(),a;if(!n.initialized)a=await kt("Create an Atelier vault passphrase: ");else if(!n.unlocked)a=await H("Vault passphrase: ");let i=await je(r,{passphrase:a});await g(u($t,{stableId:i.stableId,profileName:i.profileName,versionHash:i.version.contentSha256,sizeBytes:i.version.sizeBytes,reused:i.reused},void 0,!1,void 0,this))}async function kt(e){let t=await H(e),r=await H("Confirm vault passphrase: ");if(t!==r)throw new Error("Vault passphrases do not match");return t}async function H(e){if(!w.isTTY)return G.write(e),xt??=St(0,"utf-8").split(/\r?\n/),xt.shift()??"";return G.write(e),w.setEncoding("utf-8"),w.resume(),w.setRawMode(!0),await new Promise((t)=>{let r="",n=()=>{w.off("data",i),w.setRawMode(!1),w.pause()},a=()=>{n(),G.write(`
11
+ `),t(r)},i=(c)=>{for(let f of String(c)){if(f==="\x03")n(),G.write(`
12
+ `),process.exit(130);if(f==="\r"||f===`
13
+ `){a();return}if(f==="\x7F"){r=r.slice(0,-1);continue}r+=f}};w.on("data",i)})}function fn(e,t){return e.filter((r)=>{if(t.domain&&r.domain.toLowerCase()!==t.domain.toLowerCase())return!1;if(t.app&&r.app.toLowerCase()!==t.app.toLowerCase())return!1;if(t.secrets&&r.secretFindings.length===0)return!1;if(t.drift&&!r.mirrors.some((n)=>n.exists&&n.identical===!1))return!1;if(t.generated&&r.kind!=="generated")return!1;if(t.private&&r.shareability!=="private")return!1;if(t.missing&&r.exists)return!1;return!0})}function Zt(e,t){let r=Te(t);return e.items.find((n)=>n.id===t||Te(n.path)===r||Te(n.displayPath)===r)??e.items.find((n)=>n.displayPath.includes(t)||n.path.includes(t))}function Te(e){return e.replace(/^~(?=\/|$)/,process.env.HOME??"").toLowerCase()}function gn(){let e=[],t=Ct(X)?Y():void 0,r=W();return e.push({label:"runtime",status:process.versions.bun?"pass":"fail",detail:process.versions.bun?`Bun ${process.versions.bun}`:"Bun is required"}),e.push({label:"api",status:"pass",detail:J()}),e.push({label:"session",status:r?"pass":"warn",detail:r?`logged in as ${r.user.login}`:"not logged in; run `atl login`"}),e.push({label:"state directory",status:"pass",detail:Rt}),e.push({label:"inventory",status:t?"pass":"warn",detail:t?`${t.summary.existing}/${t.summary.total} existing, generated ${t.generatedAt}`:"missing; run `atl scan`"}),e.push({label:"secret warnings",status:t&&t.summary.secrets>0?"warn":"pass",detail:t?`${t.summary.secrets} item${t.summary.secrets===1?"":"s"} flagged`:"no inventory"}),e}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manan_joshi/atelier",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Atelier config management CLI",
5
5
  "type": "module",
6
6
  "bin": {