rightbrain-cli-alpha 0.1.1-alpha → 0.2.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.
- package/dist/index.js +28 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import Pe,{z}from'zod';import
|
|
2
|
+
import Pe,{z}from'zod';import Vr from'http';import*as m from'@clack/prompts';import Bt from'dotenv';import Ot from'dotenv-expand';import re from'fs';import X from'path';import j from'picocolors';import Yr from'strip-json-comments';import eo from'os';import wt from'crypto';import {ClientCredentials}from'simple-oauth2';import {isAxiosError}from'axios';import {inspect}from'util';import {UsersApi,Configuration,OrganizationsApi,ProjectsApi,APIKeysApi,TasksApi,ListingsApi}from'@rightbrain/brain-api-client';import ko from'open';import {parseDocument,isScalar,isMap}from'yaml';import {Eta}from'eta';import fr from'just-camel-case';import Pt from'just-kebab-case';import ur from'just-pascal-case';import mr from'just-snake-case';import {execSync}from'child_process';import {fileTypeFromBuffer}from'file-type';import {Command}from'commander';var _e={name:"rightbrain-cli-alpha",version:"0.2.0",description:"Command line interface for RightBrain AI",type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",bin:{rightbrain:"dist/index.js"},files:["dist","README.md","LICENSE"],publishConfig:{access:"public"},keywords:["rightbrain","rightbrainai","ai","cli","interactive","generator"],scripts:{clean:"rm -rf dist",build:"dotenv -e ../../.env -- tsup && chmod +x dist/index.js",dev:"dotenv -e ../../.env -- tsup --watch","type-check":"tsc --noEmit",lint:"eslint .","link:global":"pnpm run build && pnpm link --global",prepublishOnly:"pnpm run build","generate:schema":"pnpm dlx tsx scripts/generate-schema.ts"},dependencies:{"@clack/prompts":"1.0.0-alpha.9","@rightbrain/brain-api-client":"0.0.1-dev.8.6a38b3e",axios:"^1.12.0",commander:"^13.1.0",dotenv:"^16.5.0","dotenv-cli":"^10.0.0","dotenv-expand":"^12.0.2",eslint:"^9.39.2",eta:"^4.5.0","file-type":"21.3.0","just-camel-case":"^6.2.0","just-kebab-case":"^4.2.0","just-pascal-case":"^3.2.0","just-snake-case":"^3.2.0",open:"^11.0.0",picocolors:"^1.1.0","simple-oauth2":"^5.1.0","strip-json-comments":"^5.0.3",yaml:"^2.8.0",zod:"^4.3.6"},devDependencies:{"@rightbrainai/eslint-config":"workspace:*","@rightbrainai/tsconfig":"workspace:*","@types/node":"^20.19.22","@types/simple-oauth2":"^5.0.7",tsup:"^8.3.5",typescript:"5.7.3"}};var De=e=>{let t=new Map;for(let r of e){let o=r.provider;t.has(o)||t.set(o,[]),t.get(o)?.push(r);}return t},H=e=>typeof e=="string"&&/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/i.test(e);function Be(e){return e instanceof Error?e.message:String(e)}var Nr=Pe.object({CLI_PUBLIC_API_URL:Pe.url().default("https://app.rightbrain.ai/api/v1"),CLI_PUBLIC_RB_OAUTH2_CLIENT_ID:Pe.string().refine(H,{message:"Invalid UUID format"}).default("ae8c4f7f-d12f-4975-98bd-e5e42ff52f8e"),CLI_PUBLIC_RB_OAUTH2_URL:Pe.url().default("https://oauth.rightbrain.ai"),CLI_PUBLIC_TEMPLATES_URL:Pe.url().default("https://app.rightbrain.ai/cli")}),I=Nr.parse({CLI_PUBLIC_API_URL:"https://stag.leftbrain.me/api/v1",CLI_PUBLIC_RB_OAUTH2_CLIENT_ID:"6e50b63e-7256-4269-97ea-69eb0821fff2",CLI_PUBLIC_RB_OAUTH2_URL:"https://oauth.leftbrain.me",CLI_PUBLIC_TEMPLATES_URL:"https://stag.leftbrain.me/cli"});function p(e){try{if(typeof e=="function"){let t=e();return t instanceof Promise?t.then(r=>[r,null]).catch(r=>[null,r]):[t,null]}return e.then(t=>[t,null]).catch(t=>[null,t])}catch(t){return [null,t]}}var St=`
|
|
3
3
|
:root {
|
|
4
4
|
--bg-primary: #ffffff;
|
|
5
5
|
--bg-secondary: #f9fafb;
|
|
@@ -188,7 +188,7 @@ import Pe,{z}from'zod';import Kr from'http';import*as m from'@clack/prompts';imp
|
|
|
188
188
|
color: var(--error-primary);
|
|
189
189
|
word-break: break-word;
|
|
190
190
|
}
|
|
191
|
-
`,
|
|
191
|
+
`,Ft=`
|
|
192
192
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none">
|
|
193
193
|
<path stroke="#F89013" stroke-width="2"
|
|
194
194
|
d="m12.454 3.514.009.037.001.003c.265.473.498.96.7 1.463.257.636.442 1.292.557 1.968.05.297.085.646.103 1.049" />
|
|
@@ -337,19 +337,19 @@ import Pe,{z}from'zod';import Kr from'http';import*as m from'@clack/prompts';imp
|
|
|
337
337
|
<path fill="#951D89" d="M5.245 21.235a.525.525 0 1 0 0-1.05.525.525 0 0 0 0 1.05Z" />
|
|
338
338
|
<path fill="#00BDC9" d="M16.477 21.704a.524.524 0 1 0 0-1.049.524.524 0 0 0 0 1.05Z" />
|
|
339
339
|
</svg>
|
|
340
|
-
`,
|
|
340
|
+
`,zr=`
|
|
341
341
|
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
342
342
|
<circle cx="24" cy="24" r="24" fill="var(--success-primary)" fill-opacity="0.12"/>
|
|
343
343
|
<circle cx="24" cy="24" r="16" fill="var(--success-primary)"/>
|
|
344
344
|
<path d="M17 24L21.5 28.5L31 19" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
345
345
|
</svg>
|
|
346
|
-
`,
|
|
346
|
+
`,qr=`
|
|
347
347
|
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
348
348
|
<circle cx="24" cy="24" r="24" fill="var(--error-primary)" fill-opacity="0.12"/>
|
|
349
349
|
<circle cx="24" cy="24" r="16" fill="var(--error-primary)"/>
|
|
350
350
|
<path d="M19 19L29 29M29 19L19 29" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
351
351
|
</svg>
|
|
352
|
-
`;function
|
|
352
|
+
`;function Rt(){return `<!DOCTYPE html>
|
|
353
353
|
<html lang="en">
|
|
354
354
|
<head>
|
|
355
355
|
<meta charset="UTF-8">
|
|
@@ -366,12 +366,12 @@ import Pe,{z}from'zod';import Kr from'http';import*as m from'@clack/prompts';imp
|
|
|
366
366
|
<body>
|
|
367
367
|
<div class="bg-pattern"></div>
|
|
368
368
|
<div class="logo">
|
|
369
|
-
${
|
|
369
|
+
${Ft}
|
|
370
370
|
<span class="logo-text">Rightbrain.ai</span>
|
|
371
371
|
</div>
|
|
372
372
|
<div class="container">
|
|
373
373
|
<div style="margin-bottom: 20px;">
|
|
374
|
-
${
|
|
374
|
+
${zr}
|
|
375
375
|
</div>
|
|
376
376
|
<div class="badge">
|
|
377
377
|
<span class="badge-dot success"></span>
|
|
@@ -395,12 +395,12 @@ import Pe,{z}from'zod';import Kr from'http';import*as m from'@clack/prompts';imp
|
|
|
395
395
|
<body>
|
|
396
396
|
<div class="bg-pattern"></div>
|
|
397
397
|
<div class="logo">
|
|
398
|
-
${
|
|
398
|
+
${Ft}
|
|
399
399
|
<span class="logo-text">Rightbrain.ai</span>
|
|
400
400
|
</div>
|
|
401
401
|
<div class="container">
|
|
402
402
|
<div style="margin-bottom: 20px;">
|
|
403
|
-
${
|
|
403
|
+
${qr}
|
|
404
404
|
</div>
|
|
405
405
|
<div class="badge">
|
|
406
406
|
<span class="badge-dot error"></span>
|
|
@@ -408,30 +408,30 @@ import Pe,{z}from'zod';import Kr from'http';import*as m from'@clack/prompts';imp
|
|
|
408
408
|
</div>
|
|
409
409
|
<h1 class="error">Login Failed</h1>
|
|
410
410
|
<p class="subtitle">Something went wrong during authentication. Please try again.</p>
|
|
411
|
-
<div class="error-message">${
|
|
411
|
+
<div class="error-message">${Kr(e)}</div>
|
|
412
412
|
</div>
|
|
413
413
|
</body>
|
|
414
|
-
</html>`}function
|
|
415
|
-
Expected a file (e.g., ${Ne}), but received a directory.`)),process.exit(1)),ue=e;}var Yr=z.object({$schema:z.string().optional(),orgId:z.string().refine(H,{message:"Invalid UUID format"}),projectId:z.string().refine(H,{message:"Invalid UUID format"}),envFile:z.string().default(yt).optional(),apiKey:z.string().optional(),generate:z.object({language:z.string(),outputDir:z.string().refine(e=>{if(!e)return true;let t=e.replace(/^\.\//,"").replace(/\/$/,"");return !(t===""||t===".")},{message:'outputDir cannot be project root ("./" or "."). It must be inside the project below rightbrain.json level.'}),taskIds:z.array(z.string().refine(H,{message:"Invalid UUID format"})),hardcodeTaskIds:z.boolean().default(false).optional()}).optional(),clientId:z.string().refine(H,{message:"Invalid UUID format"}).optional(),clientSecret:z.string().optional(),oauthUrl:z.url().optional(),apiUrl:z.url().default(b.CLI_PUBLIC_API_URL).optional()}).refine(e=>{let t=e.clientId&&e.clientSecret,r=!!e.apiKey;return t||r},{message:"Either 'apiKey' or both 'clientId' and 'clientSecret' must be provided to authenticate"});function Zr(){return ue?X.dirname(ue):process.cwd()}function Gr(e=yt,t=false){let r=Zr(),o=X.isAbsolute(e),n=o?e:X.join(r,e);if(te.existsSync(n)){if(!te.statSync(n).isFile())throw new Error(`envFile path "${e}" exists but is not a file (it's a directory).`);Bt.expand(Ut.config({path:n,override:true}));return}if(!o){let i=X.join(r,`${e}.local`);if(te.existsSync(i)){if(!te.statSync(i).isFile())throw new Error(`envFile path "${e}.local" exists but is not a file (it's a directory).`);Bt.expand(Ut.config({path:i,override:true}));return}}if(t){let i=o?[n]:[n,X.join(r,`${e}.local`)];throw new Error(`envFile "${e}" specified in config but not found. Expected at: ${i.join(" or ")}`)}}function Hr(e){let t="",r=0;for(;r<e.length;)if(e[r]==="$"&&e[r+1]==="{"){let o=1,n=r+2,i=false;for(;n<e.length&&o>0;)e[n]==="$"&&e[n+1]==="{"?(i=true,o++,n++):e[n]==="}"&&o--,n++;if(o===0){let s=e.slice(r+2,n-1);if(i)throw new Error(`\${${s}}: bad substitution`);{let a=s.trim();t+=process.env[a]??"",r=n;}}else t+=e[r],r++;}else t+=e[r],r++;return t}function ht(e){if(typeof e=="string")return Hr(e);if(Array.isArray(e))return e.map(ht);if(e!==null&&typeof e=="object"){let t={};for(let[r,o]of Object.entries(e))t[r]=ht(o);return t}return e}function Jr(){if(ue)return ue;let e=X.join(process.cwd(),Ne);return te.existsSync(e)?e:(ue=X.join(process.cwd(),Ne),ue)}function Xr(){let e=Jr();if(!te.existsSync(e))return null;let t=te.readFileSync(e,"utf-8");return {config:JSON.parse(Wr(t)),filepath:e}}var Oe=null;function je(){if(Oe)return Oe;let[e,t]=p(Xr);if(t&&((f?console.error:m.outro)(j.red(`Error loading configuration file: ${t}`)),process.exit(1)),!e)return null;let r=e.config,o=yt,n=false;r&&typeof r=="object"&&r!==null&&"envFile"in r&&typeof r.envFile=="string"&&(o=r.envFile,n=true);let[i]=p(()=>{Gr(o,n);});i&&((f?console.error:m.outro)(j.red(`Error loading env file: ${i}`)),process.exit(1));let[s,a]=p(()=>ht(e.config));a&&((f?console.error:m.outro)(j.red(`Error resolving environment variables: ${a}`)),process.exit(1));let c=Yr.safeParse(s);if(c.success||((f?console.error:m.log.error)("Invalid Configuration: "),(f?console.error:m.log.error)(z.prettifyError(c.error)),(f?console.error:m.outro)(j.red("Please check your configuration file and try again.")),process.exit(1)),c.data.generate?.outputDir){let u=X.dirname(e.filepath),l=c.data.generate.outputDir,d=X.resolve(u,l),v=X.relative(u,d);(v===""||v==="."||v.startsWith(".."))&&((f?console.error:m.log.error)(j.red(`Invalid outputDir: "${l}" resolves to "${v}" which is outside the project or at project root. outputDir must be inside the project below rightbrain.json level.`)),process.exit(1));}return Oe={...c.data,filePath:e.filepath,rawConfig:r},Oe}function Nt(){let e=je();return e||((f?console.error:m.outro)(j.red(`No configuration file found. Expected: ${Ne}`)),process.exit(1)),e}var kt=X.join(Qr.homedir(),".rightbrain"),we=X.join(kt,"credentials.json"),ke=null;function me(){if(ke)return ke;if(!te.existsSync(we))return null;try{let e=te.readFileSync(we,"utf-8"),t=JSON.parse(e);return t.access_token?(ke=t,ke):null}catch{return null}}function eo(){te.existsSync(kt)||te.mkdirSync(kt,{recursive:true,mode:448});}function re(e,t=false){eo();let r=t?e:{...me(),...e};te.writeFileSync(we,JSON.stringify(r,null,2),"utf-8"),te.chmodSync(we,384),ke=r;}function qt(){te.existsSync(we)&&te.unlinkSync(we),ke=null;}function Kt(e){if(!e.expires_at)return false;let t=300*1e3;return Date.now()>=e.expires_at-t}var ve=null,xe=null,ze=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Me=0,Vt=process.stderr.isTTY,to=()=>{Vt&&process.stderr.write("\x1B[?25l");},qe=()=>{Vt&&process.stderr.write("\x1B[?25h");};process.on("exit",qe);process.on("SIGINT",()=>{qe(),process.exit(130);});process.on("SIGTERM",()=>{qe(),process.exit(143);});var ro=()=>{let e=false;return {start:()=>{e||(e=true,Me=0,xe&&clearInterval(xe),to(),process.stderr.write("\r"+ze[Me]),xe=setInterval(()=>{Me=(Me+1)%ze.length,process.stderr.write("\r"+ze[Me]);},80));},stop:()=>{xe&&(clearInterval(xe),xe=null),e&&(process.stderr.write("\r"+" ".repeat(ze[0].length)+"\r"),qe()),e=false;}}},_=()=>(ve||(ve=ro()),ve),Ke=()=>{ve&&(ve.stop(),ve=null);};async function W(e){let t=e?.loadGlobalConfig?null:je();if(!t){let o=me();if(o)if(Kt(o)){let n=await io(o);if(n)return {accessToken:n.access_token,orgId:n.org_id,projectId:n.project_id}}else return {accessToken:o.access_token,orgId:o.org_id,projectId:o.project_id};Ke(),(f?console.error:m.outro)("Not authenticated. Please run `npx rightbrain login` command to authenticate."),process.exit(1);}return {accessToken:await no(t),orgId:t.orgId,projectId:t.projectId,filePath:t.filePath}}var Ve=null;async function no(e){if(e.apiKey)return e.apiKey;if((!e.clientId||!e.clientSecret)&&(Ke(),(f?console.error:m.outro)(j.red("Client ID and secret are required to authenticate via OAuth")),process.exit(1)),!Ve||Ve.expired()){let t=new ClientCredentials({auth:{tokenHost:e.oauthUrl??b.CLI_PUBLIC_RB_OAUTH2_URL,tokenPath:"/oauth2/token"},client:{id:e.clientId,secret:e.clientSecret},http:{json:"force"}}),[r,o]=await p(()=>t.getToken({}));return (o||!r?.token.access_token)&&(Ke(),(f?console.error:m.outro)(j.red("Failed to obtain access token")),process.exit(1)),Ve=r,r.token.access_token}return Ve.token.access_token}var J={oauthUrl:b.CLI_PUBLIC_RB_OAUTH2_URL,authPath:"/oauth2/auth",tokenPath:"/oauth2/token",clientId:b.CLI_PUBLIC_RB_OAUTH2_CLIENT_ID};async function io(e){if(!e.refresh_token)return null;let t=`${J.oauthUrl}${J.tokenPath}`,r=new URLSearchParams({grant_type:"refresh_token",refresh_token:e.refresh_token,client_id:J.clientId});try{let o=await fetch(t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()});if(!o.ok)return null;let n=await o.json(),i=n.expires_in?Date.now()+n.expires_in*1e3:void 0,s={...e,access_token:n.access_token,refresh_token:n.refresh_token??e.refresh_token,expires_at:i};return re(s,!0),s}catch{return null}}function Yt(){return wt.randomBytes(32).toString("base64url")}async function Zt(e){return wt.createHash("sha256").update(e).digest().toString("base64url")}function Gt(e,t){let r=gt(),o=new URLSearchParams({client_id:J.clientId,redirect_uri:r,response_type:"code",scope:"offline_access",state:e});return t&&(o.append("code_challenge",t),o.append("code_challenge_method","S256")),`${J.oauthUrl}${J.authPath}?${o.toString()}`}function Ht(){return wt.randomBytes(32).toString("hex")}function L(e){if(f||m.outro("Something went wrong"),isAxiosError(e)){let t=e.response;if(t?.data){t.status===401&&console.error("Unauthorized Access please login again."),console.error("Error:"),console.info(f?JSON.stringify(t.data,null,2):inspect(t.data,{depth:null,colors:true}));return}if(t?.status){console.error(`Error: Request failed with status ${t.status}`);return}}if(e instanceof Error){console.error(e.message);return}(f?console.error:m.outro)("An unexpected error occurred");}async function de({accessToken:e,orgId:t,projectId:r}){let o=_();if(!t){o.start();let[n,i]=await p(async()=>await new OrganizationsApi(O(e)).listOrganizations().then(a=>a.data.results));if((i||!n)&&(o.stop(),L(i),process.exit(1)),o.stop(),n.length===0&&(m.cancel("No organizations found. Please create one first."),process.exit(1)),n.length===1)t=n[0].id,m.log.info(`Using organization: ${j.cyan(n[0].name)}`);else {let s=await m.select({message:"Select an organization",options:n.map(a=>({value:a.id,label:a.name,hint:a.id}))});m.isCancel(s)&&(m.outro("Select project cancelled"),process.exit(0)),t=s;}}if(!r){o.start();let[n,i]=await p(async()=>await new ProjectsApi(O(e)).listProjects(t).then(a=>a.data.results));if((i||!n)&&(o.stop(),L(i),process.exit(1)),o.stop(),n.length===0&&(m.cancel("No projects found. Please create one first."),process.exit(1)),n.length===1)r=n[0].id,m.log.info(`Using project: ${j.cyan(n[0].name)}`);else {let s=await m.select({message:"Select a project",options:n.map(a=>({value:a.id,label:a.name,hint:a.id}))});m.isCancel(s)&&(m.outro("Select project cancelled"),process.exit(0)),r=s;}}return (typeof t!="string"||typeof r!="string")&&(m.cancel("Failed to select project"),process.exit(1)),{orgId:t,projectId:r}}var O=e=>new Configuration({basePath:b.CLI_PUBLIC_API_URL,accessToken:e}),T=class e{_options;tasksApi;listingsApi;organizationsApi;projectsApi;apiKeysApi;constructor(t){this._options=t;let r=O(t.accessToken);this.tasksApi=new TasksApi(r),this.listingsApi=new ListingsApi(r),this.organizationsApi=new OrganizationsApi(r),this.projectsApi=new ProjectsApi(r),this.apiKeysApi=new APIKeysApi(r);}get orgId(){return this._options.orgId}get projectId(){return this._options.projectId}getTaskUrl(t){return `${b.CLI_PUBLIC_API_URL}/org/${this.orgId}/project/${this.projectId}/task/${t}`}static async fromAuthContext(){let t=await W(),r=await de(t);return (!t.orgId||!t.projectId)&&re({access_token:t.accessToken,org_id:r.orgId,project_id:r.projectId}),new e({...t,...r})}static async fromConfig(){let t=await W();return (!t.orgId||!t.projectId)&&((f?console.error:m.outro)("orgId and projectId are required to authenticate."),process.exit(1)),new e({accessToken:t.accessToken,orgId:t.orgId,projectId:t.projectId})}async listModels(){return (await this.listingsApi.getAllModels(this.orgId,this.projectId)).data}async createTask(t){return (await this.tasksApi.createTask(this.orgId,this.projectId,t)).data}async getOrganization(t){return (await this.organizationsApi.getOrganization(t)).data}async getProject(t,r){return (await this.projectsApi.getProject(t,r)).data}async listTasks(){return (await this.tasksApi.listTasks(this.orgId,this.projectId)).data.results}async getTask(t){return (await this.tasksApi.getTask(this.orgId,this.projectId,t,null,true)).data}async runTask({body:t,taskId:r,revisionId:o,useFallbackModel:n=false}){let i=new FormData;if(i.append("task_input",JSON.stringify(t.task_input)),t.task_files&&t.task_files.length>0)for(let c of t.task_files)i.append("task_file",c,c.name);let s=new URLSearchParams;return o&&s.set("revision_id",o),(await this.tasksApi.runTask(this.orgId,this.projectId,r,o,null,null,n,{data:i})).data}async listApiKeys(){return (await this.apiKeysApi.listApiKeys(this.orgId,this.projectId)).data}async createApiKey(t){return (await this.apiKeysApi.createApiKey(this.orgId,this.projectId,{name:t})).data}};var Q=e=>{let{canRunWithOptions:t=true}=e||{};process.env.TERM_PROGRAM?.toLowerCase().includes("mintty")&&(console.warn(`WARNING: It looks like you are using MinTTY, which is non-interactive. This is most likely because you are
|
|
414
|
+
</html>`}function Kr(e){let t={"&":"&","<":"<",">":">",'"':""","'":"'"};return e.replace(/[&<>"']/g,r=>t[r]||r)}var $e=27246;function Ut(){return `http://localhost:${$e}/login`}function gt(){return `http://localhost:${$e}/callback`}async function Wr(e,t){let r=gt(),o=`${J.oauthUrl}${J.tokenPath}`,n=new URLSearchParams({grant_type:"authorization_code",code:e,redirect_uri:r,client_id:J.clientId});t&&n.append("code_verifier",t);let i=await fetch(o,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()});if(!i.ok)throw new Error(`Token exchange failed: ${i.status} - ${await i.text()}`);return await i.json()}function Dt(e,t,r){return new Promise(o=>{let n=Vr.createServer(async(s,a)=>{let c=new URL(s.url||"/",`http://localhost:${$e}`);if(c.pathname==="/login"){a.writeHead(302,{Location:r}),a.end();return}if(c.pathname!=="/callback"){a.writeHead(404,{"Content-Type":"text/plain"}),a.end("Not Found");return}let u=c.searchParams.get("code"),l=c.searchParams.get("state"),d=c.searchParams.get("error"),w=c.searchParams.get("error_description");if(d){let h=w||d;a.writeHead(400,{"Content-Type":"text/html"}),a.end(Ae(h)),n.close(),o({success:false,error:h});return}if(l!==e){let h="State mismatch - possible CSRF attack";a.writeHead(400,{"Content-Type":"text/html"}),a.end(Ae(h)),n.close(),o({success:false,error:h});return}if(!u){let h="No authorization code received";a.writeHead(400,{"Content-Type":"text/html"}),a.end(Ae(h)),n.close(),o({success:false,error:h});return}let[b,_]=await p(()=>Wr(u,t));if(_||!b){let h=_ instanceof Error?_.message:"Token exchange failed";a.writeHead(500,{"Content-Type":"text/html"}),a.end(Ae(h)),n.close(),o({success:false,error:h});return}a.writeHead(200,{"Content-Type":"text/html"}),a.end(Rt()),n.close(),o({success:true,token:b});});n.listen($e),n.on("error",s=>{o({success:false,error:`Failed to start callback server on port ${$e}: ${s.message}`});});let i=setTimeout(()=>{n.close(),o({success:false,error:"Login timeout - please try again"});},120*1e3);n.on("close",()=>{clearTimeout(i);});})}var f=!process.stdout.isTTY;var Ne="rightbrain.json",yt=".env",ue=null;function Nt(e){re.existsSync(e)||((f?console.error:m.outro)(j.red(`Configuration file not found: ${e}`)),process.exit(1)),re.statSync(e).isDirectory()&&((f?console.error:m.outro)(j.red(`Invalid configuration path: ${e}
|
|
415
|
+
Expected a file (e.g., ${Ne}), but received a directory.`)),process.exit(1)),ue=e;}var Zr=z.object({$schema:z.string().optional(),orgId:z.string().refine(H,{message:"Invalid UUID format"}),projectId:z.string().refine(H,{message:"Invalid UUID format"}),envFile:z.string().default(yt).optional(),apiKey:z.string().optional(),generate:z.object({language:z.string(),outputDir:z.string().refine(e=>{if(!e)return true;let t=e.replace(/^\.\//,"").replace(/\/$/,"");return !(t===""||t===".")},{message:'outputDir cannot be project root ("./" or "."). It must be inside the project below rightbrain.json level.'}),taskIds:z.array(z.string().refine(H,{message:"Invalid UUID format"})),hardcodeTaskIds:z.boolean().default(false).optional()}).optional(),clientId:z.string().refine(H,{message:"Invalid UUID format"}).optional(),clientSecret:z.string().optional(),oauthUrl:z.url().optional(),apiUrl:z.url().default(I.CLI_PUBLIC_API_URL).optional()}).refine(e=>{let t=e.clientId&&e.clientSecret,r=!!e.apiKey;return t||r},{message:"Either 'apiKey' or both 'clientId' and 'clientSecret' must be provided to authenticate"});function Gr(){return ue?X.dirname(ue):process.cwd()}function Hr(e=yt,t=false){let r=Gr(),o=X.isAbsolute(e),n=o?e:X.join(r,e);if(re.existsSync(n)){if(!re.statSync(n).isFile())throw new Error(`envFile path "${e}" exists but is not a file (it's a directory).`);Ot.expand(Bt.config({path:n,override:true}));return}if(!o){let i=X.join(r,`${e}.local`);if(re.existsSync(i)){if(!re.statSync(i).isFile())throw new Error(`envFile path "${e}.local" exists but is not a file (it's a directory).`);Ot.expand(Bt.config({path:i,override:true}));return}}if(t){let i=o?[n]:[n,X.join(r,`${e}.local`)];throw new Error(`envFile "${e}" specified in config but not found. Expected at: ${i.join(" or ")}`)}}function Jr(e){let t="",r=0;for(;r<e.length;)if(e[r]==="$"&&e[r+1]==="{"){let o=1,n=r+2,i=false;for(;n<e.length&&o>0;)e[n]==="$"&&e[n+1]==="{"?(i=true,o++,n++):e[n]==="}"&&o--,n++;if(o===0){let s=e.slice(r+2,n-1);if(i)throw new Error(`\${${s}}: bad substitution`);{let a=s.trim();t+=process.env[a]??"",r=n;}}else t+=e[r],r++;}else t+=e[r],r++;return t}function ht(e){if(typeof e=="string")return Jr(e);if(Array.isArray(e))return e.map(ht);if(e!==null&&typeof e=="object"){let t={};for(let[r,o]of Object.entries(e))t[r]=ht(o);return t}return e}function Xr(){if(ue)return ue;let e=X.join(process.cwd(),Ne);return re.existsSync(e)?e:(ue=X.join(process.cwd(),Ne),ue)}function Qr(){let e=Xr();if(!re.existsSync(e))return null;let t=re.readFileSync(e,"utf-8");return {config:JSON.parse(Yr(t)),filepath:e}}var Oe=null;function je(){if(Oe)return Oe;let[e,t]=p(Qr);if(t&&((f?console.error:m.outro)(j.red(`Error loading configuration file: ${t}`)),process.exit(1)),!e)return null;let r=e.config,o=yt,n=false;r&&typeof r=="object"&&r!==null&&"envFile"in r&&typeof r.envFile=="string"&&(o=r.envFile,n=true);let[i]=p(()=>{Hr(o,n);});i&&((f?console.error:m.outro)(j.red(`Error loading env file: ${i}`)),process.exit(1));let[s,a]=p(()=>ht(e.config));a&&((f?console.error:m.outro)(j.red(`Error resolving environment variables: ${a}`)),process.exit(1));let c=Zr.safeParse(s);if(c.success||((f?console.error:m.log.error)("Invalid Configuration: "),(f?console.error:m.log.error)(z.prettifyError(c.error)),(f?console.error:m.outro)(j.red("Please check your configuration file and try again.")),process.exit(1)),c.data.generate?.outputDir){let u=X.dirname(e.filepath),l=c.data.generate.outputDir,d=X.resolve(u,l),w=X.relative(u,d);(w===""||w==="."||w.startsWith(".."))&&((f?console.error:m.log.error)(j.red(`Invalid outputDir: "${l}" resolves to "${w}" which is outside the project or at project root. outputDir must be inside the project below rightbrain.json level.`)),process.exit(1));}return Oe={...c.data,filePath:e.filepath,rawConfig:r},Oe}function zt(){let e=je();return e||((f?console.error:m.outro)(j.red(`No configuration file found. Expected: ${Ne}`)),process.exit(1)),e}var kt=X.join(eo.homedir(),".rightbrain"),we=X.join(kt,"credentials.json"),ke=null;function me(){if(ke)return ke;if(!re.existsSync(we))return null;try{let e=re.readFileSync(we,"utf-8"),t=JSON.parse(e);return t.access_token?(ke=t,ke):null}catch{return null}}function to(){re.existsSync(kt)||re.mkdirSync(kt,{recursive:true,mode:448});}function oe(e,t=false){to();let r=t?e:{...me(),...e};re.writeFileSync(we,JSON.stringify(r,null,2),"utf-8"),re.chmodSync(we,384),ke=r;}function Kt(){re.existsSync(we)&&re.unlinkSync(we),ke=null;}function Vt(e){if(!e.expires_at)return false;let t=300*1e3;return Date.now()>=e.expires_at-t}var ve=null,xe=null,ze=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Le=0,Wt=process.stderr.isTTY,ro=()=>{Wt&&process.stderr.write("\x1B[?25l");},qe=()=>{Wt&&process.stderr.write("\x1B[?25h");};process.on("exit",qe);process.on("SIGINT",()=>{qe(),process.exit(130);});process.on("SIGTERM",()=>{qe(),process.exit(143);});var oo=()=>{let e=false;return {start:()=>{e||(e=true,Le=0,xe&&clearInterval(xe),ro(),process.stderr.write("\r"+ze[Le]),xe=setInterval(()=>{Le=(Le+1)%ze.length,process.stderr.write("\r"+ze[Le]);},80));},stop:()=>{xe&&(clearInterval(xe),xe=null),e&&(process.stderr.write("\r"+" ".repeat(ze[0].length)+"\r"),qe()),e=false;}}},P=()=>(ve||(ve=oo()),ve),Ke=()=>{ve&&(ve.stop(),ve=null);};async function V(e){let t=e?.loadGlobalConfig?null:je();if(!t){let o=me();if(o)if(Vt(o)){let n=await so(o);if(n)return {accessToken:n.access_token,orgId:n.org_id,projectId:n.project_id}}else return {accessToken:o.access_token,orgId:o.org_id,projectId:o.project_id};Ke(),(f?console.error:m.outro)("Not authenticated. Please run `npx rightbrain login` command to authenticate."),process.exit(1);}return {accessToken:await io(t),orgId:t.orgId,projectId:t.projectId,filePath:t.filePath}}var Ve=null;async function io(e){if(e.apiKey)return e.apiKey;if((!e.clientId||!e.clientSecret)&&(Ke(),(f?console.error:m.outro)(j.red("Client ID and secret are required to authenticate via OAuth")),process.exit(1)),!Ve||Ve.expired()){let t=new ClientCredentials({auth:{tokenHost:e.oauthUrl??I.CLI_PUBLIC_RB_OAUTH2_URL,tokenPath:"/oauth2/token"},client:{id:e.clientId,secret:e.clientSecret},http:{json:"force"}}),[r,o]=await p(()=>t.getToken({}));return (o||!r?.token.access_token)&&(Ke(),(f?console.error:m.outro)(j.red("Failed to obtain access token")),process.exit(1)),Ve=r,r.token.access_token}return Ve.token.access_token}var J={oauthUrl:I.CLI_PUBLIC_RB_OAUTH2_URL,authPath:"/oauth2/auth",tokenPath:"/oauth2/token",clientId:I.CLI_PUBLIC_RB_OAUTH2_CLIENT_ID};async function so(e){if(!e.refresh_token)return null;let t=`${J.oauthUrl}${J.tokenPath}`,r=new URLSearchParams({grant_type:"refresh_token",refresh_token:e.refresh_token,client_id:J.clientId});try{let o=await fetch(t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()});if(!o.ok)return null;let n=await o.json(),i=n.expires_in?Date.now()+n.expires_in*1e3:void 0,s={...e,access_token:n.access_token,refresh_token:n.refresh_token??e.refresh_token,expires_at:i};return oe(s,!0),s}catch{return null}}function Zt(){return wt.randomBytes(32).toString("base64url")}async function Gt(e){return wt.createHash("sha256").update(e).digest().toString("base64url")}function Ht(e,t){let r=gt(),o=new URLSearchParams({client_id:J.clientId,redirect_uri:r,response_type:"code",scope:"offline_access",state:e});return t&&(o.append("code_challenge",t),o.append("code_challenge_method","S256")),`${J.oauthUrl}${J.authPath}?${o.toString()}`}function Jt(){return wt.randomBytes(32).toString("hex")}function M(e){if(f||m.outro("Something went wrong"),isAxiosError(e)){let t=e.response;if(t?.data){t.status===401&&console.error("Unauthorized Access please login again."),console.error("Error:"),console.info(f?JSON.stringify(t.data,null,2):inspect(t.data,{depth:null,colors:true}));return}if(t?.status){console.error(`Error: Request failed with status ${t.status}`);return}}if(e instanceof Error){console.error(e.message);return}(f?console.error:m.outro)("An unexpected error occurred");}async function pe({accessToken:e,orgId:t,projectId:r}){let o=P();if(!t){o.start();let[n,i]=await p(async()=>await new OrganizationsApi(N(e)).listOrganizations().then(a=>a.data.results));if((i||!n)&&(o.stop(),M(i),process.exit(1)),o.stop(),n.length===0&&(m.cancel("No organizations found. Please create one first."),process.exit(1)),n.length===1)t=n[0].id,m.log.info(`Using organization: ${j.cyan(n[0].name)}`);else {let s=await m.select({message:"Select an organization",options:n.map(a=>({value:a.id,label:a.name,hint:a.id}))});m.isCancel(s)&&(m.outro("Select project cancelled"),process.exit(0)),t=s;}}if(!r){o.start();let[n,i]=await p(async()=>await new ProjectsApi(N(e)).listProjects(t).then(a=>a.data.results));if((i||!n)&&(o.stop(),M(i),process.exit(1)),o.stop(),n.length===0&&(m.cancel("No projects found. Please create one first."),process.exit(1)),n.length===1)r=n[0].id,m.log.info(`Using project: ${j.cyan(n[0].name)}`);else {let s=await m.select({message:"Select a project",options:n.map(a=>({value:a.id,label:a.name,hint:a.id}))});m.isCancel(s)&&(m.outro("Select project cancelled"),process.exit(0)),r=s;}}return (typeof t!="string"||typeof r!="string")&&(m.cancel("Failed to select project"),process.exit(1)),{orgId:t,projectId:r}}var N=e=>new Configuration({basePath:I.CLI_PUBLIC_API_URL,accessToken:e}),T=class e{_options;tasksApi;listingsApi;organizationsApi;projectsApi;apiKeysApi;constructor(t){this._options=t;let r=N(t.accessToken);this.tasksApi=new TasksApi(r),this.listingsApi=new ListingsApi(r),this.organizationsApi=new OrganizationsApi(r),this.projectsApi=new ProjectsApi(r),this.apiKeysApi=new APIKeysApi(r);}get orgId(){return this._options.orgId}get projectId(){return this._options.projectId}getTaskUrl(t){return `${I.CLI_PUBLIC_API_URL}/org/${this.orgId}/project/${this.projectId}/task/${t}`}static async fromAuthContext(){let t=await V(),r=await pe(t);return (!t.orgId||!t.projectId)&&oe({access_token:t.accessToken,org_id:r.orgId,project_id:r.projectId}),new e({...t,...r})}static async fromConfig(){let t=await V();return (!t.orgId||!t.projectId)&&((f?console.error:m.outro)("orgId and projectId are required to authenticate."),process.exit(1)),new e({accessToken:t.accessToken,orgId:t.orgId,projectId:t.projectId})}async listModels(){return (await this.listingsApi.getAllModels(this.orgId,this.projectId)).data}async createTask(t){return (await this.tasksApi.createTask(this.orgId,this.projectId,t)).data}async getOrganization(t){return (await this.organizationsApi.getOrganization(t)).data}async getProject(t,r){return (await this.projectsApi.getProject(t,r)).data}async listTasks(){return (await this.tasksApi.listTasks(this.orgId,this.projectId)).data.results}async getTask(t){return (await this.tasksApi.getTask(this.orgId,this.projectId,t,null,true)).data}async runTask({body:t,taskId:r,revisionId:o,useFallbackModel:n=false}){let i=new FormData;if(i.append("task_input",JSON.stringify(t.task_input)),t.task_files&&t.task_files.length>0)for(let c of t.task_files)i.append("task_file",c,c.name);let s=new URLSearchParams;return o&&s.set("revision_id",o),(await this.tasksApi.runTask(this.orgId,this.projectId,r,o,null,null,n,{data:i})).data}async listApiKeys(){return (await this.apiKeysApi.listApiKeys(this.orgId,this.projectId)).data}async createApiKey(t){return (await this.apiKeysApi.createApiKey(this.orgId,this.projectId,{name:t})).data}};var Q=e=>{let{canRunWithOptions:t=true}=e||{};process.env.TERM_PROGRAM?.toLowerCase().includes("mintty")&&(console.warn(`WARNING: It looks like you are using MinTTY, which is non-interactive. This is most likely because you are
|
|
416
416
|
using Git Bash. If that's that case, please use Git Bash from another terminal, such as Windows Terminal.
|
|
417
|
-
`),t&&console.warn("Alternatively, you can provide the arguments from the CLI directly to skip the prompts."),process.exit(1));};var Ye=async e=>{let t=await
|
|
418
|
-
`))&&(r(),e());};return process.stdin.on("data",o),r};function
|
|
417
|
+
`),t&&console.warn("Alternatively, you can provide the arguments from the CLI directly to skip the prompts."),process.exit(1));};var Ye=async e=>{let t=await ko(e);await new Promise(r=>{t?.addListener("exit",()=>{r();}),setTimeout(()=>{r();},3e3);});};function Y(e){return e.startsWith("~/")?X.join(eo.homedir(),e.slice(2)):X.resolve(e)}function xo(e){return re.existsSync(e)&&re.statSync(e).isDirectory()}function Ze(e,t){let r="$SRC/",o="$PWD/",n=X.join(t,"src"),i=xo(n);if(e.startsWith(r)){let s=i?"./src":"./",a=e.slice(r.length);return s+a}return e.startsWith(o)?"./"+e.slice(o.length):e}var Ge=e=>{let t=false,r=()=>{t||(t=true,process.stdin.removeListener("data",o));},o=n=>{let i=n.toString();(i.includes("\r")||i.includes(`
|
|
418
|
+
`))&&(r(),e());};return process.stdin.on("data",o),r};function rr(e){let t=re.readFileSync(e,"utf8");return parseDocument(t).toJS()}function or(e){return !!e.model_params?.temperature}function bt(e,t){let r=re.readFileSync(e,"utf8"),o=parseDocument(r);if(t.model){o.set("llm_model_id",t.model.id);let i=o.get("llm_model_id",true);if(isScalar(i)&&(i.commentBefore=" Selected model: "+t.model.name),or(t.model)){let s=o.get("llm_config",true),a=`Temperature config is not available to selected model
|
|
419
419
|
temperature: `;if(isMap(s)&&s.commentBefore?.startsWith(a)){let c=s.commentBefore.slice(a.length).trim(),u=parseFloat(c);isNaN(u)||s.set("temperature",u),s.commentBefore=void 0;}}else {let s=o.get("llm_config",true);if(isMap(s)&&s.has("temperature")){let a=s.get("temperature");s.commentBefore=`Temperature config is not available to selected model
|
|
420
|
-
temperature: ${a}`,s.delete("temperature");}}}t.taskName&&o.set("name",t.taskName);let n=o.toString();
|
|
421
|
-
temperature: ${d}`,l.delete("temperature");}}i=c.toString();}let[,a]=p(()=>
|
|
422
|
-
${j.cyan(u)}`),m.outro(j.green("Task created successfully!")),process.exit(0);}let t=await m.text({message:"Where would you like to save the task file?",placeholder:Et,defaultValue:Et,validate(n){if(typeof n=="string"&&n.trim()===".")return "File path cannot be empty"}});m.isCancel(t)&&(m.outro("Create task cancelled"),process.exit(0));let r=t||Et,o=Y(r);if(te.existsSync(o)){let n=await m.confirm({message:`File "${r}" already exists. Overwrite?`,initialValue:false});(m.isCancel(n)||!n)&&(m.outro("Create task cancelled"),process.exit(0));}ee.start(),await or(o),ee.stop(),m.outro(`Edit the file, then run ${j.cyan(`npx rightbrain create-task --file ${r}`)} to create the task.`),process.exit(0);}function ar(e){return e instanceof Error?e.message:String(e)}var cr=_();async function Je(e,t){cr.start();let[r,o]=await p(async()=>{let s=await fetch(e);if(!s.ok)throw new Error(`Failed to fetch ${t}: ${s.status} ${s.statusText}`);return s});if(cr.stop(),o||!r){let s=ar(o);throw m.log.error(j.red(`Failed to fetch ${t}: ${s}`)),new Error(`Failed to fetch ${t}: ${s}`)}let[n,i]=await p(async()=>{let s=await r.text();return JSON.parse(s)});if(i||!n){let s=ar(i);throw m.log.error(j.red(`Failed to parse ${t}: ${s}`)),new Error(`Failed to parse ${t}: ${s}`)}return n}var _t=null;async function Xe(e){if(_t)return _t;let t=await Je(`${e}/discovery.json`,"discovery configuration");return _t=t,t}function Qe(e){let t=e.map(n=>({...n,version:"0"})).sort((n,i)=>n.created.localeCompare(i.created)),r=1,o=1;for(let n=0;n<t.length;n++)if(!t[n].test)t[n].version=`${r}`,r++,o=1;else {let i=r===1?1:r-1;t[n].version=`${i}.${o}`,o++;}return t.reverse()}var et=e=>{if(!e||e.active_revisions.length===0)return;let t=e.active_revisions[0].weight??0,r=0;for(let n=1;n<e.active_revisions.length;n++){let i=e.active_revisions?.[n]?.weight;typeof i=="number"&&i>t&&(t=i,r=n);}return e?.revisions?.find(n=>n.id===e.active_revisions[r].task_revision_id)};var Ie=null;async function _o(e){if(Ie&&Ie[e])return Ie[e];let t=`${b.CLI_PUBLIC_TEMPLATES_URL}/${e}.eta`,r=await fetch(t);if(!r.ok)throw new Error(`Failed to fetch template ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return Ie||(Ie={}),Ie[e]=o,o}async function lr(e){let t=new Eta({autoEscape:false,autoTrim:false,cache:true}),r=await _o(e);return t.loadTemplate("@task-types",r),t}var pr={TASK_TYPES:"@task-types"};function Po(e,t="kebab-case"){switch(t){case "camel-case":return `${dr(e)}.ts`;case "kebab-case":return `${Pt(e)}.ts`;case "pascal-case":return `${fr(e)}.ts`;case "snake-case":return `${ur(e)}.ts`}return `${Pt(e)}.ts`}function Ao(e){let t=e.match(/^\$\{([^}]+)\}$/);return t?t[1].trim():null}function $o(e){let t={};if(e&&typeof e=="object"&&"generate"in e&&e.generate&&typeof e.generate=="object"&&"taskIds"in e.generate&&Array.isArray(e.generate.taskIds)){for(let r of e.generate.taskIds)if(typeof r=="string"){let o=Ao(r);if(o){let n=process.env[o];n&&(t[n]=o);}}}return t}function jo(e){return e&&typeof e=="object"&&"generate"in e&&e.generate&&typeof e.generate=="object"&&"hardcodeTaskIds"in e.generate?e.generate.hardcodeTaskIds===true:false}function Mo(e,t){let r=Qe(e.revisions||[]),o={...e,revisions:r},n=et({...o,revisions:r});if(!n)return null;let i=t?jo(t):false,a=(t&&!i?$o(t):{})[o.id]||null;return {task:o,activeRevision:n,taskIdEnvVar:a,utils:{camelCase:dr,kebabCase:Pt,pascalCase:fr,snakeCase:ur}}}var tt=class{constructor(t,r){this.language=t;this.languageConfig=r;}eta=null;initialized=false;async initialize(){this.initialized||(this.eta=await lr(this.language),this.initialized=true);}generate(t,r){if(!this.eta)throw new Error("TypeGenerator not initialized. Call initialize() first.");let o=Mo(t,r);if(!o)return null;let n=this.eta.render(pr.TASK_TYPES,o);return {fileName:Po(t.name,this.languageConfig.filenameCase),content:n}}generateAll(t,r){let o=[];for(let n of t){let i=this.generate(n,r);i&&o.push(i);}return o}};function Le(e){return e instanceof Error?e.message:String(e)}async function ot(e){let{init:t=false}=e||{},r=Nt(),o=r.generate?.outputDir;o||(m.cancel(`Error: No generate.outputDir found in ${r.filePath}`),process.exit(1)),o=X.join(o);let n=r.generate?.taskIds||[];n.length===0&&(m.cancel(`Error: No generate.taskIds found in ${r.filePath}`),process.exit(1));let i=r.generate?.language;i||(m.cancel(`Error: No generate.language found in ${r.filePath}`),process.exit(1));let s=X.dirname(r.filePath),a=X.resolve(s,o),[c,u]=await p(()=>Xe(b.CLI_PUBLIC_TEMPLATES_URL));(u||!c)&&(m.cancel(`Failed to fetch discovery: ${Le(u)}`),process.exit(1));let l=c[i];l||(m.cancel(`Language ${i} is not currently supported.`),process.exit(1));let d=m.spinner();d.start("Generating types");let v=new tt(i,l);await v.initialize();let E=await T.fromConfig(),I=new Set(n),h=[];for(let P of I){let[q,ae]=await p(()=>E.getTask(P));if(ae){d.stop("Something went wrong"),m.log.warn(j.yellow(`Failed to fetch task ${P}: ${Le(ae)}`)),d.start("Generating types");continue}q&&h.push(q);}h.length===0&&!t&&(m.cancel("No valid tasks to generate."),process.exit(0));let[U,w]=p(()=>v.generateAll(h,r.rawConfig));U||(d.stop("Something went wrong"),m.cancel(`Failed to generate types: ${Le(w)}`),process.exit(1));let[,C]=await p(()=>te.promises.mkdir(a,{recursive:!0}));C&&(d.stop("Something went wrong"),m.cancel(`Failed to create output directory: ${Le(C)}`),process.exit(1));let S=[];for(let{fileName:P,content:q}of U){let ae=X.join(a,P),[,ce]=await p(()=>te.promises.writeFile(ae,q,"utf-8"));if(ce){m.log.warn(j.yellow(`Failed to write ${P}: ${Le(ce)}`));continue}S.push(P);}d.stop(`Generated ${j.cyan(S.length.toString())} file(s) at ${j.green(a)}`),t||m.outro(j.green("Done!"));}function gr(e){e.description("Generate task interface for your RightBrain tasks").action(ot);}var hr=_();function yr(e){return te.existsSync(e)&&te.statSync(e).isFile()}function kr(e){return te.existsSync(e)&&te.statSync(e).isDirectory()}function be(e,t,r){if("all"in e)return e.all.every(o=>be(o,t,r));if("any"in e)return e.any.some(o=>be(o,t,r));if("fileExists"in e)return yr(X.join(t,e.fileExists));if("fileNotExists"in e)return !yr(X.join(t,e.fileNotExists));if("dirExists"in e)return kr(X.join(t,e.dirExists));if("dirNotExists"in e)return !kr(X.join(t,e.dirNotExists));if("fileContains"in e){let o=X.join(t,e.fileContains);if(!te.existsSync(o))return false;try{let n=te.readFileSync(o,"utf-8");return new RegExp(e.pattern,e.flags||"").test(n)}catch{return false}}return "environmentExists"in e?r.has(e.environmentExists):"environmentNotExists"in e?!r.has(e.environmentNotExists):false}function xr(e,t){for(let[r,o]of Object.entries(e))if(o.require){let n=new Set;if(be(o.require,t,n))return r}return null}async function nt(e,t){let r=Object.keys(e);if(r.length===0)throw m.log.error(j.red("No languages available in discovery configuration.")),new Error("No languages available");let o=await m.select({message:"Select a language for your project",options:r.map(s=>({value:s,label:s}))});m.isCancel(o)&&(m.outro("Init cancelled."),process.exit(0));let n=o,i=e[n];if(i.require){let s=new Set;if(!be(i.require,t,s)){let c=i.errorMessage||`Your project does not meet the requirements for ${n}.`;m.log.warn(j.yellow(c));let u=await m.confirm({message:"Do you want to continue anyway?",initialValue:false});if(m.isCancel(u)||!u)return nt(e,t)}}return n}async function So(e,t){let r=await Je(`${e}/${t}.json`,`${t} template`),o={};if(r.environments)for(let[n,i]of Object.entries(r.environments))o[n]={require:i.require,files:[]};return {files:r.files||[],environments:o}}async function Lo(e,t,r){let o=`${e}/${t}-${r}.json`;hr.start();let[n,i]=await p(async()=>{let c=await fetch(o);if(!c.ok){if(c.status===404)return null;throw new Error(`Failed to fetch environment template: ${c.status} ${c.statusText}`)}return c});if(hr.stop(),i||!n)return i&&m.log.warn(j.yellow(`Failed to fetch ${t}-${r} template: ${Be(i)}`)),[];let[s,a]=await p(async()=>{let c=await n.text();return JSON.parse(c)});return a||!s?(m.log.warn(j.yellow(`Failed to parse ${t}-${r} template: ${Be(a)}`)),[]):s.files||[]}function At(e,t){return "environmentNotExists"in e?e.environmentNotExists===t:"all"in e||"any"in e?("all"in e?e.all:e.any).some(o=>At(o,t)):false}function $t(e){return "environmentNotExists"in e?true:"all"in e||"any"in e?("all"in e?e.all:e.any).some(r=>$t(r)):false}function Fo(e,t,r){let o=[],n=new Set(r);for(let[c,u]of Object.entries(e.environments))be(u.require,t,n)&&o.push(c);let i=o.sort((c,u)=>{let l=$t(e.environments[c].require),d=$t(e.environments[u].require);return l&&!d?1:!l&&d?-1:0}),s=[],a=new Set(r);for(let c of i){let u=e.environments[c];if(be(u.require,t,a)&&!s.some(d=>At(e.environments[d].require,c))){for(let d=s.length-1;d>=0;d--){let v=s[d];At(u.require,v)&&(s.splice(d,1),a.delete(v));}s.push(c),a.add(c),r.add(c);}}return s}function wr(e,t){for(let r of e){let o=Ze(r.path,t),n=X.join(t,o),i=X.dirname(n);te.existsSync(i)||te.mkdirSync(i,{recursive:true});try{te.writeFileSync(n,r.content,"utf-8");}catch(s){m.log.warn(j.yellow(`Failed to write ${o}: ${Be(s)}`));}}}async function vr(e,t,r){let o=await So(r,e),n=new Set,i=0;if(o.files.length>0&&(wr(o.files,t),i+=o.files.length),Object.keys(o.environments).length>0){let s=Fo(o,t,n);for(let a of s){let c=await Lo(r,e,a);c.length>0?(wr(c,t),i+=c.length):m.log.warn(j.yellow(`Environment ${a} matched but has no files to apply`));}}i>0&&m.log.success(`Written ${j.cyan(i.toString())} file(s) to quickly get started!`);}var st="rightbrain.json",Ir=".env";function br(e){e.description("Initialize RightBrain configuration for your project").action(Vo);}var Ee=_();async function Uo(e){let t=X.join(e,st);if(te.existsSync(t)){m.log.warn(j.yellow(`A ${st} file already exists at ${e}.`));let r=await m.confirm({message:"Do you want to override the existing configuration?",initialValue:false});(m.isCancel(r)||!r)&&(m.outro("Init cancelled."),process.exit(0));}}async function Bo(e){let[t]=p(()=>(execSync("git rev-parse --is-inside-work-tree",{cwd:e,encoding:"utf-8",stdio:"pipe"}),!0));if(t){let[,r]=p(()=>execSync("git diff --quiet",{cwd:e,encoding:"utf-8"})),o=!!r,[n,i]=p(()=>execSync("git status --porcelain",{cwd:e,encoding:"utf-8"})),s=!i&&n&&n.split(`
|
|
420
|
+
temperature: ${a}`,s.delete("temperature");}}}t.taskName&&o.set("name",t.taskName);let n=o.toString();re.writeFileSync(e,n,"utf8");}async function Co(){let[e,t]=await p(()=>T.fromAuthContext());if(t||!e)return null;let[r,o]=await p(()=>e.listModels());if(o||!r)return null;let i=r.filter(a=>!a.replaced_by);return i.length===0?null:i.find(a=>a.provider.toLowerCase()==="openai")||i[0]}async function nr(e){let t=X.dirname(e),[,r]=p(()=>{t&&t!=="."&&!re.existsSync(t)&&re.mkdirSync(t,{recursive:!0});});if(r){let c=r instanceof Error?r.message:String(r);(f?console.error:m.outro)(`Failed to create directory "${t}": ${c}`),process.exit(1);}let o=`${I.CLI_PUBLIC_TEMPLATES_URL}/create-task.yaml`,n=await fetch(o,{headers:{accept:"text/yaml"},redirect:"manual"});n.ok||((f?console.error:m.outro)(`Failed to download template: Server returned ${n.status} ${n.statusText}`),process.exit(1));let i=await n.text(),s=await Co();if(s){let c=parseDocument(i);c.set("llm_model_id",s.id);let u=c.get("llm_model_id",true);if(isScalar(u)&&(u.commentBefore=" Selected model: "+s.name),!or(s)){let l=c.get("llm_config",true);if(isMap(l)&&l.has("temperature")){let d=l.get("temperature");l.commentBefore=`Temperature config is not available to selected model
|
|
421
|
+
temperature: ${d}`,l.delete("temperature");}}i=c.toString();}let[,a]=p(()=>re.writeFileSync(e,i,"utf8"));if(a){let c=a instanceof Error?a.message:String(a);(f?console.error:m.outro)(`Failed to write file "${e}": ${c}`),process.exit(1);}}function sr(e){e.description("Create a new task").option("-f, --file <file>","Create task from a YAML file.").action(Eo);}async function Eo(e){if(ee.start(),await T.fromAuthContext(),ee.stop(),!e.file){Q();let t=await m.confirm({message:"Create tasks directly from the dashboard",initialValue:true});m.isCancel(t)?(m.outro("Create task cancelled"),process.exit(0)):t?await To():await ir(e);return}await ir(e);}var ee=P();async function To(){let e=await T.fromAuthContext();ee.start();let[t]=await p(()=>e.getProject(e.orgId,e.projectId));ee.stop();let r=t?.name||e.projectId;m.log.info(`Opening dashboard to create task in project: ${j.cyan(r)}`);let o=m.spinner();o.start("Press Enter to open dashboard..."),Ge(async()=>{o.message("Opening dashboard...");let{origin:n}=new URL(I.CLI_PUBLIC_TEMPLATES_URL),i=`${n}/server/org/${e.orgId}/project/${e.projectId}/task/create`,[,s]=await p(()=>Ye(i));s&&(o.stop("Could not open browser automatically."),m.outro(`Please open the URL manually: ${j.cyan(i)}`),process.exit(1)),o.stop("Dashboard opened in your browser"),m.outro(j.green("Please create the task in the dashboard.")),process.exit(0);});}var Et="create-task.yaml";async function ir({file:e}){if(e){let n=Y(e),i=null,s=null,a=null;for(;;){ee.start(),a=await T.fromAuthContext();let d=a,[w,b]=p(()=>rr(n)),[_,h]=await p(()=>d.createTask(w));if(ee.stop(),b&&(M(b),process.exit(1)),h){(f||!isAxiosError(h))&&(M(h),process.exit(1));let R=h.response?.data;if(typeof R=="object"&&R!==null&&"detail"in R&&Array.isArray(R.detail)){let E=R.detail;if(Array.isArray(E)&&E.length>0){if(E.find(x=>typeof x=="object"&&x!==null&&"type"in x&&x.type==="invalid_llm_model")){m.log.error("Invalid LLM model ID detected."),ee.start();let[x,C]=await p(()=>d.listModels());ee.stop(),(C||!x)&&(m.cancel(`Error: Failed to fetch available models. Please run ${j.cyan("npx rightbrain list-models")} to see available models.`),process.exit(1));let O=x.filter(G=>!G.replaced_by);O.length===0&&(m.cancel("Error: No available models found."),process.exit(1));let te=De(O),fe=Array.from(te.keys()).sort(),Ue=[];for(let G of fe){let Br=te.get(G);for(let mt of Br)Ue.push({value:mt.id,label:`${mt.alias} (${G})`,hint:mt.id});}let Mt=await m.autocomplete({message:"Please select a valid LLM model:",options:Ue});m.isCancel(Mt)&&(m.outro("Model selection cancelled"),process.exit(0));let ut=O.find(G=>G.id===Mt);ut||(m.cancel("Error: Selected model not found."),process.exit(1));try{bt(n,{model:ut}),m.log.info(`Updated ${j.cyan(e)} with model: ${j.cyan(ut.alias)}`);}catch(G){m.cancel(`Error: Failed to update file: ${G instanceof Error?G.message:String(G)}`),process.exit(1);}continue}if(E.find(x=>typeof x=="object"&&x!==null&&"type"in x&&x.type==="duplicate_task_name")){m.log.error("Duplicate task name detected.");let x=await m.text({message:"Please enter a unique task name:",placeholder:"Enter task name",initialValue:w&&typeof w=="object"&&"name"in w&&typeof w.name=="string"&&w?.name||"",validate(C){if(typeof C=="string"&&C.trim()===".")return "Task name cannot be empty"}});m.isCancel(x)&&(m.outro("Create task cancelled"),process.exit(0));try{bt(n,{taskName:x}),m.log.info(`Updated ${j.cyan(e)} with task name: ${j.cyan(x)}`);}catch(C){m.outro(`Error: Failed to update file: ${C instanceof Error?C.message:String(C)}`),process.exit(1);}continue}}}}i=_,s=h;break}i||(s?M(s):(f?console.error:m.outro)(j.red("Failed to create task")),process.exit(1));let c=i.id,{origin:u}=new URL(I.CLI_PUBLIC_TEMPLATES_URL),l=`${u}/server/org/${a.orgId}/project/${a.projectId}/task/${c}`;f&&(console.info(JSON.stringify(i,null,2)),process.exit(0)),m.log.info(`Run this task with ${j.cyan(`npx rightbrain run-task --task ${c}`)} command.`),m.log.info(`View in dashboard:
|
|
422
|
+
${j.cyan(l)}`),m.outro(j.green("Task created successfully!")),process.exit(0);}let t=await m.text({message:"Where would you like to save the task file?",placeholder:Et,defaultValue:Et,validate(n){if(typeof n=="string"&&n.trim()===".")return "File path cannot be empty"}});m.isCancel(t)&&(m.outro("Create task cancelled"),process.exit(0));let r=t||Et,o=Y(r);if(re.existsSync(o)){let n=await m.confirm({message:`File "${r}" already exists. Overwrite?`,initialValue:false});(m.isCancel(n)||!n)&&(m.outro("Create task cancelled"),process.exit(0));}ee.start(),await nr(o),ee.stop(),m.outro(`Edit the file, then run ${j.cyan(`npx rightbrain create-task --file ${r}`)} to create the task.`),process.exit(0);}function cr(e){return e instanceof Error?e.message:String(e)}var lr=P();async function Je(e,t){lr.start();let[r,o]=await p(async()=>{let s=await fetch(e);if(!s.ok)throw new Error(`Failed to fetch ${t}: ${s.status} ${s.statusText}`);return s});if(lr.stop(),o||!r){let s=cr(o);throw m.log.error(j.red(`Failed to fetch ${t}: ${s}`)),new Error(`Failed to fetch ${t}: ${s}`)}let[n,i]=await p(async()=>{let s=await r.text();return JSON.parse(s)});if(i||!n){let s=cr(i);throw m.log.error(j.red(`Failed to parse ${t}: ${s}`)),new Error(`Failed to parse ${t}: ${s}`)}return n}var _t=null;async function Xe(e){if(_t)return _t;let t=await Je(`${e}/discovery.json`,"discovery configuration");return _t=t,t}function Qe(e){let t=e.map(n=>({...n,version:"0"})).sort((n,i)=>n.created.localeCompare(i.created)),r=1,o=1;for(let n=0;n<t.length;n++)if(!t[n].test)t[n].version=`${r}`,r++,o=1;else {let i=r===1?1:r-1;t[n].version=`${i}.${o}`,o++;}return t.reverse()}var et=e=>{if(!e||e.active_revisions.length===0)return;let t=e.active_revisions[0].weight??0,r=0;for(let n=1;n<e.active_revisions.length;n++){let i=e.active_revisions?.[n]?.weight;typeof i=="number"&&i>t&&(t=i,r=n);}return e?.revisions?.find(n=>n.id===e.active_revisions[r].task_revision_id)};var Ie=null;async function Po(e){if(Ie&&Ie[e])return Ie[e];let t=`${I.CLI_PUBLIC_TEMPLATES_URL}/${e}.eta`,r=await fetch(t);if(!r.ok)throw new Error(`Failed to fetch template ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return Ie||(Ie={}),Ie[e]=o,o}async function pr(e){let t=new Eta({autoEscape:false,autoTrim:false,cache:true}),r=await Po(e);return t.loadTemplate("@task-types",r),t}var dr={TASK_TYPES:"@task-types"};function Ao(e,t="kebab-case"){switch(t){case "camel-case":return `${fr(e)}.ts`;case "kebab-case":return `${Pt(e)}.ts`;case "pascal-case":return `${ur(e)}.ts`;case "snake-case":return `${mr(e)}.ts`}return `${Pt(e)}.ts`}function $o(e){let t=e.match(/^\$\{([^}]+)\}$/);return t?t[1].trim():null}function jo(e){let t={};if(e&&typeof e=="object"&&"generate"in e&&e.generate&&typeof e.generate=="object"&&"taskIds"in e.generate&&Array.isArray(e.generate.taskIds)){for(let r of e.generate.taskIds)if(typeof r=="string"){let o=$o(r);if(o){let n=process.env[o];n&&(t[n]=o);}}}return t}function Lo(e){return e&&typeof e=="object"&&"generate"in e&&e.generate&&typeof e.generate=="object"&&"hardcodeTaskIds"in e.generate?e.generate.hardcodeTaskIds===true:false}function Mo(e,t){let r=Qe(e.revisions||[]),o={...e,revisions:r},n=et({...o,revisions:r});if(!n)return null;let i=t?Lo(t):false,a=(t&&!i?jo(t):{})[o.id]||null;return {task:o,activeRevision:n,taskIdEnvVar:a,utils:{camelCase:fr,kebabCase:Pt,pascalCase:ur,snakeCase:mr}}}var tt=class{constructor(t,r){this.language=t;this.languageConfig=r;}eta=null;initialized=false;async initialize(){this.initialized||(this.eta=await pr(this.language),this.initialized=true);}generate(t,r){if(!this.eta)throw new Error("TypeGenerator not initialized. Call initialize() first.");let o=Mo(t,r);if(!o)return null;let n=this.eta.render(dr.TASK_TYPES,o);return {fileName:Ao(t.name,this.languageConfig.filenameCase),content:n}}generateAll(t,r){let o=[];for(let n of t){let i=this.generate(n,r);i&&o.push(i);}return o}};function Se(e){return e instanceof Error?e.message:String(e)}async function ot(e){let{init:t=false}=e||{},r=zt(),o=r.generate?.outputDir;o||(m.cancel(`Error: No generate.outputDir found in ${r.filePath}`),process.exit(1)),o=X.join(o);let n=r.generate?.taskIds||[];n.length===0&&(m.cancel(`Error: No generate.taskIds found in ${r.filePath}`),process.exit(1));let i=r.generate?.language;i||(m.cancel(`Error: No generate.language found in ${r.filePath}`),process.exit(1));let s=X.dirname(r.filePath),a=X.resolve(s,o),[c,u]=await p(()=>Xe(I.CLI_PUBLIC_TEMPLATES_URL));(u||!c)&&(m.cancel(`Failed to fetch discovery: ${Se(u)}`),process.exit(1));let l=c[i];l||(m.cancel(`Language ${i} is not currently supported.`),process.exit(1));let d=m.spinner();d.start("Generating types");let w=new tt(i,l);await w.initialize();let b=await T.fromConfig(),_=new Set(n),h=[];for(let D of _){let[O,te]=await p(()=>b.getTask(D));if(te){d.stop("Something went wrong"),m.log.warn(j.yellow(`Failed to fetch task ${D}: ${Se(te)}`)),d.start("Generating types");continue}O&&h.push(O);}h.length===0&&!t&&(m.cancel("No valid tasks to generate."),process.exit(0));let[R,E]=p(()=>w.generateAll(h,r.rawConfig));R||(d.stop("Something went wrong"),m.cancel(`Failed to generate types: ${Se(E)}`),process.exit(1));let[,x]=await p(()=>re.promises.mkdir(a,{recursive:!0}));x&&(d.stop("Something went wrong"),m.cancel(`Failed to create output directory: ${Se(x)}`),process.exit(1));let C=[];for(let{fileName:D,content:O}of R){let te=X.join(a,D),[,fe]=await p(()=>re.promises.writeFile(te,O,"utf-8"));if(fe){m.log.warn(j.yellow(`Failed to write ${D}: ${Se(fe)}`));continue}C.push(D);}d.stop(`Generated ${j.cyan(C.length.toString())} file(s) at ${j.green(a)}`),t||m.outro(j.green("Done!"));}function hr(e){e.description("Generate task interface for your RightBrain tasks").action(ot);}var yr=P();function kr(e){return re.existsSync(e)&&re.statSync(e).isFile()}function wr(e){return re.existsSync(e)&&re.statSync(e).isDirectory()}function be(e,t,r){if("all"in e)return e.all.every(o=>be(o,t,r));if("any"in e)return e.any.some(o=>be(o,t,r));if("fileExists"in e)return kr(X.join(t,e.fileExists));if("fileNotExists"in e)return !kr(X.join(t,e.fileNotExists));if("dirExists"in e)return wr(X.join(t,e.dirExists));if("dirNotExists"in e)return !wr(X.join(t,e.dirNotExists));if("fileContains"in e){let o=X.join(t,e.fileContains);if(!re.existsSync(o))return false;try{let n=re.readFileSync(o,"utf-8");return new RegExp(e.pattern,e.flags||"").test(n)}catch{return false}}return "environmentExists"in e?r.has(e.environmentExists):"environmentNotExists"in e?!r.has(e.environmentNotExists):false}function vr(e,t){for(let[r,o]of Object.entries(e))if(o.require){let n=new Set;if(be(o.require,t,n))return r}return null}async function nt(e,t){let r=Object.keys(e);if(r.length===0)throw m.log.error(j.red("No languages available in discovery configuration.")),new Error("No languages available");let o=await m.select({message:"Select a language for your project",options:r.map(s=>({value:s,label:s}))});m.isCancel(o)&&(m.outro("Init cancelled."),process.exit(0));let n=o,i=e[n];if(i.require){let s=new Set;if(!be(i.require,t,s)){let c=i.errorMessage||`Your project does not meet the requirements for ${n}.`;m.log.warn(j.yellow(c));let u=await m.confirm({message:"Do you want to continue anyway?",initialValue:false});if(m.isCancel(u)||!u)return nt(e,t)}}return n}async function So(e,t){let r=await Je(`${e}/${t}.json`,`${t} template`),o={};if(r.environments)for(let[n,i]of Object.entries(r.environments))o[n]={require:i.require,files:[]};return {files:r.files||[],environments:o}}async function Fo(e,t,r){let o=`${e}/${t}-${r}.json`;yr.start();let[n,i]=await p(async()=>{let c=await fetch(o);if(!c.ok){if(c.status===404)return null;throw new Error(`Failed to fetch environment template: ${c.status} ${c.statusText}`)}return c});if(yr.stop(),i||!n)return i&&m.log.warn(j.yellow(`Failed to fetch ${t}-${r} template: ${Be(i)}`)),[];let[s,a]=await p(async()=>{let c=await n.text();return JSON.parse(c)});return a||!s?(m.log.warn(j.yellow(`Failed to parse ${t}-${r} template: ${Be(a)}`)),[]):s.files||[]}function At(e,t){return "environmentNotExists"in e?e.environmentNotExists===t:"all"in e||"any"in e?("all"in e?e.all:e.any).some(o=>At(o,t)):false}function $t(e){return "environmentNotExists"in e?true:"all"in e||"any"in e?("all"in e?e.all:e.any).some(r=>$t(r)):false}function Ro(e,t,r){let o=[],n=new Set(r);for(let[c,u]of Object.entries(e.environments))be(u.require,t,n)&&o.push(c);let i=o.sort((c,u)=>{let l=$t(e.environments[c].require),d=$t(e.environments[u].require);return l&&!d?1:!l&&d?-1:0}),s=[],a=new Set(r);for(let c of i){let u=e.environments[c];if(be(u.require,t,a)&&!s.some(d=>At(e.environments[d].require,c))){for(let d=s.length-1;d>=0;d--){let w=s[d];At(u.require,w)&&(s.splice(d,1),a.delete(w));}s.push(c),a.add(c),r.add(c);}}return s}function xr(e,t){for(let r of e){let o=Ze(r.path,t),n=X.join(t,o),i=X.dirname(n);re.existsSync(i)||re.mkdirSync(i,{recursive:true});try{re.writeFileSync(n,r.content,"utf-8");}catch(s){m.log.warn(j.yellow(`Failed to write ${o}: ${Be(s)}`));}}}async function Cr(e,t,r){let o=await So(r,e),n=new Set,i=0;if(o.files.length>0&&(xr(o.files,t),i+=o.files.length),Object.keys(o.environments).length>0){let s=Ro(o,t,n);for(let a of s){let c=await Fo(r,e,a);c.length>0?(xr(c,t),i+=c.length):m.log.warn(j.yellow(`Environment ${a} matched but has no files to apply`));}}i>0&&m.log.success(`Written ${j.cyan(i.toString())} file(s) to quickly get started!`);}var st="rightbrain.json",br=".env";function Er(e){e.description("Initialize RightBrain configuration for your project").action(Wo);}var Ee=P();async function Bo(e){let t=X.join(e,st);if(re.existsSync(t)){m.log.warn(j.yellow(`A ${st} file already exists at ${e}.`));let r=await m.confirm({message:"Do you want to override the existing configuration?",initialValue:false});(m.isCancel(r)||!r)&&(m.outro("Init cancelled."),process.exit(0));}}async function Oo(e){let[t]=p(()=>(execSync("git rev-parse --is-inside-work-tree",{cwd:e,encoding:"utf-8",stdio:"pipe"}),!0));if(t){let[,r]=p(()=>execSync("git diff --quiet",{cwd:e,encoding:"utf-8"})),o=!!r,[n,i]=p(()=>execSync("git status --porcelain",{cwd:e,encoding:"utf-8"})),s=!i&&n&&n.split(`
|
|
423
423
|
`).some(a=>a.trim().startsWith("??"));if(o||s){let a=o&&s?"You have unstaged changes and untracked files in your repository.":o?"You have unstaged changes in your repository.":"You have untracked files in your repository.";m.log.warn(j.yellow(a));let c=await m.confirm({message:"Do you want to continue anyway?",initialValue:false});(m.isCancel(c)||!c)&&(m.outro("Init cancelled. Please stage or stash your changes first."),process.exit(0));}}else m.log.warn(j.yellow(`No git repository detected.
|
|
424
|
-
Files generated in the next step will not be tracked.`));}async function
|
|
425
|
-
Visit dashboard to create or retrieve your API key.`)),s=true);let a=(o||[]).filter(c=>!c.revoked);if(a.length>0){let c="__create_new__",u=await m.autocomplete({message:"Select an API key to use",options:[...a.map(l=>({value:l.id,label:l.name,hint:`Created: ${new Date(l.created).toLocaleDateString()}`})),{value:c,label:"Create a new API key",hint:"Generate a new API key for this project"}]});if(m.isCancel(u)&&(m.outro("Init cancelled."),process.exit(0)),u===c)i=await
|
|
426
|
-
`,"utf-8");let c=X.join(e,
|
|
424
|
+
Files generated in the next step will not be tracked.`));}async function No(){let e,t;try{let r=await Xe(I.CLI_PUBLIC_TEMPLATES_URL),o=vr(r,process.cwd());if(o){let i=await m.confirm({message:`Detected ${j.cyan(o)}, do you want to proceed with it?`,initialValue:!0});m.isCancel(i)&&(m.outro("Init cancelled."),process.exit(0)),i?e=o:e=await nt(r,process.cwd());}else e=await nt(r,process.cwd());t=r[e]?.outputDir||"./lib/rightbrain";}catch(r){let o=r instanceof Error?r.message:String(r);m.log.error(j.red(`Language detection failed: ${o}`)),process.exit(1);}return {selectedLanguage:e,outputDir:Ze(t,process.cwd())}}async function zo(){let e=await V({loadGlobalConfig:true});return {selectedProject:await pe({accessToken:e.accessToken}),context:e}}async function Ir(e,t,r){let o=await m.text({message:"Enter a name for the new API key",placeholder:"my-api-key",validate:s=>{if(!s||s.trim().length===0)return "API key name is required"}});m.isCancel(o)&&(m.outro("Init cancelled."),process.exit(0)),Ee.start();let[n,i]=await p(async()=>(await e.createApiKey(t,r,{name:o})).data);return Ee.stop(),i||!n?(m.log.error(j.red("Failed to create API key.")),null):(m.log.success(`Created API key: ${j.cyan(n.name)}`),{id:n.id,name:n.name,key:n.key})}async function qo({selectedProject:e}){let t=await V({loadGlobalConfig:true});Ee.start();let r=new APIKeysApi(N(t.accessToken)),[o,n]=await p(async()=>(await r.listApiKeys(e.orgId,e.projectId)).data);Ee.stop();let i=null,s=false;n&&(m.log.warn(j.yellow(`Unable to fetch API keys.
|
|
425
|
+
Visit dashboard to create or retrieve your API key.`)),s=true);let a=(o||[]).filter(c=>!c.revoked);if(a.length>0){let c="__create_new__",u=await m.autocomplete({message:"Select an API key to use",options:[...a.map(l=>({value:l.id,label:l.name,hint:`Created: ${new Date(l.created).toLocaleDateString()}`})),{value:c,label:"Create a new API key",hint:"Generate a new API key for this project"}]});if(m.isCancel(u)&&(m.outro("Init cancelled."),process.exit(0)),u===c)i=await Ir(r,e.orgId,e.projectId);else {let l=a.find(d=>d.id===u);l&&(i={id:l.id,name:l.name,key:l.key});}}else i=await Ir(r,e.orgId,e.projectId);return {selectedApiKey:i,apiKeysFailed:s}}async function Ko({wd:e,configFilePath:t,selectedApiKey:r,selectedProject:o,language:n,outputDir:i}){let s=X.join(e,i);re.existsSync(s)||re.mkdirSync(s,{recursive:true});let a={$schema:I.CLI_PUBLIC_TEMPLATES_URL+"/schema.json",orgId:"${RB_ORG_ID}",projectId:"${RB_PROJECT_ID}",apiKey:"${RB_API_KEY}",generate:{language:n,outputDir:i,taskIds:[]}};re.writeFileSync(t,JSON.stringify(a,null,2)+`
|
|
426
|
+
`,"utf-8");let c=X.join(e,br),u=r?.key||"<YOUR_API_KEY>",l=`# RightBrain Configuration
|
|
427
427
|
RB_ORG_ID="${o.orgId}"
|
|
428
428
|
RB_PROJECT_ID="${o.projectId}"
|
|
429
429
|
RB_API_KEY="${u}"
|
|
430
|
-
`,d=false;if(
|
|
430
|
+
`,d=false;if(re.existsSync(c)){let b=re.readFileSync(c,"utf-8").endsWith(`
|
|
431
431
|
`)?"":`
|
|
432
|
-
`;
|
|
433
|
-
You can manually add task IDs to your config later.`)),false;let l=c||[];if(l.length===0)return m.log.info("No tasks found in this project. You can add task IDs later."),false;let d=await m.autocompleteMultiselect({message:"Select tasks for type generation (type to filter, tab to select)",options:l.map(h=>({value:h.id,label:h.name,hint:h.description?h.description.slice(0,50)+(h.description.length>50?"...":""):void 0})),required:false});if(m.isCancel(d)||d.length===0)return m.log.info("No tasks selected. You can add task IDs later."),false;let
|
|
434
|
-
`),
|
|
432
|
+
`;re.appendFileSync(c,`${b}${l}`,"utf-8"),d=true;}else re.writeFileSync(c,l,"utf-8");return {isEnvFileUpdated:d,configContent:a}}async function Vo({accessToken:e,orgId:t,projectId:r,config:o,configFilePath:n,outputDir:i,language:s}){let a=new TasksApi(N(e));Ee.start();let[c,u]=await p(async()=>(await a.listTasks(t,r)).data.results);if(Ee.stop(),u)return m.log.warn(j.yellow(`Unable to fetch tasks.
|
|
433
|
+
You can manually add task IDs to your config later.`)),false;let l=c||[];if(l.length===0)return m.log.info("No tasks found in this project. You can add task IDs later."),false;let d=await m.autocompleteMultiselect({message:"Select tasks for type generation (type to filter, tab to select)",options:l.map(h=>({value:h.id,label:h.name,hint:h.description?h.description.slice(0,50)+(h.description.length>50?"...":""):void 0})),required:false});if(m.isCancel(d)||d.length===0)return m.log.info("No tasks selected. You can add task IDs later."),false;let w=new Map(l.map(h=>[h.id,h.name])),b=d.map(h=>` /* ${w.get(h)} */ "${h}"`).join(`,
|
|
434
|
+
`),_=`{
|
|
435
435
|
"$schema": "${o.$schema}",
|
|
436
436
|
"orgId": "${o.orgId}",
|
|
437
437
|
"projectId": "${o.projectId}",
|
|
@@ -440,10 +440,10 @@ You can manually add task IDs to your config later.`)),false;let l=c||[];if(l.le
|
|
|
440
440
|
"language": "${s}",
|
|
441
441
|
"outputDir": "${i}",
|
|
442
442
|
"taskIds": [
|
|
443
|
-
${
|
|
443
|
+
${b}
|
|
444
444
|
]
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
|
-
`;return
|
|
448
|
-
${j.cyan(i)}`):a.message("Browser opened. Waiting for authentication...");}let l=await s;(!l.success||!l.token)&&(a.stop("Authentication failed"),m.cancel(`Error: Authentication failed: ${l.error||"Unknown error"}`),process.exit(1));let d=l.token.expires_in?Date.now()+l.token.expires_in*1e3:void 0;
|
|
449
|
-
`)+" If you want to switch projects inside a specific project/config-based setup, please update the orgId and projectId values in your configuration file directly."),(e.orgId||e.projectId)&&(e.orgId||(m.cancel("Organization ID (--org-id) is required when specifying a project ID (--project-id)"),process.exit(1)),e.projectId||(m.cancel("Project ID (--project-id) is required when specifying an organization ID (--org-id)"),process.exit(1)));let r;if(e.orgId||e.projectId){dt.start();let i=e.orgId,s=e.projectId,a=new T({accessToken:t.accessToken,orgId:i,projectId:s}),[c,u]=await p(()=>a.getOrganization(i));(u||!c)&&(
|
|
447
|
+
`;return re.writeFileSync(n,_,"utf-8"),m.log.success(`Added ${j.cyan(d.length.toString())} task(s) to configuration`),true}async function Wo(){Q({canRunWithOptions:false}),V({loadGlobalConfig:true}),await Bo(process.cwd()),await Oo(process.cwd());let{selectedLanguage:e,outputDir:t}=await No(),{selectedProject:r,context:o}=await zo(),{selectedApiKey:n,apiKeysFailed:i}=await qo({selectedProject:r});!n&&!i&&(m.cancel("Error: Failed to select or create an API key."),process.exit(1));let s=X.join(process.cwd(),st),{isEnvFileUpdated:a,configContent:c}=await Ko({configFilePath:s,selectedApiKey:n,selectedProject:r,wd:process.cwd(),language:e,outputDir:t});m.log.success(`Generated ${j.cyan(st)}, and ${a?"updated ":""}${j.cyan(br)}`);try{await Cr(e,process.cwd(),I.CLI_PUBLIC_TEMPLATES_URL);}catch(l){let d=l instanceof Error?l.message:String(l);m.log.error(j.red(`Failed to apply templates: ${d}`)),process.exit(1);}await Vo({accessToken:o.accessToken,orgId:r.orgId,projectId:r.projectId,configFilePath:s,outputDir:t,config:c,language:e})&&await ot({init:true}),m.outro(j.green("RightBrain project initialized successfully!"));}function Tr(e){e.description("List available LLM models").option("-p, --provider <name>","Filter by provider (e.g., openai, anthropic)").option("--json","Output as JSON").option("-c, --compact","Compact output (ID and name only)").action(Zo);}var at=P();function Yo(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${Math.round(e/1e3)}K`:e.toString()}async function Zo(e){at.start();let t=await T.fromAuthContext();at.stop(),at.start();let[r,o]=await p(()=>t.listModels());at.stop(),(o||!r)&&(M(o||new Error("Failed to fetch models")),process.exit(1));let n=r;n.length===0&&((f?console.error:m.outro)(j.red("No models available")),process.exit(0));let i=n.filter(c=>!c.replaced_by);if(e.provider){let c=e.provider.toLowerCase();i=i.filter(u=>u.provider.toLowerCase().includes(c)||u.vendor.toLowerCase().includes(c)),i.length===0&&((f?console.error:m.outro)(j.red(`No models found for provider: ${e.provider}`)),process.exit(0));}(e.json||f)&&(console.info(JSON.stringify(i,null,2)),process.exit(0));let s=De(i),a=Array.from(s.keys()).sort();if(m.log.info(j.bold(`Available Models (${i.length} total)`)),console.info(),e.compact)for(let c of a){let u=s.get(c);console.info(j.bold(j.cyan(`\u25B8 ${c}`)));for(let l of u)console.info(` ${l.alias}`),console.info(` ${j.dim(l.id)}`);console.info();}else for(let c of a){let u=s.get(c);console.info(j.bold(j.cyan(`\u25B8 ${c}`))+j.dim(` (${u.length} models)`)),console.info();for(let l of u){console.info(` ${j.bold(l.alias)}`),console.info(` ${j.dim("ID:")} ${j.green(l.id)}`);let d=[];l.vendor!==l.provider&&d.push(`via ${l.vendor}`),l.description&&d.push(l.description),l.supports_vision&&d.push(j.magenta("\u{1F441} vision")),l.max_context_window&&d.push(`${Yo(l.max_context_window)} ctx`),d.length>0&&console.info(` ${j.dim(d.join(" \xB7 "))}`),console.info();}}(!e.provider||!e.compact)&&console.info(j.dim("\u2500".repeat(40))),e.provider||console.info(j.dim("Use --provider <name> to filter by provider.")),e.compact||console.info(j.dim("Use --compact for a condensed view."));}function _r(e){e.description("Authenticate with RightBrain").action(Ho);}async function Ho(){Q({canRunWithOptions:false});let e=me();if(e){let[b]=await p(async()=>await new UsersApi(N(e.access_token)).getCurrentUser().then(h=>h.data));if(b){let _=await m.confirm({message:`You are already logged in as ${j.cyan(b.email)}. Do you want to login again?`,initialValue:false});(m.isCancel(_)||!_)&&(m.outro("Login cancelled"),process.exit(0));}}let t=Zt(),r=await Gt(t),o=Jt(),n=Ht(o,r),i=Ut(),s=Dt(o,t,n),a=m.spinner();a.start("Press Enter to open browser for authentication...");let c=new Promise(b=>{let _=Ge(b);s.finally(_);});if((await Promise.race([c.then(()=>({type:"enter"})),s.then(()=>({type:"auth"}))])).type==="enter"){a.message("Opening browser for authentication...");let[,b]=await p(()=>Ye(i));b?m.log.warn(`Could not open browser automatically. Please open the URL manually.
|
|
448
|
+
${j.cyan(i)}`):a.message("Browser opened. Waiting for authentication...");}let l=await s;(!l.success||!l.token)&&(a.stop("Authentication failed"),m.cancel(`Error: Authentication failed: ${l.error||"Unknown error"}`),process.exit(1));let d=l.token.expires_in?Date.now()+l.token.expires_in*1e3:void 0;oe({access_token:l.token.access_token,refresh_token:l.token.refresh_token,expires_at:d,org_id:void 0,project_id:void 0}),a.stop(j.green("You're now logged in!"));let w=await pe({accessToken:l.token.access_token});oe({org_id:w.orgId,project_id:w.projectId}),m.outro(j.green("Selected organization and project"));}function Pr(e){e.description("Log out from RightBrain").option("-y, --yes","Skip confirmation prompt").action(Qo);}async function Qo(e){Q({canRunWithOptions:false});let t=me();if(!t){m.log.info("You are not logged in.");return}if(!e.yes){let[r]=await p(async()=>await new UsersApi(N(t.access_token)).getCurrentUser().then(n=>n.data));if(r){let o=await m.confirm({message:"Are you sure you want to log out?",initialValue:false});(m.isCancel(o)||!o)&&(m.outro("Logout cancelled"),process.exit(0));}}Kt(),m.log.success(j.green("Successfully logged out!"));}var rn=Pe.url(),$r=async(e,{providedInputNames:t,inputs:r,providedInputs:o})=>{if(t.indexOf(e.param_name)!==-1){r[e.param_name]=o[e.param_name],m.log.info(`${e.param_name}: ${j.cyan(o[e.param_name])}`);return}let i=await m.text({message:`${e.param_name} (${e.input_processor==="perplexity_search"?"Perplexity":"Text"}):`,placeholder:e.input_processor==="perplexity_search"?"e.g., Latest news about renewable energy":"e.g., Text that's contextually relevant to the task",validate:s=>{if(!s)return `${e.param_name} is required`}});m.isCancel(i)&&(m.outro("Run task cancelled"),process.exit(0)),r[e.param_name]=i;},jr={"":$r,perplexity_search:$r,url_fetcher:async(e,{providedInputNames:t,inputs:r,providedInputs:o})=>{if(t.indexOf(e.param_name)!==-1){r[e.param_name]=o[e.param_name],m.log.info(`${e.param_name}: ${j.cyan(o[e.param_name])}`);return}let i=await m.text({message:`${e.param_name} (Web crawler):`,placeholder:"e.g., https://docs.rightbrain.ai/llms-full.txt",validate:s=>{if(!s)return "URL is required";if(!rn.safeParse(s).success)return "Invalid URL format"}});m.isCancel(i)&&(m.outro("Run task cancelled"),process.exit(0)),r[e.param_name]=i;},document_content_extractor:async(e,{files:t,providedFileInputNames:r,providedFiles:o})=>{(!e.config||!("filename"in e.config)||typeof e.config.filename!="string")&&(m.outro(j.red(`ERROR: Unable to find input processor for ${e.param_name}`)),process.exit(1));let n=e.config.filename,i=r.indexOf(n);if(i!==-1){t.push(o[i]),m.log.info(`${e.param_name}: ${j.cyan(n)}`);return}let s=await m.text({message:`${e.param_name} (Document):`,placeholder:"path/to/document.pdf",validate:d=>{if(!d)return "File path is required";let w=Y(d);if(!re.existsSync(w))return "File not found"}});m.isCancel(s)&&(m.outro("Run task cancelled"),process.exit(0));let a=Y(s),c=re.readFileSync(a),l=(await fileTypeFromBuffer(c))?.mime||"application/octet-stream";t.push(new File([c],n,{type:l}));}};function nn(e){let t=e.indexOf("=");return t===-1?null:{key:e.slice(0,t),value:e.slice(t+1)}}function Mr(e){e.description("Run a task").option("-t, --task <id>","Task ID to run").option("-r, --revision <id>","Specific revision ID").option("-i, --input <name=value>","Input parameter (repeatable)",(t,r)=>(r.push(t),r),[]).option("-f, --file <name=path>","File to upload (repeatable)",(t,r)=>(r.push(t),r),[]).option("--image <path>","Image to attach (repeatable)",(t,r)=>(r.push(t),r),[]).option("-d, --direct","Run the task directly without fetching resources first. Recommended for production environments where inputs and files are already provided.").option("--use-fallback-model","Use fallback model for the task").action(sn);}var de=P();async function sn(e){de.start();let t=await T.fromAuthContext();de.stop();let r=await(e.direct||f?cn(e):an(e,t)),o=m.spinner();f?de.start():o.start("Running task...");let[n,i]=await p(()=>t.runTask({...r,useFallbackModel:e.useFallbackModel}));de.stop(),(f?console.error:o.stop)(i?"Failed to run task":"Task run successfully"),i&&(M(i),process.exit(1)),console.info(f?JSON.stringify(n,null,2):inspect(n,{depth:null,colors:true}));}function pt(e,t="name=value"){let r={};for(let o of e){let n=nn(o);n||((f?console.error:m.outro)(j.red(`Invalid input format: ${o}. Expected ${t}`)),process.exit(1)),r[n.key]=n.value;}return r}async function Sr(e){return await Promise.all(Object.entries(e).map(async([r,o])=>{let n=Y(o);re.existsSync(n)||((f?console.error:m.outro)(j.red(`Error: File not found: ${o}`)),process.exit(1));let i=re.readFileSync(n),a=(await fileTypeFromBuffer(i))?.mime||"application/octet-stream";return new File([i],r,{type:a})}))}async function Fr(e){return await Promise.all(e.map(async r=>{let o=Y(r);re.existsSync(o)||((f?console.error:m.outro)(j.red(`Error: File not found: ${r}`)),process.exit(1));let n=re.readFileSync(o),s=(await fileTypeFromBuffer(n))?.mime||"application/octet-stream",a=X.basename(o);return new File([n],a,{type:s})}))}async function an(e,t){if(!e.task){de.start();let[E,x]=await p(()=>t.listTasks());de.stop(),x&&(M(x),process.exit(1));let C=E;if((!C||C.length===0)&&((f?console.error:m.outro)(j.red("No tasks found in this project.")),(f?console.error:m.outro)("Create a task with `npx rightbrain create-task` command."),process.exit(1)),C.length===1)e.task=C[0].id,(f?console.error:m.log.info)(`Using task: ${j.cyan(C[0].name)}`);else {let D=await m.select({message:"Select a task to run",options:C.map(O=>({value:O.id,label:O.name,hint:O.id}))});m.isCancel(D)&&(m.outro("Run task cancelled"),process.exit(0)),e.task=D;}}de.start();let[r,o]=await p(()=>t.getTask(e.task));de.stop(),(o||!r)&&(M(o||new Error("Task not found")),process.exit(1));let n={...r,revisions:Qe(r.revisions||[])},i=n.revisions.length===1?n.revisions[0]:void 0;i||(e.revision?(i=n.revisions?.find(E=>E.id===e.revision||E.version===e.revision),i||((f?console.error:m.outro)(j.red(`Error: Revision ${e.revision} not found`)),process.exit(1))):(i=et(n),i?(f?console.error:m.log.info)("Using active revision"):((f?console.error:m.outro)(j.red("Error: No active revision found for this task. Please specify a revision ID.")),process.exit(1))));let s=i.input_params??[],a=i.input_processors??[],c=i.image_required??false,u=pt(e.input||[]),l=Object.keys(u),d=pt(e.file||[],"name=path"),w=Object.keys(d),b=await Sr(d),_={},h=[];for(let E of s){let x=a.find(D=>D.param_name===E)??{param_name:E,input_processor:""},C=jr[x.input_processor];C||((f?console.error:m.outro)(j.red(`ERROR: Unable to find input processor for ${x.param_name}`)),process.exit(1)),await C(x,{files:h,inputs:_,providedFileInputNames:w,providedFiles:b,providedInputNames:l,providedInputs:u});}let R=await Fr(e.image||[]);if(R.length>0&&!f&&m.log.info(`Image${R.length>1?"s":""}: ${j.cyan(R.map(E=>E.name).join(", "))}`),c&&R.length===0){let E=await m.text({message:"Image required - enter path:",placeholder:"path/to/image.jpg",validate:fe=>{if(!fe)return "Path is required";let Ue=Y(fe);if(!re.existsSync(Ue))return "File not found"}});m.isCancel(E)&&(m.outro("Run task cancelled"),process.exit(0));let x=Y(E),C=re.readFileSync(x),D=X.basename(x),te=(await fileTypeFromBuffer(C))?.mime||"application/octet-stream";R.push(new File([C],D,{type:te}));}return {taskId:n.id,revisionId:i.id,body:{task_input:_,task_files:[...R,...h]}}}async function cn(e){e.task||((f?console.error:m.outro)(j.red("Error: Task ID is required when running directly")),process.exit(1)),H(e.task)||((f?console.error:m.outro)(j.red("Error: Task ID must be a valid UUID when running directly")),process.exit(1)),e.revision&&!H(e.revision)&&((f?console.error:m.outro)(j.red("Error: Revision must be a valid UUID when running directly")),process.exit(1));let t=await Fr(e.image||[]),r=await Sr(pt(e.file||[],"name=path"));return {body:{task_input:pt(e.input||[]),task_files:[...t,...r]},taskId:e.task,revisionId:e.revision}}function Rr(e){e.description("Switch to a different organization and project").option("--org-id <orgId>","Organization ID to switch to").option("--project-id <projectId>","Project ID to switch to").action(ln);}var dt=P();async function ln(e){Q();let t=await V();t.filePath&&m.log.info(j.yellow(`\u26A0\uFE0F This command is for updating the global project/organization context used by the CLI.
|
|
449
|
+
`)+" If you want to switch projects inside a specific project/config-based setup, please update the orgId and projectId values in your configuration file directly."),(e.orgId||e.projectId)&&(e.orgId||(m.cancel("Organization ID (--org-id) is required when specifying a project ID (--project-id)"),process.exit(1)),e.projectId||(m.cancel("Project ID (--project-id) is required when specifying an organization ID (--org-id)"),process.exit(1)));let r;if(e.orgId||e.projectId){dt.start();let i=e.orgId,s=e.projectId,a=new T({accessToken:t.accessToken,orgId:i,projectId:s}),[c,u]=await p(()=>a.getOrganization(i));(u||!c)&&(M(u||new Error("Organization not found")),process.exit(1)),dt.stop(),m.log.info(`\u2713 Organization access confirmed: ${j.cyan(c.name||i)}`),dt.start();let[l,d]=await p(()=>a.getProject(i,s));(d||!l)&&(M(d||new Error("Project not found")),process.exit(1)),dt.stop(),m.log.info(`\u2713 Project access confirmed: ${j.cyan(l.name||s)}`),r={orgId:i,projectId:s},m.log.success(`Switched to organization: ${j.cyan(c.name||i)}, project: ${j.cyan(l.name||s)}`);}else r=await pe({...await V({loadGlobalConfig:true}),orgId:void 0,projectId:void 0}),m.log.success("Switched successfully");let{orgId:o,projectId:n}=r;oe({org_id:o,project_id:n});}function Ur(e){e.description("Display current user information and selected organization/project").action(dn);}var ye=P();async function dn(){let e=await V();if(e.filePath){if(e.orgId&&e.projectId){ye.start();let o=await T.fromConfig(),[n]=await p(async()=>o.getOrganization(e.orgId)),[i]=await p(async()=>o.getProject(e.orgId,e.projectId));ye.stop(),m.log.info(j.bold("Selected Organization & Project:")),m.log.info(` Organization: ${j.cyan(n?.name||e.orgId)}`),m.log.info(` Project: ${j.cyan(i?.name||e.projectId)}`);}process.exit(0);}ye.start();let[t,r]=await p(async()=>await new UsersApi(N(e.accessToken)).getCurrentUser().then(n=>n.data));if((r||!t)&&(ye.stop(),m.cancel("Failed to get user information. Please login again."),process.exit(1)),ye.stop(),m.log.info(j.bold("User Information:")),m.log.info(` Email: ${j.cyan(t.email||"N/A")}`),t.name&&m.log.info(` Name: ${j.cyan(t.name)}`),t.id&&m.log.info(` ID: ${j.cyan(t.id)}`),m.log.info(j.bold("Selected Organization & Project:")),e.orgId&&e.projectId){ye.start();let o=await T.fromAuthContext(),[n]=await p(async()=>o.getOrganization(e.orgId)),[i]=await p(async()=>o.getProject(e.orgId,e.projectId));ye.stop(),m.log.info(` Organization: ${j.cyan(n?.name||e.orgId)}`),m.log.info(` Project: ${j.cyan(i?.name||e.projectId)}`);}else m.log.warn(j.yellow(" No organization and project selected")),m.log.info(" Run `npx rightbrain switch-project` command to select an organization and project");}async function un(){let[,e]=p(()=>{let t=new Command;t.name(Object.keys(_e.bin)[0]).description(_e.description).version(_e.version).option("--config <path>","Path to configuration file").hook("preAction",r=>{(f?console.error:m.intro)(j.dim(`RightBrain CLI ${_e.version}`));let o=r.opts();if(o.config&&Nt(o.config),r.args?.[0]!=="init"){let n=je();n&&(f?console.error:m.log.info)(j.dim(`Using configuration file: ${n.filePath}`));}}),_r(t.command("login")),Pr(t.command("logout")),Er(t.command("init")),Rr(t.command("switch-project")),Ur(t.command("whoami")),sr(t.command("create-task")),Mr(t.command("run-task")),Tr(t.command("list-models")),hr(t.command("generate")),t.parse(process.argv);});e&&(e instanceof Error?console.error("Error:",e.message):console.error("Unknown error occurred"),process.exit(1));}un().catch(console.error);
|