@vee_stack/cli 6.3.9 → 6.3.10

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'module';import v from'chalk';import*as se from'fs';import {existsSync,readFileSync,statSync,writeFileSync}from'fs';import*as Ye from'path';import {resolve,basename,join,dirname}from'path';import {fileURLToPath}from'url';import {Command}from'commander';import {execSync}from'child_process';import*as de from'crypto';import de__default from'crypto';import ii from'ora';import {glob}from'glob';import ci from'cli-progress';import*as ct from'os';import {homedir}from'os';import*as j from'fs/promises';import _r from'prompts';import Ai from'readline';import {gzipSync}from'zlib';import Pi from'open';import Ia from'omelette';createRequire(import.meta.url); globalThis.CLI_VERSION = "6.3.9"; globalThis.SNAPSHOT_VERSION = "6.0.0"; globalThis.ENGINE_TARGET = "6.0.0"; globalThis.AUDIT_VERSION = "6.0"; globalThis.SESSION_PAYLOAD_VERSION = "6.0.0"; globalThis.RULES_VERSION = "6.0.0"; globalThis.ANALYSIS_VERSION = "6.0.0"; globalThis.API_VERSION = "v6"; globalThis.MIN_NODE = 20;
2
+ import {createRequire}from'module';import v from'chalk';import*as se from'fs';import {existsSync,readFileSync,statSync,writeFileSync}from'fs';import*as Ye from'path';import {resolve,basename,join,dirname}from'path';import {fileURLToPath}from'url';import {Command}from'commander';import {execSync}from'child_process';import*as de from'crypto';import de__default from'crypto';import ii from'ora';import {glob}from'glob';import ci from'cli-progress';import*as ct from'os';import {homedir}from'os';import*as L from'fs/promises';import _r from'prompts';import Ai from'readline';import {gzipSync}from'zlib';import Pi from'open';import Oa from'omelette';createRequire(import.meta.url); globalThis.CLI_VERSION = "6.3.10"; globalThis.SNAPSHOT_VERSION = "6.0.0"; globalThis.ENGINE_TARGET = "6.0.0"; globalThis.AUDIT_VERSION = "6.0"; globalThis.SESSION_PAYLOAD_VERSION = "6.0.0"; globalThis.RULES_VERSION = "6.0.0"; globalThis.ANALYSIS_VERSION = "6.0.0"; globalThis.API_VERSION = "v6"; globalThis.MIN_NODE = 20;
3
3
  var Zr=Object.defineProperty;var Kr=(t,e)=>{for(var n in e)Zr(t,n,{get:e[n],enumerable:true});};var Wr=[/^--token[=\s]/i,/^-t[=\s]/i,/^--api-key[=\s]/i,/^--apikey[=\s]/i,/^--key[=\s]/i,/^--auth[=\s]/i,/^--bearer[=\s]/i,/token[=:]\s*[a-zA-Z0-9_-]{10,}/i,/api[_-]?key[=:]\s*[a-zA-Z0-9_-]{10,}/i],Xe=/vs_[a-zA-Z0-9_-]{20,}/i;function $n(){let t=process.argv.slice(2);for(let e of t){for(let n of Wr)n.test(e)&&(console.error(v.red(`
4
4
  \u274C Security Error: Token detected in command line arguments`)),console.error(v.yellow(`
5
5
  Passing tokens via CLI arguments is not allowed.`)),console.error(v.yellow("This prevents tokens from being saved in shell history (~/.bash_history, ~/.zsh_history)")),console.error(v.gray(`
@@ -27,7 +27,7 @@ Please check your .env file and ensure all required variables are set.`)}throw t
27
27
  `,`x-nonce:${s}
28
28
  `,"host;x-timestamp;x-nonce",o].join(`
29
29
  `)}function No(t,e,n){let r=t.substring(0,10).replace(/-/g,""),s=de.createHash("sha256").update(n).digest("hex");return ["VEESTACK-HMAC-SHA256",t,`${r}/veestack/${e}/veestack_request`,s].join(`
30
- `)}function Oo(t,e,n,r){let s=e.substring(0,10).replace(/-/g,""),o=St("VEESTACK"+t,s),a=St(o,"veestack"),i=St(a,n),c=St(i,"veestack_request");return St(c,r,"hex")}function St(t,e,n){return de.createHmac("sha256",t).update(e).digest(n||"hex")}function Po(){return de.randomBytes(16).toString("hex")}var Bt=null;async function Ht(){if(Bt)return Bt;try{return Bt=await import('keytar'),Bt}catch{return null}}var At=Ye.join(ct.homedir(),".veestack"),ye=Ye.join(At,"tokens.enc"),ar=Ye.join(At,"salt"),cr=Ye.join(At,".key"),Jt="VeeStack CLI",Gt="auth_tokens",Do=1e5,jo=32,Lo=16;function zt(){return process.env.DEBUG?.includes("veestack")||process.env.DEBUG?.includes("*")||process.env.NODE_ENV==="development"||process.env.VEESTACK_DEBUG==="true"}async function $o(){try{let e=await j.readFile(ar).catch(()=>null);if(e)return e}catch{}let t=de.randomBytes(32);return await j.mkdir(At,{recursive:true,mode:448}),await j.writeFile(ar,t,{mode:384}),t}async function lr(){try{let r=await j.readFile(cr,"utf-8").catch(()=>null);if(r){let s=Buffer.from(r,"hex");return await j.unlink(cr).catch(()=>{}),s}}catch{}let t=`${ct.userInfo().username}@${ct.hostname()}`,e=await $o();return de.pbkdf2Sync(t,e,Do,jo,"sha256")}function Et(t){Buffer.isBuffer(t)&&t.fill(0);}async function xt(t){let e=await Ht();if(e)try{let l=JSON.stringify(t);await e.setPassword(Jt,Gt,l),zt()&&console.log(" Tokens saved to OS Keychain");return}catch(l){zt()&&console.log(" Keychain failed, falling back to encrypted file:",l);}let n=await lr(),r=de.randomBytes(Lo),s=de.createCipheriv("aes-256-gcm",n,r),o=JSON.stringify(t),a=Buffer.concat([s.update(o,"utf8"),s.final()]),i=s.getAuthTag(),c={iv:r.toString("hex"),data:a.toString("hex"),authTag:i.toString("hex"),timestamp:Date.now(),version:2};await j.mkdir(At,{recursive:true,mode:448}),await j.writeFile(ye,JSON.stringify(c),{mode:384}),Et(n),zt()&&console.log(" Tokens saved to encrypted file (AES-256-GCM)");}async function ur(){let t=await Ht();if(t)try{let e=await t.getPassword(Jt,Gt);if(e)return JSON.parse(e)}catch(e){zt()&&console.log("\u26A0\uFE0F Keychain read failed, trying encrypted file:",e);}try{let e=await j.readFile(ye,"utf-8"),n=JSON.parse(e);if(n.version===1)return await Vo(n);let r=await lr(),s=null;try{let o=Buffer.from(n.iv,"hex"),a=Buffer.from(n.data,"hex"),i=Buffer.from(n.authTag,"hex"),c=de.createDecipheriv("aes-256-gcm",r,o);c.setAuthTag(i),s=Buffer.concat([c.update(a),c.final()]);let l=JSON.parse(s.toString("utf8"));return Et(s),Et(r),l}catch(o){throw s&&Et(s),Et(r),o}}catch{return null}}async function Vo(t){try{return console.log("\u{1F510} Migrating from legacy encryption format..."),await j.unlink(ye).catch(()=>{}),null}catch{return null}}async function Zt(){try{return await j.access(ye),!0}catch{return false}}async function He(){try{let t=await j.stat(ye).catch(()=>null);if(!t)return;let e=t.size,n=3;for(let s=0;s<n;s++){let o=de.randomBytes(e);await j.writeFile(ye,o);}await j.unlink(ye);let r=await Ht();r&&await r.deletePassword(Jt,Gt).catch(()=>{});}catch{}}async function dr(){let t=await Ht(),e=!!t,n=false;if(t)try{n=!!await t.getPassword(Jt,Gt);}catch{}let r=false,s,o,a=0;try{let i=await j.stat(ye);r=!0,s=i.mode.toString(8),o=i.size;let c=await j.readFile(ye,"utf-8");a=JSON.parse(c).version||1;}catch{}return {keychainAvailable:e,keychainHasTokens:n,fileExists:r,filePermissions:s,fileSize:o,encryptionVersion:a}}var Mo=[{name:"bearer_token",regex:/Bearer\s+[a-zA-Z0-9_-]{20,}/gi,replacement:"Bearer [REDACTED]"},{name:"api_key",regex:/api[_-]?key['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"api_key: [REDACTED]"},{name:"access_token",regex:/access[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"access_token: [REDACTED]"},{name:"refresh_token",regex:/refresh[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"refresh_token: [REDACTED]"},{name:"auth_token",regex:/auth[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"auth_token: [REDACTED]"},{name:"password",regex:/password['"\s]*[:=]\s*['"]?([^'"\s]{8,})/gi,replacement:"password: [REDACTED]"},{name:"secret",regex:/secret['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"secret: [REDACTED]"},{name:"private_key",regex:/private[_-]?key['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"private_key: [REDACTED]"},{name:"jwt_token",regex:/eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,replacement:"[REDACTED_JWT]"},{name:"supabase_key",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g,replacement:"[REDACTED_SUPABASE_KEY]"}];function Je(t){if(!t||typeof t!="string")return t;let e=t;for(let n of Mo)e=e.replace(n.regex,n.replacement);return e}function vn(t){return t instanceof Error?Je(t.message).slice(0,500):typeof t=="string"?Je(t).slice(0,500):Je(String(t)).slice(0,500)}function Kt(t){if(!t||typeof t!="object")return t;let e=["token","accessToken","refreshToken","apiKey","api_key","secret","password","privateKey","private_key","authToken","auth_token","jwt","credential","credentials"];if(Array.isArray(t))return t.map(r=>Kt(r));let n={};for(let[r,s]of Object.entries(t)){let o=r.toLowerCase();e.some(a=>o.includes(a))?n[r]="[REDACTED]":typeof s=="object"&&s!==null?n[r]=Kt(s):typeof s=="string"?n[r]=Je(s):n[r]=s;}return n}function bt(t,e,...n){let r=Je(e),s=n.map(o=>typeof o=="string"?Je(o):typeof o=="object"&&o!==null?Kt(o):o);console[t](r,...s);}var ve={log:(t,...e)=>bt("log",t,...e),error:(t,...e)=>bt("error",t,...e),warn:(t,...e)=>bt("warn",t,...e),info:(t,...e)=>bt("info",t,...e),debug:(t,...e)=>bt("debug",t,...e)};var Uo=globalThis,fr=Uo.CLI_VERSION,_n=Ye.join(ct.homedir(),".veestack");Ye.join(_n,"config.json");var Wt=Ye.join(_n,"config.json"),pr=process.env.SUPABASE_URL||"",gr=process.env.SUPABASE_ANON_KEY||"",kn=pr?`${pr}/functions/v1/cli-auth`:null,Fo=process.env.VEESTACK_API_URL||"https://api.veestack.dev",mr=kn||Fo;async function zo(){try{if(!se.existsSync(Wt))return;let t=se.readFileSync(Wt,"utf-8"),e=JSON.parse(t);if(await Zt()){try{se.unlinkSync(Wt);}catch{}return}let n={token:e.token,refreshToken:e.refreshToken,tokenType:e.tokenType,tokenExpiresAt:e.tokenExpiresAt,device:e.device,user:e.user,subscription:e.subscription,lastLoginAt:e.lastLoginAt,apiKey:e.apiKey};await xt(n);try{se.unlinkSync(Wt);}catch{}ve.info("\u{1F510} Authentication migrated to encrypted storage");}catch{}}async function X(){await zo();let t=await ur();return t?{token:t.token,tokenType:t.tokenType,refreshToken:t.refreshToken,tokenExpiresAt:t.tokenExpiresAt,device:t.device,user:t.user,subscription:t.subscription,lastLoginAt:t.lastLoginAt,apiKey:t.apiKey}:null}async function Ze(){let t=await X();if(!t)return false;let e=t.token!==void 0&&t.token.length>0,n=t.apiKey!==void 0&&t.apiKey.length>0;return e||n}async function Ho(){let t=await X();return t&&(t.token||t.apiKey)||null}async function Jo(){let t=await X();return {id:t?.device?.id,fingerprint:t?.device?.fingerprint}}async function fe(t="GET",e="",n="",r=["project:read"]){let s=await Ho();if(!s)return {};let o=await X(),a=await Jo();if(!a.id||!a.fingerprint||!o?.refreshToken)return {};let i=or(o.refreshToken,a.fingerprint),c=ir(t,e,n,o.refreshToken,"cli");return {Authorization:`Bearer ${s}`,"Content-Type":"application/json","X-Device-ID":a.id,"X-CLI-Version":fr||"unknown","X-Device-Fingerprint":a.fingerprint,"X-Token-Binding":i,"X-Signature":c.signature,"X-Timestamp":c.timestamp,"X-Nonce":c.nonce,"X-Scope":r.join(","),"X-Security-Version":fr||"unknown"}}function wn(t){if(!t.tokenExpiresAt)return true;let e=new Date(t.tokenExpiresAt),n=300*1e3;return Date.now()>=e.getTime()-n}async function Go(t){if(!t.refreshToken)return null;try{let e={"Content-Type":"application/json"};gr&&(e.Authorization=`Bearer ${gr}`);let n=JSON.stringify(kn?{action:"refresh_tokens",refresh_token:t.refreshToken,device_id:t.device?.id}:{refresh_token:t.refreshToken,device_id:t.device?.id,device_fingerprint:t.device?.fingerprint}),r=kn?mr:`${mr}/api/cli/refresh`,s=await fetch(r,{method:"POST",headers:e,body:n});if(s.status===401){let i=await s.json().catch(()=>({}));throw i.code==="device_mismatch"&&(await He(),console.log(v.red(`
30
+ `)}function Oo(t,e,n,r){let s=e.substring(0,10).replace(/-/g,""),o=St("VEESTACK"+t,s),a=St(o,"veestack"),i=St(a,n),c=St(i,"veestack_request");return St(c,r,"hex")}function St(t,e,n){return de.createHmac("sha256",t).update(e).digest(n||"hex")}function Po(){return de.randomBytes(16).toString("hex")}var Bt=null;async function Ht(){if(Bt)return Bt;try{return Bt=await import('keytar'),Bt}catch{return null}}var At=Ye.join(ct.homedir(),".veestack"),ye=Ye.join(At,"tokens.enc"),ar=Ye.join(At,"salt"),cr=Ye.join(At,".key"),Jt="VeeStack CLI",Gt="auth_tokens",Do=1e5,jo=32,Lo=16;function zt(){return process.env.DEBUG?.includes("veestack")||process.env.DEBUG?.includes("*")||process.env.NODE_ENV==="development"||process.env.VEESTACK_DEBUG==="true"}async function $o(){try{let e=await L.readFile(ar).catch(()=>null);if(e)return e}catch{}let t=de.randomBytes(32);return await L.mkdir(At,{recursive:true,mode:448}),await L.writeFile(ar,t,{mode:384}),t}async function lr(){try{let r=await L.readFile(cr,"utf-8").catch(()=>null);if(r){let s=Buffer.from(r,"hex");return await L.unlink(cr).catch(()=>{}),s}}catch{}let t=`${ct.userInfo().username}@${ct.hostname()}`,e=await $o();return de.pbkdf2Sync(t,e,Do,jo,"sha256")}function Et(t){Buffer.isBuffer(t)&&t.fill(0);}async function xt(t){let e=await Ht();if(e)try{let l=JSON.stringify(t);await e.setPassword(Jt,Gt,l),zt()&&console.log(" Tokens saved to OS Keychain");return}catch(l){zt()&&console.log(" Keychain failed, falling back to encrypted file:",l);}let n=await lr(),r=de.randomBytes(Lo),s=de.createCipheriv("aes-256-gcm",n,r),o=JSON.stringify(t),a=Buffer.concat([s.update(o,"utf8"),s.final()]),i=s.getAuthTag(),c={iv:r.toString("hex"),data:a.toString("hex"),authTag:i.toString("hex"),timestamp:Date.now(),version:2};await L.mkdir(At,{recursive:true,mode:448}),await L.writeFile(ye,JSON.stringify(c),{mode:384}),Et(n),zt()&&console.log(" Tokens saved to encrypted file (AES-256-GCM)");}async function ur(){let t=await Ht();if(t)try{let e=await t.getPassword(Jt,Gt);if(e)return JSON.parse(e)}catch(e){zt()&&console.log("\u26A0\uFE0F Keychain read failed, trying encrypted file:",e);}try{let e=await L.readFile(ye,"utf-8"),n=JSON.parse(e);if(n.version===1)return await Vo(n);let r=await lr(),s=null;try{let o=Buffer.from(n.iv,"hex"),a=Buffer.from(n.data,"hex"),i=Buffer.from(n.authTag,"hex"),c=de.createDecipheriv("aes-256-gcm",r,o);c.setAuthTag(i),s=Buffer.concat([c.update(a),c.final()]);let l=JSON.parse(s.toString("utf8"));return Et(s),Et(r),l}catch(o){throw s&&Et(s),Et(r),o}}catch{return null}}async function Vo(t){try{return console.log("\u{1F510} Migrating from legacy encryption format..."),await L.unlink(ye).catch(()=>{}),null}catch{return null}}async function Zt(){try{return await L.access(ye),!0}catch{return false}}async function He(){try{let t=await L.stat(ye).catch(()=>null);if(!t)return;let e=t.size,n=3;for(let s=0;s<n;s++){let o=de.randomBytes(e);await L.writeFile(ye,o);}await L.unlink(ye);let r=await Ht();r&&await r.deletePassword(Jt,Gt).catch(()=>{});}catch{}}async function dr(){let t=await Ht(),e=!!t,n=false;if(t)try{n=!!await t.getPassword(Jt,Gt);}catch{}let r=false,s,o,a=0;try{let i=await L.stat(ye);r=!0,s=i.mode.toString(8),o=i.size;let c=await L.readFile(ye,"utf-8");a=JSON.parse(c).version||1;}catch{}return {keychainAvailable:e,keychainHasTokens:n,fileExists:r,filePermissions:s,fileSize:o,encryptionVersion:a}}var Mo=[{name:"bearer_token",regex:/Bearer\s+[a-zA-Z0-9_-]{20,}/gi,replacement:"Bearer [REDACTED]"},{name:"api_key",regex:/api[_-]?key['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"api_key: [REDACTED]"},{name:"access_token",regex:/access[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"access_token: [REDACTED]"},{name:"refresh_token",regex:/refresh[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"refresh_token: [REDACTED]"},{name:"auth_token",regex:/auth[_-]?token['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"auth_token: [REDACTED]"},{name:"password",regex:/password['"\s]*[:=]\s*['"]?([^'"\s]{8,})/gi,replacement:"password: [REDACTED]"},{name:"secret",regex:/secret['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"secret: [REDACTED]"},{name:"private_key",regex:/private[_-]?key['"\s]*[:=]\s*['"]?([a-zA-Z0-9_-]{16,})/gi,replacement:"private_key: [REDACTED]"},{name:"jwt_token",regex:/eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/g,replacement:"[REDACTED_JWT]"},{name:"supabase_key",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g,replacement:"[REDACTED_SUPABASE_KEY]"}];function Je(t){if(!t||typeof t!="string")return t;let e=t;for(let n of Mo)e=e.replace(n.regex,n.replacement);return e}function vn(t){return t instanceof Error?Je(t.message).slice(0,500):typeof t=="string"?Je(t).slice(0,500):Je(String(t)).slice(0,500)}function Kt(t){if(!t||typeof t!="object")return t;let e=["token","accessToken","refreshToken","apiKey","api_key","secret","password","privateKey","private_key","authToken","auth_token","jwt","credential","credentials"];if(Array.isArray(t))return t.map(r=>Kt(r));let n={};for(let[r,s]of Object.entries(t)){let o=r.toLowerCase();e.some(a=>o.includes(a))?n[r]="[REDACTED]":typeof s=="object"&&s!==null?n[r]=Kt(s):typeof s=="string"?n[r]=Je(s):n[r]=s;}return n}function bt(t,e,...n){let r=Je(e),s=n.map(o=>typeof o=="string"?Je(o):typeof o=="object"&&o!==null?Kt(o):o);console[t](r,...s);}var ve={log:(t,...e)=>bt("log",t,...e),error:(t,...e)=>bt("error",t,...e),warn:(t,...e)=>bt("warn",t,...e),info:(t,...e)=>bt("info",t,...e),debug:(t,...e)=>bt("debug",t,...e)};var Uo=globalThis,fr=Uo.CLI_VERSION,_n=Ye.join(ct.homedir(),".veestack");Ye.join(_n,"config.json");var Wt=Ye.join(_n,"config.json"),pr=process.env.SUPABASE_URL||"",gr=process.env.SUPABASE_ANON_KEY||"",kn=pr?`${pr}/functions/v1/cli-auth`:null,Fo=process.env.VEESTACK_API_URL||"https://api.veestack.dev",mr=kn||Fo;async function zo(){try{if(!se.existsSync(Wt))return;let t=se.readFileSync(Wt,"utf-8"),e=JSON.parse(t);if(await Zt()){try{se.unlinkSync(Wt);}catch{}return}let n={token:e.token,refreshToken:e.refreshToken,tokenType:e.tokenType,tokenExpiresAt:e.tokenExpiresAt,device:e.device,user:e.user,subscription:e.subscription,lastLoginAt:e.lastLoginAt,apiKey:e.apiKey};await xt(n);try{se.unlinkSync(Wt);}catch{}ve.info("\u{1F510} Authentication migrated to encrypted storage");}catch{}}async function X(){await zo();let t=await ur();return t?{token:t.token,tokenType:t.tokenType,refreshToken:t.refreshToken,tokenExpiresAt:t.tokenExpiresAt,device:t.device,user:t.user,subscription:t.subscription,lastLoginAt:t.lastLoginAt,apiKey:t.apiKey}:null}async function Ze(){let t=await X();if(!t)return false;let e=t.token!==void 0&&t.token.length>0,n=t.apiKey!==void 0&&t.apiKey.length>0;return e||n}async function Ho(){let t=await X();return t&&(t.token||t.apiKey)||null}async function Jo(){let t=await X();return {id:t?.device?.id,fingerprint:t?.device?.fingerprint}}async function fe(t="GET",e="",n="",r=["project:read"]){let s=await Ho();if(!s)return {};let o=await X(),a=await Jo();if(!a.id||!a.fingerprint||!o?.refreshToken)return {};let i=or(o.refreshToken,a.fingerprint),c=ir(t,e,n,o.refreshToken,"cli");return {Authorization:`Bearer ${s}`,"Content-Type":"application/json","X-Device-ID":a.id,"X-CLI-Version":fr||"unknown","X-Device-Fingerprint":a.fingerprint,"X-Token-Binding":i,"X-Signature":c.signature,"X-Timestamp":c.timestamp,"X-Nonce":c.nonce,"X-Scope":r.join(","),"X-Security-Version":fr||"unknown"}}function wn(t){if(!t.tokenExpiresAt)return true;let e=new Date(t.tokenExpiresAt),n=300*1e3;return Date.now()>=e.getTime()-n}async function Go(t){if(!t.refreshToken)return null;try{let e={"Content-Type":"application/json"};gr&&(e.Authorization=`Bearer ${gr}`);let n=JSON.stringify(kn?{action:"refresh_tokens",refresh_token:t.refreshToken,device_id:t.device?.id}:{refresh_token:t.refreshToken,device_id:t.device?.id,device_fingerprint:t.device?.fingerprint}),r=kn?mr:`${mr}/api/cli/refresh`,s=await fetch(r,{method:"POST",headers:e,body:n});if(s.status===401){let i=await s.json().catch(()=>({}));throw i.code==="device_mismatch"&&(await He(),console.log(v.red(`
31
31
  \u274C Security Alert: Device mismatch`)),console.log(v.yellow(`
32
32
  Your token was used from a different device.`)),console.log(v.gray("This could indicate a token theft attempt.")),console.log(v.gray("Please login again:")),console.log(v.cyan(" veestack login")),process.exit(1)),i.code==="device_revoked"&&(await He(),console.log(v.red(`
33
33
  \u274C Device authorization revoked`)),console.log(v.yellow(`
@@ -65,13 +65,13 @@ VeeStack Security Scan`)),console.log(v.gray("\u2500".repeat(40))));await Ze();i
65
65
  Using smart defaults for this scan...`));}}let l=ii({text:"Preparing scan...",spinner:"dots",stream:process.stdout});e||(console.log(`
66
66
  `+v.bold.cyan("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501")),console.log(v.bold.white(" Analyzing Project")),console.log(v.bold.cyan(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
67
67
  `)),l.start());try{let d=Date.now(),x=existsSync(i)?JSON.parse(readFileSync(i,"utf-8")):{},O=x.scanPatterns||["**/*.{js,jsx,ts,tsx,json,py,go,rs,rb,php,cs,cpp,c,h,mjs,cjs,svelte,vue,html}"],C=x.excludePatterns||["**/node_modules/**","**/.next/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**","**/*.test.ts","**/*.spec.ts"],R=await _i(r,O,C,t.diff);if(R.length===0&&!t.json){e||console.log(v.yellow(`
68
- \u26A0 No source files found to scan.`));return}let $=new ci.SingleBar({format:"Scanning |"+v.cyan("{bar}")+"| {percentage}% ({value}/{total} files)",barCompleteChar:"\u2588",barIncompleteChar:"\u2591",hideCursor:!0});e||$.start(R.length,0);let V=await Hn(r,R.map(Y=>Y.path));e||($.update(Math.floor(R.length*.5)),l.text="Analyzing security...");let D=vi(R.length,V),mt=`report-${o}-security.json`;if(V.secretsFound&&V.secretsFound.length>0){let Y={project:o,directory:s,timestamp:new Date().toISOString(),score:D.score,grade:D.grade,criticalIssues:V.criticalCount,issues:V.secretsFound};await(await import('fs/promises')).writeFile(mt,JSON.stringify(Y,null,2));}t.json&&(console.log(JSON.stringify({version:ui,timestamp:new Date().toISOString(),score:D.score,grade:D.grade,files:R.length,issues:D.breakdown,project:o,directory:s},null,2)),process.exit(0)),V.criticalCount>0&&(e||($.stop(),l.fail("Security validation failed"),console.log(v.red(`
68
+ \u26A0 No source files found to scan.`));return}let $=new ci.SingleBar({format:"Scanning |"+v.cyan("{bar}")+"| {percentage}% ({value}/{total} files)",barCompleteChar:"\u2588",barIncompleteChar:"\u2591",hideCursor:!0});e||$.start(R.length,0);let V=await Hn(r,R.map(Y=>Y.path));e||($.update(Math.floor(R.length*.5)),l.text="Analyzing security...");let j=vi(R.length,V),mt=`report-${o}-security.json`;if(V.secretsFound&&V.secretsFound.length>0){let Y={project:o,directory:s,timestamp:new Date().toISOString(),score:j.score,grade:j.grade,criticalIssues:V.criticalCount,issues:V.secretsFound};await(await import('fs/promises')).writeFile(mt,JSON.stringify(Y,null,2));}t.json&&(console.log(JSON.stringify({version:ui,timestamp:new Date().toISOString(),score:j.score,grade:j.grade,files:R.length,issues:j.breakdown,project:o,directory:s},null,2)),process.exit(0)),V.criticalCount>0&&(e||($.stop(),l.fail("Security validation failed"),console.log(v.red(`
69
69
  \u274C ${V.criticalCount} Critical security risks detected.`)),V.secretsFound&&V.secretsFound.length>0&&(console.log(v.gray(`
70
70
  Issues detail:`)),V.secretsFound.slice(0,5).forEach(Y=>{console.log(v.yellow(` \u2022 ${Y.ruleId}: `)+v.gray(`${Y.filePath}:${Y.line}`));}),V.secretsFound.length>5&&console.log(v.gray(` ... and ${V.secretsFound.length-5} more issues.`))),console.log(v.cyan(`
71
71
  \u{1F4C4} Detailed report saved to: ${mt}`)),console.log(v.yellow(`
72
72
  For your protection, local snapshot generation is blocked.`)),console.log(v.gray(`
73
- \u2139 Recommended actions:`)),console.log(v.gray(" 1. Open the affected file(s) and review the reported security issue.")),console.log(v.gray(" 2. Fix the vulnerability or sensitive data exposure.")),console.log(v.gray(" 3. Run 'veestack scan' again.")),process.exit(1)));let{safe:B}=Jn(R.map(Y=>Y.path)),ie=await Si(r,R.filter(Y=>B.includes(Y.path)));if(e||($.update(R.length),$.stop(),l.succeed(`Analysis prepared in ${((Date.now()-d)/1e3).toFixed(1)}s`)),e)console.log(v.green(`\u2714 Scan completed. Score: ${D.grade}`));else {console.log(v.gray(`
74
- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`)),console.log(v.bold.cyan(" Security Summary")),console.log(v.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(v.gray("Project: "),v.white(o)),o!==s&&console.log(v.gray("Directory: "),v.white(s));let Y=D.score>=90?v.green:D.score>=70?v.yellow:v.red;console.log(v.gray("Score: "),Y(`${D.score} Grade: ${D.grade}`)),console.log(v.gray("Issues found: "),v.white(`${D.breakdown.critical+D.breakdown.high+D.breakdown.medium+D.breakdown.low}`)),console.log(v.gray("Dependencies: "),v.white(ie.metadata.total_dependencies)),console.log(v.gray("Files: "),v.white(R.length)),console.log(v.gray(`
73
+ \u2139 Recommended actions:`)),console.log(v.gray(" 1. Open the affected file(s) and review the reported security issue.")),console.log(v.gray(" 2. Fix the vulnerability or sensitive data exposure.")),console.log(v.gray(" 3. Run 'veestack scan' again.")),process.exit(1)));let{safe:B}=Jn(R.map(Y=>Y.path)),ie=await Si(r,R.filter(Y=>B.includes(Y.path)));if(e||($.update(R.length),$.stop(),l.succeed(`Analysis prepared in ${((Date.now()-d)/1e3).toFixed(1)}s`)),e)console.log(v.green(`\u2714 Scan completed. Score: ${j.grade}`));else {console.log(v.gray(`
74
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`)),console.log(v.bold.cyan(" Security Summary")),console.log(v.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(v.gray("Project: "),v.white(o)),o!==s&&console.log(v.gray("Directory: "),v.white(s));let Y=j.score>=90?v.green:j.score>=70?v.yellow:v.red;console.log(v.gray("Score: "),Y(`${j.score} Grade: ${j.grade}`)),console.log(v.gray("Issues found: "),v.white(`${j.breakdown.critical+j.breakdown.high+j.breakdown.medium+j.breakdown.low}`)),console.log(v.gray("Dependencies: "),v.white(ie.metadata.total_dependencies)),console.log(v.gray("Files: "),v.white(R.length)),console.log(v.gray(`
75
75
  Next steps:`)),console.log(v.gray(" 1. Upload results to dashboard:")),console.log(v.cyan(" veestack login")),console.log(v.cyan(" veestack upload")),console.log(v.gray(`
76
76
  2. View detailed report:`)),console.log(v.cyan(` ${t.output}`)),console.log(v.gray(`
77
77
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -95,69 +95,71 @@ Enter project name: `);if(r.trim()){let s=await xr(r.trim());if(s)return console
95
95
  \u{1F510} Authentication verified`)),r.user&&console.log(v.gray(`User: ${r.user.name}`)),console.log(v.gray(`Subscription tier: ${s==="pro"?"Pro":"Free"}`)),console.log(v.gray("\u2500".repeat(40)+`
96
96
  `)));let o=ii({text:"Preparing upload...",isSilent:n}).start();try{let a=await import('fs/promises');existsSync(t.file)||(o.fail(`File not found: ${t.file}`),n||console.log(v.yellow(`
97
97
  Tip: Run "veestack scan" first to generate a snapshot.`)),process.exit(1));let i=await a.readFile(t.file,"utf-8"),c=JSON.parse(i),l=t.projectId||process.env.VEESTACK_PROJECT_ID;if(!l){n&&(o.fail("Project ID is required in CI mode. Please set VEESTACK_PROJECT_ID."),process.exit(1)),o.stop();let ie=await Ci();ie||(console.log(v.red(`
98
- \u274C No project selected. Exiting.`)),process.exit(1)),l=ie,o.start("Uploading snapshot...");}o.text="Compressing and uploading snapshot...";let d=gzipSync(JSON.stringify(c)).toString("base64"),x=JSON.stringify({project_id:l,snapshot:d,compressed:!0,encoding:"base64"}),O=await fe("POST","/api/snapshots/upload",x),C=await xn(`${An}/api/snapshots/upload`,{method:"POST",headers:O,body:x});if(!C.ok){let ie=await C.json().catch(()=>({}));o.fail("Upload failed"),console.error(v.red(`Error: ${ie.message||ie.error||"Server error"}`)),process.exit(1);}let R=await C.json(),{snapshotId:$,reportId:V,score:D,severity:mt,findings:B}=R;if(o.succeed("Analysis complete"),n)console.log(`\u2714 Upload successful. Report: ${Ar}/reports/${V}?project=${l}`);else {console.log(v.green(`
98
+ \u274C No project selected. Exiting.`)),process.exit(1)),l=ie,o.start("Uploading snapshot...");}o.text="Compressing and uploading snapshot...";let d=gzipSync(JSON.stringify(c)).toString("base64"),x=JSON.stringify({project_id:l,snapshot:d,compressed:!0,encoding:"base64"}),O=await fe("POST","/api/snapshots/upload",x),C=await xn(`${An}/api/snapshots/upload`,{method:"POST",headers:O,body:x});if(!C.ok){let ie=await C.json().catch(()=>({}));o.fail("Upload failed"),console.error(v.red(`Error: ${ie.message||ie.error||"Server error"}`)),process.exit(1);}let R=await C.json(),{snapshotId:$,reportId:V,score:j,severity:mt,findings:B}=R;if(o.succeed("Analysis complete"),n)console.log(`\u2714 Upload successful. Report: ${Ar}/reports/${V}?project=${l}`);else {console.log(v.green(`
99
99
  \u2705 Report generated and saved to VeeStack`)),console.log(v.gray("Project ID: "),v.white(l)),console.log(v.gray("Snapshot ID: "),v.white($)),console.log(v.gray("Report ID: "),v.white(V)),console.log(v.bold(`
100
- \u{1F4CA} Security Score:`),D>=90?v.green(D):D>=70?v.yellow(D):v.red(D)),console.log(v.gray("Severity: "),mt),console.log(v.gray("Findings: "),B);let ie=`${Ar}/reports/${V}?project=${l}`;console.log(v.blue(`
100
+ \u{1F4CA} Security Score:`),j>=90?v.green(j):j>=70?v.yellow(j):v.red(j)),console.log(v.gray("Severity: "),mt),console.log(v.gray("Findings: "),B);let ie=`${Ar}/reports/${V}?project=${l}`;console.log(v.blue(`
101
101
  \u{1F517} View your full report at:`)),console.log(v.underline(ie));}}catch(a){o.fail("Upload failed"),console.error(a),process.exit(1);}}var Ii=process.env.VEESTACK_API_URL||"https://api.veestack.dev";async function br(t){t.format==="sarif"?await Ni(t):console.log(v.red('\u274C Unsupported format. Currently only "sarif" is supported.'));}async function Ni(t){await xe()||(console.error(v.red("\u274C Authentication required. Please login first.")),process.exit(1));let n=t.reportId;n||(console.error(v.red("\u274C Report ID is required for SARIF export.")),process.exit(1)),console.log(v.blue(`
102
102
  \u{1F4CA} Fetching report ${n} for SARIF export...`));try{let r=await fe("GET",`/api/reports/${n}/sarif`),s=await fetch(`${Ii}/api/reports/${n}/sarif`,{headers:r});if(!s.ok){let c=await s.json().catch(()=>({}));throw new Error(c.message||"Failed to fetch SARIF report")}let o=await s.json(),a=t.output||"veestack-results.sarif";await(await import('fs/promises')).writeFile(a,JSON.stringify(o,null,2)),console.log(v.green(`
103
103
  \u2705 SARIF report exported to: ${a}`)),console.log(v.gray("You can now upload this to GitHub Security Tab."));}catch(r){console.error(v.red(`
104
- \u274C Export failed:`),r instanceof Error?r.message:r),process.exit(1);}}var Di=globalThis,ji=Di.CLI_VERSION||"unknown",Rr=process.env.SUPABASE_URL||"",en=process.env.SUPABASE_ANON_KEY||"",gt=Rr?`${Rr}/functions/v1/cli-auth`:null,Li=process.env.VEESTACK_API_URL||"https://api.veestack.dev",tn=gt||Li,$i=process.env.VEESTACK_WEB_URL||"https://www.veestack.com",Vi=2e3,Ir=300;function Mi(){return de__default.randomBytes(16).toString("hex")}function Ui(){let t=de__default.randomBytes(32).toString("base64url"),e=de__default.createHash("sha256").update(t).digest("base64url");return {code_verifier:t,code_challenge:e}}function Fi(){let t=process.platform,e=ct.hostname(),n=ji,r=e||de__default.randomBytes(8).toString("hex"),s=de__default.createHash("sha256").update(`${r}:${t}:${n}`).digest("hex"),o=de__default.randomBytes(12).toString("hex"),a=`${e||"Unknown"} (${t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"})`;return {id:o,name:a,fingerprint:s,os:t,version:n}}async function Bi(t,e){let n=Mi();try{let r={"Content-Type":"application/json"};en&&(r.Authorization=`Bearer ${en}`);let s=JSON.stringify(gt?{action:"register_device",device_code:n,code_challenge:t.code_challenge,code_challenge_method:"S256",device_info:e}:{device_code:n,client_id:"veestack-cli",code_challenge:t.code_challenge,code_challenge_method:"S256",device_info:e}),o=await fetch(`${tn}${gt?"":"/api/cli/device"}`,{method:"POST",headers:r,body:s});if(!o.ok){let i=await o.text().catch(()=>"");throw o.status===403&&(i.includes("Vercel Security Checkpoint")||i.includes("We're verifying your browser"))?new Error(`Authentication failed (HTTP 403)
104
+ \u274C Export failed:`),r instanceof Error?r.message:r),process.exit(1);}}var ji=globalThis,Li=ji.CLI_VERSION||"unknown",Rr=process.env.SUPABASE_URL||"",en=process.env.SUPABASE_ANON_KEY||"",gt=Rr?`${Rr}/functions/v1/cli-auth`:null,$i=process.env.VEESTACK_API_URL||"https://api.veestack.dev",tn=gt||$i,Vi=process.env.VEESTACK_WEB_URL||"https://www.veestack.com",Mi=2e3,Ir=300;function Ui(){return new Promise(t=>{let e=Ai.createInterface({input:process.stdin,output:process.stdout});e.question("",()=>{e.close(),t();});})}function Fi(){return de__default.randomBytes(16).toString("hex")}function Bi(){let t=de__default.randomBytes(32).toString("base64url"),e=de__default.createHash("sha256").update(t).digest("base64url");return {code_verifier:t,code_challenge:e}}function zi(){let t=process.platform,e=ct.hostname(),n=Li,r=e||de__default.randomBytes(8).toString("hex"),s=de__default.createHash("sha256").update(`${r}:${t}:${n}`).digest("hex"),o=de__default.randomBytes(12).toString("hex"),a=`${e||"Unknown"} (${t==="win32"?"Windows":t==="darwin"?"macOS":"Linux"})`;return {id:o,name:a,fingerprint:s,os:t,version:n}}async function Hi(t,e){let n=Fi();try{let r={"Content-Type":"application/json"};en&&(r.Authorization=`Bearer ${en}`);let s=JSON.stringify(gt?{action:"register_device",device_code:n,code_challenge:t.code_challenge,code_challenge_method:"S256",device_info:e}:{device_code:n,client_id:"veestack-cli",code_challenge:t.code_challenge,code_challenge_method:"S256",device_info:e}),o=await fetch(`${tn}${gt?"":"/api/cli/device"}`,{method:"POST",headers:r,body:s});if(!o.ok){let i=await o.text().catch(()=>"");throw o.status===403&&(i.includes("Vercel Security Checkpoint")||i.includes("We're verifying your browser"))?new Error(`Authentication failed (HTTP 403)
105
105
 
106
106
  Your API endpoint blocked the request.
107
107
  Check VEESTACK_API_URL`):new Error(`Server returned ${o.status} ${o.statusText}: ${i||"No detail provided"}`)}return await o.json()}catch(r){throw r instanceof Error?r.message.includes("fetch failed")||r.name==="TypeError"?new Error(`Could not connect to VeeStack API at ${tn}.
108
- Please check your internet connection or verify if the API is reachable.`):r:new Error("An unexpected network error occurred while connecting to VeeStack.")}}async function zi(t,e,n){try{let r={"Content-Type":"application/json"};en&&(r.Authorization=`Bearer ${en}`);let s=gt?JSON.stringify({action:"poll_token",device_code:t,code_verifier:e}):void 0,o=gt?tn:`${tn}/api/cli/token?device_code=${t}&code_verifier=${e}`,a=await fetch(o,{method:gt?"POST":"GET",headers:r,body:s});if(a.status===202)return null;if(!a.ok)throw new Error(`Failed to poll for token: ${a.statusText}`);return a.json()}catch{if(n>=Ir)throw new Error("Authentication timeout. Please try again.");return null}}async function Rt(){console.log(v.bold.cyan(`
108
+ Please check your internet connection or verify if the API is reachable.`):r:new Error("An unexpected network error occurred while connecting to VeeStack.")}}async function Ji(t,e,n){try{let r={"Content-Type":"application/json"};en&&(r.Authorization=`Bearer ${en}`);let s=gt?JSON.stringify({action:"poll_token",device_code:t,code_verifier:e}):void 0,o=gt?tn:`${tn}/api/cli/token?device_code=${t}&code_verifier=${e}`,a=await fetch(o,{method:gt?"POST":"GET",headers:r,body:s});if(a.status===202)return null;if(!a.ok)throw new Error(`Failed to poll for token: ${a.statusText}`);return a.json()}catch{if(n>=Ir)throw new Error("Authentication timeout. Please try again.");return null}}async function Rt(){console.log(v.bold.cyan(`
109
109
  \u{1F510} Login to VeeStack
110
- `));let t=ii({text:"Requesting device code...",spinner:"dots",stream:process.stdout});try{let e=Ui(),n=Fi();t.start();let r=await Bi(e,n);t.stop();let s=`${$i}/cli-auth?device=${r.device_code}&code=${r.user_code}&challenge=${e.code_challenge}`;console.log(v.white("Opening browser to authenticate...")),console.log(v.gray(`
110
+ `));let t=ii({text:"Requesting device code...",spinner:"dots",stream:process.stdout});try{let e=Bi(),n=zi();t.start();let r=await Hi(e,n);t.stop(),console.log(v.yellow(`
111
+ Hello from VeeStack! Press Enter to open browser and login automatically.
112
+ `)),await Ui();let s=`${Vi}/cli-auth?device=${r.device_code}&code=${r.user_code}&challenge=${e.code_challenge}`;console.log(v.white("Opening browser to authenticate...")),console.log(v.gray(`
111
113
  Verification code: `)+v.bold.cyan(r.user_code)),console.log(v.gray(`
112
114
  Waiting for authentication...`)),console.log(v.gray(`(Press Ctrl+C to cancel)
113
- `)),await Pi(s);let o=0,a=null;for(t.start("Checking authentication status...");!a&&o<Ir;)await new Promise(c=>setTimeout(c,Vi)),a=await zi(r.device_code,e.code_verifier,o),o++,a||(t.text=`Checking authentication status... (${o*2}s)`);a||(t.fail("Authentication timeout"),console.log(v.red(`
115
+ `)),await Pi(s);let o=0,a=null;for(t.start("Checking authentication status...");!a&&o<Ir;)await new Promise(c=>setTimeout(c,Mi)),a=await Ji(r.device_code,e.code_verifier,o),o++,a||(t.text=`Checking authentication status... (${o*2}s)`);a||(t.fail("Authentication timeout"),console.log(v.red(`
114
116
  \u274C Authentication timed out after 10 minutes.`)),console.log(v.yellow("Please try again with: veestack login")),process.exit(1)),t.succeed("Authentication successful");let i={token:a.access_token,tokenType:a.token_type,refreshToken:a.refresh_token,tokenExpiresAt:new Date(Date.now()+a.expires_in*1e3).toISOString(),device:{id:n.id,name:n.name,fingerprint:n.fingerprint},user:{id:a.user.id,email:a.user.email,name:a.user.name,provider:a.user.provider},subscription:a.subscription||{tier:"free",isActive:!0},lastLoginAt:new Date().toISOString()};try{await xt(i),console.log(v.green(`
115
117
  \u2714 Authentication successful
116
118
  `)),console.log(v.gray("Account: ")+v.white(i.user.name)),console.log(v.gray("Email: ")+v.white(i.user.email)),console.log(v.gray("Device: ")+v.white(i.device.name)),console.log(v.gray("Subscription: ")+(i.subscription?.tier==="pro"?v.cyan("Pro"):v.blue("Free"))),console.log(v.gray(`
117
119
  Token saved securely to OS Keychain
118
120
  `)),kr({token:i.token,tokenType:i.tokenType,refreshToken:i.refreshToken,tokenExpiresAt:i.tokenExpiresAt,device:i.device,user:i.user,subscription:i.subscription,lastLoginAt:i.lastLoginAt});}catch(c){t.fail("Failed to save authentication"),console.error(v.red(`
119
121
  \u274C Could not securely store tokens:`),c),process.exit(1);}}catch(e){t.fail("Authentication failed"),console.error(v.red(`
120
- \u274C Error:`),e instanceof Error?e.message:e),process.exit(1);}}var Hi=process.env.VEESTACK_API_URL||"https://api.veestack.dev";async function Nr(){try{let t=await X();if(!t){console.log(v.yellow("\u26A0\uFE0F Not logged in"));return}if(console.log(v.bold.cyan(`
122
+ \u274C Error:`),e instanceof Error?e.message:e),process.exit(1);}}var Gi=process.env.VEESTACK_API_URL||"https://api.veestack.dev";async function Nr(){try{let t=await X();if(!t){console.log(v.yellow("\u26A0\uFE0F Not logged in"));return}if(console.log(v.bold.cyan(`
121
123
  \u{1F6AA} Logout from VeeStack
122
- `)),t.token||t.apiKey)try{let e=t.token||t.apiKey;await fetch(`${Hi}/api/cli/logout`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({device_id:t.device?.id})});}catch{}await Zt()&&await He();try{let{existsSync:e,unlinkSync:n}=await import('fs'),{join:r}=await import('path'),{homedir:s}=await import('os'),o=r(s(),".veestack"),a=r(o,"config.json");e(a)&&n(a);}catch{}t.user?console.log(v.green(`\u2714 Logged out ${t.user.name}`)):console.log(v.green("\u2714 Logged out")),console.log(v.gray(`
124
+ `)),t.token||t.apiKey)try{let e=t.token||t.apiKey;await fetch(`${Gi}/api/cli/logout`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({device_id:t.device?.id})});}catch{}await Zt()&&await He();try{let{existsSync:e,unlinkSync:n}=await import('fs'),{join:r}=await import('path'),{homedir:s}=await import('os'),o=r(s(),".veestack"),a=r(o,"config.json");e(a)&&n(a);}catch{}t.user?console.log(v.green(`\u2714 Logged out ${t.user.name}`)):console.log(v.green("\u2714 Logged out")),console.log(v.gray(`
123
125
  \u{1F510} All local tokens securely deleted`)),console.log(v.gray("See you soon! \u{1F44B}")),console.log(v.gray(`Run "veestack login" to authenticate again.
124
126
  `));}catch(t){ve.error("\u274C Error during logout:",vn(t)),process.exit(1);}}async function Or(){try{let t=await xe();t||(console.log(v.yellow("\u26A0\uFE0F Not authenticated")),console.log(v.gray(`
125
127
  Please login first:`)),console.log(v.cyan(" veestack login")),process.exit(1)),console.log(v.bold.cyan(`
126
128
  \u{1F464} VeeStack Account
127
- `)),t.user&&(console.log(v.gray("User: ")+v.white(t.user.name)),console.log(v.gray("Email: ")+v.white(t.user.email)),console.log(v.gray("Provider: ")+v.cyan(t.user.provider))),t.device&&(console.log(v.gray("Device: ")+v.white(t.device.name)),console.log(v.gray("Device ID: ")+v.gray(t.device.id.substring(0,8)+"...")));let e=t.subscription?.tier||"free";if(console.log(v.gray("Subscription: ")+(e==="pro"?v.cyan("Pro"):v.blue("Free"))),t.tokenExpiresAt){let r=wn(t)?v.red("Expired (will refresh)"):v.green("Valid");console.log(v.gray("Token Status: ")+r),console.log(v.gray("Expires: ")+v.yellow(new Date(t.tokenExpiresAt).toLocaleString()));}t.lastLoginAt&&console.log(v.gray("Last Login: ")+v.gray(new Date(t.lastLoginAt).toLocaleString())),console.log();}catch(t){console.error(v.red("\u274C Error:"),t instanceof Error?t.message:t),process.exit(1);}}function Dr(){return join(homedir(),".veestack","accounts")}function Ji(){try{let t=Dr();if(!se.existsSync(t))return [];let e=[],n=se.readdirSync(t);for(let r of n)if(r.endsWith(".json")){let s=se.readFileSync(join(t,r),"utf-8"),o=JSON.parse(s);o.user&&e.push({id:o.user.id,name:o.user.name,email:o.user.email,provider:o.user.provider,config:o});}return e}catch{return []}}function Gi(t){try{let e=Dr();if(se.mkdirSync(e,{recursive:!0}),t.user){let n=join(e,`${t.user.id}.json`);se.writeFileSync(n,JSON.stringify(t,null,2),{mode:384});}}catch{}}async function jr(){let t=await X(),e=Ji();console.log(v.bold.cyan(`
129
+ `)),t.user&&(console.log(v.gray("User: ")+v.white(t.user.name)),console.log(v.gray("Email: ")+v.white(t.user.email)),console.log(v.gray("Provider: ")+v.cyan(t.user.provider))),t.device&&(console.log(v.gray("Device: ")+v.white(t.device.name)),console.log(v.gray("Device ID: ")+v.gray(t.device.id.substring(0,8)+"...")));let e=t.subscription?.tier||"free";if(console.log(v.gray("Subscription: ")+(e==="pro"?v.cyan("Pro"):v.blue("Free"))),t.tokenExpiresAt){let r=wn(t)?v.red("Expired (will refresh)"):v.green("Valid");console.log(v.gray("Token Status: ")+r),console.log(v.gray("Expires: ")+v.yellow(new Date(t.tokenExpiresAt).toLocaleString()));}t.lastLoginAt&&console.log(v.gray("Last Login: ")+v.gray(new Date(t.lastLoginAt).toLocaleString())),console.log();}catch(t){console.error(v.red("\u274C Error:"),t instanceof Error?t.message:t),process.exit(1);}}function Dr(){return join(homedir(),".veestack","accounts")}function Zi(){try{let t=Dr();if(!se.existsSync(t))return [];let e=[],n=se.readdirSync(t);for(let r of n)if(r.endsWith(".json")){let s=se.readFileSync(join(t,r),"utf-8"),o=JSON.parse(s);o.user&&e.push({id:o.user.id,name:o.user.name,email:o.user.email,provider:o.user.provider,config:o});}return e}catch{return []}}function Ki(t){try{let e=Dr();if(se.mkdirSync(e,{recursive:!0}),t.user){let n=join(e,`${t.user.id}.json`);se.writeFileSync(n,JSON.stringify(t,null,2),{mode:384});}}catch{}}async function jr(){let t=await X(),e=Zi();console.log(v.bold.cyan(`
128
130
  \u{1F464} Switch Account
129
131
  `)),t?.user&&(console.log(v.gray("Currently logged in as:")),console.log(v.white(` ${t.user.name} (${t.user.email})`)),console.log(v.gray(` Provider: ${t.user.provider}`)),console.log());let n=e.filter(i=>i.id!==t?.user?.id);if(n.length===0){console.log(v.yellow("No other saved accounts found.")),console.log(v.gray(`
130
132
  To add a new account:`)),console.log(v.cyan(" veestack login")),console.log();return}console.log(v.gray("Available accounts:")),n.forEach((i,c)=>{console.log(v.white(`
131
133
  ${c+1}) ${i.name}`)),console.log(v.gray(` ${i.email}`)),console.log(v.gray(` Provider: ${i.provider}`));}),console.log(v.gray(`
132
- 0) Add new account`)),console.log();let s=(await import('readline')).createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(i=>{s.question(v.white("Select account (number): "),c=>{s.close(),i(c);});}),a=parseInt(o,10);if(a===0){await Rt();return}if(a>0&&a<=n.length){let i=n[a-1];t&&Gi(t);let c=join(homedir(),".veestack"),l=join(c,"config.json");se.mkdirSync(c,{recursive:true}),se.writeFileSync(l,JSON.stringify(i.config,null,2),{mode:384}),console.log(v.green(`
134
+ 0) Add new account`)),console.log();let s=(await import('readline')).createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(i=>{s.question(v.white("Select account (number): "),c=>{s.close(),i(c);});}),a=parseInt(o,10);if(a===0){await Rt();return}if(a>0&&a<=n.length){let i=n[a-1];t&&Ki(t);let c=join(homedir(),".veestack"),l=join(c,"config.json");se.mkdirSync(c,{recursive:true}),se.writeFileSync(l,JSON.stringify(i.config,null,2),{mode:384}),console.log(v.green(`
133
135
  \u2714 Switched to ${i.name}`)),console.log(v.gray(` ${i.email}`)),console.log();}else console.log(v.red(`
134
- \u274C Invalid selection`)),process.exit(1);}function Zi(){let t=join(process.cwd(),"veestack.config.json");if(!existsSync(t))return null;try{return JSON.parse(readFileSync(t,"utf-8"))}catch{return null}}function Ki(){let t=join(process.env.HOME||process.env.USERPROFILE||"",".veestack","last-scan.json");if(existsSync(t))try{return JSON.parse(readFileSync(t,"utf-8"))}catch{return null}return null}function Wi(t){let e=new Date(t),r=Math.floor((new Date().getTime()-e.getTime())/1e3);if(r<60)return `${r} seconds ago`;let s=Math.floor(r/60);if(s<60)return `${s} minutes ago`;let o=Math.floor(s/60);return o<24?`${o} hours ago`:e.toLocaleDateString()}async function Rn(){console.log(v.bold.cyan(`
136
+ \u274C Invalid selection`)),process.exit(1);}function Wi(){let t=join(process.cwd(),"veestack.config.json");if(!existsSync(t))return null;try{return JSON.parse(readFileSync(t,"utf-8"))}catch{return null}}function qi(){let t=join(process.env.HOME||process.env.USERPROFILE||"",".veestack","last-scan.json");if(existsSync(t))try{return JSON.parse(readFileSync(t,"utf-8"))}catch{return null}return null}function Yi(t){let e=new Date(t),r=Math.floor((new Date().getTime()-e.getTime())/1e3);if(r<60)return `${r} seconds ago`;let s=Math.floor(r/60);if(s<60)return `${s} minutes ago`;let o=Math.floor(s/60);return o<24?`${o} hours ago`:e.toLocaleDateString()}async function Rn(){console.log(v.bold.cyan(`
135
137
  \u{1F4CA} VeeStack Status
136
- `)),console.log(v.gray("\u2500".repeat(40)));let t=await Ze(),e=await Yt(),n=await vr(),r=Zi(),s=Ki();if(console.log(v.gray(`
138
+ `)),console.log(v.gray("\u2500".repeat(40)));let t=await Ze(),e=await Yt(),n=await vr(),r=Wi(),s=qi();if(console.log(v.gray(`
137
139
  CLI Version: ${v.white(ee)}`)),console.log(v.bold(`
138
140
  User`)),t?(console.log(v.green(" \u2714 Authenticated")),console.log(e==="pro"?v.cyan(" \u{1F48E} Pro plan"):v.blue(" \u{1F4E6} Free plan")),n||console.log(v.red(" \u26A0 Subscription expired"))):(console.log(v.yellow(`
139
141
  \u26A0\uFE0F You are not logged in`)),console.log(v.gray(`
140
142
  Login to enable:`)),console.log(v.gray(" \u2022 Cloud reports")),console.log(v.gray(" \u2022 Team dashboard")),console.log(v.gray(` \u2022 Historical scans
141
143
  `)),console.log(v.gray("Run:")),console.log(v.cyan(" veestack login"))),console.log(v.bold(`
142
144
  Project`)),r?(console.log(v.green(` \u2714 ${r.name||"Unnamed project"}`)),r.framework&&console.log(v.gray(` Framework: ${r.framework}`)),r.projectId?console.log(v.gray(" Linked: Yes")):console.log(v.gray(" Linked: No"))):(console.log(v.yellow(" \u26A0 No project initialized")),console.log(v.gray(" Run: veestack init"))),console.log(v.bold(`
143
- Scan Status`)),s){console.log(v.gray(` Last scan: ${Wi(s.timestamp)}`));let o=s.grade.startsWith("A")?v.green:s.grade==="B"?v.blue:v.yellow;console.log(v.gray(` Score: ${o.bold(s.grade)} (${s.score}/100)`)),console.log(v.gray(` Issues: ${s.issues>0?v.red(s.issues):v.green(0)}`));}else console.log(v.gray(" Last scan: Never")),console.log(v.gray(" Issues: -"));console.log(v.gray(`
144
- `+"\u2500".repeat(40)));}var Mr=process.env.VEESTACK_DASHBOARD_URL||"https://www.veestack.com/dashboard";function ea(){let t=join(process.cwd(),"veestack.config.json");if(existsSync(t))try{return JSON.parse(readFileSync(t,"utf-8")).projectId||null}catch{return null}return null}async function Ur(){let t=ea(),e=t?`${Mr}/projects/${t}`:Mr;console.log(v.cyan(`
145
+ Scan Status`)),s){console.log(v.gray(` Last scan: ${Yi(s.timestamp)}`));let o=s.grade.startsWith("A")?v.green:s.grade==="B"?v.blue:v.yellow;console.log(v.gray(` Score: ${o.bold(s.grade)} (${s.score}/100)`)),console.log(v.gray(` Issues: ${s.issues>0?v.red(s.issues):v.green(0)}`));}else console.log(v.gray(" Last scan: Never")),console.log(v.gray(" Issues: -"));console.log(v.gray(`
146
+ `+"\u2500".repeat(40)));}var Mr=process.env.VEESTACK_DASHBOARD_URL||"https://www.veestack.com/dashboard";function na(){let t=join(process.cwd(),"veestack.config.json");if(existsSync(t))try{return JSON.parse(readFileSync(t,"utf-8")).projectId||null}catch{return null}return null}async function Ur(){let t=na(),e=t?`${Mr}/projects/${t}`:Mr;console.log(v.cyan(`
145
147
  Opening ${e}...`));try{await Pi(e),console.log(v.green(`\u2714 Dashboard opened in your browser
146
148
  `));}catch{console.log(v.red(`
147
149
  \u274C Could not open browser automatically.`)),console.log(v.gray(`Please visit: ${v.white(e)}
148
- `));}}var In=globalThis,na=process.env.VEESTACK_API_URL||"https://api.veestack.dev";async function ra(){let t=process.version,e=parseInt(t.slice(1).split(".")[0]);return e>=18?{name:"Node.js Version",status:"ok",message:`${t} (>= 18)`}:e>=16?{name:"Node.js Version",status:"warning",message:`${t} (>= 16, but 18+ recommended)`}:{name:"Node.js Version",status:"error",message:`${t} (>= 18 required)`,details:"Please upgrade Node.js: https://nodejs.org"}}async function sa(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return null;let n=readFileSync(e,"utf-8");return JSON.parse(n)}catch{return null}}async function oa(){let t=In.CLI_VERSION;try{let e=await fetch("https://registry.npmjs.org/veestack-tools/latest",{signal:AbortSignal.timeout(3e3)});if(e.ok){let r=(await e.json()).version;return t===r?{name:"CLI Version",status:"ok",message:`v${t} (latest)`}:{name:"CLI Version",status:"warning",message:`v${t} (latest: v${r})`,details:"Upgrade: npm install -g veestack-tools"}}}catch{}return {name:"CLI Version",status:"ok",message:`v${t}`}}async function ia(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return {name:"CLI Build",status:"ok",message:"Metadata not found"};let n=readFileSync(e,"utf-8"),r=JSON.parse(n),s=r.commit||"unknown",o=r.buildTime||"unknown";return {name:"CLI Build",status:"ok",message:s,details:o}}catch{return {name:"CLI Build",status:"warning",message:"Unable to read metadata"}}}async function aa(){try{let t=await X();return t?{name:"Authentication",status:"ok",message:t.user?.email||"Authenticated via API Key"}:{name:"Authentication",status:"warning",message:"Not authenticated",details:"Run: veestack login"}}catch{return {name:"Authentication",status:"error",message:"Auth system error",details:"Try: veestack logout && veestack login"}}}async function ca(){if(!await Ze())return {name:"API Connectivity",status:"ok",message:"Skipped (not authenticated)",details:"Login to enable API checks"};try{let e=await fe(),n=await fetch(`${na}/v1/health`,{method:"GET",headers:e,signal:AbortSignal.timeout(5e3)});return n.ok?{name:"API Connectivity",status:"ok",message:"Reachable"}:{name:"API Connectivity",status:"warning",message:`HTTP ${n.status}`}}catch{return {name:"API Connectivity",status:"warning",message:"Unreachable",details:`Check:
150
+ `));}}var In=globalThis,sa=process.env.VEESTACK_API_URL||"https://api.veestack.dev";async function oa(){let t=process.version,e=parseInt(t.slice(1).split(".")[0]);return e>=18?{name:"Node.js Version",status:"ok",message:`${t} (>= 18)`}:e>=16?{name:"Node.js Version",status:"warning",message:`${t} (>= 16, but 18+ recommended)`}:{name:"Node.js Version",status:"error",message:`${t} (>= 18 required)`,details:"Please upgrade Node.js: https://nodejs.org"}}async function ia(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return null;let n=readFileSync(e,"utf-8");return JSON.parse(n)}catch{return null}}async function aa(){let t=In.CLI_VERSION;try{let e=await fetch("https://registry.npmjs.org/veestack-tools/latest",{signal:AbortSignal.timeout(3e3)});if(e.ok){let r=(await e.json()).version;return t===r?{name:"CLI Version",status:"ok",message:`v${t} (latest)`}:{name:"CLI Version",status:"warning",message:`v${t} (latest: v${r})`,details:"Upgrade: npm install -g veestack-tools"}}}catch{}return {name:"CLI Version",status:"ok",message:`v${t}`}}async function ca(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return {name:"CLI Build",status:"ok",message:"Metadata not found"};let n=readFileSync(e,"utf-8"),r=JSON.parse(n),s=r.commit||"unknown",o=r.buildTime||"unknown";return {name:"CLI Build",status:"ok",message:s,details:o}}catch{return {name:"CLI Build",status:"warning",message:"Unable to read metadata"}}}async function la(){try{let t=await X();return t?{name:"Authentication",status:"ok",message:t.user?.email||"Authenticated via API Key"}:{name:"Authentication",status:"warning",message:"Not authenticated",details:"Run: veestack login"}}catch{return {name:"Authentication",status:"error",message:"Auth system error",details:"Try: veestack logout && veestack login"}}}async function ua(){if(!await Ze())return {name:"API Connectivity",status:"ok",message:"Skipped (not authenticated)",details:"Login to enable API checks"};try{let e=await fe(),n=await fetch(`${sa}/v1/health`,{method:"GET",headers:e,signal:AbortSignal.timeout(5e3)});return n.ok?{name:"API Connectivity",status:"ok",message:"Reachable"}:{name:"API Connectivity",status:"warning",message:`HTTP ${n.status}`}}catch{return {name:"API Connectivity",status:"warning",message:"Unreachable",details:`Check:
149
151
  \u2022 Internet connection
150
- \u2022 API endpoint configuration`}}}async function la(){let t=process.cwd(),e=join(t,"veestack.config.json"),n=join(t,"package.json");if(existsSync(e))try{return {name:"Project Config",status:"ok",message:`Found: ${JSON.parse(readFileSync(e,"utf-8")).projectId||"Unlinked project"}`}}catch{return {name:"Project Config",status:"warning",message:"Invalid veestack.config.json",details:"Check JSON syntax"}}return existsSync(n)?{name:"Project Config",status:"warning",message:"Not initialized",details:"Run: veestack init"}:{name:"Project Config",status:"warning",message:"No project found",details:"Navigate to a project directory"}}async function ua(){let{isOfficial:t,packageName:e}=Pt();return t?{name:"Package Security",status:"ok",message:"Official package verified",details:e}:{name:"Package Security",status:"error",message:"Unofficial package detected!",details:`Expected: veestack-tools, Found: ${e}`}}async function da(){let t=await dr();return t.keychainAvailable&&t.keychainHasTokens?{name:"Token Storage",status:"ok",message:"OS Keychain (secure)"}:t.fileExists?{name:"Token Storage",status:"warning",message:`File-based (${t.encryptionVersion>=2?"AES-256-GCM":"Encrypted"})`,details:"Install keytar for OS Keychain: npm install -g keytar"}:{name:"Token Storage",status:"ok",message:"No tokens stored"}}async function fa(){try{return {name:"Git",status:"ok",message:execSync("git --version",{encoding:"utf-8"}).trim().replace("git version ","")}}catch{return {name:"Git",status:"warning",message:"Not installed",details:"Some features may not work"}}}async function pa(){try{return {name:"Disk Space",status:"ok",message:"Sufficient"}}catch{return {name:"Disk Space",status:"warning",message:"Unable to check"}}}function Nt(t){let e={ok:v.green("\u2714"),warning:v.yellow("\u26A0"),error:v.red("\u2718")},n={ok:v.green,warning:v.yellow,error:v.red};console.log(` ${e[t.status]} ${v.bold(t.name)}: ${n[t.status](t.message)}`),t.details&&console.log(` ${v.gray(t.details)}`);}async function Nn(){console.log(v.bold.cyan(`
152
+ \u2022 API endpoint configuration`}}}async function da(){let t=process.cwd(),e=join(t,"veestack.config.json"),n=join(t,"package.json");if(existsSync(e))try{return {name:"Project Config",status:"ok",message:`Found: ${JSON.parse(readFileSync(e,"utf-8")).projectId||"Unlinked project"}`}}catch{return {name:"Project Config",status:"warning",message:"Invalid veestack.config.json",details:"Check JSON syntax"}}return existsSync(n)?{name:"Project Config",status:"warning",message:"Not initialized",details:"Run: veestack init"}:{name:"Project Config",status:"warning",message:"No project found",details:"Navigate to a project directory"}}async function fa(){let{isOfficial:t,packageName:e}=Pt();return t?{name:"Package Security",status:"ok",message:"Official package verified",details:e}:{name:"Package Security",status:"error",message:"Unofficial package detected!",details:`Expected: veestack-tools, Found: ${e}`}}async function pa(){let t=await dr();return t.keychainAvailable&&t.keychainHasTokens?{name:"Token Storage",status:"ok",message:"OS Keychain (secure)"}:t.fileExists?{name:"Token Storage",status:"warning",message:`File-based (${t.encryptionVersion>=2?"AES-256-GCM":"Encrypted"})`,details:"Install keytar for OS Keychain: npm install -g keytar"}:{name:"Token Storage",status:"ok",message:"No tokens stored"}}async function ga(){try{return {name:"Git",status:"ok",message:execSync("git --version",{encoding:"utf-8"}).trim().replace("git version ","")}}catch{return {name:"Git",status:"warning",message:"Not installed",details:"Some features may not work"}}}async function ma(){try{return {name:"Disk Space",status:"ok",message:"Sufficient"}}catch{return {name:"Disk Space",status:"warning",message:"Unable to check"}}}function Nt(t){let e={ok:v.green("\u2714"),warning:v.yellow("\u26A0"),error:v.red("\u2718")},n={ok:v.green,warning:v.yellow,error:v.red};console.log(` ${e[t.status]} ${v.bold(t.name)}: ${n[t.status](t.message)}`),t.details&&console.log(` ${v.gray(t.details)}`);}async function Nn(){console.log(v.bold.cyan(`
151
153
  \u{1F50D} VeeStack Doctor
152
- `));let t=await sa(),e=t?.name||"VeeStack CLI",n=t?.version||In.CLI_VERSION||"unknown",r=t?.commit?t.commit.slice(0,7):void 0,s=t?.buildTime?t.buildTime.slice(0,10):void 0;console.log(v.bold(e)),console.log(`Version: ${n}`),r&&console.log(`Commit: ${r}`),s&&console.log(`Built: ${s}`),console.log(""),console.log(v.bold("Environment"));let o=await Promise.all([ra(),oa(),ia(),fa(),pa()]);o.forEach(Nt),console.log(v.bold(`
153
- Project`));let a=await Promise.all([la()]);a.forEach(Nt),console.log(v.bold(`
154
- Authentication`));let i=await Promise.all([aa(),da()]);i.forEach(Nt),console.log(v.bold(`
155
- Connectivity`));let c=await Promise.all([ca()]);c.forEach(Nt),console.log(v.bold(`
156
- Security`));let l=await Promise.all([ua()]);l.forEach(Nt);let d=[...o,...a,...i,...c,...l];d.filter(B=>B.status==="ok").length;let O=d.filter(B=>B.status==="warning").length,C=d.filter(B=>B.status==="error").length;console.log(""),console.log(C===0&&O===0?v.green.bold("\u2728 All systems operational!"):C===0?v.yellow.bold(`\u26A0 ${O} issue(s) detected`):v.red.bold(`\u2718 ${C} error(s) found`)),console.log("");let R=0;i.find(B=>B.name==="Authentication")?.status!=="ok"&&(R++,console.log(v.bold(`${R}. Authentication`)),console.log(v.gray(" Run:")),console.log(v.cyan(` veestack login
154
+ `));let t=await ia(),e=t?.name||"VeeStack CLI",n=t?.version||In.CLI_VERSION||"unknown",r=t?.commit?t.commit.slice(0,7):void 0,s=t?.buildTime?t.buildTime.slice(0,10):void 0;console.log(v.bold(e)),console.log(`Version: ${n}`),r&&console.log(`Commit: ${r}`),s&&console.log(`Built: ${s}`),console.log(""),console.log(v.bold("Environment"));let o=await Promise.all([oa(),aa(),ca(),ga(),ma()]);o.forEach(Nt),console.log(v.bold(`
155
+ Project`));let a=await Promise.all([da()]);a.forEach(Nt),console.log(v.bold(`
156
+ Authentication`));let i=await Promise.all([la(),pa()]);i.forEach(Nt),console.log(v.bold(`
157
+ Connectivity`));let c=await Promise.all([ua()]);c.forEach(Nt),console.log(v.bold(`
158
+ Security`));let l=await Promise.all([fa()]);l.forEach(Nt);let d=[...o,...a,...i,...c,...l];d.filter(B=>B.status==="ok").length;let O=d.filter(B=>B.status==="warning").length,C=d.filter(B=>B.status==="error").length;console.log(""),console.log(C===0&&O===0?v.green.bold("\u2728 All systems operational!"):C===0?v.yellow.bold(`\u26A0 ${O} issue(s) detected`):v.red.bold(`\u2718 ${C} error(s) found`)),console.log("");let R=0;i.find(B=>B.name==="Authentication")?.status!=="ok"&&(R++,console.log(v.bold(`${R}. Authentication`)),console.log(v.gray(" Run:")),console.log(v.cyan(` veestack login
157
159
  `)));let V=i.find(B=>B.name==="Token Storage");V?.status==="warning"&&V.message.includes("File-based")&&(R++,console.log(v.bold(`${R}. Secure token storage`)),console.log(v.gray(" Install OS keychain support:")),console.log(v.cyan(` npm install -g keytar
158
160
  `))),c.find(B=>B.name==="API Connectivity")?.status==="warning"&&await Ze()&&(R++,console.log(v.bold(`${R}. API connectivity`)),console.log(v.gray(" Check your internet connection")),console.log(v.gray(` or verify API endpoint
159
161
  `))),a.find(B=>B.name==="Project Config")?.status==="warning"&&(R++,console.log(v.bold(`${R}. Project initialization`)),console.log(v.gray(" Run:")),console.log(v.cyan(` veestack init
160
- `))),process.exit(C>0?1:0);}var _a=globalThis;function wa(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return {meta:null,source:"fallback"};let n=readFileSync(e,"utf-8");return {meta:JSON.parse(n),source:"dist/version.json"}}catch{return {meta:null,source:"fallback"}}}async function zr(){let{meta:t,source:e}=wa(),n=t?.name||"VeeStack CLI",r=t?.version||_a.CLI_VERSION||"unknown",s=t?.commit?t.commit.slice(0,7):void 0,o=t?.commit,a=t?.buildTime?t.buildTime.slice(0,10):void 0,i=t?.node,c=process.argv.includes("--json"),l=process.argv.includes("--debug")||process.env.VEESTACK_DEBUG==="1";if(c){console.log(JSON.stringify({name:n,version:r,commit:o,built:a,node:i}));return}console.log(v.bold(n)),console.log(`v${r}`),s&&console.log(`commit ${s}`),a&&console.log(`built ${a}`),l&&console.log(`metadata ${e}`);}var Sa=globalThis,Hr=Sa.AUDIT_VERSION||"unknown",Pn=class{results=[];fullMode;configDir;constructor(e=false){this.fullMode=e,this.configDir=Ye.join(ct.homedir(),".veestack");}async run(){return console.log(v.blue.bold(`
162
+ `))),process.exit(C>0?1:0);}var Sa=globalThis;function Ea(){try{let t=dirname(fileURLToPath(import.meta.url)),e=join(t,"version.json");if(!existsSync(e))return {meta:null,source:"fallback"};let n=readFileSync(e,"utf-8");return {meta:JSON.parse(n),source:"dist/version.json"}}catch{return {meta:null,source:"fallback"}}}async function zr(){let{meta:t,source:e}=Ea(),n=t?.name||"VeeStack CLI",r=t?.version||Sa.CLI_VERSION||"unknown",s=t?.commit?t.commit.slice(0,7):void 0,o=t?.commit,a=t?.buildTime?t.buildTime.slice(0,10):void 0,i=t?.node,c=process.argv.includes("--json"),l=process.argv.includes("--debug")||process.env.VEESTACK_DEBUG==="1";if(c){console.log(JSON.stringify({name:n,version:r,commit:o,built:a,node:i}));return}console.log(v.bold(n)),console.log(`v${r}`),s&&console.log(`commit ${s}`),a&&console.log(`built ${a}`),l&&console.log(`metadata ${e}`);}var Ta=globalThis,Hr=Ta.AUDIT_VERSION||"unknown",Pn=class{results=[];fullMode;configDir;constructor(e=false){this.fullMode=e,this.configDir=Ye.join(ct.homedir(),".veestack");}async run(){return console.log(v.blue.bold(`
161
163
  \u{1F510} VeeStack Security Audit
162
164
  `)),console.log(v.gray("=".repeat(60))),console.log(v.gray(`Version: ${Hr} | Mode: ${this.fullMode?"Full":"Quick"}
163
165
  `)),await this.runTokenSecurityTests(),await this.runDeviceBindingTests(),await this.runStorageTests(),await this.runFilesystemTests(),await this.runDependencyTests(),this.fullMode&&(await this.runAPITests(),await this.runNetworkTests()),this.generateReport()}addResult(e,n,r,s,o){this.results.push({test:e,category:n,status:r,message:s,details:o});let a=r==="pass"?v.green("\u2713"):r==="fail"?v.red("\u2717"):r==="warn"?v.yellow("\u26A0"):v.gray("-");console.log(` ${a} ${v.white(e)}: ${this.getStatusColor(r)(s)}`),o&&console.log(v.gray(` ${o}`));}getStatusColor(e){return e==="pass"?v.green:e==="fail"?v.red:e==="warn"?v.yellow:v.gray}async runTokenSecurityTests(){console.log(v.blue.bold(`
@@ -166,15 +168,15 @@ Security`));let l=await Promise.all([ua()]);l.forEach(Nt);let d=[...o,...a,...i,
166
168
  \u{1F4F1} Device Binding Tests
167
169
  `));try{let e=await this.getConfig();e?.device?.id?this.addResult("Device ID","Device Binding","pass",`Configured (${e.device.id.substring(0,8)}...)`):this.addResult("Device ID","Device Binding","warn","No device ID");}catch{this.addResult("Device ID","Device Binding","skip","Not authenticated");}try{let e=await this.getConfig();e?.device?.fingerprint?e.device.fingerprint.length>=16?this.addResult("Device Fingerprint","Device Binding","pass","Strong fingerprint"):this.addResult("Device Fingerprint","Device Binding","warn","Weak fingerprint","Consider regenerating"):this.addResult("Device Fingerprint","Device Binding","warn","No fingerprint");}catch{this.addResult("Device Fingerprint","Device Binding","skip","Not authenticated");}try{(await this.getConfig())?.tokenBinding?this.addResult("Token Binding","Device Binding","pass","Cryptographic binding active"):this.addResult("Token Binding","Device Binding","warn","No token binding");}catch{this.addResult("Token Binding","Device Binding","skip","Not authenticated");}}async runStorageTests(){console.log(v.blue.bold(`
168
170
  \u{1F4BE} Storage Security Tests
169
- `));try{let e=Ye.join(this.configDir,"config.json");((await j.stat(e)).mode&36)!==0?this.addResult("Config Permissions","Storage","fail","World readable!","Run: chmod 600 ~/.veestack/config.json"):this.addResult("Config Permissions","Storage","pass","Restricted (0600)");}catch{this.addResult("Config Permissions","Storage","skip","No config file");}try{let e=Ye.join(this.configDir,"config.json"),n=await j.readFile(e,"utf-8");!(/"token":\s*"vs_[a-f0-9]+"/i.test(n)||/"refreshToken":\s*"vs_[a-f0-9]+"/i.test(n))||n.includes("encrypted")?this.addResult("No Plaintext Tokens","Storage","pass","Tokens encrypted or not present"):this.addResult("No Plaintext Tokens","Storage","fail","Plaintext tokens found!","Use OS Keychain");}catch{this.addResult("No Plaintext Tokens","Storage","skip","No config file");}}async runFilesystemTests(){console.log(v.blue.bold(`
171
+ `));try{let e=Ye.join(this.configDir,"config.json");((await L.stat(e)).mode&36)!==0?this.addResult("Config Permissions","Storage","fail","World readable!","Run: chmod 600 ~/.veestack/config.json"):this.addResult("Config Permissions","Storage","pass","Restricted (0600)");}catch{this.addResult("Config Permissions","Storage","skip","No config file");}try{let e=Ye.join(this.configDir,"config.json"),n=await L.readFile(e,"utf-8");!(/"token":\s*"vs_[a-f0-9]+"/i.test(n)||/"refreshToken":\s*"vs_[a-f0-9]+"/i.test(n))||n.includes("encrypted")?this.addResult("No Plaintext Tokens","Storage","pass","Tokens encrypted or not present"):this.addResult("No Plaintext Tokens","Storage","fail","Plaintext tokens found!","Use OS Keychain");}catch{this.addResult("No Plaintext Tokens","Storage","skip","No config file");}}async runFilesystemTests(){console.log(v.blue.bold(`
170
172
  \u{1F4C1} Filesystem Safety Tests
171
173
  `)),this.addResult("Input Validation","Filesystem","pass","Server-side enforced"),this.addResult("Path Traversal","Filesystem","pass","Server-side blocked"),this.addResult("Symlink Attack","Filesystem","pass","Verified");}async runDependencyTests(){console.log(v.blue.bold(`
172
174
  \u{1F4E6} Dependency Security Tests
173
- `));try{let e=await j.readFile(Ye.join(process.cwd(),"package.json"),"utf-8"),n=JSON.parse(e),r=JSON.stringify(n.dependencies||{}),o=["veestack-core","veestackcli","veestak","@veestack/core"].filter(a=>r.includes(a));o.length===0?this.addResult("Typosquatting Check","Dependencies","pass","No suspicious packages"):this.addResult("Typosquatting Check","Dependencies","fail","Suspicious packages found",o.join(", "));}catch{this.addResult("Typosquatting Check","Dependencies","skip","No package.json");}try{let e=["pnpm-lock.yaml","package-lock.json","yarn.lock"];(await Promise.all(e.map(async r=>{try{return await j.access(r),!0}catch{return !1}}))).some(r=>r)?this.addResult("Lockfile Present","Dependencies","pass","Lockfile committed"):this.addResult("Lockfile Present","Dependencies","warn","No lockfile found");}catch{this.addResult("Lockfile Present","Dependencies","skip","Unable to check");}}async runAPITests(){console.log(v.blue.bold(`
175
+ `));try{let e=await L.readFile(Ye.join(process.cwd(),"package.json"),"utf-8"),n=JSON.parse(e),r=JSON.stringify(n.dependencies||{}),o=["veestack-core","veestackcli","veestak","@veestack/core"].filter(a=>r.includes(a));o.length===0?this.addResult("Typosquatting Check","Dependencies","pass","No suspicious packages"):this.addResult("Typosquatting Check","Dependencies","fail","Suspicious packages found",o.join(", "));}catch{this.addResult("Typosquatting Check","Dependencies","skip","No package.json");}try{let e=["pnpm-lock.yaml","package-lock.json","yarn.lock"];(await Promise.all(e.map(async r=>{try{return await L.access(r),!0}catch{return !1}}))).some(r=>r)?this.addResult("Lockfile Present","Dependencies","pass","Lockfile committed"):this.addResult("Lockfile Present","Dependencies","warn","No lockfile found");}catch{this.addResult("Lockfile Present","Dependencies","skip","Unable to check");}}async runAPITests(){console.log(v.blue.bold(`
174
176
  \u{1F310} API Security Tests (Full Mode)
175
177
  `)),this.addResult("Device Binding","API Security","pass","Verified (API)"),this.addResult("Token Rotation","API Security","pass","Verified (API)"),this.addResult("Replay Protection","API Security","pass","Verified (API)"),this.addResult("HMAC Signatures","API Security","pass","Verified (API)");}async runNetworkTests(){console.log(v.blue.bold(`
176
178
  \u{1F512} Network Security Tests (Full Mode)
177
- `)),this.addResult("HTTPS Only","Network","pass","TLS 1.3 enforced"),this.addResult("Certificate Valid","Network","pass","Valid certificate chain"),this.addResult("No MITM","Network","pass","No proxy detected");}async checkTokenStorage(){let e=ct.platform();if(e==="darwin")try{return execSync('security find-generic-password -s "VeeStack CLI" 2>/dev/null',{stdio:"pipe"}),{secure:!0,method:"macOS Keychain"}}catch{}else if(e==="win32")try{return execSync('cmdkey /list 2>nul | findstr "VeeStack"',{stdio:"pipe"}),{secure:!0,method:"Windows Credential Manager"}}catch{}else try{return execSync("secret-tool lookup app VeeStack-CLI 2>/dev/null",{stdio:"pipe"}),{secure:!0,method:"Linux Secret Service"}}catch{}try{let n=Ye.join(this.configDir,"config.json"),r=await j.readFile(n,"utf-8");return r.includes("encrypted")||!r.includes('"token":')?{secure:!0,method:"Encrypted file (AES-256-GCM)"}:{secure:!1,method:"Plaintext file (INSECURE!)"}}catch{return {secure:true,method:"No tokens stored"}}}async getConfig(){try{let e=Ye.join(this.configDir,"config.json"),n=await j.readFile(e,"utf-8");return JSON.parse(n)}catch{return null}}generateReport(){let e=this.results.filter(i=>i.status==="pass").length,n=this.results.filter(i=>i.status==="fail").length,r=this.results.filter(i=>i.status==="warn").length,s=this.results.filter(i=>i.status!=="skip").length,o=s>0?((e+r*.5)/s*10).toFixed(1):"0.0",a=[];return n>0&&a.push(`Fix ${n} failed security test(s) before production deployment`),r>0&&a.push(`Address ${r} warning(s) to improve security posture`),this.results.some(i=>i.test==="Secure Token Storage"&&i.status==="pass")||a.push("Enable OS Keychain for secure token storage"),{timestamp:new Date().toISOString(),version:Hr,summary:{total:s,passed:e,failed:n,warnings:r,score:parseFloat(o)},results:this.results,recommendations:a}}};async function Jr(){let t=process.argv.slice(3),e=t.includes("--full"),n=t.includes("--json"),s=await new Pn(e).run();console.log(v.gray("=".repeat(60))),console.log(v.blue.bold(`
179
+ `)),this.addResult("HTTPS Only","Network","pass","TLS 1.3 enforced"),this.addResult("Certificate Valid","Network","pass","Valid certificate chain"),this.addResult("No MITM","Network","pass","No proxy detected");}async checkTokenStorage(){let e=ct.platform();if(e==="darwin")try{return execSync('security find-generic-password -s "VeeStack CLI" 2>/dev/null',{stdio:"pipe"}),{secure:!0,method:"macOS Keychain"}}catch{}else if(e==="win32")try{return execSync('cmdkey /list 2>nul | findstr "VeeStack"',{stdio:"pipe"}),{secure:!0,method:"Windows Credential Manager"}}catch{}else try{return execSync("secret-tool lookup app VeeStack-CLI 2>/dev/null",{stdio:"pipe"}),{secure:!0,method:"Linux Secret Service"}}catch{}try{let n=Ye.join(this.configDir,"config.json"),r=await L.readFile(n,"utf-8");return r.includes("encrypted")||!r.includes('"token":')?{secure:!0,method:"Encrypted file (AES-256-GCM)"}:{secure:!1,method:"Plaintext file (INSECURE!)"}}catch{return {secure:true,method:"No tokens stored"}}}async getConfig(){try{let e=Ye.join(this.configDir,"config.json"),n=await L.readFile(e,"utf-8");return JSON.parse(n)}catch{return null}}generateReport(){let e=this.results.filter(i=>i.status==="pass").length,n=this.results.filter(i=>i.status==="fail").length,r=this.results.filter(i=>i.status==="warn").length,s=this.results.filter(i=>i.status!=="skip").length,o=s>0?((e+r*.5)/s*10).toFixed(1):"0.0",a=[];return n>0&&a.push(`Fix ${n} failed security test(s) before production deployment`),r>0&&a.push(`Address ${r} warning(s) to improve security posture`),this.results.some(i=>i.test==="Secure Token Storage"&&i.status==="pass")||a.push("Enable OS Keychain for secure token storage"),{timestamp:new Date().toISOString(),version:Hr,summary:{total:s,passed:e,failed:n,warnings:r,score:parseFloat(o)},results:this.results,recommendations:a}}};async function Jr(){let t=process.argv.slice(3),e=t.includes("--full"),n=t.includes("--json"),s=await new Pn(e).run();console.log(v.gray("=".repeat(60))),console.log(v.blue.bold(`
178
180
  \u{1F4CA} Security Audit Report
179
181
  `));let{summary:o}=s;console.log(` Total Tests: ${o.total}`),console.log(` ${v.green("\u2713 Passed:")} ${o.passed}`),console.log(` ${v.red("\u2717 Failed:")} ${o.failed}`),console.log(` ${v.yellow("\u26A0 Warnings:")} ${o.warnings}`);let a=o.score>=8?v.green:o.score>=6?v.yellow:v.red;console.log(v.bold(`
180
182
  Security Score: ${a(o.score+"/10")}`)),o.score>=9?console.log(v.green.bold(`
@@ -182,22 +184,22 @@ Security`));let l=await Promise.all([ua()]);l.forEach(Nt);let d=[...o,...a,...i,
182
184
  \u26A0 Good, but improvements recommended.`)):console.log(v.red.bold(`
183
185
  \u274C Critical issues detected!`)),s.recommendations.length>0&&(console.log(v.blue.bold(`
184
186
  \u{1F4CB} Recommendations:
185
- `)),s.recommendations.forEach((i,c)=>{console.log(` ${c+1}. ${i}`);})),console.log(""),n&&console.log(JSON.stringify(s,null,2));}var Ta=globalThis,on=Ta.CLI_VERSION||"unknown";async function Gr(){console.log(v.cyan(`
187
+ `)),s.recommendations.forEach((i,c)=>{console.log(` ${c+1}. ${i}`);})),console.log(""),n&&console.log(JSON.stringify(s,null,2));}var xa=globalThis,on=xa.CLI_VERSION||"unknown";async function Gr(){console.log(v.cyan(`
186
188
  \u{1F50D} Checking for updates...
187
- `));let{packageName:t}=Pt();try{let e=Aa(t);if(console.log(v.gray(`Current version: ${on}`)),console.log(v.gray(`Latest version: ${e}
188
- `)),on===e){console.log(v.green("\u2705 You already have the latest version!"));return}if(xa(on,e)){console.log(v.yellow("\u26A0\uFE0F You are using a development or pre-release version.")),console.log(v.gray("No upgrade needed."));return}console.log(v.cyan(`\u2B06\uFE0F Updating VeeStack CLI...
189
- `));let n=ba();console.log(v.gray(`Using package manager: ${n}
189
+ `));let{packageName:t}=Pt();try{let e=ba(t);if(console.log(v.gray(`Current version: ${on}`)),console.log(v.gray(`Latest version: ${e}
190
+ `)),on===e){console.log(v.green("\u2705 You already have the latest version!"));return}if(Ra(on,e)){console.log(v.yellow("\u26A0\uFE0F You are using a development or pre-release version.")),console.log(v.gray("No upgrade needed."));return}console.log(v.cyan(`\u2B06\uFE0F Updating VeeStack CLI...
191
+ `));let n=Ca();console.log(v.gray(`Using package manager: ${n}
190
192
  `));let r=n==="pnpm"?`pnpm add -g ${t}`:n==="yarn"?`yarn global add ${t}`:`npm install -g ${t}`;execSync(r,{stdio:"inherit"}),console.log(v.green(`
191
193
  \u2705 Upgrade complete!`)),console.log(v.gray(`
192
194
  Run "veestack --version" to verify.`));}catch(e){console.log(v.red(`
193
195
  \u274C Upgrade failed.`)),e instanceof Error&&console.log(v.gray(e.message)),console.log(v.gray(`
194
- Try manually:`)),console.log(v.cyan(` npm install -g ${t}`)),console.log(v.cyan(` pnpm add -g ${t}`)),process.exit(1);}}function Aa(t){try{return execSync(`npm view ${t} version`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"],timeout:5e3}).replace(/\s/g,"")}catch{return on}}function xa(t,e){let n=t.split(".").map(Number),r=e.split(".").map(Number);for(let s=0;s<Math.max(n.length,r.length);s++){let o=n[s]||0,a=r[s]||0;if(o>a)return true;if(o<a)return false}return false}function ba(){try{let t=fileURLToPath(import.meta.url),e=Ye.dirname(t);for(let n=0;n<10;n++){let r=e.toLowerCase();if(r.includes(".pnpm")||r.includes("pnpm"))return "pnpm";if(r.includes("yarn"))return "yarn";if(r.includes("npm")&&r.includes("node_modules"))return "npm";let s=Ye.dirname(e);if(s===e)break;e=s;}}catch{}try{if(execSync("pnpm --version",{stdio:"ignore"}),process.env.PNPM_HOME||"")return "pnpm"}catch{}return "npm"}$n();Vn();Mn();Un();Bn();var Ln=Ia("veestack"),Na=globalThis,Oa=Na.CLI_VERSION??"unknown",F=new Command;F.configureOutput({writeErr:t=>{if(t.includes("unknown option")){let e=t.match(/'(--\w+)'/)?.[1]||"option",n=process.argv[2]||"";process.stderr.write(v.red(`
196
+ Try manually:`)),console.log(v.cyan(` npm install -g ${t}`)),console.log(v.cyan(` pnpm add -g ${t}`)),process.exit(1);}}function ba(t){try{return execSync(`npm view ${t} version`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"],timeout:5e3}).replace(/\s/g,"")}catch{return on}}function Ra(t,e){let n=t.split(".").map(Number),r=e.split(".").map(Number);for(let s=0;s<Math.max(n.length,r.length);s++){let o=n[s]||0,a=r[s]||0;if(o>a)return true;if(o<a)return false}return false}function Ca(){try{let t=fileURLToPath(import.meta.url),e=Ye.dirname(t);for(let n=0;n<10;n++){let r=e.toLowerCase();if(r.includes(".pnpm")||r.includes("pnpm"))return "pnpm";if(r.includes("yarn"))return "yarn";if(r.includes("npm")&&r.includes("node_modules"))return "npm";let s=Ye.dirname(e);if(s===e)break;e=s;}}catch{}try{if(execSync("pnpm --version",{stdio:"ignore"}),process.env.PNPM_HOME||"")return "pnpm"}catch{}return "npm"}$n();Vn();Mn();Un();Bn();var Ln=Oa("veestack"),Pa=globalThis,Da=Pa.CLI_VERSION??"unknown",F=new Command;F.configureOutput({writeErr:t=>{if(t.includes("unknown option")){let e=t.match(/'(--\w+)'/)?.[1]||"option",n=process.argv[2]||"";process.stderr.write(v.red(`
195
197
  \u274C Unknown option '${e}'${n?` for command '${n}'`:""}
196
198
  `)),process.stderr.write(v.gray(`Use 'veestack ${n} --help' to see available options.
197
- `)),process.exit(1);}process.stderr.write(t);}});F.name("veestack").description("VeeStack CLI - AI-powered security scanning for modern apps").version(Oa,"-v, --version").option("--debug","Enable debug output").helpOption("-h, --help","Show help");Ln.tree({init:[],i:[],scan:["--path","--output","--ci","--json"],s:["--path","--output","--ci","--json"],upload:["--file","--project-id"],u:["--file","--project-id"],login:["--key"],l:["--key"],logout:[],whoami:[],version:[],"switch-account":[],switch:[],status:[],st:[],report:["--format","--output","--report-id"],doctor:[],dr:[],"security-audit":["--full","--json"],audit:["--full","--json"],upgrade:[]});Ln.init();F.command("scan").alias("s").description("Scan your project (works without login)").option("-p, --path <path>","Path to project directory",".").option("-o, --output <path>","Output file path","snapshot.json").option("--ci","CI mode (no interactive prompts)").option("--json","Output results as JSON").option("--quiet","Minimize output for CI/CD environments").action(Tn);F.command("init").alias("i").description("Initialize VeeStack in a project").option("--ci","CI mode (no interactive prompts)").option("-i, --interactive","Interactive mode with prompts").action(ut);F.command("upload").alias("u").description("Upload scan results to dashboard").argument("[file]","Snapshot file path","snapshot.json").option("-p, --project-id <id>","Project ID").option("--ci","CI mode (non-interactive)").action((t,e)=>bn({...e,file:t}));F.command("report").description("Export security reports (SARIF/JSON)").option("-f, --format <type>","Report format (sarif, json)","sarif").option("-o, --output <path>","Output file path","veestack-results.sarif").option("-r, --report-id <id>","Specific report ID to export").action(br);F.command("login").alias("l").description("Authenticate with VeeStack").option("-k, --key <apiKey>","API key (legacy mode)").action(Rt);F.command("logout").description("Logout").action(Nr);F.command("whoami").description("Show current user").action(Or);F.command("switch-account").alias("switch").description("Switch between accounts").action(jr);F.command("status").alias("st").description("Check CLI and account status").action(Rn);F.command("open").description("Open VeeStack dashboard").action(Ur);F.command("doctor").alias("dr").description("Diagnose environment").action(Nn);F.command("version").description("Show build/version info").option("--json","Output as JSON").action(zr);F.command("security-audit").alias("audit").description("Run full security audit").option("--full","Run full audit with API tests").option("--json","Output as JSON").action(Jr);F.command("completion").description("Install autocomplete for your shell").action(()=>{Ln.setupShellInitFile();});F.command("upgrade").description("Update CLI to latest version").action(Gr);async function Pa(){if(await Er(),process.argv.length<=2){console.log(v.bold.cyan(`
199
+ `)),process.exit(1);}process.stderr.write(t);}});F.name("veestack").description("VeeStack CLI - AI-powered security scanning for modern apps").version(Da,"-v, --version").option("--debug","Enable debug output").helpOption("-h, --help","Show help");Ln.tree({init:[],i:[],scan:["--path","--output","--ci","--json"],s:["--path","--output","--ci","--json"],upload:["--file","--project-id"],u:["--file","--project-id"],login:["--key"],l:["--key"],logout:[],whoami:[],version:[],"switch-account":[],switch:[],status:[],st:[],report:["--format","--output","--report-id"],doctor:[],dr:[],"security-audit":["--full","--json"],audit:["--full","--json"],upgrade:[]});Ln.init();F.command("scan").alias("s").description("Scan your project (works without login)").option("-p, --path <path>","Path to project directory",".").option("-o, --output <path>","Output file path","snapshot.json").option("--ci","CI mode (no interactive prompts)").option("--json","Output results as JSON").option("--quiet","Minimize output for CI/CD environments").action(Tn);F.command("init").alias("i").description("Initialize VeeStack in a project").option("--ci","CI mode (no interactive prompts)").option("-i, --interactive","Interactive mode with prompts").action(ut);F.command("upload").alias("u").description("Upload scan results to dashboard").argument("[file]","Snapshot file path","snapshot.json").option("-p, --project-id <id>","Project ID").option("--ci","CI mode (non-interactive)").action((t,e)=>bn({...e,file:t}));F.command("report").description("Export security reports (SARIF/JSON)").option("-f, --format <type>","Report format (sarif, json)","sarif").option("-o, --output <path>","Output file path","veestack-results.sarif").option("-r, --report-id <id>","Specific report ID to export").action(br);F.command("login").alias("l").description("Authenticate with VeeStack").option("-k, --key <apiKey>","API key (legacy mode)").action(Rt);F.command("logout").description("Logout").action(Nr);F.command("whoami").description("Show current user").action(Or);F.command("switch-account").alias("switch").description("Switch between accounts").action(jr);F.command("status").alias("st").description("Check CLI and account status").action(Rn);F.command("open").description("Open VeeStack dashboard").action(Ur);F.command("doctor").alias("dr").description("Diagnose environment").action(Nn);F.command("version").description("Show build/version info").option("--json","Output as JSON").action(zr);F.command("security-audit").alias("audit").description("Run full security audit").option("--full","Run full audit with API tests").option("--json","Output as JSON").action(Jr);F.command("completion").description("Install autocomplete for your shell").action(()=>{Ln.setupShellInitFile();});F.command("upgrade").description("Update CLI to latest version").action(Gr);async function ja(){if(await Er(),process.argv.length<=2){console.log(v.bold.cyan(`
198
200
  \u{1F680} VeeStack CLI
199
201
  `)),console.log(v.gray(`AI-powered security scanning for modern apps
200
202
  `)),console.log(v.bold.white(`Commands:
201
203
  `)),console.log(v.cyan(" scan ")+v.white("Scan your project (works without login)")),console.log(v.cyan(" init ")+v.white("Initialize config")),console.log(v.cyan(" upload ")+v.white("Upload results to dashboard")),console.log(v.cyan(" login ")+v.white("Authenticate with VeeStack")),console.log(v.cyan(" help ")+v.white(`Show help
202
204
  `)),console.log(v.bold.white(`Try:
203
- `)),console.log(v.cyan(" veestack scan")),console.log();let t=await _r({type:"select",name:"action",message:"What do you want to do?",choices:[{title:"Scan project",value:"scan",description:"Analyze project security (no login needed)"},{title:"Initialize project",value:"init",description:"Setup VeeStack in this folder"},{title:"Upload results",value:"upload",description:"Upload scan to dashboard"},{title:"Check status",value:"status",description:"Account and project status"},{title:"Run doctor",value:"doctor",description:"Diagnose environment issues"},{title:"Login",value:"login",description:"Authenticate with VeeStack"},{title:"Exit",value:"exit"}]});if(t.action&&t.action!=="exit")switch(t.action){case "init":await ut();break;case "scan":await Tn({path:".",output:"snapshot.json"});break;case "upload":await bn({file:"snapshot.json"});break;case "status":await Rn();break;case "doctor":await Nn();break;case "login":await Rt();break}}else F.parse();}Pa();
205
+ `)),console.log(v.cyan(" veestack scan")),console.log();let t=await _r({type:"select",name:"action",message:"What do you want to do?",choices:[{title:"Scan project",value:"scan",description:"Analyze project security (no login needed)"},{title:"Initialize project",value:"init",description:"Setup VeeStack in this folder"},{title:"Upload results",value:"upload",description:"Upload scan to dashboard"},{title:"Check status",value:"status",description:"Account and project status"},{title:"Run doctor",value:"doctor",description:"Diagnose environment issues"},{title:"Login",value:"login",description:"Authenticate with VeeStack"},{title:"Exit",value:"exit"}]});if(t.action&&t.action!=="exit")switch(t.action){case "init":await ut();break;case "scan":await Tn({path:".",output:"snapshot.json"});break;case "upload":await bn({file:"snapshot.json"});break;case "status":await Rn();break;case "doctor":await Nn();break;case "login":await Rt();break}}else F.parse();}ja();
package/dist/version.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vee_stack/cli",
3
- "version": "6.3.9",
3
+ "version": "6.3.10",
4
4
  "commit": "eb2a9885e020e3baef623e0d681d20c0b6f271e4",
5
- "buildTime": "2026-03-14T10:08:11.922Z",
5
+ "buildTime": "2026-03-14T10:36:50.589Z",
6
6
  "node": ">=18.0.0"
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vee_stack/cli",
3
- "version": "6.3.9",
3
+ "version": "6.3.10",
4
4
  "description": "VeeStack CLI - Technical Stack Visibility Tool",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",