@venos-inc/venos 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +62 -0
  2. package/dist/index.js +80 -0
  3. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # venos
2
+
3
+ The venos CLI wires your AI clients (Claude Code, Codex, Cursor, Cline, Aider,
4
+ Windsurf, Zed, JetBrains, and more) to your venos security gateway in one
5
+ command. After it runs, every tool call your AI agents make is classified,
6
+ policy-checked, and recorded — with no change to how your developers work.
7
+
8
+ Closed-source, free to install. Access to a gateway is provisioned by venos: the
9
+ CLI is inert without a valid API key, so only paying customers can use it.
10
+
11
+ ## Requirements
12
+
13
+ - Node.js 18 or newer
14
+
15
+ ## 1. Install
16
+
17
+ ```bash
18
+ npm i -g venos
19
+ ```
20
+
21
+ (Or run it without installing: `npx venos init`.) The bundled security
22
+ components ship inside the package — there is nothing else to download.
23
+
24
+ ## 2. Connect your AI clients
25
+
26
+ ```bash
27
+ venos init --orchestrator https://gateway.your-org.venos.ai --api-key venos_xxx
28
+ ```
29
+
30
+ `venos init` detects the AI clients installed on your machine and wires each one
31
+ to the gateway. It is safe to re-run; it only adds what is missing. The API key
32
+ (issued to you by venos) is stored in `~/.venos/config.json` and sent on every
33
+ request — re-running without `--api-key` keeps the stored key.
34
+
35
+ Options:
36
+
37
+ | Flag | Effect |
38
+ |---|---|
39
+ | `--orchestrator <url>` | Gateway base URL (default `http://127.0.0.1:8788`) |
40
+ | `--api-key <key>` | Per-customer API key (`venos_*`) for the hosted gateway |
41
+ | `--json` | Emit machine-readable JSON instead of the human summary |
42
+ | `--no-telemetry` | Skip the activation ping |
43
+ | `--remove` | Undo `init` — remove the venos entry from every wired client and delete `~/.venos/config.json`. Pre-venos backups are preserved. |
44
+
45
+ ## 3. Verify
46
+
47
+ Run your AI client as usual. Activity appears in the venos dashboard within a
48
+ few seconds of the first tool call. If nothing shows up, confirm the
49
+ `--orchestrator` URL is reachable and the API key is valid.
50
+
51
+ ## Other commands
52
+
53
+ ```bash
54
+ venos help # show all commands
55
+ venos init --remove # disconnect every client
56
+ ```
57
+
58
+ ## Upgrading
59
+
60
+ ```bash
61
+ npm i -g venos@latest
62
+ ```
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import{existsSync as rr,mkdirSync as yt,readFileSync as vt,rmSync as wt,writeFileSync as St}from"node:fs";import{dirname as xt,join as Ct}from"node:path";import{randomBytes as kt}from"node:crypto";import{existsSync as wr,readFileSync as Sr}from"node:fs";import{join as xr}from"node:path";import{copyFileSync as pr,existsSync as Q,mkdirSync as gr,renameSync as hr,writeFileSync as yr}from"node:fs";import{dirname as vr}from"node:path";var ee=".venos-backup";function d(e,r){gr(vr(e),{recursive:!0}),Q(e)&&!Q(e+ee)&&pr(e,e+ee);let t=e+".tmp";yr(t,r,{mode:420}),hr(t,e)}function m(e){return JSON.stringify(e,null,2)+`
3
+ `}var w="http://127.0.0.1:4000/v1";var ne="venos";function R(e){return(e??[]).some(r=>r.hooks.some(t=>typeof t.command=="string"&&t.command.includes(ne)))}function re(e,r){let t=e??[];return R(t)?t:[...t,{matcher:"*",hooks:[{type:"command",command:r}]}]}function te(e){return(e??[]).map(r=>({...r,hooks:r.hooks.filter(t=>typeof t.command!="string"||!t.command.includes(ne))})).filter(r=>r.hooks.length>0)}var U={name:"claude-code",transport:"claude-hook",configPath(e){return xr(e,".claude","settings.json")},isInstalled(e){return!0},load(e){if(!wr(e))return{};try{return JSON.parse(Sr(e,"utf8"))}catch{return{}}},isWired(e){return R(e.hooks?.PreToolUse)&&R(e.hooks?.PostToolUse)},inject(e,r){let t=e.hooks??{};return{...e,hooks:{...t,PreToolUse:re(t.PreToolUse,r.hookCommand),PostToolUse:re(t.PostToolUse,r.hookCommand)}}},remove(e){return e.hooks?{...e,hooks:{...e.hooks,PreToolUse:te(e.hooks.PreToolUse),PostToolUse:te(e.hooks.PostToolUse)}}:e},write(e,r){d(e,m(r))}};import{existsSync as S,readFileSync as Cr}from"node:fs";import{join as E}from"node:path";function oe(e){let r=e.mcpServers?.venos;if(!r||r.command!=="node")return!1;let t=r.args?.[0];return!t||t.includes("/A2A/")?!1:S(t)}var I={name:"cursor",transport:"mcp-json",configPath(e){return E(e,".cursor","mcp.json")},isInstalled(e){let r=E(e,".cursor");return S(r)?S(E(r,"mcp.json"))||S(E(r,"extensions")):!1},load(e){if(!S(e))return{};try{return JSON.parse(Cr(e,"utf8"))}catch{return{}}},isWired(e){return oe(e)},inject(e,r){return oe(e)?e:{...e,mcpServers:{...e.mcpServers??{},venos:{command:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{}}}}}},remove(e){if(!e.mcpServers?.venos)return e;let{venos:r,...t}=e.mcpServers;return{...e,mcpServers:t}},write(e,r){d(e,m(r))}};import{existsSync as M,readFileSync as $r}from"node:fs";import{join as de}from"node:path";function kr(e,r){let t=e.slice(0,r).split(/\r\n|\n|\r/g);return[t.length,t.pop().length+1]}function Or(e,r,t){let n=e.split(/\r\n|\n|\r/g),o="",i=(Math.log10(r+1)|0)+1;for(let s=r-1;s<=r+1;s++){let a=n[s-1];a&&(o+=s.toString().padEnd(i," "),o+=": ",o+=a,o+=`
4
+ `,s===r&&(o+=" ".repeat(i+t+2),o+=`^
5
+ `))}return o}var u=class extends Error{line;column;codeblock;constructor(r,t){let[n,o]=kr(t.toml,t.ptr),i=Or(t.toml,n,o);super(`Invalid TOML document: ${r}
6
+
7
+ ${i}`,t),this.line=n,this.column=o,this.codeblock=i}};function Er(e,r){let t=0;for(;e[r-++t]==="\\";);return--t&&t%2}function P(e,r=0,t=e.length){let n=e.indexOf(`
8
+ `,r);return e[n-1]==="\r"&&n--,n<=t?n:-1}function y(e,r){for(let t=r;t<e.length;t++){let n=e[t];if(n===`
9
+ `)return t;if(n==="\r"&&e[t+1]===`
10
+ `)return t+1;if(n<" "&&n!==" "||n==="\x7F")throw new u("control characters are not allowed in comments",{toml:e,ptr:r})}return e.length}function g(e,r,t,n){let o;for(;;){for(;(o=e[r])===" "||o===" "||!t&&(o===`
11
+ `||o==="\r"&&e[r+1]===`
12
+ `);)r++;if(n||o!=="#")break;r=y(e,r)}return r}function ie(e,r,t,n,o=!1){if(!n)return r=P(e,r),r<0?e.length:r;for(let i=r;i<e.length;i++){let s=e[i];if(s==="#")i=P(e,i);else{if(s===t)return i+1;if(s===n||o&&(s===`
13
+ `||s==="\r"&&e[i+1]===`
14
+ `))return i}}throw new u("cannot find end of structure",{toml:e,ptr:r})}function b(e,r){let t=e[r],n=t===e[r+1]&&e[r+1]===e[r+2]?e.slice(r,r+3):t;r+=n.length-1;do r=e.indexOf(n,++r);while(r>-1&&t!=="'"&&Er(e,r));return r>-1&&(r+=n.length,n.length>1&&(e[r]===t&&r++,e[r]===t&&r++)),r}var Pr=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,x=class e extends Date{#r=!1;#t=!1;#e=null;constructor(r){let t=!0,n=!0,o="Z";if(typeof r=="string"){let i=r.match(Pr);i?(i[1]||(t=!1,r=`0000-01-01T${r}`),n=!!i[2],n&&r[10]===" "&&(r=r.replace(" ","T")),i[2]&&+i[2]>23?r="":(o=i[3]||null,r=r.toUpperCase(),!o&&n&&(r+="Z"))):r=""}super(r),isNaN(this.getTime())||(this.#r=t,this.#t=n,this.#e=o)}isDateTime(){return this.#r&&this.#t}isLocal(){return!this.#r||!this.#t||!this.#e}isDate(){return this.#r&&!this.#t}isTime(){return this.#t&&!this.#r}isValid(){return this.#r||this.#t}toISOString(){let r=super.toISOString();if(this.isDate())return r.slice(0,10);if(this.isTime())return r.slice(11,23);if(this.#e===null)return r.slice(0,-1);if(this.#e==="Z")return r;let t=+this.#e.slice(1,3)*60+ +this.#e.slice(4,6);return t=this.#e[0]==="-"?t:-t,new Date(this.getTime()-t*6e4).toISOString().slice(0,-1)+this.#e}static wrapAsOffsetDateTime(r,t="Z"){let n=new e(r);return n.#e=t,n}static wrapAsLocalDateTime(r){let t=new e(r);return t.#e=null,t}static wrapAsLocalDate(r){let t=new e(r);return t.#t=!1,t.#e=null,t}static wrapAsLocalTime(r){let t=new e(r);return t.#r=!1,t.#e=null,t}};var br=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,Tr=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,_r=/^[+-]?0[0-9_]/,Ar=/^[0-9a-f]{2,8}$/i,se={b:"\b",t:" ",n:`
15
+ `,f:"\f",r:"\r",e:"\x1B",'"':'"',"\\":"\\"};function T(e,r=0,t=e.length){let n=e[r]==="'",o=e[r++]===e[r]&&e[r]===e[r+1];o&&(t-=2,e[r+=2]==="\r"&&r++,e[r]===`
16
+ `&&r++);let i=0,s,a="",l=r;for(;r<t-1;){let c=e[r++];if(c===`
17
+ `||c==="\r"&&e[r]===`
18
+ `){if(!o)throw new u("newlines are not allowed in strings",{toml:e,ptr:r-1})}else if(c<" "&&c!==" "||c==="\x7F")throw new u("control characters are not allowed in strings",{toml:e,ptr:r-1});if(s){if(s=!1,c==="x"||c==="u"||c==="U"){let f=e.slice(r,r+=c==="x"?2:c==="u"?4:8);if(!Ar.test(f))throw new u("invalid unicode escape",{toml:e,ptr:i});try{a+=String.fromCodePoint(parseInt(f,16))}catch{throw new u("invalid unicode escape",{toml:e,ptr:i})}}else if(o&&(c===`
19
+ `||c===" "||c===" "||c==="\r")){if(r=g(e,r-1,!0),e[r]!==`
20
+ `&&e[r]!=="\r")throw new u("invalid escape: only line-ending whitespace may be escaped",{toml:e,ptr:i});r=g(e,r)}else if(c in se)a+=se[c];else throw new u("unrecognized escape sequence",{toml:e,ptr:i});l=r}else!n&&c==="\\"&&(i=r-1,s=!0,a+=e.slice(l,i))}return a+e.slice(l,t-1)}function ae(e,r,t,n){if(e==="true")return!0;if(e==="false")return!1;if(e==="-inf")return-1/0;if(e==="inf"||e==="+inf")return 1/0;if(e==="nan"||e==="+nan"||e==="-nan")return NaN;if(e==="-0")return n?0n:0;let o=br.test(e);if(o||Tr.test(e)){if(_r.test(e))throw new u("leading zeroes are not allowed",{toml:r,ptr:t});e=e.replace(/_/g,"");let s=+e;if(isNaN(s))throw new u("invalid number",{toml:r,ptr:t});if(o){if((o=!Number.isSafeInteger(s))&&!n)throw new u("integer value cannot be represented losslessly",{toml:r,ptr:t});(o||n===!0)&&(s=BigInt(e))}return s}let i=new x(e);if(!i.isValid())throw new u("invalid value",{toml:r,ptr:t});return i}function Rr(e,r,t){let n=e.slice(r,t),o=n.indexOf("#");return o>-1&&(y(e,o),n=n.slice(0,o)),[n.trimEnd(),o]}function C(e,r,t,n,o){if(n===0)throw new u("document contains excessively nested structures. aborting.",{toml:e,ptr:r});let i=e[r];if(i==="["||i==="{"){let[l,c]=i==="["?le(e,r,n,o):ce(e,r,n,o);if(t){if(c=g(e,c),e[c]===",")c++;else if(e[c]!==t)throw new u("expected comma or end of structure",{toml:e,ptr:c})}return[l,c]}let s;if(i==='"'||i==="'"){s=b(e,r);let l=T(e,r,s);if(t){if(s=g(e,s),e[s]&&e[s]!==","&&e[s]!==t&&e[s]!==`
21
+ `&&e[s]!=="\r")throw new u("unexpected character encountered",{toml:e,ptr:s});s+=+(e[s]===",")}return[l,s]}s=ie(e,r,",",t);let a=Rr(e,r,s-+(e[s-1]===","));if(!a[0])throw new u("incomplete key-value declaration: no value specified",{toml:e,ptr:r});return t&&a[1]>-1&&(s=g(e,r+a[1]),s+=+(e[s]===",")),[ae(a[0],e,r,o),s]}var Ur=/^[a-zA-Z0-9-_]+[ \t]*$/;function _(e,r,t="="){let n=r-1,o=[],i=e.indexOf(t,r);if(i<0)throw new u("incomplete key-value: cannot find end of key",{toml:e,ptr:r});do{let s=e[r=++n];if(s!==" "&&s!==" ")if(s==='"'||s==="'"){if(s===e[r+1]&&s===e[r+2])throw new u("multiline strings are not allowed in keys",{toml:e,ptr:r});let a=b(e,r);if(a<0)throw new u("unfinished string encountered",{toml:e,ptr:r});n=e.indexOf(".",a);let l=e.slice(a,n<0||n>i?i:n),c=P(l);if(c>-1)throw new u("newlines are not allowed in keys",{toml:e,ptr:r+n+c});if(l.trimStart())throw new u("found extra tokens after the string part",{toml:e,ptr:a});if(i<a&&(i=e.indexOf(t,a),i<0))throw new u("incomplete key-value: cannot find end of key",{toml:e,ptr:r});o.push(T(e,r,a))}else{n=e.indexOf(".",r);let a=e.slice(r,n<0||n>i?i:n);if(!Ur.test(a))throw new u("only letter, numbers, dashes and underscores are allowed in keys",{toml:e,ptr:r});o.push(a.trimEnd())}}while(n+1&&n<i);return[o,g(e,i+1,!0,!0)]}function ce(e,r,t,n){let o={},i=new Set,s;for(r++;(s=e[r++])!=="}"&&s;){if(s===",")throw new u("expected value, found comma",{toml:e,ptr:r-1});if(s==="#")r=y(e,r);else if(s!==" "&&s!==" "&&s!==`
22
+ `&&s!=="\r"){let a,l=o,c=!1,[f,p]=_(e,r-1);for(let O=0;O<f.length;O++){if(O&&(l=c?l[a]:l[a]={}),a=f[O],(c=Object.hasOwn(l,a))&&(typeof l[a]!="object"||i.has(l[a])))throw new u("trying to redefine an already defined value",{toml:e,ptr:r});!c&&a==="__proto__"&&Object.defineProperty(l,a,{enumerable:!0,configurable:!0,writable:!0})}if(c)throw new u("trying to redefine an already defined value",{toml:e,ptr:r});let[h,mr]=C(e,p,"}",t-1,n);i.add(h),l[a]=h,r=mr}}if(!s)throw new u("unfinished table encountered",{toml:e,ptr:r});return[o,r]}function le(e,r,t,n){let o=[],i;for(r++;(i=e[r++])!=="]"&&i;){if(i===",")throw new u("expected value, found comma",{toml:e,ptr:r-1});if(i==="#")r=y(e,r);else if(i!==" "&&i!==" "&&i!==`
23
+ `&&i!=="\r"){let s=C(e,r-1,"]",t-1,n);o.push(s[0]),r=s[1]}}if(!i)throw new u("unfinished array encountered",{toml:e,ptr:r});return[o,r]}function ue(e,r,t,n){let o=r,i=t,s,a=!1,l;for(let c=0;c<e.length;c++){if(c){if(o=a?o[s]:o[s]={},i=(l=i[s]).c,n===0&&(l.t===1||l.t===2))return null;if(l.t===2){let f=o.length-1;o=o[f],i=i[f].c}}if(s=e[c],(a=Object.hasOwn(o,s))&&i[s]?.t===0&&i[s]?.d)return null;a||(s==="__proto__"&&(Object.defineProperty(o,s,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(i,s,{enumerable:!0,configurable:!0,writable:!0})),i[s]={t:c<e.length-1&&n===2?3:n,d:!1,i:0,c:{}})}if(l=i[s],l.t!==n&&!(n===1&&l.t===3)||(n===2&&(l.d||(l.d=!0,o[s]=[]),o[s].push(o={}),l.c[l.i++]=l={t:1,d:!1,i:0,c:{}}),l.d))return null;if(l.d=!0,n===1)o=a?o[s]:o[s]={};else if(n===0&&a)return null;return[s,o,l.c]}function j(e,{maxDepth:r=1e3,integersAsBigInt:t}={}){let n={},o={},i=n,s=o;for(let a=g(e,0);a<e.length;){if(e[a]==="["){let l=e[++a]==="[",c=_(e,a+=+l,"]");if(l){if(e[c[1]-1]!=="]")throw new u("expected end of table declaration",{toml:e,ptr:c[1]-1});c[1]++}let f=ue(c[0],n,o,l?2:1);if(!f)throw new u("trying to redefine an already defined table or value",{toml:e,ptr:a});s=f[2],i=f[1],a=c[1]}else{let l=_(e,a),c=ue(l[0],i,s,0);if(!c)throw new u("trying to redefine an already defined table or value",{toml:e,ptr:a});let f=C(e,l[1],void 0,r,t);c[1][c[0]]=f[0],a=f[1]}if(a=g(e,a,!0),e[a]&&e[a]!==`
24
+ `&&e[a]!=="\r")throw new u("each key-value declaration must be followed by an end-of-line",{toml:e,ptr:a});a=g(e,a)}return n}var fe=/^[a-z0-9-_]+$/i;function k(e){let r=typeof e;if(r==="object"){if(Array.isArray(e))return"array";if(e instanceof Date)return"date"}return r}function Ir(e){for(let r=0;r<e.length;r++)if(k(e[r])!=="object")return!1;return e.length!=0}function W(e){return JSON.stringify(e).replace(/\x7f/g,"\\u007f")}function N(e,r,t,n){if(t===0)throw new Error("Could not stringify the object: maximum object depth exceeded");if(r==="number")return isNaN(e)?"nan":e===1/0?"inf":e===-1/0?"-inf":n&&Number.isInteger(e)?e.toFixed(1):e.toString();if(r==="bigint"||r==="boolean")return e.toString();if(r==="string")return W(e);if(r==="date"){if(isNaN(e.getTime()))throw new TypeError("cannot serialize invalid date");return e.toISOString()}if(r==="object")return jr(e,t,n);if(r==="array")return Wr(e,t,n)}function jr(e,r,t){let n=Object.keys(e);if(n.length===0)return"{}";let o="{ ";for(let i=0;i<n.length;i++){let s=n[i];i&&(o+=", "),o+=fe.test(s)?s:W(s),o+=" = ",o+=N(e[s],k(e[s]),r-1,t)}return o+" }"}function Wr(e,r,t){if(e.length===0)return"[]";let n="[ ";for(let o=0;o<e.length;o++){if(o&&(n+=", "),e[o]===null||e[o]===void 0)throw new TypeError("arrays cannot contain null or undefined values");n+=N(e[o],k(e[o]),r-1,t)}return n+" ]"}function Nr(e,r,t,n){if(t===0)throw new Error("Could not stringify the object: maximum object depth exceeded");let o="";for(let i=0;i<e.length;i++)o+=`${o&&`
25
+ `}[[${r}]]
26
+ `,o+=$(0,e[i],r,t,n);return o}function $(e,r,t,n,o){if(n===0)throw new Error("Could not stringify the object: maximum object depth exceeded");let i="",s="",a=Object.keys(r);for(let l=0;l<a.length;l++){let c=a[l];if(r[c]!==null&&r[c]!==void 0){let f=k(r[c]);if(f==="symbol"||f==="function")throw new TypeError(`cannot serialize values of type '${f}'`);let p=fe.test(c)?c:W(c);if(f==="array"&&Ir(r[c]))s+=(s&&`
27
+ `)+Nr(r[c],t?`${t}.${p}`:p,n-1,o);else if(f==="object"){let h=t?`${t}.${p}`:p;s+=(s&&`
28
+ `)+$(h,r[c],h,n-1,o)}else i+=p,i+=" = ",i+=N(r[c],f,n,o),i+=`
29
+ `}}return e&&(i||!s)&&(i=i?`[${e}]
30
+ ${i}`:`[${e}]`),i&&s?`${i}
31
+ ${s}`:i||s}function V(e,{maxDepth:r=1e3,numbersAsFloat:t=!1}={}){if(k(e)!=="object")throw new TypeError("stringify can only be called with an object");let n=$(0,e,"",r,t);return n[n.length-1]!==`
32
+ `?n+`
33
+ `:n}function me(e){let r=e.mcp_servers?.venos;if(!r||r.command!=="node")return!1;let t=r.args?.[0];return!t||t.includes("/A2A/")?!1:M(t)}var pe={name:"codex",transport:"mcp-toml",configPath(e){return de(e,".codex","config.toml")},isInstalled(e){return M(de(e,".codex"))},load(e){if(!M(e))return{};try{return j($r(e,"utf8"))}catch{return{}}},isWired(e){return me(e)},inject(e,r){return me(e)?e:{...e,mcp_servers:{...e.mcp_servers??{},venos:{command:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{},VENOS_SOURCE:"codex"}}}}},remove(e){if(!e.mcp_servers?.venos)return e;let{venos:r,...t}=e.mcp_servers;return{...e,mcp_servers:t}},write(e,r){d(e,V(r)+`
34
+ `)}};import{existsSync as ge,readFileSync as Vr}from"node:fs";import{join as he}from"node:path";var we="venos";function J(e){return(e??[]).some(r=>r.hooks.some(t=>typeof t.command=="string"&&t.command.includes(we)))}function ye(e,r){let t=e??[];return J(t)?t:[...t,{matcher:"*",hooks:[{type:"command",command:r}]}]}function ve(e){return(e??[]).map(r=>({...r,hooks:r.hooks.filter(t=>typeof t.command!="string"||!t.command.includes(we))})).filter(r=>r.hooks.length>0)}function Mr(e){return`${e.hookCommand} --source codex`}var Se={name:"codex-hook",transport:"claude-hook",configPath(e){return he(e,".codex","hooks.json")},isInstalled(e){return ge(he(e,".codex"))},load(e){if(!ge(e))return{};try{return JSON.parse(Vr(e,"utf8"))}catch{return{}}},isWired(e){return J(e.hooks?.PreToolUse)&&J(e.hooks?.PostToolUse)},inject(e,r){let t=e.hooks??{},n=Mr(r);return{...e,hooks:{...t,PreToolUse:ye(t.PreToolUse,n),PostToolUse:ye(t.PostToolUse,n)}}},remove(e){return e.hooks?{...e,hooks:{...e.hooks,PreToolUse:ve(e.hooks.PreToolUse),PostToolUse:ve(e.hooks.PostToolUse)}}:e},write(e,r){d(e,m(r))}};import{existsSync as L,readFileSync as Jr}from"node:fs";import{join as xe}from"node:path";function Ce(e){let r=e.mcpServers?.venos;if(!r||r.command!=="node")return!1;let t=r.args?.[0];return!t||t.includes("/A2A/")?!1:L(t)}var ke={name:"windsurf",transport:"mcp-json",configPath(e){return xe(e,".codeium","windsurf","mcp_config.json")},isInstalled(e){return L(xe(e,".codeium","windsurf"))},load(e){if(!L(e))return{};try{return JSON.parse(Jr(e,"utf8"))}catch{return{}}},isWired(e){return Ce(e)},inject(e,r){return Ce(e)?e:{...e,mcpServers:{...e.mcpServers??{},venos:{command:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{}}}}}},remove(e){if(!e.mcpServers?.venos)return e;let{venos:r,...t}=e.mcpServers;return{...e,mcpServers:t}},write(e,r){d(e,m(r))}};import{existsSync as H,readFileSync as Lr}from"node:fs";import{join as v}from"node:path";var Oe="saoudrizwan.claude-dev",Hr="cline_mcp_settings.json";function Ee(e){if(process.platform==="darwin")return v(e,"Library","Application Support","Code","User");if(process.platform==="win32"){let r=process.env.APPDATA??v(e,"AppData","Roaming");return v(r,"Code","User")}return v(e,".config","Code","User")}function Pe(e){let r=e.mcpServers?.venos;if(!r||r.command!=="node")return!1;let t=r.args?.[0];return!t||t.includes("/A2A/")?!1:H(t)}var be={name:"cline",transport:"mcp-json",configPath(e){return v(Ee(e),"globalStorage",Oe,"settings",Hr)},isInstalled(e){return H(v(Ee(e),"globalStorage",Oe))},load(e){if(!H(e))return{};try{return JSON.parse(Lr(e,"utf8"))}catch{return{}}},isWired(e){return Pe(e)},inject(e,r){return Pe(e)?e:{...e,mcpServers:{...e.mcpServers??{},venos:{command:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{}}}}}},remove(e){if(!e.mcpServers?.venos)return e;let{venos:r,...t}=e.mcpServers;return{...e,mcpServers:t}},write(e,r){d(e,m(r))}};import{existsSync as F,readFileSync as Fr}from"node:fs";import{join as Te}from"node:path";function _e(e){let r=e.context_servers?.venos;if(!r||r.command?.path!=="node")return!1;let t=r.command.args?.[0];return!t||t.includes("/A2A/")?!1:F(t)}var Ae={name:"zed",transport:"mcp-json",configPath(e){return Te(e,".config","zed","settings.json")},isInstalled(e){return F(Te(e,".config","zed"))},load(e){if(!F(e))return{};try{return JSON.parse(Fr(e,"utf8"))}catch{return{}}},isWired(e){return _e(e)},inject(e,r){return _e(e)?e:{...e,context_servers:{...e.context_servers??{},venos:{command:{path:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{}}},settings:{}}}}},remove(e){if(!e.context_servers?.venos)return e;let{venos:r,...t}=e.context_servers;return{...e,context_servers:t}},write(e,r){d(e,m(r))}};import{existsSync as K,readFileSync as Kr}from"node:fs";import{join as Re}from"node:path";function Ue(e){let r=e.mcpServers?.venos;if(!r||r.command!=="node")return!1;let t=r.args?.[0];return!t||t.includes("/A2A/")?!1:K(t)}var Ie={name:"jetbrains",transport:"mcp-json",configPath(e){return Re(e,".junie","mcp","mcp.json")},isInstalled(e){return K(Re(e,".junie"))},load(e){if(!K(e))return{};try{return JSON.parse(Kr(e,"utf8"))}catch{return{}}},isWired(e){return Ue(e)},inject(e,r){return Ue(e)?e:{...e,mcpServers:{...e.mcpServers??{},venos:{command:"node",args:[r.mcpServerPath],env:{VENOS_URL:r.orchestratorUrl,VENOS_ORG_ID:r.orgId,...r.apiKey?{VENOS_API_KEY:r.apiKey}:{}}}}}},remove(e){if(!e.mcpServers?.venos)return e;let{venos:r,...t}=e.mcpServers;return{...e,mcpServers:t}},write(e,r){d(e,m(r))}};import{existsSync as je,readFileSync as Dr,rmSync as Br}from"node:fs";import{join as Gr}from"node:path";var zr="openai-api-base",Yr=".aider.conf.yml";function We(){return`${zr}: ${w}`}function Zr(e){return/^\s*openai-api-base\s*:/.test(e)}var Ne={name:"aider",transport:"mcp-json",configPath(e){return Gr(e,Yr)},isInstalled(){return!0},load(e){let r=je(e)?Dr(e,"utf8"):"";return{wired:r.split(`
35
+ `).some(n=>n.trim()===We()),raw:r}},isWired(e){return e.wired},inject(e){return e.wired?e:{...e,wired:!0}},remove(e){return{...e,wired:!1}},write(e,r){let t=r.raw===""?[]:r.raw.split(`
36
+ `);t.length>0&&t[t.length-1]===""&&t.pop();let n=t.filter(i=>!Zr(i)),o=r.wired?[...n,We()]:n;if(o.length===0){je(e)&&Br(e,{force:!0});return}d(e,o.join(`
37
+ `)+`
38
+ `)}};import{accessSync as Xr,constants as qr,existsSync as Ve,readFileSync as Qr}from"node:fs";import{delimiter as et}from"node:path";import{join as Me}from"node:path";var rt="obsidian-cli",tt="obsidian-cli.json";function nt(e){try{return Xr(e,qr.X_OK),!0}catch{return!1}}function ot(e){return(process.env.PATH??"").split(et).some(t=>{if(t.trim()==="")return!1;let n=Me(t,e);return Ve(n)&&nt(n)})}function $e(e){return e.venos?.source==="obsidian-cli"&&e.venos.wired===!0}var Je={name:"obsidian-cli",transport:"mcp-json",configPath(e){return Me(e,".venos",tt)},isInstalled(){return ot(rt)},load(e){if(!Ve(e))return{};try{return JSON.parse(Qr(e,"utf8"))}catch{return{}}},isWired(e){return $e(e)},inject(e,r){return $e(e)?e:{...e,venos:{source:"obsidian-cli",orgId:r.orgId,orchestratorUrl:r.orchestratorUrl,wired:!0}}},remove(e){if(!e.venos)return e;let r={...e};return delete r.venos,r},write(e,r){d(e,m(r))}};var D=[U,I,pe,Se,ke,be,Ae,Ie,Ne,Je];import{existsSync as B}from"node:fs";import{dirname as it,join as Le,resolve as G}from"node:path";import{fileURLToPath as st}from"node:url";var He=it(st(import.meta.url));function Fe(){let e=process.env.VENOS_MCP_SERVER_PATH;if(e&&B(e))return G(e);let r=G(Le(He,"..","etc","mcp-server","bin.js"));if(B(r))return r;let t=G(Le(He,"..","..","..","packages","mcp-server","dist","bin.js"));if(B(t))return t;throw new Error(`venos: bundled mcp-server not found. Tried:
39
+ VENOS_MCP_SERVER_PATH=${e??"(unset)"}
40
+ bundled: ${r}
41
+ sibling: ${t}
42
+ If you are developing locally, run: pnpm --filter @venos/mcp-server build`)}import{existsSync as at}from"node:fs";function ct(e,r,t){let n=e.configPath(r);if(!e.isInstalled(r))return{client:e.name,transport:e.transport,status:"skipped-not-installed"};try{let o=e.load(n);if(e.isWired(o,t))return{client:e.name,transport:e.transport,status:"already-wired",path:n};let i=e.inject(o,t);return e.write(n,i),{client:e.name,transport:e.transport,status:"wired",path:n}}catch(o){return{client:e.name,transport:e.transport,status:"error",path:n,error:o instanceof Error?o.message:String(o)}}}function Ke(e,r,t){return t.map(n=>ct(n,e,r))}function lt(e,r){let t=e.configPath(r);if(!e.isInstalled(r))return{client:e.name,transport:e.transport,status:"skipped-not-installed"};if(!at(t))return{client:e.name,transport:e.transport,status:"already-removed",path:t};try{let n=e.load(t),o=e.remove(n);return JSON.stringify(o)===JSON.stringify(n)?{client:e.name,transport:e.transport,status:"already-removed",path:t}:(e.write(t,o),{client:e.name,transport:e.transport,status:"removed",path:t})}catch(n){return{client:e.name,transport:e.transport,status:"error",path:t,error:n instanceof Error?n.message:String(n)}}}function De(e,r){return r.map(t=>lt(t,e))}import{existsSync as Be,mkdirSync as ut,readFileSync as ft}from"node:fs";import{join as Ge}from"node:path";var ze="cline.openaiBaseUrl";function Ye(e){let r=Ge(e,".vscode");if(!Be(r))return{status:"no-workspace"};let t=Ge(r,"settings.json"),n={};if(Be(t))try{let o=JSON.parse(ft(t,"utf8"));o&&typeof o=="object"&&(n=o)}catch{}return n[ze]===w?{status:"already-wired",path:t}:(ut(r,{recursive:!0}),d(t,m({...n,[ze]:w})),{status:"wired",path:t})}var dt={wired:"OK","already-wired":"\xB7","skipped-not-installed":"\u2014",error:"FAIL"},mt={wired:"wired","already-wired":"already wired","skipped-not-installed":"skipped (not installed)",error:"ERROR"},z="http://127.0.0.1:4000/v1";function Ze(e,r){let t=e.some(n=>n.status==="wired");console.log(`
43
+ venos init ${t?"done":"(no changes)"}`),console.log(` org ID : ${r.orgId}`),console.log(` orchestrator: ${r.orchestratorUrl}`);for(let n of e){let o=dt[n.status],i=mt[n.status],s=n.path?` ${n.path}`:"",a=n.error?` \u2014 ${n.error}`:"";console.log(` ${o} ${n.client.padEnd(12)} ${i}${s}${a}`)}if(r.clineWorkspace){let n=r.clineWorkspace;n.status==="wired"?console.log(` OK cline (ws) wired ${n.path}`):n.status==="already-wired"&&console.log(` \xB7 cline (ws) already wired ${n.path}`)}if(t){console.log(`
44
+ Next steps:`);let n={"claude-code":"Restart Claude Code for the hook to take effect.",cursor:"Restart Cursor to load the venos MCP server.",codex:"Restart Codex to pick up the new MCP config + gateway routing (~/.codex/.env).",windsurf:"Restart Windsurf to load the venos MCP server.",cline:"Reload the Cline extension (or restart VS Code) to load the venos MCP server.",zed:"Restart Zed to load the venos context server.",jetbrains:"Restart your JetBrains IDE (or just Junie) to load the venos MCP server.",aider:"Aider will route LLM calls through the venos gateway on next launch (~/.aider.conf.yml)."};for(let o of e){if(o.status!=="wired")continue;let i=n[o.client];i&&console.log(` \u2022 ${i}`)}console.log(` \u2022 Test: curl ${r.orchestratorUrl}/healthz`)}pt(r.clineWorkspace)}function pt(e){console.log(`
45
+ Gateway routing (hard block via apps/mcp-proxy):`),console.log(` \u2022 Cursor \u2014 Settings \u2192 Models \u2192 Custom OpenAI Base URL: ${z}`),console.log(" Optional: Custom HTTP Headers \u2192 X-Venos-Source: cursor"),console.log(` \u2022 Windsurf \u2014 Settings \u2192 Models \u2192 Custom OpenAI Base URL: ${z}`),(!e||e.status==="no-workspace")&&(console.log(" \u2022 Cline \u2014 Open VS Code in your project, then add to .vscode/settings.json:"),console.log(` "cline.openaiBaseUrl": "${z}"`)),console.log(" \u2022 VS Code Copilot \u2014 closed provider, no custom endpoint. Coverage = MCP advisory only."),console.log(" \u2022 JetBrains AI Assistant \u2014 closed provider, no custom endpoint. Coverage = MCP advisory only.")}function Xe(e,r){console.log(JSON.stringify({...r,outcomes:e},null,2))}var gt={removed:"OK","already-removed":"\xB7","skipped-not-installed":"\u2014",error:"FAIL"},ht={removed:"removed","already-removed":"already removed","skipped-not-installed":"skipped (not installed)",error:"ERROR"};function qe(e,r){let t=e.some(i=>i.status==="removed");console.log(`
46
+ venos init --remove ${t?"done":"(no changes)"}`);for(let i of e){let s=gt[i.status],a=ht[i.status],l=i.path?` ${i.path}`:"",c=i.error?` \u2014 ${i.error}`:"";console.log(` ${s} ${i.client.padEnd(12)} ${a}${l}${c}`)}let n=r.venosConfigRemoved?"OK":"\xB7",o=r.venosConfigRemoved?"removed":"already removed";console.log(` ${n} venos-config ${o} ${r.venosConfigPath}`),console.log("\nPre-venos `.venos-backup` snapshots are preserved \u2014 delete manually if you don't want them.")}function Qe(e,r){console.log(JSON.stringify({...r,outcomes:e},null,2))}var er=1;function Y(e){return Ct(e,".venos","config.json")}function Ot(){return`org-${kt(4).toString("hex")}`}function Et(e,r,t){let n=Y(e);if(rr(n))try{let o=JSON.parse(vt(n,"utf8")),i={schemaVersion:o.schemaVersion??er,...o,orchestratorUrl:r};return t&&(i.apiKey=t),i}catch{}return{schemaVersion:er,orgId:Ot(),orchestratorUrl:r,createdAt:new Date().toISOString(),...t?{apiKey:t}:{}}}function Pt(e,r){let t=Y(e);yt(xt(t),{recursive:!0}),St(t,JSON.stringify(r,null,2)+`
47
+ `,"utf8")}var bt=5e3,Tt=5e3;async function _t(e){let r=e.replace(/\/$/,""),t=new AbortController,n=setTimeout(()=>t.abort(),bt);try{return(await fetch(`${r}/healthz`,{signal:t.signal})).ok}catch{return!1}finally{clearTimeout(n)}}async function At(e,r){let t=e.replace(/\/$/,""),n=new AbortController,o=setTimeout(()=>n.abort(),Tt);try{let i=await fetch(`${t}/api/activation/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({orgId:r}),signal:n.signal});i.ok||console.warn(`[venos] activation telemetry: non-200 response (${i.status}) \u2014 init continues`)}catch{console.warn("[venos] activation telemetry: failed to reach orchestrator \u2014 init continues")}finally{clearTimeout(o)}}function Rt(e){try{let r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"||r.hostname==="::1"}catch{return!1}}async function tr(e={}){let r=e.home??process.env.HOME??process.env.USERPROFILE??"",t=e.orchestratorUrl??"http://127.0.0.1:8788";await _t(t)||(console.error(`
48
+ venos init failed: orchestrator unreachable at ${t}/healthz`),console.error("Start the orchestrator first: apps/orchestrator/orchestrator"),process.exit(1));let n=Et(r,t,e.apiKey),o={orgId:n.orgId,orchestratorUrl:t,mcpServerPath:Fe(),hookCommand:"venos hook",...n.apiKey?{apiKey:n.apiKey}:{}},i=Ke(r,o,D);Pt(r,n);let s=Ye(e.cwd??process.cwd());e.noTelemetry===!0||Rt(t)||await At(t,n.orgId);let l={orgId:n.orgId,orchestratorUrl:t,clineWorkspace:s};e.json?Xe(i,l):Ze(i,l)}function nr(e={}){let r=e.home??process.env.HOME??process.env.USERPROFILE??"",t=De(r,D),n=Y(r),o=rr(n);o&&wt(n,{force:!0});let i={venosConfigPath:n,venosConfigRemoved:o};e.json?Qe(t,i):qe(t,i)}import{readFileSync as or,existsSync as Ut}from"node:fs";import{userInfo as It}from"node:os";import{join as jt}from"node:path";function Wt(e){return jt(e,".venos","config.json")}function Nt(e){let r=Wt(e);if(!Ut(r))throw new Error(`venos config not found at ${r} \u2014 run "venos init" first`);return JSON.parse(or(r,"utf8"))}function $t(){return new Promise((e,r)=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>e(t)),process.stdin.on("error",r)})}function Vt(e){let r;try{r=or(e,"utf8")}catch{return null}let t=r.split(/\r?\n/);for(let n=t.length-1;n>=0;n--){let o=t[n]?.trim();if(!o)continue;let i;try{i=JSON.parse(o)}catch{continue}if(i.type!=="assistant"||!i.message||i.message.model==="<synthetic>")continue;let s=i.message.usage;if(!s)continue;let a=typeof s.cache_creation_input_tokens=="number"?s.cache_creation_input_tokens:void 0,l=typeof s.cache_read_input_tokens=="number"?s.cache_read_input_tokens:void 0,c=(s.input_tokens??0)+(a??0)+(l??0),f=s.output_tokens??0,p=i.message.model??"";if(c===0&&f===0&&p==="")return null;let h={tokensIn:c,tokensOut:f,model:p};return l!==void 0&&(h.cacheReadTokens=l),a!==void 0&&(h.cacheWriteTokens=a),h}return null}function Mt(e){let r;try{r=JSON.parse(e)}catch{return e}if(typeof r!="object"||r===null||Array.isArray(r))return e;let t=r,n=t.transcript_path;if(typeof n!="string"||n==="")return e;let o=Vt(n);return o?(t.usage_tokens_in=o.tokensIn,t.usage_tokens_out=o.tokensOut,o.cacheReadTokens!==void 0&&(t.cache_read_input_tokens=o.cacheReadTokens),o.cacheWriteTokens!==void 0&&(t.cache_creation_input_tokens=o.cacheWriteTokens),o.model!==""&&(t.usage_model=o.model),JSON.stringify(t)):e}function Jt(e,r){if(r==="")return e;let t;try{t=JSON.parse(e)}catch{return JSON.stringify({orgId:r,content:e})}if(typeof t!="object"||t===null||Array.isArray(t))return e;let n=t;for(let o of["orgId","org_id","tenantId","tenant_id"]){let i=n[o];if(typeof i=="string"&&i.trim()!=="")return e}return n.orgId=r,JSON.stringify(n)}function Lt(e){try{let t=JSON.parse(e).cursor_version;return typeof t=="string"&&t!==""}catch{return!1}}function Ht(){try{let e=It().username;if(typeof e=="string"&&e.trim()!=="")return e.trim()}catch{}for(let e of["USER","USERNAME","LOGNAME"]){let r=process.env[e];if(typeof r=="string"&&r.trim()!=="")return r.trim()}return""}function Ft(e,r){if(r==="")return e;let t;try{t=JSON.parse(e)}catch{return e}if(typeof t!="object"||t===null||Array.isArray(t))return e;let n=t;for(let o of["userId","user_id"]){let i=n[o];if(typeof i=="string"&&i.trim()!=="")return e}return n.userId=r,JSON.stringify(n)}function Kt(e,r){let t={"Content-Type":"application/json","X-Venos-Org":e};return r&&(t.Authorization=`Bearer ${r}`),t}async function ir(e,r="claude-code"){let t=e??process.env.HOME??process.env.USERPROFILE??"",n=Nt(t),o=await $t(),i=Lt(o),s=Ft(Mt(Jt(o,n.orgId)),Ht()),l=`${n.orchestratorUrl.replace(/\/$/,"")}/v1/hooks/${encodeURIComponent(r)}`,c=await fetch(l,{method:"POST",headers:Kt(n.orgId,n.apiKey),body:s});if(i){await c.text();return}let f=await c.text(),p=r==="codex"?Dt(f):f;process.stdout.write(p),c.ok||(process.stderr.write(`venos hook: orchestrator returned ${c.status}
49
+ `),process.exit(1))}function Dt(e){let r;try{r=JSON.parse(e)}catch{return e}let t=typeof r.decision=="string"?r.decision:"";if(t==="deny"||t==="block"){let n=typeof r.severity=="string"?r.severity:"",o=typeof r.eventId=="string"?r.eventId:"",i=`blocked by venos policy${n?` (severity=${n})`:""}${o?` [event ${o}]`:""}`;return JSON.stringify({decision:"block",reason:i})}return t==="allow"?JSON.stringify({decision:"approve"}):e}import{readFile as Bt}from"node:fs/promises";import{homedir as Gt}from"node:os";import{join as zt}from"node:path";async function sr(e={}){let r=e.home??Gt(),t=zt(r,".venos","config.json"),n;try{n=JSON.parse(await Bt(t,"utf8"))}catch{process.stderr.write("venos: no config found \u2014 run `venos init` first\n"),process.exit(1);return}let o=`${n.orchestratorUrl}/api/billing/checkout`,i;try{i=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({orgId:n.orgId}),signal:AbortSignal.timeout(5e3)})}catch{process.stderr.write(`venos: could not reach orchestrator
50
+ `),process.exit(1);return}if(i.status===503){process.stderr.write(`venos: billing is not yet configured on this server
51
+ `),process.exit(1);return}if(!i.ok){process.stderr.write(`venos: checkout failed (${i.status})
52
+ `),process.exit(1);return}let s=await i.json();if(!s.url){process.stderr.write(`venos: no checkout URL returned
53
+ `),process.exit(1);return}process.stdout.write(`
54
+ Open this URL to upgrade your venos plan:
55
+
56
+ ${s.url}
57
+
58
+ `)}import{readFileSync as Xt,existsSync as qt}from"node:fs";import{join as ur}from"node:path";import{execFile as Qt}from"node:child_process";import{promisify as en}from"node:util";import{existsSync as Z}from"node:fs";import{dirname as Yt,join as ar,resolve as X}from"node:path";import{fileURLToPath as Zt}from"node:url";var cr=Yt(Zt(import.meta.url));function lr(){let e=process.env.VENOS_SESSION_WASTE_PATH;if(e&&Z(e))return X(e);let r=X(ar(cr,"..","etc","session-waste","bin.js"));if(Z(r))return r;let t=X(ar(cr,"..","..","..","packages","session-waste","dist","bin.js"));if(Z(t))return t;throw new Error(`venos: bundled session-waste scanner not found. Tried:
59
+ VENOS_SESSION_WASTE_PATH=${e??"(unset)"}
60
+ bundled: ${r}
61
+ sibling: ${t}
62
+ If you are developing locally, run: pnpm --filter @venos/session-waste build`)}var rn=en(Qt);async function fr(e){let r=e??process.env.HOME??process.env.USERPROFILE??"",t=ur(r,".venos","config.json");if(!qt(t))throw new Error(`venos config not found at ${t} \u2014 run "venos init" first`);let n=JSON.parse(Xt(t,"utf8")),o=lr(),i=ur(r,".claude"),{stdout:s}=await rn(process.execPath,[o,i],{maxBuffer:32*1024*1024}),a=JSON.parse(s),l=Array.isArray(a.findings)?a.findings:[];if(l.length===0)return{sessionsScanned:a.sessionsScanned??0,findingsStored:0};let f=`${n.orchestratorUrl.replace(/\/$/,"")}/api/finops/session-waste?orgId=${encodeURIComponent(n.orgId)}`,p=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json","X-Venos-Org":n.orgId},body:JSON.stringify({findings:l})});if(!p.ok)throw new Error(`venos waste-scan: orchestrator returned ${p.status}`);let h=await p.json();return{sessionsScanned:a.sessionsScanned??0,findingsStored:h.stored??l.length}}var dr=`Usage: venos <command> [options]
63
+
64
+ Commands:
65
+ init Wire your AI client(s) to the venos security gateway
66
+ hook Forward a PreToolUse hook payload to the venos orchestrator
67
+ waste-scan Scan recent sessions for cost waste and report to the orchestrator
68
+ help Show this help
69
+
70
+ Options (init):
71
+ --orchestrator <url> Orchestrator base URL (default: http://127.0.0.1:8788)
72
+ --api-key <key> Per-customer API key (venos_*) for the hosted gateway
73
+ --json Emit machine-readable JSON instead of the human summary
74
+ --no-telemetry Skip activation ping even on a non-localhost URL
75
+ --remove Inverse of init \u2014 drop the venos entry from every
76
+ wired client's config and delete ~/.venos/config.json.
77
+ Pre-venos .venos-backup snapshots are preserved.
78
+ `;function q(e,r){let t=e.indexOf(r);if(!(t===-1||t+1>=e.length))return e[t+1]}function A(e,r){return e.includes(r)}async function tn(){let e=process.argv.slice(2),r=e[0];switch(r){case"init":{if(A(e,"--remove")){nr({json:A(e,"--json")});break}let t=q(e,"--orchestrator"),n=q(e,"--api-key");await tr({...t!==void 0?{orchestratorUrl:t}:{},...n!==void 0?{apiKey:n}:{},json:A(e,"--json"),noTelemetry:A(e,"--no-telemetry")});break}case"hook":{let t=q(e,"--source");await ir(void 0,t??"claude-code");break}case"waste-scan":{let t=await fr();process.stdout.write(`venos waste-scan: ${t.sessionsScanned} session(s) scanned, ${t.findingsStored} finding(s) reported
79
+ `);break}case"upgrade":await sr();return;case"help":case void 0:process.stdout.write(dr),process.exit(0);break;default:process.stderr.write(`Unknown subcommand: ${r}
80
+ ${dr}`),process.exit(2)}}await tn();
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@venos-inc/venos",
3
+ "version": "0.1.0",
4
+ "description": "Self-service CLI for venos — wire your AI client to the venos security gateway in one command.",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "bin": {
11
+ "venos": "./dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "typecheck": "tsc -p tsconfig.json --noEmit",
19
+ "build": "pnpm typecheck && node scripts/bundle-cli.mjs",
20
+ "bundle:mcp-server": "node scripts/bundle-mcp-server.mjs",
21
+ "bundle:session-waste": "node scripts/bundle-session-waste.mjs",
22
+ "prepublishOnly": "pnpm build",
23
+ "test": "vitest run"
24
+ },
25
+ "dependencies": {
26
+ "smol-toml": "^1.3.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.0.0",
30
+ "@venos/tsconfig": "workspace:*",
31
+ "esbuild": "0.21.5",
32
+ "typescript": "5.6.3",
33
+ "vitest": "2.1.9"
34
+ }
35
+ }