@shieldly/cli 1.0.0 → 1.0.1

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/cli.cjs +33 -33
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var J=Object.create;var O=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,Z=Object.prototype.hasOwnProperty;var Q=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of q(o))!Z.call(e,s)&&s!==t&&O(e,s,{get:()=>o[s],enumerable:!(n=B(o,s))||n.enumerable});return e};var C=(e,o,t)=>(t=e!=null?J(V(e)):{},Q(o||!e||!e.__esModule?O(t,"default",{value:e,enumerable:!0}):t,e));var $=require("node:fs"),j=require("node:os"),D=require("node:path"),b="Shieldly-CLI/1.0.0",z=(0,D.join)((0,j.homedir)(),".shieldly","config.json"),X="https://api.shieldly.io",ee="https://www.shieldly.io";function g(e){if(e)return e;if(process.env.SHIELDLY_API_KEY)return process.env.SHIELDLY_API_KEY;if((0,$.existsSync)(z))try{let o=JSON.parse((0,$.readFileSync)(z,"utf8"));if(o.apiKey)return o.apiKey}catch{}return null}function _(){return(process.env.SHIELDLY_API_URL||X).replace(/\/$/,"")}function oe(){return(process.env.SHIELDLY_WEB_URL||ee).replace(/\/$/,"")}async function R(e,o){let t=oe(),n=await fetch(`${t}${e}`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":b},body:JSON.stringify(o)});if(!n.ok){let s=await n.json().catch(()=>({}));throw new Error(s.error||`API error ${n.status}`)}return n.json()}async function I(e,o,t){let n=_(),s=await fetch(`${n}${e}`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":b,Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(s.status===202){let r=await s.json().catch(()=>({}));if(r.jobId)return se(r.jobId,t)}if(!s.ok){let r=await s.json().catch(()=>({}));throw new Error(r.error||`API error ${s.status}`)}return s.json()}async function se(e,o){let t=[2e3,3e3,5e3],n=Date.now(),s=0;for(let r=0;r<180;r++){let i=t[Math.min(r,t.length-1)];await new Promise(c=>setTimeout(c,i));let l=Math.round((Date.now()-n)/1e3);process.stderr.write(`\rAI-Powered analysis in progress\u2026 (${l}s)`);let a;try{a=await v(`/v1/jobs/${encodeURIComponent(e)}`,o),s=0}catch(c){if(++s>=3)throw process.stderr.write(`
3
- `),c;continue}if(a.status==="complete")return process.stderr.write(`
4
- `),{...a.result,unitInfo:a.unitInfo};if(a.status==="failed")throw process.stderr.write(`
5
- `),new Error(a.error||"Analysis failed")}throw process.stderr.write(`
6
- `),new Error("Analysis timed out after polling")}async function v(e,o){let t=_(),n=await fetch(`${t}${e}`,{headers:{Authorization:`Bearer ${o}`,"User-Agent":b}});if(!n.ok){let s=await n.json().catch(()=>({}));throw new Error(s.error||`API error ${n.status}`)}return n.json()}async function M(e,o,t){let n=_(),s=await fetch(`${n}${e}`,{method:"DELETE",headers:{"Content-Type":"application/json","User-Agent":b,Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(!s.ok){let r=await s.json().catch(()=>({}));throw new Error(r.error||`API error ${s.status}`)}return s.json()}function w(e){return(0,$.existsSync)(e)||(console.error(`Error: File not found: ${e}`),process.exit(1)),(0,$.readFileSync)(e,"utf8")}var K={CRITICAL:"\x1B[31m",HIGH:"\x1B[33m",MEDIUM:"\x1B[36m",LOW:"\x1B[32m",INFO:"\x1B[90m"},m="\x1B[0m",k="\x1B[1m",L="\x1B[2m",Y="\x1B[36m";function x(e,o){if(o==="json"){console.log(JSON.stringify(e,null,2));return}let{score:t,riskLevel:n,findings:s=[],cached:r}=e;if(console.log(""),console.log(`${k}AI-Powered Security Analysis \u2014 Shieldly${m}`),console.log(`${L}${"\u2500".repeat(50)}${m}`),console.log(` ${k}Security Score:${m} ${te(t)}${t}/100${m}`),console.log(` ${k}Risk Level:${m} ${ne(n)}${n}${m}`),r&&console.log(` ${L}(cached result)${m}`),console.log(""),s.length===0)console.log(` ${Y}[PASS] No findings${m}`);else{console.log(`${k}Findings (${s.length}):${m}`);for(let i of s){let l=K[(i.severity||"").toUpperCase()]||"";console.log(`
7
- ${l}[${i.severity}]${m} ${k}${i.title}${m}`),i.description&&console.log(` ${L}${i.description}${m}`),i.remediation&&console.log(` ${Y}Fix:${m} ${i.remediation}`)}}console.log("")}function te(e){return e>=80?"\x1B[32m":e>=50?"\x1B[33m":"\x1B[31m"}function ne(e){let o=(e||"").toUpperCase();return K[o]||""}var le=`
2
+ var B=Object.create;var O=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var X=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of V(o))!Q.call(e,s)&&s!==t&&O(e,s,{get:()=>o[s],enumerable:!(n=q(o,s))||n.enumerable});return e};var z=(e,o,t)=>(t=e!=null?B(Z(e)):{},X(o||!e||!e.__esModule?O(t,"default",{value:e,enumerable:!0}):t,e));var g=require("node:fs"),j=require("node:os"),D=require("node:path"),w="Shieldly-CLI/1.0.1",C=(0,D.join)((0,j.homedir)(),".shieldly","config.json"),ee="https://api.shieldly.io",oe="https://www.shieldly.io";function I(e){if(e)return e;if(process.env.SHIELDLY_API_KEY)return process.env.SHIELDLY_API_KEY;if((0,g.existsSync)(C))try{let o=JSON.parse((0,g.readFileSync)(C,"utf8"));if(o.apiKey)return o.apiKey}catch{}return null}function L(){return(process.env.SHIELDLY_API_URL||ee).replace(/\/$/,"")}function se(){return(process.env.SHIELDLY_WEB_URL||oe).replace(/\/$/,"")}async function R(e,o){let t=se(),n=await fetch(`${t}${e}`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":w},body:JSON.stringify(o)});if(!n.ok){let s=await n.json().catch(()=>({}));throw new Error(s.error||`API error ${n.status}`)}return n.json()}async function k(e,o,t){let n=L(),s=await fetch(`${n}${e}`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":w,Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(s.status===202){let r=await s.json().catch(()=>({}));if(r.jobId)return te(r.jobId,t)}if(!s.ok){let r=await s.json().catch(()=>({}));throw new Error(r.error||`API error ${s.status}`)}return s.json()}async function te(e,o){let t=[2e3,3e3,5e3],n=Date.now(),s=0;for(let r=0;r<180;r++){let a=t[Math.min(r,t.length-1)];await new Promise(c=>setTimeout(c,a));let l=Math.round((Date.now()-n)/1e3);process.stderr.write(`\rAI-Powered analysis in progress\u2026 (${l}s)`);let i;try{i=await v(`/v1/jobs/${encodeURIComponent(e)}`,o),s=0}catch(c){if(++s>=3)throw process.stderr.write(`
3
+ `),c;continue}if(i.status==="complete")return process.stderr.write(`
4
+ `),{...i.result,unitInfo:i.unitInfo};if(i.status==="failed")throw process.stderr.write(`
5
+ `),new Error(i.error||"Analysis failed")}throw process.stderr.write(`
6
+ `),new Error("Analysis timed out after polling")}async function v(e,o){let t=L(),n=await fetch(`${t}${e}`,{headers:{Authorization:`Bearer ${o}`,"User-Agent":w}});if(!n.ok){let s=await n.json().catch(()=>({}));throw new Error(s.error||`API error ${n.status}`)}return n.json()}async function M(e,o,t){let n=L(),s=await fetch(`${n}${e}`,{method:"DELETE",headers:{"Content-Type":"application/json","User-Agent":w,Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(!s.ok){let r=await s.json().catch(()=>({}));throw new Error(r.error||`API error ${s.status}`)}return s.json()}function x(e){return(0,g.existsSync)(e)||(console.error(`Error: File not found: ${e}`),process.exit(1)),(0,g.readFileSync)(e,"utf8")}var K={CRITICAL:"\x1B[31m",HIGH:"\x1B[33m",MEDIUM:"\x1B[36m",LOW:"\x1B[32m",INFO:"\x1B[90m"},y="\x1B[0m",A="\x1B[1m",_="\x1B[2m",Y="\x1B[36m";function P(e,o){if(o==="json"){console.log(JSON.stringify(e,null,2));return}let{score:t,riskLevel:n,findings:s=[],cached:r}=e;if(console.log(""),console.log(`${A}AI-Powered Security Analysis \u2014 Shieldly${y}`),console.log(`${_}${"\u2500".repeat(50)}${y}`),console.log(` ${A}Security Score:${y} ${ne(t)}${t}/100${y}`),console.log(` ${A}Risk Level:${y} ${le(n)}${n}${y}`),r&&console.log(` ${_}(cached result)${y}`),console.log(""),s.length===0)console.log(` ${Y}[PASS] No findings${y}`);else{console.log(`${A}Findings (${s.length}):${y}`);for(let a of s){let l=K[(a.severity||"").toUpperCase()]||"";console.log(`
7
+ ${l}[${a.severity}]${y} ${A}${a.title}${y}`),a.description&&console.log(` ${_}${a.description}${y}`),a.remediation&&console.log(` ${Y}Fix:${y} ${a.remediation}`)}}console.log("")}function ne(e){return e>=80?"\x1B[32m":e>=50?"\x1B[33m":"\x1B[31m"}function le(e){let o=(e||"").toUpperCase();return K[o]||""}var re=`
8
8
  Usage: shieldly analyze-cf <template-file> [options]
9
9
 
10
10
  Analyze a CloudFormation template for security issues using AI.
@@ -20,8 +20,8 @@ Options:
20
20
  Examples:
21
21
  shieldly analyze-cf template.json
22
22
  shieldly analyze-cf template.yaml --format json
23
- `;async function H(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(le);return}let o=e.find(l=>!l.startsWith("--"));o||(console.error("Error: template-file argument is required"),process.exit(1));let t=e.indexOf("--format"),n=t!==-1?e[t+1]:"table",s=e.indexOf("--api-key"),r=g(s!==-1?e[s+1]:null);r||(console.error(`Error: API key required. Set SHIELDLY_API_KEY env var or use --api-key.
24
- Get your free key at https://www.shieldly.io/app/api`),process.exit(1));let i=w(o);n!=="json"&&console.log(`Analyzing ${o}\u2026`);try{let l=await I("/v1/analyze/cf",{template:i},r);x(l,n);let a=(l.findings||[]).filter(y=>y.severity==="CRITICAL").length,c=(l.findings||[]).filter(y=>y.severity==="HIGH").length;(a>0||c>0)&&process.exit(1)}catch(l){console.error(`Error: ${l.message}`),process.exit(1)}}var re=`
23
+ `;async function H(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(re);return}let o=e.find(l=>!l.startsWith("--"));o||(console.error("Error: template-file argument is required"),process.exit(1));let t=e.indexOf("--format"),n=t!==-1?e[t+1]:"table",s=e.indexOf("--api-key"),r=I(s!==-1?e[s+1]:null);r||(console.error(`Error: API key required. Set SHIELDLY_API_KEY env var or use --api-key.
24
+ Get your free key at https://www.shieldly.io/app/api`),process.exit(1));let a=x(o);n!=="json"&&console.log(`Analyzing ${o}\u2026`);try{let l=await k("/v1/analyze/cf",{template:a},r);P(l,n);let i=(l.findings||[]).filter(h=>h.severity==="CRITICAL").length,c=(l.findings||[]).filter(h=>h.severity==="HIGH").length;(i>0||c>0)&&process.exit(1)}catch(l){console.error(`Error: ${l.message}`),process.exit(1)}}var ie=`
25
25
  Usage: shieldly analyze-iam <policy-file> [options]
26
26
 
27
27
  Analyze an AWS IAM policy for security issues using AI.
@@ -41,7 +41,7 @@ Examples:
41
41
  shieldly analyze-iam policy.json
42
42
  shieldly analyze-iam policy.json --type resource --format json
43
43
  SHIELDLY_API_KEY=sk_... shieldly analyze-iam policy.json
44
- `;async function F(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(re);return}let o=e.find(y=>!y.startsWith("--"));o||(console.error("Error: policy-file argument is required"),process.exit(1));let t=e.indexOf("--type"),n=t!==-1?e[t+1]:"identity",s=e.indexOf("--format"),r=s!==-1?e[s+1]:"table",i=e.indexOf("--api-key"),l=g(i!==-1?e[i+1]:null),a=w(o),c;try{c=JSON.parse(a)}catch{console.error("Error: policy-file must be valid JSON"),process.exit(1)}r!=="json"&&(console.log(`Analyzing ${o} (type: ${n})\u2026`),l||console.log("Demo mode (5 lifetime analyses). Get a free key at https://www.shieldly.io/app/api"));try{let y=l?await I("/v1/analyze/iam",{policy:c,policyType:n},l):await R("/api/demo/analyze-iam",{policy:c,policyType:n});x(y,r);let E=(y.findings||[]).filter(S=>S.severity==="CRITICAL").length,d=(y.findings||[]).filter(S=>S.severity==="HIGH").length;(E>0||d>0)&&process.exit(1)}catch(y){console.error(`Error: ${y.message}`),process.exit(1)}}var U=`
44
+ `;async function F(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(ie);return}let o=e.find(d=>!d.startsWith("--"));o||(console.error("Error: policy-file argument is required"),process.exit(1));let t=e.indexOf("--type"),n=t!==-1?e[t+1]:"identity",s=e.indexOf("--format"),r=s!==-1?e[s+1]:"table",a=e.indexOf("--api-key"),l=I(a!==-1?e[a+1]:null),i=x(o);try{JSON.parse(i)}catch{console.error("Error: policy-file must be valid JSON"),process.exit(1)}let c=i.trim(),h=n==="identity"||n==="iam_identity"?"iam_identity":n==="cross_account"?"cross_account":"iam_identity";r!=="json"&&(console.log(`Analyzing ${o} (type: ${h})\u2026`),l||console.log("Demo mode (5 lifetime analyses). Get a free key at https://www.shieldly.io/app/api"));try{let d=l?await k("/v1/analyze/iam",{policy:c,policyType:h},l):await R("/api/demo/analyze-iam",{policy:c,policyType:h});P(d,r);let u=(d.findings||[]).filter(S=>S.severity==="CRITICAL").length,J=(d.findings||[]).filter(S=>S.severity==="HIGH").length;(u>0||J>0)&&process.exit(1)}catch(d){console.error(`Error: ${d.message}`),process.exit(1)}}var U=`
45
45
  Usage: shieldly api-keys <subcommand> [options]
46
46
 
47
47
  Manage Shieldly API keys.
@@ -61,9 +61,9 @@ Examples:
61
61
  shieldly api-keys list
62
62
  shieldly api-keys create --label "CI/CD Key" --scopes iam,cf
63
63
  shieldly api-keys revoke key_abc123
64
- `,u="\x1B[1m",N="\x1B[2m",T="\x1B[36m",h="\x1B[0m";function ie(e){return e?new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"\u2014"}async function G(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(U);return}let o=e[0],t=e.slice(1),n=t.indexOf("--api-key"),s=g(n!==-1?t[n+1]:null),r=t.indexOf("--format"),i=r!==-1?t[r+1]:"table";if(s||(console.error(`Error: API key required. Set SHIELDLY_API_KEY env var or use --api-key.
65
- Get your free key at https://www.shieldly.io/app/api`),process.exit(1)),o==="list"){try{let a=(await v("/v1/api-keys",s)).keys||[];if(i==="json"){console.log(JSON.stringify(a,null,2));return}if(a.length===0){console.log("No API keys found. Create one at https://www.shieldly.io/app/api");return}console.log(""),console.log(`${u}API Keys (${a.length}):${h}`),console.log(`${N}${"\u2500".repeat(60)}${h}`);for(let c of a){let y=(c.scopes||[]).join(", ")||"all";console.log(` ${T}${c.keyId}${h}`),console.log(` ${u}Label:${h} ${c.label||"(unlabeled)"}`),console.log(` ${u}Scopes:${h} ${y}`),console.log(` ${u}Uses:${h} ${c.usageCount||0}`),console.log(` ${u}Created:${h} ${ie(c.createdAt)}`),console.log("")}}catch(l){console.error(`Error: ${l.message}`),process.exit(1)}return}if(o==="create"){let l=t.indexOf("--label"),a=l!==-1?t[l+1]:"CLI Key",c=t.indexOf("--scopes"),E=(c!==-1?t[c+1]:"iam,cf").split(",").map(d=>d.trim()).filter(Boolean);try{let d=await I("/v1/api-keys",{label:a,scopes:E},s);if(i==="json"){console.log(JSON.stringify(d,null,2));return}console.log(""),console.log(`${u}[OK] API key created${h}`),console.log(` ${u}Key ID:${h} ${d.keyId}`),console.log(` ${u}API Key:${h} ${T}${d.apiKey}${h}`),console.log(` ${N}Store this key securely \u2014 it won't be shown again.${h}`),console.log("")}catch(d){console.error(`Error: ${d.message}`),process.exit(1)}return}if(o==="revoke"){let l=t.find(a=>!a.startsWith("--")&&a!=="revoke");l||(console.error(`Error: key-id argument is required
66
- Usage: shieldly api-keys revoke <key-id>`),process.exit(1));try{if(await M("/v1/api-keys",{keyId:l},s),i==="json"){console.log(JSON.stringify({success:!0,keyId:l}));return}console.log(`[OK] API key ${l} revoked`)}catch(a){console.error(`Error: ${a.message}`),process.exit(1)}return}console.error(`Unknown subcommand: ${o}`),console.log(U),process.exit(1)}var ae=`
64
+ `,f="\x1B[1m",N="\x1B[2m",T="\x1B[36m",m="\x1B[0m";function ae(e){return e?new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"\u2014"}async function G(e){if(e.includes("-h")||e.includes("--help")||e.length===0){console.log(U);return}let o=e[0],t=e.slice(1),n=t.indexOf("--api-key"),s=I(n!==-1?t[n+1]:null),r=t.indexOf("--format"),a=r!==-1?t[r+1]:"table";if(s||(console.error(`Error: API key required. Set SHIELDLY_API_KEY env var or use --api-key.
65
+ Get your free key at https://www.shieldly.io/app/api`),process.exit(1)),o==="list"){try{let i=(await v("/v1/api-keys",s)).keys||[];if(a==="json"){console.log(JSON.stringify(i,null,2));return}if(i.length===0){console.log("No API keys found. Create one at https://www.shieldly.io/app/api");return}console.log(""),console.log(`${f}API Keys (${i.length}):${m}`),console.log(`${N}${"\u2500".repeat(60)}${m}`);for(let c of i){let h=(c.scopes||[]).join(", ")||"all";console.log(` ${T}${c.keyId}${m}`),console.log(` ${f}Label:${m} ${c.label||"(unlabeled)"}`),console.log(` ${f}Scopes:${m} ${h}`),console.log(` ${f}Uses:${m} ${c.usageCount||0}`),console.log(` ${f}Created:${m} ${ae(c.createdAt)}`),console.log("")}}catch(l){console.error(`Error: ${l.message}`),process.exit(1)}return}if(o==="create"){let l=t.indexOf("--label"),i=l!==-1?t[l+1]:"CLI Key",c=t.indexOf("--scopes"),d=(c!==-1?t[c+1]:"iam,cf").split(",").map(u=>u.trim()).filter(Boolean);try{let u=await k("/v1/api-keys",{label:i,scopes:d},s);if(a==="json"){console.log(JSON.stringify(u,null,2));return}console.log(""),console.log(`${f}[OK] API key created${m}`),console.log(` ${f}Key ID:${m} ${u.keyId}`),console.log(` ${f}API Key:${m} ${T}${u.apiKey}${m}`),console.log(` ${N}Store this key securely \u2014 it won't be shown again.${m}`),console.log("")}catch(u){console.error(`Error: ${u.message}`),process.exit(1)}return}if(o==="revoke"){let l=t.find(i=>!i.startsWith("--")&&i!=="revoke");l||(console.error(`Error: key-id argument is required
66
+ Usage: shieldly api-keys revoke <key-id>`),process.exit(1));try{if(await M("/v1/api-keys",{keyId:l},s),a==="json"){console.log(JSON.stringify({success:!0,keyId:l}));return}console.log(`[OK] API key ${l} revoked`)}catch(i){console.error(`Error: ${i.message}`),process.exit(1)}return}console.error(`Unknown subcommand: ${o}`),console.log(U),process.exit(1)}var ce=`
67
67
  _shieldly() {
68
68
  local cur prev words cword
69
69
  _init_completion || return
@@ -123,7 +123,7 @@ _shieldly() {
123
123
  fi
124
124
  } &&
125
125
  complete -F _shieldly shieldly
126
- `,ce=`
126
+ `,pe=`
127
127
  #compdef shieldly
128
128
 
129
129
  _shieldly() {
@@ -194,7 +194,7 @@ _shieldly() {
194
194
  }
195
195
 
196
196
  _shieldly
197
- `,pe=`
197
+ `,ye=`
198
198
  Usage: shieldly completion <shell>
199
199
 
200
200
  Generate shell completion scripts for the shieldly CLI.
@@ -208,42 +208,42 @@ Examples:
208
208
  eval "$(shieldly completion bash)" # Source bash completion
209
209
  shieldly completion zsh > /usr/local/share/zsh/site-functions/_shieldly # Install zsh completion
210
210
  shieldly completion install # Auto-detect and install
211
- `;async function W(e){if(!e.length||e.includes("-h")||e.includes("--help")){console.log(pe);return}let o=e[0];switch(o){case"bash":console.log(ae.trimStart());break;case"zsh":console.log(ce.trimStart());break;case"install":await ye();break;default:console.error(`Unsupported shell: ${o}`),console.log("Supported shells: bash, zsh"),process.exit(1)}}async function ye(){let e=process.env.SHELL||"",o=process.env.HOME||"";if(e.includes("zsh")){let t=`${o}/.zshrc`,n=`
211
+ `;async function W(e){if(!e.length||e.includes("-h")||e.includes("--help")){console.log(ye);return}let o=e[0];switch(o){case"bash":console.log(ce.trimStart());break;case"zsh":console.log(pe.trimStart());break;case"install":await me();break;default:console.error(`Unsupported shell: ${o}`),console.log("Supported shells: bash, zsh"),process.exit(1)}}async function me(){let e=process.env.SHELL||"",o=process.env.HOME||"";if(e.includes("zsh")){let t=`${o}/.zshrc`,n=`
212
212
  # shieldly CLI completion
213
213
  autoload -Uz compinit && compinit -C 2>/dev/null
214
- eval "$(shieldly completion zsh)" 2>/dev/null`;try{let{readFileSync:s,appendFileSync:r,existsSync:i}=await import("node:fs");if(i(t)&&s(t,"utf8").includes("shieldly completion")){console.log("shieldly completion already installed in ~/.zshrc");return}r(t,n),console.log("Installed shieldly completion in ~/.zshrc"),console.log("Run: source ~/.zshrc")}catch(s){console.error(`Failed to install: ${s.message}`),process.exit(1)}}else if(e.includes("bash")){let t=`${o}/.bashrc`,n=`
214
+ eval "$(shieldly completion zsh)" 2>/dev/null`;try{let{readFileSync:s,appendFileSync:r,existsSync:a}=await import("node:fs");if(a(t)&&s(t,"utf8").includes("shieldly completion")){console.log("shieldly completion already installed in ~/.zshrc");return}r(t,n),console.log("Installed shieldly completion in ~/.zshrc"),console.log("Run: source ~/.zshrc")}catch(s){console.error(`Failed to install: ${s.message}`),process.exit(1)}}else if(e.includes("bash")){let t=`${o}/.bashrc`,n=`
215
215
  # shieldly CLI completion
216
- source /dev/stdin <<< "$(shieldly completion bash)" 2>/dev/null`;try{let{readFileSync:s,appendFileSync:r,existsSync:i}=await import("node:fs");if(i(t)&&s(t,"utf8").includes("shieldly completion")){console.log("shieldly completion already installed in ~/.bashrc");return}r(t,n),console.log("Installed shieldly completion in ~/.bashrc"),console.log("Run: source ~/.bashrc")}catch(s){console.error(`Failed to install: ${s.message}`),process.exit(1)}}else console.error(`Unsupported shell: ${e}. Install manually:`),console.log(' eval "$(shieldly completion bash)" # For bash'),console.log(' eval "$(shieldly completion zsh)" # For zsh'),process.exit(1)}var f="\x1B[1m",A="\x1B[36m",P="\x1B[2m",p="\x1B[0m",me="1.0.0",he=`
217
- ${f}shieldly${p} \u2014 AI-Powered Security Analysis for AWS
216
+ source /dev/stdin <<< "$(shieldly completion bash)" 2>/dev/null`;try{let{readFileSync:s,appendFileSync:r,existsSync:a}=await import("node:fs");if(a(t)&&s(t,"utf8").includes("shieldly completion")){console.log("shieldly completion already installed in ~/.bashrc");return}r(t,n),console.log("Installed shieldly completion in ~/.bashrc"),console.log("Run: source ~/.bashrc")}catch(s){console.error(`Failed to install: ${s.message}`),process.exit(1)}}else console.error(`Unsupported shell: ${e}. Install manually:`),console.log(' eval "$(shieldly completion bash)" # For bash'),console.log(' eval "$(shieldly completion zsh)" # For zsh'),process.exit(1)}var $="\x1B[1m",b="\x1B[36m",E="\x1B[2m",p="\x1B[0m",he="1.0.0",de=`
217
+ ${$}shieldly${p} \u2014 AI-Powered Security Analysis for AWS
218
218
 
219
- ${f}Usage:${p}
219
+ ${$}Usage:${p}
220
220
  shieldly <command> [args] [options]
221
221
 
222
- ${f}Commands:${p}
223
- ${A}analyze-iam${p} <policy-file> Analyze an IAM policy for security issues
224
- ${A}analyze-cf${p} <template-file> Analyze a CloudFormation template
225
- ${A}api-keys${p} list|create|revoke Manage API keys
226
- ${A}completion${p} bash|zsh|install Generate shell completion
222
+ ${$}Commands:${p}
223
+ ${b}analyze-iam${p} <policy-file> Analyze an IAM policy for security issues
224
+ ${b}analyze-cf${p} <template-file> Analyze a CloudFormation template
225
+ ${b}api-keys${p} list|create|revoke Manage API keys
226
+ ${b}completion${p} bash|zsh|install Generate shell completion
227
227
 
228
- ${f}Global Options:${p}
228
+ ${$}Global Options:${p}
229
229
  --api-key <key> API key (or set SHIELDLY_API_KEY env var)
230
230
  --version Show version
231
231
  -h, --help Show this help
232
232
 
233
- ${f}Authentication:${p}
233
+ ${$}Authentication:${p}
234
234
  Set your API key via env var: export SHIELDLY_API_KEY=sk_...
235
- Get a free API key at: ${A}https://www.shieldly.io/app/api${p}
235
+ Get a free API key at: ${b}https://www.shieldly.io/app/api${p}
236
236
 
237
- ${f}Examples:${p}
238
- ${P}# Analyze an IAM policy${p}
237
+ ${$}Examples:${p}
238
+ ${E}# Analyze an IAM policy${p}
239
239
  shieldly analyze-iam policy.json
240
240
 
241
- ${P}# Analyze a CloudFormation template${p}
241
+ ${E}# Analyze a CloudFormation template${p}
242
242
  shieldly analyze-cf template.yaml
243
243
 
244
- ${P}# List API keys${p}
244
+ ${E}# List API keys${p}
245
245
  shieldly api-keys list
246
246
 
247
- ${P}# Use in CI${p}
247
+ ${E}# Use in CI${p}
248
248
  SHIELDLY_API_KEY=\${{ secrets.SHIELDLY_API_KEY }} shieldly analyze-iam policy.json
249
- `;async function de(){let[,,e,...o]=process.argv;switch((!e||e==="-h"||e==="--help")&&(console.log(he),process.exit(0)),(e==="--version"||e==="-v")&&(console.log(me),process.exit(0)),e){case"analyze-iam":await F(o);break;case"analyze-cf":await H(o);break;case"api-keys":await G(o);break;case"completion":await W(o);break;default:console.error(`Unknown command: ${e}`),console.log(`Run ${f}shieldly --help${p} for usage`),process.exit(1)}}de().catch(e=>{console.error("Fatal error:",e.message),process.exit(1)});
249
+ `;async function ue(){let[,,e,...o]=process.argv;switch((!e||e==="-h"||e==="--help")&&(console.log(de),process.exit(0)),(e==="--version"||e==="-v")&&(console.log(he),process.exit(0)),e){case"analyze-iam":await F(o);break;case"analyze-cf":await H(o);break;case"api-keys":await G(o);break;case"completion":await W(o);break;default:console.error(`Unknown command: ${e}`),console.log(`Run ${$}shieldly --help${p} for usage`),process.exit(1)}}ue().catch(e=>{console.error("Fatal error:",e.message),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shieldly/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AI-Powered Security Analysis for AWS — official CLI",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.shieldly.io",