@sr-connect/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +3 -2
  2. package/dist/index.js +17 -16
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -21,10 +21,10 @@ Expecting one of '${allowedValues.join("', '")}'`);return this._lifeCycleHooks[e
21
21
  - ${executableDirMessage}`;throw new Error(executableMissing)}_executeSubCommand(subcommand,args){args=args.slice();let sourceExt=[".js",".ts",".tsx",".mjs",".cjs"];function findFile(baseDir,baseName){let localBin=path.resolve(baseDir,baseName);if(fs.existsSync(localBin))return localBin;if(sourceExt.includes(path.extname(baseName)))return;let foundExt=sourceExt.find(ext=>fs.existsSync(`${localBin}${ext}`));if(foundExt)return`${localBin}${foundExt}`}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let executableFile=subcommand._executableFile||`${this._name}-${subcommand._name}`,executableDir=this._executableDir||"";if(this._scriptPath){let resolvedScriptPath;try{resolvedScriptPath=fs.realpathSync(this._scriptPath)}catch{resolvedScriptPath=this._scriptPath}executableDir=path.resolve(path.dirname(resolvedScriptPath),executableDir)}if(executableDir){let localFile=findFile(executableDir,executableFile);if(!localFile&&!subcommand._executableFile&&this._scriptPath){let legacyName=path.basename(this._scriptPath,path.extname(this._scriptPath));legacyName!==this._name&&(localFile=findFile(executableDir,`${legacyName}-${subcommand._name}`))}executableFile=localFile||executableFile}let launchWithNode=sourceExt.includes(path.extname(executableFile)),proc;process2.platform!=="win32"?launchWithNode?(args.unshift(executableFile),args=incrementNodeInspectorPort(process2.execArgv).concat(args),proc=childProcess.spawn(process2.argv[0],args,{stdio:"inherit"})):proc=childProcess.spawn(executableFile,args,{stdio:"inherit"}):(this._checkForMissingExecutable(executableFile,executableDir,subcommand._name),args.unshift(executableFile),args=incrementNodeInspectorPort(process2.execArgv).concat(args),proc=childProcess.spawn(process2.execPath,args,{stdio:"inherit"})),proc.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(signal=>{process2.on(signal,()=>{proc.killed===!1&&proc.exitCode===null&&proc.kill(signal)})});let exitCallback=this._exitCallback;proc.on("close",code=>{code=code??1,exitCallback?exitCallback(new CommanderError(code,"commander.executeSubCommandAsync","(close)")):process2.exit(code)}),proc.on("error",err=>{if(err.code==="ENOENT")this._checkForMissingExecutable(executableFile,executableDir,subcommand._name);else if(err.code==="EACCES")throw new Error(`'${executableFile}' not executable`);if(!exitCallback)process2.exit(1);else{let wrappedError=new CommanderError(1,"commander.executeSubCommandAsync","(error)");wrappedError.nestedError=err,exitCallback(wrappedError)}}),this.runningCommand=proc}_dispatchSubcommand(commandName,operands,unknown2){let subCommand=this._findCommand(commandName);subCommand||this.help({error:!0}),subCommand._prepareForParse();let promiseChain;return promiseChain=this._chainOrCallSubCommandHook(promiseChain,subCommand,"preSubcommand"),promiseChain=this._chainOrCall(promiseChain,()=>{if(subCommand._executableHandler)this._executeSubCommand(subCommand,operands.concat(unknown2));else return subCommand._parseCommand(operands,unknown2)}),promiseChain}_dispatchHelpCommand(subcommandName){subcommandName||this.help();let subCommand=this._findCommand(subcommandName);return subCommand&&!subCommand._executableHandler&&subCommand.help(),this._dispatchSubcommand(subcommandName,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((arg,i)=>{arg.required&&this.args[i]==null&&this.missingArgument(arg.name())}),!(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)&&this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){let myParseArg=(argument,value,previous)=>{let parsedValue=value;if(value!==null&&argument.parseArg){let invalidValueMessage=`error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;parsedValue=this._callParseArg(argument,value,previous,invalidValueMessage)}return parsedValue};this._checkNumberOfArguments();let processedArgs=[];this.registeredArguments.forEach((declaredArg,index)=>{let value=declaredArg.defaultValue;declaredArg.variadic?index<this.args.length?(value=this.args.slice(index),declaredArg.parseArg&&(value=value.reduce((processed,v2)=>myParseArg(declaredArg,v2,processed),declaredArg.defaultValue))):value===void 0&&(value=[]):index<this.args.length&&(value=this.args[index],declaredArg.parseArg&&(value=myParseArg(declaredArg,value,declaredArg.defaultValue))),processedArgs[index]=value}),this.processedArgs=processedArgs}_chainOrCall(promise2,fn){return promise2?.then&&typeof promise2.then=="function"?promise2.then(()=>fn()):fn()}_chainOrCallHooks(promise2,event){let result=promise2,hooks=[];return this._getCommandAndAncestors().reverse().filter(cmd=>cmd._lifeCycleHooks[event]!==void 0).forEach(hookedCommand=>{hookedCommand._lifeCycleHooks[event].forEach(callback=>{hooks.push({hookedCommand,callback})})}),event==="postAction"&&hooks.reverse(),hooks.forEach(hookDetail=>{result=this._chainOrCall(result,()=>hookDetail.callback(hookDetail.hookedCommand,this))}),result}_chainOrCallSubCommandHook(promise2,subCommand,event){let result=promise2;return this._lifeCycleHooks[event]!==void 0&&this._lifeCycleHooks[event].forEach(hook=>{result=this._chainOrCall(result,()=>hook(this,subCommand))}),result}_parseCommand(operands,unknown2){let parsed=this.parseOptions(unknown2);if(this._parseOptionsEnv(),this._parseOptionsImplied(),operands=operands.concat(parsed.operands),unknown2=parsed.unknown,this.args=operands.concat(unknown2),operands&&this._findCommand(operands[0]))return this._dispatchSubcommand(operands[0],operands.slice(1),unknown2);if(this._getHelpCommand()&&operands[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(operands[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(unknown2),this._dispatchSubcommand(this._defaultCommandName,operands,unknown2);this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName&&this.help({error:!0}),this._outputHelpIfRequested(parsed.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let checkForUnknownOptions=()=>{parsed.unknown.length>0&&this.unknownOption(parsed.unknown[0])},commandEvent=`command:${this.name()}`;if(this._actionHandler){checkForUnknownOptions(),this._processArguments();let promiseChain;return promiseChain=this._chainOrCallHooks(promiseChain,"preAction"),promiseChain=this._chainOrCall(promiseChain,()=>this._actionHandler(this.processedArgs)),this.parent&&(promiseChain=this._chainOrCall(promiseChain,()=>{this.parent.emit(commandEvent,operands,unknown2)})),promiseChain=this._chainOrCallHooks(promiseChain,"postAction"),promiseChain}if(this.parent?.listenerCount(commandEvent))checkForUnknownOptions(),this._processArguments(),this.parent.emit(commandEvent,operands,unknown2);else if(operands.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",operands,unknown2);this.listenerCount("command:*")?this.emit("command:*",operands,unknown2):this.commands.length?this.unknownCommand():(checkForUnknownOptions(),this._processArguments())}else this.commands.length?(checkForUnknownOptions(),this.help({error:!0})):(checkForUnknownOptions(),this._processArguments())}_findCommand(name){if(name)return this.commands.find(cmd=>cmd._name===name||cmd._aliases.includes(name))}_findOption(arg){return this.options.find(option=>option.is(arg))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(cmd=>{cmd.options.forEach(anOption=>{anOption.mandatory&&cmd.getOptionValue(anOption.attributeName())===void 0&&cmd.missingMandatoryOptionValue(anOption)})})}_checkForConflictingLocalOptions(){let definedNonDefaultOptions=this.options.filter(option=>{let optionKey=option.attributeName();return this.getOptionValue(optionKey)===void 0?!1:this.getOptionValueSource(optionKey)!=="default"});definedNonDefaultOptions.filter(option=>option.conflictsWith.length>0).forEach(option=>{let conflictingAndDefined=definedNonDefaultOptions.find(defined=>option.conflictsWith.includes(defined.attributeName()));conflictingAndDefined&&this._conflictingOption(option,conflictingAndDefined)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(cmd=>{cmd._checkForConflictingLocalOptions()})}parseOptions(args){let operands=[],unknown2=[],dest=operands;function maybeOption(arg){return arg.length>1&&arg[0]==="-"}let negativeNumberArg=arg=>/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)?!this._getCommandAndAncestors().some(cmd=>cmd.options.map(opt=>opt.short).some(short=>/^-\d$/.test(short))):!1,activeVariadicOption=null,activeGroup=null,i=0;for(;i<args.length||activeGroup;){let arg=activeGroup??args[i++];if(activeGroup=null,arg==="--"){dest===unknown2&&dest.push(arg),dest.push(...args.slice(i));break}if(activeVariadicOption&&(!maybeOption(arg)||negativeNumberArg(arg))){this.emit(`option:${activeVariadicOption.name()}`,arg);continue}if(activeVariadicOption=null,maybeOption(arg)){let option=this._findOption(arg);if(option){if(option.required){let value=args[i++];value===void 0&&this.optionMissingArgument(option),this.emit(`option:${option.name()}`,value)}else if(option.optional){let value=null;i<args.length&&(!maybeOption(args[i])||negativeNumberArg(args[i]))&&(value=args[i++]),this.emit(`option:${option.name()}`,value)}else this.emit(`option:${option.name()}`);activeVariadicOption=option.variadic?option:null;continue}}if(arg.length>2&&arg[0]==="-"&&arg[1]!=="-"){let option=this._findOption(`-${arg[1]}`);if(option){option.required||option.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${option.name()}`,arg.slice(2)):(this.emit(`option:${option.name()}`),activeGroup=`-${arg.slice(2)}`);continue}}if(/^--[^=]+=/.test(arg)){let index=arg.indexOf("="),option=this._findOption(arg.slice(0,index));if(option&&(option.required||option.optional)){this.emit(`option:${option.name()}`,arg.slice(index+1));continue}}if(dest===operands&&maybeOption(arg)&&!(this.commands.length===0&&negativeNumberArg(arg))&&(dest=unknown2),(this._enablePositionalOptions||this._passThroughOptions)&&operands.length===0&&unknown2.length===0){if(this._findCommand(arg)){operands.push(arg),unknown2.push(...args.slice(i));break}else if(this._getHelpCommand()&&arg===this._getHelpCommand().name()){operands.push(arg,...args.slice(i));break}else if(this._defaultCommandName){unknown2.push(arg,...args.slice(i));break}}if(this._passThroughOptions){dest.push(arg,...args.slice(i));break}dest.push(arg)}return{operands,unknown:unknown2}}opts(){if(this._storeOptionsAsProperties){let result={},len=this.options.length;for(let i=0;i<len;i++){let key=this.options[i].attributeName();result[key]=key===this._versionOptionName?this._version:this[key]}return result}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((combinedOptions,cmd)=>Object.assign(combinedOptions,cmd.opts()),{})}error(message,errorOptions){this._outputConfiguration.outputError(`${message}
22
22
  `,this._outputConfiguration.writeErr),typeof this._showHelpAfterError=="string"?this._outputConfiguration.writeErr(`${this._showHelpAfterError}
23
23
  `):this._showHelpAfterError&&(this._outputConfiguration.writeErr(`
24
- `),this.outputHelp({error:!0}));let config2=errorOptions||{},exitCode=config2.exitCode||1,code=config2.code||"commander.error";this._exit(exitCode,code,message)}_parseOptionsEnv(){this.options.forEach(option=>{if(option.envVar&&option.envVar in process2.env){let optionKey=option.attributeName();(this.getOptionValue(optionKey)===void 0||["default","config","env"].includes(this.getOptionValueSource(optionKey)))&&(option.required||option.optional?this.emit(`optionEnv:${option.name()}`,process2.env[option.envVar]):this.emit(`optionEnv:${option.name()}`))}})}_parseOptionsImplied(){let dualHelper=new DualOptions(this.options),hasCustomOptionValue=optionKey=>this.getOptionValue(optionKey)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(optionKey));this.options.filter(option=>option.implied!==void 0&&hasCustomOptionValue(option.attributeName())&&dualHelper.valueFromOption(this.getOptionValue(option.attributeName()),option)).forEach(option=>{Object.keys(option.implied).filter(impliedKey=>!hasCustomOptionValue(impliedKey)).forEach(impliedKey=>{this.setOptionValueWithSource(impliedKey,option.implied[impliedKey],"implied")})})}missingArgument(name){let message=`error: missing required argument '${name}'`;this.error(message,{code:"commander.missingArgument"})}optionMissingArgument(option){let message=`error: option '${option.flags}' argument missing`;this.error(message,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(option){let message=`error: required option '${option.flags}' not specified`;this.error(message,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(option,conflictingOption){let findBestOptionFromValue=option2=>{let optionKey=option2.attributeName(),optionValue=this.getOptionValue(optionKey),negativeOption=this.options.find(target=>target.negate&&optionKey===target.attributeName()),positiveOption=this.options.find(target=>!target.negate&&optionKey===target.attributeName());return negativeOption&&(negativeOption.presetArg===void 0&&optionValue===!1||negativeOption.presetArg!==void 0&&optionValue===negativeOption.presetArg)?negativeOption:positiveOption||option2},getErrorMessage=option2=>{let bestOption=findBestOptionFromValue(option2),optionKey=bestOption.attributeName();return this.getOptionValueSource(optionKey)==="env"?`environment variable '${bestOption.envVar}'`:`option '${bestOption.flags}'`},message=`error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;this.error(message,{code:"commander.conflictingOption"})}unknownOption(flag){if(this._allowUnknownOption)return;let suggestion="";if(flag.startsWith("--")&&this._showSuggestionAfterError){let candidateFlags=[],command=this;do{let moreFlags=command.createHelp().visibleOptions(command).filter(option=>option.long).map(option=>option.long);candidateFlags=candidateFlags.concat(moreFlags),command=command.parent}while(command&&!command._enablePositionalOptions);suggestion=suggestSimilar(flag,candidateFlags)}let message=`error: unknown option '${flag}'${suggestion}`;this.error(message,{code:"commander.unknownOption"})}_excessArguments(receivedArgs){if(this._allowExcessArguments)return;let expected=this.registeredArguments.length,s=expected===1?"":"s",received=receivedArgs.length,forSubcommand=this.parent?` for '${this.name()}'`:"",details=receivedArgs.join(", "),message=`error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${received}: ${details}.`;this.error(message,{code:"commander.excessArguments"})}unknownCommand(){let unknownName=this.args[0],suggestion="";if(this._showSuggestionAfterError){let candidateNames=[];this.createHelp().visibleCommands(this).forEach(command=>{candidateNames.push(command.name()),command.alias()&&candidateNames.push(command.alias())}),suggestion=suggestSimilar(unknownName,candidateNames)}let message=`error: unknown command '${unknownName}'${suggestion}`;this.error(message,{code:"commander.unknownCommand"})}version(str,flags,description){if(str===void 0)return this._version;this._version=str,flags=flags||"-V, --version",description=description||"output the version number";let versionOption=this.createOption(flags,description);return this._versionOptionName=versionOption.attributeName(),this._registerOption(versionOption),this.on("option:"+versionOption.name(),()=>{this._outputConfiguration.writeOut(`${str}
24
+ `),this.outputHelp({error:!0}));let config2=errorOptions||{},exitCode=config2.exitCode||1,code=config2.code||"commander.error";this._exit(exitCode,code,message)}_parseOptionsEnv(){this.options.forEach(option=>{if(option.envVar&&option.envVar in process2.env){let optionKey=option.attributeName();(this.getOptionValue(optionKey)===void 0||["default","config","env"].includes(this.getOptionValueSource(optionKey)))&&(option.required||option.optional?this.emit(`optionEnv:${option.name()}`,process2.env[option.envVar]):this.emit(`optionEnv:${option.name()}`))}})}_parseOptionsImplied(){let dualHelper=new DualOptions(this.options),hasCustomOptionValue=optionKey=>this.getOptionValue(optionKey)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(optionKey));this.options.filter(option=>option.implied!==void 0&&hasCustomOptionValue(option.attributeName())&&dualHelper.valueFromOption(this.getOptionValue(option.attributeName()),option)).forEach(option=>{Object.keys(option.implied).filter(impliedKey=>!hasCustomOptionValue(impliedKey)).forEach(impliedKey=>{this.setOptionValueWithSource(impliedKey,option.implied[impliedKey],"implied")})})}missingArgument(name){let message=`error: missing required argument '${name}'`;this.error(message,{code:"commander.missingArgument"})}optionMissingArgument(option){let message=`error: option '${option.flags}' argument missing`;this.error(message,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(option){let message=`error: required option '${option.flags}' not specified`;this.error(message,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(option,conflictingOption){let findBestOptionFromValue=option2=>{let optionKey=option2.attributeName(),optionValue=this.getOptionValue(optionKey),negativeOption=this.options.find(target=>target.negate&&optionKey===target.attributeName()),positiveOption=this.options.find(target=>!target.negate&&optionKey===target.attributeName());return negativeOption&&(negativeOption.presetArg===void 0&&optionValue===!1||negativeOption.presetArg!==void 0&&optionValue===negativeOption.presetArg)?negativeOption:positiveOption||option2},getErrorMessage=option2=>{let bestOption=findBestOptionFromValue(option2),optionKey=bestOption.attributeName();return this.getOptionValueSource(optionKey)==="env"?`environment variable '${bestOption.envVar}'`:`option '${bestOption.flags}'`},message=`error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;this.error(message,{code:"commander.conflictingOption"})}unknownOption(flag){if(this._allowUnknownOption)return;let suggestion="";if(flag.startsWith("--")&&this._showSuggestionAfterError){let candidateFlags=[],command=this;do{let moreFlags=command.createHelp().visibleOptions(command).filter(option=>option.long).map(option=>option.long);candidateFlags=candidateFlags.concat(moreFlags),command=command.parent}while(command&&!command._enablePositionalOptions);suggestion=suggestSimilar(flag,candidateFlags)}let message=`error: unknown option '${flag}'${suggestion}`;this.error(message,{code:"commander.unknownOption"})}_excessArguments(receivedArgs){if(this._allowExcessArguments)return;let expected=this.registeredArguments.length,s=expected===1?"":"s",received=receivedArgs.length,forSubcommand=this.parent?` for '${this.name()}'`:"",details=receivedArgs.join(", "),message=`error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${received}: ${details}.`;this.error(message,{code:"commander.excessArguments"})}unknownCommand(){let unknownName=this.args[0],suggestion="";if(this._showSuggestionAfterError){let candidateNames2=[];this.createHelp().visibleCommands(this).forEach(command=>{candidateNames2.push(command.name()),command.alias()&&candidateNames2.push(command.alias())}),suggestion=suggestSimilar(unknownName,candidateNames2)}let message=`error: unknown command '${unknownName}'${suggestion}`;this.error(message,{code:"commander.unknownCommand"})}version(str,flags,description){if(str===void 0)return this._version;this._version=str,flags=flags||"-V, --version",description=description||"output the version number";let versionOption=this.createOption(flags,description);return this._versionOptionName=versionOption.attributeName(),this._registerOption(versionOption),this.on("option:"+versionOption.name(),()=>{this._outputConfiguration.writeOut(`${str}
25
25
  `),this._exit(0,"commander.version",str)}),this}description(str,argsDescription){return str===void 0&&argsDescription===void 0?this._description:(this._description=str,argsDescription&&(this._argsDescription=argsDescription),this)}summary(str){return str===void 0?this._summary:(this._summary=str,this)}alias(alias){if(alias===void 0)return this._aliases[0];let command=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler&&(command=this.commands[this.commands.length-1]),alias===command._name)throw new Error("Command alias can't be the same as its name");let matchingCommand=this.parent?._findCommand(alias);if(matchingCommand){let existingCmd=[matchingCommand.name()].concat(matchingCommand.aliases()).join("|");throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`)}return command._aliases.push(alias),this}aliases(aliases){return aliases===void 0?this._aliases:(aliases.forEach(alias=>this.alias(alias)),this)}usage(str){if(str===void 0){if(this._usage)return this._usage;let args=this.registeredArguments.map(arg=>humanReadableArgName(arg));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?args:[]).join(" ")}return this._usage=str,this}name(str){return str===void 0?this._name:(this._name=str,this)}helpGroup(heading){return heading===void 0?this._helpGroupHeading??"":(this._helpGroupHeading=heading,this)}commandsGroup(heading){return heading===void 0?this._defaultCommandGroup??"":(this._defaultCommandGroup=heading,this)}optionsGroup(heading){return heading===void 0?this._defaultOptionGroup??"":(this._defaultOptionGroup=heading,this)}_initOptionGroup(option){this._defaultOptionGroup&&!option.helpGroupHeading&&option.helpGroup(this._defaultOptionGroup)}_initCommandGroup(cmd){this._defaultCommandGroup&&!cmd.helpGroup()&&cmd.helpGroup(this._defaultCommandGroup)}nameFromFilename(filename){return this._name=path.basename(filename,path.extname(filename)),this}executableDir(path2){return path2===void 0?this._executableDir:(this._executableDir=path2,this)}helpInformation(contextOptions){let helper=this.createHelp(),context=this._getOutputContext(contextOptions);helper.prepareContext({error:context.error,helpWidth:context.helpWidth,outputHasColors:context.hasColors});let text=helper.formatHelp(this,helper);return context.hasColors?text:this._outputConfiguration.stripColor(text)}_getOutputContext(contextOptions){contextOptions=contextOptions||{};let error51=!!contextOptions.error,baseWrite,hasColors,helpWidth;return error51?(baseWrite=str=>this._outputConfiguration.writeErr(str),hasColors=this._outputConfiguration.getErrHasColors(),helpWidth=this._outputConfiguration.getErrHelpWidth()):(baseWrite=str=>this._outputConfiguration.writeOut(str),hasColors=this._outputConfiguration.getOutHasColors(),helpWidth=this._outputConfiguration.getOutHelpWidth()),{error:error51,write:str=>(hasColors||(str=this._outputConfiguration.stripColor(str)),baseWrite(str)),hasColors,helpWidth}}outputHelp(contextOptions){let deprecatedCallback;typeof contextOptions=="function"&&(deprecatedCallback=contextOptions,contextOptions=void 0);let outputContext=this._getOutputContext(contextOptions),eventContext={error:outputContext.error,write:outputContext.write,command:this};this._getCommandAndAncestors().reverse().forEach(command=>command.emit("beforeAllHelp",eventContext)),this.emit("beforeHelp",eventContext);let helpInformation=this.helpInformation({error:outputContext.error});if(deprecatedCallback&&(helpInformation=deprecatedCallback(helpInformation),typeof helpInformation!="string"&&!Buffer.isBuffer(helpInformation)))throw new Error("outputHelp callback must return a string or a Buffer");outputContext.write(helpInformation),this._getHelpOption()?.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",eventContext),this._getCommandAndAncestors().forEach(command=>command.emit("afterAllHelp",eventContext))}helpOption(flags,description){return typeof flags=="boolean"?(flags?(this._helpOption===null&&(this._helpOption=void 0),this._defaultOptionGroup&&this._initOptionGroup(this._getHelpOption())):this._helpOption=null,this):(this._helpOption=this.createOption(flags??"-h, --help",description??"display help for command"),(flags||description)&&this._initOptionGroup(this._helpOption),this)}_getHelpOption(){return this._helpOption===void 0&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(option){return this._helpOption=option,this._initOptionGroup(option),this}help(contextOptions){this.outputHelp(contextOptions);let exitCode=Number(process2.exitCode??0);exitCode===0&&contextOptions&&typeof contextOptions!="function"&&contextOptions.error&&(exitCode=1),this._exit(exitCode,"commander.help","(outputHelp)")}addHelpText(position,text){let allowedValues=["beforeAll","before","after","afterAll"];if(!allowedValues.includes(position))throw new Error(`Unexpected value for position to addHelpText.
26
26
  Expecting one of '${allowedValues.join("', '")}'`);let helpEvent=`${position}Help`;return this.on(helpEvent,context=>{let helpStr;typeof text=="function"?helpStr=text({error:context.error,command:context.command}):helpStr=text,helpStr&&context.write(`${helpStr}
27
- `)}),this}_outputHelpIfRequested(args){let helpOption=this._getHelpOption();helpOption&&args.find(arg=>helpOption.is(arg))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function incrementNodeInspectorPort(args){return args.map(arg=>{if(!arg.startsWith("--inspect"))return arg;let debugOption,debugHost="127.0.0.1",debugPort="9229",match;return(match=arg.match(/^(--inspect(-brk)?)$/))!==null?debugOption=match[1]:(match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(debugOption=match[1],/^\d+$/.test(match[3])?debugPort=match[3]:debugHost=match[3]):(match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(debugOption=match[1],debugHost=match[3],debugPort=match[4]),debugOption&&debugPort!=="0"?`${debugOption}=${debugHost}:${parseInt(debugPort)+1}`:arg})}function useColor(){if(process2.env.NO_COLOR||process2.env.FORCE_COLOR==="0"||process2.env.FORCE_COLOR==="false")return!1;if(process2.env.FORCE_COLOR||process2.env.CLICOLOR_FORCE!==void 0)return!0}var program=new Command;import{appendFileSync as appendFileSync2,mkdirSync as mkdirSync4,readFileSync as readFileSync5,readdirSync as readdirSync2,renameSync as renameSync3,rmSync as rmSync3,statSync as statSync2}from"fs";import{join as join4}from"path";import{mkdirSync,readFileSync as readFileSync2,writeFileSync}from"fs";import{homedir as homedir2}from"os";import{join}from"path";import{readFileSync}from"fs";var PACKAGE="@sr-connect/cli",CLI=`npx ${PACKAGE}`;function manifestVersion(){let url2=new URL("../package.json",import.meta.url),manifest=JSON.parse(readFileSync(url2,"utf8")),record4=typeof manifest=="object"&&manifest!==null?manifest:{};if(record4.name!==PACKAGE||typeof record4.version!="string")throw new Error(`${url2.pathname} is not the manifest of ${PACKAGE}.`);return record4.version}var VERSION=manifestVersion(),USER_AGENT=`${PACKAGE}@${VERSION}`,APP_DIR="sr-connect";var import_picocolors=__toESM(require_picocolors(),1);import{appendFileSync}from"fs";import{homedir}from"os";import{resolve,sep}from"path";var EXIT={OK:0,API_ERROR:1,USAGE:2,UNAUTHENTICATED:3,NOT_FOUND:4,CANCELLED:130},rawMode=!1;function configureRawMode(opts){let value=process.env.SR_CONNECT_CLI_RAW;rawMode=opts.enabled===!0||value!==void 0&&!/^(0|false|no|off|)$/i.test(value.trim())}function isRaw(){return rawMode}var promptsAllowed=!0;function setPromptsAllowed(allowed){promptsAllowed=allowed}var agentMode=!1;function agentEnvOn(){let value=process.env.SR_CONNECT_CLI_AGENT;return value!==void 0&&!/^(0|false|no|off|)$/i.test(value.trim())}function configureAgentMode(opts){agentMode=opts.enabled===!0||agentEnvOn()}function isAgent(){return agentMode}function promptsDeclined(){return!promptsAllowed||agentMode}function supplyHint(opts={}){let pass=opts.pass??"Pass it",env=opts.env===void 0?"":`, set ${opts.env}`,ask=opts.ask??"pick one";return promptsDeclined()?`${pass}${env}, or ${restorePrompts()} and run on a terminal to ${ask}.`:`${pass}${env}, or run on a terminal to ${ask}.`}function restorePrompts(){return agentMode?agentEnvOn()?"unset SR_CONNECT_CLI_AGENT":"drop --agent":process.env.SR_CONNECT_CLI_NO_PROMPTS?"unset SR_CONNECT_CLI_NO_PROMPTS":"drop --no-prompts"}function canPrompt(){return promptsAllowed&&!agentMode&&!!(process.stdin.isTTY&&process.stderr.isTTY)}var copyPath;function generatedOutputName(){return`output-${Math.floor(Date.now()/1e3)}.${rawMode?"json":"txt"}`}function setOutputCopy(target){if(!target){copyPath=void 0;return}let name=typeof target=="string"&&target.trim()!==""?target.trim():void 0,path2=resolve(name??generatedOutputName());try{appendFileSync(path2,"")}catch(err){fail(EXIT.USAGE,"OUTPUT_FILE_ERROR",`--copy-output-to-file ${path2} is not writable: ${err instanceof Error?err.message:String(err)}`)}return copyPath=path2,path2}function outputCopyPath(){return copyPath}function assertOutputCopyValue(argv2,commandNames){for(let[at2,token]of argv2.entries()){if(token!=="--copy-output-to-file")continue;let value=argv2[at2+1];value===void 0||value.startsWith("-")||!commandNames.includes(value)||fail(EXIT.USAGE,"OUTPUT_FILE_ERROR",`--copy-output-to-file took '${value}' as the file name, which is a command group; the file name is optional and the next word is taken as it.`,{hint:`Put the flag after the command, or name the file: --copy-output-to-file ./${value} if that really is the file.`})}}function assertVersionFlagIsRoot(argv2,commandNames){let rest=argv2.slice(2),flag=rest.find(a=>a==="-V"||a==="--version");if(flag===void 0)return;let group=rest.findIndex(a=>!a.startsWith("-")&&commandNames.includes(a));if(group===-1)return;let verb=rest[group+1],command=verb!==void 0&&!verb.startsWith("-")?`${rest[group]} ${verb}`:rest[group];fail(EXIT.USAGE,"USAGE_ERROR",`${flag} prints this CLI's own version and belongs to the root, so it would have sent nothing and exited 0.`,{hint:`Drop it to run '${command}', or use the flag the verb means: --release-version for a release, --package-version for a package.`})}function reportOutputCopy(){if(copyPath===void 0)return;let line=`Output copied to ${copyPath}`;rawMode?console.error(import_picocolors.default.dim(line)):console.log(import_picocolors.default.green(line))}async function flushOutput(){let drain=stream=>new Promise(done=>{if(stream.writableLength===0){done();return}stream.write("",()=>done())});await Promise.all([drain(process.stdout),drain(process.stderr)])}function ignoreBrokenPipe(){for(let stream of[process.stdout,process.stderr])stream.on("error",err=>{throw(err.code==="EPIPE"||err.code==="ERR_STREAM_DESTROYED")&&process.exit(EXIT.OK),err})}function displayPath(path2,home=safeHomedir()){if(process.platform==="win32")return path2;let base=home.endsWith(sep)?home.slice(0,-sep.length):home;return base===""||base===sep?path2:path2===base?"~":path2.startsWith(base+sep)?`~${path2.slice(base.length)}`:path2}function shellQuote(value){return/^[\w.:@/+-]+$/.test(value)?value:`'${value.replaceAll("'","'\\''")}'`}function safeHomedir(){try{return homedir()}catch{return""}}var ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function stripAnsi(text){return text.replaceAll(ANSI,"")}function emit(text){console.log(text),appendCopy(`${text}
27
+ `)}),this}_outputHelpIfRequested(args){let helpOption=this._getHelpOption();helpOption&&args.find(arg=>helpOption.is(arg))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function incrementNodeInspectorPort(args){return args.map(arg=>{if(!arg.startsWith("--inspect"))return arg;let debugOption,debugHost="127.0.0.1",debugPort="9229",match;return(match=arg.match(/^(--inspect(-brk)?)$/))!==null?debugOption=match[1]:(match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(debugOption=match[1],/^\d+$/.test(match[3])?debugPort=match[3]:debugHost=match[3]):(match=arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(debugOption=match[1],debugHost=match[3],debugPort=match[4]),debugOption&&debugPort!=="0"?`${debugOption}=${debugHost}:${parseInt(debugPort)+1}`:arg})}function useColor(){if(process2.env.NO_COLOR||process2.env.FORCE_COLOR==="0"||process2.env.FORCE_COLOR==="false")return!1;if(process2.env.FORCE_COLOR||process2.env.CLICOLOR_FORCE!==void 0)return!0}var program=new Command;import{appendFileSync as appendFileSync2,mkdirSync as mkdirSync4,readFileSync as readFileSync5,readdirSync as readdirSync2,renameSync as renameSync3,rmSync as rmSync3,statSync as statSync2}from"fs";import{join as join5}from"path";import{mkdirSync,readFileSync as readFileSync2,writeFileSync}from"fs";import{homedir as homedir2}from"os";import{join as join2}from"path";import{readFileSync}from"fs";import{realpathSync}from"fs";import{dirname,join,resolve,sep}from"path";import{fileURLToPath}from"url";function globalRoots(site){let nodeDir=dirname(site.execPath),roots=[{manager:"npm",root:join(nodeDir,"..","lib","node_modules")},{manager:"npm",root:join(nodeDir,"node_modules")}],prefix=site.env.npm_config_prefix??site.env.PREFIX;if(prefix){let root=site.platform==="win32"?join(prefix,"node_modules"):join(prefix,"lib","node_modules");roots.push({manager:"npm",root})}let pnpmHome=site.env.PNPM_HOME;pnpmHome&&roots.push({manager:"pnpm",root:pnpmHome});let bunInstall=site.env.BUN_INSTALL;return bunInstall&&roots.push({manager:"bun",root:join(bunInstall,"install","global")}),roots}function under(path2,root){let normalized=resolve(root);return path2===normalized||path2.startsWith(normalized.endsWith(sep)?normalized:normalized+sep)}function classifyInstall(site){if(site.entry.includes(`${sep}_npx${sep}`)||site.entry.includes(`${sep}dlx${sep}`))return{kind:"npx",manager:"npm"};for(let{manager,root}of globalRoots(site))if(under(site.entry,root))return{kind:"global",manager};return{kind:site.entry.includes(`${sep}node_modules${sep}`)?"local":"unknown",manager:"npm"}}function currentSite(){let file2=fileURLToPath(import.meta.url),entry2=file2;try{entry2=realpathSync(file2)}catch{}return{entry:entry2,env:process.env,execPath:process.execPath,platform:process.platform}}var DEFAULT_PATH_EXT=".COM;.EXE;.BAT;.CMD";function pathLookup(){let realpathOrNone=candidate=>{try{return realpathSync(candidate)}catch{return}};return{main:process.argv[1]===void 0?void 0:realpathOrNone(process.argv[1]),path:process.env.PATH,pathExt:process.env.PATHEXT,platform:process.platform,resolve:realpathOrNone}}function candidateNames(bin,lookup){return lookup.platform!=="win32"?[bin]:[...(lookup.pathExt??DEFAULT_PATH_EXT).split(";").filter(Boolean),".ps1"].map(ext=>`${bin}${ext}`)}function isEphemeral(path2){return path2.includes(`${sep}_npx${sep}`)||path2.includes(`${sep}dlx${sep}`)}function spawnedByPackageManager(env){return["npm_command","npm_config_user_agent","npm_execpath","npm_lifecycle_event"].some(key=>env[key]!==void 0)}function binIsOnPath(bin,entry2,lookup){let windows=lookup.platform==="win32",delimiter=windows?";":":",separator=windows?"\\":"/",names=candidateNames(bin,lookup);for(let dir of(lookup.path??"").split(delimiter)){if(!dir)continue;let base=dir.endsWith(separator)?dir:dir+separator;for(let name of names){let found2=lookup.resolve(base+name);if(found2!==void 0)return isEphemeral(base+name)?!1:found2===entry2||found2===lookup.main}}return!1}function invocationCommand(bin,npxSpec,site=currentSite(),lookup=pathLookup()){let{kind}=classifyInstall(site);return kind==="global"?bin:kind==="npx"||spawnedByPackageManager(site.env)?npxSpec:binIsOnPath(bin,site.entry,lookup)?bin:npxSpec}var PACKAGE="@sr-connect/cli",BIN="sr-connect",CLI=invocationCommand(BIN,`npx ${PACKAGE}`);function manifestVersion(){let url2=new URL("../package.json",import.meta.url),manifest=JSON.parse(readFileSync(url2,"utf8")),record4=typeof manifest=="object"&&manifest!==null?manifest:{};if(record4.name!==PACKAGE||typeof record4.version!="string")throw new Error(`${url2.pathname} is not the manifest of ${PACKAGE}.`);return record4.version}var VERSION=manifestVersion(),USER_AGENT=`${PACKAGE}@${VERSION}`,APP_DIR="sr-connect";var import_picocolors=__toESM(require_picocolors(),1);import{appendFileSync}from"fs";import{homedir}from"os";import{resolve as resolve2,sep as sep2}from"path";var EXIT={OK:0,API_ERROR:1,USAGE:2,UNAUTHENTICATED:3,NOT_FOUND:4,CANCELLED:130},rawMode=!1;function configureRawMode(opts){let value=process.env.SR_CONNECT_CLI_RAW;rawMode=opts.enabled===!0||value!==void 0&&!/^(0|false|no|off|)$/i.test(value.trim())}function isRaw(){return rawMode}var promptsAllowed=!0;function setPromptsAllowed(allowed){promptsAllowed=allowed}var agentMode=!1;function agentEnvOn(){let value=process.env.SR_CONNECT_CLI_AGENT;return value!==void 0&&!/^(0|false|no|off|)$/i.test(value.trim())}function configureAgentMode(opts){agentMode=opts.enabled===!0||agentEnvOn()}function isAgent(){return agentMode}function promptsDeclined(){return!promptsAllowed||agentMode}function supplyHint(opts={}){let pass=opts.pass??"Pass it",env=opts.env===void 0?"":`, set ${opts.env}`,ask=opts.ask??"pick one";return promptsDeclined()?`${pass}${env}, or ${restorePrompts()} and run on a terminal to ${ask}.`:`${pass}${env}, or run on a terminal to ${ask}.`}function restorePrompts(){return agentMode?agentEnvOn()?"unset SR_CONNECT_CLI_AGENT":"drop --agent":process.env.SR_CONNECT_CLI_NO_PROMPTS?"unset SR_CONNECT_CLI_NO_PROMPTS":"drop --no-prompts"}function canPrompt(){return promptsAllowed&&!agentMode&&!!(process.stdin.isTTY&&process.stderr.isTTY)}var copyPath;function generatedOutputName(){return`output-${Math.floor(Date.now()/1e3)}.${rawMode?"json":"txt"}`}function setOutputCopy(target){if(!target){copyPath=void 0;return}let name=typeof target=="string"&&target.trim()!==""?target.trim():void 0,path2=resolve2(name??generatedOutputName());try{appendFileSync(path2,"")}catch(err){fail(EXIT.USAGE,"OUTPUT_FILE_ERROR",`--copy-output-to-file ${path2} is not writable: ${err instanceof Error?err.message:String(err)}`)}return copyPath=path2,path2}function outputCopyPath(){return copyPath}function assertOutputCopyValue(argv2,commandNames){for(let[at2,token]of argv2.entries()){if(token!=="--copy-output-to-file")continue;let value=argv2[at2+1];value===void 0||value.startsWith("-")||!commandNames.includes(value)||fail(EXIT.USAGE,"OUTPUT_FILE_ERROR",`--copy-output-to-file took '${value}' as the file name, which is a command group; the file name is optional and the next word is taken as it.`,{hint:`Put the flag after the command, or name the file: --copy-output-to-file ./${value} if that really is the file.`})}}function assertVersionFlagIsRoot(argv2,commandNames){let rest=argv2.slice(2),flag=rest.find(a=>a==="-V"||a==="--version");if(flag===void 0)return;let group=rest.findIndex(a=>!a.startsWith("-")&&commandNames.includes(a));if(group===-1)return;let verb=rest[group+1],command=verb!==void 0&&!verb.startsWith("-")?`${rest[group]} ${verb}`:rest[group];fail(EXIT.USAGE,"USAGE_ERROR",`${flag} prints this CLI's own version and belongs to the root, so it would have sent nothing and exited 0.`,{hint:`Drop it to run '${command}', or use the flag the verb means: --release-version for a release, --package-version for a package.`})}function reportOutputCopy(){if(copyPath===void 0)return;let line=`Output copied to ${copyPath}`;rawMode?console.error(import_picocolors.default.dim(line)):console.log(import_picocolors.default.green(line))}async function flushOutput(){let drain=stream=>new Promise(done=>{if(stream.writableLength===0){done();return}stream.write("",()=>done())});await Promise.all([drain(process.stdout),drain(process.stderr)])}function ignoreBrokenPipe(){for(let stream of[process.stdout,process.stderr])stream.on("error",err=>{throw(err.code==="EPIPE"||err.code==="ERR_STREAM_DESTROYED")&&process.exit(EXIT.OK),err})}function displayPath(path2,home=safeHomedir()){if(process.platform==="win32")return path2;let base=home.endsWith(sep2)?home.slice(0,-sep2.length):home;return base===""||base===sep2?path2:path2===base?"~":path2.startsWith(base+sep2)?`~${path2.slice(base.length)}`:path2}function shellQuote(value){return/^[\w.:@/+-]+$/.test(value)?value:`'${value.replaceAll("'","'\\''")}'`}function safeHomedir(){try{return homedir()}catch{return""}}var ANSI=new RegExp("\x1B\\[[0-9;]*m","g");function stripAnsi(text){return text.replaceAll(ANSI,"")}function emit(text){console.log(text),appendCopy(`${text}
28
28
  `)}function appendCopy(text){if(copyPath!==void 0)try{appendFileSync(copyPath,stripAnsi(text))}catch(err){let message=err instanceof Error?err.message:String(err);console.error(import_picocolors.default.yellow(`\u26A0 Could not append to ${copyPath}: ${message}`)),copyPath=void 0}}function describeError(err,depth=0){if(!(err instanceof Error))return String(err);let code=err.code,head=typeof code=="string"&&!err.message.includes(code)?`${err.message} (${code})`:err.message;if(depth>=3)return head;let nested=err instanceof AggregateError&&err.errors.length>0?err.errors[0]:err.cause;if(nested==null)return head;let tail=describeError(nested,depth+1);return head===""?tail:`${head}: ${tail}`}var CliError=class extends Error{exitCode;code;hint;status;tone;banner;expected;constructor(exitCode,code,message,opts){super(message),this.exitCode=exitCode,this.code=code,this.hint=opts?.hint,this.status=opts?.status,this.tone=opts?.tone??"error",this.banner=opts?.banner,this.expected=opts?.expected??!1}};function fail(exitCode,code,message,opts){throw new CliError(exitCode,code,message,opts)}function reportError(err){if(rawMode){let envelope={code:err.code,message:err.message};err.status!==void 0&&(envelope.status=err.status),err.hint!==void 0&&(envelope.hint=err.hint),emit(JSON.stringify({error:envelope}))}else if(err.banner?.length)for(let line of err.banner)console.error(import_picocolors.default.red(line));else console.error(err.tone==="ok"?import_picocolors.default.green(`\u2714 ${err.message}`):import_picocolors.default.red(`\u2716 ${err.message}`)),err.hint&&console.error(import_picocolors.default.dim(` ${err.hint}`));return err.exitCode}function isPrimitive(v2){return v2===null||["string","number","boolean"].includes(typeof v2)}function cell(v2){return v2==null?"":isPrimitive(v2)?String(v2):typeof v2=="object"&&"name"in v2&&isPrimitive(v2.name)?String(v2.name):JSON.stringify(v2)}function humanizeKey(key){return key.replaceAll(/([a-z0-9])([A-Z])/g,"$1_$2").replaceAll(/[\s-]+/g,"_").toUpperCase()}function tableRows(columns,rows2){return rows2.map(row=>Object.fromEntries(columns.map(column=>[column,row[column]??null])))}function renderTable(rows2){if(rows2.length===0)return import_picocolors.default.dim("(no results)");let cols=[];for(let row of rows2)for(let key of Object.keys(row))cols.includes(key)||cols.push(key);let headers=cols.map(humanizeKey),widths=cols.map((c,i)=>Math.max(headers[i]?.length??0,...rows2.map(r=>cell(r[c]).length))),line=vals=>vals.map((v2,i)=>v2.padEnd(widths[i]??0)).join(" ").trimEnd();return[import_picocolors.default.bold(line(headers)),...rows2.map(r=>line(cols.map(c=>cell(r[c]))))].join(`
29
29
  `)}function isNamedResource(v2){return typeof v2=="object"&&v2!==null&&!Array.isArray(v2)&&"name"in v2&&typeof v2.name=="string"}function detailValue(v2){if(v2!==void 0){if(v2===null)return"";if(isPrimitive(v2))return String(v2);if(isNamedResource(v2))return v2.id!==void 0?`${v2.name} (${v2.id})`:v2.name;if(Array.isArray(v2))return v2.every(isPrimitive)?v2.map(String).join(", "):v2.every(isNamedResource)?v2.map(item=>detailValue(item)??"").join(", "):JSON.stringify(v2)}}var WARNING_GLYPH="\u26A0";function isWarning(line){return line.trimStart().startsWith(WARNING_GLYPH)}function formatBytes(bytes){return bytes<1024?`${bytes} B`:bytes<1024*1024?`${trimmedNumber(bytes/1024)} KiB`:`${trimmedNumber(bytes/(1024*1024))} MiB`}function trimmedNumber(value){return String(Number(value.toFixed(1)))}function grouped(bytes){return String(bytes).replace(/\B(?=(\d{3})+(?!\d))/g,",")}function sizesAgainstCap(bytes,cap){let actual=formatBytes(bytes),capped=formatBytes(cap);return actual!==capped?{actual,cap:capped}:{actual:`${grouped(bytes)} bytes`,cap:`${capped} (${grouped(cap)} bytes)`}}function warnLine(line){process.stderr.write(`${import_picocolors.default.yellow(line)}
30
30
  `)}function noteLine(line){process.stderr.write(`${line}
@@ -33,13 +33,13 @@ Expecting one of '${allowedValues.join("', '")}'`);let helpEvent=`${position}Hel
33
33
  `).join(`
34
34
  ${continuation}`);return`${import_picocolors.default.dim(label.padEnd(width))} ${aligned2}`}).join(`
35
35
  `)}function renderHuman(data){if(typeof data=="string")return data;let rows2=data;if(rows2&&typeof rows2=="object"&&!Array.isArray(rows2)){let arrayProps=Object.entries(rows2).filter(([,v2])=>Array.isArray(v2));arrayProps.length===1&&Object.keys(rows2).length===1&&(rows2=arrayProps[0]?.[1])}return Array.isArray(rows2)?renderTable(rows2):data&&typeof data=="object"?renderDetail(data):JSON.stringify(data,null,2)}function ok(data,opts){emit(rawMode?JSON.stringify(data):renderHuman(opts?.human?opts.human(data):data))}function okText(text){emit(text)}function okFile(bytes){process.stdout.write(bytes),appendCopy(bytes)}function okMutation(message,payload,detail){if(rawMode){emit(JSON.stringify(payload));return}emit(detail===void 0?import_picocolors.default.green(`\u2714 ${message}.`):`${import_picocolors.default.green(`\u2714 ${message}:`)}
36
- ${renderHuman(detail)}`)}var KNOWN_INSTANCES={eu:{label:"EU",url:"https://api.scriptrunnerconnect.com",appUrl:"https://app.eu.scriptrunnerconnect.com"},us:{label:"US",url:"https://api.us.scriptrunnerconnect.com",appUrl:"https://app.us.scriptrunnerconnect.com"}},INSTANCE_KEYS=Object.keys(KNOWN_INSTANCES);function knownInstance(value){return KNOWN_INSTANCES[value]}var INSTANCE_FORMAT=`${INSTANCE_KEYS.join(", ")}, or an API base URL (e.g. https://api.example.com)`;function parseInstance(raw){let value=raw.trim();if(value==="")return{error:`An instance is required: ${INSTANCE_FORMAT}.`};let lower=value.toLowerCase();if(knownInstance(lower))return{instance:lower};let withScheme=/^[a-z][a-z0-9+.-]*:\/\//i.test(value)?value:`https://${value}`,url2;try{url2=new URL(withScheme)}catch{return{error:`'${value}' is not a valid instance \u2014 use ${INSTANCE_FORMAT}.`}}return url2.protocol!=="https:"&&url2.protocol!=="http:"?{error:`An instance URL must be http:// or https:// \u2014 '${value}' is ${url2.protocol}//.`}:url2.hostname===""?{error:`'${value}' has no host \u2014 use ${INSTANCE_FORMAT}.`}:url2.username!==""||url2.password!==""?{error:`An instance URL must not embed a username or password \u2014 got '${value}'.`}:url2.search!==""||url2.hash!==""?{error:`An instance URL must not carry a query string or fragment \u2014 got '${value}'.`}:{instance:`${url2.protocol}//${url2.host}${url2.pathname.replace(/\/+$/,"")}`}}function instanceError(value){return parseInstance(value).error}function normalizeInstance(value){let{instance:instance4,error:error51}=parseInstance(value);if(!instance4)throw new Error(error51??`not an instance: '${value}'`);return instance4}function assertInstance(value,origin){let{instance:instance4,error:error51}=parseInstance(value);return instance4||fail(EXIT.USAGE,"INVALID_INSTANCE",`${origin}: ${error51}`),instance4}function configDir(){return join(userConfigHome(process.platform,process.env,homedir2()),APP_DIR)}function userConfigHome(platform2,env,home){let xdg=env.XDG_CONFIG_HOME;if(xdg&&xdg!=="")return xdg;if(platform2==="win32"){let appData=env.APPDATA;return appData&&appData!==""?appData:join(home,"AppData","Roaming")}return join(home,".config")}function readConfig(){try{return JSON.parse(readFileSync2(join(configDir(),"config.json"),"utf8"))}catch{return{}}}function writeConfig(config2){mkdirSync(configDir(),{recursive:!0}),writeFileSync(join(configDir(),"config.json"),JSON.stringify(config2,null,2)+`
37
- `)}function baseUrl(instance4){return knownInstance(instance4)?.url??instance4}function instanceLabel(instance4){let known=knownInstance(instance4);return known?`${known.label} (${known.url})`:instance4}var API_KEYS_PATH="/apiKeys";function apiKeysUrl(instance4){let known=knownInstance(instance4);return known?`${known.appUrl}${API_KEYS_PATH}`:void 0}var LOOPBACK=new Set(["localhost","127.0.0.1","[::1]","::1"]);function insecureInstanceWarning(instance4){let url2=baseUrl(instance4);if(!url2.startsWith("http://"))return;let host;try{host=new URL(url2).hostname}catch{return}if(!LOOPBACK.has(host))return`\u26A0 ${url2} is not HTTPS \u2014 your API credentials are sent unencrypted.`}function explicitInstance(flag){let fromEnv=process.env.SR_CONNECT_CLI_INSTANCE;if(flag!==void 0&&flag!=="")return assertInstance(flag,"--instance");if(fromEnv!==void 0&&fromEnv!=="")return assertInstance(fromEnv,"SR_CONNECT_CLI_INSTANCE")}function resolveInstance(flag){let explicit2=explicitInstance(flag);if(explicit2!==void 0)return explicit2;let stored=readConfig().instance;if(stored!==void 0&&stored!=="")return assertInstance(stored,`the instance in ${join(configDir(),"config.json")}`)}var RUN_ID=`${Date.now().toString(36)}-${process.pid}`;import{createHash}from"crypto";import{fstatSync,mkdirSync as mkdirSync2,readFileSync as readFileSync3,readdirSync,renameSync,rmSync,statSync,writeFileSync as writeFileSync2}from"fs";import{homedir as homedir3}from"os";import{join as join2}from"path";var SESSION_KEYS=["team","workspace","environment"],SESSION_RECORD_VERSION=2,SESSION_TTL_MS=720*60*1e3,PRUNE_MS=10080*60*1e3,LOCK_KEEP_MS=3600*1e3,runtimeInstance,enabled=!0;function configureSession(opts){runtimeInstance=opts.instance,enabled=opts.enabled!==!1}function sessionEnabled(){return enabled}function stateHome(){return userStateHome(process.platform,process.env,homedir3())}function userStateHome(platform2,env,home){let explicit2=env.SR_CONNECT_CLI_STATE_HOME;if(explicit2&&explicit2!=="")return explicit2;let xdg=env.XDG_STATE_HOME;if(xdg&&xdg!=="")return xdg;if(platform2==="win32"){let local=env.LOCALAPPDATA;return local&&local!==""?local:join2(home,"AppData","Local")}return join2(home,".local","state")}function sessionsDir(){return join2(stateHome(),APP_DIR,"sessions")}var sanitize=v2=>v2.replace(/[^A-Za-z0-9_.-]/g,"_").slice(0,96);function terminalMarker(){let pair=(a,b2)=>a&&a!==""?`${a}:${b2??""}`:void 0;return[process.env.TERM_SESSION_ID,process.env.ITERM_SESSION_ID,pair(process.env.WEZTERM_UNIX_SOCKET,process.env.WEZTERM_PANE),pair(process.env.KITTY_PID,process.env.KITTY_WINDOW_ID),process.env.ALACRITTY_WINDOW_ID,process.env.WT_SESSION,pair(process.env.TMUX,process.env.TMUX_PANE),process.env.STY].find(c=>c&&c!=="")}function sessionKey(){let explicit2=process.env.SR_CONNECT_CLI_SESSION_ID;if(explicit2&&explicit2!=="")return`id-${sanitize(explicit2)}`;let marker=terminalMarker();if(marker)return`mark-${sanitize(marker)}`;for(let fd of[0,1,2])try{let st2=fstatSync(fd);if(st2.isCharacterDevice()&&st2.rdev)return`tty-${st2.rdev}`}catch{}return process.ppid?`ppid-${process.ppid}`:void 0}function instanceSlug(instance4){return createHash("sha256").update(instance4).digest("hex").slice(0,12)}function sessionFile(){let key=sessionKey();if(!key)return;let instance4=effectiveInstance();return join2(sessionsDir(),instance4?`${key}.${instanceSlug(instance4)}.json`:`${key}.json`)}function hasScope(record4){return!!(record4&&SESSION_KEYS.some(k2=>record4[k2]))}function effectiveInstance(){return resolveInstance(runtimeInstance)}function readSession(){if(!enabled)return;let file2=sessionFile();if(!file2)return;let record4;try{record4=JSON.parse(readFileSync3(file2,"utf8"))}catch{return}if(record4.version!==SESSION_RECORD_VERSION){dropSession(file2);return}let age=Date.now()-Date.parse(record4.updatedAt);if(!Number.isFinite(age)||age>SESSION_TTL_MS){dropSession(file2);return}let instance4=effectiveInstance();if(record4.instance&&instance4&&record4.instance!==instance4){warnStrandedLocks(pruneLocks(record4.locks)),dropSession(file2),hasScope(record4)&&(instanceCleared=instanceLabel(record4.instance));return}return record4}function warnStrandedLocks(locks){if(!locks)return;let kept=keptLocksOf(locks);if(kept.length!==0){warnLine(`${kept.length} workspace lock${kept.length===1?"":"s"} taken against another instance cannot be presented from here and are being forgotten.`);for(let lock of kept)warnLine(` ${lockReleaseCommand(lock)}`)}}var instanceCleared;function takeInstanceClear(){let cleared=instanceCleared;return instanceCleared=void 0,cleared}function readRecord(file2,opts={}){let record4;try{record4=JSON.parse(readFileSync3(file2,"utf8"))}catch{return}if(record4.version!==SESSION_RECORD_VERSION)return;let age=Date.now()-Date.parse(record4.updatedAt);if(!Number.isFinite(age)||age>SESSION_TTL_MS)return;if(opts.anyInstance)return record4;let instance4=effectiveInstance();if(!(record4.instance&&instance4&&record4.instance!==instance4))return record4}function prune(dir){try{for(let name of readdirSync(dir)){if(!name.endsWith(".json"))continue;let path2=join2(dir,name);try{Date.now()-statSync(path2).mtimeMs>PRUNE_MS&&rmSync(path2)}catch{}}}catch{}}function writeSession(record4){let file2=sessionFile();file2||fail(EXIT.USAGE,"NO_SESSION","No shell session detected (no TTY). Set SR_CONNECT_CLI_SESSION_ID, or pass --team/-w/-e explicitly."),persist(file2,record4)}function persist(file2,record4,instance4,options){let dir=sessionsDir();mkdirSync2(dir,{recursive:!0,mode:448}),prune(dir);let existing=options?.replace?void 0:readRecord(file2),carried=record4.serviceInfo??existing?.serviceInfo,locks=pruneLocks("locks"in record4?record4.locks:existing?.locks),update=record4.updateCheck??existing?.updateCheck,payload={...record4,version:SESSION_RECORD_VERSION,...carried===void 0?{}:{serviceInfo:carried},...locks===void 0?{}:{locks},...update===void 0?{}:{updateCheck:update},instance:instance4??effectiveInstance(),updatedAt:new Date().toISOString()},tmp=`${file2}.${process.pid}.tmp`;try{writeFileSync2(tmp,JSON.stringify(payload)+`
38
- `,{mode:384}),renameSync(tmp,file2)}catch(err){throw rmSync(tmp,{force:!0}),err}}function pruneLocks(locks){if(!locks)return;let kept=Object.fromEntries(Object.entries(locks).filter(([,lock])=>{let expiry=Date.parse(lock.expiresAt);return!Number.isFinite(expiry)||Date.now()-expiry<LOCK_KEEP_MS}));return Object.keys(kept).length>0?kept:void 0}function readWorkspaceLock(workspaceId){let file2=sessionFile();if(file2)return readRecord(file2)?.locks?.[workspaceId]}function storeWorkspaceLock(workspaceId,lock){let file2=sessionFile();if(!file2)return!1;try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,locks,...rest}=existing??{};return persist(file2,{...rest,locks:{...locks,[workspaceId]:lock}}),!0}catch{return!1}}function forgetWorkspaceLock(workspaceId){let file2=sessionFile();if(!file2)return;let existing=readRecord(file2);if(existing?.locks?.[workspaceId])try{let{instance:_instance,updatedAt:_updatedAt,locks,...rest}=existing,remaining={...locks};delete remaining[workspaceId],persist(file2,{...rest,locks:remaining})}catch{}}function cachedServiceInfo(){return readSession()?.serviceInfo}function cacheServiceInfo(info){if(!enabled)return;let file2=sessionFile();if(file2)try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,...rest}=existing??{};persist(file2,{...rest,serviceInfo:info})}catch{}}function readUpdateCheck(){let file2=sessionFile();if(file2)return readRecord(file2)?.updateCheck}function storeUpdateCheck(check2){let file2=sessionFile();if(file2)try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,...rest}=existing??{};persist(file2,{...rest,updateCheck:check2})}catch{}}function forgetScopeValue(key,value,dependents=[]){if(!enabled)return[];let file2=sessionFile();if(!file2)return[];let existing=readRecord(file2);if(!existing||existing[key]!==value)return[];try{let{instance:_instance,updatedAt:_updatedAt,labels,...rest}=existing,removed=[key];delete rest[key];let remaining={...labels};delete remaining[key];for(let dependent of dependents)rest[dependent]!==void 0&&removed.push(dependent),delete rest[dependent],delete remaining[dependent];return persist(file2,{...rest,...Object.keys(remaining).length>0?{labels:remaining}:{}}),removed}catch{return[]}}function lockReleaseCommand(lock){let instance4=lock.instance?` --instance ${shellQuote(lock.instance)}`:"";return`${CLI} workspace-lock release -w ${lock.workspaceId} --lock-id ${lock.lockId}${instance4}`}function dropSession(file2){try{return rmSync(file2),!0}catch{return!1}}function clearSession(){let file2=sessionFile();if(!file2)return{cleared:!1,keptLocks:[]};let existing=readRecord(file2),locks=pruneLocks(existing?.locks);if(!locks)return{cleared:dropSession(file2),keptLocks:[]};let kept=keptLocksOf(locks);try{return persist(file2,{locks},void 0,{replace:!0}),{cleared:!0,keptLocks:kept}}catch{return{cleared:dropSession(file2),keptLocks:kept}}}function clearAllSessions(){let removed=0,keptLocks=[];try{for(let name of readdirSync(sessionsDir())){if(!name.endsWith(".json"))continue;let file2=join2(sessionsDir(),name),record4=readRecord(file2,{anyInstance:!0}),locks=pruneLocks(record4?.locks);try{locks?(persist(file2,{locks},record4?.instance,{replace:!0}),keptLocks.push(...keptLocksOf(locks,record4?.instance))):rmSync(file2),removed+=1}catch{}}}catch{}return{removed,keptLocks}}function keptLocksOf(locks,instance4){let now=Date.now(),foreign=instance4!==void 0&&instance4!==effectiveInstance()?{instance:instance4}:{};return Object.entries(locks).filter(([,lock])=>Date.parse(lock.expiresAt)>now).map(([workspaceId,lock])=>({workspaceId,lockId:lock.lockId,...foreign}))}function describeValue(record4,key){let id=record4[key]??"",label=record4.labels?.[key];return label?`${label} (${id})`:id}import{mkdirSync as mkdirSync3,readFileSync as readFileSync4,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync3}from"fs";import{join as join3}from"path";var SETTING_KEYS=["recordApiCalls","workspaceLock","localSync","crashReports","agenticFeedback"],SETTINGS={recordApiCalls:{label:"Record API calls",hint:"records this CLI's own requests to a local log, readable with `cli list-api-logs` \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_RECORD_API_CALLS",flag:"--no-record-api-calls"},workspaceLock:{label:"Auto workspace lock",hint:"takes a workspace lock before a write, so nothing else changes the workspace mid-command \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_LOCK",flag:"--no-lock"},localSync:{label:"Auto local sync",hint:"mirrors a change into the local copy of the workspace, if the local directory is a local workspace clone \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_LOCAL_SYNC",flag:"--no-local-sync"},crashReports:{label:"Generate crash reports",hint:"writes a report when a run fails unexpectedly, and offers to send it \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_CRASH_REPORTS",flag:"--no-crash-reports"},agenticFeedback:{label:"Allow agentic feedback",hint:"allows agents to send feedback autonomously for improvements \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_AGENTIC_FEEDBACK",flag:"--no-agentic-feedback"}},SETTINGS_VERSION=1;function settingsFile(){return join3(stateHome(),APP_DIR,"settings.json")}var cache,warned=!1;function readSettings(){if(cache)return cache;let parsed;try{parsed=JSON.parse(readFileSync4(settingsFile(),"utf8"))}catch{return cache={},cache}let file2=parsed;if(typeof file2?.version=="number"&&file2.version>SETTINGS_VERSION)return warned||(warned=!0,warnLine(`\u26A0 ${settingsFile()} was written by a newer CLI (format ${file2.version}) \u2014 using the defaults. Update the CLI to read it.`)),cache={},cache;let values={},stored=file2?.values;if(stored&&typeof stored=="object")for(let key of SETTING_KEYS){let value=stored[key];typeof value=="boolean"&&(values[key]=value)}return cache=values,values}function envDisabled(key){let value=process.env[SETTINGS[key].envVar];return value===void 0?!1:!["","0","false","no","off"].includes(value.trim().toLowerCase())}function settingEnabled(key){return readSettings()[key]!==!1}function writeSettings(values){let forced=[],stored={};for(let key of SETTING_KEYS){if(envDisabled(key)){forced.push(key),stored[key]=!1;continue}values[key]||(stored[key]=!1)}let file2={version:SETTINGS_VERSION,updatedAt:new Date().toISOString(),values:stored},path2=settingsFile();mkdirSync3(join3(stateHome(),APP_DIR),{recursive:!0,mode:448});let tmp=`${path2}.${process.pid}.tmp`;try{writeFileSync3(tmp,JSON.stringify(file2)+`
39
- `,{mode:384}),renameSync2(tmp,path2)}catch(err){throw rmSync2(tmp,{force:!0}),err}return cache=stored,forced}function setSetting(key,value){let stored=readSettings(),values=Object.fromEntries(SETTING_KEYS.map(candidate=>[candidate,candidate===key?value:stored[candidate]!==!1]));return writeSettings(values)}function settingStates(flagOff={}){let stored=readSettings();return SETTING_KEYS.map(key=>{let descriptor=SETTINGS[key],flagDisabled=flagOff[key]===!0,env=envDisabled(key),value=stored[key],source=flagDisabled?"flag":env?"env":value===void 0?"default":"stored";return{key,label:descriptor.label,hint:descriptor.hint,enabled:!flagDisabled&&!env&&value!==!1,stored:value??null,envVar:descriptor.envVar,envDisabled:env,flag:descriptor.flag,flagDisabled,source}})}var ENTRY_VERSION=2,MAX_BODY=4*1024,PRUNE_MS2=10080*60*1e3,MAX_SESSION_BYTES=25*1024*1024,ROLLED=".1.jsonl",SECRET_KEY=/password|secret|token|credential|apikey|authorization|lockid/i,SECRET_PARAM=/^(x-amz-signature|x-amz-credential|x-amz-security-token|signature|awsaccesskeyid|googleaccessid|sig|se|sp|sig_key|token|password|apikey)$/i,REDACTED="<redacted>",KEEP_HEADERS=["content-type","content-length","retry-after","x-sr-connect-workspace-lock-expires-at","x-request-id","x-amzn-requestid","x-amzn-trace-id"],enabled2=!1,argv=[],instance,runId="",runSequence=0,runStarted="",runWritten=!1,maintained=!1,SECRET_ARGV_FLAG=/^(--header|--lock-id)(=|$)/;function redactArg(flag,value){if(flag.startsWith("--lock-id"))return REDACTED;let at2=value.indexOf(":");return at2===-1?REDACTED:`${value.slice(0,at2)}: ${REDACTED}`}function sanitizeArgv(tokens){let out=[];for(let i=0;i<tokens.length;i++){let token=tokens[i]??"";if(!SECRET_ARGV_FLAG.test(token)){out.push(token);continue}let eq=token.indexOf("=");if(eq!==-1){out.push(`${token.slice(0,eq)}=${redactArg(token,token.slice(eq+1))}`);continue}out.push(token);let next=tokens[i+1];next!==void 0&&(out.push(redactArg(token,next)),i++)}return out}function configureRecorder(opts){let off=process.env.SR_CONNECT_CLI_NO_RECORD_API_CALLS;enabled2=opts.enabled!==!1&&(off===void 0||/^(0|false|no|off|)$/i.test(off.trim()))&&settingEnabled("recordApiCalls"),instance=opts.instance,argv=sanitizeArgv(process.argv.slice(2)),runStarted=new Date().toISOString(),runSequence+=1,runId=`${RUN_ID}-${runSequence}`,runWritten=!1,maintained=!1}function recordingEnabled(){return enabled2}function apiCallsDir(){return join4(stateHome(),APP_DIR,"api-calls")}function sessionFile2(key){return join4(apiCallsDir(),`${key}.jsonl`)}function sessionOf(name){return name.replace(/(\.1)?\.jsonl$/,"")}function sanitizeBody(text){if(text==="")return"";let bytes=Buffer.byteLength(text),out;try{out=JSON.stringify(redact(JSON.parse(text)))}catch{return`<non-json, ${bytes} bytes>`}return out.length>MAX_BODY?`${out.slice(0,MAX_BODY)}\u2026(truncated, ${bytes} bytes)`:out}function redactHeaders(value){return Array.isArray(value)?value.map(entry2=>entry2&&typeof entry2=="object"&&!Array.isArray(entry2)&&"name"in entry2&&"value"in entry2?{...entry2,value:REDACTED}:redact(entry2)):redact(value)}function redactAttachments(value){return Array.isArray(value)?value.map(entry2=>entry2&&typeof entry2=="object"&&!Array.isArray(entry2)&&"content"in entry2?{...entry2,content:REDACTED}:redact(entry2)):redact(value)}function redact(value){return Array.isArray(value)?value.map(redact):value&&typeof value=="object"?Object.fromEntries(Object.entries(value).map(([key,child])=>[key,SECRET_KEY.test(key)?REDACTED:key==="headers"?redactHeaders(child):key==="attachments"?redactAttachments(child):redact(child)])):typeof value=="string"&&/^https?:\/\//i.test(value)?sanitizeUrl(value):value}function pickHeaders(headers){let picked={};for(let name of KEEP_HEADERS){let value=headers.get(name);value!==null&&(picked[name]=value)}return picked}function instanceBaseUrl(value=instance){let resolved=resolveInstance(value);return resolved?baseUrl(resolved):void 0}function redactLockPath(url2){return url2.replace(/\/lock\/[^/?#]+/i,`/lock/${REDACTED}`)}function sanitizeUrl(url2,base=instanceBaseUrl()){if(url2=redactLockPath(url2),base!==void 0&&url2.startsWith(base))return url2;let cut=url2.indexOf("?");if(cut===-1)return url2;let query=url2.slice(cut+1).split("&").map(pair=>{let eq=pair.indexOf("="),name=eq===-1?pair:pair.slice(0,eq);return SECRET_PARAM.test(name)?`${name}=${REDACTED}`:pair}).join("&");return`${url2.slice(0,cut)}?${query}`}function recordApiCall(call){if(!enabled2)return;let key=sessionKey();if(!key)return;let path2=sessionFile2(key);try{mkdirSync4(apiCallsDir(),{recursive:!0,mode:448}),maintainOnce(path2,key);let lines=[];runWritten||lines.push({v:ENTRY_VERSION,t:"run",runId,ts:runStarted,argv,pid:process.pid,...instance===void 0?{}:{instance}}),lines.push({v:ENTRY_VERSION,t:"call",runId,...call,url:sanitizeUrl(call.url)}),appendFileSync2(path2,lines.map(line=>`${JSON.stringify(line)}
40
- `).join(""),{mode:384}),runWritten=!0}catch(err){enabled2=!1;let message=err instanceof Error?err.message:String(err);warnLine(`\u26A0 Could not record API calls to ${path2}: ${message}`)}}function maintainOnce(path2,key){maintained||(maintained=!0,prune2(),roll(path2,key))}function prune2(){for(let name of listFiles()){let path2=join4(apiCallsDir(),name);try{Date.now()-statSync2(path2).mtimeMs>PRUNE_MS2&&rmSync3(path2)}catch{}}}function roll(path2,key){try{if(statSync2(path2).size<MAX_SESSION_BYTES)return;renameSync3(path2,join4(apiCallsDir(),`${key}${ROLLED}`))}catch{}}function listFiles(){try{return readdirSync2(apiCallsDir()).filter(name=>name.endsWith(".jsonl")).sort()}catch{return[]}}function filesToRead(opts){if(opts.allSessions)return listFiles();let key=opts.session??sessionKey();if(!key)return[];let present=new Set(listFiles());return[`${key}${ROLLED}`,`${key}.jsonl`].filter(name=>present.has(name))}function parseFile(name){let text;try{text=readFileSync5(join4(apiCallsDir(),name),"utf8")}catch{return[]}let lines=[];for(let line of text.split(`
41
- `))if(line.trim()!=="")try{let parsed=JSON.parse(line);parsed.v===ENTRY_VERSION&&lines.push(parsed)}catch{}return lines}function readApiCalls(opts){let runs=[],byId=new Map;for(let name of filesToRead(opts)){let session=sessionOf(name),runOf=(id,ts)=>{let runKey=`${session}\0${id}`,known=byId.get(runKey);if(known)return known;let created={runId:id,ts,argv:[],pid:0,session,calls:[],totalCalls:0};return byId.set(runKey,created),runs.push(created),created};for(let line of parseFile(name)){if(line.t==="run"){let run2=runOf(line.runId,line.ts);run2.ts=line.ts,run2.argv=line.argv,run2.pid=line.pid,run2.instance=line.instance;continue}let run=runOf(line.runId,line.ts),{v:_version,t:_type,runId:_runId,...call}=line;run.calls.push(call),run.totalCalls+=1}}return runs.sort((a,b2)=>a.ts.localeCompare(b2.ts))}function listRecordedSessions(){return summarize(listFiles())}function recordedTargets(opts){return summarize(filesToRead(opts))}function summarize(names){let rows2=new Map;for(let name of names){let session=sessionOf(name),row=rows2.get(session)??{session,files:0,runs:0,calls:0,bytes:0},lines=parseFile(name),calls=lines.filter(line=>line.t==="call");row.files+=1,row.runs+=lines.filter(line=>line.t==="run").length,row.calls+=calls.length,row.first??=calls[0]?.ts,row.last=calls.at(-1)?.ts??row.last;try{row.bytes+=statSync2(join4(apiCallsDir(),name)).size}catch{}rows2.set(session,row)}return[...rows2.values()]}function clearApiCalls(opts){let removed=new Set;for(let name of filesToRead(opts))try{rmSync3(join4(apiCallsDir(),name)),removed.add(sessionOf(name))}catch{}return[...removed]}import{closeSync,mkdirSync as mkdirSync6,openSync,readFileSync as readFileSync8,readSync,readdirSync as readdirSync4,rmSync as rmSync5,statSync as statSync4,writeFileSync as writeFileSync5}from"fs";import{arch,platform,release}from"os";import{join as join8}from"path";var PATH_PARAM_RE=/\{[^{}]+\}/g,supportsRequestInitExt=()=>typeof process=="object"&&Number.parseInt(process?.versions?.node?.substring(0,2))>=18&&process.versions.undici;function randomID(){return Math.random().toString(36).slice(2,11)}function createClient(clientOptions){let{baseUrl:baseUrl2="",Request:CustomRequest=globalThis.Request,fetch:baseFetch=globalThis.fetch,querySerializer:globalQuerySerializer,bodySerializer:globalBodySerializer,pathSerializer:globalPathSerializer,headers:baseHeaders,requestInitExt=void 0,...baseOptions}={...clientOptions};requestInitExt=supportsRequestInitExt()?requestInitExt:void 0,baseUrl2=removeTrailingSlash(baseUrl2);let globalMiddlewares=[];async function coreFetch(schemaPath,fetchOptions){let{baseUrl:localBaseUrl,fetch:fetch2=baseFetch,Request:Request2=CustomRequest,headers,params={},parseAs="json",querySerializer:requestQuerySerializer,bodySerializer=globalBodySerializer??defaultBodySerializer,pathSerializer:requestPathSerializer,body,middleware:requestMiddlewares=[],...init}=fetchOptions||{},finalBaseUrl=baseUrl2;localBaseUrl&&(finalBaseUrl=removeTrailingSlash(localBaseUrl)??baseUrl2);let querySerializer=typeof globalQuerySerializer=="function"?globalQuerySerializer:createQuerySerializer(globalQuerySerializer);requestQuerySerializer&&(querySerializer=typeof requestQuerySerializer=="function"?requestQuerySerializer:createQuerySerializer({...typeof globalQuerySerializer=="object"?globalQuerySerializer:{},...requestQuerySerializer}));let pathSerializer=requestPathSerializer||globalPathSerializer||defaultPathSerializer,serializedBody=body===void 0?void 0:bodySerializer(body,mergeHeaders(baseHeaders,headers,params.header)),finalHeaders=mergeHeaders(serializedBody===void 0||serializedBody instanceof FormData?{}:{"Content-Type":"application/json"},baseHeaders,headers,params.header),finalMiddlewares=[...globalMiddlewares,...requestMiddlewares],requestInit={redirect:"follow",...baseOptions,...init,body:serializedBody,headers:finalHeaders},id,options,request=new Request2(createFinalURL(schemaPath,{baseUrl:finalBaseUrl,params,querySerializer,pathSerializer}),requestInit),response;for(let key in init)key in request||(request[key]=init[key]);if(finalMiddlewares.length){id=randomID(),options=Object.freeze({baseUrl:finalBaseUrl,fetch:fetch2,parseAs,querySerializer,bodySerializer,pathSerializer});for(let m2 of finalMiddlewares)if(m2&&typeof m2=="object"&&typeof m2.onRequest=="function"){let result=await m2.onRequest({request,schemaPath,params,options,id});if(result)if(result instanceof Request2)request=result;else if(result instanceof Response){response=result;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!response){try{response=await fetch2(request,requestInitExt)}catch(error210){let errorAfterMiddleware=error210;if(finalMiddlewares.length)for(let i=finalMiddlewares.length-1;i>=0;i--){let m2=finalMiddlewares[i];if(m2&&typeof m2=="object"&&typeof m2.onError=="function"){let result=await m2.onError({request,error:errorAfterMiddleware,schemaPath,params,options,id});if(result){if(result instanceof Response){errorAfterMiddleware=void 0,response=result;break}if(result instanceof Error){errorAfterMiddleware=result;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(errorAfterMiddleware)throw errorAfterMiddleware}if(finalMiddlewares.length)for(let i=finalMiddlewares.length-1;i>=0;i--){let m2=finalMiddlewares[i];if(m2&&typeof m2=="object"&&typeof m2.onResponse=="function"){let result=await m2.onResponse({request,response,schemaPath,params,options,id});if(result){if(!(result instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");response=result}}}}let contentLength=response.headers.get("Content-Length");if(response.status===204||request.method==="HEAD"||contentLength==="0"&&!response.headers.get("Transfer-Encoding")?.includes("chunked"))return response.ok?{data:void 0,response}:{error:void 0,response};if(response.ok)return{data:await(async()=>{if(parseAs==="stream")return response.body;if(parseAs==="json"&&!contentLength){let raw=await response.text();return raw?JSON.parse(raw):void 0}return await response[parseAs]()})(),response};let error51=await response.text();try{error51=JSON.parse(error51)}catch{}return{error:error51,response}}return{request(method,url2,init){return coreFetch(url2,{...init,method:method.toUpperCase()})},GET(url2,init){return coreFetch(url2,{...init,method:"GET"})},PUT(url2,init){return coreFetch(url2,{...init,method:"PUT"})},POST(url2,init){return coreFetch(url2,{...init,method:"POST"})},DELETE(url2,init){return coreFetch(url2,{...init,method:"DELETE"})},OPTIONS(url2,init){return coreFetch(url2,{...init,method:"OPTIONS"})},HEAD(url2,init){return coreFetch(url2,{...init,method:"HEAD"})},PATCH(url2,init){return coreFetch(url2,{...init,method:"PATCH"})},TRACE(url2,init){return coreFetch(url2,{...init,method:"TRACE"})},use(...middleware){for(let m2 of middleware)if(m2){if(typeof m2!="object"||!("onRequest"in m2||"onResponse"in m2||"onError"in m2))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");globalMiddlewares.push(m2)}},eject(...middleware){for(let m2 of middleware){let i=globalMiddlewares.indexOf(m2);i!==-1&&globalMiddlewares.splice(i,1)}}}}function serializePrimitiveParam(name,value,options){if(value==null)return"";if(typeof value=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return`${name}=${options?.allowReserved===!0?value:encodeURIComponent(value)}`}function serializeObjectParam(name,value,options){if(!value||typeof value!="object")return"";let values=[],joiner={simple:",",label:".",matrix:";"}[options.style]||"&";if(options.style!=="deepObject"&&options.explode===!1){for(let k2 in value)values.push(k2,options.allowReserved===!0?value[k2]:encodeURIComponent(value[k2]));let final2=values.join(",");switch(options.style){case"form":return`${name}=${final2}`;case"label":return`.${final2}`;case"matrix":return`;${name}=${final2}`;default:return final2}}for(let k2 in value){let finalName=options.style==="deepObject"?`${name}[${k2}]`:k2;values.push(serializePrimitiveParam(finalName,value[k2],options))}let final=values.join(joiner);return options.style==="label"||options.style==="matrix"?`${joiner}${final}`:final}function serializeArrayParam(name,value,options){if(!Array.isArray(value))return"";if(options.explode===!1){let joiner2={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[options.style]||",",final=(options.allowReserved===!0?value:value.map(v2=>encodeURIComponent(v2))).join(joiner2);switch(options.style){case"simple":return final;case"label":return`.${final}`;case"matrix":return`;${name}=${final}`;default:return`${name}=${final}`}}let joiner={simple:",",label:".",matrix:";"}[options.style]||"&",values=[];for(let v2 of value)options.style==="simple"||options.style==="label"?values.push(options.allowReserved===!0?v2:encodeURIComponent(v2)):values.push(serializePrimitiveParam(name,v2,options));return options.style==="label"||options.style==="matrix"?`${joiner}${values.join(joiner)}`:values.join(joiner)}function createQuerySerializer(options){return function(queryParams){let search=[];if(queryParams&&typeof queryParams=="object")for(let name in queryParams){let value=queryParams[name];if(value!=null){if(Array.isArray(value)){if(value.length===0)continue;search.push(serializeArrayParam(name,value,{style:"form",explode:!0,...options?.array,allowReserved:options?.allowReserved||!1}));continue}if(typeof value=="object"){search.push(serializeObjectParam(name,value,{style:"deepObject",explode:!0,...options?.object,allowReserved:options?.allowReserved||!1}));continue}search.push(serializePrimitiveParam(name,value,options))}}return search.join("&")}}function defaultPathSerializer(pathname,pathParams){let nextURL=pathname;for(let match of pathname.match(PATH_PARAM_RE)??[]){let name=match.substring(1,match.length-1),explode=!1,style="simple";if(name.endsWith("*")&&(explode=!0,name=name.substring(0,name.length-1)),name.startsWith(".")?(style="label",name=name.substring(1)):name.startsWith(";")&&(style="matrix",name=name.substring(1)),!pathParams||pathParams[name]===void 0||pathParams[name]===null)continue;let value=pathParams[name];if(Array.isArray(value)){nextURL=nextURL.replace(match,serializeArrayParam(name,value,{style,explode}));continue}if(typeof value=="object"){nextURL=nextURL.replace(match,serializeObjectParam(name,value,{style,explode}));continue}if(style==="matrix"){nextURL=nextURL.replace(match,`;${serializePrimitiveParam(name,value)}`);continue}nextURL=nextURL.replace(match,style==="label"?`.${encodeURIComponent(value)}`:encodeURIComponent(value))}return nextURL}function defaultBodySerializer(body,headers){return body instanceof FormData?body:headers&&(headers.get instanceof Function?headers.get("Content-Type")??headers.get("content-type"):headers["Content-Type"]??headers["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(body).toString():JSON.stringify(body)}function createFinalURL(pathname,options){let finalURL=`${options.baseUrl}${pathname}`;options.params?.path&&(finalURL=options.pathSerializer(finalURL,options.params.path));let search=options.querySerializer(options.params.query??{});return search.startsWith("?")&&(search=search.substring(1)),search&&(finalURL+=`?${search}`),finalURL}function mergeHeaders(...allHeaders){let finalHeaders=new Headers;for(let h of allHeaders){if(!h||typeof h!="object")continue;let iterator=h instanceof Headers?h.entries():Object.entries(h);for(let[k2,v2]of iterator)if(v2===null)finalHeaders.delete(k2);else if(Array.isArray(v2))for(let v22 of v2)finalHeaders.append(k2,v22);else v2!==void 0&&finalHeaders.set(k2,v2)}return finalHeaders}function removeTrailingSlash(url2){return url2.endsWith("/")?url2.substring(0,url2.length-1):url2}var import_picocolors4=__toESM(require_picocolors(),1);import{chmodSync,mkdirSync as mkdirSync5,readFileSync as readFileSync6,rmSync as rmSync4,writeFileSync as writeFileSync4}from"fs";import{join as join5}from"path";var SERVICE=APP_DIR,ACCOUNT="default";async function entry(){if(process.env.SR_CONNECT_CLI_DISABLE_KEYCHAIN)throw new Error("Keychain disabled via SR_CONNECT_CLI_DISABLE_KEYCHAIN.");let{Entry}=await import("@napi-rs/keyring");return new Entry(SERVICE,ACCOUNT)}async function keychainGet(){try{let raw=(await entry()).getPassword();return raw?JSON.parse(raw):null}catch{return null}}async function keychainSet(creds){(await entry()).setPassword(JSON.stringify(creds))}async function keychainDelete(){try{return(await entry()).deletePassword()}catch{return!1}}var CREDENTIALS_FILE=()=>join5(configDir(),"credentials.json");function fileGet(){try{return JSON.parse(readFileSync6(CREDENTIALS_FILE(),"utf8"))}catch{return null}}function fileSet(creds){mkdirSync5(configDir(),{recursive:!0}),writeFileSync4(CREDENTIALS_FILE(),JSON.stringify(creds,null,2)+`
42
- `,{mode:384}),chmodSync(CREDENTIALS_FILE(),384)}function fileDelete(){rmSync4(CREDENTIALS_FILE(),{force:!0})}async function resolveCredentials(){let creds=await lookupCredentials();return creds&&(resolvedUsername=creds.username),creds}async function lookupCredentials(){let envUser=process.env.SR_CONNECT_CLI_USERNAME,envPass=process.env.SR_CONNECT_CLI_PASSWORD;if(envUser&&envPass)return{username:envUser,password:envPass,source:"env"};let fromKeychain=await keychainGet();if(fromKeychain)return{...fromKeychain,source:"keychain"};let fromFile=fileGet();return fromFile?{...fromFile,source:"file"}:null}var resolvedUsername;function currentUsername(){return resolvedUsername}async function requireCredentials(){let creds=await resolveCredentials();return creds||fail(EXIT.UNAUTHENTICATED,"UNAUTHENTICATED","Not authenticated.",{hint:`Run \`${CLI} auth login\`, or set SR_CONNECT_CLI_USERNAME, SR_CONNECT_CLI_PASSWORD and SR_CONNECT_CLI_INSTANCE.`}),creds}function basicAuthHeader(creds){return"Basic "+Buffer.from(`${creds.username}:${creds.password}`).toString("base64")}var MIN_NODE_MAJOR=22;function runtimeNodeVersion(){return process.versions.node}function nodeMajor(version2=runtimeNodeVersion()){let major=Number.parseInt(version2??"",10);return Number.isFinite(major)?major:void 0}function nodeVersionWarning(version2=runtimeNodeVersion()){let major=Number.parseInt(version2??"",10);if(!(!Number.isFinite(major)||major>=MIN_NODE_MAJOR))return`\u26A0 Node ${version2} is older than the Node ${MIN_NODE_MAJOR} this CLI needs \u2014 live log streaming (--stream-logs) is unavailable and other commands may fail.`}var warned2=!1;function warnIfNodeUnsupported(){if(warned2)return;let warning=nodeVersionWarning();warning&&(warned2=!0,warnLine(warning))}var SEMVER_FORMAT="major.minor.patch",SEMVER=/^\d+\.\d+\.\d+$/;function semverError(version2){let trimmed=version2.trim();if(!SEMVER.test(trimmed))return`Expected a version in ${SEMVER_FORMAT} format, e.g. 1.4.0 \u2014 got "${trimmed}".`}function assertSemver(version2){let error51=semverError(version2);return error51&&fail(EXIT.USAGE,"INVALID_VERSION",error51),version2.trim()}var LOOSE_SEMVER=/^v?(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function parseVersion(version2){let trimmed=version2.trim(),match=LOOSE_SEMVER.exec(trimmed);if(match)return{major:Number(match[1]??0),minor:Number(match[2]??0),patch:Number(match[3]??0),release:trimmed.includes("-")?0:1}}function compareSemver(a,b2){let left=parseVersion(a),right=parseVersion(b2);return left?right?left.major-right.major||left.minor-right.minor||left.patch-right.patch||left.release-right.release:1:right?-1:0}import{realpathSync}from"fs";import{dirname,join as join6,resolve as resolve2,sep as sep2}from"path";import{fileURLToPath}from"url";var DEFAULT_REGISTRY="https://registry.npmjs.org",LOOKUP_TIMEOUT_MS=5e3,MAX_OFFERED_VERSIONS=30,fetchImpl=(...args)=>fetch(...args);function registryBase(){let configured=process.env.SR_CONNECT_CLI_NPM_REGISTRY;return(configured&&configured.trim()!==""?configured.trim():DEFAULT_REGISTRY).replace(/\/+$/,"")}function isPrerelease(version2){return version2.includes("-")}async function fetchVersions(name){try{let response=await fetchImpl(`${registryBase()}/${encodeURIComponent(name)}`,{headers:{accept:"application/vnd.npm.install-v1+json","user-agent":USER_AGENT},signal:AbortSignal.timeout(LOOKUP_TIMEOUT_MS)});if(response.status===404)return"not-found";if(!response.ok)return;let body=await response.json();if(!body.versions||typeof body.versions!="object"||Array.isArray(body.versions))return;let versions=Object.keys(body.versions).reverse();if(versions.length===0)return;let distTags=body["dist-tags"]&&typeof body["dist-tags"]=="object"&&!Array.isArray(body["dist-tags"])?body["dist-tags"]:{},latest=typeof distTags.latest=="string"?distTags.latest:void 0;return{versions,distTags,...latest?{latest}:{}}}catch{return}}var enabled3=!0;function configureUpdateCheck(opts){let off=process.env.SR_CONNECT_CLI_NO_UPDATE_CHECK;enabled3=opts.enabled&&(off===void 0||/^(0|false|no|off|)$/i.test(off.trim()))}function latestStable(lookup){return lookup.latest&&!isPrerelease(lookup.latest)?lookup.latest:lookup.versions.filter(v2=>!isPrerelease(v2)).sort(compareSemver).at(-1)}function isFresh(checkedAt){let age=Date.now()-Date.parse(checkedAt);return Number.isFinite(age)&&age>=0&&age<SESSION_TTL_MS}function startUpdateCheck(){if(!enabled3)return;let stored=readUpdateCheck();stored&&isFresh(stored.checkedAt)||fetchVersions(PACKAGE).then(lookup=>{if(!lookup||lookup==="not-found")return;let latest=latestStable(lookup);latest&&storeUpdateCheck({checkedAt:new Date().toISOString(),latest})})}function globalRoots(site){let nodeDir=dirname(site.execPath),roots=[{manager:"npm",root:join6(nodeDir,"..","lib","node_modules")},{manager:"npm",root:join6(nodeDir,"node_modules")}],prefix=site.env.npm_config_prefix??site.env.PREFIX;prefix&&roots.push({manager:"npm",root:join6(prefix,"lib","node_modules")});let pnpmHome=site.env.PNPM_HOME;pnpmHome&&roots.push({manager:"pnpm",root:pnpmHome});let bunInstall=site.env.BUN_INSTALL;return bunInstall&&roots.push({manager:"bun",root:join6(bunInstall,"install","global")}),roots}function under(path2,root){let normalized=resolve2(root);return path2===normalized||path2.startsWith(normalized.endsWith(sep2)?normalized:normalized+sep2)}function classifyInstall(site){if(site.entry.includes(`${sep2}_npx${sep2}`)||site.entry.includes(`${sep2}dlx${sep2}`))return{kind:"npx",manager:"npm"};for(let{manager,root}of globalRoots(site))if(under(site.entry,root))return{kind:"global",manager};return{kind:site.entry.includes(`${sep2}node_modules${sep2}`)?"local":"unknown",manager:"npm"}}function updateCommand(kind,manager){let spec=`${PACKAGE}@latest`;return kind==="npx"?`npx ${spec}`:kind!=="global"?`npm install ${spec}`:manager==="pnpm"?`pnpm add -g ${spec}`:manager==="bun"?`bun add -g ${spec}`:`npm install -g ${spec}`}function currentSite(){let file2=fileURLToPath(import.meta.url),entry2=file2;try{entry2=realpathSync(file2)}catch{}return{entry:entry2,env:process.env,execPath:process.execPath}}function updateNotice(latest,current=VERSION,site=currentSite()){if(compareSemver(latest,current)<=0)return;let{kind,manager}=classifyInstall(site);return{command:updateCommand(kind,manager),current,latest}}function renderBanner(body){let width=Math.max(...body.map(line=>Array.from(line).length)),rule="*".repeat(width+6),pad=line=>`* ${line}${" ".repeat(width-Array.from(line).length)} *`;return[rule,pad(""),...body.map(pad),pad(""),rule]}function updateBody(notice){return[`New version of ${PACKAGE} available!`,`${notice.current} \u2192 ${notice.latest}`,"","Update with:",notice.command]}function unsupportedNotice(current=VERSION,site=currentSite()){let{kind,manager}=classifyInstall(site),command=updateCommand(kind,manager);return{message:`${PACKAGE} ${current} is no longer supported by this deployment.`,hint:`Update with: ${command}`,banner:renderBanner([`${PACKAGE} ${current} is no longer supported.`,"","Update with:",command])}}function renderCompact(notice){return[`\u2714 ${PACKAGE} ${notice.latest} is available (you have ${notice.current}).`,` Update with: ${notice.command}`]}var announced=!1;function printUpdateNotice(){if(announced||!enabled3)return;let stored=readUpdateCheck();if(!stored)return;let notice=updateNotice(stored.latest);if(notice){announced=!0;for(let line of isRaw()?renderCompact(notice):renderBanner(updateBody(notice)))successLine(line)}}var flagEnabled=!0;function configureVersionGate(opts){flagEnabled=opts.enabled}function gateEnabled(){return flagEnabled&&!process.env.SR_CONNECT_CLI_NO_VERSION_GATE}var refreshed=!1;async function readServiceInfo(client,opts={}){let cached2=cachedServiceInfo(),refresh=opts.refreshWithoutStreamUrl===!0&&!cached2?.logsStreamUrl&&!refreshed;if(cached2&&!refresh)return cached2;refresh&&cached2&&(refreshed=!0);let answer=await client.GET("/v1/serviceInfo",{}).catch(()=>{});if(!answer)return cached2;let{data,response}=answer;if(response.status===401&&fail(EXIT.UNAUTHENTICATED,"INVALID_CREDENTIALS","The API rejected these credentials.",{hint:`Run \`${CLI} auth login\` and try again.`}),!response.ok||!data)return cached2;let info={readAt:new Date().toISOString(),...data.logsStreamUrl?{logsStreamUrl:data.logsStreamUrl}:{},...data.minimumCliVersion?{minimumCliVersion:data.minimumCliVersion}:{}};return cacheServiceInfo(info),info}async function assertSupportedVersion(client){if(!gateEnabled())return;let minimum=(await readServiceInfo(client))?.minimumCliVersion;if(!minimum||compareSemver(VERSION,minimum)>=0)return;let notice=unsupportedNotice();fail(EXIT.USAGE,"CLI_TOO_OLD",notice.message,{banner:notice.banner,hint:notice.hint})}var import_picocolors3=__toESM(require_picocolors(),1);import crypto from"crypto";var ENCODING="0123456789ABCDEFGHJKMNPQRSTVWXYZ",ENCODING_LEN=32;var RANDOM_LEN=16,TIME_LEN=10,TIME_MAX=0xffffffffffff;var ULIDErrorCode;(function(ULIDErrorCode2){ULIDErrorCode2.Base32IncorrectEncoding="B32_ENC_INVALID",ULIDErrorCode2.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",ULIDErrorCode2.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",ULIDErrorCode2.EncodeTimeNegative="ENC_TIME_NEG",ULIDErrorCode2.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",ULIDErrorCode2.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",ULIDErrorCode2.PRNGDetectFailure="PRNG_DETECT",ULIDErrorCode2.ULIDInvalid="ULID_INVALID",ULIDErrorCode2.Unexpected="UNEXPECTED",ULIDErrorCode2.UUIDInvalid="UUID_INVALID"})(ULIDErrorCode||(ULIDErrorCode={}));var ULIDError=class extends Error{constructor(errorCode,message){super(`${message} (${errorCode})`),this.name="ULIDError",this.code=errorCode}};function randomChar(prng){let randomPosition=Math.floor(prng()*ENCODING_LEN)%ENCODING_LEN;return ENCODING.charAt(randomPosition)}function detectPRNG(root){let rootLookup=detectRoot(),globalCrypto=rootLookup&&(rootLookup.crypto||rootLookup.msCrypto)||(typeof crypto<"u"?crypto:null);if(typeof globalCrypto?.getRandomValues=="function")return()=>{let buffer=new Uint8Array(1);return globalCrypto.getRandomValues(buffer),buffer[0]/256};if(typeof globalCrypto?.randomBytes=="function")return()=>globalCrypto.randomBytes(1).readUInt8()/256;if(crypto?.randomBytes)return()=>crypto.randomBytes(1).readUInt8()/256;throw new ULIDError(ULIDErrorCode.PRNGDetectFailure,"Failed to find a reliable PRNG")}function detectRoot(){return inWebWorker()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function encodeRandom(len,prng){let str="";for(;len>0;len--)str=randomChar(prng)+str;return str}function encodeTime(now,len=TIME_LEN){if(isNaN(now))throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed,`Time must be a number: ${now}`);if(now>TIME_MAX)throw new ULIDError(ULIDErrorCode.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${TIME_MAX}: ${now}`);if(now<0)throw new ULIDError(ULIDErrorCode.EncodeTimeNegative,`Time must be positive: ${now}`);if(Number.isInteger(now)===!1)throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed,`Time must be an integer: ${now}`);let mod,str="";for(let currentLen=len;currentLen>0;currentLen--)mod=now%ENCODING_LEN,str=ENCODING.charAt(mod)+str,now=(now-mod)/ENCODING_LEN;return str}function inWebWorker(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ulid(seedTime,prng){let currentPRNG=prng||detectPRNG(),seed=!seedTime||isNaN(seedTime)?Date.now():seedTime;return encodeTime(seed,TIME_LEN)+encodeRandom(RANDOM_LEN,currentPRNG)}function personName(person){return[person.firstName,person.lastName].filter(Boolean).join(" ")||person.email||""}function personCell(person){return`${personName(person)||person.id}${person.id?` (${person.id})`:""}`}var import_cronstrue=__toESM(require_cronstrue(),1);var CRON_FIELDS="second minute hour day-of-month month day-of-week",HOURLY_CRON="0 0 * * * *";function everyMinutesCron(minutes){return`0 */${minutes} * * * *`}function dailyCron(hour,minute){return`0 ${minute} ${hour} * * *`}function weeklyCron(day,hour,minute){return`0 ${minute} ${hour} * * ${day}`}function normalizeCron(expression){return expression.trim().split(/\s+/).join(" ")}function errorForNormalized(normalized){let parts=normalized.split(" ").filter(Boolean);if(parts.length!==6)return`CRON expression must have 6 fields (${CRON_FIELDS}) \u2014 got ${parts.length}.`;try{(0,import_cronstrue.toString)(parts.join(" "))}catch(err){return`Invalid CRON expression: ${(err instanceof Error?err.message:String(err)).replace(/^Error:\s*/,"")}`}}function cronError(expression){return errorForNormalized(normalizeCron(expression))}function describeCron(expression){try{return(0,import_cronstrue.toString)(normalizeCron(expression))}catch{return}}var MIN_TRIGGER_INTERVAL_MINUTES=15;function scheduleOf(trigger){return trigger.cronExpressionDescription??trigger.cronExpression??"not scheduled"}function assertCron(expression){let normalized=normalizeCron(expression),message=errorForNormalized(normalized);return message&&fail(EXIT.USAGE,"INVALID_CRON",message,{hint:`Once per hour is ${HOURLY_CRON}`}),normalized}var ResolverFetchError=class extends Error{status;constructor(status,message){super(message),this.status=status}};function listenerAppRegistry(){let app=RESOLVERS.app;return app?{...RESOLVERS,app:{...app,async fetch(client,deps){let payload=await fetchApps(client),withListeners=new Set(payload.apps.filter(a=>connectionTypes(a).some(ct2=>(ct2.eventListenerTypes??[]).length>0)).map(a=>a.id));return(await app.fetch(client,deps)).filter(choice=>withListeners.has(choice.value))}}}:RESOLVERS}function mapResolverError(err,spec){err.status===401&&fail(EXIT.UNAUTHENTICATED,"INVALID_CREDENTIALS",err.message,{status:401}),fail(err.status===404?EXIT.NOT_FOUND:EXIT.API_ERROR,err.status===404?"NOT_FOUND":"API_ERROR",`Fetching ${spec.plural} failed: ${err.message}`,{status:err.status})}function must(deps,key){let v2=deps[key];if(!v2)throw new Error(`resolver dependency '${key}' missing`);return v2}async function unwrap(res){if(!res.response.ok||res.data===void 0){let message=res.error?.errorMessage??`Request failed with HTTP status ${res.response.status}.`;throw new ResolverFetchError(res.response.status,message)}return res.data}var appsCache=new WeakMap,featuresCache=new WeakMap;async function teamFeatures(client,teamId){return await teamFeaturesIfKnown(client,teamId)??{eventQueues:!1,remoteWorkspace:!1}}async function teamFeaturesIfKnown(client,teamId){let perTeam=featuresCache.get(client);perTeam||featuresCache.set(client,perTeam=new Map);let cached2=perTeam.get(teamId);return cached2||(cached2=client.GET("/v1/team/{teamId}",{params:{path:{teamId}}}).then(res=>res.response.ok&&res.data?res.data.features:void 0).catch(()=>{}),perTeam.set(teamId,cached2)),cached2}function connectionTypes(app){return app.connectionTypes??(app.connectionType?[app.connectionType]:[])}async function fetchApps(client){let cached2=appsCache.get(client);return cached2||(cached2=client.GET("/v1/apps").then(unwrap),appsCache.set(client,cached2)),cached2}function findApp(payload,appId){return payload.apps.find(a=>a.id===appId)}function findApiConnectionType(app,apiConnectionTypeId){return connectionTypes(app).flatMap(ct2=>ct2.apiConnectionTypes??[]).find(t=>t.id===apiConnectionTypeId)}async function apiConnectionPackages(client,appId,apiConnectionTypeId){let app=findApp(await fetchApps(client),appId);if(!app)throw new ResolverFetchError(404,`App '${appId}' not found.`);let type=findApiConnectionType(app,apiConnectionTypeId);if(!type)throw new ResolverFetchError(404,`API connection type '${apiConnectionTypeId}' not found.`);return type.packages??[]}var GENERIC_APP="Generic";async function appConnectionTypeName(client,appId){let app=findApp(await fetchApps(client),appId);if(app)return connectionTypes(app)[0]?.name}async function isGenericApp(client,appId){try{return await appConnectionTypeName(client,appId)===GENERIC_APP}catch{return!1}}var environmentsCache=new WeakMap;function fetchEnvironments(client,workspaceId){let perWorkspace=environmentsCache.get(client);perWorkspace||environmentsCache.set(client,perWorkspace=new Map);let cached2=perWorkspace.get(workspaceId);return cached2||(cached2=client.GET("/v1/workspace/{workspaceId}/environments",{params:{path:{workspaceId}}}).then(unwrap),cached2.catch(()=>perWorkspace.delete(workspaceId)),perWorkspace.set(workspaceId,cached2)),cached2}async function environmentRelease(client,workspaceId,environmentId){return(await environmentInfo(client,workspaceId,environmentId))?.release}async function environmentInfo(client,workspaceId,environmentId){return(await fetchEnvironments(client,workspaceId).catch(()=>{}))?.environments.find(e=>e.id===environmentId)}async function environmentBelongsTo(client,workspaceId,environmentId){let data=await fetchEnvironments(client,workspaceId).catch(()=>{});if(data)return data.environments.some(e=>e.id===environmentId)}var packagesCache=new WeakMap;function fetchWorkspacePackages(client,workspaceId){let perWorkspace=packagesCache.get(client);perWorkspace||packagesCache.set(client,perWorkspace=new Map);let cached2=perWorkspace.get(workspaceId);return cached2||(cached2=client.GET("/v1/workspace/{workspaceId}/packages",{params:{path:{workspaceId}}}).then(unwrap),cached2.catch(()=>perWorkspace.delete(workspaceId)),perWorkspace.set(workspaceId,cached2)),cached2}async function packageInfo(client,workspaceId,packageId){return(await fetchWorkspacePackages(client,workspaceId).catch(()=>{}))?.packages.find(p=>p.id===packageId)}var connectorsCache=new WeakMap;function fetchConnectors(client,teamId){let perTeam=connectorsCache.get(client);perTeam||connectorsCache.set(client,perTeam=new Map);let cached2=perTeam.get(teamId);return cached2||(cached2=client.GET("/v1/team/{teamId}/connectors",{params:{path:{teamId}}}).then(unwrap),cached2.catch(()=>perTeam.delete(teamId)),perTeam.set(teamId,cached2)),cached2}async function connectorInfo(client,teamId,connectorId){return(await fetchConnectors(client,teamId).catch(()=>{}))?.connections.find(c=>c.id===connectorId)}var userCache=new WeakMap;async function currentUser(client){let cached2=userCache.get(client);return cached2||(cached2=client.GET("/v1/user/me").then(res=>res.response.ok&&res.data?res.data:void 0).catch(()=>{}),userCache.set(client,cached2)),cached2}async function currentUserId(client){return(await currentUser(client))?.id}var RESOLVERS={team:{key:"team",flag:"--team",label:"Team",plural:"teams",listCommand:`${CLI} team list`,dependsOn:[],async fetch(client){return(await unwrap(await client.GET("/v1/teams"))).teams.map(t=>({value:t.id,label:t.name,hint:t.id}))}},workspace:{key:"workspace",flag:"-w, --workspace",label:"Workspace",plural:"workspaces",listCommand:`${CLI} workspace list`,dependsOn:["team"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/team/{teamId}/workspaces",{params:{path:{teamId:must(deps,"team")}}}))).workspaces.map(w=>({value:w.id,label:w.name,hint:w.id}))}},environment:{key:"environment",flag:"-e, --env",label:"Environment",plural:"environments",listCommand:`${CLI} environment list`,dependsOn:["workspace"],async fetch(client,deps){return(await fetchEnvironments(client,must(deps,"workspace"))).environments.map(e=>({value:e.id??"",label:e.name??e.id??"?",display:`${e.name??e.id??"?"} (${e.release?.version??"HEAD"})`,hint:e.id}))}},release:{key:"release",flag:"<releaseId>",label:"Release",plural:"releases",listCommand:`${CLI} release list`,dependsOn:["workspace"],async fetch(client,deps){return[...(await unwrap(await client.GET("/v1/workspace/{workspaceId}/releases",{params:{path:{workspaceId:must(deps,"workspace")}}}))).releases].reverse().map(r=>({value:r.id,label:r.version,...r.label?{display:`${r.version} \u2014 ${r.label}`}:{},hint:r.created}))}},parameter:{key:"parameter",flag:"<parameterId>",label:"Parameter",plural:"parameters",listCommand:`${CLI} environment-parameter list`,dependsOn:["workspace","environment"],async fetch(client,deps){let data=await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/parameters",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}})),flatten2=(params,prefix="")=>params.flatMap(p=>{let path2=prefix?`${prefix} / ${p.key}`:p.key,self2={value:p.id,label:`${path2} \xB7 ${p.type}`,hint:p.id};return p.children?.length?[self2,...flatten2(p.children,path2)]:[self2]});return flatten2(data.parameters)}},app:{key:"app",flag:"--app-id",label:"App",plural:"apps",listCommand:`${CLI} app list`,dependsOn:[],async fetch(client){return(await fetchApps(client)).apps.map(a=>({value:a.id??"",label:a.name??a.id??"?",hint:a.id}))}},apiConnectionType:{key:"apiConnectionType",flag:"--api-connection-type-id",label:"API connection type",plural:"API connection types",listCommand:`${CLI} app list`,dependsOn:["app"],autoSelectSingle:!0,async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);return connectionTypes(app).flatMap(ct2=>(ct2.apiConnectionTypes??[]).map(t=>({value:t.id??"",label:t.name??t.id??"?",hint:ct2.name})))}},apiConnectionPackage:{key:"apiConnectionPackage",flag:"--package-id",label:"API connection package",plural:"API connection packages",listCommand:`${CLI} app list`,dependsOn:["app","apiConnectionType"],async fetch(client,deps){return(await apiConnectionPackages(client,must(deps,"app"),must(deps,"apiConnectionType"))).map(p=>({value:p.id??"",label:p.name??p.id??"?",hint:p.recommended?"recommended":p.deprecated?"deprecated":void 0}))}},listenerType:{key:"listenerType",flag:"--listener-type-id",label:"Event listener type",plural:"event listener types",listCommand:`${CLI} app list`,dependsOn:["app"],autoSelectSingle:!0,async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);return connectionTypes(app).flatMap(ct2=>(ct2.eventListenerTypes??[]).map(lt2=>({value:lt2.id??"",label:lt2.name??lt2.id??"?",hint:ct2.name})))}},eventType:{key:"eventType",flag:"--event-type-id",label:"Event type",plural:"event types",listCommand:`${CLI} app list`,dependsOn:["app","listenerType"],async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);let listenerType=connectionTypes(app).flatMap(ct2=>ct2.eventListenerTypes??[]).find(lt2=>lt2.id===must(deps,"listenerType"));if(!listenerType)throw new ResolverFetchError(404,`Event listener type '${deps.listenerType}' not found.`);return(listenerType.eventTypes??[]).map(et2=>({value:et2.id??"",label:et2.name??et2.id??"?",hint:et2.category}))}},connector:{key:"connector",flag:"--connector-id",label:"Connector",plural:"connectors",listCommand:`${CLI} connector list`,dependsOn:["team"],async fetch(client,deps){let data=await fetchConnectors(client,must(deps,"team")),me2=await currentUserId(client),allowed,appId=deps.app;if(appId){let app=findApp(await fetchApps(client),appId);if(app){let cts=connectionTypes(app),listenerTypeId=deps.listenerType;if(listenerTypeId){let owning=cts.filter(ct2=>(ct2.eventListenerTypes??[]).some(lt2=>lt2.id===listenerTypeId));owning.length>0&&(cts=owning)}let apiConnectionTypeId=deps.apiConnectionType;if(apiConnectionTypeId){let owning=cts.filter(ct2=>(ct2.apiConnectionTypes??[]).some(t=>t.id===apiConnectionTypeId));owning.length>0&&(cts=owning)}allowed=new Set(cts.map(ct2=>ct2.id??""))}}return data.connections.filter(c=>!allowed||allowed.has(c.connectionType?.id??"")).filter(c=>!appId||c.canUse!==!1).map(c=>{let sharer=me2&&c.owner?.id&&c.owner.id!==me2?personName(c.owner):"",notes=[c.authorized===!1?"unauthorized":void 0,sharer?`explicitly shared with you by ${sharer}`:void 0,c.canUse===!1?"not for use":void 0].filter(note=>note!==void 0),label=c.name??c.id??"?";return{value:c.id??"",label,...notes.length>0?{display:`${label} (${notes.join(", ")})`}:{},hint:c.connectionType?.name}})}},ownedConnector:{key:"ownedConnector",flag:"--connector-id",label:"Connector",plural:"connectors you own",listCommand:`${CLI} connector list`,dependsOn:["team"],async fetch(client,deps){let data=await fetchConnectors(client,must(deps,"team")),me2=await currentUserId(client);return data.connections.filter(c=>!me2||c.owner?.id===me2).map(c=>{let label=c.name??c.id??"?";return{value:c.id??"",label,...c.authorized===!1?{display:`${label} (unauthorized)`}:{},hint:c.connectionType?.name}})}},script:{key:"script",flag:"<scriptId>",label:"Script",plural:"scripts",dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/scripts",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).scripts.map(s=>({value:s.id,label:s.name,hint:s.id}))}},eventListener:{key:"eventListener",flag:"<eventListenerId>",label:"Event listener",plural:"event listeners",listCommand:`${CLI} event-listener list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListeners",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).eventListeners.map(el=>({value:el.id,label:el.eventType?`${el.app.name} \xB7 ${el.eventType.name}${el.script?` \u2192 ${el.script.name}`:""}`:`${el.app.name} (setup incomplete)`,hint:el.id}))}},apiConnection:{key:"apiConnection",flag:"<apiConnectionId>",label:"API connection",plural:"API connections",listCommand:`${CLI} api-connection list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnections",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).apiConnections.map(c=>{let label=c.path??c.id;return{value:c.id,label,display:`${label} \xB7 ${c.app.name}${c.connector?` \u2014 ${c.connector.name||c.connector.id}`:" \u2014 no connector here"}`,hint:c.id}})}},eventQueue:{key:"eventQueue",flag:"--event-queue-id",label:"Event queue",plural:"event queues",listCommand:`${CLI} event-queue list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventQueues",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).eventQueues.map(q2=>({value:q2.id,label:q2.name,...q2.disabled?{display:`${q2.name} (disabled)`}:{},hint:q2.id}))}},testPayload:{key:"testPayload",flag:"<testPayloadId>",label:"Test payload",plural:"test payloads",listCommand:`${CLI} event-listener-test-payload list`,dependsOn:["workspace","environment","eventListener"],async fetch(client,deps){let data=await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListener/{eventListenerId}/testPayloads",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment"),eventListenerId:must(deps,"eventListener")}}}));return data.testPayloads.map(p=>({value:p.id,label:p.name,...p.id===data.defaultTestPayloadId?{display:`${p.name} (default)`}:{},hint:p.id}))}},scheduledTrigger:{key:"scheduledTrigger",flag:"<scheduledTriggerId>",label:"Scheduled trigger",plural:"scheduled triggers",listCommand:`${CLI} scheduled-trigger list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/scheduledTriggers",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).scheduledTriggers.map(t=>{let label=t.script?.name??t.id;return{value:t.id,label,display:`${label} \xB7 ${scheduleOf(t)}${t.disabled?" (disabled)":""}`,hint:t.id}})}},workspacePackage:{key:"workspacePackage",flag:"<packageId>",label:"Package",plural:"packages",listCommand:`${CLI} package list`,dependsOn:["workspace"],async fetch(client,deps){return(await fetchWorkspacePackages(client,must(deps,"workspace"))).packages.map(p=>({value:p.id,label:p.name,display:`${p.name}@${p.version} \xB7 ${p.type}${p.required?" \xB7 required":""}`,hint:p.id}))}}};var import_picocolors2=__toESM(require_picocolors(),1);import{existsSync,lstatSync,readdirSync as readdirSync3}from"fs";import{dirname as dirname2,join as join7}from"path";import{PassThrough}from"stream";import{styleText}from"util";function pathOptions(userInput,extensions){if(userInput==="")return[];let allowed=p=>!extensions?.length||extensions.some(ext=>p.toLowerCase().endsWith(ext.toLowerCase())),isDirectory=p=>{try{return lstatSync(p).isDirectory()}catch{return!1}},entriesOf=(dir,prefix)=>readdirSync3(dir).map(name=>join7(dir,name)).filter(full=>full.startsWith(prefix)).filter(full=>isDirectory(full)||allowed(full)).map(full=>isDirectory(full)?`${full}/`:full);try{let insideDir=userInput.length>1&&userInput.endsWith("/"),prefix=insideDir?userInput.slice(0,-1):userInput,values=[];insideDir||values.push(...entriesOf(dirname2(userInput),prefix)),isDirectory(userInput)&&values.push(...entriesOf(userInput,prefix));let options=[...new Set(values)].map(value=>({value}));return existsSync(userInput)&&lstatSync(userInput).isFile()&&!options.some(o=>o.value===userInput)&&options.unshift({value:userInput}),options}catch{return[]}}var AUTOCOMPLETE_THRESHOLD=8;function cancelled(){fail(EXIT.CANCELLED,"CANCELLED","Cancelled.")}var SUBMIT_KEY="Ctrl-S",CTRL_S=19,TAB=9,TAB_SENTINEL_BYTE=28,TAB_SENTINEL="";function detabSentinel(text){return text.replaceAll(TAB_SENTINEL," ")}function rewriteSubmitKeys(chunk){let out=[];for(let byte of chunk)byte===CTRL_S?out.push(TAB):byte===TAB?out.push(TAB_SENTINEL_BYTE):out.push(byte);return Buffer.from(out)}function submitOnCtrlS(source=process.stdin){if(!source.isTTY)return;let proxy=new PassThrough,onData=chunk=>{proxy.write(rewriteSubmitKeys(chunk))};source.on("data",onData),source.resume();let restoreTty=()=>{source.isRaw&&source.setRawMode(!1)};process.once("exit",restoreTty);let input=Object.assign(proxy,{isTTY:!0,setRawMode(mode){return source.setRawMode(mode),input}});return{input,done:()=>{process.off("exit",restoreTty),source.off("data",onData),source.pause(),proxy.end()}}}var clackAdapter={async select(message,choices,opts){let clack=await import("./dist-A3XXQMMP.js"),options=choices.map(c=>({value:c.value,label:c.display??c.label,hint:c.hint,disabled:c.disabled})),initialValue=opts?.initial,result=choices.length>AUTOCOMPLETE_THRESHOLD?await clack.autocomplete({message,options,initialValue,maxItems:10,output:process.stderr}):await clack.select({message,options,initialValue,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async multiselect(message,choices,opts){let clack=await import("./dist-A3XXQMMP.js"),options=choices.map(c=>({value:c.value,label:c.display??c.label,hint:c.hint,disabled:c.disabled})),initialValues=opts?.initial,result=choices.length>AUTOCOMPLETE_THRESHOLD?await clack.autocompleteMultiselect({message,options,initialValues,required:!1,maxItems:10,output:process.stderr}):await clack.multiselect({message,options,initialValues,required:!1,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async confirm(message,initial=!1){let clack=await import("./dist-A3XXQMMP.js"),result=await clack.confirm({message,initialValue:initial,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async text(message,opts){let clack=await import("./dist-A3XXQMMP.js"),result=await clack.text({message,initialValue:opts?.initial,validate:v2=>v2||opts?.allowEmpty?void 0:"Required.",output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async multiline(message,opts){let clack=await import("./dist-A3XXQMMP.js"),core=await import("./dist-UQEAKLYF.js"),{highlightWithCursor,insertCursor}=await import("./highlight-7NU3CBVT.js"),keys=submitOnCtrlS();try{let language=opts?.language,output=process.stderr,style=(format,text)=>styleText(format,text,{stream:output}),result=await new core.MultiLinePrompt({placeholder:opts?.placeholder,initialValue:opts?.initial,showSubmit:!0,validate:()=>{},output,...keys?{input:keys.input}:{},render(){let withGuide=clack.settings.withGuide,title=`${withGuide?`${style("gray",clack.S_BAR)}
36
+ ${renderHuman(detail)}`)}var KNOWN_INSTANCES={eu:{label:"EU",url:"https://api.scriptrunnerconnect.com",appUrl:"https://app.eu.scriptrunnerconnect.com"},us:{label:"US",url:"https://api.us.scriptrunnerconnect.com",appUrl:"https://app.us.scriptrunnerconnect.com"}},INSTANCE_KEYS=Object.keys(KNOWN_INSTANCES);function knownInstance(value){return KNOWN_INSTANCES[value]}var INSTANCE_FORMAT=`${INSTANCE_KEYS.join(", ")}, or an API base URL (e.g. https://api.example.com)`;function parseInstance(raw){let value=raw.trim();if(value==="")return{error:`An instance is required: ${INSTANCE_FORMAT}.`};let lower=value.toLowerCase();if(knownInstance(lower))return{instance:lower};let withScheme=/^[a-z][a-z0-9+.-]*:\/\//i.test(value)?value:`https://${value}`,url2;try{url2=new URL(withScheme)}catch{return{error:`'${value}' is not a valid instance \u2014 use ${INSTANCE_FORMAT}.`}}return url2.protocol!=="https:"&&url2.protocol!=="http:"?{error:`An instance URL must be http:// or https:// \u2014 '${value}' is ${url2.protocol}//.`}:url2.hostname===""?{error:`'${value}' has no host \u2014 use ${INSTANCE_FORMAT}.`}:url2.username!==""||url2.password!==""?{error:`An instance URL must not embed a username or password \u2014 got '${value}'.`}:url2.search!==""||url2.hash!==""?{error:`An instance URL must not carry a query string or fragment \u2014 got '${value}'.`}:{instance:`${url2.protocol}//${url2.host}${url2.pathname.replace(/\/+$/,"")}`}}function instanceError(value){return parseInstance(value).error}function normalizeInstance(value){let{instance:instance4,error:error51}=parseInstance(value);if(!instance4)throw new Error(error51??`not an instance: '${value}'`);return instance4}function assertInstance(value,origin){let{instance:instance4,error:error51}=parseInstance(value);return instance4||fail(EXIT.USAGE,"INVALID_INSTANCE",`${origin}: ${error51}`),instance4}function configDir(){return join2(userConfigHome(process.platform,process.env,homedir2()),APP_DIR)}function userConfigHome(platform2,env,home){let xdg=env.XDG_CONFIG_HOME;if(xdg&&xdg!=="")return xdg;if(platform2==="win32"){let appData=env.APPDATA;return appData&&appData!==""?appData:join2(home,"AppData","Roaming")}return join2(home,".config")}function readConfig(){try{return JSON.parse(readFileSync2(join2(configDir(),"config.json"),"utf8"))}catch{return{}}}function writeConfig(config2){mkdirSync(configDir(),{recursive:!0}),writeFileSync(join2(configDir(),"config.json"),JSON.stringify(config2,null,2)+`
37
+ `)}function baseUrl(instance4){return knownInstance(instance4)?.url??instance4}function instanceLabel(instance4){let known=knownInstance(instance4);return known?`${known.label} (${known.url})`:instance4}var API_KEYS_PATH="/apiKeys";function apiKeysUrl(instance4){let known=knownInstance(instance4);return known?`${known.appUrl}${API_KEYS_PATH}`:void 0}var LOOPBACK=new Set(["localhost","127.0.0.1","[::1]","::1"]);function insecureInstanceWarning(instance4){let url2=baseUrl(instance4);if(!url2.startsWith("http://"))return;let host;try{host=new URL(url2).hostname}catch{return}if(!LOOPBACK.has(host))return`\u26A0 ${url2} is not HTTPS \u2014 your API credentials are sent unencrypted.`}function explicitInstance(flag){let fromEnv=process.env.SR_CONNECT_CLI_INSTANCE;if(flag!==void 0&&flag!=="")return assertInstance(flag,"--instance");if(fromEnv!==void 0&&fromEnv!=="")return assertInstance(fromEnv,"SR_CONNECT_CLI_INSTANCE")}function resolveInstance(flag){let explicit2=explicitInstance(flag);if(explicit2!==void 0)return explicit2;let stored=readConfig().instance;if(stored!==void 0&&stored!=="")return assertInstance(stored,`the instance in ${join2(configDir(),"config.json")}`)}var RUN_ID=`${Date.now().toString(36)}-${process.pid}`;import{createHash}from"crypto";import{fstatSync,mkdirSync as mkdirSync2,readFileSync as readFileSync3,readdirSync,renameSync,rmSync,statSync,writeFileSync as writeFileSync2}from"fs";import{homedir as homedir3}from"os";import{join as join3}from"path";var SESSION_KEYS=["team","workspace","environment"],SESSION_RECORD_VERSION=2,SESSION_TTL_MS=720*60*1e3,PRUNE_MS=10080*60*1e3,LOCK_KEEP_MS=3600*1e3,runtimeInstance,enabled=!0;function configureSession(opts){runtimeInstance=opts.instance,enabled=opts.enabled!==!1}function sessionEnabled(){return enabled}function stateHome(){return userStateHome(process.platform,process.env,homedir3())}function userStateHome(platform2,env,home){let explicit2=env.SR_CONNECT_CLI_STATE_HOME;if(explicit2&&explicit2!=="")return explicit2;let xdg=env.XDG_STATE_HOME;if(xdg&&xdg!=="")return xdg;if(platform2==="win32"){let local=env.LOCALAPPDATA;return local&&local!==""?local:join3(home,"AppData","Local")}return join3(home,".local","state")}function sessionsDir(){return join3(stateHome(),APP_DIR,"sessions")}var sanitize=v2=>v2.replace(/[^A-Za-z0-9_.-]/g,"_").slice(0,96);function terminalMarker(){let pair=(a,b2)=>a&&a!==""?`${a}:${b2??""}`:void 0;return[process.env.TERM_SESSION_ID,process.env.ITERM_SESSION_ID,pair(process.env.WEZTERM_UNIX_SOCKET,process.env.WEZTERM_PANE),pair(process.env.KITTY_PID,process.env.KITTY_WINDOW_ID),process.env.ALACRITTY_WINDOW_ID,process.env.WT_SESSION,pair(process.env.TMUX,process.env.TMUX_PANE),process.env.STY].find(c=>c&&c!=="")}function sessionKey(){let explicit2=process.env.SR_CONNECT_CLI_SESSION_ID;if(explicit2&&explicit2!=="")return`id-${sanitize(explicit2)}`;let marker=terminalMarker();if(marker)return`mark-${sanitize(marker)}`;for(let fd of[0,1,2])try{let st2=fstatSync(fd);if(st2.isCharacterDevice()&&st2.rdev)return`tty-${st2.rdev}`}catch{}return process.ppid?`ppid-${process.ppid}`:void 0}function instanceSlug(instance4){return createHash("sha256").update(instance4).digest("hex").slice(0,12)}function sessionFile(){let key=sessionKey();if(!key)return;let instance4=effectiveInstance();return join3(sessionsDir(),instance4?`${key}.${instanceSlug(instance4)}.json`:`${key}.json`)}function hasScope(record4){return!!(record4&&SESSION_KEYS.some(k2=>record4[k2]))}function effectiveInstance(){return resolveInstance(runtimeInstance)}function readSession(){if(!enabled)return;let file2=sessionFile();if(!file2)return;let record4;try{record4=JSON.parse(readFileSync3(file2,"utf8"))}catch{return}if(record4.version!==SESSION_RECORD_VERSION){dropSession(file2);return}let age=Date.now()-Date.parse(record4.updatedAt);if(!Number.isFinite(age)||age>SESSION_TTL_MS){dropSession(file2);return}let instance4=effectiveInstance();if(record4.instance&&instance4&&record4.instance!==instance4){warnStrandedLocks(pruneLocks(record4.locks)),dropSession(file2),hasScope(record4)&&(instanceCleared=instanceLabel(record4.instance));return}return record4}function warnStrandedLocks(locks){if(!locks)return;let kept=keptLocksOf(locks);if(kept.length!==0){warnLine(`${kept.length} workspace lock${kept.length===1?"":"s"} taken against another instance cannot be presented from here and are being forgotten.`);for(let lock of kept)warnLine(` ${lockReleaseCommand(lock)}`)}}var instanceCleared;function takeInstanceClear(){let cleared=instanceCleared;return instanceCleared=void 0,cleared}function readRecord(file2,opts={}){let record4;try{record4=JSON.parse(readFileSync3(file2,"utf8"))}catch{return}if(record4.version!==SESSION_RECORD_VERSION)return;let age=Date.now()-Date.parse(record4.updatedAt);if(!Number.isFinite(age)||age>SESSION_TTL_MS)return;if(opts.anyInstance)return record4;let instance4=effectiveInstance();if(!(record4.instance&&instance4&&record4.instance!==instance4))return record4}function prune(dir){try{for(let name of readdirSync(dir)){if(!name.endsWith(".json"))continue;let path2=join3(dir,name);try{Date.now()-statSync(path2).mtimeMs>PRUNE_MS&&rmSync(path2)}catch{}}}catch{}}function writeSession(record4){let file2=sessionFile();file2||fail(EXIT.USAGE,"NO_SESSION","No shell session detected (no TTY). Set SR_CONNECT_CLI_SESSION_ID, or pass --team/-w/-e explicitly."),persist(file2,record4)}function persist(file2,record4,instance4,options){let dir=sessionsDir();mkdirSync2(dir,{recursive:!0,mode:448}),prune(dir);let existing=options?.replace?void 0:readRecord(file2),carried=record4.serviceInfo??existing?.serviceInfo,locks=pruneLocks("locks"in record4?record4.locks:existing?.locks),update=record4.updateCheck??existing?.updateCheck,payload={...record4,version:SESSION_RECORD_VERSION,...carried===void 0?{}:{serviceInfo:carried},...locks===void 0?{}:{locks},...update===void 0?{}:{updateCheck:update},instance:instance4??effectiveInstance(),updatedAt:new Date().toISOString()},tmp=`${file2}.${process.pid}.tmp`;try{writeFileSync2(tmp,JSON.stringify(payload)+`
38
+ `,{mode:384}),renameSync(tmp,file2)}catch(err){throw rmSync(tmp,{force:!0}),err}}function pruneLocks(locks){if(!locks)return;let kept=Object.fromEntries(Object.entries(locks).filter(([,lock])=>{let expiry=Date.parse(lock.expiresAt);return!Number.isFinite(expiry)||Date.now()-expiry<LOCK_KEEP_MS}));return Object.keys(kept).length>0?kept:void 0}function readWorkspaceLock(workspaceId){let file2=sessionFile();if(file2)return readRecord(file2)?.locks?.[workspaceId]}function storeWorkspaceLock(workspaceId,lock){let file2=sessionFile();if(!file2)return!1;try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,locks,...rest}=existing??{};return persist(file2,{...rest,locks:{...locks,[workspaceId]:lock}}),!0}catch{return!1}}function forgetWorkspaceLock(workspaceId){let file2=sessionFile();if(!file2)return;let existing=readRecord(file2);if(existing?.locks?.[workspaceId])try{let{instance:_instance,updatedAt:_updatedAt,locks,...rest}=existing,remaining={...locks};delete remaining[workspaceId],persist(file2,{...rest,locks:remaining})}catch{}}function cachedServiceInfo(){return readSession()?.serviceInfo}function cacheServiceInfo(info){if(!enabled)return;let file2=sessionFile();if(file2)try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,...rest}=existing??{};persist(file2,{...rest,serviceInfo:info})}catch{}}function readUpdateCheck(){let file2=sessionFile();if(file2)return readRecord(file2)?.updateCheck}function storeUpdateCheck(check2){let file2=sessionFile();if(file2)try{let existing=readRecord(file2),{instance:_instance,updatedAt:_updatedAt,...rest}=existing??{};persist(file2,{...rest,updateCheck:check2})}catch{}}function forgetScopeValue(key,value,dependents=[]){if(!enabled)return[];let file2=sessionFile();if(!file2)return[];let existing=readRecord(file2);if(!existing||existing[key]!==value)return[];try{let{instance:_instance,updatedAt:_updatedAt,labels,...rest}=existing,removed=[key];delete rest[key];let remaining={...labels};delete remaining[key];for(let dependent of dependents)rest[dependent]!==void 0&&removed.push(dependent),delete rest[dependent],delete remaining[dependent];return persist(file2,{...rest,...Object.keys(remaining).length>0?{labels:remaining}:{}}),removed}catch{return[]}}function lockReleaseCommand(lock){let instance4=lock.instance?` --instance ${shellQuote(lock.instance)}`:"";return`${CLI} workspace-lock release -w ${lock.workspaceId} --lock-id ${lock.lockId}${instance4}`}function dropSession(file2){try{return rmSync(file2),!0}catch{return!1}}function clearSession(){let file2=sessionFile();if(!file2)return{cleared:!1,keptLocks:[]};let existing=readRecord(file2),locks=pruneLocks(existing?.locks);if(!locks)return{cleared:dropSession(file2),keptLocks:[]};let kept=keptLocksOf(locks);try{return persist(file2,{locks},void 0,{replace:!0}),{cleared:!0,keptLocks:kept}}catch{return{cleared:dropSession(file2),keptLocks:kept}}}function clearAllSessions(){let removed=0,keptLocks=[];try{for(let name of readdirSync(sessionsDir())){if(!name.endsWith(".json"))continue;let file2=join3(sessionsDir(),name),record4=readRecord(file2,{anyInstance:!0}),locks=pruneLocks(record4?.locks);try{locks?(persist(file2,{locks},record4?.instance,{replace:!0}),keptLocks.push(...keptLocksOf(locks,record4?.instance))):rmSync(file2),removed+=1}catch{}}}catch{}return{removed,keptLocks}}function keptLocksOf(locks,instance4){let now=Date.now(),foreign=instance4!==void 0&&instance4!==effectiveInstance()?{instance:instance4}:{};return Object.entries(locks).filter(([,lock])=>Date.parse(lock.expiresAt)>now).map(([workspaceId,lock])=>({workspaceId,lockId:lock.lockId,...foreign}))}function describeValue(record4,key){let id=record4[key]??"",label=record4.labels?.[key];return label?`${label} (${id})`:id}import{mkdirSync as mkdirSync3,readFileSync as readFileSync4,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync3}from"fs";import{join as join4}from"path";var SETTING_KEYS=["recordApiCalls","workspaceLock","localSync","crashReports","agenticFeedback"],SETTINGS={recordApiCalls:{label:"Record API calls",hint:"records this CLI's own requests to a local log, readable with `cli list-api-logs` \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_RECORD_API_CALLS",flag:"--no-record-api-calls"},workspaceLock:{label:"Auto workspace lock",hint:"takes a workspace lock before a write, so nothing else changes the workspace mid-command \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_LOCK",flag:"--no-lock"},localSync:{label:"Auto local sync",hint:"mirrors a change into the local copy of the workspace, if the local directory is a local workspace clone \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_LOCAL_SYNC",flag:"--no-local-sync"},crashReports:{label:"Generate crash reports",hint:"writes a report when a run fails unexpectedly, and offers to send it \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_CRASH_REPORTS",flag:"--no-crash-reports"},agenticFeedback:{label:"Allow agentic feedback",hint:"allows agents to send feedback autonomously for improvements \u2014 recommended to keep on",envVar:"SR_CONNECT_CLI_NO_AGENTIC_FEEDBACK",flag:"--no-agentic-feedback"}},SETTINGS_VERSION=1;function settingsFile(){return join4(stateHome(),APP_DIR,"settings.json")}var cache,warned=!1;function readSettings(){if(cache)return cache;let parsed;try{parsed=JSON.parse(readFileSync4(settingsFile(),"utf8"))}catch{return cache={},cache}let file2=parsed;if(typeof file2?.version=="number"&&file2.version>SETTINGS_VERSION)return warned||(warned=!0,warnLine(`\u26A0 ${settingsFile()} was written by a newer CLI (format ${file2.version}) \u2014 using the defaults. Update the CLI to read it.`)),cache={},cache;let values={},stored=file2?.values;if(stored&&typeof stored=="object")for(let key of SETTING_KEYS){let value=stored[key];typeof value=="boolean"&&(values[key]=value)}return cache=values,values}function envDisabled(key){let value=process.env[SETTINGS[key].envVar];return value===void 0?!1:!["","0","false","no","off"].includes(value.trim().toLowerCase())}function settingEnabled(key){return readSettings()[key]!==!1}function writeSettings(values){let forced=[],stored={};for(let key of SETTING_KEYS){if(envDisabled(key)){forced.push(key),stored[key]=!1;continue}values[key]||(stored[key]=!1)}let file2={version:SETTINGS_VERSION,updatedAt:new Date().toISOString(),values:stored},path2=settingsFile();mkdirSync3(join4(stateHome(),APP_DIR),{recursive:!0,mode:448});let tmp=`${path2}.${process.pid}.tmp`;try{writeFileSync3(tmp,JSON.stringify(file2)+`
39
+ `,{mode:384}),renameSync2(tmp,path2)}catch(err){throw rmSync2(tmp,{force:!0}),err}return cache=stored,forced}function setSetting(key,value){let stored=readSettings(),values=Object.fromEntries(SETTING_KEYS.map(candidate=>[candidate,candidate===key?value:stored[candidate]!==!1]));return writeSettings(values)}function settingStates(flagOff={}){let stored=readSettings();return SETTING_KEYS.map(key=>{let descriptor=SETTINGS[key],flagDisabled=flagOff[key]===!0,env=envDisabled(key),value=stored[key],source=flagDisabled?"flag":env?"env":value===void 0?"default":"stored";return{key,label:descriptor.label,hint:descriptor.hint,enabled:!flagDisabled&&!env&&value!==!1,stored:value??null,envVar:descriptor.envVar,envDisabled:env,flag:descriptor.flag,flagDisabled,source}})}var ENTRY_VERSION=2,MAX_BODY=4*1024,PRUNE_MS2=10080*60*1e3,MAX_SESSION_BYTES=25*1024*1024,ROLLED=".1.jsonl",SECRET_KEY=/password|secret|token|credential|apikey|authorization|lockid/i,SECRET_PARAM=/^(x-amz-signature|x-amz-credential|x-amz-security-token|signature|awsaccesskeyid|googleaccessid|sig|se|sp|sig_key|token|password|apikey)$/i,REDACTED="<redacted>",KEEP_HEADERS=["content-type","content-length","retry-after","x-sr-connect-workspace-lock-expires-at","x-request-id","x-amzn-requestid","x-amzn-trace-id"],enabled2=!1,argv=[],instance,runId="",runSequence=0,runStarted="",runWritten=!1,maintained=!1,SECRET_ARGV_FLAG=/^(--header|--lock-id)(=|$)/;function redactArg(flag,value){if(flag.startsWith("--lock-id"))return REDACTED;let at2=value.indexOf(":");return at2===-1?REDACTED:`${value.slice(0,at2)}: ${REDACTED}`}function sanitizeArgv(tokens){let out=[];for(let i=0;i<tokens.length;i++){let token=tokens[i]??"";if(!SECRET_ARGV_FLAG.test(token)){out.push(token);continue}let eq=token.indexOf("=");if(eq!==-1){out.push(`${token.slice(0,eq)}=${redactArg(token,token.slice(eq+1))}`);continue}out.push(token);let next=tokens[i+1];next!==void 0&&(out.push(redactArg(token,next)),i++)}return out}function configureRecorder(opts){let off=process.env.SR_CONNECT_CLI_NO_RECORD_API_CALLS;enabled2=opts.enabled!==!1&&(off===void 0||/^(0|false|no|off|)$/i.test(off.trim()))&&settingEnabled("recordApiCalls"),instance=opts.instance,argv=sanitizeArgv(process.argv.slice(2)),runStarted=new Date().toISOString(),runSequence+=1,runId=`${RUN_ID}-${runSequence}`,runWritten=!1,maintained=!1}function recordingEnabled(){return enabled2}function apiCallsDir(){return join5(stateHome(),APP_DIR,"api-calls")}function sessionFile2(key){return join5(apiCallsDir(),`${key}.jsonl`)}function sessionOf(name){return name.replace(/(\.1)?\.jsonl$/,"")}function sanitizeBody(text){if(text==="")return"";let bytes=Buffer.byteLength(text),out;try{out=JSON.stringify(redact(JSON.parse(text)))}catch{return`<non-json, ${bytes} bytes>`}return out.length>MAX_BODY?`${out.slice(0,MAX_BODY)}\u2026(truncated, ${bytes} bytes)`:out}function redactHeaders(value){return Array.isArray(value)?value.map(entry2=>entry2&&typeof entry2=="object"&&!Array.isArray(entry2)&&"name"in entry2&&"value"in entry2?{...entry2,value:REDACTED}:redact(entry2)):redact(value)}function redactAttachments(value){return Array.isArray(value)?value.map(entry2=>entry2&&typeof entry2=="object"&&!Array.isArray(entry2)&&"content"in entry2?{...entry2,content:REDACTED}:redact(entry2)):redact(value)}function redact(value){return Array.isArray(value)?value.map(redact):value&&typeof value=="object"?Object.fromEntries(Object.entries(value).map(([key,child])=>[key,SECRET_KEY.test(key)?REDACTED:key==="headers"?redactHeaders(child):key==="attachments"?redactAttachments(child):redact(child)])):typeof value=="string"&&/^https?:\/\//i.test(value)?sanitizeUrl(value):value}function pickHeaders(headers){let picked={};for(let name of KEEP_HEADERS){let value=headers.get(name);value!==null&&(picked[name]=value)}return picked}function instanceBaseUrl(value=instance){let resolved=resolveInstance(value);return resolved?baseUrl(resolved):void 0}function redactLockPath(url2){return url2.replace(/\/lock\/[^/?#]+/i,`/lock/${REDACTED}`)}function sanitizeUrl(url2,base=instanceBaseUrl()){if(url2=redactLockPath(url2),base!==void 0&&url2.startsWith(base))return url2;let cut=url2.indexOf("?");if(cut===-1)return url2;let query=url2.slice(cut+1).split("&").map(pair=>{let eq=pair.indexOf("="),name=eq===-1?pair:pair.slice(0,eq);return SECRET_PARAM.test(name)?`${name}=${REDACTED}`:pair}).join("&");return`${url2.slice(0,cut)}?${query}`}function recordApiCall(call){if(!enabled2)return;let key=sessionKey();if(!key)return;let path2=sessionFile2(key);try{mkdirSync4(apiCallsDir(),{recursive:!0,mode:448}),maintainOnce(path2,key);let lines=[];runWritten||lines.push({v:ENTRY_VERSION,t:"run",runId,ts:runStarted,argv,pid:process.pid,...instance===void 0?{}:{instance}}),lines.push({v:ENTRY_VERSION,t:"call",runId,...call,url:sanitizeUrl(call.url)}),appendFileSync2(path2,lines.map(line=>`${JSON.stringify(line)}
40
+ `).join(""),{mode:384}),runWritten=!0}catch(err){enabled2=!1;let message=err instanceof Error?err.message:String(err);warnLine(`\u26A0 Could not record API calls to ${path2}: ${message}`)}}function maintainOnce(path2,key){maintained||(maintained=!0,prune2(),roll(path2,key))}function prune2(){for(let name of listFiles()){let path2=join5(apiCallsDir(),name);try{Date.now()-statSync2(path2).mtimeMs>PRUNE_MS2&&rmSync3(path2)}catch{}}}function roll(path2,key){try{if(statSync2(path2).size<MAX_SESSION_BYTES)return;renameSync3(path2,join5(apiCallsDir(),`${key}${ROLLED}`))}catch{}}function listFiles(){try{return readdirSync2(apiCallsDir()).filter(name=>name.endsWith(".jsonl")).sort()}catch{return[]}}function filesToRead(opts){if(opts.allSessions)return listFiles();let key=opts.session??sessionKey();if(!key)return[];let present=new Set(listFiles());return[`${key}${ROLLED}`,`${key}.jsonl`].filter(name=>present.has(name))}function parseFile(name){let text;try{text=readFileSync5(join5(apiCallsDir(),name),"utf8")}catch{return[]}let lines=[];for(let line of text.split(`
41
+ `))if(line.trim()!=="")try{let parsed=JSON.parse(line);parsed.v===ENTRY_VERSION&&lines.push(parsed)}catch{}return lines}function readApiCalls(opts){let runs=[],byId=new Map;for(let name of filesToRead(opts)){let session=sessionOf(name),runOf=(id,ts)=>{let runKey=`${session}\0${id}`,known=byId.get(runKey);if(known)return known;let created={runId:id,ts,argv:[],pid:0,session,calls:[],totalCalls:0};return byId.set(runKey,created),runs.push(created),created};for(let line of parseFile(name)){if(line.t==="run"){let run2=runOf(line.runId,line.ts);run2.ts=line.ts,run2.argv=line.argv,run2.pid=line.pid,run2.instance=line.instance;continue}let run=runOf(line.runId,line.ts),{v:_version,t:_type,runId:_runId,...call}=line;run.calls.push(call),run.totalCalls+=1}}return runs.sort((a,b2)=>a.ts.localeCompare(b2.ts))}function listRecordedSessions(){return summarize(listFiles())}function recordedTargets(opts){return summarize(filesToRead(opts))}function summarize(names){let rows2=new Map;for(let name of names){let session=sessionOf(name),row=rows2.get(session)??{session,files:0,runs:0,calls:0,bytes:0},lines=parseFile(name),calls=lines.filter(line=>line.t==="call");row.files+=1,row.runs+=lines.filter(line=>line.t==="run").length,row.calls+=calls.length,row.first??=calls[0]?.ts,row.last=calls.at(-1)?.ts??row.last;try{row.bytes+=statSync2(join5(apiCallsDir(),name)).size}catch{}rows2.set(session,row)}return[...rows2.values()]}function clearApiCalls(opts){let removed=new Set;for(let name of filesToRead(opts))try{rmSync3(join5(apiCallsDir(),name)),removed.add(sessionOf(name))}catch{}return[...removed]}import{closeSync,mkdirSync as mkdirSync6,openSync,readFileSync as readFileSync8,readSync,readdirSync as readdirSync4,rmSync as rmSync5,statSync as statSync4,writeFileSync as writeFileSync5}from"fs";import{arch,platform,release}from"os";import{join as join8}from"path";var PATH_PARAM_RE=/\{[^{}]+\}/g,supportsRequestInitExt=()=>typeof process=="object"&&Number.parseInt(process?.versions?.node?.substring(0,2))>=18&&process.versions.undici;function randomID(){return Math.random().toString(36).slice(2,11)}function createClient(clientOptions){let{baseUrl:baseUrl2="",Request:CustomRequest=globalThis.Request,fetch:baseFetch=globalThis.fetch,querySerializer:globalQuerySerializer,bodySerializer:globalBodySerializer,pathSerializer:globalPathSerializer,headers:baseHeaders,requestInitExt=void 0,...baseOptions}={...clientOptions};requestInitExt=supportsRequestInitExt()?requestInitExt:void 0,baseUrl2=removeTrailingSlash(baseUrl2);let globalMiddlewares=[];async function coreFetch(schemaPath,fetchOptions){let{baseUrl:localBaseUrl,fetch:fetch2=baseFetch,Request:Request2=CustomRequest,headers,params={},parseAs="json",querySerializer:requestQuerySerializer,bodySerializer=globalBodySerializer??defaultBodySerializer,pathSerializer:requestPathSerializer,body,middleware:requestMiddlewares=[],...init}=fetchOptions||{},finalBaseUrl=baseUrl2;localBaseUrl&&(finalBaseUrl=removeTrailingSlash(localBaseUrl)??baseUrl2);let querySerializer=typeof globalQuerySerializer=="function"?globalQuerySerializer:createQuerySerializer(globalQuerySerializer);requestQuerySerializer&&(querySerializer=typeof requestQuerySerializer=="function"?requestQuerySerializer:createQuerySerializer({...typeof globalQuerySerializer=="object"?globalQuerySerializer:{},...requestQuerySerializer}));let pathSerializer=requestPathSerializer||globalPathSerializer||defaultPathSerializer,serializedBody=body===void 0?void 0:bodySerializer(body,mergeHeaders(baseHeaders,headers,params.header)),finalHeaders=mergeHeaders(serializedBody===void 0||serializedBody instanceof FormData?{}:{"Content-Type":"application/json"},baseHeaders,headers,params.header),finalMiddlewares=[...globalMiddlewares,...requestMiddlewares],requestInit={redirect:"follow",...baseOptions,...init,body:serializedBody,headers:finalHeaders},id,options,request=new Request2(createFinalURL(schemaPath,{baseUrl:finalBaseUrl,params,querySerializer,pathSerializer}),requestInit),response;for(let key in init)key in request||(request[key]=init[key]);if(finalMiddlewares.length){id=randomID(),options=Object.freeze({baseUrl:finalBaseUrl,fetch:fetch2,parseAs,querySerializer,bodySerializer,pathSerializer});for(let m2 of finalMiddlewares)if(m2&&typeof m2=="object"&&typeof m2.onRequest=="function"){let result=await m2.onRequest({request,schemaPath,params,options,id});if(result)if(result instanceof Request2)request=result;else if(result instanceof Response){response=result;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!response){try{response=await fetch2(request,requestInitExt)}catch(error210){let errorAfterMiddleware=error210;if(finalMiddlewares.length)for(let i=finalMiddlewares.length-1;i>=0;i--){let m2=finalMiddlewares[i];if(m2&&typeof m2=="object"&&typeof m2.onError=="function"){let result=await m2.onError({request,error:errorAfterMiddleware,schemaPath,params,options,id});if(result){if(result instanceof Response){errorAfterMiddleware=void 0,response=result;break}if(result instanceof Error){errorAfterMiddleware=result;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(errorAfterMiddleware)throw errorAfterMiddleware}if(finalMiddlewares.length)for(let i=finalMiddlewares.length-1;i>=0;i--){let m2=finalMiddlewares[i];if(m2&&typeof m2=="object"&&typeof m2.onResponse=="function"){let result=await m2.onResponse({request,response,schemaPath,params,options,id});if(result){if(!(result instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");response=result}}}}let contentLength=response.headers.get("Content-Length");if(response.status===204||request.method==="HEAD"||contentLength==="0"&&!response.headers.get("Transfer-Encoding")?.includes("chunked"))return response.ok?{data:void 0,response}:{error:void 0,response};if(response.ok)return{data:await(async()=>{if(parseAs==="stream")return response.body;if(parseAs==="json"&&!contentLength){let raw=await response.text();return raw?JSON.parse(raw):void 0}return await response[parseAs]()})(),response};let error51=await response.text();try{error51=JSON.parse(error51)}catch{}return{error:error51,response}}return{request(method,url2,init){return coreFetch(url2,{...init,method:method.toUpperCase()})},GET(url2,init){return coreFetch(url2,{...init,method:"GET"})},PUT(url2,init){return coreFetch(url2,{...init,method:"PUT"})},POST(url2,init){return coreFetch(url2,{...init,method:"POST"})},DELETE(url2,init){return coreFetch(url2,{...init,method:"DELETE"})},OPTIONS(url2,init){return coreFetch(url2,{...init,method:"OPTIONS"})},HEAD(url2,init){return coreFetch(url2,{...init,method:"HEAD"})},PATCH(url2,init){return coreFetch(url2,{...init,method:"PATCH"})},TRACE(url2,init){return coreFetch(url2,{...init,method:"TRACE"})},use(...middleware){for(let m2 of middleware)if(m2){if(typeof m2!="object"||!("onRequest"in m2||"onResponse"in m2||"onError"in m2))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");globalMiddlewares.push(m2)}},eject(...middleware){for(let m2 of middleware){let i=globalMiddlewares.indexOf(m2);i!==-1&&globalMiddlewares.splice(i,1)}}}}function serializePrimitiveParam(name,value,options){if(value==null)return"";if(typeof value=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return`${name}=${options?.allowReserved===!0?value:encodeURIComponent(value)}`}function serializeObjectParam(name,value,options){if(!value||typeof value!="object")return"";let values=[],joiner={simple:",",label:".",matrix:";"}[options.style]||"&";if(options.style!=="deepObject"&&options.explode===!1){for(let k2 in value)values.push(k2,options.allowReserved===!0?value[k2]:encodeURIComponent(value[k2]));let final2=values.join(",");switch(options.style){case"form":return`${name}=${final2}`;case"label":return`.${final2}`;case"matrix":return`;${name}=${final2}`;default:return final2}}for(let k2 in value){let finalName=options.style==="deepObject"?`${name}[${k2}]`:k2;values.push(serializePrimitiveParam(finalName,value[k2],options))}let final=values.join(joiner);return options.style==="label"||options.style==="matrix"?`${joiner}${final}`:final}function serializeArrayParam(name,value,options){if(!Array.isArray(value))return"";if(options.explode===!1){let joiner2={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[options.style]||",",final=(options.allowReserved===!0?value:value.map(v2=>encodeURIComponent(v2))).join(joiner2);switch(options.style){case"simple":return final;case"label":return`.${final}`;case"matrix":return`;${name}=${final}`;default:return`${name}=${final}`}}let joiner={simple:",",label:".",matrix:";"}[options.style]||"&",values=[];for(let v2 of value)options.style==="simple"||options.style==="label"?values.push(options.allowReserved===!0?v2:encodeURIComponent(v2)):values.push(serializePrimitiveParam(name,v2,options));return options.style==="label"||options.style==="matrix"?`${joiner}${values.join(joiner)}`:values.join(joiner)}function createQuerySerializer(options){return function(queryParams){let search=[];if(queryParams&&typeof queryParams=="object")for(let name in queryParams){let value=queryParams[name];if(value!=null){if(Array.isArray(value)){if(value.length===0)continue;search.push(serializeArrayParam(name,value,{style:"form",explode:!0,...options?.array,allowReserved:options?.allowReserved||!1}));continue}if(typeof value=="object"){search.push(serializeObjectParam(name,value,{style:"deepObject",explode:!0,...options?.object,allowReserved:options?.allowReserved||!1}));continue}search.push(serializePrimitiveParam(name,value,options))}}return search.join("&")}}function defaultPathSerializer(pathname,pathParams){let nextURL=pathname;for(let match of pathname.match(PATH_PARAM_RE)??[]){let name=match.substring(1,match.length-1),explode=!1,style="simple";if(name.endsWith("*")&&(explode=!0,name=name.substring(0,name.length-1)),name.startsWith(".")?(style="label",name=name.substring(1)):name.startsWith(";")&&(style="matrix",name=name.substring(1)),!pathParams||pathParams[name]===void 0||pathParams[name]===null)continue;let value=pathParams[name];if(Array.isArray(value)){nextURL=nextURL.replace(match,serializeArrayParam(name,value,{style,explode}));continue}if(typeof value=="object"){nextURL=nextURL.replace(match,serializeObjectParam(name,value,{style,explode}));continue}if(style==="matrix"){nextURL=nextURL.replace(match,`;${serializePrimitiveParam(name,value)}`);continue}nextURL=nextURL.replace(match,style==="label"?`.${encodeURIComponent(value)}`:encodeURIComponent(value))}return nextURL}function defaultBodySerializer(body,headers){return body instanceof FormData?body:headers&&(headers.get instanceof Function?headers.get("Content-Type")??headers.get("content-type"):headers["Content-Type"]??headers["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(body).toString():JSON.stringify(body)}function createFinalURL(pathname,options){let finalURL=`${options.baseUrl}${pathname}`;options.params?.path&&(finalURL=options.pathSerializer(finalURL,options.params.path));let search=options.querySerializer(options.params.query??{});return search.startsWith("?")&&(search=search.substring(1)),search&&(finalURL+=`?${search}`),finalURL}function mergeHeaders(...allHeaders){let finalHeaders=new Headers;for(let h of allHeaders){if(!h||typeof h!="object")continue;let iterator=h instanceof Headers?h.entries():Object.entries(h);for(let[k2,v2]of iterator)if(v2===null)finalHeaders.delete(k2);else if(Array.isArray(v2))for(let v22 of v2)finalHeaders.append(k2,v22);else v2!==void 0&&finalHeaders.set(k2,v2)}return finalHeaders}function removeTrailingSlash(url2){return url2.endsWith("/")?url2.substring(0,url2.length-1):url2}var import_picocolors4=__toESM(require_picocolors(),1);import{chmodSync,mkdirSync as mkdirSync5,readFileSync as readFileSync6,rmSync as rmSync4,writeFileSync as writeFileSync4}from"fs";import{join as join6}from"path";var SERVICE=APP_DIR,ACCOUNT="default";async function entry(){if(process.env.SR_CONNECT_CLI_DISABLE_KEYCHAIN)throw new Error("Keychain disabled via SR_CONNECT_CLI_DISABLE_KEYCHAIN.");let{Entry}=await import("@napi-rs/keyring");return new Entry(SERVICE,ACCOUNT)}async function keychainGet(){try{let raw=(await entry()).getPassword();return raw?JSON.parse(raw):null}catch{return null}}async function keychainSet(creds){(await entry()).setPassword(JSON.stringify(creds))}async function keychainDelete(){try{return(await entry()).deletePassword()}catch{return!1}}var CREDENTIALS_FILE=()=>join6(configDir(),"credentials.json");function fileGet(){try{return JSON.parse(readFileSync6(CREDENTIALS_FILE(),"utf8"))}catch{return null}}function fileSet(creds){mkdirSync5(configDir(),{recursive:!0}),writeFileSync4(CREDENTIALS_FILE(),JSON.stringify(creds,null,2)+`
42
+ `,{mode:384}),chmodSync(CREDENTIALS_FILE(),384)}function fileDelete(){rmSync4(CREDENTIALS_FILE(),{force:!0})}async function resolveCredentials(){let creds=await lookupCredentials();return creds&&(resolvedUsername=creds.username),creds}async function lookupCredentials(){let envUser=process.env.SR_CONNECT_CLI_USERNAME,envPass=process.env.SR_CONNECT_CLI_PASSWORD;if(envUser&&envPass)return{username:envUser,password:envPass,source:"env"};let fromKeychain=await keychainGet();if(fromKeychain)return{...fromKeychain,source:"keychain"};let fromFile=fileGet();return fromFile?{...fromFile,source:"file"}:null}var resolvedUsername;function currentUsername(){return resolvedUsername}async function requireCredentials(){let creds=await resolveCredentials();return creds||fail(EXIT.UNAUTHENTICATED,"UNAUTHENTICATED","Not authenticated.",{hint:`Run \`${CLI} auth login\`, or set SR_CONNECT_CLI_USERNAME, SR_CONNECT_CLI_PASSWORD and SR_CONNECT_CLI_INSTANCE.`}),creds}function basicAuthHeader(creds){return"Basic "+Buffer.from(`${creds.username}:${creds.password}`).toString("base64")}var MIN_NODE_MAJOR=22;function runtimeNodeVersion(){return process.versions.node}function nodeMajor(version2=runtimeNodeVersion()){let major=Number.parseInt(version2??"",10);return Number.isFinite(major)?major:void 0}function nodeVersionWarning(version2=runtimeNodeVersion()){let major=Number.parseInt(version2??"",10);if(!(!Number.isFinite(major)||major>=MIN_NODE_MAJOR))return`\u26A0 Node ${version2} is older than the Node ${MIN_NODE_MAJOR} this CLI needs \u2014 live log streaming (--stream-logs) is unavailable and other commands may fail.`}var warned2=!1;function warnIfNodeUnsupported(){if(warned2)return;let warning=nodeVersionWarning();warning&&(warned2=!0,warnLine(warning))}var SEMVER_FORMAT="major.minor.patch",SEMVER=/^\d+\.\d+\.\d+$/;function semverError(version2){let trimmed=version2.trim();if(!SEMVER.test(trimmed))return`Expected a version in ${SEMVER_FORMAT} format, e.g. 1.4.0 \u2014 got "${trimmed}".`}function assertSemver(version2){let error51=semverError(version2);return error51&&fail(EXIT.USAGE,"INVALID_VERSION",error51),version2.trim()}var LOOSE_SEMVER=/^v?(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function parseVersion(version2){let trimmed=version2.trim(),match=LOOSE_SEMVER.exec(trimmed);if(match)return{major:Number(match[1]??0),minor:Number(match[2]??0),patch:Number(match[3]??0),release:trimmed.includes("-")?0:1}}function compareSemver(a,b2){let left=parseVersion(a),right=parseVersion(b2);return left?right?left.major-right.major||left.minor-right.minor||left.patch-right.patch||left.release-right.release:1:right?-1:0}var DEFAULT_REGISTRY="https://registry.npmjs.org",LOOKUP_TIMEOUT_MS=5e3,MAX_OFFERED_VERSIONS=30,fetchImpl=(...args)=>fetch(...args);function registryBase(){let configured=process.env.SR_CONNECT_CLI_NPM_REGISTRY;return(configured&&configured.trim()!==""?configured.trim():DEFAULT_REGISTRY).replace(/\/+$/,"")}function isPrerelease(version2){return version2.includes("-")}async function fetchVersions(name){try{let response=await fetchImpl(`${registryBase()}/${encodeURIComponent(name)}`,{headers:{accept:"application/vnd.npm.install-v1+json","user-agent":USER_AGENT},signal:AbortSignal.timeout(LOOKUP_TIMEOUT_MS)});if(response.status===404)return"not-found";if(!response.ok)return;let body=await response.json();if(!body.versions||typeof body.versions!="object"||Array.isArray(body.versions))return;let versions=Object.keys(body.versions).reverse();if(versions.length===0)return;let distTags=body["dist-tags"]&&typeof body["dist-tags"]=="object"&&!Array.isArray(body["dist-tags"])?body["dist-tags"]:{},latest=typeof distTags.latest=="string"?distTags.latest:void 0;return{versions,distTags,...latest?{latest}:{}}}catch{return}}var enabled3=!0;function configureUpdateCheck(opts){let off=process.env.SR_CONNECT_CLI_NO_UPDATE_CHECK;enabled3=opts.enabled&&(off===void 0||/^(0|false|no|off|)$/i.test(off.trim()))}function latestStable(lookup){return lookup.latest&&!isPrerelease(lookup.latest)?lookup.latest:lookup.versions.filter(v2=>!isPrerelease(v2)).sort(compareSemver).at(-1)}function isFresh(checkedAt){let age=Date.now()-Date.parse(checkedAt);return Number.isFinite(age)&&age>=0&&age<SESSION_TTL_MS}function startUpdateCheck(){if(!enabled3)return;let stored=readUpdateCheck();stored&&isFresh(stored.checkedAt)||fetchVersions(PACKAGE).then(lookup=>{if(!lookup||lookup==="not-found")return;let latest=latestStable(lookup);latest&&storeUpdateCheck({checkedAt:new Date().toISOString(),latest})})}function updateCommand(kind,manager){let spec=`${PACKAGE}@latest`;return kind==="npx"?`npx ${spec}`:kind!=="global"?`npm install ${spec}`:manager==="pnpm"?`pnpm add -g ${spec}`:manager==="bun"?`bun add -g ${spec}`:`npm install -g ${spec}`}function updateNotice(latest,current=VERSION,site=currentSite()){if(compareSemver(latest,current)<=0)return;let{kind,manager}=classifyInstall(site);return{command:updateCommand(kind,manager),current,latest}}function renderBanner(body){let width=Math.max(...body.map(line=>Array.from(line).length)),rule="*".repeat(width+6),pad=line=>`* ${line}${" ".repeat(width-Array.from(line).length)} *`;return[rule,pad(""),...body.map(pad),pad(""),rule]}function updateBody(notice){return[`New version of ${PACKAGE} available!`,`${notice.current} \u2192 ${notice.latest}`,"","Update with:",notice.command]}function unsupportedNotice(current=VERSION,site=currentSite()){let{kind,manager}=classifyInstall(site),command=updateCommand(kind,manager);return{message:`${PACKAGE} ${current} is no longer supported by this deployment.`,hint:`Update with: ${command}`,banner:renderBanner([`${PACKAGE} ${current} is no longer supported.`,"","Update with:",command])}}function renderCompact(notice){return[`\u2714 ${PACKAGE} ${notice.latest} is available (you have ${notice.current}).`,` Update with: ${notice.command}`]}var announced=!1;function printUpdateNotice(){if(announced||!enabled3)return;let stored=readUpdateCheck();if(!stored)return;let notice=updateNotice(stored.latest);if(notice){announced=!0;for(let line of isRaw()?renderCompact(notice):renderBanner(updateBody(notice)))successLine(line)}}function asksForUpdates(argv2){let words=argv2.slice(2).filter(token=>!token.startsWith("-"));return words[0]==="cli"&&words[1]==="check-updates"}async function checkForUpdate(){let lookup=await fetchVersions(PACKAGE);if(lookup==="not-found")return{state:"unpublished"};if(!lookup)return{state:"unreachable"};let latest=latestStable(lookup);if(!latest)return{state:"unpublished"};storeUpdateCheck({checkedAt:new Date().toISOString(),latest});let notice=updateNotice(latest);return notice?{notice,state:"available"}:{current:VERSION,latest,state:"current"}}function renderUpdateLine(answer){if(answer.state==="available"){let{command,current,latest}=answer.notice;return`\u2714 ${PACKAGE} ${latest} is available (you have ${current}). Update with: ${command}`}return`\u2714 ${PACKAGE} ${answer.current} is the latest version.`}var flagEnabled=!0;function configureVersionGate(opts){flagEnabled=opts.enabled}function gateEnabled(){return flagEnabled&&!process.env.SR_CONNECT_CLI_NO_VERSION_GATE}var refreshed=!1;async function readServiceInfo(client,opts={}){let cached2=cachedServiceInfo(),refresh=opts.refreshWithoutStreamUrl===!0&&!cached2?.logsStreamUrl&&!refreshed;if(cached2&&!refresh)return cached2;refresh&&cached2&&(refreshed=!0);let answer=await client.GET("/v1/serviceInfo",{}).catch(()=>{});if(!answer)return cached2;let{data,response}=answer;if(response.status===401&&fail(EXIT.UNAUTHENTICATED,"INVALID_CREDENTIALS","The API rejected these credentials.",{hint:`Run \`${CLI} auth login\` and try again.`}),!response.ok||!data)return cached2;let info={readAt:new Date().toISOString(),...data.logsStreamUrl?{logsStreamUrl:data.logsStreamUrl}:{},...data.minimumCliVersion?{minimumCliVersion:data.minimumCliVersion}:{}};return cacheServiceInfo(info),info}async function assertSupportedVersion(client){if(!gateEnabled())return;let minimum=(await readServiceInfo(client))?.minimumCliVersion;if(!minimum||compareSemver(VERSION,minimum)>=0)return;let notice=unsupportedNotice();fail(EXIT.USAGE,"CLI_TOO_OLD",notice.message,{banner:notice.banner,hint:notice.hint})}var import_picocolors3=__toESM(require_picocolors(),1);import crypto from"crypto";var ENCODING="0123456789ABCDEFGHJKMNPQRSTVWXYZ",ENCODING_LEN=32;var RANDOM_LEN=16,TIME_LEN=10,TIME_MAX=0xffffffffffff;var ULIDErrorCode;(function(ULIDErrorCode2){ULIDErrorCode2.Base32IncorrectEncoding="B32_ENC_INVALID",ULIDErrorCode2.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",ULIDErrorCode2.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",ULIDErrorCode2.EncodeTimeNegative="ENC_TIME_NEG",ULIDErrorCode2.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",ULIDErrorCode2.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",ULIDErrorCode2.PRNGDetectFailure="PRNG_DETECT",ULIDErrorCode2.ULIDInvalid="ULID_INVALID",ULIDErrorCode2.Unexpected="UNEXPECTED",ULIDErrorCode2.UUIDInvalid="UUID_INVALID"})(ULIDErrorCode||(ULIDErrorCode={}));var ULIDError=class extends Error{constructor(errorCode,message){super(`${message} (${errorCode})`),this.name="ULIDError",this.code=errorCode}};function randomChar(prng){let randomPosition=Math.floor(prng()*ENCODING_LEN)%ENCODING_LEN;return ENCODING.charAt(randomPosition)}function detectPRNG(root){let rootLookup=detectRoot(),globalCrypto=rootLookup&&(rootLookup.crypto||rootLookup.msCrypto)||(typeof crypto<"u"?crypto:null);if(typeof globalCrypto?.getRandomValues=="function")return()=>{let buffer=new Uint8Array(1);return globalCrypto.getRandomValues(buffer),buffer[0]/256};if(typeof globalCrypto?.randomBytes=="function")return()=>globalCrypto.randomBytes(1).readUInt8()/256;if(crypto?.randomBytes)return()=>crypto.randomBytes(1).readUInt8()/256;throw new ULIDError(ULIDErrorCode.PRNGDetectFailure,"Failed to find a reliable PRNG")}function detectRoot(){return inWebWorker()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function encodeRandom(len,prng){let str="";for(;len>0;len--)str=randomChar(prng)+str;return str}function encodeTime(now,len=TIME_LEN){if(isNaN(now))throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed,`Time must be a number: ${now}`);if(now>TIME_MAX)throw new ULIDError(ULIDErrorCode.EncodeTimeSizeExceeded,`Cannot encode a time larger than ${TIME_MAX}: ${now}`);if(now<0)throw new ULIDError(ULIDErrorCode.EncodeTimeNegative,`Time must be positive: ${now}`);if(Number.isInteger(now)===!1)throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed,`Time must be an integer: ${now}`);let mod,str="";for(let currentLen=len;currentLen>0;currentLen--)mod=now%ENCODING_LEN,str=ENCODING.charAt(mod)+str,now=(now-mod)/ENCODING_LEN;return str}function inWebWorker(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ulid(seedTime,prng){let currentPRNG=prng||detectPRNG(),seed=!seedTime||isNaN(seedTime)?Date.now():seedTime;return encodeTime(seed,TIME_LEN)+encodeRandom(RANDOM_LEN,currentPRNG)}function personName(person){return[person.firstName,person.lastName].filter(Boolean).join(" ")||person.email||""}function personCell(person){return`${personName(person)||person.id}${person.id?` (${person.id})`:""}`}var import_cronstrue=__toESM(require_cronstrue(),1);var CRON_FIELDS="second minute hour day-of-month month day-of-week",HOURLY_CRON="0 0 * * * *";function everyMinutesCron(minutes){return`0 */${minutes} * * * *`}function dailyCron(hour,minute){return`0 ${minute} ${hour} * * *`}function weeklyCron(day,hour,minute){return`0 ${minute} ${hour} * * ${day}`}function normalizeCron(expression){return expression.trim().split(/\s+/).join(" ")}function errorForNormalized(normalized){let parts=normalized.split(" ").filter(Boolean);if(parts.length!==6)return`CRON expression must have 6 fields (${CRON_FIELDS}) \u2014 got ${parts.length}.`;try{(0,import_cronstrue.toString)(parts.join(" "))}catch(err){return`Invalid CRON expression: ${(err instanceof Error?err.message:String(err)).replace(/^Error:\s*/,"")}`}}function cronError(expression){return errorForNormalized(normalizeCron(expression))}function describeCron(expression){try{return(0,import_cronstrue.toString)(normalizeCron(expression))}catch{return}}var MIN_TRIGGER_INTERVAL_MINUTES=15;function scheduleOf(trigger){return trigger.cronExpressionDescription??trigger.cronExpression??"not scheduled"}function assertCron(expression){let normalized=normalizeCron(expression),message=errorForNormalized(normalized);return message&&fail(EXIT.USAGE,"INVALID_CRON",message,{hint:`Once per hour is ${HOURLY_CRON}`}),normalized}var ResolverFetchError=class extends Error{status;constructor(status,message){super(message),this.status=status}};function listenerAppRegistry(){let app=RESOLVERS.app;return app?{...RESOLVERS,app:{...app,async fetch(client,deps){let payload=await fetchApps(client),withListeners=new Set(payload.apps.filter(a=>connectionTypes(a).some(ct2=>(ct2.eventListenerTypes??[]).length>0)).map(a=>a.id));return(await app.fetch(client,deps)).filter(choice=>withListeners.has(choice.value))}}}:RESOLVERS}function mapResolverError(err,spec){err.status===401&&fail(EXIT.UNAUTHENTICATED,"INVALID_CREDENTIALS",err.message,{status:401}),fail(err.status===404?EXIT.NOT_FOUND:EXIT.API_ERROR,err.status===404?"NOT_FOUND":"API_ERROR",`Fetching ${spec.plural} failed: ${err.message}`,{status:err.status})}function must(deps,key){let v2=deps[key];if(!v2)throw new Error(`resolver dependency '${key}' missing`);return v2}async function unwrap(res){if(!res.response.ok||res.data===void 0){let message=res.error?.errorMessage??`Request failed with HTTP status ${res.response.status}.`;throw new ResolverFetchError(res.response.status,message)}return res.data}var appsCache=new WeakMap,featuresCache=new WeakMap;async function teamFeatures(client,teamId){return await teamFeaturesIfKnown(client,teamId)??{eventQueues:!1,remoteWorkspace:!1}}async function teamFeaturesIfKnown(client,teamId){let perTeam=featuresCache.get(client);perTeam||featuresCache.set(client,perTeam=new Map);let cached2=perTeam.get(teamId);return cached2||(cached2=client.GET("/v1/team/{teamId}",{params:{path:{teamId}}}).then(res=>res.response.ok&&res.data?res.data.features:void 0).catch(()=>{}),perTeam.set(teamId,cached2)),cached2}function connectionTypes(app){return app.connectionTypes??(app.connectionType?[app.connectionType]:[])}async function fetchApps(client){let cached2=appsCache.get(client);return cached2||(cached2=client.GET("/v1/apps").then(unwrap),appsCache.set(client,cached2)),cached2}function findApp(payload,appId){return payload.apps.find(a=>a.id===appId)}function findApiConnectionType(app,apiConnectionTypeId){return connectionTypes(app).flatMap(ct2=>ct2.apiConnectionTypes??[]).find(t=>t.id===apiConnectionTypeId)}async function apiConnectionPackages(client,appId,apiConnectionTypeId){let app=findApp(await fetchApps(client),appId);if(!app)throw new ResolverFetchError(404,`App '${appId}' not found.`);let type=findApiConnectionType(app,apiConnectionTypeId);if(!type)throw new ResolverFetchError(404,`API connection type '${apiConnectionTypeId}' not found.`);return type.packages??[]}var GENERIC_APP="Generic";async function appConnectionTypeName(client,appId){let app=findApp(await fetchApps(client),appId);if(app)return connectionTypes(app)[0]?.name}async function isGenericApp(client,appId){try{return await appConnectionTypeName(client,appId)===GENERIC_APP}catch{return!1}}var environmentsCache=new WeakMap;function fetchEnvironments(client,workspaceId){let perWorkspace=environmentsCache.get(client);perWorkspace||environmentsCache.set(client,perWorkspace=new Map);let cached2=perWorkspace.get(workspaceId);return cached2||(cached2=client.GET("/v1/workspace/{workspaceId}/environments",{params:{path:{workspaceId}}}).then(unwrap),cached2.catch(()=>perWorkspace.delete(workspaceId)),perWorkspace.set(workspaceId,cached2)),cached2}async function environmentRelease(client,workspaceId,environmentId){return(await environmentInfo(client,workspaceId,environmentId))?.release}async function environmentInfo(client,workspaceId,environmentId){return(await fetchEnvironments(client,workspaceId).catch(()=>{}))?.environments.find(e=>e.id===environmentId)}async function environmentBelongsTo(client,workspaceId,environmentId){let data=await fetchEnvironments(client,workspaceId).catch(()=>{});if(data)return data.environments.some(e=>e.id===environmentId)}var packagesCache=new WeakMap;function fetchWorkspacePackages(client,workspaceId){let perWorkspace=packagesCache.get(client);perWorkspace||packagesCache.set(client,perWorkspace=new Map);let cached2=perWorkspace.get(workspaceId);return cached2||(cached2=client.GET("/v1/workspace/{workspaceId}/packages",{params:{path:{workspaceId}}}).then(unwrap),cached2.catch(()=>perWorkspace.delete(workspaceId)),perWorkspace.set(workspaceId,cached2)),cached2}async function packageInfo(client,workspaceId,packageId){return(await fetchWorkspacePackages(client,workspaceId).catch(()=>{}))?.packages.find(p=>p.id===packageId)}var connectorsCache=new WeakMap;function fetchConnectors(client,teamId){let perTeam=connectorsCache.get(client);perTeam||connectorsCache.set(client,perTeam=new Map);let cached2=perTeam.get(teamId);return cached2||(cached2=client.GET("/v1/team/{teamId}/connectors",{params:{path:{teamId}}}).then(unwrap),cached2.catch(()=>perTeam.delete(teamId)),perTeam.set(teamId,cached2)),cached2}async function connectorInfo(client,teamId,connectorId){return(await fetchConnectors(client,teamId).catch(()=>{}))?.connections.find(c=>c.id===connectorId)}var userCache=new WeakMap;async function currentUser(client){let cached2=userCache.get(client);return cached2||(cached2=client.GET("/v1/user/me").then(res=>res.response.ok&&res.data?res.data:void 0).catch(()=>{}),userCache.set(client,cached2)),cached2}async function currentUserId(client){return(await currentUser(client))?.id}var RESOLVERS={team:{key:"team",flag:"--team",label:"Team",plural:"teams",listCommand:`${CLI} team list`,dependsOn:[],async fetch(client){return(await unwrap(await client.GET("/v1/teams"))).teams.map(t=>({value:t.id,label:t.name,hint:t.id}))}},workspace:{key:"workspace",flag:"-w, --workspace",label:"Workspace",plural:"workspaces",listCommand:`${CLI} workspace list`,dependsOn:["team"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/team/{teamId}/workspaces",{params:{path:{teamId:must(deps,"team")}}}))).workspaces.map(w=>({value:w.id,label:w.name,hint:w.id}))}},environment:{key:"environment",flag:"-e, --env",label:"Environment",plural:"environments",listCommand:`${CLI} environment list`,dependsOn:["workspace"],async fetch(client,deps){return(await fetchEnvironments(client,must(deps,"workspace"))).environments.map(e=>({value:e.id??"",label:e.name??e.id??"?",display:`${e.name??e.id??"?"} (${e.release?.version??"HEAD"})`,hint:e.id}))}},release:{key:"release",flag:"<releaseId>",label:"Release",plural:"releases",listCommand:`${CLI} release list`,dependsOn:["workspace"],async fetch(client,deps){return[...(await unwrap(await client.GET("/v1/workspace/{workspaceId}/releases",{params:{path:{workspaceId:must(deps,"workspace")}}}))).releases].reverse().map(r=>({value:r.id,label:r.version,...r.label?{display:`${r.version} \u2014 ${r.label}`}:{},hint:r.created}))}},parameter:{key:"parameter",flag:"<parameterId>",label:"Parameter",plural:"parameters",listCommand:`${CLI} environment-parameter list`,dependsOn:["workspace","environment"],async fetch(client,deps){let data=await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/parameters",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}})),flatten2=(params,prefix="")=>params.flatMap(p=>{let path2=prefix?`${prefix} / ${p.key}`:p.key,self2={value:p.id,label:`${path2} \xB7 ${p.type}`,hint:p.id};return p.children?.length?[self2,...flatten2(p.children,path2)]:[self2]});return flatten2(data.parameters)}},app:{key:"app",flag:"--app-id",label:"App",plural:"apps",listCommand:`${CLI} app list`,dependsOn:[],async fetch(client){return(await fetchApps(client)).apps.map(a=>({value:a.id??"",label:a.name??a.id??"?",hint:a.id}))}},apiConnectionType:{key:"apiConnectionType",flag:"--api-connection-type-id",label:"API connection type",plural:"API connection types",listCommand:`${CLI} app list`,dependsOn:["app"],autoSelectSingle:!0,async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);return connectionTypes(app).flatMap(ct2=>(ct2.apiConnectionTypes??[]).map(t=>({value:t.id??"",label:t.name??t.id??"?",hint:ct2.name})))}},apiConnectionPackage:{key:"apiConnectionPackage",flag:"--package-id",label:"API connection package",plural:"API connection packages",listCommand:`${CLI} app list`,dependsOn:["app","apiConnectionType"],async fetch(client,deps){return(await apiConnectionPackages(client,must(deps,"app"),must(deps,"apiConnectionType"))).map(p=>({value:p.id??"",label:p.name??p.id??"?",hint:p.recommended?"recommended":p.deprecated?"deprecated":void 0}))}},listenerType:{key:"listenerType",flag:"--listener-type-id",label:"Event listener type",plural:"event listener types",listCommand:`${CLI} app list`,dependsOn:["app"],autoSelectSingle:!0,async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);return connectionTypes(app).flatMap(ct2=>(ct2.eventListenerTypes??[]).map(lt2=>({value:lt2.id??"",label:lt2.name??lt2.id??"?",hint:ct2.name})))}},eventType:{key:"eventType",flag:"--event-type-id",label:"Event type",plural:"event types",listCommand:`${CLI} app list`,dependsOn:["app","listenerType"],async fetch(client,deps){let app=findApp(await fetchApps(client),must(deps,"app"));if(!app)throw new ResolverFetchError(404,`App '${deps.app}' not found.`);let listenerType=connectionTypes(app).flatMap(ct2=>ct2.eventListenerTypes??[]).find(lt2=>lt2.id===must(deps,"listenerType"));if(!listenerType)throw new ResolverFetchError(404,`Event listener type '${deps.listenerType}' not found.`);return(listenerType.eventTypes??[]).map(et2=>({value:et2.id??"",label:et2.name??et2.id??"?",hint:et2.category}))}},connector:{key:"connector",flag:"--connector-id",label:"Connector",plural:"connectors",listCommand:`${CLI} connector list`,dependsOn:["team"],async fetch(client,deps){let data=await fetchConnectors(client,must(deps,"team")),me2=await currentUserId(client),allowed,appId=deps.app;if(appId){let app=findApp(await fetchApps(client),appId);if(app){let cts=connectionTypes(app),listenerTypeId=deps.listenerType;if(listenerTypeId){let owning=cts.filter(ct2=>(ct2.eventListenerTypes??[]).some(lt2=>lt2.id===listenerTypeId));owning.length>0&&(cts=owning)}let apiConnectionTypeId=deps.apiConnectionType;if(apiConnectionTypeId){let owning=cts.filter(ct2=>(ct2.apiConnectionTypes??[]).some(t=>t.id===apiConnectionTypeId));owning.length>0&&(cts=owning)}allowed=new Set(cts.map(ct2=>ct2.id??""))}}return data.connections.filter(c=>!allowed||allowed.has(c.connectionType?.id??"")).filter(c=>!appId||c.canUse!==!1).map(c=>{let sharer=me2&&c.owner?.id&&c.owner.id!==me2?personName(c.owner):"",notes=[c.authorized===!1?"unauthorized":void 0,sharer?`explicitly shared with you by ${sharer}`:void 0,c.canUse===!1?"not for use":void 0].filter(note=>note!==void 0),label=c.name??c.id??"?";return{value:c.id??"",label,...notes.length>0?{display:`${label} (${notes.join(", ")})`}:{},hint:c.connectionType?.name}})}},ownedConnector:{key:"ownedConnector",flag:"--connector-id",label:"Connector",plural:"connectors you own",listCommand:`${CLI} connector list`,dependsOn:["team"],async fetch(client,deps){let data=await fetchConnectors(client,must(deps,"team")),me2=await currentUserId(client);return data.connections.filter(c=>!me2||c.owner?.id===me2).map(c=>{let label=c.name??c.id??"?";return{value:c.id??"",label,...c.authorized===!1?{display:`${label} (unauthorized)`}:{},hint:c.connectionType?.name}})}},script:{key:"script",flag:"<scriptId>",label:"Script",plural:"scripts",dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/scripts",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).scripts.map(s=>({value:s.id,label:s.name,hint:s.id}))}},eventListener:{key:"eventListener",flag:"<eventListenerId>",label:"Event listener",plural:"event listeners",listCommand:`${CLI} event-listener list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListeners",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).eventListeners.map(el=>({value:el.id,label:el.eventType?`${el.app.name} \xB7 ${el.eventType.name}${el.script?` \u2192 ${el.script.name}`:""}`:`${el.app.name} (setup incomplete)`,hint:el.id}))}},apiConnection:{key:"apiConnection",flag:"<apiConnectionId>",label:"API connection",plural:"API connections",listCommand:`${CLI} api-connection list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnections",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).apiConnections.map(c=>{let label=c.path??c.id;return{value:c.id,label,display:`${label} \xB7 ${c.app.name}${c.connector?` \u2014 ${c.connector.name||c.connector.id}`:" \u2014 no connector here"}`,hint:c.id}})}},eventQueue:{key:"eventQueue",flag:"--event-queue-id",label:"Event queue",plural:"event queues",listCommand:`${CLI} event-queue list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventQueues",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).eventQueues.map(q2=>({value:q2.id,label:q2.name,...q2.disabled?{display:`${q2.name} (disabled)`}:{},hint:q2.id}))}},testPayload:{key:"testPayload",flag:"<testPayloadId>",label:"Test payload",plural:"test payloads",listCommand:`${CLI} event-listener-test-payload list`,dependsOn:["workspace","environment","eventListener"],async fetch(client,deps){let data=await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListener/{eventListenerId}/testPayloads",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment"),eventListenerId:must(deps,"eventListener")}}}));return data.testPayloads.map(p=>({value:p.id,label:p.name,...p.id===data.defaultTestPayloadId?{display:`${p.name} (default)`}:{},hint:p.id}))}},scheduledTrigger:{key:"scheduledTrigger",flag:"<scheduledTriggerId>",label:"Scheduled trigger",plural:"scheduled triggers",listCommand:`${CLI} scheduled-trigger list`,dependsOn:["workspace","environment"],async fetch(client,deps){return(await unwrap(await client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/scheduledTriggers",{params:{path:{workspaceId:must(deps,"workspace"),environmentId:must(deps,"environment")}}}))).scheduledTriggers.map(t=>{let label=t.script?.name??t.id;return{value:t.id,label,display:`${label} \xB7 ${scheduleOf(t)}${t.disabled?" (disabled)":""}`,hint:t.id}})}},workspacePackage:{key:"workspacePackage",flag:"<packageId>",label:"Package",plural:"packages",listCommand:`${CLI} package list`,dependsOn:["workspace"],async fetch(client,deps){return(await fetchWorkspacePackages(client,must(deps,"workspace"))).packages.map(p=>({value:p.id,label:p.name,display:`${p.name}@${p.version} \xB7 ${p.type}${p.required?" \xB7 required":""}`,hint:p.id}))}}};var import_picocolors2=__toESM(require_picocolors(),1);import{existsSync,lstatSync,readdirSync as readdirSync3}from"fs";import{dirname as dirname2,join as join7}from"path";import{PassThrough}from"stream";import{styleText}from"util";function pathOptions(userInput,extensions){if(userInput==="")return[];let allowed=p=>!extensions?.length||extensions.some(ext=>p.toLowerCase().endsWith(ext.toLowerCase())),isDirectory=p=>{try{return lstatSync(p).isDirectory()}catch{return!1}},entriesOf=(dir,prefix)=>readdirSync3(dir).map(name=>join7(dir,name)).filter(full=>full.startsWith(prefix)).filter(full=>isDirectory(full)||allowed(full)).map(full=>isDirectory(full)?`${full}/`:full);try{let insideDir=userInput.length>1&&userInput.endsWith("/"),prefix=insideDir?userInput.slice(0,-1):userInput,values=[];insideDir||values.push(...entriesOf(dirname2(userInput),prefix)),isDirectory(userInput)&&values.push(...entriesOf(userInput,prefix));let options=[...new Set(values)].map(value=>({value}));return existsSync(userInput)&&lstatSync(userInput).isFile()&&!options.some(o=>o.value===userInput)&&options.unshift({value:userInput}),options}catch{return[]}}var AUTOCOMPLETE_THRESHOLD=8;function cancelled(){fail(EXIT.CANCELLED,"CANCELLED","Cancelled.")}var SUBMIT_KEY="Ctrl-S",CTRL_S=19,TAB=9,TAB_SENTINEL_BYTE=28,TAB_SENTINEL="";function detabSentinel(text){return text.replaceAll(TAB_SENTINEL," ")}function rewriteSubmitKeys(chunk){let out=[];for(let byte of chunk)byte===CTRL_S?out.push(TAB):byte===TAB?out.push(TAB_SENTINEL_BYTE):out.push(byte);return Buffer.from(out)}function submitOnCtrlS(source=process.stdin){if(!source.isTTY)return;let proxy=new PassThrough,onData=chunk=>{proxy.write(rewriteSubmitKeys(chunk))};source.on("data",onData),source.resume();let restoreTty=()=>{source.isRaw&&source.setRawMode(!1)};process.once("exit",restoreTty);let input=Object.assign(proxy,{isTTY:!0,setRawMode(mode){return source.setRawMode(mode),input}});return{input,done:()=>{process.off("exit",restoreTty),source.off("data",onData),source.pause(),proxy.end()}}}var clackAdapter={async select(message,choices,opts){let clack=await import("./dist-A3XXQMMP.js"),options=choices.map(c=>({value:c.value,label:c.display??c.label,hint:c.hint,disabled:c.disabled})),initialValue=opts?.initial,result=choices.length>AUTOCOMPLETE_THRESHOLD?await clack.autocomplete({message,options,initialValue,maxItems:10,output:process.stderr}):await clack.select({message,options,initialValue,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async multiselect(message,choices,opts){let clack=await import("./dist-A3XXQMMP.js"),options=choices.map(c=>({value:c.value,label:c.display??c.label,hint:c.hint,disabled:c.disabled})),initialValues=opts?.initial,result=choices.length>AUTOCOMPLETE_THRESHOLD?await clack.autocompleteMultiselect({message,options,initialValues,required:!1,maxItems:10,output:process.stderr}):await clack.multiselect({message,options,initialValues,required:!1,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async confirm(message,initial=!1){let clack=await import("./dist-A3XXQMMP.js"),result=await clack.confirm({message,initialValue:initial,output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async text(message,opts){let clack=await import("./dist-A3XXQMMP.js"),result=await clack.text({message,initialValue:opts?.initial,validate:v2=>v2||opts?.allowEmpty?void 0:"Required.",output:process.stderr});return clack.isCancel(result)&&cancelled(),result},async multiline(message,opts){let clack=await import("./dist-A3XXQMMP.js"),core=await import("./dist-UQEAKLYF.js"),{highlightWithCursor,insertCursor}=await import("./highlight-7NU3CBVT.js"),keys=submitOnCtrlS();try{let language=opts?.language,output=process.stderr,style=(format,text)=>styleText(format,text,{stream:output}),result=await new core.MultiLinePrompt({placeholder:opts?.placeholder,initialValue:opts?.initial,showSubmit:!0,validate:()=>{},output,...keys?{input:keys.input}:{},render(){let withGuide=clack.settings.withGuide,title=`${withGuide?`${style("gray",clack.S_BAR)}
43
43
  `:""}${clack.symbol(this.state)} ${message}
44
44
  `,placeholder=opts?.placeholder&&opts.placeholder.length>0?style("inverse",opts.placeholder[0])+style("dim",opts.placeholder.slice(1)):style(["inverse","hidden"],"_"),userInput=detabSentinel(this.userInput),input=userInput?language?highlightWithCursor(userInput,this.cursor,language):insertCursor(userInput,userInput,this.cursor):placeholder,value=detabSentinel(this.value??""),submit=`
45
45
  ${style("dim",`${SUBMIT_KEY} to reach [ submit ], then enter`)}
@@ -1249,12 +1249,13 @@ export default {
1249
1249
  ${child.key}${optionalMark(child)}: ${parameterType(child)};`).join(`
1250
1250
  `);return parameter.children?.length?`{
1251
1251
  ${children}
1252
- }`:"Record<string, any>"}default:return"string"}}function optionalMark(parameter){return parameter.type==="BOOLEAN"||parameter.type==="FOLDER"||parameter.required?"":"?"}function jsDoc(indent,parameter){let type=parameter.type.toLowerCase();return parameter.description?`${indent}/**
1252
+ }`:"Record<string, any>"}default:return"string"}}function optionalMark(parameter){return parameter.type==="BOOLEAN"||parameter.type==="FOLDER"?"":"?"}function jsDoc(indent,parameter){let type=parameter.type.toLowerCase(),caveat=optionalMark(parameter)?" (can still be unset \u2014 check before use)":"",required2=parameter.required?`
1253
+ ${indent} * Required: yes${caveat}`:"";return parameter.description?`${indent}/**
1253
1254
  ${indent} * ${escapeJsDoc(parameter.description)}
1254
1255
  ${indent} *
1255
- ${indent} * Type: ${type}
1256
+ ${indent} * Type: ${type}${required2}
1256
1257
  ${indent} */`:`${indent}/**
1257
- ${indent} * Type: ${type}
1258
+ ${indent} * Type: ${type}${required2}
1258
1259
  ${indent} */`}function generateEvParams(parameters){return`export {};
1259
1260
 
1260
1261
  declare global {
@@ -1289,11 +1290,11 @@ export default (API_REGISTRY['${input.path}'] as ${input.namespace}) ??
1289
1290
  `)?`
1290
1291
  `:"")}function generateTsconfigBase(language){let template=JSON.parse(TSCONFIG_BASE_TEMPLATE);return template.compilerOptions.strict=language==="ts-strict",toJson(template)}var FORBIDDEN_IN_FILE_NAME='<>:"/\\|?*',WINDOWS_RESERVED=/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i;function unportableNameReason(name){if(!name.trim())return"it is blank";let forbidden=Array.from(new Set(Array.from(name).filter(ch=>FORBIDDEN_IN_FILE_NAME.includes(ch)||ch<" ")));if(forbidden.length>0){let printable=forbidden.map(ch=>ch<" "?"a control character":`'${ch}'`);return`${printable.length>1?`${printable.slice(0,-1).join(", ")} and ${printable.at(-1)}`:printable[0]} cannot appear in a file name on every platform`}if(/[. ]$/.test(name))return"it ends in a dot or a space, which Windows strips";let base=name.split(".")[0]??name;if(WINDOWS_RESERVED.test(base))return`${base} is a reserved device name on Windows`}function listenerFolderName(listener){let app=pascalCase(listener.app.name)||listener.app.name,event=listener.eventType?pascalCase(listener.eventType.name)||listener.eventType.name:void 0;return`${event?`${app}\u2192${event}`:app} (${listener.id})`}function payloadFileName(payloadName){return`${payloadName}.json`}var CONCURRENCY=5;async function apiConnectionFileInputs(client,connections){let withPath=connections.filter(c=>c.path);return(await throttleAll(CONCURRENCY,withPath.map(connection=>async()=>{let catalogue=await apiConnectionPackages(client,connection.app.id,connection.apiConnectionTypeId).catch(()=>[]),fromCatalogue=connection.package?catalogue.find(p=>p.id===connection.package?.id):catalogue.find(p=>p.recommended&&!p.deprecated)??catalogue.find(p=>!p.deprecated)??catalogue[0],packageName=connection.package?.name??fromCatalogue?.name;if(!packageName){warnLine(`\u26A0 API connection "${connection.path}" has no package and the catalogue offers none \u2014 scripts/api/${connection.path}/index.ts was not generated.`);return}let namespace=fromCatalogue?.namespace;return namespace||warnLine(`\u26A0 The app catalogue records no exported class for ${packageName} \u2014 scripts/api/${connection.path}/index.ts uses the guessed name ${guessNamespace(packageName)}.`),{path:connection.path??"",namespace:namespace??guessNamespace(packageName),packageName,connectionId:connection.id,namespaceGuessed:!namespace}}))).filter(input=>input!==void 0)}function apiConnectionFilePath(connectionPath){return`scripts/api/${connectionPath.replaceAll(/\/+/g,"/").replace(/^\//,"").replace(/\/$/,"")}/index.ts`}async function apiConnectionFiles(client,connections){return(await apiConnectionFileInputs(client,connections)).map(input=>({path:apiConnectionFilePath(input.path),content:generateApiConnectionFile(input)}))}import{lstatSync as lstatSync2,mkdirSync as mkdirSync7,readFileSync as readFileSync10,readdirSync as readdirSync5,rmSync as rmSync6,unlinkSync,writeFileSync as writeFileSync6}from"fs";import{join as join10,resolve as resolve3,sep as sep3}from"path";var MARKER_PACKAGES=[...TYPE_PACKAGES,"@sr-connect/convert","@sr-connect/record-storage"],EMPTINESS_IGNORED=new Set([".git",".DS_Store"]);function mergedDependencies(parsed){if(parsed===null||typeof parsed!="object"||Array.isArray(parsed))return{};let manifest=parsed,merged={};for(let section of[manifest.dependencies,manifest.devDependencies])section!==null&&typeof section=="object"&&!Array.isArray(section)&&Object.assign(merged,section);return merged}function looksLikeClonedWorkspace(directory){try{return lstatSync2(join10(directory,METADATA_FILE)),!0}catch{}let raw;try{raw=readFileSync10(join10(directory,"package.json"),"utf8")}catch{return!1}let parsed;try{parsed=JSON.parse(raw)}catch{return!1}let dependencies=mergedDependencies(parsed);return MARKER_PACKAGES.every(name=>name in dependencies)}function inspectDirectory(directory){let entries;try{entries=readdirSync5(directory)}catch{return"empty"}return entries.every(entry2=>EMPTINESS_IGNORED.has(entry2))?"empty":looksLikeClonedWorkspace(directory)?"cloned-workspace":"non-empty"}var KEPT_IN_UPDATE_MODE=new Set(["tsconfig.json","tsconfig.base.json","eslint.config.js",".gitignore",".prettierrc","pnpm-workspace.yaml",".vscode/extensions.json","node/apiRegistry.ts","node/runtimeMocks.ts","node/global.d.ts","node/tsconfig.json","node/jest.config.ts"]),BARE_DIRECTORIES=["scripts/api","node/tests"];function assertInside(directory,relativePath){let absolute2=resolve3(directory,relativePath),base=resolve3(directory);if(absolute2!==base&&!absolute2.startsWith(base+sep3))throw new Error(`Refusing to write outside the target directory: ${relativePath}`);return absolute2}function entryExists(absolute2){try{return lstatSync2(absolute2),!0}catch{return!1}}function ensureParents(directory,relativePath){let segments=relativePath.split("/").slice(0,-1),current=resolve3(directory);for(let segment of segments){current=join10(current,segment);let stat=entryExists(current)?lstatSync2(current):void 0;stat?.isSymbolicLink()?unlinkSync(current):stat&&!stat.isDirectory()&&rmSync6(current,{force:!0}),mkdirSync7(current,{recursive:!0})}}function writeClone(directory,files,updateMode){let written=[],kept=[];mkdirSync7(resolve3(directory),{recursive:!0});for(let file2 of files){let absolute2=assertInside(directory,file2.path);if(updateMode&&KEPT_IN_UPDATE_MODE.has(file2.path)&&entryExists(absolute2)){kept.push(file2.path);continue}ensureParents(directory,file2.path);let existing=entryExists(absolute2)?lstatSync2(absolute2):void 0;existing?.isSymbolicLink()?unlinkSync(absolute2):existing&&!existing.isFile()&&rmSync6(absolute2,{recursive:!0,force:!0}),writeFileSync6(absolute2,file2.content),written.push(file2.path)}for(let bare of BARE_DIRECTORIES)ensureParents(directory,`${bare}/.`),mkdirSync7(assertInside(directory,bare),{recursive:!0});return{written,kept}}function walkFiles(root,prefix,out){let entries;try{entries=readdirSync5(root)}catch{return}for(let entry2 of entries){let absolute2=join10(root,entry2),relativePath=prefix?`${prefix}/${entry2}`:entry2;lstatSync2(absolute2).isDirectory()?walkFiles(absolute2,relativePath,out):out.push(relativePath)}}var SWEPT_ROOTS=["scripts/api","test-payloads"];function sweepStaleFiles(directory,manifestPaths){return SWEPT_ROOTS.flatMap(root=>sweepRoot(directory,root,manifestPaths))}function sweepRoot(directory,root,keep){let deleted=[],rootPath=resolve3(directory,root),present=[];walkFiles(rootPath,root,present);for(let relativePath of present)keep.has(relativePath)||(rmSync6(assertInside(directory,relativePath),{force:!0}),deleted.push(relativePath));return prune3(rootPath,rootPath),deleted}function prune3(dir,root){let entries;try{entries=readdirSync5(dir)}catch{return}for(let entry2 of entries){let absolute2=join10(dir,entry2);lstatSync2(absolute2).isDirectory()&&prune3(absolute2,root)}resolve3(dir)!==root&&readdirSync5(dir).length===0&&rmSync6(dir,{recursive:!0})}var CONCURRENCY2=5,enabled5=!0,instance2;function configureLocalSync(opts){enabled5=opts.enabled!==!1&&!truthy2(process.env.SR_CONNECT_CLI_NO_LOCAL_SYNC)&&settingEnabled("localSync"),instance2=opts.instance}function truthy2(value){return value===void 0?!1:!["","0","false","no","off"].includes(value.trim().toLowerCase())}var MAX_LEVELS=40,lookedUp=!1,found;function findLocalClone(){if(lookedUp)return found;lookedUp=!0;let directory=resolve4(process.cwd());for(let level=0;level<MAX_LEVELS;level+=1){let read=readMetadata(directory);if(read.metadata)return found={directory,metadata:read.metadata},found;if(read.problem){warnLine(`\u26A0 ${displayPath(join11(directory,METADATA_FILE))}: ${read.problem} Ignoring the local copy.`);return}let parent=dirname3(directory);if(parent===directory)break;directory=parent}}var noted=new Set;function noteOnce(line){noted.has(line)||(noted.add(line),warnLine(line))}function cloneFor(scope2){if(!enabled5)return;let clone2=findLocalClone();if(!clone2)return;let record4=clone2.metadata;if(instance2!==void 0&&record4.instance!==""&&baseUrl(record4.instance)!==baseUrl(instance2)){noteOnce(`\u26A0 The local copy in ${displayPath(clone2.directory)} was cloned from ${record4.instance} \u2014 not updated.`);return}if(record4.workspace.id!==scope2.workspaceId){noteOnce(`\u26A0 The local copy in ${displayPath(clone2.directory)} is workspace ${record4.workspace.name??record4.workspace.id} (${record4.workspace.id}) \u2014 not updated.`);return}if(scope2.environmentId!==void 0&&record4.environment.id!==scope2.environmentId){noteOnce(`\u26A0 The local copy in ${displayPath(clone2.directory)} is environment ${record4.environment.name??record4.environment.id} (${record4.environment.id}) \u2014 not updated.`);return}if(record4.environment.release){noteOnce(`\u26A0 The local copy in ${displayPath(clone2.directory)} is release ${record4.environment.release}'s snapshot \u2014 not updated. Re-clone it to pick up what the environment runs now.`);return}return clone2}function absolute(clone2,relativePath){return assertInside(clone2.directory,relativePath)}function readLocal(clone2,relativePath){try{return readFileSync11(absolute(clone2,relativePath),"utf8")}catch{return}}function noteWritten(relativePath){isRaw()||noteLine(`\u2714 Local copy updated: ${relativePath}`)}function noteRemoved(relativePath){isRaw()||noteLine(`\u2714 Local copy updated: ${relativePath} removed`)}function warnDirty(relativePath){warnLine(`\u26A0 ${relativePath} has local changes \u2014 left alone. It no longer matches the workspace.`)}function warnLeftBehind(scope2,relativePath){cloneFor(scope2)&&warnLine(`\u26A0 ${relativePath??"The local copy"} was not updated \u2014 you chose to edit the version in the workspace. Fetch it with \`${CLI} local-workspace clone\`, which rewrites the whole local copy, so check for other unsynced changes first.`)}function ensureParent(clone2,relativePath){mkdirSync8(dirname3(absolute(clone2,relativePath)),{recursive:!0})}async function attempt(run){try{return await run()}catch{return}}async function readOrSkip(run){let got=await attempt(run);return got?.response.ok?got.data:void 0}function writeOrWarn(relativePath,run){try{return run()}catch(error51){warnLine(`\u26A0 ${relativePath} could not be updated in the local copy (${describeError(error51)}). The workspace has the change; this directory does not.`);return}}function putFile(clone2,relativePath,content){return readLocal(clone2,relativePath)===content||!writeOrWarn(relativePath,()=>(ensureParent(clone2,relativePath),writeFileSync7(absolute(clone2,relativePath),content),!0))?!1:(noteWritten(relativePath),!0)}function dropFile(clone2,relativePath){let target=absolute(clone2,relativePath);try{lstatSync3(target)}catch{return!1}return writeOrWarn(relativePath,()=>(rmSync7(target,{force:!0}),pruneUpwards(clone2,dirname3(relativePath)),!0))?(noteRemoved(relativePath),!0):!1}function pruneUpwards(clone2,relativeDir){let roots=new Set([".","","scripts","scripts/api","test-payloads"]),current=relativeDir;for(;!roots.has(current);){let target=absolute(clone2,current);try{if(readdirSync6(target).length>0)return;rmSync7(target,{recursive:!0,force:!0})}catch{return}current=dirname3(current)}}function saveRecord(clone2,mutate){mutate(clone2.metadata),clone2.metadata.cli=writerTag();try{writeFileSync7(absolute(clone2,METADATA_FILE),renderMetadata(clone2.metadata))}catch{warnLine(`\u26A0 ${METADATA_FILE} could not be updated \u2014 the next \`${CLI} local-workspace push\` may re-send files that are already in the workspace.`)}}function syncScript(scope2,change){if(change.mode==="skip-write"){warnLeftBehind(scope2,scriptPath(change.name));return}let clone2=cloneFor(scope2);if(!clone2)return;let relativePath=scriptPath(change.name),recordedName=change.id===void 0?void 0:Object.entries(clone2.metadata.scripts).find(([,entry2])=>entry2.id===change.id)?.[0],candidate=change.previousName??recordedName,previous=candidate!==void 0&&candidate!==change.name?candidate:void 0;if(previous!==void 0){let from=scriptPath(previous),recorded2=clone2.metadata.scripts[previous];if(readLocal(clone2,from)!==void 0)try{ensureParent(clone2,relativePath),renameSync4(absolute(clone2,from),absolute(clone2,relativePath)),pruneUpwards(clone2,dirname3(from)),noteWritten(`${from} \u2192 ${relativePath}`)}catch{warnLine(`\u26A0 ${from} could not be moved to ${relativePath}.`)}saveRecord(clone2,record4=>{delete record4.scripts[previous],recorded2&&(record4.scripts[change.name]=recorded2)})}let recorded=clone2.metadata.scripts[change.name],onDisk=readLocal(clone2,relativePath);onDisk!==void 0&&recorded?.checksum!==void 0&&recorded.checksum!==""&&checksumOf(onDisk)!==recorded.checksum&&onDisk!==change.content&&change.mode!=="always"?warnDirty(relativePath):putFile(clone2,relativePath,change.content),saveRecord(clone2,record4=>{record4.scripts[change.name]={...change.id===void 0?{}:{id:change.id},checksum:checksumOf(change.content)}})}async function syncScriptFromServer(client,scope2,scriptId){if(!cloneFor(scope2)||scope2.environmentId===void 0)return;let path2={workspaceId:scope2.workspaceId,environmentId:scope2.environmentId},data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/script/{scriptId}",{params:{path:{...path2,scriptId}}}));data&&syncScript(scope2,{name:data.name,content:data.content,id:data.id})}function syncScriptDeleted(scope2,ref){let clone2=cloneFor(scope2);if(!clone2)return;let name=ref.name??Object.entries(clone2.metadata.scripts).find(([,entry2])=>entry2.id===ref.id)?.[0];if(name===void 0)return;let relativePath=scriptPath(name),recorded=clone2.metadata.scripts[name],onDisk=readLocal(clone2,relativePath);onDisk!==void 0&&recorded?.checksum&&checksumOf(onDisk)!==recorded.checksum?warnLine(`\u26A0 ${relativePath} has local changes \u2014 left in place, though the script is gone from the workspace.`):dropFile(clone2,relativePath),saveRecord(clone2,record4=>{delete record4.scripts[name]})}var folderCache=new Map;async function folderForListener(clone2,client,scope2,eventListenerId){let cached2=folderCache.get(eventListenerId);if(cached2!==void 0)return cached2;for(let[path2,entry2]of Object.entries(clone2.metadata.testPayloads)){if(entry2.eventListenerId!==eventListenerId)continue;let folder2=path2.split("/")[1];if(folder2)return folderCache.set(eventListenerId,folder2),folder2}let listener=await fetchListener(client,scope2,eventListenerId),folder=listener?listenerFolderName(listener):void 0;if(folder&&unportableNameReason(folder)){folderCache.set(eventListenerId,void 0);return}return folderCache.set(eventListenerId,folder),folder}async function fetchListener(client,scope2,eventListenerId){let environmentId=scope2.environmentId;if(environmentId===void 0)return;let data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListeners",{params:{path:{workspaceId:scope2.workspaceId,environmentId}}}));if(data)return data.eventListeners.find(listener=>listener.id===eventListenerId)}function payloadPathById(clone2,id){if(id!==void 0)return Object.entries(clone2.metadata.testPayloads).find(([,entry2])=>entry2.id===id)?.[0]}function payloadNameFromPath(path2){let file2=path2.split("/")[2];return file2?.endsWith(".json")?file2.slice(0,-5):void 0}async function syncTestPayload(client,scope2,eventListenerId,change){if(change.mode==="skip-write"){let skipped=cloneFor(scope2),folder2=skipped?await folderForListener(skipped,client,scope2,eventListenerId):void 0;warnLeftBehind(scope2,folder2&&change.name?`test-payloads/${folder2}/${payloadFileName(change.name)}`:void 0);return}let clone2=cloneFor(scope2);if(!clone2)return;let folder=await folderForListener(clone2,client,scope2,eventListenerId);if(!folder)return;let knownPath=payloadPathById(clone2,change.id),recordedName=knownPath===void 0?void 0:payloadNameFromPath(knownPath),name=change.name??recordedName;if(name===void 0)return;let previousName=change.previousName??recordedName,reason=unportableNameReason(payloadFileName(name));if(reason){warnLine(`\u26A0 Test payload "${name}" was not written to the local copy: ${reason}.`);return}let relativePath=`test-payloads/${folder}/${payloadFileName(name)}`;if(previousName!==void 0&&previousName!==name){let from=`test-payloads/${folder}/${payloadFileName(previousName)}`,recorded2=clone2.metadata.testPayloads[from];if(readLocal(clone2,from)!==void 0)try{ensureParent(clone2,relativePath),renameSync4(absolute(clone2,from),absolute(clone2,relativePath)),noteWritten(`${from} \u2192 ${relativePath}`)}catch{warnLine(`\u26A0 ${from} could not be moved to ${relativePath}.`)}saveRecord(clone2,record4=>{delete record4.testPayloads[from],recorded2&&(record4.testPayloads[relativePath]=recorded2)})}let recorded=clone2.metadata.testPayloads[relativePath],onDisk=readLocal(clone2,relativePath);onDisk!==void 0&&recorded?.checksum!==void 0&&recorded.checksum!==""&&checksumOf(onDisk)!==recorded.checksum&&onDisk!==change.content&&change.mode!=="always"?warnDirty(relativePath):putFile(clone2,relativePath,change.content),saveRecord(clone2,record4=>{record4.testPayloads[relativePath]={eventListenerId,...change.id===void 0?{}:{id:change.id},checksum:checksumOf(change.content)}})}async function syncTestPayloadDeleted(client,scope2,eventListenerId,ref){let clone2=cloneFor(scope2);if(!clone2)return;let byId=payloadPathById(clone2,ref.id),folder=byId?void 0:await folderForListener(clone2,client,scope2,eventListenerId),relativePath=byId??(folder&&ref.name!==void 0?`test-payloads/${folder}/${payloadFileName(ref.name)}`:void 0);relativePath!==void 0&&(dropFile(clone2,relativePath),saveRecord(clone2,record4=>{delete record4.testPayloads[relativePath]}))}async function syncTestPayloadRenamed(client,scope2,eventListenerId,change){let clone2=cloneFor(scope2);if(!clone2)return;let from=payloadPathById(clone2,change.id);if(from===void 0)return;let folder=from.split("/")[1];if(!folder||unportableNameReason(payloadFileName(change.name)))return;let to=`test-payloads/${folder}/${payloadFileName(change.name)}`;if(to===from)return;let entry2=clone2.metadata.testPayloads[from];if(readLocal(clone2,from)!==void 0)try{renameSync4(absolute(clone2,from),absolute(clone2,to)),noteWritten(`${from} \u2192 ${to}`)}catch{warnLine(`\u26A0 ${from} could not be moved to ${to}.`);return}saveRecord(clone2,record4=>{delete record4.testPayloads[from],entry2&&(record4.testPayloads[to]=entry2)})}async function syncTestPayloadById(client,scope2,eventListenerId,testPayloadId){let environmentId=scope2.environmentId;if(!cloneFor(scope2)||environmentId===void 0)return;let data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListener/{eventListenerId}/testPayload/{testPayloadId}",{params:{path:{workspaceId:scope2.workspaceId,environmentId,eventListenerId,testPayloadId}}}));data&&await syncTestPayload(client,scope2,eventListenerId,{name:data.name,content:data.content,id:data.id})}async function syncNewEventListener(client,scope2,eventListenerId){let clone2=cloneFor(scope2);if(!clone2||scope2.environmentId===void 0||!await folderForListener(clone2,client,scope2,eventListenerId))return;let path2={workspaceId:scope2.workspaceId,environmentId:scope2.environmentId},list=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListener/{eventListenerId}/testPayloads",{params:{path:{...path2,eventListenerId}}}));if(!list)return;let contents=await throttleAll(CONCURRENCY2,list.testPayloads.map(payload=>async()=>readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/eventListener/{eventListenerId}/testPayload/{testPayloadId}",{params:{path:{...path2,eventListenerId,testPayloadId:payload.id}}}))));for(let payload of contents)payload&&await syncTestPayload(client,scope2,eventListenerId,{name:payload.name,content:payload.content,id:payload.id})}async function syncEventListenerFolder(client,scope2,eventListenerId,op){let clone2=cloneFor(scope2);if(!clone2)return;let current=folderFromRecord(clone2,eventListenerId);if(!current)return;if(op==="delete"){let removed=Object.keys(clone2.metadata.testPayloads).filter(path2=>path2.startsWith(`test-payloads/${current}/`));try{rmSync7(absolute(clone2,`test-payloads/${current}`),{recursive:!0,force:!0}),noteRemoved(`test-payloads/${current}`)}catch{}saveRecord(clone2,record4=>{for(let path2 of removed)delete record4.testPayloads[path2]});return}folderCache.delete(eventListenerId);let listener=await fetchListener(client,scope2,eventListenerId);if(!listener)return;let next=listenerFolderName(listener);if(!(next===current||unportableNameReason(next))){try{renameSync4(absolute(clone2,`test-payloads/${current}`),absolute(clone2,`test-payloads/${next}`)),noteWritten(`test-payloads/${current} \u2192 test-payloads/${next}`)}catch{return}saveRecord(clone2,record4=>{for(let[path2,entry2]of Object.entries(record4.testPayloads))path2.startsWith(`test-payloads/${current}/`)&&(delete record4.testPayloads[path2],record4.testPayloads[path2.replace(`test-payloads/${current}/`,`test-payloads/${next}/`)]=entry2)}),folderCache.set(eventListenerId,next)}}function folderFromRecord(clone2,eventListenerId){for(let[path2,entry2]of Object.entries(clone2.metadata.testPayloads))if(entry2.eventListenerId===eventListenerId)return path2.split("/")[1]}async function syncParameters(client,scope2){let clone2=cloneFor(scope2),environmentId=scope2.environmentId;if(!clone2||environmentId===void 0)return;let data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/parameters",{params:{path:{workspaceId:scope2.workspaceId,environmentId}}}));data&&putFile(clone2,"ev-params.ts",generateEvParams(data.parameters))}async function syncPackages(client,workspaceId){let clone2=cloneFor({workspaceId});if(!clone2)return;let existing=readLocal(clone2,"package.json");if(existing===void 0)return;let data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/packages",{params:{path:{workspaceId}}}));if(!data)return;let merged=mergePackageJson(existing,data.packages);if(merged===void 0)return;let delta=dependencyDelta(existing,merged);putFile(clone2,"package.json",merged)&&delta.length>0&&warnDependenciesChanged(clone2,delta)}function dependencyDelta(before,after){let read=raw=>{try{return JSON.parse(raw).dependencies??{}}catch{return{}}},from=read(before),to=read(after),words=[];for(let[name,version2]of Object.entries(to))from[name]===void 0?words.push(`+${name}@${version2}`):from[name]!==version2&&words.push(`${name} ${from[name]} \u2192 ${version2}`);for(let name of Object.keys(from))to[name]===void 0&&words.push(`-${name}`);return words}function installCommand(clone2){let lockFiles=[["pnpm-lock.yaml","pnpm install"],["yarn.lock","yarn install"],["package-lock.json","npm install"]];for(let[file2,command]of lockFiles)try{return lstatSync3(absolute(clone2,file2)),command}catch{}}function warnDependenciesChanged(clone2,delta){let command=installCommand(clone2);warnLine(`\u26A0 The workspace's dependencies changed (${delta.join(", ")}) and package.json was updated. `+(command?`Install them again: ${command}`:"Install them again with whichever package manager this project uses."))}function syncReadme(scope2,content,mode){if(mode==="skip-write"){warnLeftBehind(scope2,"README.md");return}let clone2=cloneFor(scope2);if(!clone2)return;let recorded=clone2.metadata.readme,onDisk=readLocal(clone2,"README.md");onDisk!==void 0&&recorded?.checksum!==void 0&&recorded.checksum!==""&&checksumOf(onDisk)!==recorded.checksum&&onDisk!==content&&mode!=="always"?warnDirty("README.md"):putFile(clone2,"README.md",content),saveRecord(clone2,record4=>{record4.readme={checksum:checksumOf(content)}})}async function syncWorkspaceSettings(workspaceId,change){let clone2=cloneFor({workspaceId});if(!clone2)return;if(change.language!==void 0){let existing=readLocal(clone2,"tsconfig.base.json"),strictNow=existing!==void 0&&/"strict"\s*:\s*true/.test(existing);change.language==="ts-strict"?existing===void 0?putFile(clone2,"tsconfig.base.json",generateTsconfigBase("ts-strict")):strictNow||putFile(clone2,"tsconfig.base.json",existing.replace(/"strict"(\s*):(\s*)false/,'"strict"$1:$2true')):strictNow&&!isRaw()&&noteLine("\u2714 tsconfig.base.json keeps strict mode \u2014 the local copy is stricter than the workspace, which is allowed.")}let previousName=change.previousName??clone2.metadata.workspace.name;if(change.name!==void 0&&previousName!==void 0){let existing=readLocal(clone2,"package.json");if(existing===void 0)return;let parsed;try{parsed=JSON.parse(existing)}catch{return}if(parsed.description!==previousName)return;parsed.description=change.name;let trailing=existing.endsWith(`
1291
1292
  `)?`
1292
- `:"";putFile(clone2,"package.json",`${JSON.stringify(parsed,null,4)}${trailing}`),saveRecord(clone2,record4=>{record4.workspace.name=change.name})}}async function syncApiConnections(client,scope2){let clone2=cloneFor(scope2);if(!clone2)return;let environmentId=scope2.environmentId??clone2.metadata.environment.id,data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnections",{params:{path:{workspaceId:scope2.workspaceId,environmentId}}}));if(!data)return;let files=await attempt(()=>apiConnectionFiles(client,data.apiConnections));if(!files)return;for(let file2 of files)putFile(clone2,file2.path,file2.content);let swept=sweepRoot(clone2.directory,"scripts/api",new Set(files.map(file2=>file2.path)));for(let path2 of swept)noteRemoved(path2)}function noteRedeployed(scope2,what){let clone2=cloneFor(scope2);clone2&&warnLine(`\u26A0 The local copy in ${displayPath(clone2.directory)} no longer matches this environment (${what}). Re-clone it with \`${CLI} local-workspace clone\`.`)}async function localEditSource(client,scope2,target,serverContent){let clone2=cloneFor(scope2);if(!clone2)return{content:serverContent,mode:"if-clean"};let relativePath=await editPath(clone2,client,scope2,target);if(!relativePath)return{content:serverContent,mode:"if-clean"};let onDisk=readLocal(clone2,relativePath);return onDisk===void 0||onDisk===serverContent?{content:serverContent,mode:"if-clean"}:canPrompt()?(prompts().note(`This ${nounOf(target)} differs from your local copy at ${relativePath}.`),await prompts().select("Which one do you want to edit?",[{value:"local",label:`The local file \u2014 ${relativePath}`,hint:"edited here, then uploaded"},{value:"server",label:"The version in the workspace",hint:"the local file is left alone"}],{initial:"local"})==="local"?{content:onDisk,mode:"always"}:{content:serverContent,mode:"skip-write"}):{content:serverContent,mode:"if-clean"}}function nounOf(target){return target.kind==="script"?"script":target.kind==="payload"?"test payload":"README"}async function editPath(clone2,client,scope2,target){if(target.kind==="script")return scriptPath(target.name);if(target.kind==="readme")return"README.md";let folder=await folderForListener(clone2,client,scope2,target.eventListenerId);return folder?`test-payloads/${folder}/${payloadFileName(target.name)}`:void 0}var flagEnabled2=!0,instance3;function configureLocalWorkspaceScope(opts){flagEnabled2=opts.enabled!==!1,instance3=opts.instance}function truthy3(value){return value===void 0?!1:!["","0","false","no","off"].includes(value.trim().toLowerCase())}function localWorkspaceScopeEnabled(){return flagEnabled2&&!truthy3(process.env.SR_CONNECT_CLI_NO_LOCAL_WORKSPACE)}function localWorkspaceScope(){if(!localWorkspaceScopeEnabled())return;let clone2=findLocalClone();if(!clone2)return;let record4=clone2.metadata;if(instance3!==void 0&&record4.instance!==""&&baseUrl(record4.instance)!==baseUrl(instance3))return;let labels={team:record4.team.name};return record4.workspace.name&&(labels.workspace=record4.workspace.name),record4.environment.name&&(labels.environment=record4.environment.name),{directory:clone2.directory,recordPath:join12(clone2.directory,METADATA_FILE),values:{team:record4.team.id,workspace:record4.workspace.id,environment:record4.environment.id},labels}}var SCOPE_ENV={team:"SR_CONNECT_CLI_TEAM",workspace:"SR_CONNECT_CLI_WORKSPACE",environment:"SR_CONNECT_CLI_ENVIRONMENT"};function scopeEnvVar(key){return Object.hasOwn(SCOPE_ENV,key)?SCOPE_ENV[key]:void 0}var SKIPPED_DEFAULT_HINT={destructive:"A session default and a local workspace record are only borrowed by a destructive verb when someone is there to see the question naming it \u2014 pass the scope with flags or environment variables, or run it on a terminal.","save-flow":"This verb writes the session defaults rather than reading them, so a stored value is never the answer here \u2014 pass all three with flags or environment variables, or run it on a terminal to pick them."},workspaceOrigin,inheritedWorkspaceNoted=!1;function inheritedWorkspaceNote(from,workspaceId){return from===void 0||from==="flag"||from==="picker"?void 0:`\u26A0 Workspace ${workspaceId} came from ${from==="env"?"SR_CONNECT_CLI_WORKSPACE":from==="local"?"a local workspace's workspace.json":"this shell's session defaults"}, not from -w \u2014 ${from==="local"?"the clone may name a workspace that no longer exists.":"check that it is the one the ID belongs to."}`}function warnInheritedWorkspace(from,workspaceId){if(inheritedWorkspaceNoted)return;let origin=from!==void 0&&workspaceId!==void 0?{from,value:workspaceId}:workspaceOrigin;if(origin===void 0)return;let note=inheritedWorkspaceNote(origin.from,origin.value);note!==void 0&&(inheritedWorkspaceNoted=!0,warnLine(note))}function recordWorkspaceOrigin(source,values){let from=source.get("workspace"),value=values.workspace;from===void 0||value===void 0||(workspaceOrigin={from,value})}var sessionAnswers=new Map,announcedKeys=new Set,localAnswers=new Map,announcedLocalKeys=new Set,notedLocalClash=!1;function relevantScope(keys,registry2){let seen=new Set,walk2=key=>{if(!seen.has(key)){seen.add(key);for(let dep of registry2[key]?.dependsOn??[])walk2(dep)}};for(let key of keys)walk2(key);return seen}function describeScope(list,record4,registry2){return list.map(k2=>{let noun=(registry2[k2]?.label??k2).toLowerCase(),label=record4.labels?.[k2];return label?`${noun} "${label}" (${record4[k2]??""})`:`${noun} ${record4[k2]??""}`}).join(", ")}async function resolveParams(keys,provided,ctx){let registry2=ctx.registry??RESOLVERS,values={},userProvided=new Set,source=new Map;for(let[key,value]of Object.entries(provided))value&&(values[key]=value,userProvided.add(key),source.set(key,"flag"));for(let key of SESSION_KEYS){let fromEnv=process.env[SCOPE_ENV[key]];!values[key]&&fromEnv&&fromEnv!==""&&(values[key]=fromEnv,userProvided.add(key),source.set(key,"env"))}let blame=(key,form)=>{let spec=registry2[key],value=values[key]??"",origin=source.get(key)==="env"?scopeEnvVar(key)??key:source.get(key)==="session"?`session default \u2014 ${CLI} cli clear-session to clear`:source.get(key)==="local"?`local workspace record \u2014 ${local?.recordPath??""}`:ctx.blame?.[key]??spec?.flag??key;return form==="long"?`${spec?.label??key} '${value}' (${origin})`:`${origin} '${value}'`},skippedDefault=key=>ctx.useSession!==!1||!SESSION_KEYS.includes(key)?!1:readSession()?.[key]?!0:!!localWorkspaceScope()?.values[key],local=ctx.useSession===!1?void 0:localWorkspaceScope();local&&await applyLocalScope(local);let session=ctx.useSession===!1?void 0:readSession(),instanceCleared2=takeInstanceClear();if(instanceCleared2&&prompts().note(`Session defaults cleared \u2014 they belonged to instance '${instanceCleared2}', which is no longer the active instance.`),session){let applied=[];for(let key of SESSION_KEYS){let value=session[key];value&&!values[key]&&(values[key]=value,userProvided.add(key),source.set(key,"session"),applied.push(key))}let relevant=relevantScope(ctx.needs??keys,registry2),shown=applied.filter(k2=>relevant.has(k2)),describeKeys=list=>describeScope(list,session,registry2),drop=list=>{for(let key of list)delete values[key],userProvided.delete(key),source.delete(key)};if(canPrompt()){let unanswered=shown.filter(k2=>!sessionAnswers.has(k2));if(unanswered.length>0){let use=await prompts().confirm(`Use session defaults: ${describeKeys(unanswered)}?`,!0);for(let key of unanswered)sessionAnswers.set(key,use);use||prompts().note("Not using session defaults \u2014 resolving for this run only.")}let refused=applied.filter(k2=>sessionAnswers.get(k2)===!1);drop(refused),shown=shown.filter(k2=>!refused.includes(k2))}else if(shown.length>0){let fresh=shown.filter(k2=>!announcedKeys.has(k2));if(fresh.length>0){for(let key of fresh)announcedKeys.add(key);prompts().note(`Using session defaults: ${describeKeys(fresh)} (${CLI} cli clear-session to clear)`)}}}async function applyLocalScope(record4){let asRecord={...record4.values,labels:record4.labels},clash=SESSION_KEYS.filter(k2=>values[k2]&&values[k2]!==record4.values[k2]);if(clash.length>0&&!(clash.length===1&&clash[0]==="environment"&&await environmentBelongsTo(ctx.client,record4.values.workspace,values.environment??"")===!0)){if(!notedLocalClash){notedLocalClash=!0;let blamed=clash.map(k2=>blame(k2,"short")).join(", ");prompts().note(`The local workspace in ${displayPath(record4.directory)} is ${describeScope(clash,asRecord,registry2)} \u2014 set aside for this run, because ${blamed} was passed instead; its team and workspace are not used either.`)}return}let missing=SESSION_KEYS.filter(k2=>!values[k2]);if(missing.length===0)return;let relevant=relevantScope(ctx.needs??keys,registry2),shown=missing.filter(k2=>relevant.has(k2));if(canPrompt()){let unanswered=shown.filter(k2=>!localAnswers.has(k2));if(unanswered.length>0){let use=await prompts().confirm(`Use the local workspace in ${displayPath(record4.directory)} \u2014 ${describeScope(unanswered,asRecord,registry2)}?`,!0);for(let key of unanswered)localAnswers.set(key,use);if(!use){for(let key of SESSION_KEYS)localAnswers.set(key,!1);prompts().note("Not using the local workspace \u2014 resolving for this run only.")}}}else{let fresh=shown.filter(k2=>!announcedLocalKeys.has(k2));if(fresh.length>0){for(let key of fresh)announcedLocalKeys.add(key);prompts().note(`Using the local workspace in ${displayPath(record4.directory)}: ${describeScope(fresh,asRecord,registry2)} (--no-local-workspace to ignore)`)}}for(let key of missing)localAnswers.get(key)!==!1&&(values[key]=record4.values[key],userProvided.add(key),source.set(key,"local"))}let resolving=new Set,picked=new Set,labels={};async function need(key){let existing=values[key];if(existing)return existing;if(resolving.has(key))throw new Error(`circular resolver dependency at '${key}'`);resolving.add(key);let spec=registry2[key];if(!spec)throw new Error(`no resolver registered for param '${key}'`);if(!ctx.interactive){let envVar=scopeEnvVar(key);fail(EXIT.USAGE,"USAGE_ERROR",ctx.missing?.[key]??`${ctx.blame?.[key]??spec.flag} is required. ${supplyHint({env:envVar})}`,skippedDefault(key)?{hint:SKIPPED_DEFAULT_HINT[ctx.sessionSkipped??"destructive"]}:void 0)}let deps={};for(let dep of spec.dependsOn)deps[dep]=await need(dep);let providedDeps=spec.dependsOn.filter(d=>userProvided.has(d)),choices;try{choices=await withSpinner(`Fetching ${spec.plural}`,()=>spec.fetch(ctx.client,{...values}))}catch(err){if(err instanceof ResolverFetchError){if(err.status===404&&providedDeps.length>0){let blamed=providedDeps.map(d=>blame(d,"long")).join(", ");fail(EXIT.NOT_FOUND,"INVALID_PARAM",`${blamed} is invalid \u2014 the API returned 404 for it.`,{status:404})}mapResolverError(err,spec)}throw err}if(choices.length===0){if(providedDeps.length>0){let blamed=providedDeps.map(d=>blame(d,"short")).join(", ");fail(EXIT.NOT_FOUND,"NO_RESULTS",`No ${spec.plural} found for ${blamed} \u2014 double-check the value.`,{hint:spec.listCommand?`See what exists with \`${spec.listCommand}\`.`:void 0})}fail(EXIT.NOT_FOUND,"NO_RESULTS",`No ${spec.plural} available.`)}let sole=spec.autoSelectSingle&&choices.length===1?choices[0]:void 0,value,label;return sole?(value=sole.value,label=sole.label,prompts().note(`\u2714 ${spec.label}: ${label} (${value}) \u2014 only one, auto-selected`)):(value=await prompts().select(`${spec.label}:`,choices),label=choices.find(c=>c.value===value)?.label??value,prompts().note(`\u2714 ${spec.label}: ${label} (${value})`)),values[key]=value,labels[key]=label,ctx.labels&&(ctx.labels[key]=label),source.set(key,"picker"),picked.add(key),resolving.delete(key),value}for(let key of Object.keys(values))picked.has(key)||(values[key]=assertResourceId(values[key]??"",blame(key,"short")));recordWorkspaceOrigin(source,values);for(let key of keys)await need(key);if(ctx.sources)for(let[key,from]of source)ctx.sources[key]=from;recordWorkspaceOrigin(source,values);let pickedScope=SESSION_KEYS.some(k2=>picked.has(k2));return ctx.offerSession!==!1&&pickedScope&&keys.includes("environment")&&await maybeOfferSession(values,session,registry2,labels),values}async function maybeOfferSession(values,existing,registry2,labels){if(!sessionEnabled()||!canPrompt()||existing?.declined||hasScope(existing)||!values.environment||!values.workspace)return;let record4={team:values.team,workspace:values.workspace,environment:values.environment,labels:pickLabels(values,labels)},summary=describeScope(SESSION_KEYS.filter(k2=>values[k2]),record4,registry2);if(await prompts().confirm(`Remember these as defaults for this shell session \u2014 ${summary}?`,!0)){writeSession(record4);for(let key of SESSION_KEYS)record4[key]&&sessionAnswers.set(key,!0);prompts().note(`\u2714 Saved. Clear with: ${CLI} cli clear-session (or just open a new shell)`)}else writeSession({declined:!0}),prompts().note(`Not saved. Run ${CLI} cli set-session if you change your mind.`)}function pickLabels(values,labels){if(!labels)return;let out={};for(let key of SESSION_KEYS){let label=labels[key];label&&values[key]&&(out[key]=label)}return Object.keys(out).length>0?out:void 0}async function askVersion(message,allowEmpty=!1){for(;;){let answer=(await prompts().text(message,{allowEmpty})).trim();if(answer===""&&allowEmpty)return;let error51=semverError(answer);if(!error51)return answer;prompts().note(`\u2716 ${error51}`)}}var OTHER_INSTANCE="",INSTANCE_URL_PROMPT="Instance API base URL (usually https://api.<your-domain>)";async function askInstance(current){let known=current!==void 0&&INSTANCE_KEYS.includes(current),choice=await prompts().select("Instance:",[...INSTANCE_KEYS.map(key=>({value:key,label:KNOWN_INSTANCES[key].label,hint:KNOWN_INSTANCES[key].url})),{value:OTHER_INSTANCE,label:"Other\u2026",hint:"enter an API base URL"}],{initial:current===void 0?void 0:known?current:OTHER_INSTANCE});if(choice!==OTHER_INSTANCE)return choice;for(;;){let answer=await prompts().text(INSTANCE_URL_PROMPT,{initial:current!==void 0&&!known?current:"https://"}),error51=instanceError(answer);if(!error51)return normalizeInstance(answer);prompts().note(`\u2716 ${error51}`)}}async function askOutputCopy(){if(outputCopyPath())return outputCopyPath();if(!await prompts().confirm("Also copy the output to a file?",!1))return;let answer=await prompts().text(`File name (empty for ${generatedOutputName()} in the current directory)`,{allowEmpty:!0});return setOutputCopy(answer.trim()||!0)}async function resolverChoices(client,key,deps){let spec=RESOLVERS[key];if(!spec)throw new Error(`no resolver registered for param '${key}'`);try{return await withSpinner(`Fetching ${spec.plural}`,()=>spec.fetch(client,deps))}catch(err){if(!(err instanceof ResolverFetchError))throw err;mapResolverError(err,spec)}}async function pickEnvironments(client,workspaceId,message="Deploy into which environments? (space to pick, enter for none)"){let environments=await resolverChoices(client,"environment",{workspace:workspaceId});if(environments.length===0)return prompts().note("\u26A0 No environments in this workspace \u2014 nothing to deploy into."),{ids:[],labels:{}};let ids=await prompts().multiselect(message,environments),labels=Object.fromEntries(ids.map(id=>[id,environments.find(e=>e.value===id)?.label??id]));return{ids,labels}}async function askScript(opts){let existing={value:"existing",label:"Pick an existing script"},create={value:"new",label:"Create a new script",...opts.recommendCreate?{hint:opts.recommendCreate}:{}};if(await prompts().select(opts.message??"Script to run:",opts.recommendCreate?[create,existing]:[existing,create])==="existing")try{return{scriptId:(await resolveParams(["script"],{workspace:opts.workspace,environment:opts.environment},{client:opts.client,interactive:!0,offerSession:!1})).script}}catch(err){if(!(err instanceof CliError)||err.code!=="NO_RESULTS")throw err;prompts().note("\u26A0 No scripts in this environment yet \u2014 creating a new one instead.")}return{scriptName:await askScriptName(opts.suggestedName)}}async function askScriptName(suggested){for(;;){let answer=await prompts().text("New script name (use / for folders, e.g. handlers/OnIssueCreated)",{...suggested?{initial:suggested}:{},allowEmpty:!0}),error51=scriptNameError(answer);if(!error51)return normalizeScriptName(answer);prompts().note(`\u2716 ${error51}`)}}async function askKeepOrChange(opts){let choices=await resolverChoices(opts.client,opts.key,opts.deps),currentValue=opts.current?.value,marked=choices.map(choice=>choice.value===currentValue?{...choice,display:`${choice.display??choice.label} (current)`}:choice),missing=!!currentValue&&!choices.some(c=>c.value===currentValue);if(currentValue&&missing){let label=opts.current?.label??currentValue;marked.unshift({value:currentValue,label,display:`${label} (${opts.missingCurrentMark??"current"})`,hint:currentValue})}let offered=[...marked,...opts.extra??[]];if(offered.length===0)return;let picked=await prompts().select(opts.message,offered,currentValue?{initial:currentValue}:{});return picked===currentValue?void 0:picked}async function askStatus(current,noun="it"){let disabled=await prompts().select("Status:",[{value:"enabled",label:"Enabled",...current?{}:{hint:`enables ${noun}`}},{value:"disabled",label:"Disabled",...current?{hint:`disables ${noun}`}:{}}].map(choice=>choice.value==="disabled"===current?{...choice,display:`${choice.label} (current)`}:choice),{initial:current?"disabled":"enabled"})==="disabled";return disabled===current?void 0:disabled}var REGISTRY=new Map;function defineCommandDoc(command,doc){return REGISTRY.set(command,doc),doc}function docKeys(schema,hidden=[]){let json2=external_exports.toJSONSchema(schema,{unrepresentable:"any"}),all=Object.keys(json2.properties??{}).filter(key=>!hidden.includes(key)),required2=new Set(json2.required??[]);return{required:all.filter(key=>required2.has(key)).sort(),optional:all.filter(key=>!required2.has(key)).sort()}}function nestedKeysOf(property,key){let properties=[property,...property?.anyOf??[]].find(shape=>shape?.type==="object"&&shape.properties)?.properties;return properties?Object.keys(properties).map(child=>`${key}.${child}`):[]}function flagBlockKeys(schema,order){let json2=external_exports.toJSONSchema(schema,{unrepresentable:"any"});return order.flatMap(key=>[key,...nestedKeysOf(json2.properties?.[key],key)])}function aligned(rows2){let width=Math.max(...rows2.map(row=>row.term.length));return rows2.map(row=>` ${row.term.padEnd(width)} ${row.description}`)}function explainLines(doc,ctx={}){let lines=[],flagFor=ctx.flagFor;if(ctx.arguments&&ctx.arguments.length>0&&(lines.push("Arguments:"),lines.push(...aligned(ctx.arguments))),ctx.scope&&ctx.scope.length>0&&(lines.push("Scope flags:"),lines.push(...aligned(ctx.scope))),doc.schema){let{required:required2,optional:optional2}=docKeys(doc.schema,doc.hidden),conditional=doc.conditional??[];lines.push(`Required: ${required2.length>0?required2.join(", "):"none"}`),optional2.length>0&&lines.push(`Optional: ${optional2.map(key=>conditional.includes(key)?`${key}*`:key).join(", ")}`),conditional.length>0&&lines.push(` * ${conditional.join(" and ")} are optional to the schema; a rule below makes one required.`);let mapped=flagFor?flagBlockKeys(doc.schema,[...required2,...optional2]).map(key=>[key,flagFor(key)]).filter(([,flag])=>flag):[];if(mapped.length>0){lines.push("Keys as flags:");for(let[key,flag]of mapped){let env=credentialEnvFor(key,doc);lines.push(` ${key} = ${flag??""}${env===void 0?"":` + ${env}`}`)}}}if(doc.rules.length>0){lines.push("Rules:");for(let rule of doc.rules)lines.push(` \xB7 ${rule}`)}if(doc.notes&&doc.notes.length>0){lines.push("Notes:");for(let note of doc.notes)lines.push(` \xB7 ${note}`)}return lines}function explained(cmd,doc){return cmd.opts().explain!==!0?!1:(printExplain(doc,explainContext(cmd,doc)),!0)}var SCOPE_FLAGS=["--workspace","--env","--team"];function explainContext(cmd,doc){return{flagFor:flagResolver(cmd,doc),arguments:cmd.registeredArguments.map(argument=>({term:argument.required?`<${argument.name()}>`:`[${argument.name()}]`,description:argument.description})),scope:SCOPE_FLAGS.flatMap(long=>{let option=cmd.options.find(declared=>declared.long===long);return option?[{term:option.flags,description:option.description}]:[]})}}var SCOPE_KEY_FLAGS={teamId:"--team",workspaceId:"--workspace",environmentId:"--env",environmentIds:"--env"};function nestedFlag(key,doc,declared){let rule=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `));if(rule===void 0)return;let mentioned=new Set([...rule.matchAll(/--[a-z][a-z-]*/g)].map(match=>match[0]).filter(long=>declared.has(long)));if(mentioned.size!==1)return;let flag=/(--[a-z][a-z-]*)(?: <[^>]+>)? as a (?:repeatable )?flag/i.exec(rule)?.[1];return flag!==void 0&&mentioned.has(flag)?flag:void 0}function credentialEnvFor(key,doc){let rule=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `));if(rule===void 0||!/never from argv/i.test(rule))return;let named=new Set([...rule.matchAll(/SR_CONNECT_CLI_[A-Z0-9_]+/g)].map(match=>match[0]));return named.size===1?[...named][0]:void 0}function flagResolver(cmd,doc){let declared=new Set(cmd.options.map(option=>option.long).filter(long=>long!==void 0));return key=>{let kebab=`--${key.slice(key.lastIndexOf(".")+1).replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`;if(declared.has(kebab))return kebab;if(key.includes("."))return nestedFlag(key,doc,declared);let scope2=SCOPE_KEY_FLAGS[key];if(scope2!==void 0&&declared.has(scope2))return scope2;let beside=doc.rules.map(text=>new RegExp(`${key} \\((?:spelled )?(?:-[a-z]/)?(--[a-z][a-z-]*) as a flag[^)]*\\)`).exec(text)).find(match=>match!==null);if(beside?.[1]!==void 0&&declared.has(beside[1]))return beside[1];let spelled=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `))?.match(/(?:spelled|it is the) (?:-[a-z]\/)?(--[a-z][a-z-]*)|\((?:-[a-z]\/)?(--[a-z][a-z-]*) as a flag\)/i),flag=spelled?.[1]??spelled?.[2];return flag!==void 0&&declared.has(flag)?flag:void 0}}function printExplain(doc,ctx={}){let body=doc.body??{};if(isRaw())okText(JSON.stringify(body));else{let pretty=JSON.stringify(body,null,2);okText(process.stdout.isTTY?highlightContent(pretty,"json"):pretty)}for(let line of explainLines(doc,ctx))noteLine(line)}import{readFileSync as readFileSync12}from"fs";import{readSync as readSync2}from"fs";var CHUNK_BYTES=65536,IDLE_WAIT_MS=5;function readStdinSync(){let chunks=[],buffer=Buffer.alloc(CHUNK_BYTES),parked=new Int32Array(new SharedArrayBuffer(4));for(;;){let read;try{read=readSync2(0,buffer,0,CHUNK_BYTES,null)}catch(err){let code=err.code;if(code==="EAGAIN"){Atomics.wait(parked,0,0,IDLE_WAIT_MS);continue}if(code==="EOF")break;throw err}if(read===0)break;chunks.push(Buffer.from(buffer.subarray(0,read)))}return Buffer.concat(chunks).toString("utf8")}var SCOPE_ENV_VAR={team:"SR_CONNECT_CLI_TEAM",workspace:"SR_CONNECT_CLI_WORKSPACE",environment:"SR_CONNECT_CLI_ENVIRONMENT"};function scopeDescription(noun,opts={}){let tokens=[opts.required===!1||opts.behindPositional?"optional":"required","interactive",opts.sessionOnTty?"session default on a TTY only":"session default",`env ${SCOPE_ENV_VAR[noun]}`];return opts.behindPositional&&tokens.push("ignored when the positional argument is given"),`${capitalize(opts.prose??`${noun} ID`)} (${tokens.join(", ")})`}function capitalize(prose){return prose.charAt(0).toUpperCase()+prose.slice(1)}var SCOPE_TEAM=scopeDescription("team"),SCOPE_WORKSPACE=scopeDescription("workspace"),SCOPE_ENVIRONMENT=scopeDescription("environment"),SCOPE_ENVIRONMENT_BESIDE_POSITIONAL=scopeDescription("environment",{behindPositional:!0}),SCOPE_ENVIRONMENT_BESIDE_POSITIONAL_DESTRUCTIVE=scopeDescription("environment",{behindPositional:!0,sessionOnTty:!0}),SCOPE_TEAM_FILTER=scopeDescription("team",{prose:"team ID \u2014 filters the interactive workspace picker",required:!1}),SCOPE_TEAM_SEARCHED=scopeDescription("team",{prose:"team ID \u2014 searched for when omitted, every workspace read being keyed by team",required:!1}),SCOPE_TEAM_DESTRUCTIVE=scopeDescription("team",{sessionOnTty:!0}),SCOPE_WORKSPACE_DESTRUCTIVE=scopeDescription("workspace",{sessionOnTty:!0}),SCOPE_ENVIRONMENT_DESTRUCTIVE=scopeDescription("environment",{sessionOnTty:!0}),SCOPE_TEAM_FILTER_DESTRUCTIVE=scopeDescription("team",{prose:"team ID \u2014 filters the interactive workspace picker",required:!1,sessionOnTty:!0}),GATE_PROSE="environment ID \u2014 the change applies to the whole workspace, whatever environment is named",SCOPE_ENVIRONMENT_GATE=scopeDescription("environment",{prose:GATE_PROSE}),SCOPE_ENVIRONMENT_GATE_DESTRUCTIVE=scopeDescription("environment",{prose:GATE_PROSE,sessionOnTty:!0}),SCOPE_ENVIRONMENT_GATE_HEAD=scopeDescription("environment",{prose:"environment ID \u2014 the change applies to the whole workspace, and the environment named must run HEAD"}),INPUT_BODY="Read the full request body as JSON from a file, or - for stdin (optional, supersedes every body flag)",EXPLAIN="Print what the verb takes on stdout and the rules for every parameter on stderr, then exit without sending anything (optional, supersedes every other flag)",CONFIRM_YES="Skip the confirmation prompt (optional on a TTY, required otherwise)";function readInput(input){try{let raw=input==="-"?readStdinSync():readFileSync12(input,"utf8");return JSON.parse(raw)}catch(error51){fail(EXIT.USAGE,"INVALID_INPUT",`--input ${input==="-"?"stdin":input} could not be read or is not valid JSON.`,{hint:describeError(error51)})}}function validate(schema,body){let result=schema.safeParse(body);return result.success||fail(EXIT.USAGE,"INVALID_BODY",formatBodyError(result.error,body),{hint:EXPLAIN_HINT}),normalizeBodyIds(result.data,schema),result.data}function normalizeBodyIds(body,schema){if(body===null||typeof body!="object")return;let shape=objectShape(schema),record4=body;for(let[key,value]of Object.entries(record4)){if(/Ids?$/.test(key)){if(typeof value=="string"&&(record4[key]=assertBodyId(value,key)),Array.isArray(value))for(let[index,item]of value.entries())typeof item=="string"&&(value[index]=assertBodyId(item,key));continue}if(value===null||typeof value!="object"||Array.isArray(value))continue;let declared=shape?.[key];objectShape(declared)&&normalizeBodyIds(value,declared)}}function objectShape(schema){let current=schema;for(;current instanceof external_exports.ZodOptional||current instanceof external_exports.ZodNullable||current instanceof external_exports.ZodDefault||current instanceof external_exports.ZodReadonly;)current=current.unwrap();return current instanceof external_exports.ZodObject?current.shape:void 0}function assertBodyId(value,key){return value.trim()||fail(EXIT.USAGE,"INVALID_ID",`${key} is empty. Pass ${RESOURCE_ID_FORMAT}, null to detach where the key accepts it, or omit the key to leave it as it is.`),assertResourceId(value,key)}function formatBodyError(error51,body){let seen=new Set;for(let issue2 of error51.issues)seen.add(houseSentence(issue2,body));return[...seen].join(" ")}var EXPLAIN_HINT="Run the verb with --explain to see every key it takes and the flag each key is spelled as.";function houseSentence(issue2,body){let path2=issue2.path.map(String).join("."),subject=path2===""?"body":path2;if(issue2.code==="unrecognized_keys"){let keys=issue2.keys.join(", "),verb=issue2.keys.length>1?"are not keys":"is not a key";return`${keys} ${verb} of this body.`}if(issue2.code==="invalid_type"){if(valueAt(body,issue2.path)===void 0)return`${subject} is required.`;let wanted=TYPE_NOUNS[issue2.expected];if(wanted)return`${subject} must be ${wanted}.`}return issue2.code==="too_big"?issue2.origin==="array"?`${subject} takes at most ${issue2.maximum} items.`:isNumeric(issue2.origin)?`${subject} can be at most ${issue2.maximum}.`:`${subject} can be at most ${issue2.maximum} characters.`:issue2.code==="too_small"?issue2.origin==="array"?`${subject} needs at least ${issue2.minimum} items.`:isNumeric(issue2.origin)?`${subject} must be ${issue2.minimum} or more.`:`${subject} needs at least ${plural(Number(issue2.minimum),"character")}.`:path2===""?issue2.message:`${path2}: ${issue2.message}`}var TYPE_NOUNS={int:"a whole number",number:"a number",string:"text",boolean:"true or false",array:"a list",object:"an object"};function isNumeric(origin){return origin==="number"||origin==="int"||origin==="bigint"||origin==="date"}function plural(count,noun){return`${count} ${noun}${count===1?"":"s"}`}function valueAt(body,path2){let cursor=body;for(let key of path2){if(cursor===null||typeof cursor!="object")return;cursor=cursor[key]}return cursor}function failNothingToUpdate(flags){let list=flags.length>1?`${flags.slice(0,-1).join(", ")} or ${flags.at(-1)}`:flags[0]??"--input";fail(EXIT.USAGE,"USAGE_ERROR",`Nothing to update: pass ${list}.`)}function failNeedsYes(target,verb="Deleting"){fail(EXIT.USAGE,"CONFIRMATION_REQUIRED",`${verb} ${target} is irreversible. Re-run with --yes to confirm.`)}function assertChoice(flag,value,allowed){if(value!==void 0)return allowed.includes(value)||fail(EXIT.USAGE,"INVALID_OPTION",`${flag} must be one of: ${allowed.join(", ")}.`),value}function collect(value,previous){return[...previous??[],...value.split(",").map(v2=>v2.trim()).filter(v2=>v2!=="")]}function disabledFromFlags(opts){return switchFromFlags(opts,"disabled","enabled")}function switchFromFlags(opts,on2,off){if(opts[on2]&&opts[off]&&fail(EXIT.USAGE,"USAGE_ERROR",`--${on2} and --${off} cannot be combined.`),opts[on2])return!0;if(opts[off])return!1}function assertExplicitEnvironmentAgrees(envFlag,inBody){let explicit2=envFlag??process.env.SR_CONNECT_CLI_ENVIRONMENT;if(!explicit2||!inBody||explicit2===inBody)return;let source=envFlag===void 0?"SR_CONNECT_CLI_ENVIRONMENT names":"-e/--env names";fail(EXIT.USAGE,"USAGE_ERROR",`${source} ${explicit2} but the --input body's environmentId is ${inBody}; the body is what is sent, so drop one of them or make them agree.`)}async function teamForQuestions(scope2,globals){let known=scope2.team??globals.team;if(known)return known;if(canPrompt()){if(scope2.askedTeam!==void 0)return scope2.askedTeam||void 0;try{let resolved=await resolveParams(["team"],{},{client:scope2.client,interactive:!0,offerSession:!1});scope2.askedTeam=resolved.team??""}catch(err){if(!(err instanceof CliError))throw err;scope2.askedTeam=""}return scope2.askedTeam||void 0}}function stripUndefined(obj){return Object.fromEntries(Object.entries(obj).filter(([,v2])=>v2!==void 0))}function implicitShareMark(owner){let who=owner?personName(owner):"";return who?`current \u2014 implicitly shared via the workspace, owned by ${who}`:"current \u2014 implicitly shared via the workspace"}async function confirmImplicitReplacement(current,replacement,owner){let who=owner?personName(owner):"",contact=owner?.email&&who!==owner.email?` (${owner.email})`:"";return prompts().note([`"${current}" is attached here and reaches this workspace only because the workspace`,"is shared with you. Removing it cannot be undone by you: only",who?`${who}${contact}, who owns it, or someone it is explicitly shared with, can`:"the connector's owner, or someone it is explicitly shared with, can","attach it back."].join(`
1293
+ `:"";putFile(clone2,"package.json",`${JSON.stringify(parsed,null,4)}${trailing}`),saveRecord(clone2,record4=>{record4.workspace.name=change.name})}}async function syncApiConnections(client,scope2){let clone2=cloneFor(scope2);if(!clone2)return;let environmentId=scope2.environmentId??clone2.metadata.environment.id,data=await readOrSkip(()=>client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnections",{params:{path:{workspaceId:scope2.workspaceId,environmentId}}}));if(!data)return;let files=await attempt(()=>apiConnectionFiles(client,data.apiConnections));if(!files)return;for(let file2 of files)putFile(clone2,file2.path,file2.content);let swept=sweepRoot(clone2.directory,"scripts/api",new Set(files.map(file2=>file2.path)));for(let path2 of swept)noteRemoved(path2)}function noteRedeployed(scope2,what){let clone2=cloneFor(scope2);clone2&&warnLine(`\u26A0 The local copy in ${displayPath(clone2.directory)} no longer matches this environment (${what}). Re-clone it with \`${CLI} local-workspace clone\`.`)}async function localEditSource(client,scope2,target,serverContent){let clone2=cloneFor(scope2);if(!clone2)return{content:serverContent,mode:"if-clean"};let relativePath=await editPath(clone2,client,scope2,target);if(!relativePath)return{content:serverContent,mode:"if-clean"};let onDisk=readLocal(clone2,relativePath);return onDisk===void 0||onDisk===serverContent?{content:serverContent,mode:"if-clean"}:canPrompt()?(prompts().note(`This ${nounOf(target)} differs from your local copy at ${relativePath}.`),await prompts().select("Which one do you want to edit?",[{value:"local",label:`The local file \u2014 ${relativePath}`,hint:"edited here, then uploaded"},{value:"server",label:"The version in the workspace",hint:"the local file is left alone"}],{initial:"local"})==="local"?{content:onDisk,mode:"always"}:{content:serverContent,mode:"skip-write"}):{content:serverContent,mode:"if-clean"}}function nounOf(target){return target.kind==="script"?"script":target.kind==="payload"?"test payload":"README"}async function editPath(clone2,client,scope2,target){if(target.kind==="script")return scriptPath(target.name);if(target.kind==="readme")return"README.md";let folder=await folderForListener(clone2,client,scope2,target.eventListenerId);return folder?`test-payloads/${folder}/${payloadFileName(target.name)}`:void 0}var flagEnabled2=!0,instance3;function configureLocalWorkspaceScope(opts){flagEnabled2=opts.enabled!==!1,instance3=opts.instance}function truthy3(value){return value===void 0?!1:!["","0","false","no","off"].includes(value.trim().toLowerCase())}function localWorkspaceScopeEnabled(){return flagEnabled2&&!truthy3(process.env.SR_CONNECT_CLI_NO_LOCAL_WORKSPACE)}function localWorkspaceScope(){if(!localWorkspaceScopeEnabled())return;let clone2=findLocalClone();if(!clone2)return;let record4=clone2.metadata;if(instance3!==void 0&&record4.instance!==""&&baseUrl(record4.instance)!==baseUrl(instance3))return;let labels={team:record4.team.name};return record4.workspace.name&&(labels.workspace=record4.workspace.name),record4.environment.name&&(labels.environment=record4.environment.name),{directory:clone2.directory,recordPath:join12(clone2.directory,METADATA_FILE),values:{team:record4.team.id,workspace:record4.workspace.id,environment:record4.environment.id},labels}}var SCOPE_ENV={team:"SR_CONNECT_CLI_TEAM",workspace:"SR_CONNECT_CLI_WORKSPACE",environment:"SR_CONNECT_CLI_ENVIRONMENT"};function scopeEnvVar(key){return Object.hasOwn(SCOPE_ENV,key)?SCOPE_ENV[key]:void 0}var SKIPPED_DEFAULT_HINT={destructive:"A session default and a local workspace record are only borrowed by a destructive verb when someone is there to see the question naming it \u2014 pass the scope with flags or environment variables, or run it on a terminal.","save-flow":"This verb writes the session defaults rather than reading them, so a stored value is never the answer here \u2014 pass all three with flags or environment variables, or run it on a terminal to pick them."},workspaceOrigin,inheritedWorkspaceNoted=!1;function inheritedWorkspaceNote(from,workspaceId){return from===void 0||from==="flag"||from==="picker"?void 0:`\u26A0 Workspace ${workspaceId} came from ${from==="env"?"SR_CONNECT_CLI_WORKSPACE":from==="local"?"a local workspace's workspace.json":"this shell's session defaults"}, not from -w \u2014 ${from==="local"?"the clone may name a workspace that no longer exists.":"check that it is the one the ID belongs to."}`}function warnInheritedWorkspace(from,workspaceId){if(inheritedWorkspaceNoted)return;let origin=from!==void 0&&workspaceId!==void 0?{from,value:workspaceId}:workspaceOrigin;if(origin===void 0)return;let note=inheritedWorkspaceNote(origin.from,origin.value);note!==void 0&&(inheritedWorkspaceNoted=!0,warnLine(note))}function recordWorkspaceOrigin(source,values){let from=source.get("workspace"),value=values.workspace;from===void 0||value===void 0||(workspaceOrigin={from,value})}var sessionAnswers=new Map,announcedKeys=new Set,localAnswers=new Map,announcedLocalKeys=new Set,notedLocalClash=!1;function relevantScope(keys,registry2){let seen=new Set,walk2=key=>{if(!seen.has(key)){seen.add(key);for(let dep of registry2[key]?.dependsOn??[])walk2(dep)}};for(let key of keys)walk2(key);return seen}function describeScope(list,record4,registry2){return list.map(k2=>{let noun=(registry2[k2]?.label??k2).toLowerCase(),label=record4.labels?.[k2];return label?`${noun} "${label}" (${record4[k2]??""})`:`${noun} ${record4[k2]??""}`}).join(", ")}async function resolveParams(keys,provided,ctx){let registry2=ctx.registry??RESOLVERS,values={},userProvided=new Set,source=new Map;for(let[key,value]of Object.entries(provided))value&&(values[key]=value,userProvided.add(key),source.set(key,"flag"));for(let key of SESSION_KEYS){let fromEnv=process.env[SCOPE_ENV[key]];!values[key]&&fromEnv&&fromEnv!==""&&(values[key]=fromEnv,userProvided.add(key),source.set(key,"env"))}let blame=(key,form)=>{let spec=registry2[key],value=values[key]??"",origin=source.get(key)==="env"?scopeEnvVar(key)??key:source.get(key)==="session"?`session default \u2014 ${CLI} cli clear-session to clear`:source.get(key)==="local"?`local workspace record \u2014 ${local?.recordPath??""}`:ctx.blame?.[key]??spec?.flag??key;return form==="long"?`${spec?.label??key} '${value}' (${origin})`:`${origin} '${value}'`},skippedDefault=key=>ctx.useSession!==!1||!SESSION_KEYS.includes(key)?!1:readSession()?.[key]?!0:!!localWorkspaceScope()?.values[key],local=ctx.useSession===!1?void 0:localWorkspaceScope();local&&await applyLocalScope(local);let session=ctx.useSession===!1?void 0:readSession(),instanceCleared2=takeInstanceClear();if(instanceCleared2&&prompts().note(`Session defaults cleared \u2014 they belonged to instance '${instanceCleared2}', which is no longer the active instance.`),session){let applied=[];for(let key of SESSION_KEYS){let value=session[key];value&&!values[key]&&(values[key]=value,userProvided.add(key),source.set(key,"session"),applied.push(key))}let relevant=relevantScope(ctx.needs??keys,registry2),shown=applied.filter(k2=>relevant.has(k2)),describeKeys=list=>describeScope(list,session,registry2),drop=list=>{for(let key of list)delete values[key],userProvided.delete(key),source.delete(key)};if(canPrompt()){let unanswered=shown.filter(k2=>!sessionAnswers.has(k2));if(unanswered.length>0){let use=await prompts().confirm(`Use session defaults: ${describeKeys(unanswered)}?`,!0);for(let key of unanswered)sessionAnswers.set(key,use);use||prompts().note("Not using session defaults \u2014 resolving for this run only.")}let refused=applied.filter(k2=>sessionAnswers.get(k2)===!1);drop(refused),shown=shown.filter(k2=>!refused.includes(k2))}else if(shown.length>0){let fresh=shown.filter(k2=>!announcedKeys.has(k2));if(fresh.length>0){for(let key of fresh)announcedKeys.add(key);prompts().note(`Using session defaults: ${describeKeys(fresh)} (${CLI} cli clear-session to clear)`)}}}async function applyLocalScope(record4){let asRecord={...record4.values,labels:record4.labels},clash=SESSION_KEYS.filter(k2=>values[k2]&&values[k2]!==record4.values[k2]);if(clash.length>0&&!(clash.length===1&&clash[0]==="environment"&&await environmentBelongsTo(ctx.client,record4.values.workspace,values.environment??"")===!0)){if(!notedLocalClash){notedLocalClash=!0;let blamed=clash.map(k2=>blame(k2,"short")).join(", ");prompts().note(`The local workspace in ${displayPath(record4.directory)} is ${describeScope(clash,asRecord,registry2)} \u2014 set aside for this run, because ${blamed} was passed instead; its team and workspace are not used either.`)}return}let missing=SESSION_KEYS.filter(k2=>!values[k2]);if(missing.length===0)return;let relevant=relevantScope(ctx.needs??keys,registry2),shown=missing.filter(k2=>relevant.has(k2));if(canPrompt()){let unanswered=shown.filter(k2=>!localAnswers.has(k2));if(unanswered.length>0){let use=await prompts().confirm(`Use the local workspace in ${displayPath(record4.directory)} \u2014 ${describeScope(unanswered,asRecord,registry2)}?`,!0);for(let key of unanswered)localAnswers.set(key,use);if(!use){for(let key of SESSION_KEYS)localAnswers.set(key,!1);prompts().note("Not using the local workspace \u2014 resolving for this run only.")}}}else{let fresh=shown.filter(k2=>!announcedLocalKeys.has(k2));if(fresh.length>0){for(let key of fresh)announcedLocalKeys.add(key);prompts().note(`Using the local workspace in ${displayPath(record4.directory)}: ${describeScope(fresh,asRecord,registry2)} (--no-local-workspace to ignore)`)}}for(let key of missing)localAnswers.get(key)!==!1&&(values[key]=record4.values[key],userProvided.add(key),source.set(key,"local"))}let resolving=new Set,picked=new Set,labels={};async function need(key){let existing=values[key];if(existing)return existing;if(resolving.has(key))throw new Error(`circular resolver dependency at '${key}'`);resolving.add(key);let spec=registry2[key];if(!spec)throw new Error(`no resolver registered for param '${key}'`);if(!ctx.interactive){let envVar=scopeEnvVar(key);fail(EXIT.USAGE,"USAGE_ERROR",ctx.missing?.[key]??`${ctx.blame?.[key]??spec.flag} is required. ${supplyHint({env:envVar})}`,skippedDefault(key)?{hint:SKIPPED_DEFAULT_HINT[ctx.sessionSkipped??"destructive"]}:void 0)}let deps={};for(let dep of spec.dependsOn)deps[dep]=await need(dep);let providedDeps=spec.dependsOn.filter(d=>userProvided.has(d)),choices;try{choices=await withSpinner(`Fetching ${spec.plural}`,()=>spec.fetch(ctx.client,{...values}))}catch(err){if(err instanceof ResolverFetchError){if(err.status===404&&providedDeps.length>0){let blamed=providedDeps.map(d=>blame(d,"long")).join(", ");fail(EXIT.NOT_FOUND,"INVALID_PARAM",`${blamed} is invalid \u2014 the API returned 404 for it.`,{status:404})}mapResolverError(err,spec)}throw err}if(choices.length===0){if(providedDeps.length>0){let blamed=providedDeps.map(d=>blame(d,"short")).join(", ");fail(EXIT.NOT_FOUND,"NO_RESULTS",`No ${spec.plural} found for ${blamed} \u2014 double-check the value.`,{hint:spec.listCommand?`See what exists with \`${spec.listCommand}\`.`:void 0})}fail(EXIT.NOT_FOUND,"NO_RESULTS",`No ${spec.plural} available.`)}let sole=spec.autoSelectSingle&&choices.length===1?choices[0]:void 0,value,label;return sole?(value=sole.value,label=sole.label,prompts().note(`\u2714 ${spec.label}: ${label} (${value}) \u2014 only one, auto-selected`)):(value=await prompts().select(`${spec.label}:`,choices),label=choices.find(c=>c.value===value)?.label??value,prompts().note(`\u2714 ${spec.label}: ${label} (${value})`)),values[key]=value,labels[key]=label,ctx.labels&&(ctx.labels[key]=label),source.set(key,"picker"),picked.add(key),resolving.delete(key),value}for(let key of Object.keys(values))picked.has(key)||(values[key]=assertResourceId(values[key]??"",blame(key,"short")));recordWorkspaceOrigin(source,values);for(let key of keys)await need(key);if(ctx.sources)for(let[key,from]of source)ctx.sources[key]=from;recordWorkspaceOrigin(source,values);let pickedScope=SESSION_KEYS.some(k2=>picked.has(k2));return ctx.offerSession!==!1&&pickedScope&&keys.includes("environment")&&await maybeOfferSession(values,session,registry2,labels),values}async function maybeOfferSession(values,existing,registry2,labels){if(!sessionEnabled()||!canPrompt()||existing?.declined||hasScope(existing)||!values.environment||!values.workspace)return;let record4={team:values.team,workspace:values.workspace,environment:values.environment,labels:pickLabels(values,labels)},summary=describeScope(SESSION_KEYS.filter(k2=>values[k2]),record4,registry2);if(await prompts().confirm(`Remember these as defaults for this shell session \u2014 ${summary}?`,!0)){writeSession(record4);for(let key of SESSION_KEYS)record4[key]&&sessionAnswers.set(key,!0);prompts().note(`\u2714 Saved. Clear with: ${CLI} cli clear-session (or just open a new shell)`)}else writeSession({declined:!0}),prompts().note(`Not saved. Run ${CLI} cli set-session if you change your mind.`)}function pickLabels(values,labels){if(!labels)return;let out={};for(let key of SESSION_KEYS){let label=labels[key];label&&values[key]&&(out[key]=label)}return Object.keys(out).length>0?out:void 0}async function askVersion(message,allowEmpty=!1){for(;;){let answer=(await prompts().text(message,{allowEmpty})).trim();if(answer===""&&allowEmpty)return;let error51=semverError(answer);if(!error51)return answer;prompts().note(`\u2716 ${error51}`)}}var OTHER_INSTANCE="",INSTANCE_URL_PROMPT="Instance API base URL (usually https://api.<your-domain>)";async function askInstance(current){let known=current!==void 0&&INSTANCE_KEYS.includes(current),choice=await prompts().select("Instance:",[...INSTANCE_KEYS.map(key=>({value:key,label:KNOWN_INSTANCES[key].label,hint:KNOWN_INSTANCES[key].url})),{value:OTHER_INSTANCE,label:"Other\u2026",hint:"enter an API base URL"}],{initial:current===void 0?void 0:known?current:OTHER_INSTANCE});if(choice!==OTHER_INSTANCE)return choice;for(;;){let answer=await prompts().text(INSTANCE_URL_PROMPT,{initial:current!==void 0&&!known?current:"https://"}),error51=instanceError(answer);if(!error51)return normalizeInstance(answer);prompts().note(`\u2716 ${error51}`)}}async function askOutputCopy(){if(outputCopyPath())return outputCopyPath();if(!await prompts().confirm("Also copy the output to a file?",!1))return;let answer=await prompts().text(`File name (empty for ${generatedOutputName()} in the current directory)`,{allowEmpty:!0});return setOutputCopy(answer.trim()||!0)}async function resolverChoices(client,key,deps){let spec=RESOLVERS[key];if(!spec)throw new Error(`no resolver registered for param '${key}'`);try{return await withSpinner(`Fetching ${spec.plural}`,()=>spec.fetch(client,deps))}catch(err){if(!(err instanceof ResolverFetchError))throw err;mapResolverError(err,spec)}}async function pickEnvironments(client,workspaceId,message="Deploy into which environments? (space to pick, enter for none)"){let environments=await resolverChoices(client,"environment",{workspace:workspaceId});if(environments.length===0)return prompts().note("\u26A0 No environments in this workspace \u2014 nothing to deploy into."),{ids:[],labels:{}};let ids=await prompts().multiselect(message,environments),labels=Object.fromEntries(ids.map(id=>[id,environments.find(e=>e.value===id)?.label??id]));return{ids,labels}}async function askScript(opts){let existing={value:"existing",label:"Pick an existing script"},create={value:"new",label:"Create a new script",...opts.recommendCreate?{hint:opts.recommendCreate}:{}};if(await prompts().select(opts.message??"Script to run:",opts.recommendCreate?[create,existing]:[existing,create])==="existing")try{return{scriptId:(await resolveParams(["script"],{workspace:opts.workspace,environment:opts.environment},{client:opts.client,interactive:!0,offerSession:!1})).script}}catch(err){if(!(err instanceof CliError)||err.code!=="NO_RESULTS")throw err;prompts().note("\u26A0 No scripts in this environment yet \u2014 creating a new one instead.")}return{scriptName:await askScriptName(opts.suggestedName)}}async function askScriptName(suggested){for(;;){let answer=await prompts().text("New script name (use / for folders, e.g. handlers/OnIssueCreated)",{...suggested?{initial:suggested}:{},allowEmpty:!0}),error51=scriptNameError(answer);if(!error51)return normalizeScriptName(answer);prompts().note(`\u2716 ${error51}`)}}async function askKeepOrChange(opts){let choices=await resolverChoices(opts.client,opts.key,opts.deps),currentValue=opts.current?.value,marked=choices.map(choice=>choice.value===currentValue?{...choice,display:`${choice.display??choice.label} (current)`}:choice),missing=!!currentValue&&!choices.some(c=>c.value===currentValue);if(currentValue&&missing){let label=opts.current?.label??currentValue;marked.unshift({value:currentValue,label,display:`${label} (${opts.missingCurrentMark??"current"})`,hint:currentValue})}let offered=[...marked,...opts.extra??[]];if(offered.length===0)return;let picked=await prompts().select(opts.message,offered,currentValue?{initial:currentValue}:{});return picked===currentValue?void 0:picked}async function askStatus(current,noun="it"){let disabled=await prompts().select("Status:",[{value:"enabled",label:"Enabled",...current?{}:{hint:`enables ${noun}`}},{value:"disabled",label:"Disabled",...current?{hint:`disables ${noun}`}:{}}].map(choice=>choice.value==="disabled"===current?{...choice,display:`${choice.label} (current)`}:choice),{initial:current?"disabled":"enabled"})==="disabled";return disabled===current?void 0:disabled}var REGISTRY=new Map;function defineCommandDoc(command,doc){return REGISTRY.set(command,doc),doc}function docKeys(schema,hidden=[]){let json2=external_exports.toJSONSchema(schema,{unrepresentable:"any"}),all=Object.keys(json2.properties??{}).filter(key=>!hidden.includes(key)),required2=new Set(json2.required??[]);return{required:all.filter(key=>required2.has(key)).sort(),optional:all.filter(key=>!required2.has(key)).sort()}}function nestedKeysOf(property,key){let properties=[property,...property?.anyOf??[]].find(shape=>shape?.type==="object"&&shape.properties)?.properties;return properties?Object.keys(properties).map(child=>`${key}.${child}`):[]}function flagBlockKeys(schema,order){let json2=external_exports.toJSONSchema(schema,{unrepresentable:"any"});return order.flatMap(key=>[key,...nestedKeysOf(json2.properties?.[key],key)])}function aligned(rows2){let width=Math.max(...rows2.map(row=>row.term.length));return rows2.map(row=>` ${row.term.padEnd(width)} ${row.description}`)}function explainLines(doc,ctx={}){let lines=[],flagFor=ctx.flagFor;if(ctx.arguments&&ctx.arguments.length>0&&(lines.push("Arguments:"),lines.push(...aligned(ctx.arguments))),ctx.scope&&ctx.scope.length>0&&(lines.push("Scope flags:"),lines.push(...aligned(ctx.scope)),ctx.ttyOnlyScope&&lines.push(` ${TTY_ONLY_SCOPE_NOTE}`)),doc.schema){let{required:required2,optional:optional2}=docKeys(doc.schema,doc.hidden),conditional=doc.conditional??[];lines.push(`Required: ${required2.length>0?required2.join(", "):"none"}`),optional2.length>0&&lines.push(`Optional: ${optional2.map(key=>conditional.includes(key)?`${key}*`:key).join(", ")}`),conditional.length>0&&lines.push(` * ${conditional.join(" and ")} are optional to the schema; a rule below makes one required.`);let mapped=flagFor?flagBlockKeys(doc.schema,[...required2,...optional2]).map(key=>[key,flagFor(key)]).filter(([,flag])=>flag):[];if(mapped.length>0){lines.push("Keys as flags:");for(let[key,flag]of mapped){let env=credentialEnvFor(key,doc);lines.push(` ${key} = ${flag??""}${env===void 0?"":` + ${env}`}`)}}}if(doc.rules.length>0){lines.push("Rules:");for(let rule of doc.rules)lines.push(` \xB7 ${rule}`)}if(doc.notes&&doc.notes.length>0){lines.push("Notes:");for(let note of doc.notes)lines.push(` \xB7 ${note}`)}return lines}function explained(cmd,doc){return cmd.opts().explain!==!0?!1:(printExplain(doc,explainContext(cmd,doc)),!0)}var SCOPE_FLAGS=["--workspace","--env","--team"],TTY_ONLY_TOKEN="session default on a TTY only",TTY_ONLY_SCOPE_NOTE=`${TTY_ONLY_TOKEN}: the session record and a clone's workspace.json answer such a flag only on a terminal, where the confirmation names what is about to change; elsewhere pass it or its environment variable, or the run is exit 2.`;function explainContext(cmd,doc){return{flagFor:flagResolver(cmd,doc),arguments:cmd.registeredArguments.map(argument=>({term:argument.required?`<${argument.name()}>`:`[${argument.name()}]`,description:argument.description})),scope:SCOPE_FLAGS.flatMap(long=>{let option=cmd.options.find(declared=>declared.long===long);return option?[{term:option.flags,description:option.description}]:[]}),ttyOnlyScope:SCOPE_FLAGS.some(long=>cmd.options.some(declared=>declared.long===long&&declared.description.includes(TTY_ONLY_TOKEN)))}}var SCOPE_KEY_FLAGS={teamId:"--team",workspaceId:"--workspace",environmentId:"--env",environmentIds:"--env"};function nestedFlag(key,doc,declared){let rule=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `));if(rule===void 0)return;let mentioned=new Set([...rule.matchAll(/--[a-z][a-z-]*/g)].map(match=>match[0]).filter(long=>declared.has(long)));if(mentioned.size!==1)return;let flag=/(--[a-z][a-z-]*)(?: <[^>]+>)? as a (?:repeatable )?flag/i.exec(rule)?.[1];return flag!==void 0&&mentioned.has(flag)?flag:void 0}function credentialEnvFor(key,doc){let rule=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `));if(rule===void 0||!/never from argv/i.test(rule))return;let named=new Set([...rule.matchAll(/SR_CONNECT_CLI_[A-Z0-9_]+/g)].map(match=>match[0]));return named.size===1?[...named][0]:void 0}function flagResolver(cmd,doc){let declared=new Set(cmd.options.map(option=>option.long).filter(long=>long!==void 0));return key=>{let kebab=`--${key.slice(key.lastIndexOf(".")+1).replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`;if(declared.has(kebab))return kebab;if(key.includes("."))return nestedFlag(key,doc,declared);let scope2=SCOPE_KEY_FLAGS[key];if(scope2!==void 0&&declared.has(scope2))return scope2;let beside=doc.rules.map(text=>new RegExp(`${key} \\((?:spelled )?(?:-[a-z]/)?(--[a-z][a-z-]*) as a flag[^)]*\\)`).exec(text)).find(match=>match!==null);if(beside?.[1]!==void 0&&declared.has(beside[1]))return beside[1];let spelled=doc.rules.find(text=>text.startsWith(`${key}:`)||text.startsWith(`${key} `))?.match(/(?:spelled|it is the) (?:-[a-z]\/)?(--[a-z][a-z-]*)|\((?:-[a-z]\/)?(--[a-z][a-z-]*) as a flag\)/i),flag=spelled?.[1]??spelled?.[2];return flag!==void 0&&declared.has(flag)?flag:void 0}}function printExplain(doc,ctx={}){let body=doc.body??{};if(isRaw())okText(JSON.stringify(body));else{let pretty=JSON.stringify(body,null,2);okText(process.stdout.isTTY?highlightContent(pretty,"json"):pretty)}for(let line of explainLines(doc,ctx))noteLine(line)}import{readFileSync as readFileSync12}from"fs";import{readSync as readSync2}from"fs";var CHUNK_BYTES=65536,IDLE_WAIT_MS=5;function readStdinSync(){let chunks=[],buffer=Buffer.alloc(CHUNK_BYTES),parked=new Int32Array(new SharedArrayBuffer(4));for(;;){let read;try{read=readSync2(0,buffer,0,CHUNK_BYTES,null)}catch(err){let code=err.code;if(code==="EAGAIN"){Atomics.wait(parked,0,0,IDLE_WAIT_MS);continue}if(code==="EOF")break;throw err}if(read===0)break;chunks.push(Buffer.from(buffer.subarray(0,read)))}return Buffer.concat(chunks).toString("utf8")}var SCOPE_ENV_VAR={team:"SR_CONNECT_CLI_TEAM",workspace:"SR_CONNECT_CLI_WORKSPACE",environment:"SR_CONNECT_CLI_ENVIRONMENT"};function scopeDescription(noun,opts={}){let tokens=[opts.required===!1||opts.behindPositional?"optional":"required","interactive",opts.sessionOnTty?"session default on a TTY only":"session default",`env ${SCOPE_ENV_VAR[noun]}`];return opts.behindPositional&&tokens.push("ignored when the positional argument is given"),`${capitalize(opts.prose??`${noun} ID`)} (${tokens.join(", ")})`}function capitalize(prose){return prose.charAt(0).toUpperCase()+prose.slice(1)}var SCOPE_TEAM=scopeDescription("team"),SCOPE_WORKSPACE=scopeDescription("workspace"),SCOPE_ENVIRONMENT=scopeDescription("environment"),SCOPE_ENVIRONMENT_BESIDE_POSITIONAL=scopeDescription("environment",{behindPositional:!0}),SCOPE_ENVIRONMENT_BESIDE_POSITIONAL_DESTRUCTIVE=scopeDescription("environment",{behindPositional:!0,sessionOnTty:!0}),SCOPE_TEAM_FILTER=scopeDescription("team",{prose:"team ID \u2014 filters the interactive workspace picker",required:!1}),SCOPE_TEAM_SEARCHED=scopeDescription("team",{prose:"team ID \u2014 searched for when omitted, every workspace read being keyed by team",required:!1}),SCOPE_TEAM_DESTRUCTIVE=scopeDescription("team",{sessionOnTty:!0}),SCOPE_WORKSPACE_DESTRUCTIVE=scopeDescription("workspace",{sessionOnTty:!0}),SCOPE_ENVIRONMENT_DESTRUCTIVE=scopeDescription("environment",{sessionOnTty:!0}),SCOPE_TEAM_FILTER_DESTRUCTIVE=scopeDescription("team",{prose:"team ID \u2014 filters the interactive workspace picker",required:!1,sessionOnTty:!0}),GATE_PROSE="environment ID \u2014 the change applies to the whole workspace, whatever environment is named",SCOPE_ENVIRONMENT_GATE=scopeDescription("environment",{prose:GATE_PROSE}),SCOPE_ENVIRONMENT_GATE_DESTRUCTIVE=scopeDescription("environment",{prose:GATE_PROSE,sessionOnTty:!0}),SCOPE_ENVIRONMENT_GATE_HEAD=scopeDescription("environment",{prose:"environment ID \u2014 the change applies to the whole workspace, and the environment named must run HEAD"}),INPUT_BODY="Read the full request body as JSON from a file, or - for stdin (optional, supersedes every body flag)",EXPLAIN="Print what the verb takes on stdout and the rules for every parameter on stderr, then exit without sending anything (optional, supersedes every other flag)",CONFIRM_YES="Skip the confirmation prompt (optional on a TTY, required otherwise)";function readInput(input){try{let raw=input==="-"?readStdinSync():readFileSync12(input,"utf8");return JSON.parse(raw)}catch(error51){fail(EXIT.USAGE,"INVALID_INPUT",`--input ${input==="-"?"stdin":input} could not be read or is not valid JSON.`,{hint:describeError(error51)})}}function validate(schema,body){let result=schema.safeParse(body);return result.success||fail(EXIT.USAGE,"INVALID_BODY",formatBodyError(result.error,body),{hint:EXPLAIN_HINT}),normalizeBodyIds(result.data,schema),result.data}function normalizeBodyIds(body,schema){if(body===null||typeof body!="object")return;let shape=objectShape(schema),record4=body;for(let[key,value]of Object.entries(record4)){if(/Ids?$/.test(key)){if(typeof value=="string"&&(record4[key]=assertBodyId(value,key)),Array.isArray(value))for(let[index,item]of value.entries())typeof item=="string"&&(value[index]=assertBodyId(item,key));continue}if(value===null||typeof value!="object"||Array.isArray(value))continue;let declared=shape?.[key];objectShape(declared)&&normalizeBodyIds(value,declared)}}function objectShape(schema){let current=schema;for(;current instanceof external_exports.ZodOptional||current instanceof external_exports.ZodNullable||current instanceof external_exports.ZodDefault||current instanceof external_exports.ZodReadonly;)current=current.unwrap();return current instanceof external_exports.ZodObject?current.shape:void 0}function assertBodyId(value,key){return value.trim()||fail(EXIT.USAGE,"INVALID_ID",`${key} is empty. Pass ${RESOURCE_ID_FORMAT}, null to detach where the key accepts it, or omit the key to leave it as it is.`),assertResourceId(value,key)}function formatBodyError(error51,body){let seen=new Set;for(let issue2 of error51.issues)seen.add(houseSentence(issue2,body));return[...seen].join(" ")}var EXPLAIN_HINT="Run the verb with --explain to see every key it takes and the flag each key is spelled as.";function houseSentence(issue2,body){let path2=issue2.path.map(String).join("."),subject=path2===""?"body":path2;if(issue2.code==="unrecognized_keys"){let keys=issue2.keys.join(", "),verb=issue2.keys.length>1?"are not keys":"is not a key";return`${keys} ${verb} of this body.`}if(issue2.code==="invalid_type"){if(valueAt(body,issue2.path)===void 0)return`${subject} is required.`;let wanted=TYPE_NOUNS[issue2.expected];if(wanted)return`${subject} must be ${wanted}.`}return issue2.code==="too_big"?issue2.origin==="array"?`${subject} takes at most ${issue2.maximum} items.`:isNumeric(issue2.origin)?`${subject} can be at most ${issue2.maximum}.`:`${subject} can be at most ${issue2.maximum} characters.`:issue2.code==="too_small"?issue2.origin==="array"?`${subject} needs at least ${issue2.minimum} items.`:isNumeric(issue2.origin)?`${subject} must be ${issue2.minimum} or more.`:`${subject} needs at least ${plural(Number(issue2.minimum),"character")}.`:path2===""?issue2.message:`${path2}: ${issue2.message}`}var TYPE_NOUNS={int:"a whole number",number:"a number",string:"text",boolean:"true or false",array:"a list",object:"an object"};function isNumeric(origin){return origin==="number"||origin==="int"||origin==="bigint"||origin==="date"}function plural(count,noun){return`${count} ${noun}${count===1?"":"s"}`}function valueAt(body,path2){let cursor=body;for(let key of path2){if(cursor===null||typeof cursor!="object")return;cursor=cursor[key]}return cursor}function failNothingToUpdate(flags){let list=flags.length>1?`${flags.slice(0,-1).join(", ")} or ${flags.at(-1)}`:flags[0]??"--input";fail(EXIT.USAGE,"USAGE_ERROR",`Nothing to update: pass ${list}.`)}function failNeedsYes(target,verb="Deleting"){fail(EXIT.USAGE,"CONFIRMATION_REQUIRED",`${verb} ${target} is irreversible. Re-run with --yes to confirm.`)}function assertChoice(flag,value,allowed){if(value!==void 0)return allowed.includes(value)||fail(EXIT.USAGE,"INVALID_OPTION",`${flag} must be one of: ${allowed.join(", ")}.`),value}function collect(value,previous){return[...previous??[],...value.split(",").map(v2=>v2.trim()).filter(v2=>v2!=="")]}function disabledFromFlags(opts){return switchFromFlags(opts,"disabled","enabled")}function switchFromFlags(opts,on2,off){if(opts[on2]&&opts[off]&&fail(EXIT.USAGE,"USAGE_ERROR",`--${on2} and --${off} cannot be combined.`),opts[on2])return!0;if(opts[off])return!1}function assertExplicitEnvironmentAgrees(envFlag,inBody){let explicit2=envFlag??process.env.SR_CONNECT_CLI_ENVIRONMENT;if(!explicit2||!inBody||explicit2===inBody)return;let source=envFlag===void 0?"SR_CONNECT_CLI_ENVIRONMENT names":"-e/--env names";fail(EXIT.USAGE,"USAGE_ERROR",`${source} ${explicit2} but the --input body's environmentId is ${inBody}; the body is what is sent, so drop one of them or make them agree.`)}async function teamForQuestions(scope2,globals){let known=scope2.team??globals.team;if(known)return known;if(canPrompt()){if(scope2.askedTeam!==void 0)return scope2.askedTeam||void 0;try{let resolved=await resolveParams(["team"],{},{client:scope2.client,interactive:!0,offerSession:!1});scope2.askedTeam=resolved.team??""}catch(err){if(!(err instanceof CliError))throw err;scope2.askedTeam=""}return scope2.askedTeam||void 0}}function stripUndefined(obj){return Object.fromEntries(Object.entries(obj).filter(([,v2])=>v2!==void 0))}function implicitShareMark(owner){let who=owner?personName(owner):"";return who?`current \u2014 implicitly shared via the workspace, owned by ${who}`:"current \u2014 implicitly shared via the workspace"}async function confirmImplicitReplacement(current,replacement,owner){let who=owner?personName(owner):"",contact=owner?.email&&who!==owner.email?` (${owner.email})`:"";return prompts().note([`"${current}" is attached here and reaches this workspace only because the workspace`,"is shared with you. Removing it cannot be undone by you: only",who?`${who}${contact}, who owns it, or someone it is explicitly shared with, can`:"the connector's owner, or someone it is explicitly shared with, can","attach it back."].join(`
1293
1294
  `)),prompts().confirm(`Replace it with "${replacement}"?`,!1)}var createBodySchema=external_exports.object({appId:external_exports.string().min(1),apiConnectionTypeId:external_exports.string().min(1),path:external_exports.string(),packageId:external_exports.string().optional(),connectorId:external_exports.string().optional(),environmentId:external_exports.string().optional()}).strict(),updateBodySchema=external_exports.object({path:external_exports.string().optional(),connectorId:external_exports.string().min(1).optional(),packageId:external_exports.string().min(1).optional()}).strict().refine(body=>Object.keys(body).length>0,{message:"At least one of path, connectorId or packageId is required."}),LIST_DOC=defineCommandDoc("api-connection list",{rules:["The workspace is -w and the environment -e; there is no positional argument, the verb listing every API connection of the workspace."],notes:["A path and its package belong to the workspace, so every environment lists the same connections. The connector column is the exception: it shows what is attached in the environment -e names, which is per-environment configuration."]}),GET_DOC=defineCommandDoc("api-connection get",{rules:["The API connection is the positional argument; the workspace is -w and the environment -e."],notes:["The one read that names the attached connector's owner, which matters because a connector you cannot use is still reported as attached.","Read through a non-HEAD environment it answers what that release captured."]}),DELETE_DOC=defineCommandDoc("api-connection delete",{rules:["The API connection is the positional argument; the workspace is -w and the environment -e, which gates the write rather than choosing what is deleted.","--yes skips the confirmation, and is required without a terminal."],notes:["Removes the API connection from the whole workspace rather than from one environment, and every script importing ./api/<path> stops working.","Its package leaves the workspace unless another API connection on HEAD still uses it. A release that captured a connection on that package does not keep the package in the workspace's dependency list, and pointing a connection back at it puts the package back.","A non-HEAD environment keeps running the copy its release captured."]}),CREATE_DOC=defineCommandDoc("api-connection create",{schema:createBodySchema,body:{appId:"<appId>",apiConnectionTypeId:"<apiConnectionTypeId>",path:"jira",packageId:"<packageId>",connectorId:"<connectorId>",environmentId:"<environmentId>"},rules:[`appId and apiConnectionTypeId come from ${CLI} app list, and the type must be one of the app's.`,`path: ${API_CONNECTION_PATH_FORMAT}; scripts import the connection as ./api/<path>, a pasted ./api/ prefix is dropped, and uniqueness within the workspace is the API's to refuse.`,"packageId: the vendor API package the connection is built on, one of the app's packages in app list; omitted, the API picks the recommended package, or the first one not deprecated, and refuses to choose at all when every package for the API connection type is deprecated.","connectorId attaches a connector in one environment and needs environmentId in the same body: -e/--env fills it on the flags path only, an --input body superseding every body flag; the connector must be of the same API connection type and usable by you in the team; connector list reports each connector's connectionType, which is the app's, and never its API connection type.","environmentId is required with connectorId, and validated whenever it is sent: it must exist and belong to the workspace, and the attachment is refused when that environment is non-HEAD. Sent without connectorId it attaches nothing, so the flags path drops it. The body is what is sent: an -e or SR_CONNECT_CLI_ENVIRONMENT that names a different environment from the body is exit 2 rather than a tie-break, and the session record and a clone's workspace.json are not consulted for the environment when a body is given.","The workspace is -w and never a body key; path and packageId are shared by every environment."]}),UPDATE_DOC=defineCommandDoc("api-connection update",{schema:updateBodySchema,body:{path:"jira",packageId:"<packageId>",connectorId:"<connectorId>"},rules:["An omitted key keeps the current value, and a body with no keys is refused: at least one of path, connectorId or packageId is required.",`connectorId attaches a connector in the environment named by -e, and there is no way to detach one; the connector must be of the connection's API connection type and usable by you in the team, and connector list reports each connector's connectionType, which is the app's, never its API connection type. Omitted, it is kept from that environment's own record, so an API connection with nothing attached there refuses every update \u2014 a path-only one included \u2014 with 400 "Connector is required." until a connector is sent.`,`path: ${API_CONNECTION_PATH_FORMAT}; a pasted ./api/ prefix is dropped; shared by every environment, and every script importing the old ./api/<path> breaks.`,"packageId: the vendor API package, as reported in package.id by get; shared by every environment.","In a non-HEAD environment only connectorId can change. path and packageId are read-only rather than refused there: echo back what that environment's own get reports, or omit them, and only a differing value is a 400 naming it."]});function withScope(cmd,opts={}){let env=opts.gate?opts.destructive?SCOPE_ENVIRONMENT_GATE_DESTRUCTIVE:SCOPE_ENVIRONMENT_GATE:opts.destructive?SCOPE_ENVIRONMENT_DESTRUCTIVE:SCOPE_ENVIRONMENT;return cmd.option("-w, --workspace <workspaceId>",opts.destructive?SCOPE_WORKSPACE_DESTRUCTIVE:SCOPE_WORKSPACE).option("-e, --env <environmentId>",env).option("--team <teamId>",opts.destructive?SCOPE_TEAM_FILTER_DESTRUCTIVE:SCOPE_TEAM_FILTER)}async function resolveScope(globals,opts={}){let client=await apiClient(globals.instance),resolved=await resolveParams(["workspace","environment"],{team:globals.team,workspace:globals.workspace,environment:globals.env},{client,interactive:canPrompt(),useSession:opts.useSession});return{client,workspace:resolved.workspace??"",environment:resolved.environment??"",team:resolved.team}}async function resolveApiConnection(scope2,provided){if(provided)return{id:assertResourceId(provided,"apiConnectionId")};canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR",`<apiConnectionId> is required. ${supplyHint()}`);let labels={};return{id:(await resolveParams(["apiConnection"],{workspace:scope2.workspace,environment:scope2.environment},{client:scope2.client,interactive:!0,labels})).apiConnection??"",label:labels.apiConnection}}function connectorCell(connection,empty="\u2014"){let connector=connection.connector;return connector?`${connector.name||connector.id} (${connector.id})`:empty}function packageCell(pkg,empty="\u2014"){return pkg?pkg.label??pkg.name:empty}function packageDetail(pkg,empty="(none)"){return pkg?pkg.label?`${pkg.label} (${pkg.name})`:pkg.name:empty}async function askPackage(client,appId,apiConnectionTypeId){let packages;try{packages=await withSpinner("Fetching packages",()=>apiConnectionPackages(client,appId,apiConnectionTypeId))}catch{return}if(packages.length===0)return;let auto=packages.find(p=>p.recommended)??packages.find(p=>!p.deprecated);if(auto&&packages.length===1)return;auto||prompts().note("Every package for this API connection type is deprecated \u2014 pick one.");let choices=packages.map(p=>{let label=p.name??p.id??"?",hint=p.deprecated?"deprecated":p.recommended?"recommended":void 0;return{value:p.id??"",label,...p.id===auto?.id?{display:`${label} (default)`,hint:hint??"the API picks this"}:hint?{hint}:{}}}),picked=await prompts().select("Package:",choices,auto?.id?{initial:auto.id}:{});return picked===auto?.id?void 0:picked}async function askPath(initial){for(;;){let answer=await prompts().text(PATH_PROMPT,{...initial?{initial}:{},allowEmpty:!0}),error51=apiConnectionPathError(answer);if(!error51)return normalizeApiConnectionPath(answer);prompts().note(`\u2716 ${error51}`)}}function updateFail(status,body,scope2){let error51=body,message=error51?.errorMessage??error51?.message??"";status===400&&/^connector is required\.?$/i.test(message.trim())&&fail(EXIT.API_ERROR,"BAD_REQUEST",message,{status,hint:`No connector is attached in that environment, and an omitted --connector-id keeps whatever is: send one. \`${CLI} api-connection list -w ${scope2.workspace} -e ${scope2.environment}\` shows what each environment has.`}),apiFail(status,body)}function releasedNote(version2){return`\u26A0 This environment has ${version2?`release ${version2}`:"a release"} deployed. Only the connector can be changed there; the import path and the package belong to the API connection and are shared by every environment.`}async function askConnector(scope2,globals,current){let team=await teamForQuestions(scope2,globals);if(!team)return;let deps={team,app:current.appId,apiConnectionType:current.apiConnectionTypeId,workspace:scope2.workspace,environment:scope2.environment},implicit=!1;if(current.connectorId)try{let absent=!(await resolverChoices(scope2.client,"connector",deps)).some(choice=>choice.value===current.connectorId),me2=await currentUserId(scope2.client),someoneElse=!current.owner||!me2||current.owner.id!==me2;implicit=absent&&someoneElse}catch(err){if(!(err instanceof CliError))throw err}for(;;){let picked;try{picked=await askKeepOrChange({client:scope2.client,key:"connector",deps,message:"Connector:",current:{value:current.connectorId,label:current.label},...implicit?{missingCurrentMark:implicitShareMark(current.owner)}:{}})}catch(err){if(!(err instanceof CliError))throw err;return}if(picked===void 0||!implicit)return picked;let replacement=await connectorName(scope2.client,deps,picked);if(await confirmImplicitReplacement(current.label??current.connectorId??"",replacement,current.owner))return picked}}async function connectorName(client,deps,connectorId){try{return(await resolverChoices(client,"connector",deps)).find(choice=>choice.value===connectorId)?.label??connectorId}catch{return connectorId}}var NO_CONNECTOR="\0no-connector";async function askConnectorOnCreate(client,globals,current,scopeTeam){let scope2={client,workspace:current.workspace,environment:current.environment??"",team:scopeTeam},team=await teamForQuestions(scope2,globals);if(!team)return;let choices;try{choices=await resolverChoices(client,"connector",{team,app:current.appId,apiConnectionType:current.apiConnectionTypeId,workspace:current.workspace,...current.environment?{environment:current.environment}:{}})}catch(err){if(!(err instanceof CliError))throw err;return}if(choices.length===0){prompts().note("\u26A0 No connector of this type exists in the team \u2014 creating the API connection unattached.");return}let picked=await prompts().select("Connector:",[{value:NO_CONNECTOR,label:"No connector",hint:"attach one later; scripts using it fail until then"},...choices],{initial:choices[0]?.value??NO_CONNECTOR});return picked===NO_CONNECTOR?void 0:picked}async function buildCreateBody(client,workspaceId,scope2,opts,interactive){let labels={},resolved=await resolveParams(["app","apiConnectionType"],{team:scope2.team,workspace:workspaceId,environment:opts.env??scope2.environment,app:opts.appId,apiConnectionType:opts.apiConnectionTypeId},{client,interactive,labels,offerSession:!1}),appId=resolved.app??"",apiConnectionTypeId=resolved.apiConnectionType??"",path2=opts.path;path2===void 0&&(interactive||fail(EXIT.USAGE,"USAGE_ERROR","--path is required."),path2=await askPath(suggestPathFromLabel(labels.app??"")));let packageId=opts.packageId??(interactive?await askPackage(client,appId,apiConnectionTypeId):void 0),environmentId=opts.env??scope2.environment,connectorId=opts.connectorId;return!connectorId&&interactive&&(connectorId=await askConnectorOnCreate(client,{team:opts.team},{workspace:workspaceId,...environmentId?{environment:environmentId}:{},appId,apiConnectionTypeId},resolved.team)),connectorId&&!environmentId&&interactive&&(environmentId=(await resolveParams(["environment"],{team:resolved.team,workspace:workspaceId},{client,interactive:!0,offerSession:!1})).environment),stripUndefined({appId,apiConnectionTypeId,path:path2,packageId,connectorId,environmentId:connectorId?environmentId:void 0})}async function buildUpdateBody(scope2,globals,apiConnectionId,opts){if(opts.input)return readInput(opts.input);if(!canPrompt()){let rawBody=stripUndefined({path:opts.path===void 0?void 0:assertApiConnectionPath(opts.path),connectorId:opts.connectorId,packageId:opts.packageId});return Object.keys(rawBody).length===0&&failNothingToUpdate(["--path","--connector-id","--package-id","--input"]),rawBody}let current=await withSpinner("Fetching API connection",()=>scope2.client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnection/{apiConnectionId}",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment,apiConnectionId}}}));(!current.response.ok||!current.data)&&apiFail(current.response.status,current.error);let release2=await withSpinner("Checking the environment",()=>environmentRelease(scope2.client,scope2.workspace,scope2.environment));if(release2&&prompts().note(releasedNote(release2.version)),release2){let shared=[...opts.path===void 0?[]:["--path"],...opts.packageId===void 0?[]:["--package-id"]];shared.length>0&&fail(EXIT.USAGE,"USAGE_ERROR",`${shared.join(" and ")} cannot be changed in an environment with a release deployed \u2014 the import path and the package belong to the API connection and are shared by every environment. Target a HEAD environment, or pass only --connector-id.`)}let path2=release2?void 0:opts.path===void 0?await askPath(current.data.path):assertApiConnectionPath(opts.path),packageId=release2?void 0:opts.packageId??await askKeepOrChange({client:scope2.client,key:"apiConnectionPackage",deps:{app:current.data.app.id,apiConnectionType:current.data.apiConnectionTypeId},message:"Package:",current:{value:current.data.package?.id,label:packageCell(current.data.package,"")}}),connectorId=opts.connectorId??await askConnector(scope2,globals,{appId:current.data.app.id,apiConnectionTypeId:current.data.apiConnectionTypeId,connectorId:current.data.connector?.id,label:current.data.connector?.name,owner:current.data.connector?.owner});!current.data.connector?.id&&connectorId===void 0&&fail(EXIT.USAGE,"CONNECTOR_REQUIRED",`This API connection has no connector attached in this environment, and the API refuses every update to one that has none. Attach one with --connector-id <id>, from \`${CLI} connector list\`.`);let renamed=path2===void 0||path2===current.data.path?void 0:path2;if(renamed===void 0&&packageId===void 0&&connectorId===void 0){prompts().note("Nothing to update \u2014 the API connection was left as it is.");return}return stripUndefined({path:renamed,connectorId,packageId})}function apiConnectionCommand(){let conn=new Command("api-connection").alias("ac").description("Manage workspace API connections");return conn.command("create").description("Create an API connection in a workspace").option("-w, --workspace <workspaceId>",SCOPE_WORKSPACE).option("--team <teamId>",SCOPE_TEAM_FILTER).option("--app-id <id>","App ID (required unless --input, interactive)").option("--api-connection-type-id <id>","API connection type ID (required unless --input, interactive)").option("--path <path>",`Import path scripts use to reference the connection as ${importSpecifier("<path>")}, ${API_CONNECTION_PATH_FORMAT} (required unless --input, interactive)`).option("--package-id <id>","Package ID (optional, interactive, API default: the recommended or first non-deprecated package)").option("--connector-id <id>","Connector to authorize the connection with (optional, interactive, requires -e/--env, refused in a non-HEAD environment)").option("-e, --env <environmentId>","Environment ID (required with --connector-id unless --input, interactive, session default, env SR_CONNECT_CLI_ENVIRONMENT, ignored with --input)").option("--input <file>",INPUT_BODY).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CREATE_DOC))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),interactive=canPrompt(),scope2=await resolveParams(["workspace"],{team:opts.team??globals.team,workspace:opts.workspace??globals.workspace,environment:opts.env??globals.env},{client,interactive,offerSession:!1,needs:["workspace","environment"]}),workspaceId=scope2.workspace??"",rawBody=opts.input?readInput(opts.input):await buildCreateBody(client,workspaceId,scope2,opts,interactive),parsed=validate(createBodySchema,rawBody),body={...parsed,path:assertApiConnectionPath(parsed.path)};body.connectorId&&!body.environmentId&&fail(EXIT.USAGE,"USAGE_ERROR",opts.input?"connectorId needs environmentId in the same body \u2014 -e/--env does not fill it, an --input body superseding every body flag (a connector is attached per environment).":"--connector-id needs an environment \u2014 pass -e/--env (a connector is attached per environment)."),opts.input&&assertExplicitEnvironmentAgrees(opts.env,body.environmentId);let{data,response,error:error51}=await withSpinner("Creating API connection",()=>client.POST("/v1/workspace/{workspaceId}/apiConnection",{params:{path:{workspaceId}},body}));(!response.ok||!data)&&apiFail(response.status,error51),await syncApiConnections(client,{workspaceId}),await syncPackages(client,workspaceId),okMutation("API connection created",data,{...data,path:body.path,import:importSpecifier(body.path)})}),withScope(conn.command("list").description("List API connections in a workspace")).option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,LIST_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope(globals),{data,response,error:error51}=await withSpinner("Fetching API connections",()=>scope2.client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnections",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment}}}));(!response.ok||!data)&&apiFail(response.status,error51),ok(data,{human:d=>({apiConnections:d.apiConnections.map(c=>({id:c.id,path:c.path??"\u2014",app:`${c.app.name} (${c.app.id})`,connector:connectorCell(c),package:packageDetail(c.package,"\u2014")}))})})}),withScope(conn.command("get").description("Get a single API connection as the environment sees it").argument("[apiConnectionId]","API connection ID (required, interactive)")).option("--explain",EXPLAIN).action(async(idArg,_opts,cmd)=>{if(explained(cmd,GET_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope(globals),connection=await resolveApiConnection(scope2,idArg),{data,response,error:error51}=await withSpinner("Fetching API connection",()=>scope2.client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnection/{apiConnectionId}",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment,apiConnectionId:connection.id}}}));(!response.ok||!data)&&apiFail(response.status,error51),ok(data,{human:d=>({id:d.id,path:d.path??"(none)",import:d.path?importSpecifier(d.path):"(none)",app:`${d.app.name} (${d.app.id})`,apiConnectionTypeId:d.apiConnectionTypeId,connector:connectorCell(d,"(none)"),...d.connector?.owner?{connectorOwner:personCell(d.connector.owner)}:{},package:packageDetail(d.package)})})}),withScope(conn.command("update").description("Update an API connection").argument("[apiConnectionId]","API connection ID (required, interactive)")).option("--path <path>",`New import path, used by scripts as ${importSpecifier("<path>")}, ${API_CONNECTION_PATH_FORMAT} (optional, interactive on HEAD only, refused when it differs from what a non-HEAD environment reports)`).option("--package-id <id>","Vendor API package to use, as reported in package.id (optional, interactive on HEAD only, refused when it differs from what a non-HEAD environment reports)").option("--connector-id <id>","Connector to attach in the specified environment \u2014 there is no way to detach one (optional, interactive, required when the specified environment has no connector attached)").option("--input <file>",INPUT_BODY).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,UPDATE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope(globals),connection=await resolveApiConnection(scope2,idArg),rawBody=await buildUpdateBody(scope2,globals,connection.id,opts);if(rawBody===void 0)return;let parsed=validate(updateBodySchema,rawBody),body=parsed.path===void 0?parsed:{...parsed,path:assertApiConnectionPath(parsed.path)},{response,error:error51}=await withSpinner("Updating API connection",()=>scope2.client.PUT("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnection/{apiConnectionId}",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment,apiConnectionId:connection.id}},body}));response.ok||updateFail(response.status,error51,scope2),await syncApiConnections(scope2.client,{workspaceId:scope2.workspace,environmentId:scope2.environment}),await syncPackages(scope2.client,scope2.workspace);let echoed=body.path?{path:body.path,import:importSpecifier(body.path)}:void 0;okMutation("API connection updated",{updated:!0,id:connection.id},echoed)}),withScope(conn.command("delete").description("Delete an API connection from a workspace").argument("[apiConnectionId]","API connection ID (required, interactive)"),{destructive:!0,gate:!0}).option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,DELETE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope(globals,{useSession:canPrompt()}),connection=await resolveApiConnection(scope2,idArg);if(!opts.yes){canPrompt()||failNeedsYes(`API connection ${connection.id}`);let current=await withSpinner("Fetching API connection",()=>scope2.client.GET("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnection/{apiConnectionId}",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment,apiConnectionId:connection.id}}}));(!current.response.ok||!current.data)&&apiFail(current.response.status,current.error);let path2=current.data.path,pkg=current.data.package;prompts().note(["Deleting removes the API connection from the whole workspace, not just this environment.",path2?`Scripts importing "${importSpecifier(path2)}" stop working.`:"Scripts importing it stop working.",pkg?`The vendor API package ${packageDetail(pkg)} is removed from the workspace unless another API connection still uses it.`:"The vendor API package it uses is removed from the workspace unless another API connection still uses it.","An environment with a release deployed keeps running the API connection captured in that release until the release is replaced."].join(`
1294
1295
  `)),await prompts().confirm(`Delete API connection ${path2??connection.id} (${connection.id})? This is irreversible.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled.")}let{response,error:error51}=await withSpinner("Deleting API connection",()=>scope2.client.DELETE("/v1/workspace/{workspaceId}/environment/{environmentId}/apiConnection/{apiConnectionId}",{params:{path:{workspaceId:scope2.workspace,environmentId:scope2.environment,apiConnectionId:connection.id}}}));response.ok||apiFail(response.status,error51),await syncApiConnections(scope2.client,{workspaceId:scope2.workspace,environmentId:scope2.environment}),await syncPackages(scope2.client,scope2.workspace),okMutation("API connection deleted",{deleted:!0,id:connection.id})}),conn}function parseCredentials(raw){if(raw.startsWith("{")){try{let parsed=JSON.parse(raw);if(parsed.username&&parsed.password)return{username:parsed.username,password:parsed.password}}catch{}fail(EXIT.USAGE,"INVALID_CREDENTIALS_INPUT",'JSON credentials must be {"username": "...", "password": "..."}.')}let colon=raw.indexOf(":");return(colon<1||colon===raw.length-1)&&fail(EXIT.USAGE,"INVALID_CREDENTIALS_INPUT","Expected credentials as username:password on stdin."),{username:raw.slice(0,colon),password:raw.slice(colon+1)}}function apiKeyInstructions(instance4){let url2=apiKeysUrl(instance4),profile='click your profile name in the bottom-left corner and select "API Keys"';return["Generate an API key in the ScriptRunner Connect web app:",url2?` 1. Open ${url2}
1295
1296
  (or ${profile})`:` 1. In the web app, ${profile}`,' 2. Click "Create new", name it \u2014 for example "CLI" \u2014 then "Create new"'," 3. Copy Email into the username below, and API Key into the password"].join(`
1296
- `)}async function verify(creds,instance4){warnIfInsecure(instance4);let client=createClient({baseUrl:baseUrl(instance4),headers:{Authorization:basicAuthHeader(creds),...identityHeaders()},fetch:fetchWithRetry}),{data,response,error:error51}=await withSpinner("Verifying credentials",()=>client.GET("/v1/user/me"));return(!response.ok||!data)&&apiFail(response.status,error51),data}async function askAgenticFeedback(){let descriptor=SETTINGS.agenticFeedback;if(envDisabled("agenticFeedback")){prompts().note(`Agentic feedback is off in this environment (${descriptor.envVar}) \u2014 not asking.`);return}let current=storedAgenticFeedback(),answer;try{answer=await prompts().confirm("May agents send feedback to the ScriptRunner Connect team on their own, to improve the CLI's agentic capabilities?",current)}catch(err){if(!(err instanceof CliError&&err.code==="CANCELLED")){warnLine(`\u26A0 Could not ask about agentic feedback (${describeError(err)}).`);return}prompts().note(`Agentic feedback left as it is (${current?"on":"off"}).`);return}if(answer!==current)try{setSetting("agenticFeedback",answer)}catch(err){warnLine(`\u26A0 Could not store the setting (${describeError(err)}) \u2014 the login itself is unaffected.`);return}prompts().note(answer?`Agentic feedback: on. Change it any time with \`${CLI} cli settings\`.`:`Agentic feedback: off \u2014 only the interactive flow can post. Change it any time with \`${CLI} cli settings\`.`)}function storedAgenticFeedback(){return settingStates().find(state=>state.key==="agenticFeedback")?.enabled!==!1}var LOGIN_DOC=defineCommandDoc("auth login",{rules:['--credentials-stdin reads username:password from stdin, split on the first colon, or {"username":\u2026,"password":\u2026}. Required without a terminal, a key never riding in argv.',"--insecure-storage writes a credentials.json only you can read instead of using the secure store. Without it, a machine with no reachable secure store cannot log in: exit 2 KEYCHAIN_UNAVAILABLE, with the flag named in the hint."],notes:["The secure store is the macOS Keychain, Windows Credential Manager or Secret Service on Linux.","SR_CONNECT_CLI_USERNAME and SR_CONNECT_CLI_PASSWORD are not read here. They replace a stored login for every other command, so with them set no login is needed at all.","The instance must come from --instance or SR_CONNECT_CLI_INSTANCE when none is stored and nobody can be asked.","The document reports authenticated, source (keychain or file \u2014 the same word auth status answers with), the instance, the agentic-feedback switch and the user."]}),STATUS_DOC=defineCommandDoc("auth status",{rules:["No parameters of its own: it reports on whatever credentials and instance the run resolves to."],notes:["Which credential source is in use \u2014 environment, secure store or file \u2014 and which instance it verifies against.","It sends the same request as login and fails the same way, which is what makes it the first thing to run when something answers 3."]}),LOGOUT_DOC=defineCommandDoc("auth logout",{rules:["No parameters: it removes whatever is stored."],notes:["Removes the stored credentials and every terminal's session defaults. A lock whose lease has not run out is kept in the record and named on stderr with the command that gives it back, because logging out leaves nothing here able to release it; the raw document reports them as keptLocks.","Keeps the configured instance, the API-call recordings, the crash reports and the settings \u2014 none of which is a credential, and all of which you want when authentication is the thing that broke."]});function authCommand(){let auth=new Command("auth").description("Manage CLI authentication");return auth.command("login").description("Verify and store API credentials in the OS keychain").option("--credentials-stdin","Read username:password (or JSON) from stdin instead of prompting (optional on a TTY, required otherwise)").option("--insecure-storage","Store credentials in a plaintext 0600 file instead of the OS keychain (optional)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,LOGIN_DOC))return;let globals=cmd.optsWithGlobals();!opts.credentialsStdin&&!canPrompt()&&fail(EXIT.USAGE,"CREDENTIALS_REQUIRED","Not interactive. Pipe credentials with --credentials-stdin, or set SR_CONNECT_CLI_USERNAME and SR_CONNECT_CLI_PASSWORD.");let instance4=explicitInstance(globals.instance);!instance4&&canPrompt()&&(instance4=await askInstance(resolveInstance())),instance4||(instance4=requireInstance(globals.instance));let chosenInstance=instance4,creds;if(opts.credentialsStdin)creds=parseCredentials(readStdinSync().trim());else{prompts().note(apiKeyInstructions(chosenInstance));let username=await prompts().text("ScriptRunner Connect API username:"),password=await prompts().password("ScriptRunner Connect API password:");creds={username,password}}let user=await verify(creds,chosenInstance),source;if(opts.insecureStorage)fileSet(creds),source="file";else try{await keychainSet(creds),source="keychain"}catch(err){fail(EXIT.USAGE,"KEYCHAIN_UNAVAILABLE",`OS keychain unavailable (${err instanceof Error?err.message:String(err)}).`,{hint:"Re-run with --insecure-storage to use a 0600 file, or use SR_CONNECT_CLI_USERNAME/SR_CONNECT_CLI_PASSWORD env vars."})}writeConfig({...readConfig(),instance:chosenInstance}),canPrompt()&&await askAgenticFeedback(),ok({authenticated:!0,source,instance:chosenInstance,agenticFeedback:storedAgenticFeedback(),user},{human:d=>({...d,instance:instanceLabel(d.instance)})})}),auth.command("status").description("Show credential source, instance, and verify against the API").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,STATUS_DOC))return;let globals=cmd.optsWithGlobals(),creds=await requireCredentials(),instance4=requireInstance(globals.instance),user=await verify(creds,instance4);ok({authenticated:!0,source:creds.source,instance:instance4,username:creds.username,user},{human:d=>({...d,instance:instanceLabel(d.instance)})})}),auth.command("logout").description("Remove stored credentials and every shell session's remembered scope").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,LOGOUT_DOC))return;let removed=[];await keychainDelete()&&removed.push("keychain"),fileGet()&&(fileDelete(),removed.push("file"));let{removed:sessions,keptLocks}=clearAllSessions();if(sessions>0&&removed.push("sessions"),keptLocks.length>0){let lines=keptLocks.map(lock=>` ${lockReleaseCommand(lock)}`);warnLine(`\u26A0 ${keptLocks.length===1?"One workspace lock is":`${keptLocks.length} workspace locks are`} still held, and logging out leaves nothing here able to release ${keptLocks.length===1?"it":"them"}.
1297
+ `)}async function verify(creds,instance4){warnIfInsecure(instance4);let client=createClient({baseUrl:baseUrl(instance4),headers:{Authorization:basicAuthHeader(creds),...identityHeaders()},fetch:fetchWithRetry}),{data,response,error:error51}=await withSpinner("Verifying credentials",()=>client.GET("/v1/user/me"));return(!response.ok||!data)&&apiFail(response.status,error51),data}async function askAgenticFeedback(){let descriptor=SETTINGS.agenticFeedback;if(envDisabled("agenticFeedback")){prompts().note(`Agentic feedback is off in this environment (${descriptor.envVar}) \u2014 not asking.`);return}let current=storedAgenticFeedback(),answer;try{answer=await prompts().confirm("May agents send feedback to the ScriptRunner Connect team on their own, to improve the CLI's agentic capabilities?",current)}catch(err){if(!(err instanceof CliError&&err.code==="CANCELLED")){warnLine(`\u26A0 Could not ask about agentic feedback (${describeError(err)}).`);return}prompts().note(`Agentic feedback left as it is (${current?"on":"off"}).`);return}if(answer!==current)try{setSetting("agenticFeedback",answer)}catch(err){warnLine(`\u26A0 Could not store the setting (${describeError(err)}) \u2014 the login itself is unaffected.`);return}prompts().note(answer?`Agentic feedback: on. Change it any time with \`${CLI} cli settings\`.`:`Agentic feedback: off \u2014 only the interactive flow can post. Change it any time with \`${CLI} cli settings\`.`)}function storedAgenticFeedback(){return settingStates().find(state=>state.key==="agenticFeedback")?.enabled!==!1}var LOGIN_DOC=defineCommandDoc("auth login",{rules:['--credentials-stdin reads username:password from stdin, split on the first colon, or {"username":\u2026,"password":\u2026}. Required without a terminal, a key never riding in argv.',"--insecure-storage writes a credentials.json only you can read instead of using the secure store. Without it, a machine with no reachable secure store cannot log in: exit 2 KEYCHAIN_UNAVAILABLE, with the flag named in the hint."],notes:["The secure store is the macOS Keychain, Windows Credential Manager or Secret Service on Linux.","SR_CONNECT_CLI_USERNAME and SR_CONNECT_CLI_PASSWORD are not read here. They replace a stored login for every other command, so with them set no login is needed at all.","The instance must come from --instance or SR_CONNECT_CLI_INSTANCE when none is stored and nobody can be asked.","The document reports authenticated, source (keychain or file \u2014 the same word auth status answers with), the instance, the agentic-feedback switch and the user."]}),STATUS_DOC=defineCommandDoc("auth status",{rules:["No parameters of its own: it reports on whatever credentials and instance the run resolves to."],notes:["Which credential source is in use \u2014 environment, secure store or file \u2014 and which instance it verifies against.","It sends the same request as login and fails the same way, which is what makes it the first thing to run when something answers 3."]}),LOGOUT_DOC=defineCommandDoc("auth logout",{rules:["No parameters: it removes whatever is stored."],notes:["Removes the stored credentials and every terminal's session defaults. A lock whose lease has not run out is kept in the record and named on stderr with the command that gives it back, because logging out leaves nothing here able to release it; the raw document reports them as keptLocks.","Keeps the configured instance, the API-call recordings, the crash reports and the settings \u2014 none of which is a credential, and all of which you want when authentication is the thing that broke."]});function authCommand(){let auth=new Command("auth").description("Manage CLI authentication");return auth.command("login").description("Verify and store API credentials in the OS keychain").option("--credentials-stdin","Read username:password (or JSON) from stdin instead of prompting (optional on a TTY, required otherwise)").option("--insecure-storage","Store credentials in a plaintext 0600 file instead of the OS keychain (optional)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,LOGIN_DOC))return;let globals=cmd.optsWithGlobals();!opts.credentialsStdin&&!canPrompt()&&fail(EXIT.USAGE,"CREDENTIALS_REQUIRED","Not interactive. Pipe credentials with --credentials-stdin, or set SR_CONNECT_CLI_USERNAME and SR_CONNECT_CLI_PASSWORD.");let instance4=explicitInstance(globals.instance);!instance4&&canPrompt()&&(instance4=await askInstance(resolveInstance())),instance4||(instance4=requireInstance(globals.instance));let chosenInstance=instance4,creds;if(opts.credentialsStdin)creds=parseCredentials(readStdinSync().trim());else{prompts().note(apiKeyInstructions(chosenInstance));let username=await prompts().text("ScriptRunner Connect API username:"),password=await prompts().password("ScriptRunner Connect API password:");creds={username,password}}let user=await verify(creds,chosenInstance),source;if(opts.insecureStorage)fileSet(creds),source="file";else try{await keychainSet(creds),source="keychain"}catch(err){fail(EXIT.USAGE,"KEYCHAIN_UNAVAILABLE",`OS keychain unavailable (${err instanceof Error?err.message:String(err)}).`,{hint:"Re-run with --insecure-storage to use a 0600 file, or use SR_CONNECT_CLI_USERNAME/SR_CONNECT_CLI_PASSWORD env vars."})}writeConfig({...readConfig(),instance:chosenInstance}),canPrompt()&&await askAgenticFeedback();let payload={authenticated:!0,source,instance:chosenInstance,agenticFeedback:storedAgenticFeedback(),user};okMutation("Logged in",payload,{...payload,instance:instanceLabel(payload.instance)})}),auth.command("status").description("Show credential source, instance, and verify against the API").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,STATUS_DOC))return;let globals=cmd.optsWithGlobals(),creds=await requireCredentials(),instance4=requireInstance(globals.instance),user=await verify(creds,instance4);ok({authenticated:!0,source:creds.source,instance:instance4,username:creds.username,user},{human:d=>({...d,instance:instanceLabel(d.instance)})})}),auth.command("logout").description("Remove stored credentials and every shell session's remembered scope").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,LOGOUT_DOC))return;let removed=[];await keychainDelete()&&removed.push("keychain"),fileGet()&&(fileDelete(),removed.push("file"));let{removed:sessions,keptLocks}=clearAllSessions();if(sessions>0&&removed.push("sessions"),keptLocks.length>0){let lines=keptLocks.map(lock=>` ${lockReleaseCommand(lock)}`);warnLine(`\u26A0 ${keptLocks.length===1?"One workspace lock is":`${keptLocks.length} workspace locks are`} still held, and logging out leaves nothing here able to release ${keptLocks.length===1?"it":"them"}.
1297
1298
  Log back in and give ${keptLocks.length===1?"it":"them"} back with:
1298
1299
  ${lines.join(`
1299
1300
  `)}
@@ -1325,7 +1326,7 @@ ${table2}`}).join(`
1325
1326
  `)}function noteWhyEmpty(opts){let recorded=listRecordedSessions();if(recorded.length===0){prompts().note("No API calls recorded yet \u2014 recording is on unless --no-record-api-calls or SR_CONNECT_CLI_NO_RECORD_API_CALLS turned it off, and a run that reaches no API records nothing.");return}opts.allSessions||filterApiCalls(readApiCalls({allSessions:!0}),opts).length>0&&prompts().note(`Nothing recorded for this shell session, but ${recorded.length} other session${recorded.length===1?" has":"s have"} calls \u2014 try --all-sessions.`)}function crashRow(report){return{id:report.id,created:report.createdAt,command:report.command,kind:crashTitle(report),size:formatBytes(report.bytes)}}function settingRow(state){return{setting:state.label,status:state.enabled?"on":"off",source:sourceLabel2(state),flag:state.flag}}function sourceLabel2(state){return state.source==="env"?`env ${state.envVar}`:state.source==="flag"?`flag ${state.flag}`:state.source}function settingsUnchanged(before,values){let wasOff=before.filter(state=>state.stored===!1).map(state=>state.key),nowOff=SETTING_KEYS.filter(key=>!values[key]||envDisabled(key));return wasOff.length===nowOff.length&&wasOff.every(key=>nowOff.includes(key))}async function askSettings(){let states=settingStates(),choices=states.map(state=>({value:state.key,label:state.label,hint:state.envDisabled?`off \u2014 ${state.envVar} is set in this environment`:state.hint,...state.envDisabled?{disabled:!0}:{}})),initial=states.filter(state=>!state.envDisabled&&state.stored!==!1).map(state=>state.key),picked=await prompts().multiselect("CLI settings:",choices,{initial});return SETTING_KEYS.filter(key=>picked.includes(key))}function noteKeptLocks(keptLocks){if(keptLocks.length===0)return;let lines=keptLocks.map(lock=>` ${lockReleaseCommand(lock)}`);warnLine(`\u26A0 ${keptLocks.length===1?"One workspace lock is":`${keptLocks.length} workspace locks are`} still held and kept in the record \u2014 writes from this shell go on reusing ${keptLocks.length===1?"it":"them"}.
1326
1327
  Give ${keptLocks.length===1?"it":"them"} back early with:
1327
1328
  ${lines.join(`
1328
- `)}`)}var GET_README_DOC=defineCommandDoc("cli get-readme",{rules:["No parameters: it prints the README of the installed package."],notes:["Rendered for the terminal in human mode, the markdown source under --raw.","Needs no credentials and no instance, like every verb in this group but set-session.","It is orientation, not per-verb reference: what a verb takes is --explain on that verb."]}),SETTINGS_DOC=defineCommandDoc("cli settings",{rules:["No parameters: there is no flag that sets a switch, and a scripted run is read-only."],notes:["The five stored switches with their current state and which source decided it: flag, env, stored or default.","On a terminal without --raw, one multiselect changes them. Under --raw the command is read-only \u2014 the one place --raw suppresses a question, because there the table is the answer a scripted run wants.","Only the offs are stored, in a file that survives cli clear-session and auth logout. A switch disabled by its environment variable cannot be toggled and is written as off.","Answers that change nothing make no request at all \u2014 this verb never makes one."]}),SET_SESSION_DOC=defineCommandDoc("cli set-session",{rules:["The team is --team, the workspace -w and the environment -e. They carry no session default here, this verb being the save flow itself, though the scope environment variables still pre-fill."],notes:["Remembers all three as this shell's defaults, for 12 hours and for one instance.","A typed -e is checked against the workspace first, one request, and an environment belonging to another workspace is exit 2 ENVIRONMENT_MISMATCH \u2014 the pair would otherwise be stored and fail every command that read it.",`The document carries the three IDs and a labels object holding each one's name, which the checks above already read; every later command's "Using session defaults: \u2026" line reads those names, so a record written here announces itself the same way a picked one does.`,"Where the shell cannot be identified, in a container step for example, set SR_CONNECT_CLI_SESSION_ID."]}),CLEAR_SESSION_DOC=defineCommandDoc("cli clear-session",{rules:["--all forgets every shell's record rather than this one's."],notes:["A workspace lock rides the same record but is not a default, so clearing the scope keeps it: a clear that leaves one names the lock and the command that gives it back."]}),LIST_API_LOGS_DOC=defineCommandDoc("cli list-api-logs",{rules:["--limit counts runs rather than calls, default 20, 0 for all; a run is never cut in half.","--session reads another shell's recording, --all-sessions reads them all, and --list-sessions lists the recorded shells instead and ignores every filter.","--since and --to take an ISO instant or a startTime exactly as printed in log results.","--status repeats, and filters by the HTTP status the call answered with.","--method filters by HTTP method and --path by a substring of the URL; --failed-only keeps the calls that answered 400 or above and the ones that never answered at all. All three are ignored with --list-sessions, as every filter here is."],notes:["Runs of this shell, newest first, each with its calls. Needs no credentials, which is what makes it readable when authentication is the thing that broke.","Secrets are redacted at record time, so what is stored is what is printed."]}),CLEAR_API_LOGS_DOC=defineCommandDoc("cli clear-api-logs",{rules:["--session names another shell's recording to delete, spelled as cli list-api-logs --list-sessions reports it; omitted, this shell's own is the one cleared.","--all-sessions deletes every shell's recording rather than this one's."],notes:["Recording is on unless --no-record-api-calls or the stored switch turns it off; deleting does not turn it off."]}),LIST_CRASH_REPORTS_DOC=defineCommandDoc("cli list-crash-reports",{rules:["No parameters: it lists what is stored."],notes:["Newest first: the run ID, when, the command, the kind and the size.","The store keeps 7 days and the newest 20, pruned on write."]}),GET_CRASH_REPORT_DOC=defineCommandDoc("cli get-crash-report",{rules:["--report names a report by its run ID; omitted, the newest is read.","--content-only prints the markdown verbatim, identically in both modes."],notes:["A report carries the metadata, the stack and the API calls that run recorded, composed against a 512 KB budget."]}),CLEAR_CRASH_REPORTS_DOC=defineCommandDoc("cli clear-crash-reports",{rules:["--report deletes a single report by its run ID; omitted, every stored report goes."],notes:["A report is deleted on a successful feedback post-crash-report too, unless --keep."]});function cliCommand(){let cli=new Command("cli").description("Operations related to the CLI");return cli.command("get-readme").description("Print the CLI's own README").option("--explain",EXPLAIN).action((_opts,cmd)=>{if(explained(cmd,GET_README_DOC))return;let source=selfReadme();source===void 0&&fail(EXIT.NOT_FOUND,"README_UNAVAILABLE","This build does not carry its README.",{hint:`Read it at https://www.npmjs.com/package/${PACKAGE}.`}),isRaw()?okFile(source):okText(renderMarkdown(source))}),cli.command("settings").description("View or change the CLI's own switches").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,SETTINGS_DOC))return;let globals=cmd.optsWithGlobals(),flagOff={recordApiCalls:globals.recordApiCalls===!1,workspaceLock:globals.lock===!1,localSync:globals.localSync===!1,crashReports:globals.crashReports===!1,agenticFeedback:globals.agenticFeedback===!1};if(!canPrompt()||isRaw()){let states=settingStates(flagOff);ok(states,{human:rows2=>renderTable(rows2.map(settingRow))});return}let before=settingStates(),chosen=new Set(await askSettings()),values=Object.fromEntries(SETTING_KEYS.map(key=>[key,chosen.has(key)]));if(settingsUnchanged(before,values)){prompts().note("Settings unchanged.");return}let forced;try{forced=writeSettings(values)}catch(err){fail(EXIT.API_ERROR,"SETTINGS_WRITE_FAILED",`Could not store the settings: ${describeError(err)}`,{hint:`The file is ${settingsFile()}.`})}for(let key of forced){let state=before.find(candidate=>candidate.key===key);state&&warnLine(`\u26A0 ${state.label} is off because ${state.envVar} is set \u2014 stored as off too.`)}let after=settingStates();okMutation("Settings updated",after,renderTable(after.map(settingRow)))}),cli.command("set-session").description("Remember team/workspace/environment as defaults for this shell session").option("--team <teamId>","Team ID (required, interactive, env SR_CONNECT_CLI_TEAM)").option("-w, --workspace <workspaceId>","Workspace ID (required, interactive, env SR_CONNECT_CLI_WORKSPACE)").option("-e, --env <environmentId>","Environment ID (required, interactive, env SR_CONNECT_CLI_ENVIRONMENT)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,SET_SESSION_DOC))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),labels={},sources={},resolved=await resolveParams(["team","workspace","environment"],{team:opts.team,workspace:opts.workspace,environment:opts.env},{client,interactive:canPrompt(),labels,sources,offerSession:!1,useSession:!1,sessionSkipped:"save-flow"}),teamId=resolved.team??"",workspaceId=resolved.workspace??"",environmentId=resolved.environment??"";if(sources.team!=="picker"||sources.workspace!=="picker"){let{data,response,error:error51}=await withSpinner("Checking the workspace",()=>client.GET("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));response.ok||apiFail(response.status,error51),data?.name&&(labels.workspace=data.name)}if(sources.environment!=="picker"){let{environments}=await withSpinner("Checking the environment",()=>fetchEnvironments(client,workspaceId)),named=environments.find(e=>e.id===environmentId);named?.name&&(labels.environment=named.name),named||fail(EXIT.USAGE,"ENVIRONMENT_MISMATCH",`Environment ${environmentId} is not an environment of workspace ${workspaceId}, so storing the pair would fail every command that read it.`,{hint:`List the workspace's own environments with \`${CLI} environment list -w ${workspaceId}\`.`})}if(sources.team!=="picker"){let{data,response,error:error51}=await withSpinner("Checking the team",()=>client.GET("/v1/team/{teamId}",{params:{path:{teamId}}}));response.ok||apiFail(response.status,error51),data?.name&&(labels.team=data.name)}let record4={team:resolved.team,workspace:workspaceId,environment:environmentId,labels};writeSession(record4);let stored=readSession(),detail=stored?Object.fromEntries(SESSION_KEYS.map(k2=>[k2,describeValue(stored,k2)])):record4;okMutation("Session defaults set",record4,detail)}),cli.command("clear-session").description("Forget the session defaults for this shell session").option("--all","Forget the stored defaults of every shell session, not just this one (optional)").option("--explain",EXPLAIN).action((opts,cmd)=>{if(explained(cmd,CLEAR_SESSION_DOC))return;if(opts.all){let{removed,keptLocks:keptLocks2}=clearAllSessions();noteKeptLocks(keptLocks2),okMutation(removed>0?`Cleared session defaults for ${removed} shell session${removed===1?"":"s"}`:"No session defaults were stored",{cleared:removed>0,sessions:removed,keptLocks:keptLocks2});return}let{cleared,keptLocks}=clearSession();noteKeptLocks(keptLocks),okMutation(cleared?"Session defaults cleared":"No session defaults were set",{cleared,keptLocks})}),cli.command("list-api-logs").description("List the API calls this CLI recorded").option("--session <key>","Read another shell session's recording, see --list-sessions (optional, default: this shell's session, ignored with --all-sessions)").option("--all-sessions","Read every recorded shell session, not just this one (optional)").option("--list-sessions","List the recorded shell sessions instead of the calls (optional)").option("--limit <n>",`Keep the newest N runs, with all their calls; 0 for all (optional, default: ${DEFAULT_RECORDED_LIMIT}, ignored with --list-sessions)`).option("--since <iso>","Only calls at or after the specified ISO time (optional, ignored with --list-sessions)").option("--to <iso>","Only calls at or before the specified ISO time (optional, ignored with --list-sessions)").option("--failed-only","Only calls that returned HTTP >= 400 or never got a response (optional, ignored with --list-sessions)").option("--status <code>","Only calls with this HTTP status (optional, repeatable, ignored with --list-sessions)",collect).option("--method <verb>","Only calls with this HTTP method (optional, ignored with --list-sessions)").option("--path <substring>","Only calls whose URL contains this substring (optional, ignored with --list-sessions)").option("--explain",EXPLAIN).action((opts,cmd)=>{if(explained(cmd,LIST_API_LOGS_DOC))return;if(opts.listSessions){let sessions=listRecordedSessions();ok(sessions,{human:rows2=>rows2.map(row=>({session:row.session,files:row.files,runs:row.runs,calls:row.calls,first:row.first??"",last:row.last??"",size:formatBytes(row.bytes)}))});return}let limit=parseLimit(opts.limit),matched=filterApiCalls(readApiCalls(opts),opts),runs=limit>0?matched.slice(-limit):matched;runs.length===0&&!isRaw()&&noteWhyEmpty(opts);let showSession=!!(opts.allSessions||opts.session);ok(runs,{human:rows2=>renderApiCallRuns(rows2,showSession)})}),cli.command("clear-api-logs").description("Delete recorded API calls").option("--session <key>","Clear another shell session's recording (optional, default: this shell's session, ignored with --all-sessions)").option("--all-sessions","Clear every recorded shell session, not just this one (optional)").option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CLEAR_API_LOGS_DOC))return;let targets=recordedTargets(opts),bytes=targets.reduce((total,summary)=>total+summary.bytes,0),files=targets.reduce((total,summary)=>total+summary.files,0);!opts.yes&&targets.length>0&&(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED","Deleting recorded API calls is irreversible. Re-run with --yes to confirm."),await prompts().confirm(`Delete the recorded API calls of ${targets.length} shell session${targets.length===1?"":"s"} (${formatBytes(bytes)})? This is irreversible.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled."));let removed=clearApiCalls(opts);okMutation(removed.length>0?`Cleared recorded API calls for ${removed.length} shell session${removed.length===1?"":"s"}`:"No recorded API calls were stored",{deleted:removed.length>0,files,sessions:removed})}),cli.command("list-crash-reports").description("List the crash reports this CLI stored").option("--explain",EXPLAIN).action((_opts,cmd)=>{if(explained(cmd,LIST_CRASH_REPORTS_DOC))return;let reports=listCrashReports();reports.length===0&&!isRaw()&&prompts().note("No crash reports stored \u2014 one is written when a run fails unexpectedly or the API answers 5xx, unless --no-crash-reports or SR_CONNECT_CLI_NO_CRASH_REPORTS turned that off."),ok(reports,{human:rows2=>renderTable(rows2.map(crashRow))})}),cli.command("get-crash-report").description("Read one stored crash report").option("--report <id>",`The crash report to print, see ${CLI} cli list-crash-reports (optional, interactive, default: the newest one)`).option("--content-only","Print the report as markdown, with no rendering or JSON envelope (optional)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,GET_CRASH_REPORT_DOC))return;let report=await resolveCrashReport(opts.report,"Which crash report do you want to read?");if(opts.contentOnly){okFile(report.markdown);return}ok(report,{human:data=>renderMarkdown(stripCrashHeader(data.markdown))})}),cli.command("clear-crash-reports").description("Delete stored crash reports").option("--report <id>","The crash report to delete (optional, default: every stored report)").option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CLEAR_CRASH_REPORTS_DOC))return;let targets=listCrashReports().filter(report=>opts.report===void 0||report.id===opts.report),bytes=targets.reduce((total,report)=>total+report.bytes,0);!opts.yes&&targets.length>0&&(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED","Deleting crash reports is irreversible. Re-run with --yes to confirm."),await prompts().confirm(`Delete ${targets.length} crash report${targets.length===1?"":"s"} (${formatBytes(bytes)})? This is irreversible \u2014 nothing has been sent.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled."));let removed=clearCrashReports(opts.report);okMutation(removed.length>0?`Deleted ${removed.length} crash report${removed.length===1?"":"s"}`:"No crash reports were stored",{deleted:removed.length>0,reports:removed})}),cli.command("simulate-server-error",{hidden:!0}).description("Make a request that really fails, to exercise the crash-report path").option("--status <code>","HTTP status the simulated API answers with (optional, default: 500)").option("--body <json>",'Response body the simulated API answers with (optional, default: {"message":"Internal server error"})').option("--calls <n>","How many requests to make, the last one failing (optional, default: 1)").action(async opts=>{let status=wholeNumber(opts.status,500,"--status",100,599),calls=wholeNumber(opts.calls,1,"--calls",1,50),body=opts.body??'{"message":"Internal server error"}',seen=0,server=createServer((_request,response)=>{seen+=1;let last=seen>=calls;response.writeHead(last?status:200,{"content-type":"application/json"}),response.end(last?body:"{}")});await new Promise(resolve8=>server.listen(0,"127.0.0.1",resolve8));let address=server.address(),port=typeof address=="object"&&address!==null?address.port:0,client=createClient({baseUrl:`http://127.0.0.1:${port}`,headers:identityHeaders(),fetch:fetchWithRetry});try{let result=await withSpinner("Simulating a server error",async()=>{let last=await client.GET("/v1/serviceInfo",{});for(let call=1;call<calls;call+=1)last=await client.GET("/v1/serviceInfo",{});return last});(!result.response.ok||!result.data)&&apiFail(result.response.status,result.error),okMutation("Simulated server response",{simulated:!0,status:result.response.status,calls})}finally{server.closeAllConnections(),await new Promise(resolve8=>server.close(()=>resolve8()))}}),cli.command("simulate-cli-error",{hidden:!0}).description("Throw an unexpected client-side error, to exercise the crash-report path").option("--message <text>","Message the simulated failure carries (optional, default: Simulated client-side failure)").option("--async","Throw from inside an awaited helper rather than a synchronous one (optional)").action(async opts=>{let message=opts.message??"Simulated client-side failure";opts.async&&await throwLater(message),throwNow(message)}),cli}function wholeNumber(value,fallback,flag,min,max){if(value===void 0)return fallback;let parsed=Number(value);return(!Number.isInteger(parsed)||parsed<min||parsed>max)&&fail(EXIT.USAGE,"INVALID_ARGUMENT",`${flag} must be a whole number between ${min} and ${max}.`),parsed}function throwNow(message){throw new TypeError(message,{cause:Object.assign(new Error("socket hang up"),{code:"ECONNRESET"})})}async function throwLater(message){await Promise.resolve(),throwNow(message)}var shareBodySchema=external_exports.object({edit:external_exports.boolean(),use:external_exports.object({permission:external_exports.boolean(),scope:external_exports.enum(["ALL_TEAMS","SPECIFIC_TEAMS"]).optional(),teamIds:external_exports.array(external_exports.string().min(1)).optional()}).strict().refine(use=>!use.permission||use.scope!==void 0,{message:"use.scope is required when use.permission is true."}).refine(use=>use.permission||use.scope===void 0&&use.teamIds===void 0,{message:"use.scope and use.teamIds are only valid when use.permission is true."}).refine(use=>use.scope!=="SPECIFIC_TEAMS"||use.teamIds!==void 0&&use.teamIds.length>0,{message:"use.teamIds must contain at least one team when use.scope is SPECIFIC_TEAMS."}).refine(use=>use.scope!=="ALL_TEAMS"||use.teamIds===void 0,{message:"use.teamIds cannot be provided when use.scope is ALL_TEAMS."})}).strict().refine(body=>body.edit||body.use.permission,{message:"At least one permission must be granted \u2014 use `connector-sharing remove` to revoke access."}),LIST_DOC2=defineCommandDoc("connector-sharing list",{rules:["The connector is --connector-id and the team is --team; there is no positional argument, the verb listing every share."],notes:["Everyone the connector is shared with, the owner included. A narrowed use permission shows as a count of teams here; get names them."]}),GET_DOC2=defineCommandDoc("connector-sharing get",{rules:["The user is the positional argument; the connector is --connector-id and the team is --team."],notes:["A single user's permissions, with the teams a narrowed use permission covers and every team it could cover.",`Your own user ID is refused here (403 "User cannot share connector with themselves."). The owner's own entry is readable through list alone.`]}),ASSIGNABLE_DOC=defineCommandDoc("connector-sharing list-assignable-users",{rules:["The connector is --connector-id and the team is --team; there is no positional argument."],notes:["The users the connector can still be shared with, each with the teams you have in common. Anyone already holding a permission is excluded, so an empty list means everyone already has some access."]}),REMOVE_DOC=defineCommandDoc("connector-sharing remove",{rules:["The user is the positional argument; the connector is --connector-id and the team is --team.","--dry-run reports what revoking their access would detach and commits nothing, the same flag set takes and the way to see the cost before paying it.","--yes skips the confirmation, and is required without a terminal."],notes:["Revokes all access at once; there is no partial removal here, which is what set is for.","API connections and event listeners the user attached the connector to are detached, in workspaces you are not a member of included, and are listed before the confirmation. Granting access back does not re-attach them.",'The document is {"deleted":true,"id":\u2026,"userId":\u2026,"connectorId":\u2026}: id is the user, the resource the verb acted on, and userId says so. set answers the same three keys under updated.']}),SET_DOC=defineCommandDoc("connector-sharing set",{schema:shareBodySchema,body:{edit:!1,use:{permission:!0,scope:"SPECIFIC_TEAMS",teamIds:["<teamId>"]}},rules:["edit (--edit as a flag): true lets the user rename the connector and replace its credentials, in every team; it never lets them delete it.","use.permission: true lets the user attach the connector to API connections and event listeners; use.scope is then required.","use.scope: ALL_TEAMS covers every team you share with the user, including teams they join later, and use.teamIds must then be absent (--use-all-teams as a flag); SPECIFIC_TEAMS needs use.teamIds naming at least one team both of you are members of (--use-team <teamId>, repeatable). The use block has no flag of its own: which of those two was passed is what implies the scope.","use.scope and use.teamIds are refused when use.permission is false.",`At least one of edit or use.permission must be true; access is revoked with ${CLI} connector-sharing remove.`,"The body is the whole permission set and both keys are required: edit false and use.permission false revoke, rather than being left as they are, and losing or narrowing use detaches the connector from that user's workspaces in the teams it no longer covers.","Only the connector's owner can share it, and never with themselves. The user is the positional argument and the connector is --connector-id; neither is a body key.","--dry-run, a flag rather than a key, reports what the body would detach and commits nothing."],notes:['The document is {"updated":true,"id":\u2026,"userId":\u2026,"connectorId":\u2026}: id is the user here, the resource the verb acted on, and userId says so. remove answers the same three keys under deleted.']});async function resolveScope2(globals,opts={}){let client=await apiClient(globals.instance),resolved=await resolveParams(["team"],{team:globals.team},{client,interactive:canPrompt(),useSession:opts.useSession});return{client,team:resolved.team??""}}async function resolveTarget(scope2,provided){if(provided)return{...scope2,connector:assertResourceId(provided,"--connector-id")};canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR","--connector-id is required.");let labels={},resolved=await resolveParams(["ownedConnector"],{team:scope2.team},{client:scope2.client,interactive:!0,labels});return{...scope2,connector:resolved.ownedConnector??"",...labels.ownedConnector?{connectorLabel:labels.ownedConnector}:{}}}function shareFail(status,error51){let message=error51?.errorMessage??"";status===404&&/connector not found/i.test(message)&&fail(EXIT.NOT_FOUND,"NOT_FOUND",message,{status,hint:`The connector-sharing verbs are the owner's alone, so a connector you do not own reads as missing here \u2014 ${CLI} connector list shows the ones you can see, with the owner of each.`}),apiFail(status,error51)}var sharesCache=new WeakMap;async function fetchShares(target){let perConnector=sharesCache.get(target.client);perConnector||sharesCache.set(target.client,perConnector=new Map);let key=`${target.team}/${target.connector}`,cached2=perConnector.get(key);return cached2||(cached2=withSpinner("Fetching connector sharing",async()=>{let{data,response,error:error51}=await target.client.GET("/v1/team/{teamId}/connector/{connectorId}/shares",{params:{path:{teamId:target.team,connectorId:target.connector}}});return(!response.ok||!data)&&shareFail(response.status,error51),data.shares}),cached2.catch(()=>perConnector.delete(key)),perConnector.set(key,cached2)),cached2}async function fetchShare(target,userId){let{data,error:error51,response}=await withSpinner("Fetching connector share",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params:{path:{teamId:target.team,connectorId:target.connector,userId}}}));return response.ok&&data?{share:data,status:response.status}:{status:response.status,error:error51}}async function fetchAssignableMembers(target){let{data,response,error:error51}=await withSpinner("Fetching assignable members",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/assignableMembers",{params:{path:{teamId:target.team,connectorId:target.connector}}}));return(!response.ok||!data)&&shareFail(response.status,error51),data.members}function userName(user){return personName(user)||"that user"}function useCell(permissions,teams=[]){let use=permissions.use;if(!use.permission)return"no";if(use.scope==="ALL_TEAMS")return"all teams";if(use.teamIds.length===0)return"no teams";let named=use.teamIds.map(id=>teams.find(t=>t.id===id)?.name).filter(name=>!!name);return named.length===use.teamIds.length?named.join(", "):`${use.teamIds.length} team${use.teamIds.length===1?"":"s"}`}function humanShare(share){return{user:personCell(share.user),email:share.user.email,owner:share.owner?"yes":"no",edit:share.permissions.edit?"yes":"no",use:useCell(share.permissions)}}function reducesAccess(current,next){if(!current)return!1;if(current.edit&&!next.edit)return!0;let had=current.use,gets=next.use;if(!had.permission)return!1;if(!gets.permission)return!0;if(had.scope==="ALL_TEAMS")return gets.scope!=="ALL_TEAMS";let kept=new Set(gets.scope==="ALL_TEAMS"?[]:gets.teamIds??[]);return gets.scope!=="ALL_TEAMS"&&had.teamIds.some(id=>!kept.has(id))}function sameAsCurrent(current,next){if(!current||current.edit!==next.edit||current.use.permission!==next.use.permission)return!1;if(!next.use.permission)return!0;if(current.use.scope!==next.use.scope)return!1;if(next.use.scope==="ALL_TEAMS")return!0;let before=[...current.use.teamIds].sort(),after=[...next.use.teamIds??[]].sort();return before.length===after.length&&before.every((id,i)=>id===after[i])}function detachRows(impact){return impact.detaches.map(entry2=>({workspace:`${entry2.workspace.name} (${entry2.workspace.id})`,team:`${entry2.team.name} (${entry2.team.id})`,apiConnections:entry2.apiConnections,eventListeners:entry2.eventListeners}))}function humanImpact(impact){return{effect:impact.effect,...impact.detaches.length>0?{detaches:detachRows(impact)}:{detaches:"nothing would be detached"}}}function impactNote(impact){let rows2=detachRows(impact).map(row=>` ${row.workspace} \xB7 ${row.team} \xB7 ${row.apiConnections} API connection(s), ${row.eventListeners} event listener(s)`).join(`
1329
+ `)}`)}var GET_README_DOC=defineCommandDoc("cli get-readme",{rules:["No parameters: it prints the README of the installed package."],notes:["Rendered for the terminal in human mode, the markdown source under --raw.","Needs no credentials and no instance, like every verb in this group but set-session.","It is orientation, not per-verb reference: what a verb takes is --explain on that verb."]}),SETTINGS_DOC=defineCommandDoc("cli settings",{rules:["No parameters: there is no flag that sets a switch, and a scripted run is read-only."],notes:["The five stored switches with their current state and which source decided it: flag, env, stored or default.","On a terminal without --raw, one multiselect changes them. Under --raw the command is read-only \u2014 the one place --raw suppresses a question, because there the table is the answer a scripted run wants.","Only the offs are stored, in a file that survives cli clear-session and auth logout. A switch disabled by its environment variable cannot be toggled and is written as off.","Answers that change nothing make no request at all \u2014 this verb never makes one."]}),SET_SESSION_DOC=defineCommandDoc("cli set-session",{rules:["The team is --team, the workspace -w and the environment -e. They carry no session default here, this verb being the save flow itself, though the scope environment variables still pre-fill."],notes:["Remembers all three as this shell's defaults, for 12 hours and for one instance.","A typed -e is checked against the workspace first, one request, and an environment belonging to another workspace is exit 2 ENVIRONMENT_MISMATCH \u2014 the pair would otherwise be stored and fail every command that read it.",`The document carries the three IDs and a labels object holding each one's name, which the checks above already read; every later command's "Using session defaults: \u2026" line reads those names, so a record written here announces itself the same way a picked one does.`,"Where the shell cannot be identified, in a container step for example, set SR_CONNECT_CLI_SESSION_ID."]}),CLEAR_SESSION_DOC=defineCommandDoc("cli clear-session",{rules:["--all forgets every shell's record rather than this one's."],notes:["A workspace lock rides the same record but is not a default, so clearing the scope keeps it: a clear that leaves one names the lock and the command that gives it back."]}),LIST_API_LOGS_DOC=defineCommandDoc("cli list-api-logs",{rules:["--limit counts runs rather than calls, default 20, 0 for all; a run is never cut in half.","--session reads another shell's recording, --all-sessions reads them all, and --list-sessions lists the recorded shells instead and ignores every filter.","--since and --to take an ISO instant or a startTime exactly as printed in log results.","--status repeats, and filters by the HTTP status the call answered with.","--method filters by HTTP method and --path by a substring of the URL; --failed-only keeps the calls that answered 400 or above and the ones that never answered at all. All three are ignored with --list-sessions, as every filter here is."],notes:["Runs of this shell, newest first, each with its calls. Needs no credentials, which is what makes it readable when authentication is the thing that broke.","Secrets are redacted at record time, so what is stored is what is printed."]}),CLEAR_API_LOGS_DOC=defineCommandDoc("cli clear-api-logs",{rules:["--session names another shell's recording to delete, spelled as cli list-api-logs --list-sessions reports it; omitted, this shell's own is the one cleared.","--all-sessions deletes every shell's recording rather than this one's."],notes:["Recording is on unless --no-record-api-calls or the stored switch turns it off; deleting does not turn it off."]}),LIST_CRASH_REPORTS_DOC=defineCommandDoc("cli list-crash-reports",{rules:["No parameters: it lists what is stored."],notes:["Newest first: the run ID, when, the command, the kind and the size.","The store keeps 7 days and the newest 20, pruned on write."]}),GET_CRASH_REPORT_DOC=defineCommandDoc("cli get-crash-report",{rules:["--report names a report by its run ID; omitted, the newest is read.","--content-only prints the markdown verbatim, identically in both modes."],notes:["A report carries the metadata, the stack and the API calls that run recorded, composed against a 512 KB budget."]}),CLEAR_CRASH_REPORTS_DOC=defineCommandDoc("cli clear-crash-reports",{rules:["--report deletes a single report by its run ID; omitted, every stored report goes."],notes:["A report is deleted on a successful feedback post-crash-report too, unless --keep."]}),CHECK_UPDATES_DOC=defineCommandDoc("cli check-updates",{rules:["No parameters: it reads the NPM registry now."],notes:["The answer is live. The notice an ordinary run prints comes from a lookup an earlier run made, at most one per shell every twelve hours; this verb asks every time.","Exit 0 whether or not there is a newer version, updateAvailable being the answer. A registry that cannot be read is exit 1, and one that publishes no release of the package is exit 4.","The update command printed is derived from how this copy was installed: a global install is told to reinstall globally, one run through npx is told to run npx.","Prereleases are never offered.","--no-update-check silences the automatic notice and does not apply here, asking being the whole command. SR_CONNECT_CLI_NPM_REGISTRY points the lookup at another registry."]});function cliCommand(){let cli=new Command("cli").description("Operations related to the CLI");return cli.command("get-readme").description("Print the CLI's own README").option("--explain",EXPLAIN).action((_opts,cmd)=>{if(explained(cmd,GET_README_DOC))return;let source=selfReadme();source===void 0&&fail(EXIT.NOT_FOUND,"README_UNAVAILABLE","This build does not carry its README.",{hint:`Read it at https://www.npmjs.com/package/${PACKAGE}.`}),isRaw()?okFile(source):okText(renderMarkdown(source))}),cli.command("check-updates").description("Check the NPM registry for a newer version of this CLI").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,CHECK_UPDATES_DOC))return;let status=await withSpinner("Checking the NPM registry",()=>checkForUpdate());status.state==="unpublished"&&fail(EXIT.NOT_FOUND,"NPM_PACKAGE_NOT_FOUND",`The NPM registry publishes no release of ${PACKAGE}.`,{hint:"SR_CONNECT_CLI_NPM_REGISTRY points the lookup at another registry; unset it to ask NPM itself."}),status.state==="unreachable"&&fail(EXIT.API_ERROR,"NPM_LOOKUP_FAILED",`Could not read ${registryBase()}.`,{hint:"Check the network and any proxy; SR_CONNECT_CLI_NPM_REGISTRY points the lookup at another registry."});let payload=status.state==="available"?{command:status.notice.command,current:status.notice.current,latest:status.notice.latest,updateAvailable:!0}:{current:status.current,latest:status.latest,updateAvailable:!1};ok(payload,{human:()=>import_picocolors8.default.green(renderUpdateLine(status))})}),cli.command("settings").description("View or change the CLI's own switches").option("--explain",EXPLAIN).action(async(_opts,cmd)=>{if(explained(cmd,SETTINGS_DOC))return;let globals=cmd.optsWithGlobals(),flagOff={recordApiCalls:globals.recordApiCalls===!1,workspaceLock:globals.lock===!1,localSync:globals.localSync===!1,crashReports:globals.crashReports===!1,agenticFeedback:globals.agenticFeedback===!1};if(!canPrompt()||isRaw()){let states=settingStates(flagOff);ok(states,{human:rows2=>renderTable(rows2.map(settingRow))});return}let before=settingStates(),chosen=new Set(await askSettings()),values=Object.fromEntries(SETTING_KEYS.map(key=>[key,chosen.has(key)]));if(settingsUnchanged(before,values)){prompts().note("Settings unchanged.");return}let forced;try{forced=writeSettings(values)}catch(err){fail(EXIT.API_ERROR,"SETTINGS_WRITE_FAILED",`Could not store the settings: ${describeError(err)}`,{hint:`The file is ${settingsFile()}.`})}for(let key of forced){let state=before.find(candidate=>candidate.key===key);state&&warnLine(`\u26A0 ${state.label} is off because ${state.envVar} is set \u2014 stored as off too.`)}let after=settingStates();okMutation("Settings updated",after,renderTable(after.map(settingRow)))}),cli.command("set-session").description("Remember team/workspace/environment as defaults for this shell session").option("--team <teamId>","Team ID (required, interactive, env SR_CONNECT_CLI_TEAM)").option("-w, --workspace <workspaceId>","Workspace ID (required, interactive, env SR_CONNECT_CLI_WORKSPACE)").option("-e, --env <environmentId>","Environment ID (required, interactive, env SR_CONNECT_CLI_ENVIRONMENT)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,SET_SESSION_DOC))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),labels={},sources={},resolved=await resolveParams(["team","workspace","environment"],{team:opts.team,workspace:opts.workspace,environment:opts.env},{client,interactive:canPrompt(),labels,sources,offerSession:!1,useSession:!1,sessionSkipped:"save-flow"}),teamId=resolved.team??"",workspaceId=resolved.workspace??"",environmentId=resolved.environment??"";if(sources.team!=="picker"||sources.workspace!=="picker"){let{data,response,error:error51}=await withSpinner("Checking the workspace",()=>client.GET("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));response.ok||apiFail(response.status,error51),data?.name&&(labels.workspace=data.name)}if(sources.environment!=="picker"){let{environments}=await withSpinner("Checking the environment",()=>fetchEnvironments(client,workspaceId)),named=environments.find(e=>e.id===environmentId);named?.name&&(labels.environment=named.name),named||fail(EXIT.USAGE,"ENVIRONMENT_MISMATCH",`Environment ${environmentId} is not an environment of workspace ${workspaceId}, so storing the pair would fail every command that read it.`,{hint:`List the workspace's own environments with \`${CLI} environment list -w ${workspaceId}\`.`})}if(sources.team!=="picker"){let{data,response,error:error51}=await withSpinner("Checking the team",()=>client.GET("/v1/team/{teamId}",{params:{path:{teamId}}}));response.ok||apiFail(response.status,error51),data?.name&&(labels.team=data.name)}let record4={team:resolved.team,workspace:workspaceId,environment:environmentId,labels};writeSession(record4);let stored=readSession(),detail=stored?Object.fromEntries(SESSION_KEYS.map(k2=>[k2,describeValue(stored,k2)])):record4;okMutation("Session defaults set",record4,detail)}),cli.command("clear-session").description("Forget the session defaults for this shell session").option("--all","Forget the stored defaults of every shell session, not just this one (optional)").option("--explain",EXPLAIN).action((opts,cmd)=>{if(explained(cmd,CLEAR_SESSION_DOC))return;if(opts.all){let{removed,keptLocks:keptLocks2}=clearAllSessions();noteKeptLocks(keptLocks2),okMutation(removed>0?`Cleared session defaults for ${removed} shell session${removed===1?"":"s"}`:"No session defaults were stored",{cleared:removed>0,sessions:removed,keptLocks:keptLocks2});return}let{cleared,keptLocks}=clearSession();noteKeptLocks(keptLocks),okMutation(cleared?"Session defaults cleared":"No session defaults were set",{cleared,keptLocks})}),cli.command("list-api-logs").description("List the API calls this CLI recorded").option("--session <key>","Read another shell session's recording, see --list-sessions (optional, default: this shell's session, ignored with --all-sessions)").option("--all-sessions","Read every recorded shell session, not just this one (optional)").option("--list-sessions","List the recorded shell sessions instead of the calls (optional)").option("--limit <n>",`Keep the newest N runs, with all their calls; 0 for all (optional, default: ${DEFAULT_RECORDED_LIMIT}, ignored with --list-sessions)`).option("--since <iso>","Only calls at or after the specified ISO time (optional, ignored with --list-sessions)").option("--to <iso>","Only calls at or before the specified ISO time (optional, ignored with --list-sessions)").option("--failed-only","Only calls that returned HTTP >= 400 or never got a response (optional, ignored with --list-sessions)").option("--status <code>","Only calls with this HTTP status (optional, repeatable, ignored with --list-sessions)",collect).option("--method <verb>","Only calls with this HTTP method (optional, ignored with --list-sessions)").option("--path <substring>","Only calls whose URL contains this substring (optional, ignored with --list-sessions)").option("--explain",EXPLAIN).action((opts,cmd)=>{if(explained(cmd,LIST_API_LOGS_DOC))return;if(opts.listSessions){let sessions=listRecordedSessions();ok(sessions,{human:rows2=>rows2.map(row=>({session:row.session,files:row.files,runs:row.runs,calls:row.calls,first:row.first??"",last:row.last??"",size:formatBytes(row.bytes)}))});return}let limit=parseLimit(opts.limit),matched=filterApiCalls(readApiCalls(opts),opts),runs=limit>0?matched.slice(-limit):matched;runs.length===0&&!isRaw()&&noteWhyEmpty(opts);let showSession=!!(opts.allSessions||opts.session);ok(runs,{human:rows2=>renderApiCallRuns(rows2,showSession)})}),cli.command("clear-api-logs").description("Delete recorded API calls").option("--session <key>","Clear another shell session's recording (optional, default: this shell's session, ignored with --all-sessions)").option("--all-sessions","Clear every recorded shell session, not just this one (optional)").option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CLEAR_API_LOGS_DOC))return;let targets=recordedTargets(opts),bytes=targets.reduce((total,summary)=>total+summary.bytes,0),files=targets.reduce((total,summary)=>total+summary.files,0);!opts.yes&&targets.length>0&&(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED","Deleting recorded API calls is irreversible. Re-run with --yes to confirm."),await prompts().confirm(`Delete the recorded API calls of ${targets.length} shell session${targets.length===1?"":"s"} (${formatBytes(bytes)})? This is irreversible.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled."));let removed=clearApiCalls(opts);okMutation(removed.length>0?`Cleared recorded API calls for ${removed.length} shell session${removed.length===1?"":"s"}`:"No recorded API calls were stored",{deleted:removed.length>0,files,sessions:removed})}),cli.command("list-crash-reports").description("List the crash reports this CLI stored").option("--explain",EXPLAIN).action((_opts,cmd)=>{if(explained(cmd,LIST_CRASH_REPORTS_DOC))return;let reports=listCrashReports();reports.length===0&&!isRaw()&&prompts().note("No crash reports stored \u2014 one is written when a run fails unexpectedly or the API answers 5xx, unless --no-crash-reports or SR_CONNECT_CLI_NO_CRASH_REPORTS turned that off."),ok(reports,{human:rows2=>renderTable(rows2.map(crashRow))})}),cli.command("get-crash-report").description("Read one stored crash report").option("--report <id>",`The crash report to print, see ${CLI} cli list-crash-reports (optional, interactive, default: the newest one)`).option("--content-only","Print the report as markdown, with no rendering or JSON envelope (optional)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,GET_CRASH_REPORT_DOC))return;let report=await resolveCrashReport(opts.report,"Which crash report do you want to read?");if(opts.contentOnly){okFile(report.markdown);return}ok(report,{human:data=>renderMarkdown(stripCrashHeader(data.markdown))})}),cli.command("clear-crash-reports").description("Delete stored crash reports").option("--report <id>","The crash report to delete (optional, default: every stored report)").option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CLEAR_CRASH_REPORTS_DOC))return;let targets=listCrashReports().filter(report=>opts.report===void 0||report.id===opts.report),bytes=targets.reduce((total,report)=>total+report.bytes,0);!opts.yes&&targets.length>0&&(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED","Deleting crash reports is irreversible. Re-run with --yes to confirm."),await prompts().confirm(`Delete ${targets.length} crash report${targets.length===1?"":"s"} (${formatBytes(bytes)})? This is irreversible \u2014 nothing has been sent.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled."));let removed=clearCrashReports(opts.report);okMutation(removed.length>0?`Deleted ${removed.length} crash report${removed.length===1?"":"s"}`:"No crash reports were stored",{deleted:removed.length>0,reports:removed})}),cli.command("simulate-server-error",{hidden:!0}).description("Make a request that really fails, to exercise the crash-report path").option("--status <code>","HTTP status the simulated API answers with (optional, default: 500)").option("--body <json>",'Response body the simulated API answers with (optional, default: {"message":"Internal server error"})').option("--calls <n>","How many requests to make, the last one failing (optional, default: 1)").action(async opts=>{let status=wholeNumber(opts.status,500,"--status",100,599),calls=wholeNumber(opts.calls,1,"--calls",1,50),body=opts.body??'{"message":"Internal server error"}',seen=0,server=createServer((_request,response)=>{seen+=1;let last=seen>=calls;response.writeHead(last?status:200,{"content-type":"application/json"}),response.end(last?body:"{}")});await new Promise(resolve8=>server.listen(0,"127.0.0.1",resolve8));let address=server.address(),port=typeof address=="object"&&address!==null?address.port:0,client=createClient({baseUrl:`http://127.0.0.1:${port}`,headers:identityHeaders(),fetch:fetchWithRetry});try{let result=await withSpinner("Simulating a server error",async()=>{let last=await client.GET("/v1/serviceInfo",{});for(let call=1;call<calls;call+=1)last=await client.GET("/v1/serviceInfo",{});return last});(!result.response.ok||!result.data)&&apiFail(result.response.status,result.error),okMutation("Simulated server response",{simulated:!0,status:result.response.status,calls})}finally{server.closeAllConnections(),await new Promise(resolve8=>server.close(()=>resolve8()))}}),cli.command("simulate-cli-error",{hidden:!0}).description("Throw an unexpected client-side error, to exercise the crash-report path").option("--message <text>","Message the simulated failure carries (optional, default: Simulated client-side failure)").option("--async","Throw from inside an awaited helper rather than a synchronous one (optional)").action(async opts=>{let message=opts.message??"Simulated client-side failure";opts.async&&await throwLater(message),throwNow(message)}),cli}function wholeNumber(value,fallback,flag,min,max){if(value===void 0)return fallback;let parsed=Number(value);return(!Number.isInteger(parsed)||parsed<min||parsed>max)&&fail(EXIT.USAGE,"INVALID_ARGUMENT",`${flag} must be a whole number between ${min} and ${max}.`),parsed}function throwNow(message){throw new TypeError(message,{cause:Object.assign(new Error("socket hang up"),{code:"ECONNRESET"})})}async function throwLater(message){await Promise.resolve(),throwNow(message)}var shareBodySchema=external_exports.object({edit:external_exports.boolean(),use:external_exports.object({permission:external_exports.boolean(),scope:external_exports.enum(["ALL_TEAMS","SPECIFIC_TEAMS"]).optional(),teamIds:external_exports.array(external_exports.string().min(1)).optional()}).strict().refine(use=>!use.permission||use.scope!==void 0,{message:"use.scope is required when use.permission is true."}).refine(use=>use.permission||use.scope===void 0&&use.teamIds===void 0,{message:"use.scope and use.teamIds are only valid when use.permission is true."}).refine(use=>use.scope!=="SPECIFIC_TEAMS"||use.teamIds!==void 0&&use.teamIds.length>0,{message:"use.teamIds must contain at least one team when use.scope is SPECIFIC_TEAMS."}).refine(use=>use.scope!=="ALL_TEAMS"||use.teamIds===void 0,{message:"use.teamIds cannot be provided when use.scope is ALL_TEAMS."})}).strict().refine(body=>body.edit||body.use.permission,{message:"At least one permission must be granted \u2014 use `connector-sharing remove` to revoke access."}),LIST_DOC2=defineCommandDoc("connector-sharing list",{rules:["The connector is --connector-id and the team is --team; there is no positional argument, the verb listing every share."],notes:["Everyone the connector is shared with, the owner included. A narrowed use permission shows as a count of teams here; get names them."]}),GET_DOC2=defineCommandDoc("connector-sharing get",{rules:["The user is the positional argument; the connector is --connector-id and the team is --team."],notes:["A single user's permissions, with the teams a narrowed use permission covers and every team it could cover.",`Your own user ID is refused here (403 "User cannot share connector with themselves."). The owner's own entry is readable through list alone.`]}),ASSIGNABLE_DOC=defineCommandDoc("connector-sharing list-assignable-users",{rules:["The connector is --connector-id and the team is --team; there is no positional argument."],notes:["The users the connector can still be shared with, each with the teams you have in common. Anyone already holding a permission is excluded, so an empty list means everyone already has some access."]}),REMOVE_DOC=defineCommandDoc("connector-sharing remove",{rules:["The user is the positional argument; the connector is --connector-id and the team is --team.","--dry-run reports what revoking their access would detach and commits nothing, the same flag set takes and the way to see the cost before paying it.","--yes skips the confirmation, and is required without a terminal."],notes:["Revokes all access at once; there is no partial removal here, which is what set is for.","API connections and event listeners the user attached the connector to are detached, in workspaces you are not a member of included, and are listed before the confirmation. Granting access back does not re-attach them.",'The document is {"deleted":true,"id":\u2026,"userId":\u2026,"connectorId":\u2026}: id is the user, the resource the verb acted on, and userId says so. set answers the same three keys under updated.']}),SET_DOC=defineCommandDoc("connector-sharing set",{schema:shareBodySchema,body:{edit:!1,use:{permission:!0,scope:"SPECIFIC_TEAMS",teamIds:["<teamId>"]}},rules:["edit (--edit as a flag): true lets the user rename the connector and replace its credentials, in every team; it never lets them delete it.","use.permission: true lets the user attach the connector to API connections and event listeners; use.scope is then required.","use.scope: ALL_TEAMS covers every team you share with the user, including teams they join later, and use.teamIds must then be absent (--use-all-teams as a flag); SPECIFIC_TEAMS needs use.teamIds naming at least one team both of you are members of (--use-team <teamId>, repeatable). The use block has no flag of its own: which of those two was passed is what implies the scope.","use.scope and use.teamIds are refused when use.permission is false.",`At least one of edit or use.permission must be true; access is revoked with ${CLI} connector-sharing remove.`,"The body is the whole permission set and both keys are required: edit false and use.permission false revoke, rather than being left as they are, and losing or narrowing use detaches the connector from that user's workspaces in the teams it no longer covers.","Only the connector's owner can share it, and never with themselves. The user is the positional argument and the connector is --connector-id; neither is a body key.","--dry-run, a flag rather than a key, reports what the body would detach and commits nothing."],notes:['The document is {"updated":true,"id":\u2026,"userId":\u2026,"connectorId":\u2026}: id is the user here, the resource the verb acted on, and userId says so. remove answers the same three keys under deleted.']});async function resolveScope2(globals,opts={}){let client=await apiClient(globals.instance),resolved=await resolveParams(["team"],{team:globals.team},{client,interactive:canPrompt(),useSession:opts.useSession});return{client,team:resolved.team??""}}async function resolveTarget(scope2,provided){if(provided)return{...scope2,connector:assertResourceId(provided,"--connector-id")};canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR","--connector-id is required.");let labels={},resolved=await resolveParams(["ownedConnector"],{team:scope2.team},{client:scope2.client,interactive:!0,labels});return{...scope2,connector:resolved.ownedConnector??"",...labels.ownedConnector?{connectorLabel:labels.ownedConnector}:{}}}function shareFail(status,error51){let message=error51?.errorMessage??"";status===404&&/connector not found/i.test(message)&&fail(EXIT.NOT_FOUND,"NOT_FOUND",message,{status,hint:`The connector-sharing verbs are the owner's alone, so a connector you do not own reads as missing here \u2014 ${CLI} connector list shows the ones you can see, with the owner of each.`}),apiFail(status,error51)}var sharesCache=new WeakMap;async function fetchShares(target){let perConnector=sharesCache.get(target.client);perConnector||sharesCache.set(target.client,perConnector=new Map);let key=`${target.team}/${target.connector}`,cached2=perConnector.get(key);return cached2||(cached2=withSpinner("Fetching connector sharing",async()=>{let{data,response,error:error51}=await target.client.GET("/v1/team/{teamId}/connector/{connectorId}/shares",{params:{path:{teamId:target.team,connectorId:target.connector}}});return(!response.ok||!data)&&shareFail(response.status,error51),data.shares}),cached2.catch(()=>perConnector.delete(key)),perConnector.set(key,cached2)),cached2}async function fetchShare(target,userId){let{data,error:error51,response}=await withSpinner("Fetching connector share",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params:{path:{teamId:target.team,connectorId:target.connector,userId}}}));return response.ok&&data?{share:data,status:response.status}:{status:response.status,error:error51}}async function fetchAssignableMembers(target){let{data,response,error:error51}=await withSpinner("Fetching assignable members",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/assignableMembers",{params:{path:{teamId:target.team,connectorId:target.connector}}}));return(!response.ok||!data)&&shareFail(response.status,error51),data.members}function userName(user){return personName(user)||"that user"}function useCell(permissions,teams=[]){let use=permissions.use;if(!use.permission)return"no";if(use.scope==="ALL_TEAMS")return"all teams";if(use.teamIds.length===0)return"no teams";let named=use.teamIds.map(id=>teams.find(t=>t.id===id)?.name).filter(name=>!!name);return named.length===use.teamIds.length?named.join(", "):`${use.teamIds.length} team${use.teamIds.length===1?"":"s"}`}function humanShare(share){return{user:personCell(share.user),email:share.user.email,owner:share.owner?"yes":"no",edit:share.permissions.edit?"yes":"no",use:useCell(share.permissions)}}function reducesAccess(current,next){if(!current)return!1;if(current.edit&&!next.edit)return!0;let had=current.use,gets=next.use;if(!had.permission)return!1;if(!gets.permission)return!0;if(had.scope==="ALL_TEAMS")return gets.scope!=="ALL_TEAMS";let kept=new Set(gets.scope==="ALL_TEAMS"?[]:gets.teamIds??[]);return gets.scope!=="ALL_TEAMS"&&had.teamIds.some(id=>!kept.has(id))}function sameAsCurrent(current,next){if(!current||current.edit!==next.edit||current.use.permission!==next.use.permission)return!1;if(!next.use.permission)return!0;if(current.use.scope!==next.use.scope)return!1;if(next.use.scope==="ALL_TEAMS")return!0;let before=[...current.use.teamIds].sort(),after=[...next.use.teamIds??[]].sort();return before.length===after.length&&before.every((id,i)=>id===after[i])}function detachRows(impact){return impact.detaches.map(entry2=>({workspace:`${entry2.workspace.name} (${entry2.workspace.id})`,team:`${entry2.team.name} (${entry2.team.id})`,apiConnections:entry2.apiConnections,eventListeners:entry2.eventListeners}))}function humanImpact(impact){return{effect:impact.effect,...impact.detaches.length>0?{detaches:detachRows(impact)}:{detaches:"nothing would be detached"}}}function impactNote(impact){let rows2=detachRows(impact).map(row=>` ${row.workspace} \xB7 ${row.team} \xB7 ${row.apiConnections} API connection(s), ${row.eventListeners} event listener(s)`).join(`
1329
1330
  `);prompts().note(["Reducing access detaches the connector. This change would remove it from:","",rows2,"","Those API connections and event listeners stop working the moment the connector is","detached, and every script importing them fails until somebody attaches a","replacement. Granting the permission back does not re-attach anything.","","These are not your workspaces \u2014 one appears above only when you are not a member of","the team that owns it \u2014 so the repair is someone else's to make."].join(`
1330
1331
  `))}async function dryRun(target,userId,body){let params={path:{teamId:target.team,connectorId:target.connector,userId},query:{dryRun:"true"}},{data,response,error:error51}=await withSpinner("Checking what would change",()=>body===void 0?target.client.DELETE("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params}):target.client.PUT("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params,body}));return response.ok||shareFail(response.status,error51),data}async function confirmReduction(target,userId,body,question,opts={}){let impact=await dryRun(target,userId,body),detached=impact?.detaches.length??0;if(detached===0&&!opts.always)return;impact&&detached>0&&impactNote(impact);let suffix=detached>0?` This detaches ${detached} workspace${detached===1?"":"s"}.`:"";await prompts().confirm(`${question}${suffix}`,!1)||fail(EXIT.CANCELLED,"CANCELLED","Change cancelled.")}function permissionsFromFlags(opts){opts.useAllTeams&&(opts.useTeam?.length??0)>0&&fail(EXIT.USAGE,"USAGE_ERROR","--use-all-teams and --use-team cannot be combined.");let use=opts.useAllTeams?{permission:!0,scope:"ALL_TEAMS"}:(opts.useTeam?.length??0)>0?{permission:!0,scope:"SPECIFIC_TEAMS",teamIds:opts.useTeam}:{permission:!1};return{edit:opts.edit===!0,use}}async function askShareUser(target,opts){let shares=(await fetchShares(target)).filter(s=>!s.owner),assignable=opts.includeAssignable?await fetchAssignableMembers(target):[],existing=shares.map(share2=>{let label=userName(share2.user),held=[share2.permissions.edit?"edit":void 0,share2.permissions.use.permission?`use in ${useCell(share2.permissions)}`:void 0].filter(note=>note!==void 0);return{value:share2.user.id,label,display:`${label} (shared: ${held.join(", ")||"nothing"})`,hint:share2.user.email}}),candidates=assignable.map(member2=>({value:member2.id,label:userName(member2),hint:`${member2.email} \xB7 ${member2.teams.length} team${member2.teams.length===1?"":"s"} in common`})),choices=[...existing,...candidates];choices.length===0&&(opts.includeAssignable&&fail(EXIT.NOT_FOUND,"NO_ASSIGNABLE_MEMBERS","There is nobody to share this connector with: it is already shared with everyone you share a team with.",{hint:"Share a team with someone first, or change an existing share."}),fail(EXIT.NOT_FOUND,"NO_SHARES","This connector is not shared with anyone."));let picked=await prompts().select(opts.includeAssignable?"Who should hold access to this connector?":`Whose access should be ${opts.verb}?`,choices),share=shares.find(s=>s.user.id===picked),member=assignable.find(m2=>m2.id===picked);return{userId:picked,...share?{share}:{},...share||member?{name:userName(share?share.user:member)}:{}}}function teamChoices(available,current){let choices=available.map(team=>({value:team.id,label:team.name,hint:team.id}));for(let id of current)available.some(team=>team.id===id)||choices.push({value:id,label:id,display:`${id} (current \u2014 no longer a team you share)`,hint:"keep it to leave that access alone"});return choices}async function askPermissions(current,teams){for(;;){let currentEdit=current?.edit,edit=await prompts().select("Can they rename the connector and replace its credentials?",[{value:"no",label:"No",...currentEdit===!1?{display:"No (current)"}:{},hint:"they can still use it, if you grant that next"},{value:"yes",label:"Yes \u2014 edit permission",...currentEdit===!0?{display:"Yes \u2014 edit permission (current)"}:{},hint:"renaming and replacing credentials, never deleting"}],{initial:currentEdit===!0?"yes":"no"})==="yes",currentUse=current?.use,currentScope=currentUse?.permission?currentUse.scope:"none",scope2=await prompts().select("Where may they use it?",[{value:"ALL_TEAMS",label:"Every team you share with them",...currentScope==="ALL_TEAMS"?{display:"Every team you share with them (current)"}:{},hint:"including teams they join later"},{value:"SPECIFIC_TEAMS",label:"Only teams I pick",...currentScope==="SPECIFIC_TEAMS"?{display:"Only teams I pick (current)"}:{}},...edit?[{value:"none",label:"Nowhere \u2014 no use permission",...currentScope==="none"?{display:"Nowhere \u2014 no use permission (current)"}:{},hint:"they cannot use the connector in any workspace"}]:[]],{initial:current&&(edit||currentScope!=="none")?currentScope:"SPECIFIC_TEAMS"}),teamIds;if(scope2==="SPECIFIC_TEAMS"){let held=currentUse?.permission&&currentUse.scope==="SPECIFIC_TEAMS"?currentUse.teamIds:[],choices=teamChoices(teams,held);if(choices.length===0){prompts().note("\u2716 You share no teams with this user, so there is no team to allow.");continue}let picked=await prompts().multiselect("Which teams may they use it in?",choices,{initial:held.length>0?held:choices.length===1?[choices[0]?.value??""]:[]});if(picked.length===0){prompts().note("\u2716 Pick at least one team, or choose a different answer above.");continue}teamIds=picked}let body={edit,use:scope2==="none"?{permission:!1}:scope2==="ALL_TEAMS"?{permission:!0,scope:"ALL_TEAMS"}:{permission:!0,scope:"SPECIFIC_TEAMS",teamIds}};if(!body.edit&&!body.use.permission){prompts().note("\u2716 That grants nothing. Grant at least one permission, or remove their access with `connector-sharing remove`.");continue}return body}}function sentCells(userId,target,body,teams){return{user:userId,connector:target.connectorLabel?`${target.connectorLabel} (${target.connector})`:target.connector,edit:body.edit?"yes":"no",use:useCell({edit:body.edit,use:body.use.permission?{permission:!0,scope:body.use.scope??"ALL_TEAMS",teamIds:body.use.teamIds??[]}:{permission:!1,scope:"ALL_TEAMS",teamIds:[]}},teams)}}function connectorSharingCommand(){let sharing=new Command("connector-sharing").alias("cs").description("Manage connector sharing"),CONNECTOR_ID="Connector ID (required, interactive)",USER_ID="User ID, see list-assignable-users for users the connector is not yet shared with and list for those it is (required, interactive)",SHARED_USER_ID="User ID, one of those list reports (required, interactive)";return sharing.command("list").description("List everyone a connector is shared with").option("--connector-id <connectorId>",CONNECTOR_ID).option("--team <teamId>",SCOPE_TEAM).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,LIST_DOC2))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope2(globals),target=await resolveTarget(scope2,opts.connectorId),{data,response,error:error51}=await withSpinner("Fetching connector sharing",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/shares",{params:{path:{teamId:target.team,connectorId:target.connector}}}));(!response.ok||!data)&&shareFail(response.status,error51),ok(data,{human:d=>({shares:d.shares.map(humanShare)})})}),sharing.command("get").description("Get a single user's permissions on a connector").argument("[userId]",SHARED_USER_ID).option("--connector-id <connectorId>",CONNECTOR_ID).option("--team <teamId>",SCOPE_TEAM).option("--explain",EXPLAIN).action(async(userArg,opts,cmd)=>{if(explained(cmd,GET_DOC2))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope2(globals),target=await resolveTarget(scope2,opts.connectorId),userId=userArg===void 0?void 0:assertResourceId(userArg,"userId");userId||(canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR",`<userId> is required. ${supplyHint()}`),userId=(await askShareUser(target,{includeAssignable:!1,verb:"shown"})).userId);let{data,response,error:error51}=await withSpinner("Fetching connector share",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params:{path:{teamId:target.team,connectorId:target.connector,userId}}}));(!response.ok||!data)&&shareFail(response.status,error51),ok(data,{human:d=>({user:personCell(d.user),email:d.user.email,owner:d.owner?"yes":"no",edit:d.permissions.edit?"yes":"no",use:useCell(d.permissions,d.teams),useTeams:d.permissions.use.teamIds.map(id=>{let team=d.teams.find(t=>t.id===id);return team?`${team.name} (${team.id})`:id}).join(", "),sharedTeams:d.teams.map(t=>`${t.name} (${t.id})`).join(", ")})})}),sharing.command("list-assignable-users").description("List the users a connector can still be shared with").option("--connector-id <connectorId>",CONNECTOR_ID).option("--team <teamId>",SCOPE_TEAM).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,ASSIGNABLE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope2(globals),target=await resolveTarget(scope2,opts.connectorId),{data,response,error:error51}=await withSpinner("Fetching assignable members",()=>target.client.GET("/v1/team/{teamId}/connector/{connectorId}/assignableMembers",{params:{path:{teamId:target.team,connectorId:target.connector}}}));(!response.ok||!data)&&shareFail(response.status,error51),ok(data,{human:d=>({members:d.members.map(m2=>({user:personCell(m2),email:m2.email,teams:m2.teams.map(t=>`${t.name} (${t.id})`).join(", ")}))})})}),sharing.command("set").description("Share a connector with a user, or change what they may do with it").argument("[userId]",USER_ID).option("--connector-id <connectorId>",CONNECTOR_ID).option("--team <teamId>",SCOPE_TEAM).option("--edit","Let them rename the connector and replace its credentials, in every team; never lets them delete it. The flags carry the whole permission set, so omitting it revokes the permission from a user who holds it (optional, interactive, default: false)").option("--use-all-teams","Let them use the connector in every team you share with them, including teams they join later. Passing neither this nor --use-team revokes the use permission from a user who holds it (optional, interactive, exclusive with --use-team)").option("--use-team <teamId>","Let them use the connector in the specified team only; you and that user must both be members of every team named. Passing neither this nor --use-all-teams revokes the use permission from a user who holds it (optional, interactive, repeatable, exclusive with --use-all-teams)",(value,previous)=>[...previous??[],value]).option("--dry-run","Report what the request would change, and what it would detach, without committing anything (optional)").option("--input <file>",INPUT_BODY).option("--explain",EXPLAIN).action(async(userArg,opts,cmd)=>{if(explained(cmd,SET_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope2(globals),target=await resolveTarget(scope2,opts.connectorId),fromFlags=opts.input!==void 0||opts.edit===!0||opts.useAllTeams===!0||(opts.useTeam?.length??0)>0,userId=userArg===void 0?void 0:assertResourceId(userArg,"userId"),current,readCurrent=!1,teams=[],who;if(!userId){canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR",`<userId> is required. ${supplyHint()}`);let picked=await askShareUser(target,{includeAssignable:!0,verb:"changed"});userId=picked.userId,current=picked.share?.permissions,readCurrent=!0,who=picked.share?userName(picked.share.user):picked.name}let typedUserId=userArg!==void 0,body;if(fromFlags){if(body=opts.input!==void 0?validate(shareBodySchema,readInput(opts.input)):validate(shareBodySchema,permissionsFromFlags(opts)),typedUserId&&canPrompt()){let{share,status,error:error52}=await fetchShare(target,userId);!share&&status!==404&&apiFail(status,error52),readCurrent=!0,share&&(current=share.permissions,teams=share.teams,who??=userName(share.user))}}else{canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR","No permission specified: pass --edit, --use-all-teams, --use-team or --input.");let{share,status,error:error52}=await fetchShare(target,userId);if(!share&&status!==404&&apiFail(status,error52),readCurrent=!0,share?(current=share.permissions,teams=share.teams,who??=userName(share.user)):status===404&&(teams=(await fetchAssignableMembers(target)).find(m2=>m2.id===userId)?.teams??[]),body=await askPermissions(current,teams),sameAsCurrent(current,body)){prompts().note("Nothing to change \u2014 they already hold exactly that.");return}}if(opts.dryRun){let impact=await dryRun(target,userId,body);impact||fail(EXIT.API_ERROR,"NO_IMPACT_REPORTED","The API reported no impact for the change."),ok(impact,{human:humanImpact});return}canPrompt()&&reducesAccess(current,body)&&await confirmReduction(target,userId,body,`Reduce ${who??userId}'s access to this connector?`);let{response,error:error51}=await withSpinner("Sharing connector",()=>target.client.PUT("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params:{path:{teamId:target.team,connectorId:target.connector,userId}},body}));response.ok||shareFail(response.status,error51),okMutation(current?"Connector sharing updated":"Connector shared",{updated:!0,id:userId,userId,connectorId:target.connector},sentCells(userId,target,body,teams)),readCurrent&&!current&&prompts().note("They may be emailed about the new access.")}),sharing.command("remove").description("Remove a user's access to a connector").argument("[userId]",USER_ID).option("--connector-id <connectorId>",CONNECTOR_ID).option("--team <teamId>",SCOPE_TEAM_DESTRUCTIVE).option("--dry-run","Report what removing their access would detach, without committing anything (optional)").option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(userArg,opts,cmd)=>{if(explained(cmd,REMOVE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope2(globals,{useSession:canPrompt()}),target=await resolveTarget(scope2,opts.connectorId),userId=userArg===void 0?void 0:assertResourceId(userArg,"userId"),name;if(!userId){canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR",`<userId> is required. ${supplyHint()}`);let picked=await askShareUser(target,{includeAssignable:!1,verb:"removed"});userId=picked.userId,name=picked.share?userName(picked.share.user):void 0}if(opts.dryRun){let impact=await dryRun(target,userId,void 0);impact||fail(EXIT.API_ERROR,"NO_IMPACT_REPORTED","The API reported no impact for the removal."),ok(impact,{human:humanImpact});return}opts.yes||(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED","Removing access can detach the connector from workspaces. Re-run with --yes to confirm."),await confirmReduction(target,userId,void 0,`Remove ${name??userId}'s access to this connector?`,{always:!0}));let{response,error:error51}=await withSpinner("Removing access",()=>target.client.DELETE("/v1/team/{teamId}/connector/{connectorId}/share/{userId}",{params:{path:{teamId:target.team,connectorId:target.connector,userId}}}));response.ok||shareFail(response.status,error51),okMutation("Connector sharing removed",{deleted:!0,id:userId,userId,connectorId:target.connector})}),sharing}var CONNECTOR_NAME_FORMAT="up to 100 characters",MAX_CONNECTOR_NAME=100;function normalizeConnectorName(name){return name.trim()}function connectorNameError(name){let normalized=normalizeConnectorName(name);if(!normalized)return"A connector name is required.";if(normalized.length>MAX_CONNECTOR_NAME)return`A connector name can be at most ${MAX_CONNECTOR_NAME} characters (that one is ${normalized.length}).`}function assertConnectorName(name){let error51=connectorNameError(name);return error51&&fail(EXIT.USAGE,"INVALID_CONNECTOR_NAME",error51),normalizeConnectorName(name)}var BASE_URL_FORMAT="must start with https:// or http://",MAX_HEADER_NAME=250,BASIC_AUTH_PASSWORD_ENV="SR_CONNECT_CLI_BASIC_AUTH_PASSWORD";function normalizeBaseUrl(url2){return url2.trim()}function baseUrlError(url2){let normalized=normalizeBaseUrl(url2);if(!normalized)return"A base URL is required.";if(!/^https?:\/\/\S/i.test(normalized))return`A base URL ${BASE_URL_FORMAT}.`}function assertBaseUrl(url2){let error51=baseUrlError(url2);return error51&&fail(EXIT.USAGE,"INVALID_BASE_URL",error51),normalizeBaseUrl(url2)}function parseHeaderFlag(input){let at2=input.indexOf(":");at2===-1&&fail(EXIT.USAGE,"INVALID_HEADER",`--header ${JSON.stringify(input)} is not "name: value".`);let name=input.slice(0,at2).trim();return name||fail(EXIT.USAGE,"INVALID_HEADER","A header name cannot be empty."),{name,value:input.slice(at2+1).replace(/^ /,"")}}function headerNameError(name){let normalized=name.trim();if(!normalized)return"A header name is required.";if(normalized.length>MAX_HEADER_NAME)return`A header name can be at most ${MAX_HEADER_NAME} characters (that one is ${normalized.length}).`}function assertHeaders(headers){let seen=new Set,normalized=[];for(let header of headers){let name=header.name.trim(),error51=headerNameError(name);error51&&fail(EXIT.USAGE,"INVALID_HEADER",error51);let key=name.toLowerCase();seen.has(key)&&fail(EXIT.USAGE,"DUPLICATE_HEADER",`Header "${name}" is given more than once.`),seen.add(key),normalized.push({name,value:header.value})}return normalized}function isAuthorizationHeader(name){return name.trim().toLowerCase()==="authorization"}function assertGenericConfiguration(configuration){return{...configuration,baseUrl:assertBaseUrl(configuration.baseUrl),...configuration.headers===void 0?{}:{headers:assertHeaders(configuration.headers)}}}async function basicAuthPassword(opts){let fromEnv=process.env[BASIC_AUTH_PASSWORD_ENV];return fromEnv||(opts.ask||fail(EXIT.USAGE,"USAGE_ERROR",`--basic-auth-username needs a password: set ${BASIC_AUTH_PASSWORD_ENV}, or run on a terminal without --no-prompts to be asked for it.`),opts.ask())}var genericConfigurationSchema=external_exports.object({baseUrl:external_exports.string().min(1),headers:external_exports.array(external_exports.object({name:external_exports.string().min(1),value:external_exports.string()}).strict()).optional(),basicAuth:external_exports.object({username:external_exports.string().min(1),password:external_exports.string().min(1)}).strict().optional()}).strict(),createBodySchema2=external_exports.object({appId:external_exports.string().min(1),name:external_exports.string().min(1),apiConnectionTypeId:external_exports.string().min(1).optional(),eventListenerTypeId:external_exports.string().min(1).optional(),genericConfiguration:genericConfigurationSchema.optional()}).strict(),updateBodySchema2=external_exports.object({name:external_exports.string().min(1).optional(),genericConfiguration:genericConfigurationSchema.optional()}).strict().refine(body=>body.name!==void 0||body.genericConfiguration!==void 0,{message:"Either a new name or a configuration is required."}),EXAMPLE_CONFIGURATION={baseUrl:"https://api.example.com",headers:[{name:"X-Api-Key",value:"<apiKey>"}],basicAuth:{username:"<username>",password:"<password>"}},LIST_DOC3=defineCommandDoc("connector list",{rules:["The team is --team and there is no positional argument; this group stops at the team, a connector belonging to a user and being looked up through one."],notes:["Your own connectors and those shared with you for use in the team named. connectionType is the app the connector is for, and is what an API connection or an event listener is matched against; it is never the API connection type.","Under --raw the list arrives under the key connections, which is the API's own name for it and not connectors. Responses are passed through as they are sent, so that is the key to read.","The listing does not carry baseUrl, the instance a connector points at. Read a single connector for that."]}),GET_DOC3=defineCommandDoc("connector get",{rules:["The connector is the positional argument and the team is --team."],notes:["Reports the authorization URL, which is where an unauthorized connector is finished and where an expired one is renewed, so it is carried for every connector rather than only for a new one.","Reports baseUrl, the instance the connector points at: the site or host it was authorized against, such as an Atlassian site or a self-managed GitLab. The listing does not carry it. Read it as optional rather than as a field every connector has, since it is absent while a connector is unauthorized, even where a URL was already entered, and absent altogether for an app that has no instance of its own.","baseUrl is reported exactly as it was configured, which may include a trailing slash, so normalize it before joining a path onto it.","For a Generic connector it also reports the configuration: the base URL, which is the same value baseUrl carries, the derived authentication method and the header names. Header values are never reported, by this verb or any other."]}),DELETE_DOC2=defineCommandDoc("connector delete",{rules:["The connector is the positional argument and the team is --team.","--force deletes a connector that is still in use, which is otherwise refused.","--yes skips the confirmation, and is required without a terminal."],notes:["Owner only. The connector goes for everyone it was shared with, and every API connection and event listener on it is detached in every workspace, including other people's. Nobody is notified.","A connector still in use is exit 1 CONNECTOR_IN_USE without --force."]}),CREATE_DOC2=defineCommandDoc("connector create",{schema:createBodySchema2,body:{appId:"<appId>",name:"Internal API (prod)",apiConnectionTypeId:"<apiConnectionTypeId>",eventListenerTypeId:"<eventListenerTypeId>",genericConfiguration:EXAMPLE_CONFIGURATION},rules:[`appId: the app the connector is for, from ${CLI} app list; never reported back as such, but list and get report connectionType, whose id is the app's own connectionType.id in app list.`,`name: ${CONNECTOR_NAME_FORMAT}, trimmed, no charset rule, unique among your own connectors for the same app.`,"apiConnectionTypeId (--api-connection-type-id as a flag): one of the app's API connection types; a connector created without one is refused when it is attached to an API connection.","eventListenerTypeId (--listener-type-id as a flag, as on event-listener create): one of the app's event listener types; it only labels the connector, since event listeners attach by app.","genericConfiguration is accepted for the Generic app only (400 for any other) and creates the connector authorized; any other app's connector is created unauthorized and finished in a browser at the URL the response carries.",`genericConfiguration.baseUrl is required whenever the block is sent and ${BASE_URL_FORMAT}. Spelled --base-url as a flag; the block itself has no flag of its own.`,`genericConfiguration.headers: name and value pairs sent with every request, spelled --header <name:value> as a repeatable flag; names are trimmed and can be at most ${MAX_HEADER_NAME} characters, a name given twice is refused with the two compared without case, values are kept exactly as sent, and nothing ever reports a value back.`,`genericConfiguration.basicAuth: a username and password the API encodes into an Authorization header, replacing one of that name in headers. Spelled --basic-auth-username as a flag, with the password read from ${BASIC_AUTH_PASSWORD_ENV}, never from argv. The authentication method is derived from the configuration the write leaves behind and is never sent.`,"Header values and the password are credentials: keep the file out of version control."],notes:["A header value passed in argv is visible in shell history and in the process list. --input avoids that; recordings blank the values either way.","The authorization URL is reported for every connector, authorized or not, because it is also where an expired authorization is renewed."]}),UPDATE_DOC2=defineCommandDoc("connector update",{schema:updateBodySchema2,body:{name:"Internal API (prod)",genericConfiguration:EXAMPLE_CONFIGURATION},rules:["At least one of name or genericConfiguration is required, and an omitted key keeps the current value.",`name: ${CONNECTOR_NAME_FORMAT}, trimmed, unique among your own connectors for the same app; allowed for the owner and for anyone the connector is shared with for editing.`,"genericConfiguration is accepted for a connector of the Generic app only, replaces the configuration and cannot be removed.",`genericConfiguration.baseUrl is required whenever the block is sent, even when only the headers change, and ${BASE_URL_FORMAT}: send the current one back from get. Spelled --base-url as a flag.`,`genericConfiguration.headers: omit to keep the current header set, [] to clear it (--no-headers as a flag; the encoded Authorization header of basic authentication included), an array to replace it (--header <name:value>, repeatable); names are trimmed and can be at most ${MAX_HEADER_NAME} characters, and a name given twice is refused, the two compared without case.`,`genericConfiguration.basicAuth: re-encoded into the Authorization header, replacing one of that name in headers and surviving headers: []. Spelled --basic-auth-username as a flag, with the password read from ${BASIC_AUTH_PASSWORD_ENV}, never from argv.`]});async function resolveScope3(globals,opts={}){let client=await apiClient(globals.instance),resolved=await resolveParams(["team"],{team:globals.team},{client,interactive:canPrompt(),useSession:opts.useSession});return{client,team:resolved.team??""}}async function resolveConnector(scope2,provided){if(provided)return{id:assertResourceId(provided,"connectorId")};canPrompt()||fail(EXIT.USAGE,"USAGE_ERROR",`<connectorId> is required. ${supplyHint()}`);let labels={};return{id:(await resolveParams(["connector"],{team:scope2.team},{client:scope2.client,interactive:!0,labels})).connector??"",label:labels.connector}}async function askConnectorName(initial){for(;;){let answer=await prompts().text(`Connector name (${CONNECTOR_NAME_FORMAT})`,{...initial?{initial}:{},allowEmpty:!0}),error51=connectorNameError(answer);if(!error51)return normalizeConnectorName(answer);prompts().note(`\u2716 ${error51}`)}}async function askRename(current,opts={}){let name=await askConnectorName(current);if(current!==void 0&&name===current){opts.quiet||prompts().note(`"${current}" is already the connector's name \u2014 nothing to change.`);return}return name}var NO_TYPE="\0no-type";async function askOptionalType(scope2,key,appId){let optOut=key==="apiConnectionType"?{value:NO_TYPE,label:"Not for API connections",hint:"attaching it to an API connection is then refused"}:{value:NO_TYPE,label:"Not for event listeners",hint:"leaves the connector unlabelled; listeners attach by app"},choices;try{choices=await resolverChoices(scope2.client,key,{team:scope2.team,app:appId})}catch(err){if(!(err instanceof CliError))throw err;return}let noun=key==="apiConnectionType"?"API connection type":"event listener type",first=choices[0];if(!first){prompts().note(`\u26A0 This app publishes no ${noun}s \u2014 creating the connector without one.`);return}if(choices.length===1)return prompts().note(`${noun}: ${first.display??first.label} \u2014 only one, auto-selected.`),first.value;let message=key==="apiConnectionType"?"API connection type:":"Event listener type:",picked=await prompts().select(message,[...choices,optOut],{initial:first.value});return picked===NO_TYPE?void 0:picked}async function fetchConnector(scope2,connectorId){let{data}=await withSpinner("Checking the connector",()=>scope2.client.GET("/v1/team/{teamId}/connector/{connectorId}",{params:{path:{teamId:scope2.team,connectorId}}}));return data}function collectHeader(value,previous){return[...previous??[],value]}function hasConfigurationFlags(opts){return opts.baseUrl!==void 0||(opts.header?.length??0)>0||opts.headers===!1||opts.basicAuthUsername!==void 0}async function configurationFromFlags(opts,verb){if(!hasConfigurationFlags(opts))return;let clearHeaders=opts.headers===!1,headers=assertHeaders((opts.header??[]).map(parseHeaderFlag));clearHeaders&&headers.length>0&&fail(EXIT.USAGE,"USAGE_ERROR","--no-headers cannot be combined with --header."),opts.baseUrl===void 0&&fail(EXIT.USAGE,"USAGE_ERROR",`A base URL is required with any other configuration flag: re-run \`${CLI} connector ${verb}\` with --base-url.`);let basicAuth=opts.basicAuthUsername?{username:opts.basicAuthUsername,password:await basicAuthPassword(canPrompt()?{ask:()=>prompts().password("Password:")}:{})}:void 0;return stripUndefined({baseUrl:assertBaseUrl(opts.baseUrl),headers:clearHeaders?[]:headers.length>0?headers:void 0,basicAuth})}async function askBaseUrl(current){for(;;){let answer=await prompts().text(`Base URL (${BASE_URL_FORMAT})`,{...current?{initial:current}:{},allowEmpty:!0}),error51=baseUrlError(answer);if(!error51)return normalizeBaseUrl(answer);prompts().note(`\u2716 ${error51}`)}}async function askBasicAuth(){let username=await prompts().text("Username:"),password=await prompts().password("Password:");return{username,password}}async function askHeaderEntries(opts){let collected=[],taken=new Set((opts.taken??[]).map(n=>n.trim().toLowerCase()));for(;;){let name=await askHeaderName(taken,opts.hasBasicAuth),value=await prompts().password(`Value for "${name}":`,{allowEmpty:!0});if(collected.push({name,value}),taken.add(name.toLowerCase()),!await prompts().confirm("Add another header?",!1))return collected}}async function askHeaderName(taken,hasBasicAuth){for(;;){let answer=(await prompts().text("Header name:",{allowEmpty:!0})).trim(),error51=headerNameError(answer);if(error51){prompts().note(`\u2716 ${error51}`);continue}if(hasBasicAuth&&isAuthorizationHeader(answer)){prompts().note("\u2716 Basic authentication already sends an Authorization header, and the credentials replace whatever is typed here.");continue}if(taken.has(answer.toLowerCase())){prompts().note(`\u2716 Header "${answer}" was already given.`);continue}return answer}}async function askNewConfiguration(scope2,appId,opts){let fromFlags=await configurationFromFlags(opts,"create");if(fromFlags)return fromFlags;if(!canPrompt()||!await isGenericApp(scope2.client,appId)||await prompts().select("Configure this connector:",[{value:"here",label:"Here, now",hint:"a base URL and the headers it sends"},{value:"web",label:"In the web application",hint:"get a link to finish it there"}],{initial:"here"})==="web")return;let baseUrl2=await askBaseUrl(),basicAuth=await prompts().confirm("Add basic authentication?",!1)?await askBasicAuth():void 0,headers=await prompts().confirm("Add headers?",basicAuth===void 0)?await askHeaderEntries({hasBasicAuth:basicAuth!==void 0}):[];return stripUndefined({baseUrl:baseUrl2,...headers.length>0?{headers}:{},...basicAuth?{basicAuth}:{}})}function describeConfiguration(current){let names=current.headerNames??[];return[current.baseUrl?`Base URL ${current.baseUrl}`:"no base URL",current.authMethod??"no authentication",names.length===1?"1 header":`${names.length} headers`].join(" \xB7 ")}async function askConfigurationChange(current,opts){let fromFlags=await configurationFromFlags(opts,"update");if(fromFlags)return fromFlags;if(!canPrompt()||(current?prompts().note(describeConfiguration(current)):prompts().note("This connector has no configuration yet."),!await prompts().confirm(current?"Change the connector's configuration?":"Configure it now?",!current)))return;let baseUrl2=await askBaseUrl(current?.baseUrl),currentNames=current?.headerNames??[],wasBasic=current?.authMethod==="BASIC",walkable=currentNames.filter(name=>!isAuthorizationHeader(name)),headers,removed=!1;if(currentNames.length>0){let answer=await prompts().select("Headers:",[{value:"keep",label:"Keep the current headers",display:`Keep the current headers (${currentNames.join(", ")})`},{value:"replace",label:"Replace them",hint:"every value has to be given again"},{value:"remove",label:"Remove all headers",...wasBasic?{hint:"basic authentication goes with them"}:{}}],{initial:"keep"});answer==="remove"?(headers=[],removed=!0):answer==="replace"&&(prompts().note("Header values are never reported back, so a replacement asks for every value again."),headers=await askReplacementHeaders(walkable,wasBasic))}else await prompts().confirm("Add headers?",!1)&&(headers=await askHeaderEntries({hasBasicAuth:wasBasic}));let basicAuth=removed?void 0:await askCredentialsOnUpdate({wasBasic,replacingHeaders:headers!==void 0});if(!(baseUrl2===current?.baseUrl&&headers===void 0&&basicAuth===void 0))return stripUndefined({baseUrl:baseUrl2,headers,basicAuth})}async function askReplacementHeaders(currentNames,hasBasicAuth){let kept=[];for(let name of currentNames){let value=await prompts().password(`Value for "${name}" (empty removes the header):`,{allowEmpty:!0});if(value===""){prompts().note(`${name} will be removed.`);continue}kept.push({name,value})}return await prompts().confirm("Add another header?",currentNames.length===0)&&kept.push(...await askHeaderEntries({taken:kept.map(h=>h.name),hasBasicAuth})),kept}async function askCredentialsOnUpdate(opts){return opts.wasBasic&&!opts.replacingHeaders?await prompts().select("Authentication:",[{value:"keep",label:"Keep the current credentials",display:"Keep the current credentials (BASIC)"},{value:"set",label:"Set a username and password"}],{initial:"keep"})==="keep"?void 0:askBasicAuth():opts.wasBasic?(prompts().note("Replacing the headers replaces the encoded Authorization header too, so the username and password have to be given again."),await prompts().confirm("Keep basic authentication?",!0)?askBasicAuth():void 0):await prompts().confirm("Add basic authentication?",!1)?askBasicAuth():void 0}function configurationCells(config2){let names=config2.headerNames??[];return stripUndefined({baseUrl:config2.baseUrl,authMethod:config2.authMethod,headers:names.length>0?names.join(", "):"none"})}function sentConfigurationCells(config2){let names=(config2.headers??[]).map(h=>h.name);return config2.basicAuth&&names.push("Authorization (basic)"),{baseUrl:config2.baseUrl,headers:names.length>0?names.join(", "):config2.headers?"none":"unchanged"}}async function askCreateBody(scope2,opts){let appId=(await resolveParams(["app"],{team:scope2.team,app:opts.appId},{client:scope2.client,interactive:canPrompt()})).app??"",name=opts.name??await askConnectorName();return stripUndefined({appId,name,apiConnectionTypeId:opts.apiConnectionTypeId??await askOptionalType(scope2,"apiConnectionType",appId),eventListenerTypeId:opts.listenerTypeId??await askOptionalType(scope2,"listenerType",appId),genericConfiguration:await askNewConfiguration(scope2,appId,opts)})}function authorizationNote(url2,opts={}){if(isRaw())return;let lines=opts.generic?["This connector holds no credentials yet. A Generic connector is configured with a","base URL and headers rather than an authorization flow \u2014 add them in the web","application, or here with:",` ${CLI} connector update ${opts.connectorId??"<connectorId>"} --base-url \u2026 --header 'Name: value'`]:["A new connector holds no credentials yet: authorizing one needs a browser session,","so the API cannot do it and neither can this CLI."];prompts().note([...lines,url2?opts.generic?`Open ${url2} to configure it there.`:`Open ${url2} and sign in to the app to authorize it.`:"This deployment publishes no web-application URL \u2014 finish it from the Connectors page in the web app."].join(`
1331
1332
  `))}function conflictMessage(body){let message=body?.errorMessage;return typeof message=="string"&&message.length>0?message:void 0}function describeConnector(id,name){return name&&name!==id?`${name} (${id})`:id}function humanConnector(connector,detail=!1){let owner=connector.owner,{genericConfiguration:configuration,authorizationUrl,owner:_owner,...rest}=connector,connectionType=connector.connectionType;return{...rest,authorized:connector.authorized?"yes":"no",canUse:connector.canUse?"yes":"no",...connectionType&&typeof connectionType=="object"?{connectionType:`${connectionType.name??""} (${connectionType.id??""})`}:{},...owner&&typeof owner=="object"?{owner:personCell(owner)}:{},...detail&&owner&&typeof owner=="object"&&owner.email?{ownerEmail:owner.email}:{},...configuration?configurationCells(configuration):{},...authorizationUrl?{authorizationUrl}:{}}}async function deleteConnector(client,target,force){let{response,error:error51}=await withSpinner("Deleting connector",()=>client.DELETE("/v1/team/{teamId}/connector/{connectorId}",{params:{path:{teamId:target.team,connectorId:target.id},...force?{query:{force:"true"}}:{}}}));return{ok:response.ok,status:response.status,error:error51}}async function deleteConnectorWithConflict(client,target,opts){let forced=opts.force,result=await deleteConnector(client,target,forced),conflict=conflictMessage(result.error);result.status===400&&conflict&&!forced&&opts.interactive&&(prompts().note(`\u2716 ${conflict}`),await prompts().confirm("Delete it anyway? Every API connection and event listener using it is detached.",!1)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled."),forced=!0,result=await deleteConnector(client,target,forced)),!result.ok&&(result.status===400&&conflict&&!forced&&fail(EXIT.API_ERROR,"CONNECTOR_IN_USE",conflict,{status:400,hint:"Re-run with --force to delete it anyway; every API connection and event listener using it is detached."}),apiFail(result.status,result.error))}async function confirmDeletion(scope2,target){let name=(await withSpinner("Checking the connector",()=>connectorInfo(scope2.client,scope2.team,target.id)))?.name??target.label;prompts().note(["Deleting removes the connector for everyone it was shared with, and the sharing","permissions with it. Every API connection and event listener that uses it is","detached, in every workspace \u2014 including workspaces belonging to the people it was","shared with, and --force decides only whether this request is refused first, never","how much is detached. Scripts importing those API connections fail until another","connector is attached, and nobody is emailed about any of it.","Only the owner of a connector can delete it, and authorization cannot be restored:","a replacement has to be authorized again in the web application."].join(`
@@ -1386,7 +1387,7 @@ ${readme.content}`}function sizeCell(content){if(content==="")return"empty";let
1386
1387
  and API connection has to be pointed at a connector in the new team.
1387
1388
  Remote file system access is turned off with it, and any temporary credentials stop working.`),!yes&&(canPrompt()||fail(EXIT.USAGE,"CONFIRMATION_REQUIRED",`Moving workspace "${moving.workspace.name}" from team ${from} to ${teamId} clears every connector attachment in every environment and turns remote file system access off, and moving it back undoes neither. Re-run with --yes to confirm.`,{hint:`Pass --team ${moving.teamId} to update it where it is instead.`}),await prompts().confirm("Move it to that team?",!1)||fail(EXIT.CANCELLED,"CANCELLED","Cancelled."))}var LIST_DOC13=defineCommandDoc("workspace list",{rules:["The team is --team; the workspace is this group's resource, so there is no -w here and no positional argument."],notes:["Every workspace of the team, yours and the public ones you are not a member of alike."]}),GET_DOC12=defineCommandDoc("workspace get",{rules:["The workspace is the positional argument and there is no -w here, the workspace being what this verb reads rather than where it looks. --team is optional: every workspace read is keyed by team, and a team that was not given is found by searching the ones you are a member of, which is one request per team until the workspace turns up."],notes:["Reports the language, which is worth reading after creating from a template or another workspace: either brings its own, and ts-strict is the one to prefer.","Also reports remoteWorkspaceEnabled, which a move between teams turns off."]}),DELETE_DOC11=defineCommandDoc("workspace delete",{rules:["The workspace is the positional argument and the team is --team.","--yes skips the confirmation, and is required without a terminal."],notes:["Deletes the workspace with its environments, scripts, API connections, event listeners, scheduled triggers and releases; anything running from a release stops.","The lock this shell holds is presented and never stands in the way. Another holder is exit 1 WORKSPACE_LOCKED naming them, with workspace-lock check and workspace-lock take --force in the hint.","Dropped from this shell's session defaults afterwards, along with the environment the record named."]}),CREATE_DOC12=defineCommandDoc("workspace create",{schema:createBodySchema12,body:{name:"Order sync",description:"Keeps Jira and the order system in step.",sourceWorkspaceId:"<workspaceId>",sourceTemplateId:"<templateId>",language:"ts-strict",visibility:"private"},rules:[`name: ${WORKSPACE_NAME_FORMAT}.`,`description: free text, up to ${MAX_WORKSPACE_DESCRIPTION} characters.`,`sourceWorkspaceId (--source-workspace-id as a flag) copies another workspace; sourceTemplateId (--source-template-id) creates from a published template, as listed by ${CLI} template list; at most one of the two. Either brings its own language, and language is then ignored: read the language back with ${CLI} workspace get and upgrade it with update. A copy has one environment, the default one, holding the source's default environment's parameters with each default value as the value; parameter values, other environments and releases are not copied.`,`language: ${LANGUAGES.join(", ")}; API default ts; ts-strict is the one to prefer.`,`visibility: ${VISIBILITY_MEANINGS}; API default private. Creating a public one needs you to be an admin of the team, and a member who is not gets exit 1 "User is not in any of the required roles: ADMIN,SUPER_ADMIN"; seeing one needs nothing, which is what public means.`,"The team is --team, never a body key."]}),UPDATE_DOC12=defineCommandDoc("workspace update",{schema:updateBodySchema12,body:{name:"Order sync",description:"Keeps Jira and the order system in step.",language:"ts-strict",visibility:"private"},rules:[`name is required even when it does not change: send the current one back. ${WORKSPACE_NAME_FORMAT}.`,`description is cleared when the body omits it, so send the current one back to keep it; "" clears it too. Up to ${MAX_WORKSPACE_DESCRIPTION} characters. The flags path reads the workspace and carries it forward, so only a body given here has to.`,`language: ${LANGUAGES.join(", ")}; omitted, the current one is kept.`,`visibility: ${VISIBILITIES.join(" or ")}; omitted, the current one is kept, except when --team moves the workspace to another team, where a body that does not name one makes it private. Changing it needs you to be an admin of the team.`,"The sources a workspace was created from cannot change. --team names the workspace's team, or a new team to move it to; it is not a body key.","A --team that names another team moves the workspace, which clears every connector attachment in every environment and turns remote file system access off \u2014 neither undone by moving it back. So it takes --yes without a terminal (exit 2 CONFIRMATION_REQUIRED otherwise) and a confirmation with one, and only a typed flag can move at all: a team from an environment variable, a clone or the session record is exit 2 TEAM_MISMATCH. An --input body is held to both, the team being resolved outside it."],notes:["--yes is for the move alone: an ordinary update never needs it, and passing it to one is accepted and ignored.","The workspace is found by looking through your teams for the one holding it, which is named on stderr. Only a move pays for that search \u2014 an ordinary update reads the workspace once. An ID in none of your teams is exit 4.","A workspace published as a template stays one: the template flag is not part of this request, and editing such a workspace needs permission to author templates, which the API answers 403 for when you do not have it."]});function assertOneSource2(opts){opts.sourceWorkspaceId&&opts.sourceTemplateId&&fail(EXIT.USAGE,"USAGE_ERROR","--source-workspace-id and --source-template-id cannot be combined.")}async function fillCreateBody4(client,teamId,opts){let sourceWorkspaceId=opts.sourceWorkspaceId;!sourceWorkspaceId&&!opts.sourceTemplateId&&await prompts().confirm("Clone from an existing workspace?",!1)&&(sourceWorkspaceId=(await resolveParams(["workspace"],{team:teamId},{client,interactive:!0})).workspace);let name=opts.name??await prompts().text("Workspace name"),description=opts.description;description===void 0&&(description=await prompts().text("Workspace description, optional (empty for none)",{allowEmpty:!0})||void 0);let language=opts.language??(sourceWorkspaceId||opts.sourceTemplateId?void 0:await prompts().select("Scripting language",LANGUAGE_CHOICES)),visibility=opts.visibility??await prompts().select("Visibility",VISIBILITY_CHOICES);return stripUndefined({name,description,sourceWorkspaceId,sourceTemplateId:opts.sourceTemplateId,language,visibility})}async function locateWorkspace(client,teamId,workspaceId){let direct=teamId===void 0?void 0:await withSpinner("Fetching workspace",()=>client.GET("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));return direct?.response.ok&&direct.data?{workspace:direct.data,teamId:teamId??""}:(direct&&direct.response.status!==404&&apiFail(direct.response.status,direct.error),withSpinner("Looking for the workspace in your other teams",async()=>{let teams=await client.GET("/v1/teams");(!teams.response.ok||!teams.data)&&apiFail(teams.response.status,teams.error);for(let team of teams.data.teams){if(!team.id||team.id===teamId)continue;let list=await client.GET("/v1/team/{teamId}/workspaces",{params:{path:{teamId:team.id}}});(!list.response.ok||!list.data)&&apiFail(list.response.status,list.error);let found2=list.data.workspaces.find(w=>w.id===workspaceId);if(found2)return{workspace:found2,teamId:team.id,...team.name?{teamName:team.name}:{}}}}))}async function fetchWorkspace(client,teamId,workspaceId){let{data,response,error:error51}=await withSpinner("Fetching workspace",()=>client.GET("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));return(!response.ok||!data)&&apiFail(response.status,error51),data}async function fillUpdateBody2(current,moving){let name=await prompts().text("Workspace name",{initial:current.name}),description=current.description,currently=current.description?`(currently "${current.description}")`:"(currently unset)";await prompts().confirm(`Change the description? ${currently}`,!1)&&(description=await prompts().text("Description",{allowEmpty:!0}));let language;await prompts().confirm("Change the scripting language?",!1)&&(language=await prompts().select("Scripting language",LANGUAGE_CHOICES));let visibility;return moving?visibility=await prompts().select("Visibility",VISIBILITY_CHOICES,{initial:current.visibility}):await prompts().confirm("Change the visibility?",!1)&&(visibility=await prompts().select("Visibility",VISIBILITY_CHOICES)),{name,...description===void 0?{}:{description},...language===void 0?{}:{language},...visibility===void 0?{}:{visibility}}}async function confirmDeletion4(client,teamId,workspaceId){let current=await fetchWorkspace(client,teamId,workspaceId);prompts().note(["Deleting removes the workspace from the whole team, and everything in it goes with it:","environments, scripts, API connections, event listeners, scheduled triggers \u2014 and releases,","so anything still running from one stops immediately.",`It disappears from ${CLI} workspace list, and every later request naming it is a 404.`].join(`
1388
1389
  `)),await prompts().confirm(`Delete workspace "${current.name}" (${workspaceId})? This is irreversible.`)||fail(EXIT.CANCELLED,"CANCELLED","Deletion cancelled.")}async function failDeletion2(client,status,error51,workspaceId){if(status===409){let holder=error51?.lockedBy;lockedFail(holder,workspaceId,`See who holds it with \`${CLI} workspace-lock check -w ${workspaceId}\`, then take it with \`${CLI} workspace-lock take -w ${workspaceId} --force\` and delete again.`,await currentUser(client))}apiFail(status,error51)}function workspaceCommand(){let ws=new Command("workspace").description("Manage workspaces");return ws.command("list").description("List workspaces").option("--team <teamId>",SCOPE_TEAM).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,LIST_DOC13))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),resolved=await resolveParams(["team"],{team:opts.team},{client,interactive:canPrompt()}),{data,response,error:error51}=await withSpinner("Fetching workspaces",()=>client.GET("/v1/team/{teamId}/workspaces",{params:{path:{teamId:resolved.team??""}}}));(!response.ok||!data)&&apiFail(response.status,error51),ok(data,{human:d=>({workspaces:tableRows(["id","name","description","language","remoteWorkspaceEnabled","visibility","incomingApps","outgoingApps","createdFromTemplate"],d.workspaces.map(w=>({...w,incomingApps:w.incomingApps.join(", "),outgoingApps:w.outgoingApps.join(", ")})))})})}),ws.command("create").description("Create a workspace, optionally from another workspace or a published template").option("--team <teamId>",SCOPE_TEAM).option("--name <name>","Workspace name (required unless --input, interactive)").option("--description <text>","Workspace description (optional, interactive)").option("--source-workspace-id <id>","Clone from the specified workspace, whose language is used (optional, interactive, exclusive with --source-template-id)").option("--source-template-id <id>",`Create from the specified published template, whose language is used, as listed by ${CLI} template list (optional, exclusive with --source-workspace-id)`).option("--language <lang>","Scripting language: js, ts, or ts-strict (optional, interactive, API default: ts, ignored with --source-workspace-id or --source-template-id)").option("--visibility <mode>","Sharing mode: public or private (optional, interactive, API default: private)").option("--input <file>",INPUT_BODY).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CREATE_DOC12))return;let globals=cmd.optsWithGlobals();assertOneSource2(opts);let client=await apiClient(globals.instance),teamId=(await resolveParams(["team"],{team:opts.team??globals.team},{client,interactive:canPrompt()})).team??"",rawBody=opts.input?readInput(opts.input):!opts.name&&canPrompt()?await fillCreateBody4(client,teamId,opts):stripUndefined({name:opts.name,description:opts.description,sourceWorkspaceId:opts.sourceWorkspaceId,sourceTemplateId:opts.sourceTemplateId,language:assertChoice("--language",opts.language,LANGUAGES),visibility:assertChoice("--visibility",opts.visibility,VISIBILITIES)}),body=assertWorkspaceBody(validate(createBodySchema12,rawBody)),{data,response,error:error51}=await withSpinner("Creating workspace",()=>client.POST("/v1/team/{teamId}/workspace",{params:{path:{teamId}},body}));(!response.ok||!data)&&apiFail(response.status,error51),okMutation("Workspace created",data,data)}),ws.command("get").description("Get a single workspace").argument("[workspaceId]",SCOPE_WORKSPACE).option("--team <teamId>",SCOPE_TEAM_SEARCHED).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,GET_DOC12))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),resolved=await resolveParams(["workspace"],{team:opts.team??globals.team,workspace:idArg??globals.workspace},{client,interactive:canPrompt(),missing:MISSING_WORKSPACE,...idArg===void 0?{}:{blame:BLAME_WORKSPACE}}),workspaceId=resolved.workspace??"",teamId=resolved.team,located=teamId===void 0?await locateWorkspace(client,void 0,workspaceId):void 0;teamId===void 0&&!located&&fail(EXIT.NOT_FOUND,"NOT_FOUND",`No workspace ${workspaceId} in any of your teams.`,{status:404});let data=located?located.workspace:await fetchWorkspace(client,teamId??"",workspaceId);ok(data,{human:d=>({...d,incomingApps:d.incomingApps.join(", "),outgoingApps:d.outgoingApps.join(", ")})})}),ws.command("update").description("Update a workspace").argument("[workspaceId]","Workspace ID (required, interactive, session default, env SR_CONNECT_CLI_WORKSPACE)").option("--team <teamId>","Team ID \u2014 the workspace's team, or a new team to move it to; only the flag itself can move, a session default or environment variable never does (required, interactive, session default, env SR_CONNECT_CLI_TEAM)").option("--name <name>","New workspace name (optional, interactive, default: the current name)").option("--description <text>",'New workspace description; "" clears it (optional, interactive, default: the current description)').option("--language <lang>","Scripting language: js, ts, or ts-strict (optional, interactive, default: the current language)").option("--visibility <mode>","Sharing mode: public or private; a move to another team makes the workspace private unless this says otherwise (optional, interactive, default: the current mode)").option("--yes",CONFIRM_MOVE_YES).option("--input <file>",INPUT_BODY).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,UPDATE_DOC12))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),resolved=await resolveParams(["team","workspace"],{team:opts.team??globals.team,workspace:idArg??globals.workspace},{client,interactive:canPrompt(),missing:MISSING_WORKSPACE,...idArg===void 0?{}:{blame:BLAME_WORKSPACE}}),teamId=resolved.team??"",workspaceId=resolved.workspace??"",{name,description,language,visibility}=opts,interactive=[name,description,language,visibility].every(v2=>v2===void 0)&&opts.input===void 0&&canPrompt(),located=await locateWorkspace(client,teamId,workspaceId);located||fail(EXIT.NOT_FOUND,"NOT_FOUND",`Workspace '${workspaceId}' is not in team '${teamId}', or in any other team you are a member of.`,{status:404});let current=located.workspace,moving=located.teamId!==teamId?located:void 0;moving&&(opts.team===void 0&&fail(EXIT.USAGE,"TEAM_MISMATCH",`Workspace "${moving.workspace.name}" is in team ${teamLabel(moving)}, but this run took --team ${teamId} from a default rather than the flag, and only the flag can move a workspace.`,{hint:`Pass --team ${moving.teamId} to update it where it is, or --team ${teamId} to move it there.`}),await confirmMove(moving,teamId,opts.yes===!0));let body;if(opts.input)body=assertWorkspaceBody(validate(updateBodySchema12,readInput(opts.input)));else{if(interactive){let walked=await fillUpdateBody2(current,!!moving);name=walked.name,description=walked.description,language=walked.language,visibility=walked.visibility}else!moving&&!name&&description===void 0&&!language&&!visibility&&failNothingToUpdate(["--name","--description","--language","--visibility","--input"]),name||(name=current.name),description??=current.description;body=assertWorkspaceBody(validate(updateBodySchema12,stripUndefined({name,description,language,visibility})))}moving&&current.visibility==="public"&&body.visibility===void 0&&warnLine(`\u26A0 Moving a workspace makes it private unless the update names a visibility.
1389
- Pass --visibility public to keep it public.`);let{response,error:error51}=await withSpinner("Updating workspace",()=>client.PUT("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}},body}));response.ok||apiFail(response.status,error51);let sent=body;await syncWorkspaceSettings(workspaceId,{...sent.name===void 0?{}:{name:sent.name},...sent.language===void 0?{}:{language:sent.language}}),okMutation("Workspace updated",{updated:!0,id:workspaceId})}),ws.command("delete").description("Delete a workspace").argument("[workspaceId]",SCOPE_WORKSPACE_DESTRUCTIVE).option("--team <teamId>",SCOPE_TEAM_DESTRUCTIVE).option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,DELETE_DOC11))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),resolved=await resolveParams(["team","workspace"],{team:opts.team??globals.team,workspace:idArg??globals.workspace},{client,interactive:canPrompt(),useSession:canPrompt(),missing:MISSING_WORKSPACE,...idArg===void 0?{}:{blame:BLAME_WORKSPACE}}),teamId=resolved.team??"",workspaceId=resolved.workspace??"";opts.yes||(canPrompt()||failNeedsYes(`workspace ${workspaceId}`),await confirmDeletion4(client,teamId,workspaceId));let{response,error:error51}=await withSpinner("Deleting workspace",()=>client.DELETE("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));response.ok||await failDeletion2(client,response.status,error51,workspaceId),forgetWorkspaceLock(workspaceId);let removed=forgetScopeValue("workspace",workspaceId,["environment"]);if(removed.length>0){let what=removed.includes("environment")?"workspace and its environment":"workspace";prompts().note(`Removed the deleted ${what} from this shell's session defaults (${CLI} cli set-session to store another).`)}okMutation("Workspace deleted",{deleted:!0,id:workspaceId})}),ws}var CHECK_DOC=defineCommandDoc("workspace-lock check",{rules:["The workspace is -w and there is no positional argument: a workspace holds at most one lock, so there is nothing to name."],notes:["Reports who holds the lock, how they took it, and when the lease lapses. A held lock is exit 0 \u2014 the read succeeded \u2014 and leads with a neutral `\u2139 Workspace lock is taken.` above the rows.","Nobody holding it is exit 4 NO_WORKSPACE_LOCK, printed green with a \u2714: for a script polling for a free workspace that is the good answer, and the code is what to branch on."]}),TAKE_DOC=defineCommandDoc("workspace-lock take",{rules:["--force takes the lock even though another session holds it, which makes a browser tab lose edit control at once. Never pass it on your own when the holder is somebody else: stop and ask. A refusal naming you as the holder is the exception, and its hint says so.","--lock-id names the ID to take or renew rather than generating one, and it is the one place an explicit ID is stored for the rest of the shell session; every other command presents it and stores nothing."],notes:["Takes the lock and keeps it for the rest of the shell session, so the writes that follow renew it rather than taking their own. Re-running renews rather than replaces.","The document adds lockId, which no read reports, for --lock-id elsewhere.","Another holder is exit 1 WORKSPACE_LOCKED without --force.","A lock renews only through writes and lapses without them. Trust the lapse time the command prints over any number written down elsewhere."]}),RELEASE_DOC=defineCommandDoc("workspace-lock release",{rules:["--lock-id releases the lock of that ID rather than the one this shell took; the same flag every command accepts, read here whichever side of the verb it is on. Required when this shell holds none."],notes:["Only the session that took a lock can release it. A workspace nobody holds is exit 4; an ID that is not what holds the workspace is exit 1 WORKSPACE_LOCK_NOT_HELD, which means either another session of yours has it under a different ID or another user does \u2014 the refusal says which. Nothing is released either way.","Releasing early is the polite thing to do: the alternative is leaving somebody locked out until the lease lapses."]});function withScope8(cmd){return cmd.option("-w, --workspace <workspaceId>",SCOPE_WORKSPACE).option("--team <teamId>",SCOPE_TEAM_FILTER)}async function resolveScope11(globals){let client=await apiClient(globals.instance),resolved=await resolveParams(["workspace"],{workspace:globals.workspace,team:globals.team},{client,interactive:canPrompt()});return{client,workspace:resolved.workspace??""}}function lockReadFail(status,error51,workspaceId){let message=error51?.errorMessage??"";status===404&&/lock not found/i.test(message)&&fail(EXIT.NOT_FOUND,"NO_WORKSPACE_LOCK","Nobody holds the lock on this workspace.",{status,tone:"ok",hint:`Take it with \`${CLI} workspace-lock take -w ${workspaceId}\`.`}),apiFail(status,error51)}function renderLock(lock,me2,extra={}){return renderDetail({workspaceId:lock.workspaceId,source:lock.source,acquiredAt:lock.acquiredAt,expiresAt:expiryCell(lock.expiresAt),holder:holderCell(lock.holder,me2),...extra})}function workspaceLockCommand(){let lock=new Command("workspace-lock").alias("wl").description("Manage workspace locks");return withScope8(lock.command("check").description("Check who holds the workspace lock (exit 4 when nobody does)")).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CHECK_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),result=await withSpinner("Reading the workspace lock",()=>readLock(scope2.client,scope2.workspace));result.lock||lockReadFail(result.status,result.error,scope2.workspace);let me2=isRaw()?void 0:await currentUser(scope2.client),lockDoc=result.lock;isRaw()||console.error("\u2139 Workspace lock is taken."),ok(lockDoc,{human:()=>renderLock(lockDoc,me2)})}),withScope8(lock.command("take").description("Take the workspace lock, or renew one this shell already holds; kept for the rest of the shell session")).option("--force","Take the lock even though another session holds it \u2014 a web application session loses edit control and is warned about unsaved changes (optional, interactive)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,TAKE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),lockId=explicitLockId()??ownStoredLock(scope2.workspace)?.lockId??newLockId(),result=await withSpinner("Taking the workspace lock",()=>takeLock(scope2.client,scope2.workspace,{lockId,force:opts.force}));if(result.conflict){let holder=result.conflict===!0?void 0:result.conflict;canPrompt()||lockedFail(holder,scope2.workspace,void 0,await currentUser(scope2.client)),await askLockConflict(holder,await currentUser(scope2.client),{allowUnlocked:!1})!=="force"&&fail(EXIT.CANCELLED,"CANCELLED","Cancelled."),result=await withSpinner("Taking the workspace lock",()=>takeLock(scope2.client,scope2.workspace,{lockId,force:!0}))}result.lock||apiFail(result.status,result.error),storeTaken(scope2.workspace,lockId,result.lock.expiresAt);let human=isRaw()?"":renderLock(result.lock,await currentUser(scope2.client),{lockId});okMutation("Workspace lock taken",{...result.lock,lockId},human),isRaw()||console.error(`Held for this shell session. Release it with \`${CLI} workspace-lock release -w ${scope2.workspace}\`.`)}),withScope8(lock.command("release").description("Release the workspace lock, rather than waiting for the lease to lapse")).option("--lock-id <lockId>","Lock ID to release; the same flag every command accepts, read here whichever side of the verb it is on (required unless this shell holds one, env SR_CONNECT_CLI_LOCK_ID, default: the lock this shell took)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,RELEASE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),stored=ownStoredLock(scope2.workspace,"read")?.lockId,lockId=opts.lockId??explicitLockId()??stored;lockId||fail(EXIT.USAGE,"USAGE_ERROR","No workspace lock to release: this shell holds none. Pass --lock-id, or set SR_CONNECT_CLI_LOCK_ID.");let result=await withSpinner("Releasing the workspace lock",()=>releaseLock(scope2.client,scope2.workspace,lockId));if(lockId===stored&&(result.ok||result.status===404)&&forgetWorkspaceLock(scope2.workspace),result.status===409){let holder=result.error?.lockedBy;releaseFail(holder,scope2.workspace,lockId,await currentUser(scope2.client))}result.ok||apiFail(result.status,result.error),okMutation("Workspace lock released",{deleted:!0,id:lockId,workspaceId:scope2.workspace},renderDetail({workspaceId:scope2.workspace}))}),lock}var refusedBy;function positionalNamed(cmd,flag){let named=cmd?.registeredArguments.find(argument=>`--${argument.name().replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`===flag)?.name();if(named!==void 0)return named;let asPositional=SCOPE_POSITIONALS[flag];return asPositional!==void 0&&cmd?.registeredArguments.some(argument=>argument.name()===asPositional)?asPositional:void 0}var SCOPE_POSITIONALS={"-w":"workspaceId","--workspace":"workspaceId","-e":"environmentId","--env":"environmentId","--environment":"environmentId","--team":"teamId"};function scopeNamed(cmd,flag){if(SCOPE_POSITIONALS[flag]===void 0)return;let declared=(cmd?.options??[]).flatMap(option=>option.long!==void 0&&SCOPE_POSITIONALS[option.long]!==void 0?[option.long]:[]);return declared.length>0?declared:void 0}var MIN_SUFFIX_STEM=4;function suffixNamed(cmd,flag){let stem=flag.replace(/^--/,"");if(stem.length<MIN_SUFFIX_STEM)return;let matches=(cmd?.options??[]).map(option=>option.long).filter(long=>long!==void 0&&long!==flag&&long.endsWith(`-${stem}`));return matches.length===1?matches[0]:void 0}function nounOf2(name){return name.replace(/Id$/,"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase()}function valuedOptions(cmd){return(cmd?.options??[]).filter(option=>(option.required||option.optional)&&option.long!==void 0).map(option=>option.long??"")}function usageErrorOf(err,cmd=refusedBy){let raw=err.message.replace(/^error: /,""),quoted=/'([^']+)'/.exec(raw)?.[1],flag=quoted===void 0?void 0:/--[a-z][a-z-]*/.exec(quoted)?.[0]??quoted,path2=cmd===void 0?void 0:commandPath2(cmd);switch(err.code){case"commander.missingMandatoryOptionValue":return new CliError(EXIT.USAGE,"USAGE_ERROR",`${flag??"An option"} is required.`,{hint:supplyHint({ask:"be asked for it"})});case"commander.optionMissingArgument":{let value=quoted===void 0?void 0:/<[^>]+>/.exec(quoted)?.[0];return new CliError(EXIT.USAGE,"USAGE_ERROR",`${flag??"The option"} needs a value${value?` (${value})`:""}.`)}case"commander.unknownOption":{let suggestion=/\(Did you mean ([^?]+)\?\)/.exec(raw)?.[1],options="Add --help to the command to list its options.",positional=quoted===void 0?void 0:positionalNamed(cmd,quoted),suffix=quoted===void 0?void 0:suffixNamed(cmd,quoted),scope2=quoted===void 0?void 0:scopeNamed(cmd,quoted),lead=positional!==void 0&&path2!==void 0?`The ${nounOf2(positional)} is the positional argument: ${path2} <${positional}>.`:scope2!==void 0?`This verb's scope ${scope2.length===1?"flag is":"flags are"} ${scope2.join(" and ")}.`:(suffix??suggestion)!==void 0?`Did you mean ${suffix??suggestion}?`:void 0;return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${quoted??""}' is not an option here.`,{hint:lead===void 0?options:`${lead} ${options}`})}case"commander.excessArguments":{let options="Add --help to the command to list its options.";if(cmd!==void 0&&cmd.registeredArguments.length===0){let valued=valuedOptions(cmd),named=valued.length>0?`Name it with ${valued.join(" or ")}. `:"";return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${path2??"The command"}' takes no positional arguments.`,{hint:`${named}${options}`})}return new CliError(EXIT.USAGE,"USAGE_ERROR",raw.charAt(0).toUpperCase()+raw.slice(1),{hint:options})}case"commander.unknownCommand":{let suggestion=/\(Did you mean ([^?]+)\?\)/.exec(raw)?.[1],groups=`\`${CLI}\` lists the groups, and a group run alone lists its verbs.`;return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${quoted??""}' is not a command.`,{hint:suggestion?`Did you mean ${suggestion}? ${groups}`:groups})}case"commander.missingArgument":return new CliError(EXIT.USAGE,"USAGE_ERROR",`<${quoted??"argument"}> is required.`,{hint:supplyHint()});default:return new CliError(EXIT.USAGE,"USAGE_ERROR",raw.charAt(0).toUpperCase()+raw.slice(1))}}var program2=addGlobalOptions(new Command(CLI).description("CLI for ScriptRunner Connect")).exitOverride();program2.addCommand(apiConnectionCommand());program2.addCommand(appCommand());program2.addCommand(authCommand());program2.addCommand(cliCommand());program2.addCommand(connectorCommand());program2.addCommand(connectorSharingCommand());program2.addCommand(environmentCommand());program2.addCommand(environmentParameterCommand());program2.addCommand(eventListenerCommand());program2.addCommand(eventListenerTestPayloadCommand());program2.addCommand(eventQueueCommand());program2.addCommand(feedbackCommand());program2.addCommand(localWorkspaceCommand());program2.addCommand(logsCommand());program2.addCommand(packageCommand());program2.addCommand(workspaceReadmeCommand());program2.addCommand(workspaceReleaseCommand());program2.addCommand(scheduledTriggerCommand());program2.addCommand(scriptCommand());program2.addCommand(teamCommand());program2.addCommand(tempRemoteWorkspaceCommand());program2.addCommand(templateCommand());program2.addCommand(workspaceCommand());program2.addCommand(workspaceLockCommand());function overrideExits(cmd){cmd.exitOverride(err=>{throw refusedBy=cmd,err}),cmd.configureOutput({outputError:()=>{},writeErr:str=>{process.stdout.write(str)}});for(let sub of cmd.commands)overrideExits(sub)}overrideExits(program2);applyHelpConventions(program2);program2.addHelpText("after",rootHelpFooter());function commandPath2(cmd){let names=[];for(let c=cmd;c.parent;c=c.parent)names.unshift(c.name());return names.join(" ")}program2.hook("preAction",(thisCommand,actionCommand)=>{let globals=thisCommand.optsWithGlobals();configureRawMode({enabled:!!globals.raw}),setCommandPath(commandPath2(actionCommand)),configureAgentMode({enabled:!!globals.agent}),setPromptsAllowed(globals.prompts!==!1&&!process.env.SR_CONNECT_CLI_NO_PROMPTS),setOutputCopy(globals.copyOutputToFile),configureSession({instance:globals.instance,enabled:globals.session!==!1}),configureRecorder({enabled:globals.recordApiCalls!==!1,instance:globals.instance}),configureWorkspaceLocking({enabled:globals.lock!==!1,lockId:globals.lockId}),configureLocalSync({enabled:globals.localSync!==!1,instance:globals.instance}),configureLocalWorkspaceScope({enabled:globals.localWorkspace!==!1,instance:globals.instance}),configureVersionGate({enabled:globals.versionGate!==!1}),configureCrashReports({enabled:globals.crashReports!==!1,instance:globals.instance}),configureAgenticFeedback({enabled:globals.agenticFeedback!==!1})});try{ignoreBrokenPipe(),warnIfNodeUnsupported(),configureRawMode({enabled:process.argv.includes("--raw")});let commandNames=program2.commands.flatMap(c=>[c.name(),...c.aliases()]);assertOutputCopyValue(process.argv,commandNames),assertVersionFlagIsRoot(process.argv,commandNames),configureUpdateCheck({enabled:!process.argv.includes("--no-update-check")}),configureCrashReports({enabled:!process.argv.includes("--no-crash-reports")}),printUpdateNotice(),startUpdateCheck(),await program2.parseAsync(process.argv),reportOutputCopy(),await flushOutput(),process.exit(EXIT.OK)}catch(err){if(err instanceof CliError){err.exitCode===EXIT.NOT_FOUND&&warnInheritedWorkspace();let code2=reportError(err);reportOutputCopy(),await offerCrashReport(err),await flushOutput(),process.exit(code2)}if(err instanceof CommanderError){(err.code==="commander.helpDisplayed"||err.code==="commander.version"||err.code==="commander.help")&&(await flushOutput(),process.exit(err.exitCode===1?0:err.exitCode));let code2=reportError(usageErrorOf(err));reportOutputCopy(),await flushOutput(),process.exit(code2)}let message=err instanceof Error?err.message:String(err),code=reportError(new CliError(EXIT.API_ERROR,"UNEXPECTED_ERROR",message));reportOutputCopy(),await offerCrashReport(err),await flushOutput(),process.exit(code)}
1390
+ Pass --visibility public to keep it public.`);let{response,error:error51}=await withSpinner("Updating workspace",()=>client.PUT("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}},body}));response.ok||apiFail(response.status,error51);let sent=body;await syncWorkspaceSettings(workspaceId,{...sent.name===void 0?{}:{name:sent.name},...sent.language===void 0?{}:{language:sent.language}}),okMutation("Workspace updated",{updated:!0,id:workspaceId})}),ws.command("delete").description("Delete a workspace").argument("[workspaceId]",SCOPE_WORKSPACE_DESTRUCTIVE).option("--team <teamId>",SCOPE_TEAM_DESTRUCTIVE).option("--yes",CONFIRM_YES).option("--explain",EXPLAIN).action(async(idArg,opts,cmd)=>{if(explained(cmd,DELETE_DOC11))return;let globals=cmd.optsWithGlobals(),client=await apiClient(globals.instance),resolved=await resolveParams(["team","workspace"],{team:opts.team??globals.team,workspace:idArg??globals.workspace},{client,interactive:canPrompt(),useSession:canPrompt(),missing:MISSING_WORKSPACE,...idArg===void 0?{}:{blame:BLAME_WORKSPACE}}),teamId=resolved.team??"",workspaceId=resolved.workspace??"";opts.yes||(canPrompt()||failNeedsYes(`workspace ${workspaceId}`),await confirmDeletion4(client,teamId,workspaceId));let{response,error:error51}=await withSpinner("Deleting workspace",()=>client.DELETE("/v1/team/{teamId}/workspace/{workspaceId}",{params:{path:{teamId,workspaceId}}}));response.ok||await failDeletion2(client,response.status,error51,workspaceId),forgetWorkspaceLock(workspaceId);let removed=forgetScopeValue("workspace",workspaceId,["environment"]);if(removed.length>0){let what=removed.includes("environment")?"workspace and its environment":"workspace";prompts().note(`Removed the deleted ${what} from this shell's session defaults (${CLI} cli set-session to store another).`)}okMutation("Workspace deleted",{deleted:!0,id:workspaceId})}),ws}var CHECK_DOC=defineCommandDoc("workspace-lock check",{rules:["The workspace is -w and there is no positional argument: a workspace holds at most one lock, so there is nothing to name."],notes:["Reports who holds the lock, how they took it, and when the lease lapses. A held lock is exit 0 \u2014 the read succeeded \u2014 and leads with a neutral `\u2139 Workspace lock is taken.` above the rows.","Nobody holding it is exit 4 NO_WORKSPACE_LOCK, printed green with a \u2714: for a script polling for a free workspace that is the good answer, and the code is what to branch on."]}),TAKE_DOC=defineCommandDoc("workspace-lock take",{rules:["--force takes the lock even though another session holds it, which makes a browser tab lose edit control at once. Never pass it on your own when the holder is somebody else: stop and ask. A refusal naming you as the holder is the exception, and its hint says so.","--lock-id names the ID to take or renew rather than generating one, and it is the one place an explicit ID is stored for the rest of the shell session; every other command presents it and stores nothing."],notes:["Takes the lock and keeps it for the rest of the shell session, so the writes that follow renew it rather than taking their own. Re-running renews rather than replaces.","The document adds lockId, which no read reports, for --lock-id elsewhere.","Another holder is exit 1 WORKSPACE_LOCKED without --force.","A lock renews only through writes and lapses without them. Trust the lapse time the command prints over any number written down elsewhere."]}),RELEASE_DOC=defineCommandDoc("workspace-lock release",{rules:["--lock-id releases the lock of that ID rather than the one this shell took; the same flag every command accepts, read here whichever side of the verb it is on. Required when this shell holds none."],notes:["Only the session that took a lock can release it. A workspace nobody holds is exit 4; an ID that is not what holds the workspace is exit 1 WORKSPACE_LOCK_NOT_HELD, which means either another session of yours has it under a different ID or another user does \u2014 the refusal says which. Nothing is released either way.","Releasing early is the polite thing to do: the alternative is leaving somebody locked out until the lease lapses."]});function withScope8(cmd){return cmd.option("-w, --workspace <workspaceId>",SCOPE_WORKSPACE).option("--team <teamId>",SCOPE_TEAM_FILTER)}async function resolveScope11(globals){let client=await apiClient(globals.instance),resolved=await resolveParams(["workspace"],{workspace:globals.workspace,team:globals.team},{client,interactive:canPrompt()});return{client,workspace:resolved.workspace??""}}function lockReadFail(status,error51,workspaceId){let message=error51?.errorMessage??"";status===404&&/lock not found/i.test(message)&&fail(EXIT.NOT_FOUND,"NO_WORKSPACE_LOCK","Nobody holds the lock on this workspace.",{status,tone:"ok",hint:`Take it with \`${CLI} workspace-lock take -w ${workspaceId}\`.`}),apiFail(status,error51)}function renderLock(lock,me2,extra={}){return renderDetail({workspaceId:lock.workspaceId,source:lock.source,acquiredAt:lock.acquiredAt,expiresAt:expiryCell(lock.expiresAt),holder:holderCell(lock.holder,me2),...extra})}function workspaceLockCommand(){let lock=new Command("workspace-lock").alias("wl").description("Manage workspace locks");return withScope8(lock.command("check").description("Check who holds the workspace lock (exit 4 when nobody does)")).option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,CHECK_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),result=await withSpinner("Reading the workspace lock",()=>readLock(scope2.client,scope2.workspace));result.lock||lockReadFail(result.status,result.error,scope2.workspace);let me2=isRaw()?void 0:await currentUser(scope2.client),lockDoc=result.lock;isRaw()||console.error("\u2139 Workspace lock is taken."),ok(lockDoc,{human:()=>renderLock(lockDoc,me2)})}),withScope8(lock.command("take").description("Take the workspace lock, or renew one this shell already holds; kept for the rest of the shell session")).option("--force","Take the lock even though another session holds it \u2014 a web application session loses edit control and is warned about unsaved changes (optional, interactive)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,TAKE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),lockId=explicitLockId()??ownStoredLock(scope2.workspace)?.lockId??newLockId(),result=await withSpinner("Taking the workspace lock",()=>takeLock(scope2.client,scope2.workspace,{lockId,force:opts.force}));if(result.conflict){let holder=result.conflict===!0?void 0:result.conflict;canPrompt()||lockedFail(holder,scope2.workspace,void 0,await currentUser(scope2.client)),await askLockConflict(holder,await currentUser(scope2.client),{allowUnlocked:!1})!=="force"&&fail(EXIT.CANCELLED,"CANCELLED","Cancelled."),result=await withSpinner("Taking the workspace lock",()=>takeLock(scope2.client,scope2.workspace,{lockId,force:!0}))}result.lock||apiFail(result.status,result.error),storeTaken(scope2.workspace,lockId,result.lock.expiresAt);let human=isRaw()?"":renderLock(result.lock,await currentUser(scope2.client),{lockId});okMutation("Workspace lock taken",{...result.lock,lockId},human),isRaw()||console.error(`Held for this shell session. Release it with \`${CLI} workspace-lock release -w ${scope2.workspace}\`.`)}),withScope8(lock.command("release").description("Release the workspace lock, rather than waiting for the lease to lapse")).option("--lock-id <lockId>","Lock ID to release; the same flag every command accepts, read here whichever side of the verb it is on (required unless this shell holds one, env SR_CONNECT_CLI_LOCK_ID, default: the lock this shell took)").option("--explain",EXPLAIN).action(async(opts,cmd)=>{if(explained(cmd,RELEASE_DOC))return;let globals=cmd.optsWithGlobals(),scope2=await resolveScope11(globals),stored=ownStoredLock(scope2.workspace,"read")?.lockId,lockId=opts.lockId??explicitLockId()??stored;lockId||fail(EXIT.USAGE,"USAGE_ERROR","No workspace lock to release: this shell holds none. Pass --lock-id, or set SR_CONNECT_CLI_LOCK_ID.");let result=await withSpinner("Releasing the workspace lock",()=>releaseLock(scope2.client,scope2.workspace,lockId));if(lockId===stored&&(result.ok||result.status===404)&&forgetWorkspaceLock(scope2.workspace),result.status===409){let holder=result.error?.lockedBy;releaseFail(holder,scope2.workspace,lockId,await currentUser(scope2.client))}result.ok||apiFail(result.status,result.error),okMutation("Workspace lock released",{deleted:!0,id:lockId,workspaceId:scope2.workspace},renderDetail({workspaceId:scope2.workspace}))}),lock}var refusedBy;function positionalNamed(cmd,flag){let named=cmd?.registeredArguments.find(argument=>`--${argument.name().replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`===flag)?.name();if(named!==void 0)return named;let asPositional=SCOPE_POSITIONALS[flag];return asPositional!==void 0&&cmd?.registeredArguments.some(argument=>argument.name()===asPositional)?asPositional:void 0}var SCOPE_POSITIONALS={"-w":"workspaceId","--workspace":"workspaceId","-e":"environmentId","--env":"environmentId","--environment":"environmentId","--team":"teamId"};function scopeNamed(cmd,flag){if(SCOPE_POSITIONALS[flag]===void 0)return;let declared=(cmd?.options??[]).flatMap(option=>option.long!==void 0&&SCOPE_POSITIONALS[option.long]!==void 0?[option.long]:[]);return declared.length>0?declared:void 0}var MIN_SUFFIX_STEM=4;function suffixNamed(cmd,flag){let stem=flag.replace(/^--/,"");if(stem.length<MIN_SUFFIX_STEM)return;let matches=(cmd?.options??[]).map(option=>option.long).filter(long=>long!==void 0&&long!==flag&&long.endsWith(`-${stem}`));return matches.length===1?matches[0]:void 0}function nounOf2(name){return name.replace(/Id$/,"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase()}function valuedOptions(cmd){return(cmd?.options??[]).filter(option=>(option.required||option.optional)&&option.long!==void 0).map(option=>option.long??"")}function usageErrorOf(err,cmd=refusedBy){let raw=err.message.replace(/^error: /,""),quoted=/'([^']+)'/.exec(raw)?.[1],flag=quoted===void 0?void 0:/--[a-z][a-z-]*/.exec(quoted)?.[0]??quoted,path2=cmd===void 0?void 0:commandPath2(cmd);switch(err.code){case"commander.missingMandatoryOptionValue":return new CliError(EXIT.USAGE,"USAGE_ERROR",`${flag??"An option"} is required.`,{hint:supplyHint({ask:"be asked for it"})});case"commander.optionMissingArgument":{let value=quoted===void 0?void 0:/<[^>]+>/.exec(quoted)?.[0];return new CliError(EXIT.USAGE,"USAGE_ERROR",`${flag??"The option"} needs a value${value?` (${value})`:""}.`)}case"commander.unknownOption":{let suggestion=/\(Did you mean ([^?]+)\?\)/.exec(raw)?.[1],options="Add --help to the command to list its options.",positional=quoted===void 0?void 0:positionalNamed(cmd,quoted),suffix=quoted===void 0?void 0:suffixNamed(cmd,quoted),scope2=quoted===void 0?void 0:scopeNamed(cmd,quoted),lead=positional!==void 0&&path2!==void 0?`The ${nounOf2(positional)} is the positional argument: ${path2} <${positional}>.`:scope2!==void 0?`This verb's scope ${scope2.length===1?"flag is":"flags are"} ${scope2.join(" and ")}.`:(suffix??suggestion)!==void 0?`Did you mean ${suffix??suggestion}?`:void 0;return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${quoted??""}' is not an option here.`,{hint:lead===void 0?options:`${lead} ${options}`})}case"commander.excessArguments":{let options="Add --help to the command to list its options.";if(cmd!==void 0&&cmd.registeredArguments.length===0){let valued=valuedOptions(cmd),named=valued.length>0?`Name it with ${valued.join(" or ")}. `:"";return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${path2??"The command"}' takes no positional arguments.`,{hint:`${named}${options}`})}return new CliError(EXIT.USAGE,"USAGE_ERROR",raw.charAt(0).toUpperCase()+raw.slice(1),{hint:options})}case"commander.unknownCommand":{let suggestion=/\(Did you mean ([^?]+)\?\)/.exec(raw)?.[1],groups=`\`${CLI}\` lists the groups, and a group run alone lists its verbs.`;return new CliError(EXIT.USAGE,"USAGE_ERROR",`'${quoted??""}' is not a command.`,{hint:suggestion?`Did you mean ${suggestion}? ${groups}`:groups})}case"commander.missingArgument":return new CliError(EXIT.USAGE,"USAGE_ERROR",`<${quoted??"argument"}> is required.`,{hint:supplyHint()});default:return new CliError(EXIT.USAGE,"USAGE_ERROR",raw.charAt(0).toUpperCase()+raw.slice(1))}}var program2=addGlobalOptions(new Command(CLI).description("CLI for ScriptRunner Connect")).exitOverride();program2.addCommand(apiConnectionCommand());program2.addCommand(appCommand());program2.addCommand(authCommand());program2.addCommand(cliCommand());program2.addCommand(connectorCommand());program2.addCommand(connectorSharingCommand());program2.addCommand(environmentCommand());program2.addCommand(environmentParameterCommand());program2.addCommand(eventListenerCommand());program2.addCommand(eventListenerTestPayloadCommand());program2.addCommand(eventQueueCommand());program2.addCommand(feedbackCommand());program2.addCommand(localWorkspaceCommand());program2.addCommand(logsCommand());program2.addCommand(packageCommand());program2.addCommand(workspaceReadmeCommand());program2.addCommand(workspaceReleaseCommand());program2.addCommand(scheduledTriggerCommand());program2.addCommand(scriptCommand());program2.addCommand(teamCommand());program2.addCommand(tempRemoteWorkspaceCommand());program2.addCommand(templateCommand());program2.addCommand(workspaceCommand());program2.addCommand(workspaceLockCommand());function overrideExits(cmd){cmd.exitOverride(err=>{throw refusedBy=cmd,err}),cmd.configureOutput({outputError:()=>{},writeErr:str=>{process.stdout.write(str)}});for(let sub of cmd.commands)overrideExits(sub)}overrideExits(program2);applyHelpConventions(program2);program2.addHelpText("after",rootHelpFooter());function commandPath2(cmd){let names=[];for(let c=cmd;c.parent;c=c.parent)names.unshift(c.name());return names.join(" ")}program2.hook("preAction",(thisCommand,actionCommand)=>{let globals=thisCommand.optsWithGlobals();configureRawMode({enabled:!!globals.raw}),setCommandPath(commandPath2(actionCommand)),configureAgentMode({enabled:!!globals.agent}),setPromptsAllowed(globals.prompts!==!1&&!process.env.SR_CONNECT_CLI_NO_PROMPTS),setOutputCopy(globals.copyOutputToFile),configureSession({instance:globals.instance,enabled:globals.session!==!1}),configureRecorder({enabled:globals.recordApiCalls!==!1,instance:globals.instance}),configureWorkspaceLocking({enabled:globals.lock!==!1,lockId:globals.lockId}),configureLocalSync({enabled:globals.localSync!==!1,instance:globals.instance}),configureLocalWorkspaceScope({enabled:globals.localWorkspace!==!1,instance:globals.instance}),configureVersionGate({enabled:globals.versionGate!==!1}),configureCrashReports({enabled:globals.crashReports!==!1,instance:globals.instance}),configureAgenticFeedback({enabled:globals.agenticFeedback!==!1})});try{ignoreBrokenPipe(),warnIfNodeUnsupported(),configureRawMode({enabled:process.argv.includes("--raw")});let commandNames=program2.commands.flatMap(c=>[c.name(),...c.aliases()]);assertOutputCopyValue(process.argv,commandNames),assertVersionFlagIsRoot(process.argv,commandNames),configureUpdateCheck({enabled:!process.argv.includes("--no-update-check")}),configureCrashReports({enabled:!process.argv.includes("--no-crash-reports")}),asksForUpdates(process.argv)||(printUpdateNotice(),startUpdateCheck()),await program2.parseAsync(process.argv),reportOutputCopy(),await flushOutput(),process.exit(EXIT.OK)}catch(err){if(err instanceof CliError){err.exitCode===EXIT.NOT_FOUND&&warnInheritedWorkspace();let code2=reportError(err);reportOutputCopy(),await offerCrashReport(err),await flushOutput(),process.exit(code2)}if(err instanceof CommanderError){(err.code==="commander.helpDisplayed"||err.code==="commander.version"||err.code==="commander.help")&&(await flushOutput(),process.exit(err.exitCode===1?0:err.exitCode));let code2=reportError(usageErrorOf(err));reportOutputCopy(),await flushOutput(),process.exit(code2)}let message=err instanceof Error?err.message:String(err),code=reportError(new CliError(EXIT.API_ERROR,"UNEXPECTED_ERROR",message));reportOutputCopy(),await offerCrashReport(err),await flushOutput(),process.exit(code)}
1390
1391
  /*! Bundled license information:
1391
1392
 
1392
1393
  promise-throttle-all/dist/index.mjs: