@ciandt-flow/cli 2.2.0-beta.235 → 2.2.0-beta.238
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 +119 -119
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {execa}from'execa';import
|
|
3
|
-
`;try{
|
|
4
|
-
`);}formatTui(t){return `[flow:${t.module}] ${t.message}`}formatCli(t){let r=String(t.timestamp.getHours()).padStart(2,"0"),n=String(t.timestamp.getMinutes()).padStart(2,"0"),o=String(t.timestamp.getSeconds()).padStart(2,"0");return `[${r}:${n}:${o}] [${t.level.toUpperCase()}] ${t.message}`}};var
|
|
5
|
-
`);}};var
|
|
6
|
-
`));}function
|
|
7
|
-
`));}function
|
|
8
|
-
`));}function
|
|
2
|
+
import {execa}from'execa';import dc,{HTTPError}from'ky';import {Box,Text,render,useWindowSize,useInput,useApp}from'ink';import Cf,{useRef,useCallback,useMemo,useEffect,useState}from'react';import {create}from'zustand';import*as Dr from'crypto';import {randomUUID,createHash}from'crypto';import*as he from'fs';import he__default,{readFileSync,mkdirSync,existsSync,realpathSync}from'fs';import*as ge from'path';import ge__default,{join,dirname,basename,normalize,resolve,sep,relative,isAbsolute}from'path';import*as be from'os';import be__default,{tmpdir,homedir}from'os';import {execFile,exec,spawnSync,spawn}from'child_process';import {promisify}from'util';import*as ji from'readline';import {createInterface}from'readline';import R from'chalk';import si from'conf';import {StatusCodes}from'http-status-codes';import {jsxs,jsx,Fragment}from'react/jsx-runtime';import sf from'jsonwebtoken';import gf from'ink-big-text';import iu from'ink-spinner';import*as wt from'fs/promises';import {readFile,mkdir,writeFile,rename,stat,rm,mkdtemp,readdir,cp as cp$1}from'fs/promises';import lg from'proper-lockfile';import xg from'extract-zip';import {simpleGit}from'simple-git';import ea from'semver';import Aa from'yocto-spinner';import {Command,Option}from'commander';import {parse}from'yaml';var em=Object.defineProperty;var Ks=(e,t)=>()=>(e&&(t=e(e=0)),t);var tm=(e,t)=>{for(var r in t)em(e,r,{get:t[r],enumerable:true});};function Dm(e){if(!e.startsWith("[")||!e.endsWith("]"))return null;let r=e.slice(1,-1).match(/^::(?:ffff:)?([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);if(!r)return null;let n=parseInt(r[1],16),o=parseInt(r[2],16);return `${n>>8&255}.${n&255}.${o>>8&255}.${o&255}`}function di(e){if(il.some(r=>r.test(e)))return true;let t=Dm(e);return !!(t&&il.some(r=>r.test(t)))}function Om(e,t){let r=process.env[e]??t;if(!r)throw new Error(`Missing required environment variable: ${e}`);return r}function jr(e,t){let r=Om(e,t),n;try{n=new URL(r);}catch{throw new Error(`${e} must be a valid URL. Got: "${r}"`)}let o=process.env.NODE_ENV==="development";if(!o&&n.protocol!=="https:")throw new Error(`${e} must be an HTTPS URL. Got protocol: "${n.protocol}"`);if(n.username||n.password)throw new Error(`${e} must not contain embedded credentials (user:pass@host is not allowed)`);if(!o&&di(n.hostname))throw new Error(`${e} must not point to a private/loopback address. Got: "${n.hostname}"`);return r}var il,vn=Ks(()=>{il=[/^localhost\.?$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^100\.(6[4-9]|[7-9]\d|1[0-2][0-7])\./,/^::1$/,/^\[::1\]$/,/^\[::ffff:/i,/^0\.0\.0\.0$/,/^\[f[cd]/i,/^\[fe80:/i,/^metadata\.google\.internal\.?$/i,/^metadata\.azure\.internal\.?$/i];});function hg(){let e=process.env.GH_TOKEN??process.env.GITHUB_TOKEN;return e?Promise.resolve(e):execa("gh",["auth","token"],{reject:false}).then(({stdout:t})=>t.trim()||void 0).catch(()=>{})}function cc(){return lc??=hg(),lc}var lc,uc=Ks(()=>{});var mc={};tm(mc,{GitRepoAdapter:()=>zr});function pc(e,t){if(!Sg.test(e))throw new Error(`Invalid ${t} in catalog source URL: "${e}"`)}var Sg,zr,Ai=Ks(()=>{uc();vn();Sg=/^[a-zA-Z0-9_.-]+$/;zr=class{id;name;source;constructor(t,r,n){this.id=t,this.name=r,this.source=n;}buildRawUrl(t,r="marketplace.json"){let n=new URL(this.source),{hostname:o,pathname:s}=n;if(di(o))throw new Error(`Catalog source URL points to a private/loopback address: "${o}"`);let i=s.replace(/^\//,"").split("/"),[a,l]=i;return pc(a,"owner"),pc(l,"repo"),o==="github.com"?`https://raw.githubusercontent.com/${a}/${l}/${t}/${r}`:o==="bitbucket.org"?`https://bitbucket.org/${a}/${l}/raw/${t}/${r}`:o==="gitlab.com"||o.startsWith("git.")?`https://${o}/${a}/${l}/-/raw/${t}/${r}`:`https://${o}/${a}/${l}/raw/${t}/${r}`}async fetchItems(){return this._fetchFromBranch("main").catch(t=>{if(this._is404(t))return this._fetchFromBranch("master");throw t})}async _fetchFromBranch(t){let r=await this._buildHeaders();try{let s=this.buildRawUrl(t,".claude-plugin/marketplace.json"),{plugins:i}=await dc.get(s,{headers:r}).json();return i.map(a=>({...a,catalogId:this.id,origin:a.origin??"external"}))}catch(s){if(this._is401or403(s))throw this._authError();if(!this._is404(s))throw s}let n=this.buildRawUrl(t),{plugins:o}=await dc.get(n,{headers:r}).json();return o.map(s=>({...s,catalogId:this.id,origin:s.origin??"external"}))}async _buildHeaders(){if(new URL(this.source).hostname!=="github.com")return {};let r=await cc();return r?{Authorization:`token ${r}`}:{}}_is404(t){return t!==null&&typeof t=="object"&&"response"in t&&t.response?.status===404}_is401or403(t){return t!==null&&typeof t=="object"&&"response"in t&&[401,403].includes(t.response?.status??0)}_authError(){return Object.assign(new Error("Private repository or insufficient permissions. Set GH_TOKEN or GITHUB_TOKEN env var, or run `gh auth login`."),{code:"GITHUB_AUTH_REQUIRED"})}async fetchManifest(t){throw new Error("GitRepoAdapter does not support individual manifest fetch")}async ping(){try{return await this.fetchItems(),!0}catch{return false}}};});var oo="FLOW",re="flow-skills",Vs="flow-cli",yn="internal",Rr="external",_r={skill:{label:"Skill",color:"cyan"},mcp:{label:"MCP",color:"yellow"},bundle:{label:"Bundle",color:"green"},agent:{label:"Agent",color:"green"},hook:{label:"Hook",color:"blue"}},Ua={internal:{label:"Flow",color:"blue"},external:{label:"External",color:"white"}},Hs=new Set(["internal","external"]),hn={user:{label:"Global",pathHint:"~/.claude/",actionLabel:"Global (~/.claude)",description:"available in all projects on this machine"},project:{label:"Project",pathHint:".claude/ (shared)",actionLabel:"Project (.claude/)",description:"shared with the team via version control"},local:{label:"Local",pathHint:".claude/ (local only)",actionLabel:"Local (.claude/)",description:"only on your machine, not committed"}},ie="flow-claude-md-setup",Je=5,ur=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;var Fa=new Set(["skill","mcp","bundle"]),S=create(e=>({screen:"auth",activeTab:"discover",focus:"list",selectedIndex:0,actionMenuOpen:false,notification:null,loading:false,loadingMessage:"",catalogError:null,pendingExit:false,debugPanelOpen:false,catalogVersion:0,bundleInstallFlow:null,catalogFilters:{types:new Set(Fa),origins:new Set(Hs)},setScreen:t=>e({screen:t}),setActiveTab:t=>e({activeTab:t}),setFocus:t=>e({focus:t}),setSelectedIndex:t=>e({selectedIndex:t}),setActionMenuOpen:t=>e({actionMenuOpen:t}),showNotification:(t,r)=>e({notification:{message:t,type:r}}),clearNotification:()=>e({notification:null}),setLoading:(t,r="")=>e({loading:t,loadingMessage:t?r:""}),setCatalogError:t=>e({catalogError:t}),setPendingExit:t=>e({pendingExit:t}),toggleTypeFilter:t=>e(r=>{let{types:n}=r.catalogFilters;return n.size===1&&n.has(t)?{}:{catalogFilters:{...r.catalogFilters,types:new Set([t])},selectedIndex:0}}),selectAllTypes:()=>e(t=>({catalogFilters:{...t.catalogFilters,types:new Set(Fa)},selectedIndex:0})),toggleOriginFilter:t=>e(r=>{let{origins:n}=r.catalogFilters;return n.size===1&&n.has(t)?{}:{catalogFilters:{...r.catalogFilters,origins:new Set([t])},selectedIndex:0}}),selectAllOrigins:()=>e(t=>({catalogFilters:{...t.catalogFilters,origins:new Set(Hs)},selectedIndex:0})),setDebugPanelOpen:t=>e({debugPanelOpen:t}),incrementCatalogVersion:()=>e(t=>({catalogVersion:t.catalogVersion+1})),setBundleInstallFlow:t=>e({bundleInstallFlow:t})}));var so="aes-256-gcm",nm=16,ja=16,Sn=class{key;constructor(t){if(t.length!==32)throw new Error(`Invalid key length: expected 32 bytes, got ${t.length}`);this.key=t;}encrypt(t){let r=Dr.randomBytes(nm),n=Dr.createCipheriv(so,this.key,r,{authTagLength:ja}),o=Buffer.concat([n.update(t,"utf8"),n.final()]),s=n.getAuthTag();return {iv:r.toString("hex"),authTag:s.toString("hex"),ciphertext:o.toString("hex"),algorithm:so}}decrypt(t){if(t.algorithm!==so)throw new Error(`Unsupported encryption algorithm: ${t.algorithm}`);let r=Dr.createDecipheriv(so,this.key,Buffer.from(t.iv,"hex"),{authTagLength:ja});return r.setAuthTag(Buffer.from(t.authTag,"hex")),Buffer.concat([r.update(Buffer.from(t.ciphertext,"hex")),r.final()]).toString("utf8")}};var om=/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,sm=/eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,im=/[A-Za-z0-9+/]{40,}={0,2}/g;function Js(e){return e.replace(om,"Bearer ***").replace(sm,"***").replace(im,"***")}var dr=".claude",io=".flow";function Ka(e,t){return Ws(re,e,t)}function Gs(e){return ge.join(be.homedir(),dr,"plugins","marketplaces",re,"plugins","native",e)}function ao(){return ge.join(be.homedir(),dr,"plugins","marketplaces",re,".claude-plugin","marketplace.json")}function lo(){return ge.join(be.homedir(),dr,"plugins","known_marketplaces.json")}function Va(){return ge.join(be.homedir(),dr,"plugins","marketplaces",re)}function Ha(){return ge.join(be.homedir(),io,"cache","install.lock")}function Ja(){return ge.join(be.homedir(),io,"logs","flowsetup.log")}function Ws(e,t,r){return ge.join(be.homedir(),dr,"plugins","cache",e,t,r)}function pr(e){let t=e==="global"?be.homedir():process.cwd();return ge.join(t,".claude","skills")}function wn(e){let t=e==="global"?be.homedir():process.cwd();return ge.join(t,".claude","skills-lock.json")}function co(e="user"){return e==="project"?ge.join(process.cwd(),".opencode","plugins"):ge.join(be.homedir(),".config","opencode","plugins")}function Ga(){return ge.join(be.homedir(),io,"flow-catalogs.json")}function Wa(){let e=process.env.FLOW_HOME??ge.join(be.homedir(),io);return ge.join(e,"config.json")}function uo(e="user"){return e==="project"||e==="local"?ge.join(process.cwd(),dr,"agents"):ge.join(be.homedir(),dr,"agents")}var am=5*1024*1024,lm=3,po=class{filePath;constructor(){this.filePath=Ja(),this.ensureDir(),this.rotateIfNeeded();}write(t){let r=`[${t.timestamp.toISOString()}] [${t.level.toUpperCase()}] [${t.module}] ${t.message}
|
|
3
|
+
`;try{he.appendFileSync(this.filePath,r,"utf-8");}catch{}}ensureDir(){try{let t=ge.dirname(this.filePath);he.mkdirSync(t,{recursive:!0});}catch{}}rotateIfNeeded(){try{if(he.statSync(this.filePath).size>am){let r=new Date().toISOString().replace(/[:.]/g,"-"),n=this.filePath.replace(".log",`-${r}.log`);he.renameSync(this.filePath,n),this.cleanOldBackups();}}catch{}}cleanOldBackups(){try{let t=ge.dirname(this.filePath),r=ge.basename(this.filePath,".log"),n=he.readdirSync(t).filter(o=>o.startsWith(r+"-")&&o.endsWith(".log")).sort().reverse();for(let o of n.slice(lm))he.unlinkSync(ge.join(t,o));}catch{}}};var mo=class{context;constructor(t){this.context=t;}write(t){let r=this.context==="tui"?this.formatTui(t):this.formatCli(t);process.stderr.write(r+`
|
|
4
|
+
`);}formatTui(t){return `[flow:${t.module}] ${t.message}`}formatCli(t){let r=String(t.timestamp.getHours()).padStart(2,"0"),n=String(t.timestamp.getMinutes()).padStart(2,"0"),o=String(t.timestamp.getSeconds()).padStart(2,"0");return `[${r}:${n}:${o}] [${t.level.toUpperCase()}] ${t.message}`}};var fo=class{write(t){process.stdout.write(t.message+`
|
|
5
|
+
`);}};var go=[],zs=new Set;function Xs(){return go}function za(e){return zs.add(e),()=>{zs.delete(e);}}var yo=class{write(t){go.push(t),go.length>100&&go.shift();for(let r of zs)r();}};var Or={debug:0,info:1,warn:2,error:3},fr={context:"cli",transports:[],minLevel:"warn",debugModules:null};function cm(){let e=process.env.DEBUG;if(!e)return null;let t=e.split(",").map(n=>n.trim()).filter(Boolean);for(let n of t)if(n==="flow:*")return "all";let r=new Set;for(let n of t)n.startsWith("flow:")&&r.add(n.slice(5));return r.size>0?r:null}function De(e,t){if(e==="tui"){let r=cm();fr={context:e,transports:[new yo,new po],minLevel:r?"debug":"warn",debugModules:r};}else t?.silent?fr={context:e,transports:[],minLevel:"error",debugModules:null}:t?.verbose?fr={context:e,transports:[new mo("cli")],minLevel:"debug",debugModules:null}:fr={context:e,transports:[new fo],minLevel:"info",debugModules:null};}function Xa(){return fr.transports}function qa(e,t){let{debugModules:r,minLevel:n}=fr;return fr.context==="tui"&&r&&r!=="all"?r.has(t)?Or[e]>=Or.debug:Or[e]>=Or.warn:Or[e]>=Or[n]}var Ya=new Map;function ho(e,t,r){if(!qa(e,t))return;let n={level:e,module:t,message:Js(r),timestamp:new Date};for(let o of Xa())o.write(n);}function I(e){let t=Ya.get(e);if(t)return t;let r={debug:n=>ho("debug",e,n),info:n=>ho("info",e,n),warn:n=>ho("warn",e,n),error:n=>ho("error",e,n)};return Ya.set(e,r),r}var qs=I("encryption"),Ys="__encrypted__";function um(e){return typeof e=="object"&&e!==null&&Ys in e&&e[Ys]===true}function Zs(e){return {serialize(t){let r=JSON.stringify(t),n=e.encrypt(r),o={[Ys]:true,envelope:n};return JSON.stringify(o,null," ")},deserialize(t){let r;try{r=JSON.parse(t);}catch{return qs.warn("[encryption] Config file contains unparseable data, treating as empty"),{}}if(um(r))try{let n=e.decrypt(r.envelope);return JSON.parse(n)}catch(n){return qs.error(`[encryption] Decryption failed: ${n instanceof Error?n.message:"unknown error"}. Config will be treated as empty. Re-authentication may be required.`),{}}return qs.info("[encryption] Detected plaintext config \u2014 will encrypt on next write"),r}}}var Qs=promisify(execFile),mm=promisify(exec),at=I("encryption:macos-keyvault"),Nr=class{static async isAvailable(){try{let{stdout:t}=await mm("command -v security");return at.debug(`security binary found at: ${t.trim()}`),!0}catch{return at.debug("security binary not found in PATH"),false}}async getSecret(t,r){try{at.debug(`Looking up secret: service=${t}, account=${r}`);let{stdout:n}=await Qs("security",["find-generic-password","-w","-a",r,"-s",t]),o=n.trim();return at.debug(`security find-generic-password result: ${o?"found":"empty"}`),o||null}catch(n){let o=n;return at.debug(`security find-generic-password failed: code=${o.code}, stderr=${o.stderr?.trim()}, message=${o.message}`),null}}async setSecret(t,r,n){try{at.debug(`Storing secret: service=${t}, account=${r}`),await Qs("security",["add-generic-password","-U","-a",r,"-s",t,"-w",n]),at.debug("security add-generic-password succeeded");}catch(o){let s=o;throw at.error(`security add-generic-password failed: code=${s.code}, stderr=${s.stderr?.trim()}, message=${s.message}`),o}}async deleteSecret(t,r){try{return at.debug(`Deleting secret: service=${t}, account=${r}`),await Qs("security",["delete-generic-password","-a",r,"-s",t]),at.debug("security delete-generic-password succeeded"),!0}catch(n){let o=n;return at.debug(`security delete-generic-password failed: code=${o.code}, stderr=${o.stderr?.trim()}, message=${o.message}`),false}}getStoragePath(){return "macOS Keychain (security)"}};function h(e){return e==null?"":e.replace(/\x1b\[[0-9;:<=>?]*[ -/]*[@-~]/g,"").replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,"").replace(/\x1b./g,"").replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g,"")}function ne(e){process.stdout.write(R.green(` \u2713 ${h(e)}
|
|
6
|
+
`));}function P(e){process.stderr.write(R.red(` \u2717 ${h(e)}
|
|
7
|
+
`));}function C(e){process.stdout.write(R.cyan(` \u2139 ${h(e)}
|
|
8
|
+
`));}function Br(e,t){let r=t.map(a=>a.map(h)),n=[e,...r],o=e.map((a,l)=>Math.max(...n.map(u=>(u[l]??"").length))),s=o.map(a=>"\u2500".repeat(a)).join(" "),i=a=>a.map((l,u)=>l.padEnd(o[u])).join(" ");process.stdout.write(`
|
|
9
9
|
`),process.stdout.write(` ${R.bold(i(e))}
|
|
10
10
|
`),process.stdout.write(` ${R.dim(s)}
|
|
11
11
|
`);for(let a of r)process.stdout.write(` ${i(a)}
|
|
12
12
|
`);process.stdout.write(`
|
|
13
|
-
`);}function
|
|
14
|
-
`);}function
|
|
15
|
-
`);}function
|
|
16
|
-
`);}function Q(e){return e instanceof Error?e.message:String(e)}function
|
|
13
|
+
`);}function Ur(e){process.stdout.write(JSON.stringify(e,null,2)+`
|
|
14
|
+
`);}function Oe(e){process.stdout.write(JSON.stringify(e)+`
|
|
15
|
+
`);}function We(e){process.stderr.write(JSON.stringify(e)+`
|
|
16
|
+
`);}function Q(e){return e instanceof Error?e.message:String(e)}function Wt(e){let t=new Date(e);return isNaN(t.getTime())?"\u2014":new Intl.DateTimeFormat("en-US",{dateStyle:"short"}).format(t)}var ei=promisify(execFile),ti=promisify(exec),hm=[{name:"apt",command:"sudo apt install -y libsecret-tools"},{name:"dnf",command:"sudo dnf install -y libsecret"},{name:"pacman",command:"sudo pacman -S --noconfirm libsecret"},{name:"apk",command:"sudo apk add libsecret-tools"},{name:"zypper",command:"sudo zypper install -y libsecret-tools"}],z=I("encryption:linux-keyvault");async function Sm(e,t){let r=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0,o=setInterval(()=>{process.stderr.write(`\r${r[n++%r.length]} ${e}`);},80);try{return await t()}finally{clearInterval(o),process.stderr.write("\r\x1B[2K");}}function wm(e){let t=ji.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(h(e),n=>{t.close(),r(n.trim().toLowerCase());});})}var zt=class e{static async isAvailable(){try{let{stdout:t}=await ti("command -v secret-tool");z.debug(`secret-tool found at: ${t.trim()}`);}catch{return z.debug("secret-tool binary not found in PATH"),false}try{return await ei("secret-tool",["lookup","service","__flow_connectivity_check__"]),z.debug("Secret Service D-Bus connectivity check passed"),!0}catch(t){let n=t.stderr?.trim()??"";return n.includes("org.freedesktop.secrets")?(z.debug(`Secret Service D-Bus not available: ${n}`),false):(z.debug("secret-tool is available and D-Bus service is reachable"),true)}}static async detectPackageManager(){for(let t of hm)try{return await ti(`command -v ${t.name}`),t}catch{}return null}static async ensureInstalled(){if(await e.isAvailable())return true;z.info("Secure credential storage requires 'secret-tool' (libsecret). This tool allows us to store your encryption key in the OS keyring, so your credentials are protected even if someone copies the config file.");let t=await e.detectPackageManager();if(!t)return z.warn("Could not detect a supported package manager. Please install libsecret manually."),false;let r=await wm(" ? Install secret-tool? This requires sudo. (y/N) ");if(r!=="y"&&r!=="yes")return false;try{return z.info(`Running: ${t.command}`),await Sm("Installing secret-tool...",()=>ti(t.command)),e.isAvailable()}catch{return z.warn("Installation failed. Falling back to derived key."),false}}async getSecret(t,r){try{z.debug(`Looking up secret: service=${t}, account=${r}`);let{stdout:n}=await ei("secret-tool",["lookup","service",t,"account",r]),o=n.trim();return z.debug(`secret-tool lookup result: ${o?"found":"empty"}`),o||null}catch(n){let o=n;return z.debug(`secret-tool lookup failed: code=${o.code}, stderr=${o.stderr?.trim()}, message=${o.message}`),null}}async setSecret(t,r,n){z.debug(`Storing secret: service=${t}, account=${r}`),z.debug(`Environment: DBUS_SESSION_BUS_ADDRESS=${process.env.DBUS_SESSION_BUS_ADDRESS??"NOT SET"}`),z.debug(`Environment: DISPLAY=${process.env.DISPLAY??"NOT SET"}, WAYLAND_DISPLAY=${process.env.WAYLAND_DISPLAY??"NOT SET"}`),z.debug(`Environment: WSL_DISTRO_NAME=${process.env.WSL_DISTRO_NAME??"NOT SET"}`),await new Promise((o,s)=>{let i=spawn("secret-tool",["store","--label",t,"service",t,"account",r]),a="";i.stderr.on("data",l=>{a+=l.toString();}),i.stdin.end(n,"utf8"),i.on("close",l=>{l===0?(z.debug("secret-tool store succeeded"),o()):(z.error(`secret-tool store failed: code=${l}, stderr=${a.trim()}`),s(new Error(`secret-tool exited with code ${l}${a?`: ${a.trim()}`:""}`)));}),i.on("error",l=>{z.error(`secret-tool store spawn error: ${l.message}`),s(l);});});}async deleteSecret(t,r){try{return z.debug(`Deleting secret: service=${t}, account=${r}`),await ei("secret-tool",["clear","service",t,"account",r]),z.debug("secret-tool clear succeeded"),!0}catch(n){let o=n;return z.debug(`secret-tool clear failed: code=${o.code}, stderr=${o.stderr?.trim()}, message=${o.message}`),false}}getStoragePath(){return "Linux Secret Service (secret-tool)"}};var vm=promisify(execFile),lt=I("encryption:windows-keyvault"),ri=1,bm=1,Pm=2,Em=3;function ni(e,t){return `${e}:${t}`}var oi=`
|
|
17
17
|
using System;
|
|
18
18
|
using System.Runtime.InteropServices;
|
|
19
19
|
using System.Text;
|
|
@@ -49,7 +49,7 @@ public class FlowCredManager {
|
|
|
49
49
|
|
|
50
50
|
public static string Read(string target) {
|
|
51
51
|
IntPtr credPtr;
|
|
52
|
-
if (!CredRead(target, ${
|
|
52
|
+
if (!CredRead(target, ${ri}, 0, out credPtr)) return "";
|
|
53
53
|
try {
|
|
54
54
|
var cred = (CREDENTIAL)Marshal.PtrToStructure(credPtr, typeof(CREDENTIAL));
|
|
55
55
|
if (cred.CredentialBlobSize <= 0) return "";
|
|
@@ -63,7 +63,7 @@ public class FlowCredManager {
|
|
|
63
63
|
byte[] bytes = Encoding.UTF8.GetBytes(secret);
|
|
64
64
|
IntPtr targetPtr = Marshal.StringToHGlobalUni(target);
|
|
65
65
|
IntPtr userPtr = Marshal.StringToHGlobalUni(userName);
|
|
66
|
-
int[] persistLevels = new int[] { ${
|
|
66
|
+
int[] persistLevels = new int[] { ${Pm}, ${Em}, ${bm} };
|
|
67
67
|
int lastErr = 0;
|
|
68
68
|
try {
|
|
69
69
|
foreach (int persist in persistLevels) {
|
|
@@ -71,7 +71,7 @@ public class FlowCredManager {
|
|
|
71
71
|
try {
|
|
72
72
|
Marshal.Copy(bytes, 0, blobPtr, bytes.Length);
|
|
73
73
|
var cred = new CREDENTIAL();
|
|
74
|
-
cred.Type = ${
|
|
74
|
+
cred.Type = ${ri};
|
|
75
75
|
cred.TargetName = targetPtr;
|
|
76
76
|
cred.CredentialBlobSize = bytes.Length;
|
|
77
77
|
cred.CredentialBlob = blobPtr;
|
|
@@ -89,146 +89,146 @@ public class FlowCredManager {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
public static bool Delete(string target) {
|
|
92
|
-
return CredDelete(target, ${
|
|
92
|
+
return CredDelete(target, ${ri}, 0);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
`;function
|
|
96
|
-
${
|
|
95
|
+
`;function In(e){return e.replace(/'/g,"''")}function So(e){return ["-NoProfile","-NonInteractive","-Command",e]}function Cm(e){return `Add-Type -TypeDefinition @'
|
|
96
|
+
${oi}
|
|
97
97
|
'@
|
|
98
|
-
[FlowCredManager]::Read('${
|
|
99
|
-
${
|
|
98
|
+
[FlowCredManager]::Read('${In(e)}')`}function Tm(e,t,r){return `Add-Type -TypeDefinition @'
|
|
99
|
+
${oi}
|
|
100
100
|
'@
|
|
101
|
-
[FlowCredManager]::Write('${
|
|
102
|
-
${
|
|
101
|
+
[FlowCredManager]::Write('${In(e)}', '${In(t)}', '${In(r)}')`}function km(e){return `Add-Type -TypeDefinition @'
|
|
102
|
+
${oi}
|
|
103
103
|
'@
|
|
104
|
-
[FlowCredManager]::Delete('${
|
|
105
|
-
`)[0]:"unknown error";return
|
|
106
|
-
`)[0]:"unknown error";return
|
|
107
|
-
`)[0]:"unknown error",i=`Failed to store secret in Windows Credential Manager [service="${t}", account="${r}"]: ${s}`;throw
|
|
108
|
-
`)[0]:"unknown error";return
|
|
104
|
+
[FlowCredManager]::Delete('${In(e)}')`}async function wo(e){return vm("powershell.exe",e)}var Fr=class{static async isAvailable(){try{let{stdout:t}=await wo(So('Write-Output "ok"')),r=t.trim()==="ok";return lt.debug(`PowerShell availability check: ${r?"available":"unexpected output"}`),r}catch(t){let r=t instanceof Error?t.message.split(`
|
|
105
|
+
`)[0]:"unknown error";return lt.debug(`PowerShell not available: ${r}`),false}}async getSecret(t,r){try{let n=ni(t,r);lt.debug(`Looking up secret: target=${n}`);let o=Cm(n),{stdout:s}=await wo(So(o)),i=s.trim();return lt.debug(`CredRead result: ${i?"found":"empty"}`),i||null}catch(n){let o=n instanceof Error?n.message.split(`
|
|
106
|
+
`)[0]:"unknown error";return lt.error(`Failed to read secret from Windows Credential Manager [service="${t}", account="${r}"]: ${o}`),null}}async setSecret(t,r,n){try{let o=ni(t,r);lt.debug(`Storing secret: target=${o}`);let s=Tm(o,n,r),{stdout:i}=await wo(So(s)),a=i.trim();if(a.startsWith("OK:")){let u=a.split(":")[1];lt.debug(`CredWrite succeeded (persist=${u})`);return}let l=a.startsWith("ERR:")?a.split(":")[1]:"unknown";throw new Error(`CredWrite failed with Win32 error ${l}`)}catch(o){let s=o instanceof Error?o.message.split(`
|
|
107
|
+
`)[0]:"unknown error",i=`Failed to store secret in Windows Credential Manager [service="${t}", account="${r}"]: ${s}`;throw lt.error(i),new Error(i)}}async deleteSecret(t,r){try{let n=ni(t,r);lt.debug(`Deleting secret: target=${n}`);let o=km(n),{stdout:s}=await wo(So(o)),i=s.trim()==="True";return lt.debug(`CredDelete result: ${i}`),i}catch(n){let o=n instanceof Error?n.message.split(`
|
|
108
|
+
`)[0]:"unknown error";return lt.debug(`Failed to delete secret from Windows Credential Manager [service="${t}", account="${r}"]: ${o}`),false}}getStoragePath(){return "Windows Credential Manager (PowerShell)"}};var Am=32,$m="flow-plugins-cli-fallback",ii="flow-plugins-cli-fallback",Mm={linux:"install secret-tool (e.g. sudo apt install libsecret-tools)",darwin:"ensure the Keychain is accessible (security binary must be available)",win32:"ensure Credential Manager is available (cmdkey must be in PATH)"};function Lm(){let e=`${be.hostname()}${be.userInfo().username}`;return Dr.scryptSync(e,$m,Am)}function Rm(){let e=Lm(),t=new Sn(e),r=Zs(t);return new si({projectName:ii,serialize:r.serialize,deserialize:r.deserialize,configFileMode:384})}var Io=null;function xo(){return Io||(Io=Rm()),Io}var Ne=class{warned=false;async getSecret(t,r){return xo().get(`${t}:${r}`)??null}async setSecret(t,r,n){if(!this.warned){let o=Mm[process.platform]??"ensure the OS keyring is available";process.stderr.write(`\u26A0 Secure keyring unavailable. Credentials are stored in an encrypted file
|
|
109
109
|
using a machine-derived key. For stronger security, ${o}.
|
|
110
|
-
`),this.warned=true;}ho().set(`${t}:${r}`,n);}async deleteSecret(t,r){let n=ho(),o=`${t}:${r}`;return n.has(o)?(n.delete(o),true):false}getStoragePath(){return ho().path}static hasExistingData(){try{let t=new ti({projectName:ri});return be.existsSync(t.path)}catch{return false}}static clearFallbackFile(){try{let t=new ti({projectName:ri});be.rmSync(t.path,{force:!0});}catch{}yo=null;}};async function ni(){if(De.hasExistingData())return new De;switch(process.platform){case "darwin":return await Lr.isAvailable()?new Lr:new De;case "linux":return await Kt.isAvailable()?new Kt:await Kt.ensureInstalled()?new Kt:new De;case "win32":return await Dr.isAvailable()?new Dr:new De;default:throw new Error(`Unsupported platform: ${process.platform}`)}}var $m=I("config:credentials"),Pt="flow-plugins-cli",oi="credentials",si="token-cache",ii="user-info",xo=null;async function Vt(){return xo||(xo=ni()),xo}function Io(){xo=null;}async function oe(){let t=await(await Vt()).getSecret(Pt,oi);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function Tt(e){let{clientId:t,clientSecret:r,tenant:n}=e,o=[!t?.trim()&&"clientId",!r?.trim()&&"clientSecret",!n?.trim()&&"tenant"].filter(Boolean);if(o.length>0)throw $m.error(`missing or empty fields: ${o.join(", ")}`),new Error("Cannot save credentials: clientId, clientSecret, and tenant are required");await(await Vt()).setSecret(Pt,oi,JSON.stringify(e));}async function Ya(){let e=await Vt();await e.deleteSecret(Pt,oi),await e.deleteSecret(Pt,si),await e.deleteSecret(Pt,ii);}async function Za(){return (await Vt()).getStoragePath()}async function Qa(e){await(await Vt()).setSecret(Pt,si,JSON.stringify(e));}async function bo(){let t=await(await Vt()).getSecret(Pt,si);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function vo(e){await(await Vt()).setSecret(Pt,ii,JSON.stringify(e));}async function el(){let t=await(await Vt()).getSecret(Pt,ii);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function Ht(){let e=await bo();return e?new Date(e.expiresAt)>new Date:false}function Eo(e){let t=e.split(".");if(t.length!==3)throw new Error(`Invalid JWT: expected 3 segments, got ${t.length}`);let r=t[1].replace(/-/g,"+").replace(/_/g,"/"),n=Buffer.from(r,"base64").toString("utf8");try{return JSON.parse(n)}catch{throw new Error("Invalid JWT: payload segment is not valid JSON")}}xn();var li=I("api:auth");function Dm(e){if(!ir.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var rl={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};async function Om(e){if(e instanceof HTTPError){let t=e.response.status;li.error(`HTTP error during authentication [status=${t}]`);let r="";try{let n=await e.response.text(),o=JSON.parse(n);typeof o.error=="string"&&(r=o.error);}catch{}return r&&rl[r]?new Error(rl[r]):t===StatusCodes.UNAUTHORIZED||t===StatusCodes.FORBIDDEN||t===StatusCodes.INTERNAL_SERVER_ERROR?new Error("Invalid credentials"):t>=StatusCodes.BAD_REQUEST&&t<StatusCodes.INTERNAL_SERVER_ERROR?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}return e instanceof Error?(li.debug(`Non-HTTP error during authentication: ${e.message}`),e):(li.debug("Unknown error during authentication"),new Error("Authentication failed"))}async function ur(e){let t=Or("AUTH_ENGINE_URL","https://flow.ciandt.com/auth-engine-api/v2/api-key/token");Dm(e.tenant);let r;try{r=await ac.post(t,{headers:{FlowTenant:e.tenant},json:{clientSecret:e.clientSecret}}).json();}catch(s){throw await Om(s)}let n=r.expires_at??new Date(Date.now()+(r.expires_in??3600)*1e3).toISOString();await Tt(e),await Qa({accessToken:r.access_token,expiresAt:n});let o=Eo(r.access_token);await vo({sub:o.sub,name:o.name,email:o.email});}var nl=I("lib:tokenProvider");async function Jt(){if(await Ht()){let n=await bo();if(n)return n.accessToken}nl.debug("Token expired or missing, re-authenticating...");let t=await oe();if(!t)throw new Error("Not authenticated. Run: flow auth login");De.clearFallbackFile(),Io(),await ur(t);let r=await bo();if(!r)throw new Error("Authentication succeeded but token was not persisted");return nl.debug("Token refreshed successfully"),r.accessToken}xn();var Po=I("api:metrics");function ol(){return Or("METRICS_COLLECTOR_URL","https://flow.ciandt.com/metrics-collector-api/")+"log-event"}function sl(e,t,r){return ac.post(e,{json:t,headers:r})}async function Bm(e){let t=await el();if(t)return t;let r=Eo(e),n={sub:r.sub,name:r.name,email:r.email};return await vo(n),n}async function v(e,t){let r=await Jt(),n=await Bm(r),o=await oe();if(!ir.test(o.tenant))throw new Error(`Invalid tenant value: "${o.tenant}"`);let s={action:e,booster:Us,metadata:{...t},success:true,tenant:o.tenant,timestamp:new Date().toISOString(),user:{id:n.sub,name:n.name,email:n.email}};try{await sl(ol(),s,{Authorization:`Bearer ${r}`,FlowTenant:o.tenant}),Po.debug(`Metrics event sent: ${e}`);}catch(i){throw Po.warn(`Failed to send metrics event "${e}": ${String(i)}`),i}}async function il(e,t,r){try{let n=r&&ir.test(r)?r:"unknown",o={action:e,booster:Us,metadata:t,success:!0,tenant:n,timestamp:new Date().toISOString(),user:{id:"anonymous",name:"unknown",email:"unknown"}};await sl(ol(),o,{FlowTenant:n}),Po.debug(`Anonymous metrics event sent: ${e}`);}catch(n){Po.warn(`Failed to send anonymous metrics event "${e}": ${String(n)}`);}}var b={CLI_SESSION_STARTED:"CLI_SESSION_STARTED",CLI_AUTH_FAILED:"CLI_AUTH_FAILED",CLI_STEP_COMPLETED:"CLI_STEP_COMPLETED",CLI_KIT_DISPLAYED:"CLI_KIT_DISPLAYED",CLI_KIT_ACCEPTED:"CLI_KIT_ACCEPTED",CLI_KIT_REJECTED:"CLI_KIT_REJECTED",CLI_ONBOARDING_COMPLETED:"CLI_ONBOARDING_COMPLETED",CLI_ONBOARDING_ABANDONED:"CLI_ONBOARDING_ABANDONED",CLI_CLAUDE_MD_ACCEPTED:"CLI_CLAUDE_MD_ACCEPTED",CLI_CLAUDE_MD_SKIPPED:"CLI_CLAUDE_MD_SKIPPED",CLI_TOOL_INSTALLED:"CLI_TOOL_INSTALLED",CLI_TOOL_UNINSTALLED:"CLI_TOOL_UNINSTALLED",CLI_TOOL_UPDATED:"CLI_TOOL_UPDATED",CLI_TOOL_ENABLED:"CLI_TOOL_ENABLED",CLI_TOOL_INSTALL_FAILED:"CLI_TOOL_INSTALL_FAILED",CLI_TOOL_DISABLED:"CLI_TOOL_DISABLED",CLI_CATALOG_VIEWED:"CLI_CATALOG_VIEWED",CLI_TUI_SESSION_ENDED:"CLI_TUI_SESSION_ENDED",CLI_MODULE_INSTALL_STARTED:"CLI_MODULE_INSTALL_STARTED",CLI_MODULE_INSTALL_COMPLETED:"CLI_MODULE_INSTALL_COMPLETED",CLI_MODULE_INSTALL_FAILED:"CLI_MODULE_INSTALL_FAILED",CLI_MODULE_PROXY_EXECUTED:"CLI_MODULE_PROXY_EXECUTED",CLI_MODULE_NOT_FOUND:"CLI_MODULE_NOT_FOUND",CLI_MODULE_UPDATED:"CLI_MODULE_UPDATED",CLI_BUNDLE_INSTALL_STARTED:"CLI_BUNDLE_INSTALL_STARTED",CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS:"CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS",CLI_BUNDLE_INSTALL_PLUGIN_FAILED:"CLI_BUNDLE_INSTALL_PLUGIN_FAILED",CLI_BUNDLE_INSTALL_COMPLETED:"CLI_BUNDLE_INSTALL_COMPLETED"};var Um={sessionStart:0,stepStart:0,currentStep:"auth",interfaceType:"cli",tuiSessionStart:0},st={...Um};function al(e){let t=Date.now();st={sessionStart:t,stepStart:t,currentStep:"auth",interfaceType:e,tuiSessionStart:0};}function dr(e){st.currentStep=e,st.stepStart=Date.now();}function H(){return {...st}}function Ct(){return st.sessionStart===0?0:Date.now()-st.sessionStart}function pr(){return st.stepStart===0?0:Date.now()-st.stepStart}function ll(){st.tuiSessionStart=Date.now();}function cl(){return st.tuiSessionStart===0?0:Date.now()-st.tuiSessionStart}var Fm=3e3,jm=I("abandonment");async function To(e){let{currentStep:t,sessionStart:r}=H();if(r===0)return;let n={last_step:t,trigger:e,duration_ms:Ct()};try{await Promise.race([v(b.CLI_ONBOARDING_ABANDONED,n),new Promise((o,s)=>setTimeout(()=>s(new Error("abandonment timeout")),Fm))]);}catch(o){jm.warn(`Abandonment event failed: ${String(o)}`);}}function ul(e,t){return Promise.race([e,new Promise(r=>setTimeout(r,t))])}var Km=3e3,Vm=I("session-end");async function bn(e,t,r){let n=cl(),s=[v(b.CLI_TUI_SESSION_ENDED,{duration_ms:n,active_tab:t,interface:"tui"})];r!=="main"&&s.push(To(e));try{await ul(Promise.all(s).then(()=>{}),Km);}catch(i){Vm.warn(`Session end event failed: ${String(i)}`);}}var Wm=2e3;function pl(){let{exit:e}=useApp(),t=useRef(false),r=useRef(null),n=S(l=>l.pendingExit),o=S(l=>l.setPendingExit),s=S(l=>l.activeTab),i=S(l=>l.screen),a=useCallback(()=>{if(t.current){r.current&&clearTimeout(r.current),bn("double-ctrl-c",s,i).finally(()=>e());return}t.current=true,o(true),r.current=setTimeout(()=>{t.current=false,o(false);},Wm);},[e,o,s,i]);return useInput((l,u)=>{u.ctrl&&l==="c"&&a();}),{pendingExit:n}}var Ym=16;function ml({label:e,value:t,onChange:r,masked:n=false,isActive:o,error:s}){let i=useRef(t);useEffect(()=>{i.current=t;},[t]),useInput((l,u)=>{if(u.backspace){let c=i.current.slice(0,-1);i.current=c,r(c);}else if(l&&!u.ctrl&&!u.meta&&!u.escape&&!u.return&&!u.tab&&!u.upArrow&&!u.downArrow&&!u.leftArrow&&!u.rightArrow){let c=i.current+l;i.current=c,r(c);}},{isActive:o});let a=n?"\u2022".repeat(t.length):t;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{color:o?"cyan":"gray",children:o?"\u25B8 ":" "}),jsx(Text,{color:o?"white":"gray",bold:o,children:e.padEnd(Ym)}),jsx(Text,{color:o?"cyan":"gray",children:a}),o&&jsx(Text,{color:"cyan",children:"\u2588"})]}),s&&jsx(Box,{paddingLeft:3,children:jsxs(Text,{color:"red",children:["\u26A0 ",s]})})]})}var Ge=create(e=>({credentials:null,isAuthenticated:false,justAuthenticated:false,setCredentials:t=>e({credentials:t,isAuthenticated:true}),clearCredentials:()=>e({credentials:null,isAuthenticated:false,justAuthenticated:false}),setJustAuthenticated:t=>e({justAuthenticated:t})}));function mr(){return me__default.join(Le__default.homedir(),".claude","settings.json")}function di(){let e=mr();if(!be__default.existsSync(e))return {status:"missing"};let t=be__default.readFileSync(e,"utf-8");try{let r=JSON.parse(t);return r===null||typeof r!="object"||Array.isArray(r)?{status:"malformed",raw:t}:{status:"ok",settings:r}}catch{return {status:"malformed",raw:t}}}function gl(e){let t=mr();be__default.mkdirSync(me__default.dirname(t),{recursive:true});let r=`${t}.${randomUUID()}.tmp`;be__default.writeFileSync(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),be__default.renameSync(r,t);}function hl(e,t){let r=e.env&&typeof e.env=="object"&&!Array.isArray(e.env)?e.env:{};return {...e,env:{...r,ANTHROPIC_AUTH_TOKEN:t}}}function pi(e){let t=e.env;if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t.ANTHROPIC_AUTH_TOKEN;return typeof r=="string"&&r.length>0?r:null}var rf=3600,fr=class extends Error{constructor(){super("~/.claude/settings.json contains invalid JSON"),this.name="MalformedSettingsError";}};function nf(e){return tf.sign({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},e.clientSecret,{algorithm:"HS256",expiresIn:rf})}function Co(e,t={}){let r=di();if(r.status==="malformed"&&!t.allowOverwriteMalformed)throw new fr;let n=r.status==="ok"?r.settings:{},o=r.status==="ok"?pi(r.settings):null,s=nf(e),i=hl(n,s);return {jwt:s,merged:i,previousToken:o,hadExistingFile:r.status!=="missing"}}function ko(e){gl(e.merged);}function yl(){let e=di();return e.status!=="ok"?false:pi(e.settings)!==null}var Sl="0.0.0";try{let e=JSON.parse(readFileSync(join(import.meta.dirname,"..","package.json"),"utf8"));typeof e.version=="string"&&(Sl=e.version);}catch{}var ae=Sl;function lf(e){if(!(e instanceof Error))return "unknown";let t=e.message.toLowerCase();return t.includes("401")||t.includes("unauthorized")?"invalid_credentials":t.includes("403")||t.includes("forbidden")?"forbidden":t.includes("timeout")||t.includes("timed out")?"timeout":t.includes("network")||t.includes("econnrefused")||t.includes("fetch")?"network_error":"unknown"}var pt=["clientId","clientSecret","tenant"],cf={clientId:"Client ID",clientSecret:"Client Secret",tenant:"Tenant"};function xl(){let[e,t]=useState({clientId:"",clientSecret:"",tenant:""}),[r,n]=useState("clientId"),[o,s]=useState({}),[i,a]=useState(null),[l,u]=useState(false),[c,d]=useState("fields"),[p,m]=useState(null),f=useRef(0),g=useRef(false),{setCredentials:h,setJustAuthenticated:w}=Ge(),P=()=>({clientId:e.clientId.trim(),clientSecret:e.clientSecret.trim(),tenant:e.tenant.trim()}),C=()=>{d("fields"),m(null),t(M=>({...M,clientSecret:""})),n("clientSecret");},k=async()=>{g.current=true;let M=P();try{await Tt(M);}catch(F){a(F instanceof Error?F.message:"Failed to persist credentials"),C(),g.current=false;return}let{clientSecret:x,...A}=M;h(A),w(true),v(b.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Ct(),interface:"tui"}).catch(()=>{}),Tn({starterKit:A.starterKit});},$=async M=>{g.current=true;let x=P();try{ko(M),await Tt(x);}catch(W){a(W instanceof Error?W.message:"Failed to persist credentials"),C(),g.current=false;return}let{clientSecret:A,...F}=x;h(F),w(true),v(b.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Ct(),interface:"tui"}).catch(()=>{}),Tn({starterKit:F.starterKit});},O=M=>{try{return Co(P(),{allowOverwriteMalformed:M})}catch(x){return x instanceof fr?(d("malformedConfirm"),null):(a(x instanceof Error?x.message:"Failed to read settings.json"),d("fields"),null)}};useInput((M,x)=>{if(!(l||g.current)){if(c==="preview"){x.return&&p?$(p):x.escape?k():M==="q"&&C();return}if(c==="malformedConfirm"){if(x.return){let A=O(true);A&&(m(A),$(A));}else x.escape&&C();return}if(x.shift&&x.tab){let A=pt.indexOf(r);A>0&&n(pt[A-1]);}else if(x.tab){let A=pt.indexOf(r);A<pt.length-1&&n(pt[A+1]);}else if(x.return)if(r==="tenant")G();else {let A=pt.indexOf(r);n(pt[A+1]);}}},{isActive:true});let G=async()=>{let M={};for(let x of pt)e[x].trim()||(M[x]="This field is required");if(Object.keys(M).length>0){s(M);let x=pt.find(A=>M[A]);x&&n(x);return}u(true),a(null),f.current+=1;try{await ur(P());let x=O(!1);x&&(m(x),d("preview"));}catch(x){let A=x instanceof Error?x.message:"Authentication failed";a(A),il(b.CLI_AUTH_FAILED,{error_code:lf(x),attempt:f.current},e.tenant.trim()).catch(()=>{}),t(F=>({...F,clientSecret:""}));}finally{u(false);}},ye=M=>x=>{t(A=>({...A,[M]:x})),o[M]&&s(A=>({...A,[M]:void 0}));};return c==="preview"&&p?jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"cyan",children:[to," \u2014 Confirm Settings Update"]})}),jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsx(Text,{children:"Ready to update ~/.claude/settings.json:"}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsx(Text,{color:"green",children:p.previousToken?" ~ env.ANTHROPIC_AUTH_TOKEN (replaced)":" + env.ANTHROPIC_AUTH_TOKEN (new)"}),p.hadExistingFile&&jsx(Text,{dimColor:true,children:" Existing settings preserved."})]})]}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"Enter \u2014 update settings.json and continue"}),jsx(Text,{dimColor:true,children:"Esc \u2014 skip JWT update, continue"}),jsx(Text,{dimColor:true,children:"q \u2014 back to form"})]})]}):c==="malformedConfirm"?jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"yellow",children:[to," \u2014 settings.json is invalid"]})}),jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsx(Text,{children:"Your ~/.claude/settings.json contains invalid JSON."}),jsx(Text,{children:"Press Enter to overwrite it with a fresh file containing only the auth token,"}),jsx(Text,{children:"or Esc to cancel and fix the file manually."})]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter overwrite \xB7 Esc cancel"})})]}):jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"cyan",children:[to," \u2014 Initial Setup"]})}),jsxs(Box,{marginBottom:1,flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"The data collected during setup is used solely to improve"}),jsx(Text,{dimColor:true,children:"Flow's internal tools and will not be shared externally."})]}),jsx(Box,{flexDirection:"column",children:pt.map(M=>jsx(Box,{marginBottom:1,children:jsx(ml,{label:cf[M],value:e[M],onChange:ye(M),masked:M==="clientSecret",isActive:r===M&&!l,error:o[M]})},M))}),l&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"cyan",children:"Authenticating..."})}),i&&jsx(Box,{marginTop:1,children:jsxs(Text,{color:"red",children:["\u26A0 ",y(i)]})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Tab next field \xB7 Enter confirm"})})]})}function Nr(){return jsxs(Box,{flexDirection:"column",alignItems:"center",children:[jsx(df,{text:"FLOW",font:"block",colors:["white","white"]}),jsx(Box,{marginTop:-1,marginBottom:1,children:jsxs(Text,{dimColor:true,children:["Marketplace \xB7 v",ae]})})]})}function pf(){let e=Ka();if(!be__default.existsSync(e))return {};try{return JSON.parse(be__default.readFileSync(e,"utf-8"))}catch{return {}}}var mi=null;function mf(){return mi===null&&(mi=pf()),mi}function Gt(){return !!mf().ENABLE_EXPERIMENTAL_BETAS}var Pl=[{id:"discover",focus:"list"},{id:"installed",focus:"list"},{id:"updates",focus:"list"},{id:"marketplaces",focus:"marketplaces"}],X=Gt()?Pl:Pl.slice(0,3);function ff(e){return X.findIndex(t=>t.id===e)}function fi(e,t,r){let n=ff(r.activeTab);if(t.rightArrow||t.tab){let o=X[(n+1)%X.length];return [{type:"setTab",tab:o.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:o.focus}]}if(t.leftArrow){let o=X[(n-1+X.length)%X.length];return [{type:"setTab",tab:o.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:o.focus}]}return t.downArrow?[{type:"setFocus",focus:X[n]?.focus??"list"}]:[]}var kl={discover:"Discover",installed:"Installed",updates:"Updates",marketplaces:"Marketplaces"};function Al({outdatedCount:e=0}){let t=S(r=>r.activeTab);return jsx(Box,{paddingX:1,paddingBottom:1,children:X.map(({id:r})=>{let n=r===t,o=r==="updates"&&e>0?`${kl[r]} (${e})`:kl[r];return jsx(Box,{marginRight:1,children:n?jsx(Text,{bold:true,inverse:true,children:` ${o} `}):jsx(Text,{dimColor:true,children:` ${o} `})},r)})})}var Oe=create(e=>({query:"",cursorPosition:0,setQuery:t=>e({query:t}),setCursorPosition:t=>e({cursorPosition:t}),resetQuery:()=>e({query:"",cursorPosition:0})}));function Ml(){let e=S(i=>i.focus),t=Oe(i=>i.query),r=Oe(i=>i.cursorPosition),n=e==="search",o=t.slice(0,r),s=t.slice(r);return jsxs(Box,{borderStyle:"single",borderTop:false,borderBottom:true,borderLeft:false,borderRight:false,paddingX:1,marginX:1,marginBottom:1,children:[jsx(Text,{color:n?"cyan":"gray",children:"\u{1F50D} "}),n?jsxs(Fragment,{children:[jsx(Text,{color:"white",children:o}),jsx(Text,{inverse:true,children:s[0]??" "}),jsx(Text,{color:"white",children:s.slice(1)})]}):jsx(Text,{dimColor:true,children:t||"Search..."})]})}var Sf=["skill","mcp","bundle"].map((e,t)=>({key:String(t+2),type:e,...Ar[e]})),wf=["internal","external"].map((e,t)=>({key:String(t+6),origin:e,..._a[e]}));function Ll(){let e=S(n=>n.catalogFilters),t=e.types.has("skill")&&e.types.has("mcp")&&e.types.has("bundle"),r=e.origins.has("internal")&&e.origins.has("external");return jsxs(Box,{paddingX:1,paddingBottom:1,gap:1,children:[jsx(Text,{bold:true,children:"Type:"}),jsxs(Box,{gap:0,children:[jsx(Text,{dimColor:true,children:"[1] "}),jsxs(Text,{color:t?"green":void 0,dimColor:!t,children:[t?"\u25C9":"\u25CB"," All"]})]}),Sf.map(n=>{let o=!t&&e.types.has(n.type);return jsxs(Box,{gap:0,children:[jsxs(Text,{dimColor:true,children:["[",n.key,"] "]}),jsxs(Text,{color:o?n.color:void 0,dimColor:!o,children:[o?"\u25C9":"\u25CB"," ",n.label]})]},n.key)}),jsx(Box,{marginLeft:2,children:jsx(Text,{bold:true,children:"|"})}),jsx(Box,{marginLeft:2,children:jsx(Text,{bold:true,children:"Origin:"})}),jsxs(Box,{gap:0,children:[jsx(Text,{dimColor:true,children:"[5] "}),jsxs(Text,{color:r?"green":void 0,dimColor:!r,children:[r?"\u25C9":"\u25CB"," All"]})]}),wf.map(n=>{let o=!r&&e.origins.has(n.origin);return jsxs(Box,{gap:0,children:[jsxs(Text,{dimColor:true,children:["[",n.key,"] "]}),jsxs(Text,{color:o?n.color:void 0,dimColor:!o,children:[o?"\u25C9":"\u25CB"," ",n.label]})]},n.key)})]})}function Rl({type:e}){let{label:t,color:r}=Ar[e];return jsx(Text,{color:r,children:t})}function Ol({origin:e}){return e===mn?jsx(Text,{color:"blue",children:"[Flow]"}):jsx(Text,{color:"white",children:"[External]"})}var $o=bf.memo(function({item:t,isSelected:r}){let n=t.status==="disabled"?"yellow":"green";return jsxs(Box,{flexDirection:"column",paddingBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":"\u25CB "}),jsx(Text,{bold:r,color:r?"cyan":"white",children:t.name}),t.type&&jsxs(Text,{children:[" ",jsx(Rl,{type:t.type})]}),t.origin&&jsxs(Text,{children:[" ",jsx(Ol,{origin:t.origin})]}),jsxs(Text,{dimColor:true,children:[t.authorName?` \xB7 ${t.authorName}`:"",t.version?` \xB7 v${t.version}`:" \xB7 n/a"]}),t.status&&jsxs(Text,{color:n,children:[" [",t.status,"]"]}),t.updateAvailable&&jsx(Text,{color:"yellow",children:" [\u2191 update available]"}),t.installedAt&&jsxs(Text,{dimColor:true,children:[" \xB7 ",jt(t.installedAt)]})]}),jsx(Box,{paddingLeft:2,children:jsx(Text,{dimColor:true,children:t.description})})]})});function Br({message:e}){return jsx(Box,{paddingX:2,paddingY:1,children:jsx(Text,{dimColor:true,children:e??"No items found."})})}function Ul({items:e,emptyMessage:t}){let r=S(l=>l.selectedIndex);if(e.length===0)return jsx(Br,{message:t});let n=Math.max(0,r-Math.floor(Ve/2)),o=Math.min(e.length,n+Ve);o===e.length&&(n=Math.max(0,o-Ve));let s=e.slice(n,o),i=n,a=e.length-o;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:i>0?`\u2191 ${i} more above`:" "})}),s.map((l,u)=>jsx($o,{item:l,isSelected:n+u===r},l.name)),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:a>0?`\u2193 ${a} more below`:" "})})]})}function Kl({label:e,pathHint:t}){return jsxs(Box,{paddingBottom:1,children:[jsx(Text,{bold:true,color:"blueBright",children:e}),jsxs(Text,{dimColor:true,children:[" ",t]})]})}function Hl({groups:e,emptyMessage:t}){let r=S(m=>m.selectedIndex),n=[],o=0;for(let m of e){n.push({kind:"header",label:m.label,pathHint:m.pathHint,key:`h-${m.scope}`});for(let f of m.items)n.push({kind:"item",item:f,itemIndex:o,key:`i-${m.scope}-${f.name}-${f.marketplace??""}`}),o++;}if(o===0)return jsx(Br,{message:t});let i=n.findIndex(m=>m.kind==="item"&&m.itemIndex===r),a=i>=0?i:0,l=Math.max(0,a-Math.floor(Ve/2)),u=Math.min(n.length,l+Ve);u===n.length&&(l=Math.max(0,u-Ve));let c=n.slice(l,u),d=l,p=n.length-u;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:d>0?`\u2191 ${d} more above`:" "})}),c.map(m=>m.kind==="header"?jsx(Kl,{label:m.label,pathHint:m.pathHint},m.key):jsx($o,{item:m.item,isSelected:m.itemIndex===r},m.key)),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:p>0?`\u2193 ${p} more below`:" "})})]})}var $f={discover:"Discover",installed:"Installed",updates:"Updates",marketplaces:"Marketplaces"};function Mf({items:e,tabId:t,emptyMessage:r,groups:n,actionHint:o}){return jsxs(Box,{flexDirection:"column",children:[jsx(Ml,{}),jsx(Ll,{}),jsxs(Box,{paddingX:1,marginTop:1,children:[jsx(Text,{bold:true,children:$f[t]}),jsxs(Text,{dimColor:true,children:[" (",e.length,")"]}),o&&e.length>0&&jsx(Text,{dimColor:true,children:` \xB7 ${o}`})]}),n&&n.length>0?jsx(Hl,{groups:n,emptyMessage:r}):jsx(Ul,{items:e,emptyMessage:r})]})}function Jl({filteredItems:e,emptyMessage:t,groups:r,onBatchUpdate:n}){let o=S(l=>l.activeTab),s=S(l=>l.focus);return useInput(l=>{l==="a"&&e.length>0&&n?.();},{isActive:o==="updates"&&s==="list"}),jsx(Box,{flexDirection:"column",flexGrow:1,children:jsx(Mf,{items:e,tabId:o,emptyMessage:t,groups:o!=="discover"?r:void 0,actionHint:o==="updates"?"press 'a' to update all":void 0},o)})}var _f={tabs:"\u2190\u2192: switch tab | \u2193: navigate | Enter: select | Ctrl+C Ctrl+C: quit",list:"\u2191\u2193: navigate | Enter: select | Type: 1=All 2=Skill 3=MCP 4=Bundle | Origin: 5=All 6=Flow 7=External | \u2190\u2192/Tab: tabs | Ctrl+C\xD72: quit",search:"Type to filter | \u2193/Esc: exit search | Enter: confirm",actionMenu:"\u2191\u2193: navigate options | Enter: confirm | Esc: close menu",auth:"Tab: next field | Enter: confirm | Ctrl+C Ctrl+C: quit",starterKitList:"\u2191\u2193: navigate | Enter: select Starter Kit | Esc: skip",starterKitDetail:"\u2191\u2193: navigate | Enter: confirm & install | Esc: back",installProgress:"\u2191\u2193: navigate | Enter: select",moduleSetup:"\u2191\u2193: navigate | Space: toggle | Tab: change method | Enter: confirm",marketplaces:"\u2191\u2193: navigate | a: add catalog | d: remove catalog | r: refresh | \u2190\u2192/Tab: tabs | Ctrl+C\xD72: quit",verify:"\u2191\u2193: navigate | Enter: confirm | Ctrl+C Ctrl+C: quit",bundleInstallProgress:"Enter/Esc: back to catalog"};function Mo(){let e=S(r=>r.focus),t=!!process.env.DEBUG;return jsx(Box,{borderStyle:"single",borderTop:true,borderBottom:false,borderLeft:false,borderRight:false,children:jsxs(Text,{dimColor:true,children:[_f[e],t?" | Ctrl+D: debug log":""]})})}function Gl({message:e,type:t}){return e?jsx(Box,{paddingX:1,children:jsxs(Text,{color:t==="success"?"green":t==="info"?"cyan":"red",children:[t==="success"?"\u2713":t==="info"?"(i)":"\u2717"," ",y(e)]})}):null}function Lo({message:e}){return jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{children:[" ",e]})]})}function Ro({message:e,onRetry:t,onBack:r}){return useInput((n,o)=>{n==="r"&&o.ctrl&&t?t():o.escape&&r&&r();}),jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsxs(Text,{color:"red",children:["\u2717 ",e]}),t&&jsx(Text,{dimColor:true,children:"Press Ctrl+R to retry"}),r&&jsx(Text,{dimColor:true,children:"Press Escape to go back"})]})}function ze({itemName:e,actions:t,descriptions:r,onAction:n,onClose:o}){let s=S(l=>l.focus),[i,a]=useState(0);return useInput((l,u)=>{u.upArrow?a(c=>c>0?c-1:c):u.downArrow?a(c=>c<t.length-1?c+1:c):u.return?n(t[i]):u.escape&&o();},{isActive:s==="actionMenu"}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsx(Box,{flexDirection:"column",marginTop:1,children:t.map((l,u)=>jsxs(Box,{children:[jsxs(Text,{bold:u===i,color:u===i?"cyan":void 0,children:[u===i?"\u203A ":" ",l]}),r?.[l]&&jsxs(Text,{dimColor:true,children:[" \u2014 ",r[l]]})]},u))})]})}var Ei=Object.entries(fn),Ql=[...Ei.map(([,e])=>e.actionLabel),"Cancel"],ec=Object.fromEntries(Ei.map(([,e])=>[e.actionLabel,e.description]));function tc(e){let t=Ei.find(([,r])=>r.actionLabel===e);return t?t[0]:null}var Wf=I("provider.registry"),zf=3e4,Do=class{adapters=new Map;availabilityCache=new Map;register(t){this.adapters.set(t.id,t);}async checkAvailability(t){let r=this.availabilityCache.get(t.id);if(r&&Date.now()<r.expiresAt)return r.result;let n=await t.isAvailable();return this.availabilityCache.set(t.id,{result:n,expiresAt:Date.now()+zf}),n}async getAvailableProviders(t){let r=[...this.adapters.values()].filter(o=>t in o.installers),n=await Promise.allSettled(r.map(o=>this.checkAvailability(o)));return n.forEach((o,s)=>{o.status==="rejected"&&Wf.warn(`Provider "${r[s].id}" isAvailable() threw: ${String(o.reason)}`);}),r.filter((o,s)=>{let i=n[s];return i.status==="fulfilled"&&i.value===true})}getAdapter(t){return this.adapters.get(t)}listAdapters(){return [...this.adapters.values()]}};var Xf={user:"global",project:"project",local:"local"};function Oo(e){return e?Xf[e]:"global"}var Ne=class extends Error{constructor(r,n){super(`${r} v${n} is already installed. Use --force to reinstall.`);this.pluginName=r;this.version=n;this.name="AlreadyInstalledError";}pluginName;version},zt=class extends Error{constructor(r,n){super(`${r} is already up to date (v${n})`);this.pluginName=r;this.version=n;this.name="AlreadyUpToDateError";}pluginName;version};xn();function mt(){return ac.create({prefix:Or("PROMPT_MANAGER_URL","https://flow.ciandt.com/prompt-manager-api/"),hooks:{beforeRequest:[async({request:e})=>{let t=await Jt();e.headers.set("Authorization",`Bearer ${t}`);let r=await oe();r?.tenant&&ir.test(r.tenant)&&e.headers.set("FlowTenant",r.tenant);}]}})}var Yf=I("catalog.registry"),No=class{adapters=new Map;register(t){this.adapters.set(t.id,t);}unregister(t){this.adapters.delete(t);}async fetchAllWithErrors(){let t=this.listAdapters(),r=await Promise.allSettled(t.map(s=>s.fetchItems())),n=[],o=[];for(let s=0;s<r.length;s++){let i=r[s],a=t[s];if(i.status==="fulfilled")n.push(...i.value);else {let l=String(i.reason);Yf.warn(`Catalog adapter failed: ${l}`),o.push({adapterId:a.id,adapterName:a.name,reason:l});}}return {items:n,failures:o}}async fetchAll(){let{items:t}=await this.fetchAllWithErrors();return t}getAdapter(t){return this.adapters.get(t)}listAdapters(){return [...this.adapters.values()]}};var sg={retries:5,minTimeout:50};async function Pi(e,t){mkdirSync(dirname(e),{recursive:true});let r=await og.lock(e+".lock",{realpath:false,retries:sg});try{return await t()}finally{await r();}}var Bo=class{filePath;constructor(t){this.filePath=t??ja();}async read(){try{let t=await readFile(this.filePath,"utf-8");return JSON.parse(t).catalogs??[]}catch(t){if(t.code==="ENOENT")return [];throw t}}async write(t){let r=dirname(this.filePath);await mkdir(r,{recursive:true});let n=`${this.filePath}.${randomUUID()}.tmp`;await writeFile(n,JSON.stringify({catalogs:t},null,2),"utf-8"),await rename(n,this.filePath);}async add(t){await Pi(this.filePath,async()=>{let r=await this.read();if(r.some(o=>o.id===t.id))return;let n={...t,lastUpdated:t.lastUpdated??new Date().toISOString()};await this.write([...r,n]);});}async remove(t){if(t==="flow-api")throw new Error("The Flow Marketplace catalog cannot be removed");await Pi(this.filePath,async()=>{let r=await this.read();await this.write(r.filter(n=>n.id!==t));});}async updateField(t,r){await Pi(this.filePath,async()=>{let n=await this.read();n.some(o=>o.id===t)&&await this.write(n.map(o=>o.id===t?{...o,...r}:o));});}};var ig=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function An(e){if(!e||!ig.test(e))throw new Error(`Invalid plugin name: "${e}". Must be 1-64 chars, lowercase alphanumeric and hyphens only.`)}var ag=/^[^@]+@[^@]+$/;function Fr(e){return ag.test(e)}function jr(e){let t=e.indexOf("@");return t>0?e.slice(0,t):e}var lg=/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/;function cg(e){if(!lg.test(e))throw new Error(`Invalid plugin name: "${e}". Plugin names must start with an alphanumeric character and contain only letters, digits, dots, hyphens, underscores, and slashes.`)}function Kr(e,t){let r=jr(e);cg(r);let n=["claude","plugin","install",r];return t&&n.push("--scope",t),n.join(" ")}var ug=/^[\w./:@?&=+#%-]+$/;function Uo(e){let t=e.trim();if(!t)throw new Error("No marketplace source provided.");if(!ug.test(t))throw new Error(`Invalid marketplace source: "${t}". Must be owner/repo or a URL (no spaces or special characters).`);return t}var dg=I("catalog.flow-api"),Fo=class{id="flow-api";name="Flow Marketplace";source;removable=false;constructor(){this.source=process.env.PROMPT_MANAGER_URL??"";}async fetchItems(){try{let{plugins:t}=await mt().get("v1/plugins/catalog").json();return t.map(r=>({...r,catalogId:this.id,origin:r.origin??"internal",type:r.type??"bundle"}))}catch(t){if(t instanceof HTTPError){let{status:r}=t.response;throw r===401||r===403?new Error("Authentication failed. Run: flow auth login"):new Error(`Failed to fetch plugin catalog: HTTP ${r}`)}throw t instanceof Error?t.name==="TimeoutError"||t.message.includes("timeout")?new Error("Request timed out while fetching plugin catalog"):new Error(`Failed to fetch plugin catalog: ${t.message}`):t}}async fetchManifest(t){An(t);try{return await mt().get(`v1/plugins/${t}/manifest`).json()}catch(r){if(r instanceof HTTPError){let{status:n}=r.response;throw n===404?new Error(`Plugin '${t}' not found in catalog`):new Error(`Failed to fetch manifest: HTTP ${n}`)}throw r instanceof Error?new Error(`Failed to fetch manifest: ${r.message}`):r}}async ping(){try{return await mt().head("v1/plugins/catalog"),dg.debug("ping ok"),!0}catch{return false}}};var ge=new No,At=new Bo;ge.register(new Fo);var uc=false;async function dc(){if(uc)return;uc=true;let e=await At.read(),{GitRepoAdapter:t}=await Promise.resolve().then(()=>(Ti(),cc));for(let r of e)ge.register(new t(r.id,r.name,r.source));}async function Xt(){return ge.fetchAll()}async function pc(){return ge.fetchAllWithErrors()}async function Hr(e){An(e);try{return await mt().get(`v1/plugins/${e}/manifest`).json()}catch(t){throw t instanceof Error?t.message.includes("404")?new Error(`Plugin '${e}' not found in catalog`):t.message.includes("timeout")?new Error("Download timed out after 30s"):new Error(`Failed to fetch plugin manifest: ${t.message}`):t}}async function mc(e){An(e);try{let t=await mt().get(`v1/plugins/${e}/archive`);return Buffer.from(await t.arrayBuffer())}catch(t){throw t instanceof Error?t.message.includes("timeout")?new Error("Download timed out after 30s"):new Error(`Failed to download plugin: ${t.message}`):t}}async function jo(){try{let{profiles:e}=await mt().get("v1/plugins/profiles").json();return e}catch(e){throw e instanceof Error?e.message.includes("401")||e.message.includes("403")?new Error("Authentication failed. Run: flow auth login"):e.message.includes("timeout")?new Error("Request timed out while fetching starter kits"):new Error(`Failed to fetch starter kits: ${e.message}`):e}}async function fc(e,t){let r=me.resolve(t);await ft.mkdir(r,{recursive:true});let n=me.join(me.dirname(r),`${randomUUID()}.zip`);try{await ft.writeFile(n,e),await hg(n,{dir:r,onEntry(o){if((o.externalFileAttributes>>16&61440)===40960)throw new Error(`Zip Slip (symlink): entry "${o.fileName}" is a symbolic link and was rejected`);let i=me.resolve(r,o.fileName);if(!i.startsWith(r+me.sep)&&i!==r)throw new Error(`Zip Slip detected: entry "${o.fileName}" would escape target directory`)}});try{let o=realpathSync(r);if(!o.startsWith(me.resolve(me.dirname(r))))throw new Error(`Zip Slip (post-extract): resolved path "${o}" is outside expected parent`)}catch(o){if(o.code!=="ENOENT")throw o}}finally{try{await ft.unlink(n);}catch{}}}async function Ci(e){await ft.rm(e,{recursive:true,force:true});}async function qt(){let e=Ua();await ft.mkdir(me.dirname(e),{recursive:true});try{await ft.writeFile(e,"",{flag:"wx"});}catch(r){if(r.code!=="EEXIST")throw r}return await og.lock(e,{stale:1e4,retries:{retries:2,minTimeout:500,maxTimeout:500}})}function wg(){return {$schema:"https://anthropic.com/claude-code/marketplace.schema.json",name:re,description:"Flow Skills marketplace",owner:{name:"Flow Team",email:"flow@ciandt.com"},plugins:[]}}function yc(){let e=oo();if(!be__default.existsSync(e))return null;try{return JSON.parse(be__default.readFileSync(e,"utf-8"))}catch{return null}}function xg(){let e=yc();if(e)return e;let t=wg(),r=oo();return be__default.mkdirSync(me__default.dirname(r),{recursive:true}),ki(t),t}function ki(e){let t=oo(),r=`${t}.${randomUUID()}.tmp`;be__default.writeFileSync(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),be__default.renameSync(r,t);}function Ig(){let e=so(),t={};try{be__default.existsSync(e)&&(t=JSON.parse(be__default.readFileSync(e,"utf-8")));}catch{t={};}if(t[re])return;t[re]={source:{source:"github",repo:"CI-T-HyperX/flow-skills"},installLocation:Ba(),lastUpdated:new Date().toISOString()};let r=`${e}.${randomUUID()}.tmp`;be__default.writeFileSync(r,JSON.stringify(t,null,2),{encoding:"utf-8",mode:384}),be__default.renameSync(r,e);}function Sc(e,t){Jr(e.name),Ig();let r=Ks(e.name);be__default.mkdirSync(me__default.dirname(r),{recursive:true});try{be__default.lstatSync(r),be__default.rmSync(r,{recursive:!0,force:!0});}catch{}be__default.symlinkSync(t,r,process.platform==="win32"?"junction":"dir");let n=xg();n.plugins.some(s=>s.name===e.name)||(n.plugins.push({name:e.name,description:e.description,version:e.version,author:e.author,source:`./plugins/native/${e.name}`,category:e.category}),ki(n));}function Ai(e){Jr(e);let t=Ks(e);try{be__default.rmSync(t,{recursive:!0,force:!0});}catch{}let r=yc();if(!r)return;let n=r.plugins.length;r.plugins=r.plugins.filter(o=>o.name!==e),r.plugins.length!==n&&ki(r);}var vg=I("mcpConfigReader"),Eg=500,Pg=512;function Tg(){return me__default.join(Le__default.homedir(),".claude.json")}function Cg(){return me__default.join(process.cwd(),".mcp.json")}function xc(e){if(!be__default.existsSync(e))return null;try{return JSON.parse(be__default.readFileSync(e,"utf-8"))}catch{return vg.debug(`[mcpConfigReader] Failed to parse ${e}`),null}}function $n(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function $i(e){if(!$n(e))return {};let t=e.mcpServers;return $n(t)?t:{}}function Mi(e,t){return Object.keys(e).slice(0,Eg).map(n=>({name:y(n.slice(0,Pg)),marketplace:"",version:void 0,installedAt:"",installPath:"",scope:t,description:void 0,author:void 0,status:"enabled",type:"mcp"}))}function bc(){let e=[],t=Tg(),r=xc(t);if($n(r)){let a=r,l=$i(a);e.push(...Mi(l,"user"));let u=process.cwd();if($n(a.projects)){let c=a.projects[u];if($n(c)){let d=$i(c);e.push(...Mi(d,"local"));}}}let n=Cg(),o=xc(n),s=$i(o);e.push(...Mi(s,"project"));let i=new Map;for(let a of e){let l=`${a.name}@${a.scope}`;i.has(l)||i.set(l,a);}return [...i.values()]}var qe=I("storage");async function Ag(e,t,r){try{await v(b.CLI_TOOL_UNINSTALLED,{tool_id:e,tool_type:r,source:t,interface:H().interfaceType});}catch(n){qe.warn(`Failed to send uninstall metrics: ${String(n)}`);}}function $g(e,t,r){let n=t==="enabled"?b.CLI_TOOL_ENABLED:b.CLI_TOOL_DISABLED;v(n,{tool_id:e,source:r,interface:H().interfaceType}).catch(o=>qe.warn(`Failed to send ${t} metrics: ${String(o)}`));}function Di(){return me__default.join(Le__default.homedir(),".claude","plugins","installed_plugins.json")}function Mg(){return me__default.join(Le__default.homedir(),".claude","plugins")}function vc(e){let t=me__default.resolve(e),r=me__default.resolve(Mg()),n=me__default.resolve(me__default.join(process.cwd(),".claude","plugins")),o=t.startsWith(r+me__default.sep)||t===r,s=t.startsWith(n+me__default.sep)||t===n;if(!o&&!s)throw new Error(`Security error: installPath '${e}' is outside the plugins directory`)}function Ec(e="user"){return e==="local"?me__default.join(process.cwd(),".claude","settings.local.json"):e==="project"?me__default.join(process.cwd(),".claude","settings.json"):me__default.join(Le__default.homedir(),".claude","settings.json")}function Mt(){let e=Di();if(!be__default.existsSync(e))return {version:2,plugins:{}};try{return JSON.parse(be__default.readFileSync(e,"utf-8"))}catch{return {version:2,plugins:{}}}}async function Pc(){let e=Di();try{let t=await be__default.promises.readFile(e,"utf-8");return JSON.parse(t)}catch{return {version:2,plugins:{}}}}function Lg(e){let t=e?.code;return t==="EACCES"||t==="EPERM"}function Tc(e,t){try{be__default.mkdirSync(me__default.dirname(e),{recursive:!0});let r=`${e}.${randomUUID()}.tmp`;be__default.writeFileSync(r,JSON.stringify(t,null,2),{encoding:"utf-8",mode:384}),be__default.renameSync(r,e);}catch(r){throw Lg(r)?new Error(`Permission denied: cannot write to '${e}'. Check your file system permissions.`):r}}function $t(e){Tc(Di(),e);}function Mn(e){let t=e.lastIndexOf("@");return t===-1?{name:e,marketplace:""}:{name:e.slice(0,t),marketplace:e.slice(t+1)}}function Rg(e,t){let r=me__default.join(e,".claude-plugin"),n=me__default.join(r,"plugin.json");if(be__default.existsSync(n))try{return JSON.parse(be__default.readFileSync(n,"utf-8"))}catch{return null}let o=me__default.join(r,"marketplace.json");if(be__default.existsSync(o))try{let s=JSON.parse(be__default.readFileSync(o,"utf-8"));return {description:s.plugins?.find(a=>a.name===t)?.description,author:s.owner}}catch{return null}return null}function Oi(e="user"){let t=Ec(e);if(!be__default.existsSync(t))return {};try{return JSON.parse(be__default.readFileSync(t,"utf-8"))}catch{return {}}}function Cc(e,t="user"){Tc(Ec(t),e);}function _g(e,t){let{name:r,marketplace:n}=Mn(e),o;if(n?(o=`${r}@${n}`,t[o]||(o=void 0)):o=Object.keys(t).filter(i=>Mn(i).name===r)[0],!o)throw qe.error(`[${r}] Plugin is not installed`),new Error(`Plugin '${r}' is not installed`);return {key:o,name:r}}function Dg(e,t){let{name:r,marketplace:n}=Mn(e),o;return n?(o=`${r}@${n}`,t[o]||(o=void 0)):o=Object.keys(t).filter(i=>Mn(i).name===r)[0],o?{key:o,name:r}:null}function Li(e="user"){return Oi(e).enabledPlugins??{}}function Ri(e,t="user"){let r=Oi(t),n=r.enabledPlugins;if(!n||!(e in n))return;let{[e]:o,...s}=n;r.enabledPlugins=s,Cc(r,t);}function Ln(e,t,r="user"){let n=Oi(r),o=n.enabledPlugins??{};n.enabledPlugins={...o,[e]:t},Cc(n,r);}function Og(e){let t=new Map;for(let r of e){let n=t.get(r.scope);(!n||r.installedAt>n.installedAt)&&t.set(r.scope,r);}return [...t.values()]}function se(){let e=Mt(),t=Li(),r=Li("project"),n=Li("local"),o={project:r,local:n},s=Object.entries(e.plugins).flatMap(([u,c])=>{let{name:d,marketplace:p}=Mn(u),m=c.map(g=>g.scope==="managed"?{...g,scope:"user"}:g);return Og(m).map(g=>{let h=Rg(g.installPath,d),P=(o[g.scope]??t)[u];return {name:d,marketplace:p,version:g.version&&g.version!=="unknown"?g.version:void 0,installedAt:g.installedAt,installPath:g.installPath,scope:g.scope,providerId:g.providerId,type:g.type,description:h?.description,author:h?.author,status:P===false?"disabled":"enabled"}})}),i=bc(),a=new Set(s.map(u=>`${u.name}@${u.scope}`)),l=i.filter(u=>!a.has(`${u.name}@${u.scope}`));return [...s,...l]}async function Ko(e,t){qe.debug(`[${e}] Acquiring lock to uninstall`);let r=await qt();try{let n=Mt(),o=Dg(e,n.plugins);if(!o)throw new Error(`Plugin '${e}' is not in installed_plugins.json. If this is an MCP server from config, use the MCP remove command instead.`);let{key:s,name:i}=o,a=n.plugins[s];if(t){let l=a.find(d=>d.scope===t);if(!l)throw new Error(`Plugin '${i}' is not installed in ${t} scope`);qe.debug(`[${i}] Resolved key: ${s}, scope: ${t}`),vc(l.installPath);let u=me__default.dirname(l.installPath);qe.debug(`[${i}] Removing directory: ${u}`),be__default.rmSync(u,{recursive:!0,force:!0});let c=a.filter(d=>d.scope!==t);if(c.length===0){let{[s]:d,...p}=n.plugins;$t({...n,plugins:p}),Ri(s,t),Ai(i);}else n.plugins[s]=c,$t(n),Ri(s,t);}else {qe.debug(`[${i}] Resolved key: ${s}`);for(let c of a){vc(c.installPath);let d=me__default.dirname(c.installPath);qe.debug(`[${i}] Removing directory: ${d}`),be__default.rmSync(d,{recursive:!0,force:!0}),Ri(s,c.scope);}Ai(i);let{[s]:l,...u}=n.plugins;$t({...n,plugins:u});}await Ag(i,a[0].origin??"internal",a[0].type??"skill"),qe.debug(`[${i}] Uninstalled successfully`);}finally{await r();}}async function Rn(e,t,r){qe.debug(`[${e}] Acquiring lock to set status \u2192 ${t}`);let n=await qt();try{let o=Mt(),{key:s,name:i}=_g(e,o.plugins),a=o.plugins[s],l=r??a[0].scope,u=a[0].origin??"internal";qe.debug(`[${i}] Resolved key: ${s}, scope: ${l}`),Ln(s,t==="enabled",l),$g(i,t,u),qe.debug(`[${i}] Status updated to ${t}`);}finally{await n();}}var Ng=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/,Bg=/^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?$/;function Jr(e){if(!Ng.test(e))throw new Error(`Invalid plugin name from manifest: "${e}". Plugin names must be lowercase alphanumeric and hyphens (1-64 chars).`)}function Ug(e){if(!Bg.test(e))throw new Error(`Invalid plugin version from manifest: "${e}". Versions must follow semver format (e.g. 1.0.0 or 1.0.0-beta.1).`)}var Yt=I("installer");function Fg(e,t){let r=`${e}@${re}`,o=Mt().plugins[r];if(o&&!t)throw new Ne(e,o[0].version??"unknown");return {pluginKey:r,alreadyInstalled:o}}async function jg(e,t,r){r&&await Ci(t);try{Yt.debug(`[${t}] Extracting archive...`),await fc(e,t);}catch(n){throw await Ci(t),n}}function Kg(e,t,r,n,o,s="claude-code",i){let a=Mt(),l={scope:n,installPath:t,version:r,installedAt:new Date().toISOString(),origin:o,providerId:s,type:i},u=a.plugins[e]??[];a.plugins[e]=[...u.filter(c=>c.scope!==n),l],$t(a),Ln(e,true,n);}async function Vg(e,t,r,n,o,s){try{await v(b.CLI_TOOL_INSTALLED,{tool_id:e,tool_type:s,source:o,scope:n,version:t,duration_ms:r,interface:H().interfaceType});}catch(i){Yt.warn(`Failed to send install metrics: ${String(i)}`);}}async function Hg(e,t,r,n){try{await v(b.CLI_TOOL_INSTALL_FAILED,{tool_id:e,tool_type:n,source:r,error_code:t instanceof Error?t.name:"UNKNOWN",error_message:(t instanceof Error?t.message:String(t)).slice(0,500),interface:H().interfaceType});}catch(o){Yt.warn(`Failed to send install-failed metrics: ${String(o)}`);}}async function Ee(e,t={}){let r=Date.now(),n=null;try{Yt.debug(`[${e}] Acquiring lock...`),n=await qt();let{pluginKey:o,alreadyInstalled:s}=Fg(e,t.force);Yt.debug(`[${e}] Fetching manifest...`);let i=await Hr(e);Jr(i.name),Ug(i.version),Yt.debug(`[${e}] Downloading archive...`);let a=await mc(e),l=t.scope??"user",u=t.type??"skill",c=Na(i.name,i.version);await jg(a,c,!!s&&!!t.force),Kg(o,c,i.version,l,"internal",t.providerId,u),Sc(i,c);let d=Date.now()-r;Yt.debug(`[${e}] Installed successfully in ${d}ms`);let p={name:i.name,version:i.version,path:c,duration_ms:d};return t.skipMetrics||await Vg(i.name,i.version,d,Oo(l),"internal",u),p}catch(o){throw await Hg(e,o,"internal",t.type??"skill"),Yt.error(`[${e}] Installation failed: ${o instanceof Error?o.message:String(o)}`),o}finally{n&&await n();}}var Jg=I("commands:helpers");async function fe(){if(!await oe())return E("Not authenticated. Run: flow auth login"),false;try{await Jt();}catch(t){return Jg.debug(`Token validation failed: ${String(t)}`),E("Session expired. Run: flow auth login"),false}return true}async function gt(e){let t=Ni.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(y(e),n=>{t.close(),r(["y","yes"].includes(n.toLowerCase().trim()));});})}async function kc(e){let t=Ni.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(y(e),n=>{t.close(),r(n.trim());});})}var Gr=I("claudeProxy"),Ki="claude ",Ac="flow ",Bi=class extends Error{constructor(t){super(`Invalid install command: "${t}". Command must start with "claude " for security.`),this.name="InvalidInstallCommandError";}},Ui=class extends Error{constructor(t){super(`Disallowed subcommand: "${t}". Only "plugin install", "plugin marketplace add", "mcp add", and "mcp remove" are permitted.`),this.name="DisallowedSubcommandError";}},Gg=/^plugins?\s+(install|i)\s+|^plugins?\s+marketplace\s+add\s+|^mcp\s+(add|remove)\s+/,Wg=/^npm\s+(i|install)\s+-g\s+@ciandt-flow\/cli$/,zg=/^(flow|claude)\s+auth\s+login(\s|$)/,$c=/^flow\s+plugins?\s+(install|i)\s+([^@\s]+)$/;function Mc(e){return $c.test(e.trim())}function Xg(e){return $c.exec(e.trim())?.[2]??""}async function Lc(e){let t=Xg(e),r=Date.now();Gr.debug(`[${t}] Executing: flow plugin install ${t}`);try{let n=await execa("flow",["plugin","install",t],{reject:!1});return {name:t,command:`flow plugin install ${t}`,exitCode:n.exitCode??1,stdout:n.stdout,stderr:n.stderr,duration_ms:Date.now()-r}}catch(n){throw Vi(n)?new Fi:n}}function qg(e){Rc(e);let t=e.slice(Ki.length);if(!Gg.test(t))throw new Ui(e)}var Vo=class extends Error{constructor(){super('Claude Code CLI not found. Ensure "claude" is installed and available on your PATH.'),this.name="ClaudeCliNotFoundError";}},Fi=class extends Error{constructor(){super('Flow CLI not found. Ensure "flow" is installed and available on your PATH.'),this.name="FlowCliNotFoundError";}};function Rc(e){if(!e||!/^claude /.test(e))throw new Bi(e)}async function we(e){Rc(e);let t=e.slice(Ki.length).split(/\s+/).filter(Boolean),r=Yg(t);Gr.debug(`[${r}] Executing proxy command: claude ${t.join(" ")}`);let n=Date.now();try{let o=await execa("claude",t,{reject:!1}),s=Date.now()-n;return Gr.debug(`[${r}] Proxy command finished with exit code ${o.exitCode} in ${s}ms`),{name:r,command:e,exitCode:o.exitCode??1,stdout:o.stdout,stderr:o.stderr,duration_ms:s}}catch(o){throw Vi(o)?new Vo:o}}function Yg(e){return e.length>=3?e[2]:e.join(" ")}function Vi(e){return e instanceof Error&&"code"in e&&e.code==="ENOENT"}function Zg(e){return e.startsWith(Ac)?Ki+e.slice(Ac.length):e}function Qg(e){return Wg.test(e)||zg.test(e)}function eh(e){let t=0;for(;t<e.length&&Qg(e[t]);)t++;return e.slice(t)}var th=/^claude\s+(?:plugins?\s+(?:install|i)\s+|mcp\s+(?:add|remove)\s+)/;function rh(e,t){return !t||e.includes("--scope")||!th.test(e)?e:`${e} --scope ${t}`}async function _n(e,t){let r=e.split("&&").map(i=>i.trim()).filter(Boolean),o=eh(r).map(i=>Zg(i)).map(i=>rh(i,t));if(o.length===0)throw new Error("Empty install command");for(let i of o)qg(i);Gr.debug(`[installCommand] Executing ${o.length} command(s)`);let s=await we(o[0]);if(s.exitCode!==0)return s;for(let i=1;i<o.length;i++)if(s=await we(o[i]),s.exitCode!==0)return s;return s}async function Ho(e,t,r){let n=jr(e),o=t?.trim();if(!o&&(o=(await kc(`Plugin "${n}" could not be installed.
|
|
111
|
-
If a marketplace is needed, enter the source (owner/repo or URL), or press Enter to skip: `))?.trim(),!o))throw new Error("No marketplace source provided. Cannot retry install.");o=Uo(o),r?.(),Gr.debug(`[${n}] Adding marketplace via: claude plugin marketplace add ${o}`);try{let s=await execa("claude",["plugin","marketplace","add",o],{reject:!1});if(s.exitCode!==0)throw new Error(`Failed to add marketplace: ${s.stderr||"unknown error"}`);Gr.debug(`[${n}] Marketplace added successfully`);}catch(s){throw Vi(s)?new Vo:s}}var ah=6e4,Zt=class extends Error{url;isTimeout;isAuthError;constructor(t,r,n=false,o=false){super(t),this.name="GitCloneError",this.url=r,this.isTimeout=n,this.isAuthError=o;}};async function Qt(e,t){let r=await mkdtemp(join(tmpdir(),"flow-skills-")),n=simpleGit({timeout:{block:ah}}).env("GIT_TERMINAL_PROMPT","0").env("GIT_LFS_SKIP_SMUDGE","1"),o=t?["--depth","1","--branch",t]:["--depth","1"];try{return await n.clone(e,r,o),r}catch(s){await rm$1(r,{recursive:true,force:true}).catch(()=>{});let i=s instanceof Error?s.message:String(s),a=i.includes("block timeout")||i.includes("timed out"),l=i.includes("Authentication failed")||i.includes("could not read Username")||i.includes("Permission denied")||i.includes("Repository not found");throw a?new Zt("Clone timed out after 60s. Check your SSH keys or credentials.",e,true,false):l?new Zt(`Authentication failed for ${e}. Ensure you have access and credentials are configured.`,e,false,true):new Zt(`Failed to clone ${e}: ${i}`,e,false,false)}}async function er(e){let t=normalize(resolve(e)),r=normalize(resolve(tmpdir()));if(!t.startsWith(r+sep))throw new Error("Attempted to clean up directory outside of temp directory");await rm$1(e,{recursive:true,force:true});}async function Ir(e,t=["--version"]){try{return (await execa(e,t,{reject:!1})).exitCode===0}catch(r){if(r instanceof Error&&"code"in r&&r.code==="ENOENT")return false;throw r}}function ch(e){return typeof e=="object"&&e!==null&&e.source==="git-subdir"}function uh(e){return typeof e=="object"&&e!==null&&e.source==="url"}function dh(e){return typeof e=="object"&&e!==null&&e.source==="github"}function Jo(e,t){let r=e.source;if(ch(r)){let n=r.path?r.path.replace(/^\.\//,""):".",o=r.ref&&!/^[0-9a-f]{40}$/i.test(r.ref)?r.ref:void 0;return {cloneUrl:r.url,subPath:n||".",ref:o}}if(uh(r))return {cloneUrl:r.url,subPath:"."};if(dh(r))return {cloneUrl:`https://github.com/${r.repo}`,subPath:"."};if(typeof r=="string"){if(r.startsWith("https://")||r.startsWith("git@"))return {cloneUrl:r,subPath:"."};if((r.startsWith("./")||r===".")&&t){let n=r==="."?".":r.replace(/^\.\//,"")||".";return {cloneUrl:t,subPath:n}}}return null}var tr=I("claude-code.adapter");function mh(e,t){let r=e??"external";if(!t)return r;let n=t.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:[/?#]|$)/);if(!n)return r;let o=n[1],s=so();if(!be__default.existsSync(s))return r;try{let i=JSON.parse(be__default.readFileSync(s,"utf-8"));for(let[a,l]of Object.entries(i))if(l.source?.repo===o)return a}catch{}return r}async function jc(e,t){let r=e.catalogId?ge.getAdapter(e.catalogId):void 0,n=Jo(e,r?.source);if(!n)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let o=e.type==="bundle"||e.type==null,s=mh(e.catalogId,r?.source),i=t.scope??"user",a;o?a=Vs(s,e.name,"external"):a=join(ar(i==="user"?"global":"project"),e.name);let l=null;try{Jr(e.name),l=await Qt(n.cloneUrl,n.ref);let u=n.subPath==="."?l:join(l,n.subPath);if(be__default.existsSync(a)&&be__default.rmSync(a,{recursive:!0,force:!0}),be__default.mkdirSync(dirname(a),{recursive:!0}),be__default.cpSync(u,a,{recursive:!0}),o){let c=`${e.name}@${s}`,d=await Pc(),p={scope:i,installPath:a,version:"external",installedAt:new Date().toISOString(),origin:"external",providerId:"claude-code",type:e.type},m=d.plugins[c]??[];d.plugins[c]=[...m.filter(f=>f.scope!==i),p],$t(d),Ln(c,!0,i);}return {success:!0,message:`Installed ${e.name} from ${n.cloneUrl}`}}catch(u){return tr.debug(`[${e.name}] External catalog install failed: ${String(u)}`),{success:false,message:u instanceof Error?u.message:String(u)}}finally{l&&await er(l).catch(()=>{});}}async function Hi(e,t,r,n){try{await v(b.CLI_TOOL_INSTALLED,{tool_id:e,tool_type:r,source:"external",scope:Oo(n),version:"unknown",duration_ms:t,interface:H().interfaceType});}catch(o){tr.warn(`Failed to send external install metrics: ${String(o)}`);}}async function Uc(e,t,r){try{await v(b.CLI_TOOL_INSTALL_FAILED,{tool_id:e,tool_type:r,source:"external",error_code:t instanceof Error?t.name:"UNKNOWN",error_message:(t instanceof Error?t.message:String(t)).slice(0,500),interface:H().interfaceType});}catch(n){tr.warn(`Failed to send external install-failed metrics: ${String(n)}`);}}var fh={async install(e,t){if(e.origin===kr&&!e.installCommand&&!Fr(e.name))return jc(e,t);if(e.origin===kr&&e.installCommand){let r=e.type??"skill",n=await _n(e.installCommand,t.scope);return n.exitCode===0?(await Hi(e.name,n.duration_ms,r,t.scope),{success:true,message:`Installed ${e.name}`}):(await Uc(e.name,new Error(n.stderr||"Install failed"),r),{success:false,message:n.stderr||`Install failed with exit code ${n.exitCode}`})}if(Fr(e.name)){let r=e.type??"skill",n=Kr(e.name,t.scope);tr.debug(`[${e.name}] Attempting install: ${n}`);let o=await we(n);if(o.exitCode===0)return await Hi(e.name,o.duration_ms,r,t.scope),{success:true};tr.debug(`[${e.name}] First attempt failed, adding marketplace`),await Ho(e.name,t.marketplaceSource,()=>{});let s=await we(n);return s.exitCode===0?(await Hi(e.name,s.duration_ms,r,t.scope),{success:true}):(await Uc(e.name,new Error(s.stderr||"Install failed"),r),{success:false,message:s.stderr||`Install failed with exit code ${s.exitCode}`})}try{let r=await Ee(e.name,{...t,type:e.type});return {success:!0,message:`Installed ${e.name}@${r.version}`}}catch(r){return tr.debug(`[${e.name}] Plugin install failed: ${String(r)}`),{success:false,message:r instanceof Error?r.message:String(r)}}},async uninstall(e,t){await Ko(e,t);},getInstallPath(e,t){return ""}};function Fc(e){return {async install(t,r){if(t.origin===kr&&!t.installCommand&&!Fr(t.name))return jc(t,r);if(!t.installCommand)try{let o=await Ee(t.name,{...r,type:e});return {success:!0,message:`Installed ${t.name}@${o.version}`}}catch(o){return tr.debug(`[${t.name}] ${e} install failed: ${String(o)}`),{success:false,message:o instanceof Error?o.message:String(o)}}tr.debug(`[${t.name}] Executing install command: ${t.installCommand}`);let n=await _n(t.installCommand,r.scope);return n.exitCode===0?{success:true}:{success:false,message:n.stderr||`Install failed with exit code ${n.exitCode}`}},async uninstall(t,r){throw new Error(`${e.toUpperCase()} uninstall via claude CLI not supported \u2014 use: claude ${e} remove ${t}`)},getInstallPath(t,r){return ""}}}var Go=class{id="claude-code";name="Claude Code";async isAvailable(){return Ir("claude",["--version"])}getSupportedScopes(){return ["user","project","local"]}installers={bundle:fh,skill:Fc("skill"),mcp:Fc("mcp")}};function Wo(e,t){return {async install(r,n){if(!r.installCommand)return {success:false,message:"No install command provided"};let[o,...s]=r.installCommand.split(/\s+/).filter(Boolean);if(!o||!e.has(o))return {success:false,message:`Disallowed command: "${o??""}"`};let i=await execa(o,s,{reject:false});return i.exitCode===0?{success:true}:{success:false,message:i.stderr||`Install failed with exit code ${i.exitCode}`}},async uninstall(r,n){throw new Error(`MCP uninstall not supported \u2014 ${t.replace("<name>",r)}`)},getInstallPath(r,n){return ""}}}var hh=new Set(["gh"]),yh=Wo(hh,"use: gh copilot mcp remove <name>"),zo=class{id="copilot";name="GitHub Copilot";async isAvailable(){return await Ir("gh",["--version"])?Ir("gh",["copilot","--version"]):false}getSupportedScopes(){return ["user"]}installers={mcp:yh}};var Sh=new Set(["opencode"]),wh=Wo(Sh,"use: opencode config remove mcp <name>");function xh(e){return [`// Auto-generated by Flow CLI for OpenCode compatibility \u2014 plugin: ${e}`,"import { readFileSync, readdirSync, existsSync } from 'node:fs';","import { join, dirname } from 'node:path';","import { fileURLToPath } from 'node:url';","",`const CONTENT_DIR = join(dirname(fileURLToPath(import.meta.url)), '${e}-content');`,"","function loadContent() {"," for (const dir of ['skills', '.']) {"," const d = join(CONTENT_DIR, dir);"," if (!existsSync(d)) continue;"," const files = readdirSync(d)"," .filter(f => f.endsWith('.md') && f !== 'README.md' && f !== 'LICENSE.md')"," .sort();"," if (files.length) return files.map(f => readFileSync(join(d, f), 'utf-8')).join('\\n\\n---\\n\\n');"," }"," return '';","}","","export const Plugin = async () => ({ getBootstrapContent: () => loadContent() });"].join(`
|
|
112
|
-
`)}function Kc(){return {async install(e,t){let r=e.catalogId?ge.getAdapter(e.catalogId):void 0,n=Jo(e,r?.source);if(!n)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let o=null;try{o=await Qt(n.cloneUrl,n.ref);let s=n.subPath==="."?o:join(o,n.subPath),i=io(t.scope??"user"),a=join(s,".opencode","plugins");if(be__default.existsSync(a)){let l=be__default.readdirSync(a).filter(u=>u.endsWith(".js")||u.endsWith(".mjs"));if(l.length===0)return {success:!1,message:"No JS plugin file found in .opencode/plugins/"};be__default.mkdirSync(i,{recursive:!0}),be__default.copyFileSync(join(a,l[0]),join(i,`${e.name}.js`));}else {let l=join(i,`${e.name}-content`);be__default.existsSync(l)&&be__default.rmSync(l,{recursive:!0,force:!0}),be__default.mkdirSync(l,{recursive:!0}),be__default.cpSync(s,l,{recursive:!0}),be__default.mkdirSync(i,{recursive:!0}),be__default.writeFileSync(join(i,`${e.name}.js`),xh(e.name),"utf-8");}return {success:!0,message:`Installed ${e.name} for OpenCode`}}catch(s){return {success:false,message:s instanceof Error?s.message:String(s)}}finally{o&&await er(o).catch(()=>{});}},async uninstall(e,t){let r=io(t),n=join(r,`${e}.js`),o=join(r,`${e}-content`);be__default.existsSync(n)&&be__default.rmSync(n,{force:true}),be__default.existsSync(o)&&be__default.rmSync(o,{recursive:true,force:true});},getInstallPath(e,t){return join(io(t),`${e}.js`)}}}var Xo=class{id="opencode";name="OpenCode";async isAvailable(){return Ir("opencode",["--version"])}getSupportedScopes(){return ["user","project"]}installers={mcp:wh,skill:Kc(),bundle:Kc()}};var ht=new Do;ht.register(new Go);Gt()&&(ht.register(new zo),ht.register(new Xo));function Vc({itemName:e,itemType:t,onInstall:r,onClose:n}){let[o,s]=useState(false),[i,a]=useState(false),[l,u]=useState([]),[c,d]=useState(void 0);useEffect(()=>{ht.getAvailableProviders(t??"bundle").then(u).catch(()=>{});},[t]);let p=useCallback(h=>{h==="Install"?l.length>1?a(true):s(true):n();},[n,l.length]),m=useCallback(h=>{if(h==="Cancel"){a(false);return}let w=l.find(P=>P.name===h);w?(d(w.id),a(false),s(true)):a(false);},[l]),f=useCallback(h=>{let w=tc(h);w?r(w,c):s(false);},[r,c]),g=useCallback(()=>{s(false);},[]);if(i){let h=[...l.map(w=>w.name),"Cancel"];return jsx(ze,{itemName:`${e} \u2014 Choose provider`,actions:h,onAction:m,onClose:()=>a(false)},"provider")}return o?jsx(ze,{itemName:`${e} \u2014 Choose scope`,actions:Ql,descriptions:ec,onAction:f,onClose:g},"scope"):jsx(ze,{itemName:e,actions:["Install","Cancel"],onAction:p,onClose:n},"main")}function Jc({itemName:e,bundle:t,onInstall:r,onConfirm:n,onClose:o}){let s=S(f=>f.focus),[i,a]=useState(0),u=(t?.artifact.artifacts??[]).filter(f=>f.available),c=t!==void 0&&u.length===0,d=useMemo(()=>c?["Cancel"]:["Confirm Install","Cancel"],[c]);useEffect(()=>{a(0);},[t]);let p=useCallback((f,g)=>{g.upArrow?a(h=>Math.max(0,h-1)):g.downArrow?a(h=>Math.min(d.length-1,h+1)):g.return?d[i]==="Confirm Install"?n():o():g.escape&&o();},[d,i,n,o]);useInput(p,{isActive:s==="actionMenu"&&t!==void 0});let m=useCallback(f=>{f==="Install Bundle"?r():o();},[r,o]);return t?jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:t.title}),jsx(Box,{marginTop:1,children:jsxs(Text,{children:[u.length," artifact",u.length!==1?"s":""," available"]})}),jsx(Box,{flexDirection:"column",marginTop:1,marginBottom:1,children:u.map(f=>{let g=f.name??f.flowId,h=f.type??"unknown";return jsxs(Box,{gap:1,children:[jsx(Text,{color:"green",children:"\u2713"}),jsx(Text,{children:g}),jsxs(Text,{dimColor:true,children:["(",h,")"]})]},f.flowId)})}),jsx(Box,{flexDirection:"column",children:d.map((f,g)=>jsx(Box,{children:jsxs(Text,{bold:g===i,color:g===i?"cyan":void 0,children:[g===i?"\u203A ":" ",f]})},f))})]}):jsx(ze,{itemName:e,actions:["Install Bundle","Cancel"],onAction:m,onClose:o})}function Zo({activeFocus:e,onConfirm:t}){let[r,n]=useState("idle"),o=S(s=>s.focus);return useInput((s,i)=>{i.escape||s==="n"?n("idle"):s==="y"&&t();},{isActive:r==="confirming"&&o===e}),{isConfirming:r==="confirming",requestConfirm:()=>n("confirming"),cancelConfirm:()=>n("idle")}}function zc({itemName:e,itemScope:t,itemStatus:r,updateAvailable:n,catalogVersion:o,onUninstall:s,onToggleStatus:i,onUpdate:a,onClose:l}){let{isConfirming:u,requestConfirm:c}=Zo({activeFocus:"actionMenu",onConfirm:()=>s(t)});if(u)return jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Uninstall "}),jsx(Text,{bold:true,color:"red",children:e}),jsx(Text,{children:"? (y/N)"})]})]});let d=r==="enabled"?"Disable":"Enable",p=o&&y(o),m=p?`Update to v${p}`:"Update";return jsx(ze,{itemName:e,actions:n?["Uninstall",d,m,"Cancel"]:["Uninstall",d,"Cancel"],onAction:h=>{h==="Uninstall"?c():h===d?i(t):h.startsWith("Update")?a?.():l();},onClose:l})}function Yc({itemName:e,itemScope:t,onUninstall:r,onClose:n}){let{isConfirming:o,requestConfirm:s}=Zo({activeFocus:"actionMenu",onConfirm:()=>r(t)});return o?jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Remove MCP "}),jsx(Text,{bold:true,color:"red",children:e}),jsx(Text,{children:"? (y/N)"})]})]}):jsx(ze,{itemName:e,actions:["Uninstall","Cancel"],onAction:l=>{l==="Uninstall"?s():n();},onClose:n})}var qr=I("bundle:installer"),Zc=/already exists/i;async function kh(e){if(!e.installCommand)throw new Error("Missing install command");let t=e.installCommand;if(Mc(t)){let r=await Lc(t);if(r.exitCode!==0){let n=r.stderr?.trim()||r.stdout?.trim()||`exit code ${r.exitCode}`;if(Zc.test(n))return;throw new Error(n)}}else {let r=await _n(t);if(r.exitCode!==0){let n=r.stderr?.trim()||r.stdout?.trim()||`exit code ${r.exitCode}`;if(Zc.test(n))return;throw new Error(n)}}}async function Ah(e,t){try{await v(b.CLI_BUNDLE_INSTALL_STARTED,{bundle_slug:e,artifact_count:t});}catch(r){qr.warn(`Failed to emit bundle install started event: ${String(r)}`);}}async function $h(e,t,r){try{await v(b.CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS,{bundle_slug:e,artifact_name:t,artifact_type:r});}catch(n){qr.warn(`Failed to emit bundle install plugin success event: ${String(n)}`);}}async function Qc(e,t,r,n){try{await v(b.CLI_BUNDLE_INSTALL_PLUGIN_FAILED,{bundle_slug:e,artifact_name:t,artifact_type:r,error_message:n});}catch(o){qr.warn(`Failed to emit bundle install plugin failed event: ${String(o)}`);}}async function Mh(e,t,r,n,o){try{await v(b.CLI_BUNDLE_INSTALL_COMPLETED,{bundle_slug:e,installed_count:t,failed_count:r,unavailable_count:n,duration_ms:o});}catch(s){qr.warn(`Failed to emit bundle install completed event: ${String(s)}`);}}async function ts(e,t={}){let{onProgress:r}=t,n=e.artifact.artifacts,o=n.filter(m=>m.available),s=n.length-o.length,i=e.artifact.name,a=Date.now();await Ah(i,o.length);let l=[],u=0,c=o.length;for(let[m,f]of o.entries()){let g=f.name??f.flowId,h=f.type??"unknown";if(!f.type){qr.warn(`Artifact "${g}" has no type \u2014 treated as failed`),l.push({name:g,type:h,reason:"unknown artifact type"}),await Qc(i,g,h,"unknown artifact type"),r?.({index:m+1,total:c,artifact:f,success:false,error:"unknown artifact type"});continue}try{await kh(f),u++,await $h(i,g,h),r?.({index:m+1,total:c,artifact:f,success:!0});}catch(w){let P=w instanceof Error?w.message:String(w);qr.error(`Failed to install artifact "${g}": ${P}`),l.push({name:g,type:h,reason:P}),await Qc(i,g,h,P),r?.({index:m+1,total:c,artifact:f,success:false,error:P});}}let d=Date.now()-a,p=l.length;return await Mh(i,u,p,s,d),{bundleTitle:e.title,total:n.length,installed:u,skipped:s,failed:p,failures:l}}function nu({bundle:e,onComplete:t}){let[r,n]=useState(null),[o,s]=useState(null),i=useRef(false);return useEffect(()=>{i.current||(i.current=true,ts(e,{onProgress:n}).then(s).catch(a=>{let l=a instanceof Error?a.message:"Installation failed",u=e.artifact.artifacts,c=u.filter(d=>d.available);s({bundleTitle:e.title,total:u.length,installed:0,skipped:u.length-c.length,failed:c.length,failures:c.map(d=>({name:d.name??d.flowId,type:d.type??"unknown",reason:l}))});}));},[e]),useEffect(()=>{o&&t(o);},[o,t]),jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsx(Box,{paddingBottom:1,children:jsxs(Text,{bold:true,children:["Installing ",e.title,"..."]})}),r&&jsxs(Box,{gap:1,children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{color:"cyan",children:["[",r.index,"/",r.total,"] Installing"," ",r.artifact.name??r.artifact.flowId," (",r.artifact.type??"unknown",")"]})]}),!r&&jsxs(Box,{gap:1,children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsx(Text,{color:"cyan",children:"Preparing..."})]})]})}var ue=create(e=>({installedItems:[],setInstalledItems:t=>e({installedItems:t}),loadFromDisk:()=>e({installedItems:se()})}));function ou({entries:e,selectedIndex:t,focusPanel:r}){let n=r==="list",o=t===0&&n;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{marginBottom:1,children:[jsx(Text,{color:"cyan",bold:true,children:o?"\u203A ":" "}),jsx(Text,{color:"cyan",bold:o,dimColor:!n,children:"+ Add Marketplace"})]}),e.map((s,i)=>{let a=i+1,l=t===a&&n,u=s.stored?.autoUpdate!==false;return jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:"cyan",children:l?"\u203A ":" "}),jsx(Text,{bold:l,dimColor:!n,children:s.adapter.name}),u&&s.stored&&jsx(Text,{color:"yellow",children:" \u2605"})]}),s.stored?.lastUpdated&&jsx(Box,{marginLeft:2,children:jsxs(Text,{dimColor:true,children:["Updated ",jt(s.stored.lastUpdated)]})})]},s.adapter.id)})]})}function su({entry:e,detailData:t,installedCount:r,focusPanel:n,actionIndex:o,onBrowse:s,onUpdate:i,onToggleAutoUpdate:a,onRemove:l}){let{adapter:u,stored:c}=e,d=u.removable!==false,p=c?.autoUpdate!==false,m=n==="detail",f=[{label:`Browse plugins${t&&!t.loading?` (${t.items.length})`:""}`,handler:s},{label:"Update marketplace",handler:i},...d?[{label:"Toggle auto-update",handler:a},{label:"Remove marketplace",handler:l,danger:true}]:[]];return m?jsxs(Box,{flexDirection:"column",paddingLeft:1,children:[jsx(Text,{bold:true,children:u.name}),jsx(Text,{dimColor:true,children:u.source}),jsx(Box,{marginTop:1,children:t?.loading?jsx(Text,{dimColor:true,children:"Loading..."}):t?.error?jsx(Text,{color:"red",children:t.error}):jsxs(Text,{dimColor:true,children:[t?`${t.items.length} available`:"\u2014 available",r>0?` \xB7 ${r} installed`:"",c?.lastUpdated?` \xB7 Updated ${jt(c.lastUpdated)}`:""]})}),c&&jsxs(Box,{marginTop:1,children:[jsx(Text,{dimColor:true,children:"Auto-update: "}),p?jsx(Text,{color:"green",children:"enabled \u2605"}):jsx(Text,{dimColor:true,children:"disabled"})]}),jsx(Box,{flexDirection:"column",marginTop:1,children:f.map((g,h)=>{let w=h===o;return jsxs(Box,{children:[jsx(Text,{color:w?"cyan":void 0,children:w?"\u203A ":" "}),jsx(Text,{bold:w,color:g.danger?"yellow":void 0,dimColor:!w,children:g.label})]},g.label)})})]}):jsxs(Box,{flexDirection:"column",paddingLeft:1,children:[jsx(Text,{bold:true,children:u.name}),jsx(Text,{dimColor:true,children:u.source}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter or Tab to see details"})})]})}function iu(e){return e.adapter.removable!==false?4:2}function au({item:e,adapterName:t,isInstalled:r,onBack:n,onInstall:o,onUninstall:s}){let i=[...r&&s?[{label:"Uninstall",handler:()=>s(e),danger:true}]:!r&&o?[{label:"Install",handler:()=>o(e)}]:[],{label:"Back",handler:n}],[a,l]=useState(0);return useInput((u,c)=>{if(c.escape){n();return}if(c.upArrow){l(d=>Math.max(0,d-1));return}if(c.downArrow){l(d=>Math.min(i.length-1,d+1));return}c.return&&i[a].handler();}),jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",t," \u203A Browse plugins \u203A ",y(e.name)]}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{bold:true,children:y(e.name)}),e.type&&jsxs(Text,{dimColor:true,children:[" [",y(e.type),"]"]}),e.origin&&jsxs(Text,{dimColor:true,children:[" [",y(e.origin),"]"]})]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2500".repeat(50)})}),e.description?jsx(Box,{marginTop:1,children:jsx(Text,{children:y(e.description)})}):null,(e.author?.name||e.version||e.category)&&jsxs(Box,{flexDirection:"column",marginTop:1,children:[e.author?.name&&jsxs(Text,{dimColor:true,children:["Author ",y(e.author.name)]}),e.version&&jsxs(Text,{dimColor:true,children:["Version ",y(e.version)]}),e.category&&jsxs(Text,{dimColor:true,children:["Category ",y(e.category)]})]})]}),jsx(Box,{flexDirection:"column",marginTop:1,children:i.map((u,c)=>jsxs(Box,{children:[jsx(Text,{color:c===a?"cyan":void 0,children:c===a?"\u203A ":" "}),jsx(Text,{bold:c===a,color:u.danger?"yellow":void 0,dimColor:c!==a,children:u.label})]},u.label))}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter: confirm \xB7 Esc: back"})})]})}function cu({item:e,isSelected:t,isInstalled:r}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{color:"cyan",children:t?"\u203A ":" "}),jsx(Text,{color:r?"green":void 0,bold:t,children:e.name}),r&&jsx(Text,{color:"green",children:" \u2713"})]}),e.description?jsx(Box,{paddingLeft:4,children:jsx(Text,{dimColor:true,wrap:"truncate",children:e.description})}):null]})}function uu({entry:e,items:t,installedKeys:r,onBack:n}){let o=e.adapter.id??"default",s=t.filter($=>r.has(`${$.name}@${o}`)),i=t.filter($=>!r.has(`${$.name}@${o}`)),a=[...s,...i],[l,u]=useState(0),[c,d]=useState(null);if(useInput(($,O)=>{if(O.escape){n();return}if(O.return){d(a[l]??null);return}if(O.upArrow){u(G=>Math.max(0,G-1));return}O.downArrow&&u(G=>Math.min(a.length-1,G+1));},{isActive:c===null}),c!==null)return jsx(au,{item:c,adapterName:e.adapter.name,isInstalled:r.has(`${c.name}@${o}`),onBack:()=>d(null)});if(t.length===0)return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",e.adapter.name," \u203A Browse plugins"]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Empty catalog"})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Esc: back"})})]});let p=Math.max(0,l-Math.floor(Ve/2)),m=Math.min(a.length,p+Ve);m===a.length&&(p=Math.max(0,m-Ve));let f=a.slice(p,m),g=p,h=a.length-m,w=s.length>0&&p<s.length,P=m>s.length,C=f.filter($=>r.has(`${$.name}@${o}`)),k=f.filter($=>!r.has(`${$.name}@${o}`));return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",e.adapter.name," \u203A Browse plugins"]}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:g>0?`\u2191 ${g} more above`:" "})}),w&&jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{dimColor:true,children:["\u2500\u2500 Installed (",s.length,") \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"]}),C.map($=>jsx(cu,{item:$,isSelected:a.indexOf($)===l,isInstalled:true},$.name))]}),P&&jsxs(Box,{flexDirection:"column",marginTop:w?1:0,children:[jsxs(Text,{dimColor:true,children:["\u2500\u2500 Available (",i.length,") \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"]}),k.map($=>jsx(cu,{item:$,isSelected:a.indexOf($)===l,isInstalled:false},$.name))]}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:h>0?`\u2193 ${h} more below`:" "})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter: details \xB7 Esc: back"})})]})}Ti();var Bh=/^https?:\/\/.+/;function Uh(e){return e!==null&&typeof e=="object"&&"response"in e&&e.response?.status===404}function Fh(e){return e instanceof Error&&e.code==="GITHUB_AUTH_REQUIRED"}function fu(e){let t=S(h=>h.showNotification),r=S(h=>h.incrementCatalogVersion),[n,o]=useState("idle"),[s,i]=useState(""),[a,l]=useState(""),[u,c]=useState(null),d=useRef(""),p=useRef("");useEffect(()=>{d.current=s;},[s]),useEffect(()=>{p.current=a;},[a]);let m=useCallback(()=>{d.current="",p.current="",i(""),l(""),c(null),o("add-name");},[]),f=useCallback(()=>{o("idle");},[]),g=useCallback(async()=>{let h=p.current,w=d.current;if(!Bh.test(h)){c("URL must start with http:// or https://");return}c(null),o("adding");let P=randomUUID(),C=new Vr(P,w,h);try{await C.fetchItems(),await At.add({id:P,name:w,source:h}),ge.register(new Vr(P,w,h)),r(),e(),t(`Catalog "${w}" added`,"success"),i(""),l(""),d.current="",p.current="",o("idle");}catch(k){let $=Uh(k)?"No marketplace.json found in this repository (checked main and master branches). Ensure the repo has a marketplace.json at its root.":Fh(k)?k.message:k instanceof Error?`Could not reach catalog URL: ${k.message}`:"Failed to validate catalog URL";t($,"error"),o("add-url");}},[e,t,r]);return useInput((h,w)=>{if(w.escape){o("idle");return}if(w.return){d.current.trim().length>0&&o("add-url");return}if(w.backspace||w.delete){d.current=d.current.slice(0,-1),i(d.current);return}h&&!w.ctrl&&!w.meta&&(d.current=d.current+h,i(d.current));},{isActive:n==="add-name"}),useInput((h,w)=>{if(w.escape){o("add-name");return}if(w.return){g();return}if(w.backspace||w.delete){p.current=p.current.slice(0,-1),l(p.current),c(null);return}h&&!w.ctrl&&!w.meta&&(p.current=p.current+h,l(p.current),c(null));},{isActive:n==="add-url"}),{phase:n,inputName:s,inputUrl:a,urlError:u,setInputName:i,setInputUrl:l,startAdd:m,cancelAdd:f}}function gu(e){let t=S(o=>o.showNotification),r=S(o=>o.incrementCatalogVersion);return {handleRemove:useCallback(async o=>{try{await At.remove(o),ge.unregister(o),r(),e(),t("Catalog removed","success");}catch(s){t(s instanceof Error?s.message:"Failed to remove catalog","error");}},[e,t,r])}}function yu(){let e=S(L=>L.focus),t=S(L=>L.setFocus),r=S(L=>L.showNotification),n=ue(L=>L.installedItems),[o,s]=useState(()=>ge.listAdapters().map(L=>({adapter:L,stored:null}))),[i,a]=useState(0),[l,u]=useState("list"),[c,d]=useState(0),[p,m]=useState(null),[f,g]=useState("main"),h=useRef(o);useEffect(()=>{h.current=o;},[o]),useEffect(()=>{f==="browse"&&!o[i-1]&&g("main");},[f,o,i]);let w=useCallback(()=>{(async()=>{let L=ge.listAdapters(),N=await At.read(),V=new Map(N.map(Ie=>[Ie.id,Ie]));s(L.map(Ie=>({adapter:Ie,stored:V.get(Ie.id)??null})));})();},[]);useEffect(()=>{t("marketplaces"),w();},[t,w]),useEffect(()=>{if(i===0){m(null);return}let L=h.current[i-1];if(!L)return;let N=false;return m({items:[],loading:true,error:null}),L.adapter.fetchItems().then(V=>{N||m({items:V,loading:false,error:null});}).catch(V=>{N||m({items:[],loading:false,error:V instanceof Error?V.message:"Failed to load catalog"});}),()=>{N=true;}},[i]);let P=fu(w),C=useCallback(()=>{w(),a(0),u("list"),m(null),g("main");},[w]),{handleRemove:k}=gu(C),$=useCallback(async L=>{g("removing"),await k(L);},[k]),O=useCallback(async L=>{try{let N=await L.adapter.fetchItems();if(m({items:N,loading:!1,error:null}),L.stored){let V=new Date().toISOString();await At.updateField(L.stored.id,{lastUpdated:V}),w();}r("Marketplace updated","success");}catch(N){r(N instanceof Error?N.message:"Update failed","error");}},[w,r]),G=useCallback(async L=>{if(!L.stored)return;let N=L.stored.autoUpdate!==false;await At.updateField(L.stored.id,{autoUpdate:!N}),w();},[w]),ye=useCallback(()=>g("browse"),[]),M=useCallback(L=>{let N=o[i-1];if(!N)return;let V=N.adapter.removable!==false;[ye,()=>{O(N);},...V?[()=>{G(N);},()=>{$(N.adapter.id);}]:[]][L]?.();},[o,i,ye,O,G,$]),x=useCallback(()=>g("main"),[]),A=useCallback(()=>{let L=o[i-1];L&&O(L);},[o,i,O]),F=useCallback(()=>{let L=o[i-1];L&&G(L);},[o,i,G]),W=useCallback(()=>{let L=o[i-1];L&&$(L.adapter.id);},[o,i,$]);if(useInput((L,N)=>{if(N.upArrow){a(V=>Math.max(0,V-1));return}if(N.downArrow){a(V=>Math.min(o.length,V+1));return}(N.return||N.tab)&&(i===0?P.startAdd():(u("detail"),d(0)));},{isActive:f==="main"&&P.phase==="idle"&&l==="list"&&e==="marketplaces"}),useInput((L,N)=>{if(N.escape||N.tab){u("list");return}if(N.upArrow){d(V=>Math.max(0,V-1));return}if(N.downArrow){let V=o[i-1],Ie=V?iu(V)-1:0;d(Ns=>Math.min(Ns+1,Ie));return}N.return&&M(c);},{isActive:f==="main"&&P.phase==="idle"&&l==="detail"&&e==="marketplaces"}),P.phase==="add-name")return jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Text,{bold:true,children:"Add Catalog \u2014 Step 1/2"}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Name: "}),jsx(Text,{color:"cyan",children:P.inputName}),jsx(Text,{color:"gray",children:"\u2588"})]}),P.inputName.trim().length===0&&jsx(Text,{dimColor:true,children:"Enter a display name for this catalog"}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter: next | Esc: cancel"})})]});if(P.phase==="add-url")return jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Text,{bold:true,children:"Add Catalog \u2014 Step 2/2"}),jsxs(Box,{marginTop:1,children:[jsx(Text,{dimColor:true,children:"Name: "}),jsx(Text,{children:P.inputName})]}),jsxs(Box,{children:[jsx(Text,{children:"URL: "}),jsx(Text,{color:"cyan",children:P.inputUrl}),jsx(Text,{color:"gray",children:"\u2588"})]}),P.urlError&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"red",children:P.urlError})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter: confirm | Esc: back | Must start with http:// or https://"})})]});if(P.phase==="adding")return jsx(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:jsx(Text,{children:"Validating catalog URL..."})});if(f==="removing")return jsx(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:jsx(Text,{children:"Removing catalog..."})});if(f==="browse"){let L=o[i-1];if(!L)return jsx(Box,{});let N=L.adapter.id??"default",V=new Set(n.filter(Ie=>Ie.marketplace===L.adapter.name).map(Ie=>`${Ie.name}@${N}`));return jsx(uu,{entry:L,items:p?.items??[],installedKeys:V,onBack:x})}if(o.length===0)return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsx(Box,{paddingX:1,marginBottom:1,children:jsx(Text,{bold:true,children:"Marketplaces"})}),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:"No catalogs registered"})}),jsx(Box,{marginTop:1,paddingX:1,children:jsx(Text,{dimColor:true,children:"Enter or Tab: add marketplace \xB7 \u2190\u2192: switch tab"})})]});let Et=o[i-1]??null,pn=Et?n.filter(L=>L.marketplace===Et.adapter.name).length:0;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Box,{flexDirection:"column",width:30,marginRight:1,children:jsx(ou,{entries:o,selectedIndex:i,focusPanel:l})}),jsx(Box,{flexDirection:"column",flexGrow:1,children:l==="detail"&&Et?jsx(su,{entry:Et,detailData:p,installedCount:pn,focusPanel:l,actionIndex:c,onBrowse:ye,onUpdate:A,onToggleAutoUpdate:F,onRemove:W}):jsx(Box,{paddingLeft:1,children:jsx(Text,{dimColor:true,children:Et?"Enter or Tab to see details":"\u2191\u2193 to navigate, Enter or Tab to see details"})})})]}),jsx(Box,{marginTop:1,paddingX:1,children:l==="list"?jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter / Tab: see details \xB7 \u2190\u2192: switch tab"}):jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate actions \xB7 Enter: execute \xB7 Esc / Tab: back to list"})})]})}function Su(e,t,r,n){if(t.upArrow)return r.selectedIndex===0?[{type:"setSelectedIndex",index:-1},{type:"setFocus",focus:"search"}]:[{type:"setSelectedIndex",index:r.selectedIndex-1}];if(t.downArrow&&r.selectedIndex<n-1)return [{type:"setSelectedIndex",index:r.selectedIndex+1}];if(t.leftArrow){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o-1+X.length)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}if(t.rightArrow){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o+1)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}if(t.tab){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o+1)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}return t.return?[{type:"setActionMenuOpen",open:true},{type:"setFocus",focus:"actionMenu"}]:e==="/"?[{type:"setFocus",focus:"search"}]:e==="1"?[{type:"selectAllTypes"}]:e==="2"?[{type:"toggleTypeFilter",catalogType:"skill"}]:e==="3"?[{type:"toggleTypeFilter",catalogType:"mcp"}]:e==="4"?[{type:"toggleTypeFilter",catalogType:"bundle"}]:e==="5"?[{type:"selectAllOrigins"}]:e==="6"?[{type:"toggleOriginFilter",origin:"internal"}]:e==="7"?[{type:"toggleOriginFilter",origin:"external"}]:e==="a"&&r.activeTab==="updates"?[]:e&&e!==" "&&!t.ctrl&&!t.meta&&!t.escape?[{type:"setSelectedIndex",index:-1},{type:"setFocus",focus:"search"},{type:"searchAppend",char:e}]:[]}function wu(e,t){return t.escape?[{type:"setActionMenuOpen",open:false},{type:"setFocus",focus:"list"}]:[]}function xu(e,t,r){return t.escape?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:"reset"}:t.downArrow?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:null}:t.leftArrow?{actions:[],queryUpdate:{cursorMove:-1}}:t.rightArrow?{actions:[],queryUpdate:{cursorMove:1}}:t.return?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:null}:t.backspace?r.length===0?{actions:[{type:"setFocus",focus:"list"},{type:"setSelectedIndex",index:0}],queryUpdate:null}:{actions:[],queryUpdate:{backspace:true}}:e&&!t.ctrl&&!t.meta?{actions:[],queryUpdate:{append:e}}:{actions:[],queryUpdate:null}}var Jh=new Set(X.filter(e=>e.focus!=="list").map(e=>e.focus));function Hn(e){let{setActiveTab:t,setFocus:r,setSelectedIndex:n,setActionMenuOpen:o}=S.getState();for(let s of e)if(s.type==="setTab")t(s.tab);else if(s.type==="setFocus")r(s.focus);else if(s.type==="setSelectedIndex")n(s.index);else if(s.type==="setActionMenuOpen")o(s.open);else if(s.type==="searchAppend"){let{setQuery:i,query:a,setCursorPosition:l,cursorPosition:u}=Oe.getState();i(a.slice(0,u)+s.char+a.slice(u)),l(u+s.char.length);}else s.type==="toggleTypeFilter"?S.getState().toggleTypeFilter(s.catalogType):s.type==="selectAllTypes"?S.getState().selectAllTypes():s.type==="toggleOriginFilter"?S.getState().toggleOriginFilter(s.origin):s.type==="selectAllOrigins"&&S.getState().selectAllOrigins();}function Iu({listLength:e}){let t=S(g=>g.focus),r=S(g=>g.selectedIndex),n=S(g=>g.actionMenuOpen),o=S(g=>g.setFocus),s=S(g=>g.setActionMenuOpen),i=Oe(g=>g.query),a=Oe(g=>g.setQuery),l=Oe(g=>g.resetQuery),u=useRef(e);useEffect(()=>{u.current=e;},[e]),useEffect(()=>{if(t==="search"){let{query:g,setCursorPosition:h}=Oe.getState();h(g.length);}},[t]);let[c,d]=useState("");useEffect(()=>{let g=setTimeout(()=>d(i),300);return ()=>clearTimeout(g)},[i]),useInput((g,h)=>{let{activeTab:w,selectedIndex:P,actionMenuOpen:C}=S.getState();Hn(fi(g,h,{activeTab:w}));},{isActive:t==="tabs"}),useInput((g,h)=>{if(!h.leftArrow&&!h.rightArrow)return;let{activeTab:w,selectedIndex:P,actionMenuOpen:C}=S.getState();Hn(fi("",h,{activeTab:w}));},{isActive:Jh.has(t)}),useInput((g,h)=>{let{activeTab:w,selectedIndex:P,actionMenuOpen:C}=S.getState();Hn(Su(g,h,{activeTab:w,selectedIndex:P},u.current));},{isActive:t==="list"}),useInput((g,h)=>{Hn(wu(g,h));},{isActive:t==="actionMenu"}),useInput((g,h)=>{let w=xu(g,h,Oe.getState().query),P=w.queryUpdate;if(Hn(w.actions),P==="reset")l(),d("");else if(P!==null){let{query:C,cursorPosition:k,setCursorPosition:$}=Oe.getState();if("backspace"in P)k>0&&(a(C.slice(0,k-1)+C.slice(k)),$(k-1));else if("append"in P)a(C.slice(0,k)+P.append+C.slice(k)),$(k+P.append.length);else if("cursorMove"in P){let O=k+P.cursorMove;O>=0&&O<=C.length&&$(O);}}},{isActive:t==="search"});let p=useCallback(()=>{s(false),o("list");},[s,o]),m=useCallback(g=>{let{setSelectedIndex:h,selectedIndex:w}=S.getState();g===0?h(0):w>=g&&h(g-1);},[]),f=useCallback(g=>{if(!c)return u.current=g.length,g;let h=c.toLowerCase(),w=g.filter(P=>P.name.toLowerCase().includes(h)||P.description?.toLowerCase().includes(h));return u.current=w.length,w},[c]);return {actionMenuOpen:n,closeMenu:p,selectedIndex:r,clampIndex:m,filteredItems:f}}function vu(){let e=S(a=>a.notification),t=S(a=>a.showNotification),r=S(a=>a.clearNotification),n=Ge(a=>a.justAuthenticated),o=Ge(a=>a.credentials),s=Ge(a=>a.setJustAuthenticated);return useEffect(()=>{n&&o&&(t(`Authenticated. Tenant: ${o.tenant}`,"success"),s(false));},[n,o]),useEffect(()=>{if(!e)return;let a=setTimeout(r,3e3);return ()=>clearTimeout(a)},[e]),{notify:(a,l)=>{t(a,l);}}}function Te(e,t,r=false){return r?true:!Xi.valid(e)||!Xi.valid(t)?false:Xi.gt(t,e)}var _t=I("updater");async function Gh(e,t,r,n,o,s){try{await v(b.CLI_TOOL_UPDATED,{tool_id:e,tool_type:s,source:o,from_version:t,to_version:r,duration_ms:n,interface:H().interfaceType});}catch(i){_t.warn(`Failed to send update metrics: ${String(i)}`);}}function Wh(e){let t=Mt(),r=`${e}@${re}`,n=t.plugins[r];return !n||n.length===0?null:{pluginKey:r,entry:n[0]}}async function ss(e,t={}){let r=Date.now(),n=null;try{_t.debug(`[${e}] Acquiring lock...`),n=await qt();let o=Wh(e);if(!o)throw _t.error(`[${e}] Plugin is not installed`),new Error(`Plugin "${e}" is not installed`);let{entry:s}=o,i=s.version,a=s.installPath;_t.debug(`[${e}] Fetching manifest...`);let u=(await Hr(e)).version;if(!i||!Te(i,u,t.force))throw _t.debug(`[${e}] Already up to date (v${i??"n/a"})`),new zt(e,i??"unknown");_t.info(`[${e}] Updating v${i} \u2192 v${u}...`),await n(),n=null;try{let c=await Ee(e,{force:!0,skipMetrics:!0}),d=Date.now()-r;return await Gh(c.name,i,c.version,d,s.origin??"internal",s.type??"skill"),_t.debug(`[${e}] Updated successfully in ${d}ms`),{name:c.name,previousVersion:i,newVersion:c.version,path:c.path,duration_ms:d}}catch(c){_t.warn(`[${e}] Install failed, rolling back to v${i}...`),n=await qt();let d=Mt(),p=`${e}@${re}`;throw d.plugins[p]&&(d.plugins[p][0].version=i,d.plugins[p][0].installPath=a,$t(d),_t.info(`[${e}] Rollback completed, restored to v${i}`)),c}}finally{n&&await n();}}var is=I("dispatcher");async function zh(e,t,r,n,o){let s=jr(e);return is.debug(`[${e}] Install failed (exit code), attempting marketplace add`),o?.onError?.(r),n?o?.onStatus?.(`Adding marketplace for ${s}...`):o?.onPause?.(),await Ho(e,n,()=>{}),o?.onResume?.(`Retrying install for ${s}...`),is.debug(`[${e}] Retrying install after marketplace add`),we(t)}async function Eu(e,t,r,n){let o=Kr(e,n),s=jr(e);r?.onStatus?.(`Installing ${s}...`),is.debug(`[${e}] Attempting install: ${o}`);let i=await we(o);if(i.exitCode===0)return i;is.debug(`[${e}] Install failed (exit ${i.exitCode}), attempting marketplace add`);let a=i.stderr||`Install failed with exit code ${i.exitCode}`;return zh(e,o,a,t,r)}async function Pu(e,t,r){let n=e.type??"bundle",o=await ht.getAvailableProviders(n),s=o[0];if(!s)throw new Error(`No available provider for artifact type "${n}"`);let i=s.installers[n];if(!i)throw new Error(`Provider "${s.id}" does not support type "${n}"`);let a=t??{},l=a;return i.install(e,l)}function Tu(){let e=ue(i=>i.installedItems),t=ue(i=>i.loadFromDisk),r=useCallback(async(i,a)=>{let l=await Pu(i,a);if(!l.success)throw new Error(l.message||"Installation failed");t();},[t]),n=useCallback(async(i,a)=>{let l=se().find(m=>m.name===i),u=l?.providerId??"claude-code",c=ht.getAdapter(u);if(!c)throw new Error(`Provider "${u}" not found`);let d=l?.type??"bundle",p=c.installers[d];if(!p)throw new Error(`Provider "${u}" does not support type "${d}"`);await p.uninstall(i,a??"user"),t();},[t]),o=useCallback(async(i,a)=>{let u=e.find(c=>c.name===i)?.status==="enabled"?"disabled":"enabled";await Rn(i,u,a),t();},[e,t]),s=useCallback(async i=>{await ss(i),t();},[t]);return {install:r,uninstall:n,toggle:o,update:s}}var ls=I("mcp");function Jn(e,t){e.silent?Je({status:"error",mcp:t.name,...t.exitCode!==void 0&&{exitCode:t.exitCode},message:t.message}):E(`Failed to ${t.action} MCP "${t.name}": ${t.message}`);}function ku(e,t){e.silent?_e({status:"success",mcp:t.name,command:t.command,duration_ms:t.durationMs}):(ne(`MCP "${t.name}" ${t.actionPastTense} successfully`),e.verbose&&t.stdout&&T(t.stdout));}function Xh(e,t,r,n){let o=["claude","mcp","add","--transport",r,e];return t.length>0&&o.push(...t),n&&o.push("--scope",n),o.join(" ")}function qi(e,t){if(e.startsWith("-"))throw new Error(`Invalid MCP server name: "${e}". Names must not start with '-'.`);let r=["claude","mcp","remove",e];return t&&r.push("--scope",t),r.join(" ")}async function Au(e,t,r){if(!await fe())return 1;if(t.length===0){let s=r.transport==="http"?"a URL":"a command";return Jn(r,{name:e,action:"add",message:`${r.transport} transport requires ${s}`}),1}ls.debug(`[${e}] Starting MCP add with args: ${t.join(" ")}`);let n=Xh(e,t,r.transport,r.scope);if(!r.force){let s=y(e),i=y(n);if(!await gt(`Install external MCP "${s}"?
|
|
110
|
+
`),this.warned=true;}xo().set(`${t}:${r}`,n);}async deleteSecret(t,r){let n=xo(),o=`${t}:${r}`;return n.has(o)?(n.delete(o),true):false}getStoragePath(){return xo().path}static hasExistingData(){try{let t=new si({projectName:ii});return he.existsSync(t.path)}catch{return false}}static clearFallbackFile(){try{let t=new si({projectName:ii});he.rmSync(t.path,{force:!0});}catch{}Io=null;}};async function ai(){if(Ne.hasExistingData())return new Ne;switch(process.platform){case "darwin":return await Nr.isAvailable()?new Nr:new Ne;case "linux":return await zt.isAvailable()?new zt:await zt.ensureInstalled()?new zt:new Ne;case "win32":return await Fr.isAvailable()?new Fr:new Ne;default:throw new Error(`Unsupported platform: ${process.platform}`)}}var _m=I("config:credentials"),Rt="flow-plugins-cli",li="credentials",ci="token-cache",ui="user-info",Po=null;async function Xt(){return Po||(Po=ai()),Po}function Eo(){Po=null;}async function oe(){let t=await(await Xt()).getSecret(Rt,li);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function _t(e){let{clientId:t,clientSecret:r,tenant:n}=e,o=[!t?.trim()&&"clientId",!r?.trim()&&"clientSecret",!n?.trim()&&"tenant"].filter(Boolean);if(o.length>0)throw _m.error(`missing or empty fields: ${o.join(", ")}`),new Error("Cannot save credentials: clientId, clientSecret, and tenant are required");await(await Xt()).setSecret(Rt,li,JSON.stringify(e));}async function rl(){let e=await Xt();await e.deleteSecret(Rt,li),await e.deleteSecret(Rt,ci),await e.deleteSecret(Rt,ui);}async function nl(){return (await Xt()).getStoragePath()}async function ol(e){await(await Xt()).setSecret(Rt,ci,JSON.stringify(e));}async function Co(){let t=await(await Xt()).getSecret(Rt,ci);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function To(e){await(await Xt()).setSecret(Rt,ui,JSON.stringify(e));}async function sl(){let t=await(await Xt()).getSecret(Rt,ui);if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function qt(){let e=await Co();return e?new Date(e.expiresAt)>new Date:false}function ko(e){let t=e.split(".");if(t.length!==3)throw new Error(`Invalid JWT: expected 3 segments, got ${t.length}`);let r=t[1].replace(/-/g,"+").replace(/_/g,"/"),n=Buffer.from(r,"base64").toString("utf8");try{return JSON.parse(n)}catch{throw new Error("Invalid JWT: payload segment is not valid JSON")}}vn();var pi=I("api:auth");function Um(e){if(!ur.test(e))throw new Error(`Invalid tenant value: "${e}". Tenant must be lowercase alphanumeric and hyphens (1-64 chars).`)}var al={INVALID_CLIENT_SECRET:"Invalid Client Secret \u2014 check the value and try again",INVALID_CLIENT_ID:"Invalid Client ID \u2014 check the value and try again",INVALID_TENANT:"Invalid Tenant \u2014 check the value and try again",TENANT_NOT_FOUND:"Tenant not found \u2014 verify the tenant identifier"};async function Fm(e){if(e instanceof HTTPError){let t=e.response.status;pi.error(`HTTP error during authentication [status=${t}]`);let r="";try{let n=await e.response.text(),o=JSON.parse(n);typeof o.error=="string"&&(r=o.error);}catch{}return r&&al[r]?new Error(al[r]):t===StatusCodes.UNAUTHORIZED||t===StatusCodes.FORBIDDEN||t===StatusCodes.INTERNAL_SERVER_ERROR?new Error("Invalid credentials"):t>=StatusCodes.BAD_REQUEST&&t<StatusCodes.INTERNAL_SERVER_ERROR?new Error("Authentication request was rejected"):new Error("Authentication service unavailable, please try again later")}return e instanceof Error?(pi.debug(`Non-HTTP error during authentication: ${e.message}`),e):(pi.debug("Unknown error during authentication"),new Error("Authentication failed"))}async function gr(e){let t=jr("AUTH_ENGINE_URL","https://flow.ciandt.com/auth-engine-api/v2/api-key/token");Um(e.tenant);let r;try{r=await dc.post(t,{headers:{FlowTenant:e.tenant},json:{clientSecret:e.clientSecret}}).json();}catch(s){throw await Fm(s)}let n=r.expires_at??new Date(Date.now()+(r.expires_in??3600)*1e3).toISOString();await _t(e),await ol({accessToken:r.access_token,expiresAt:n});let o=ko(r.access_token);await To({sub:o.sub,name:o.name,email:o.email});}var ll=I("lib:tokenProvider");async function Yt(){if(await qt()){let n=await Co();if(n)return n.accessToken}ll.debug("Token expired or missing, re-authenticating...");let t=await oe();if(!t)throw new Error("Not authenticated. Run: flow auth login");Ne.clearFallbackFile(),Eo(),await gr(t);let r=await Co();if(!r)throw new Error("Authentication succeeded but token was not persisted");return ll.debug("Token refreshed successfully"),r.accessToken}vn();var Ao=I("api:metrics");function cl(){return jr("METRICS_COLLECTOR_URL","https://flow.ciandt.com/metrics-collector-api/")+"log-event"}function ul(e,t,r){return dc.post(e,{json:t,headers:r})}async function Km(e){let t=await sl();if(t)return t;let r=ko(e),n={sub:r.sub,name:r.name,email:r.email};return await To(n),n}async function b(e,t){let r=await Yt(),n=await Km(r),o=await oe();if(!ur.test(o.tenant))throw new Error(`Invalid tenant value: "${o.tenant}"`);let s={action:e,booster:Vs,metadata:{...t},success:true,tenant:o.tenant,timestamp:new Date().toISOString(),user:{id:n.sub,name:n.name,email:n.email}};try{await ul(cl(),s,{Authorization:`Bearer ${r}`,FlowTenant:o.tenant}),Ao.debug(`Metrics event sent: ${e}`);}catch(i){throw Ao.warn(`Failed to send metrics event "${e}": ${String(i)}`),i}}async function dl(e,t,r){try{let n=r&&ur.test(r)?r:"unknown",o={action:e,booster:Vs,metadata:t,success:!0,tenant:n,timestamp:new Date().toISOString(),user:{id:"anonymous",name:"unknown",email:"unknown"}};await ul(cl(),o,{FlowTenant:n}),Ao.debug(`Anonymous metrics event sent: ${e}`);}catch(n){Ao.warn(`Failed to send anonymous metrics event "${e}": ${String(n)}`);}}var v={CLI_SESSION_STARTED:"CLI_SESSION_STARTED",CLI_AUTH_FAILED:"CLI_AUTH_FAILED",CLI_STEP_COMPLETED:"CLI_STEP_COMPLETED",CLI_KIT_DISPLAYED:"CLI_KIT_DISPLAYED",CLI_KIT_ACCEPTED:"CLI_KIT_ACCEPTED",CLI_KIT_REJECTED:"CLI_KIT_REJECTED",CLI_ONBOARDING_COMPLETED:"CLI_ONBOARDING_COMPLETED",CLI_ONBOARDING_ABANDONED:"CLI_ONBOARDING_ABANDONED",CLI_CLAUDE_MD_ACCEPTED:"CLI_CLAUDE_MD_ACCEPTED",CLI_CLAUDE_MD_SKIPPED:"CLI_CLAUDE_MD_SKIPPED",CLI_TOOL_INSTALLED:"CLI_TOOL_INSTALLED",CLI_TOOL_UNINSTALLED:"CLI_TOOL_UNINSTALLED",CLI_TOOL_UPDATED:"CLI_TOOL_UPDATED",CLI_TOOL_ENABLED:"CLI_TOOL_ENABLED",CLI_TOOL_INSTALL_FAILED:"CLI_TOOL_INSTALL_FAILED",CLI_TOOL_DISABLED:"CLI_TOOL_DISABLED",CLI_CATALOG_VIEWED:"CLI_CATALOG_VIEWED",CLI_TUI_SESSION_ENDED:"CLI_TUI_SESSION_ENDED",CLI_MODULE_INSTALL_STARTED:"CLI_MODULE_INSTALL_STARTED",CLI_MODULE_INSTALL_COMPLETED:"CLI_MODULE_INSTALL_COMPLETED",CLI_MODULE_INSTALL_FAILED:"CLI_MODULE_INSTALL_FAILED",CLI_MODULE_PROXY_EXECUTED:"CLI_MODULE_PROXY_EXECUTED",CLI_MODULE_NOT_FOUND:"CLI_MODULE_NOT_FOUND",CLI_MODULE_UPDATED:"CLI_MODULE_UPDATED",CLI_BUNDLE_INSTALL_STARTED:"CLI_BUNDLE_INSTALL_STARTED",CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS:"CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS",CLI_BUNDLE_INSTALL_PLUGIN_FAILED:"CLI_BUNDLE_INSTALL_PLUGIN_FAILED",CLI_BUNDLE_INSTALL_COMPLETED:"CLI_BUNDLE_INSTALL_COMPLETED"};var Vm={sessionStart:0,stepStart:0,currentStep:"auth",interfaceType:"cli",tuiSessionStart:0},ct={...Vm};function pl(e){let t=Date.now();ct={sessionStart:t,stepStart:t,currentStep:"auth",interfaceType:e,tuiSessionStart:0};}function yr(e){ct.currentStep=e,ct.stepStart=Date.now();}function H(){return {...ct}}function Dt(){return ct.sessionStart===0?0:Date.now()-ct.sessionStart}function hr(){return ct.stepStart===0?0:Date.now()-ct.stepStart}function ml(){ct.tuiSessionStart=Date.now();}function fl(){return ct.tuiSessionStart===0?0:Date.now()-ct.tuiSessionStart}var Hm=3e3,Jm=I("abandonment");async function $o(e){let{currentStep:t,sessionStart:r}=H();if(r===0)return;let n={last_step:t,trigger:e,duration_ms:Dt()};try{await Promise.race([b(v.CLI_ONBOARDING_ABANDONED,n),new Promise((o,s)=>setTimeout(()=>s(new Error("abandonment timeout")),Hm))]);}catch(o){Jm.warn(`Abandonment event failed: ${String(o)}`);}}function gl(e,t){return Promise.race([e,new Promise(r=>setTimeout(r,t))])}var Gm=3e3,Wm=I("session-end");async function Pn(e,t,r){let n=fl(),s=[b(v.CLI_TUI_SESSION_ENDED,{duration_ms:n,active_tab:t,interface:"tui"})];r!=="main"&&s.push($o(e));try{await gl(Promise.all(s).then(()=>{}),Gm);}catch(i){Wm.warn(`Session end event failed: ${String(i)}`);}}var Ym=2e3;function hl(){let{exit:e}=useApp(),t=useRef(false),r=useRef(null),n=S(l=>l.pendingExit),o=S(l=>l.setPendingExit),s=S(l=>l.activeTab),i=S(l=>l.screen),a=useCallback(()=>{if(t.current){r.current&&clearTimeout(r.current),Pn("double-ctrl-c",s,i).finally(()=>e());return}t.current=true,o(true),r.current=setTimeout(()=>{t.current=false,o(false);},Ym);},[e,o,s,i]);return useInput((l,u)=>{u.ctrl&&l==="c"&&a();}),{pendingExit:n}}var tf=16;function Sl({label:e,value:t,onChange:r,masked:n=false,isActive:o,error:s}){let i=useRef(t);useEffect(()=>{i.current=t;},[t]),useInput((l,u)=>{if(u.backspace){let c=i.current.slice(0,-1);i.current=c,r(c);}else if(l&&!u.ctrl&&!u.meta&&!u.escape&&!u.return&&!u.tab&&!u.upArrow&&!u.downArrow&&!u.leftArrow&&!u.rightArrow){let c=i.current+l;i.current=c,r(c);}},{isActive:o});let a=n?"\u2022".repeat(t.length):t;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{color:o?"cyan":"gray",children:o?"\u25B8 ":" "}),jsx(Text,{color:o?"white":"gray",bold:o,children:e.padEnd(tf)}),jsx(Text,{color:o?"cyan":"gray",children:a}),o&&jsx(Text,{color:"cyan",children:"\u2588"})]}),s&&jsx(Box,{paddingLeft:3,children:jsxs(Text,{color:"red",children:["\u26A0 ",s]})})]})}var ze=create(e=>({credentials:null,isAuthenticated:false,justAuthenticated:false,setCredentials:t=>e({credentials:t,isAuthenticated:true}),clearCredentials:()=>e({credentials:null,isAuthenticated:false,justAuthenticated:false}),setJustAuthenticated:t=>e({justAuthenticated:t})}));function Sr(){return ge__default.join(be__default.homedir(),".claude","settings.json")}function kn(){let e=Sr();if(!he__default.existsSync(e))return {status:"missing"};let t=he__default.readFileSync(e,"utf-8"),r=t.charCodeAt(0)===65279?t.slice(1):t;try{let n=JSON.parse(r);return n===null||typeof n!="object"||Array.isArray(n)?{status:"malformed",raw:t}:{status:"ok",settings:n}}catch{return {status:"malformed",raw:t}}}function Mo(e){let t=Sr();he__default.mkdirSync(ge__default.dirname(t),{recursive:true});let r=`${t}.${randomUUID()}.tmp`;he__default.writeFileSync(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),he__default.renameSync(r,t);}function xl(e,t){let r=e.env&&typeof e.env=="object"&&!Array.isArray(e.env)?e.env:{};return {...e,env:{...r,ANTHROPIC_AUTH_TOKEN:t}}}function gi(e){let t=e.env;if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t.ANTHROPIC_AUTH_TOKEN;return typeof r=="string"&&r.length>0?r:null}var af=3600,wr=class extends Error{constructor(){super("~/.claude/settings.json contains invalid JSON"),this.name="MalformedSettingsError";}};function lf(e){return sf.sign({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},e.clientSecret,{algorithm:"HS256",expiresIn:af})}function Lo(e,t={}){let r=kn();if(r.status==="malformed"&&!t.allowOverwriteMalformed)throw new wr;let n=r.status==="ok"?r.settings:{},o=r.status==="ok"?gi(r.settings):null,s=lf(e),i=xl(n,s);return {jwt:s,merged:i,previousToken:o,hadExistingFile:r.status!=="missing"}}function Ro(e){Mo(e.merged);}function Il(){let e=kn();return e.status!=="ok"?false:gi(e.settings)!==null}var vl="0.0.0";try{let e=JSON.parse(readFileSync(join(import.meta.dirname,"..","package.json"),"utf8"));typeof e.version=="string"&&(vl=e.version);}catch{}var ae=vl;function pf(e){if(!(e instanceof Error))return "unknown";let t=e.message.toLowerCase();return t.includes("401")||t.includes("unauthorized")?"invalid_credentials":t.includes("403")||t.includes("forbidden")?"forbidden":t.includes("timeout")||t.includes("timed out")?"timeout":t.includes("network")||t.includes("econnrefused")||t.includes("fetch")?"network_error":"unknown"}var ht=["clientId","clientSecret","tenant"],mf={clientId:"Client ID",clientSecret:"Client Secret",tenant:"Tenant"};function Pl(){let[e,t]=useState({clientId:"",clientSecret:"",tenant:""}),[r,n]=useState("clientId"),[o,s]=useState({}),[i,a]=useState(null),[l,u]=useState(false),[c,d]=useState("fields"),[p,m]=useState(null),f=useRef(0),g=useRef(false),{setCredentials:y,setJustAuthenticated:w}=ze(),E=()=>({clientId:e.clientId.trim(),clientSecret:e.clientSecret.trim(),tenant:e.tenant.trim()}),T=()=>{d("fields"),m(null),t(M=>({...M,clientSecret:""})),n("clientSecret");},k=async()=>{g.current=true;let M=E();try{await _t(M);}catch(F){a(F instanceof Error?F.message:"Failed to persist credentials"),T(),g.current=false;return}let{clientSecret:x,...A}=M;y(A),w(true),b(v.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Dt(),interface:"tui"}).catch(()=>{}),An({starterKit:A.starterKit});},$=async M=>{g.current=true;let x=E();try{Ro(M),await _t(x);}catch(W){a(W instanceof Error?W.message:"Failed to persist credentials"),T(),g.current=false;return}let{clientSecret:A,...F}=x;y(F),w(true),b(v.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Dt(),interface:"tui"}).catch(()=>{}),An({starterKit:F.starterKit});},O=M=>{try{return Lo(E(),{allowOverwriteMalformed:M})}catch(x){return x instanceof wr?(d("malformedConfirm"),null):(a(x instanceof Error?x.message:"Failed to read settings.json"),d("fields"),null)}};useInput((M,x)=>{if(!(l||g.current)){if(c==="preview"){x.return&&p?$(p):x.escape?k():M==="q"&&T();return}if(c==="malformedConfirm"){if(x.return){let A=O(true);A&&(m(A),$(A));}else x.escape&&T();return}if(x.shift&&x.tab){let A=ht.indexOf(r);A>0&&n(ht[A-1]);}else if(x.tab){let A=ht.indexOf(r);A<ht.length-1&&n(ht[A+1]);}else if(x.return)if(r==="tenant")G();else {let A=ht.indexOf(r);n(ht[A+1]);}}},{isActive:true});let G=async()=>{let M={};for(let x of ht)e[x].trim()||(M[x]="This field is required");if(Object.keys(M).length>0){s(M);let x=ht.find(A=>M[A]);x&&n(x);return}u(true),a(null),f.current+=1;try{await gr(E());let x=O(!1);x&&(m(x),d("preview"));}catch(x){let A=x instanceof Error?x.message:"Authentication failed";a(A),dl(v.CLI_AUTH_FAILED,{error_code:pf(x),attempt:f.current},e.tenant.trim()).catch(()=>{}),t(F=>({...F,clientSecret:""}));}finally{u(false);}},we=M=>x=>{t(A=>({...A,[M]:x})),o[M]&&s(A=>({...A,[M]:void 0}));};return c==="preview"&&p?jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"cyan",children:[oo," \u2014 Confirm Settings Update"]})}),jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsx(Text,{children:"Ready to update ~/.claude/settings.json:"}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsx(Text,{color:"green",children:p.previousToken?" ~ env.ANTHROPIC_AUTH_TOKEN (replaced)":" + env.ANTHROPIC_AUTH_TOKEN (new)"}),p.hadExistingFile&&jsx(Text,{dimColor:true,children:" Existing settings preserved."})]})]}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"Enter \u2014 update settings.json and continue"}),jsx(Text,{dimColor:true,children:"Esc \u2014 skip JWT update, continue"}),jsx(Text,{dimColor:true,children:"q \u2014 back to form"})]})]}):c==="malformedConfirm"?jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"yellow",children:[oo," \u2014 settings.json is invalid"]})}),jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsx(Text,{children:"Your ~/.claude/settings.json contains invalid JSON."}),jsx(Text,{children:"Press Enter to overwrite it with a fresh file containing only the auth token,"}),jsx(Text,{children:"or Esc to cancel and fix the file manually."})]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter overwrite \xB7 Esc cancel"})})]}):jsxs(Box,{flexDirection:"column",padding:2,children:[jsx(Box,{marginBottom:1,children:jsxs(Text,{bold:true,color:"cyan",children:[oo," \u2014 Initial Setup"]})}),jsxs(Box,{marginBottom:1,flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"The data collected during setup is used solely to improve"}),jsx(Text,{dimColor:true,children:"Flow's internal tools and will not be shared externally."})]}),jsx(Box,{flexDirection:"column",children:ht.map(M=>jsx(Box,{marginBottom:1,children:jsx(Sl,{label:mf[M],value:e[M],onChange:we(M),masked:M==="clientSecret",isActive:r===M&&!l,error:o[M]})},M))}),l&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"cyan",children:"Authenticating..."})}),i&&jsx(Box,{marginTop:1,children:jsxs(Text,{color:"red",children:["\u26A0 ",h(i)]})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Tab next field \xB7 Enter confirm"})})]})}function Kr(){return jsxs(Box,{flexDirection:"column",alignItems:"center",children:[jsx(gf,{text:"FLOW",font:"block",colors:["white","white"]}),jsx(Box,{marginTop:-1,marginBottom:1,children:jsxs(Text,{dimColor:true,children:["Marketplace \xB7 v",ae]})})]})}function yf(){let e=Wa();if(!he__default.existsSync(e))return {};try{return JSON.parse(he__default.readFileSync(e,"utf-8"))}catch{return {}}}var yi=null;function hf(){return yi===null&&(yi=yf()),yi}function Zt(){return !!hf().ENABLE_EXPERIMENTAL_BETAS}var Al=[{id:"discover",focus:"list"},{id:"installed",focus:"list"},{id:"updates",focus:"list"},{id:"marketplaces",focus:"marketplaces"}],X=Zt()?Al:Al.slice(0,3);function Sf(e){return X.findIndex(t=>t.id===e)}function hi(e,t,r){let n=Sf(r.activeTab);if(t.rightArrow||t.tab){let o=X[(n+1)%X.length];return [{type:"setTab",tab:o.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:o.focus}]}if(t.leftArrow){let o=X[(n-1+X.length)%X.length];return [{type:"setTab",tab:o.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:o.focus}]}return t.downArrow?[{type:"setFocus",focus:X[n]?.focus??"list"}]:[]}var Ll={discover:"Discover",installed:"Installed",updates:"Updates",marketplaces:"Marketplaces"};function Rl({outdatedCount:e=0}){let t=S(r=>r.activeTab);return jsx(Box,{paddingX:1,paddingBottom:1,children:X.map(({id:r})=>{let n=r===t,o=r==="updates"&&e>0?`${Ll[r]} (${e})`:Ll[r];return jsx(Box,{marginRight:1,children:n?jsx(Text,{bold:true,inverse:true,children:` ${o} `}):jsx(Text,{dimColor:true,children:` ${o} `})},r)})})}var Be=create(e=>({query:"",cursorPosition:0,setQuery:t=>e({query:t}),setCursorPosition:t=>e({cursorPosition:t}),resetQuery:()=>e({query:"",cursorPosition:0})}));function Dl(){let e=S(i=>i.focus),t=Be(i=>i.query),r=Be(i=>i.cursorPosition),n=e==="search",o=t.slice(0,r),s=t.slice(r);return jsxs(Box,{borderStyle:"single",borderTop:false,borderBottom:true,borderLeft:false,borderRight:false,paddingX:1,marginX:1,marginBottom:1,children:[jsx(Text,{color:n?"cyan":"gray",children:"\u{1F50D} "}),n?jsxs(Fragment,{children:[jsx(Text,{color:"white",children:o}),jsx(Text,{inverse:true,children:s[0]??" "}),jsx(Text,{color:"white",children:s.slice(1)})]}):jsx(Text,{dimColor:true,children:t||"Search..."})]})}var vf=["skill","mcp","bundle"].map((e,t)=>({key:String(t+2),type:e,..._r[e]})),bf=["internal","external"].map((e,t)=>({key:String(t+6),origin:e,...Ua[e]}));function Ol(){let e=S(n=>n.catalogFilters),t=e.types.has("skill")&&e.types.has("mcp")&&e.types.has("bundle"),r=e.origins.has("internal")&&e.origins.has("external");return jsxs(Box,{paddingX:1,paddingBottom:1,gap:1,children:[jsx(Text,{bold:true,children:"Type:"}),jsxs(Box,{gap:0,children:[jsx(Text,{dimColor:true,children:"[1] "}),jsxs(Text,{color:t?"green":void 0,dimColor:!t,children:[t?"\u25C9":"\u25CB"," All"]})]}),vf.map(n=>{let o=!t&&e.types.has(n.type);return jsxs(Box,{gap:0,children:[jsxs(Text,{dimColor:true,children:["[",n.key,"] "]}),jsxs(Text,{color:o?n.color:void 0,dimColor:!o,children:[o?"\u25C9":"\u25CB"," ",n.label]})]},n.key)}),jsx(Box,{marginLeft:2,children:jsx(Text,{bold:true,children:"|"})}),jsx(Box,{marginLeft:2,children:jsx(Text,{bold:true,children:"Origin:"})}),jsxs(Box,{gap:0,children:[jsx(Text,{dimColor:true,children:"[5] "}),jsxs(Text,{color:r?"green":void 0,dimColor:!r,children:[r?"\u25C9":"\u25CB"," All"]})]}),bf.map(n=>{let o=!r&&e.origins.has(n.origin);return jsxs(Box,{gap:0,children:[jsxs(Text,{dimColor:true,children:["[",n.key,"] "]}),jsxs(Text,{color:o?n.color:void 0,dimColor:!o,children:[o?"\u25C9":"\u25CB"," ",n.label]})]},n.key)})]})}function Nl({type:e}){let{label:t,color:r}=_r[e];return jsx(Text,{color:r,children:t})}function Fl({origin:e}){return e===yn?jsx(Text,{color:"blue",children:"[Flow]"}):jsx(Text,{color:"white",children:"[External]"})}var Do=Cf.memo(function({item:t,isSelected:r}){let n=t.status==="disabled"?"yellow":"green";return jsxs(Box,{flexDirection:"column",paddingBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":"\u25CB "}),jsx(Text,{bold:r,color:r?"cyan":"white",children:t.name}),t.type&&jsxs(Text,{children:[" ",jsx(Nl,{type:t.type})]}),t.origin&&jsxs(Text,{children:[" ",jsx(Fl,{origin:t.origin})]}),jsxs(Text,{dimColor:true,children:[t.authorName?` \xB7 ${t.authorName}`:"",t.version?` \xB7 v${t.version}`:" \xB7 n/a"]}),t.status&&jsxs(Text,{color:n,children:[" [",t.status,"]"]}),t.updateAvailable&&jsx(Text,{color:"yellow",children:" [\u2191 update available]"}),t.installedAt&&jsxs(Text,{dimColor:true,children:[" \xB7 ",Wt(t.installedAt)]})]}),jsx(Box,{paddingLeft:2,children:jsx(Text,{dimColor:true,children:t.description})})]})});function Vr({message:e}){return jsx(Box,{paddingX:2,paddingY:1,children:jsx(Text,{dimColor:true,children:e??"No items found."})})}function Vl({items:e,emptyMessage:t}){let r=S(l=>l.selectedIndex);if(e.length===0)return jsx(Vr,{message:t});let n=Math.max(0,r-Math.floor(Je/2)),o=Math.min(e.length,n+Je);o===e.length&&(n=Math.max(0,o-Je));let s=e.slice(n,o),i=n,a=e.length-o;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:i>0?`\u2191 ${i} more above`:" "})}),s.map((l,u)=>jsx(Do,{item:l,isSelected:n+u===r},l.name)),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:a>0?`\u2193 ${a} more below`:" "})})]})}function Gl({label:e,pathHint:t}){return jsxs(Box,{paddingBottom:1,children:[jsx(Text,{bold:true,color:"blueBright",children:e}),jsxs(Text,{dimColor:true,children:[" ",t]})]})}function zl({groups:e,emptyMessage:t}){let r=S(m=>m.selectedIndex),n=[],o=0;for(let m of e){n.push({kind:"header",label:m.label,pathHint:m.pathHint,key:`h-${m.scope}`});for(let f of m.items)n.push({kind:"item",item:f,itemIndex:o,key:`i-${m.scope}-${f.name}-${f.marketplace??""}`}),o++;}if(o===0)return jsx(Vr,{message:t});let i=n.findIndex(m=>m.kind==="item"&&m.itemIndex===r),a=i>=0?i:0,l=Math.max(0,a-Math.floor(Je/2)),u=Math.min(n.length,l+Je);u===n.length&&(l=Math.max(0,u-Je));let c=n.slice(l,u),d=l,p=n.length-u;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:d>0?`\u2191 ${d} more above`:" "})}),c.map(m=>m.kind==="header"?jsx(Gl,{label:m.label,pathHint:m.pathHint},m.key):jsx(Do,{item:m.item,isSelected:m.itemIndex===r},m.key)),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:p>0?`\u2193 ${p} more below`:" "})})]})}var _f={discover:"Discover",installed:"Installed",updates:"Updates",marketplaces:"Marketplaces"};function Df({items:e,tabId:t,emptyMessage:r,groups:n,actionHint:o}){return jsxs(Box,{flexDirection:"column",children:[jsx(Dl,{}),jsx(Ol,{}),jsxs(Box,{paddingX:1,marginTop:1,children:[jsx(Text,{bold:true,children:_f[t]}),jsxs(Text,{dimColor:true,children:[" (",e.length,")"]}),o&&e.length>0&&jsx(Text,{dimColor:true,children:` \xB7 ${o}`})]}),n&&n.length>0?jsx(zl,{groups:n,emptyMessage:r}):jsx(Vl,{items:e,emptyMessage:r})]})}function Xl({filteredItems:e,emptyMessage:t,groups:r,onBatchUpdate:n}){let o=S(l=>l.activeTab),s=S(l=>l.focus);return useInput(l=>{l==="a"&&e.length>0&&n?.();},{isActive:o==="updates"&&s==="list"}),jsx(Box,{flexDirection:"column",flexGrow:1,children:jsx(Df,{items:e,tabId:o,emptyMessage:t,groups:o!=="discover"?r:void 0,actionHint:o==="updates"?"press 'a' to update all":void 0},o)})}var Bf={tabs:"\u2190\u2192: switch tab | \u2193: navigate | Enter: select | Ctrl+C Ctrl+C: quit",list:"\u2191\u2193: navigate | Enter: select | Type: 1=All 2=Skill 3=MCP 4=Bundle | Origin: 5=All 6=Flow 7=External | \u2190\u2192/Tab: tabs | Ctrl+C\xD72: quit",search:"Type to filter | \u2193/Esc: exit search | Enter: confirm",actionMenu:"\u2191\u2193: navigate options | Enter: confirm | Esc: close menu",auth:"Tab: next field | Enter: confirm | Ctrl+C Ctrl+C: quit",starterKitList:"\u2191\u2193: navigate | Enter: select Starter Kit | Esc: skip",starterKitDetail:"\u2191\u2193: navigate | Enter: confirm & install | Esc: back",installProgress:"\u2191\u2193: navigate | Enter: select",moduleSetup:"\u2191\u2193: navigate | Space: toggle | Tab: change method | Enter: confirm",marketplaces:"\u2191\u2193: navigate | a: add catalog | d: remove catalog | r: refresh | \u2190\u2192/Tab: tabs | Ctrl+C\xD72: quit",verify:"\u2191\u2193: navigate | Enter: confirm | Ctrl+C Ctrl+C: quit",bundleInstallProgress:"Enter/Esc: back to catalog"};function Oo(){let e=S(r=>r.focus),t=!!process.env.DEBUG;return jsx(Box,{borderStyle:"single",borderTop:true,borderBottom:false,borderLeft:false,borderRight:false,children:jsxs(Text,{dimColor:true,children:[Bf[e],t?" | Ctrl+D: debug log":""]})})}function ql({message:e,type:t}){return e?jsx(Box,{paddingX:1,children:jsxs(Text,{color:t==="success"?"green":t==="info"?"cyan":"red",children:[t==="success"?"\u2713":t==="info"?"(i)":"\u2717"," ",h(e)]})}):null}function No({message:e}){return jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{children:[" ",e]})]})}function Bo({message:e,onRetry:t,onBack:r}){return useInput((n,o)=>{n==="r"&&o.ctrl&&t?t():o.escape&&r&&r();}),jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsxs(Text,{color:"red",children:["\u2717 ",e]}),t&&jsx(Text,{dimColor:true,children:"Press Ctrl+R to retry"}),r&&jsx(Text,{dimColor:true,children:"Press Escape to go back"})]})}function qe({itemName:e,actions:t,descriptions:r,onAction:n,onClose:o}){let s=S(l=>l.focus),[i,a]=useState(0);return useInput((l,u)=>{u.upArrow?a(c=>c>0?c-1:c):u.downArrow?a(c=>c<t.length-1?c+1:c):u.return?n(t[i]):u.escape&&o();},{isActive:s==="actionMenu"}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsx(Box,{flexDirection:"column",marginTop:1,children:t.map((l,u)=>jsxs(Box,{children:[jsxs(Text,{bold:u===i,color:u===i?"cyan":void 0,children:[u===i?"\u203A ":" ",l]}),r?.[l]&&jsxs(Text,{dimColor:true,children:[" \u2014 ",r[l]]})]},u))})]})}var Ti=Object.entries(hn),nc=[...Ti.map(([,e])=>e.actionLabel),"Cancel"],oc=Object.fromEntries(Ti.map(([,e])=>[e.actionLabel,e.description]));function sc(e){let t=Ti.find(([,r])=>r.actionLabel===e);return t?t[0]:null}var Yf=I("provider.registry"),Zf=3e4,Fo=class{adapters=new Map;availabilityCache=new Map;register(t){this.adapters.set(t.id,t);}async checkAvailability(t){let r=this.availabilityCache.get(t.id);if(r&&Date.now()<r.expiresAt)return r.result;let n=await t.isAvailable();return this.availabilityCache.set(t.id,{result:n,expiresAt:Date.now()+Zf}),n}async getAvailableProviders(t){let r=[...this.adapters.values()].filter(o=>t in o.installers),n=await Promise.allSettled(r.map(o=>this.checkAvailability(o)));return n.forEach((o,s)=>{o.status==="rejected"&&Yf.warn(`Provider "${r[s].id}" isAvailable() threw: ${String(o.reason)}`);}),r.filter((o,s)=>{let i=n[s];return i.status==="fulfilled"&&i.value===true})}getAdapter(t){return this.adapters.get(t)}listAdapters(){return [...this.adapters.values()]}};var Qf={user:"global",project:"project",local:"local"};function jo(e){return e?Qf[e]:"global"}var Ue=class extends Error{constructor(r,n){super(`${r} v${n} is already installed. Use --force to reinstall.`);this.pluginName=r;this.version=n;this.name="AlreadyInstalledError";}pluginName;version},er=class extends Error{constructor(r,n){super(`${r} is already up to date (v${n})`);this.pluginName=r;this.version=n;this.name="AlreadyUpToDateError";}pluginName;version};vn();function St(){return dc.create({prefix:jr("PROMPT_MANAGER_URL","https://flow.ciandt.com/prompt-manager-api/"),hooks:{beforeRequest:[async({request:e})=>{let t=await Yt();e.headers.set("Authorization",`Bearer ${t}`);let r=await oe();r?.tenant&&ur.test(r.tenant)&&e.headers.set("FlowTenant",r.tenant);}]}})}var tg=I("catalog.registry"),Ko=class{adapters=new Map;register(t){this.adapters.set(t.id,t);}unregister(t){this.adapters.delete(t);}async fetchAllWithErrors(){let t=this.listAdapters(),r=await Promise.allSettled(t.map(s=>s.fetchItems())),n=[],o=[];for(let s=0;s<r.length;s++){let i=r[s],a=t[s];if(i.status==="fulfilled")n.push(...i.value);else {let l=String(i.reason);tg.warn(`Catalog adapter failed: ${l}`),o.push({adapterId:a.id,adapterName:a.name,reason:l});}}return {items:n,failures:o}}async fetchAll(){let{items:t}=await this.fetchAllWithErrors();return t}getAdapter(t){return this.adapters.get(t)}listAdapters(){return [...this.adapters.values()]}};var cg={retries:5,minTimeout:50};async function ki(e,t){mkdirSync(dirname(e),{recursive:true});let r=await lg.lock(e+".lock",{realpath:false,retries:cg});try{return await t()}finally{await r();}}var Vo=class{filePath;constructor(t){this.filePath=t??Ga();}async read(){try{let t=await readFile(this.filePath,"utf-8");return JSON.parse(t).catalogs??[]}catch(t){if(t.code==="ENOENT")return [];throw t}}async write(t){let r=dirname(this.filePath);await mkdir(r,{recursive:true});let n=`${this.filePath}.${randomUUID()}.tmp`;await writeFile(n,JSON.stringify({catalogs:t},null,2),"utf-8"),await rename(n,this.filePath);}async add(t){await ki(this.filePath,async()=>{let r=await this.read();if(r.some(o=>o.id===t.id))return;let n={...t,lastUpdated:t.lastUpdated??new Date().toISOString()};await this.write([...r,n]);});}async remove(t){if(t==="flow-api")throw new Error("The Flow Marketplace catalog cannot be removed");await ki(this.filePath,async()=>{let r=await this.read();await this.write(r.filter(n=>n.id!==t));});}async updateField(t,r){await ki(this.filePath,async()=>{let n=await this.read();n.some(o=>o.id===t)&&await this.write(n.map(o=>o.id===t?{...o,...r}:o));});}};var ug=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/;function Ln(e){if(!e||!ug.test(e))throw new Error(`Invalid plugin name: "${e}". Must be 1-64 chars, lowercase alphanumeric and hyphens only.`)}var dg=/^[^@]+@[^@]+$/;function Jr(e){return dg.test(e)}function Gr(e){let t=e.indexOf("@");return t>0?e.slice(0,t):e}var pg=/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/;function mg(e){if(!pg.test(e))throw new Error(`Invalid plugin name: "${e}". Plugin names must start with an alphanumeric character and contain only letters, digits, dots, hyphens, underscores, and slashes.`)}function Wr(e,t){let r=Gr(e);mg(r);let n=["claude","plugin","install",r];return t&&n.push("--scope",t),n.join(" ")}var fg=/^[\w./:@?&=+#%-]+$/;function Ho(e){let t=e.trim();if(!t)throw new Error("No marketplace source provided.");if(!fg.test(t))throw new Error(`Invalid marketplace source: "${t}". Must be owner/repo or a URL (no spaces or special characters).`);return t}var gg=I("catalog.flow-api"),Jo=class{id="flow-api";name="Flow Marketplace";source;removable=false;constructor(){this.source=process.env.PROMPT_MANAGER_URL??"";}async fetchItems(){try{let{plugins:t}=await St().get("v1/plugins/catalog").json();return t.map(r=>({...r,catalogId:this.id,origin:r.origin??"internal",type:r.type??"bundle"}))}catch(t){if(t instanceof HTTPError){let{status:r}=t.response;throw r===401||r===403?new Error("Authentication failed. Run: flow auth login"):new Error(`Failed to fetch plugin catalog: HTTP ${r}`)}throw t instanceof Error?t.name==="TimeoutError"||t.message.includes("timeout")?new Error("Request timed out while fetching plugin catalog"):new Error(`Failed to fetch plugin catalog: ${t.message}`):t}}async fetchManifest(t){Ln(t);try{return await St().get(`v1/plugins/${t}/manifest`).json()}catch(r){if(r instanceof HTTPError){let{status:n}=r.response;throw n===404?new Error(`Plugin '${t}' not found in catalog`):new Error(`Failed to fetch manifest: HTTP ${n}`)}throw r instanceof Error?new Error(`Failed to fetch manifest: ${r.message}`):r}}async ping(){try{return await St().head("v1/plugins/catalog"),gg.debug("ping ok"),!0}catch{return false}}};var ue=new Ko,Nt=new Vo;ue.register(new Jo);var fc=false;async function gc(){if(fc)return;fc=true;let e=await Nt.read(),{GitRepoAdapter:t}=await Promise.resolve().then(()=>(Ai(),mc));for(let r of e)ue.register(new t(r.id,r.name,r.source));}async function tr(){return ue.fetchAll()}async function yc(){return ue.fetchAllWithErrors()}async function Xr(e){Ln(e);try{return await St().get(`v1/plugins/${e}/manifest`).json()}catch(t){throw t instanceof Error?t.message.includes("404")?new Error(`Plugin '${e}' not found in catalog`):t.message.includes("timeout")?new Error("Download timed out after 30s"):new Error(`Failed to fetch plugin manifest: ${t.message}`):t}}async function hc(e){Ln(e);try{let t=await St().get(`v1/plugins/${e}/archive`);return Buffer.from(await t.arrayBuffer())}catch(t){throw t instanceof Error?t.message.includes("timeout")?new Error("Download timed out after 30s"):new Error(`Failed to download plugin: ${t.message}`):t}}async function Go(){try{let{profiles:e}=await St().get("v1/plugins/profiles").json();return e}catch(e){throw e instanceof Error?e.message.includes("401")||e.message.includes("403")?new Error("Authentication failed. Run: flow auth login"):e.message.includes("timeout")?new Error("Request timed out while fetching starter kits"):new Error(`Failed to fetch starter kits: ${e.message}`):e}}async function Sc(e,t){let r=ge.resolve(t);await wt.mkdir(r,{recursive:true});let n=ge.join(ge.dirname(r),`${randomUUID()}.zip`);try{await wt.writeFile(n,e),await xg(n,{dir:r,onEntry(o){if((o.externalFileAttributes>>16&61440)===40960)throw new Error(`Zip Slip (symlink): entry "${o.fileName}" is a symbolic link and was rejected`);let i=ge.resolve(r,o.fileName);if(!i.startsWith(r+ge.sep)&&i!==r)throw new Error(`Zip Slip detected: entry "${o.fileName}" would escape target directory`)}});try{let o=realpathSync(r);if(!o.startsWith(ge.resolve(ge.dirname(r))))throw new Error(`Zip Slip (post-extract): resolved path "${o}" is outside expected parent`)}catch(o){if(o.code!=="ENOENT")throw o}}finally{try{await wt.unlink(n);}catch{}}}async function $i(e){await wt.rm(e,{recursive:true,force:true});}async function rr(){let e=Ha();await wt.mkdir(ge.dirname(e),{recursive:true});try{await wt.writeFile(e,"",{flag:"wx"});}catch(r){if(r.code!=="EEXIST")throw r}return await lg.lock(e,{stale:1e4,retries:{retries:2,minTimeout:500,maxTimeout:500}})}function bg(){return {$schema:"https://anthropic.com/claude-code/marketplace.schema.json",name:re,description:"Flow Skills marketplace",owner:{name:"Flow Team",email:"flow@ciandt.com"},plugins:[]}}function Ic(){let e=ao();if(!he__default.existsSync(e))return null;try{return JSON.parse(he__default.readFileSync(e,"utf-8"))}catch{return null}}function Pg(){let e=Ic();if(e)return e;let t=bg(),r=ao();return he__default.mkdirSync(ge__default.dirname(r),{recursive:true}),Mi(t),t}function Mi(e){let t=ao(),r=`${t}.${randomUUID()}.tmp`;he__default.writeFileSync(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),he__default.renameSync(r,t);}function Eg(){let e=lo(),t={};try{he__default.existsSync(e)&&(t=JSON.parse(he__default.readFileSync(e,"utf-8")));}catch{t={};}if(t[re])return;t[re]={source:{source:"github",repo:"CI-T-HyperX/flow-skills"},installLocation:Va(),lastUpdated:new Date().toISOString()};let r=`${e}.${randomUUID()}.tmp`;he__default.writeFileSync(r,JSON.stringify(t,null,2),{encoding:"utf-8",mode:384}),he__default.renameSync(r,e);}function vc(e,t){nr(e.name),Eg();let r=Gs(e.name);he__default.mkdirSync(ge__default.dirname(r),{recursive:true});try{he__default.lstatSync(r),he__default.rmSync(r,{recursive:!0,force:!0});}catch{}he__default.symlinkSync(t,r,process.platform==="win32"?"junction":"dir");let n=Pg();n.plugins.some(s=>s.name===e.name)||(n.plugins.push({name:e.name,description:e.description,version:e.version,author:e.author,source:`./plugins/native/${e.name}`,category:e.category}),Mi(n));}function Li(e){nr(e);let t=Gs(e);try{he__default.rmSync(t,{recursive:!0,force:!0});}catch{}let r=Ic();if(!r)return;let n=r.plugins.length;r.plugins=r.plugins.filter(o=>o.name!==e),r.plugins.length!==n&&Mi(r);}var Tg=I("mcpConfigReader"),kg=500,Ag=512;function $g(){return ge__default.join(be__default.homedir(),".claude.json")}function Mg(){return ge__default.join(process.cwd(),".mcp.json")}function Pc(e){if(!he__default.existsSync(e))return null;try{return JSON.parse(he__default.readFileSync(e,"utf-8"))}catch{return Tg.debug(`[mcpConfigReader] Failed to parse ${e}`),null}}function Rn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ri(e){if(!Rn(e))return {};let t=e.mcpServers;return Rn(t)?t:{}}function _i(e,t){return Object.keys(e).slice(0,kg).map(n=>({name:h(n.slice(0,Ag)),marketplace:"",version:void 0,installedAt:"",installPath:"",scope:t,description:void 0,author:void 0,status:"enabled",type:"mcp"}))}function Cc(){let e=[],t=$g(),r=Pc(t);if(Rn(r)){let a=r,l=Ri(a);e.push(..._i(l,"user"));let u=process.cwd();if(Rn(a.projects)){let c=a.projects[u];if(Rn(c)){let d=Ri(c);e.push(..._i(d,"local"));}}}let n=Mg(),o=Pc(n),s=Ri(o);e.push(..._i(s,"project"));let i=new Map;for(let a of e){let l=`${a.name}@${a.scope}`;i.has(l)||i.set(l,a);}return [...i.values()]}var Ze=I("storage");async function Rg(e,t,r){try{await b(v.CLI_TOOL_UNINSTALLED,{tool_id:e,tool_type:r,source:t,interface:H().interfaceType});}catch(n){Ze.warn(`Failed to send uninstall metrics: ${String(n)}`);}}function _g(e,t,r){let n=t==="enabled"?v.CLI_TOOL_ENABLED:v.CLI_TOOL_DISABLED;b(n,{tool_id:e,source:r,interface:H().interfaceType}).catch(o=>Ze.warn(`Failed to send ${t} metrics: ${String(o)}`));}function Bi(){return ge__default.join(be__default.homedir(),".claude","plugins","installed_plugins.json")}function Dg(){return ge__default.join(be__default.homedir(),".claude","plugins")}function Tc(e){let t=ge__default.resolve(e),r=ge__default.resolve(Dg()),n=ge__default.resolve(ge__default.join(process.cwd(),".claude","plugins")),o=t.startsWith(r+ge__default.sep)||t===r,s=t.startsWith(n+ge__default.sep)||t===n;if(!o&&!s)throw new Error(`Security error: installPath '${e}' is outside the plugins directory`)}function kc(e="user"){return e==="local"?ge__default.join(process.cwd(),".claude","settings.local.json"):e==="project"?ge__default.join(process.cwd(),".claude","settings.json"):ge__default.join(be__default.homedir(),".claude","settings.json")}function pt(){let e=Bi();if(!he__default.existsSync(e))return {version:2,plugins:{}};try{return JSON.parse(he__default.readFileSync(e,"utf-8"))}catch{return {version:2,plugins:{}}}}async function Ui(){let e=Bi();try{let t=await he__default.promises.readFile(e,"utf-8");return JSON.parse(t)}catch{return {version:2,plugins:{}}}}function Og(e){let t=e?.code;return t==="EACCES"||t==="EPERM"}function Ac(e,t){try{he__default.mkdirSync(ge__default.dirname(e),{recursive:!0});let r=`${e}.${randomUUID()}.tmp`;he__default.writeFileSync(r,JSON.stringify(t,null,2),{encoding:"utf-8",mode:384}),he__default.renameSync(r,e);}catch(r){throw Og(r)?new Error(`Permission denied: cannot write to '${e}'. Check your file system permissions.`):r}}function Qe(e){Ac(Bi(),e);}function _n(e){let t=e.lastIndexOf("@");return t===-1?{name:e,marketplace:""}:{name:e.slice(0,t),marketplace:e.slice(t+1)}}function Ng(e,t){let r=ge__default.join(e,".claude-plugin"),n=ge__default.join(r,"plugin.json");if(he__default.existsSync(n))try{return JSON.parse(he__default.readFileSync(n,"utf-8"))}catch{return null}let o=ge__default.join(r,"marketplace.json");if(he__default.existsSync(o))try{let s=JSON.parse(he__default.readFileSync(o,"utf-8"));return {description:s.plugins?.find(a=>a.name===t)?.description,author:s.owner}}catch{return null}return null}function Fi(e="user"){let t=kc(e);if(!he__default.existsSync(t))return {};try{return JSON.parse(he__default.readFileSync(t,"utf-8"))}catch{return {}}}function $c(e,t="user"){Ac(kc(t),e);}function Bg(e,t){let{name:r,marketplace:n}=_n(e),o;if(n?(o=`${r}@${n}`,t[o]||(o=void 0)):o=Object.keys(t).filter(i=>_n(i).name===r)[0],!o)throw Ze.error(`[${r}] Plugin is not installed`),new Error(`Plugin '${r}' is not installed`);return {key:o,name:r}}function Ug(e,t){let{name:r,marketplace:n}=_n(e),o;return n?(o=`${r}@${n}`,t[o]||(o=void 0)):o=Object.keys(t).filter(i=>_n(i).name===r)[0],o?{key:o,name:r}:null}function Di(e="user"){return Fi(e).enabledPlugins??{}}function Oi(e,t="user"){let r=Fi(t),n=r.enabledPlugins;if(!n||!(e in n))return;let{[e]:o,...s}=n;r.enabledPlugins=s,$c(r,t);}function Dn(e,t,r="user"){let n=Fi(r),o=n.enabledPlugins??{};n.enabledPlugins={...o,[e]:t},$c(n,r);}function Fg(e){let t=new Map;for(let r of e){let n=t.get(r.scope);(!n||r.installedAt>n.installedAt)&&t.set(r.scope,r);}return [...t.values()]}function se(){let e=pt(),t=Di(),r=Di("project"),n=Di("local"),o={project:r,local:n},s=Object.entries(e.plugins).flatMap(([u,c])=>{let{name:d,marketplace:p}=_n(u),m=c.map(g=>g.scope==="managed"?{...g,scope:"user"}:g);return Fg(m).map(g=>{let y=Ng(g.installPath,d),E=(o[g.scope]??t)[u];return {name:d,marketplace:p,version:g.version&&g.version!=="unknown"?g.version:void 0,installedAt:g.installedAt,installPath:g.installPath,scope:g.scope,providerId:g.providerId,type:g.type,description:y?.description,author:y?.author,status:E===false?"disabled":"enabled"}})}),i=Cc(),a=new Set(s.map(u=>`${u.name}@${u.scope}`)),l=i.filter(u=>!a.has(`${u.name}@${u.scope}`));return [...s,...l]}async function Wo(e,t){Ze.debug(`[${e}] Acquiring lock to uninstall`);let r=await rr();try{let n=pt(),o=Ug(e,n.plugins);if(!o)throw new Error(`Plugin '${e}' is not in installed_plugins.json. If this is an MCP server from config, use the MCP remove command instead.`);let{key:s,name:i}=o,a=n.plugins[s];if(t){let l=a.find(d=>d.scope===t);if(!l)throw new Error(`Plugin '${i}' is not installed in ${t} scope`);Ze.debug(`[${i}] Resolved key: ${s}, scope: ${t}`),Tc(l.installPath);let u=ge__default.dirname(l.installPath);Ze.debug(`[${i}] Removing directory: ${u}`),he__default.rmSync(u,{recursive:!0,force:!0});let c=a.filter(d=>d.scope!==t);if(c.length===0){let{[s]:d,...p}=n.plugins;Qe({...n,plugins:p}),Oi(s,t),Li(i);}else n.plugins[s]=c,Qe(n),Oi(s,t);}else {Ze.debug(`[${i}] Resolved key: ${s}`);for(let c of a){Tc(c.installPath);let d=ge__default.dirname(c.installPath);Ze.debug(`[${i}] Removing directory: ${d}`),he__default.rmSync(d,{recursive:!0,force:!0}),Oi(s,c.scope);}Li(i);let{[s]:l,...u}=n.plugins;Qe({...n,plugins:u});}await Rg(i,a[0].origin??"internal",a[0].type??"skill"),Ze.debug(`[${i}] Uninstalled successfully`);}finally{await r();}}async function On(e,t,r){Ze.debug(`[${e}] Acquiring lock to set status \u2192 ${t}`);let n=await rr();try{let o=pt(),{key:s,name:i}=Bg(e,o.plugins),a=o.plugins[s],l=r??a[0].scope,u=a[0].origin??"internal";Ze.debug(`[${i}] Resolved key: ${s}, scope: ${l}`),Dn(s,t==="enabled",l),_g(i,t,u),Ze.debug(`[${i}] Status updated to ${t}`);}finally{await n();}}var jg=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$|^[a-z0-9]$/,Kg=/^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*)?$/;function nr(e){if(!jg.test(e))throw new Error(`Invalid plugin name from manifest: "${e}". Plugin names must be lowercase alphanumeric and hyphens (1-64 chars).`)}function Vg(e){if(!Kg.test(e))throw new Error(`Invalid plugin version from manifest: "${e}". Versions must follow semver format (e.g. 1.0.0 or 1.0.0-beta.1).`)}var or=I("installer");function Hg(e,t){let r=`${e}@${re}`,o=pt().plugins[r];if(o&&!t)throw new Ue(e,o[0].version??"unknown");return {pluginKey:r,alreadyInstalled:o}}async function Jg(e,t,r){r&&await $i(t);try{or.debug(`[${t}] Extracting archive...`),await Sc(e,t);}catch(n){throw await $i(t),n}}function Gg(e,t,r,n,o,s="claude-code",i){let a=pt(),l={scope:n,installPath:t,version:r,installedAt:new Date().toISOString(),origin:o,providerId:s,type:i},u=a.plugins[e]??[];a.plugins[e]=[...u.filter(c=>c.scope!==n),l],Qe(a),Dn(e,true,n);}async function Wg(e,t,r,n,o,s){try{await b(v.CLI_TOOL_INSTALLED,{tool_id:e,tool_type:s,source:o,scope:n,version:t,duration_ms:r,interface:H().interfaceType});}catch(i){or.warn(`Failed to send install metrics: ${String(i)}`);}}async function zg(e,t,r,n){try{await b(v.CLI_TOOL_INSTALL_FAILED,{tool_id:e,tool_type:n,source:r,error_code:t instanceof Error?t.name:"UNKNOWN",error_message:(t instanceof Error?t.message:String(t)).slice(0,500),interface:H().interfaceType});}catch(o){or.warn(`Failed to send install-failed metrics: ${String(o)}`);}}async function Ce(e,t={}){let r=Date.now(),n=null;try{or.debug(`[${e}] Acquiring lock...`),n=await rr();let{pluginKey:o,alreadyInstalled:s}=Hg(e,t.force);or.debug(`[${e}] Fetching manifest...`);let i=await Xr(e);nr(i.name),Vg(i.version),or.debug(`[${e}] Downloading archive...`);let a=await hc(e),l=t.scope??"user",u=t.type??"skill",c=Ka(i.name,i.version);await Jg(a,c,!!s&&!!t.force),Gg(o,c,i.version,l,"internal",t.providerId,u),vc(i,c);let d=Date.now()-r;or.debug(`[${e}] Installed successfully in ${d}ms`);let p={name:i.name,version:i.version,path:c,duration_ms:d};return t.skipMetrics||await Wg(i.name,i.version,d,jo(l),"internal",u),p}catch(o){throw await zg(e,o,"internal",t.type??"skill"),or.error(`[${e}] Installation failed: ${o instanceof Error?o.message:String(o)}`),o}finally{n&&await n();}}var Xg=I("commands:helpers");async function ye(){if(!await oe())return P("Not authenticated. Run: flow auth login"),false;try{await Yt();}catch(t){return Xg.debug(`Token validation failed: ${String(t)}`),P("Session expired. Run: flow auth login"),false}return true}async function xt(e){let t=ji.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(h(e),n=>{t.close(),r(["y","yes"].includes(n.toLowerCase().trim()));});})}async function Mc(e){let t=ji.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(h(e),n=>{t.close(),r(n.trim());});})}var qr=I("claudeProxy"),Gi="claude ",Lc="flow ",Ki=class extends Error{constructor(t){super(`Invalid install command: "${t}". Command must start with "claude " for security.`),this.name="InvalidInstallCommandError";}},Vi=class extends Error{constructor(t){super(`Disallowed subcommand: "${t}". Only "plugin install", "plugin marketplace add", "mcp add", and "mcp remove" are permitted.`),this.name="DisallowedSubcommandError";}},qg=/^plugins?\s+(install|i)\s+|^plugins?\s+marketplace\s+add\s+|^mcp\s+(add|remove)\s+/,Yg=/^npm\s+(i|install)\s+-g\s+@ciandt-flow\/cli$/,Zg=/^(flow|claude)\s+auth\s+login(\s|$)/,Rc=/^flow\s+plugins?\s+(install|i)\s+([^@\s]+)$/;function _c(e){return Rc.test(e.trim())}function Qg(e){return Rc.exec(e.trim())?.[2]??""}async function Dc(e){let t=Qg(e),r=Date.now();qr.debug(`[${t}] Executing: flow plugin install ${t}`);try{let n=await execa("flow",["plugin","install",t],{reject:!1});return {name:t,command:`flow plugin install ${t}`,exitCode:n.exitCode??1,stdout:n.stdout,stderr:n.stderr,duration_ms:Date.now()-r}}catch(n){throw Wi(n)?new Hi:n}}function ey(e){Oc(e);let t=e.slice(Gi.length);if(!qg.test(t))throw new Vi(e)}var zo=class extends Error{constructor(){super('Claude Code CLI not found. Ensure "claude" is installed and available on your PATH.'),this.name="ClaudeCliNotFoundError";}},Hi=class extends Error{constructor(){super('Flow CLI not found. Ensure "flow" is installed and available on your PATH.'),this.name="FlowCliNotFoundError";}};function Oc(e){if(!e||!/^claude /.test(e))throw new Ki(e)}async function xe(e){Oc(e);let t=e.slice(Gi.length).split(/\s+/).filter(Boolean),r=ty(t);qr.debug(`[${r}] Executing proxy command: claude ${t.join(" ")}`);let n=Date.now();try{let o=await execa("claude",t,{reject:!1}),s=Date.now()-n;return qr.debug(`[${r}] Proxy command finished with exit code ${o.exitCode} in ${s}ms`),{name:r,command:e,exitCode:o.exitCode??1,stdout:o.stdout,stderr:o.stderr,duration_ms:s}}catch(o){throw Wi(o)?new zo:o}}function ty(e){return e.length>=3?e[2]:e.join(" ")}function Wi(e){return e instanceof Error&&"code"in e&&e.code==="ENOENT"}function ry(e){return e.startsWith(Lc)?Gi+e.slice(Lc.length):e}function ny(e){return Yg.test(e)||Zg.test(e)}function oy(e){let t=0;for(;t<e.length&&ny(e[t]);)t++;return e.slice(t)}var sy=/^claude\s+(?:plugins?\s+(?:install|i)\s+|mcp\s+(?:add|remove)\s+)/;function iy(e,t){return !t||e.includes("--scope")||!sy.test(e)?e:`${e} --scope ${t}`}async function Nn(e,t){let r=e.split("&&").map(i=>i.trim()).filter(Boolean),o=oy(r).map(i=>ry(i)).map(i=>iy(i,t));if(o.length===0)throw new Error("Empty install command");for(let i of o)ey(i);qr.debug(`[installCommand] Executing ${o.length} command(s)`);let s=await xe(o[0]);if(s.exitCode!==0)return s;for(let i=1;i<o.length;i++)if(s=await xe(o[i]),s.exitCode!==0)return s;return s}async function Xo(e,t,r){let n=Gr(e),o=t?.trim();if(!o&&(o=(await Mc(`Plugin "${n}" could not be installed.
|
|
111
|
+
If a marketplace is needed, enter the source (owner/repo or URL), or press Enter to skip: `))?.trim(),!o))throw new Error("No marketplace source provided. Cannot retry install.");o=Ho(o),r?.(),qr.debug(`[${n}] Adding marketplace via: claude plugin marketplace add ${o}`);try{let s=await execa("claude",["plugin","marketplace","add",o],{reject:!1});if(s.exitCode!==0)throw new Error(`Failed to add marketplace: ${s.stderr||"unknown error"}`);qr.debug(`[${n}] Marketplace added successfully`);}catch(s){throw Wi(s)?new zo:s}}var dy=6e4,sr=class extends Error{url;isTimeout;isAuthError;constructor(t,r,n=false,o=false){super(t),this.name="GitCloneError",this.url=r,this.isTimeout=n,this.isAuthError=o;}};async function It(e,t){let r=await mkdtemp(join(tmpdir(),"flow-skills-")),n=simpleGit({timeout:{block:dy}}).env("GIT_TERMINAL_PROMPT","0").env("GIT_LFS_SKIP_SMUDGE","1"),o=t?["--depth","1","--branch",t]:["--depth","1"];try{return await n.clone(e,r,o),r}catch(s){await rm(r,{recursive:true,force:true}).catch(()=>{});let i=s instanceof Error?s.message:String(s),a=i.includes("block timeout")||i.includes("timed out"),l=i.includes("Authentication failed")||i.includes("could not read Username")||i.includes("Permission denied")||i.includes("Repository not found");throw a?new sr("Clone timed out after 60s. Check your SSH keys or credentials.",e,true,false):l?new sr(`Authentication failed for ${e}. Ensure you have access and credentials are configured.`,e,false,true):new sr(`Failed to clone ${e}: ${i}`,e,false,false)}}async function vt(e){let t=normalize(resolve(e)),r=normalize(resolve(tmpdir()));if(!t.startsWith(r+sep))throw new Error("Attempted to clean up directory outside of temp directory");await rm(e,{recursive:true,force:true});}async function Cr(e,t=["--version"]){try{return (await execa(e,t,{reject:!1})).exitCode===0}catch(r){if(r instanceof Error&&"code"in r&&r.code==="ENOENT")return false;throw r}}function my(e){return typeof e=="object"&&e!==null&&e.source==="git-subdir"}function fy(e){return typeof e=="object"&&e!==null&&e.source==="url"}function gy(e){return typeof e=="object"&&e!==null&&e.source==="github"}function Yr(e,t){let r=e.source;if(my(r)){let n=r.path?r.path.replace(/^\.\//,""):".",o=r.ref&&!/^[0-9a-f]{40}$/i.test(r.ref)?r.ref:void 0;return {cloneUrl:r.url,subPath:n||".",ref:o}}if(fy(r))return {cloneUrl:r.url,subPath:"."};if(gy(r))return {cloneUrl:`https://github.com/${r.repo}`,subPath:"."};if(typeof r=="string"){if(r.startsWith("https://")||r.startsWith("git@"))return {cloneUrl:r,subPath:"."};if((r.startsWith("./")||r===".")&&t){let n=r==="."?".":r.replace(/^\.\//,"")||".";return {cloneUrl:t,subPath:n}}}return null}function et(e){return e.toLowerCase().replace(/[^a-z0-9._]+/g,"-").replace(/^[.-]+|[.-]+$/g,"").substring(0,255)||"unnamed"}var bt=I("claude-code.adapter");function Sy(e,t){let r=e??"external";if(!t)return r;let n=t.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?(?:[/?#]|$)/);if(!n)return r;let o=n[1],s=lo();if(!he__default.existsSync(s))return r;try{let i=JSON.parse(he__default.readFileSync(s,"utf-8"));for(let[a,l]of Object.entries(i))if(l.source?.repo===o)return a}catch{}return r}async function Vc(e,t){let r=e.catalogId?ue.getAdapter(e.catalogId):void 0,n=Yr(e,r?.source);if(!n)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let o=e.type==="bundle"||e.type==null,s=Sy(e.catalogId,r?.source),i=t.scope??"user",a;o?a=Ws(s,e.name,"external"):a=join(pr(i==="user"?"global":"project"),e.name);let l=null;try{nr(e.name),l=await It(n.cloneUrl,n.ref);let u=n.subPath==="."?l:join(l,n.subPath);if(he__default.existsSync(a)&&he__default.rmSync(a,{recursive:!0,force:!0}),he__default.mkdirSync(dirname(a),{recursive:!0}),he__default.cpSync(u,a,{recursive:!0}),o){let c=`${e.name}@${s}`,d=await Ui(),p={scope:i,installPath:a,version:"external",installedAt:new Date().toISOString(),origin:"external",providerId:"claude-code",type:e.type},m=d.plugins[c]??[];d.plugins[c]=[...m.filter(f=>f.scope!==i),p],Qe(d),Dn(c,!0,i);}return {success:!0,message:`Installed ${e.name} from ${n.cloneUrl}`}}catch(u){return bt.debug(`[${e.name}] External catalog install failed: ${String(u)}`),{success:false,message:u instanceof Error?u.message:String(u)}}finally{l&&await vt(l).catch(()=>{});}}async function zi(e,t,r,n){try{await b(v.CLI_TOOL_INSTALLED,{tool_id:e,tool_type:r,source:"external",scope:jo(n),version:"unknown",duration_ms:t,interface:H().interfaceType});}catch(o){bt.warn(`Failed to send external install metrics: ${String(o)}`);}}async function jc(e,t,r){try{await b(v.CLI_TOOL_INSTALL_FAILED,{tool_id:e,tool_type:r,source:"external",error_code:t instanceof Error?t.name:"UNKNOWN",error_message:(t instanceof Error?t.message:String(t)).slice(0,500),interface:H().interfaceType});}catch(n){bt.warn(`Failed to send external install-failed metrics: ${String(n)}`);}}var wy={async install(e,t){if(e.origin===Rr&&!e.installCommand&&!Jr(e.name))return Vc(e,t);if(e.origin===Rr&&e.installCommand){let r=e.type??"skill",n=await Nn(e.installCommand,t.scope);return n.exitCode===0?(await zi(e.name,n.duration_ms,r,t.scope),{success:true,message:`Installed ${e.name}`}):(await jc(e.name,new Error(n.stderr||"Install failed"),r),{success:false,message:n.stderr||`Install failed with exit code ${n.exitCode}`})}if(Jr(e.name)){let r=e.type??"skill",n=Wr(e.name,t.scope);bt.debug(`[${e.name}] Attempting install: ${n}`);let o=await xe(n);if(o.exitCode===0)return await zi(e.name,o.duration_ms,r,t.scope),{success:true};bt.debug(`[${e.name}] First attempt failed, adding marketplace`),await Xo(e.name,t.marketplaceSource,()=>{});let s=await xe(n);return s.exitCode===0?(await zi(e.name,s.duration_ms,r,t.scope),{success:true}):(await jc(e.name,new Error(s.stderr||"Install failed"),r),{success:false,message:s.stderr||`Install failed with exit code ${s.exitCode}`})}try{let r=await Ce(e.name,{...t,type:e.type});return {success:!0,message:`Installed ${e.name}@${r.version}`}}catch(r){return bt.debug(`[${e.name}] Plugin install failed: ${String(r)}`),{success:false,message:r instanceof Error?r.message:String(r)}}},async uninstall(e,t){await Wo(e,t);},getInstallPath(e,t){return ""}};function Kc(e){return {async install(t,r){if(t.origin===Rr&&!t.installCommand&&!Jr(t.name))return Vc(t,r);if(!t.installCommand)try{let o=await Ce(t.name,{...r,type:e});return {success:!0,message:`Installed ${t.name}@${o.version}`}}catch(o){return bt.debug(`[${t.name}] ${e} install failed: ${String(o)}`),{success:false,message:o instanceof Error?o.message:String(o)}}bt.debug(`[${t.name}] Executing install command: ${t.installCommand}`);let n=await Nn(t.installCommand,r.scope);return n.exitCode===0?{success:true}:{success:false,message:n.stderr||`Install failed with exit code ${n.exitCode}`}},async uninstall(t,r){throw new Error(`${e.toUpperCase()} uninstall via claude CLI not supported \u2014 use: claude ${e} remove ${t}`)},getInstallPath(t,r){return ""}}}function xy(e){for(let t of [join(e,".claude","agents"),join(e,"agents")]){if(!he__default.existsSync(t))continue;let r=he__default.readdirSync(t).filter(n=>n.endsWith(".md")&&he__default.lstatSync(join(t,n)).isFile());if(r.length>0)return r.map(n=>join(t,n))}return []}function Xi(e){return e===null||typeof e!="object"||Array.isArray(e)?e:Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,Xi(r)]))}function Hc(e,t){let r={...e};for(let[n,o]of Object.entries(t)){let s=r[n];if(Array.isArray(o)&&Array.isArray(s)){let i=new Set(s.map(a=>JSON.stringify(Xi(a))));r[n]=[...s,...o.filter(a=>!i.has(JSON.stringify(Xi(a))))];}else o!==null&&typeof o=="object"&&!Array.isArray(o)&&s!==null&&typeof s=="object"&&!Array.isArray(s)?r[n]=Hc(s,o):r[n]=o;}return r}async function Jc(e,t,r,n){let o=await Ui(),s=`${e}@claude-code`,i={scope:t,installPath:r,version:"external",installedAt:new Date().toISOString(),origin:"external",providerId:"claude-code",type:n},a=o.plugins[s]??[];o.plugins[s]=[...a.filter(l=>l.scope!==t),i],Qe(o);}var Iy={async install(e,t){let r=t.scope??"user",n=e.catalogId?ue.getAdapter(e.catalogId):void 0,o=Yr(e,n?.source);if(!o)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let s=null;try{nr(e.name),s=await It(o.cloneUrl,o.ref);let i=o.subPath==="."?s:join(s,o.subPath),a=xy(i);if(a.length===0)return {success:!1,message:`No agent files found in "${e.name}"`};let l=uo(r);he__default.mkdirSync(l,{recursive:!0});let u=et(e.name);if(a.length===1)he__default.copyFileSync(a[0],join(l,`${u}.md`));else for(let d of a){let p=et(basename(d,".md"));he__default.copyFileSync(d,join(l,`${u}--${p}.md`));}let c=a.length===1?join(l,`${u}.md`):l;return await Jc(e.name,r,c,"agent"),{success:!0,message:`Installed agent(s) from ${e.name}`}}catch(i){return bt.debug(`[${e.name}] Agent install failed: ${String(i)}`),{success:false,message:i instanceof Error?i.message:String(i)}}finally{s&&await vt(s).catch(()=>{});}},async uninstall(e,t){let r=uo(t),n=et(e);if(he__default.existsSync(r))for(let a of he__default.readdirSync(r).filter(l=>l===`${n}.md`||l.startsWith(`${n}--`)&&l.endsWith(".md")))he__default.rmSync(join(r,a),{force:true});let o=`${e}@claude-code`,s=pt(),i=(s.plugins[o]??[]).filter(a=>a.scope!==t);if(i.length===0){let{[o]:a,...l}=s.plugins;Qe({...s,plugins:l});}else Qe({...s,plugins:{...s.plugins,[o]:i}});},getInstallPath(e,t){return join(uo(t),`${et(e)}.md`)}},vy={async install(e,t){let r=t.scope??"user",n=e.catalogId?ue.getAdapter(e.catalogId):void 0,o=Yr(e,n?.source);if(!o)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let s=null;try{nr(e.name),s=await It(o.cloneUrl,o.ref);let i=o.subPath==="."?s:join(s,o.subPath),a=join(i,"settings.json");if(!he__default.existsSync(a))return {success:!1,message:`No settings.json found in "${e.name}"`};let l;try{l=JSON.parse(he__default.readFileSync(a,"utf-8"));}catch{return {success:!1,message:`settings.json in "${e.name}" contains invalid JSON`}}let u=l.hooks;if(!u||typeof u!="object"||Array.isArray(u))return {success:!1,message:`No hooks found in "${e.name}" settings.json`};let c=kn();if(c.status==="malformed")return {success:!1,message:"settings.json at destination contains invalid JSON \u2014 refusing to overwrite"};let d=c.status==="ok"?c.settings:{},p=d.hooks!==null&&typeof d.hooks=="object"&&!Array.isArray(d.hooks)?d.hooks:{},m=Hc(p,u);return Mo({...d,hooks:m}),await Jc(e.name,r,"hooks","hook"),{success:!0,message:`Installed hooks from ${e.name}`}}catch(i){return bt.debug(`[${e.name}] Hook install failed: ${String(i)}`),{success:false,message:i instanceof Error?i.message:String(i)}}finally{s&&await vt(s).catch(()=>{});}},async uninstall(e,t){throw new Error("Hook uninstall not supported \u2014 remove entries manually from settings.json")},getInstallPath(e,t){return ""}},qo=class{id="claude-code";name="Claude Code";async isAvailable(){return Cr("claude",["--version"])}getSupportedScopes(){return ["user","project","local"]}installers={bundle:wy,skill:Kc("skill"),mcp:Kc("mcp"),agent:Iy,hook:vy}};function Yo(e,t){return {async install(r,n){if(!r.installCommand)return {success:false,message:"No install command provided"};let[o,...s]=r.installCommand.split(/\s+/).filter(Boolean);if(!o||!e.has(o))return {success:false,message:`Disallowed command: "${o??""}"`};let i=await execa(o,s,{reject:false});return i.exitCode===0?{success:true}:{success:false,message:i.stderr||`Install failed with exit code ${i.exitCode}`}},async uninstall(r,n){throw new Error(`MCP uninstall not supported \u2014 ${t.replace("<name>",r)}`)},getInstallPath(r,n){return ""}}}var Py=new Set(["gh"]),Ey=Yo(Py,"use: gh copilot mcp remove <name>"),Zo=class{id="copilot";name="GitHub Copilot";async isAvailable(){return await Cr("gh",["--version"])?Cr("gh",["copilot","--version"]):false}getSupportedScopes(){return ["user"]}installers={mcp:Ey}};var Cy=new Set(["opencode"]),Ty=Yo(Cy,"use: opencode config remove mcp <name>");function ky(e){return [`// Auto-generated by Flow CLI for OpenCode compatibility \u2014 plugin: ${e}`,"import { readFileSync, readdirSync, existsSync } from 'node:fs';","import { join, dirname } from 'node:path';","import { fileURLToPath } from 'node:url';","",`const CONTENT_DIR = join(dirname(fileURLToPath(import.meta.url)), '${e}-content');`,"","function loadContent() {"," for (const dir of ['skills', '.']) {"," const d = join(CONTENT_DIR, dir);"," if (!existsSync(d)) continue;"," const files = readdirSync(d)"," .filter(f => f.endsWith('.md') && f !== 'README.md' && f !== 'LICENSE.md')"," .sort();"," if (files.length) return files.map(f => readFileSync(join(d, f), 'utf-8')).join('\\n\\n---\\n\\n');"," }"," return '';","}","","export const Plugin = async () => ({ getBootstrapContent: () => loadContent() });"].join(`
|
|
112
|
+
`)}function Gc(){return {async install(e,t){let r=e.catalogId?ue.getAdapter(e.catalogId):void 0,n=Yr(e,r?.source);if(!n)return {success:false,message:`Cannot install "${e.name}": unsupported source format.`};let o=null;try{o=await It(n.cloneUrl,n.ref);let s=n.subPath==="."?o:join(o,n.subPath),i=co(t.scope??"user"),a=join(s,".opencode","plugins");if(he__default.existsSync(a)){let l=he__default.readdirSync(a).filter(u=>u.endsWith(".js")||u.endsWith(".mjs"));if(l.length===0)return {success:!1,message:"No JS plugin file found in .opencode/plugins/"};he__default.mkdirSync(i,{recursive:!0}),he__default.copyFileSync(join(a,l[0]),join(i,`${e.name}.js`));}else {let l=join(i,`${e.name}-content`);he__default.existsSync(l)&&he__default.rmSync(l,{recursive:!0,force:!0}),he__default.mkdirSync(l,{recursive:!0}),he__default.cpSync(s,l,{recursive:!0}),he__default.mkdirSync(i,{recursive:!0}),he__default.writeFileSync(join(i,`${e.name}.js`),ky(e.name),"utf-8");}return {success:!0,message:`Installed ${e.name} for OpenCode`}}catch(s){return {success:false,message:s instanceof Error?s.message:String(s)}}finally{o&&await vt(o).catch(()=>{});}},async uninstall(e,t){let r=co(t),n=join(r,`${e}.js`),o=join(r,`${e}-content`);he__default.existsSync(n)&&he__default.rmSync(n,{force:true}),he__default.existsSync(o)&&he__default.rmSync(o,{recursive:true,force:true});},getInstallPath(e,t){return join(co(t),`${e}.js`)}}}var Qo=class{id="opencode";name="OpenCode";async isAvailable(){return Cr("opencode",["--version"])}getSupportedScopes(){return ["user","project"]}installers={mcp:Ty,skill:Gc(),bundle:Gc()}};var Pt=new Fo;Pt.register(new qo);Zt()&&(Pt.register(new Zo),Pt.register(new Qo));function Wc({itemName:e,itemType:t,onInstall:r,onClose:n}){let[o,s]=useState(false),[i,a]=useState(false),[l,u]=useState([]),[c,d]=useState(void 0);useEffect(()=>{Pt.getAvailableProviders(t??"bundle").then(u).catch(()=>{});},[t]);let p=useCallback(y=>{y==="Install"?l.length>1?a(true):s(true):n();},[n,l.length]),m=useCallback(y=>{if(y==="Cancel"){a(false);return}let w=l.find(E=>E.name===y);w?(d(w.id),a(false),s(true)):a(false);},[l]),f=useCallback(y=>{let w=sc(y);w?r(w,c):s(false);},[r,c]),g=useCallback(()=>{s(false);},[]);if(i){let y=[...l.map(w=>w.name),"Cancel"];return jsx(qe,{itemName:`${e} \u2014 Choose provider`,actions:y,onAction:m,onClose:()=>a(false)},"provider")}return o?jsx(qe,{itemName:`${e} \u2014 Choose scope`,actions:nc,descriptions:oc,onAction:f,onClose:g},"scope"):jsx(qe,{itemName:e,actions:["Install","Cancel"],onAction:p,onClose:n},"main")}function Xc({itemName:e,bundle:t,onInstall:r,onConfirm:n,onClose:o}){let s=S(f=>f.focus),[i,a]=useState(0),u=(t?.artifact.artifacts??[]).filter(f=>f.available),c=t!==void 0&&u.length===0,d=useMemo(()=>c?["Cancel"]:["Confirm Install","Cancel"],[c]);useEffect(()=>{a(0);},[t]);let p=useCallback((f,g)=>{g.upArrow?a(y=>Math.max(0,y-1)):g.downArrow?a(y=>Math.min(d.length-1,y+1)):g.return?d[i]==="Confirm Install"?n():o():g.escape&&o();},[d,i,n,o]);useInput(p,{isActive:s==="actionMenu"&&t!==void 0});let m=useCallback(f=>{f==="Install Bundle"?r():o();},[r,o]);return t?jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:t.title}),jsx(Box,{marginTop:1,children:jsxs(Text,{children:[u.length," artifact",u.length!==1?"s":""," available"]})}),jsx(Box,{flexDirection:"column",marginTop:1,marginBottom:1,children:u.map(f=>{let g=f.name??f.flowId,y=f.type??"unknown";return jsxs(Box,{gap:1,children:[jsx(Text,{color:"green",children:"\u2713"}),jsx(Text,{children:g}),jsxs(Text,{dimColor:true,children:["(",y,")"]})]},f.flowId)})}),jsx(Box,{flexDirection:"column",children:d.map((f,g)=>jsx(Box,{children:jsxs(Text,{bold:g===i,color:g===i?"cyan":void 0,children:[g===i?"\u203A ":" ",f]})},f))})]}):jsx(qe,{itemName:e,actions:["Install Bundle","Cancel"],onAction:m,onClose:o})}function rs({activeFocus:e,onConfirm:t}){let[r,n]=useState("idle"),o=S(s=>s.focus);return useInput((s,i)=>{i.escape||s==="n"?n("idle"):s==="y"&&t();},{isActive:r==="confirming"&&o===e}),{isConfirming:r==="confirming",requestConfirm:()=>n("confirming"),cancelConfirm:()=>n("idle")}}function Zc({itemName:e,itemScope:t,itemStatus:r,updateAvailable:n,catalogVersion:o,onUninstall:s,onToggleStatus:i,onUpdate:a,onClose:l}){let{isConfirming:u,requestConfirm:c}=rs({activeFocus:"actionMenu",onConfirm:()=>s(t)});if(u)return jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Uninstall "}),jsx(Text,{bold:true,color:"red",children:e}),jsx(Text,{children:"? (y/N)"})]})]});let d=r==="enabled"?"Disable":"Enable",p=o&&h(o),m=p?`Update to v${p}`:"Update";return jsx(qe,{itemName:e,actions:n?["Uninstall",d,m,"Cancel"]:["Uninstall",d,"Cancel"],onAction:y=>{y==="Uninstall"?c():y===d?i(t):y.startsWith("Update")?a?.():l();},onClose:l})}function tu({itemName:e,itemScope:t,onUninstall:r,onClose:n}){let{isConfirming:o,requestConfirm:s}=rs({activeFocus:"actionMenu",onConfirm:()=>r(t)});return o?jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,flexShrink:0,children:[jsx(Text,{bold:true,children:e}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Remove MCP "}),jsx(Text,{bold:true,color:"red",children:e}),jsx(Text,{children:"? (y/N)"})]})]}):jsx(qe,{itemName:e,actions:["Uninstall","Cancel"],onAction:l=>{l==="Uninstall"?s():n();},onClose:n})}var en=I("bundle:installer"),ru=/already exists/i;async function Oy(e){if(!e.installCommand)throw new Error("Missing install command");let t=e.installCommand;if(_c(t)){let r=await Dc(t);if(r.exitCode!==0){let n=r.stderr?.trim()||r.stdout?.trim()||`exit code ${r.exitCode}`;if(ru.test(n))return;throw new Error(n)}}else {let r=await Nn(t);if(r.exitCode!==0){let n=r.stderr?.trim()||r.stdout?.trim()||`exit code ${r.exitCode}`;if(ru.test(n))return;throw new Error(n)}}}async function Ny(e,t){try{await b(v.CLI_BUNDLE_INSTALL_STARTED,{bundle_slug:e,artifact_count:t});}catch(r){en.warn(`Failed to emit bundle install started event: ${String(r)}`);}}async function By(e,t,r){try{await b(v.CLI_BUNDLE_INSTALL_PLUGIN_SUCCESS,{bundle_slug:e,artifact_name:t,artifact_type:r});}catch(n){en.warn(`Failed to emit bundle install plugin success event: ${String(n)}`);}}async function nu(e,t,r,n){try{await b(v.CLI_BUNDLE_INSTALL_PLUGIN_FAILED,{bundle_slug:e,artifact_name:t,artifact_type:r,error_message:n});}catch(o){en.warn(`Failed to emit bundle install plugin failed event: ${String(o)}`);}}async function Uy(e,t,r,n,o){try{await b(v.CLI_BUNDLE_INSTALL_COMPLETED,{bundle_slug:e,installed_count:t,failed_count:r,unavailable_count:n,duration_ms:o});}catch(s){en.warn(`Failed to emit bundle install completed event: ${String(s)}`);}}async function ss(e,t={}){let{onProgress:r}=t,n=e.artifact.artifacts,o=n.filter(m=>m.available),s=n.length-o.length,i=e.artifact.name,a=Date.now();await Ny(i,o.length);let l=[],u=0,c=o.length;for(let[m,f]of o.entries()){let g=f.name??f.flowId,y=f.type??"unknown";if(!f.type){en.warn(`Artifact "${g}" has no type \u2014 treated as failed`),l.push({name:g,type:y,reason:"unknown artifact type"}),await nu(i,g,y,"unknown artifact type"),r?.({index:m+1,total:c,artifact:f,success:false,error:"unknown artifact type"});continue}try{await Oy(f),u++,await By(i,g,y),r?.({index:m+1,total:c,artifact:f,success:!0});}catch(w){let E=w instanceof Error?w.message:String(w);en.error(`Failed to install artifact "${g}": ${E}`),l.push({name:g,type:y,reason:E}),await nu(i,g,y,E),r?.({index:m+1,total:c,artifact:f,success:false,error:E});}}let d=Date.now()-a,p=l.length;return await Uy(i,u,p,s,d),{bundleTitle:e.title,total:n.length,installed:u,skipped:s,failed:p,failures:l}}function au({bundle:e,onComplete:t}){let[r,n]=useState(null),[o,s]=useState(null),i=useRef(false);return useEffect(()=>{i.current||(i.current=true,ss(e,{onProgress:n}).then(s).catch(a=>{let l=a instanceof Error?a.message:"Installation failed",u=e.artifact.artifacts,c=u.filter(d=>d.available);s({bundleTitle:e.title,total:u.length,installed:0,skipped:u.length-c.length,failed:c.length,failures:c.map(d=>({name:d.name??d.flowId,type:d.type??"unknown",reason:l}))});}));},[e]),useEffect(()=>{o&&t(o);},[o,t]),jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsx(Box,{paddingBottom:1,children:jsxs(Text,{bold:true,children:["Installing ",e.title,"..."]})}),r&&jsxs(Box,{gap:1,children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{color:"cyan",children:["[",r.index,"/",r.total,"] Installing"," ",r.artifact.name??r.artifact.flowId," (",r.artifact.type??"unknown",")"]})]}),!r&&jsxs(Box,{gap:1,children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsx(Text,{color:"cyan",children:"Preparing..."})]})]})}var de=create(e=>({installedItems:[],setInstalledItems:t=>e({installedItems:t}),loadFromDisk:()=>e({installedItems:se()})}));function lu({entries:e,selectedIndex:t,focusPanel:r}){let n=r==="list",o=t===0&&n;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{marginBottom:1,children:[jsx(Text,{color:"cyan",bold:true,children:o?"\u203A ":" "}),jsx(Text,{color:"cyan",bold:o,dimColor:!n,children:"+ Add Marketplace"})]}),e.map((s,i)=>{let a=i+1,l=t===a&&n,u=s.stored?.autoUpdate!==false;return jsxs(Box,{flexDirection:"column",marginBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:"cyan",children:l?"\u203A ":" "}),jsx(Text,{bold:l,dimColor:!n,children:s.adapter.name}),u&&s.stored&&jsx(Text,{color:"yellow",children:" \u2605"})]}),s.stored?.lastUpdated&&jsx(Box,{marginLeft:2,children:jsxs(Text,{dimColor:true,children:["Updated ",Wt(s.stored.lastUpdated)]})})]},s.adapter.id)})]})}function cu({entry:e,detailData:t,installedCount:r,focusPanel:n,actionIndex:o,onBrowse:s,onUpdate:i,onToggleAutoUpdate:a,onRemove:l}){let{adapter:u,stored:c}=e,d=u.removable!==false,p=c?.autoUpdate!==false,m=n==="detail",f=[{label:`Browse plugins${t&&!t.loading?` (${t.items.length})`:""}`,handler:s},{label:"Update marketplace",handler:i},...d?[{label:"Toggle auto-update",handler:a},{label:"Remove marketplace",handler:l,danger:true}]:[]];return m?jsxs(Box,{flexDirection:"column",paddingLeft:1,children:[jsx(Text,{bold:true,children:u.name}),jsx(Text,{dimColor:true,children:u.source}),jsx(Box,{marginTop:1,children:t?.loading?jsx(Text,{dimColor:true,children:"Loading..."}):t?.error?jsx(Text,{color:"red",children:t.error}):jsxs(Text,{dimColor:true,children:[t?`${t.items.length} available`:"\u2014 available",r>0?` \xB7 ${r} installed`:"",c?.lastUpdated?` \xB7 Updated ${Wt(c.lastUpdated)}`:""]})}),c&&jsxs(Box,{marginTop:1,children:[jsx(Text,{dimColor:true,children:"Auto-update: "}),p?jsx(Text,{color:"green",children:"enabled \u2605"}):jsx(Text,{dimColor:true,children:"disabled"})]}),jsx(Box,{flexDirection:"column",marginTop:1,children:f.map((g,y)=>{let w=y===o;return jsxs(Box,{children:[jsx(Text,{color:w?"cyan":void 0,children:w?"\u203A ":" "}),jsx(Text,{bold:w,color:g.danger?"yellow":void 0,dimColor:!w,children:g.label})]},g.label)})})]}):jsxs(Box,{flexDirection:"column",paddingLeft:1,children:[jsx(Text,{bold:true,children:u.name}),jsx(Text,{dimColor:true,children:u.source}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter or Tab to see details"})})]})}function uu(e){return e.adapter.removable!==false?4:2}function du({item:e,adapterName:t,isInstalled:r,onBack:n,onInstall:o,onUninstall:s}){let i=[...r&&s?[{label:"Uninstall",handler:()=>s(e),danger:true}]:!r&&o?[{label:"Install",handler:()=>o(e)}]:[],{label:"Back",handler:n}],[a,l]=useState(0);return useInput((u,c)=>{if(c.escape){n();return}if(c.upArrow){l(d=>Math.max(0,d-1));return}if(c.downArrow){l(d=>Math.min(i.length-1,d+1));return}c.return&&i[a].handler();}),jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",t," \u203A Browse plugins \u203A ",h(e.name)]}),jsxs(Box,{marginTop:1,flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{bold:true,children:h(e.name)}),e.type&&jsxs(Text,{dimColor:true,children:[" [",h(e.type),"]"]}),e.origin&&jsxs(Text,{dimColor:true,children:[" [",h(e.origin),"]"]})]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2500".repeat(50)})}),e.description?jsx(Box,{marginTop:1,children:jsx(Text,{children:h(e.description)})}):null,(e.author?.name||e.version||e.category)&&jsxs(Box,{flexDirection:"column",marginTop:1,children:[e.author?.name&&jsxs(Text,{dimColor:true,children:["Author ",h(e.author.name)]}),e.version&&jsxs(Text,{dimColor:true,children:["Version ",h(e.version)]}),e.category&&jsxs(Text,{dimColor:true,children:["Category ",h(e.category)]})]})]}),jsx(Box,{flexDirection:"column",marginTop:1,children:i.map((u,c)=>jsxs(Box,{children:[jsx(Text,{color:c===a?"cyan":void 0,children:c===a?"\u203A ":" "}),jsx(Text,{bold:c===a,color:u.danger?"yellow":void 0,dimColor:c!==a,children:u.label})]},u.label))}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter: confirm \xB7 Esc: back"})})]})}function mu({item:e,isSelected:t,isInstalled:r}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Text,{color:"cyan",children:t?"\u203A ":" "}),jsx(Text,{color:r?"green":void 0,bold:t,children:e.name}),r&&jsx(Text,{color:"green",children:" \u2713"})]}),e.description?jsx(Box,{paddingLeft:4,children:jsx(Text,{dimColor:true,wrap:"truncate",children:e.description})}):null]})}function fu({entry:e,items:t,installedKeys:r,onBack:n}){let o=e.adapter.id??"default",s=t.filter($=>r.has(`${$.name}@${o}`)),i=t.filter($=>!r.has(`${$.name}@${o}`)),a=[...s,...i],[l,u]=useState(0),[c,d]=useState(null);if(useInput(($,O)=>{if(O.escape){n();return}if(O.return){d(a[l]??null);return}if(O.upArrow){u(G=>Math.max(0,G-1));return}O.downArrow&&u(G=>Math.min(a.length-1,G+1));},{isActive:c===null}),c!==null)return jsx(du,{item:c,adapterName:e.adapter.name,isInstalled:r.has(`${c.name}@${o}`),onBack:()=>d(null)});if(t.length===0)return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",e.adapter.name," \u203A Browse plugins"]}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Empty catalog"})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Esc: back"})})]});let p=Math.max(0,l-Math.floor(Je/2)),m=Math.min(a.length,p+Je);m===a.length&&(p=Math.max(0,m-Je));let f=a.slice(p,m),g=p,y=a.length-m,w=s.length>0&&p<s.length,E=m>s.length,T=f.filter($=>r.has(`${$.name}@${o}`)),k=f.filter($=>!r.has(`${$.name}@${o}`));return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsxs(Text,{dimColor:true,children:["Marketplaces \u203A ",e.adapter.name," \u203A Browse plugins"]}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:g>0?`\u2191 ${g} more above`:" "})}),w&&jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{dimColor:true,children:["\u2500\u2500 Installed (",s.length,") \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"]}),T.map($=>jsx(mu,{item:$,isSelected:a.indexOf($)===l,isInstalled:true},$.name))]}),E&&jsxs(Box,{flexDirection:"column",marginTop:w?1:0,children:[jsxs(Text,{dimColor:true,children:["\u2500\u2500 Available (",i.length,") \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"]}),k.map($=>jsx(mu,{item:$,isSelected:a.indexOf($)===l,isInstalled:false},$.name))]}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:y>0?`\u2193 ${y} more below`:" "})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter: details \xB7 Esc: back"})})]})}Ai();var Gy=/^https?:\/\/.+/;function Wy(e){return e!==null&&typeof e=="object"&&"response"in e&&e.response?.status===404}function zy(e){return e instanceof Error&&e.code==="GITHUB_AUTH_REQUIRED"}function Su(e){let t=S(y=>y.showNotification),r=S(y=>y.incrementCatalogVersion),[n,o]=useState("idle"),[s,i]=useState(""),[a,l]=useState(""),[u,c]=useState(null),d=useRef(""),p=useRef("");useEffect(()=>{d.current=s;},[s]),useEffect(()=>{p.current=a;},[a]);let m=useCallback(()=>{d.current="",p.current="",i(""),l(""),c(null),o("add-name");},[]),f=useCallback(()=>{o("idle");},[]),g=useCallback(async()=>{let y=p.current,w=d.current;if(!Gy.test(y)){c("URL must start with http:// or https://");return}c(null),o("adding");let E=randomUUID(),T=new zr(E,w,y);try{await T.fetchItems(),await Nt.add({id:E,name:w,source:y}),ue.register(new zr(E,w,y)),r(),e(),t(`Catalog "${w}" added`,"success"),i(""),l(""),d.current="",p.current="",o("idle");}catch(k){let $=Wy(k)?"No marketplace.json found in this repository (checked main and master branches). Ensure the repo has a marketplace.json at its root.":zy(k)?k.message:k instanceof Error?`Could not reach catalog URL: ${k.message}`:"Failed to validate catalog URL";t($,"error"),o("add-url");}},[e,t,r]);return useInput((y,w)=>{if(w.escape){o("idle");return}if(w.return){d.current.trim().length>0&&o("add-url");return}if(w.backspace||w.delete){d.current=d.current.slice(0,-1),i(d.current);return}y&&!w.ctrl&&!w.meta&&(d.current=d.current+y,i(d.current));},{isActive:n==="add-name"}),useInput((y,w)=>{if(w.escape){o("add-name");return}if(w.return){g();return}if(w.backspace||w.delete){p.current=p.current.slice(0,-1),l(p.current),c(null);return}y&&!w.ctrl&&!w.meta&&(p.current=p.current+y,l(p.current),c(null));},{isActive:n==="add-url"}),{phase:n,inputName:s,inputUrl:a,urlError:u,setInputName:i,setInputUrl:l,startAdd:m,cancelAdd:f}}function wu(e){let t=S(o=>o.showNotification),r=S(o=>o.incrementCatalogVersion);return {handleRemove:useCallback(async o=>{try{await Nt.remove(o),ue.unregister(o),r(),e(),t("Catalog removed","success");}catch(s){t(s instanceof Error?s.message:"Failed to remove catalog","error");}},[e,t,r])}}function Iu(){let e=S(L=>L.focus),t=S(L=>L.setFocus),r=S(L=>L.showNotification),n=de(L=>L.installedItems),[o,s]=useState(()=>ue.listAdapters().map(L=>({adapter:L,stored:null}))),[i,a]=useState(0),[l,u]=useState("list"),[c,d]=useState(0),[p,m]=useState(null),[f,g]=useState("main"),y=useRef(o);useEffect(()=>{y.current=o;},[o]),useEffect(()=>{f==="browse"&&!o[i-1]&&g("main");},[f,o,i]);let w=useCallback(()=>{(async()=>{let L=ue.listAdapters(),N=await Nt.read(),V=new Map(N.map(ve=>[ve.id,ve]));s(L.map(ve=>({adapter:ve,stored:V.get(ve.id)??null})));})();},[]);useEffect(()=>{t("marketplaces"),w();},[t,w]),useEffect(()=>{if(i===0){m(null);return}let L=y.current[i-1];if(!L)return;let N=false;return m({items:[],loading:true,error:null}),L.adapter.fetchItems().then(V=>{N||m({items:V,loading:false,error:null});}).catch(V=>{N||m({items:[],loading:false,error:V instanceof Error?V.message:"Failed to load catalog"});}),()=>{N=true;}},[i]);let E=Su(w),T=useCallback(()=>{w(),a(0),u("list"),m(null),g("main");},[w]),{handleRemove:k}=wu(T),$=useCallback(async L=>{g("removing"),await k(L);},[k]),O=useCallback(async L=>{try{let N=await L.adapter.fetchItems();if(m({items:N,loading:!1,error:null}),L.stored){let V=new Date().toISOString();await Nt.updateField(L.stored.id,{lastUpdated:V}),w();}r("Marketplace updated","success");}catch(N){r(N instanceof Error?N.message:"Update failed","error");}},[w,r]),G=useCallback(async L=>{if(!L.stored)return;let N=L.stored.autoUpdate!==false;await Nt.updateField(L.stored.id,{autoUpdate:!N}),w();},[w]),we=useCallback(()=>g("browse"),[]),M=useCallback(L=>{let N=o[i-1];if(!N)return;let V=N.adapter.removable!==false;[we,()=>{O(N);},...V?[()=>{G(N);},()=>{$(N.adapter.id);}]:[]][L]?.();},[o,i,we,O,G,$]),x=useCallback(()=>g("main"),[]),A=useCallback(()=>{let L=o[i-1];L&&O(L);},[o,i,O]),F=useCallback(()=>{let L=o[i-1];L&&G(L);},[o,i,G]),W=useCallback(()=>{let L=o[i-1];L&&$(L.adapter.id);},[o,i,$]);if(useInput((L,N)=>{if(N.upArrow){a(V=>Math.max(0,V-1));return}if(N.downArrow){a(V=>Math.min(o.length,V+1));return}(N.return||N.tab)&&(i===0?E.startAdd():(u("detail"),d(0)));},{isActive:f==="main"&&E.phase==="idle"&&l==="list"&&e==="marketplaces"}),useInput((L,N)=>{if(N.escape||N.tab){u("list");return}if(N.upArrow){d(V=>Math.max(0,V-1));return}if(N.downArrow){let V=o[i-1],ve=V?uu(V)-1:0;d(js=>Math.min(js+1,ve));return}N.return&&M(c);},{isActive:f==="main"&&E.phase==="idle"&&l==="detail"&&e==="marketplaces"}),E.phase==="add-name")return jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Text,{bold:true,children:"Add Catalog \u2014 Step 1/2"}),jsxs(Box,{marginTop:1,children:[jsx(Text,{children:"Name: "}),jsx(Text,{color:"cyan",children:E.inputName}),jsx(Text,{color:"gray",children:"\u2588"})]}),E.inputName.trim().length===0&&jsx(Text,{dimColor:true,children:"Enter a display name for this catalog"}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter: next | Esc: cancel"})})]});if(E.phase==="add-url")return jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Text,{bold:true,children:"Add Catalog \u2014 Step 2/2"}),jsxs(Box,{marginTop:1,children:[jsx(Text,{dimColor:true,children:"Name: "}),jsx(Text,{children:E.inputName})]}),jsxs(Box,{children:[jsx(Text,{children:"URL: "}),jsx(Text,{color:"cyan",children:E.inputUrl}),jsx(Text,{color:"gray",children:"\u2588"})]}),E.urlError&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"red",children:E.urlError})}),jsx(Box,{marginTop:1,children:jsx(Text,{dimColor:true,children:"Enter: confirm | Esc: back | Must start with http:// or https://"})})]});if(E.phase==="adding")return jsx(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:jsx(Text,{children:"Validating catalog URL..."})});if(f==="removing")return jsx(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:jsx(Text,{children:"Removing catalog..."})});if(f==="browse"){let L=o[i-1];if(!L)return jsx(Box,{});let N=L.adapter.id??"default",V=new Set(n.filter(ve=>ve.marketplace===L.adapter.name).map(ve=>`${ve.name}@${N}`));return jsx(fu,{entry:L,items:p?.items??[],installedKeys:V,onBack:x})}if(o.length===0)return jsxs(Box,{flexDirection:"column",paddingX:1,children:[jsx(Box,{paddingX:1,marginBottom:1,children:jsx(Text,{bold:true,children:"Marketplaces"})}),jsx(Box,{paddingX:2,children:jsx(Text,{dimColor:true,children:"No catalogs registered"})}),jsx(Box,{marginTop:1,paddingX:1,children:jsx(Text,{dimColor:true,children:"Enter or Tab: add marketplace \xB7 \u2190\u2192: switch tab"})})]});let Lt=o[i-1]??null,gn=Lt?n.filter(L=>L.marketplace===Lt.adapter.name).length:0;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsx(Box,{flexDirection:"column",width:30,marginRight:1,children:jsx(lu,{entries:o,selectedIndex:i,focusPanel:l})}),jsx(Box,{flexDirection:"column",flexGrow:1,children:l==="detail"&&Lt?jsx(cu,{entry:Lt,detailData:p,installedCount:gn,focusPanel:l,actionIndex:c,onBrowse:we,onUpdate:A,onToggleAutoUpdate:F,onRemove:W}):jsx(Box,{paddingLeft:1,children:jsx(Text,{dimColor:true,children:Lt?"Enter or Tab to see details":"\u2191\u2193 to navigate, Enter or Tab to see details"})})})]}),jsx(Box,{marginTop:1,paddingX:1,children:l==="list"?jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Enter / Tab: see details \xB7 \u2190\u2192: switch tab"}):jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate actions \xB7 Enter: execute \xB7 Esc / Tab: back to list"})})]})}function vu(e,t,r,n){if(t.upArrow)return r.selectedIndex===0?[{type:"setSelectedIndex",index:-1},{type:"setFocus",focus:"search"}]:[{type:"setSelectedIndex",index:r.selectedIndex-1}];if(t.downArrow&&r.selectedIndex<n-1)return [{type:"setSelectedIndex",index:r.selectedIndex+1}];if(t.leftArrow){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o-1+X.length)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}if(t.rightArrow){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o+1)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}if(t.tab){let o=X.findIndex(i=>i.id===r.activeTab),s=X[(o+1)%X.length];return [{type:"setTab",tab:s.id},{type:"setSelectedIndex",index:0},{type:"setFocus",focus:s.focus}]}return t.return?[{type:"setActionMenuOpen",open:true},{type:"setFocus",focus:"actionMenu"}]:e==="/"?[{type:"setFocus",focus:"search"}]:e==="1"?[{type:"selectAllTypes"}]:e==="2"?[{type:"toggleTypeFilter",catalogType:"skill"}]:e==="3"?[{type:"toggleTypeFilter",catalogType:"mcp"}]:e==="4"?[{type:"toggleTypeFilter",catalogType:"bundle"}]:e==="5"?[{type:"selectAllOrigins"}]:e==="6"?[{type:"toggleOriginFilter",origin:"internal"}]:e==="7"?[{type:"toggleOriginFilter",origin:"external"}]:e==="a"&&r.activeTab==="updates"?[]:e&&e!==" "&&!t.ctrl&&!t.meta&&!t.escape?[{type:"setSelectedIndex",index:-1},{type:"setFocus",focus:"search"},{type:"searchAppend",char:e}]:[]}function bu(e,t){return t.escape?[{type:"setActionMenuOpen",open:false},{type:"setFocus",focus:"list"}]:[]}function Pu(e,t,r){return t.escape?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:"reset"}:t.downArrow?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:null}:t.leftArrow?{actions:[],queryUpdate:{cursorMove:-1}}:t.rightArrow?{actions:[],queryUpdate:{cursorMove:1}}:t.return?{actions:[{type:"setSelectedIndex",index:0},{type:"setFocus",focus:"list"}],queryUpdate:null}:t.backspace?r.length===0?{actions:[{type:"setFocus",focus:"list"},{type:"setSelectedIndex",index:0}],queryUpdate:null}:{actions:[],queryUpdate:{backspace:true}}:e&&!t.ctrl&&!t.meta?{actions:[],queryUpdate:{append:e}}:{actions:[],queryUpdate:null}}var Qy=new Set(X.filter(e=>e.focus!=="list").map(e=>e.focus));function Wn(e){let{setActiveTab:t,setFocus:r,setSelectedIndex:n,setActionMenuOpen:o}=S.getState();for(let s of e)if(s.type==="setTab")t(s.tab);else if(s.type==="setFocus")r(s.focus);else if(s.type==="setSelectedIndex")n(s.index);else if(s.type==="setActionMenuOpen")o(s.open);else if(s.type==="searchAppend"){let{setQuery:i,query:a,setCursorPosition:l,cursorPosition:u}=Be.getState();i(a.slice(0,u)+s.char+a.slice(u)),l(u+s.char.length);}else s.type==="toggleTypeFilter"?S.getState().toggleTypeFilter(s.catalogType):s.type==="selectAllTypes"?S.getState().selectAllTypes():s.type==="toggleOriginFilter"?S.getState().toggleOriginFilter(s.origin):s.type==="selectAllOrigins"&&S.getState().selectAllOrigins();}function Eu({listLength:e}){let t=S(g=>g.focus),r=S(g=>g.selectedIndex),n=S(g=>g.actionMenuOpen),o=S(g=>g.setFocus),s=S(g=>g.setActionMenuOpen),i=Be(g=>g.query),a=Be(g=>g.setQuery),l=Be(g=>g.resetQuery),u=useRef(e);useEffect(()=>{u.current=e;},[e]),useEffect(()=>{if(t==="search"){let{query:g,setCursorPosition:y}=Be.getState();y(g.length);}},[t]);let[c,d]=useState("");useEffect(()=>{let g=setTimeout(()=>d(i),300);return ()=>clearTimeout(g)},[i]),useInput((g,y)=>{let{activeTab:w,selectedIndex:E,actionMenuOpen:T}=S.getState();Wn(hi(g,y,{activeTab:w}));},{isActive:t==="tabs"}),useInput((g,y)=>{if(!y.leftArrow&&!y.rightArrow)return;let{activeTab:w,selectedIndex:E,actionMenuOpen:T}=S.getState();Wn(hi("",y,{activeTab:w}));},{isActive:Qy.has(t)}),useInput((g,y)=>{let{activeTab:w,selectedIndex:E,actionMenuOpen:T}=S.getState();Wn(vu(g,y,{activeTab:w,selectedIndex:E},u.current));},{isActive:t==="list"}),useInput((g,y)=>{Wn(bu(g,y));},{isActive:t==="actionMenu"}),useInput((g,y)=>{let w=Pu(g,y,Be.getState().query),E=w.queryUpdate;if(Wn(w.actions),E==="reset")l(),d("");else if(E!==null){let{query:T,cursorPosition:k,setCursorPosition:$}=Be.getState();if("backspace"in E)k>0&&(a(T.slice(0,k-1)+T.slice(k)),$(k-1));else if("append"in E)a(T.slice(0,k)+E.append+T.slice(k)),$(k+E.append.length);else if("cursorMove"in E){let O=k+E.cursorMove;O>=0&&O<=T.length&&$(O);}}},{isActive:t==="search"});let p=useCallback(()=>{s(false),o("list");},[s,o]),m=useCallback(g=>{let{setSelectedIndex:y,selectedIndex:w}=S.getState();g===0?y(0):w>=g&&y(g-1);},[]),f=useCallback(g=>{if(!c)return u.current=g.length,g;let y=c.toLowerCase(),w=g.filter(E=>E.name.toLowerCase().includes(y)||E.description?.toLowerCase().includes(y));return u.current=w.length,w},[c]);return {actionMenuOpen:n,closeMenu:p,selectedIndex:r,clampIndex:m,filteredItems:f}}function Tu(){let e=S(a=>a.notification),t=S(a=>a.showNotification),r=S(a=>a.clearNotification),n=ze(a=>a.justAuthenticated),o=ze(a=>a.credentials),s=ze(a=>a.setJustAuthenticated);return useEffect(()=>{n&&o&&(t(`Authenticated. Tenant: ${o.tenant}`,"success"),s(false));},[n,o]),useEffect(()=>{if(!e)return;let a=setTimeout(r,3e3);return ()=>clearTimeout(a)},[e]),{notify:(a,l)=>{t(a,l);}}}function Ae(e,t,r=false){return r?true:!ea.valid(e)||!ea.valid(t)?false:ea.gt(t,e)}var Ft=I("updater");async function eh(e,t,r,n,o,s){try{await b(v.CLI_TOOL_UPDATED,{tool_id:e,tool_type:s,source:o,from_version:t,to_version:r,duration_ms:n,interface:H().interfaceType});}catch(i){Ft.warn(`Failed to send update metrics: ${String(i)}`);}}function th(e){let t=pt(),r=`${e}@${re}`,n=t.plugins[r];return !n||n.length===0?null:{pluginKey:r,entry:n[0]}}async function cs(e,t={}){let r=Date.now(),n=null;try{Ft.debug(`[${e}] Acquiring lock...`),n=await rr();let o=th(e);if(!o)throw Ft.error(`[${e}] Plugin is not installed`),new Error(`Plugin "${e}" is not installed`);let{entry:s}=o,i=s.version,a=s.installPath;Ft.debug(`[${e}] Fetching manifest...`);let u=(await Xr(e)).version;if(!i||!Ae(i,u,t.force))throw Ft.debug(`[${e}] Already up to date (v${i??"n/a"})`),new er(e,i??"unknown");Ft.info(`[${e}] Updating v${i} \u2192 v${u}...`),await n(),n=null;try{let c=await Ce(e,{force:!0,skipMetrics:!0}),d=Date.now()-r;return await eh(c.name,i,c.version,d,s.origin??"internal",s.type??"skill"),Ft.debug(`[${e}] Updated successfully in ${d}ms`),{name:c.name,previousVersion:i,newVersion:c.version,path:c.path,duration_ms:d}}catch(c){Ft.warn(`[${e}] Install failed, rolling back to v${i}...`),n=await rr();let d=pt(),p=`${e}@${re}`;throw d.plugins[p]&&(d.plugins[p][0].version=i,d.plugins[p][0].installPath=a,Qe(d),Ft.info(`[${e}] Rollback completed, restored to v${i}`)),c}}finally{n&&await n();}}var us=I("dispatcher");async function rh(e,t,r,n,o){let s=Gr(e);return us.debug(`[${e}] Install failed (exit code), attempting marketplace add`),o?.onError?.(r),n?o?.onStatus?.(`Adding marketplace for ${s}...`):o?.onPause?.(),await Xo(e,n,()=>{}),o?.onResume?.(`Retrying install for ${s}...`),us.debug(`[${e}] Retrying install after marketplace add`),xe(t)}async function ku(e,t,r,n){let o=Wr(e,n),s=Gr(e);r?.onStatus?.(`Installing ${s}...`),us.debug(`[${e}] Attempting install: ${o}`);let i=await xe(o);if(i.exitCode===0)return i;us.debug(`[${e}] Install failed (exit ${i.exitCode}), attempting marketplace add`);let a=i.stderr||`Install failed with exit code ${i.exitCode}`;return rh(e,o,a,t,r)}async function Au(e,t,r){let n=e.type??"bundle",o=await Pt.getAvailableProviders(n),s=o[0];if(!s)throw new Error(`No available provider for artifact type "${n}"`);let i=s.installers[n];if(!i)throw new Error(`Provider "${s.id}" does not support type "${n}"`);let a=t??{},l=a;return i.install(e,l)}function $u(){let e=de(i=>i.installedItems),t=de(i=>i.loadFromDisk),r=useCallback(async(i,a)=>{let l=await Au(i,a);if(!l.success)throw new Error(l.message||"Installation failed");t();},[t]),n=useCallback(async(i,a)=>{let l=se().find(m=>m.name===i),u=l?.providerId??"claude-code",c=Pt.getAdapter(u);if(!c)throw new Error(`Provider "${u}" not found`);let d=l?.type??"bundle",p=c.installers[d];if(!p)throw new Error(`Provider "${u}" does not support type "${d}"`);await p.uninstall(i,a??"user"),t();},[t]),o=useCallback(async(i,a)=>{let u=e.find(c=>c.name===i)?.status==="enabled"?"disabled":"enabled";await On(i,u,a),t();},[e,t]),s=useCallback(async i=>{await cs(i),t();},[t]);return {install:r,uninstall:n,toggle:o,update:s}}var ps=I("mcp");function zn(e,t){e.silent?We({status:"error",mcp:t.name,...t.exitCode!==void 0&&{exitCode:t.exitCode},message:t.message}):P(`Failed to ${t.action} MCP "${t.name}": ${t.message}`);}function Lu(e,t){e.silent?Oe({status:"success",mcp:t.name,command:t.command,duration_ms:t.durationMs}):(ne(`MCP "${t.name}" ${t.actionPastTense} successfully`),e.verbose&&t.stdout&&C(t.stdout));}function nh(e,t,r,n){let o=["claude","mcp","add","--transport",r,e];return t.length>0&&o.push(...t),n&&o.push("--scope",n),o.join(" ")}function ta(e,t){if(e.startsWith("-"))throw new Error(`Invalid MCP server name: "${e}". Names must not start with '-'.`);let r=["claude","mcp","remove",e];return t&&r.push("--scope",t),r.join(" ")}async function Ru(e,t,r){if(!await ye())return 1;if(t.length===0){let s=r.transport==="http"?"a URL":"a command";return zn(r,{name:e,action:"add",message:`${r.transport} transport requires ${s}`}),1}ps.debug(`[${e}] Starting MCP add with args: ${t.join(" ")}`);let n=nh(e,t,r.transport,r.scope);if(!r.force){let s=h(e),i=h(n);if(!await xt(`Install external MCP "${s}"?
|
|
113
113
|
This will run: ${i}
|
|
114
|
-
[y/N] `))return
|
|
114
|
+
[y/N] `))return ps.debug(`[${e}] Installation cancelled by user`),C("Operation cancelled."),0}let o=r.silent?void 0:Aa({text:`Adding MCP "${h(e)}"...`}).start();try{let s=await xe(n);return o?.stop(),s.exitCode!==0?(zn(r,{name:e,action:"add",message:s.stderr||"Command failed",exitCode:s.exitCode}),!r.silent&&r.verbose&&s.stdout&&C(`stdout: ${s.stdout}`),1):(Lu(r,{name:e,actionPastTense:"added",command:n,durationMs:s.duration_ms,stdout:s.stdout}),0)}catch(s){return o?.stop(),zn(r,{name:e,action:"add",message:Q(s)}),1}}async function _u(e,t){if(!await ye())return 1;ps.debug(`[${e}] Starting MCP remove`);let r=ta(e,t.scope);if(!t.force){let o=h(e),s=h(r);if(!await xt(`Remove MCP "${o}"?
|
|
115
115
|
This will run: ${s}
|
|
116
|
-
[y/N] `))return ls.debug(`[${e}] Removal cancelled by user`),T("Operation cancelled."),0}let n=t.silent?void 0:Ea({text:`Removing MCP "${y(e)}"...`}).start();try{let o=await we(r);return n?.stop(),o.exitCode!==0?(Jn(t,{name:e,action:"remove",message:o.stderr||"Command failed",exitCode:o.exitCode}),!t.silent&&t.verbose&&o.stdout&&T(`stdout: ${o.stdout}`),1):(ku(t,{name:e,actionPastTense:"removed",command:r,durationMs:o.duration_ms,stdout:o.stdout}),0)}catch(o){return n?.stop(),Jn(t,{name:e,action:"remove",message:Q(o)}),1}}function Mu({selectedItem:e,selectedCatalogItem:t,items:r,closeMenu:n,clampIndex:o,notify:s}){let i=I("pluginHandlers"),a=S(C=>C.setLoading),{install:l,uninstall:u,toggle:c,update:d}=Tu(),p=async(C,k,$)=>{a(true,C),n();try{await k(),o(r.length),s($,"success");}catch(O){let G=O instanceof Error?O.message:"Something went wrong";i.error(`[withLoading] ${C} failed: ${G}`),s(G,"error");}finally{a(false);}};return {handleInstall:(C,k)=>{e&&t&&p(`Installing ${e.name}...`,()=>l(t,{scope:C,...k!==void 0?{providerId:k}:{}}),"\u2713 Installed successfully");},handleUninstall:C=>{e&&p(`Uninstalling ${e.name}...`,()=>u(e.name,C),"\u2713 Uninstalled");},handleToggleStatus:C=>{if(!e)return;let k=e.status==="enabled";p(k?`Disabling ${e.name}...`:`Enabling ${e.name}...`,()=>c(e.name,C),k?"\u2713 Disabled":"\u2713 Enabled");},handleUpdate:()=>{if(!e)return;let C=t?` to v${t.version}`:"";(async()=>{a(true,`Updating ${e.name}${C}...`),n();try{await d(e.name),o(r.length),s(`\u2713 Updated ${e.name}${C}`,"success");}catch($){if($ instanceof zt)s($.message,"info");else {let O=$ instanceof Error?$.message:"Something went wrong";i.error(`[handleUpdate] ${e.name} failed: ${O}`),s(O,"error");}}finally{a(false);}})();},handleBatchUpdate:C=>{if(C.length===0)return;let k=C.length;(async()=>{a(true,`Updating ${k} plugin${k>1?"s":""}...`),n();try{let O=[];for(let M of C)O.push(await d(M.name).then(()=>({status:"fulfilled",value:void 0}),x=>({status:"rejected",reason:x})));let G=O.filter(M=>M.status==="fulfilled").length,ye=O.map((M,x)=>M.status==="rejected"?C[x].name:null).filter(M=>M!==null);o(r.length),ye.length===0?s(`\u2713 Updated ${G}/${k} plugin${k>1?"s":""}`,"success"):(i.error(`[handleBatchUpdate] failed: ${ye.join(", ")}`),s(`Updated ${G}/${k}; failed: ${ye.join(", ")}`,G>0?"info":"error"));}finally{a(false);}})();},handleMcpConfigUninstall:C=>{e&&p(`Removing MCP ${e.name}...`,async()=>{let k=qi(e.name,C),$=await we(k);if($.exitCode!==0)throw new Error($.stderr||"MCP removal failed");ue.getState().loadFromDisk();},"\u2713 MCP removed");}}}var cs=I("api:bundle"),tn=class extends Error{constructor(t){super(`Bundle '${t}' not found in your tenant. Verify the name with whoever shared the command.`),this.name="BundleNotFoundError";}},Gn=class extends Error{constructor(){super("The server encountered an error while fetching the bundle. Please try again later."),this.name="BundleServerError";}};async function us(e){let t=encodeURIComponent(e);cs.debug(`Fetching bundle by name "${e}"`);let r;try{r=await mt().get(`v1/use-cases/by-name/${t}`).json(),cs.debug(`API returned ${r.length} result(s) for "${e}"`);}catch(n){if(n instanceof HTTPError){let o=n.response.status;throw cs.error(`HTTP error fetching bundle '${e}' [status=${o}]`),o===StatusCodes.NOT_FOUND?new tn(e):o===StatusCodes.INTERNAL_SERVER_ERROR?new Gn:new Error(`Server error (${o}) \u2014 please try again later.`)}throw cs.error(`Unexpected error fetching bundle '${e}': ${n instanceof Error?n.message:String(n)}`),n}if(r.length===0)throw new tn(e);return r[0]}function Ru({closeMenu:e,notify:t}){let r=S(a=>a.bundleInstallFlow);return {handleBundleInstallStart:a=>{let{setLoading:l,setBundleInstallFlow:u}=S.getState();l(true,"Loading bundle..."),us(a).then(c=>{l(false),S.getState().actionMenuOpen&&u({phase:"detail",bundle:c});}).catch(c=>{l(false),t(c instanceof Error?c.message:"Failed to load bundle","error");});},handleBundleDetailConfirm:()=>{if(!r||r.phase!=="detail")return;let{setBundleInstallFlow:a,setFocus:l}=S.getState();a({phase:"installing",bundle:r.bundle}),l("bundleInstallProgress");},handleBundleDetailBack:()=>{let{setBundleInstallFlow:a}=S.getState();a(null),e();},handleBundleInstallComplete:a=>{S.getState().setBundleInstallFlow(null),e(),ue.getState().loadFromDisk(),t(`\u2713 Installed ${a.installed} of ${a.total} artifacts`,"success");}}}var Wn=["local","project","user"],Yh=new Set(["--transport","--scope","-s"]);function _u(e){let t=e.split(/\s+/).filter(Boolean),r=t.indexOf("add");if(r===-1)return null;let n=r+1;for(;n<t.length;){let o=t[n];if(Yh.has(o))n+=2;else if(o.startsWith("-"))n+=1;else return o.replace(/^["']|["']$/g,"")}return null}function vr(e,t){return t?`${e}::${t}`:e}function Yi(e){return e===re?mn:kr}function Du(e){return {name:y(e.name),version:e.version?y(e.version):e.version,description:e.description?y(e.description):e.description,authorName:e.author?.name?y(e.author.name):e.author?.name,updateAvailable:e.updateAvailable,type:e.type??"bundle",origin:e.origin??mn}}function Zi(e,t){let r=Yi(e.marketplace);return {name:y(e.name),version:e.version?y(e.version):e.version,description:e.description?y(e.description):e.description,authorName:e.author?.name?y(e.author.name):e.author?.name,status:e.status,scope:e.scope,marketplace:e.marketplace,updateAvailable:e.updateAvailable,installedAt:e.installedAt,type:t?.type??e.type??"bundle",origin:t?.origin??r}}function Ou(e){let t=new Map;for(let r of e){if(!r.scope)continue;let n=t.get(r.scope)??[];n.push(r),t.set(r.scope,n);}return Wn.filter(r=>t.has(r)).map(r=>({scope:r,label:fn[r].label,pathHint:fn[r].pathHint,items:t.get(r)??[]}))}function Nu(e){let t=r=>{if(!r)return 1/0;let n=Wn.indexOf(r);return n===-1?1/0:n};return [...e].sort((r,n)=>t(r.scope)-t(n.scope))}function Bu({catalog:e,installedItems:t,activeTab:r,catalogFilters:n,searchQuery:o}){let s=useMemo(()=>new Set(t.map(f=>vr(f.name,f.author?.name))),[t]),i=useMemo(()=>new Set(t.filter(f=>f.type==="mcp").map(f=>f.name.toLowerCase())),[t]),a=useMemo(()=>{let f=new Map(e.map(h=>[vr(h.name,h.author?.name),h])),g=new Map(e.map(h=>[h.name,h]));return t.map(h=>{let w=f.get(vr(h.name,h.author?.name))??g.get(h.name),P=w?.version,C=!!P&&!!h.version&&Te(h.version,P);return {...h,updateAvailable:C,catalogItem:w}})},[t,e]),l=useMemo(()=>r==="discover"?e.filter(f=>{if(s.has(vr(f.name,f.author?.name)))return false;if(f.type==="mcp"){let g=f.installCommand?_u(f.installCommand)?.toLowerCase():null;if(i.has(f.name.toLowerCase())||g&&i.has(g))return false}return true}).map(f=>Du(f)):r==="updates"?a.filter(f=>f.updateAvailable).map(f=>Zi(f,f.catalogItem)):a.map(f=>Zi(f,f.catalogItem)),[r,e,s,i,a]),u=useMemo(()=>l.filter(f=>{let g=f.type??"bundle";if(!n.types.has(g))return false;let h=f.origin??"internal";return n.origins.has(h)}),[l,n]),c=useMemo(()=>{let{types:f}=n;if(f.size===1){if(f.has("skill"))return "skills";if(f.has("mcp"))return "MCPs";if(f.has("bundle"))return "bundles"}return "items"},[n]),d=useMemo(()=>r==="installed"?o?`No ${c} found for '${o}' \u2014 explore the Discover tab!`:`No ${c} installed \u2014 explore the Discover tab!`:r==="updates"?o?`No ${c} found for '${o}' \u2014 all up to date!`:"All up to date \u2014 nothing to update":o?`No ${c} found for '${o}'`:`No ${c} available in the catalog`,[r,o,c]),p=useMemo(()=>{let f=new Map(e.map(h=>[vr(h.name,h.author?.name),h])),g=new Map(e.map(h=>[h.name,h]));return h=>h?f.get(vr(h.name,h.authorName))??g.get(h.name)??null:null},[e]),m=useMemo(()=>a.filter(f=>f.updateAvailable).length,[a]);return {items:u,emptyMessage:d,getSelectedCatalogItem:p,outdatedCount:m}}function Qi(){let[e,t]=useState([]),[r,n]=useState(true),[o,s]=useState(null),[i,a]=useState(null),l=useRef(false),u=S(d=>d.catalogVersion),c=useCallback(async()=>{n(true),s(null),a(null);try{let{items:d,failures:p}=await pc();if(t(d),p.length>0){let m=p.map(f=>f.adapterName).join(", ");a(`Some catalogs failed to load: ${m}`);}l.current||(l.current=!0,v(b.CLI_CATALOG_VIEWED,{interface:"tui",filter_type:"all",result_count:d.length}).catch(()=>{}));}catch(d){s(d instanceof Error?d:new Error(String(d))),t([]);}finally{n(false);}},[]);return useEffect(()=>{c();},[c,u]),{catalog:e,isLoading:r,error:o,partialError:i,refetch:c}}function Uu(){return {items:ue(t=>t.installedItems)}}var ry=I("catalog");function ju(){let e=S(Z=>Z.bundleInstallFlow),t=S(Z=>Z.activeTab),r=S(Z=>Z.notification),n=S(Z=>Z.loading),o=S(Z=>Z.loadingMessage),s=S(Z=>Z.catalogError),i=S(Z=>Z.setCatalogError),a=S(Z=>Z.catalogFilters),l=Oe(Z=>Z.query),{catalog:u,isLoading:c,error:d,refetch:p}=Qi(),{items:m}=Uu(),f=ue(Z=>Z.loadFromDisk),{items:g,emptyMessage:h,getSelectedCatalogItem:w,outdatedCount:P}=Bu({catalog:u,installedItems:m,activeTab:t,catalogFilters:a,searchQuery:l}),{actionMenuOpen:C,closeMenu:k,selectedIndex:$,clampIndex:O,filteredItems:G}=Iu({listLength:g.length}),ye=G(g),M=useMemo(()=>t!=="installed"&&t!=="updates"?ye:Nu(ye),[t,ye]),x=useMemo(()=>t==="installed"||t==="updates"?Ou(M):[],[t,M]),A=M[$]??null,F=useMemo(()=>w(A),[w,A]),{notify:W}=vu(),{handleInstall:Et,handleUninstall:pn,handleToggleStatus:L,handleUpdate:N,handleBatchUpdate:V,handleMcpConfigUninstall:Ie}=Mu({selectedItem:A,selectedCatalogItem:F,items:g,closeMenu:k,clampIndex:O,notify:W}),{handleBundleInstallStart:Ns,handleBundleDetailConfirm:Gp,handleBundleDetailBack:Wp,handleBundleInstallComplete:zp}=Ru({closeMenu:k,notify:W}),Xp=useCallback(()=>V(M),[V,M]);return useEffect(()=>{f();},[]),useEffect(()=>{O(M.length);},[M.length,O]),useEffect(()=>{d&&(ry.error(`[catalog] ${d instanceof Error?d.message:String(d)}`),i("Failed to load catalog"));},[d]),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Nr,{}),jsx(Al,{outdatedCount:P}),t==="marketplaces"&&Gt()?jsx(Box,{flexDirection:"column",flexGrow:1,children:jsx(yu,{})}):jsx(Jl,{filteredItems:M,groups:x,emptyMessage:h,onBatchUpdate:Xp}),(n||c)&&jsx(Lo,{message:n?o:"Loading catalog..."}),s&&!c&&t==="discover"&&jsx(Ro,{message:s,onRetry:()=>{i(null),p();},onBack:()=>i(null)}),r&&jsx(Gl,{message:r.message,type:r.type}),C&&A&&(t==="discover"?F?.type==="bundle"?e?.phase==="installing"?jsx(nu,{bundle:e.bundle,onComplete:zp}):jsx(Jc,{itemName:A.name,bundle:e?.phase==="detail"?e.bundle:void 0,onInstall:()=>Ns(A.name),onConfirm:Gp,onClose:e?.phase==="detail"?Wp:k}):jsx(Vc,{itemName:A.name,itemType:F?.type,onInstall:Et,onClose:k}):A.type==="mcp"?jsx(Yc,{itemName:A.name,itemScope:A.scope??"user",onUninstall:Ie,onClose:k}):jsx(zc,{itemName:A.name,itemScope:A.scope??"user",itemStatus:A.status??"enabled",updateAvailable:A.updateAvailable??false,catalogVersion:F?.version,onUninstall:pn,onToggleStatus:Z=>L(Z),onUpdate:N,onClose:k})),jsx(Mo,{})]})}var _=create((e,t)=>({starterKits:[],selectedStarterKitIndex:0,selectedStarterKit:null,plugins:[],pluginCursorIndex:0,step:"starterKitList",isLoadingStarterKits:false,starterKitsError:null,successCount:0,failedCount:0,summaryActionIndex:0,setStarterKits:r=>e({starterKits:r}),setSelectedStarterKitIndex:r=>e({selectedStarterKitIndex:r}),selectStarterKit:r=>{let n=new Set(ue.getState().installedItems.map(o=>o.name));e({selectedStarterKit:r,plugins:r.plugins.map(o=>({name:o,selected:true,status:n.has(o)?"success":"pending",installed:n.has(o)})),pluginCursorIndex:0,step:"starterKitDetail"});},setPluginCursorIndex:r=>e({pluginCursorIndex:r}),setStep:r=>e({step:r}),setPluginStatus:(r,n,o)=>{let s=t().plugins.map(i=>i.name===r?{...i,status:n,error:o}:i);e({plugins:s});},setIsLoadingStarterKits:r=>e({isLoadingStarterKits:r}),setStarterKitsError:r=>e({starterKitsError:r}),setSummaryActionIndex:r=>e({summaryActionIndex:r}),computeSummary:()=>{let n=t().plugins.filter(o=>o.selected);e({successCount:n.filter(o=>o.status==="success").length,failedCount:n.filter(o=>o.status==="failed").length});},resetForRetry:()=>{let r=t().plugins.map(n=>n.status==="failed"?{...n,status:"pending",error:void 0}:n);e({plugins:r,step:"installing"});},goBackToList:()=>e({selectedStarterKit:null,plugins:[],pluginCursorIndex:0,step:"starterKitList"})}));var iy=3;function Vu(){let e=_(l=>l.setStarterKits),t=_(l=>l.setIsLoadingStarterKits),r=_(l=>l.setStarterKitsError),n=_(l=>l.setPluginStatus),o=_(l=>l.setStep),s=_(l=>l.computeSummary),i=useCallback(async()=>{t(true),r(null);try{let l=await jo();e(l);}catch(l){r(l instanceof Error?l.message:String(l));}finally{t(false);}},[t,r,e]);useEffect(()=>{ue.getState().loadFromDisk(),i();},[i]);let a=useCallback(async()=>{let l=_.getState().plugins.filter(c=>c.selected&&c.status==="pending");for(let c of l){n(c.name,"installing");let d="",p=false;for(let m=1;m<=iy;m++)try{await Ee(c.name),n(c.name,"success"),p=!0;break}catch(f){if(f instanceof Ne){n(c.name,"success"),p=true;break}d=f instanceof Error?f.message:"Unknown error";}p||(n(c.name,"failed",d),v(b.CLI_TOOL_INSTALL_FAILED,{tool_id:c.name,tool_type:"skill",source:"internal",error_code:"install_failed",error_message:d,interface:H().interfaceType}).catch(()=>{}));}let u=pr();dr("summary_review"),v(b.CLI_STEP_COMPLETED,{step:"tool_installation",duration_ms:u}).catch(()=>{}),ue.getState().loadFromDisk(),s(),o("summary");},[n,s,o]);return {loadStarterKits:i,installSelected:a}}var zn={cursorDelta:0,confirm:false,back:false};function Hu(e,t){return t.upArrow?{...zn,cursorDelta:-1}:t.downArrow?{...zn,cursorDelta:1}:t.escape?{...zn,back:true}:t.return?{...zn,confirm:true}:zn}var ay={cursorDelta:0,select:false};function Ju(e,t){return t.upArrow?{cursorDelta:-1,select:false}:t.downArrow?{cursorDelta:1,select:false}:t.return?{cursorDelta:0,select:true}:ay}var Gu=bf.memo(function({starterKit:t,isSelected:r}){return jsxs(Box,{flexDirection:"column",paddingBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":"\u25CB "}),jsx(Text,{bold:r,color:r?"cyan":"white",children:y(t.name)}),jsxs(Text,{dimColor:true,children:[" \xB7 ",t.plugins.length," ",t.plugins.length===1?"plugin":"plugins"]})]}),jsx(Box,{paddingLeft:2,children:jsx(Text,{dimColor:true,children:y(t.description)})})]})});var sa=5;function Wu({onRetry:e}){let t=_(c=>c.starterKits),r=_(c=>c.selectedStarterKitIndex),n=_(c=>c.isLoadingStarterKits),o=_(c=>c.starterKitsError);if(n)return jsx(Lo,{message:"Loading Starter Kits..."});if(o)return jsx(Ro,{message:o,onRetry:e,onBack:e});if(t.length===0)return jsx(Br,{message:"No Starter Kits available."});let s=Math.max(0,r-Math.floor(sa/2)),i=Math.min(t.length,s+sa);i===t.length&&(s=Math.max(0,i-sa));let a=t.slice(s,i),l=s,u=t.length-i;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Select a Starter Kit to get started"})}),l>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2191 ",l," more above"]})}),a.map((c,d)=>jsx(Gu,{starterKit:c,isSelected:s+d===r},c.slug)),u>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2193 ",u," more below"]})})]})}var Xu=bf.memo(function({plugin:t,isCursor:r}){return jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":" "}),jsx(Text,{color:"cyan",children:"\u2022"}),jsxs(Text,{bold:r,color:r?"cyan":"white",children:[" ",y(t.name)]}),t.installed&&jsx(Text,{color:"green",children:" (installed)"})]})});var la=8;function qu(){let e=_(c=>c.selectedStarterKit),t=_(c=>c.plugins),r=_(c=>c.pluginCursorIndex),n=useRef(false);if(useEffect(()=>{e&&!n.current&&(n.current=true,v(b.CLI_KIT_DISPLAYED,{bundle_slug:e.slug,tool_count:t.length}).catch(()=>{}));},[e,t.length]),!e)return jsx(Text,{dimColor:true,children:"No Starter Kit selected."});let o=t.filter(c=>c.installed).length,s=Math.max(0,r-Math.floor(la/2)),i=Math.min(t.length,s+la);i===t.length&&(s=Math.max(0,i-la));let a=t.slice(s,i),l=s,u=t.length-i;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:[jsx(Text,{bold:true,color:"cyan",children:y(e.name)}),jsx(Text,{dimColor:true,children:y(e.description)})]}),jsx(Box,{paddingX:1,paddingBottom:1,children:jsxs(Text,{children:[t.length," plugins to install",o>0&&` \xB7 ${o} already installed`]})}),l>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2191 ",l," more above"]})}),a.map((c,d)=>jsx(Xu,{plugin:c,isCursor:s+d===r},c.name)),u>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2193 ",u," more below"]})})]})}var hy=["Retry failed","Continue anyway"];function Yu({name:e,status:t,error:r}){let n=y(e);return t==="installing"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",n]})]}):t==="success"?jsx(Box,{children:jsxs(Text,{color:"green",children:["\u2713 ",n]})}):t==="failed"?jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",n]}),r&&jsxs(Text,{dimColor:true,children:[" \u2014 ",y(r)]})]}):jsx(Box,{children:jsxs(Text,{dimColor:true,children:["\u25CB ",n]})})}function Zu({onComplete:e,onRetry:t}){let r=_(u=>u.plugins),n=_(u=>u.step),o=_(u=>u.successCount),s=_(u=>u.failedCount),i=_(u=>u.summaryActionIndex),a=r.filter(u=>u.selected),l=useRef(false);return useEffect(()=>{if(n==="summary"&&s===0&&!l.current){l.current=true;let u=setTimeout(e,1500);return ()=>clearTimeout(u)}},[n,s,e]),n==="installing"?jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Installing plugins..."})}),jsx(Box,{flexDirection:"column",paddingX:1,children:a.map(u=>jsx(Yu,{name:u.name,status:u.status,error:u.error},u.name))})]}):jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Installation Complete"})}),jsxs(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:[o>0&&jsxs(Text,{color:"green",children:["\u2713 ",o," ",o===1?"plugin":"plugins"," installed successfully"]}),s>0&&jsxs(Text,{color:"red",children:["\u2717 ",s," ",s===1?"plugin":"plugins"," failed"]})]}),s>0&&jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:a.filter(u=>u.status==="failed").map(u=>jsx(Yu,{name:u.name,status:u.status,error:u.error},u.name))}),s>0&&jsx(Box,{flexDirection:"column",paddingX:1,children:hy.map((u,c)=>jsx(Box,{children:jsxs(Text,{bold:c===i,color:c===i?"cyan":void 0,children:[c===i?"\u203A ":" ",u]})},u))}),s===0&&jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:"Proceeding to main screen..."})})]})}function Qu(){let e=_(x=>x.step),t=_(x=>x.starterKits),r=_(x=>x.selectedStarterKitIndex),n=_(x=>x.setSelectedStarterKitIndex),o=_(x=>x.selectStarterKit),s=_(x=>x.plugins),i=_(x=>x.pluginCursorIndex),a=_(x=>x.setPluginCursorIndex),l=_(x=>x.setStep),u=_(x=>x.summaryActionIndex),c=_(x=>x.setSummaryActionIndex),d=_(x=>x.failedCount),p=_(x=>x.resetForRetry),m=_(x=>x.goBackToList),f=S(x=>x.setScreen),g=S(x=>x.setFocus),h=S(x=>x.focus),w=Ge(x=>x.setJustAuthenticated),P=Ge(x=>x.justAuthenticated),{loadStarterKits:C,installSelected:k}=Vu(),$=useRef(false);useEffect(()=>{e==="starterKitList"?(g("starterKitList"),$.current||($.current=true,dr("bundle_selection"))):g(e==="starterKitDetail"?"starterKitDetail":"installProgress");},[e,g]);let O=useCallback(async()=>{let x=_.getState().selectedStarterKit;if(x){let F=await oe();F&&await Tt({...F,starterKit:x.slug});}v(b.CLI_STEP_COMPLETED,{step:"summary_review",duration_ms:pr()}).catch(()=>{});let{successCount:A}=_.getState();v(b.CLI_ONBOARDING_COMPLETED,{duration_ms:Ct(),tools_installed_count:A}).catch(()=>{}),w(false),g("verify"),f("verify");},[w,g,f]),G=useCallback(()=>{p(),k();},[p,k]),ye=useCallback(()=>{C();},[C]),M=useCallback(()=>{g("verify"),f("verify");},[g,f]);return useInput((x,A)=>{if(A.escape)To("esc"),M();else if(A.upArrow&&r>0)n(r-1);else if(A.downArrow&&r<t.length-1)n(r+1);else if(A.return&&t.length>0){let F=pr();o(t[r]),dr("kit_display"),v(b.CLI_STEP_COMPLETED,{step:"bundle_selection",duration_ms:F}).catch(()=>{});}},{isActive:h==="starterKitList"}),useInput((x,A)=>{let F=Hu(x,A);if(F.cursorDelta!==0){let W=i+F.cursorDelta;W>=0&&W<s.length&&a(W);}if(F.confirm){let W=_.getState().selectedStarterKit;W&&(async()=>(await oe())?.starterKit!==W.slug&&v(b.CLI_KIT_ACCEPTED,{bundle_slug:W.slug}).catch(()=>{}))();let Et=pr();dr("kit_confirmation"),v(b.CLI_STEP_COMPLETED,{step:"kit_display",duration_ms:Et}).catch(()=>{});let pn=pr();dr("tool_installation"),v(b.CLI_STEP_COMPLETED,{step:"kit_confirmation",duration_ms:pn}).catch(()=>{}),l("installing"),k();}if(F.back){let W=_.getState().selectedStarterKit;W&&v(b.CLI_KIT_REJECTED,{bundle_slug:W.slug}).catch(()=>{}),m();}},{isActive:h==="starterKitDetail"}),useInput((x,A)=>{if(d===0)return;let F=Ju(x,A);if(F.cursorDelta!==0){let W=u+F.cursorDelta;W>=0&&W<=1&&c(W);}F.select&&(u===0?G():O());},{isActive:h==="installProgress"&&e==="summary"}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Nr,{}),jsxs(Box,{flexDirection:"column",paddingX:1,marginBottom:1,children:[jsx(Text,{dimColor:true,children:"The data collected during setup is used solely to improve"}),jsx(Text,{dimColor:true,children:"Flow's internal tools and will not be shared externally."}),!P&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"yellow",children:"Welcome back! We noticed your Starter Kit is not set up yet. Choose a Starter Kit below to get your recommended tools."})})]}),jsxs(Box,{flexDirection:"column",flexGrow:1,children:[e==="starterKitList"&&jsx(Wu,{onRetry:ye}),e==="starterKitDetail"&&jsx(qu,{}),(e==="installing"||e==="summary")&&jsx(Zu,{onComplete:O,onRetry:G})]}),jsx(Mo,{})]})}var by=I("moduleState");function ws(){let e=process.env.FLOW_HOME??me__default.join(Le__default.homedir(),".flow");return me__default.join(e,"modules.json")}var vy={retries:5,minTimeout:50};async function ed(e,t){be__default.mkdirSync(me__default.dirname(e),{recursive:true});let r=await og.lock(e+".lock",{realpath:false,retries:vy});try{return await t()}finally{await r();}}function td(){let e=ws();if(!be__default.existsSync(e))return [];try{let t=JSON.parse(be__default.readFileSync(e,"utf-8"));return t.schemaVersion!==1?(by.warn(`modules.json has unknown schemaVersion ${t.schemaVersion}, resetting`),be__default.rmSync(e,{force:!0}),[]):Array.isArray(t.modules)?t.modules.map(r=>({...r,name:r.name??null})):[]}catch{return be__default.rmSync(e,{force:true}),[]}}function Pr(){return td()}function rd(e){let t=ws();be__default.mkdirSync(me__default.dirname(t),{recursive:true});let r=`${t}.${randomUUID()}.tmp`,n={schemaVersion:1,modules:e};be__default.writeFileSync(r,JSON.stringify(n,null,2),"utf-8"),be__default.renameSync(r,t);}function et(e){return Pr().find(t=>t.alias===e)??null}async function xt(e){let t=ws();await ed(t,async()=>{let r=td(),n=r.findIndex(o=>o.alias===e.alias);n===-1?r.push(e):r[n]=e,rd(r);});}async function nn(){let e=ws();be__default.existsSync(e)||await ed(e,async()=>{be__default.existsSync(e)||rd([]);});}var Ty=promisify(execFile);function sr(e,t){let r=e.platforms[process.platform];return !r||r.status!=="supported"?null:r.strategies.find(n=>n.type===t)??null}async function It(e){let t=process.platform==="win32"?"where":"which";try{return await Ty(t,[e]),!0}catch{return false}}function Nt(){return process.platform==="win32"?"npm.cmd":"npm"}var nd=promisify(execFile),xs=class{type="npm";async isAvailable(){return It("npm")}async install(t){let r=await this.getInstalledVersion(t);return r?{success:true,version:r,method:"npm",durationMs:0}:this.runNpmInstall(t,false)}async update(t,r){return this.runNpmInstall(t,true)}async getInstalledVersion(t){let r=sr(t,"npm");if(!r)return null;try{let{stdout:n}=await nd(Nt(),["list","-g",r.package,"--depth=0","--json"],{shell:process.platform==="win32"});return JSON.parse(n).dependencies?.[r.package]?.version??null}catch{return null}}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async runNpmInstall(t,r){let n=Date.now(),o=sr(t,"npm");if(!o)return {success:false,error:{code:"NPM_NOT_AVAILABLE",message:"No npm config for this module on this platform"},durationMs:Date.now()-n};let s=r?`${o.package}@latest`:o.package;try{return await nd(Nt(),["install","-g",s],{shell:process.platform==="win32"}),{success:!0,version:await this.getInstalledVersion(t)??void 0,method:"npm",durationMs:Date.now()-n}}catch(i){return {success:false,error:{code:"NPM_INSTALL_FAILED",message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-n}}}};var od=promisify(execFile),My=/^(\S+)\s+([\d]+\.[\d]+(?:\.[\d]+)*(?:[-_][^\s]+)?)/,Is=class{type="homebrew";async isAvailable(){return It("brew")}async install(t){return this.runBrewCommand(t,"install")}async update(t,r){return this.runBrewCommand(t,"upgrade")}async getInstalledVersion(t){let r=sr(t,"homebrew");return r?this.getVersionByFormula(r.formula):null}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async runBrewCommand(t,r){let n=Date.now(),o=sr(t,"homebrew");if(!o)return {success:false,error:{code:"HOMEBREW_NOT_AVAILABLE",message:"No homebrew config for this module on this platform"},durationMs:Date.now()-n};let s=r==="install"?"HOMEBREW_INSTALL_FAILED":"HOMEBREW_UPGRADE_FAILED";try{return await od("brew",[r,o.formula]),{success:!0,version:await this.getVersionByFormula(o.formula)??void 0,method:"homebrew",durationMs:Date.now()-n}}catch(i){return {success:false,error:{code:s,message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-n}}}async getVersionByFormula(t){try{let{stdout:r}=await od("brew",["list","--versions",t]),n=r.trim().match(My);return n?n[2]:null}catch{return null}}};var on=promisify(execFile),Dy=I("curlStrategy"),id=/([\d]+\.[\d]+(?:\.[\d]+)*(?:[-_][^\s]+)?)/;function ad(){let e=process.env.FLOW_HOME??me__default.join(Le__default.homedir(),".flow");return me__default.join(e,"bin")}var bs=class{type="curl";async isAvailable(){return It("curl")}async install(t){let r=Date.now(),n=sr(t,"curl");if(!n)return {success:false,error:{code:"CURL_NOT_AVAILABLE",message:"No curl config for this module on this platform"},durationMs:Date.now()-r};let o=typeof n.url=="function"?n.url(process.arch):n.url;return (n.mode??"binary")==="script"?this.installScript(o,n.checksumUrl,t,r):this.installBinary(o,n.checksumUrl,t,r)}async update(t,r){return this.install(t)}async getInstalledVersion(t){let r=me__default.join(ad(),t.binaryName);for(let n of [r,t.binaryName])try{let{stdout:o}=await on(n,["--version"]),s=o.match(id);if(s)return s[1]}catch{}return null}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async installScript(t,r,n,o){let s=me__default.join(Le__default.tmpdir(),`flow-install-${randomUUID()}.sh`);try{if(await on("curl",["-sSL","--fail","-o",s,t]),r||Dy.warn(`Installing script for "${n.alias}" without checksum verification \u2014 checksumUrl not provided`),r){let a=await this.validateChecksum(s,r);if(!a.valid){try{be__default.unlinkSync(s);}catch{}return {success:!1,error:{code:"CHECKSUM_MISMATCH",message:a.message},durationMs:Date.now()-o}}}return be__default.chmodSync(s,448),await on("bash",[s]),{success:!0,version:await this.getInstalledVersion(n)??void 0,method:"curl",durationMs:Date.now()-o}}catch(i){return {success:false,error:{code:"CURL_SCRIPT_FAILED",message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-o}}finally{try{be__default.unlinkSync(s);}catch{}}}async installBinary(t,r,n,o){let s=ad(),i=me__default.join(s,n.binaryName),a=false;try{if(be__default.mkdirSync(s,{recursive:!0}),a=!0,await on("curl",["-L","--fail","-o",i,t]),r){let u=await this.validateChecksum(i,r);if(!u.valid)return be__default.unlinkSync(i),{success:!1,error:{code:"CHECKSUM_MISMATCH",message:u.message},durationMs:Date.now()-o}}be__default.chmodSync(i,493);let l=null;try{let{stdout:u}=await on(i,["--version"]),c=u.match(id);l=c?c[1]:null;}catch{}return {success:!0,version:l??void 0,method:"curl",durationMs:Date.now()-o}}catch(l){if(a)try{be__default.unlinkSync(i);}catch{}return {success:false,error:{code:"CURL_DOWNLOAD_FAILED",message:l instanceof Error?l.message:String(l)},durationMs:Date.now()-o}}}async validateChecksum(t,r){let n=me__default.join(Le__default.tmpdir(),`curl-checksum-${randomUUID()}`);try{await on("curl",["-L","--fail","-o",n,r]);let o=be__default.readFileSync(n,"utf-8").trim().split(/\s+/)[0],s=be__default.readFileSync(t),i=createHash("sha256").update(s).digest("hex");return i!==o?{valid:!1,message:`SHA256 mismatch: expected ${o}, got ${i}`}:{valid:!0,message:""}}catch(o){return {valid:false,message:`Checksum validation failed: ${String(o)}`}}finally{try{be__default.unlinkSync(n);}catch{}}}};var Ae=I("moduleInstaller");function Bt(e){switch(e){case "npm":return new xs;case "homebrew":return new Is;case "curl":return new bs}}async function Yn(e,t,r){try{await v(b.CLI_MODULE_INSTALL_FAILED,{module_alias:e.alias,module_name:e.name,os:process.platform,error_code:r.code,error_message:r.message,trigger:t});}catch(n){Ae.warn(`Failed to emit install failed event: ${String(n)}`);}}async function an(e,t,r){let n=Date.now(),o=e.platforms[process.platform];if(!o)return {success:false,error:{code:"PLATFORM_NOT_SUPPORTED",message:`Platform ${process.platform} is not listed for module ${e.alias}`},durationMs:Date.now()-n};if(o.status==="experimental"){Ae.warn(`Module "${e.alias}" has experimental support on ${process.platform}`);let l={code:"PLATFORM_EXPERIMENTAL",message:`Experimental support on ${process.platform} \u2014 install manually`};return await Yn(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}if(o.status!=="supported"){let l={code:"PLATFORM_NOT_SUPPORTED",message:`Module ${e.alias} is not supported on ${process.platform}`};return await Yn(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}if(!o.strategies.some(l=>l.type===r)){let l={code:"STRATEGY_NOT_FOUND",message:`Strategy "${r}" is not configured for module "${e.alias}" on ${process.platform}`};return await Yn(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}let s=Bt(r),i=false;try{i=await s.isAvailable();}catch(l){Ae.warn(`${r} availability check failed: ${String(l)}`);}if(!i){let l={code:"STRATEGY_NOT_AVAILABLE",message:`"${r}" is not installed on this system`};return await Yn(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}try{await v(b.CLI_MODULE_INSTALL_STARTED,{module_alias:e.alias,module_name:e.name,os:process.platform,cli_version:ae,trigger:t});}catch(l){Ae.warn(`Failed to emit install started event: ${String(l)}`);}let a;try{a=await s.install(e);}catch(l){let u=l instanceof Error?l.message:String(l);Ae.warn(`${r} install threw: ${u}`),a={success:false,error:{code:"INSTALL_THREW",message:u},durationMs:Date.now()-n};}if(a.success){await xt({alias:e.alias,name:e.name,installedVersion:a.version??null,installMethod:a.method??null,installedAt:new Date().toISOString(),lastChecked:new Date().toISOString()});try{await v(b.CLI_MODULE_INSTALL_COMPLETED,{module_alias:e.alias,module_name:e.name,installed_version:a.version??"unknown",duration_ms:a.durationMs,os:process.platform,trigger:t});}catch(u){Ae.warn(`Failed to emit install completed event: ${String(u)}`);}let l=await Ny(e,t);return l?{...a,pendingInteractiveSetup:l}:a}return await Yn(e,t,a.error??{code:"UNKNOWN",message:"unknown error"}),a}async function Ny(e,t){if(!e.postInstall)return null;let r=t==="onboarding"?e.postInstall.onboarding:e.postInstall.onDemand;if(r==null)return null;let n;if(typeof r=="function"){let o=await oe(),s={credentials:o?{clientId:o.clientId,clientSecret:o.clientSecret,tenant:o.tenant}:null};try{n=r(s);}catch(i){return Ae.warn(`postInstall function threw: ${String(i)}`),null}}else n=r;if(n.length===0)return null;if((e.postInstall.mode??"non-interactive")==="interactive")return n[0]??null;for(let o of n){if(o.length===0)continue;let s=spawnSync(o[0],o.slice(1),{stdio:"pipe",env:process.env,encoding:"utf-8",shell:process.platform==="win32"});if(s.status!==0)return Ae.warn(`postInstall "${o.join(" ")}" exited with status ${s.status??"null"}`),s.stderr&&Ae.warn(s.stderr),null}return null}async function vs(e,t){let r=Date.now(),n=et(e.alias);if(!n?.installMethod)return {success:false,error:{code:"NOT_INSTALLED",message:`Module '${e.alias}' is not installed`},durationMs:Date.now()-r};let o=Bt(n.installMethod),s=n.installedVersion??"unknown";if(t==="command")try{await v(b.CLI_MODULE_INSTALL_STARTED,{module_alias:e.alias,module_name:e.name,os:process.platform,cli_version:ae,trigger:"command"});}catch(a){Ae.warn(`Failed to emit update started event: ${String(a)}`);}let i;try{i=await o.update(e,s);}catch(a){let l=a instanceof Error?a.message:String(a);Ae.warn(`${n.installMethod} update threw: ${l}`),i={success:false,error:{code:"UPDATE_THREW",message:l},durationMs:Date.now()-r};}if(i.success)if(await xt({...n,installedVersion:i.version??n.installedVersion,lastChecked:new Date().toISOString()}),t==="command")try{await v(b.CLI_MODULE_INSTALL_COMPLETED,{module_alias:e.alias,module_name:e.name,installed_version:i.version??"unknown",duration_ms:i.durationMs,os:process.platform,trigger:"command"});}catch(a){Ae.warn(`Failed to emit update completed event: ${String(a)}`);}else try{await v(b.CLI_MODULE_UPDATED,{module_alias:e.alias,from_version:s,to_version:i.version??"unknown",duration_ms:i.durationMs});}catch(a){Ae.warn(`Failed to emit module updated event: ${String(a)}`);}else if(t==="command")try{await v(b.CLI_MODULE_INSTALL_FAILED,{module_alias:e.alias,module_name:e.name,os:process.platform,error_code:i.error?.code??"UNKNOWN",error_message:i.error?.message??"unknown error",trigger:"command"});}catch(a){Ae.warn(`Failed to emit update failed event: ${String(a)}`);}return i}function By(e){let t=e.module.platforms[process.platform];return (t?.status==="supported"?t.strategies:[]).map(n=>n.type==="npm"?`npm install -g ${n.package}`:n.type==="homebrew"?`brew install ${n.formula}`:"curl (see docs)").join(" or ")}function ud(e){let[t,r]=useState(()=>e.map(c=>({alias:c.module.alias,name:c.module.name,status:"pending"}))),[n,o]=useState(false),s=useCallback((c,d)=>{r(p=>p.map(m=>m.alias===c?{...m,...d}:m));},[]),i=useCallback(async()=>{for(let c of e){let d=By(c);if(!c.selectedStrategy){let p=d?`No package manager available. Install manually: ${d}`:"No package manager available for this platform";s(c.module.alias,{status:"failed",error:p,manualInstallHint:d||void 0});continue}s(c.module.alias,{status:"installing"});try{let p=await an(c.module,"onboarding",c.selectedStrategy);p.success?s(c.module.alias,{status:"installed",pendingSetupCommand:p.pendingInteractiveSetup?.join(" ")}):s(c.module.alias,{status:"failed",error:p.error?.message??"Installation failed",manualInstallHint:d});}catch(p){s(c.module.alias,{status:"failed",error:p instanceof Error?p.message:"Unknown error",manualInstallHint:d});}}o(true);},[e,s]),a=useMemo(()=>t.filter(c=>c.status==="installed").length,[t]),l=useMemo(()=>t.filter(c=>c.status==="failed").length,[t]),u=useMemo(()=>t.filter(c=>c.status==="skipped").length,[t]);return {modules:t,install:i,isComplete:n,installedCount:a,failedCount:l,skippedCount:u}}function jy(e){return e.filter(t=>t.module.platforms[process.platform]?.status==="supported").filter(t=>!t.alreadyInstalled).map(t=>({module:t.module,alreadyInstalled:t.alreadyInstalled,checked:!t.alreadyInstalled&&(t.availableStrategies.length>0||t.module.required===true),selectedStrategy:t.availableStrategies[0]??null,availableStrategies:t.availableStrategies}))}function gd(e,t){let[r,n]=useState(()=>jy(e)),[o,s]=useState(0),i=useRef(o);useEffect(()=>{i.current=o;},[o]);let a=useRef(r);useEffect(()=>{a.current=r;},[r]);let l=useCallback(d=>{n(p=>p.map(m=>m.module.alias!==d||m.module.required?m:{...m,checked:!m.checked}));},[]),u=useCallback((d,p)=>{n(m=>m.map(f=>f.module.alias===d?{...f,selectedStrategy:p}:f));},[]);useInput((d,p)=>{let m=i.current,f=a.current,g=p.upArrow||d==="[A",h=p.downArrow||d==="[B";if(g||h)g&&m>0?s(m-1):h&&m<f.length-1&&s(m+1);else if(d===" "){let w=f[m];w&&!w.module.required&&l(w.module.alias);}else if(p.tab){let w=f[m];if(w&&w.availableStrategies.length>1){let P=w.availableStrategies.indexOf(w.selectedStrategy??w.availableStrategies[0]),C=w.availableStrategies[(P+1)%w.availableStrategies.length];n(k=>k.map($=>$.module.alias===w.module.alias?{...$,selectedStrategy:C}:$));}}},{isActive:t});let c=useMemo(()=>r.filter(d=>d.checked),[r]);return {items:r,focusedIndex:o,toggle:l,setStrategy:u,confirmedItems:c}}function Ky(){return te.filter(e=>e.platforms[process.platform]?.status==="supported")}function yd(e){let t=Ky();return t.length>0&&t.every(r=>e.find(n=>n.module.alias===r.alias)?.alreadyInstalled===true)}var hd={alias:"metrics",required:true,name:"flow-ai-obs",binaryName:"flow-ai-obs",description:"AI usage telemetry and observability (hooks, OTEL, LLM proxy)",platforms:{darwin:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]},linux:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]},win32:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]}},versionCheck:{type:"npm-registry",package:"@ciandt-flow/flow-ai-obs"},versionCommand:["flow-ai-obs","--version"],hasOwnUpdateCheck:true,postInstall:{onboarding:e=>{if(!e.credentials)throw new Error("flow-ai-obs setup requires credentials");let{clientId:t,clientSecret:r,tenant:n}=e.credentials;return [["flow-ai-obs","auth","login","--client-id",t,"--client-secret",r,"--tenant",n],["flow-ai-obs","install"]]},onDemand:null,mode:"non-interactive"}},Vy={alias:"dashboard",name:"ccboard",binaryName:"ccboard",description:"Claude Code session monitoring dashboard",docs:"https://github.com/FlorianBruniaux/ccboard",platforms:{darwin:{status:"supported",strategies:[{type:"homebrew",formula:"ccboard"},{type:"curl",url:"https://raw.githubusercontent.com/FlorianBruniaux/ccboard/main/install.sh",mode:"script"}]},linux:{status:"supported",strategies:[{type:"curl",url:"https://raw.githubusercontent.com/FlorianBruniaux/ccboard/main/install.sh",mode:"script"}]},win32:{status:"experimental"}},versionCheck:{type:"github-releases",repo:"florianbruniaux/ccboard"},versionCommand:["ccboard","--version"],hasOwnUpdateCheck:false},te=Gt()?[hd,Vy]:[hd];var xd=null;function Id(){return xd}async function Es(){let t=Pr().filter(r=>r.installedVersion===null&&r.installMethod===null);for(let r of t){let n=te.find(i=>i.alias===r.alias);if(!n)continue;let{installedVersion:o,installMethod:s}=await bd(n);(o||s)&&await xt({...r,installedVersion:o,installMethod:s});}}async function bd(e){let t=e.platforms[process.platform];if(t?.status!=="supported")return {installedVersion:null,installMethod:null};for(let r of t.strategies)if(r.type!=="curl")try{let o=await Bt(r.type).getInstalledVersion(e);if(o)return {installedVersion:o,installMethod:r.type}}catch{}return {installedVersion:null,installMethod:null}}async function ln(e){let t=await Promise.all(e.map(r=>Hy(r)));return xd=t,t}async function Hy(e){let t=Sd(e.versionCommand);t==="permission-denied"&&(Jy(e.versionCommand[0]),t=Sd(e.versionCommand));let r=t==="installed",n=e.platforms[process.platform],o=n?.status==="supported"?n.strategies:[],i=(await Promise.all(o.map(async a=>{try{return await Bt(a.type).isAvailable()?a.type:null}catch{return null}}))).filter(a=>a!==null);if(r&&!et(e.alias)){let{installedVersion:a,installMethod:l}=await bd(e);await xt({alias:e.alias,name:e.name,installedVersion:a,installMethod:l,installedAt:null,lastChecked:new Date().toISOString()});}return {module:e,alreadyInstalled:r,availableStrategies:i}}function Sd(e){if(e.length===0)return "not-found";try{let t=spawnSync(e[0],e.slice(1),{timeout:3e3,stdio:"pipe",shell:process.platform==="win32"});return t.status===0?"installed":t.status===126?"permission-denied":"not-found"}catch{return "not-found"}}function Jy(e){if(process.platform!=="win32")try{let t=spawnSync("which",[e],{stdio:"pipe"});if(t.status!==0)return;let r=t.stdout.toString().trim(),n=be__default.realpathSync(r),{mode:o}=be__default.statSync(n);be__default.chmodSync(n,o|73);}catch{}}function Wy({module:e}){let t=y(e.name);return e.status==="installing"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",t," \u2014 Installing..."]})]}):e.status==="installed"?jsxs(Box,{flexDirection:"column",children:[jsx(Box,{children:jsxs(Text,{color:"green",children:["\u2713 ",t]})}),e.pendingSetupCommand&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["\u2139 Run '",y(e.pendingSetupCommand),"' to complete configuration"]})})]}):e.status==="failed"?jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",t]}),e.error&&jsxs(Text,{dimColor:true,children:[" \u2014 ",y(e.error)]})]}),e.manualInstallHint&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["Install manually: ",y(e.manualInstallHint)]})})]}):e.status==="skipped"?jsx(Box,{children:jsxs(Text,{dimColor:true,children:["- ",t," (not supported on this platform)"]})}):jsx(Box,{children:jsxs(Text,{dimColor:true,children:["\u25CB ",t]})})}function zy({confirmedItems:e}){let t=S(f=>f.setScreen),r=S(f=>f.setFocus),{modules:n,install:o,isComplete:s,installedCount:i,failedCount:a,skippedCount:l}=ud(e),u=useRef(false),c=useRef(false);useEffect(()=>{u.current||(u.current=true,o());},[o]);let d=useCallback(()=>{nn().catch(()=>{}),r("list");let f=se().some(g=>g.name===ie);t(f?"main":"claudeMdSuggestion");},[r,t]);useEffect(()=>{if(s&&a===0&&!c.current){c.current=true;let f=setTimeout(d,1500);return ()=>clearTimeout(f)}},[s,a,d]),useInput((f,g)=>{g.return&&d();},{isActive:s});let p=s,m=[];return i>0&&m.push(jsxs(Text,{color:"green",children:[i," installed"]},"i")),a>0&&m.push(jsxs(Text,{color:"red",children:[a," failed"]},"f")),l>0&&m.push(jsxs(Text,{dimColor:true,children:[l," skipped"]},"s")),jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:s?"Modules ready":"Setting up modules..."})}),jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:n.map(f=>jsx(Wy,{module:f},f.alias))}),p&&jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:m.reduce((f,g,h)=>(h>0&&f.push(jsx(Text,{children:" | "},`sep-${h}`)),f.push(g),f),[])}),jsx(Box,{paddingX:1,children:a>0?jsx(Text,{dimColor:true,children:"Press Enter to continue"}):jsx(Text,{dimColor:true,children:"Proceeding..."})})]})]})}function Xy({probeResults:e,onConfirm:t}){let r=S(m=>m.focus),n=S(m=>m.actionMenuOpen),o=S(m=>m.setActionMenuOpen),s=S(m=>m.setFocus),{items:i,focusedIndex:a,confirmedItems:l}=gd(e,r==="moduleSetup"),u=useCallback(()=>{o(false),s("moduleSetup");},[o,s]),c=useCallback(m=>{(m==="Install"||m==="Skip")&&t(l),u();},[l,t,u]);useInput((m,f)=>{f.return&&(o(true),s("actionMenu"));},{isActive:r==="moduleSetup"});let d=l.length>0?["Install","Cancel"]:["Skip","Cancel"],p=l.length>0?`Install ${l.length} module(s)?`:"No modules selected";return jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Configure modules"})}),jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:i.map((m,f)=>{let g=f===a,h=y(m.module.name);return m.availableStrategies.length===0?jsxs(Box,{children:[jsxs(Text,{dimColor:true,children:[" [ ] ",h," "]}),jsx(Text,{dimColor:true,children:"\u2014 no installer available"})]},m.module.alias):jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:g?"cyan":void 0,children:[g?"\u25B6":" ",m.checked?" [\u2713] ":" [ ] ",h]}),m.module.required&&jsx(Text,{dimColor:true,children:" (required)"}),jsxs(Text,{dimColor:true,children:[" ",m.selectedStrategy??""]}),m.availableStrategies.length>1&&jsxs(Text,{dimColor:true,children:[" ","(",m.availableStrategies.indexOf(m.selectedStrategy??m.availableStrategies[0])+1,"/",m.availableStrategies.length," \u2194)"]})]}),m.module.description&&jsx(Box,{paddingLeft:6,children:jsx(Text,{dimColor:true,children:y(m.module.description)})})]},m.module.alias)})}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Space toggle \xB7 Tab change method \xB7 Enter confirm"})}),n&&jsx(ze,{itemName:p,actions:d,onAction:c,onClose:u})]})}function Pd(){let[e,t]=useState("loading"),[r,n]=useState([]),[o,s]=useState([]),i=S(c=>c.setFocus),a=S(c=>c.setScreen),l=useCallback(c=>{if(yd(c)){nn().catch(()=>{}),i("list");let p=se().some(m=>m.name===ie);a(p?"main":"claudeMdSuggestion");}else n(c),t("selection");},[i,a]);useEffect(()=>{let c=Id();if(c){l(c);return}ln(te).then(l).catch(()=>{n([]),t("selection");});},[l]);let u=useCallback(c=>{s(c),t("installation");},[]);return jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[e==="loading"&&jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Setting up modules..."})}),e==="selection"&&jsx(Xy,{probeResults:r,onConfirm:u}),e==="installation"&&jsx(zy,{confirmedItems:o})]})}var Qy=I("ClaudeMdSuggestion"),eS=[`Install ${ie}`,"Skip for now"],tS=["Retry","Skip for now"];function kd(){let e=S(p=>p.setScreen),t=S(p=>p.setFocus),r=_(p=>p.successCount),[n,o]=useState("prompt"),[s,i]=useState(0),a=useRef(0),l=useCallback(()=>{t("list"),e("main");},[t,e]),u=useCallback(()=>{v(b.CLI_CLAUDE_MD_SKIPPED,{interface:"tui"}).catch(()=>{}),l();},[l]),c=useCallback(async()=>{a.current+=1,v(b.CLI_CLAUDE_MD_ACCEPTED,{interface:"tui",attempt:a.current}).catch(()=>{}),o("installing");try{await Ee(ie),o("installed");}catch(p){if(p instanceof Ne){o("installed");return}Qy.warn(`Failed to install ${ie}: ${p instanceof Error?p.message:p}`),o("error");}},[]),d=n==="error"?tS:eS;return useInput((p,m)=>{if(m.escape){n==="prompt"||n==="error"?u():n==="installed"&&l();return}if(n==="prompt"||n==="error"){m.upArrow&&s>0?i(s-1):m.downArrow&&s<d.length-1?i(s+1):m.return&&(s===0?(i(0),c()):u());return}n==="installed"&&m.return&&l();}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Nr,{}),jsxs(Box,{flexDirection:"column",paddingX:1,gap:1,children:[jsx(Text,{color:"green",bold:true,children:r>0?"\u2713 Starter kit installed!":"\u2713 Setup complete!"}),n==="prompt"&&jsxs(Fragment,{children:[jsxs(Box,{flexDirection:"column",children:[jsx(Text,{bold:true,children:"Personalize your Claude Code"}),jsx(Text,{children:"This plugin helps Claude understand your preferences and work style."})]}),jsx(Cd,{options:d,cursorIndex:s}),jsx(Text,{dimColor:true,children:"You can always install it later from the catalog."})]}),n==="installing"&&jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" Installing ",ie,"..."]})]}),n==="installed"&&jsxs(Fragment,{children:[jsxs(Text,{color:"green",bold:true,children:["\u2713 ",ie," installed!"]}),jsxs(Box,{flexDirection:"column",children:[jsx(Text,{children:"Open Claude in a new terminal or in VS Code and type:"}),jsxs(Text,{bold:true,color:"cyan",children:["/",ie]})]}),jsx(Text,{children:"Claude will guide you through the rest."}),jsx(Text,{dimColor:true,children:"Press Enter to continue to the catalog..."})]}),n==="error"&&jsxs(Fragment,{children:[jsxs(Text,{color:"red",bold:true,children:["\u2717 Failed to install ",ie]}),jsx(Cd,{options:d,cursorIndex:s}),jsx(Text,{dimColor:true,children:"You can always install it later from the catalog."})]})]})]})}function Cd({options:e,cursorIndex:t}){return jsx(Box,{flexDirection:"column",children:e.map((r,n)=>jsxs(Text,{bold:n===t,color:n===t?"cyan":void 0,children:[n===t?"\u203A ":" ",r]},r))})}var sS=promisify(execFile),Ps="@ciandt-flow/cli";async function Ad(){let e=ae;if(Xi.prerelease(e)||process.env.NODE_ENV==="development")return {currentVersion:e,latestVersion:e,isOutdated:false,packageName:Ps};try{let t=await fetch(`https://registry.npmjs.org/${Ps}/latest`);if(!t.ok)throw new Error(`Registry returned ${t.status}`);let n=(await t.json()).version;return {currentVersion:e,latestVersion:n,isOutdated:n!==e,packageName:Ps}}catch{return {currentVersion:e,latestVersion:e,isOutdated:false,packageName:Ps}}}async function Ts(e){try{return await sS(Nt(),["install","-g",e.packageName],{timeout:6e4,shell:process.platform==="win32"}),{success:!0}}catch(t){return {success:false,error:String(t)}}}async function $d(e){let r=et(e.alias)?.installedVersion??null,n=null;try{if(e.versionCheck.type==="npm-registry"){let s=await fetch(`https://registry.npmjs.org/${e.versionCheck.package}/latest`);if(!s.ok)throw new Error(`Registry returned ${s.status}`);n=(await s.json()).version;}else if(e.versionCheck.type==="github-releases"){let s=await fetch(`https://api.github.com/repos/${e.versionCheck.repo}/releases/latest`);if(!s.ok)throw new Error(`GitHub returned ${s.status}`);n=(await s.json()).tag_name.replace(/^v/,"");}}catch{}let o=r!==null&&n!==null&&r!==n;return {moduleAlias:e.alias,currentVersion:r,latestVersion:n,isOutdated:o}}async function Md(e,t){let r=et(e.alias);if(!r?.installMethod)return {success:false,error:"Unknown install method"};let o=await Bt(r.installMethod).update(e,t.currentVersion??"");return o.success?(await xt({...r,installedVersion:o.version??r.installedVersion,lastChecked:new Date().toISOString()}),{success:true,newVersion:o.version}):{success:false,error:o.error?.message}}function Ld(e){let r=et(e.alias)?.installMethod,n=e.platforms[process.platform];if(n?.status==="supported"){if(r==="npm"){let o=n.strategies.find(s=>s.type==="npm");if(o?.type==="npm")return `npm install -g ${o.package}`}if(r==="homebrew"){let o=n.strategies.find(s=>s.type==="homebrew");if(o?.type==="homebrew")return `brew upgrade ${o.formula}`}}}function Rd(){let[e,t]=useState({outcome:"running",items:[{id:"cli",label:"@ciandt-flow/cli",status:"pending"},...te.map(n=>({id:n.alias,label:n.name,status:"pending"}))]}),r=useCallback((n,o)=>{t(s=>({...s,items:s.items.map(i=>i.id===n?{...i,...o}:i)}));},[]);return useEffect(()=>{async function n(){try{let[o,s,i]=await Promise.all([Ad(),ln(te),Promise.all(te.map(l=>$d(l)))]);if(Es(),o.isOutdated){r("cli",{status:"updating",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`}),(await Ts(o)).success?(r("cli",{status:"updated",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`}),t(u=>({...u,outcome:"cli-updated"}))):(r("cli",{status:"error",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`,manualCommand:`npm install -g ${o.packageName}`}),t(u=>({...u,outcome:"cli-update-failed"})));return}r("cli",{status:"ok",detail:`v${o.currentVersion}`});let a=s.some(l=>!l.alreadyInstalled);for(let l of s)l.alreadyInstalled||r(l.module.alias,{status:"missing"});if(a){t(l=>({...l,outcome:"module-missing"}));return}for(let l of i){let u=te.find(d=>d.alias===l.moduleAlias);if(!u)continue;if(!l.isOutdated){r(l.moduleAlias,{status:"ok",detail:l.currentVersion?`v${l.currentVersion}`:void 0});continue}r(l.moduleAlias,{status:"updating",detail:`v${l.currentVersion} \u2192 v${l.latestVersion}`});let c=await Md(u,l);c.success?r(l.moduleAlias,{status:"updated",detail:`v${c.newVersion}`}):r(l.moduleAlias,{status:"error",detail:`v${l.currentVersion} \u2192 v${l.latestVersion}`,manualCommand:Ld(u)});}t(l=>({...l,items:l.items.map(u=>u.status==="pending"?{...u,status:"ok"}:u)})),await nn(),t(l=>({...l,outcome:"done"}));}catch{await nn(),t(o=>({...o,outcome:"done"}));}}n();},[r]),e}function dS({item:e}){return e.status==="pending"||e.status==="updating"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(ru,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",e.label,e.detail?` ${e.detail}...`:""]})]}):e.status==="ok"||e.status==="updated"?jsxs(Box,{children:[jsxs(Text,{color:"green",children:["\u2713 ",e.label]}),e.detail&&jsxs(Text,{dimColor:true,children:[" ",e.detail]})]}):e.status==="missing"?jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",e.label]}),jsx(Text,{dimColor:true,children:" \u2014 not installed"})]}):jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",e.label]}),e.detail&&jsxs(Text,{dimColor:true,children:[" ",e.detail]})]}),e.manualCommand&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["To update manually: ",e.manualCommand]})})]})}function pS({outcome:e}){return e==="done"?jsx(Text,{color:"green",children:"All good!"}):e==="cli-updated"||e==="cli-update-failed"?jsx(Text,{color:"yellow",children:"Restart the CLI to use the new version."}):null}function _d(){let{outcome:e,items:t}=Rd(),r=S(o=>o.setScreen),n=S(o=>o.setFocus);return useEffect(()=>{if(e==="done"){let o=setTimeout(()=>{let s=se().some(i=>i.name===ie);r(s?"main":"claudeMdSuggestion"),n("list");},1500);return ()=>clearTimeout(o)}if(e==="module-missing"){let o=setTimeout(()=>{r("moduleSetup"),n("moduleSetup");},500);return ()=>clearTimeout(o)}},[e,r,n]),jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Box,{marginBottom:1,children:jsx(Text,{bold:true,children:"Checking environment..."})}),jsx(Box,{flexDirection:"column",gap:0,children:t.map(o=>jsx(dS,{item:o},o.id))}),e!=="running"&&jsx(Box,{marginTop:1,children:jsx(pS,{outcome:e})})]})}var hS={debug:"gray",info:"cyan",warn:"yellow",error:"red"},Dd=10;function Od(){let[e,t]=useState(Js());useEffect(()=>Va(()=>{t([...Js()]);}),[]);let r=e.slice(-Dd);return jsxs(Box,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[jsxs(Text,{color:"cyan",bold:true,children:["Debug Log (last ",Dd,") \u2014 press Ctrl+D to close"]}),r.length===0?jsx(Text,{dimColor:true,children:"No log entries yet"}):r.map((n,o)=>jsxs(Text,{color:hS[n.level],children:["[",n.level.toUpperCase(),"] [",n.module,"] ",n.message]},o))]})}var xS=I("app"),IS={auth:xl,starterKitSetup:Qu,moduleSetup:Pd,claudeMdSuggestion:kd,verify:_d,main:ju};function Ud(){let{setScreen:e,setFocus:t}=S.getState();e("auth"),t("auth");}function Tn(e){let{setScreen:t,setFocus:r}=S.getState();!e.starterKit||e.starterKit.trim()===""?(t("starterKitSetup"),r("starterKitList")):(t("verify"),r("verify"));}function Fd(){v(b.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Ct(),interface:"tui"}).catch(()=>{});}async function Kd(){let e=await oe();if(e&&yl()&&await Ht()){let{clientSecret:n,...o}=e;Ge.getState().setCredentials(o),Fd(),Tn(e);return}if(!e){Ud();return}try{await Jt();}catch(n){xS.debug(`Token validation failed: ${String(n)}`),Ud();return}Fd();let{clientSecret:t,...r}=e;Ge.getState().setCredentials(r),Tn(e);}function Vd(){let{columns:e,rows:t}=useWindowSize(),r=S(a=>a.screen),n=IS[r],{pendingExit:o}=pl(),s=S(a=>a.debugPanelOpen),i=!!process.env.DEBUG;return useInput((a,l)=>{if(i&&l.ctrl&&a==="d"){let u=S.getState().debugPanelOpen;S.getState().setDebugPanelOpen(!u);}}),n?jsxs(Box,{flexDirection:"column",width:e,height:t,children:[jsx(n,{}),i&&s&&jsx(Od,{}),o&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:"Press Ctrl+C again to quit"})})]}):jsxs(Text,{color:"red",children:["Unknown screen: ",r]})}async function ba(e,t={}){let r=Co({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},t);return ko(r),await Tt(e),{jwt:r.jwt,previousToken:r.previousToken,hadExistingFile:r.hadExistingFile}}var ut=I("auth");function Jd(){De.clearFallbackFile(),Io();}var bS=3,Hd=3,Gd=` \u2139 The data collected during setup is used solely to improve
|
|
116
|
+
[y/N] `))return ps.debug(`[${e}] Removal cancelled by user`),C("Operation cancelled."),0}let n=t.silent?void 0:Aa({text:`Removing MCP "${h(e)}"...`}).start();try{let o=await xe(r);return n?.stop(),o.exitCode!==0?(zn(t,{name:e,action:"remove",message:o.stderr||"Command failed",exitCode:o.exitCode}),!t.silent&&t.verbose&&o.stdout&&C(`stdout: ${o.stdout}`),1):(Lu(t,{name:e,actionPastTense:"removed",command:r,durationMs:o.duration_ms,stdout:o.stdout}),0)}catch(o){return n?.stop(),zn(t,{name:e,action:"remove",message:Q(o)}),1}}function Du({selectedItem:e,selectedCatalogItem:t,items:r,closeMenu:n,clampIndex:o,notify:s}){let i=I("pluginHandlers"),a=S(T=>T.setLoading),{install:l,uninstall:u,toggle:c,update:d}=$u(),p=async(T,k,$)=>{a(true,T),n();try{await k(),o(r.length),s($,"success");}catch(O){let G=O instanceof Error?O.message:"Something went wrong";i.error(`[withLoading] ${T} failed: ${G}`),s(G,"error");}finally{a(false);}};return {handleInstall:(T,k)=>{e&&t&&p(`Installing ${e.name}...`,()=>l(t,{scope:T,...k!==void 0?{providerId:k}:{}}),"\u2713 Installed successfully");},handleUninstall:T=>{e&&p(`Uninstalling ${e.name}...`,()=>u(e.name,T),"\u2713 Uninstalled");},handleToggleStatus:T=>{if(!e)return;let k=e.status==="enabled";p(k?`Disabling ${e.name}...`:`Enabling ${e.name}...`,()=>c(e.name,T),k?"\u2713 Disabled":"\u2713 Enabled");},handleUpdate:()=>{if(!e)return;let T=t?` to v${t.version}`:"";(async()=>{a(true,`Updating ${e.name}${T}...`),n();try{await d(e.name),o(r.length),s(`\u2713 Updated ${e.name}${T}`,"success");}catch($){if($ instanceof er)s($.message,"info");else {let O=$ instanceof Error?$.message:"Something went wrong";i.error(`[handleUpdate] ${e.name} failed: ${O}`),s(O,"error");}}finally{a(false);}})();},handleBatchUpdate:T=>{if(T.length===0)return;let k=T.length;(async()=>{a(true,`Updating ${k} plugin${k>1?"s":""}...`),n();try{let O=[];for(let M of T)O.push(await d(M.name).then(()=>({status:"fulfilled",value:void 0}),x=>({status:"rejected",reason:x})));let G=O.filter(M=>M.status==="fulfilled").length,we=O.map((M,x)=>M.status==="rejected"?T[x].name:null).filter(M=>M!==null);o(r.length),we.length===0?s(`\u2713 Updated ${G}/${k} plugin${k>1?"s":""}`,"success"):(i.error(`[handleBatchUpdate] failed: ${we.join(", ")}`),s(`Updated ${G}/${k}; failed: ${we.join(", ")}`,G>0?"info":"error"));}finally{a(false);}})();},handleMcpConfigUninstall:T=>{e&&p(`Removing MCP ${e.name}...`,async()=>{let k=ta(e.name,T),$=await xe(k);if($.exitCode!==0)throw new Error($.stderr||"MCP removal failed");de.getState().loadFromDisk();},"\u2713 MCP removed");}}}var ms=I("api:bundle"),sn=class extends Error{constructor(t){super(`Bundle '${t}' not found in your tenant. Verify the name with whoever shared the command.`),this.name="BundleNotFoundError";}},Xn=class extends Error{constructor(){super("The server encountered an error while fetching the bundle. Please try again later."),this.name="BundleServerError";}};async function fs(e){let t=encodeURIComponent(e);ms.debug(`Fetching bundle by name "${e}"`);let r;try{r=await St().get(`v1/use-cases/by-name/${t}`).json(),ms.debug(`API returned ${r.length} result(s) for "${e}"`);}catch(n){if(n instanceof HTTPError){let o=n.response.status;throw ms.error(`HTTP error fetching bundle '${e}' [status=${o}]`),o===StatusCodes.NOT_FOUND?new sn(e):o===StatusCodes.INTERNAL_SERVER_ERROR?new Xn:new Error(`Server error (${o}) \u2014 please try again later.`)}throw ms.error(`Unexpected error fetching bundle '${e}': ${n instanceof Error?n.message:String(n)}`),n}if(r.length===0)throw new sn(e);return r[0]}function Nu({closeMenu:e,notify:t}){let r=S(a=>a.bundleInstallFlow);return {handleBundleInstallStart:a=>{let{setLoading:l,setBundleInstallFlow:u}=S.getState();l(true,"Loading bundle..."),fs(a).then(c=>{l(false),S.getState().actionMenuOpen&&u({phase:"detail",bundle:c});}).catch(c=>{l(false),t(c instanceof Error?c.message:"Failed to load bundle","error");});},handleBundleDetailConfirm:()=>{if(!r||r.phase!=="detail")return;let{setBundleInstallFlow:a,setFocus:l}=S.getState();a({phase:"installing",bundle:r.bundle}),l("bundleInstallProgress");},handleBundleDetailBack:()=>{let{setBundleInstallFlow:a}=S.getState();a(null),e();},handleBundleInstallComplete:a=>{S.getState().setBundleInstallFlow(null),e(),de.getState().loadFromDisk(),t(`\u2713 Installed ${a.installed} of ${a.total} artifacts`,"success");}}}var qn=["local","project","user"],sh=new Set(["--transport","--scope","-s"]);function Bu(e){let t=e.split(/\s+/).filter(Boolean),r=t.indexOf("add");if(r===-1)return null;let n=r+1;for(;n<t.length;){let o=t[n];if(sh.has(o))n+=2;else if(o.startsWith("-"))n+=1;else return o.replace(/^["']|["']$/g,"")}return null}function kr(e,t){return t?`${e}::${t}`:e}function ra(e){return e===re?yn:Rr}function Uu(e){return {name:h(e.name),version:e.version?h(e.version):e.version,description:e.description?h(e.description):e.description,authorName:e.author?.name?h(e.author.name):e.author?.name,updateAvailable:e.updateAvailable,type:e.type??"bundle",origin:e.origin??yn}}function na(e,t){let r=ra(e.marketplace);return {name:h(e.name),version:e.version?h(e.version):e.version,description:e.description?h(e.description):e.description,authorName:e.author?.name?h(e.author.name):e.author?.name,status:e.status,scope:e.scope,marketplace:e.marketplace,updateAvailable:e.updateAvailable,installedAt:e.installedAt,type:t?.type??e.type??"bundle",origin:t?.origin??r}}function Fu(e){let t=new Map;for(let r of e){if(!r.scope)continue;let n=t.get(r.scope)??[];n.push(r),t.set(r.scope,n);}return qn.filter(r=>t.has(r)).map(r=>({scope:r,label:hn[r].label,pathHint:hn[r].pathHint,items:t.get(r)??[]}))}function ju(e){let t=r=>{if(!r)return 1/0;let n=qn.indexOf(r);return n===-1?1/0:n};return [...e].sort((r,n)=>t(r.scope)-t(n.scope))}function Ku({catalog:e,installedItems:t,activeTab:r,catalogFilters:n,searchQuery:o}){let s=useMemo(()=>new Set(t.map(f=>kr(f.name,f.author?.name))),[t]),i=useMemo(()=>new Set(t.filter(f=>f.type==="mcp").map(f=>f.name.toLowerCase())),[t]),a=useMemo(()=>{let f=new Map(e.map(y=>[kr(y.name,y.author?.name),y])),g=new Map(e.map(y=>[y.name,y]));return t.map(y=>{let w=f.get(kr(y.name,y.author?.name))??g.get(y.name),E=w?.version,T=!!E&&!!y.version&&Ae(y.version,E);return {...y,updateAvailable:T,catalogItem:w}})},[t,e]),l=useMemo(()=>r==="discover"?e.filter(f=>{if(s.has(kr(f.name,f.author?.name)))return false;if(f.type==="mcp"){let g=f.installCommand?Bu(f.installCommand)?.toLowerCase():null;if(i.has(f.name.toLowerCase())||g&&i.has(g))return false}return true}).map(f=>Uu(f)):r==="updates"?a.filter(f=>f.updateAvailable).map(f=>na(f,f.catalogItem)):a.map(f=>na(f,f.catalogItem)),[r,e,s,i,a]),u=useMemo(()=>l.filter(f=>{let g=f.type??"bundle";if(!n.types.has(g))return false;let y=f.origin??"internal";return n.origins.has(y)}),[l,n]),c=useMemo(()=>{let{types:f}=n;if(f.size===1){if(f.has("skill"))return "skills";if(f.has("mcp"))return "MCPs";if(f.has("bundle"))return "bundles"}return "items"},[n]),d=useMemo(()=>r==="installed"?o?`No ${c} found for '${o}' \u2014 explore the Discover tab!`:`No ${c} installed \u2014 explore the Discover tab!`:r==="updates"?o?`No ${c} found for '${o}' \u2014 all up to date!`:"All up to date \u2014 nothing to update":o?`No ${c} found for '${o}'`:`No ${c} available in the catalog`,[r,o,c]),p=useMemo(()=>{let f=new Map(e.map(y=>[kr(y.name,y.author?.name),y])),g=new Map(e.map(y=>[y.name,y]));return y=>y?f.get(kr(y.name,y.authorName))??g.get(y.name)??null:null},[e]),m=useMemo(()=>a.filter(f=>f.updateAvailable).length,[a]);return {items:u,emptyMessage:d,getSelectedCatalogItem:p,outdatedCount:m}}function oa(){let[e,t]=useState([]),[r,n]=useState(true),[o,s]=useState(null),[i,a]=useState(null),l=useRef(false),u=S(d=>d.catalogVersion),c=useCallback(async()=>{n(true),s(null),a(null);try{let{items:d,failures:p}=await yc();if(t(d),p.length>0){let m=p.map(f=>f.adapterName).join(", ");a(`Some catalogs failed to load: ${m}`);}l.current||(l.current=!0,b(v.CLI_CATALOG_VIEWED,{interface:"tui",filter_type:"all",result_count:d.length}).catch(()=>{}));}catch(d){s(d instanceof Error?d:new Error(String(d))),t([]);}finally{n(false);}},[]);return useEffect(()=>{c();},[c,u]),{catalog:e,isLoading:r,error:o,partialError:i,refetch:c}}function Vu(){return {items:de(t=>t.installedItems)}}var uh=I("catalog");function Ju(){let e=S(Z=>Z.bundleInstallFlow),t=S(Z=>Z.activeTab),r=S(Z=>Z.notification),n=S(Z=>Z.loading),o=S(Z=>Z.loadingMessage),s=S(Z=>Z.catalogError),i=S(Z=>Z.setCatalogError),a=S(Z=>Z.catalogFilters),l=Be(Z=>Z.query),{catalog:u,isLoading:c,error:d,refetch:p}=oa(),{items:m}=Vu(),f=de(Z=>Z.loadFromDisk),{items:g,emptyMessage:y,getSelectedCatalogItem:w,outdatedCount:E}=Ku({catalog:u,installedItems:m,activeTab:t,catalogFilters:a,searchQuery:l}),{actionMenuOpen:T,closeMenu:k,selectedIndex:$,clampIndex:O,filteredItems:G}=Eu({listLength:g.length}),we=G(g),M=useMemo(()=>t!=="installed"&&t!=="updates"?we:ju(we),[t,we]),x=useMemo(()=>t==="installed"||t==="updates"?Fu(M):[],[t,M]),A=M[$]??null,F=useMemo(()=>w(A),[w,A]),{notify:W}=Tu(),{handleInstall:Lt,handleUninstall:gn,handleToggleStatus:L,handleUpdate:N,handleBatchUpdate:V,handleMcpConfigUninstall:ve}=Du({selectedItem:A,selectedCatalogItem:F,items:g,closeMenu:k,clampIndex:O,notify:W}),{handleBundleInstallStart:js,handleBundleDetailConfirm:qp,handleBundleDetailBack:Yp,handleBundleInstallComplete:Zp}=Nu({closeMenu:k,notify:W}),Qp=useCallback(()=>V(M),[V,M]);return useEffect(()=>{f();},[]),useEffect(()=>{O(M.length);},[M.length,O]),useEffect(()=>{d&&(uh.error(`[catalog] ${d instanceof Error?d.message:String(d)}`),i("Failed to load catalog"));},[d]),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Kr,{}),jsx(Rl,{outdatedCount:E}),t==="marketplaces"&&Zt()?jsx(Box,{flexDirection:"column",flexGrow:1,children:jsx(Iu,{})}):jsx(Xl,{filteredItems:M,groups:x,emptyMessage:y,onBatchUpdate:Qp}),(n||c)&&jsx(No,{message:n?o:"Loading catalog..."}),s&&!c&&t==="discover"&&jsx(Bo,{message:s,onRetry:()=>{i(null),p();},onBack:()=>i(null)}),r&&jsx(ql,{message:r.message,type:r.type}),T&&A&&(t==="discover"?F?.type==="bundle"?e?.phase==="installing"?jsx(au,{bundle:e.bundle,onComplete:Zp}):jsx(Xc,{itemName:A.name,bundle:e?.phase==="detail"?e.bundle:void 0,onInstall:()=>js(A.name),onConfirm:qp,onClose:e?.phase==="detail"?Yp:k}):jsx(Wc,{itemName:A.name,itemType:F?.type,onInstall:Lt,onClose:k}):A.type==="mcp"?jsx(tu,{itemName:A.name,itemScope:A.scope??"user",onUninstall:ve,onClose:k}):jsx(Zc,{itemName:A.name,itemScope:A.scope??"user",itemStatus:A.status??"enabled",updateAvailable:A.updateAvailable??false,catalogVersion:F?.version,onUninstall:gn,onToggleStatus:Z=>L(Z),onUpdate:N,onClose:k})),jsx(Oo,{})]})}var _=create((e,t)=>({starterKits:[],selectedStarterKitIndex:0,selectedStarterKit:null,plugins:[],pluginCursorIndex:0,step:"starterKitList",isLoadingStarterKits:false,starterKitsError:null,successCount:0,failedCount:0,summaryActionIndex:0,setStarterKits:r=>e({starterKits:r}),setSelectedStarterKitIndex:r=>e({selectedStarterKitIndex:r}),selectStarterKit:r=>{let n=new Set(de.getState().installedItems.map(o=>o.name));e({selectedStarterKit:r,plugins:r.plugins.map(o=>({name:o,selected:true,status:n.has(o)?"success":"pending",installed:n.has(o)})),pluginCursorIndex:0,step:"starterKitDetail"});},setPluginCursorIndex:r=>e({pluginCursorIndex:r}),setStep:r=>e({step:r}),setPluginStatus:(r,n,o)=>{let s=t().plugins.map(i=>i.name===r?{...i,status:n,error:o}:i);e({plugins:s});},setIsLoadingStarterKits:r=>e({isLoadingStarterKits:r}),setStarterKitsError:r=>e({starterKitsError:r}),setSummaryActionIndex:r=>e({summaryActionIndex:r}),computeSummary:()=>{let n=t().plugins.filter(o=>o.selected);e({successCount:n.filter(o=>o.status==="success").length,failedCount:n.filter(o=>o.status==="failed").length});},resetForRetry:()=>{let r=t().plugins.map(n=>n.status==="failed"?{...n,status:"pending",error:void 0}:n);e({plugins:r,step:"installing"});},goBackToList:()=>e({selectedStarterKit:null,plugins:[],pluginCursorIndex:0,step:"starterKitList"})}));var fh=3;function Wu(){let e=_(l=>l.setStarterKits),t=_(l=>l.setIsLoadingStarterKits),r=_(l=>l.setStarterKitsError),n=_(l=>l.setPluginStatus),o=_(l=>l.setStep),s=_(l=>l.computeSummary),i=useCallback(async()=>{t(true),r(null);try{let l=await Go();e(l);}catch(l){r(l instanceof Error?l.message:String(l));}finally{t(false);}},[t,r,e]);useEffect(()=>{de.getState().loadFromDisk(),i();},[i]);let a=useCallback(async()=>{let l=_.getState().plugins.filter(c=>c.selected&&c.status==="pending");for(let c of l){n(c.name,"installing");let d="",p=false;for(let m=1;m<=fh;m++)try{await Ce(c.name),n(c.name,"success"),p=!0;break}catch(f){if(f instanceof Ue){n(c.name,"success"),p=true;break}d=f instanceof Error?f.message:"Unknown error";}p||(n(c.name,"failed",d),b(v.CLI_TOOL_INSTALL_FAILED,{tool_id:c.name,tool_type:"skill",source:"internal",error_code:"install_failed",error_message:d,interface:H().interfaceType}).catch(()=>{}));}let u=hr();yr("summary_review"),b(v.CLI_STEP_COMPLETED,{step:"tool_installation",duration_ms:u}).catch(()=>{}),de.getState().loadFromDisk(),s(),o("summary");},[n,s,o]);return {loadStarterKits:i,installSelected:a}}var Yn={cursorDelta:0,confirm:false,back:false};function zu(e,t){return t.upArrow?{...Yn,cursorDelta:-1}:t.downArrow?{...Yn,cursorDelta:1}:t.escape?{...Yn,back:true}:t.return?{...Yn,confirm:true}:Yn}var gh={cursorDelta:0,select:false};function Xu(e,t){return t.upArrow?{cursorDelta:-1,select:false}:t.downArrow?{cursorDelta:1,select:false}:t.return?{cursorDelta:0,select:true}:gh}var qu=Cf.memo(function({starterKit:t,isSelected:r}){return jsxs(Box,{flexDirection:"column",paddingBottom:1,children:[jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":"\u25CB "}),jsx(Text,{bold:r,color:r?"cyan":"white",children:h(t.name)}),jsxs(Text,{dimColor:true,children:[" \xB7 ",t.plugins.length," ",t.plugins.length===1?"plugin":"plugins"]})]}),jsx(Box,{paddingLeft:2,children:jsx(Text,{dimColor:true,children:h(t.description)})})]})});var ua=5;function Yu({onRetry:e}){let t=_(c=>c.starterKits),r=_(c=>c.selectedStarterKitIndex),n=_(c=>c.isLoadingStarterKits),o=_(c=>c.starterKitsError);if(n)return jsx(No,{message:"Loading Starter Kits..."});if(o)return jsx(Bo,{message:o,onRetry:e,onBack:e});if(t.length===0)return jsx(Vr,{message:"No Starter Kits available."});let s=Math.max(0,r-Math.floor(ua/2)),i=Math.min(t.length,s+ua);i===t.length&&(s=Math.max(0,i-ua));let a=t.slice(s,i),l=s,u=t.length-i;return jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Select a Starter Kit to get started"})}),l>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2191 ",l," more above"]})}),a.map((c,d)=>jsx(qu,{starterKit:c,isSelected:s+d===r},c.slug)),u>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2193 ",u," more below"]})})]})}var Qu=Cf.memo(function({plugin:t,isCursor:r}){return jsxs(Box,{children:[jsx(Text,{color:r?"cyan":"gray",children:r?"\u203A ":" "}),jsx(Text,{color:"cyan",children:"\u2022"}),jsxs(Text,{bold:r,color:r?"cyan":"white",children:[" ",h(t.name)]}),t.installed&&jsx(Text,{color:"green",children:" (installed)"})]})});var ma=8;function ed(){let e=_(c=>c.selectedStarterKit),t=_(c=>c.plugins),r=_(c=>c.pluginCursorIndex),n=useRef(false);if(useEffect(()=>{e&&!n.current&&(n.current=true,b(v.CLI_KIT_DISPLAYED,{bundle_slug:e.slug,tool_count:t.length}).catch(()=>{}));},[e,t.length]),!e)return jsx(Text,{dimColor:true,children:"No Starter Kit selected."});let o=t.filter(c=>c.installed).length,s=Math.max(0,r-Math.floor(ma/2)),i=Math.min(t.length,s+ma);i===t.length&&(s=Math.max(0,i-ma));let a=t.slice(s,i),l=s,u=t.length-i;return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:[jsx(Text,{bold:true,color:"cyan",children:h(e.name)}),jsx(Text,{dimColor:true,children:h(e.description)})]}),jsx(Box,{paddingX:1,paddingBottom:1,children:jsxs(Text,{children:[t.length," plugins to install",o>0&&` \xB7 ${o} already installed`]})}),l>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2191 ",l," more above"]})}),a.map((c,d)=>jsx(Qu,{plugin:c,isCursor:s+d===r},c.name)),u>0&&jsx(Box,{paddingX:2,children:jsxs(Text,{dimColor:true,children:["\u2193 ",u," more below"]})})]})}var Ph=["Retry failed","Continue anyway"];function td({name:e,status:t,error:r}){let n=h(e);return t==="installing"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",n]})]}):t==="success"?jsx(Box,{children:jsxs(Text,{color:"green",children:["\u2713 ",n]})}):t==="failed"?jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",n]}),r&&jsxs(Text,{dimColor:true,children:[" \u2014 ",h(r)]})]}):jsx(Box,{children:jsxs(Text,{dimColor:true,children:["\u25CB ",n]})})}function rd({onComplete:e,onRetry:t}){let r=_(u=>u.plugins),n=_(u=>u.step),o=_(u=>u.successCount),s=_(u=>u.failedCount),i=_(u=>u.summaryActionIndex),a=r.filter(u=>u.selected),l=useRef(false);return useEffect(()=>{if(n==="summary"&&s===0&&!l.current){l.current=true;let u=setTimeout(e,1500);return ()=>clearTimeout(u)}},[n,s,e]),n==="installing"?jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Installing plugins..."})}),jsx(Box,{flexDirection:"column",paddingX:1,children:a.map(u=>jsx(td,{name:u.name,status:u.status,error:u.error},u.name))})]}):jsxs(Box,{flexDirection:"column",children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Installation Complete"})}),jsxs(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:[o>0&&jsxs(Text,{color:"green",children:["\u2713 ",o," ",o===1?"plugin":"plugins"," installed successfully"]}),s>0&&jsxs(Text,{color:"red",children:["\u2717 ",s," ",s===1?"plugin":"plugins"," failed"]})]}),s>0&&jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:a.filter(u=>u.status==="failed").map(u=>jsx(td,{name:u.name,status:u.status,error:u.error},u.name))}),s>0&&jsx(Box,{flexDirection:"column",paddingX:1,children:Ph.map((u,c)=>jsx(Box,{children:jsxs(Text,{bold:c===i,color:c===i?"cyan":void 0,children:[c===i?"\u203A ":" ",u]})},u))}),s===0&&jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:"Proceeding to main screen..."})})]})}function nd(){let e=_(x=>x.step),t=_(x=>x.starterKits),r=_(x=>x.selectedStarterKitIndex),n=_(x=>x.setSelectedStarterKitIndex),o=_(x=>x.selectStarterKit),s=_(x=>x.plugins),i=_(x=>x.pluginCursorIndex),a=_(x=>x.setPluginCursorIndex),l=_(x=>x.setStep),u=_(x=>x.summaryActionIndex),c=_(x=>x.setSummaryActionIndex),d=_(x=>x.failedCount),p=_(x=>x.resetForRetry),m=_(x=>x.goBackToList),f=S(x=>x.setScreen),g=S(x=>x.setFocus),y=S(x=>x.focus),w=ze(x=>x.setJustAuthenticated),E=ze(x=>x.justAuthenticated),{loadStarterKits:T,installSelected:k}=Wu(),$=useRef(false);useEffect(()=>{e==="starterKitList"?(g("starterKitList"),$.current||($.current=true,yr("bundle_selection"))):g(e==="starterKitDetail"?"starterKitDetail":"installProgress");},[e,g]);let O=useCallback(async()=>{let x=_.getState().selectedStarterKit;if(x){let F=await oe();F&&await _t({...F,starterKit:x.slug});}b(v.CLI_STEP_COMPLETED,{step:"summary_review",duration_ms:hr()}).catch(()=>{});let{successCount:A}=_.getState();b(v.CLI_ONBOARDING_COMPLETED,{duration_ms:Dt(),tools_installed_count:A}).catch(()=>{}),w(false),g("verify"),f("verify");},[w,g,f]),G=useCallback(()=>{p(),k();},[p,k]),we=useCallback(()=>{T();},[T]),M=useCallback(()=>{g("verify"),f("verify");},[g,f]);return useInput((x,A)=>{if(A.escape)$o("esc"),M();else if(A.upArrow&&r>0)n(r-1);else if(A.downArrow&&r<t.length-1)n(r+1);else if(A.return&&t.length>0){let F=hr();o(t[r]),yr("kit_display"),b(v.CLI_STEP_COMPLETED,{step:"bundle_selection",duration_ms:F}).catch(()=>{});}},{isActive:y==="starterKitList"}),useInput((x,A)=>{let F=zu(x,A);if(F.cursorDelta!==0){let W=i+F.cursorDelta;W>=0&&W<s.length&&a(W);}if(F.confirm){let W=_.getState().selectedStarterKit;W&&(async()=>(await oe())?.starterKit!==W.slug&&b(v.CLI_KIT_ACCEPTED,{bundle_slug:W.slug}).catch(()=>{}))();let Lt=hr();yr("kit_confirmation"),b(v.CLI_STEP_COMPLETED,{step:"kit_display",duration_ms:Lt}).catch(()=>{});let gn=hr();yr("tool_installation"),b(v.CLI_STEP_COMPLETED,{step:"kit_confirmation",duration_ms:gn}).catch(()=>{}),l("installing"),k();}if(F.back){let W=_.getState().selectedStarterKit;W&&b(v.CLI_KIT_REJECTED,{bundle_slug:W.slug}).catch(()=>{}),m();}},{isActive:y==="starterKitDetail"}),useInput((x,A)=>{if(d===0)return;let F=Xu(x,A);if(F.cursorDelta!==0){let W=u+F.cursorDelta;W>=0&&W<=1&&c(W);}F.select&&(u===0?G():O());},{isActive:y==="installProgress"&&e==="summary"}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Kr,{}),jsxs(Box,{flexDirection:"column",paddingX:1,marginBottom:1,children:[jsx(Text,{dimColor:true,children:"The data collected during setup is used solely to improve"}),jsx(Text,{dimColor:true,children:"Flow's internal tools and will not be shared externally."}),!E&&jsx(Box,{marginTop:1,children:jsx(Text,{color:"yellow",children:"Welcome back! We noticed your Starter Kit is not set up yet. Choose a Starter Kit below to get your recommended tools."})})]}),jsxs(Box,{flexDirection:"column",flexGrow:1,children:[e==="starterKitList"&&jsx(Yu,{onRetry:we}),e==="starterKitDetail"&&jsx(ed,{}),(e==="installing"||e==="summary")&&jsx(rd,{onComplete:O,onRetry:G})]}),jsx(Oo,{})]})}var $h=I("moduleState");function bs(){let e=process.env.FLOW_HOME??ge__default.join(be__default.homedir(),".flow");return ge__default.join(e,"modules.json")}var Mh={retries:5,minTimeout:50};async function od(e,t){he__default.mkdirSync(ge__default.dirname(e),{recursive:true});let r=await lg.lock(e+".lock",{realpath:false,retries:Mh});try{return await t()}finally{await r();}}function sd(){let e=bs();if(!he__default.existsSync(e))return [];try{let t=JSON.parse(he__default.readFileSync(e,"utf-8"));return t.schemaVersion!==1?($h.warn(`modules.json has unknown schemaVersion ${t.schemaVersion}, resetting`),he__default.rmSync(e,{force:!0}),[]):Array.isArray(t.modules)?t.modules.map(r=>({...r,name:r.name??null})):[]}catch{return he__default.rmSync(e,{force:true}),[]}}function $r(){return sd()}function id(e){let t=bs();he__default.mkdirSync(ge__default.dirname(t),{recursive:true});let r=`${t}.${randomUUID()}.tmp`,n={schemaVersion:1,modules:e};he__default.writeFileSync(r,JSON.stringify(n,null,2),"utf-8"),he__default.renameSync(r,t);}function ot(e){return $r().find(t=>t.alias===e)??null}async function kt(e){let t=bs();await od(t,async()=>{let r=sd(),n=r.findIndex(o=>o.alias===e.alias);n===-1?r.push(e):r[n]=e,id(r);});}async function ln(){let e=bs();he__default.existsSync(e)||await od(e,async()=>{he__default.existsSync(e)||id([]);});}var _h=promisify(execFile);function cr(e,t){let r=e.platforms[process.platform];return !r||r.status!=="supported"?null:r.strategies.find(n=>n.type===t)??null}async function At(e){let t=process.platform==="win32"?"where":"which";try{return await _h(t,[e]),!0}catch{return false}}function Vt(){return process.platform==="win32"?"npm.cmd":"npm"}var ad=promisify(execFile),Ps=class{type="npm";async isAvailable(){return At("npm")}async install(t){let r=await this.getInstalledVersion(t);return r?{success:true,version:r,method:"npm",durationMs:0}:this.runNpmInstall(t,false)}async update(t,r){return this.runNpmInstall(t,true)}async getInstalledVersion(t){let r=cr(t,"npm");if(!r)return null;try{let{stdout:n}=await ad(Vt(),["list","-g",r.package,"--depth=0","--json"],{shell:process.platform==="win32"});return JSON.parse(n).dependencies?.[r.package]?.version??null}catch{return null}}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async runNpmInstall(t,r){let n=Date.now(),o=cr(t,"npm");if(!o)return {success:false,error:{code:"NPM_NOT_AVAILABLE",message:"No npm config for this module on this platform"},durationMs:Date.now()-n};let s=r?`${o.package}@latest`:o.package;try{return await ad(Vt(),["install","-g",s],{shell:process.platform==="win32"}),{success:!0,version:await this.getInstalledVersion(t)??void 0,method:"npm",durationMs:Date.now()-n}}catch(i){return {success:false,error:{code:"NPM_INSTALL_FAILED",message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-n}}}};var ld=promisify(execFile),Uh=/^(\S+)\s+([\d]+\.[\d]+(?:\.[\d]+)*(?:[-_][^\s]+)?)/,Es=class{type="homebrew";async isAvailable(){return At("brew")}async install(t){return this.runBrewCommand(t,"install")}async update(t,r){return this.runBrewCommand(t,"upgrade")}async getInstalledVersion(t){let r=cr(t,"homebrew");return r?this.getVersionByFormula(r.formula):null}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async runBrewCommand(t,r){let n=Date.now(),o=cr(t,"homebrew");if(!o)return {success:false,error:{code:"HOMEBREW_NOT_AVAILABLE",message:"No homebrew config for this module on this platform"},durationMs:Date.now()-n};let s=r==="install"?"HOMEBREW_INSTALL_FAILED":"HOMEBREW_UPGRADE_FAILED";try{return await ld("brew",[r,o.formula]),{success:!0,version:await this.getVersionByFormula(o.formula)??void 0,method:"homebrew",durationMs:Date.now()-n}}catch(i){return {success:false,error:{code:s,message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-n}}}async getVersionByFormula(t){try{let{stdout:r}=await ld("brew",["list","--versions",t]),n=r.trim().match(Uh);return n?n[2]:null}catch{return null}}};var cn=promisify(execFile),Vh=I("curlStrategy"),ud=/([\d]+\.[\d]+(?:\.[\d]+)*(?:[-_][^\s]+)?)/;function dd(){let e=process.env.FLOW_HOME??ge__default.join(be__default.homedir(),".flow");return ge__default.join(e,"bin")}var Cs=class{type="curl";async isAvailable(){return At("curl")}async install(t){let r=Date.now(),n=cr(t,"curl");if(!n)return {success:false,error:{code:"CURL_NOT_AVAILABLE",message:"No curl config for this module on this platform"},durationMs:Date.now()-r};let o=typeof n.url=="function"?n.url(process.arch):n.url;return (n.mode??"binary")==="script"?this.installScript(o,n.checksumUrl,t,r):this.installBinary(o,n.checksumUrl,t,r)}async update(t,r){return this.install(t)}async getInstalledVersion(t){let r=ge__default.join(dd(),t.binaryName);for(let n of [r,t.binaryName])try{let{stdout:o}=await cn(n,["--version"]),s=o.match(ud);if(s)return s[1]}catch{}return null}async uninstall(t){return {success:false,error:{code:"NOT_IMPLEMENTED",message:"uninstall not implemented"},durationMs:0}}async installScript(t,r,n,o){let s=ge__default.join(be__default.tmpdir(),`flow-install-${randomUUID()}.sh`);try{if(await cn("curl",["-sSL","--fail","-o",s,t]),r||Vh.warn(`Installing script for "${n.alias}" without checksum verification \u2014 checksumUrl not provided`),r){let a=await this.validateChecksum(s,r);if(!a.valid){try{he__default.unlinkSync(s);}catch{}return {success:!1,error:{code:"CHECKSUM_MISMATCH",message:a.message},durationMs:Date.now()-o}}}return he__default.chmodSync(s,448),await cn("bash",[s]),{success:!0,version:await this.getInstalledVersion(n)??void 0,method:"curl",durationMs:Date.now()-o}}catch(i){return {success:false,error:{code:"CURL_SCRIPT_FAILED",message:i instanceof Error?i.message:String(i)},durationMs:Date.now()-o}}finally{try{he__default.unlinkSync(s);}catch{}}}async installBinary(t,r,n,o){let s=dd(),i=ge__default.join(s,n.binaryName),a=false;try{if(he__default.mkdirSync(s,{recursive:!0}),a=!0,await cn("curl",["-L","--fail","-o",i,t]),r){let u=await this.validateChecksum(i,r);if(!u.valid)return he__default.unlinkSync(i),{success:!1,error:{code:"CHECKSUM_MISMATCH",message:u.message},durationMs:Date.now()-o}}he__default.chmodSync(i,493);let l=null;try{let{stdout:u}=await cn(i,["--version"]),c=u.match(ud);l=c?c[1]:null;}catch{}return {success:!0,version:l??void 0,method:"curl",durationMs:Date.now()-o}}catch(l){if(a)try{he__default.unlinkSync(i);}catch{}return {success:false,error:{code:"CURL_DOWNLOAD_FAILED",message:l instanceof Error?l.message:String(l)},durationMs:Date.now()-o}}}async validateChecksum(t,r){let n=ge__default.join(be__default.tmpdir(),`curl-checksum-${randomUUID()}`);try{await cn("curl",["-L","--fail","-o",n,r]);let o=he__default.readFileSync(n,"utf-8").trim().split(/\s+/)[0],s=he__default.readFileSync(t),i=createHash("sha256").update(s).digest("hex");return i!==o?{valid:!1,message:`SHA256 mismatch: expected ${o}, got ${i}`}:{valid:!0,message:""}}catch(o){return {valid:false,message:`Checksum validation failed: ${String(o)}`}}finally{try{he__default.unlinkSync(n);}catch{}}}};var Le=I("moduleInstaller");function Ht(e){switch(e){case "npm":return new Ps;case "homebrew":return new Es;case "curl":return new Cs}}async function eo(e,t,r){try{await b(v.CLI_MODULE_INSTALL_FAILED,{module_alias:e.alias,module_name:e.name,os:process.platform,error_code:r.code,error_message:r.message,trigger:t});}catch(n){Le.warn(`Failed to emit install failed event: ${String(n)}`);}}async function dn(e,t,r){let n=Date.now(),o=e.platforms[process.platform];if(!o)return {success:false,error:{code:"PLATFORM_NOT_SUPPORTED",message:`Platform ${process.platform} is not listed for module ${e.alias}`},durationMs:Date.now()-n};if(o.status==="experimental"){Le.warn(`Module "${e.alias}" has experimental support on ${process.platform}`);let l={code:"PLATFORM_EXPERIMENTAL",message:`Experimental support on ${process.platform} \u2014 install manually`};return await eo(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}if(o.status!=="supported"){let l={code:"PLATFORM_NOT_SUPPORTED",message:`Module ${e.alias} is not supported on ${process.platform}`};return await eo(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}if(!o.strategies.some(l=>l.type===r)){let l={code:"STRATEGY_NOT_FOUND",message:`Strategy "${r}" is not configured for module "${e.alias}" on ${process.platform}`};return await eo(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}let s=Ht(r),i=false;try{i=await s.isAvailable();}catch(l){Le.warn(`${r} availability check failed: ${String(l)}`);}if(!i){let l={code:"STRATEGY_NOT_AVAILABLE",message:`"${r}" is not installed on this system`};return await eo(e,t,l),{success:false,error:l,durationMs:Date.now()-n}}try{await b(v.CLI_MODULE_INSTALL_STARTED,{module_alias:e.alias,module_name:e.name,os:process.platform,cli_version:ae,trigger:t});}catch(l){Le.warn(`Failed to emit install started event: ${String(l)}`);}let a;try{a=await s.install(e);}catch(l){let u=l instanceof Error?l.message:String(l);Le.warn(`${r} install threw: ${u}`),a={success:false,error:{code:"INSTALL_THREW",message:u},durationMs:Date.now()-n};}if(a.success){await kt({alias:e.alias,name:e.name,installedVersion:a.version??null,installMethod:a.method??null,installedAt:new Date().toISOString(),lastChecked:new Date().toISOString()});try{await b(v.CLI_MODULE_INSTALL_COMPLETED,{module_alias:e.alias,module_name:e.name,installed_version:a.version??"unknown",duration_ms:a.durationMs,os:process.platform,trigger:t});}catch(u){Le.warn(`Failed to emit install completed event: ${String(u)}`);}let l=await Jh(e,t);return l?{...a,pendingInteractiveSetup:l}:a}return await eo(e,t,a.error??{code:"UNKNOWN",message:"unknown error"}),a}async function Jh(e,t){if(!e.postInstall)return null;let r=t==="onboarding"?e.postInstall.onboarding:e.postInstall.onDemand;if(r==null)return null;let n;if(typeof r=="function"){let o=await oe(),s={credentials:o?{clientId:o.clientId,clientSecret:o.clientSecret,tenant:o.tenant}:null};try{n=r(s);}catch(i){return Le.warn(`postInstall function threw: ${String(i)}`),null}}else n=r;if(n.length===0)return null;if((e.postInstall.mode??"non-interactive")==="interactive")return n[0]??null;for(let o of n){if(o.length===0)continue;let s=spawnSync(o[0],o.slice(1),{stdio:"pipe",env:process.env,encoding:"utf-8",shell:process.platform==="win32"});if(s.status!==0)return Le.warn(`postInstall "${o.join(" ")}" exited with status ${s.status??"null"}`),s.stderr&&Le.warn(s.stderr),null}return null}async function Ts(e,t){let r=Date.now(),n=ot(e.alias);if(!n?.installMethod)return {success:false,error:{code:"NOT_INSTALLED",message:`Module '${e.alias}' is not installed`},durationMs:Date.now()-r};let o=Ht(n.installMethod),s=n.installedVersion??"unknown";if(t==="command")try{await b(v.CLI_MODULE_INSTALL_STARTED,{module_alias:e.alias,module_name:e.name,os:process.platform,cli_version:ae,trigger:"command"});}catch(a){Le.warn(`Failed to emit update started event: ${String(a)}`);}let i;try{i=await o.update(e,s);}catch(a){let l=a instanceof Error?a.message:String(a);Le.warn(`${n.installMethod} update threw: ${l}`),i={success:false,error:{code:"UPDATE_THREW",message:l},durationMs:Date.now()-r};}if(i.success)if(await kt({...n,installedVersion:i.version??n.installedVersion,lastChecked:new Date().toISOString()}),t==="command")try{await b(v.CLI_MODULE_INSTALL_COMPLETED,{module_alias:e.alias,module_name:e.name,installed_version:i.version??"unknown",duration_ms:i.durationMs,os:process.platform,trigger:"command"});}catch(a){Le.warn(`Failed to emit update completed event: ${String(a)}`);}else try{await b(v.CLI_MODULE_UPDATED,{module_alias:e.alias,from_version:s,to_version:i.version??"unknown",duration_ms:i.durationMs});}catch(a){Le.warn(`Failed to emit module updated event: ${String(a)}`);}else if(t==="command")try{await b(v.CLI_MODULE_INSTALL_FAILED,{module_alias:e.alias,module_name:e.name,os:process.platform,error_code:i.error?.code??"UNKNOWN",error_message:i.error?.message??"unknown error",trigger:"command"});}catch(a){Le.warn(`Failed to emit update failed event: ${String(a)}`);}return i}function Gh(e){let t=e.module.platforms[process.platform];return (t?.status==="supported"?t.strategies:[]).map(n=>n.type==="npm"?`npm install -g ${n.package}`:n.type==="homebrew"?`brew install ${n.formula}`:"curl (see docs)").join(" or ")}function fd(e){let[t,r]=useState(()=>e.map(c=>({alias:c.module.alias,name:c.module.name,status:"pending"}))),[n,o]=useState(false),s=useCallback((c,d)=>{r(p=>p.map(m=>m.alias===c?{...m,...d}:m));},[]),i=useCallback(async()=>{for(let c of e){let d=Gh(c);if(!c.selectedStrategy){let p=d?`No package manager available. Install manually: ${d}`:"No package manager available for this platform";s(c.module.alias,{status:"failed",error:p,manualInstallHint:d||void 0});continue}s(c.module.alias,{status:"installing"});try{let p=await dn(c.module,"onboarding",c.selectedStrategy);p.success?s(c.module.alias,{status:"installed",pendingSetupCommand:p.pendingInteractiveSetup?.join(" ")}):s(c.module.alias,{status:"failed",error:p.error?.message??"Installation failed",manualInstallHint:d});}catch(p){s(c.module.alias,{status:"failed",error:p instanceof Error?p.message:"Unknown error",manualInstallHint:d});}}o(true);},[e,s]),a=useMemo(()=>t.filter(c=>c.status==="installed").length,[t]),l=useMemo(()=>t.filter(c=>c.status==="failed").length,[t]),u=useMemo(()=>t.filter(c=>c.status==="skipped").length,[t]);return {modules:t,install:i,isComplete:n,installedCount:a,failedCount:l,skippedCount:u}}function Xh(e){return e.filter(t=>t.module.platforms[process.platform]?.status==="supported").filter(t=>!t.alreadyInstalled).map(t=>({module:t.module,alreadyInstalled:t.alreadyInstalled,checked:!t.alreadyInstalled&&(t.availableStrategies.length>0||t.module.required===true),selectedStrategy:t.availableStrategies[0]??null,availableStrategies:t.availableStrategies}))}function wd(e,t){let[r,n]=useState(()=>Xh(e)),[o,s]=useState(0),i=useRef(o);useEffect(()=>{i.current=o;},[o]);let a=useRef(r);useEffect(()=>{a.current=r;},[r]);let l=useCallback(d=>{n(p=>p.map(m=>m.module.alias!==d||m.module.required?m:{...m,checked:!m.checked}));},[]),u=useCallback((d,p)=>{n(m=>m.map(f=>f.module.alias===d?{...f,selectedStrategy:p}:f));},[]);useInput((d,p)=>{let m=i.current,f=a.current,g=p.upArrow||d==="[A",y=p.downArrow||d==="[B";if(g||y)g&&m>0?s(m-1):y&&m<f.length-1&&s(m+1);else if(d===" "){let w=f[m];w&&!w.module.required&&l(w.module.alias);}else if(p.tab){let w=f[m];if(w&&w.availableStrategies.length>1){let E=w.availableStrategies.indexOf(w.selectedStrategy??w.availableStrategies[0]),T=w.availableStrategies[(E+1)%w.availableStrategies.length];n(k=>k.map($=>$.module.alias===w.module.alias?{...$,selectedStrategy:T}:$));}}},{isActive:t});let c=useMemo(()=>r.filter(d=>d.checked),[r]);return {items:r,focusedIndex:o,toggle:l,setStrategy:u,confirmedItems:c}}function qh(){return te.filter(e=>e.platforms[process.platform]?.status==="supported")}function Id(e){let t=qh();return t.length>0&&t.every(r=>e.find(n=>n.module.alias===r.alias)?.alreadyInstalled===true)}var xd={alias:"metrics",required:true,name:"flow-ai-obs",binaryName:"flow-ai-obs",description:"AI usage telemetry and observability (hooks, OTEL, LLM proxy)",platforms:{darwin:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]},linux:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]},win32:{status:"supported",strategies:[{type:"npm",package:"@ciandt-flow/flow-ai-obs"}]}},versionCheck:{type:"npm-registry",package:"@ciandt-flow/flow-ai-obs"},versionCommand:["flow-ai-obs","--version"],hasOwnUpdateCheck:true,postInstall:{onboarding:e=>{if(!e.credentials)throw new Error("flow-ai-obs setup requires credentials");let{clientId:t,clientSecret:r,tenant:n}=e.credentials;return [["flow-ai-obs","auth","login","--client-id",t,"--client-secret",r,"--tenant",n],["flow-ai-obs","install"]]},onDemand:null,mode:"non-interactive"}},Yh={alias:"dashboard",name:"ccboard",binaryName:"ccboard",description:"Claude Code session monitoring dashboard",docs:"https://github.com/FlorianBruniaux/ccboard",platforms:{darwin:{status:"supported",strategies:[{type:"homebrew",formula:"ccboard"},{type:"curl",url:"https://raw.githubusercontent.com/FlorianBruniaux/ccboard/main/install.sh",mode:"script"}]},linux:{status:"supported",strategies:[{type:"curl",url:"https://raw.githubusercontent.com/FlorianBruniaux/ccboard/main/install.sh",mode:"script"}]},win32:{status:"experimental"}},versionCheck:{type:"github-releases",repo:"florianbruniaux/ccboard"},versionCommand:["ccboard","--version"],hasOwnUpdateCheck:false},te=Zt()?[xd,Yh]:[xd];var Pd=null;function Ed(){return Pd}async function ks(){let t=$r().filter(r=>r.installedVersion===null&&r.installMethod===null);for(let r of t){let n=te.find(i=>i.alias===r.alias);if(!n)continue;let{installedVersion:o,installMethod:s}=await Cd(n);(o||s)&&await kt({...r,installedVersion:o,installMethod:s});}}async function Cd(e){let t=e.platforms[process.platform];if(t?.status!=="supported")return {installedVersion:null,installMethod:null};for(let r of t.strategies)if(r.type!=="curl")try{let o=await Ht(r.type).getInstalledVersion(e);if(o)return {installedVersion:o,installMethod:r.type}}catch{}return {installedVersion:null,installMethod:null}}async function pn(e){let t=await Promise.all(e.map(r=>Zh(r)));return Pd=t,t}async function Zh(e){let t=vd(e.versionCommand);t==="permission-denied"&&(Qh(e.versionCommand[0]),t=vd(e.versionCommand));let r=t==="installed",n=e.platforms[process.platform],o=n?.status==="supported"?n.strategies:[],i=(await Promise.all(o.map(async a=>{try{return await Ht(a.type).isAvailable()?a.type:null}catch{return null}}))).filter(a=>a!==null);if(r&&!ot(e.alias)){let{installedVersion:a,installMethod:l}=await Cd(e);await kt({alias:e.alias,name:e.name,installedVersion:a,installMethod:l,installedAt:null,lastChecked:new Date().toISOString()});}return {module:e,alreadyInstalled:r,availableStrategies:i}}function vd(e){if(e.length===0)return "not-found";try{let t=spawnSync(e[0],e.slice(1),{timeout:3e3,stdio:"pipe",shell:process.platform==="win32"});return t.status===0?"installed":t.status===126?"permission-denied":"not-found"}catch{return "not-found"}}function Qh(e){if(process.platform!=="win32")try{let t=spawnSync("which",[e],{stdio:"pipe"});if(t.status!==0)return;let r=t.stdout.toString().trim(),n=he__default.realpathSync(r),{mode:o}=he__default.statSync(n);he__default.chmodSync(n,o|73);}catch{}}function tS({module:e}){let t=h(e.name);return e.status==="installing"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",t," \u2014 Installing..."]})]}):e.status==="installed"?jsxs(Box,{flexDirection:"column",children:[jsx(Box,{children:jsxs(Text,{color:"green",children:["\u2713 ",t]})}),e.pendingSetupCommand&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["\u2139 Run '",h(e.pendingSetupCommand),"' to complete configuration"]})})]}):e.status==="failed"?jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",t]}),e.error&&jsxs(Text,{dimColor:true,children:[" \u2014 ",h(e.error)]})]}),e.manualInstallHint&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["Install manually: ",h(e.manualInstallHint)]})})]}):e.status==="skipped"?jsx(Box,{children:jsxs(Text,{dimColor:true,children:["- ",t," (not supported on this platform)"]})}):jsx(Box,{children:jsxs(Text,{dimColor:true,children:["\u25CB ",t]})})}function rS({confirmedItems:e}){let t=S(f=>f.setScreen),r=S(f=>f.setFocus),{modules:n,install:o,isComplete:s,installedCount:i,failedCount:a,skippedCount:l}=fd(e),u=useRef(false),c=useRef(false);useEffect(()=>{u.current||(u.current=true,o());},[o]);let d=useCallback(()=>{ln().catch(()=>{}),r("list");let f=se().some(g=>g.name===ie);t(f?"main":"claudeMdSuggestion");},[r,t]);useEffect(()=>{if(s&&a===0&&!c.current){c.current=true;let f=setTimeout(d,1500);return ()=>clearTimeout(f)}},[s,a,d]),useInput((f,g)=>{g.return&&d();},{isActive:s});let p=s,m=[];return i>0&&m.push(jsxs(Text,{color:"green",children:[i," installed"]},"i")),a>0&&m.push(jsxs(Text,{color:"red",children:[a," failed"]},"f")),l>0&&m.push(jsxs(Text,{dimColor:true,children:[l," skipped"]},"s")),jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:s?"Modules ready":"Setting up modules..."})}),jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:n.map(f=>jsx(tS,{module:f},f.alias))}),p&&jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:m.reduce((f,g,y)=>(y>0&&f.push(jsx(Text,{children:" | "},`sep-${y}`)),f.push(g),f),[])}),jsx(Box,{paddingX:1,children:a>0?jsx(Text,{dimColor:true,children:"Press Enter to continue"}):jsx(Text,{dimColor:true,children:"Proceeding..."})})]})]})}function nS({probeResults:e,onConfirm:t}){let r=S(m=>m.focus),n=S(m=>m.actionMenuOpen),o=S(m=>m.setActionMenuOpen),s=S(m=>m.setFocus),{items:i,focusedIndex:a,confirmedItems:l}=wd(e,r==="moduleSetup"),u=useCallback(()=>{o(false),s("moduleSetup");},[o,s]),c=useCallback(m=>{(m==="Install"||m==="Skip")&&t(l),u();},[l,t,u]);useInput((m,f)=>{f.return&&(o(true),s("actionMenu"));},{isActive:r==="moduleSetup"});let d=l.length>0?["Install","Cancel"]:["Skip","Cancel"],p=l.length>0?`Install ${l.length} module(s)?`:"No modules selected";return jsxs(Fragment,{children:[jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Configure modules"})}),jsx(Box,{flexDirection:"column",paddingX:1,paddingBottom:1,children:i.map((m,f)=>{let g=f===a,y=h(m.module.name);return m.availableStrategies.length===0?jsxs(Box,{children:[jsxs(Text,{dimColor:true,children:[" [ ] ",y," "]}),jsx(Text,{dimColor:true,children:"\u2014 no installer available"})]},m.module.alias):jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:g?"cyan":void 0,children:[g?"\u25B6":" ",m.checked?" [\u2713] ":" [ ] ",y]}),m.module.required&&jsx(Text,{dimColor:true,children:" (required)"}),jsxs(Text,{dimColor:true,children:[" ",m.selectedStrategy??""]}),m.availableStrategies.length>1&&jsxs(Text,{dimColor:true,children:[" ","(",m.availableStrategies.indexOf(m.selectedStrategy??m.availableStrategies[0])+1,"/",m.availableStrategies.length," \u2194)"]})]}),m.module.description&&jsx(Box,{paddingLeft:6,children:jsx(Text,{dimColor:true,children:h(m.module.description)})})]},m.module.alias)})}),jsx(Box,{paddingX:1,children:jsx(Text,{dimColor:true,children:"\u2191\u2193 navigate \xB7 Space toggle \xB7 Tab change method \xB7 Enter confirm"})}),n&&jsx(qe,{itemName:p,actions:d,onAction:c,onClose:u})]})}function Ad(){let[e,t]=useState("loading"),[r,n]=useState([]),[o,s]=useState([]),i=S(c=>c.setFocus),a=S(c=>c.setScreen),l=useCallback(c=>{if(Id(c)){ln().catch(()=>{}),i("list");let p=se().some(m=>m.name===ie);a(p?"main":"claudeMdSuggestion");}else n(c),t("selection");},[i,a]);useEffect(()=>{let c=Ed();if(c){l(c);return}pn(te).then(l).catch(()=>{n([]),t("selection");});},[l]);let u=useCallback(c=>{s(c),t("installation");},[]);return jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[e==="loading"&&jsx(Box,{paddingX:1,paddingBottom:1,children:jsx(Text,{bold:true,children:"Setting up modules..."})}),e==="selection"&&jsx(nS,{probeResults:r,onConfirm:u}),e==="installation"&&jsx(rS,{confirmedItems:o})]})}var aS=I("ClaudeMdSuggestion"),lS=[`Install ${ie}`,"Skip for now"],cS=["Retry","Skip for now"];function Ld(){let e=S(p=>p.setScreen),t=S(p=>p.setFocus),r=_(p=>p.successCount),[n,o]=useState("prompt"),[s,i]=useState(0),a=useRef(0),l=useCallback(()=>{t("list"),e("main");},[t,e]),u=useCallback(()=>{b(v.CLI_CLAUDE_MD_SKIPPED,{interface:"tui"}).catch(()=>{}),l();},[l]),c=useCallback(async()=>{a.current+=1,b(v.CLI_CLAUDE_MD_ACCEPTED,{interface:"tui",attempt:a.current}).catch(()=>{}),o("installing");try{await Ce(ie),o("installed");}catch(p){if(p instanceof Ue){o("installed");return}aS.warn(`Failed to install ${ie}: ${p instanceof Error?p.message:p}`),o("error");}},[]),d=n==="error"?cS:lS;return useInput((p,m)=>{if(m.escape){n==="prompt"||n==="error"?u():n==="installed"&&l();return}if(n==="prompt"||n==="error"){m.upArrow&&s>0?i(s-1):m.downArrow&&s<d.length-1?i(s+1):m.return&&(s===0?(i(0),c()):u());return}n==="installed"&&m.return&&l();}),jsxs(Box,{flexDirection:"column",borderStyle:"round",paddingX:1,children:[jsx(Kr,{}),jsxs(Box,{flexDirection:"column",paddingX:1,gap:1,children:[jsx(Text,{color:"green",bold:true,children:r>0?"\u2713 Starter kit installed!":"\u2713 Setup complete!"}),n==="prompt"&&jsxs(Fragment,{children:[jsxs(Box,{flexDirection:"column",children:[jsx(Text,{bold:true,children:"Personalize your Claude Code"}),jsx(Text,{children:"This plugin helps Claude understand your preferences and work style."})]}),jsx(Md,{options:d,cursorIndex:s}),jsx(Text,{dimColor:true,children:"You can always install it later from the catalog."})]}),n==="installing"&&jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" Installing ",ie,"..."]})]}),n==="installed"&&jsxs(Fragment,{children:[jsxs(Text,{color:"green",bold:true,children:["\u2713 ",ie," installed!"]}),jsxs(Box,{flexDirection:"column",children:[jsx(Text,{children:"Open Claude in a new terminal or in VS Code and type:"}),jsxs(Text,{bold:true,color:"cyan",children:["/",ie]})]}),jsx(Text,{children:"Claude will guide you through the rest."}),jsx(Text,{dimColor:true,children:"Press Enter to continue to the catalog..."})]}),n==="error"&&jsxs(Fragment,{children:[jsxs(Text,{color:"red",bold:true,children:["\u2717 Failed to install ",ie]}),jsx(Md,{options:d,cursorIndex:s}),jsx(Text,{dimColor:true,children:"You can always install it later from the catalog."})]})]})]})}function Md({options:e,cursorIndex:t}){return jsx(Box,{flexDirection:"column",children:e.map((r,n)=>jsxs(Text,{bold:n===t,color:n===t?"cyan":void 0,children:[n===t?"\u203A ":" ",r]},r))})}var mS=promisify(execFile),As="@ciandt-flow/cli";async function Rd(){let e=ae;if(ea.prerelease(e)||process.env.NODE_ENV==="development")return {currentVersion:e,latestVersion:e,isOutdated:false,packageName:As};try{let t=await fetch(`https://registry.npmjs.org/${As}/latest`);if(!t.ok)throw new Error(`Registry returned ${t.status}`);let n=(await t.json()).version;return {currentVersion:e,latestVersion:n,isOutdated:n!==e,packageName:As}}catch{return {currentVersion:e,latestVersion:e,isOutdated:false,packageName:As}}}async function $s(e){try{return await mS(Vt(),["install","-g",e.packageName],{timeout:6e4,shell:process.platform==="win32"}),{success:!0}}catch(t){return {success:false,error:String(t)}}}async function _d(e){let r=ot(e.alias)?.installedVersion??null,n=null;try{if(e.versionCheck.type==="npm-registry"){let s=await fetch(`https://registry.npmjs.org/${e.versionCheck.package}/latest`);if(!s.ok)throw new Error(`Registry returned ${s.status}`);n=(await s.json()).version;}else if(e.versionCheck.type==="github-releases"){let s=await fetch(`https://api.github.com/repos/${e.versionCheck.repo}/releases/latest`);if(!s.ok)throw new Error(`GitHub returned ${s.status}`);n=(await s.json()).tag_name.replace(/^v/,"");}}catch{}let o=r!==null&&n!==null&&r!==n;return {moduleAlias:e.alias,currentVersion:r,latestVersion:n,isOutdated:o}}async function Dd(e,t){let r=ot(e.alias);if(!r?.installMethod)return {success:false,error:"Unknown install method"};let o=await Ht(r.installMethod).update(e,t.currentVersion??"");return o.success?(await kt({...r,installedVersion:o.version??r.installedVersion,lastChecked:new Date().toISOString()}),{success:true,newVersion:o.version}):{success:false,error:o.error?.message}}function Od(e){let r=ot(e.alias)?.installMethod,n=e.platforms[process.platform];if(n?.status==="supported"){if(r==="npm"){let o=n.strategies.find(s=>s.type==="npm");if(o?.type==="npm")return `npm install -g ${o.package}`}if(r==="homebrew"){let o=n.strategies.find(s=>s.type==="homebrew");if(o?.type==="homebrew")return `brew upgrade ${o.formula}`}}}function Nd(){let[e,t]=useState({outcome:"running",items:[{id:"cli",label:"@ciandt-flow/cli",status:"pending"},...te.map(n=>({id:n.alias,label:n.name,status:"pending"}))]}),r=useCallback((n,o)=>{t(s=>({...s,items:s.items.map(i=>i.id===n?{...i,...o}:i)}));},[]);return useEffect(()=>{async function n(){try{let[o,s,i]=await Promise.all([Rd(),pn(te),Promise.all(te.map(l=>_d(l)))]);if(ks(),o.isOutdated){r("cli",{status:"updating",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`}),(await $s(o)).success?(r("cli",{status:"updated",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`}),t(u=>({...u,outcome:"cli-updated"}))):(r("cli",{status:"error",detail:`v${o.currentVersion} \u2192 v${o.latestVersion}`,manualCommand:`npm install -g ${o.packageName}`}),t(u=>({...u,outcome:"cli-update-failed"})));return}r("cli",{status:"ok",detail:`v${o.currentVersion}`});let a=s.some(l=>!l.alreadyInstalled);for(let l of s)l.alreadyInstalled||r(l.module.alias,{status:"missing"});if(a){t(l=>({...l,outcome:"module-missing"}));return}for(let l of i){let u=te.find(d=>d.alias===l.moduleAlias);if(!u)continue;if(!l.isOutdated){r(l.moduleAlias,{status:"ok",detail:l.currentVersion?`v${l.currentVersion}`:void 0});continue}r(l.moduleAlias,{status:"updating",detail:`v${l.currentVersion} \u2192 v${l.latestVersion}`});let c=await Dd(u,l);c.success?r(l.moduleAlias,{status:"updated",detail:`v${c.newVersion}`}):r(l.moduleAlias,{status:"error",detail:`v${l.currentVersion} \u2192 v${l.latestVersion}`,manualCommand:Od(u)});}t(l=>({...l,items:l.items.map(u=>u.status==="pending"?{...u,status:"ok"}:u)})),await ln(),t(l=>({...l,outcome:"done"}));}catch{await ln(),t(o=>({...o,outcome:"done"}));}}n();},[r]),e}function wS({item:e}){return e.status==="pending"||e.status==="updating"?jsxs(Box,{children:[jsx(Text,{color:"cyan",children:jsx(iu,{type:"dots"})}),jsxs(Text,{color:"cyan",children:[" ",e.label,e.detail?` ${e.detail}...`:""]})]}):e.status==="ok"||e.status==="updated"?jsxs(Box,{children:[jsxs(Text,{color:"green",children:["\u2713 ",e.label]}),e.detail&&jsxs(Text,{dimColor:true,children:[" ",e.detail]})]}):e.status==="missing"?jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",e.label]}),jsx(Text,{dimColor:true,children:" \u2014 not installed"})]}):jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{children:[jsxs(Text,{color:"red",children:["\u2717 ",e.label]}),e.detail&&jsxs(Text,{dimColor:true,children:[" ",e.detail]})]}),e.manualCommand&&jsx(Box,{paddingLeft:2,children:jsxs(Text,{dimColor:true,children:["To update manually: ",e.manualCommand]})})]})}function xS({outcome:e}){return e==="done"?jsx(Text,{color:"green",children:"All good!"}):e==="cli-updated"||e==="cli-update-failed"?jsx(Text,{color:"yellow",children:"Restart the CLI to use the new version."}):null}function Bd(){let{outcome:e,items:t}=Nd(),r=S(o=>o.setScreen),n=S(o=>o.setFocus);return useEffect(()=>{if(e==="done"){let o=setTimeout(()=>{let s=se().some(i=>i.name===ie);r(s?"main":"claudeMdSuggestion"),n("list");},1500);return ()=>clearTimeout(o)}if(e==="module-missing"){let o=setTimeout(()=>{r("moduleSetup"),n("moduleSetup");},500);return ()=>clearTimeout(o)}},[e,r,n]),jsxs(Box,{flexDirection:"column",paddingX:2,paddingY:1,children:[jsx(Box,{marginBottom:1,children:jsx(Text,{bold:true,children:"Checking environment..."})}),jsx(Box,{flexDirection:"column",gap:0,children:t.map(o=>jsx(wS,{item:o},o.id))}),e!=="running"&&jsx(Box,{marginTop:1,children:jsx(xS,{outcome:e})})]})}var PS={debug:"gray",info:"cyan",warn:"yellow",error:"red"},Ud=10;function Fd(){let[e,t]=useState(Xs());useEffect(()=>za(()=>{t([...Xs()]);}),[]);let r=e.slice(-Ud);return jsxs(Box,{flexDirection:"column",borderStyle:"single",borderColor:"cyan",paddingX:1,children:[jsxs(Text,{color:"cyan",bold:true,children:["Debug Log (last ",Ud,") \u2014 press Ctrl+D to close"]}),r.length===0?jsx(Text,{dimColor:true,children:"No log entries yet"}):r.map((n,o)=>jsxs(Text,{color:PS[n.level],children:["[",n.level.toUpperCase(),"] [",n.module,"] ",n.message]},o))]})}var kS=I("app"),AS={auth:Pl,starterKitSetup:nd,moduleSetup:Ad,claudeMdSuggestion:Ld,verify:Bd,main:Ju};function Vd(){let{setScreen:e,setFocus:t}=S.getState();e("auth"),t("auth");}function An(e){let{setScreen:t,setFocus:r}=S.getState();!e.starterKit||e.starterKit.trim()===""?(t("starterKitSetup"),r("starterKitList")):(t("verify"),r("verify"));}function Hd(){b(v.CLI_SESSION_STARTED,{cli_version:ae,os:process.platform,node_version:process.version,duration_ms:Dt(),interface:"tui"}).catch(()=>{});}async function Gd(){let e=await oe();if(e&&Il()&&await qt()){let{clientSecret:n,...o}=e;ze.getState().setCredentials(o),Hd(),An(e);return}if(!e){Vd();return}try{await Yt();}catch(n){kS.debug(`Token validation failed: ${String(n)}`),Vd();return}Hd();let{clientSecret:t,...r}=e;ze.getState().setCredentials(r),An(e);}function Wd(){let{columns:e,rows:t}=useWindowSize(),r=S(a=>a.screen),n=AS[r],{pendingExit:o}=hl(),s=S(a=>a.debugPanelOpen),i=!!process.env.DEBUG;return useInput((a,l)=>{if(i&&l.ctrl&&a==="d"){let u=S.getState().debugPanelOpen;S.getState().setDebugPanelOpen(!u);}}),n?jsxs(Box,{flexDirection:"column",width:e,height:t,children:[jsx(n,{}),i&&s&&jsx(Fd,{}),o&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:"Press Ctrl+C again to quit"})})]}):jsxs(Text,{color:"red",children:["Unknown screen: ",r]})}async function Ta(e,t={}){let r=Lo({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant},t);return Ro(r),await _t(e),{jwt:r.jwt,previousToken:r.previousToken,hadExistingFile:r.hadExistingFile}}var gt=I("auth");function Xd(){Ne.clearFallbackFile(),Eo();}var $S=3,zd=3,qd=` \u2139 The data collected during setup is used solely to improve
|
|
117
117
|
Flow's internal tools and will not be shared externally.
|
|
118
|
-
`;function
|
|
118
|
+
`;function Mr(e,t={}){return new Promise((r,n)=>{let{masked:o=false,defaultValue:s=""}=t;process.stdout.write(e+s);let i=s,a=c=>{if(c===""){l(),n(new Error("SIGINT"));return}if(c==="\r"||c===`
|
|
119
119
|
`){l(),process.stdout.write(`
|
|
120
|
-
`),r(i);return}if(c==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}c.startsWith("\x1B")||(i+=c,process.stdout.write(o?"*".repeat(c.length):c));};function l(){process.stdin.setRawMode(false),process.stdin.removeListener("data",a),process.removeListener("uncaughtException",u),process.removeListener("unhandledRejection",u),process.removeListener("SIGINT",u),process.removeListener("SIGTERM",u);}function u(){try{process.stdin.setRawMode(!1);}catch{}}process.on("uncaughtException",u),process.on("unhandledRejection",u),process.on("SIGINT",u),process.on("SIGTERM",u),process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",a);})}async function
|
|
121
|
-
`+R.yellow(" \u26A0 ")+`${
|
|
122
|
-
`),(await
|
|
120
|
+
`),r(i);return}if(c==="\x7F"){i.length>0&&(i=i.slice(0,-1),process.stdout.write("\b \b"));return}c.startsWith("\x1B")||(i+=c,process.stdout.write(o?"*".repeat(c.length):c));};function l(){process.stdin.setRawMode(false),process.stdin.removeListener("data",a),process.removeListener("uncaughtException",u),process.removeListener("unhandledRejection",u),process.removeListener("SIGINT",u),process.removeListener("SIGTERM",u);}function u(){try{process.stdin.setRawMode(!1);}catch{}}process.on("uncaughtException",u),process.on("unhandledRejection",u),process.on("SIGINT",u),process.on("SIGTERM",u),process.stdin.setRawMode(true),process.stdin.resume(),process.stdin.setEncoding("utf8"),process.stdin.on("data",a);})}async function MS(){let e=Sr();return process.stdout.write(`
|
|
121
|
+
`+R.yellow(" \u26A0 ")+`${h(e)} contains invalid JSON.
|
|
122
|
+
`),(await Mr(R.cyan(" ? ")+"Overwrite it with a fresh file containing only the auth token? (y/N): ")).trim().toLowerCase()==="y"}async function Yd(e,t){try{await Ta(e);return}catch(r){if(!(r instanceof wr))throw r;if(!t)throw new Error(`${r.message}. Fix or remove ${Sr()} and retry.`);if(!await MS())throw new Error("Setup cancelled: settings.json must be valid JSON to continue");await Ta(e,{allowOverwriteMalformed:true});}}async function Zd(){for(let e=1;e<=zd;e++)try{return await Go()}catch{if(e===zd)throw new Error("Failed to fetch starter kits after 3 attempts")}return []}async function Qd(){let e=await Zd();if(e.length===0)throw new Error("No starter kits available. Please contact your administrator.");for(process.stdout.write(`
|
|
123
123
|
`+R.cyan(" ? ")+`Starter Kit:
|
|
124
|
-
`),e.forEach((t,r)=>{process.stdout.write(` ${R.cyan(`${r+1})`)} ${
|
|
124
|
+
`),e.forEach((t,r)=>{process.stdout.write(` ${R.cyan(`${r+1})`)} ${h(t.name)}
|
|
125
125
|
`);}),process.stdout.write(`
|
|
126
|
-
`);;){let t=(await
|
|
127
|
-
`));}}async function
|
|
128
|
-
Starter kit '${
|
|
126
|
+
`);;){let t=(await Mr(R.cyan(" ? ")+`Select starter kit (1-${e.length}): `)).trim(),r=parseInt(t,10)-1;if(!isNaN(r)&&r>=0&&r<e.length)return e[r];process.stderr.write(R.yellow(` \u26A0 Invalid selection. Please try again.
|
|
127
|
+
`));}}async function ep(e){if(e.plugins.length===0)return process.stdout.write(R.dim(`
|
|
128
|
+
Starter kit '${h(e.name)}' has no plugins to install.
|
|
129
129
|
`)),true;process.stdout.write(`
|
|
130
|
-
Installing ${e.plugins.length} plugins from '${
|
|
131
|
-
`);let t=0,r=0,n=e.plugins.length;for(let o of e.plugins){let s=t+r+1;process.stdout.write(R.dim(` [${s}/${n}] Installing ${
|
|
130
|
+
Installing ${e.plugins.length} plugins from '${h(e.name)}'...
|
|
131
|
+
`);let t=0,r=0,n=e.plugins.length;for(let o of e.plugins){let s=t+r+1;process.stdout.write(R.dim(` [${s}/${n}] Installing ${h(o)}...`));let i=false;for(let a=1;a<=$S;a++)try{await Ce(o),t++,i=!0;break}catch(l){if(l instanceof Ue){t++,i=true;break}}i?process.stdout.write(R.green(` done
|
|
132
132
|
`)):(r++,process.stdout.write(R.red(` failed
|
|
133
|
-
`)));}return r===0?process.stdout.write(R.green(` \u2713 Starter kit '${
|
|
134
|
-
`)):process.stdout.write(R.yellow(` \u26A0 Starter kit '${
|
|
135
|
-
`)),r===0}async function
|
|
133
|
+
`)));}return r===0?process.stdout.write(R.green(` \u2713 Starter kit '${h(e.name)}' selected. ${t}/${n} plugins installed successfully.
|
|
134
|
+
`)):process.stdout.write(R.yellow(` \u26A0 Starter kit '${h(e.name)}' selected. ${t}/${n} plugins installed. ${r} failed.
|
|
135
|
+
`)),r===0}async function tp(){process.stdout.write(`
|
|
136
136
|
`),process.stdout.write(R.bold(` Personalize your Claude Code
|
|
137
137
|
`)),process.stdout.write(R.dim(` This plugin helps Claude understand your preferences and work style.
|
|
138
138
|
|
|
139
|
-
`));let e=(await
|
|
139
|
+
`));let e=(await Mr(R.cyan(" ? ")+`Install ${ie}? (Y/n): `)).trim();if(e!==""&&e.toLowerCase()!=="y"){b(v.CLI_CLAUDE_MD_SKIPPED,{interface:"cli"}).catch(()=>{}),process.stdout.write(R.dim(`
|
|
140
140
|
You can always install it later from the catalog.
|
|
141
|
-
`));return}v
|
|
142
|
-
`));}catch(t){if(t instanceof
|
|
143
|
-
`));else {
|
|
141
|
+
`));return}b(v.CLI_CLAUDE_MD_ACCEPTED,{interface:"cli"}).catch(()=>{}),process.stdout.write(R.dim(` Installing ${ie}...`));try{await Ce(ie),process.stdout.write(R.green(` done
|
|
142
|
+
`));}catch(t){if(t instanceof Ue)process.stdout.write(R.green(` already installed
|
|
143
|
+
`));else {gt.warn(`Failed to install ${ie}: ${t instanceof Error?t.message:t}`),process.stdout.write(R.red(` failed
|
|
144
144
|
`)),process.stdout.write(R.dim(` You can install it later from the catalog.
|
|
145
145
|
`));return}}process.stdout.write(`
|
|
146
146
|
`),process.stdout.write(` Open Claude in a new terminal or in VS Code and type:
|
|
147
147
|
`),process.stdout.write(R.cyan.bold(` /${ie}
|
|
148
148
|
`)),process.stdout.write(` Claude will guide you through the rest.
|
|
149
|
-
`);}async function
|
|
150
|
-
`+
|
|
151
|
-
`),
|
|
152
|
-
`)),1}try{let t;if(e.starterKit){let r=await
|
|
149
|
+
`);}async function LS(e){Xd(),process.stdout.write(`
|
|
150
|
+
`+qd+`
|
|
151
|
+
`),gt.debug(`[${e.tenant}] Authenticating tenant`);try{await gr(e);}catch(t){let r=h(t instanceof Error?t.message:"unknown error");return gt.error(`[${e.tenant}] Authentication failed: ${r}`),process.stderr.write(R.red(` \u2717 Authentication failed: ${r}
|
|
152
|
+
`)),1}try{let t;if(e.starterKit){let r=await Zd(),n=r.find(o=>o.slug===e.starterKit);if(!n){process.stderr.write(R.red(` \u2717 Starter kit '${h(e.starterKit)}' not found.
|
|
153
153
|
`)),process.stderr.write(` Available starter kits:
|
|
154
|
-
`);for(let o of r)process.stderr.write(` - ${
|
|
155
|
-
`);return 1}t=n;}else t=await
|
|
156
|
-
\u2713 Setup complete. Tenant: ${e.tenant}. JWT written to ${
|
|
154
|
+
`);for(let o of r)process.stderr.write(` - ${h(o.slug)} (${h(o.name)})
|
|
155
|
+
`);return 1}t=n;}else t=await Qd();return await Yd({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant,starterKit:t.slug},!1),await ep(t),await tp(),gt.info(`[${e.tenant}] Authentication successful`),process.stdout.write(R.green(`
|
|
156
|
+
\u2713 Setup complete. Tenant: ${e.tenant}. JWT written to ${Sr()}.
|
|
157
157
|
|
|
158
|
-
`)),0}catch(t){if(t instanceof Error&&t.message==="SIGINT")throw t;let r=
|
|
159
|
-
`)),1}}async function
|
|
160
|
-
`),process.stdout.write(
|
|
161
|
-
`);let e=(await
|
|
162
|
-
`)),1;
|
|
163
|
-
`)),1}let n=await
|
|
164
|
-
\u2713 Setup complete. Tenant: ${r}. JWT written to ${
|
|
158
|
+
`)),0}catch(t){if(t instanceof Error&&t.message==="SIGINT")throw t;let r=h(t instanceof Error?t.message:"unknown error");return gt.error(`[${e.tenant}] Starter kit setup failed: ${r}`),process.stderr.write(R.red(` \u2717 Starter kit setup failed: ${r}
|
|
159
|
+
`)),1}}async function RS(){Xd(),gt.debug("[auth] Starting interactive authentication");try{process.stdout.write(`
|
|
160
|
+
`),process.stdout.write(qd+`
|
|
161
|
+
`);let e=(await Mr(R.cyan(" ? ")+"Client ID: ")).trim(),t=(await Mr(R.cyan(" ? ")+"Client Secret: ",{masked:!0})).trim(),r=(await Mr(R.cyan(" ? ")+"Tenant: ")).trim();if(!e||!t||!r)return gt.error("[auth] Validation failed: all fields are required"),process.stderr.write(R.red(` \u2717 All fields are required
|
|
162
|
+
`)),1;gt.debug(`[${r}] Authenticating tenant`);try{await gr({clientId:e,clientSecret:t,tenant:r});}catch(o){let s=h(o instanceof Error?o.message:"unknown error");return gt.error(`[${r}] Authentication failed: ${s}`),process.stderr.write(R.red(` \u2717 Authentication failed: ${s}
|
|
163
|
+
`)),1}let n=await Qd();return await Yd({clientId:e,clientSecret:t,tenant:r,starterKit:n.slug},!0),await ep(n),await tp(),gt.info(`[${r}] Authentication successful`),process.stdout.write(R.green(`
|
|
164
|
+
\u2713 Setup complete. Tenant: ${r}. JWT written to ${Sr()}.
|
|
165
165
|
|
|
166
|
-
`)),0}catch(e){if(e instanceof Error&&e.message==="SIGINT")throw e;let t=
|
|
167
|
-
`)),1}}async function
|
|
168
|
-
`),130;throw t}}async function
|
|
169
|
-
`),(await
|
|
166
|
+
`)),0}catch(e){if(e instanceof Error&&e.message==="SIGINT")throw e;let t=h(e instanceof Error?e.message:"unknown error");return gt.error(`[auth] Unexpected error: ${t}`),process.stderr.write(R.red(` \u2717 Unexpected error: ${t}
|
|
167
|
+
`)),1}}async function ka(e={}){if(e.clientId&&e.clientSecret&&e.tenant)return LS({clientId:e.clientId,clientSecret:e.clientSecret,tenant:e.tenant,starterKit:e.starterKit});try{return await RS()}catch(t){if(t instanceof Error&&t.message==="SIGINT")return process.stdout.write(`
|
|
168
|
+
`),130;throw t}}async function _S(){try{return process.stdout.write(`
|
|
169
|
+
`),(await Mr(R.cyan(" ? ")+"Are you sure? This will remove your local credentials. (y/N): ")).toLowerCase()!=="y"?(process.stdout.write(R.yellow(` \u26A0 Logout cancelled
|
|
170
170
|
`)),0):null}catch(e){if(e instanceof Error&&e.message==="SIGINT")return process.stdout.write(`
|
|
171
|
-
`),130;throw e}}async function
|
|
172
|
-
`)),0;if(!e){let t=await
|
|
171
|
+
`),130;throw e}}async function rp(e){if(!await oe())return process.stdout.write(R.yellow(` \u26A0 You are not authenticated
|
|
172
|
+
`)),0;if(!e){let t=await _S();if(t!==null)return t}try{return await rl(),process.stdout.write(R.green(` \u2713 Credentials removed successfully
|
|
173
173
|
`)),0}catch{return process.stderr.write(R.red(` \u2717 Error removing credentials
|
|
174
|
-
`)),1}}async function
|
|
174
|
+
`)),1}}async function np(){let e=await oe();return e?await qt()?(process.stdout.write(`
|
|
175
175
|
`+R.bold(` Authenticated
|
|
176
|
-
`)),process.stdout.write(R.dim(" Tenant: ")+
|
|
177
|
-
`),process.stdout.write(R.dim(" Client ID: ")+
|
|
178
|
-
`),process.stdout.write(R.dim(" Starter Kit: ")+
|
|
179
|
-
`),process.stdout.write(R.dim(" Config: ")+
|
|
176
|
+
`)),process.stdout.write(R.dim(" Tenant: ")+h(e.tenant)+`
|
|
177
|
+
`),process.stdout.write(R.dim(" Client ID: ")+h(e.clientId)+`
|
|
178
|
+
`),process.stdout.write(R.dim(" Starter Kit: ")+h(e.starterKit??"not set")+`
|
|
179
|
+
`),process.stdout.write(R.dim(" Config: ")+h(await nl())+`
|
|
180
180
|
`),process.stdout.write(`
|
|
181
|
-
`),0):(process.stdout.write(R.yellow(" \u26A0 Session expired. Run `flow auth login` to re-authenticate.\n")),0):(process.stdout.write(R.yellow(" \u26A0 Not authenticated. Run `flow auth login` to set up.\n")),0)}async function
|
|
181
|
+
`),0):(process.stdout.write(R.yellow(" \u26A0 Session expired. Run `flow auth login` to re-authenticate.\n")),0):(process.stdout.write(R.yellow(" \u26A0 Not authenticated. Run `flow auth login` to set up.\n")),0)}async function DS(e){let t=se(),r;try{r=await tr();}catch{r=[];}let n=new Set(t.map(o=>o.name));return b(v.CLI_CATALOG_VIEWED,{interface:H().interfaceType,filter_type:"available",result_count:r.length}).catch(()=>{}),e.json?(Ur(r.map(o=>({...o,installed:n.has(o.name)}))),0):(Br(["","Name","Version","Category","Status"],r.map(o=>[n.has(o.name)?"*":" ",o.name??"",o.version??"n/a",o.category??"",n.has(o.name)?"installed":"available"])),0)}async function OS(e){let t=se(),r=await tr(),n=new Map(r.map(s=>[s.name,s])),o=t.map(s=>{let i=n.get(s.name);return i&&s.version&&i.version&&Ae(s.version,i.version)?{...s,availableVersion:i.version}:null}).filter(s=>s!==null);return b(v.CLI_CATALOG_VIEWED,{interface:H().interfaceType,filter_type:"outdated",result_count:o.length}).catch(()=>{}),o.length===0?(C("All plugins are up to date."),0):e.json?(Ur(o),0):(Br(["Name","Installed","Available"],o.map(s=>[s.name??"",s.version??"n/a",s.availableVersion??"n/a"])),process.stdout.write(`
|
|
182
182
|
${o.length} plugin(s) outdated.
|
|
183
|
-
`),0)}async function
|
|
183
|
+
`),0)}async function NS(e){let t=se();if(b(v.CLI_CATALOG_VIEWED,{interface:H().interfaceType,filter_type:"all",result_count:t.length}).catch(()=>{}),t.length===0)return C("No plugins installed. Use `flow plugin install <name>` to install one."),0;if(e.json)return Ur(t),0;let r=[];try{r=await tr();}catch{r=[];}let n=new Map(r.map(s=>[s.name,s])),o=[...t].sort((s,i)=>{let a=qn.indexOf(s.scope??"user"),l=qn.indexOf(i.scope??"user");return (a===-1?1/0:a)-(l===-1?1/0:l)});return Br(["Name","Version","Type","Origin","Scope","Status","Installed at"],o.map(s=>{let i=n.get(s.name),a=i?.type??"bundle",l=i?.origin??ra(s.marketplace);return [s.name??"",s.version??"n/a",_r[a]?.label??"Plugin",l,s.scope??"user",s.status??"enabled",Wt(s.installedAt??"")]})),process.stdout.write(`
|
|
184
184
|
${t.length} plugin(s) installed.
|
|
185
|
-
`),0}async function
|
|
185
|
+
`),0}async function op(e){if(!await ye())return 1;try{return e.available?await DS(e):e.outdated?await OS(e):await NS(e)}catch(t){return P(t instanceof Error?t.message:"Failed to list plugins."),1}}var le=I("manage");function Ls(e,t){return t?se().find(r=>r.name===e&&r.scope===t):se().find(r=>r.name===e)}function BS(e,t){let r=t;return {callbacks:{onStatus:o=>{r&&(r.text=`${e}${o}`);},onError:o=>{r?.stop(),r=void 0,C(`${e}${o}`);},onPause:()=>{r?.stop(),r=void 0;},onResume:o=>{r?.stop(),r=Aa({text:`${e}${o}`}).start();}},stopSpinner:()=>{r?.stop(),r=void 0;}}}async function US(e,t,r,n){let o=n;if(!r.force){o?.stop();let i=h(e),a=h(Wr(e,r.scope));if(!await xt(`${t}Install external plugin "${i}"?
|
|
186
186
|
This will run: ${a}
|
|
187
|
-
[y/N] `))return le.debug(`[${e}] Installation cancelled by user`),r.silent||
|
|
188
|
-
Installation summary: ${t} succeeded, ${r} failed`);}async function
|
|
189
|
-
Update summary: ${t} updated, ${r} already up to date, ${n} failed`);}async function
|
|
190
|
-
Bundle: ${
|
|
191
|
-
`);for(let o of t)process.stdout.write(`${
|
|
187
|
+
[y/N] `))return le.debug(`[${e}] Installation cancelled by user`),r.silent||C(`${t}Skipped ${e} (cancelled).`),{name:e,success:true};r.silent||(o=Aa({text:`${t}Installing ${e}...`}).start());}let s=o?BS(t,o):void 0;try{let i=await ku(e,r.marketplaceSource,s?.callbacks,r.scope);if(s?.stopSpinner(),i.exitCode!==0){let a=i.stderr||"Command failed";return r.silent?We({status:"error",plugin:e,message:a}):P(`${t}Failed to install "${e}": ${a}`),{name:e,success:!1,error:a}}return r.silent?Oe({status:"success",plugin:e,command:i.command,duration_ms:i.duration_ms}):ne(`${t}${e} installed successfully (via proxy)`),{name:e,success:!0,duration_ms:i.duration_ms}}catch(i){s?.stopSpinner();let a=Q(i);return r.silent?We({status:"error",plugin:e,message:a}):P(`${t}Failed to install "${e}": ${a}`),{name:e,success:false,error:a}}}async function FS(e,t,r){let n=r.silent?void 0:Aa({text:`${t}Installing ${e}...`}).start();if(Jr(e))return US(e,t,r,n);try{let o=await Ce(e,r);return n?.stop(),r.silent?Oe({status:"success",plugin:e,version:o.version,duration_ms:o.duration_ms}):ne(`${t}${e} v${o.version} installed successfully`),{name:e,success:!0,version:o.version,duration_ms:o.duration_ms}}catch(o){if(n?.stop(),o instanceof Ue)return r.silent?Oe({status:"already_installed",plugin:e,message:o.message}):C(`${t}${o.message}`),{name:e,success:true};let s=Q(o);return r.silent?We({status:"error",plugin:e,message:s}):P(`${t}Failed to install "${e}": ${s}`),{name:e,success:false,error:s}}}function jS(e){let t=e.filter(n=>n.success).length,r=e.filter(n=>!n.success).length;C(`
|
|
188
|
+
Installation summary: ${t} succeeded, ${r} failed`);}async function Rs(e,t={}){if(!await ye())return 1;let r=[];for(let n=0;n<e.length;n++){let o=e.length>1?`[${n+1}/${e.length}] `:"",s=await FS(e[n],o,t);r.push(s);}return e.length>1&&(t.silent?Oe({status:"summary",succeeded:r.filter(n=>n.success).length,failed:r.filter(n=>!n.success).length,results:r.map(n=>({plugin:n.name,success:n.success,...n.error?{error:n.error}:{}}))}):jS(r)),r.some(n=>!n.success)?1:0}async function sp(e,t){if(!await ye())return 1;if(le.debug(`[${e}] Looking up installed plugin`),!t.force){let r=Ls(e,t.scope);if(!r)return le.error(`[${e}] Plugin is not installed`),P(`Plugin "${e}" is not installed`),1;let n=h(r.name),o=r.version?h(r.version):void 0,s=t.scope?` (${t.scope})`:"";if(!await xt(`Remove ${n} ${o?`v${o}`:"(n/a)"}${s}? [y/N] `))return le.debug(`[${e}] Uninstall cancelled by user`),C("Operation cancelled."),0}try{return le.debug(`[${e}] Uninstalling plugin${t.scope?` (scope: ${t.scope})`:""}`),await Wo(e,t.scope),le.info(`[${e}] Uninstalled successfully`),ne("Plugin removed successfully"),0}catch(r){return le.error(`[${e}] Failed to uninstall: ${Q(r)}`),P(Q(r)),1}}async function ip(e,t={}){if(!await ye())return 1;le.debug(`[${e}] Looking up installed plugin`);let r=Ls(e,t.scope);if(!r)return le.error(`[${e}] Plugin is not installed`),P(`Plugin "${e}" is not installed`),1;if(r.status==="enabled")return le.debug(`[${e}] Already enabled, skipping`),C(`${r.name} is already enabled`),0;try{return le.debug(`[${e}] Enabling plugin (current status: ${r.status})`),await On(e,"enabled",t.scope),le.info(`[${e}] Enabled successfully`),ne(`${r.name} enabled successfully`),0}catch(n){return le.error(`[${e}] Failed to enable: ${Q(n)}`),P(Q(n)),1}}async function ap(e,t={}){if(!await ye())return 1;le.debug(`[${e}] Looking up installed plugin`);let r=Ls(e,t.scope);if(!r)return le.error(`[${e}] Plugin is not installed`),P(`Plugin "${e}" is not installed`),1;if(r.status==="disabled")return le.debug(`[${e}] Already disabled, skipping`),C(`${r.name} is already disabled`),0;try{return le.debug(`[${e}] Disabling plugin (current status: ${r.status})`),await On(e,"disabled",t.scope),le.info(`[${e}] Disabled successfully`),ne(`${r.name} disabled successfully`),0}catch(n){return le.error(`[${e}] Failed to disable: ${Q(n)}`),P(Q(n)),1}}async function lp(e,t,r){r.silent||C(`${t}Updating ${e}...`);try{let n=await cs(e,r);return r.silent?Oe({status:"updated",plugin:n.name,previousVersion:n.previousVersion,newVersion:n.newVersion,duration_ms:n.duration_ms}):ne(`${t}${n.name} v${n.previousVersion} \u2192 v${n.newVersion}`),{name:e,success:!0}}catch(n){if(n instanceof er)return r.silent?Oe({status:"up_to_date",plugin:e,message:n.message}):C(`${t}${n.message}`),{name:e,success:true,skipped:true};let o=Q(n);return r.silent?We({status:"error",plugin:e,message:o}):P(`${t}Failed to update ${e}: ${o}`),{name:e,success:false,error:o}}}function KS(e){let t=e.filter(o=>o.success&&!o.skipped).length,r=e.filter(o=>o.skipped).length,n=e.filter(o=>!o.success).length;C(`
|
|
189
|
+
Update summary: ${t} updated, ${r} already up to date, ${n} failed`);}async function VS(e,t,r){try{let n=await Xr(e);Ae(t,n.version,r.force)?C(`Would update ${e}: v${t} \u2192 v${n.version}`):C(`${e} is already up to date (v${t})`);}catch(n){return P(Q(n)),1}return 0}function HS(e){return new Map(e.filter(t=>!!t.version).map(t=>[t.name,t.version]))}function JS(e,t,r){let n=t.get(e.name);return n?e.version&&Ae(e.version,n,r)?(C(`Would update ${e.name}: v${e.version} \u2192 v${n}`),true):(C(`${e.name} is already up to date (${e.version?`v${e.version}`:"n/a"})`),false):(C(`Skipping ${e.name}: not found in catalog`),false)}async function GS(e,t){try{let r=await tr(),n=HS(r),o=0;for(let s of e)JS(s,n,t.force)&&o++;o===0&&C("All plugins are up to date");}catch(r){return P(Q(r)),1}return 0}async function WS(e,t){let r=[];for(let n=0;n<e.length;n++){let o=`[${n+1}/${e.length}] `,s=await lp(e[n].name,o,t);r.push(s);}return t.silent?Oe({status:"summary",updated:r.filter(n=>n.success&&!n.skipped).length,upToDate:r.filter(n=>n.skipped).length,failed:r.filter(n=>!n.success).length,results:r.map(n=>({plugin:n.name,success:n.success,...n.skipped?{skipped:true}:{},...n.error?{error:n.error}:{}}))}):KS(r),r.some(n=>!n.success)?1:0}async function cp(e,t={}){if(!await ye())return 1;if(e){let o=Ls(e,t.scope);return o?t.dryRun?VS(e,o.version??"",t):(await lp(e,"",t)).success?0:1:(t.silent?We({status:"error",plugin:e,message:`Plugin "${e}" is not installed`}):P(`Plugin "${e}" is not installed`),1)}let n=se().filter(o=>o.marketplace===re);return n.length===0?(t.silent?Oe({status:"empty",message:"No plugins installed"}):C("No plugins installed"),0):t.dryRun?GS(n,t):WS(n,t)}var ro=I("cli:bundle");function zS(e){let t=h(e.name??e.flowId),r=h(e.type??"unknown");return e.available?` \u2713 ${t} (${r})`:` \u2717 ${t} (${r}) \u2014 unavailable`}function XS(e,t){let r=t.filter(o=>o.available).length,n=t.length-r;process.stdout.write(`
|
|
190
|
+
Bundle: ${h(e)} (${t.length} artifacts)
|
|
191
|
+
`);for(let o of t)process.stdout.write(`${zS(o)}
|
|
192
192
|
`);process.stdout.write(`
|
|
193
193
|
${r} available for installation`),n>0&&process.stdout.write(` | ${n} unavailable`),process.stdout.write(`
|
|
194
194
|
|
|
195
|
-
`);}async function
|
|
195
|
+
`);}async function up(e){if(!e.trim())return P("Bundle name cannot be empty."),1;if(!await ye())return 1;ro.debug(`Fetching bundle "${e}"`);let r;try{r=await fs(e);}catch(a){return a instanceof sn||a instanceof Xn?(P(a.message),1):(P(`Failed to fetch bundle: ${a instanceof Error?a.message:String(a)}`),1)}let n=r.artifact.artifacts,o=n.filter(a=>a.available);if(ro.debug(`Bundle "${r.title}" \u2014 ${n.length} artifact(s), ${o.length} available`),XS(r.title,n),o.length===0)return P("No artifacts available for installation in this bundle."),1;if(!await xt(`Install ${o.length} artifact(s)? [Y/n] `))return ro.debug("Installation cancelled by user"),0;ro.debug(`Starting installation of ${o.length} artifact(s)`);let i=await ss(r,{onProgress:({index:a,total:l,artifact:u,success:c,error:d})=>{let p=h(u.name??u.flowId),m=h(u.type??"unknown"),f=c?"\u2713":`\u2717 (${h(d??"failed")})`;a===1&&process.stdout.write(`
|
|
196
196
|
`),process.stdout.write(`[${a}/${l}] Installing ${p} (${m})... ${f}
|
|
197
197
|
`),a===l&&process.stdout.write(`
|
|
198
|
-
`);}});if(
|
|
198
|
+
`);}});if(ro.debug(`Installation complete \u2014 ${i.installed} installed, ${i.failed} failed, ${i.skipped} skipped`),i.installed>0&&ne(`${i.installed} installed successfully`),i.failed>0){let a=i.failures.map(l=>l.name).join(", ");P(`${i.failed} failed: ${h(a)}`);}if(i.skipped>0){let a=n.filter(l=>!l.available).map(l=>h(l.name??l.flowId)).join(", ");C(`${i.skipped} unavailable: ${a}`);}return 0}var dp=I("marketplace");function YS(e){return `claude plugin marketplace add ${e}`}async function pp(e,t){if(!await ye())return 1;let r;try{r=Ho(e);}catch(s){let i=Q(s);return t.silent?We({status:"error",source:e,message:i}):P(i),1}dp.debug(`[marketplace] Adding marketplace source: ${r}`);let n=YS(r);if(!t.force){let s=h(r),i=h(n);if(!await xt(`Add marketplace "${s}"?
|
|
199
199
|
This will run: ${i}
|
|
200
|
-
[y/N] `))return
|
|
200
|
+
[y/N] `))return dp.debug("[marketplace] Operation cancelled by user"),C("Operation cancelled."),0}let o=t.silent?void 0:Aa({text:`Adding marketplace "${h(r)}"...`}).start();try{let s=await xe(n);return o?.stop(),s.exitCode!==0?(t.silent?We({status:"error",source:r,exitCode:s.exitCode,message:s.stderr||"Command failed"}):(P(`Failed to add marketplace "${r}": ${s.stderr||"Command failed"}`),t.verbose&&s.stdout&&C(`stdout: ${s.stdout}`)),1):(t.silent?Oe({status:"success",source:r,command:n,duration_ms:s.duration_ms}):(ne(`Marketplace "${r}" added successfully`),t.verbose&&s.stdout&&C(s.stdout)),0)}catch(s){o?.stop();let i=Q(s);return t.silent?We({status:"error",source:r,message:i}):P(`Failed to add marketplace "${r}": ${i}`),1}}async function tw(){return await oe()?{passed:true,message:"Credentials configured"}:{passed:false,message:"Credentials not configured \u2014 Run `flow auth login`"}}async function rw(){let e=Date.now();try{await tr();let t=Date.now()-e;return {passed:!0,message:`Prompt Manager accessible (${t}ms)`,latency:t}}catch(t){return t instanceof Error&&t.name==="TimeoutError"?{passed:false,message:"Timeout after 5s \u2014 check your connection"}:{passed:false,message:`Connection error: ${t instanceof Error?t.message:"Unknown"}`}}}async function nw(){return await qt()?{passed:true,message:"Token is valid"}:{passed:false,message:"Token expired \u2014 run `flow auth login` to re-authenticate"}}function ow(){let e=join(homedir(),".claude","settings.json");return existsSync(e)?{passed:true,message:"Claude Code detected"}:{passed:false,message:"Claude Code not detected"}}async function mp(){process.stdout.write(`
|
|
201
201
|
`+R.bold(` FlowSetup CLI Diagnostics
|
|
202
202
|
|
|
203
|
-
`));let e=[{name:"Credentials",fn:
|
|
203
|
+
`));let e=[{name:"Credentials",fn:tw},{name:"Prompt Manager",fn:rw},{name:"Valid Token",fn:nw},{name:"Claude Code",fn:ow}],t=true;for(let r of e){let n=await r.fn(),o="",s=R.green;n.passed?o=R.green("[OK] "):(o=R.red("[FAIL]"),s=R.red,t=false);let i=` ${o} ${s(r.name.padEnd(18))} ${h(n.message)}`;process.stdout.write(i+`
|
|
204
204
|
`);}return process.stdout.write(`
|
|
205
205
|
`),t?(process.stdout.write(R.green(` \u2713 All checks passed!
|
|
206
206
|
|
|
207
207
|
`)),0):(process.stdout.write(R.red(` \u2717 Some checks failed \u2014 verify your configuration
|
|
208
208
|
|
|
209
|
-
`)),1)}var
|
|
210
|
-
`,"utf-8");}async function
|
|
211
|
-
`);for(let a of o){let l=
|
|
209
|
+
`)),1)}var aw=["github.com","www.github.com"],lw=/^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.@-]+)(\/.*)?$/,cw=/^([^@]+)@(.+)$/;function uw(e){return !!(isAbsolute(e)||e==="."||e===".."||e.startsWith("./")||e.startsWith("../")||e.startsWith(".\\")||e.startsWith("..\\")||/^[a-zA-Z]:[/\\]/.test(e))}function $a(e){let t=e.replace(/\\/g,"/");t=t.replace(/^\/+/,"").replace(/\/+$/,"");let r=t.split("/").filter(Boolean);for(let n of r)if(n==="..")throw new Error(`Invalid subpath: "${e}" contains path traversal ("..").`);return r.join("/")}function dw(e){let t=e.pathname.split("/").filter(Boolean);if(t.length<2)throw new Error(`Invalid GitHub URL: expected at least owner/repo in "${e.href}"`);let r=t[0],n=t[1];n.endsWith(".git")&&(n=n.slice(0,-4));let o={type:"github",url:`https://github.com/${r}/${n}.git`};if(t.length>=3&&(t[2]==="tree"||t[2]==="blob")){if(t.length>=4&&(o.ref=t[3]),t.length>=5){let s=t.slice(4).join("/");o.subpath=$a(s);}}else if(t.length>2){let s=t.slice(2).join("/");o.subpath=$a(s);}return e.hash&&e.hash.length>1&&(o.ref=decodeURIComponent(e.hash.slice(1))),o}function _s(e){let t=e.trim();if(!t)throw new Error("Skill source cannot be empty.");if(uw(t)){let r=resolve(t);return {type:"local",url:r,localPath:r}}try{let r=new URL(t);if((r.protocol==="https:"||r.protocol==="http:")&&aw.includes(r.hostname))return dw(r);if(r.protocol==="https:"||r.protocol==="http:"){let n={type:"git",url:t};return r.hash&&r.hash.length>1&&(n.ref=decodeURIComponent(r.hash.slice(1)),n.url=t.replace(r.hash,"")),n}if(r.protocol==="git:"){let n={type:"git",url:t};return r.hash&&r.hash.length>1&&(n.ref=decodeURIComponent(r.hash.slice(1)),n.url=t.replace(r.hash,"")),n}}catch{}if(t.startsWith("git@")||t.includes(":")&&t.includes(".git")){let r=t,n,o=t.indexOf("#");o!==-1&&(n=t.slice(o+1),r=t.slice(0,o));let s={type:"git",url:r};return n&&(s.ref=n),s}{let r=t,n,o=r.indexOf("#");o!==-1&&(n=r.slice(o+1),r=r.slice(0,o));let s=r.match(lw);if(s){let i=s[1],a=s[2],l=s[3],u,c=a.match(cw);c&&(a=c[1],u=c[2]),a.endsWith(".git")&&(a=a.slice(0,-4));let d={type:"github",url:`https://github.com/${i}/${a}.git`};if(n&&(d.ref=n),u&&(d.skillFilter=u),l){let p=l.replace(/^\//,"");p&&(d.subpath=$a(p));}return d}}return {type:"git",url:t}}function Ds(e){if(e.type!=="github")return null;try{let r=new URL(e.url).pathname.split("/").filter(Boolean);if(r.length<2)return null;let n=r[1];return n.endsWith(".git")&&(n=n.slice(0,-4)),`${r[0]}/${n}`}catch{return null}}function fp(e){let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);return t?{data:parse(t[1])??{},content:t[2]??""}:{data:{},content:e}}var La=new Set(["node_modules",".git","dist","build","__pycache__"]);function hp(e,t){let r=normalize(resolve(e)),n=normalize(resolve(t));return n.startsWith(r+sep)||n===r}function yw(e,t){let r=normalize(resolve(e)),n=normalize(resolve(join(e,t)));return n.startsWith(r+sep)||n===r}async function Ma(e){try{let t=join(e,"SKILL.md");return (await stat(t)).isFile()}catch{return false}}async function no(e){try{let t=await readFile(e,"utf-8"),{data:r}=fp(t);return typeof r.name!="string"||typeof r.description!="string"?null:{name:r.name,description:r.description,path:dirname(e),rawContent:t,metadata:r.metadata}}catch{return null}}async function Sp(e,t=0,r=5){if(t>r)return [];try{let[n,o]=await Promise.all([Ma(e),readdir(e,{withFileTypes:!0}).catch(()=>[])]),s=n?[e]:[],i=await Promise.all(o.filter(a=>a.isDirectory()&&!La.has(a.name)).map(a=>Sp(join(e,a.name),t+1,r)));return [...s,...i.flat()]}catch{return []}}async function Bs(e,t){let r=[],n=new Set;if(t&&!yw(e,t))throw new Error(`Invalid subpath: "${t}" resolves outside the repository directory.`);let o=t?join(e,t):e;if(await Ma(o)){let i=await no(join(o,"SKILL.md"));if(i)return r.push(i),n.add(i.name),r}let s=[o,join(o,"skills"),join(o,".claude/skills"),join(o,".agents/skills")];for(let i of s)try{let a=await readdir(i,{withFileTypes:!0});for(let l of a){if(!l.isDirectory())continue;let u=join(i,l.name);if(await Ma(u)){let c=await no(join(u,"SKILL.md"));c&&!n.has(c.name)&&(r.push(c),n.add(c.name));}}}catch{}if(r.length===0){let i=await Sp(o);for(let a of i){let l=await no(join(a,"SKILL.md"));l&&!n.has(l.name)&&(r.push(l),n.add(l.name));}}return r}function wp(e,t){let r=t.map(n=>n.toLowerCase());return e.filter(n=>{let o=n.name.toLowerCase();return r.some(s=>s===o)})}var vp=1,vw={retries:5,minTimeout:50};async function bp(e,t){mkdirSync(dirname(e),{recursive:true});let r=await lg.lock(e+".lock",{realpath:false,retries:vw});try{return await t()}finally{await r();}}function xp(){return {version:vp,skills:{}}}async function Us(e){let t=wn(e);try{let r=await readFile(t,"utf-8"),n=JSON.parse(r);return !n.version||n.version<vp?xp():n}catch{return xp()}}function bw(e){let t={};for(let r of Object.keys(e).sort())t[r]=e[r];return t}async function Pp(e,t){let r=wn(t);await mkdir(dirname(r),{recursive:true});let n={version:e.version,skills:bw(e.skills)};await writeFile(r,JSON.stringify(n,null,2)+`
|
|
210
|
+
`,"utf-8");}async function Ep(e,t,r){let n=wn(r);await bp(n,async()=>{let o=await Us(r),s=new Date().toISOString(),i=o.skills[e];o.skills[e]={...t,installedAt:i?.installedAt??s,updatedAt:s},await Pp(o,r);});}async function Cp(e,t){let r=wn(t);await bp(r,async()=>{let n=await Us(t);e in n.skills&&(delete n.skills[e],await Pp(n,t));});}var Tp=I("skillInstaller");async function $w(e,t,r,n){try{await b(v.CLI_TOOL_INSTALLED,{tool_id:e,tool_type:"skill",source:"external",scope:t,version:r,duration_ms:n,interface:H().interfaceType});}catch(o){Tp.warn(`Failed to send skill install metrics: ${String(o)}`);}}async function Mw(e,t){try{await b(v.CLI_TOOL_INSTALL_FAILED,{tool_id:e,tool_type:"skill",source:"external",error_code:t instanceof Error?t.name:"UNKNOWN",error_message:(t instanceof Error?t.message:String(t)).slice(0,500),interface:H().interfaceType});}catch(r){Tp.warn(`Failed to send skill install-failed metrics: ${String(r)}`);}}async function Lw(e,t){await cp$1(e,t,{recursive:true,dereference:true,filter:r=>!La.has(basename(r))});}async function Rw(e,t,r){let n=et(e.name),o=pr(t),s=join(o,n);if(!hp(o,s))return {skill:e.name,success:false,path:s,error:`Unsafe install path: "${s}" escapes skills directory`};try{await rm(s,{recursive:!0,force:!0}),await mkdir(s,{recursive:!0}),await Lw(e.path,s);let a=Ds(r)??r.url;return await Ep(n,{source:a,sourceType:r.type,sourceUrl:r.url,ref:r.ref,skillPath:r.subpath},t),{skill:e.name,success:!0,path:s}}catch(i){return {skill:e.name,success:false,path:s,error:i instanceof Error?i.message:String(i)}}}async function kp(e,t){let r=_s(e),n;try{let o;if(r.type==="local"){if(!r.localPath||!existsSync(r.localPath))return {source:e,results:[],discovered:0,installed:0,failed:0};o=r.localPath;}else n=await It(r.url,r.ref),o=n;let s=await Bs(o,r.subpath),i=[...t.skillFilter??[]];r.skillFilter&&i.push(r.skillFilter);let a=i.length>0?wp(s,i):s,l=[],u=r.ref??"latest";for(let c of a){let d=Date.now(),p=await Rw(c,t.scope,r);l.push(p);let m=Date.now()-d;p.success?await $w(c.name,t.scope,u,m):await Mw(c.name,new Error(p.error??"Unknown error"));}return {source:e,results:l,discovered:s.length,installed:l.filter(c=>c.success).length,failed:l.filter(c=>!c.success).length}}finally{n&&await vt(n).catch(()=>{});}}var Bw=I("skills");async function Uw(e){try{await b(v.CLI_TOOL_UNINSTALLED,{tool_id:e,tool_type:"skill",source:"external",interface:H().interfaceType});}catch(t){Bw.warn(`Failed to send skill uninstall metrics: ${String(t)}`);}}async function Fw(e){let t=createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(`${h(e)} (y/N) `,n=>{t.close(),r(n.trim().toLowerCase()==="y");});})}async function jw(e){let t=_s(e),r;try{let n;if(t.type==="local"){if(!t.localPath)return P("Invalid local path."),1;n=t.localPath;}else C(`Fetching skills from ${h(e)}...`),r=await It(t.url,t.ref),n=r;let o=await Bs(n,t.subpath);if(o.length===0)return C("No skills found in this source."),0;let i=Ds(t)??h(e);C(`Found ${o.length} skill(s) in ${i}:
|
|
211
|
+
`);for(let a of o){let l=h(a.name),u=h(a.description);process.stdout.write(` ${R.bold(l)} ${R.dim(u)}
|
|
212
212
|
`);}return process.stdout.write(`
|
|
213
|
-
`),0}catch(n){return n instanceof
|
|
214
|
-
`);let t=e.source;e.installed>0&&
|
|
215
|
-
`);for(let s of r){let i=n.skills[
|
|
213
|
+
`),0}catch(n){return n instanceof sr?P(n.message):P(n instanceof Error?n.message:String(n)),1}finally{r&&await vt(r).catch(()=>{});}}function Kw(e){for(let r of e.results){let n=h(r.skill);if(r.success){let o=relative(process.cwd(),r.path);ne(`${n} installed ${R.dim(`\u2192 ${o}/`)}`);}else P(`${n}: ${h(r.error??"unknown error")}`);}process.stdout.write(`
|
|
214
|
+
`);let t=e.source;e.installed>0&&C(`Installed ${e.installed} of ${e.discovered} skill(s) from ${h(t)}`),e.failed>0&&P(`${e.failed} skill(s) failed to install`),e.results.length===0&&e.discovered===0?C("No skills found in this source."):e.results.length===0&&e.discovered>0&&C(`Found ${e.discovered} skill(s) but none matched the filter. Use --list to see available skills.`);}async function $p(e,t){if(t.list)return jw(e);let r=t.global?"global":"project";try{let n=await kp(e,{scope:r,skillFilter:t.skill,yes:t.yes});return Kw(n),n.failed>0?1:0}catch(n){return n instanceof sr?P(n.message):P(n instanceof Error?n.message:String(n)),1}}async function Mp(e){let t=pr(e),r=[];try{let n=await readdir(t,{withFileTypes:!0});for(let o of n){if(!o.isDirectory())continue;let s=join(t,o.name),i=join(s,"SKILL.md");try{if(!(await stat(i)).isFile())continue}catch{continue}let a=await no(i);a?r.push({name:a.name,description:a.description,path:s}):r.push({name:o.name,description:"(no metadata)",path:s});}}catch{}return r}async function Lp(e){let t=e.global?"global":"project",r=await Mp(t),n=await Us(t);if(e.json){let s=r.map(i=>({name:i.name,description:i.description,path:i.path,source:n.skills[et(i.name)]?.source}));return Ur(s),0}if(r.length===0)return C(`No skills installed (${t==="global"?"global":"project"} scope).`),0;C(`${t==="global"?"Global":"Project"} skills (${r.length}):
|
|
215
|
+
`);for(let s of r){let i=n.skills[et(s.name)]?.source,a=h(s.name),l=h(s.description),u=l.length>80?l.slice(0,77)+"...":l,c=i?R.dim(` (${i})`):"";process.stdout.write(` ${R.bold(a)}${c}
|
|
216
216
|
`),process.stdout.write(` ${R.dim(u)}
|
|
217
217
|
|
|
218
|
-
`);}return 0}async function
|
|
218
|
+
`);}return 0}async function Rp(e,t){let r=t.global?"global":"project";if(!e){let i=await Mp(r);if(i.length===0)return C("No skills installed."),0;C("Installed skills:");for(let a of i)process.stdout.write(` - ${h(a.name)}
|
|
219
219
|
`);return process.stdout.write(`
|
|
220
|
-
`),
|
|
221
|
-
Import summary: 0 installed, ${o.length} failed`);for(let a of o)
|
|
222
|
-
Import summary: ${i} installed, ${o.length} failed`);for(let a of o)
|
|
220
|
+
`),C("Specify a skill name to remove: flow skills remove <name>"),1}let n=et(e),o=pr(r),s=join(o,n);try{await stat(s);}catch{return P(`Skill "${h(e)}" is not installed.`),1}if(!t.force&&!await Fw(`Remove skill "${h(n)}"?`))return C("Cancelled."),0;try{return await rm(s,{recursive:!0,force:!0}),await Cp(n,r),await Uw(n),ne(`Skill "${h(n)}" removed.`),0}catch(i){return P(`Failed to remove skill: ${i instanceof Error?i.message:String(i)}`),1}}var Fs=I("transfer"),_a=1;function Vw(e){return e.marketplace&&e.marketplace!==re?`${e.name}@${e.marketplace}`:e.name}function Hw(e,t){let r=e.filter(o=>t.has(o.name)),n=e.filter(o=>!t.has(o.name));r.length>0&&C(`Already installed (${r.length}): ${r.map(o=>o.name).join(", ")}`),C(`To install (${n.length}): ${n.length>0?n.map(o=>o.name).join(", "):"none"}`);}function Op(e){let t=ge__default.resolve(e.output);try{let r=se(),n={version:_a,exportedAt:new Date().toISOString(),plugins:r.map(o=>({name:o.name,marketplace:o.marketplace,scope:o.scope,...o.type!==void 0?{type:o.type}:{}}))};return he__default.writeFileSync(t,JSON.stringify(n,null,2),"utf-8"),ne(`Exported ${r.length} plugin(s) to ${t}`),0}catch(r){let n=Q(r);return Fs.error(`Export failed: ${n}`),P(`Failed to export plugins: ${n}`),1}}async function Np(e,t={}){if(!await ye())return 1;let r;try{let a=he__default.readFileSync(ge__default.resolve(e),"utf-8");r=JSON.parse(a);}catch(a){return P(`Failed to read import file "${e}": ${Q(a)}`),1}if(r.version!==_a)return P(`Unsupported export format version ${r.version??"(none)"} \u2014 expected ${_a}`),1;if(!Array.isArray(r.plugins))return P('Invalid export file format: missing or invalid "plugins" array'),1;if(r.plugins.length===0)return C("No plugins to import"),0;let n=[],o=[],s=0;for(let[a,l]of r.plugins.entries())if(!l?.name||typeof l.name!="string"){let u=`entry[${a}]`;Fs.warn(`Skipping ${u}: missing or invalid name`),o.push({name:u,error:"missing or invalid name"});}else l.type==="mcp"?(Fs.debug(`[${l.name}] Skipping MCP entry`),s++):n.push(l);if(s>0&&C(`Skipping ${s} MCP(s) \u2014 use 'flow mcp add' to install them manually`),t.diff||t.dryRun){let a=new Set(se().map(l=>l.name));Hw(n,a);}if(t.dryRun)return C("Dry-run mode: no plugins were installed"),0;if(n.length===0){C(`
|
|
221
|
+
Import summary: 0 installed, ${o.length} failed`);for(let a of o)P(` ${a.name}: ${a.error}`);return o.length>0?1:0}C(`Importing ${n.length} plugin(s)...`);let i=0;for(let a of n){let l=t.scope??a.scope??"user",u=Vw(a);Fs.debug(`[${a.name}] Installing as "${u}" in scope "${l}"`),await Rs([u],{scope:l,force:t.force})===0?i++:o.push({name:a.name,error:"installation failed"});}C(`
|
|
222
|
+
Import summary: ${i} installed, ${o.length} failed`);for(let a of o)P(` ${a.name}: ${a.error}`);return o.length>0?1:0}function B(e){process.exitCode=e,setTimeout(()=>process.exit(e),100).unref();}var Gw=I("moduleProxy");function Ww(e){if(!process.stdin.isTTY)return Promise.resolve(false);let t=ji.createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{t.question(h(e),n=>{t.close(),r(!["n","no"].includes(n.toLowerCase().trim()));});})}async function Bp(e,t){let r=Date.now(),o=spawnSync(e.binaryName,t,{stdio:"inherit",env:process.env}).status??1;await b(v.CLI_MODULE_PROXY_EXECUTED,{module_alias:e.alias,exit_code:o,duration_ms:Date.now()-r,subcommand:t[0]??null}).catch(s=>{Gw.warn(`Failed to emit proxy executed event: ${String(s)}`);}),B(o);}async function Fp(e,t){let r=te.find(o=>o.alias===e);if(!r){P(`Unknown module alias: '${e}'`),B(1);return}if(!await At(r.binaryName)){P(`Module '${e}' (${r.binaryName}) is not installed.`);let o=r.platforms[process.platform];if(!o||o.status!=="supported"){await b(v.CLI_MODULE_NOT_FOUND,{module_alias:e,action_taken:"install_not_supported"}).catch(()=>{}),B(1);return}let s=(await Promise.all(o.strategies.map(async a=>{try{return await Ht(a.type).isAvailable()?a.type:null}catch{return null}}))).find(a=>a!==null)??null;if(!s){P(`No supported installation method available for '${e}' on this platform.`),B(1);return}if(await Ww("Would you like to install it now? [Y/n] ")){await b(v.CLI_MODULE_NOT_FOUND,{module_alias:e,action_taken:"install_accepted"}).catch(()=>{});let a=await dn(r,"inline",s);if(!a.success){P(`Failed to install '${e}': ${a.error?.message??"unknown error"}`),B(1);return}await Bp(r,t);}else C(`To install manually, run: flow modules install ${e}`),await b(v.CLI_MODULE_NOT_FOUND,{module_alias:e,action_taken:"install_declined"}).catch(()=>{}),B(1);return}await Bp(r,t);}var Yw=promisify(execFile);async function Zw(e){try{if(e.versionCheck.type==="npm-registry"){let{stdout:n}=await Yw(Vt(),["view",e.versionCheck.package,"version"],{timeout:5e3,shell:process.platform==="win32"});return String(n).trim()||null}let t=new AbortController,r=setTimeout(()=>t.abort(),5e3);try{let n={"User-Agent":`flow-plugins-cli/${ae}`,Accept:"application/vnd.github+json"};process.env.GITHUB_TOKEN&&(n.Authorization=`Bearer ${process.env.GITHUB_TOKEN}`);let o=await fetch(`https://api.github.com/repos/${e.versionCheck.repo}/releases/latest`,{signal:t.signal,headers:n});return o.ok?(await o.json()).tag_name?.replace(/^v/,"")??null:null}finally{clearTimeout(r);}}catch{return null}}function Qw(e,t,r,n){return n?.status==="experimental"?"experimental":!n||n.status!=="supported"||!e?"not_installed":t&&r&&Ae(t,r)?"outdated":"installed"}async function Da(){let e=await Promise.all(te.map(async t=>{let[r,n]=await Promise.all([At(t.binaryName),Zw(t)]),s=ot(t.alias)?.installedVersion??null,i=t.platforms[process.platform],a=Qw(r,s,n,i),l=s??"\u2014";return [t.name,t.alias,l,a,process.platform]}));return Br(["Name","Alias","Version","Status","Platform"],e),0}async function Vp(e){let t=te.find(i=>i.alias===e);if(!t)return P(`Unknown module alias: '${e}'`),1;let[r]=await pn([t]);if(r.alreadyInstalled){let i=ot(t.alias),a=i?.installedVersion?` (v${i.installedVersion})`:"";return C(`Module ${t.name} already installed${a}. Use: flow modules update ${e}`),0}if(r.availableStrategies.length===0){let i=t.platforms[process.platform],a=t.docs?` See: ${t.docs}`:"";return !i||i.status!=="supported"?P(`Module ${t.name} is not supported on ${process.platform}.${a}`):P(`No installation method available for ${t.name} on ${process.platform}.${a}`),1}let n=r.availableStrategies[0],o=Aa({text:`Installing ${t.name}...`}).start(),s;try{s=await dn(t,"on_demand",n);}finally{o.stop();}return s.success?(ne(`${t.name} v${s.version??"unknown"} installed`),s.pendingInteractiveSetup&&spawnSync(s.pendingInteractiveSetup[0],s.pendingInteractiveSetup.slice(1),{stdio:"inherit"}),0):(P(s.error?.message??"Installation failed"),1)}async function jp(e,t){let r=Aa({text:`Updating ${e.name}...`}).start(),n;try{n=await Ts(e,"command");}catch(o){return r.error(`${e.name}: ${o instanceof Error?o.message:String(o)}`),"error"}if(n.success){let o=n.version??"unknown";return o===t?(r.success(`${e.name}: already up to date (v${t})`),"up_to_date"):(r.success(`${e.name}: v${t} \u2192 v${o}`),"success")}return r.error(`${e.name}: ${n.error?.message??"Update failed"}`),"error"}async function Hp(e){if(e!==null){let n=te.find(i=>i.alias===e);if(!n)return P(`Unknown module alias: '${e}'`),1;let o=ot(n.alias);return o?.installMethod?await jp(n,o.installedVersion??"unknown")==="error"?1:0:(P(`Module '${e}' not installed. Run: flow modules install ${e}`),1)}let t=$r().filter(n=>n.installMethod!==null);if(t.length===0)return C("No installed modules to update."),0;let r=0;for(let n of t){let o=te.find(i=>i.alias===n.alias);if(!o)continue;await jp(o,n.installedVersion??"unknown")==="error"&&(r=1);}return r}function Jp(e){let t=new Command;t.enablePositionalOptions(),t.name("flow").description("FlowSetup CLI \u2014 Manage Flow plugins in your Claude Code").version(`@ciandt-flow/cli v${ae}`,"-V, --version","Display the CLI version").addHelpText("after",`
|
|
223
223
|
Without arguments, opens the interactive interface (TUI).
|
|
224
224
|
Use 'flow <command> --help' for details on each command.`).action(async()=>{await e();});let r=new Command("setup").description("Configure the CLI by detecting Claude Code credentials");r.command("init").description("Initialize the Flow CLI configuration").addHelpText("after",`
|
|
225
225
|
Examples:
|
|
226
|
-
$ flow setup init`).action(async()=>{let c=await
|
|
226
|
+
$ flow setup init`).action(async()=>{let c=await ka();B(c);}),t.addCommand(r);let n=new Command("plugin").description("Manage plugins from the Findr catalog installed in your Claude Code");n.command("list").description("List available or installed plugins").option("--available","show full catalog with installation status",false).option("--outdated","show only plugins with updates available",false).option("--json","output as JSON",false).addHelpText("after",`
|
|
227
227
|
Examples:
|
|
228
228
|
$ flow plugin list
|
|
229
229
|
$ flow plugin list --available
|
|
230
230
|
$ flow plugin list --outdated
|
|
231
|
-
$ flow plugin list --json`).action(async c=>{let d=await
|
|
231
|
+
$ flow plugin list --json`).action(async c=>{let d=await op(c);B(d);}),n.command("install").description("Install one or more plugins from the Findr catalog into Claude Code").argument("<name...>","Name(s) of the plugin(s) to install (space-separated)").option("--force","Reinstall even if the version is already installed").option("--verbose","Display each step of the installation process").option("--silent","Output in JSON only").option("--marketplace-source <source>","GitHub source (owner/repo) for marketplace auto-add when installing external plugins").addOption(new Option("--scope <scope>","Scope to install into: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
232
232
|
Examples:
|
|
233
233
|
$ flow plugin install flow-adr-writer
|
|
234
234
|
$ flow plugin install flow-adr-writer --scope project
|
|
@@ -236,11 +236,11 @@ Examples:
|
|
|
236
236
|
$ flow plugin install flow-adr-writer --force
|
|
237
237
|
$ flow plugin install flow-adr-writer --silent
|
|
238
238
|
$ flow plugin install superpowers@claude-plugins-official
|
|
239
|
-
$ flow plugin install agent-sdk-dev@claude-code-plugins --marketplace-source anthropics/claude-code`).action(async(c,d)=>{let p=c.filter(f=>f.trim());if(p.length===0){
|
|
239
|
+
$ flow plugin install agent-sdk-dev@claude-code-plugins --marketplace-source anthropics/claude-code`).action(async(c,d)=>{let p=c.filter(f=>f.trim());if(p.length===0){P("No valid plugin names provided"),B(1);return}De("cli",{verbose:d.verbose,silent:d.silent});let m=await Rs(p,d);B(m);}),n.command("uninstall").description("Remove an installed plugin from Claude Code").argument("<name>","Name of the plugin to remove").option("--force","Skip interactive confirmation").addOption(new Option("--scope <scope>","Scope to uninstall from: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
240
240
|
Examples:
|
|
241
241
|
$ flow plugin uninstall flow-adr-writer
|
|
242
242
|
$ flow plugin uninstall flow-adr-writer --scope project
|
|
243
|
-
$ flow plugin uninstall startup-pack-ai --force`).action(async(c,d)=>{let p=await
|
|
243
|
+
$ flow plugin uninstall startup-pack-ai --force`).action(async(c,d)=>{let p=await sp(c,d);B(p);}),n.command("update").description("Update plugins to the latest version").argument("[name]","Name of the plugin to update (omit to update all)").option("--force","Force update even if already on latest version").option("--dry-run","Show what would be updated without making changes").option("--verbose","Display each step of the update process").option("--silent","Output in JSON only").addOption(new Option("--scope <scope>","Scope to update in: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
244
244
|
Examples:
|
|
245
245
|
$ flow plugin update flow-adr-writer
|
|
246
246
|
$ flow plugin update flow-adr-writer --scope project
|
|
@@ -249,74 +249,74 @@ Examples:
|
|
|
249
249
|
$ flow plugin update flow-adr-writer --verbose
|
|
250
250
|
$ flow plugin update flow-adr-writer --silent
|
|
251
251
|
$ flow plugin update
|
|
252
|
-
$ flow plugin update --dry-run`).action(async(c,d)=>{
|
|
252
|
+
$ flow plugin update --dry-run`).action(async(c,d)=>{De("cli",{verbose:d.verbose,silent:d.silent});let p=await cp(c??null,d);B(p);}),n.command("enable").description("Enable an installed plugin").argument("<name>","Name of the plugin to enable").addOption(new Option("--scope <scope>","Scope to enable in: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
253
253
|
Examples:
|
|
254
254
|
$ flow plugin enable flow-adr-writer
|
|
255
|
-
$ flow plugin enable flow-adr-writer --scope project`).action(async(c,d)=>{
|
|
255
|
+
$ flow plugin enable flow-adr-writer --scope project`).action(async(c,d)=>{De("cli");let p=await ip(c,d);B(p);}),n.command("disable").description("Disable an installed plugin").argument("<name>","Name of the plugin to disable").addOption(new Option("--scope <scope>","Scope to disable in: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
256
256
|
Examples:
|
|
257
257
|
$ flow plugin disable flow-adr-writer
|
|
258
|
-
$ flow plugin disable flow-adr-writer --scope project`).action(async(c,d)=>{
|
|
258
|
+
$ flow plugin disable flow-adr-writer --scope project`).action(async(c,d)=>{De("cli");let p=await ap(c,d);B(p);}),n.command("export").description("Export installed plugins to a JSON file").option("--output <file>","Output file path","flow-plugins.json").addHelpText("after",`
|
|
259
259
|
Examples:
|
|
260
260
|
$ flow plugin export
|
|
261
|
-
$ flow plugin export --output my-plugins.json`).action(async c=>{let d=await
|
|
261
|
+
$ flow plugin export --output my-plugins.json`).action(async c=>{let d=await Op(c);B(d);}),n.command("import").description("Install plugins from an exported JSON file").argument("<file>","Path to the export JSON file").option("--force","Force reinstall even if already installed",false).option("--dry-run","Preview what would be installed without installing",false).option("--diff","Show which plugins are already installed vs new",false).addOption(new Option("--scope <scope>","Override scope for all plugins: user, project, or local").choices(["user","project","local"])).addHelpText("after",`
|
|
262
262
|
Examples:
|
|
263
263
|
$ flow plugin import flow-plugins.json
|
|
264
264
|
$ flow plugin import flow-plugins.json --scope user
|
|
265
265
|
$ flow plugin import flow-plugins.json --force
|
|
266
266
|
$ flow plugin import flow-plugins.json --dry-run
|
|
267
|
-
$ flow plugin import flow-plugins.json --diff`).action(async(c,d)=>{let p=await
|
|
267
|
+
$ flow plugin import flow-plugins.json --diff`).action(async(c,d)=>{let p=await Np(c,d);B(p);});let o=new Command("marketplace").description("Manage plugin marketplaces");o.command("add").description("Register a plugin marketplace in Claude Code").argument("<source>","Marketplace source (owner/repo or URL)").option("--force","Skip confirmation prompt").option("--verbose","Display command output").option("--silent","Output as JSON only").addHelpText("after",`
|
|
268
268
|
Examples:
|
|
269
269
|
$ flow plugin marketplace add anthropics/claude-code
|
|
270
270
|
$ flow plugin marketplace add https://github.com/owner/repo
|
|
271
271
|
$ flow plugin marketplace add anthropics/claude-code --force
|
|
272
|
-
$ flow plugin marketplace add anthropics/claude-code --silent`).action(async(c,d)=>{
|
|
272
|
+
$ flow plugin marketplace add anthropics/claude-code --silent`).action(async(c,d)=>{De("cli",{verbose:d.verbose,silent:d.silent});let p=await pp(c,d);B(p);}),n.addCommand(o),t.addCommand(n);let s=new Command("mcp").description("Manage MCP servers from the Findr catalog");s.command("add").description("Install an MCP server into Claude Code").argument("<name>","Name of the MCP server to install").argument("[args...]","Arguments to pass to the MCP server (URL for http, command for stdio)").addOption(new Option("--transport <type>","Transport type: http or stdio").choices(["http","stdio"]).makeOptionMandatory()).addOption(new Option("--scope <scope>","Scope to install into: user, project, or local").choices(["user","project","local"])).option("--force","Skip confirmation prompt").option("--verbose","Display command output").option("--silent","Output as JSON only").addHelpText("after",`
|
|
273
273
|
Examples:
|
|
274
274
|
$ flow mcp add notion --transport http https://mcp.notion.com/mcp
|
|
275
275
|
$ flow mcp add mcp-chrome --transport stdio uvx mcp-chrome
|
|
276
276
|
$ flow mcp add playwright-mcp --transport stdio uvx playwright-mcp --force
|
|
277
|
-
$ flow mcp add notion --transport http https://mcp.notion.com/mcp --scope project`).action(async(c,d,p)=>{
|
|
277
|
+
$ flow mcp add notion --transport http https://mcp.notion.com/mcp --scope project`).action(async(c,d,p)=>{De("cli",{verbose:p.verbose,silent:p.silent});let m=await Ru(c,d,p);B(m);}),s.command("remove").description("Remove an MCP server from Claude Code").argument("<name>","Name of the MCP server to remove").addOption(new Option("--scope <scope>","Scope to remove from: user, project, or local").choices(["user","project","local"])).option("--force","Skip confirmation prompt").option("--verbose","Display command output").option("--silent","Output as JSON only").addHelpText("after",`
|
|
278
278
|
Examples:
|
|
279
279
|
$ flow mcp remove notion
|
|
280
280
|
$ flow mcp remove notion --scope project
|
|
281
|
-
$ flow mcp remove playwright-mcp --force`).action(async(c,d)=>{
|
|
281
|
+
$ flow mcp remove playwright-mcp --force`).action(async(c,d)=>{De("cli",{verbose:d.verbose,silent:d.silent});let p=await _u(c,d);B(p);}),t.addCommand(s);let i=new Command("auth").description("Manage authentication credentials");i.command("login").description("Authenticate and save credentials locally").option("--client-id <id>","Client ID for non-interactive authentication").option("--client-secret <secret>","Client Secret for non-interactive authentication").option("--tenant <tenant>","Tenant for non-interactive authentication").option("--starter-kit <slug>","Starter kit slug for non-interactive setup").option("--verbose","Display each step of the authentication process").addHelpText("after",`
|
|
282
282
|
Examples:
|
|
283
283
|
$ flow auth login
|
|
284
284
|
$ flow auth login --client-id ID --client-secret SECRET --tenant TENANT
|
|
285
285
|
$ flow auth login --client-id ID --client-secret SECRET --tenant TENANT --starter-kit dev
|
|
286
|
-
$ flow auth login --verbose`).action(async c=>{
|
|
286
|
+
$ flow auth login --verbose`).action(async c=>{De("cli",{verbose:c.verbose});let d=await ka(c);B(d);}),i.command("logout").description("Remove locally saved credentials").option("--force","Skip interactive confirmation").addHelpText("after",`
|
|
287
287
|
Examples:
|
|
288
288
|
$ flow auth logout
|
|
289
|
-
$ flow auth logout --force`).action(async c=>{let d=await
|
|
289
|
+
$ flow auth logout --force`).action(async c=>{let d=await rp(c.force);B(d);}),i.command("status").description("Display the current authentication status").addHelpText("after",`
|
|
290
290
|
Examples:
|
|
291
|
-
$ flow auth status`).action(async()=>{let c=await
|
|
291
|
+
$ flow auth status`).action(async()=>{let c=await np();B(c);}),t.addCommand(i);let a=new Command("skills").description("Manage skills for Claude Code from GitHub repositories or local paths");a.command("add").description("Install skills from a GitHub repo or local path into Claude Code").argument("<source>","GitHub repo (owner/repo), URL, or local path").option("-g, --global","Install globally (~/.claude/skills/)").option("-s, --skill <names...>","Install only specific skills by name").option("-y, --yes","Skip confirmation prompts").option("--list","List available skills without installing").addHelpText("after",`
|
|
292
292
|
Examples:
|
|
293
293
|
$ flow skills add vercel-labs/agent-skills
|
|
294
294
|
$ flow skills add owner/repo -g
|
|
295
295
|
$ flow skills add owner/repo --skill pr-review commit
|
|
296
296
|
$ flow skills add ./local/skills -y
|
|
297
|
-
$ flow skills add owner/repo --list`).action(async(c,d)=>{let p=await
|
|
297
|
+
$ flow skills add owner/repo --list`).action(async(c,d)=>{let p=await $p(c,d);B(p);}),a.command("list").description("List installed skills").option("-g, --global","List global skills (default: project)").option("--json","Output as JSON").addHelpText("after",`
|
|
298
298
|
Examples:
|
|
299
299
|
$ flow skills list
|
|
300
300
|
$ flow skills list -g
|
|
301
|
-
$ flow skills list --json`).action(async c=>{let d=await
|
|
301
|
+
$ flow skills list --json`).action(async c=>{let d=await Lp(c);B(d);}),a.command("remove").description("Remove an installed skill").argument("[name]","Name of the skill to remove").option("-g, --global","Remove from global scope").option("--force","Skip confirmation").addHelpText("after",`
|
|
302
302
|
Examples:
|
|
303
303
|
$ flow skills remove pr-review
|
|
304
|
-
$ flow skills remove pr-review -g --force`).action(async(c,d)=>{let p=await
|
|
304
|
+
$ flow skills remove pr-review -g --force`).action(async(c,d)=>{let p=await Rp(c,d);B(p);}),t.addCommand(a);let l=new Command("bundle").description("Manage Flow bundles");l.command("install").description("Install all artifacts from a Findr bundle").argument("<name>","Bundle name to install").option("--verbose","Display each step of the installation process").addHelpText("after",`
|
|
305
305
|
Examples:
|
|
306
306
|
$ flow bundle install "My React Kit"
|
|
307
307
|
$ flow bundle install "Squad Setup Bundle"
|
|
308
|
-
$ flow bundle install "My React Kit" --verbose`).action(async(c,d)=>{
|
|
308
|
+
$ flow bundle install "My React Kit" --verbose`).action(async(c,d)=>{De("cli",{verbose:d.verbose});let p=await up(c);B(p);}),t.addCommand(l),t.command("health").description("Check the CLI configuration and connectivity").addHelpText("after",`
|
|
309
309
|
Examples:
|
|
310
|
-
$ flow health`).action(async()=>{let c=await
|
|
310
|
+
$ flow health`).action(async()=>{let c=await mp();B(c);});let u=new Command("modules").description("Manage Flow modules (binary companions for Claude Code)");u.action(async()=>{let c=await Da();B(c);}),u.command("list").description("List available and installed modules").addHelpText("after",`
|
|
311
311
|
Examples:
|
|
312
|
-
$ flow modules list`).action(async()=>{let c=await
|
|
312
|
+
$ flow modules list`).action(async()=>{let c=await Da();B(c);}),u.command("install").description("Install a module by alias").argument("<alias>","Module alias to install (e.g. metrics, dashboard)").addHelpText("after",`
|
|
313
313
|
Examples:
|
|
314
314
|
$ flow modules install metrics
|
|
315
|
-
$ flow modules install dashboard`).action(async c=>{let d=await
|
|
315
|
+
$ flow modules install dashboard`).action(async c=>{let d=await Vp(c);B(d);}),u.command("update").description("Update an installed module, or all installed modules").argument("[alias]","Module alias to update (omit to update all installed)").addHelpText("after",`
|
|
316
316
|
Examples:
|
|
317
317
|
$ flow modules update
|
|
318
|
-
$ flow modules update metrics`).action(async c=>{let d=await
|
|
318
|
+
$ flow modules update metrics`).action(async c=>{let d=await Hp(c??null);B(d);}),t.addCommand(u);for(let c of te)t.command(c.alias).description(c.description).helpOption(false).allowUnknownOption().passThroughOptions().argument("[passthrough...]","Arguments forwarded to the module binary").action(async d=>{await Fp(c.alias,d);});return t.hook("preAction",()=>{ks();}),t}function rx(){return ge__default.join(be__default.homedir(),".claude","settings.json")}function Wp(){let e=rx();try{if(!he__default.existsSync(e))return !0;let r=JSON.parse(he__default.readFileSync(e,"utf-8")).flowCli?.autoUpdate;return r===!1?!1:r==="modules-only"?"modules-only":!0}catch{return true}}var lx=I("updateChecker"),cx=promisify(execFile),ux=1440*60*1e3,zp=3e4;function dx(){let e=process.env.FLOW_HOME??ge__default.join(be__default.homedir(),".flow");return ge__default.join(e,"update.lock")}async function Xp(e){try{let{stdout:t}=await cx(Vt(),["view",e,"version"],{timeout:zp,shell:process.platform==="win32"});return String(t).trim()||null}catch{return null}}async function px(e){let t=new AbortController,r=setTimeout(()=>t.abort(),zp);try{let n=await fetch(`https://api.github.com/repos/${e}/releases/latest`,{signal:t.signal});return n.ok?(await n.json()).tag_name?.replace(/^v/,"")??null:null}catch{return null}finally{clearTimeout(r);}}async function mx(e){return e.versionCheck.type==="npm-registry"?Xp(e.versionCheck.package):px(e.versionCheck.repo)}async function fx(){let e=await Xp("@ciandt-flow/cli");return e&&Ae(ae,e)?($s({currentVersion:ae,latestVersion:e,isOutdated:true,packageName:"@ciandt-flow/cli"}).catch(()=>{}),e):null}async function gx(){let e=$r().filter(t=>t.installMethod!==null);await Promise.all(e.map(async t=>{let r=te.find(i=>i.alias===t.alias);if(!r||r.hasOwnUpdateCheck)return;let n=Date.now(),o=t.lastChecked?new Date(t.lastChecked).getTime():0;if(n-o<ux)return;let s=await mx(r);try{await kt({...t,lastChecked:new Date().toISOString()});}catch(i){lx.warn(`Failed to update lastChecked for ${t.alias}: ${String(i)}`);}s&&t.installedVersion&&Ae(t.installedVersion,s)&&Ts(r,"background").catch(()=>{});}));}async function Na(){let e=Wp();if(e===false)return;let t=dx();he__default.mkdirSync(ge__default.dirname(t),{recursive:true});let r=null;try{r=await lg.lock(t,{realpath:!1,retries:0});}catch{return}try{if(e!=="modules-only"){let n=await fx().catch(()=>null);n&&process.stdout.write(`
|
|
319
319
|
\u26A0 @ciandt-flow/cli v${n} installing in background.
|
|
320
320
|
Restart flow to apply the update.
|
|
321
321
|
|
|
322
|
-
`);}await
|
|
322
|
+
`);}await gx().catch(()=>{});}finally{await r().catch(()=>{});}}var hx=I("cli"),Ba=Jp(async()=>{De("tui"),pl("tui"),ml(),process.on("SIGINT",()=>{let{activeTab:t,screen:r}=S.getState();Pn("sigint",t,r).finally(()=>process.exit(130));}),process.on("SIGTERM",()=>{let{activeTab:t,screen:r}=S.getState();Pn("sigterm",t,r).finally(()=>process.exit(143));}),await Na().catch(()=>{}),await gc().catch(t=>{hx.error(`Failed to init catalog registry: ${String(t)}`);}),await Gd();let{waitUntilExit:e}=render(jsx(Wd,{}),{alternateScreen:true,exitOnCtrlC:false});await e(),process.exit(0);});Ba.hook("preAction",async(e,t)=>{t!==Ba&&await Na().catch(()=>{});});Ba.parse();
|