uptide 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { fileURLToPath as __uptideFileURLToPath } from 'node:url';
4
4
  const require = __uptideCreateRequire(import.meta.url);
5
5
  const __filename = __uptideFileURLToPath(import.meta.url);
6
6
  const __dirname = __uptideFileURLToPath(new URL('.', import.meta.url));
7
- import{CliError,EXIT,cleanRuns,depthOf,foldForDisplay,openPr,renderError,require_picocolors,runJob,updatePrBody}from"./chunk-L5ZAH6WD.js";import{compareVersions,createNpmFetcher,diffPackage,formatFix,isNativeProbeSkip,majorsBehind,migrationBody,planPackage,summaryCells,typescriptAdapter}from"./chunk-ZPE5ILXP.js";import{publishTarget}from"./chunk-NXKGLXJR.js";import{UptideError,__toESM,errorCode,uptideCommand}from"./chunk-W7QEZJ57.js";import"fs";import{basename as basename3,resolve as resolve5}from"path";var CommanderError=class extends Error{constructor(exitCode,code,message){super(message),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=code,this.exitCode=exitCode,this.nestedError=void 0}},InvalidArgumentError=class extends CommanderError{constructor(message){super(1,"commander.invalidArgument",message),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};var Argument=class{constructor(name,description){switch(this.description=description||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,name[0]){case"<":this.required=!0,this._name=name.slice(1,-1);break;case"[":this.required=!1,this._name=name.slice(1,-1);break;default:this.required=!0,this._name=name;break}this._name.endsWith("...")&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_collectValue(value,previous){return previous===this.defaultValue||!Array.isArray(previous)?[value]:(previous.push(value),previous)}default(value,description){return this.defaultValue=value,this.defaultValueDescription=description,this}argParser(fn){return this.parseArg=fn,this}choices(values){return this.argChoices=values.slice(),this.parseArg=(arg,previous)=>{if(!this.argChoices.includes(arg))throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(arg,previous):arg},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function humanReadableArgName(arg){let nameOutput=arg.name()+(arg.variadic===!0?"...":"");return arg.required?"<"+nameOutput+">":"["+nameOutput+"]"}import{EventEmitter}from"events";import childProcess from"child_process";import path from"path";import fs from"fs";import process2 from"process";import{stripVTControlCharacters as stripVTControlCharacters2}from"util";import{stripVTControlCharacters}from"util";var Help=class{constructor(){this.helpWidth=void 0,this.minWidthToWrap=40,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}prepareContext(contextOptions){this.helpWidth=this.helpWidth??contextOptions.helpWidth??80}visibleCommands(cmd){let visibleCommands=cmd.commands.filter(cmd2=>!cmd2._hidden),helpCommand=cmd._getHelpCommand();return helpCommand&&!helpCommand._hidden&&visibleCommands.push(helpCommand),this.sortSubcommands&&visibleCommands.sort((a,b)=>a.name().localeCompare(b.name())),visibleCommands}compareOptions(a,b){let getSortKey=option=>option.short?option.short.replace(/^-/,""):option.long.replace(/^--/,"");return getSortKey(a).localeCompare(getSortKey(b))}visibleOptions(cmd){let visibleOptions=cmd.options.filter(option=>!option.hidden),helpOption=cmd._getHelpOption();if(helpOption&&!helpOption.hidden){let removeShort=helpOption.short&&cmd._findOption(helpOption.short),removeLong=helpOption.long&&cmd._findOption(helpOption.long);!removeShort&&!removeLong?visibleOptions.push(helpOption):helpOption.long&&!removeLong?visibleOptions.push(cmd.createOption(helpOption.long,helpOption.description)):helpOption.short&&!removeShort&&visibleOptions.push(cmd.createOption(helpOption.short,helpOption.description))}return this.sortOptions&&visibleOptions.sort(this.compareOptions),visibleOptions}visibleGlobalOptions(cmd){if(!this.showGlobalOptions)return[];let globalOptions=[];for(let ancestorCmd=cmd.parent;ancestorCmd;ancestorCmd=ancestorCmd.parent){let visibleOptions=ancestorCmd.options.filter(option=>!option.hidden);globalOptions.push(...visibleOptions)}return this.sortOptions&&globalOptions.sort(this.compareOptions),globalOptions}visibleArguments(cmd){return cmd._argsDescription&&cmd.registeredArguments.forEach(argument=>{argument.description=argument.description||cmd._argsDescription[argument.name()]||""}),cmd.registeredArguments.find(argument=>argument.description)?cmd.registeredArguments:[]}subcommandTerm(cmd){let args=cmd.registeredArguments.map(arg=>humanReadableArgName(arg)).join(" ");return cmd._name+(cmd._aliases[0]?"|"+cmd._aliases[0]:"")+(cmd.options.length?" [options]":"")+(args?" "+args:"")}optionTerm(option){return option.flags}argumentTerm(argument){return argument.name()}longestSubcommandTermLength(cmd,helper){return helper.visibleCommands(cmd).reduce((max,command)=>Math.max(max,this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command)))),0)}longestOptionTermLength(cmd,helper){return helper.visibleOptions(cmd).reduce((max,option)=>Math.max(max,this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))),0)}longestGlobalOptionTermLength(cmd,helper){return helper.visibleGlobalOptions(cmd).reduce((max,option)=>Math.max(max,this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))),0)}longestArgumentTermLength(cmd,helper){return helper.visibleArguments(cmd).reduce((max,argument)=>Math.max(max,this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument)))),0)}commandUsage(cmd){let cmdName=cmd._name;cmd._aliases[0]&&(cmdName=cmdName+"|"+cmd._aliases[0]);let ancestorCmdNames="";for(let ancestorCmd=cmd.parent;ancestorCmd;ancestorCmd=ancestorCmd.parent)ancestorCmdNames=ancestorCmd.name()+" "+ancestorCmdNames;return ancestorCmdNames+cmdName+" "+cmd.usage()}commandDescription(cmd){return cmd.description()}subcommandDescription(cmd){return cmd.summary()||cmd.description()}optionDescription(option){let extraInfo=[];if(option.argChoices&&extraInfo.push(`choices: ${option.argChoices.map(choice=>JSON.stringify(choice)).join(", ")}`),option.defaultValue!==void 0&&(option.required||option.optional||option.isBoolean()&&typeof option.defaultValue=="boolean")&&extraInfo.push(`default: ${option.defaultValueDescription||JSON.stringify(option.defaultValue)}`),option.presetArg!==void 0&&option.optional&&extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`),option.envVar!==void 0&&extraInfo.push(`env: ${option.envVar}`),extraInfo.length>0){let extraDescription=`(${extraInfo.join(", ")})`;return option.description?`${option.description} ${extraDescription}`:extraDescription}return option.description}argumentDescription(argument){let extraInfo=[];if(argument.argChoices&&extraInfo.push(`choices: ${argument.argChoices.map(choice=>JSON.stringify(choice)).join(", ")}`),argument.defaultValue!==void 0&&extraInfo.push(`default: ${argument.defaultValueDescription||JSON.stringify(argument.defaultValue)}`),extraInfo.length>0){let extraDescription=`(${extraInfo.join(", ")})`;return argument.description?`${argument.description} ${extraDescription}`:extraDescription}return argument.description}formatItemList(heading,items,helper){return items.length===0?[]:[helper.styleTitle(heading),...items,""]}groupItems(unsortedItems,visibleItems,getGroup){let result=new Map;return unsortedItems.forEach(item=>{let group=getGroup(item);result.has(group)||result.set(group,[])}),visibleItems.forEach(item=>{let group=getGroup(item);result.has(group)||result.set(group,[]),result.get(group).push(item)}),result}formatHelp(cmd,helper){let termWidth=helper.padWidth(cmd,helper),helpWidth=helper.helpWidth??80;function callFormatItem(term,description){return helper.formatItem(term,termWidth,description,helper)}let output=[`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,""],commandDescription=helper.commandDescription(cmd);commandDescription.length>0&&(output=output.concat([helper.boxWrap(helper.styleCommandDescription(commandDescription),helpWidth),""]));let argumentList=helper.visibleArguments(cmd).map(argument=>callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)),helper.styleArgumentDescription(helper.argumentDescription(argument))));if(output=output.concat(this.formatItemList("Arguments:",argumentList,helper)),this.groupItems(cmd.options,helper.visibleOptions(cmd),option=>option.helpGroupHeading??"Options:").forEach((options,group)=>{let optionList=options.map(option=>callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)),helper.styleOptionDescription(helper.optionDescription(option))));output=output.concat(this.formatItemList(group,optionList,helper))}),helper.showGlobalOptions){let globalOptionList=helper.visibleGlobalOptions(cmd).map(option=>callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)),helper.styleOptionDescription(helper.optionDescription(option))));output=output.concat(this.formatItemList("Global Options:",globalOptionList,helper))}return this.groupItems(cmd.commands,helper.visibleCommands(cmd),sub=>sub.helpGroup()||"Commands:").forEach((commands,group)=>{let commandList=commands.map(sub=>callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)),helper.styleSubcommandDescription(helper.subcommandDescription(sub))));output=output.concat(this.formatItemList(group,commandList,helper))}),output.join(`
7
+ import{BUILD_HOST,BUILD_KEY,COMMANDS,NAME_PATTERN,VERSION_PATTERN,atomicJson,buildEvent,captureUrl,enabled,identity,isCi,readSettings,sanitizeEvent,settingsPath}from"./chunk-S5MVBT7A.js";import{ACCEPTED_KEYS,CliError,EXIT,INVOCATION,PRICE_DATE,VERSION,cleanRuns,depthOf,explain,fixPreflight,foldForDisplay,listDependencies,openPr,priceFor,renderError,require_picocolors,runJob,runnable,selectLlm,updatePrBody}from"./chunk-AGUD7WFB.js";import{BY,TIER_LEGEND,buildToolMajor,compareVersions,createNpmFetcher,defaultCacheDir,diffPackage,formatFix,isFailure,isNativeProbeSkip,majorsBehind,migrationBody,planPackage,summaryCells,typescriptAdapter,verdictOf,workerHeapMb}from"./chunk-2QJIOZA7.js";import"./chunk-GHXBU767.js";import{publishTarget}from"./chunk-VHIIYAJM.js";import{UptideError,errorCode}from"./chunk-W74OVIU4.js";import"./chunk-JHZ22Y6X.js";import{__toESM}from"./chunk-Z5YHBDVG.js";import{readFileSync as readFileSync7}from"fs";import{basename as basename5,resolve as resolve7}from"path";var CommanderError=class extends Error{constructor(exitCode,code,message){super(message),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=code,this.exitCode=exitCode,this.nestedError=void 0}},InvalidArgumentError=class extends CommanderError{constructor(message){super(1,"commander.invalidArgument",message),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};var Argument=class{constructor(name,description){switch(this.description=description||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,name[0]){case"<":this.required=!0,this._name=name.slice(1,-1);break;case"[":this.required=!1,this._name=name.slice(1,-1);break;default:this.required=!0,this._name=name;break}this._name.endsWith("...")&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_collectValue(value,previous){return previous===this.defaultValue||!Array.isArray(previous)?[value]:(previous.push(value),previous)}default(value,description){return this.defaultValue=value,this.defaultValueDescription=description,this}argParser(fn){return this.parseArg=fn,this}choices(values){return this.argChoices=values.slice(),this.parseArg=(arg,previous)=>{if(!this.argChoices.includes(arg))throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(arg,previous):arg},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function humanReadableArgName(arg){let nameOutput=arg.name()+(arg.variadic===!0?"...":"");return arg.required?"<"+nameOutput+">":"["+nameOutput+"]"}import{EventEmitter}from"events";import childProcess from"child_process";import path from"path";import fs from"fs";import process2 from"process";import{stripVTControlCharacters as stripVTControlCharacters2}from"util";import{stripVTControlCharacters}from"util";var Help=class{constructor(){this.helpWidth=void 0,this.minWidthToWrap=40,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}prepareContext(contextOptions){this.helpWidth=this.helpWidth??contextOptions.helpWidth??80}visibleCommands(cmd){let visibleCommands=cmd.commands.filter(cmd2=>!cmd2._hidden),helpCommand=cmd._getHelpCommand();return helpCommand&&!helpCommand._hidden&&visibleCommands.push(helpCommand),this.sortSubcommands&&visibleCommands.sort((a,b)=>a.name().localeCompare(b.name())),visibleCommands}compareOptions(a,b){let getSortKey=option=>option.short?option.short.replace(/^-/,""):option.long.replace(/^--/,"");return getSortKey(a).localeCompare(getSortKey(b))}visibleOptions(cmd){let visibleOptions=cmd.options.filter(option=>!option.hidden),helpOption=cmd._getHelpOption();if(helpOption&&!helpOption.hidden){let removeShort=helpOption.short&&cmd._findOption(helpOption.short),removeLong=helpOption.long&&cmd._findOption(helpOption.long);!removeShort&&!removeLong?visibleOptions.push(helpOption):helpOption.long&&!removeLong?visibleOptions.push(cmd.createOption(helpOption.long,helpOption.description)):helpOption.short&&!removeShort&&visibleOptions.push(cmd.createOption(helpOption.short,helpOption.description))}return this.sortOptions&&visibleOptions.sort(this.compareOptions),visibleOptions}visibleGlobalOptions(cmd){if(!this.showGlobalOptions)return[];let globalOptions=[];for(let ancestorCmd=cmd.parent;ancestorCmd;ancestorCmd=ancestorCmd.parent){let visibleOptions=ancestorCmd.options.filter(option=>!option.hidden);globalOptions.push(...visibleOptions)}return this.sortOptions&&globalOptions.sort(this.compareOptions),globalOptions}visibleArguments(cmd){return cmd._argsDescription&&cmd.registeredArguments.forEach(argument=>{argument.description=argument.description||cmd._argsDescription[argument.name()]||""}),cmd.registeredArguments.find(argument=>argument.description)?cmd.registeredArguments:[]}subcommandTerm(cmd){let args=cmd.registeredArguments.map(arg=>humanReadableArgName(arg)).join(" ");return cmd._name+(cmd._aliases[0]?"|"+cmd._aliases[0]:"")+(cmd.options.length?" [options]":"")+(args?" "+args:"")}optionTerm(option){return option.flags}argumentTerm(argument){return argument.name()}longestSubcommandTermLength(cmd,helper){return helper.visibleCommands(cmd).reduce((max,command)=>Math.max(max,this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command)))),0)}longestOptionTermLength(cmd,helper){return helper.visibleOptions(cmd).reduce((max,option)=>Math.max(max,this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))),0)}longestGlobalOptionTermLength(cmd,helper){return helper.visibleGlobalOptions(cmd).reduce((max,option)=>Math.max(max,this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))),0)}longestArgumentTermLength(cmd,helper){return helper.visibleArguments(cmd).reduce((max,argument)=>Math.max(max,this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument)))),0)}commandUsage(cmd){let cmdName=cmd._name;cmd._aliases[0]&&(cmdName=cmdName+"|"+cmd._aliases[0]);let ancestorCmdNames="";for(let ancestorCmd=cmd.parent;ancestorCmd;ancestorCmd=ancestorCmd.parent)ancestorCmdNames=ancestorCmd.name()+" "+ancestorCmdNames;return ancestorCmdNames+cmdName+" "+cmd.usage()}commandDescription(cmd){return cmd.description()}subcommandDescription(cmd){return cmd.summary()||cmd.description()}optionDescription(option){let extraInfo=[];if(option.argChoices&&extraInfo.push(`choices: ${option.argChoices.map(choice=>JSON.stringify(choice)).join(", ")}`),option.defaultValue!==void 0&&(option.required||option.optional||option.isBoolean()&&typeof option.defaultValue=="boolean")&&extraInfo.push(`default: ${option.defaultValueDescription||JSON.stringify(option.defaultValue)}`),option.presetArg!==void 0&&option.optional&&extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`),option.envVar!==void 0&&extraInfo.push(`env: ${option.envVar}`),extraInfo.length>0){let extraDescription=`(${extraInfo.join(", ")})`;return option.description?`${option.description} ${extraDescription}`:extraDescription}return option.description}argumentDescription(argument){let extraInfo=[];if(argument.argChoices&&extraInfo.push(`choices: ${argument.argChoices.map(choice=>JSON.stringify(choice)).join(", ")}`),argument.defaultValue!==void 0&&extraInfo.push(`default: ${argument.defaultValueDescription||JSON.stringify(argument.defaultValue)}`),extraInfo.length>0){let extraDescription=`(${extraInfo.join(", ")})`;return argument.description?`${argument.description} ${extraDescription}`:extraDescription}return argument.description}formatItemList(heading,items,helper){return items.length===0?[]:[helper.styleTitle(heading),...items,""]}groupItems(unsortedItems,visibleItems,getGroup){let result=new Map;return unsortedItems.forEach(item=>{let group=getGroup(item);result.has(group)||result.set(group,[])}),visibleItems.forEach(item=>{let group=getGroup(item);result.has(group)||result.set(group,[]),result.get(group).push(item)}),result}formatHelp(cmd,helper){let termWidth=helper.padWidth(cmd,helper),helpWidth=helper.helpWidth??80;function callFormatItem(term,description){return helper.formatItem(term,termWidth,description,helper)}let output=[`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,""],commandDescription=helper.commandDescription(cmd);commandDescription.length>0&&(output=output.concat([helper.boxWrap(helper.styleCommandDescription(commandDescription),helpWidth),""]));let argumentList=helper.visibleArguments(cmd).map(argument=>callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)),helper.styleArgumentDescription(helper.argumentDescription(argument))));if(output=output.concat(this.formatItemList("Arguments:",argumentList,helper)),this.groupItems(cmd.options,helper.visibleOptions(cmd),option=>option.helpGroupHeading??"Options:").forEach((options,group)=>{let optionList=options.map(option=>callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)),helper.styleOptionDescription(helper.optionDescription(option))));output=output.concat(this.formatItemList(group,optionList,helper))}),helper.showGlobalOptions){let globalOptionList=helper.visibleGlobalOptions(cmd).map(option=>callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)),helper.styleOptionDescription(helper.optionDescription(option))));output=output.concat(this.formatItemList("Global Options:",globalOptionList,helper))}return this.groupItems(cmd.commands,helper.visibleCommands(cmd),sub=>sub.helpGroup()||"Commands:").forEach((commands,group)=>{let commandList=commands.map(sub=>callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)),helper.styleSubcommandDescription(helper.subcommandDescription(sub))));output=output.concat(this.formatItemList(group,commandList,helper))}),output.join(`
8
8
  `)}displayWidth(str){return stripVTControlCharacters(str).length}styleTitle(str){return str}styleUsage(str){return str.split(" ").map(word=>word==="[options]"?this.styleOptionText(word):word==="[command]"?this.styleSubcommandText(word):word[0]==="["||word[0]==="<"?this.styleArgumentText(word):this.styleCommandText(word)).join(" ")}styleCommandDescription(str){return this.styleDescriptionText(str)}styleOptionDescription(str){return this.styleDescriptionText(str)}styleSubcommandDescription(str){return this.styleDescriptionText(str)}styleArgumentDescription(str){return this.styleDescriptionText(str)}styleDescriptionText(str){return str}styleOptionTerm(str){return this.styleOptionText(str)}styleSubcommandTerm(str){return str.split(" ").map(word=>word==="[options]"?this.styleOptionText(word):word[0]==="["||word[0]==="<"?this.styleArgumentText(word):this.styleSubcommandText(word)).join(" ")}styleArgumentTerm(str){return this.styleArgumentText(str)}styleOptionText(str){return str}styleArgumentText(str){return str}styleSubcommandText(str){return str}styleCommandText(str){return str}padWidth(cmd,helper){return Math.max(helper.longestOptionTermLength(cmd,helper),helper.longestGlobalOptionTermLength(cmd,helper),helper.longestSubcommandTermLength(cmd,helper),helper.longestArgumentTermLength(cmd,helper))}preformatted(str){return/\n[^\S\r\n]/.test(str)}formatItem(term,termWidth,description,helper){let itemIndentStr=" ".repeat(2);if(!description)return itemIndentStr+term;let paddedTerm=term.padEnd(termWidth+term.length-helper.displayWidth(term)),spacerWidth=2,remainingWidth=(this.helpWidth??80)-termWidth-spacerWidth-2,formattedDescription;return remainingWidth<this.minWidthToWrap||helper.preformatted(description)?formattedDescription=description:formattedDescription=helper.boxWrap(description,remainingWidth).replace(/\n/g,`
9
9
  `+" ".repeat(termWidth+spacerWidth)),itemIndentStr+paddedTerm+" ".repeat(spacerWidth)+formattedDescription.replace(/\n/g,`
10
10
  ${itemIndentStr}`)}boxWrap(str,width2){if(width2<this.minWidthToWrap)return str;let rawLines=str.split(/\r\n|\n/),chunkPattern=/[\s]*[^\s]+/g,wrappedLines=[];return rawLines.forEach(line=>{let chunks=line.match(chunkPattern);if(chunks===null){wrappedLines.push("");return}let sumChunks=[chunks.shift()],sumWidth=this.displayWidth(sumChunks[0]);chunks.forEach(chunk=>{let visibleWidth=this.displayWidth(chunk);if(sumWidth+visibleWidth<=width2){sumChunks.push(chunk),sumWidth+=visibleWidth;return}wrappedLines.push(sumChunks.join(""));let nextChunk=chunk.trimStart();sumChunks=[nextChunk],sumWidth=this.displayWidth(nextChunk)}),wrappedLines.push(sumChunks.join(""))}),wrappedLines.join(`
@@ -29,34 +29,52 @@ Expecting one of '${allowedValues.join("', '")}'`);return this._lifeCycleHooks[e
29
29
  `),this.outputHelp({error:!0}));let config=errorOptions||{},exitCode=config.exitCode||1,code=config.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}
