@culvii/cli 0.0.6 → 0.0.8
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/COMMANDS.md +1 -1
- package/USAGE.md +4 -3
- package/dist/{DeployView-I4Y55LV4.js → DeployView-D4UEXMDJ.js} +1 -1
- package/dist/{HelpView-ZMOAJNYC.js → HelpView-E7HS4SVF.js} +1 -1
- package/dist/{WhoamiView-VHDXFFLX.js → WhoamiView-TKSYSHQ2.js} +1 -1
- package/dist/{WorkspaceView-RNFALIPM.js → WorkspaceView-ID7ZMBHV.js} +1 -1
- package/dist/chunk-IPETC2TK.js +3 -0
- package/dist/index.js +27 -676
- package/dist/lib/evaluator.js +2 -2
- package/dist/login-OGOHEHFE.js +39 -0
- package/dist/{logout-VOWHM2QB.js → logout-BRUJBFUK.js} +1 -1
- package/dist/skill-bundle-7KYK5GBL.js +1377 -0
- package/package.json +9 -5
- package/skills/culvii/.culvii-skill.json +59 -0
- package/skills/culvii/SKILL.md +73 -0
- package/skills/culvii/agents/openai.yaml +4 -0
- package/skills/culvii/examples/agent-workflow.culvii.ts +24 -0
- package/skills/culvii/examples/complete-workflow.culvii.ts +37 -0
- package/skills/culvii/examples/output-surface.culvii.ts +45 -0
- package/skills/culvii/examples/wait-surface.culvii.ts +24 -0
- package/skills/culvii/references/agents.md +29 -0
- package/skills/culvii/references/authoring-files.md +21 -0
- package/skills/culvii/references/cli-guide.md +22 -0
- package/skills/culvii/references/cli-reference.md +184 -0
- package/skills/culvii/references/feedback-cycle.md +43 -0
- package/skills/culvii/references/integrations.md +13 -0
- package/skills/culvii/references/kit-api.md +35 -0
- package/skills/culvii/references/node-core-agent.md +27 -0
- package/skills/culvii/references/node-core-browser-automation.md +53 -0
- package/skills/culvii/references/node-core-code.md +28 -0
- package/skills/culvii/references/node-core-http.md +42 -0
- package/skills/culvii/references/node-core-if.md +26 -0
- package/skills/culvii/references/node-core-jwt.md +31 -0
- package/skills/culvii/references/node-core-set.md +24 -0
- package/skills/culvii/references/node-cron-trigger.md +25 -0
- package/skills/culvii/references/node-elasticsearch.md +39 -0
- package/skills/culvii/references/node-gmail-trigger.md +44 -0
- package/skills/culvii/references/node-gmail.md +57 -0
- package/skills/culvii/references/node-google-calendar.md +51 -0
- package/skills/culvii/references/node-google-docs.md +46 -0
- package/skills/culvii/references/node-manual-trigger.md +24 -0
- package/skills/culvii/references/node-microsoft-outlook-trigger.md +41 -0
- package/skills/culvii/references/node-microsoft-outlook.md +55 -0
- package/skills/culvii/references/node-microsoft-sharepoint.md +40 -0
- package/skills/culvii/references/node-s3.md +40 -0
- package/skills/culvii/references/node-slack-trigger.md +40 -0
- package/skills/culvii/references/node-slack.md +38 -0
- package/skills/culvii/references/node-twilio.md +39 -0
- package/skills/culvii/references/node-wait-timer.md +24 -0
- package/skills/culvii/references/node-webhook-trigger.md +24 -0
- package/skills/culvii/references/nodes-index.md +27 -0
- package/skills/culvii/references/runtime-values.md +36 -0
- package/skills/culvii/references/surface-authoring.md +27 -0
- package/skills/culvii/references/surface-display.md +390 -0
- package/skills/culvii/references/surface-feedback.md +41 -0
- package/skills/culvii/references/surface-input-actions.md +143 -0
- package/skills/culvii/references/surface-layout.md +97 -0
- package/skills/culvii/references/validation.md +18 -0
- package/skills/culvii/references/workflows.md +30 -0
- package/dist/chunk-LD5ISISS.js +0 -3
- package/dist/login-4VBBCK4V.js +0 -36
- /package/dist/{chunk-5NBKYMD7.js → chunk-56C3DFV2.js} +0 -0
- /package/dist/{chunk-JFIFRAAR.js → chunk-RS5GDTRN.js} +0 -0
package/dist/lib/evaluator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
`),e=true;}try{
|
|
2
|
+
import i from'path';async function o(){let r=process.argv.slice(2);r.length===0&&process.exit(0);let e=false;for(let s of r)try{await import(i.resolve(s));}catch(t){process.stderr.write(`[culvii evaluator] Failed to import ${s}: ${t.message}
|
|
3
|
+
`),e=true;}try{await globalThis.__culvii_dev_registry__?.flushAsync();}catch{}process.exit(e?1:0);}o().catch(r=>{process.stderr.write(`[culvii evaluator] Fatal error: ${r.message}
|
|
4
4
|
`),process.exit(1);});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a as a$4}from'./chunk-RS5GDTRN.js';import {b,c,a as a$2}from'./chunk-KZG5CFSB.js';import {e,a,j as j$1,q,l,m,b as b$1,h,g,i as i$1,c as c$1,f}from'./chunk-IPETC2TK.js';import {a as a$3}from'./chunk-HX54IFSD.js';import {a as a$1}from'./chunk-JYNOILCD.js';import'./chunk-57XLDHK6.js';import'./chunk-YKFGEPLO.js';import'./chunk-YPLDPHHD.js';import'./chunk-7UWDMECF.js';import ue from'open';import i from'react';import {render}from'ink';import Y,{timingSafeEqual}from'crypto';import {createInterface}from'readline/promises';import se from'http';import {jsx}from'react/jsx-runtime';function j(n){return n.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function ne(){let n=Y.randomBytes(64);return j(n)}function ae(n){let y=Y.createHash("sha256").update(n).digest();return j(y)}function oe(){let n=Y.randomBytes(32);return j(n)}var de=`<!DOCTYPE html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>Login Successful</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: system-ui, sans-serif; background: #000; color: #fff; text-align: center; padding: 4rem; }
|
|
9
|
+
.success { color: #10B981; font-size: 48px; margin-bottom: 1rem; }
|
|
10
|
+
p { color: #C4CAD4; }
|
|
11
|
+
</style>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div class="success">\u2713</div>
|
|
15
|
+
<h2>Authentication Successful</h2>
|
|
16
|
+
<p>You can close this window and return to your terminal.</p>
|
|
17
|
+
<script>window.close()</script>
|
|
18
|
+
</body>
|
|
19
|
+
</html>`,ie=`<!DOCTYPE html>
|
|
20
|
+
<html>
|
|
21
|
+
<head>
|
|
22
|
+
<meta charset="utf-8">
|
|
23
|
+
<title>Login Failed</title>
|
|
24
|
+
<style>
|
|
25
|
+
body { font-family: system-ui, sans-serif; background: #000; color: #fff; text-align: center; padding: 4rem; }
|
|
26
|
+
.error { color: #EF4444; font-size: 48px; margin-bottom: 1rem; }
|
|
27
|
+
p { color: #C4CAD4; }
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
<div class="error">\u2717</div>
|
|
32
|
+
<h2>Authentication Failed</h2>
|
|
33
|
+
<p>An error occurred during login. Check your terminal for details.</p>
|
|
34
|
+
</body>
|
|
35
|
+
</html>`;async function ce(){return new Promise((n,y)=>{let f=0,t=se.createServer(),s=()=>{if(f>=q.callbackPorts.length)return y(new Error("All callback ports are in use (52700\u201352709). Check for conflicting processes."));let w=q.callbackPorts[f];t.listen(w,"127.0.0.1");},C=w=>{w.code==="EADDRINUSE"?(f++,t.removeAllListeners(),t.close(),t=se.createServer(),t.on("error",C),t.once("listening",h),s()):y(w);},h=()=>{let w=t.address();if(!w||typeof w=="string")return t.close(),y(new Error("Failed to get server address"));let _=w.port,A=null,R=null,T=false,E=null;t.on("request",(l,o)=>{if(!T)try{let x=new URL(l.url||"/",`http://${l.headers.host}`);if(x.pathname===q.callbackPath){T=!0,E&&clearTimeout(E);let I=x.searchParams.get("code"),k=x.searchParams.get("state"),e=x.searchParams.get("error");if(e&&k){o.writeHead(200,{"Content-Type":"text/html",Connection:"close"}),o.end(ie),A?.({error:e,state:k}),t.close();return}if(I&&k){o.writeHead(200,{"Content-Type":"text/html",Connection:"close"}),o.end(de),A?.({code:I,state:k}),t.close();return}o.writeHead(400,{"Content-Type":"text/html",Connection:"close"}),o.end(ie),R?.(new Error("Invalid callback parameters")),t.close();}else o.writeHead(404),o.end();}catch{o.writeHead(500),o.end();}}),n({port:_,waitForCallback:()=>new Promise((l,o)=>{A=l,R=o,E=setTimeout(()=>{T||(T=true,t.close(),o(new Error("Callback timeout")));},300*1e3);})});};t.on("error",C),t.once("listening",h),s();})}function le({tenants:n,onSelect:y}){let f=n.map((t,s)=>({key:String(s+1),label:t.name||t.slug}));return jsx(a$4,{label:"You belong to multiple tenants. Please select one to set as active:",options:f,onSubmit:t=>{let s=n[parseInt(t)-1];s&&y(s);}})}async function pe(n,y=process.stdin,f=process.stdout){f.write(`You belong to multiple tenants. Please select one to set as active:
|
|
36
|
+
`),n.forEach((s,C)=>f.write(`[${C+1}] ${s.name||s.slug}
|
|
37
|
+
`));let t=createInterface({input:y,output:f,terminal:false});try{for(;;){let s=await t.question("Select tenant by number: "),C=n[Number(s.trim())-1];if(C)return C;f.write(`Enter a number from 1 to ${n.length}.
|
|
38
|
+
`);}}finally{t.close();}}async function He(){b.info("Login flow started"),await e(a.LOGIN_STARTED);try{let n=ne(),y=ae(n),f$1=oe(),t;try{t=await ce();}catch(e$1){b.error("Failed to start callback server",{error:e$1.message}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:"Couldn't start local listener \u2014 check firewall or sandbox restrictions"}})),await e(a.LOGIN_FAILED,{reason:"callback_server_failed"}),await j$1(),process.exit(1);}let{port:s,waitForCallback:C}=t,h$1=new URL(`https://${q.cognitoDomain}/oauth2/authorize`);h$1.searchParams.set("client_id",q.clientId),h$1.searchParams.set("response_type","code"),h$1.searchParams.set("redirect_uri",`http://127.0.0.1:${s}/callback`),h$1.searchParams.set("code_challenge",y),h$1.searchParams.set("code_challenge_method","S256"),h$1.searchParams.set("state",f$1),h$1.searchParams.set("scope",q.scopes.join(" ")),await ue(h$1.toString()),b.info("Browser opened");let{unmount:w}=render(i.createElement(a$1,{label:"Waiting for browser authentication\u2026"})),_;try{_=await C(),b.info("Callback received");}catch(e){w(),b.error("Callback error",{error:e.message}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:e.message}})),await j$1(),process.exit(1);}w(),"error"in _&&(_.error==="access_denied"?(b.warn("Login cancelled by user"),render(i.createElement(c,{state:{type:"login_error",message:"Login cancelled"}}))):(b.error("Auth server returned error",{error:_.error}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:_.error}}))),await e(a.LOGIN_FAILED,{reason:_.error==="access_denied"?"user_cancelled":_.error}),await j$1(),process.exit(1));let A=Buffer.from(_.state),R=Buffer.from(f$1);(A.length!==R.length||!timingSafeEqual(A,R))&&(b.error("State mismatch in callback"),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:"Auth response mismatch \u2014 possible CSRF, aborting"}})),await e(a.LOGIN_FAILED,{reason:"state_mismatch"}),await j$1(),process.exit(1)),b.info("Token exchange initiated");let T=`https://${q.cognitoDomain}/oauth2/token`,E=new URLSearchParams;E.set("grant_type","authorization_code"),E.set("code",_.code),E.set("redirect_uri",`http://127.0.0.1:${s}/callback`),E.set("client_id",q.clientId),E.set("code_verifier",n);let F;try{F=await fetch(T,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E.toString()});}catch(e$1){b.error("Network error during token exchange",{error:e$1.message}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:"Could not reach auth server \u2014 check your connection"}})),await e(a.LOGIN_FAILED,{reason:"network_error"}),await j$1(),process.exit(1);}let l$1=await F.json();if(!F.ok||l$1.error==="invalid_grant"){let e$1=l$1.error_description||l$1.error||"Unknown error";b.error("Token exchange failed",{reason:e$1}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:`Token exchange failed: ${e$1}`}})),await e(a.LOGIN_FAILED,{reason:"token_exchange_failed"}),await j$1(),process.exit(1);}let o=Date.now(),x=o+l$1.expires_in*1e3;b.info("Token exchange succeeded",{expiresAt:x});let I=new a$2;await I.withLock(async()=>{await I.set({accessToken:l$1.access_token,refreshToken:l$1.refresh_token,idToken:l$1.id_token,expiresAt:x,tokenType:"Bearer",scope:q.scopes.join(" "),issuedAt:o,issuer:`https://${q.cognitoDomain}`});}),b.info("Tokens persisted"),b.info("/auth/me called");let k;try{k=await fetch(`${q.apiBaseUrl}/auth/me`,{headers:{Authorization:`Bearer ${l$1.access_token}`}});}catch(e){b.warn("Network error fetching identity details",{error:e.message}),render(i.createElement(c,{state:{type:"login_warning",message:"Logged in \u2014 could not verify identity with backend"}})),await j$1(),process.exit(0);}if(b.info("/auth/me result",{status:k.status}),k.status===401&&(render(i.createElement(c,{state:{type:"login_warning",message:"Logged in \u2014 could not verify identity with backend"}})),await j$1(),process.exit(0)),k.status===403&&(b.warn("Login rejected \u2014 user not invited"),await I.delete(),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:"You must be invited to use Culvii CLI. Contact your administrator."}})),await e(a.LOGIN_FAILED,{reason:"not_invited"}),await j$1(),process.exit(1)),k.ok){let e$1=await k.json(),N=e$1.tenants||(e$1.tenant?[e$1.tenant]:[]),d=N[0];if(N.length>1&&(d=process.stdin.isTTY&&typeof process.stdin.setRawMode=="function"?await new Promise(O=>{let{unmount:L}=render(i.createElement(le,{tenants:N,onSelect:r=>{L(),O(r);}}));}):await pe(N)),d){let D=new a$3;await D.withLock(async()=>{let L=null;try{L=await D.read({exitOnError:!1});}catch{L=null;}let r=L?.contexts||{};for(let S of N){let m$1=S.slug||S.id,M=(S.environments||[]).map(P=>P.slug),$=Object.fromEntries((S.environments||[]).map(P=>[l(P.slug)??P.slug,P.id])),G=m(M)??"dev";r[m$1]?(r[m$1].tenant_id=S.id,r[m$1].tenant_slug=m$1,r[m$1].environment_ids={...r[m$1].environment_ids||{},...$},M.some(V=>l(V)===r[m$1].environment)||(r[m$1].environment=G),r[m$1].environment_id=r[m$1].environment_ids?.[r[m$1].environment]??r[m$1].environment_id):r[m$1]={tenant_id:S.id,tenant_slug:m$1,workspace_id:null,workspace_slug:null,environment:G,environment_id:$[G],environment_ids:$,workspace_ids:{},workspace_slugs:{},api_keys:{}};}for(let S of Object.keys(r))e$1.user_id&&(r[S].user_id=e$1.user_id);let B=d.slug||d.id;await D.write({version:L?.version??1,active:B,contexts:r});});let O=await b$1();e$1.user_id?(await h(e$1.user_id,O),await g(e$1.user_id,{email:e$1.email,name:e$1.name}),d&&await i$1(e$1.user_id,d.id,{name:d.name,slug:d.slug}),c$1(),await f(a.LOGIN_SUCCEEDED,e$1.user_id,d?.id??null,{})):await e(a.LOGIN_SUCCEEDED),await j$1();}let z=e$1.roles||[];if(d){let D=(d.environments||[]).map(r=>r.slug),O=m(D),L=(d.environments||[]).find(r=>l(r.slug)===O);if(L)try{let r=await fetch(`${q.apiBaseUrl}/auth/me`,{headers:{Authorization:`Bearer ${l$1.access_token}`,"x-tenant-id":d.id,"x-environment-id":L.id}});if(r.ok){let B=await r.json();Array.isArray(B.roles)&&(z=B.roles);}}catch{}}render(i.createElement(c,{state:{type:"login_success",email:e$1.email||"N/A",tenant:d?.name||"N/A",roles:z}}));}else render(i.createElement(c,{state:{type:"login_warning",message:"Logged in \u2014 could not verify identity with backend"}}));}catch(n){b.error("Unexpected error during login",{error:n.message}),render(i.createElement(c,{state:{type:"login_error",message:"Login failed",detail:"An unexpected error occurred during login."}})),await e(a.LOGIN_FAILED,{reason:"unexpected_error"}),await j$1(),process.exit(1);}}
|
|
39
|
+
export{He as login,pe as selectTenantWithoutRawMode};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {b,a,c}from'./chunk-KZG5CFSB.js';import {q,d,f,a as a$1,e,j}from'./chunk-
|
|
2
|
+
import {b,a,c}from'./chunk-KZG5CFSB.js';import {q,d,f,a as a$1,e,j}from'./chunk-IPETC2TK.js';import'./chunk-HX54IFSD.js';import'./chunk-YKFGEPLO.js';import'./chunk-YPLDPHHD.js';import'./chunk-7UWDMECF.js';import w from'react';import {render}from'ink';async function S(){b.info("Logout flow started");let e$1=new a,o=false;await e$1.withLock(async()=>{let a=await e$1.get();if(!a){o=false;return}if(a.refreshToken){b.info("Revocation attempted");let g=`https://${q.cognitoDomain}/oauth2/revoke`,r=new URLSearchParams;r.set("token",a.refreshToken),r.set("client_id",q.clientId);try{await fetch(g,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()}),b.info("Revocation completed");}catch{b.info("Revocation network error ignored");}}await e$1.delete(),b.info("Tokens deleted"),o=true;let{userId:c,tenantId:u}=await d();c?await f(a$1.LOGOUT,c,u):await e(a$1.LOGOUT),await j();}),o?render(w.createElement(c,{state:{type:"logout_success"}})):render(w.createElement(c,{state:{type:"already_logged_out"}}));}
|
|
3
3
|
export{S as logout};
|