30
30
  `),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 error=!!contextOptions.error,baseWrite,hasColors,helpWidth;return error?(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,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.
31
31
  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}
32
- `)}),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{existsSync as existsSync2,readFileSync as readFileSync2}from"fs";import{dirname as dirname2,join as join2,resolve as resolve2}from"path";import{execFileSync}from"child_process";import{existsSync,readFileSync,realpathSync}from"fs";import{dirname,join,resolve}from"path";var INSTALL={pnpm:{fresh:"pnpm install",locked:"pnpm install --frozen-lockfile"},npm:{fresh:"npm install",locked:"npm ci"},yarn:{fresh:"yarn install",locked:"yarn install --frozen-lockfile"},bun:{fresh:"bun install",locked:"bun install --frozen-lockfile"}},names=list2=>list2.length<=1?list2[0]??"":`${list2.slice(0,-1).join(", ")} or ${list2.at(-1)}`;function noProject(cwd){return new CliError(`no package.json in ${resolve(cwd)} or any parent directory`,{why:"uptide analyzes a TypeScript or JavaScript project; this directory is not one.",next:"cd path/to/your/project && npx uptide"})}function noLockfile(root,manager){return new CliError(`no lockfile found for ${root}`,{why:"Installed versions are read from pnpm-lock.yaml, package-lock.json, yarn.lock or bun.lock.",next:INSTALL[manager??"npm"].fresh})}function binaryBunLockfile(root){return new CliError(`${join(root,"bun.lockb")} is a binary lockfile, which uptide cannot read`,{why:"bun writes a text lockfile (bun.lock) since 1.2; that one is supported.",next:"bun install --save-text-lockfile"})}function yarnPlugAndPlay(root){return new CliError(`${root} uses Yarn Plug'n'Play, which is not supported`,{why:"The analysis compiles against packages in node_modules; Plug'n'Play keeps them in zip archives.",next:"yarn config set nodeLinker node-modules && yarn install"})}function missingNodeModules(repo,missing){return new CliError(`${names(missing).replace(" or "," and ")} ${missing.length===1?"is":"are"} in the lockfile but not installed in node_modules`,{why:"The analysis compiles your code against the installed and the target version.",next:repo.manager==="yarn"&&(existsSync(join(dirname(repo.lockfile),".yarnrc.yml"))||/^__metadata:/m.test(readFileSync(repo.lockfile,"utf8")))?"yarn install --immutable":INSTALL[repo.manager].locked})}function notInLockfile(repo,name){return new CliError(`${name} is declared in package.json but missing from ${repo.lockfile}`,{why:"The lockfile is out of date with package.json.",next:INSTALL[repo.manager].fresh})}function notADependency(repo,missing){return new CliError(`${names(missing).replace(" or "," and ")} ${missing.length===1?"is":"are"} not a dependency of ${repo.name??repo.root}`,{why:workspaceCount(repo)>0?`Looked in the root and ${workspaceCount(repo)} workspace packages.`:void 0,next:"uptide"})}var workspaceCount=repo=>repo.workspaces.filter(w=>w!==".").length;function nothingToCheck(repo,supported){let count=workspaceCount(repo);return[`${count>0?`None of the ${count} workspace packages (or the root) depends on ${names(supported)}`:`This project does not depend on ${names(supported)}`}.`," Those are the upgrades uptide covers today; nothing to check."," Next: uptide check --only all (generic check of every dependency, no migrations)",""].join(`
33
- `)}var REGISTRY_FAILURES=["REGISTRY_UNREACHABLE","REGISTRY_HTTP_ERROR"];function isNetworkError(error){return REGISTRY_FAILURES.includes(errorCode(error)??"")}function noNetwork(detail){let first=detail.split(`
34
- `)[0]??detail,http=/HTTP (\d+)(, rate limited)?/.exec(first);if(http){let wait=/wait (\d+)s/.exec(first)?.[1];return new CliError(http[2]?`the npm registry is rate limiting this machine (HTTP ${http[1]})`:`the npm registry answered HTTP ${http[1]}`,{why:`Target versions and their type declarations come from the registry, and it kept refusing after 3 retries (${first}). Nothing was analyzed, so there is no result to trust.`,next:wait?`run the same command again in ${wait}s`:"run the same command again in a minute"})}return new CliError("cannot reach the npm registry",{why:`Target versions and their type declarations come from the registry (${first}). Behind a proxy, set HTTPS_PROXY; a custom registry is read from .npmrc.`,next:"npm ping"})}function networkFailure(report){let failed=report.packages.filter(p=>REGISTRY_FAILURES.includes(p.skipReason??""));return failed.length>0?noNetwork(failed[0]?.notes[0]??"registry unavailable"):void 0}function installedIn(dir,name){for(let current=dir;;current=dirname(current)){if(existsSync(join(current,"node_modules",name,"package.json")))return!0;if(dirname(current)===current)return!1}}function requireInstalled(repo,dependencies){for(let dep of dependencies)if(dep.workspaces.length>0&&!dep.installed)throw notInLockfile(repo,dep.name);let missing=dependencies.filter(dep=>dep.workspaces.some(w=>!installedIn(join(repo.root,w),dep.name))).map(dep=>dep.name);if(missing.length>0)throw missingNodeModules(repo,missing)}function git(root,...args){try{return execFileSync("git",["-C",root,...args],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function requireFixable(repo,only){if(!["pnpm","npm","yarn"].includes(repo.manager))throw new CliError(`fix does not support ${repo.manager} repositories yet`,{why:"It updates the lockfile and verifies the result, which is implemented for npm, pnpm and Yarn. `check` works here and lists every site to migrate.",next:`uptide check --only ${only} --details`});let top=git(repo.root,"rev-parse","--show-toplevel");if(top===void 0)throw new CliError(`${repo.root} is not a git repository`,{why:"fix commits the upgrade and each migration step on a new branch.",next:'git init && git add -A && git commit -m "baseline"'});for(let dir=dirname(realpathSync(repo.root));dir.startsWith(realpathSync(top));dir=dirname(dir)){if(existsSync(join(dir,"package.json")))throw new CliError("fix has to run at the project root",{why:"Every workspace declaring the dependency is upgraded together.",next:`uptide fix --only ${only} --cwd ${dir}`});if(dir===realpathSync(top))break}if(git(repo.root,"status","--porcelain","--untracked-files=all"))throw new CliError("the working tree has uncommitted changes",{why:"fix only commits its own edits, so it starts from a clean tree.",next:"git stash --include-untracked"})}function noApiKeyNote(only){return["note: ANTHROPIC_API_KEY is not set, so assisted fixes are off."," Rule-based fixes still run; sites they cannot migrate are listed for manual work.",` Next: export ANTHROPIC_API_KEY=<your key> && uptide fix --only ${only}`," (or pass --no-llm to keep it that way without this note)",""].join(`
35
- `)}var ASSISTED_NOTE=["note: assisted fixes are on. For sites the rules cannot migrate, the finding, the"," enclosing function and the compiler error are sent to Anthropic with your key."," Pass --no-llm to keep everything on this machine.",""].join(`
36
- `);var LOCKFILES=[["pnpm-lock.yaml","pnpm"],["package-lock.json","npm"],["npm-shrinkwrap.json","npm"],["yarn.lock","yarn"],["bun.lock","bun"]];function upwards(from,visit){let dir=resolve2(from);for(;;){let found=visit(dir);if(found!==void 0)return found;let parent=dirname2(dir);if(parent===dir)return;dir=parent}}function findProjectRoot(cwd){return upwards(cwd,dir=>existsSync2(join2(dir,"package.json"))?dir:void 0)}function findLockfile(root){let declared=declaredManager(root);return upwards(root,dir=>{let present=LOCKFILES.filter(([name])=>existsSync2(join2(dir,name))),byDeclaration=present.find(([,manager])=>manager===declared),pick=byDeclaration??present[0];if(!pick)return;let others=present.filter(p=>p!==pick).map(([name])=>name);return{file:join2(dir,pick[0]),manager:pick[1],...others.length?{chosen:`${pick[0]} (${byDeclaration?`packageManager says ${declared}`:"first by precedence: pnpm, npm, yarn, bun"}); ${others.join(", ")} left untouched`}:{}}})}function declaredManager(root){return upwards(root,dir=>{try{let field=JSON.parse(readFileSync2(join2(dir,"package.json"),"utf8")).packageManager,name=typeof field=="string"?field.split("@")[0]:void 0;return name==="pnpm"||name==="npm"||name==="yarn"||name==="bun"?name:void 0}catch{return}})}async function detectRepo(cwd,workspacesOf){let root=findProjectRoot(cwd);if(!root)throw noProject(cwd);let lock=findLockfile(root);if(!lock){let bun=upwards(root,dir=>existsSync2(join2(dir,"bun.lockb"))?dir:void 0);throw bun?binaryBunLockfile(bun):noLockfile(root,declaredManager(root))}if(lock.manager==="yarn"&&existsSync2(join2(dirname2(lock.file),".pnp.cjs")))throw yarnPlugAndPlay(dirname2(lock.file));let name;try{name=JSON.parse(readFileSync2(join2(root,"package.json"),"utf8")).name}catch{throw new CliError(`${join2(root,"package.json")} is not valid JSON`)}return{root,name,manager:lock.manager,lockfile:lock.file,...lock.chosen?{chosen:lock.chosen}:{},workspaces:await workspacesOf(root)}}function describeRepo(repo){let packages=repo.workspaces.filter(w=>w!==".").length,shape=packages>0?`${repo.manager} workspace, ${packages} package${packages===1?"":"s"}`:repo.manager;return`${repo.name??repo.root} (${shape})${repo.chosen?` \xB7 ${repo.chosen}`:""}`}async function offThread(job,onProgress){let here=import.meta.url;if(here.endsWith(".ts"))return await runJob(job,onProgress);let{Worker}=await import("worker_threads");return new Promise((resolvePromise,reject)=>{let worker=new Worker(new URL("./engine-worker.js",here),{workerData:job,resourceLimits:{maxOldGenerationSizeMb:4096}}),settled=!1;worker.on("message",reply=>{if("type"in reply){onProgress?.(reply.event);return}settled=!0,reply.ok?resolvePromise(reply.value):reject(new UptideError(reply.code,reply.message))}),worker.once("error",reject),worker.once("exit",code=>{settled||reject(new Error(`analysis stopped unexpectedly (worker exit code ${code})`))})})}function defaultEngine(){return{check:(request,onProgress)=>offThread({kind:"check",request},onProgress),fix:(request,onProgress)=>offThread({kind:"fix",request},onProgress),verify:(request,onProgress)=>offThread({kind:"verify",request},onProgress),clean:days=>cleanRuns({days}),pr:(request,print)=>openPr(request,print),publishTarget:(cwd,repo)=>publishTarget(cwd,repo),diff:(name,from,to)=>diffPackage({name,from,to}),latest:name=>createNpmFetcher().resolve(name,"latest"),workspaces:async root=>await typescriptAdapter.workspacePackages?.({dir:root})??["."],installed:async dir=>await typescriptAdapter.installedDependencies?.({dir})??new Map,declared:async dir=>await typescriptAdapter.declaredSpecifiers?.({dir})??new Map,updatePrBody}}var import_picocolors=__toESM(require_picocolors(),1),ORDER=["breaking","deprecated","additive"],KIND_ORDER=["signature","narrowed","type","required","removed","moved","renamed","widened","deprecated","added"];function describe(c){switch(c.kind){case"removed":return c.replacement===c.path?"no longer exported here":c.replacement?`removed, possibly renamed to ${c.replacement}`:"removed";case"added":return"added";case"required":return"now required";case"deprecated":return typeof c.notes=="string"?`deprecated: ${c.notes}`:"deprecated";case"signature":return c.notes??"signature changed";case"type":return c.notes??"type changed";case"renamed":return`renamed to ${c.replacement??"?"}`;case"moved":return`moved to ${c.replacement??"?"}`;case"widened":return c.notes??"type widened";case"narrowed":return c.notes??"type narrowed";case"cause":return c.notes??"root cause";case"module-format":return c.notes??"ESM only"}}function transition(c){if(c.before===void 0||c.after===void 0)return;let text=`${c.before} -> ${c.after}`;return text.length<=160?text:`${text.slice(0,157)}...`}function formatHuman(changes,opts={}){let colors=import_picocolors.default.createColors(opts.color??!0),tint={breaking:colors.red,deprecated:colors.yellow,additive:colors.green,info:colors.dim,unverified:colors.magenta},folded=foldForDisplay(changes),visible=opts.all?changes:folded.shown,lines=[],first=changes[0];first&&lines.push(colors.bold(`${first.package} ${first.from} -> ${first.to}`),"");for(let severity of ORDER){let group=visible.filter(c=>c.severity===severity).sort((x,y)=>depthOf(x.path)-depthOf(y.path)||KIND_ORDER.indexOf(x.kind)-KIND_ORDER.indexOf(y.kind)||(x.path<y.path?-1:x.path>y.path?1:0));if(group.length!==0){lines.push(tint[severity](colors.bold(`${severity.toUpperCase()} (${group.length})`)));for(let c of group){let confidence=c.confidence<1?colors.dim(` (${Math.round(c.confidence*100)}%)`):"";lines.push(` ${tint[severity](c.path)} ${describe(c)}${confidence}`);let t=transition(c);t&&lines.push(colors.dim(` ${t}`))}lines.push("")}}if(visible.length===0&&lines.push("no changes to the public API",""),!opts.all){let{impliedByRemoval,aliasDuplicates,nonPublic}=folded.hidden,hidden=impliedByRemoval.length+aliasDuplicates.length+nonPublic.length;if(hidden>0){let parts=[impliedByRemoval.length>0?`${impliedByRemoval.length} members of removed symbols`:"",aliasDuplicates.length>0?`${aliasDuplicates.length} alias duplicates`:"",nonPublic.length>0?`${nonPublic.length} protected/@internal`:""].filter(Boolean);lines.push(colors.dim(`${hidden} hidden (${parts.join(", ")}); --all shows them, --json includes them`),"")}}return lines.join(`
32
+ `)}),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{existsSync as existsSync2,readFileSync as readFileSync2}from"fs";import{dirname as dirname2,join as join2,resolve as resolve2}from"path";import{execFileSync}from"child_process";import{existsSync,readFileSync,realpathSync}from"fs";import{dirname,join,resolve}from"path";var INSTALL={pnpm:{fresh:"pnpm install",locked:"pnpm install --frozen-lockfile"},npm:{fresh:"npm install",locked:"npm ci"},yarn:{fresh:"yarn install",locked:"yarn install --frozen-lockfile"},bun:{fresh:"bun install",locked:"bun install --frozen-lockfile"}},names=list2=>list2.length<=1?list2[0]??"":`${list2.slice(0,-1).join(", ")} or ${list2.at(-1)}`;function noProject(cwd){return new CliError(`no package.json in ${resolve(cwd)} or any parent directory`,{why:"uptide analyzes a TypeScript or JavaScript project; this directory is not one.",next:"cd path/to/your/project && npx uptide"})}function noLockfile(root,manager){return new CliError(`no lockfile found for ${root}`,{why:"Installed versions are read from pnpm-lock.yaml, package-lock.json, yarn.lock or bun.lock.",next:INSTALL[manager??"npm"].fresh})}function binaryBunLockfile(root){return new CliError(`${join(root,"bun.lockb")} is a binary lockfile, which uptide cannot read`,{why:"bun writes a text lockfile (bun.lock) since 1.2; that one is supported.",next:"bun install --save-text-lockfile"})}function yarnPlugAndPlay(root){return new CliError(`${root} uses Yarn Plug'n'Play, which is not supported`,{why:"The analysis compiles against packages in node_modules; Plug'n'Play keeps them in zip archives.",next:"yarn config set nodeLinker node-modules && yarn install"})}function missingNodeModules(repo,missing){return new CliError(`${names(missing).replace(" or "," and ")} ${missing.length===1?"is":"are"} in the lockfile but not installed in node_modules`,{why:"The analysis compiles your code against the installed and the target version.",next:repo.manager==="yarn"&&(existsSync(join(dirname(repo.lockfile),".yarnrc.yml"))||/^__metadata:/m.test(readFileSync(repo.lockfile,"utf8")))?"yarn install --immutable":INSTALL[repo.manager].locked})}function notInLockfile(repo,name){return new CliError(`${name} is declared in package.json but missing from ${repo.lockfile}`,{why:"The lockfile is out of date with package.json.",next:INSTALL[repo.manager].fresh})}function notADependency(repo,missing){return new CliError(`${names(missing).replace(" or "," and ")} ${missing.length===1?"is":"are"} not a dependency of ${repo.name??repo.root}`,{why:workspaceCount(repo)>0?`Looked in the root and ${workspaceCount(repo)} workspace packages.`:void 0,next:INVOCATION})}var workspaceCount=repo=>repo.workspaces.filter(w=>w!==".").length,REGISTRY_FAILURES=["REGISTRY_UNREACHABLE","REGISTRY_HTTP_ERROR"];function isNetworkError(error){return REGISTRY_FAILURES.includes(errorCode(error)??"")}function noNetwork(detail){let first=detail.split(`
33
+ `)[0]??detail,http=/HTTP (\d+)(, rate limited)?/.exec(first);if(http){let wait=/wait (\d+)s/.exec(first)?.[1];return new CliError(http[2]?`the npm registry is rate limiting this machine (HTTP ${http[1]})`:`the npm registry answered HTTP ${http[1]}`,{why:`Target versions and their type declarations come from the registry, and it kept refusing after 3 retries (${first}). Nothing was analyzed, so there is no result to trust.`,next:wait?`run the same command again in ${wait}s`:"run the same command again in a minute"})}return new CliError("cannot reach the npm registry",{why:`Target versions and their type declarations come from the registry (${first}). Behind a proxy, set HTTPS_PROXY; a custom registry is read from .npmrc.`,next:"npm ping"})}function networkFailure(report){let failed=report.packages.filter(p=>REGISTRY_FAILURES.includes(p.skipReason??"")),answered=report.packages.some(p=>!["skipped","not-imported","workspace","private"].includes(p.status));return failed.length>0&&!answered?noNetwork(failed[0]?.notes[0]??"registry unavailable"):void 0}function installedIn(dir,name){for(let current=dir;;current=dirname(current)){if(existsSync(join(current,"node_modules",name,"package.json")))return!0;if(dirname(current)===current)return!1}}function requireInstalled(repo,dependencies){for(let dep of dependencies)if(dep.workspaces.length>0&&!dep.installed)throw notInLockfile(repo,dep.name);let missing=dependencies.filter(dep=>dep.workspaces.some(w=>!installedIn(join(repo.root,w),dep.name))).map(dep=>dep.name);if(missing.length>0)throw missingNodeModules(repo,missing)}function requireNodeModules(repo,dependencies){let declared=dependencies.filter(dep=>dep.workspaces.length>0),missing=declared.filter(dep=>dep.workspaces.every(w=>!installedIn(join(repo.root,w),dep.name)));if(declared.length>0&&missing.length===declared.length)throw missingNodeModules(repo,missing.slice(0,3).map(dep=>dep.name))}function git(root,...args){try{return execFileSync("git",["-C",root,...args],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return}}function requireFixable(repo,only){if(!["pnpm","npm","yarn"].includes(repo.manager))throw new CliError(`fix does not support ${repo.manager} repositories yet`,{why:"It updates the lockfile and verifies the result, which is implemented for npm, pnpm and Yarn. `check` works here and lists every site to migrate.",next:`uptide check ${only} --details`});let top=git(repo.root,"rev-parse","--show-toplevel");if(top===void 0)throw new CliError(`${repo.root} is not a git repository`,{why:"fix commits the upgrade and each migration step on a new branch.",next:'git init && git add -A && git commit -m "baseline"'});for(let dir=dirname(realpathSync(repo.root));dir.startsWith(realpathSync(top));dir=dirname(dir)){if(existsSync(join(dir,"package.json")))throw new CliError("fix has to run at the project root",{why:"Every workspace declaring the dependency is upgraded together.",next:`uptide fix --only ${only} --cwd ${dir}`});if(dir===realpathSync(top))break}if(git(repo.root,"status","--porcelain","--untracked-files=all"))throw new CliError("the working tree has uncommitted changes",{why:"fix only commits its own edits, so it starts from a clean tree.",next:"git stash --include-untracked"})}function noAgentForGeneric(only,disabled){return new CliError(`${only} has no migration pack, so every fix would come from the agent, and ${disabled?"assisted fixes are off (--no-llm)":`no selected-provider API key is set (accepted: ${ACCEPTED_KEYS})`}`,{why:"Without a pack there are no rules to apply. Nothing was changed: no clone, no branch, no install.",next:disabled?`uptide check ${only} --details (every site, to migrate by hand)`:`uptide fix ${only} (set ANTHROPIC_API_KEY, OPENAI_API_KEY or GEMINI_API_KEY in your environment first)`})}function noApiKeyNote(only){return[`note: no selected-provider API key is set (${ACCEPTED_KEYS}); assisted fixes are off.`," Rule-based fixes still run; sites they cannot migrate are listed for manual work.",` Next: ${INVOCATION} fix ${only} (set ANTHROPIC_API_KEY, OPENAI_API_KEY or GEMINI_API_KEY in your environment first)`," (or pass --no-llm to keep it that way without this note)",""].join(`
34
+ `)}var assistedNote=provider=>["note: assisted fixes are on. For sites the rules cannot migrate, the finding, the",` enclosing function and the compiler error are sent to ${provider} with your key.`," Pass --no-llm to keep code on this machine.",""].join(`
35
+ `);var LOCKFILES=[["pnpm-lock.yaml","pnpm"],["package-lock.json","npm"],["npm-shrinkwrap.json","npm"],["yarn.lock","yarn"],["bun.lock","bun"]];function upwards(from,visit){let dir=resolve2(from);for(;;){let found=visit(dir);if(found!==void 0)return found;let parent=dirname2(dir);if(parent===dir)return;dir=parent}}function findProjectRoot(cwd){return upwards(cwd,dir=>existsSync2(join2(dir,"package.json"))?dir:void 0)}function findLockfile(root){let declared=declaredManager(root);return upwards(root,dir=>{let present=LOCKFILES.filter(([name])=>existsSync2(join2(dir,name))),byDeclaration=present.find(([,manager])=>manager===declared),pick=byDeclaration??present[0];if(!pick)return;let others=present.filter(p=>p!==pick).map(([name])=>name);return{file:join2(dir,pick[0]),manager:pick[1],...others.length?{chosen:`${pick[0]} (${byDeclaration?`packageManager says ${declared}`:"first by precedence: pnpm, npm, yarn, bun"}); ${others.join(", ")} left untouched`}:{}}})}function declaredManager(root){return upwards(root,dir=>{try{let field=JSON.parse(readFileSync2(join2(dir,"package.json"),"utf8")).packageManager,name=typeof field=="string"?field.split("@")[0]:void 0;return name==="pnpm"||name==="npm"||name==="yarn"||name==="bun"?name:void 0}catch{return}})}async function detectRepo(cwd,workspacesOf){let root=findProjectRoot(cwd);if(!root)throw noProject(cwd);let lock=findLockfile(root);if(!lock){let bun=upwards(root,dir=>existsSync2(join2(dir,"bun.lockb"))?dir:void 0);throw bun?binaryBunLockfile(bun):noLockfile(root,declaredManager(root))}if(lock.manager==="yarn"&&existsSync2(join2(dirname2(lock.file),".pnp.cjs")))throw yarnPlugAndPlay(dirname2(lock.file));let name;try{name=JSON.parse(readFileSync2(join2(root,"package.json"),"utf8")).name}catch{throw new CliError(`${join2(root,"package.json")} is not valid JSON`)}return{root,name,manager:lock.manager,lockfile:lock.file,...lock.chosen?{chosen:lock.chosen}:{},workspaces:await workspacesOf(root)}}function describeRepo(repo){let packages=repo.workspaces.filter(w=>w!==".").length,shape=packages>0?`${repo.manager} workspace, ${packages} package${packages===1?"":"s"}`:repo.manager;return`${repo.name??repo.root} (${shape})${repo.chosen?` \xB7 ${repo.chosen}`:""}`}async function offThread(job,onProgress){let here=import.meta.url;if(here.endsWith(".ts"))return await runJob(job,onProgress);let{Worker}=await import("worker_threads");return new Promise((resolvePromise,reject)=>{let worker=new Worker(new URL("./engine-worker.js",here),{workerData:job,resourceLimits:{maxOldGenerationSizeMb:workerHeapMb(1)}}),settled=!1;worker.on("message",reply=>{if("type"in reply){onProgress?.(reply.event);return}settled=!0,reply.ok?resolvePromise(reply.value):reject(new UptideError(reply.code,reply.message))}),worker.once("error",reject),worker.once("exit",code=>{settled||reject(new Error(`analysis stopped unexpectedly (worker exit code ${code})`))})})}function defaultEngine(){return{list:listDependencies,check:(request,onProgress)=>offThread({kind:"check",request},onProgress),plan:(request,onProgress)=>offThread({kind:"plan",request},onProgress),fix:(request,onProgress)=>offThread({kind:"fix",request},onProgress),verify:(request,onProgress)=>offThread({kind:"verify",request},onProgress),clean:days=>cleanRuns({days}),pr:(request,print)=>openPr(request,print),preflight:fixPreflight,publishTarget:(cwd,repo)=>publishTarget(cwd,repo),diff:(name,from,to)=>diffPackage({name,from,to}),latest:name=>createNpmFetcher().resolve(name,"latest"),workspaces:async root=>await typescriptAdapter.workspacePackages?.({dir:root})??["."],installed:async dir=>await typescriptAdapter.installedDependencies?.({dir})??new Map,declared:async dir=>await typescriptAdapter.declaredSpecifiers?.({dir})??new Map,updatePrBody}}var import_picocolors=__toESM(require_picocolors(),1),ORDER=["breaking","deprecated","additive"],KIND_ORDER=["signature","narrowed","type","required","removed","moved","renamed","widened","deprecated","added"];function describe(c){switch(c.kind){case"removed":return c.replacement===c.path?"no longer exported here":c.replacement?`removed, possibly renamed to ${c.replacement}`:"removed";case"added":return"added";case"required":return"now required";case"deprecated":return typeof c.notes=="string"?`deprecated: ${c.notes}`:"deprecated";case"signature":return c.notes??"signature changed";case"type":return c.notes??"type changed";case"renamed":return`renamed to ${c.replacement??"?"}`;case"moved":return`moved to ${c.replacement??"?"}`;case"widened":return c.notes??"type widened";case"narrowed":return c.notes??"type narrowed";case"cause":return c.notes??"root cause";case"module-format":return c.notes??"ESM only"}}function transition(c){if(c.before===void 0||c.after===void 0)return;let text=`${c.before} -> ${c.after}`;return text.length<=160?text:`${text.slice(0,157)}...`}function formatHuman(changes,opts={}){let colors=import_picocolors.default.createColors(opts.color??!0),tint={breaking:colors.red,deprecated:colors.yellow,additive:colors.green,info:colors.dim,unverified:colors.magenta},folded=foldForDisplay(changes),visible=opts.all?changes:folded.shown,lines=[],first=changes[0];first&&lines.push(colors.bold(`${first.package} ${first.from} -> ${first.to}`),"");for(let severity of ORDER){let group=visible.filter(c=>c.severity===severity).sort((x,y)=>depthOf(x.path)-depthOf(y.path)||KIND_ORDER.indexOf(x.kind)-KIND_ORDER.indexOf(y.kind)||(x.path<y.path?-1:x.path>y.path?1:0));if(group.length!==0){lines.push(tint[severity](colors.bold(`${severity.toUpperCase()} (${group.length})`)));for(let c of group){let confidence=c.confidence<1?colors.dim(` (${Math.round(c.confidence*100)}%)`):"";lines.push(` ${tint[severity](c.path)} ${describe(c)}${confidence}`);let t=transition(c);t&&lines.push(colors.dim(` ${t}`))}lines.push("")}}if(visible.length===0&&lines.push("no changes to the public API",""),!opts.all){let{impliedByRemoval,aliasDuplicates,nonPublic}=folded.hidden,hidden=impliedByRemoval.length+aliasDuplicates.length+nonPublic.length;if(hidden>0){let parts=[impliedByRemoval.length>0?`${impliedByRemoval.length} members of removed symbols`:"",aliasDuplicates.length>0?`${aliasDuplicates.length} alias duplicates`:"",nonPublic.length>0?`${nonPublic.length} protected/@internal`:""].filter(Boolean);lines.push(colors.dim(`${hidden} hidden (${parts.join(", ")}); --all shows them, --json includes them`),"")}}return lines.join(`
37
36
  `)}import{basename}from"path";var import_picocolors4=__toESM(require_picocolors(),1);var import_picocolors2=__toESM(require_picocolors(),1);function importerNotes(p){return(p.importers??[]).flatMap(i=>{let line=describeImporter(p.name,i);return line?[line]:[]})}function describeImporter(name,i){let where=i.workspace==="."?"root":i.workspace;if(!i.declared){let resolved=i.via?` (resolved via ${i.via})`:"";return i.analyzed?`${where} \xB7 imports ${name} without declaring it${resolved}`:`${where} \xB7 imports ${name} without declaring it, not analyzed: ${i.reason??"unknown reason"}`}if(!i.analyzed)return`${where} \xB7 imports ${name}, not analyzed: ${i.reason??"unknown reason"}`}function analyzedImporters(p){let list2=(p.importers??[]).filter(i=>i.analyzed);if(list2.length!==0)return list2.map(i=>{let where=i.workspace==="."?"root":i.workspace;return i.declared?where:`${where} (undeclared${i.via?`, via ${i.via}`:""})`}).join(", ")}var plural=(n,one,many=`${one}s`)=>`${n} ${n===1?one:many}`;function describeChange(f){let c=f.change,replacement=c.replacement!==void 0&&c.kind!=="moved"?` \u2192 ${c.replacement}`:"";if(c.path.startsWith("cause:"))return c.notes??f.reason;if(/^\d+ symbols (removed|moved) at this site: /.test(f.reason))return f.reason;if(c.kind==="module-format")return`${c.package} ${f.reason}`;if(/^TS\d+$/.test(c.path)){let concrete=(f.usage.compileError??c.notes??f.reason).split(`
38
- `)[0]??"";return`${c.path}: ${concrete.length>160?`${concrete.slice(0,157)}...`:concrete}`}switch(c.kind){case"removed":return`${c.path} removed${replacement}`;case"moved":return`${c.path} moved to ${c.replacement??"another entry point"}`;case"renamed":return`${c.path} renamed${replacement}`;case"deprecated":return`${c.path} deprecated${f.reason&&f.reason!=="deprecated"?`: ${f.reason}`:""}${replacement}`;default:return f.reason.startsWith(`${c.path},`)?`${f.reason}${replacement}`:`${c.path} ${f.reason}${replacement}`}}function findingLines(f,mark,colors,tint){let location=`${f.usage.file}:${f.usage.line}`,first=` ${tint(mark)} ${location.padEnd(34)} ${f.usage.snippet}`,description=describeChange(f),confidence=f.confidence<1?colors.dim(` (${Math.round(f.confidence*100)}%)`):"",second=` ${description.padEnd(62)} ${colors.dim(f.fixability)}${confidence}`,lines=[first,second];f.usage.compileError&&lines.push(colors.dim(` compiler: ${f.usage.compileError.split(`
39
- `)[0]}`));for(let detail of f.details??[])lines.push(colors.dim(` ${detail}`));let others=(f.sites??[]).filter(s=>s.line!==f.usage.line);return others.length>0&&lines.push(colors.dim(` also at line${others.length===1?"":"s"} ${others.map(s=>s.line).join(", ")}`)),lines}function siteLines(findings,mark,colors,tint){return findings.flatMap(f=>findingLines(f,mark,colors,tint))}function packageLines(p,opts,colors){let behind=p.majorsBehind>0?` (${plural(p.majorsBehind,"major")} behind)`:"",title=p.members?`${p.name} (${plural(p.members.length,"package")})`:p.name,where=p.workspaces?colors.dim(` \xB7 ${p.source==="catalog"?"catalog \xB7 ":""}${p.workspaces.map(w=>w==="."?"root":w).join(", ")}`):"",via=p.typesVia?colors.dim(` \xB7 types via ${p.typesVia}`):"",header=`${colors.bold(title)} ${p.installed} \u2192 ${p.target}${behind}${where}${via}`,lines=[];if(p.status==="no-types"){let typesIn=p.notes.find(n=>n.startsWith("types in ")),reason=typesIn?`${typesIn}, not analyzed`:p.notes.find(n=>/type declarations/.test(n))??"no type declarations, cannot analyze";return[`${colors.bold(p.name)} ${p.installed} \u2192 ${p.target} ${colors.dim(reason)}`]}if(p.status==="not-imported"||p.status==="workspace"||p.status==="private")return[];if(p.notes.includes("up to date"))return[];if(p.status==="skipped")return[`${colors.bold(p.name)} ${p.installed} ${colors.dim(`skipped: ${p.notes.join("; ")||"unknown reason"}`)}`];lines.push(header);let analyzed=analyzedImporters(p);analyzed&&(p.importers?.length??0)>1&&lines.push(colors.dim(` analyzed in ${analyzed}`));for(let note of importerNotes(p))lines.push(` ${colors.yellow("\u26A0")} ${note}`);let visible=p.findings.filter(f=>f.severity!=="additive"&&f.severity!=="info"&&(opts.all||f.confidence>=.5)),breaking=visible.filter(f=>f.severity==="breaking"),unverified=visible.filter(f=>f.severity==="unverified"),deprecated=visible.filter(f=>f.severity==="deprecated"),render=siteLines,unanalyzed=p.unanalyzed.length;if(visible.length===0&&(p.status==="unknown"?lines.push(` ${colors.magenta("?")} unknown: ${unanalyzed} of ${plural(p.callSitesChecked+unanalyzed,"site")} not analyzed (require/dynamic import)`):unanalyzed>0?lines.push(` ${colors.green("\u2713")} no impact in ${plural(p.callSitesChecked,"analyzed site")} \xB7 ${colors.yellow("\u26A0")} ${plural(unanalyzed,"site")} not analyzed`):lines.push(` ${colors.green("\u2713")} no impact on your code (${plural(p.callSitesChecked,"call site")} checked)`)),breaking.length>0){let files=new Set(breaking.flatMap(f=>f.change.kind==="cause"?(f.downstream??[]).map(d=>d.file):[f.usage.file])).size,sites=breaking.reduce((n,f)=>n+(f.change.kind==="cause"?f.downstream?.length??0:1),0);lines.push("",` ${colors.red(colors.bold("BREAKING"))} ${plural(sites,"call site")} in ${plural(files,"file")}`),lines.push(...render(breaking,"\u2717",colors,colors.red))}unverified.length>0&&(lines.push("",` ${colors.magenta(colors.bold("UNVERIFIED"))} ${plural(unverified.length,"call site")} ${colors.dim("(verification incomplete)")}`),lines.push(...render(unverified,"?",colors,colors.magenta))),deprecated.length>0&&(lines.push("",` ${colors.yellow(colors.bold("DEPRECATED"))} ${plural(deprecated.length,"call site")}`),lines.push(...render(deprecated,"!",colors,colors.yellow)));let hidden=p.findings.filter(f=>f.severity!=="additive"&&(f.severity==="info"||!opts.all&&f.confidence<.5)).length;hidden>0&&lines.push(colors.dim(` ${plural(hidden,"low-confidence finding")} hidden (use --all)`));for(let r of p.runtime??[]){let who=(p.runtime?.length??0)>1?`${r.package}: `:"",unused=r.changes.filter(c=>c.key&&r.usedKeys&&!r.usedKeys.includes(c.key)),unusedKeys=new Set(unused.map(c=>c.key));for(let c of r.changes)!opts.all&&unused.includes(c)||lines.push(colors.dim(` \u2699 runtime (${r.node}): ${who}${c.detail}`));unusedKeys.size>0&&lines.push(colors.dim(` \u2699 ${who}${unusedKeys.size} unused exports removed${opts.all?"":" (use --all)"}`)),isNativeProbeSkip(r.inconclusive)?lines.push(colors.dim(` \u2699 ${who}native package, runtime probe skipped`)):r.inconclusive&&lines.push(colors.dim(` \u2699 runtime (${r.node}): ${who}inconclusive, ${r.inconclusive}`))}for(let note of p.notes)visible.length===0&&/sites? not analyzed/.test(note)||lines.push(colors.dim(` \u26A0 ${note}`));return lines}function formatCheckDetails(report,opts={}){let colors=import_picocolors2.default.createColors(opts.color??!0),lines=[],grouped=report.workspaces.length>1;for(let workspace of["*",...report.workspaces]){let blocks=report.packages.filter(p=>p.workspace===workspace).map(p=>packageLines(p,opts,colors)).filter(b=>b.length>0);if(blocks.length!==0){if(grouped){let title=workspace==="*"?"(shared across workspaces)":workspace==="."?"(root)":workspace;lines.push(colors.bold(colors.underline(title)),"")}for(let block of blocks)lines.push(...block,"")}}let privates=[...new Set(report.packages.filter(p=>p.status==="private").map(p=>p.name))].sort();privates.length>0&&lines.push(colors.dim(`${plural(privates.length,"private package")} skipped: registry auth or not on the registry (${privates.join(", ")})`),"");let s=report.summary,actionable=s.breaking+s.deprecated;return lines.push(`${colors.bold("Summary:")} ${plural(s.packagesNeedingAttention,"package")} need${s.packagesNeedingAttention===1?"s":""} attention \xB7 ${s.breaking} breaking \xB7 ${s.deprecated} deprecated${s.unverified>0?` \xB7 ${s.unverified} unverified`:""} \xB7 ${s.unaffected} unaffected${s.partiallyAnalyzed>0?` \xB7 ${s.partiallyAnalyzed} partially analyzed`:""}${s.notImported>0?` \xB7 ${s.notImported} not imported`:""}`),actionable>0&&lines.push(` ${s.autoFixable} of ${plural(actionable,"finding")} ${actionable===1?"is":"are"} mechanical`),`${lines.join(`
37
+ `)[0]??"";return`${c.path}: ${concrete.length>160?`${concrete.slice(0,157)}...`:concrete}`}switch(c.kind){case"removed":return`${c.path} removed${replacement}`;case"moved":return`${c.path} moved to ${c.replacement??"another entry point"}`;case"renamed":return`${c.path} renamed${replacement}`;case"deprecated":return`${c.path} deprecated${f.reason&&f.reason!=="deprecated"?`: ${f.reason}`:""}${replacement}`;default:return f.reason.startsWith(`${c.path},`)?`${f.reason}${replacement}`:`${c.path} ${f.reason}${replacement}`}}var EVIDENCE={compiler:"your code does not compile against the target at this site",runtime:"the runtime probe loaded the target and the export is gone or changed","module-format":"a require() of a package whose target is ESM-only","removed-export":"the import of a name the target no longer exports"};function findingLines(f,mark,colors,tint){let location=`${f.usage.file}:${f.usage.line}`,first=` ${tint(mark)} ${location.padEnd(34)} ${f.usage.snippet}`,description=describeChange(f),confidence=f.confidence<1?colors.dim(` (${Math.round(f.confidence*100)}%)`):"",second=` ${description.padEnd(62)} ${colors.dim(f.fixability)}${confidence}`,lines=[first,second];f.severity==="breaking"&&f.evidence&&f.evidence!=="pack"&&lines.push(colors.dim(` evidence: ${EVIDENCE[f.evidence]}`)),f.usage.compileError&&lines.push(colors.dim(` compiler: ${f.usage.compileError.split(`
38
+ `)[0]}`));for(let detail of f.details??[])lines.push(colors.dim(` ${detail}`));let others=(f.sites??[]).filter(s=>s.line!==f.usage.line);return others.length>0&&lines.push(colors.dim(` also at line${others.length===1?"":"s"} ${others.map(s=>s.line).join(", ")}`)),lines}function siteLines(findings,mark,colors,tint){return findings.flatMap(f=>{if(f.change.kind!=="cause")return findingLines(f,mark,colors,tint);let sites=f.downstream??[];return[` ${tint(mark)} ${f.reason} (${plural(sites.length,"site")})`,...sites.flatMap(site=>[` ${site.file}:${site.line} ${site.snippet??""}`.trimEnd(),colors.dim(` TS${site.code}: ${site.message}`)]),...(f.details??[]).map(detail=>colors.dim(` ${detail}`))]})}function packageLines(p,opts,colors){let behind=p.majorsBehind>0?` (${plural(p.majorsBehind,"major")} behind)`:"",title=p.members?`${p.name} (${plural(p.members.length,"package")})`:p.name,where=p.workspaces?colors.dim(` \xB7 ${p.source==="catalog"?"catalog \xB7 ":""}${p.workspaces.map(w=>w==="."?"root":w).join(", ")}`):"",via=p.typesVia?colors.dim(` \xB7 types via ${p.typesVia}`):"",tier=p.tier?colors.dim(` \xB7 ${p.tier}`):"",header=`${colors.bold(title)} ${p.installed} \u2192 ${p.target}${behind}${tier}${where}${via}`,lines=[];if(p.status==="no-types"){let typesIn=p.notes.find(n=>n.startsWith("types in ")),reason=typesIn?`${typesIn}, not analyzed`:p.notes.find(n=>/type declarations/.test(n))??"no type declarations, cannot analyze";return[`${colors.bold(p.name)} ${p.installed} \u2192 ${p.target} ${colors.dim(reason)}`]}if(p.status==="not-imported"||p.status==="workspace"||p.status==="private")return[];if(p.notes.includes("up to date"))return[];if(p.skipReason==="TIME_BUDGET")return[];if(p.status==="skipped")return[`${colors.bold(p.name)} ${p.installed} ${colors.dim(`skipped: ${p.notes.join("; ")||"unknown reason"}`)}`];lines.push(header);let analyzed=analyzedImporters(p);analyzed&&(p.importers?.length??0)>1&&lines.push(colors.dim(` analyzed in ${analyzed}`));for(let note of importerNotes(p))lines.push(` ${colors.yellow("\u26A0")} ${note}`);let visible=p.findings.filter(f=>f.severity!=="additive"&&f.severity!=="info"&&(opts.all||f.confidence>=.5)),breaking=visible.filter(f=>f.severity==="breaking"),unverified=visible.filter(f=>f.severity==="unverified"),deprecated=visible.filter(f=>f.severity==="deprecated"),render=siteLines,unanalyzed=p.unanalyzed.length;if(visible.length===0&&(p.status==="unknown"?lines.push(` ${colors.magenta("?")} unknown: ${unanalyzed} of ${plural(p.callSitesChecked+unanalyzed,"site")} not analyzed (require/dynamic import)`):unanalyzed>0?lines.push(` ${colors.green("\u2713")} no impact in ${plural(p.callSitesChecked,"analyzed site")} \xB7 ${colors.yellow("\u26A0")} ${plural(unanalyzed,"site")} not analyzed`):lines.push(` ${colors.green("\u2713")} no impact on your code (${plural(p.callSitesChecked,"call site")} checked)`)),breaking.length>0){let files=new Set(breaking.flatMap(f=>f.change.kind==="cause"?(f.downstream??[]).map(d=>d.file):[f.usage.file])).size,sites=breaking.reduce((n,f)=>n+(f.change.kind==="cause"?f.downstream?.length??0:1),0);lines.push("",` ${colors.red(colors.bold("BREAKING"))} ${plural(sites,"call site")} in ${plural(files,"file")}`),lines.push(...render(breaking,"\u2717",colors,colors.red))}unverified.length>0&&(lines.push("",` ${colors.magenta(colors.bold("UNVERIFIED"))} ${plural(unverified.length,"call site")} ${colors.dim(p.tier==="generic"?"(the declarations changed here; nothing confirmed that the code breaks)":"(verification incomplete)")}`),lines.push(...render(unverified,"?",colors,colors.magenta))),deprecated.length>0&&(lines.push("",` ${colors.yellow(colors.bold("DEPRECATED"))} ${plural(deprecated.length,"call site")}`),lines.push(...render(deprecated,"!",colors,colors.yellow)));let hidden=p.findings.filter(f=>f.severity!=="additive"&&(f.severity==="info"||!opts.all&&f.confidence<.5)).length;hidden>0&&lines.push(colors.dim(` ${plural(hidden,"low-confidence finding")} hidden (use --all)`));for(let r of p.runtime??[]){let who=(p.runtime?.length??0)>1?`${r.package}: `:"",unused=r.changes.filter(c=>c.key&&r.usedKeys&&!r.usedKeys.includes(c.key)),unusedKeys=new Set(unused.map(c=>c.key));for(let c of r.changes)!opts.all&&unused.includes(c)||lines.push(colors.dim(` \u2699 runtime (${r.node}): ${who}${c.detail}`));unusedKeys.size>0&&lines.push(colors.dim(` \u2699 ${who}${unusedKeys.size} unused exports removed${opts.all?"":" (use --all)"}`)),isNativeProbeSkip(r.inconclusive)?lines.push(colors.dim(` \u2699 ${who}native package, runtime probe skipped`)):r.inconclusive&&lines.push(colors.dim(` \u2699 runtime (${r.node}): ${who}inconclusive, ${r.inconclusive}`))}for(let note of p.notes)visible.length===0&&/sites? not analyzed/.test(note)||lines.push(colors.dim(` \u26A0 ${note}`));return lines}function formatCheckDetails(report,opts={}){let colors=import_picocolors2.default.createColors(opts.color??!0),lines=[],grouped=report.workspaces.length>1;for(let workspace of["*",...report.workspaces]){let blocks=report.packages.filter(p=>p.workspace===workspace).map(p=>packageLines(p,opts,colors)).filter(b=>b.length>0);if(blocks.length!==0){if(grouped){let title=workspace==="*"?"(shared across workspaces)":workspace==="."?"(root)":workspace;lines.push(colors.bold(colors.underline(title)),"")}for(let block of blocks)lines.push(...block,"")}}let privates=[...new Set(report.packages.filter(p=>p.status==="private").map(p=>p.name))].sort();privates.length>0&&lines.push(colors.dim(`${plural(privates.length,"private package")} skipped: registry auth or not on the registry (${privates.join(", ")})`),"");let s=report.summary,actionable=s.breaking+s.deprecated;return lines.push(`${colors.bold("Summary:")} ${plural(s.packagesNeedingAttention,"package")} need${s.packagesNeedingAttention===1?"s":""} attention \xB7 ${s.breaking} breaking \xB7 ${s.deprecated} deprecated${s.unverified>0?` \xB7 ${s.unverified} unverified`:""} \xB7 ${s.unaffected} unaffected${s.partiallyAnalyzed>0?` \xB7 ${s.partiallyAnalyzed} partially analyzed`:""}${s.notImported>0?` \xB7 ${s.notImported} not imported`:""}`),actionable>0&&lines.push(` ${s.autoFixable} of ${plural(actionable,"finding")} ${actionable===1?"is":"are"} mechanical`),`${lines.join(`
40
39
  `)}
41
- `}var import_picocolors3=__toESM(require_picocolors(),1);function elapsed(ms){if(ms<1e3)return`${Math.round(ms)}ms`;if(ms<1e4)return`${(ms/1e3).toFixed(1)}s`;let s=Math.round(ms/1e3);return s<60?`${s}s`:`${Math.floor(s/60)}m ${String(s%60).padStart(2,"0")}s`}var FRAMES=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],HEARTBEAT_MS=1e4;function createProgress(io,ui,options={}){let colors=import_picocolors3.default.createColors(ui.color),quiet=options.quiet===!0,activity="";return{event(event){let label=[event.phase,event.detail??event.package,event.workspace].filter(Boolean).join(" \xB7 ");event.state==="start"?activity=label:(quiet||(ui.interactive&&io.err("\r\x1B[2K"),io.err(` ${label} (${elapsed(event.ms??0)})
42
- `)),activity="")},async phase(label,work,detail){let started=io.now(),since=()=>elapsed(io.now()-started),frame=0,tick=ui.interactive?setInterval(()=>{frame=(frame+1)%FRAMES.length,io.err(`\r\x1B[2K${colors.cyan(FRAMES[frame]??"")} ${activity||label} ${colors.dim(since())}`)},80):quiet?void 0:setInterval(()=>io.err(`\u2026 ${activity||label}, still working (${since()})
43
- `),HEARTBEAT_MS);tick?.unref?.(),ui.interactive&&io.err(`${colors.cyan(FRAMES[0]??"")} ${label}`);let clear=()=>{clearInterval(tick),ui.interactive&&io.err("\r\x1B[2K")};try{let result=await work();if(clear(),quiet)return result;let text=detail?.(result);return io.err(`${colors.green("\u2714")} ${label}${text?` ${text}`:""} ${colors.dim(`(${since()})`)}
44
- `),result}catch(err){throw clear(),io.err(`${colors.red("\u2716")} ${label} ${colors.dim(`(${since()})`)}
45
- `),err}},note(text){quiet||io.err(` ${colors.dim(text)}
46
- `)}}}var plural2=(n,one,many=`${one}s`)=>`${n} ${n===1?one:many}`;function repoLine(h){let shape=h.packages>0?`${h.manager}, ${plural2(h.packages,"package")}`:h.manager;return`${h.repo} (${shape})`}var planOf=p=>p.plan??planPackage(p);function targetSource(p,opts){return opts.repeat?.targets?.[p.name]!==void 0?"--target":p.target===p.latest?"latest on npm":""}function bump(installed,target){let parts=v=>(v.match(/\d+/g)??[]).slice(0,3).map(Number),[a,b]=[parts(installed),parts(target)];return a.length<3||b.length<3?"":a[0]!==b[0]?"major":a[1]!==b[1]?"minor":a[2]!==b[2]?"patch":""}function byLine(groups){let total={rule:0,agent:0,manual:0};for(let g of groups)total.rule+=g.by.rule,total.agent+=g.by.agent,total.manual+=g.by.manual;return[total.rule>0?`${total.rule} by rule`:"",total.agent>0?`${total.agent} by agent`:"",total.manual>0?`${total.manual} manual`:""].filter(Boolean).join(" \xB7 ")}var byLabel=g=>[g.by.rule>0?"by rule":"",g.by.agent>0?"by agent":"",g.by.manual>0?"manual":""].filter(Boolean).join(" + "),filesOf=groups=>new Set(groups.flatMap(g=>g.locations.map(l=>l.file))).size,sitesOf=groups=>groups.reduce((n,g)=>n+g.sites,0);function rowOf(p,multi,colors){if(["not-imported","workspace","private"].includes(p.status)||p.notes.includes("up to date"))return;let plan=planOf(p),of=severity=>plan.filter(g=>g.severity===severity),[breaking,unverified,deprecated]=[of("breaking"),of("unverified"),of("deprecated")],where=multi&&p.workspace!=="*"&&p.workspace!=="."?colors.dim(` (${p.workspace})`):"",members=p.members?` (${plural2(p.members.length,"package")})`:"",unanalyzed=p.unanalyzed.length,verdict3,by="";if(p.status==="no-types"||p.status==="skipped"){let reason=p.notes.find(n=>n.startsWith("types in "))??p.notes.find(n=>/type declarations|not installed/.test(n))??p.notes[0]??"no type declarations";verdict3=colors.dim(`\u2013 not analyzed: ${reason.split(";")[0]}`)}else if(breaking.length>0){let sites=sitesOf(breaking),files=filesOf(breaking),extra=unverified.length>0?`, ${sitesOf(unverified)} unverified`:"";verdict3=`${colors.red("\u2717")} ${sites} breaking${sites>1?` in ${plural2(files,"file")}`:""}${extra}`,by=byLine([...breaking,...unverified])}else unverified.length>0?(verdict3=`${colors.magenta("?")} ${sitesOf(unverified)} unverified`,by=byLine(unverified)):deprecated.length>0?(verdict3=`${colors.yellow("!")} ${sitesOf(deprecated)} deprecated`,by=byLine(deprecated)):p.status==="unknown"?verdict3=`${colors.magenta("?")} ${unanalyzed} of ${plural2(p.callSitesChecked+unanalyzed,"site")} not analyzed`:unanalyzed>0?verdict3=`${colors.green("\u2713")} no impact in ${plural2(p.callSitesChecked,"site")}, ${unanalyzed} not analyzed`:verdict3=`${colors.green("\u2713")} no impact ${colors.dim(`(${plural2(p.callSitesChecked,"call site")})`)}`;return{p,name:`${p.name}${members}${where}`,versions:`${p.installed} \u2192 ${p.target}`,bump:bump(p.installed,p.target),verdict:verdict3,by,plan}}var COLOR=new RegExp("\x1B\\[[0-9;]*m","g"),width=text=>text.replace(COLOR,"").length,pad=(text,to)=>text+" ".repeat(Math.max(0,to-width(text)));function deprecatedNames(groups){let counts=new Map;for(let g of groups)for(let[name,n]of Object.entries(g.symbols??{}))counts.set(name,(counts.get(name)??0)+n);let names2=[...counts].sort((a,b)=>b[1]-a[1]||a[0].localeCompare(b[0]));return`${names2.slice(0,3).map(([name])=>name).join(", ")}${names2.length>3?", ...":""}`}function sectionLines(row,colors){let acting=row.plan.filter(g=>g.severity!=="deprecated"),deprecated=row.plan.filter(g=>g.severity==="deprecated"),importers=importerNotes(row.p);if(acting.length===0&&deprecated.length===0&&importers.length===0)return[];let scope=g=>{if(g.fixes!==g.sites)return`${plural2(g.fixes,"fix","fixes")}, ${plural2(g.sites,"error")}`;let only=g.locations[0];return g.sites===1&&only?`${basename(only.file)}:${only.line}`:plural2(g.sites,"site")},titleWidth=Math.max(...acting.map(g=>g.title.length),0),scopeWidth=Math.max(...acting.map(g=>scope(g).length),0),lines=[colors.bold(row.p.name)];for(let g of acting){let mark=g.severity==="breaking"?colors.red("\u2717"):colors.magenta("?");lines.push(` ${mark} ${pad(g.title,titleWidth)} ${pad(scope(g),scopeWidth)} ${colors.dim(byLabel(g))}`),g.note&&lines.push(colors.dim(` ${g.note}`))}if(deprecated.length>0){let sites=sitesOf(deprecated),byRule=deprecated.reduce((n,g)=>n+g.by.rule,0),who=byRule>0?`${byRule} by rule`:byLine(deprecated);lines.push(` ${colors.yellow("!")} ${plural2(sites,"deprecated call")} (${deprecatedNames(deprecated)}) ${colors.dim(who)}`)}for(let note of importers)lines.push(` ${colors.yellow("\u26A0")} ${note}`);return lines}function nextCommands(rows,opts){let uptide=opts.invocation??"npx uptide",quote=s=>/^[\w./@:=+-]+$/.test(s)?s:`'${s.replaceAll("'",`'"'"'`)}'`,cwd=opts.repeat?.cwd?` --cwd ${quote(opts.repeat.cwd)}`:"",commands=[];for(let row of rows){let name=row.p.name;if(!opts.fixable?.includes(name))continue;let target=opts.repeat?.targets?.[name],pinned=target?` --target ${quote(target)}`:"";row.plan.some(g=>g.severity!=="deprecated")?commands.push([`${uptide} fix --only ${name}${pinned}${cwd}`,"migrate on a new branch, verify, no push"]):row.plan.some(g=>g.by.rule>0)&&commands.push([`${uptide} fix --only ${name}${pinned} --include-deprecated${cwd}`,"migrate the deprecated calls on a new branch, no push"])}let only=opts.repeat?.only?` --only ${quote(opts.repeat.only)}`:"",targets=Object.entries(opts.repeat?.targets??{}).map(([name,version])=>` --target ${quote(`${name}@${version}`)}`).join("");return commands.push(opts.details?[`${uptide} check${only}${targets}${cwd}`,"the summary, one line per change"]:[`${uptide} check${only}${targets} --details${cwd}`,"every site and reason"]),commands}function nextLines(rows,opts,colors){let commands=nextCommands(rows,opts),widest=Math.max(...commands.map(([command])=>command.length));return[colors.bold("Next"),...commands.map(([command,what])=>` ${pad(command,widest)} ${colors.dim(what)}`)]}function checkRows(report,colors=import_picocolors4.default.createColors(!1)){let multi=report.workspaces.length>1,weight=(row,severity)=>sitesOf(row.plan.filter(g=>g.severity===severity));return report.packages.map(p=>rowOf(p,multi,colors)).filter(row=>row!==void 0).sort((a,b)=>weight(b,"breaking")-weight(a,"breaking")||weight(b,"unverified")-weight(a,"unverified")||weight(b,"deprecated")-weight(a,"deprecated"))}function formatCheck(report,opts={}){let colors=import_picocolors4.default.createColors(opts.color??!0),lines=[];if(opts.header){let dot=colors.dim("\xB7");lines.push(`${colors.bold("uptide check")} ${dot} ${repoLine(opts.header)} ${dot} ${elapsed(opts.header.ms)}`,"")}let rows=checkRows(report,colors);if(opts.details)lines.push(formatCheckDetails(report,{color:opts.color,all:opts.all}).trimEnd(),"");else{let col=pick=>Math.max(...rows.map(r=>width(pick(r))),0),move=row=>[row.bump,targetSource(row.p,opts)].filter(Boolean).join(" \xB7 "),[names2,versions,bumps]=[col(r=>r.name),col(r=>r.versions),col(move)],verdicts=Math.max(...rows.filter(r=>r.by).map(r=>width(r.verdict)),0);for(let row of rows)lines.push(`${pad(colors.bold(row.name),names2)} ${pad(row.versions,versions)} ${pad(colors.dim(move(row)),bumps)} ${row.by?`${pad(row.verdict,verdicts)} ${colors.dim(row.by)}`:row.verdict}`);rows.length===0&&lines.push(colors.dim("Nothing to upgrade: every checked dependency is up to date.")),lines.push("");for(let row of rows){let section=sectionLines(row,colors);section.length>0&&lines.push(...section,"")}}return lines.push(...nextLines(rows,opts,colors)),`${lines.join(`
40
+ `}var import_picocolors3=__toESM(require_picocolors(),1);import{stripVTControlCharacters as stripVTControlCharacters3}from"util";var textWidth=text=>Array.from(stripVTControlCharacters3(text)).length,ellipsis=(text,width2)=>{let chars=Array.from(text);return chars.length<=width2?text:`${chars.slice(0,Math.max(0,width2-1)).join("")}\u2026`},NAME_CAP=45;function alignedRows(rows,width2,color,indent=0){let colors=import_picocolors3.default.createColors(color);rows=rows.map(row=>row.map((cell,column)=>{let marker=cell.alignAt;if(!marker||!cell.text.includes(marker))return cell;let before=cell.text.indexOf(marker),widest=Math.max(...rows.map(r=>{let other=r[column];return other&&other.alignAt===marker?Math.max(0,other.text.indexOf(marker)):0}));return{...cell,text:" ".repeat(widest-before)+cell.text}}));let lengths=Array.from({length:Math.max(0,...rows.map(r=>r.length))},(_,i)=>Math.max(0,...rows.map(r=>textWidth(r[i]?.span?"":r[i]?.text??""))));for(;lengths.at(-1)===0;)lengths.pop();let total=()=>lengths.reduce((a,b)=>a+b,0)+Math.max(0,lengths.length-1)*3+indent;for(lengths[0]&&(lengths[0]=Math.min(NAME_CAP,Math.max(12,lengths[0])));total()>width2&&lengths.length>2;)lengths.pop();return total()>width2&&lengths[1]&&(lengths[1]=Math.max(1,lengths[1]-(total()-width2))),rows.map(row=>{let cells=[],consumed=indent,wrapped="";for(let[i,length]of lengths.entries()){let cell=row[i],available=cell?.span?width2-consumed:length;if(i===0&&cell&&textWidth(cell.text)>length){wrapped=`${" ".repeat(indent)}${cell.tone?colors[cell.tone](cell.text):cell.text}
41
+ `,cells.push(" ".repeat(length)),consumed+=length+3;continue}let text=ellipsis(cell?.text??"",Math.max(1,available)),styled=cell?.tone?colors[cell.tone](text):text;if(cells.push(styled+(cell?.span||i===lengths.length-1?"":" ".repeat(Math.max(0,length-textWidth(text))))),consumed+=length+3,cell?.span)break}return wrapped+(" ".repeat(indent)+cells.join(" ")).trimEnd()})}var terminalHeader=(command,header,color)=>{let c=import_picocolors3.default.createColors(color);return`${c.bold(`uptide ${command}`)} ${c.dim("\xB7")} ${header.repo} ${c.dim("\xB7")} ${header.manager} ${c.dim("\xB7")} ${header.ms<1e3?`${Math.round(header.ms)}ms`:`${(header.ms/1e3).toFixed(header.ms<1e4?1:0)}s`}`};var NO_IMPACT_ROWS=5,MAX_RULE_LINES=8,FIX_SUGGESTIONS=3,plural2=(n,one,many=`${one}s`)=>`${n} ${n===1?one:many}`;function repoLine(h){let shape=h.packages>0?`${h.manager}, ${plural2(h.packages,"package")}`:h.manager;return`${h.repo} (${shape})`}var planOf=p=>p.plan??planPackage(p);function targetSource(p,opts){return opts.repeat?.targets?.[p.name]!==void 0?"--target":p.target===p.latest?"latest on npm":""}function bump(installed,target){let parts=v=>(v.match(/\d+/g)??[]).slice(0,3).map(Number),[a,b]=[parts(installed),parts(target)];return a.length<3||b.length<3?"":a[0]!==b[0]?(b[0]??0)-(a[0]??0)>1?`${(b[0]??0)-(a[0]??0)} majors behind`:"major":a[1]!==b[1]?"minor":a[2]!==b[2]?"patch":""}function byLine(groups){let total={rule:0,agent:0,manual:0};for(let g of groups)total.rule+=g.by.rule,total.agent+=g.by.agent,total.manual+=g.by.manual;return[total.rule>0?BY.rule(total.rule):"",total.agent>0?BY.agent(total.agent):"",total.manual>0?`${total.manual} manual`:""].filter(Boolean).join(" \xB7 ")}var byLabel=g=>[g.by.rule>0?BY.ruleTag:"",g.by.agent>0?BY.agentTag:"",g.by.manual>0?"manual":""].filter(Boolean).join(" + "),filesOf=groups=>new Set(groups.flatMap(g=>g.locations.map(l=>l.file))).size,sitesOf=groups=>groups.reduce((n,g)=>n+g.sites,0),ANALYZED=["breaking","deprecated","safe","partial","unknown"],verdictLine=p=>p.verdict?.summary??(ANALYZED.includes(p.status)?verdictOf(p).summary:void 0);function rowOf(p,multi,colors){if(["not-imported","workspace","private"].includes(p.status)||p.notes.includes("up to date")||p.installed===p.target&&p.findings.length===0&&p.status==="safe"||p.skipReason==="TIME_BUDGET"||isFailure(p))return;let generic=p.tier==="generic",plan=planOf(p).filter(g=>!(generic&&g.severity==="unverified")),unconfirmed=generic?sitesOf(planOf(p).filter(g=>g.severity==="unverified")):0,aside=unconfirmed>0?colors.dim(` \xB7 ${unconfirmed} unconfirmed in --details`):"",of=severity=>plan.filter(g=>g.severity===severity),[breaking,unverified,deprecated]=[of("breaking"),of("unverified"),of("deprecated")],where=multi&&p.workspace!=="*"&&p.workspace!=="."?colors.dim(` (${p.workspace})`):"",members=p.members?` (${plural2(p.members.length,"package")})`:"",unanalyzed=p.unanalyzed.length,gaps=(p.importers??[]).filter(i=>!i.analyzed).length,verdict3,by="";if(p.status==="no-types"||p.status==="skipped"){let reason=p.notes.find(n=>n.startsWith("types in "))??p.notes.find(n=>/type declarations|not installed/.test(n))??p.notes[0]??"no type declarations";verdict3=colors.dim(`\u2013 not analyzed: ${reason.split(";")[0]}`)}else if(breaking.length>0){let sites=sitesOf(breaking),files=filesOf(breaking),extra=unverified.length>0?`, ${sitesOf(unverified)} unverified`:"";verdict3=`${colors.red("\u2717")} ${sites} breaking${sites>1?` in ${plural2(files,"file")}`:""}${extra}${aside}`,by=byLine([...breaking,...unverified])}else unverified.length>0?(verdict3=`${colors.magenta("?")} ${sitesOf(unverified)} unverified`,by=byLine(unverified)):deprecated.length>0?(verdict3=`${colors.yellow("!")} ${sitesOf(deprecated)} deprecated${aside}`,by=byLine(deprecated)):p.status==="unknown"?verdict3=`${colors.magenta("?")} ${unanalyzed} of ${plural2(p.callSitesChecked+unanalyzed,"site")} not analyzed`:unanalyzed>0?verdict3=`${colors.green("\u2713")} no impact in ${plural2(p.callSitesChecked,"site")}, ${unanalyzed} not analyzed${aside}`:gaps>0?verdict3=`${colors.magenta("?")} no impact in ${plural2(p.callSitesChecked,"site")}, ${plural2(gaps,"workspace")} not analyzed${aside}`:unconfirmed>0?verdict3=`${colors.green("\u2713")} nothing confirmed ${colors.dim(`(${plural2(p.callSitesChecked,"call site")})`)}${aside}`:verdict3=`${colors.green("\u2713")} no impact ${colors.dim(`(${plural2(p.callSitesChecked,"call site")})`)}`;return{p,name:`${p.name}${members}${where}`,versions:`${p.installed} \u2192 ${p.target}`,bump:bump(p.installed,p.target),verdict:verdict3,by,plan,quiet:plan.length===0&&gaps===0&&!["no-types","skipped","unknown"].includes(p.status),...verdictLine(p)?{summary:verdictLine(p)}:{}}}var COLOR=new RegExp("\x1B\\[[0-9;]*m","g");function deprecatedNames(groups){let counts=new Map;for(let g of groups)for(let[name,n]of Object.entries(g.symbols??{}))counts.set(name,(counts.get(name)??0)+n);let names2=[...counts].sort((a,b)=>b[1]-a[1]||a[0].localeCompare(b[0]));return`${names2.slice(0,3).map(([name])=>name).join(", ")}${names2.length>3?", ...":""}`}function sectionLines(row,colors){let acting=row.plan.filter(g=>g.severity!=="deprecated"),deprecated=row.plan.filter(g=>g.severity==="deprecated"),importers=importerNotes(row.p),peers=row.p.notes.flatMap(note=>{let m=/: (\S+)@(\S+) is outside the peer range (.+?) of (\S+);/.exec(note);return m?[`${m[4]} ${row.p.target} needs ${m[1]} ${m[3]} (installed: ${m[2]}): upgrade ${m[1]} first`]:[]}),heading=row.summary?`${colors.bold(row.p.name)} ${colors.dim(row.summary)}`:colors.bold(row.p.name);if(acting.length===0&&deprecated.length===0&&importers.length===0&&peers.length===0)return row.summary?[heading]:[];let scope=g=>{if(g.fixes!==g.sites)return`${plural2(g.fixes,"fix","fixes")}, ${plural2(g.sites,"error")}`;let only=g.locations[0];return g.sites===1&&only?`${basename(only.file)}:${only.line}`:plural2(g.sites,"site")},listed=acting.length>MAX_RULE_LINES?acting.slice(0,MAX_RULE_LINES-1):acting,titleWidth=Math.max(...listed.map(g=>g.title.length),0),scopeWidth=Math.max(...listed.map(g=>scope(g).length),0),lines=[heading];for(let g of listed){let mark=g.severity==="breaking"?colors.red("\u2717"):colors.magenta("?");lines.push(` ${mark} ${pad(g.title,titleWidth)} ${pad(scope(g),scopeWidth)} ${colors.dim(byLabel(g))}`),g.note&&lines.push(colors.dim(` ${g.note}`))}if(listed.length<acting.length){let rest=acting.slice(listed.length);lines.push(colors.dim(` \u2026 ${plural2(rest.length,"more change")}, ${plural2(sitesOf(rest),"site")} (--details)`))}if(deprecated.length>0){let sites=sitesOf(deprecated),byRule=deprecated.reduce((n,g)=>n+g.by.rule,0),who=byRule>0?BY.rule(byRule):byLine(deprecated);lines.push(` ${colors.yellow("!")} ${plural2(sites,"deprecated call")} (${deprecatedNames(deprecated)}) ${colors.dim(who)}`)}for(let note of importers)lines.push(` ${colors.yellow("\u26A0")} ${note}`);for(let note of peers)lines.push(` ${colors.yellow("\u26A0")} peer: ${note}`);return lines}function notAnalyzed(report,opts,colors){let uptide=opts.invocation??"npx uptide",late=report.packages.filter(p=>p.skipReason==="TIME_BUDGET"),failed=report.packages.filter(p=>isFailure(p));if(late.length===0&&failed.length===0)return[];let lines=[colors.bold("Not analyzed")];if(late.length>0){let budget=opts.maxTime?` (--max-time ${opts.maxTime})`:"";lines.push(` ${colors.yellow("\u26A0")} ${late.length} behind, out of time${budget}: ${late.slice(0,6).map(p=>p.name).join(", ")}${late.length>6?`, and ${late.length-6} more`:""}`,colors.dim(` ${uptide} check ${late.slice(0,3).map(p=>p.name).join(" ")} by name, no time limit`),colors.dim(` ${uptide} list discover upgrades, then check named packages`))}let reasonOf=p=>(p.notes[0]??"analysis failed").split(`
42
+ `)[0]?.replace(/ \(check it alone with --only \S+,/," (check one alone with --only,")??"",byReason=new Map;for(let p of failed)byReason.set(reasonOf(p),[...byReason.get(reasonOf(p))??[],p]);for(let[reason,group]of byReason){let only=group[0];lines.push(group.length===1?` ${colors.red("\u2717")} ${only.name} ${only.installed}: ${(only.notes[0]??"analysis failed").split(`
43
+ `)[0]}`:` ${colors.red("\u2717")} ${group.length} failed: ${reason}: ${group.slice(0,6).map(p=>p.name).join(", ")}${group.length>6?`, and ${group.length-6} more`:""}`)}return lines}function nextCommands(rows,opts){let uptide=opts.invocation??"npx uptide",quote2=s=>/^[\w./@:=+-]+$/.test(s)?s:`'${s.replaceAll("'",`'"'"'`)}'`,cwd=opts.repeat?.cwd?` --cwd ${quote2(opts.repeat.cwd)}`:"",commands=[],fixable=name=>opts.fixable===!0||Array.isArray(opts.fixable)&&opts.fixable.includes(name);for(let row of rows){let name=row.p.name;if(!fixable(name)||row.p.members)continue;if(commands.length>=FIX_SUGGESTIONS)break;let target=opts.repeat?.targets?.[name],pinned=target?` --target ${quote2(target)}`:"";row.plan.some(g=>g.severity!=="deprecated")?commands.push([`${uptide} fix ${name}${pinned}${cwd}`,row.p.tier==="generic"?"migrate with the agent on a new branch, verify, no push":"migrate on a new branch, verify, no push"]):row.p.tier!=="generic"&&row.plan.some(g=>g.by.rule>0)&&commands.push([`${uptide} fix ${name}${pinned} --include-deprecated${cwd}`,"migrate the deprecated calls on a new branch, no push"])}let names2=opts.repeat?.only?.split(",")??[...new Set(rows.flatMap(r=>(r.p.members??[r.p]).map(p=>p.name)))],only=names2.length?` ${names2.map(quote2).join(" ")}`:" <package>",planOnly=opts.repeat?.only?` --only ${quote2(opts.repeat.only)}`:"",targets=Object.entries(opts.repeat?.targets??{}).map(([name,version])=>` --target ${quote2(`${name}@${version}`)}`).join("");return rows.filter(r=>r.plan.length>0).length>1&&commands.push([`${uptide} plan${planOnly}${cwd}`,"the order to upgrade in, with the effort"]),commands.push(opts.details?[`${uptide} check${only}${targets}${cwd}`,"the summary, one line per change"]:[`${uptide} check${only}${targets} --details${cwd}`,"every site and reason"]),commands}function nextLines(rows,opts,colors){let commands=nextCommands(rows,opts),widest=Math.max(...commands.map(([command])=>command.length));return[colors.bold("Next"),...commands.map(([command,what])=>` ${pad(command,widest)} ${colors.dim(what)}`)]}function checkRows(report,colors=import_picocolors4.default.createColors(!1)){let multi=report.workspaces.length>1,weight=(row,severity)=>sitesOf(row.plan.filter(g=>g.severity===severity));return report.packages.map(p=>rowOf(p,multi,colors)).filter(row=>row!==void 0).sort((a,b)=>weight(b,"breaking")-weight(a,"breaking")||weight(b,"unverified")-weight(a,"unverified")||weight(b,"deprecated")-weight(a,"deprecated"))}var width=text=>text.replace(COLOR,"").length,pad=(text,to)=>text+" ".repeat(Math.max(0,to-width(text)));function formatCheck(report,opts={}){let colors=import_picocolors4.default.createColors(opts.color??!0),lines=[];opts.header&&lines.push(terminalHeader("check",opts.header,opts.color??!0),"");let rows=checkRows(report,colors);if(opts.details)lines.push(formatCheckDetails(report,{color:opts.color,all:opts.all}).trimEnd(),"");else{let move=row=>[row.bump,targetSource(row.p,opts)].filter(Boolean).join(" \xB7 "),quiet=rows.filter(r=>r.quiet),folded=quiet.length>NO_IMPACT_ROWS?quiet:[],shown=rows.filter(r=>!folded.includes(r));if(lines.push(...alignedRows(shown.map(row=>[{text:row.name,tone:"bold"},{text:row.versions,alignAt:"\u2192"},{text:move(row),tone:row.bump.startsWith("major")?"yellow":"dim"},{text:row.p.tier==="verified"?"verified":"",tone:"green"},{text:row.verdict.replace(COLOR,"")},{text:row.by,tone:"dim"}]),opts.width??160,opts.color??!0)),folded.length>0){let named=folded.slice(0,6).map(r=>r.p.name),unverified=folded.filter(r=>r.p.verdict?.notVerified??!r.p.compile).length,counted=folded.every(r=>r.p.compile?.newErrors===0),how=unverified>0?`${unverified} not verified by the compiler (--details)`:`compiled against their targets${counted?": 0 new type errors":""}`;lines.push(`${colors.green("\u2713")} ${folded.length} more with no impact on your code: ${named.join(", ")}${folded.length>named.length?`, and ${folded.length-named.length} more`:""} ${colors.dim(`\xB7 0 breaking \xB7 ${how}`)}`)}let missing=notAnalyzed(report,opts,colors);rows.length===0&&missing.length===0&&lines.push(colors.dim("Nothing to upgrade: every checked dependency is up to date.")),rows.some(r=>r.p.tier==="generic")&&lines.push("",colors.dim(TIER_LEGEND)),lines.push(""),missing.length>0&&lines.push(...missing,"");for(let row of rows.filter(r=>!folded.includes(r))){let section=sectionLines(row,colors);section.length>0&&lines.push(...section,"")}}return lines.push(...nextLines(rows,opts,colors)),`${lines.join(`
47
44
  `)}
48
- `}import{isAbsolute,relative}from"path";var import_picocolors5=__toESM(require_picocolors(),1);function formatFixSummary(report,opts={}){let colors=import_picocolors5.default.createColors(opts.color??!0),uptide=opts.invocation??"npx uptide",cells=summaryCells(report),dot=colors.dim("\xB7"),title=report.mode==="pin"?`pin ${report.package} API version ${report.apiVersion??""}`:`${report.package} ${report.from??"?"} \u2192 ${report.target}${report.targetSource?` ${colors.dim(`(${report.targetSource})`)}`:""}`,verdict3=report.verification.passed?colors.green("verification passed"):colors.red("verification failed"),lines=[`${colors.bold("uptide fix")} ${dot} ${title} ${dot} ${verdict3} ${dot} ${elapsed(opts.ms??report.timingMs)}`,"",...[["Risk",cells.risk],["Changes",cells.changes],["Types",cells.types],["Behavior",cells.behavior],["Tests",cells.tests]].map(([label,text])=>` ${pad2(label,9)} ${plain(text)}`),""],from=opts.cwd??report.source??report.repo,where=report.source?"in your repository, not checked out":`in ${report.repo}`;lines.push(`${colors.bold("Branch")} ${report.branch} ${colors.dim(`(${where})`)}`);let base=report.base??"main";lines.push(` git diff ${base}..${report.branch} --stat`),report.clone?.kept&&lines.push(colors.dim(` temporary clone kept at ${report.clone.path}: ${report.clone.reason}`)),lines.push("",colors.bold("Next"));let next=[];report.prUrl?next.push([report.prUrl,"the pull request"]):report.verification.passed?next.push([`${uptide} pr --branch ${report.branch}`,`push the branch and open ${report.publication?.refused.length?"":"a draft "}PR${report.remote?` on ${report.remote.replace(/^https:\/\/github\.com\//,"")}`:""}`]):next.push([`${uptide} verify --branch ${report.branch}`,"verify again after fixing what failed"]);let local=file=>{let rel=relative(from,file);return rel.startsWith("..")||isAbsolute(rel)?file:rel};report.html&&next.push([`open ${local(report.html)}`,"the migration report"]),next.push([local(report.prBody),"the PR description"]);let width2=Math.max(...next.map(([c])=>c.length));for(let[cmd,what]of next)lines.push(` ${pad2(cmd,width2)} ${colors.dim(what)}`);return`${lines.join(`
45
+ `}import{isAbsolute,relative}from"path";var import_picocolors6=__toESM(require_picocolors(),1);var import_picocolors5=__toESM(require_picocolors(),1);function elapsed(ms){if(ms<1e3)return`${Math.round(ms)}ms`;if(ms<1e4)return`${(ms/1e3).toFixed(1)}s`;let s=Math.round(ms/1e3);return s<60?`${s}s`:`${Math.floor(s/60)}m ${String(s%60).padStart(2,"0")}s`}var FRAMES=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],HEARTBEAT_MS=1e4;function createProgress(io2,ui,options={}){let colors=import_picocolors5.default.createColors(ui.color),quiet=options.quiet===!0,activity="";return{event(event){let label=[event.phase,event.detail??event.package,event.workspace].filter(Boolean).join(" \xB7 ");event.state==="start"?activity=label:(quiet||(ui.interactive&&io2.err("\r\x1B[2K"),io2.err(` ${label} (${elapsed(event.ms??0)})
46
+ `)),activity="")},async phase(label,work,detail){let started=io2.now(),since=()=>elapsed(io2.now()-started),frame=0,tick=ui.interactive?setInterval(()=>{frame=(frame+1)%FRAMES.length,io2.err(`\r\x1B[2K${colors.cyan(FRAMES[frame]??"")} ${activity||label} ${colors.dim(since())}`)},80):quiet?void 0:setInterval(()=>io2.err(`\u2026 ${activity||label}, still working (${since()})
47
+ `),HEARTBEAT_MS);tick?.unref?.(),ui.interactive&&io2.err(`${colors.cyan(FRAMES[0]??"")} ${label}`);let clear=()=>{clearInterval(tick),ui.interactive&&io2.err("\r\x1B[2K")};try{let result=await work();if(clear(),quiet)return result;let text=detail?.(result);return io2.err(`${colors.green("\u2714")} ${label}${text?` ${text}`:""} ${colors.dim(`(${since()})`)}
48
+ `),result}catch(err){throw clear(),io2.err(`${colors.red("\u2716")} ${label} ${colors.dim(`(${since()})`)}
49
+ `),err}},note(text){quiet||io2.err(` ${colors.dim(text)}
50
+ `)}}}function formatFixSummary(report,opts={}){let colors=import_picocolors6.default.createColors(opts.color??!0),uptide=opts.invocation??"npx uptide",cells=summaryCells(report),dot=colors.dim("\xB7"),title=report.mode==="pin"?`pin ${report.package} API version ${report.apiVersion??""}`:`${report.package} ${report.from??"?"} \u2192 ${report.target}${report.targetSource?` ${colors.dim(`(${report.targetSource})`)}`:""}`,verdict3=report.verification.passed?colors.green("verification passed"):colors.red("verification failed"),lines=[`${colors.bold("uptide fix")} ${dot} ${title} ${dot} ${verdict3} ${dot} ${elapsed(opts.ms??report.timingMs)}`,"",...[["Risk",cells.risk],["Changes",cells.changes],["Types",cells.types],["Behavior",cells.behavior],["Tests",cells.tests]].map(([label,text])=>` ${pad2(label,9)} ${plain(text)}`),...report.tier==="generic"&&report.sites.some(s=>s.outcome==="agent")?[` ${pad2("Tier",9)} generic: no migration pack; every edit is the agent's, kept on the compiler's word. Review each one.`]:[],...report.llm.costLimit?[` ${pad2("Agent",9)} stopped at $${report.llm.costLimit.limitUsd.toFixed(2)} (--max-cost): ${report.llm.costLimit.notAttempted} site${report.llm.costLimit.notAttempted===1?"":"s"} not completed`]:[],""],from=opts.cwd??report.source??report.repo,where=report.source?"in your repository, not checked out":`in ${report.repo}`;lines.push(`${colors.bold("Branch")} ${report.branch} ${colors.dim(`(${where})`)}`);let base=report.base??"main";lines.push(` git diff ${base}..${report.branch} --stat`),report.clone?.kept&&lines.push(colors.dim(` temporary clone kept at ${report.clone.path}: ${report.clone.reason}`)),lines.push("",colors.bold("Next"));let next=[];report.prUrl?next.push([report.prUrl,"the pull request"]):report.verification.passed?next.push([`${uptide} pr --branch ${report.branch}`,`push the branch and open ${report.publication?.refused.length?"":"a draft "}PR${report.remote?` on ${report.remote.replace(/^https:\/\/github\.com\//,"")}`:""}`]):next.push([`${uptide} verify --branch ${report.branch}`,"verify again after fixing what failed"]);let local=file=>{let rel=relative(from,file);return rel.startsWith("..")||isAbsolute(rel)?file:rel};report.html&&next.push([`open ${local(report.html)}`,"the migration report"]),next.push([local(report.prBody),"the PR description"]);let width2=Math.max(...next.map(([c])=>c.length));for(let[cmd,what]of next)lines.push(` ${pad2(cmd,width2)} ${colors.dim(what)}`);return`${lines.join(`
49
51
  `)}
50
- `}function plain(text){return text.replaceAll("`","").replace(/\*\*([^*]+)\*\*/g,"$1")}var pad2=(text,to)=>text+" ".repeat(Math.max(0,to-text.length));import{createHash as createHash2}from"crypto";import{existsSync as existsSync3,mkdirSync,readFileSync as readFileSync4,writeFileSync}from"fs";import{dirname as dirname3,join as join3}from"path";var css=`
51
- :root{color-scheme:dark light;--bg:#0e0e11;--panel:#131316;--border:#2a2a2f;--text:#f2f1ec;--muted:#b4b3ad;--accent:#e0a458;--red:#ff8e91;--amber:#e9b55d;--gray:#c0bfc8;--green:#8dd5ae}
52
- @media(prefers-color-scheme:light){:root{--bg:#f8f7f3;--panel:#fff;--border:#d5d3ca;--text:#202026;--muted:#5c5b56;--accent:#895113;--red:#a51e32;--amber:#815100;--gray:#595963;--green:#18663b}}
53
- *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.55 'IBM Plex Sans',system-ui,sans-serif}main{max-width:1120px;margin:auto;padding:40px 28px 64px}h1{font-size:32px;letter-spacing:-1px;margin:12px 0 4px}h2{font-size:20px;margin:30px 0 12px}h3{font-size:16px;margin:0}.brand{font-weight:700;color:var(--accent);letter-spacing:2px}.meta,.muted{color:var(--muted)}.meta{display:flex;gap:8px 24px;flex-wrap:wrap}.summary,.package,.notes,.next{border:1px solid var(--border);border-radius:10px;background:var(--panel);margin:16px 0;overflow:hidden}.dep{display:grid;grid-template-columns:minmax(160px,1fr) 2fr;gap:8px;padding:16px 20px;border-bottom:1px solid var(--border);text-decoration:none;color:var(--text)}.dep:last-child{border-bottom:0}.dep strong{display:block}.breaking{color:var(--red)}.deprecated{color:var(--amber)}.unverified{color:var(--gray)}.safe{color:var(--green)}.package>header h2{margin:0 0 4px}.package>header{padding:18px 20px;border-bottom:1px solid var(--border)}details{border-top:1px solid var(--border)}summary{padding:14px 20px;cursor:pointer}summary:hover{background:color-mix(in srgb,var(--accent) 6%,transparent)}summary .counts{display:block;margin-left:16px;font-size:13px;color:var(--muted)}.group-note{margin:0 20px 12px}.site{padding:14px 20px;border-top:1px solid var(--border)}a{color:var(--accent);overflow-wrap:anywhere}p{overflow-wrap:anywhere;margin:8px 0}code,pre,.mono{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12px}pre{margin:12px 0 0;padding:8px 0;background:var(--bg);border:1px solid var(--border);border-radius:6px;overflow:auto;tab-size:2}.code-line{display:block;padding:0 12px;min-height:1.5em}.number{display:inline-block;width:4ch;margin-right:12px;text-align:right;color:var(--muted);user-select:none}.hit{background:color-mix(in srgb,var(--accent) 14%,var(--bg));border-left:3px solid var(--accent);padding-left:9px}.more{padding:12px 20px;color:var(--muted)}.notes ul{padding:0 40px 12px}.next{padding:4px 20px 16px}.command{display:flex;gap:12px;align-items:center;justify-content:space-between;margin:8px 0;padding:12px;border:1px solid var(--border);border-radius:6px}.command code{white-space:pre-wrap;overflow-wrap:anywhere}button,input{font:inherit;border:1px solid var(--border);border-radius:6px;color:var(--text);background:var(--panel);padding:8px 12px}button{cursor:pointer}button[aria-pressed=true]{border-color:var(--accent);color:var(--accent)}button:focus-visible,input:focus-visible,summary:focus-visible,a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}.filters{display:flex;gap:8px;flex-wrap:wrap;margin:24px 0 12px}.filters input{flex:1;min-width:180px}.notice{border-left:3px solid var(--accent);padding:8px 14px;margin:16px 0}footer{margin-top:28px;color:var(--muted);font-size:13px}[hidden]{display:none!important}
54
- .compiler{margin-top:8px;border:0}.compiler summary{padding:4px 0;font-size:12px;color:var(--muted)}.compiler pre{white-space:pre-wrap;overflow-wrap:anywhere;padding:12px}
55
- @media(max-width:600px){main{padding:24px 14px}.dep{grid-template-columns:1fr;padding:14px}.site,summary,.package>header h2{margin:0 0 4px}.package>header{padding:12px}.command{align-items:flex-start}h1{font-size:26px}}
56
- @media print{:root{--bg:#fff;--panel:#fff;--border:#bbb;--text:#111;--muted:#444;--accent:#644018;--red:#8a1823;--amber:#714800;--gray:#444;--green:#17582e}body{font-size:10pt}main{max-width:none;padding:0}.filters,button{display:none!important}[hidden]:not(.filters):not(button){display:block!important}details::details-content{display:block!important;content-visibility:visible!important}details>*:not(summary){display:block!important}.package,.summary,.notes{overflow:visible}pre{white-space:pre-wrap;overflow:visible}.site{break-inside:avoid}a{color:inherit;text-decoration:none}.dep{break-inside:avoid}#empty-filter{display:none!important}}
52
+ `}function plain(text){return text.replaceAll("`","").replace(/\*\*([^*]+)\*\*/g,"$1")}var pad2=(text,to)=>text+" ".repeat(Math.max(0,to-text.length));var import_picocolors7=__toESM(require_picocolors(),1);var plural3=(count,noun,multiple=`${noun}s`)=>`${count} ${count===1?noun:multiple}`,quote=s=>/^[\w./@:=+-]+$/.test(s)?s:`'${s.replaceAll("'",`'"'"'`)}'`,dependencyKey=p=>JSON.stringify([p.name,p.registryName??p.name,p.current]),listCommand=(packages,opts)=>`${opts.invocation??INVOCATION} check ${[...new Set(packages.map(p=>p.name))].map(quote).join(" ")}${opts.cwd?` --cwd ${quote(opts.cwd)}`:""}`,listChange=p=>p.majorGap>1?`${p.majorGap} majors behind`:p.change,listVersions=p=>{let outdated=p.versions?.map(v=>v.version).filter(v=>v!==p.latest)??[p.current];return`${outdated.length>2?`${outdated[0]} \u2026 ${outdated.at(-1)}`:outdated.join(", ")} \u2192 ${p.latest}`},listSpread=p=>p.versions?`${p.versions.length} versions in ${plural3(new Set(p.versions.flatMap(v=>v.workspaces)).size,"workspace")}`:"",groupCommand=(group,opts)=>`${opts.invocation??INVOCATION} check --group ${quote(group.id)}${opts.cwd?` --cwd ${quote(opts.cwd)}`:""}`,priorityCommand=(p,opts)=>`${opts.invocation??INVOCATION} check ${p.group?`--group ${quote(p.group)}`:p.packages.map(quote).join(" ")}${p.target?` --target ${quote(p.target)}`:""}${opts.cwd?` --cwd ${quote(opts.cwd)}`:""}`,cheapBatchCommand=(names2,opts)=>`${opts.invocation??INVOCATION} check ${names2.map(quote).join(" ")}${opts.cwd?` --cwd ${quote(opts.cwd)}`:""}`;function advisoryStatus(report){let a=report.advisories;return a?a.status==="checked"?`advisories checked for ${plural3(a.packages,"package")}`:`advisories not checked${a.reason?` (${a.reason})`:""}`:"advisories not checked"}function cheapBatchLabel(names2,shown=4){return`${names2.slice(0,shown).join(", ")}${names2.length>shown?` +${names2.length-shown}`:""}`}var PRIORITY_ROWS=5;function listUsage(p){return[plural3(p.usage.files,"file"),p.usage.callSites?plural3(p.usage.callSites,"call"):"",p.usage.references?plural3(p.usage.references,"reference"):""].filter(Boolean).join(" \xB7 ")}function groupCount(group){let total=group.totalMembers??group.members.length;return`${plural3(total,"package")}${total===group.members.length?"":` (${group.members.length} in this section)`}`}function groupVersions(group){let main=group.members.filter(p=>!p.peerOf),byMajor=new Map;for(let p of main){let major=Number(p.latest.split(".")[0]);byMajor.set(major,[...new Set([...byMajor.get(major)??[],p.name])])}if(byMajor.size<=1)return`\u2192 ${[...byMajor.keys()][0]}.x`;let label=names2=>{let scopes=new Set(names2.map(n=>n.startsWith("@")?n.split("/")[0]:n)),[scope]=scopes;return names2.length>1&&scopes.size===1&&scope?.startsWith("@")?`${scope}/*`:names2.join(", ")},majors=[...byMajor].sort(([a],[b])=>b-a),labels=majors.map(([,names2])=>label(names2)),named=majors.map(([major],i)=>`${labels[i]} ${major}`).join(" \xB7 ");return new Set(labels).size===labels.length&&named.length<=64?`\u2192 ${named}`:`\u2192 ${majors.map(([major])=>`${major}.x`).join(" \xB7 ")}`}var UNUSED_HINT="no usage found by Uptide's scan; verify before removing",listReasons=p=>p.reasons.filter(reason=>!p.peerOf?.some(name=>reason===`required by ${name}`||reason===`peer dependency of ${name}`)),listSymbols=p=>p.usage.topSymbols.filter(s=>s.count>0).map(s=>`${s.name} (${s.count})`).join(", ");function listSections(report){let groups=report.groups.filter(g=>groupLead(g)?.classification==="used"),grouped=new Set(groups.flatMap(g=>g.members.map(dependencyKey))),remaining=report.packages.filter(p=>!grouped.has(dependencyKey(p))),isTooling=p=>p.classification==="tooling"||p.classification==="peer"&&report.groups.some(g=>g.members.some(m=>dependencyKey(m)===dependencyKey(p))&&groupLead(g)?.classification==="tooling");return{groups,used:remaining.filter(p=>p.classification==="used"),tooling:remaining.filter(isTooling),unused:remaining.filter(p=>p.classification==="possibly-unused"||p.classification==="peer"&&!isTooling(p))}}var groupLead=group=>group.members.find(p=>p.name===group.lead)??group.members.find(p=>!p.peerOf)??group.members[0];function listBlocks(packages,report){let keys=new Set(packages.map(p=>dependencyKey(p))),groups=report.groups.filter(g=>{let lead=groupLead(g);return lead&&keys.has(dependencyKey(lead))}).map(g=>({...g,totalMembers:g.members.length,members:g.members.filter(p=>keys.has(dependencyKey(p)))})),grouped=new Set(groups.flatMap(g=>g.members.map(p=>dependencyKey(p))));return[...groups,...packages.filter(p=>!grouped.has(dependencyKey(p))).map(p=>({members:[p]}))]}function listFailureLines(report,details=!1){let failures=[...new Map(report.failures.map(f=>[f.name,f])).values()],buckets=new Map;for(let failure of failures){let key=failure.host&&failure.summary?JSON.stringify([failure.host,failure.status,failure.summary]):failure.name;buckets.set(key,[...buckets.get(key)??[],failure])}return[...buckets.values()].flatMap(members=>{let first=members[0];if(!first)return[];let denied=[401,403,405].includes(first.status??0);return first.host&&first.summary&&members.length>(denied?1:5)?[`? ${members.length} packages on ${first.host}: ${first.summary}, skipped`,...details?members.map(f=>` ${f.name}`):[]]:members.map(f=>`? ${f.name}: ${f.reason}`)})}function skippedSources(report){let groups=new Map;for(let item of report.skipped??[])groups.set(item.reason,[...groups.get(item.reason)??[],item]);return[...groups].sort(([a],[b])=>a.localeCompare(b)).map(([reason,members])=>({reason,members}))}function notCheckedLabel(report){let reasons=new Set((report.unknown??[]).map(unknown=>{let failure=report.failures.find(f=>f.name===unknown.name);if(failure?.status===403)return"access denied";if(failure?.status===401)return"auth required";if(failure?.status===404)return"not found";if(failure?.summary)return failure.summary.replace(/ \(\d{3}\)$/,"");let reason2=failure?.reason??unknown.reason;return["access denied","auth required","timed out","not found","network request failed"].find(label=>reason2.toLowerCase().includes(label))})),reason=reasons.size===1?[...reasons][0]:void 0;return`not checked${reason?` (${reason})`:""}`}function formatListTimings(report,renderMs){let phases=report.timing.phases,files=report.timing.files;return!phases||!files?[...report.scanWarnings??[],`render ${Math.max(0,renderMs).toFixed(1)} ms`,""].join(`
53
+ `):[`manifest read ${phases.manifestReadMs.toFixed(1)} ms \xB7 ${plural3(files.manifests,"package manifest")} \xB7 ${plural3(files.installedManifests,"installed manifest")}`,`registry ${phases.registryMs.toFixed(1)} ms`,`source scan ${phases.sourceScanMs.toFixed(1)} ms \xB7 ${plural3(files.source,"source file")} \xB7 ${plural3(files.assets,"asset file")}${files.parsed===void 0?"":` \xB7 ${files.parsed} parsed \xB7 ${files.workers||0} workers`}`,`config scan ${phases.configScanMs.toFixed(1)} ms \xB7 ${plural3(files.config,"config file")}`,`render ${Math.max(0,renderMs).toFixed(1)} ms`,`files ${files.visited} visited (built-in excluded directories not enumerated)`,...files.candidateSources===void 0?[]:[`source scope ${files.candidateSources} candidates \xB7 ${files.ignoredSources??0} excluded by .gitignore`],...report.scanWarnings??[],...Object.entries(files.skipped??{}).sort(([a],[b])=>a.localeCompare(b)).map(([reason,count])=>`skipped ${reason}: ${plural3(count.files,"file")} \xB7 ${plural3(count.directories,"directory","directories")}`),""].join(`
54
+ `)}function formatList(report,opts={}){let color=opts.color??!1,c=import_picocolors7.default.createColors(color),width2=Math.max(24,opts.width??120),{groups,used,tooling,unused}=listSections(report),lines=[opts.header?terminalHeader("list",opts.header,color):c.bold("uptide list"),""],stat=(n,label)=>`${c.bold(String(n))} ${label}`;lines.push([stat(report.packages.length,"outdated"),...report.unknown?.length?[stat(report.unknown.length,notCheckedLabel(report))]:[],stat(report.packages.filter(p=>p.change==="major").length,"major"),stat(report.packages.filter(p=>p.change==="minor").length,"minor"),...report.packages.some(p=>p.change==="patch")?[stat(report.packages.filter(p=>p.change==="patch").length,"patch")]:[],stat(groups.length,groups.length===1?"group":"groups"),stat(tooling.length,"tooling")].join(" "),"");for(let warning of report.scanWarnings??[]){let rest=warning;for(;rest.length>width2;){let space=rest.lastIndexOf(" ",width2),end=space>0?space:width2;lines.push(c.yellow(rest.slice(0,end))),rest=rest.slice(end).trimStart()}lines.push(c.yellow(rest),"")}let priorities=report.priorities??[];if(report.packages.length){lines.push(`${c.bold("PRIORITIES")} ${c.dim(`most urgent first \xB7 ${advisoryStatus(report)}`)}`);let tone=signal=>signal==="security"?"red":signal==="deprecated"||signal==="unsupported"?"yellow":void 0,urgent=priorities.filter(p=>p.tier==="urgent"),planning=priorities.filter(p=>p.tier!=="urgent"),top=urgent.slice(0,opts.all?urgent.length:PRIORITY_ROWS),shownRows=[...top,...opts.all?planning:[]],longest=texts=>Math.max(0,...texts.map(t=>t.length)),oneLine=4+longest(shownRows.map(p=>p.name))+3+longest(shownRows.map(p=>p.reason))+3+longest(shownRows.map(p=>priorityCommand(p,opts)))<=width2,formatted2=alignedRows(shownRows.map(p=>[{text:p.name,tone:"bold"},{text:p.reason,...tone(p.signal)?{tone:tone(p.signal)}:{}},...oneLine?[{text:priorityCommand(p,opts),tone:"dim"}]:[]]),width2,color,4),tierRows=(rows2,offset)=>rows2.forEach((p,i)=>{lines.push(formatted2[offset+i]),oneLine||lines.push(c.dim(` ${priorityCommand(p,opts)}`))});priorities.length&&(lines.push(` ${c.bold("Urgent")} ${urgent.length}${c.dim(urgent.length?" \xB7 advisories, deprecations":" \xB7 no advisories or deprecations")}`),tierRows(top,0),top.length<urgent.length&&lines.push(c.dim(` + ${urgent.length-top.length} more \xB7 --all`)),lines.push(` ${c.bold("Worth planning")} ${planning.length}${c.dim(` \xB7 unsupported, drift, blocking, majors behind${opts.all||!planning.length?"":" \xB7 --all"}`)}`),opts.all&&tierRows(planning,top.length)),priorities.length||(lines.push(" Nothing urgent: no advisories, deprecations, unsupported lines or blocking peers."),report.cheapBatch?.length&&lines.push(...alignedRows([[{text:"cheap batch",tone:"bold"},{text:`${cheapBatchLabel(report.cheapBatch)}: minor/patch, few files, one PR`},{text:cheapBatchCommand(report.cheapBatch,opts),tone:"dim"}]],width2,color,2))),lines.push("")}let showWorkspaces=report.workspaces.some(w=>w!=="."),cells=p=>[{text:p.name,tone:"bold"},{text:listVersions(p),alignAt:"\u2192"},{text:listChange(p),tone:p.change==="major"?"yellow":"dim"},{text:p.peerOf?`peer of ${p.peerOf.join(", ")}`:plural3(p.usage.files,"file"),...p.peerOf?{tone:"dim",span:"rest"}:{}},{text:!p.peerOf&&p.usage.callSites?plural3(p.usage.callSites,"call"):""},{text:!p.peerOf&&p.usage.references?plural3(p.usage.references,"ref"):""},{text:p.tier==="verified"?"verified":"",tone:"green"},...showWorkspaces?[{text:p.versions?listSpread(p):p.workspaces.join(", "),tone:"dim"}]:[]],buildMajors=tooling.filter(p=>buildToolMajor(p)),shown=[...groups.flatMap(g=>g.members),...used.filter(p=>opts.all||p.change==="major"),...opts.all?[...tooling,...unused]:buildMajors],formatted=alignedRows(shown.map(cells),width2,color,2),rows=new Map(shown.map((p,i)=>[dependencyKey(p),formatted[i]])),row=p=>{let rendered=rows.get(dependencyKey(p))??"";lines.push(rendered),p.versions&&!rendered.includes(listSpread(p))&&lines.push(c.dim(` ${listSpread(p)}`));let build=buildToolMajor(p);if(build)lines.push(c.yellow(` ${build}`));else if(p.classification==="tooling"||p.classification==="possibly-unused")for(let reason of listReasons(p))lines.push(c.dim(ellipsis(` ${reason}`,width2)));if(opts.details&&listSymbols(p)&&lines.push(c.dim(ellipsis(` symbols ${listSymbols(p)}`,width2))),opts.details&&p.usage.fileList?.length)for(let file of p.usage.fileList)lines.push(c.dim(ellipsis(` ${file}`,width2)))},group=g=>{let command=groupCommand(g,opts),head=`${c.bold(g.name)}${" ".repeat(Math.max(0,12-g.name.length))} ${groupCount(g)} ${groupVersions(g)}`,fits=textWidth(head)+3+command.length<=width2;lines.push(fits?`${head} ${c.dim(command)}`:head),fits||lines.push(c.dim(` ${command}`));for(let p of g.members)row(p)};if(groups.length){lines.push(`${c.bold("GROUPS")} ${c.dim("upgrade together")}`);for(let g of groups)group(g);lines.push("")}if(used.length){lines.push(c.bold("PACKAGES"));for(let p of used.filter(p2=>opts.all||p2.change==="major"))row(p);let count=used.filter(p=>p.change!=="major").length;!opts.all&&count&&lines.push(c.dim(` + ${count} minor/patch \xB7 --all`)),lines.push("")}for(let[label,packages,hint]of[["TOOLING",tooling,"used by scripts and config"],["POSSIBLY UNUSED",unused,UNUSED_HINT]])if(packages.length){if(lines.push(`${c.bold(label)} ${c.dim(`${plural3(packages.length,"package")}, ${hint}${opts.all?"":" \xB7 --all"}`)}`),!opts.all&&label==="TOOLING")for(let p of buildMajors)row(p);if(opts.all)for(let block of listBlocks(packages,report))if(block.name)group(block);else for(let p of block.members)row(p);lines.push("")}for(let group2 of skippedSources(report))if(lines.push(c.dim(`${plural3(group2.members.length,"package")} ${group2.reason}${opts.all||opts.details?"":" \xB7 --all"}`)),opts.all||opts.details)for(let item of group2.members)lines.push(` ${c.bold(item.name)}${showWorkspaces&&opts.details?c.dim(` \xB7 ${item.workspaces.join(", ")}`):""}`);report.skipped?.length&&lines.push(""),!report.packages.length&&!report.failures.length&&!report.unknown?.length&&!report.skipped?.length&&lines.push("Every direct dependency is up to date.",""),lines.push(...listFailureLines(report,opts.details)),lines.push(c.dim("Usage is a syntax scan, no type analysis."),c.dim("Generic analysis is the default; verified means a migration pack is available."));let first=used[0]??tooling[0]??unused[0],next=groups[0]??report.groups.find(g=>g.members.some(p=>p.name===first?.name)),nextCommand=priorities[0]?priorityCommand(priorities[0],opts):report.cheapBatch?.length?cheapBatchCommand(report.cheapBatch,opts):next?groupCommand(next,opts):first?listCommand([first],opts):void 0;return nextCommand&&lines.push(`${c.bold("Next")} ${nextCommand}`),`${lines.join(`
55
+ `).split(`
56
+ `).map(line=>{let visible=0,parts=line.split(new RegExp("(\x1B\\[[0-9;]*m)"));return parts.filter(p=>!p.startsWith("\x1B")).join("").length<=width2?line:`${parts.map(part=>{if(part.startsWith("\x1B"))return part;let left=Math.max(0,width2-1-visible),result=Array.from(part).slice(0,left).join("");return visible+=Array.from(part).length,result}).join("")}\u2026`}).join(`
57
+ `)}
58
+ `}var import_picocolors8=__toESM(require_picocolors(),1);var plural4=(n,one,many=`${one}s`)=>`${n} ${n===1?one:many}`;function effortLine(e){if(e.level==="unknown")return"not checked completely \xB7 effort unknown";if(e.level==="none")return"no code changes expected";let sites=e.byRule+e.byAgent+e.manual,by=[e.byRule>0?BY.rule(e.byRule):"",e.byAgent>0?BY.agent(e.byAgent):"",e.manual>0?`${e.manual} manual`:""].filter(Boolean);return[e.level,sites>0?`${plural4(sites,"site")}: ${by.join(", ")}`:"",e.unconfirmed>0?`${e.unconfirmed} unconfirmed to look at`:""].filter(Boolean).join(" \xB7 ")}var moveOf=p=>`${p.name} ${p.installed} \u2192 ${p.target}`;function stepTitle(step){return step.together==="no-impact"?`Bump together: ${plural4(step.packages.length,"package")}, nothing in your code is affected`:step.together==="peer"?`Upgrade together: ${step.packages.map(p=>p.name).join(" + ")}`:moveOf(step.packages[0])}function formatPlan(plan,opts={}){let colors=import_picocolors8.default.createColors(opts.color??!0),uptide=opts.invocation??"npx uptide",cwd=opts.cwd?` --cwd ${opts.cwd}`:"",lines=[];if(opts.header){let dot=colors.dim("\xB7");lines.push(`${colors.bold("uptide plan")} ${dot} ${repoLine(opts.header)} ${dot} ${elapsed(opts.header.ms)}`,"")}plan.steps.length===0&&lines.push(colors.dim("Nothing to plan: every analyzed dependency is up to date."),"");for(let note of plan.notes??[])lines.push(note);plan.notes?.length&&lines.push("");let width2=String(plan.steps.length).length,indent=" ".repeat(width2+2);for(let step of plan.steps){let single=step.packages.length===1?step.packages[0]:void 0;if(lines.push(`${colors.bold(String(step.order).padStart(width2))} ${colors.bold(stepTitle(step))}${single?colors.dim(` ${single.tier}`):""}`),single)lines.push(`${indent}${effortLine(single.effort)}`);else for(let p of step.packages)lines.push(`${indent}${moveOf(p)}${colors.dim(` ${p.tier}`)}${step.together==="peer"?` ${effortLine(p.effort)}`:""}`);for(let c of step.constraints)lines.push(`${indent}${c.effect==="blocked"?colors.red("\u2717 blocked: "):colors.yellow("peer: ")}${c.reason}`);if(opts.fixable&&step.effort!=="none")for(let p of step.packages)lines.push(colors.dim(`${indent}${uptide} ${p.effort.level==="unknown"?"check":"fix"} ${p.name}${cwd}`));lines.push("")}if(plan.notPlanned.length>0){lines.push(colors.bold("Not planned"));for(let p of plan.notPlanned.slice(0,12))lines.push(` ${p.name} ${p.installed}: ${p.reason}`);plan.notPlanned.length>12&&lines.push(colors.dim(` and ${plan.notPlanned.length-12} more`)),lines.push(colors.dim(` ${uptide} list${cwd} refresh discovery`),"")}return plan.steps.some(s=>s.packages.some(p=>p.tier==="generic"))&&lines.push(colors.dim(TIER_LEGEND)),lines.push(colors.dim("Effort is an estimate from the findings: none (nothing affected), small (rules, or up to 5 sites by hand or agent), medium (up to 25), large (more).")),`${lines.join(`
59
+ `)}
60
+ `}import{basename as basename4}from"path";var escapeHtml=value=>String(value).replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[c]??c);import{createHash}from"crypto";var css=`
61
+ :root{color-scheme:light;--bg:#F4F2EC;--surface:#FAF9F5;--line:#D5D2C8;--text:#22211E;--body:#57554F;--dim:#76736B;--accent:#1D63C4;--ok:#28724A;--warn:#996014;--bad:#B63C37;--display:'Space Grotesk',system-ui,sans-serif;--sans:'Instrument Sans',system-ui,-apple-system,sans-serif;--mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;--border:var(--line);--panel:var(--surface);--muted:var(--dim);--red:var(--bad);--green:var(--ok);--amber:var(--warn);--gray:var(--body)}
62
+ @media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--bg:#131210;--surface:#1B1A17;--line:#36342F;--text:#F0EEE7;--body:#BCB9AF;--dim:#918E83;--accent:#7CC4FF;--ok:#86C99F;--warn:#E8B66B;--bad:#ED9990}}
63
+ :root[data-theme=dark]{color-scheme:dark;--bg:#131210;--surface:#1B1A17;--line:#36342F;--text:#F0EEE7;--body:#BCB9AF;--dim:#918E83;--accent:#7CC4FF;--ok:#86C99F;--warn:#E8B66B;--bad:#ED9990}
64
+ *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.55 var(--sans);-webkit-font-smoothing:antialiased}main{max-width:1200px;margin:auto;border-left:1px solid var(--line);border-right:1px solid var(--line);min-height:100vh}h1,h2,h3{font-family:var(--display);font-weight:600;line-height:1.15;margin:0}h1{font-size:clamp(32px,4.5vw,56px);letter-spacing:-.045em;overflow-wrap:anywhere}h2{font-size:24px;letter-spacing:-.025em}h3{font-size:16px}p{margin:8px 0;overflow-wrap:anywhere}a{color:var(--accent);overflow-wrap:anywhere}code,pre,.mono{font-family:var(--mono);font-size:12px}code{overflow-wrap:anywhere}.muted,.meta{color:var(--dim)}.label{font:11px var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--dim)}.brand{display:flex;align-items:center;gap:9px;font:600 24px var(--display);letter-spacing:-.04em}.brand svg{color:var(--accent);width:31px;height:31px;flex-shrink:0}.report-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:40px;gap:20px}.hero{padding:28px 40px 32px;border-bottom:1px solid var(--line)}.dots{background-image:radial-gradient(color-mix(in srgb,var(--dim) 24%,transparent) .7px,transparent .7px);background-size:18px 18px}.hero h1{margin:12px 0 20px}.meta{display:flex;gap:8px 24px;flex-wrap:wrap;font:11px/1.8 var(--mono)}.meta span,.meta time{overflow-wrap:anywhere}.stats{display:grid;grid-template-columns:repeat(var(--stat-count,5),minmax(0,1fr));border-bottom:1px solid var(--line)}.stat{padding:24px 28px;border-right:1px solid var(--line)}.stat:last-child{border:0}.stat strong{display:block;font:500 42px/1.1 var(--display);letter-spacing:-.05em;margin-bottom:9px;font-variant-numeric:tabular-nums}.stat.warn strong{color:var(--warn)}.stat.safe strong{color:var(--ok)}.section-label{display:flex;gap:24px;align-items:center;padding:28px 40px 16px}.section-label h2{font:11px var(--mono);letter-spacing:.13em;text-transform:uppercase}.section-label p{font:12px var(--sans);color:var(--dim);margin:0}.package{border-bottom:1px solid var(--line)}.package>header{padding:24px 40px 18px;background:var(--surface)}.package>header h2{margin-bottom:7px}.package>header .term{margin-top:18px}.member-grid{display:grid;grid-template-columns:minmax(170px,1.15fr) minmax(166px,1fr) 85px minmax(150px,1fr);gap:20px;padding:18px 40px;border-top:1px solid var(--line);align-items:baseline}.member-grid>div{min-width:0}.member-grid .pkg-name{font:600 13px var(--mono);overflow-wrap:anywhere}.versions{font:12px var(--mono);white-space:nowrap}.gap{font:12px var(--mono);color:var(--warn)}.usage{font:12px/1.7 var(--mono)}.verified{color:var(--ok);font:10px var(--mono);display:inline-block;margin-left:8px}.details-line{grid-column:1/-1;color:var(--dim);font:12px var(--mono)}.term,.command{display:flex;align-items:stretch;gap:0;border:1px solid var(--line);background:var(--bg);margin:0;min-width:0}.term code,.command code{padding:13px 16px;flex:1;min-width:0;white-space:pre-wrap;line-height:1.7}.term code::before{content:'$ ';color:var(--dim);user-select:none}button,input{font:12px var(--mono);border:1px solid var(--line);border-radius:0;color:var(--text);background:var(--surface);padding:10px 14px}button{cursor:pointer}.copy,[data-copy]{border:0;border-left:1px solid var(--line);padding:10px 18px;align-self:stretch;color:var(--body);white-space:nowrap}.copy:hover,button:hover{background:color-mix(in srgb,var(--accent) 7%,var(--surface));color:var(--accent)}button:focus-visible,input:focus-visible,summary:focus-visible,a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}button[aria-pressed=true]{color:var(--accent);border-color:var(--accent)}.notes{border-bottom:1px solid var(--line)}details{border-top:1px solid var(--line)}summary{padding:20px 40px;cursor:pointer;color:var(--body)}summary:hover{background:var(--surface)}summary .counts{display:block;font:12px/1.7 var(--mono);color:var(--dim);margin-top:6px}.notes>summary{font:11px var(--mono);letter-spacing:.1em;text-transform:uppercase;list-style:none}.notes>summary::after{content:'+';float:right;color:var(--accent)}.notes[open]>summary::after{content:'\u2212'}.notes ul{padding:0 60px 16px}.group-note{margin:12px 40px}.site{padding:16px 40px;border-top:1px solid var(--line)}.more{padding:12px 40px;color:var(--body)}.summary{border-bottom:1px solid var(--line)}.dep{display:grid;grid-template-columns:minmax(220px,1fr) 1.5fr;gap:24px;padding:20px 40px;border-top:1px solid var(--line);color:var(--text);text-decoration:none}.dep strong{display:block;font:600 15px var(--mono);margin-bottom:6px}.breaking{color:var(--bad)}.deprecated{color:var(--warn)}.safe{color:var(--ok)}.unverified{color:var(--body)}.next{padding:28px 40px;border-bottom:1px solid var(--line)}.next h2{font:11px var(--mono);letter-spacing:.13em;text-transform:uppercase;margin-bottom:20px}.next .command{margin:10px 0 20px}.filters{display:flex;gap:8px;padding:24px 40px;flex-wrap:wrap}.filters input{flex:1;min-width:180px}.notice{border-left:2px solid var(--accent);padding:8px 16px;margin:20px 40px;color:var(--body)}pre{margin:12px 0 0;padding:8px 0;background:var(--surface);border:1px solid var(--line);overflow:auto;tab-size:2}.code-line{display:block;padding:0 12px;min-height:1.5em}.number{display:inline-block;width:4ch;margin-right:12px;text-align:right;color:var(--dim);user-select:none}.hit{background:color-mix(in srgb,var(--accent) 10%,var(--surface));border-left:2px solid var(--accent);padding-left:10px}.compiler{margin-top:8px;border:0}.compiler summary{padding:4px 0;font-size:12px;color:var(--dim)}.compiler pre{white-space:pre-wrap;overflow-wrap:anywhere;padding:12px}footer{padding:26px 40px;color:var(--dim);font:11px/1.9 var(--mono)}[hidden]{display:none!important}
65
+
66
+ .incomplete-row,.source-row{display:grid;grid-template-columns:1fr 100px 2fr;gap:20px;padding:18px 40px;border-top:1px solid var(--line);font:12px/1.7 var(--mono);overflow-wrap:anywhere}.member-grid.has-command{grid-template-columns:minmax(170px,1.15fr) minmax(166px,1fr) 85px minmax(150px,1fr) 34px;align-items:center}.copy-cell{position:relative;justify-self:end}.copy.copy-icon{display:grid;place-items:center;width:34px;height:34px;padding:0;border:1px solid var(--line)}.copy-icon svg{width:17px;height:17px}.copy-icon[data-copied]{color:var(--ok);border-color:var(--ok)}.copy-source{position:absolute;z-index:1;right:0;top:calc(100% + 8px);width:max-content;max-width:min(70vw,520px);padding:12px;border:1px solid var(--line);background:var(--surface);color:var(--text);white-space:pre-wrap}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
67
+ @media(max-width:800px){.member-grid.has-command{grid-template-columns:minmax(0,1fr) 34px}.has-command>div:not(.pkg-name):not(.copy-cell),.has-command>.details-line{grid-column:1/-1}.has-command>.copy-cell{grid-column:2;grid-row:1}.has-command>.pkg-name{grid-column:1;grid-row:1}.member-grid{grid-template-columns:minmax(140px,1fr) minmax(150px,1fr);gap:10px 20px}.stat{padding:20px 16px}.stat strong{font-size:32px}.stats{grid-template-columns:repeat(3,minmax(0,1fr))}.stat{border-bottom:1px solid var(--line)}}
68
+ @media(max-width:540px){.incomplete-row,.source-row{grid-template-columns:1fr;padding:20px;gap:9px}main{border:0}.hero{padding:22px 20px 26px}.report-top{margin-bottom:30px}.brand{font-size:22px}.report-top>.label{font-size:10px}.meta{display:grid;gap:5px}.stat{padding:18px 20px}.stat strong{font-size:32px}.stat .label{font-size:9px}.member-grid{grid-template-columns:1fr;padding:20px;gap:9px}.member-grid .pkg-name{font-size:14px}.member-grid .gap{display:inline}.section-label{padding:28px 20px 16px;gap:15px}.package>header,.site,summary{padding:20px}.dep{grid-template-columns:1fr;padding:20px;gap:8px}.filters,.next,footer{padding:22px 20px}.notes ul{padding:0 40px 16px}.more{padding:12px 20px}.group-note{margin:12px 20px}.notice{margin:20px}.term code,.command code{font-size:11px;padding:12px}.copy,[data-copy]{padding:10px 12px}.versions,.usage{font-size:12px}}
69
+ @media print{:root,:root[data-theme=dark]{color-scheme:light;--bg:#fff;--surface:#fff;--line:#bbb;--text:#111;--body:#333;--dim:#555;--accent:#164a85;--ok:#17582e;--warn:#714800;--bad:#8a1823}body{font-size:10pt}main{max-width:none;min-height:0;border:0}.hero{padding-top:0}.dots{background:none}.filters,button,.copy-cell{display:none!important}[hidden]:not(.filters):not(button){display:block!important}details::details-content{display:block!important;content-visibility:visible!important}details>*:not(summary){display:block!important}pre{white-space:pre-wrap;overflow:visible}.site,.member-grid,.dep{break-inside:avoid}a{color:inherit;text-decoration:none}#empty-filter{display:none!important}.stats{grid-template-columns:repeat(var(--stat-count,5),minmax(0,1fr))}}
70
+
71
+ button.stat{font:inherit;color:inherit;text-align:left;background:none;border:0;border-right:1px solid var(--line);border-bottom:1px solid var(--line);border-radius:0;cursor:pointer;padding:24px 28px}button.stat:hover{background:var(--surface)}button.stat[aria-pressed=true]{background:color-mix(in srgb,var(--accent) 12%,var(--bg));box-shadow:inset 0 -4px 0 var(--accent)}button.stat[aria-pressed=true] .label{color:var(--accent)}button.stat:focus-visible{outline-offset:-4px}
72
+ .filter-status{display:flex;gap:16px;align-items:center;justify-content:space-between;padding:14px 40px;border-bottom:1px solid var(--line);font:12px var(--mono);color:var(--accent);background:var(--surface)}
73
+ .priority-list{list-style:none;margin:0;padding:0}.priority-row{display:grid;grid-template-columns:minmax(160px,1fr) minmax(200px,2fr) minmax(240px,1.6fr);gap:20px;padding:16px 40px;border-top:1px solid var(--line);align-items:center}.priority-row .pkg-name{font:600 13px var(--mono);overflow-wrap:anywhere}.priority-row .reason{font-size:14px}.signal-security .reason{color:var(--bad)}.signal-deprecated .reason,.signal-unsupported .reason{color:var(--warn)}.priority-row .command{margin:0}
74
+ @media(max-width:800px){.priority-row{grid-template-columns:1fr;padding:16px 20px;gap:8px}button.stat{padding:20px 16px}.filter-status{padding:12px 20px}}
57
75
  `,js=`
58
76
  (()=>{
59
- const controls=document.querySelector('.filters'); controls.hidden=false;
77
+ const controls=document.querySelector('.filters'); if(controls){controls.hidden=false;
60
78
  let active='all'; const search=document.querySelector('#search');
61
79
  function filter(){const q=search.value.toLowerCase(); let count=0;
62
80
  document.querySelectorAll('.package').forEach(p=>{let shown=0;const groups=p.querySelectorAll('.group');
@@ -66,20 +84,54 @@ function filter(){const q=search.value.toLowerCase(); let count=0;
66
84
  const row=document.querySelector('[data-package="'+p.id+'"]');if(row)row.hidden=p.hidden;if(!p.hidden)count++;
67
85
  });document.querySelector('#empty-filter').hidden=count>0;
68
86
  }
69
- controls.querySelectorAll('button').forEach(b=>b.addEventListener('click',()=>{active=b.dataset.filter;controls.querySelectorAll('button').forEach(x=>x.setAttribute('aria-pressed',String(x===b)));filter();}));search.addEventListener('input',filter);
70
- document.querySelectorAll('[data-copy]').forEach(b=>{b.hidden=false;b.addEventListener('click',async()=>{const text=b.parentElement.querySelector('code').textContent;try{await navigator.clipboard.writeText(text);b.textContent='Copied';}catch{const range=document.createRange();range.selectNodeContents(b.parentElement.querySelector('code'));const s=getSelection();s.removeAllRanges();s.addRange(range);b.textContent='Selected \u2014 copy manually';}});});
87
+ controls.querySelectorAll('button').forEach(b=>b.addEventListener('click',()=>{active=b.dataset.filter;controls.querySelectorAll('button').forEach(x=>x.setAttribute('aria-pressed',String(x===b)));filter();}));search.addEventListener('input',filter);}
88
+ const list=document.querySelector('[data-list]');if(list){
89
+ const tiles=[...document.querySelectorAll('.stat[data-filter]')],rows=[...list.querySelectorAll('.member-grid')],status=document.querySelector('.filter-status'),label=status.querySelector('[data-filter-label]'),empty=document.querySelector('[data-filter-empty]');let opened=[];
90
+ const tests={major:r=>r.dataset.change==='major',minor:r=>r.dataset.change==='minor',patch:r=>r.dataset.change==='patch',groups:r=>r.dataset.section==='group',tooling:r=>r.dataset.section==='tooling',unused:r=>r.dataset.section==='unused',priority:r=>r.hasAttribute('data-priority'),verified:r=>r.hasAttribute('data-verified')};
91
+ function apply(f){if(!tests[f])f='';opened.forEach(d=>d.open=false);opened=[];
92
+ tiles.forEach(t=>t.setAttribute('aria-pressed',String(!!f&&t.dataset.filter===f)));
93
+ let shown=0;rows.forEach(r=>{r.hidden=!!f&&!tests[f](r);if(!r.hidden)shown++;});
94
+ list.querySelectorAll('.package').forEach(p=>{if(p.querySelector('.member-grid'))p.hidden=!!f&&!p.querySelector('.member-grid:not([hidden])');});
95
+ list.querySelectorAll('[data-block]').forEach(b=>{b.hidden=!!f&&!b.querySelector('.member-grid:not([hidden])');if(f&&!b.hidden&&b.tagName==='DETAILS'&&!b.open){b.open=true;opened.push(b);}});
96
+ const top=list.querySelector('.priorities');if(top)top.hidden=!!f&&f!=='priority';
97
+ status.hidden=!f;empty.hidden=!f||shown>0;
98
+ if(f){const groups=list.querySelectorAll('[data-group]:not([hidden])').length;label.textContent='Showing '+(f==='groups'?groups+' group'+(groups===1?'':'s')+' \xB7 ':'')+shown+' package'+(shown===1?'':'s')+' \xB7 '+tiles.find(t=>t.dataset.filter===f).querySelector('.label').textContent;}
99
+ const hash=f?'#filter='+f:'';if(location.hash!==hash)try{history.replaceState(null,'',location.href.replace(/#.*$/,'')+hash);}catch{location.hash=hash;}}
100
+ tiles.forEach(t=>t.addEventListener('click',()=>apply(t.getAttribute('aria-pressed')==='true'?'':t.dataset.filter)));
101
+ status.querySelector('[data-filter-clear]').addEventListener('click',()=>{apply('');tiles[0].focus();});
102
+ const fromHash=()=>apply((/^#filter=([a-z]+)$/.exec(location.hash)||[])[1]||'');addEventListener('hashchange',fromHash);fromHash();}
103
+ document.querySelectorAll('[data-copy]').forEach(b=>{b.hidden=false;b.addEventListener('click',async()=>{
104
+ const code=b.parentElement.querySelector('code');const status=b.querySelector('[data-copy-status]')||b;
105
+ try{await navigator.clipboard.writeText(code.textContent);status.textContent='Copied';b.dataset.copied='';if(code.classList.contains('copy-source'))code.hidden=true;}
106
+ catch{code.hidden=false;delete b.dataset.copied;const range=document.createRange();range.selectNodeContents(code);const s=getSelection();s.removeAllRanges();s.addRange(range);status.textContent='Selected \u2014 copy manually';}
107
+ });});
71
108
  document.querySelectorAll('.compiler a').forEach(a=>a.addEventListener('click',()=>{const target=document.querySelector(a.getAttribute('href'));for(let p=target;p;p=p.parentElement){if(p.tagName==='DETAILS')p.open=true;}}));
72
109
  let opened=[];addEventListener('beforeprint',()=>{opened=[...document.querySelectorAll('details:not([open])')];opened.forEach(d=>d.open=true);});addEventListener('afterprint',()=>opened.forEach(d=>d.open=false));
73
110
  })();
74
- `;import{createHash}from"crypto";function groupsForHtml(p,plan){let result=[];for(let original of plan){let g=structuredClone(original);if(g.severity==="deprecated"){let formats=/(?:^|[#.])(email|uuid|url|datetime|base64)$/,names2=Object.keys(g.symbols??{});p.name==="zod"&&(g.rule==="string-format"||formats.test(g.rule)||names2.length>0&&names2.every(name=>formats.test(name)))?(g.rule="string-format",g.title="Top-level string formats"):plan.some(other=>other.severity==="breaking"&&other.title===g.title)&&(g.title=`${names2.join(", ")||g.rule} deprecated`);let previous=result.find(other=>other.severity===g.severity&&other.rule===g.rule);if(previous){previous.sites+=g.sites,previous.fixes+=g.fixes;for(let key of["rule","agent","manual"])previous.by[key]+=g.by[key];previous.locations=[...new Map([...previous.locations,...g.locations].map(s=>[`${s.file}:${s.line}`,s])).values()];continue}}result.push(g)}return result}function verdict(rows){let groups=rows.flatMap(r=>r.plan),breaking=groups.filter(g=>g.severity==="breaking"),n=breaking.reduce((sum,g)=>sum+g.sites,0),files=new Set(breaking.flatMap(g=>g.locations.map(s=>s.file))).size,by=key=>breaking.reduce((sum,g)=>sum+g.by[key],0),deprecated=groups.filter(g=>g.severity==="deprecated").reduce((sum,g)=>sum+g.sites,0),unverified=groups.filter(g=>g.severity==="unverified").reduce((sum,g)=>sum+g.sites,0);return[n?`${n} breaking ${n===1?"change":"changes"} in ${files} ${files===1?"file":"files"}.`:"No confirmed breaking changes.",n?`${by("rule")} fixable by rule, ${by("agent")} by agent${by("manual")?`, ${by("manual")} manual`:""}.`:"",deprecated?`${deprecated} deprecated ${deprecated===1?"call":"calls"} (not blocking).`:"",unverified?`${unverified} unverified ${unverified===1?"site":"sites"} need review.`:""].filter(Boolean).join(" ")}function notesOf(report){let notes=new Set,skipped=[],baseline=new Map;notes.add(`Workspaces analyzed: ${[...new Set(report.workspaces)].join(", ")}.`);for(let p of report.packages){for(let note of p.notes)/low.confidence|pre-existing|workspaces? (?:analyzed|skipped)/i.test(note)||notes.add(note);if(["skipped","no-types","private","unknown"].includes(p.status)&&skipped.push(`${p.workspaces?.join(", ")??p.workspace}: ${p.name} \u2014 ${p.skipReason??p.status}`),p.compile?.baselineErrors){let n=p.compile.baselineErrors;baseline.set(n,[...baseline.get(n)??[],p.name])}p.compile?.skipped&&notes.add(`${p.name}: compile check skipped \u2014 ${p.compile.skipped}.`),p.compile?.unresolvedInTarget.length&&notes.add(`${p.name}: ${p.compile.unresolvedInTarget.length} unresolved modules in target; results may be incomplete.`);for(let s of p.unanalyzed)notes.add(`${p.name}: ${s.file}:${s.line} not analyzed (${s.kind}).`)}if(notes.add(`Workspace analysis gaps: ${[...new Set(skipped)].join("; ")||"none reported"}.`),baseline.size===1){let n=[...baseline.keys()][0];notes.add(`${n} type ${n===1?"error that already existed before the upgrade was":"errors that already existed before the upgrade were"} ignored.`)}else baseline.size>1&&notes.add(`Type errors that already existed before the upgrade were ignored: ${[...baseline].map(([n,names2])=>`${n} in the ${[...new Set(names2)].join(", ")} checks`).join("; ")}.`);return[...notes]}function groupReason(g){return g.severity==="deprecated"?g.rule==="string-format"?"Use top-level string format schemas instead of chained string methods.":g.detail||"This API is deprecated; no replacement was supplied by the package.":{"error-params":"Replace required_error and invalid_type_error with the new error parameter, preserving custom messages.","api-version":"The configured API version does not match the target Stripe SDK. Review the API behavior changes before updating it.",types:"Update the type references that are no longer supported by the target version.",ip:"Replace the removed IP validator with the supported target API."}[g.rule]??""}function stripeNote(note){return note.replace(/(none of the \d+ API changes since .+?) has evidence in your code/i,"$1 touch your code")}import{closeSync,constants,fstatSync,openSync,readFileSync as readFileSync3,realpathSync as realpathSync2}from"fs";import{isAbsolute as isAbsolute2,relative as relative2,resolve as resolve3,sep}from"path";function localFile(root,file){if(isAbsolute2(file))return;let absolute=resolve3(root,file),rel=relative2(resolve3(root),absolute);return rel===".."||rel.startsWith(`..${sep}`)?void 0:absolute}function excerptReader(root){return(file,line)=>{let fd;try{if(!Number.isSafeInteger(line)||line<1)throw new Error("invalid line");let candidate=localFile(root,file);if(!candidate)throw new Error("outside repository");let realRoot=realpathSync2(root),realFile=realpathSync2(candidate);if(!localFile(realRoot,relative2(realRoot,realFile)))throw new Error("outside repository");fd=openSync(realFile,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW);let stat=fstatSync(fd);if(!stat.isFile()||stat.size>2*1024*1024)throw new Error("not a small regular file");let lines=readFileSync3(fd,"utf8").split(/\r?\n/);if(line>lines.length)throw new Error("line unavailable");return{lines:lines.slice(Math.max(0,line-4),line+3).map((text,i)=>({number:Math.max(1,line-3)+i,text:text.length>240?`${text.slice(0,240)}\u2026`:text}))}}catch{return{lines:[],unavailable:"Excerpt unavailable (missing, outside repository, or file too large)."}}finally{fd!==void 0&&closeSync(fd)}}}var MAX_HTML_BYTES=3e5,escapeHtml=value=>String(value).replace(/[&<>"']/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[c]??c),short=(s,limit=1200)=>s.length>limit?`${s.slice(0,limit)}\u2026 [truncated]`:s;function compilerAt(p,group,file,line){let matches=p.findings.filter(f=>f.severity===group.severity&&(f.usage.file===file&&(f.usage.line===line||f.sites?.some(s=>s.line===line))||f.downstream?.some(s=>s.file===file&&s.line===line)));return[...new Set(matches.flatMap(f=>{let downstream=f.downstream?.find(s=>s.file===file&&s.line===line);return downstream?[downstream.message]:f.usage.compileError?[f.usage.compileError]:[]}))].join(" \xB7 ")||(group.severity!=="deprecated"?group.detail:"")}function renderHtml(report,opts){function render(excerptBudget,siteLimit,groupLimit,compact){let e=s=>escapeHtml(short(String(s),compact?300:1600)),rows=checkRows(report).map(r=>({...r,plan:groupsForHtml(r.p,r.plan)})),messages=new Map,groupsLeft=groupLimit;function group(p,g){if(groupsLeft--<=0)return"";let body="",overflow="";for(let[index,site]of(compact?g.locations.slice(0,siteLimit):g.locations).entries()){let absolute=localFile(opts.root,site.file),label=`${site.file}:${site.line}`,link=absolute&&Number.isSafeInteger(site.line)&&site.line>0?`<a href="${escapeHtml(`vscode://file/${absolute.replaceAll("\\","/").replace(/^\//,"").split("/").map(encodeURIComponent).join("/")}:${site.line}`)}">${e(label)}</a>`:e(label),excerpt="";if(index<siteLimit&&excerptBudget>0&&opts.readExcerpt){let result=opts.readExcerpt(site.file,site.line);if(result.lines.length){let code=result.lines.slice(0,7).map(l=>`<span class="code-line${l.number===site.line?" hit":""}"><span class="number">${e(l.number)}</span>${escapeHtml(short(l.text,240))}</span>`).join(""),cost=Buffer.byteLength(code);cost<=excerptBudget?(excerpt=`<pre aria-label="Code excerpt"><code>${code}</code></pre>`,excerptBudget-=cost):excerpt='<p class="muted">Excerpt omitted to keep this report small.</p>'}else excerpt=`<p class="muted">${e(result.unavailable??"Excerpt unavailable.")}</p>`}let message=compilerAt(p,g,site.file,site.line),compiler="";if(message){let prior=messages.get(message),id=prior??`compiler-${messages.size}`;messages.set(message,id),compiler=prior?`<details class="compiler"><summary>compiler message</summary><a href="#${id}">Same message, shown above</a></details>`:`<details class="compiler" id="${id}"><summary>compiler message</summary><pre>${escapeHtml(message)}</pre></details>`}let article=`<article class="site"><div class="mono">${link}</div>${excerpt}${compiler}</article>`;index<siteLimit?body+=article:overflow+=article}let rest=g.locations.length-Math.min(siteLimit,g.locations.length);return rest>0&&(body+=compact?`<p class="more">and ${rest} more sites \u2014 use uptide check --details for every location.</p>`:`<details><summary>and ${rest} more sites (excerpts omitted)</summary>${overflow}</details>`),g.locations.length||(body+='<p class="more">No site locations supplied by the engine.</p>'),`<details class="group" data-severity="${e(g.severity)}" data-rule="${e(g.rule)}"><summary><strong class="${e(g.severity)}">${e(g.title)}</strong><span class="counts">${g.sites} ${g.sites===1?"site":"sites"} \xB7 ${e(byLine([g]))}${g.fixes!==g.sites?` \xB7 ${g.fixes} ${g.fixes===1?"fix":"fixes"}`:""}</span><span class="counts">${e(groupReason(g))}</span></summary>${g.note?`<p class="group-note muted">${e(stripeNote(g.note))}</p>`:""}${body}</details>`}let summary=rows.map((r,i)=>`<a class="dep" href="#dependency-${i}" data-package="dependency-${i}"><div><strong>${e(r.name)}</strong><span class="mono muted">${e(r.versions)} \xB7 ${e(r.bump)}</span></div><div class="${r.plan.some(g=>g.severity==="breaking")?"breaking":r.plan.some(g=>g.severity==="unverified")||r.p.unanalyzed.length||["skipped","unknown","no-types"].includes(r.p.status)?"unverified":r.plan.some(g=>g.severity==="deprecated")?"deprecated":"safe"}">${e(r.verdict)}${r.by?`<div class="muted">${e(r.by)}</div>`:""}</div></a>`).join(""),dependencies=rows.map((r,i)=>{let ordinary=r.plan.filter(g=>g.severity!=="deprecated"),deprecated=r.plan.filter(g=>g.severity==="deprecated");return`<section class="package" id="dependency-${i}"><header><h2>${e(r.name)}</h2><span class="mono muted">${e(r.versions)}</span></header>${ordinary.map(g=>group(r.p,g)).join("")}${deprecated.length?`<details class="deprecated-section"><summary class="deprecated">Deprecated calls \xB7 ${deprecated.reduce((n,g)=>n+g.sites,0)} sites</summary>${deprecated.map(g=>group(r.p,g)).join("")}</details>`:""}${r.plan.length?"":`<p class="more">${e(r.verdict)}</p>`}</section>`}).join(""),commands=nextCommands(rows,{...opts,invocation:opts.invocation??"npx uptide",details:!1}),notes=notesOf(report);return`<!doctype html>
75
- <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'sha256-${createHash("sha256").update(js).digest("base64")}'; connect-src 'none'; base-uri 'none'; form-action 'none'"><meta name="referrer" content="no-referrer"><title>Uptide check \xB7 ${e(opts.header?.repo??report.repo)}</title><style>${css}</style></head>
76
- <body><main><header><div class="brand">UPTIDE / CHECK</div><h1>${e(opts.header?.repo??report.repo)}</h1><div class="meta"><span>${e(opts.header?.manager??"Package manager unavailable")}</span><span>${report.workspaces.length} ${report.workspaces.length===1?"workspace":"workspaces"} analyzed</span><time datetime="${e(opts.date)}">${e(new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",timeZoneName:"short",timeZone:opts.timeZone}).format(new Date(opts.date)))}</time><span>Uptide CLI ${e(opts.version)}</span><span>${elapsed(opts.header?.ms??0)}</span></div><p class="muted">${e(verdict(rows))}</p></header>
77
- <div class="filters" hidden role="search" aria-label="Filter findings">${["All","Breaking","Deprecated","Unverified"].map(s=>`<button type="button" data-filter="${s.toLowerCase()}" aria-pressed="${s==="All"}">${s}</button>`).join("")}<input id="search" type="search" aria-label="Search file paths and change rules" placeholder="Search files or rules\u2026"></div>
111
+ `;function reportDocument(title,body){return`<!doctype html>
112
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'sha256-${createHash("sha256").update(js).digest("base64")}'; connect-src 'none'; base-uri 'none'; form-action 'none'"><meta name="referrer" content="no-referrer"><title>${escapeHtml(title)}</title><style>${css}</style></head>
113
+ <body><main>${body}</main><script>${js}</script></body></html>`}var logo='<svg viewBox="0 0 32 32" fill="none" aria-hidden="true"><path d="M3 23c4.5 0 6.8-2.6 8.6-6.4C13.6 12.2 16.2 8 21.2 8c3.9 0 6.8 2.6 6.8 5.8 0 2.4-1.8 4.1-4.1 4.1-1.9 0-3.1-1.2-3.1-2.8" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 27.5h26" stroke="currentColor" stroke-width="3" stroke-linecap="round"/></svg>';function reportHeader(opts){let e=escapeHtml,when=new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",timeZoneName:"short",timeZone:opts.timeZone}).format(new Date(opts.date));return`<header class="hero dots"><div class="report-top"><div class="brand">${logo}<span>uptide</span></div><span class="label">Dependency ${opts.kind==="list"?"discovery":"check"} / local report</span></div><div class="label">${opts.kind==="list"?"Your dependencies, at a glance":"Your upgrade, before you merge"}</div><h1>${e(opts.repo)}</h1><div class="meta"><span>${e(opts.manager)}</span><time datetime="${e(opts.date)}">Generated ${e(when)}</time><span>Uptide CLI ${e(opts.version)}</span></div></header>`}function reportStats(stats){let columns=Math.ceil(stats.length/Math.ceil(stats.length/6)),tile=s=>{let inner=`<strong>${s.value}</strong><span class="label">${escapeHtml(s.label)}</span>`;return s.filter?`<button type="button" class="stat ${s.tone??""}" data-filter="${escapeHtml(s.filter)}" aria-pressed="false">${inner}</button>`:`<div class="stat ${s.tone??""}">${inner}</div>`};return`<div class="stats" style="--stat-count:${columns}">${stats.map(tile).join("")}</div>`}var reportCommand=command=>`<div class="term command"><code>${escapeHtml(command)}</code><button type="button" class="copy" data-copy hidden aria-label="Copy command">Copy</button></div>`,reportCopyButton=command=>`<div class="copy-cell"><code class="copy-source" hidden>${escapeHtml(command)}</code><button type="button" class="copy copy-icon" data-copy hidden title="${escapeHtml(command)}" aria-label="${escapeHtml(command)}"><svg viewBox="0 0 20 20" fill="none" aria-hidden="true"><rect x="7" y="7" width="10" height="10" stroke="currentColor" stroke-width="1.5"/><path d="M13 7V3H3v10h4" stroke="currentColor" stroke-width="1.5"/></svg><span class="sr-only" data-copy-status role="status"></span></button></div>`,sectionLabel=(number,label,subtitle="")=>`<div class="section-label"><h2>${number} / ${escapeHtml(label)}</h2>${subtitle?`<p>${escapeHtml(subtitle)}</p>`:""}</div>`;import{spawn}from"child_process";import{mkdirSync,writeFileSync}from"fs";import{tmpdir}from"os";import{basename as basename3,dirname as dirname3,join as join3,resolve as resolve4}from"path";import{closeSync,constants,fstatSync,openSync,readFileSync as readFileSync3,realpathSync as realpathSync2}from"fs";import{isAbsolute as isAbsolute2,relative as relative2,resolve as resolve3,sep}from"path";function localFile(root,file){if(isAbsolute2(file))return;let absolute=resolve3(root,file),rel=relative2(resolve3(root),absolute);return rel===".."||rel.startsWith(`..${sep}`)?void 0:absolute}function excerptReader(root){return(file,line)=>{let fd;try{if(!Number.isSafeInteger(line)||line<1)throw new Error("invalid line");let candidate=localFile(root,file);if(!candidate)throw new Error("outside repository");let realRoot=realpathSync2(root),realFile=realpathSync2(candidate);if(!localFile(realRoot,relative2(realRoot,realFile)))throw new Error("outside repository");fd=openSync(realFile,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW);let stat=fstatSync(fd);if(!stat.isFile()||stat.size>2*1024*1024)throw new Error("not a small regular file");let lines=readFileSync3(fd,"utf8").split(/\r?\n/);if(line>lines.length)throw new Error("line unavailable");return{lines:lines.slice(Math.max(0,line-4),line+3).map((text,i)=>({number:Math.max(1,line-3)+i,text:text.length>240?`${text.slice(0,240)}\u2026`:text}))}}catch{return{lines:[],unavailable:"Excerpt unavailable (missing, outside repository, or file too large)."}}finally{fd!==void 0&&closeSync(fd)}}}import{basename as basename2}from"path";function groupsForHtml(p,plan){let result=[];for(let original of plan){let g=structuredClone(original);if(g.severity==="deprecated"){let formats=/(?:^|[#.])(email|uuid|url|datetime|base64)$/,names2=Object.keys(g.symbols??{});p.name==="zod"&&(g.rule==="string-format"||formats.test(g.rule)||names2.length>0&&names2.every(name=>formats.test(name)))?(g.rule="string-format",g.title="Top-level string formats"):plan.some(other=>other.severity==="breaking"&&other.title===g.title)&&(g.title=`${names2.join(", ")||g.rule} deprecated`);let previous=result.find(other=>other.severity===g.severity&&other.rule===g.rule);if(previous){previous.sites+=g.sites,previous.fixes+=g.fixes;for(let key of["rule","agent","manual"])previous.by[key]+=g.by[key];previous.locations=[...new Map([...previous.locations,...g.locations].map(s=>[`${s.file}:${s.line}`,s])).values()];continue}}result.push(g)}return result}function verdict(rows){let groups=rows.flatMap(r=>r.plan),breaking=groups.filter(g=>g.severity==="breaking"),n=breaking.reduce((sum,g)=>sum+g.sites,0),files=new Set(breaking.flatMap(g=>g.locations.map(s=>s.file))).size,by=key=>breaking.reduce((sum,g)=>sum+g.by[key],0),deprecated=groups.filter(g=>g.severity==="deprecated").reduce((sum,g)=>sum+g.sites,0),unverified=groups.filter(g=>g.severity==="unverified").reduce((sum,g)=>sum+g.sites,0);return[n?`${n} breaking ${n===1?"change":"changes"} in ${files} ${files===1?"file":"files"}.`:"No confirmed breaking changes.",n?`${BY.rule(by("rule"))}, ${BY.agent(by("agent"))}${by("manual")?`, ${by("manual")} manual`:""}.`:"",deprecated?`${deprecated} deprecated ${deprecated===1?"call":"calls"} (not blocking).`:"",unverified?`${unverified} unverified ${unverified===1?"site":"sites"} need review.`:""].filter(Boolean).join(" ")}function notesOf(report){let notes=new Set,skipped=[],baseline=new Map;notes.add(`Workspaces analyzed: ${[...new Set(report.workspaces)].join(", ")}.`);for(let p of report.packages)if(p.skipReason!=="TIME_BUDGET"){for(let note of p.notes)/low.confidence|pre-existing|workspaces? (?:analyzed|skipped)/i.test(note)||notes.add(note);if(["skipped","no-types","private","unknown"].includes(p.status)&&skipped.push(`${p.workspaces?.join(", ")??p.workspace}: ${p.name} \u2014 ${p.skipReason??p.status}`),p.compile?.baselineErrors){let n=p.compile.baselineErrors;baseline.set(n,[...baseline.get(n)??[],p.name])}p.compile?.skipped&&notes.add(`${p.name}: compile check skipped \u2014 ${p.compile.skipped}.`),p.compile?.unresolvedInTarget.length&&notes.add(`${p.name}: ${p.compile.unresolvedInTarget.length} unresolved modules in target; results may be incomplete.`);for(let s of p.unanalyzed)notes.add(`${p.name}: ${s.file}:${s.line} not analyzed (${s.kind}).`)}if(notes.add(`Workspace analysis gaps: ${[...new Set(skipped)].join("; ")||"none reported"}.`),baseline.size===1){let n=[...baseline.keys()][0];notes.add(`${n} type ${n===1?"error that already existed before the upgrade was":"errors that already existed before the upgrade were"} ignored.`)}else baseline.size>1&&notes.add(`Type errors that already existed before the upgrade were ignored: ${[...baseline].map(([n,names2])=>`${n} in the ${[...new Set(names2)].join(", ")} checks`).join("; ")}.`);return[...notes]}function groupReason(g){return g.severity==="deprecated"?g.rule==="string-format"?"Use top-level string format schemas instead of chained string methods.":g.detail||"This API is deprecated; no replacement was supplied by the package.":{"error-params":"Replace required_error and invalid_type_error with the new error parameter, preserving custom messages.","api-version":"The configured API version does not match the target Stripe SDK. Review the API behavior changes before updating it.",types:"Update the type references that are no longer supported by the target version.",ip:"Replace the removed IP validator with the supported target API."}[g.rule]??""}function stripeNote(note){return note.replace(/(none of the \d+ API changes since .+?) has evidence in your code/i,"$1 touch your code")}var MAX_HTML_BYTES=3e5,short=(s,limit=1200)=>s.length>limit?`${s.slice(0,limit)}\u2026 [truncated]`:s;function compilerAt(p,group,file,line){let matches=p.findings.filter(f=>f.severity===group.severity&&(f.usage.file===file&&(f.usage.line===line||f.sites?.some(s=>s.line===line))||f.downstream?.some(s=>s.file===file&&s.line===line)));return[...new Set(matches.flatMap(f=>{let downstream=f.downstream?.find(s=>s.file===file&&s.line===line);return downstream?[downstream.message]:f.usage.compileError?[f.usage.compileError]:[]}))].join(" \xB7 ")||(group.severity!=="deprecated"?group.detail:"")}function renderHtml(report,opts){function render(excerptBudget,siteLimit,groupLimit,compact){let e=s=>escapeHtml(short(String(s),compact?300:1600)),rows=checkRows(report).map(r=>({...r,name:opts.details?r.name:r.p.name,plan:groupsForHtml(r.p,r.plan)})),messages=new Map,groupsLeft=groupLimit;function group(p,g){if(groupsLeft--<=0)return"";if(!opts.details)return`<details class="group" data-severity="${e(g.severity)}" data-rule="${e(g.rule)}"><summary><strong class="${e(g.severity)}">${e(g.title)}</strong><span class="counts">${g.sites} ${g.sites===1?"site":"sites"} \xB7 ${e(byLine([g]))}</span></summary><p class="more">Run check --html --details for locations, source excerpts and compiler messages.</p></details>`;let body="",overflow="";for(let[index,site]of(compact?g.locations.slice(0,siteLimit):g.locations).entries()){let absolute=localFile(opts.root,site.file),label=`${site.file}:${site.line}`,link=absolute&&Number.isSafeInteger(site.line)&&site.line>0?`<a href="${escapeHtml(`vscode://file/${absolute.replaceAll("\\","/").replace(/^\//,"").split("/").map(encodeURIComponent).join("/")}:${site.line}`)}">${e(label)}</a>`:e(label),excerpt="";if(index<siteLimit&&excerptBudget>0&&opts.readExcerpt){let result=opts.readExcerpt(site.file,site.line);if(result.lines.length){let code=result.lines.slice(0,7).map(l=>`<span class="code-line${l.number===site.line?" hit":""}"><span class="number">${e(l.number)}</span>${escapeHtml(short(l.text,240))}</span>`).join(""),cost=Buffer.byteLength(code);cost<=excerptBudget?(excerpt=`<pre aria-label="Code excerpt"><code>${code}</code></pre>`,excerptBudget-=cost):excerpt='<p class="muted">Excerpt omitted to keep this report small.</p>'}else excerpt=`<p class="muted">${e(result.unavailable??"Excerpt unavailable.")}</p>`}let message=compilerAt(p,g,site.file,site.line),compiler="";if(message){let prior=messages.get(message),id=prior??`compiler-${messages.size}`;messages.set(message,id),compiler=prior?`<details class="compiler"><summary>compiler message</summary><a href="#${id}">Same message, shown above</a></details>`:`<details class="compiler" id="${id}"><summary>compiler message</summary><pre>${escapeHtml(message)}</pre></details>`}let article=`<article class="site"><div class="mono">${link}</div>${excerpt}${compiler}</article>`;index<siteLimit?body+=article:overflow+=article}let rest=g.locations.length-Math.min(siteLimit,g.locations.length);return rest>0&&(body+=compact?`<p class="more">and ${rest} more sites \u2014 use uptide check &lt;package&gt; --details for every location.</p>`:`<details><summary>and ${rest} more sites (excerpts omitted)</summary>${overflow}</details>`),g.locations.length||(body+='<p class="more">No site locations supplied by the engine.</p>'),`<details class="group" data-severity="${e(g.severity)}" data-rule="${e(g.rule)}"><summary><strong class="${e(g.severity)}">${e(g.title)}</strong><span class="counts">${g.sites} ${g.sites===1?"site":"sites"} \xB7 ${e(byLine([g]))}${g.fixes!==g.sites?` \xB7 ${g.fixes} ${g.fixes===1?"fix":"fixes"}`:""}</span><span class="counts">${e(groupReason(g))}</span></summary>${g.note?`<p class="group-note muted">${e(stripeNote(g.note))}</p>`:""}${body}</details>`}let summary=rows.map((r,i)=>`<a class="dep" href="#dependency-${i}" data-package="dependency-${i}"><div><strong>${e(r.name)}</strong><span class="mono muted">${e(r.versions)} \xB7 ${e(r.bump)}${r.p.tier==="verified"?' \xB7 <span class="verified">verified</span>':""}</span></div><div class="${r.plan.some(g=>g.severity==="breaking")?"breaking":r.plan.some(g=>g.severity==="unverified")||r.p.unanalyzed.length||["skipped","unknown","no-types"].includes(r.p.status)?"unverified":r.plan.some(g=>g.severity==="deprecated")?"deprecated":"safe"}">${e(r.verdict)}${r.by?`<div class="muted">${e(r.by)}</div>`:""}${r.summary?`<div class="muted">${e(r.summary)}</div>`:""}</div></a>`).join(""),dependencies=rows.map((r,i)=>{let ordinary=r.plan.filter(g=>g.severity!=="deprecated"),deprecated=r.plan.filter(g=>g.severity==="deprecated");return`<section class="package" id="dependency-${i}"><header><h2>${e(r.name)}</h2><span class="mono muted">${e(r.versions)}${r.p.tier==="verified"?' \xB7 <span class="verified">verified</span>':""}</span>${r.summary?`<p class="more">${e(r.summary)}</p>`:""}</header>${ordinary.map(g=>group(r.p,g)).join("")}${deprecated.length?`<details class="deprecated-section"><summary class="deprecated">Deprecated calls \xB7 ${deprecated.reduce((n,g)=>n+g.sites,0)} sites</summary>${deprecated.map(g=>group(r.p,g)).join("")}</details>`:""}${r.plan.length?"":`<p class="more">${e(r.verdict)}</p>`}</section>`}).join(""),commands=nextCommands(rows,{...opts,invocation:opts.invocation??"npx uptide",details:!1,repeat:{...opts.repeat,cwd:opts.details?opts.repeat?.cwd:void 0}}),notes=opts.details?notesOf(report):[],late=report.packages.filter(p=>p.skipReason==="TIME_BUDGET"),failed=report.packages.filter(p=>isFailure(p)),missing=late.length+failed.length>0?`<section class="package" id="not-analyzed"><header><h2>Not analyzed</h2></header>${late.length?`<p class="more unverified">${late.length} behind, out of time${opts.maxTime?` (--max-time ${e(opts.maxTime)})`:""}: ${e(late.map(p=>p.name).join(", "))}. Run check with explicit package names.</p>`:""}${failed.map(p=>`<p class="more breaking">${e(p.name)} ${e(p.installed)}: ${opts.details?e((p.notes[0]??"analysis failed").split(`
114
+ `)[0]):"analysis failed; see terminal output"}</p>`).join("")}</section>`:"",repo=opts.header?.repo??basename2(report.repo);return reportDocument(`Uptide check \xB7 ${repo}`,`${reportHeader({kind:"check",repo,manager:opts.header?.manager??"Package manager unavailable",date:opts.date,version:opts.version,timeZone:opts.timeZone})}${reportStats([{label:"Packages",value:rows.length},{label:"Breaking",value:report.summary.breaking,tone:"warn"},{label:"Deprecated",value:report.summary.deprecated},{label:"Auto-fixable",value:rows.reduce((n,r)=>n+r.plan.filter(g=>g.severity==="breaking").reduce((m,g)=>m+g.by.rule,0),0),tone:"safe"},{label:"Need the agent (LLM)",value:rows.reduce((n,r)=>n+r.plan.filter(g=>g.severity==="breaking").reduce((m,g)=>m+g.by.agent,0),0)}])}<p class="more">${e(verdict(rows))}</p>${sectionLabel("01","Packages","Upgrade impact")}
115
+ <div class="filters" hidden role="search" aria-label="Filter findings">${["All","Breaking","Deprecated","Unverified"].map(s=>`<button type="button" data-filter="${s.toLowerCase()}" aria-pressed="${s==="All"}">${s}</button>`).join("")}<input id="search" type="search" aria-label="Search packages and change rules" placeholder="Search packages or rules\u2026"></div>
78
116
  <section aria-label="Dependency summary" class="summary">${summary||'<p class="more safe">\u2713 Nothing to upgrade. No findings in the analyzed scope.</p>'}</section><p id="empty-filter" class="notice" hidden>No findings match these filters.</p>
79
- ${compact?'<p class="notice">Compact report: excerpts and additional sites omitted to stay under 300 KB. Use uptide check --details for the full report.</p>':""}${dependencies}
80
- <details class="notes"><summary>Analysis notes \xB7 ${notes.length} notes</summary><ul>${notes.slice(0,compact?30:300).map(n=>`<li>${e(n)}</li>`).join("")||"<li>No analysis gaps reported.</li>"}${notes.length>(compact?30:300)?"<li>Additional notes omitted; see JSON output.</li>":""}</ul></details>
81
- <section class="next"><h2>Next</h2>${commands.map(([cmd,why])=>`<p class="muted">${e(why)}</p><div class="command"><code>${escapeHtml(cmd)}</code><button type="button" data-copy hidden aria-label="Copy command">Copy</button></div>`).join("")}</section>
82
- <footer>Local report \xB7 No network requests \xB7 Contains source excerpts from reported sites only. Review before sharing.</footer></main><script>${js}</script></body></html>`}let html=render(145e3,50,1e3,!1);if(Buffer.byteLength(html)>=MAX_HTML_BYTES&&(html=render(0,10,80,!0)),Buffer.byteLength(html)>=MAX_HTML_BYTES)throw new Error("HTML report exceeds 300 KB even without excerpts; narrow the scope with --only.");return html}function renderMigrationHtml(report,opts){let e=escapeHtml,body=migrationBody(report),title=body.split(`
117
+ ${compact?'<p class="notice">Compact report: excerpts and additional sites omitted to stay under 300 KB. Use uptide check &lt;package&gt; --details for the full report.</p>':""}${sectionLabel("02","Findings","What reaches your code")}${dependencies}${missing}
118
+ <details class="notes"><summary>Analysis notes \xB7 ${notes.length} notes</summary><ul>${notes.slice(0,compact?30:300).map(n=>`<li>${e(n)}</li>`).join("")||`<li>${opts.details?"No analysis gaps reported.":"Use --details for analysis notes, locations and source excerpts."}</li>`}${notes.length>(compact?30:300)?"<li>Additional notes omitted; see JSON output.</li>":""}</ul></details>
119
+ <section class="next"><h2>03 / Next</h2>${commands.map(([cmd,why])=>`<p class="muted">${e(why)}</p>${reportCommand(cmd)}`).join("")}</section>
120
+ <footer>Generic analysis is the default; verified means a migration pack is available.<br>Local report \xB7 No network requests \xB7 ${opts.details?"Contains file paths and source excerpts. Review before sharing.":"No file paths or source code. Use --details for locations and excerpts."}</footer>`)}let html=render(145e3,50,1e3,!1);if(Buffer.byteLength(html)>=MAX_HTML_BYTES&&(html=render(0,10,80,!0)),Buffer.byteLength(html)>=MAX_HTML_BYTES)throw new Error("HTML report exceeds 300 KB even without excerpts; check fewer named packages.");return html}function writeHtml(report,opts,path2,cwd){let html=renderHtml(report,{...opts,readExcerpt:opts.readExcerpt??excerptReader(opts.root)});return writeReportHtml(html,opts.header?.repo??basename3(opts.root),"",path2,cwd)}function writeReportHtml(html,repo,kind,path2,cwd){let slug=repo.replace(/[^a-zA-Z0-9_-]+/g,"-").slice(0,80)||"repo",target=typeof path2=="string"?resolve4(cwd,path2):join3(tmpdir(),"uptide",`${slug}${kind?`-${kind}`:""}-${Date.now()}.html`);return mkdirSync(dirname3(target),{recursive:!0}),writeFileSync(target,html,{mode:384,flag:typeof path2=="string"?"w":"wx"}),target}function browserCommand(path2,platform=process.platform){if(platform==="darwin")return["open",[path2]];if(platform==="win32"){if(/["%&|<>^!\r\n]/.test(path2))throw new Error("Open this report manually: its path contains Windows shell metacharacters.");return["cmd.exe",["/d","/s","/c","start",'""',`"${path2}"`]]}return["xdg-open",[path2]]}async function openHtml(path2){let[bin,args]=browserCommand(path2);await new Promise((resolve8,reject)=>{let child=spawn(bin,args,{stdio:"ignore",windowsVerbatimArguments:process.platform==="win32"});child.once("error",reject),child.once("close",code=>code===0?resolve8():reject(new Error(`${bin} exited ${code}`)))})}function renderListHtml(report,opts){let{groups,used,tooling,unused}=listSections(report),failures=[...new Map(report.failures.map(f=>[f.name,f])).values()],section=0,nextSection=()=>String(++section).padStart(2,"0"),commands={...opts,cwd:opts.details?opts.cwd:void 0},priorities=report.priorities??[],urgent=new Set(priorities.flatMap(p=>p.packages)),row=(p,where,command)=>`<article class="member-grid${command?" has-command":""}" data-change="${p.change}" data-section="${where}"${urgent.has(p.name)?" data-priority":""}${p.tier==="verified"?" data-verified":""}><div class="pkg-name">${escapeHtml(p.name)}${p.tier==="verified"?'<span class="verified">verified</span>':""}</div><div class="versions">${escapeHtml(listVersions(p))}${p.versions?`<div class="muted">${escapeHtml(listSpread(p))}</div>`:""}</div><div class="gap">${escapeHtml(listChange(p))}</div><div class="usage${p.peerOf?" muted":""}">${p.peerOf?`peer of ${escapeHtml(p.peerOf.join(", "))}`:escapeHtml(listUsage(p))}</div>${command?reportCopyButton(command):""}${buildToolMajor(p)?`<div class="details-line deprecated">${escapeHtml(buildToolMajor(p))}</div>`:""}${(p.classification==="tooling"||p.classification==="possibly-unused")&&listReasons(p).length?`<div class="details-line">${listReasons(p).map(escapeHtml).join(" \xB7 ")}</div>`:""}${opts.details&&listSymbols(p)?`<div class="details-line">Top symbols: ${escapeHtml(listSymbols(p))}</div>`:""}${opts.details&&p.usage.fileList?.length?`<details class="details-line"><summary>Files</summary><ul>${p.usage.fileList.map(file=>`<li>${escapeHtml(file)}</li>`).join("")}</ul></details>`:""}</article>`,group=(g,where)=>`<section class="package"${where==="group"?" data-group":""}><header><h2>${escapeHtml(g.name)}</h2><div class="meta"><span>${escapeHtml(groupCount(g))}</span><span>${escapeHtml(groupVersions(g))}</span>${g.reason?`<span>${escapeHtml(g.reason)}</span>`:""}</div>${reportCommand(groupCommand(g,commands))}</header>${g.members.map(p=>row(p,where)).join("")}</section>`,standalone=(p,where)=>row(p,where,listCommand([p],commands)),collapsed=(label,packages,where)=>packages.length?`<details class="notes" data-block><summary>${nextSection()} / ${label} / ${packages.length} package${packages.length===1?"":"s"}${packages.some(p=>buildToolMajor(p))?` \xB7 <span class="deprecated">${escapeHtml(packages.filter(p=>buildToolMajor(p)).map(p=>p.name).join(", "))}: build tool major</span>`:""}</summary>${label==="Possibly unused"?`<p class="more">${escapeHtml(UNUSED_HINT)}</p>`:""}${listBlocks(packages,report).map(block=>block.name?group(block,where):block.members.map(p=>standalone(p,where)).join("")).join("")}</details>`:"",priorityBlock=()=>{if(!report.packages.length)return"";let list2=rows2=>`<ol class="priority-list">${rows2.map(p=>`<li class="priority-row signal-${p.signal}"><div class="pkg-name">${escapeHtml(p.name)}</div><div class="reason">${escapeHtml(p.reason)}</div>${reportCommand(priorityCommand(p,commands))}</li>`).join("")}</ol>`,urgentRows=priorities.filter(p=>p.tier==="urgent"),planning=priorities.filter(p=>p.tier!=="urgent"),rows=priorities.length?`<p class="more"><strong>Urgent \xB7 ${urgentRows.length}</strong> <span class="muted">advisories, deprecations</span></p>${urgentRows.length?list2(urgentRows):""}${planning.length?`<details class="notes"><summary>Worth planning \xB7 ${planning.length} <span class="muted">unsupported, drift, blocking, majors behind</span></summary>${list2(planning)}</details>`:""}`:`<p class="more">Nothing urgent: no advisories, deprecations, unsupported lines or blocking peers.</p>${report.cheapBatch?.length?`<ol class="priority-list"><li class="priority-row"><div class="pkg-name">Cheap batch</div><div class="reason">${escapeHtml(cheapBatchLabel(report.cheapBatch,8))}: minor/patch, few files, one PR</div>${reportCommand(cheapBatchCommand(report.cheapBatch,commands))}</li></ol>`:""}`;return`<section class="priorities">${sectionLabel(nextSection(),"Priorities",`Most urgent first \xB7 ${advisoryStatus(report)}`)}${rows}</section>`},repo=opts.header?.repo??basename4(report.repo),count=change=>report.packages.filter(p=>p.change===change).length;return reportDocument(`Uptide list \xB7 ${repo}`,`${reportHeader({kind:"list",repo,manager:opts.header?.manager??"Package manager unavailable",...opts})}${reportStats([{label:"Outdated",value:report.packages.length,filter:"all"},...report.unknown?.length?[{label:"Unknown",value:report.unknown.length,tone:"warn"}]:[],{label:"Major",value:count("major"),tone:"warn",filter:"major"},{label:"Minor",value:count("minor"),filter:"minor"},{label:"Patch",value:count("patch"),filter:"patch"},{label:"Groups",value:groups.length,filter:"groups"},{label:"Tooling",value:tooling.length,filter:"tooling"},{label:"Priority",value:report.packages.filter(p=>urgent.has(p.name)).length,tone:priorities.length?"warn":"safe",filter:"priority"},{label:"Verified",value:report.packages.filter(p=>p.tier==="verified").length,filter:"verified"},{label:"Possibly unused",value:unused.length,filter:"unused"}])}
121
+ <div class="filter-status" role="status" hidden><span data-filter-label></span><button type="button" data-filter-clear>Clear</button></div>
122
+ <p class="more" data-filter-empty hidden>No packages match this filter.</p>
123
+ <div data-list>
124
+ ${priorityBlock()}
125
+ ${(report.scanWarnings??[]).map(warning=>`<p class="more">${escapeHtml(warning)}</p>`).join("")}
126
+ ${report.unknown?.length?`<p class="more">${report.unknown.length} ${escapeHtml(notCheckedLabel(report))}. Latest versions are unknown.</p>`:""}
127
+ ${groups.length?`<div data-block>${sectionLabel(nextSection(),"Groups","Upgrade together")}${groups.map(g=>group(g,"group")).join("")}</div>`:""}
128
+ ${used.length?`<div data-block>${sectionLabel(nextSection(),"Packages")}<section class="package">${used.map(p=>standalone(p,"used")).join("")}</section></div>`:""}
129
+ ${collapsed("Tooling",tooling,"tooling")}${collapsed("Possibly unused",unused,"unused")}
130
+ </div>
131
+ ${report.skipped?.length?`<details class="notes"><summary>${nextSection()} / Not checked / ${report.skipped.length} non-registry source${report.skipped.length===1?"":"s"}</summary>${report.skipped.map(p=>`<div class="source-row"><strong>${escapeHtml(p.name)}</strong><span class="label">Skipped</span><span>${escapeHtml(p.reason)}</span></div>`).join("")}</details>`:""}
132
+ ${!report.packages.length&&!report.failures.length&&!report.unknown?.length&&!report.skipped?.length?'<p class="more safe">Every direct dependency is up to date.</p>':""}
133
+ ${failures.length?`<section class="notes">${sectionLabel(nextSection(),"Incomplete discovery")}${failures.map(f=>`<div class="incomplete-row"><strong>${escapeHtml(f.name)}</strong><span class="label">${report.unknown?.some(p=>p.name===f.name)?"Unknown":"Incomplete"}</span><span>${opts.details||f.kind==="registry"?escapeHtml(f.reason):"metadata or current version unavailable; see terminal output"}</span></div>`).join("")}</section>`:""}
134
+ <footer>Usage is a syntax scan, no type analysis. Generic analysis is the default; verified means a migration pack is available.<br>Local report \xB7 No network requests \xB7 ${opts.details?"File lists included. No source code.":"No source code or file paths. Run commands from the named repository; --details adds file lists."}</footer>`)}function writeListHtml(report,opts,path2,cwd){return writeReportHtml(renderListHtml(report,opts),opts.header?.repo??basename4(report.repo),"list",path2,cwd)}import{createHash as createHash2}from"crypto";import{existsSync as existsSync3,mkdirSync as mkdirSync2,readFileSync as readFileSync4,writeFileSync as writeFileSync2}from"fs";import{dirname as dirname4,join as join4}from"path";function renderMigrationHtml(report,opts){let e=escapeHtml,body=migrationBody(report),title=body.split(`
83
135
  `)[0]?.replace(/^#+\s*/,"")??"Migration report",cells=summaryCells(report),verdict3=report.verification.passed?"verification passed":"verification failed",when=new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",timeZoneName:"short",timeZone:opts.timeZone}).format(new Date(opts.date));return`<!doctype html>
84
136
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'sha256-${createHash2("sha256").update("").digest("base64")}'; connect-src 'none'; base-uri 'none'; form-action 'none'"><meta name="referrer" content="no-referrer"><title>Uptide fix \xB7 ${e(title)}</title><style>${css}
85
137
  .summary table{width:100%;border-collapse:collapse}.summary td{padding:10px 20px;border-bottom:1px solid var(--border);vertical-align:top}.summary tr:last-child td{border-bottom:0}.summary td:first-child{width:140px;font-weight:700}.body h2{display:none}.body h3{font-size:18px;margin:28px 0 12px}.body table{border-collapse:collapse;margin:12px 0}.body td{border:1px solid var(--border);padding:6px 12px}.body details{border:1px solid var(--border);border-radius:8px;margin:12px 0}.body pre{white-space:pre-wrap;overflow-wrap:anywhere;padding:12px}.diff-add{color:var(--green)}.diff-del{color:var(--red)}</style></head>
@@ -87,68 +139,129 @@ ${compact?'<p class="notice">Compact report: excerpts and additional sites omitt
87
139
  <section class="summary"><table>${[["Risk",cells.risk],["Changes",cells.changes],["Types",cells.types],["Behavior",cells.behavior],["Tests",cells.tests]].map(([label,text])=>`<tr><td>${label}</td><td>${inline(text)}</td></tr>`).join("")}</table></section>
88
140
  <section class="body">${markdownToHtml(body)}</section>
89
141
  <footer>Local report \xB7 No network requests \xB7 Rendered from the stored run's PR description. Review before sharing.</footer></main></body></html>
90
- `}function writeMigrationHtml(report,opts){let dir=dirname3(report.prBody),path2=join3(dir,"report.html");mkdirSync(dir,{recursive:!0}),writeFileSync(path2,renderMigrationHtml(report,opts),{mode:384});let stored=join3(dir,"report.json");if(existsSync3(stored))try{let saved=JSON.parse(readFileSync4(stored,"utf8"));writeFileSync(stored,JSON.stringify({...saved,html:path2},null,2))}catch{}return path2}function inline(text){let parts=[],pattern=/`([^`]+)`|\*\*([^*]+)\*\*|\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,last=0;for(let m of text.matchAll(pattern))parts.push(escapeHtml(text.slice(last,m.index))),m[1]!==void 0?parts.push(`<code>${escapeHtml(m[1])}</code>`):m[2]!==void 0?parts.push(`<strong>${inline(m[2])}</strong>`):parts.push(`<a href="${escapeHtml(m[4])}">${inline(m[3])}</a>`),last=(m.index??0)+m[0].length;return parts.push(escapeHtml(text.slice(last))),parts.join("")}function markdownToHtml(markdown){let lines=markdown.split(`
142
+ `}function writeMigrationHtml(report,opts){let dir=dirname4(report.prBody),path2=join4(dir,"report.html");mkdirSync2(dir,{recursive:!0}),writeFileSync2(path2,renderMigrationHtml(report,opts),{mode:384});let stored=join4(dir,"report.json");if(existsSync3(stored))try{let saved=JSON.parse(readFileSync4(stored,"utf8"));writeFileSync2(stored,JSON.stringify({...saved,html:path2},null,2))}catch{}return path2}function inline(text){let parts=[],pattern=/`([^`]+)`|\*\*([^*]+)\*\*|\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,last=0;for(let m of text.matchAll(pattern))parts.push(escapeHtml(text.slice(last,m.index))),m[1]!==void 0?parts.push(`<code>${escapeHtml(m[1])}</code>`):m[2]!==void 0?parts.push(`<strong>${inline(m[2])}</strong>`):parts.push(`<a href="${escapeHtml(m[4])}">${inline(m[3])}</a>`),last=(m.index??0)+m[0].length;return parts.push(escapeHtml(text.slice(last))),parts.join("")}function markdownToHtml(markdown){let lines=markdown.split(`
91
143
  `),out=[],i=0,list2=!1,closeList=()=>{list2&&out.push("</ul>"),list2=!1};for(;i<lines.length;){let line=lines[i];if(line.startsWith("```")){closeList();let lang=line.slice(3).trim(),body=[];for(i++;i<lines.length&&!lines[i].startsWith("```");)body.push(lines[i]),i++;i++;let rendered=lang==="diff"?body.map(l=>l.startsWith("+")&&!l.startsWith("+++")?`<span class="diff-add">${escapeHtml(l)}</span>`:l.startsWith("-")&&!l.startsWith("---")?`<span class="diff-del">${escapeHtml(l)}</span>`:escapeHtml(l)).join(`
92
144
  `):escapeHtml(body.join(`
93
145
  `));out.push(`<pre><code>${rendered}</code></pre>`);continue}let heading=/^(#{1,6})\s+(.*)$/.exec(line);if(heading){closeList();let level=heading[1].length;out.push(`<h${level}>${inline(heading[2])}</h${level}>`),i++;continue}if(/^(?:<details>)?(?:<summary>|<\/details>)|^<details>$/.test(line)){closeList(),out.push(line.replace(/<summary>(.*)<\/summary>/,(_,t)=>`<summary>${inline(t)}</summary>`)),i++;continue}if(line.startsWith("|")){closeList();let rows=[];for(;i<lines.length&&lines[i].startsWith("|");){let row=lines[i];if(i++,/^\|[\s-|]*\|$/.test(row))continue;let cells=row.slice(1,row.endsWith("|")?-1:void 0).split("|");rows.push(`<tr>${cells.map(c=>`<td>${inline(c.trim())}</td>`).join("")}</tr>`)}out.push(`<table>${rows.join("")}</table>`);continue}if(/^- /.test(line)){list2||out.push("<ul>"),list2=!0,out.push(`<li>${inline(line.slice(2))}</li>`),i++;continue}if(line.trim()===""){closeList(),i++;continue}if(line==="---"){closeList(),out.push("<hr>"),i++;continue}closeList(),out.push(`<p>${inline(line)}</p>`),i++}return closeList(),out.join(`
94
- `)}import{spawn}from"child_process";import{mkdirSync as mkdirSync2,writeFileSync as writeFileSync2}from"fs";import{tmpdir}from"os";import{basename as basename2,dirname as dirname4,join as join4,resolve as resolve4}from"path";function writeHtml(report,opts,path2,cwd){let slug=(opts.header?.repo??basename2(opts.root)).replace(/[^a-zA-Z0-9_-]+/g,"-").slice(0,80)||"repo",target=typeof path2=="string"?resolve4(cwd,path2):join4(tmpdir(),"uptide",`${slug}-${Date.now()}.html`),html=renderHtml(report,{...opts,readExcerpt:opts.readExcerpt??excerptReader(opts.root)});return mkdirSync2(dirname4(target),{recursive:!0}),writeFileSync2(target,html,{mode:384,flag:typeof path2=="string"?"w":"wx"}),target}function browserCommand(path2,platform=process.platform){if(platform==="darwin")return["open",[path2]];if(platform==="win32"){if(/["%&|<>^!\r\n]/.test(path2))throw new Error("Open this report manually: its path contains Windows shell metacharacters.");return["cmd.exe",["/d","/s","/c","start",'""',`"${path2}"`]]}return["xdg-open",[path2]]}async function openHtml(path2){let[bin,args]=browserCommand(path2);await new Promise((resolve6,reject)=>{let child=spawn(bin,args,{stdio:"ignore",windowsVerbatimArguments:process.platform==="win32"});child.once("error",reject),child.once("close",code=>code===0?resolve6():reject(new Error(`${bin} exited ${code}`)))})}function processIo(){return{out:text=>{process.stdout.write(text)},err:text=>{process.stderr.write(text)},env:process.env,cwd:process.cwd(),outTty:process.stdout.isTTY===!0,errTty:process.stderr.isTTY===!0,now:()=>Date.now()}}function uiOf(io,flags){let ci=flags.ci===!0||io.env.CI!==void 0&&io.env.CI!==""&&io.env.CI!=="0",noColor=io.env.NO_COLOR!==void 0&&io.env.NO_COLOR!=="",forced=io.env.FORCE_COLOR!==void 0&&io.env.FORCE_COLOR!=="0";return{color:!ci&&flags.color!==!1&&!noColor&&(io.outTty||forced),interactive:!ci&&io.errTty&&io.env.TERM!=="dumb"}}var PRIVACY="Privacy:\n Analysis runs locally. Your code is sent only to the LLM provider (Anthropic), only\n for assisted fixes in `uptide fix`, and only with your own ANTHROPIC_API_KEY: for each\n site the rules cannot migrate, the finding, the enclosing function and the compiler\n error. `uptide fix --no-llm` turns assisted fixes off. No telemetry, no account.\n Other network use: your npm registry for package metadata and tarballs, and GitHub\n only when you pass `fix --pr` or run `pr-body`.\n";import{join as join5}from"path";var import_picocolors6=__toESM(require_picocolors(),1),SUPPORTED=["zod","stripe"];async function locateDependencies(repo,engine,names2=SUPPORTED){let dependencies=names2.map(name=>({name,workspaces:[],catalog:!1}));for(let workspace of repo.workspaces){let dir=join5(repo.root,workspace),[installed,declared]=await Promise.all([engine.installed(dir),engine.declared(dir)]);for(let dep of dependencies){let spec=declared.get(dep.name);if(spec===void 0)continue;dep.workspaces.push(workspace),spec.startsWith("catalog:")&&(dep.catalog=!0);let version=installed.get(dep.name);version&&(!dep.installed||compareVersions(version,dep.installed)<0)&&(dep.installed=version)}}return dependencies}async function collectStatus(repo,engine,names2=SUPPORTED){let dependencies=await locateDependencies(repo,engine,names2),registryError;return await Promise.all(dependencies.filter(dep=>dep.workspaces.length>0).map(async dep=>{try{dep.latest=await engine.latest(dep.name),dep.installed&&(dep.majorsBehind=majorsBehind(dep.installed,dep.latest))}catch(err){registryError=err instanceof Error?err.message:String(err)}})),{repo:repo.root,name:repo.name,packageManager:repo.manager,lockfile:repo.lockfile,workspaces:repo.workspaces,dependencies,...registryError?{registryError}:{}}}function verdict2(dep){if(dep.workspaces.length===0)return"not a dependency";if(!dep.installed)return"declared, not in the lockfile";if(!dep.latest)return`${dep.installed} installed, latest unknown`;if(compareVersions(dep.installed,dep.latest)>=0)return`${dep.installed} installed, up to date`;let majors=dep.majorsBehind??0,behind=majors===0?"same major":`${majors} major${majors===1?"":"s"} behind`;return`${dep.installed} installed, latest ${dep.latest}, ${behind}`}function formatStatus(report,opts={}){let colors=import_picocolors6.default.createColors(opts.color??!0),packages=report.workspaces.filter(w=>w!==".").length,lines=[`${colors.dim("Repository")} ${report.name?`${report.name} ${colors.dim(report.repo)}`:report.repo}`,`${colors.dim("Manager")} ${report.packageManager}${packages>0?`, ${packages} workspace package${packages===1?"":"s"}`:""}`,""],width2=Math.max(...report.dependencies.map(d=>d.name.length));for(let dep of report.dependencies){let where=packages>0&&dep.workspaces.length>0?colors.dim(` ${dep.workspaces.join(", ")}${dep.catalog?" (catalog)":""}`):"",text=verdict2(dep),behind=(dep.majorsBehind??0)>0;lines.push(`${colors.bold(dep.name.padEnd(width2))} ${behind?colors.yellow(text):text}${where}`)}lines.push("");let used=report.dependencies.filter(d=>d.workspaces.length>0);return report.registryError&&lines.push(`Could not reach the npm registry (${report.registryError}), so latest versions are unknown.`,` ${colors.bold("Next:")} npm ping`),used.length===0?lines.push(`Neither ${report.dependencies.map(d=>d.name).join(" nor ")} is a dependency here; those are the upgrades uptide covers today.`):used.some(d=>!d.latest||!d.installed||compareVersions(d.installed,d.latest)<0)?lines.push(`Run ${colors.bold("`uptide check`")} for impact.`):lines.push("Nothing to upgrade."),`${lines.join(`
146
+ `)}import{mkdirSync as mkdirSync3,writeFileSync as writeFileSync3}from"fs";import{tmpdir as tmpdir2}from"os";import{dirname as dirname5,join as join5,resolve as resolve5}from"path";function renderPlanHtml(plan,opts){let e=escapeHtml,uptide=opts.invocation??"npx uptide",tone={unknown:"unverified",none:"safe",small:"deprecated",medium:"unverified",large:"breaking"},steps=plan.steps.map(step=>{let packages=step.packages.map(p=>`<article class="site"><div class="mono">${e(p.name)} ${e(p.installed)} \u2192 ${e(p.target)} \xB7 ${e(p.tier)}</div><p class="muted">${e(effortLine(p.effort))}</p>${opts.fixable&&p.effort.level!=="none"?`<div class="command"><code>${e(`${uptide} ${p.effort.level==="unknown"?"check":"fix"} ${p.name}`)}</code></div>`:""}</article>`).join(""),constraints=step.constraints.map(c=>`<p class="more ${c.effect==="blocked"?"breaking":"unverified"}">${c.effect==="blocked"?"Blocked: ":"Peer: "}${e(c.reason)}</p>`).join("");return`<section class="package" id="step-${step.order}"><header><h2>${step.order}. ${e(stepTitle(step))}</h2><span class="mono ${tone[step.effort]}">effort: ${e(step.effort)}</span></header>${constraints}${packages}</section>`}).join(""),notPlanned=plan.notPlanned.length?`<section class="package" id="not-planned"><header><h2>Not planned</h2></header>${plan.notPlanned.map(p=>`<p class="more">${e(p.name)} ${e(p.installed)}: ${e(p.reason)}</p>`).join("")}</section>`:"",when=new Intl.DateTimeFormat("en-US",{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",timeZoneName:"short",timeZone:opts.timeZone}).format(new Date(opts.date));return`<!doctype html>
147
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; connect-src 'none'; base-uri 'none'; form-action 'none'"><meta name="referrer" content="no-referrer"><title>Uptide plan \xB7 ${e(opts.header?.repo??"repository")}</title><style>${css}</style></head>
148
+ <body><main><header><div class="brand">UPTIDE / PLAN</div><h1>${e(opts.header?.repo??"Upgrade plan")}</h1><div class="meta"><span>${e(opts.header?.manager??"")}</span><time datetime="${e(opts.date)}">${e(when)}</time><span>Uptide CLI ${e(opts.version)}</span><span>${elapsed(opts.header?.ms??0)}</span></div><p class="muted">${plan.steps.length} ${plan.steps.length===1?"step":"steps"}, in the order to take them.${plan.notPlanned.length?` ${plan.notPlanned.length} not planned.`:""}</p><p class="muted">${e(TIER_LEGEND)}</p></header>
149
+ ${(plan.notes??[]).map(note=>`<p class="more">${e(note)}</p>`).join("")}
150
+ ${steps||'<p class="more safe">\u2713 Nothing to plan: every analyzed dependency is up to date.</p>'}${notPlanned}
151
+ <footer>Effort is an estimate from the findings: none (nothing affected), small (rules, or up to 5 sites by hand or agent), medium (up to 25), large (more). Local page \xB7 No network requests.</footer></main></body></html>`}function writePlanHtml(plan,opts,path2,cwd){let slug=(opts.header?.repo??"repo").replace(/[^a-zA-Z0-9_-]+/g,"-").slice(0,80)||"repo",target=typeof path2=="string"?resolve5(cwd,path2):join5(tmpdir2(),"uptide",`${slug}-plan-${Date.now()}.html`);return mkdirSync3(dirname5(target),{recursive:!0}),writeFileSync3(target,renderPlanHtml(plan,opts),{mode:384,flag:typeof path2=="string"?"w":"wx"}),target}import{createInterface}from"readline";function processIo(){return{out:text=>{process.stdout.write(text)},err:text=>{process.stderr.write(text)},env:process.env,cwd:process.cwd(),outTty:process.stdout.isTTY===!0,columns:process.stdout.columns,errTty:process.stderr.isTTY===!0,now:()=>Date.now(),inTty:process.stdin.isTTY===!0,confirmTelemetry:()=>new Promise(resolve8=>{let rl=createInterface({input:process.stdin,output:process.stderr,terminal:!0}),settled=!1,done=yes=>{settled||(settled=!0,rl.close(),resolve8(yes))};rl.on("SIGINT",()=>done(!1)),rl.on("close",()=>done(!1)),rl.question(`Share anonymous CLI usage with Uptide (PostHog EU, 90-day retention)?
152
+ Random IDs, public package versions and aggregate counts only; no IP, code, paths or repo names.
153
+ Details: https://github.com/uptide-dev/uptide/blob/main/docs/telemetry.md
154
+ Enable telemetry? [y/N] `,answer=>done(/^y(?:es)?$/i.test(answer.trim())))})}}function uiOf(io2,flags){let ci=flags.ci===!0||io2.env.CI!==void 0&&io2.env.CI!==""&&io2.env.CI!=="0",noColor=io2.env.NO_COLOR!==void 0&&io2.env.NO_COLOR!=="",forced=io2.env.FORCE_COLOR!==void 0&&io2.env.FORCE_COLOR!=="0";return{color:!ci&&flags.color!==!1&&!noColor&&(io2.outTty||forced),interactive:!ci&&io2.errTty&&io2.env.TERM!=="dumb"}}var PRIVACY="Privacy:\n Analysis runs locally. Code snippets go to your chosen LLM provider (Anthropic, OpenAI or Gemini), only\n for assisted fixes in `uptide fix`, and only with your own API key from ANTHROPIC_API_KEY,\n OPENAI_API_KEY or GEMINI_API_KEY: for each\n site the rules cannot migrate, the finding, the enclosing function and the compiler\n error. `uptide fix --no-llm` turns assisted fixes off. No account.\n Anonymous telemetry is off by default and asks for consent in an interactive terminal.\n Set UPTIDE_TELEMETRY=0 to disable it. No IP, code, paths or repo names are collected.\n Other network use: your npm registry for package metadata and tarballs, npm's advisory\n endpoint from `list` (public package names and installed versions; `--no-advisories` turns\n it off), PostHog EU only\n after telemetry opt-in, and GitHub when you pass `fix --pr` or run `pr` / `pr-body`.\n";import{join as join6}from"path";var import_picocolors9=__toESM(require_picocolors(),1);var SUPPORTED=["zod","stripe"];async function locateDependencies(repo,engine,names2=SUPPORTED){let dependencies=names2.map(name=>({name,workspaces:[],catalog:!1}));for(let workspace of repo.workspaces){let dir=join6(repo.root,workspace),[installed,declared]=await Promise.all([engine.installed(dir),engine.declared(dir)]);for(let dep of dependencies){let spec=declared.get(dep.name);if(spec===void 0)continue;dep.workspaces.push(workspace),spec.startsWith("catalog:")&&(dep.catalog=!0);let version=installed.get(dep.name);version&&(!dep.installed||compareVersions(version,dep.installed)<0)&&(dep.installed=version)}}return dependencies}async function declaredDependencies(repo,engine){let names2=new Set;for(let workspace of repo.workspaces){let declared=await engine.declared(join6(repo.root,workspace));for(let[name,spec]of declared)/^(workspace|link|file):/.test(spec)||names2.add(name)}return[...names2].sort()}async function collectStatus(repo,engine,names2=SUPPORTED){let dependencies=await locateDependencies(repo,engine,names2),registryError;return await Promise.all(dependencies.filter(dep=>dep.workspaces.length>0).map(async dep=>{try{dep.latest=await engine.latest(dep.name),dep.installed&&(dep.majorsBehind=majorsBehind(dep.installed,dep.latest))}catch(err){registryError=err instanceof Error?err.message:String(err)}})),{repo:repo.root,name:repo.name,packageManager:repo.manager,lockfile:repo.lockfile,workspaces:repo.workspaces,dependencies,...registryError?{registryError}:{}}}function verdict2(dep){if(dep.workspaces.length===0)return"not a dependency";if(!dep.installed)return"declared, not in the lockfile";if(!dep.latest)return`${dep.installed} installed, latest unknown`;if(compareVersions(dep.installed,dep.latest)>=0)return`${dep.installed} installed, up to date`;let majors=dep.majorsBehind??0,behind=majors===0?"same major":`${majors} major${majors===1?"":"s"} behind`;return`${dep.installed} installed, latest ${dep.latest}, ${behind}`}function formatStatus(report,opts={}){let colors=import_picocolors9.default.createColors(opts.color??!0),packages=report.workspaces.filter(w=>w!==".").length,lines=[`${colors.dim("Repository")} ${report.name?`${report.name} ${colors.dim(report.repo)}`:report.repo}`,`${colors.dim("Manager")} ${report.packageManager}${packages>0?`, ${packages} workspace package${packages===1?"":"s"}`:""}`,""],width2=Math.max(...report.dependencies.map(d=>d.name.length));for(let dep of report.dependencies){let where=packages>0&&dep.workspaces.length>0?colors.dim(` ${dep.workspaces.join(", ")}${dep.catalog?" (catalog)":""}`):"",text=verdict2(dep),behind=(dep.majorsBehind??0)>0;lines.push(`${colors.bold(dep.name.padEnd(width2))} ${behind?colors.yellow(text):text}${where}`)}lines.push("");let used=report.dependencies.filter(d=>d.workspaces.length>0);return report.registryError&&lines.push(`Could not reach the npm registry (${report.registryError}), so latest versions are unknown.`,` ${colors.bold("Next:")} npm ping`),used.length===0?lines.push(`Neither ${report.dependencies.map(d=>d.name).join(" nor ")} is a dependency here; those are the upgrades uptide covers today.`):used.some(d=>!d.latest||!d.installed||compareVersions(d.installed,d.latest)<0)?lines.push(`Run ${colors.bold(runnable("`uptide list`, then `uptide check <package>`"))} for impact.`):lines.push("Nothing to upgrade."),`${lines.join(`
95
155
  `)}
96
- `}var VERSION="0.3.0",EXIT_CODES=(zero,one)=>`
156
+ `}import{readFileSync as readFileSync6,rmSync}from"fs";import{dirname as dirname6,join as join8,resolve as resolve6}from"path";import{readFileSync as readFileSync5,statSync}from"fs";import{join as join7}from"path";function cachedPublicVersion(env){return(name,version)=>{if(!NAME_PATTERN.test(name)||name.length>214||!VERSION_PATTERN.test(version)||version.length>128)return!1;for(let key of[`resolve-${version}`,"resolve-latest"])try{let path2=join7(defaultCacheDir(env),"registry",...name.split("/"),`${key}.json`);if(statSync(path2).size>1024*1024)continue;let{value}=JSON.parse(readFileSync5(path2,"utf8"));if(value.publicRegistry===!0&&value.name===name&&value.version===version)return!0}catch{}return!1}}import{spawn as spawn2}from"child_process";import{fileURLToPath}from"url";var MAX_BYTES=32*1024;function dispatch(delivery){let message=JSON.stringify(delivery);if(Buffer.byteLength(message)>MAX_BYTES)return;let child=spawn2(process.execPath,[fileURLToPath(new URL("./telemetry-sender.js",import.meta.url))],{detached:!0,windowsHide:!0,stdio:["pipe","ignore","ignore"],env:{...process.platform==="win32"?{SystemRoot:process.env.SystemRoot}:{},...process.env.NODE_EXTRA_CA_CERTS?{NODE_EXTRA_CA_CERTS:process.env.NODE_EXTRA_CA_CERTS}:{}}});child.on("error",()=>{}),child.stdin.on("error",()=>{}),child.stdin.end(message),child.stdin.unref?.(),child.unref()}function createTelemetry(io2,options){let path2=options.path??settingsPath(io2.env),last=join8(dirname6(path2),"telemetry-last.json"),publicVersion=options.publicVersion??cachedPublicVersion(io2.env),key=options.key??BUILD_KEY,url=captureUrl(io2.env.UPTIDE_TELEMETRY_HOST??options.host??BUILD_HOST),configured=/^phc_[A-Za-z0-9_-]+$/.test(key)&&url!==void 0,settings,command,metrics={},started=0,status=(ci=!1)=>{let saved=readSettings(path2),active=enabled(saved,io2.env,isCi(io2.env,ci));return{preference:saved===void 0?"unset":saved.consent?"on":"off",enabled:active,transport:configured?"configured":"disabled: no capture key or invalid HTTPS host",sending:active&&configured,override:io2.env.UPTIDE_TELEMETRY==="0"?"environment: off":io2.env.UPTIDE_TELEMETRY==="1"?"environment: on":isCi(io2.env,ci)?"CI: off (set UPTIDE_TELEMETRY=1 to opt in)":"none"}};return{async begin(name,flags){settings=void 0,command=void 0,metrics={};try{let known=name==="uptide"?"status":name;if(!COMMANDS.includes(known))return;let saved=readSettings(path2),ci=isCi(io2.env,flags.ci);if(saved===void 0&&io2.env.UPTIDE_TELEMETRY===void 0&&!ci&&!flags.json&&io2.inTty&&io2.outTty&&io2.errTty&&io2.confirmTelemetry&&(saved={consent:await io2.confirmTelemetry()===!0},atomicJson(path2,saved)),!enabled(saved,io2.env,ci))return;settings=identity(saved??{consent:!1}),atomicJson(path2,settings),command=known,metrics={repo:resolve6(io2.cwd,flags.cwd??".")},started=io2.now()}catch{settings=void 0,command=void 0}},record(value){if(command)try{metrics={...metrics,...value()}}catch{}},finish(code){try{if(!settings||!command||!enabled(readSettings(path2),io2.env,isCi(io2.env)))return;let event=buildEvent(settings,command,options.version,metrics,io2.now()-started,code,publicVersion);if(!event||(atomicJson(last,event),!configured||!url))return;(options.dispatch??dispatch)({url,key,event})}catch{}},control(action,ci){if(action==="status")return status(ci);if(action==="show")try{return sanitizeEvent(JSON.parse(readFileSync6(last,"utf8")),publicVersion)??null}catch{return null}if(action==="on")atomicJson(path2,identity({...readSettings(path2),consent:!0}));else if(action==="off")atomicJson(path2,{consent:!1}),rmSync(last,{force:!0});else throw new Error("Expected telemetry on, off, status or show.");return status(ci)}}}function checkMetrics(report){return{repo:report.repo,packages:report.packages.map(p=>({name:p.name,versions:[p.installed,p.target]})),counts:{packages:report.packages.length,workspaces:report.workspaces.length,breaking:report.summary.breaking,deprecated:report.summary.deprecated,unverified:report.summary.unverified,failed:report.summary.failed,partial:report.summary.partiallyAnalyzed},durations:{fetch:report.packages.reduce((n,p)=>n+p.timing.fetchMs,0),diff:report.packages.reduce((n,p)=>n+p.timing.diffMs,0),usages:report.packages.reduce((n,p)=>n+p.timing.usagesMs,0),compile:report.packages.reduce((n,p)=>n+p.timing.compileMs,0),runtime:report.packages.reduce((n,p)=>n+(p.timing.runtimeMs??0),0)}}}function listMetrics(report){return{repo:report.repo,packages:report.packages.map(p=>({name:p.name,versions:[p.current,p.latest]})),counts:{packages:report.packages.length,workspaces:report.workspaces.length,failed:report.failures.length},durations:{engine:report.timing.totalMs}}}function fixMetrics(report,cwd){return{repo:cwd,packages:[{name:report.package,versions:[report.from??"",report.target]}],counts:{sites:report.sites.length,files:new Set(report.sites.map(s=>s.finding.usage.file)).size,new_errors:report.verification.newErrors.length,tests:report.verification.tests.length},durations:{engine:report.timingMs,verification:report.verificationTimingMs??0},verification:report.verificationPending?"not_run":report.verification.passed?"passed":"failed",cost:report.llm.costUsd,provider:report.llm.provider,model:report.llm.model}}var EXIT_CODES=(zero,one,two="")=>`
97
157
  Exit codes:
98
158
  0 ${zero}
99
159
  1 ${one}
100
- 2 uptide could not answer: bad arguments, unsupported repository, no network
101
- `;function shared(command){return command.option("--cwd <dir>","repository to work on (default: current directory)").option("--json","machine-readable result on stdout; progress stays on stderr").option("--ci","plain output for logs: no color, no spinner").option("--no-color","no color (NO_COLOR is respected too)")}var list=value=>value?.split(",").map(s=>s.trim()).filter(Boolean);function parseTargets(specs,only){let targets={};for(let spec of specs??[]){if(spec==="latest")continue;let at=spec.lastIndexOf("@");if(at>0){let name=spec.slice(0,at);if(only&&!only.includes(name))throw new CliError(`--target ${spec}: ${name} is not among the packages selected (${only.join(", ")})`,{next:`uptide check --only ${name} --target ${spec}`});targets[name]=spec.slice(at+1)}else if(only?.length===1&&only[0]&&/^\d/.test(spec))targets[only[0]]=spec;else throw new CliError(`--target ${spec}: expected <package>@<version> or latest`,{next:"uptide check --target zod@4.6.5"})}return targets}var INVOCATION=uptideCommand(VERSION),HTML_INVOCATION=INVOCATION,FIX_MANAGERS=["pnpm","npm","yarn"];function headerOf(repo,ms){return{repo:repo.name??basename3(repo.root),manager:repo.manager,packages:repo.workspaces.filter(w=>w!==".").length,ms}}function whereItRan(report){if(!report.source)return"";let untouched=report.sourceChanged?.length?`Warning: your checkout changed during the run: ${report.sourceChanged.join("; ")}.`:"Your checkout was not touched: same branch, files, hooks and git config.";return`${report.clone?.kept?`Temporary clone kept: ${report.clone.path}
102
- ${report.clone.reason}; \`uptide clean\` removes kept clones older than 7 days.`:"Ran in a temporary clone, removed now that the run is over."}
160
+ 2 uptide could not answer: bad arguments, unsupported repository, no network${two}
161
+ `;function shared(command){return command.option("--cwd <dir>","repository to work on (default: current directory)").option("--json","machine-readable result on stdout; progress stays on stderr").option("--ci","plain output for logs: no color, no spinner").option("--no-color","no color (NO_COLOR is respected too)")}var list=value=>value?.split(",").map(s=>s.trim()).filter(Boolean);function parseTargets(specs,only){let targets={};for(let spec of specs??[]){if(spec==="latest")continue;let at=spec.lastIndexOf("@");if(at>0){let name=spec.slice(0,at);if(only&&!only.includes(name))throw new CliError(`--target ${spec}: ${name} is not among the packages selected (${only.join(", ")})`,{next:`uptide check ${name} --target ${spec}`});targets[name]=spec.slice(at+1)}else if(only?.length===1&&only[0]&&/^\d/.test(spec))targets[only[0]]=spec;else throw new CliError(`--target ${spec}: expected <package>@<version> or latest`,{next:"uptide check zod --target zod@4.6.5"})}return targets}var HTML_INVOCATION=INVOCATION,FIX_MANAGERS=["pnpm","npm","yarn"];function headerOf(repo,ms){return{repo:repo.name??basename5(repo.root),manager:repo.manager,packages:repo.workspaces.filter(w=>w!==".").length,ms}}function whereItRan(report){if(!report.source)return"";let untouched=report.sourceChanged?.length?`Warning: your checkout changed during the run: ${report.sourceChanged.join("; ")}.`:"Your checkout was not touched: same branch, files, hooks and git config.";return`${report.clone?.kept?`Temporary clone kept: ${report.clone.path}
162
+ ${report.clone.reason}; \`${INVOCATION} clean\` removes kept clones older than 7 days.`:"Ran in a temporary clone, removed now that the run is over."}
103
163
  ${untouched}
104
- `}function timingNotes(report,progress){for(let p of report.packages){let t=p.timing,parts=[["fetch",t.fetchMs],["diff",t.diffMs],["usages",t.usagesMs],["compile",t.compileMs],["runtime",t.runtimeMs??0]].filter(([,ms])=>ms>=1).map(([name,ms])=>`${name} ${elapsed(ms)}`);if(parts.length===0)continue;let where=p.workspace==="."||p.workspace==="*"?"":` (${p.workspace})`;progress.note(`${p.name} ${p.installed} \u2192 ${p.target}${where}: ${parts.join(", ")}`)}}async function run(argv,io,engine=defaultEngine()){let code=EXIT.ok,act=async(flags,body,options={})=>{let ui=uiOf(io,flags);try{code=await body({ui,progress:createProgress(io,ui,options),cwd:resolve5(io.cwd,flags.cwd??".")})}catch(err){io.err(renderError(err,ui.color)),code=err instanceof CliError?err.options.exitCode??EXIT.error:EXIT.error}},emit=value=>io.out(`${JSON.stringify(value,null,2)}
105
- `),program2=new Command().name("uptide").description(`Renovate updates the version. We update the code.
164
+ `}function timingNotes(report,progress){for(let p of report.packages){let t=p.timing,parts=[["fetch",t.fetchMs],["diff",t.diffMs],["usages",t.usagesMs],["compile",t.compileMs],["runtime",t.runtimeMs??0]].filter(([,ms])=>ms>=1).map(([name,ms])=>`${name} ${elapsed(ms)}`);if(parts.length===0)continue;let where=p.workspace==="."||p.workspace==="*"?"":` (${p.workspace})`;progress.note(`${p.name} ${p.installed} \u2192 ${p.target}${where}: ${parts.join(", ")}`)}}async function run(argv,io2,engine=defaultEngine(),telemetry){let code=EXIT.ok,fixing=!1,fixEngineStarted=!1,fixSpend,act=async(flags,body,options={})=>{let ui=uiOf(io2,flags);["list","check"].includes(argv[0]??"")&&(!io2.outTty||!ui.color)&&(ui.color=!1,ui.interactive=!1);try{code=await body({ui,progress:createProgress(io2,ui,options),cwd:resolve7(io2.cwd,flags.cwd??".")})}catch(err){io2.err(renderError(err,ui.color)),code=err instanceof CliError?err.options.exitCode??EXIT.error:EXIT.error}},emit=value=>io2.out(`${JSON.stringify(value,null,2)}
165
+ `),requireDependencies=(repo,only,progress)=>progress.phase("Dependencies",async()=>{let deps=await locateDependencies(repo,engine,only??await declaredDependencies(repo,engine));if(only){let absent=deps.filter(d=>d.workspaces.length===0).map(d=>d.name);if(absent.length>0)throw notADependency(repo,absent);requireInstalled(repo,deps)}else requireNodeModules(repo,deps);return deps},deps=>only?deps.map(d=>`${d.name} ${d.installed}`).join(", "):`${deps.length} declared`),program2=new Command().name("uptide").description(`Migrations you can merge.
106
166
 
107
- With no command: where zod and stripe stand in this repository.`).version(VERSION).exitOverride().configureOutput({writeOut:text=>io.out(text),writeErr:text=>io.err(text)}).showHelpAfterError("(run with --help for usage)").enablePositionalOptions().allowExcessArguments(!0);shared(program2).addHelpText("after",`
167
+ With no command: where zod and stripe stand in this repository.`).version(VERSION).exitOverride().configureOutput({writeOut:text=>io2.out(text),writeErr:text=>io2.err(text)}).showHelpAfterError("(run with --help for usage)").enablePositionalOptions().allowExcessArguments(!0);program2.hook("preAction",async(_parent,command)=>{fixing=command.name()==="fix",await telemetry?.begin(command.name(),command.optsWithGlobals()).catch(()=>{})}),shared(program2.command("telemetry").description("Control opt-in anonymous telemetry").argument("<action>","on, off, status or show")).action((action,flags)=>act(flags,async()=>{if(!["on","off","status","show"].includes(action))throw new CliError("Expected telemetry on, off, status or show.");let value=(telemetry??createTelemetry(io2,{version:VERSION})).control(action,flags.ci);return flags.json||action==="show"?emit(value):io2.out(`Telemetry: ${JSON.stringify(value,null,2)}
168
+ `),EXIT.ok})),shared(program2).addHelpText("after",`
108
169
  Examples:
109
170
  $ npx uptide where zod and stripe stand in this repository
110
- $ npx uptide check which of your call sites the upgrade breaks
111
- $ npx uptide fix --only zod migrate on a new branch, verified by your compiler and tests
171
+ $ npx uptide list discover outdated dependencies quickly
172
+ $ npx uptide check zod which of your call sites the upgrade breaks
173
+ $ npx uptide fix zod migrate on a new branch, verified by your compiler and tests
112
174
  ${EXIT_CODES("nothing breaking","breaking changes found, or a migration that did not verify")}
113
- ${PRIVACY}`).action(flags=>act(flags,async({ui,progress,cwd})=>{let unknown=program2.args[0];if(unknown)throw new CliError(`unknown command '${unknown}'`,{next:"uptide --help"});let repo=await progress.phase("Repository",()=>detectRepo(cwd,engine.workspaces),describeRepo),status=await progress.phase("Versions",()=>collectStatus(repo,engine),s=>s.registryError?"registry unreachable":"lockfile and registry read");return flags.json?emit(status):io.out(`
114
- ${formatStatus(status,{color:ui.color})}`),EXIT.ok})),shared(program2.command("check").description("Which of your call sites an upgrade breaks, and what fixing them costs").option("--only <packages>","comma-separated dependencies to check, or `all` (default: zod,stripe)").option("--target <spec...>","`<package>@<version>`, repeatable; a bare version with a single --only (default: latest)").option("--html [path]","write a self-contained HTML report (default: OS temp directory)").option("--open","open the HTML report in your browser (interactive terminals only)").option("--details","every site with its reason, compiler message and analysis notes").option("--all","with --details: also show findings under 50% confidence").option("--verbose","one progress line per analysis phase, with timings").option("--no-compile","skip compiling against the target version").option("--no-runtime","skip loading installed and target copies in a sandboxed Node").option("--all-deps","also analyze @types/* and dependencies the repo never imports").option("--workspaces <n>","workspaces checked in parallel (worker threads)","2").option("--no-remote","accepted for forward compatibility; there is no remote service")).addHelpText("after",`
175
+ ${PRIVACY}`).action(flags=>act(flags,async({ui,progress,cwd})=>{let unknown=program2.args[0];if(unknown)throw new CliError(`unknown command '${unknown}'`,{next:"uptide --help"});let repo=await progress.phase("Repository",()=>detectRepo(cwd,engine.workspaces),describeRepo),status=await progress.phase("Versions",()=>collectStatus(repo,engine),s=>s.registryError?"registry unreachable":"lockfile and registry read");return telemetry?.record(()=>({repo:repo.root,packages:status.dependencies.map(d=>({name:d.name,versions:[d.installed,d.latest].filter(v=>!!v)})),counts:{packages:status.dependencies.length,workspaces:status.workspaces.length}})),flags.json?emit(status):io2.out(`
176
+ ${formatStatus(status,{color:ui.color})}`),EXIT.ok})),shared(program2.command("list").description("Discover outdated dependencies without compiling or installing").option("--all","expand minor/patch upgrades, tooling and possibly unused packages").option("--html [path]","write a self-contained HTML report (default: OS temp directory)").option("--open","open the HTML report in a browser (requires --html)").option("--details","show top symbols and source file lists").option("--verbose","show discovery/render phase timings and file counts").option("--no-advisories",`never send installed versions to npm's advisory endpoint (also: "advisories": false in uptide.config.json)`)).addHelpText("after",`
177
+ Examples:
178
+ $ uptide list
179
+ $ uptide list --all --json
180
+
181
+ No compilation, install or tarball downloads: registry metadata, and one request to npm's
182
+ advisory endpoint with public packages' names and installed versions (--no-advisories).
183
+ Usage counts calls/new/JSX and references through imported bindings. Tooling and
184
+ possibly unused packages are collapsed; use --all to expand. Majors first, then importing files and call sites.
185
+ ${EXIT_CODES("discovery complete","not used","; incomplete discovery retains successful rows")}`).action(flags=>act(flags,async({cwd,progress,ui})=>{if(flags.open&&!flags.html)throw new CliError("--open requires --html");let started=io2.now(),repo=await detectRepo(cwd,engine.workspaces);if(!engine.list)throw new CliError("this build cannot list dependencies");let discover=engine.list,report=await progress.phase("Discovery",()=>discover({cwd:repo.root,details:flags.details,...flags.verbose?{verbose:!0}:{},...flags.advisories===!1?{advisories:!1}:{}}));telemetry?.record(()=>listMetrics(report));let renderStart=io2.now(),renderMs;if(flags.json?emit(report):io2.out(formatList(report,{all:flags.all,color:ui.color&&io2.outTty,width:io2.columns,details:flags.details,header:headerOf(repo,io2.now()-started),invocation:INVOCATION,cwd:flags.cwd})),flags.html){let path2=writeListHtml(report,{version:VERSION,date:new Date().toISOString(),header:headerOf(repo,io2.now()-started),invocation:INVOCATION,details:flags.details,cwd:resolve7(io2.cwd)===resolve7(repo.root)?void 0:repo.root},flags.html,io2.cwd);if(io2.err(`HTML report: ${path2}
186
+ `),renderMs=io2.now()-renderStart,flags.open&&ui.interactive&&io2.outTty)try{await openHtml(path2)}catch(error){io2.err(`Could not open browser: ${error instanceof Error?error.message:String(error)}. Open the report manually.
187
+ `)}}return flags.verbose&&io2.err(formatListTimings(report,renderMs??io2.now()-renderStart)),report.failures.length||report.unknown?.length?EXIT.error:EXIT.ok})),shared(program2.command("check [packages...]").description("Which of your call sites an upgrade breaks, and what fixing them costs").option("--only <packages>","deprecated alias for positional package names").option("--group <name>","check every member of a group shown by uptide list").option("--target <spec...>","`<package>@<version>`, repeatable; a bare version with one named package (default: latest)").option("--html [path]","write a self-contained HTML report (default: OS temp directory)").option("--open","open the HTML report in your browser (interactive terminals only)").option("--details","every site with its reason, compiler message and analysis notes").option("--all","with --details: also show findings under 50% confidence").option("--verbose","one progress line per analysis phase, with timings").option("--no-compile","skip compiling against the target version").option("--no-runtime","skip loading installed and target copies in a sandboxed Node").option("--all-deps","also analyze @types/* and dependencies the repo never imports").option("--workspaces <n>","maximum concurrent workspaces (also capped by free memory and CPU)").option("--no-remote","accepted for forward compatibility; there is no remote service")).addHelpText("after",`
188
+ What it checks:
189
+ Only the named dependencies. Run uptide list first for fast discovery.
190
+ No names: exits 2 without analysis. Failures are reported per package/workspace.
191
+
192
+ Tiers:
193
+ ${TIER_LEGEND}
194
+
195
+ Examples:
196
+ $ uptide list discover upgrades without compiling
197
+ $ uptide check zod stripe analyze the named packages
198
+ $ uptide check --group nestjs analyze every group member
199
+ $ uptide check zod --target 4.6.5
200
+ $ uptide check zod --details every site and reason
201
+ $ uptide check zod --json --ci > uptide.json
202
+ ${EXIT_CODES("no breaking change reaches your code, in everything that was analyzed","breaking changes found at your call sites",`;
203
+ or nothing breaking was found but a dependency failed to analyze (the report
204
+ still lists the others). A skipped workspace is not a safety verdict.`)}`).action((packages,flags)=>act(flags,async({ui,progress,cwd})=>{if(flags.open&&!flags.html)throw new CliError("--open requires --html");let started=io2.now(),quiet=!flags.verbose,only=[...new Set([...packages,...list(flags.only)??[]])];if(!flags.group&&only.length===0||only.includes("all"))throw new CliError("check requires one or more package names. Start with uptide list.",{next:"uptide list"});if(flags.workspaces&&(!Number.isInteger(Number(flags.workspaces))||Number(flags.workspaces)<1))throw new CliError("--workspaces must be a positive integer");let repo=await progress.phase("Repository",()=>detectRepo(cwd,engine.workspaces),describeRepo);if(flags.group){if(!engine.list)throw new CliError("this build cannot discover groups");let discoverGroup=engine.list,discovery=await progress.phase("Group discovery",()=>discoverGroup({cwd:repo.root})),group=discovery.groups.find(g=>g.id===flags.group||g.name===flags.group);if(!group)throw new CliError(`unknown group '${flags.group}'${discovery.groups.length?`; available: ${discovery.groups.map(g=>g.id).join(", ")}`:""}`,{next:"uptide list"});if(discovery.failures.length)throw new CliError("group discovery is incomplete; run uptide list to resolve its failures before checking a group");only.push(...group.members.map(p=>p.name).filter(name=>!only.includes(name)))}let targets=parseTargets(flags.target,only),htmlReport=async report2=>{if(flags.html){let path2=writeHtml(report2,{root:repo.root,details:flags.details,version:VERSION,date:new Date().toISOString(),header:headerOf(repo,io2.now()-started),invocation:HTML_INVOCATION,repeat:{cwd:resolve7(io2.cwd)===resolve7(repo.root)?void 0:repo.root,only:only.join(","),targets:{...Object.fromEntries(report2.packages.flatMap(p=>p.members??[p]).filter(p=>p.target&&p.installed!==p.target).map(p=>[p.name,p.target])),...targets}},fixable:FIX_MANAGERS.includes(repo.manager)},flags.html,io2.cwd);if(io2.err(`HTML report: ${path2}
205
+ `),flags.open&&ui.interactive&&io2.outTty)try{await openHtml(path2)}catch(error){io2.err(`Could not open browser: ${error instanceof Error?error.message:String(error)}. Open the report manually.
206
+ `)}}};quiet&&!ui.interactive&&io2.err(`uptide check \xB7 ${repoLine(headerOf(repo,0))}
207
+ `),await requireDependencies(repo,only,progress);let report=await progress.phase(only?`Analysis of ${only.join(", ")}`:"Analysis of every dependency that is behind",async()=>{let result=await engine.check({cwd:repo.root,targets,only,compile:flags.compile??!0,runtime:flags.runtime??!0,allDeps:flags.allDeps,...flags.workspaces?{workspaceConcurrency:Number(flags.workspaces)}:{}},progress.event).catch(err=>{let message=err instanceof Error?err.message:String(err);throw isNetworkError(err)?noNetwork(message):err}),offline=networkFailure(result);if(offline)throw offline;return result},r=>`${r.summary.breaking} breaking, ${r.summary.deprecated} deprecated`);telemetry?.record(()=>checkMetrics(report)),timingNotes(report,progress);let ms=io2.now()-started;return quiet&&!ui.interactive&&io2.err(`done in ${elapsed(ms)}
208
+ `),flags.json?emit(report):io2.out(formatCheck(report,{color:ui.color&&io2.outTty,width:io2.columns,details:flags.details,all:flags.all,header:headerOf(repo,ms),invocation:INVOCATION,repeat:{...flags.cwd?{cwd:flags.cwd}:{},only:only.join(","),targets},fixable:FIX_MANAGERS.includes(repo.manager)})),await htmlReport(report),report.summary.breaking>0?EXIT.breaking:report.packages.some(p=>isFailure(p))?EXIT.error:EXIT.ok},{quiet:!flags.verbose})),shared(program2.command("plan").option("--results <file>","JSON from an earlier check; matching package versions only").description("The order to upgrade your dependencies in, with the effort each one takes").option("--only <packages>","comma-separated dependencies to plan (default: every direct dependency that is behind)").option("--html [path]","write the plan as a self-contained HTML page").option("--verbose","one progress line per analysis phase, with timings")).addHelpText("after",`
209
+ What it does:
210
+ Uses list data and optional --results <check.json>. No implicit deep analysis.
211
+ Unchecked packages have unknown effort; run check before fixing them. Peer ranges between your dependencies
212
+ decide what has to come first or move together; a range nothing satisfies is named as
213
+ blocked. Effort is an estimate from the findings, not a promise.
214
+
115
215
  Examples:
116
- $ uptide check zod and stripe against their latest versions
117
- $ uptide check --only zod --target 4.6.5
118
- $ uptide check --details every site and reason
119
- $ uptide check --json --ci > uptide.json
120
- ${EXIT_CODES("no breaking change reaches your code","breaking changes found at your call sites")}`).action(flags=>act(flags,async({ui,progress,cwd})=>{if(flags.open&&!flags.html)throw new CliError("--open requires --html");let started=io.now(),quiet=!flags.verbose,requested=list(flags.only),only=requested?.length===1&&requested[0]==="all"?void 0:requested??[...SUPPORTED],targets=parseTargets(flags.target,only),repo=await progress.phase("Repository",()=>detectRepo(cwd,engine.workspaces),describeRepo),htmlReport=async report2=>{if(flags.html){let path2=writeHtml(report2,{root:repo.root,version:VERSION,date:new Date().toISOString(),header:headerOf(repo,io.now()-started),invocation:HTML_INVOCATION,repeat:{cwd:resolve5(io.cwd)===resolve5(repo.root)?void 0:repo.root,only:flags.only,targets:{...Object.fromEntries(report2.packages.flatMap(p=>p.members??[p]).filter(p=>p.target&&p.installed!==p.target).map(p=>[p.name,p.target])),...targets}},fixable:FIX_MANAGERS.includes(repo.manager)?SUPPORTED:[]},flags.html,io.cwd);if(io.err(`HTML report: ${path2}
121
- `),flags.open&&ui.interactive&&io.outTty)try{await openHtml(path2)}catch(error){io.err(`Could not open browser: ${error instanceof Error?error.message:String(error)}. Open the report manually.
122
- `)}}};if(quiet&&!ui.interactive&&io.err(`uptide check \xB7 ${repoLine(headerOf(repo,0))}
123
- `),only&&(await progress.phase("Dependencies",async()=>{let deps=await locateDependencies(repo,engine,only),absent=deps.filter(d=>d.workspaces.length===0).map(d=>d.name);if(requested&&absent.length>0)throw notADependency(repo,absent);return requireInstalled(repo,deps),deps},deps=>deps.map(d=>d.workspaces.length===0?`${d.name} not declared`:`${d.name} ${d.installed}`).join(", "))).every(d=>d.workspaces.length===0))return flags.json&&emit({repo:repo.root,workspaces:repo.workspaces,packages:[]}),io.err(nothingToCheck(repo,only)),await htmlReport({repo:repo.root,workspaces:repo.workspaces,packages:[],summary:{packagesNeedingAttention:0,breaking:0,deprecated:0,unverified:0,unaffected:0,notImported:0,partiallyAnalyzed:0,autoFixable:0}}),EXIT.ok;let report=await progress.phase(only?`Analysis of ${only.join(", ")}`:"Analysis of every dependency",async()=>{let result=await engine.check({cwd:repo.root,targets,only,compile:flags.compile??!0,runtime:flags.runtime??!0,allDeps:flags.allDeps,workspaceConcurrency:Number(flags.workspaces??2)},progress.event).catch(err=>{let message=err instanceof Error?err.message:String(err);throw isNetworkError(err)?noNetwork(message):err}),offline=networkFailure(result);if(offline)throw offline;return result},r=>`${r.summary.breaking} breaking, ${r.summary.deprecated} deprecated`);timingNotes(report,progress);let ms=io.now()-started;return quiet&&!ui.interactive&&io.err(`done in ${elapsed(ms)}
124
- `),flags.json?emit(report):io.out(formatCheck(report,{color:ui.color,details:flags.details,all:flags.all,header:headerOf(repo,ms),invocation:INVOCATION,repeat:{...flags.cwd?{cwd:flags.cwd}:{},...flags.only?{only:flags.only}:{},targets},fixable:FIX_MANAGERS.includes(repo.manager)?SUPPORTED:[]})),await htmlReport(report),report.summary.breaking>0?EXIT.breaking:EXIT.ok},{quiet:!flags.verbose})),shared(program2.command("fix").description("Upgrade zod or stripe on a new branch and migrate your code, verified").requiredOption("--only <package>","zod or stripe").option("--target <spec>","exact version, optionally `<package>@<version>` (default: latest on npm, as check uses)").option("--include-deprecated","migrate reported deprecated sites too").option("--pin-current-api","stripe only: no upgrade; write the installed SDK's default apiVersion on every client that omits it").option("--no-llm","rule-based fixes only: never send code to the LLM provider").option("--with-services","also run tests that need a database, cache or queue; prints the targets, requires --yes").option("--keep","keep the temporary clone after the run (it is kept anyway when the run fails)").option("--pr","open a draft PR after verification passes; requires --yes").option("--yes","approve what was printed: the publication plan (--pr), the services (--with-services)").option("--verbose","one progress line per phase, with timings")).addHelpText("after",`
216
+ $ uptide plan
217
+ $ uptide plan --only react,react-dom,next
218
+ $ uptide plan --json --ci > plan.json
219
+ ${EXIT_CODES("a plan was made","not used",`;
220
+ or a dependency failed to analyze (the plan still orders the others)`)}`).action(flags=>act(flags,async({ui,progress,cwd})=>{let started=io2.now(),only=list(flags.only),checkResults=flags.results?JSON.parse(readFileSync7(resolve7(io2.cwd,flags.results),"utf8")):void 0,repo=await progress.phase("Repository",()=>detectRepo(cwd,engine.workspaces),describeRepo);if(!flags.verbose&&!ui.interactive&&io2.err(`uptide plan \xB7 ${repoLine(headerOf(repo,0))}
221
+ `),!engine.plan)throw new CliError("this build cannot plan upgrades");let plan=engine.plan,result=await progress.phase(only?`Plan for ${only.join(", ")}`:"Plan for every dependency that is behind",async()=>{let planned=await plan({cwd:repo.root,only,checkResults},progress.event).catch(err=>{let message=err instanceof Error?err.message:String(err);throw isNetworkError(err)?noNetwork(message):err}),offline=networkFailure(planned.report);if(offline)throw offline;return planned},r=>`${r.plan.steps.length} steps`),ms=io2.now()-started;!flags.verbose&&!ui.interactive&&io2.err(`done in ${elapsed(ms)}
222
+ `),telemetry?.record(()=>{let metrics=checkMetrics(result.report);return{...metrics,counts:{...metrics.counts,steps:result.plan.steps.length}}});let fixable=FIX_MANAGERS.includes(repo.manager),planOptions={header:headerOf(repo,ms),invocation:INVOCATION,fixable,...flags.cwd?{cwd:flags.cwd}:{}};if(flags.json?emit(result.plan):io2.out(formatPlan(result.plan,{color:ui.color,...planOptions})),flags.html){let path2=writePlanHtml(result.plan,{...planOptions,version:VERSION,date:new Date(io2.now()).toISOString()},flags.html,io2.cwd);io2.err(`HTML plan: ${path2}
223
+ `)}return result.report.packages.some(p=>isFailure(p))?EXIT.error:EXIT.ok},{quiet:!flags.verbose})),shared(program2.command("fix [package]").allowExcessArguments(!1).description("Upgrade one dependency on a new branch and migrate your code, verified").option("--only <package>","the dependency to upgrade: zod or stripe (verified), or any other (generic, agent only)").option("--target <spec>","exact version, optionally `<package>@<version>` (default: latest on npm, as check uses)").option("--include-deprecated","migrate reported deprecated sites too").option("--pin-current-api","stripe only: no upgrade; write the installed SDK's default apiVersion on every client that omits it").option("--provider <name>","LLM provider: anthropic, openai or gemini (also UPTIDE_PROVIDER)").option("--model <id>","LLM model ID (also UPTIDE_MODEL)").option("--no-llm","rule-based fixes only: never send code to the LLM provider").option("--max-cost <usd>","reserve the worst-case cost before each LLM call, including retries (default: 1 USD for every package)").option("--with-services","also run tests that need a database, cache or queue; prints the targets, requires --yes").option("--keep","keep the temporary clone after the run (it is kept anyway when the run fails)").option("--pr","open a draft PR after verification passes; requires --yes").option("--base <branch>","with --pr: the branch on origin the PR is opened against (default: its default branch)").option("--allow-dirty","with --pr: proceed although the working tree has uncommitted changes; they are left out").option("--yes","approve what was printed: the publication plan (--pr), the services (--with-services)").option("--verbose","one progress line per phase, with timings")).addHelpText("after",`
125
224
  What it does:
126
- Works in a temporary clone of your repository, never in your checkout: your branch, files,
127
- git hooks and git config stay as they are. Install, build and test commands run with
225
+ Works in a temporary clone of your local repository at the commit you have checked out, never
226
+ in your checkout: your branch, files, git hooks and git config stay as they are. Uncommitted
227
+ changes are left out and listed. With --pr, the base branch on origin must already contain
228
+ that commit, so the PR holds the migration and nothing else. Install, build and test commands run with
128
229
  lifecycle scripts and git hooks disabled.
129
230
  Runs check, creates branch uptide/<package>-<version>, bumps the version and lockfile,
130
- applies rule-based fixes, then (with ANTHROPIC_API_KEY, unless --no-llm) assisted fixes
231
+ applies rule-based fixes, then (with the selected provider's API key, unless --no-llm) assisted fixes
131
232
  for the remaining sites, and verifies with your TypeScript and your test scripts.
132
233
  Nothing is pushed without --pr --yes.
133
234
 
235
+ Tiers:
236
+ ${TIER_LEGEND}
237
+ A generic package has no rules: every fix comes from the agent, under the same checks (an
238
+ edit is kept only if the site's compiler error disappears and no new one appears) and the
239
+ same publish gate. It needs ANTHROPIC_API_KEY, OPENAI_API_KEY or GEMINI_API_KEY; --max-cost defaults to $1.
240
+
134
241
  Examples:
135
- $ uptide fix --only zod
136
- $ uptide fix --only stripe --target 22.6.2
137
- $ uptide fix --only stripe --pin-current-api the small PR: same SDK, apiVersion made explicit
138
- $ uptide fix --only zod --no-llm no code leaves this machine
242
+ $ uptide fix zod
243
+ $ uptide fix express --max-cost 2 a generic package, with a budget for the agent
244
+ $ uptide fix stripe --target 22.6.2
245
+ $ uptide fix stripe --pin-current-api the small PR: same SDK, apiVersion made explicit
246
+ $ uptide fix zod --no-llm no code leaves this machine
139
247
  ${EXIT_CODES("migration verified: no new type errors, tests pass","verification failed or sites remain for manual work")}
140
- ${PRIVACY}`).action(flags=>act(flags,async({ui,progress,cwd})=>{let started=io.now(),quiet=!flags.verbose,only=flags.only;if(only!=="zod"&&only!=="stripe")throw new CliError(`--only ${only}: fix supports zod and stripe`,{next:"uptide fix --only zod"});if(flags.pinCurrentApi&&only!=="stripe")throw new CliError("--pin-current-api applies to stripe only",{next:"uptide fix --only stripe --pin-current-api"});if(flags.pinCurrentApi&&flags.target)throw new CliError("--pin-current-api keeps the installed version; drop --target",{next:"uptide fix --only stripe --pin-current-api"});flags.target&&parseTargets([flags.target],[only]),flags.pr&&!flags.yes&&io.err(`--pr without --yes: the publication plan is printed, nothing is pushed.
141
- `);let repo=await progress.phase("Repository",async()=>{let found=await detectRepo(cwd,engine.workspaces);requireFixable(found,only);let deps=await locateDependencies(found,engine,[only]);if(deps.every(d=>d.workspaces.length===0))throw notADependency(found,[only]);return requireInstalled(found,deps),found},describeRepo);if(quiet&&!ui.interactive&&io.err(`uptide fix \xB7 ${only} \xB7 ${repoLine(headerOf(repo,0))}
142
- `),flags.pr&&engine.publishTarget){let target=await engine.publishTarget(repo.root);io.err(`PR will be opened on ${target.nameWithOwner} (base ${target.base})${target.parent?`, a fork of ${target.parent}; use \`uptide pr --repo ${target.parent}\` afterwards to open it there`:""}
143
- `)}let llm=flags.llm!==!1&&!flags.pinCurrentApi;flags.pinCurrentApi?io.err(`pin run: the SDK stays, apiVersion is written on each client; no code leaves this machine
144
- `):llm?io.err(io.env.ANTHROPIC_API_KEY?ASSISTED_NOTE:noApiKeyNote(only)):io.err(`assisted fixes off (--no-llm): no code leaves this machine
145
- `);let report=await progress.phase(flags.pinCurrentApi?"Pin of the Stripe API version (scan, edits, verification)":`Migration of ${only} (check, upgrade, fixes, verification)`,()=>engine.fix({cwd:repo.root,only,target:flags.target,includeDeprecated:flags.includeDeprecated,...flags.pinCurrentApi?{pinCurrentApi:!0}:{},llm,withServices:flags.withServices,...flags.keep?{keep:!0}:{},pr:flags.pr,yes:flags.yes},progress.event),r=>`verification ${r.verification.passed?"passed":"failed"}`);quiet&&!ui.interactive&&io.err(`done in ${elapsed(io.now()-started)}
146
- `);try{report.html=writeMigrationHtml(report,{version:VERSION,date:new Date(io.now()).toISOString()})}catch{}return flags.json?emit(report):io.out(`
147
- ${formatFixSummary(report,{color:ui.color,invocation:INVOCATION,cwd,ms:io.now()-started})}`),io.err(whereItRan(report)),report.publicationLog&&!flags.json&&io.err(`
248
+ ${PRIVACY}`).action((packageName,flags)=>act(flags,async({ui,progress,cwd})=>{let started=io2.now(),quiet=!flags.verbose;if(packageName&&flags.only&&packageName!==flags.only)throw new CliError("choose one package for fix");let only=packageName??flags.only;if(!only)throw new CliError("fix requires a package name. Start with uptide list.",{next:"uptide list"});if(only.includes(","))throw new CliError(`--only ${only}: fix upgrades one dependency at a time`,{next:`uptide fix ${only.split(",")[0]}`});let maxCost=flags.maxCost!==void 0?Number(flags.maxCost):1,selection=selectLlm(cwd,flags,io2.env);if(maxCost!==void 0&&(!Number.isFinite(maxCost)||maxCost<=0))throw new CliError(`--max-cost ${flags.maxCost}: expected an amount in USD`,{next:`uptide fix ${only} --max-cost 2`});let hasPack=SUPPORTED.includes(only);if(!hasPack&&(flags.llm===!1||!selection.available))throw noAgentForGeneric(only,flags.llm===!1);if(flags.pinCurrentApi&&only!=="stripe")throw new CliError("--pin-current-api applies to stripe only",{next:"uptide fix stripe --pin-current-api"});if(flags.pinCurrentApi&&flags.target)throw new CliError("--pin-current-api keeps the installed version; drop --target",{next:"uptide fix stripe --pin-current-api"});flags.target&&parseTargets([flags.target],[only]),flags.pr&&!flags.yes&&io2.err(`--pr without --yes: the publication plan is printed, nothing is pushed.
249
+ `);let repo=await progress.phase("Repository",async()=>{let found=await detectRepo(cwd,engine.workspaces);requireFixable(found,only);let deps=await locateDependencies(found,engine,[only]);if(deps.every(d=>d.workspaces.length===0))throw notADependency(found,[only]);return requireInstalled(found,deps),found},describeRepo);quiet&&!ui.interactive&&io2.err(`uptide fix \xB7 ${only} \xB7 ${repoLine(headerOf(repo,0))}
250
+ `);let preflightShown=engine.preflight!==void 0;if(engine.preflight){let notes;try{({notes}=engine.preflight(repo.root,{...flags.pr?{pr:!0}:{},...flags.base?{base:flags.base}:{},...flags.allowDirty?{allowDirty:!0}:{}}))}catch(error){throw new CliError(explain(error),{exitCode:EXIT.breaking})}for(let note of notes)io2.err(`${note}
251
+ `)}if(flags.pr&&engine.publishTarget){let target=await engine.publishTarget(repo.root);io2.err(`PR will be opened on ${target.nameWithOwner} (base ${flags.base??target.base})${target.parent?`, a fork of ${target.parent}; use \`uptide pr --repo ${target.parent}\` afterwards to open it there`:""}
252
+ `)}let llm=flags.llm!==!1&&!flags.pinCurrentApi;flags.pinCurrentApi?io2.err(`pin run: the SDK stays, apiVersion is written on each client; no code leaves this machine
253
+ `):llm?selection.available?(io2.err(`LLM: ${selection.provider} / ${selection.model} \xB7 budget $${maxCost.toFixed(2)}
254
+ `),io2.err(assistedNote(selection.provider)),priceFor(selection.provider,selection.model).fallback&&io2.err(`Unknown model pricing: using ${selection.provider}'s highest listed rates (${PRICE_DATE}) for cost and budget.
255
+ `),selection.baseUrl&&io2.err(`OPENAI_BASE_URL override: compatible, not verified; endpoint pricing may differ.
256
+ `)):io2.err(noApiKeyNote(only)):io2.err(`assisted fixes off (--no-llm): no code leaves this machine
257
+ `),hasPack||io2.err(`${only} has no migration pack (generic tier): every fix comes from the agent, up to $${(maxCost??1).toFixed(2)} (--max-cost)
258
+ `),fixEngineStarted=!0;let report=await progress.phase(flags.pinCurrentApi?"Pin of the Stripe API version (scan, edits, verification)":`Migration of ${only} (check, upgrade, fixes, verification)`,()=>engine.fix({cwd:repo.root,only,target:flags.target,includeDeprecated:flags.includeDeprecated,...flags.pinCurrentApi?{pinCurrentApi:!0}:{},llm,provider:selection.provider,model:selection.model,...maxCost!==void 0?{maxCostUsd:maxCost}:{},withServices:flags.withServices,...flags.keep?{keep:!0}:{},pr:flags.pr,...flags.base?{base:flags.base}:{},...flags.allowDirty?{allowDirty:!0}:{},...preflightShown?{preflightShown:!0}:{},yes:flags.yes},progress.event),r=>`verification ${r.verification.passed?"passed":"failed"}`);quiet&&!ui.interactive&&io2.err(`done in ${elapsed(io2.now()-started)}
259
+ `),fixSpend=report.llm,telemetry?.record(()=>fixMetrics(report,repo.root));try{report.html=writeMigrationHtml(report,{version:VERSION,date:new Date(io2.now()).toISOString()})}catch{}return flags.json?emit(report):io2.out(`
260
+ ${formatFixSummary(report,{color:ui.color,invocation:INVOCATION,cwd,ms:io2.now()-started})}`),io2.err(whereItRan(report)),report.publicationLog&&!flags.json&&io2.err(`
148
261
  ${report.publicationLog}
149
- `),report.publication?.refused.length&&io.err(`PR not opened: ${report.publication.refused.join("; ")}.
262
+ `),report.publication?.refused.length&&io2.err(`PR not opened: ${report.publication.refused.join("; ")}.
150
263
  Branch ${report.branch} stays local; nothing was pushed.
151
- `),report.publication?.failed?(io.err(`PR not opened: ${report.publication.failed}
264
+ `),report.publication?.failed?(io2.err(`PR not opened: ${report.publication.failed}
152
265
  The verified run is in your repository. Retry the publish step alone:
153
266
  ${INVOCATION} pr --branch ${report.branch} --yes
154
267
  `),EXIT.error):report.verification.passed?EXIT.ok:EXIT.breaking},{quiet:!flags.verbose})),shared(program2.command("verify").description("Verify the checked-out migration branch again and refresh its stored run").option("--with-services","also run tests that need a database, cache or queue; prints the targets, requires --yes").option("--branch <name>","the migration branch (default: the branch checked out)").option("--push","push the new commits to origin, fast-forward only; requires --yes").option("--keep","keep the temporary clone after the run (it is kept anyway when the run fails)").option("--yes","confirm what was printed: the services (--with-services), the push (--push)")).addHelpText("after",`
@@ -162,13 +275,13 @@ What it does:
162
275
 
163
276
  Examples:
164
277
  $ git switch uptide/zod-4.6.5 && uptide verify
165
- ${EXIT_CODES("the branch verifies: no new type errors, tests and lint pass","verification failed")}`).action(flags=>act(flags,async({progress,cwd})=>{if(!engine.verify)throw new CliError("verify is not available in this build of uptide");let verify=engine.verify,report=await progress.phase("Verification of the migration branch",()=>verify({cwd,...flags.branch?{branch:flags.branch}:{},...flags.withServices?{withServices:!0}:{},...flags.push?{push:!0}:{},...flags.keep?{keep:!0}:{},...flags.yes?{yes:!0}:{}},progress.event),r=>`verification ${r.verification.passed?"passed":"failed"} at ${r.head?.slice(0,8)}`);return flags.json?emit(report):io.out(`
166
- ${formatFix(report)}`),io.err(whereItRan(report)),report.verification.passed?EXIT.ok:EXIT.breaking})),shared(program2.command("clean").description("Remove temporary clones that fix and verify kept, older than 7 days").option("--days <n>","age in days after which a kept clone is removed","7")).addHelpText("after",`
278
+ ${EXIT_CODES("the branch verifies: no new type errors, tests and lint pass","verification failed")}`).action(flags=>act(flags,async({progress,cwd})=>{if(!engine.verify)throw new CliError("verify is not available in this build of uptide");let verify=engine.verify,report=await progress.phase("Verification of the migration branch",()=>verify({cwd,...flags.branch?{branch:flags.branch}:{},...flags.withServices?{withServices:!0}:{},...flags.push?{push:!0}:{},...flags.keep?{keep:!0}:{},...flags.yes?{yes:!0}:{}},progress.event),r=>`verification ${r.verification.passed?"passed":"failed"} at ${r.head?.slice(0,8)}`);return flags.json?emit(report):io2.out(`
279
+ ${formatFix(report)}`),telemetry?.record(()=>fixMetrics(report,cwd)),io2.err(whereItRan(report)),report.verification.passed?EXIT.ok:EXIT.breaking})),shared(program2.command("clean").description("Remove temporary clones that fix and verify kept, older than 7 days").option("--days <n>","age in days after which a kept clone is removed","7")).addHelpText("after",`
167
280
  A clone is kept when its run failed, when --keep was passed, or when it holds commits that are
168
281
  nowhere else. Only directories uptide created under its own temporary root are ever removed.
169
- ${EXIT_CODES("done","not used")}`).action(flags=>act(flags,async()=>{if(!engine.clean)throw new CliError("clean is not available in this build of uptide");let days=Number(flags.days??7);if(!Number.isFinite(days)||days<0)throw new CliError(`--days ${flags.days}: expected a number of days`,{next:"uptide clean --days 7"});let result=engine.clean(days);if(flags.json)emit(result);else{for(let path2 of result.removed)io.out(`removed ${path2}
170
- `);io.out(`${result.removed.length} temporary clone${result.removed.length===1?"":"s"} removed, ${result.kept.length} newer than ${days} day${days===1?"":"s"} kept.
171
- `);for(let path2 of result.kept)io.out(` kept ${path2}
282
+ ${EXIT_CODES("done","not used")}`).action(flags=>act(flags,async()=>{if(!engine.clean)throw new CliError("clean is not available in this build of uptide");let days=Number(flags.days??7);if(!Number.isFinite(days)||days<0)throw new CliError(`--days ${flags.days}: expected a number of days`,{next:"uptide clean --days 7"});let result=engine.clean(days);if(telemetry?.record(()=>({counts:{removed:result.removed.length,kept:result.kept.length}})),flags.json)emit(result);else{for(let path2 of result.removed)io2.out(`removed ${path2}
283
+ `);io2.out(`${result.removed.length} temporary clone${result.removed.length===1?"":"s"} removed, ${result.kept.length} newer than ${days} day${days===1?"":"s"} kept.
284
+ `);for(let path2 of result.kept)io2.out(` kept ${path2}
172
285
  `)}return EXIT.ok})),shared(program2.command("pr").description("Push a finished migration branch and open its pull request with the stored report").option("--branch <name>","the migration branch (default: the one checked out)").option("--repo <owner/name>","where to open the PR (default: the repository origin points at, a fork included)").option("--draft","open it as a draft").option("--yes","approve the printed plan: push the branch and open the PR")).addHelpText("after",`
173
286
  What it does:
174
287
  Loads the stored run for the branch (from .git, written by fix or verify), checks that the
@@ -179,12 +292,15 @@ What it does:
179
292
  Examples:
180
293
  $ uptide pr --branch uptide/stripe-23.0.0 the plan, nothing pushed
181
294
  $ uptide pr --branch uptide/stripe-23.0.0 --yes push and open the PR
182
- ${EXIT_CODES("PR opened (or plan printed without --yes)","not used")}`).action(flags=>act(flags,async({cwd})=>{if(!engine.pr)throw new CliError("pr is not available in this build of uptide");try{let{url}=await engine.pr({cwd,branch:flags.branch,repo:flags.repo,draft:flags.draft===!0,yes:flags.yes},text=>io.err(`${text}
183
- `));return flags.json?emit({url}):io.out(`${url}
184
- `),EXIT.ok}catch(err){if(err instanceof Error&&/requires --yes/.test(err.message))return io.err(`Nothing pushed. Add --yes to push the branch and open the PR.
295
+ ${EXIT_CODES("PR opened (or plan printed without --yes)","not used")}`).action(flags=>act(flags,async({cwd})=>{if(!engine.pr)throw new CliError("pr is not available in this build of uptide");try{let{url,report}=await engine.pr({cwd,branch:flags.branch,repo:flags.repo,draft:flags.draft===!0,yes:flags.yes},text=>io2.err(`${text}
296
+ `));return telemetry?.record(()=>fixMetrics(report,cwd)),flags.json?emit({url}):io2.out(`${url}
297
+ `),EXIT.ok}catch(err){if(err instanceof Error&&/requires --yes/.test(err.message))return io2.err(`Nothing pushed. Add --yes to push the branch and open the PR.
185
298
  `),EXIT.ok;throw err}})),shared(program2.command("pr-body").description("Render a stored migration run and update only a PR description (no push)").requiredOption("--pr <number>","pull request number").option("--run <file>","stored FixReport JSON (default: .uptide/report.json)").option("--preview","print the proposed body without updating GitHub")).addHelpText("after",`
186
299
  Examples:
187
300
  $ uptide pr-body --pr 82 --preview review the proposal first
188
301
  $ uptide pr-body --pr 82 update only the description
189
- ${EXIT_CODES("description rendered (and updated unless --preview)","not used")}`).action(flags=>act(flags,async({cwd})=>{if(!engine.updatePrBody)throw new CliError("pr-body is not available in this build of uptide");let result=await engine.updatePrBody({pr:flags.pr,cwd,run:flags.run,preview:flags.preview});return flags.json?emit(result):(io.out(result.body),io.err(`${result.updated?"Updated description:":"Preview only; PR unchanged:"} ${result.url}
190
- `)),EXIT.ok})),program2.command("diff").description("Diff the public API of an npm package between two versions").argument("<package>","npm package name").argument("<from>","version A (exact version or dist-tag)").argument("<to>","version B (exact version or dist-tag)").option("--json","print the full Change[] as JSON").option("--all","also show protected/@internal symbols, alias duplicates and members of removed symbols").option("--ci","plain output for logs: no color, no spinner").option("--no-color","no color (NO_COLOR is respected too)").action((name,from,to,flags)=>act(flags,async({ui,progress})=>{let changes=await progress.phase(`Diff of ${name} ${from} \u2192 ${to}`,()=>engine.diff(name,from,to),c=>`${c.length} changes`);return flags.json?emit(changes):io.out(formatHuman(changes,{all:flags.all,color:ui.color})),EXIT.ok}));try{await program2.parseAsync(argv,{from:"user"})}catch(err){if(!(err instanceof CommanderError))throw err;return err.exitCode===0?EXIT.ok:EXIT.error}return code}run(process.argv.slice(2),processIo()).then(code=>{process.exitCode=code},err=>{process.stderr.write(renderError(err,!1)),process.exitCode=2});
302
+ ${EXIT_CODES("description rendered (and updated unless --preview)","not used")}`).action(flags=>act(flags,async({cwd})=>{if(!engine.updatePrBody)throw new CliError("pr-body is not available in this build of uptide");let result=await engine.updatePrBody({pr:flags.pr,cwd,run:flags.run,preview:flags.preview});return flags.json?emit(result):(io2.out(result.body),io2.err(`${result.updated?"Updated description:":"Preview only; PR unchanged:"} ${result.url}
303
+ `)),EXIT.ok})),program2.command("diff").description("Diff the public API of an npm package between two versions").argument("<package>","npm package name").argument("<from>","version A (exact version or dist-tag)").argument("<to>","version B (exact version or dist-tag)").option("--json","print the full Change[] as JSON").option("--all","also show protected/@internal symbols, alias duplicates and members of removed symbols").option("--ci","plain output for logs: no color, no spinner").option("--no-color","no color (NO_COLOR is respected too)").action((name,from,to,flags)=>act(flags,async({ui,progress})=>{let changes=await progress.phase(`Diff of ${name} ${from} \u2192 ${to}`,()=>engine.diff(name,from,to),c=>`${c.length} changes`);return telemetry?.record(()=>({packages:[{name,versions:[changes[0]?.from??from,changes[0]?.to??to]}],counts:{changes:changes.length}})),flags.json?emit(changes):io2.out(formatHuman(changes,{all:flags.all,color:ui.color})),EXIT.ok}));try{await program2.parseAsync(argv,{from:"user"})}catch(err){if(!(err instanceof CommanderError))throw err;return err.exitCode===0?EXIT.ok:EXIT.error}return fixing&&io2.err(fixSpend&&(fixSpend.costUsd||fixSpend.unreportedCostUsd||fixSpend.inputTokens||fixSpend.outputTokens)?`LLM spend: $${fixSpend.costUsd.toFixed(2)}${fixSpend.unreportedCostUsd?`; up to $${fixSpend.unreportedCostUsd.toFixed(2)} reserved for calls without usage`:""}
304
+ `:fixEngineStarted&&!fixSpend?`LLM spend: unavailable (the run ended before returning a usage report).
305
+ `:`LLM spend: no LLM calls.
306
+ `),telemetry?.finish(code),code}var io=processIo();run(process.argv.slice(2),io,void 0,createTelemetry(io,{version:VERSION})).then(code=>{process.exitCode=code},err=>{process.stderr.write(renderError(err,!1)),process.exitCode=2});