@meirblachman/pr-review-needed 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +8 -30
  2. package/dist/index.min.js +55 -55
  3. package/package.json +49 -49
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # PR Review Needed
2
2
 
3
3
  [![CI](https://github.com/meir017/ado-pr-review-needed/actions/workflows/ci.yml/badge.svg)](https://github.com/meir017/ado-pr-review-needed/actions/workflows/ci.yml)
4
- [![GitHub npm package](https://img.shields.io/github/package-json/v/meir017/ado-pr-review-needed)](https://github.com/meir017/ado-pr-review-needed/pkgs/npm/pr-review-needed)
4
+ [![npm](https://img.shields.io/npm/v/@meirblachman/pr-review-needed)](https://www.npmjs.com/package/@meirblachman/pr-review-needed)
5
5
 
6
6
  A TypeScript CLI tool that queries Azure DevOps for open pull requests and generates a markdown summary of PRs needing reviewer feedback — inspired by [dotnet/aspire#13834](https://github.com/dotnet/aspire/issues/13834).
7
7
 
@@ -20,45 +20,23 @@ A PR is considered **"needing review"** when:
20
20
 
21
21
  ## Prerequisites
22
22
 
23
- - **Node.js 18+**
23
+ - **Node.js 24+**
24
24
  - **Azure CLI** — logged in via `az login`
25
25
  - Access to the target Azure DevOps organization
26
26
  - (Optional) **Microsoft Graph** access — for resolving team members from org hierarchy
27
27
 
28
28
  ## Installation
29
29
 
30
- ### Quick One-Liner
31
-
32
30
  ```bash
33
- npm install -g @meir017/pr-review-needed --registry=https://npm.pkg.github.com
31
+ npm install -g @meirblachman/pr-review-needed
34
32
  ```
35
33
 
36
- ### From GitHub Packages
37
-
38
- 1. Create or edit an `.npmrc` file in your project (or home directory) to point the `@meir017` scope at the GitHub registry:
39
-
40
- ```
41
- @meir017:registry=https://npm.pkg.github.com
42
- ```
43
-
44
- 2. Authenticate with the GitHub npm registry (you need a [personal access token](https://github.com/settings/tokens) with `read:packages` scope):
45
-
46
- ```bash
47
- npm login --registry=https://npm.pkg.github.com
48
- ```
49
-
50
- 3. Install the package:
34
+ Then run the CLI:
51
35
 
52
- ```bash
53
- npm install -g @meir017/pr-review-needed
54
- ```
55
-
56
- 4. Run the CLI:
57
-
58
- ```bash
59
- pr-review-needed setup
60
- pr-review-needed run
61
- ```
36
+ ```bash
37
+ pr-review-needed setup
38
+ pr-review-needed run
39
+ ```
62
40
 
63
41
  ### From Source
64
42
 
package/dist/index.min.js CHANGED
@@ -1,63 +1,63 @@
1
1
  #!/usr/bin/env node
2
- var $n=Object.create;var rt=Object.defineProperty;var yn=Object.getOwnPropertyDescriptor;var bn=Object.getOwnPropertyNames;var _n=Object.getPrototypeOf,Cn=Object.prototype.hasOwnProperty;var z=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});var G=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports);var vn=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of bn(e))!Cn.call(i,r)&&r!==t&&rt(i,r,{get:()=>e[r],enumerable:!(n=yn(e,r))||n.enumerable});return i};var An=(i,e,t)=>(t=i!=null?$n(_n(i)):{},vn(e||!i||!i.__esModule?rt(t,"default",{value:i,enumerable:!0}):t,i));var J=G(ve=>{var Q=class extends Error{constructor(e,t,n){super(n),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}},Ce=class extends Q{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};ve.CommanderError=Q;ve.InvalidArgumentError=Ce});var ee=G(Oe=>{var{InvalidArgumentError:On}=J(),Ae=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e;break}this._name.endsWith("...")&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_collectValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:(t.push(e),t)}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,n)=>{if(!this.argChoices.includes(t))throw new On(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(t,n):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function Rn(i){let e=i.name()+(i.variadic===!0?"...":"");return i.required?"<"+e+">":"["+e+"]"}Oe.Argument=Ae;Oe.humanReadableArgName=Rn});var xe=G(Se=>{var{humanReadableArgName:Sn}=ee(),Re=class{constructor(){this.helpWidth=void 0,this.minWidthToWrap=40,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}prepareContext(e){this.helpWidth=this.helpWidth??e.helpWidth??80}visibleCommands(e){let t=e.commands.filter(r=>!r._hidden),n=e._getHelpCommand();return n&&!n._hidden&&t.push(n),this.sortSubcommands&&t.sort((r,s)=>r.name().localeCompare(s.name())),t}compareOptions(e,t){let n=r=>r.short?r.short.replace(/^-/,""):r.long.replace(/^--/,"");return n(e).localeCompare(n(t))}visibleOptions(e){let t=e.options.filter(r=>!r.hidden),n=e._getHelpOption();if(n&&!n.hidden){let r=n.short&&e._findOption(n.short),s=n.long&&e._findOption(n.long);!r&&!s?t.push(n):n.long&&!s?t.push(e.createOption(n.long,n.description)):n.short&&!r&&t.push(e.createOption(n.short,n.description))}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];let t=[];for(let n=e.parent;n;n=n.parent){let r=n.options.filter(s=>!s.hidden);t.push(...r)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(t=>t.description)?e.registeredArguments:[]}subcommandTerm(e){let t=e.registeredArguments.map(n=>Sn(n)).join(" ");return e._name+(e._aliases[0]?"|"+e._aliases[0]:"")+(e.options.length?" [options]":"")+(t?" "+t:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleSubcommandTerm(t.subcommandTerm(r)))),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleOptionTerm(t.optionTerm(r)))),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleOptionTerm(t.optionTerm(r)))),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleArgumentTerm(t.argumentTerm(r)))),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let n="";for(let r=e.parent;r;r=r.parent)n=r.name()+" "+n;return n+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&(e.required||e.optional||e.isBoolean()&&typeof e.defaultValue=="boolean")&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),e.presetArg!==void 0&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),e.envVar!==void 0&&t.push(`env: ${e.envVar}`),t.length>0){let n=`(${t.join(", ")})`;return e.description?`${e.description} ${n}`:n}return e.description}argumentDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){let n=`(${t.join(", ")})`;return e.description?`${e.description} ${n}`:n}return e.description}formatItemList(e,t,n){return t.length===0?[]:[n.styleTitle(e),...t,""]}groupItems(e,t,n){let r=new Map;return e.forEach(s=>{let o=n(s);r.has(o)||r.set(o,[])}),t.forEach(s=>{let o=n(s);r.has(o)||r.set(o,[]),r.get(o).push(s)}),r}formatHelp(e,t){let n=t.padWidth(e,t),r=t.helpWidth??80;function s(d,c){return t.formatItem(d,n,c,t)}let o=[`${t.styleTitle("Usage:")} ${t.styleUsage(t.commandUsage(e))}`,""],l=t.commandDescription(e);l.length>0&&(o=o.concat([t.boxWrap(t.styleCommandDescription(l),r),""]));let h=t.visibleArguments(e).map(d=>s(t.styleArgumentTerm(t.argumentTerm(d)),t.styleArgumentDescription(t.argumentDescription(d))));if(o=o.concat(this.formatItemList("Arguments:",h,t)),this.groupItems(e.options,t.visibleOptions(e),d=>d.helpGroupHeading??"Options:").forEach((d,c)=>{let m=d.map(f=>s(t.styleOptionTerm(t.optionTerm(f)),t.styleOptionDescription(t.optionDescription(f))));o=o.concat(this.formatItemList(c,m,t))}),t.showGlobalOptions){let d=t.visibleGlobalOptions(e).map(c=>s(t.styleOptionTerm(t.optionTerm(c)),t.styleOptionDescription(t.optionDescription(c))));o=o.concat(this.formatItemList("Global Options:",d,t))}return this.groupItems(e.commands,t.visibleCommands(e),d=>d.helpGroup()||"Commands:").forEach((d,c)=>{let m=d.map(f=>s(t.styleSubcommandTerm(t.subcommandTerm(f)),t.styleSubcommandDescription(t.subcommandDescription(f))));o=o.concat(this.formatItemList(c,m,t))}),o.join(`
3
- `)}displayWidth(e){return st(e).length}styleTitle(e){return e}styleUsage(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t==="[command]"?this.styleSubcommandText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleCommandText(t)).join(" ")}styleCommandDescription(e){return this.styleDescriptionText(e)}styleOptionDescription(e){return this.styleDescriptionText(e)}styleSubcommandDescription(e){return this.styleDescriptionText(e)}styleArgumentDescription(e){return this.styleDescriptionText(e)}styleDescriptionText(e){return e}styleOptionTerm(e){return this.styleOptionText(e)}styleSubcommandTerm(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleSubcommandText(t)).join(" ")}styleArgumentTerm(e){return this.styleArgumentText(e)}styleOptionText(e){return e}styleArgumentText(e){return e}styleSubcommandText(e){return e}styleCommandText(e){return e}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}preformatted(e){return/\n[^\S\r\n]/.test(e)}formatItem(e,t,n,r){let o=" ".repeat(2);if(!n)return o+e;let l=e.padEnd(t+e.length-r.displayWidth(e)),h=2,u=(this.helpWidth??80)-t-h-2,d;return u<this.minWidthToWrap||r.preformatted(n)?d=n:d=r.boxWrap(n,u).replace(/\n/g,`
2
+ var yn=Object.create;var rt=Object.defineProperty;var bn=Object.getOwnPropertyDescriptor;var _n=Object.getOwnPropertyNames;var Cn=Object.getPrototypeOf,vn=Object.prototype.hasOwnProperty;var Y=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});var W=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports);var An=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of _n(e))!vn.call(i,r)&&r!==t&&rt(i,r,{get:()=>e[r],enumerable:!(n=bn(e,r))||n.enumerable});return i};var Sn=(i,e,t)=>(t=i!=null?yn(Cn(i)):{},An(e||!i||!i.__esModule?rt(t,"default",{value:i,enumerable:!0}):t,i));var K=W(ve=>{var te=class extends Error{constructor(e,t,n){super(n),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}},Ce=class extends te{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}};ve.CommanderError=te;ve.InvalidArgumentError=Ce});var ne=W(Se=>{var{InvalidArgumentError:On}=K(),Ae=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e;break}this._name.endsWith("...")&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_collectValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:(t.push(e),t)}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,n)=>{if(!this.argChoices.includes(t))throw new On(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(t,n):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}};function Rn(i){let e=i.name()+(i.variadic===!0?"...":"");return i.required?"<"+e+">":"["+e+"]"}Se.Argument=Ae;Se.humanReadableArgName=Rn});var xe=W(Re=>{var{humanReadableArgName:xn}=ne(),Oe=class{constructor(){this.helpWidth=void 0,this.minWidthToWrap=40,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}prepareContext(e){this.helpWidth=this.helpWidth??e.helpWidth??80}visibleCommands(e){let t=e.commands.filter(r=>!r._hidden),n=e._getHelpCommand();return n&&!n._hidden&&t.push(n),this.sortSubcommands&&t.sort((r,s)=>r.name().localeCompare(s.name())),t}compareOptions(e,t){let n=r=>r.short?r.short.replace(/^-/,""):r.long.replace(/^--/,"");return n(e).localeCompare(n(t))}visibleOptions(e){let t=e.options.filter(r=>!r.hidden),n=e._getHelpOption();if(n&&!n.hidden){let r=n.short&&e._findOption(n.short),s=n.long&&e._findOption(n.long);!r&&!s?t.push(n):n.long&&!s?t.push(e.createOption(n.long,n.description)):n.short&&!r&&t.push(e.createOption(n.short,n.description))}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];let t=[];for(let n=e.parent;n;n=n.parent){let r=n.options.filter(s=>!s.hidden);t.push(...r)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(t=>t.description)?e.registeredArguments:[]}subcommandTerm(e){let t=e.registeredArguments.map(n=>xn(n)).join(" ");return e._name+(e._aliases[0]?"|"+e._aliases[0]:"")+(e.options.length?" [options]":"")+(t?" "+t:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleSubcommandTerm(t.subcommandTerm(r)))),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleOptionTerm(t.optionTerm(r)))),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleOptionTerm(t.optionTerm(r)))),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((n,r)=>Math.max(n,this.displayWidth(t.styleArgumentTerm(t.argumentTerm(r)))),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let n="";for(let r=e.parent;r;r=r.parent)n=r.name()+" "+n;return n+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&(e.required||e.optional||e.isBoolean()&&typeof e.defaultValue=="boolean")&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),e.presetArg!==void 0&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),e.envVar!==void 0&&t.push(`env: ${e.envVar}`),t.length>0){let n=`(${t.join(", ")})`;return e.description?`${e.description} ${n}`:n}return e.description}argumentDescription(e){let t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(n=>JSON.stringify(n)).join(", ")}`),e.defaultValue!==void 0&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){let n=`(${t.join(", ")})`;return e.description?`${e.description} ${n}`:n}return e.description}formatItemList(e,t,n){return t.length===0?[]:[n.styleTitle(e),...t,""]}groupItems(e,t,n){let r=new Map;return e.forEach(s=>{let o=n(s);r.has(o)||r.set(o,[])}),t.forEach(s=>{let o=n(s);r.has(o)||r.set(o,[]),r.get(o).push(s)}),r}formatHelp(e,t){let n=t.padWidth(e,t),r=t.helpWidth??80;function s(d,c){return t.formatItem(d,n,c,t)}let o=[`${t.styleTitle("Usage:")} ${t.styleUsage(t.commandUsage(e))}`,""],l=t.commandDescription(e);l.length>0&&(o=o.concat([t.boxWrap(t.styleCommandDescription(l),r),""]));let h=t.visibleArguments(e).map(d=>s(t.styleArgumentTerm(t.argumentTerm(d)),t.styleArgumentDescription(t.argumentDescription(d))));if(o=o.concat(this.formatItemList("Arguments:",h,t)),this.groupItems(e.options,t.visibleOptions(e),d=>d.helpGroupHeading??"Options:").forEach((d,c)=>{let m=d.map(p=>s(t.styleOptionTerm(t.optionTerm(p)),t.styleOptionDescription(t.optionDescription(p))));o=o.concat(this.formatItemList(c,m,t))}),t.showGlobalOptions){let d=t.visibleGlobalOptions(e).map(c=>s(t.styleOptionTerm(t.optionTerm(c)),t.styleOptionDescription(t.optionDescription(c))));o=o.concat(this.formatItemList("Global Options:",d,t))}return this.groupItems(e.commands,t.visibleCommands(e),d=>d.helpGroup()||"Commands:").forEach((d,c)=>{let m=d.map(p=>s(t.styleSubcommandTerm(t.subcommandTerm(p)),t.styleSubcommandDescription(t.subcommandDescription(p))));o=o.concat(this.formatItemList(c,m,t))}),o.join(`
3
+ `)}displayWidth(e){return st(e).length}styleTitle(e){return e}styleUsage(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t==="[command]"?this.styleSubcommandText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleCommandText(t)).join(" ")}styleCommandDescription(e){return this.styleDescriptionText(e)}styleOptionDescription(e){return this.styleDescriptionText(e)}styleSubcommandDescription(e){return this.styleDescriptionText(e)}styleArgumentDescription(e){return this.styleDescriptionText(e)}styleDescriptionText(e){return e}styleOptionTerm(e){return this.styleOptionText(e)}styleSubcommandTerm(e){return e.split(" ").map(t=>t==="[options]"?this.styleOptionText(t):t[0]==="["||t[0]==="<"?this.styleArgumentText(t):this.styleSubcommandText(t)).join(" ")}styleArgumentTerm(e){return this.styleArgumentText(e)}styleOptionText(e){return e}styleArgumentText(e){return e}styleSubcommandText(e){return e}styleCommandText(e){return e}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}preformatted(e){return/\n[^\S\r\n]/.test(e)}formatItem(e,t,n,r){let o=" ".repeat(2);if(!n)return o+e;let l=e.padEnd(t+e.length-r.displayWidth(e)),h=2,a=(this.helpWidth??80)-t-h-2,d;return a<this.minWidthToWrap||r.preformatted(n)?d=n:d=r.boxWrap(n,a).replace(/\n/g,`
4
4
  `+" ".repeat(t+h)),o+l+" ".repeat(h)+d.replace(/\n/g,`
5
- ${o}`)}boxWrap(e,t){if(t<this.minWidthToWrap)return e;let n=e.split(/\r\n|\n/),r=/[\s]*[^\s]+/g,s=[];return n.forEach(o=>{let l=o.match(r);if(l===null){s.push("");return}let h=[l.shift()],a=this.displayWidth(h[0]);l.forEach(u=>{let d=this.displayWidth(u);if(a+d<=t){h.push(u),a+=d;return}s.push(h.join(""));let c=u.trimStart();h=[c],a=this.displayWidth(c)}),s.push(h.join(""))}),s.join(`
6
- `)}};function st(i){let e=/\x1b\[\d*(;\d*)*m/g;return i.replace(e,"")}Se.Help=Re;Se.stripColor=st});var Pe=G(De=>{var{InvalidArgumentError:xn}=J(),Te=class{constructor(e,t){this.flags=e,this.description=t||"",this.required=e.includes("<"),this.optional=e.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(e),this.mandatory=!1;let n=Tn(e);this.short=n.shortFlag,this.long=n.longFlag,this.negate=!1,this.long&&(this.negate=this.long.startsWith("--no-")),this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0,this.helpGroupHeading=void 0}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}preset(e){return this.presetArg=e,this}conflicts(e){return this.conflictsWith=this.conflictsWith.concat(e),this}implies(e){let t=e;return typeof e=="string"&&(t={[e]:!0}),this.implied=Object.assign(this.implied||{},t),this}env(e){return this.envVar=e,this}argParser(e){return this.parseArg=e,this}makeOptionMandatory(e=!0){return this.mandatory=!!e,this}hideHelp(e=!0){return this.hidden=!!e,this}_collectValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:(t.push(e),t)}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,n)=>{if(!this.argChoices.includes(t))throw new xn(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(t,n):t},this}name(){return this.long?this.long.replace(/^--/,""):this.short.replace(/^-/,"")}attributeName(){return this.negate?ot(this.name().replace(/^no-/,"")):ot(this.name())}helpGroup(e){return this.helpGroupHeading=e,this}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}},Ee=class{constructor(e){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,e.forEach(t=>{t.negate?this.negativeOptions.set(t.attributeName(),t):this.positiveOptions.set(t.attributeName(),t)}),this.negativeOptions.forEach((t,n)=>{this.positiveOptions.has(n)&&this.dualOptions.add(n)})}valueFromOption(e,t){let n=t.attributeName();if(!this.dualOptions.has(n))return!0;let r=this.negativeOptions.get(n).presetArg,s=r!==void 0?r:!1;return t.negate===(s===e)}};function ot(i){return i.split("-").reduce((e,t)=>e+t[0].toUpperCase()+t.slice(1))}function Tn(i){let e,t,n=/^-[^-]$/,r=/^--[^-]/,s=i.split(/[ |,]+/).concat("guard");if(n.test(s[0])&&(e=s.shift()),r.test(s[0])&&(t=s.shift()),!e&&n.test(s[0])&&(e=s.shift()),!e&&r.test(s[0])&&(e=t,t=s.shift()),s[0].startsWith("-")){let o=s[0],l=`option creation failed due to '${o}' in option flags '${i}'`;throw/^-[^-][^-]/.test(o)?new Error(`${l}
5
+ ${o}`)}boxWrap(e,t){if(t<this.minWidthToWrap)return e;let n=e.split(/\r\n|\n/),r=/[\s]*[^\s]+/g,s=[];return n.forEach(o=>{let l=o.match(r);if(l===null){s.push("");return}let h=[l.shift()],u=this.displayWidth(h[0]);l.forEach(a=>{let d=this.displayWidth(a);if(u+d<=t){h.push(a),u+=d;return}s.push(h.join(""));let c=a.trimStart();h=[c],u=this.displayWidth(c)}),s.push(h.join(""))}),s.join(`
6
+ `)}};function st(i){let e=/\x1b\[\d*(;\d*)*m/g;return i.replace(e,"")}Re.Help=Oe;Re.stripColor=st});var Pe=W(De=>{var{InvalidArgumentError:Tn}=K(),Te=class{constructor(e,t){this.flags=e,this.description=t||"",this.required=e.includes("<"),this.optional=e.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(e),this.mandatory=!1;let n=En(e);this.short=n.shortFlag,this.long=n.longFlag,this.negate=!1,this.long&&(this.negate=this.long.startsWith("--no-")),this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0,this.helpGroupHeading=void 0}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}preset(e){return this.presetArg=e,this}conflicts(e){return this.conflictsWith=this.conflictsWith.concat(e),this}implies(e){let t=e;return typeof e=="string"&&(t={[e]:!0}),this.implied=Object.assign(this.implied||{},t),this}env(e){return this.envVar=e,this}argParser(e){return this.parseArg=e,this}makeOptionMandatory(e=!0){return this.mandatory=!!e,this}hideHelp(e=!0){return this.hidden=!!e,this}_collectValue(e,t){return t===this.defaultValue||!Array.isArray(t)?[e]:(t.push(e),t)}choices(e){return this.argChoices=e.slice(),this.parseArg=(t,n)=>{if(!this.argChoices.includes(t))throw new Tn(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._collectValue(t,n):t},this}name(){return this.long?this.long.replace(/^--/,""):this.short.replace(/^-/,"")}attributeName(){return this.negate?ot(this.name().replace(/^no-/,"")):ot(this.name())}helpGroup(e){return this.helpGroupHeading=e,this}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}},Ee=class{constructor(e){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,e.forEach(t=>{t.negate?this.negativeOptions.set(t.attributeName(),t):this.positiveOptions.set(t.attributeName(),t)}),this.negativeOptions.forEach((t,n)=>{this.positiveOptions.has(n)&&this.dualOptions.add(n)})}valueFromOption(e,t){let n=t.attributeName();if(!this.dualOptions.has(n))return!0;let r=this.negativeOptions.get(n).presetArg,s=r!==void 0?r:!1;return t.negate===(s===e)}};function ot(i){return i.split("-").reduce((e,t)=>e+t[0].toUpperCase()+t.slice(1))}function En(i){let e,t,n=/^-[^-]$/,r=/^--[^-]/,s=i.split(/[ |,]+/).concat("guard");if(n.test(s[0])&&(e=s.shift()),r.test(s[0])&&(t=s.shift()),!e&&n.test(s[0])&&(e=s.shift()),!e&&r.test(s[0])&&(e=t,t=s.shift()),s[0].startsWith("-")){let o=s[0],l=`option creation failed due to '${o}' in option flags '${i}'`;throw/^-[^-][^-]/.test(o)?new Error(`${l}
7
7
  - a short flag is a single dash and a single character
8
8
  - either use a single dash and a single character (for a short flag)
9
9
  - or use a double dash for a long option (and can have two, like '--ws, --workspace')`):n.test(o)?new Error(`${l}
10
10
  - too many short flags`):r.test(o)?new Error(`${l}
11
11
  - too many long flags`):new Error(`${l}
12
- - unrecognised flag format`)}if(e===void 0&&t===void 0)throw new Error(`option creation failed due to no flags found in '${i}'.`);return{shortFlag:e,longFlag:t}}De.Option=Te;De.DualOptions=Ee});var lt=G(at=>{function En(i,e){if(Math.abs(i.length-e.length)>3)return Math.max(i.length,e.length);let t=[];for(let n=0;n<=i.length;n++)t[n]=[n];for(let n=0;n<=e.length;n++)t[0][n]=n;for(let n=1;n<=e.length;n++)for(let r=1;r<=i.length;r++){let s=1;i[r-1]===e[n-1]?s=0:s=1,t[r][n]=Math.min(t[r-1][n]+1,t[r][n-1]+1,t[r-1][n-1]+s),r>1&&n>1&&i[r-1]===e[n-2]&&i[r-2]===e[n-1]&&(t[r][n]=Math.min(t[r][n],t[r-2][n-2]+1))}return t[i.length][e.length]}function Dn(i,e){if(!e||e.length===0)return"";e=Array.from(new Set(e));let t=i.startsWith("--");t&&(i=i.slice(2),e=e.map(o=>o.slice(2)));let n=[],r=3,s=.4;return e.forEach(o=>{if(o.length<=1)return;let l=En(i,o),h=Math.max(i.length,o.length);(h-l)/h>s&&(l<r?(r=l,n=[o]):l===r&&n.push(o))}),n.sort((o,l)=>o.localeCompare(l)),t&&(n=n.map(o=>`--${o}`)),n.length>1?`
12
+ - unrecognised flag format`)}if(e===void 0&&t===void 0)throw new Error(`option creation failed due to no flags found in '${i}'.`);return{shortFlag:e,longFlag:t}}De.Option=Te;De.DualOptions=Ee});var lt=W(at=>{function Dn(i,e){if(Math.abs(i.length-e.length)>3)return Math.max(i.length,e.length);let t=[];for(let n=0;n<=i.length;n++)t[n]=[n];for(let n=0;n<=e.length;n++)t[0][n]=n;for(let n=1;n<=e.length;n++)for(let r=1;r<=i.length;r++){let s=1;i[r-1]===e[n-1]?s=0:s=1,t[r][n]=Math.min(t[r-1][n]+1,t[r][n-1]+1,t[r-1][n-1]+s),r>1&&n>1&&i[r-1]===e[n-2]&&i[r-2]===e[n-1]&&(t[r][n]=Math.min(t[r][n],t[r-2][n-2]+1))}return t[i.length][e.length]}function Pn(i,e){if(!e||e.length===0)return"";e=Array.from(new Set(e));let t=i.startsWith("--");t&&(i=i.slice(2),e=e.map(o=>o.slice(2)));let n=[],r=3,s=.4;return e.forEach(o=>{if(o.length<=1)return;let l=Dn(i,o),h=Math.max(i.length,o.length);(h-l)/h>s&&(l<r?(r=l,n=[o]):l===r&&n.push(o))}),n.sort((o,l)=>o.localeCompare(l)),t&&(n=n.map(o=>`--${o}`)),n.length>1?`
13
13
  (Did you mean one of ${n.join(", ")}?)`:n.length===1?`
14
- (Did you mean ${n[0]}?)`:""}at.suggestSimilar=Dn});var ht=G(Ie=>{var Pn=z("node:events").EventEmitter,ke=z("node:child_process"),I=z("node:path"),te=z("node:fs"),_=z("node:process"),{Argument:kn,humanReadableArgName:Nn}=ee(),{CommanderError:Ne}=J(),{Help:Mn,stripColor:Ln}=xe(),{Option:ut,DualOptions:In}=Pe(),{suggestSimilar:ct}=lt(),Me=class i extends Pn{constructor(e){super(),this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!1,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=e||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._savedState=null,this._outputConfiguration={writeOut:t=>_.stdout.write(t),writeErr:t=>_.stderr.write(t),outputError:(t,n)=>n(t),getOutHelpWidth:()=>_.stdout.isTTY?_.stdout.columns:void 0,getErrHelpWidth:()=>_.stderr.isTTY?_.stderr.columns:void 0,getOutHasColors:()=>Le()??(_.stdout.isTTY&&_.stdout.hasColors?.()),getErrHasColors:()=>Le()??(_.stderr.isTTY&&_.stderr.hasColors?.()),stripColor:t=>Ln(t)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={},this._helpGroupHeading=void 0,this._defaultCommandGroup=void 0,this._defaultOptionGroup=void 0}copyInheritedSettings(e){return this._outputConfiguration=e._outputConfiguration,this._helpOption=e._helpOption,this._helpCommand=e._helpCommand,this._helpConfiguration=e._helpConfiguration,this._exitCallback=e._exitCallback,this._storeOptionsAsProperties=e._storeOptionsAsProperties,this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue,this._allowExcessArguments=e._allowExcessArguments,this._enablePositionalOptions=e._enablePositionalOptions,this._showHelpAfterError=e._showHelpAfterError,this._showSuggestionAfterError=e._showSuggestionAfterError,this}_getCommandAndAncestors(){let e=[];for(let t=this;t;t=t.parent)e.push(t);return e}command(e,t,n){let r=t,s=n;typeof r=="object"&&r!==null&&(s=r,r=null),s=s||{};let[,o,l]=e.match(/([^ ]+) *(.*)/),h=this.createCommand(o);return r&&(h.description(r),h._executableHandler=!0),s.isDefault&&(this._defaultCommandName=h._name),h._hidden=!!(s.noHelp||s.hidden),h._executableFile=s.executableFile||null,l&&h.arguments(l),this._registerCommand(h),h.parent=this,h.copyInheritedSettings(this),r?this:h}createCommand(e){return new i(e)}createHelp(){return Object.assign(new Mn,this.configureHelp())}configureHelp(e){return e===void 0?this._helpConfiguration:(this._helpConfiguration=e,this)}configureOutput(e){return e===void 0?this._outputConfiguration:(this._outputConfiguration={...this._outputConfiguration,...e},this)}showHelpAfterError(e=!0){return typeof e!="string"&&(e=!!e),this._showHelpAfterError=e,this}showSuggestionAfterError(e=!0){return this._showSuggestionAfterError=!!e,this}addCommand(e,t){if(!e._name)throw new Error(`Command passed to .addCommand() must have a name
15
- - specify the name in Command constructor or using .name()`);return t=t||{},t.isDefault&&(this._defaultCommandName=e._name),(t.noHelp||t.hidden)&&(e._hidden=!0),this._registerCommand(e),e.parent=this,e._checkForBrokenPassThrough(),this}createArgument(e,t){return new kn(e,t)}argument(e,t,n,r){let s=this.createArgument(e,t);return typeof n=="function"?s.default(r).argParser(n):s.default(n),this.addArgument(s),this}arguments(e){return e.trim().split(/ +/).forEach(t=>{this.argument(t)}),this}addArgument(e){let t=this.registeredArguments.slice(-1)[0];if(t?.variadic)throw new Error(`only the last argument can be variadic '${t.name()}'`);if(e.required&&e.defaultValue!==void 0&&e.parseArg===void 0)throw new Error(`a default value for a required argument is never used: '${e.name()}'`);return this.registeredArguments.push(e),this}helpCommand(e,t){if(typeof e=="boolean")return this._addImplicitHelpCommand=e,e&&this._defaultCommandGroup&&this._initCommandGroup(this._getHelpCommand()),this;let n=e??"help [command]",[,r,s]=n.match(/([^ ]+) *(.*)/),o=t??"display help for command",l=this.createCommand(r);return l.helpOption(!1),s&&l.arguments(s),o&&l.description(o),this._addImplicitHelpCommand=!0,this._helpCommand=l,(e||t)&&this._initCommandGroup(l),this}addHelpCommand(e,t){return typeof e!="object"?(this.helpCommand(e,t),this):(this._addImplicitHelpCommand=!0,this._helpCommand=e,this._initCommandGroup(e),this)}_getHelpCommand(){return this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))?(this._helpCommand===void 0&&this.helpCommand(void 0,void 0),this._helpCommand):null}hook(e,t){let n=["preSubcommand","preAction","postAction"];if(!n.includes(e))throw new Error(`Unexpected value for event passed to hook : '${e}'.
16
- Expecting one of '${n.join("', '")}'`);return this._lifeCycleHooks[e]?this._lifeCycleHooks[e].push(t):this._lifeCycleHooks[e]=[t],this}exitOverride(e){return e?this._exitCallback=e:this._exitCallback=t=>{if(t.code!=="commander.executeSubCommandAsync")throw t},this}_exit(e,t,n){this._exitCallback&&this._exitCallback(new Ne(e,t,n)),_.exit(e)}action(e){let t=n=>{let r=this.registeredArguments.length,s=n.slice(0,r);return this._storeOptionsAsProperties?s[r]=this:s[r]=this.opts(),s.push(this),e.apply(this,s)};return this._actionHandler=t,this}createOption(e,t){return new ut(e,t)}_callParseArg(e,t,n,r){try{return e.parseArg(t,n)}catch(s){if(s.code==="commander.invalidArgument"){let o=`${r} ${s.message}`;this.error(o,{exitCode:s.exitCode,code:s.code})}throw s}}_registerOption(e){let t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){let n=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${n}'
17
- - already used by option '${t.flags}'`)}this._initOptionGroup(e),this.options.push(e)}_registerCommand(e){let t=r=>[r.name()].concat(r.aliases()),n=t(e).find(r=>this._findCommand(r));if(n){let r=t(this._findCommand(n)).join("|"),s=t(e).join("|");throw new Error(`cannot add command '${s}' as already have command '${r}'`)}this._initCommandGroup(e),this.commands.push(e)}addOption(e){this._registerOption(e);let t=e.name(),n=e.attributeName();if(e.negate){let s=e.long.replace(/^--no-/,"--");this._findOption(s)||this.setOptionValueWithSource(n,e.defaultValue===void 0?!0:e.defaultValue,"default")}else e.defaultValue!==void 0&&this.setOptionValueWithSource(n,e.defaultValue,"default");let r=(s,o,l)=>{s==null&&e.presetArg!==void 0&&(s=e.presetArg);let h=this.getOptionValue(n);s!==null&&e.parseArg?s=this._callParseArg(e,s,h,o):s!==null&&e.variadic&&(s=e._collectValue(s,h)),s==null&&(e.negate?s=!1:e.isBoolean()||e.optional?s=!0:s=""),this.setOptionValueWithSource(n,s,l)};return this.on("option:"+t,s=>{let o=`error: option '${e.flags}' argument '${s}' is invalid.`;r(s,o,"cli")}),e.envVar&&this.on("optionEnv:"+t,s=>{let o=`error: option '${e.flags}' value '${s}' from env '${e.envVar}' is invalid.`;r(s,o,"env")}),this}_optionEx(e,t,n,r,s){if(typeof t=="object"&&t instanceof ut)throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");let o=this.createOption(t,n);if(o.makeOptionMandatory(!!e.mandatory),typeof r=="function")o.default(s).argParser(r);else if(r instanceof RegExp){let l=r;r=(h,a)=>{let u=l.exec(h);return u?u[0]:a},o.default(s).argParser(r)}else o.default(r);return this.addOption(o)}option(e,t,n,r){return this._optionEx({},e,t,n,r)}requiredOption(e,t,n,r){return this._optionEx({mandatory:!0},e,t,n,r)}combineFlagAndOptionalValue(e=!0){return this._combineFlagAndOptionalValue=!!e,this}allowUnknownOption(e=!0){return this._allowUnknownOption=!!e,this}allowExcessArguments(e=!0){return this._allowExcessArguments=!!e,this}enablePositionalOptions(e=!0){return this._enablePositionalOptions=!!e,this}passThroughOptions(e=!0){return this._passThroughOptions=!!e,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(e=!0){if(this.options.length)throw new Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw new Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!e,this}getOptionValue(e){return this._storeOptionsAsProperties?this[e]:this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,void 0)}setOptionValueWithSource(e,t,n){return this._storeOptionsAsProperties?this[e]=t:this._optionValues[e]=t,this._optionValueSources[e]=n,this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;return this._getCommandAndAncestors().forEach(n=>{n.getOptionValueSource(e)!==void 0&&(t=n.getOptionValueSource(e))}),t}_prepareUserArgs(e,t){if(e!==void 0&&!Array.isArray(e))throw new Error("first parameter to parse must be array or undefined");if(t=t||{},e===void 0&&t.from===void 0){_.versions?.electron&&(t.from="electron");let r=_.execArgv??[];(r.includes("-e")||r.includes("--eval")||r.includes("-p")||r.includes("--print"))&&(t.from="eval")}e===void 0&&(e=_.argv),this.rawArgs=e.slice();let n;switch(t.from){case void 0:case"node":this._scriptPath=e[1],n=e.slice(2);break;case"electron":_.defaultApp?(this._scriptPath=e[1],n=e.slice(2)):n=e.slice(1);break;case"user":n=e.slice(0);break;case"eval":n=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}return!this._name&&this._scriptPath&&this.nameFromFilename(this._scriptPath),this._name=this._name||"program",n}parse(e,t){this._prepareForParse();let n=this._prepareUserArgs(e,t);return this._parseCommand([],n),this}async parseAsync(e,t){this._prepareForParse();let n=this._prepareUserArgs(e,t);return await this._parseCommand([],n),this}_prepareForParse(){this._savedState===null?this.saveStateBeforeParse():this.restoreStateBeforeParse()}saveStateBeforeParse(){this._savedState={_name:this._name,_optionValues:{...this._optionValues},_optionValueSources:{...this._optionValueSources}}}restoreStateBeforeParse(){if(this._storeOptionsAsProperties)throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
18
- - either make a new Command for each call to parse, or stop storing options as properties`);this._name=this._savedState._name,this._scriptPath=null,this.rawArgs=[],this._optionValues={...this._savedState._optionValues},this._optionValueSources={...this._savedState._optionValueSources},this.args=[],this.processedArgs=[]}_checkForMissingExecutable(e,t,n){if(te.existsSync(e))return;let r=t?`searched for local subcommand relative to directory '${t}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",s=`'${e}' does not exist
14
+ (Did you mean ${n[0]}?)`:""}at.suggestSimilar=Pn});var ht=W(Ie=>{var kn=Y("node:events").EventEmitter,ke=Y("node:child_process"),F=Y("node:path"),ie=Y("node:fs"),C=Y("node:process"),{Argument:Nn,humanReadableArgName:Mn}=ne(),{CommanderError:Ne}=K(),{Help:Ln,stripColor:In}=xe(),{Option:ut,DualOptions:Fn}=Pe(),{suggestSimilar:ct}=lt(),Me=class i extends kn{constructor(e){super(),this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!1,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=e||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._savedState=null,this._outputConfiguration={writeOut:t=>C.stdout.write(t),writeErr:t=>C.stderr.write(t),outputError:(t,n)=>n(t),getOutHelpWidth:()=>C.stdout.isTTY?C.stdout.columns:void 0,getErrHelpWidth:()=>C.stderr.isTTY?C.stderr.columns:void 0,getOutHasColors:()=>Le()??(C.stdout.isTTY&&C.stdout.hasColors?.()),getErrHasColors:()=>Le()??(C.stderr.isTTY&&C.stderr.hasColors?.()),stripColor:t=>In(t)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={},this._helpGroupHeading=void 0,this._defaultCommandGroup=void 0,this._defaultOptionGroup=void 0}copyInheritedSettings(e){return this._outputConfiguration=e._outputConfiguration,this._helpOption=e._helpOption,this._helpCommand=e._helpCommand,this._helpConfiguration=e._helpConfiguration,this._exitCallback=e._exitCallback,this._storeOptionsAsProperties=e._storeOptionsAsProperties,this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue,this._allowExcessArguments=e._allowExcessArguments,this._enablePositionalOptions=e._enablePositionalOptions,this._showHelpAfterError=e._showHelpAfterError,this._showSuggestionAfterError=e._showSuggestionAfterError,this}_getCommandAndAncestors(){let e=[];for(let t=this;t;t=t.parent)e.push(t);return e}command(e,t,n){let r=t,s=n;typeof r=="object"&&r!==null&&(s=r,r=null),s=s||{};let[,o,l]=e.match(/([^ ]+) *(.*)/),h=this.createCommand(o);return r&&(h.description(r),h._executableHandler=!0),s.isDefault&&(this._defaultCommandName=h._name),h._hidden=!!(s.noHelp||s.hidden),h._executableFile=s.executableFile||null,l&&h.arguments(l),this._registerCommand(h),h.parent=this,h.copyInheritedSettings(this),r?this:h}createCommand(e){return new i(e)}createHelp(){return Object.assign(new Ln,this.configureHelp())}configureHelp(e){return e===void 0?this._helpConfiguration:(this._helpConfiguration=e,this)}configureOutput(e){return e===void 0?this._outputConfiguration:(this._outputConfiguration={...this._outputConfiguration,...e},this)}showHelpAfterError(e=!0){return typeof e!="string"&&(e=!!e),this._showHelpAfterError=e,this}showSuggestionAfterError(e=!0){return this._showSuggestionAfterError=!!e,this}addCommand(e,t){if(!e._name)throw new Error(`Command passed to .addCommand() must have a name
15
+ - specify the name in Command constructor or using .name()`);return t=t||{},t.isDefault&&(this._defaultCommandName=e._name),(t.noHelp||t.hidden)&&(e._hidden=!0),this._registerCommand(e),e.parent=this,e._checkForBrokenPassThrough(),this}createArgument(e,t){return new Nn(e,t)}argument(e,t,n,r){let s=this.createArgument(e,t);return typeof n=="function"?s.default(r).argParser(n):s.default(n),this.addArgument(s),this}arguments(e){return e.trim().split(/ +/).forEach(t=>{this.argument(t)}),this}addArgument(e){let t=this.registeredArguments.slice(-1)[0];if(t?.variadic)throw new Error(`only the last argument can be variadic '${t.name()}'`);if(e.required&&e.defaultValue!==void 0&&e.parseArg===void 0)throw new Error(`a default value for a required argument is never used: '${e.name()}'`);return this.registeredArguments.push(e),this}helpCommand(e,t){if(typeof e=="boolean")return this._addImplicitHelpCommand=e,e&&this._defaultCommandGroup&&this._initCommandGroup(this._getHelpCommand()),this;let n=e??"help [command]",[,r,s]=n.match(/([^ ]+) *(.*)/),o=t??"display help for command",l=this.createCommand(r);return l.helpOption(!1),s&&l.arguments(s),o&&l.description(o),this._addImplicitHelpCommand=!0,this._helpCommand=l,(e||t)&&this._initCommandGroup(l),this}addHelpCommand(e,t){return typeof e!="object"?(this.helpCommand(e,t),this):(this._addImplicitHelpCommand=!0,this._helpCommand=e,this._initCommandGroup(e),this)}_getHelpCommand(){return this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))?(this._helpCommand===void 0&&this.helpCommand(void 0,void 0),this._helpCommand):null}hook(e,t){let n=["preSubcommand","preAction","postAction"];if(!n.includes(e))throw new Error(`Unexpected value for event passed to hook : '${e}'.
16
+ Expecting one of '${n.join("', '")}'`);return this._lifeCycleHooks[e]?this._lifeCycleHooks[e].push(t):this._lifeCycleHooks[e]=[t],this}exitOverride(e){return e?this._exitCallback=e:this._exitCallback=t=>{if(t.code!=="commander.executeSubCommandAsync")throw t},this}_exit(e,t,n){this._exitCallback&&this._exitCallback(new Ne(e,t,n)),C.exit(e)}action(e){let t=n=>{let r=this.registeredArguments.length,s=n.slice(0,r);return this._storeOptionsAsProperties?s[r]=this:s[r]=this.opts(),s.push(this),e.apply(this,s)};return this._actionHandler=t,this}createOption(e,t){return new ut(e,t)}_callParseArg(e,t,n,r){try{return e.parseArg(t,n)}catch(s){if(s.code==="commander.invalidArgument"){let o=`${r} ${s.message}`;this.error(o,{exitCode:s.exitCode,code:s.code})}throw s}}_registerOption(e){let t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){let n=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${n}'
17
+ - already used by option '${t.flags}'`)}this._initOptionGroup(e),this.options.push(e)}_registerCommand(e){let t=r=>[r.name()].concat(r.aliases()),n=t(e).find(r=>this._findCommand(r));if(n){let r=t(this._findCommand(n)).join("|"),s=t(e).join("|");throw new Error(`cannot add command '${s}' as already have command '${r}'`)}this._initCommandGroup(e),this.commands.push(e)}addOption(e){this._registerOption(e);let t=e.name(),n=e.attributeName();if(e.negate){let s=e.long.replace(/^--no-/,"--");this._findOption(s)||this.setOptionValueWithSource(n,e.defaultValue===void 0?!0:e.defaultValue,"default")}else e.defaultValue!==void 0&&this.setOptionValueWithSource(n,e.defaultValue,"default");let r=(s,o,l)=>{s==null&&e.presetArg!==void 0&&(s=e.presetArg);let h=this.getOptionValue(n);s!==null&&e.parseArg?s=this._callParseArg(e,s,h,o):s!==null&&e.variadic&&(s=e._collectValue(s,h)),s==null&&(e.negate?s=!1:e.isBoolean()||e.optional?s=!0:s=""),this.setOptionValueWithSource(n,s,l)};return this.on("option:"+t,s=>{let o=`error: option '${e.flags}' argument '${s}' is invalid.`;r(s,o,"cli")}),e.envVar&&this.on("optionEnv:"+t,s=>{let o=`error: option '${e.flags}' value '${s}' from env '${e.envVar}' is invalid.`;r(s,o,"env")}),this}_optionEx(e,t,n,r,s){if(typeof t=="object"&&t instanceof ut)throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");let o=this.createOption(t,n);if(o.makeOptionMandatory(!!e.mandatory),typeof r=="function")o.default(s).argParser(r);else if(r instanceof RegExp){let l=r;r=(h,u)=>{let a=l.exec(h);return a?a[0]:u},o.default(s).argParser(r)}else o.default(r);return this.addOption(o)}option(e,t,n,r){return this._optionEx({},e,t,n,r)}requiredOption(e,t,n,r){return this._optionEx({mandatory:!0},e,t,n,r)}combineFlagAndOptionalValue(e=!0){return this._combineFlagAndOptionalValue=!!e,this}allowUnknownOption(e=!0){return this._allowUnknownOption=!!e,this}allowExcessArguments(e=!0){return this._allowExcessArguments=!!e,this}enablePositionalOptions(e=!0){return this._enablePositionalOptions=!!e,this}passThroughOptions(e=!0){return this._passThroughOptions=!!e,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(e=!0){if(this.options.length)throw new Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw new Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!e,this}getOptionValue(e){return this._storeOptionsAsProperties?this[e]:this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,void 0)}setOptionValueWithSource(e,t,n){return this._storeOptionsAsProperties?this[e]=t:this._optionValues[e]=t,this._optionValueSources[e]=n,this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;return this._getCommandAndAncestors().forEach(n=>{n.getOptionValueSource(e)!==void 0&&(t=n.getOptionValueSource(e))}),t}_prepareUserArgs(e,t){if(e!==void 0&&!Array.isArray(e))throw new Error("first parameter to parse must be array or undefined");if(t=t||{},e===void 0&&t.from===void 0){C.versions?.electron&&(t.from="electron");let r=C.execArgv??[];(r.includes("-e")||r.includes("--eval")||r.includes("-p")||r.includes("--print"))&&(t.from="eval")}e===void 0&&(e=C.argv),this.rawArgs=e.slice();let n;switch(t.from){case void 0:case"node":this._scriptPath=e[1],n=e.slice(2);break;case"electron":C.defaultApp?(this._scriptPath=e[1],n=e.slice(2)):n=e.slice(1);break;case"user":n=e.slice(0);break;case"eval":n=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}return!this._name&&this._scriptPath&&this.nameFromFilename(this._scriptPath),this._name=this._name||"program",n}parse(e,t){this._prepareForParse();let n=this._prepareUserArgs(e,t);return this._parseCommand([],n),this}async parseAsync(e,t){this._prepareForParse();let n=this._prepareUserArgs(e,t);return await this._parseCommand([],n),this}_prepareForParse(){this._savedState===null?this.saveStateBeforeParse():this.restoreStateBeforeParse()}saveStateBeforeParse(){this._savedState={_name:this._name,_optionValues:{...this._optionValues},_optionValueSources:{...this._optionValueSources}}}restoreStateBeforeParse(){if(this._storeOptionsAsProperties)throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
18
+ - either make a new Command for each call to parse, or stop storing options as properties`);this._name=this._savedState._name,this._scriptPath=null,this.rawArgs=[],this._optionValues={...this._savedState._optionValues},this._optionValueSources={...this._savedState._optionValueSources},this.args=[],this.processedArgs=[]}_checkForMissingExecutable(e,t,n){if(ie.existsSync(e))return;let r=t?`searched for local subcommand relative to directory '${t}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",s=`'${e}' does not exist
19
19
  - if '${n}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
20
20
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
21
- - ${r}`;throw new Error(s)}_executeSubCommand(e,t){t=t.slice();let n=!1,r=[".js",".ts",".tsx",".mjs",".cjs"];function s(u,d){let c=I.resolve(u,d);if(te.existsSync(c))return c;if(r.includes(I.extname(d)))return;let m=r.find(f=>te.existsSync(`${c}${f}`));if(m)return`${c}${m}`}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let o=e._executableFile||`${this._name}-${e._name}`,l=this._executableDir||"";if(this._scriptPath){let u;try{u=te.realpathSync(this._scriptPath)}catch{u=this._scriptPath}l=I.resolve(I.dirname(u),l)}if(l){let u=s(l,o);if(!u&&!e._executableFile&&this._scriptPath){let d=I.basename(this._scriptPath,I.extname(this._scriptPath));d!==this._name&&(u=s(l,`${d}-${e._name}`))}o=u||o}n=r.includes(I.extname(o));let h;_.platform!=="win32"?n?(t.unshift(o),t=dt(_.execArgv).concat(t),h=ke.spawn(_.argv[0],t,{stdio:"inherit"})):h=ke.spawn(o,t,{stdio:"inherit"}):(this._checkForMissingExecutable(o,l,e._name),t.unshift(o),t=dt(_.execArgv).concat(t),h=ke.spawn(_.execPath,t,{stdio:"inherit"})),h.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(d=>{_.on(d,()=>{h.killed===!1&&h.exitCode===null&&h.kill(d)})});let a=this._exitCallback;h.on("close",u=>{u=u??1,a?a(new Ne(u,"commander.executeSubCommandAsync","(close)")):_.exit(u)}),h.on("error",u=>{if(u.code==="ENOENT")this._checkForMissingExecutable(o,l,e._name);else if(u.code==="EACCES")throw new Error(`'${o}' not executable`);if(!a)_.exit(1);else{let d=new Ne(1,"commander.executeSubCommandAsync","(error)");d.nestedError=u,a(d)}}),this.runningCommand=h}_dispatchSubcommand(e,t,n){let r=this._findCommand(e);r||this.help({error:!0}),r._prepareForParse();let s;return s=this._chainOrCallSubCommandHook(s,r,"preSubcommand"),s=this._chainOrCall(s,()=>{if(r._executableHandler)this._executeSubCommand(r,t.concat(n));else return r._parseCommand(t,n)}),s}_dispatchHelpCommand(e){e||this.help();let t=this._findCommand(e);return t&&!t._executableHandler&&t.help(),this._dispatchSubcommand(e,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((e,t)=>{e.required&&this.args[t]==null&&this.missingArgument(e.name())}),!(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)&&this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){let e=(n,r,s)=>{let o=r;if(r!==null&&n.parseArg){let l=`error: command-argument value '${r}' is invalid for argument '${n.name()}'.`;o=this._callParseArg(n,r,s,l)}return o};this._checkNumberOfArguments();let t=[];this.registeredArguments.forEach((n,r)=>{let s=n.defaultValue;n.variadic?r<this.args.length?(s=this.args.slice(r),n.parseArg&&(s=s.reduce((o,l)=>e(n,l,o),n.defaultValue))):s===void 0&&(s=[]):r<this.args.length&&(s=this.args[r],n.parseArg&&(s=e(n,s,n.defaultValue))),t[r]=s}),this.processedArgs=t}_chainOrCall(e,t){return e?.then&&typeof e.then=="function"?e.then(()=>t()):t()}_chainOrCallHooks(e,t){let n=e,r=[];return this._getCommandAndAncestors().reverse().filter(s=>s._lifeCycleHooks[t]!==void 0).forEach(s=>{s._lifeCycleHooks[t].forEach(o=>{r.push({hookedCommand:s,callback:o})})}),t==="postAction"&&r.reverse(),r.forEach(s=>{n=this._chainOrCall(n,()=>s.callback(s.hookedCommand,this))}),n}_chainOrCallSubCommandHook(e,t,n){let r=e;return this._lifeCycleHooks[n]!==void 0&&this._lifeCycleHooks[n].forEach(s=>{r=this._chainOrCall(r,()=>s(this,t))}),r}_parseCommand(e,t){let n=this.parseOptions(t);if(this._parseOptionsEnv(),this._parseOptionsImplied(),e=e.concat(n.operands),t=n.unknown,this.args=e.concat(t),e&&this._findCommand(e[0]))return this._dispatchSubcommand(e[0],e.slice(1),t);if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(e[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(t),this._dispatchSubcommand(this._defaultCommandName,e,t);this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName&&this.help({error:!0}),this._outputHelpIfRequested(n.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let r=()=>{n.unknown.length>0&&this.unknownOption(n.unknown[0])},s=`command:${this.name()}`;if(this._actionHandler){r(),this._processArguments();let o;return o=this._chainOrCallHooks(o,"preAction"),o=this._chainOrCall(o,()=>this._actionHandler(this.processedArgs)),this.parent&&(o=this._chainOrCall(o,()=>{this.parent.emit(s,e,t)})),o=this._chainOrCallHooks(o,"postAction"),o}if(this.parent?.listenerCount(s))r(),this._processArguments(),this.parent.emit(s,e,t);else if(e.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",e,t);this.listenerCount("command:*")?this.emit("command:*",e,t):this.commands.length?this.unknownCommand():(r(),this._processArguments())}else this.commands.length?(r(),this.help({error:!0})):(r(),this._processArguments())}_findCommand(e){if(e)return this.commands.find(t=>t._name===e||t._aliases.includes(e))}_findOption(e){return this.options.find(t=>t.is(e))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(e=>{e.options.forEach(t=>{t.mandatory&&e.getOptionValue(t.attributeName())===void 0&&e.missingMandatoryOptionValue(t)})})}_checkForConflictingLocalOptions(){let e=this.options.filter(n=>{let r=n.attributeName();return this.getOptionValue(r)===void 0?!1:this.getOptionValueSource(r)!=="default"});e.filter(n=>n.conflictsWith.length>0).forEach(n=>{let r=e.find(s=>n.conflictsWith.includes(s.attributeName()));r&&this._conflictingOption(n,r)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(e=>{e._checkForConflictingLocalOptions()})}parseOptions(e){let t=[],n=[],r=t;function s(u){return u.length>1&&u[0]==="-"}let o=u=>/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(u)?!this._getCommandAndAncestors().some(d=>d.options.map(c=>c.short).some(c=>/^-\d$/.test(c))):!1,l=null,h=null,a=0;for(;a<e.length||h;){let u=h??e[a++];if(h=null,u==="--"){r===n&&r.push(u),r.push(...e.slice(a));break}if(l&&(!s(u)||o(u))){this.emit(`option:${l.name()}`,u);continue}if(l=null,s(u)){let d=this._findOption(u);if(d){if(d.required){let c=e[a++];c===void 0&&this.optionMissingArgument(d),this.emit(`option:${d.name()}`,c)}else if(d.optional){let c=null;a<e.length&&(!s(e[a])||o(e[a]))&&(c=e[a++]),this.emit(`option:${d.name()}`,c)}else this.emit(`option:${d.name()}`);l=d.variadic?d:null;continue}}if(u.length>2&&u[0]==="-"&&u[1]!=="-"){let d=this._findOption(`-${u[1]}`);if(d){d.required||d.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${d.name()}`,u.slice(2)):(this.emit(`option:${d.name()}`),h=`-${u.slice(2)}`);continue}}if(/^--[^=]+=/.test(u)){let d=u.indexOf("="),c=this._findOption(u.slice(0,d));if(c&&(c.required||c.optional)){this.emit(`option:${c.name()}`,u.slice(d+1));continue}}if(r===t&&s(u)&&!(this.commands.length===0&&o(u))&&(r=n),(this._enablePositionalOptions||this._passThroughOptions)&&t.length===0&&n.length===0){if(this._findCommand(u)){t.push(u),n.push(...e.slice(a));break}else if(this._getHelpCommand()&&u===this._getHelpCommand().name()){t.push(u,...e.slice(a));break}else if(this._defaultCommandName){n.push(u,...e.slice(a));break}}if(this._passThroughOptions){r.push(u,...e.slice(a));break}r.push(u)}return{operands:t,unknown:n}}opts(){if(this._storeOptionsAsProperties){let e={},t=this.options.length;for(let n=0;n<t;n++){let r=this.options[n].attributeName();e[r]=r===this._versionOptionName?this._version:this[r]}return e}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((e,t)=>Object.assign(e,t.opts()),{})}error(e,t){this._outputConfiguration.outputError(`${e}
21
+ - ${r}`;throw new Error(s)}_executeSubCommand(e,t){t=t.slice();let n=!1,r=[".js",".ts",".tsx",".mjs",".cjs"];function s(a,d){let c=F.resolve(a,d);if(ie.existsSync(c))return c;if(r.includes(F.extname(d)))return;let m=r.find(p=>ie.existsSync(`${c}${p}`));if(m)return`${c}${m}`}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let o=e._executableFile||`${this._name}-${e._name}`,l=this._executableDir||"";if(this._scriptPath){let a;try{a=ie.realpathSync(this._scriptPath)}catch{a=this._scriptPath}l=F.resolve(F.dirname(a),l)}if(l){let a=s(l,o);if(!a&&!e._executableFile&&this._scriptPath){let d=F.basename(this._scriptPath,F.extname(this._scriptPath));d!==this._name&&(a=s(l,`${d}-${e._name}`))}o=a||o}n=r.includes(F.extname(o));let h;C.platform!=="win32"?n?(t.unshift(o),t=dt(C.execArgv).concat(t),h=ke.spawn(C.argv[0],t,{stdio:"inherit"})):h=ke.spawn(o,t,{stdio:"inherit"}):(this._checkForMissingExecutable(o,l,e._name),t.unshift(o),t=dt(C.execArgv).concat(t),h=ke.spawn(C.execPath,t,{stdio:"inherit"})),h.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(d=>{C.on(d,()=>{h.killed===!1&&h.exitCode===null&&h.kill(d)})});let u=this._exitCallback;h.on("close",a=>{a=a??1,u?u(new Ne(a,"commander.executeSubCommandAsync","(close)")):C.exit(a)}),h.on("error",a=>{if(a.code==="ENOENT")this._checkForMissingExecutable(o,l,e._name);else if(a.code==="EACCES")throw new Error(`'${o}' not executable`);if(!u)C.exit(1);else{let d=new Ne(1,"commander.executeSubCommandAsync","(error)");d.nestedError=a,u(d)}}),this.runningCommand=h}_dispatchSubcommand(e,t,n){let r=this._findCommand(e);r||this.help({error:!0}),r._prepareForParse();let s;return s=this._chainOrCallSubCommandHook(s,r,"preSubcommand"),s=this._chainOrCall(s,()=>{if(r._executableHandler)this._executeSubCommand(r,t.concat(n));else return r._parseCommand(t,n)}),s}_dispatchHelpCommand(e){e||this.help();let t=this._findCommand(e);return t&&!t._executableHandler&&t.help(),this._dispatchSubcommand(e,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((e,t)=>{e.required&&this.args[t]==null&&this.missingArgument(e.name())}),!(this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)&&this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){let e=(n,r,s)=>{let o=r;if(r!==null&&n.parseArg){let l=`error: command-argument value '${r}' is invalid for argument '${n.name()}'.`;o=this._callParseArg(n,r,s,l)}return o};this._checkNumberOfArguments();let t=[];this.registeredArguments.forEach((n,r)=>{let s=n.defaultValue;n.variadic?r<this.args.length?(s=this.args.slice(r),n.parseArg&&(s=s.reduce((o,l)=>e(n,l,o),n.defaultValue))):s===void 0&&(s=[]):r<this.args.length&&(s=this.args[r],n.parseArg&&(s=e(n,s,n.defaultValue))),t[r]=s}),this.processedArgs=t}_chainOrCall(e,t){return e?.then&&typeof e.then=="function"?e.then(()=>t()):t()}_chainOrCallHooks(e,t){let n=e,r=[];return this._getCommandAndAncestors().reverse().filter(s=>s._lifeCycleHooks[t]!==void 0).forEach(s=>{s._lifeCycleHooks[t].forEach(o=>{r.push({hookedCommand:s,callback:o})})}),t==="postAction"&&r.reverse(),r.forEach(s=>{n=this._chainOrCall(n,()=>s.callback(s.hookedCommand,this))}),n}_chainOrCallSubCommandHook(e,t,n){let r=e;return this._lifeCycleHooks[n]!==void 0&&this._lifeCycleHooks[n].forEach(s=>{r=this._chainOrCall(r,()=>s(this,t))}),r}_parseCommand(e,t){let n=this.parseOptions(t);if(this._parseOptionsEnv(),this._parseOptionsImplied(),e=e.concat(n.operands),t=n.unknown,this.args=e.concat(t),e&&this._findCommand(e[0]))return this._dispatchSubcommand(e[0],e.slice(1),t);if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(e[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(t),this._dispatchSubcommand(this._defaultCommandName,e,t);this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName&&this.help({error:!0}),this._outputHelpIfRequested(n.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let r=()=>{n.unknown.length>0&&this.unknownOption(n.unknown[0])},s=`command:${this.name()}`;if(this._actionHandler){r(),this._processArguments();let o;return o=this._chainOrCallHooks(o,"preAction"),o=this._chainOrCall(o,()=>this._actionHandler(this.processedArgs)),this.parent&&(o=this._chainOrCall(o,()=>{this.parent.emit(s,e,t)})),o=this._chainOrCallHooks(o,"postAction"),o}if(this.parent?.listenerCount(s))r(),this._processArguments(),this.parent.emit(s,e,t);else if(e.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",e,t);this.listenerCount("command:*")?this.emit("command:*",e,t):this.commands.length?this.unknownCommand():(r(),this._processArguments())}else this.commands.length?(r(),this.help({error:!0})):(r(),this._processArguments())}_findCommand(e){if(e)return this.commands.find(t=>t._name===e||t._aliases.includes(e))}_findOption(e){return this.options.find(t=>t.is(e))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(e=>{e.options.forEach(t=>{t.mandatory&&e.getOptionValue(t.attributeName())===void 0&&e.missingMandatoryOptionValue(t)})})}_checkForConflictingLocalOptions(){let e=this.options.filter(n=>{let r=n.attributeName();return this.getOptionValue(r)===void 0?!1:this.getOptionValueSource(r)!=="default"});e.filter(n=>n.conflictsWith.length>0).forEach(n=>{let r=e.find(s=>n.conflictsWith.includes(s.attributeName()));r&&this._conflictingOption(n,r)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(e=>{e._checkForConflictingLocalOptions()})}parseOptions(e){let t=[],n=[],r=t;function s(a){return a.length>1&&a[0]==="-"}let o=a=>/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(a)?!this._getCommandAndAncestors().some(d=>d.options.map(c=>c.short).some(c=>/^-\d$/.test(c))):!1,l=null,h=null,u=0;for(;u<e.length||h;){let a=h??e[u++];if(h=null,a==="--"){r===n&&r.push(a),r.push(...e.slice(u));break}if(l&&(!s(a)||o(a))){this.emit(`option:${l.name()}`,a);continue}if(l=null,s(a)){let d=this._findOption(a);if(d){if(d.required){let c=e[u++];c===void 0&&this.optionMissingArgument(d),this.emit(`option:${d.name()}`,c)}else if(d.optional){let c=null;u<e.length&&(!s(e[u])||o(e[u]))&&(c=e[u++]),this.emit(`option:${d.name()}`,c)}else this.emit(`option:${d.name()}`);l=d.variadic?d:null;continue}}if(a.length>2&&a[0]==="-"&&a[1]!=="-"){let d=this._findOption(`-${a[1]}`);if(d){d.required||d.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${d.name()}`,a.slice(2)):(this.emit(`option:${d.name()}`),h=`-${a.slice(2)}`);continue}}if(/^--[^=]+=/.test(a)){let d=a.indexOf("="),c=this._findOption(a.slice(0,d));if(c&&(c.required||c.optional)){this.emit(`option:${c.name()}`,a.slice(d+1));continue}}if(r===t&&s(a)&&!(this.commands.length===0&&o(a))&&(r=n),(this._enablePositionalOptions||this._passThroughOptions)&&t.length===0&&n.length===0){if(this._findCommand(a)){t.push(a),n.push(...e.slice(u));break}else if(this._getHelpCommand()&&a===this._getHelpCommand().name()){t.push(a,...e.slice(u));break}else if(this._defaultCommandName){n.push(a,...e.slice(u));break}}if(this._passThroughOptions){r.push(a,...e.slice(u));break}r.push(a)}return{operands:t,unknown:n}}opts(){if(this._storeOptionsAsProperties){let e={},t=this.options.length;for(let n=0;n<t;n++){let r=this.options[n].attributeName();e[r]=r===this._versionOptionName?this._version:this[r]}return e}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((e,t)=>Object.assign(e,t.opts()),{})}error(e,t){this._outputConfiguration.outputError(`${e}
22
22
  `,this._outputConfiguration.writeErr),typeof this._showHelpAfterError=="string"?this._outputConfiguration.writeErr(`${this._showHelpAfterError}
23
23
  `):this._showHelpAfterError&&(this._outputConfiguration.writeErr(`
24
- `),this.outputHelp({error:!0}));let n=t||{},r=n.exitCode||1,s=n.code||"commander.error";this._exit(r,s,e)}_parseOptionsEnv(){this.options.forEach(e=>{if(e.envVar&&e.envVar in _.env){let t=e.attributeName();(this.getOptionValue(t)===void 0||["default","config","env"].includes(this.getOptionValueSource(t)))&&(e.required||e.optional?this.emit(`optionEnv:${e.name()}`,_.env[e.envVar]):this.emit(`optionEnv:${e.name()}`))}})}_parseOptionsImplied(){let e=new In(this.options),t=n=>this.getOptionValue(n)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(n));this.options.filter(n=>n.implied!==void 0&&t(n.attributeName())&&e.valueFromOption(this.getOptionValue(n.attributeName()),n)).forEach(n=>{Object.keys(n.implied).filter(r=>!t(r)).forEach(r=>{this.setOptionValueWithSource(r,n.implied[r],"implied")})})}missingArgument(e){let t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){let t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){let t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){let n=o=>{let l=o.attributeName(),h=this.getOptionValue(l),a=this.options.find(d=>d.negate&&l===d.attributeName()),u=this.options.find(d=>!d.negate&&l===d.attributeName());return a&&(a.presetArg===void 0&&h===!1||a.presetArg!==void 0&&h===a.presetArg)?a:u||o},r=o=>{let l=n(o),h=l.attributeName();return this.getOptionValueSource(h)==="env"?`environment variable '${l.envVar}'`:`option '${l.flags}'`},s=`error: ${r(e)} cannot be used with ${r(t)}`;this.error(s,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let r=[],s=this;do{let o=s.createHelp().visibleOptions(s).filter(l=>l.long).map(l=>l.long);r=r.concat(o),s=s.parent}while(s&&!s._enablePositionalOptions);t=ct(e,r)}let n=`error: unknown option '${e}'${t}`;this.error(n,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;let t=this.registeredArguments.length,n=t===1?"":"s",s=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${n} but got ${e.length}.`;this.error(s,{code:"commander.excessArguments"})}unknownCommand(){let e=this.args[0],t="";if(this._showSuggestionAfterError){let r=[];this.createHelp().visibleCommands(this).forEach(s=>{r.push(s.name()),s.alias()&&r.push(s.alias())}),t=ct(e,r)}let n=`error: unknown command '${e}'${t}`;this.error(n,{code:"commander.unknownCommand"})}version(e,t,n){if(e===void 0)return this._version;this._version=e,t=t||"-V, --version",n=n||"output the version number";let r=this.createOption(t,n);return this._versionOptionName=r.attributeName(),this._registerOption(r),this.on("option:"+r.name(),()=>{this._outputConfiguration.writeOut(`${e}
25
- `),this._exit(0,"commander.version",e)}),this}description(e,t){return e===void 0&&t===void 0?this._description:(this._description=e,t&&(this._argsDescription=t),this)}summary(e){return e===void 0?this._summary:(this._summary=e,this)}alias(e){if(e===void 0)return this._aliases[0];let t=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler&&(t=this.commands[this.commands.length-1]),e===t._name)throw new Error("Command alias can't be the same as its name");let n=this.parent?._findCommand(e);if(n){let r=[n.name()].concat(n.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${r}'`)}return t._aliases.push(e),this}aliases(e){return e===void 0?this._aliases:(e.forEach(t=>this.alias(t)),this)}usage(e){if(e===void 0){if(this._usage)return this._usage;let t=this.registeredArguments.map(n=>Nn(n));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?t:[]).join(" ")}return this._usage=e,this}name(e){return e===void 0?this._name:(this._name=e,this)}helpGroup(e){return e===void 0?this._helpGroupHeading??"":(this._helpGroupHeading=e,this)}commandsGroup(e){return e===void 0?this._defaultCommandGroup??"":(this._defaultCommandGroup=e,this)}optionsGroup(e){return e===void 0?this._defaultOptionGroup??"":(this._defaultOptionGroup=e,this)}_initOptionGroup(e){this._defaultOptionGroup&&!e.helpGroupHeading&&e.helpGroup(this._defaultOptionGroup)}_initCommandGroup(e){this._defaultCommandGroup&&!e.helpGroup()&&e.helpGroup(this._defaultCommandGroup)}nameFromFilename(e){return this._name=I.basename(e,I.extname(e)),this}executableDir(e){return e===void 0?this._executableDir:(this._executableDir=e,this)}helpInformation(e){let t=this.createHelp(),n=this._getOutputContext(e);t.prepareContext({error:n.error,helpWidth:n.helpWidth,outputHasColors:n.hasColors});let r=t.formatHelp(this,t);return n.hasColors?r:this._outputConfiguration.stripColor(r)}_getOutputContext(e){e=e||{};let t=!!e.error,n,r,s;return t?(n=l=>this._outputConfiguration.writeErr(l),r=this._outputConfiguration.getErrHasColors(),s=this._outputConfiguration.getErrHelpWidth()):(n=l=>this._outputConfiguration.writeOut(l),r=this._outputConfiguration.getOutHasColors(),s=this._outputConfiguration.getOutHelpWidth()),{error:t,write:l=>(r||(l=this._outputConfiguration.stripColor(l)),n(l)),hasColors:r,helpWidth:s}}outputHelp(e){let t;typeof e=="function"&&(t=e,e=void 0);let n=this._getOutputContext(e),r={error:n.error,write:n.write,command:this};this._getCommandAndAncestors().reverse().forEach(o=>o.emit("beforeAllHelp",r)),this.emit("beforeHelp",r);let s=this.helpInformation({error:n.error});if(t&&(s=t(s),typeof s!="string"&&!Buffer.isBuffer(s)))throw new Error("outputHelp callback must return a string or a Buffer");n.write(s),this._getHelpOption()?.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",r),this._getCommandAndAncestors().forEach(o=>o.emit("afterAllHelp",r))}helpOption(e,t){return typeof e=="boolean"?(e?(this._helpOption===null&&(this._helpOption=void 0),this._defaultOptionGroup&&this._initOptionGroup(this._getHelpOption())):this._helpOption=null,this):(this._helpOption=this.createOption(e??"-h, --help",t??"display help for command"),(e||t)&&this._initOptionGroup(this._helpOption),this)}_getHelpOption(){return this._helpOption===void 0&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(e){return this._helpOption=e,this._initOptionGroup(e),this}help(e){this.outputHelp(e);let t=Number(_.exitCode??0);t===0&&e&&typeof e!="function"&&e.error&&(t=1),this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){let n=["beforeAll","before","after","afterAll"];if(!n.includes(e))throw new Error(`Unexpected value for position to addHelpText.
24
+ `),this.outputHelp({error:!0}));let n=t||{},r=n.exitCode||1,s=n.code||"commander.error";this._exit(r,s,e)}_parseOptionsEnv(){this.options.forEach(e=>{if(e.envVar&&e.envVar in C.env){let t=e.attributeName();(this.getOptionValue(t)===void 0||["default","config","env"].includes(this.getOptionValueSource(t)))&&(e.required||e.optional?this.emit(`optionEnv:${e.name()}`,C.env[e.envVar]):this.emit(`optionEnv:${e.name()}`))}})}_parseOptionsImplied(){let e=new Fn(this.options),t=n=>this.getOptionValue(n)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(n));this.options.filter(n=>n.implied!==void 0&&t(n.attributeName())&&e.valueFromOption(this.getOptionValue(n.attributeName()),n)).forEach(n=>{Object.keys(n.implied).filter(r=>!t(r)).forEach(r=>{this.setOptionValueWithSource(r,n.implied[r],"implied")})})}missingArgument(e){let t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){let t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){let t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){let n=o=>{let l=o.attributeName(),h=this.getOptionValue(l),u=this.options.find(d=>d.negate&&l===d.attributeName()),a=this.options.find(d=>!d.negate&&l===d.attributeName());return u&&(u.presetArg===void 0&&h===!1||u.presetArg!==void 0&&h===u.presetArg)?u:a||o},r=o=>{let l=n(o),h=l.attributeName();return this.getOptionValueSource(h)==="env"?`environment variable '${l.envVar}'`:`option '${l.flags}'`},s=`error: ${r(e)} cannot be used with ${r(t)}`;this.error(s,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let r=[],s=this;do{let o=s.createHelp().visibleOptions(s).filter(l=>l.long).map(l=>l.long);r=r.concat(o),s=s.parent}while(s&&!s._enablePositionalOptions);t=ct(e,r)}let n=`error: unknown option '${e}'${t}`;this.error(n,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;let t=this.registeredArguments.length,n=t===1?"":"s",s=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${n} but got ${e.length}.`;this.error(s,{code:"commander.excessArguments"})}unknownCommand(){let e=this.args[0],t="";if(this._showSuggestionAfterError){let r=[];this.createHelp().visibleCommands(this).forEach(s=>{r.push(s.name()),s.alias()&&r.push(s.alias())}),t=ct(e,r)}let n=`error: unknown command '${e}'${t}`;this.error(n,{code:"commander.unknownCommand"})}version(e,t,n){if(e===void 0)return this._version;this._version=e,t=t||"-V, --version",n=n||"output the version number";let r=this.createOption(t,n);return this._versionOptionName=r.attributeName(),this._registerOption(r),this.on("option:"+r.name(),()=>{this._outputConfiguration.writeOut(`${e}
25
+ `),this._exit(0,"commander.version",e)}),this}description(e,t){return e===void 0&&t===void 0?this._description:(this._description=e,t&&(this._argsDescription=t),this)}summary(e){return e===void 0?this._summary:(this._summary=e,this)}alias(e){if(e===void 0)return this._aliases[0];let t=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler&&(t=this.commands[this.commands.length-1]),e===t._name)throw new Error("Command alias can't be the same as its name");let n=this.parent?._findCommand(e);if(n){let r=[n.name()].concat(n.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${r}'`)}return t._aliases.push(e),this}aliases(e){return e===void 0?this._aliases:(e.forEach(t=>this.alias(t)),this)}usage(e){if(e===void 0){if(this._usage)return this._usage;let t=this.registeredArguments.map(n=>Mn(n));return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?t:[]).join(" ")}return this._usage=e,this}name(e){return e===void 0?this._name:(this._name=e,this)}helpGroup(e){return e===void 0?this._helpGroupHeading??"":(this._helpGroupHeading=e,this)}commandsGroup(e){return e===void 0?this._defaultCommandGroup??"":(this._defaultCommandGroup=e,this)}optionsGroup(e){return e===void 0?this._defaultOptionGroup??"":(this._defaultOptionGroup=e,this)}_initOptionGroup(e){this._defaultOptionGroup&&!e.helpGroupHeading&&e.helpGroup(this._defaultOptionGroup)}_initCommandGroup(e){this._defaultCommandGroup&&!e.helpGroup()&&e.helpGroup(this._defaultCommandGroup)}nameFromFilename(e){return this._name=F.basename(e,F.extname(e)),this}executableDir(e){return e===void 0?this._executableDir:(this._executableDir=e,this)}helpInformation(e){let t=this.createHelp(),n=this._getOutputContext(e);t.prepareContext({error:n.error,helpWidth:n.helpWidth,outputHasColors:n.hasColors});let r=t.formatHelp(this,t);return n.hasColors?r:this._outputConfiguration.stripColor(r)}_getOutputContext(e){e=e||{};let t=!!e.error,n,r,s;return t?(n=l=>this._outputConfiguration.writeErr(l),r=this._outputConfiguration.getErrHasColors(),s=this._outputConfiguration.getErrHelpWidth()):(n=l=>this._outputConfiguration.writeOut(l),r=this._outputConfiguration.getOutHasColors(),s=this._outputConfiguration.getOutHelpWidth()),{error:t,write:l=>(r||(l=this._outputConfiguration.stripColor(l)),n(l)),hasColors:r,helpWidth:s}}outputHelp(e){let t;typeof e=="function"&&(t=e,e=void 0);let n=this._getOutputContext(e),r={error:n.error,write:n.write,command:this};this._getCommandAndAncestors().reverse().forEach(o=>o.emit("beforeAllHelp",r)),this.emit("beforeHelp",r);let s=this.helpInformation({error:n.error});if(t&&(s=t(s),typeof s!="string"&&!Buffer.isBuffer(s)))throw new Error("outputHelp callback must return a string or a Buffer");n.write(s),this._getHelpOption()?.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",r),this._getCommandAndAncestors().forEach(o=>o.emit("afterAllHelp",r))}helpOption(e,t){return typeof e=="boolean"?(e?(this._helpOption===null&&(this._helpOption=void 0),this._defaultOptionGroup&&this._initOptionGroup(this._getHelpOption())):this._helpOption=null,this):(this._helpOption=this.createOption(e??"-h, --help",t??"display help for command"),(e||t)&&this._initOptionGroup(this._helpOption),this)}_getHelpOption(){return this._helpOption===void 0&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(e){return this._helpOption=e,this._initOptionGroup(e),this}help(e){this.outputHelp(e);let t=Number(C.exitCode??0);t===0&&e&&typeof e!="function"&&e.error&&(t=1),this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){let n=["beforeAll","before","after","afterAll"];if(!n.includes(e))throw new Error(`Unexpected value for position to addHelpText.
26
26
  Expecting one of '${n.join("', '")}'`);let r=`${e}Help`;return this.on(r,s=>{let o;typeof t=="function"?o=t({error:s.error,command:s.command}):o=t,o&&s.write(`${o}
27
- `)}),this}_outputHelpIfRequested(e){let t=this._getHelpOption();t&&e.find(r=>t.is(r))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function dt(i){return i.map(e=>{if(!e.startsWith("--inspect"))return e;let t,n="127.0.0.1",r="9229",s;return(s=e.match(/^(--inspect(-brk)?)$/))!==null?t=s[1]:(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(t=s[1],/^\d+$/.test(s[3])?r=s[3]:n=s[3]):(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(t=s[1],n=s[3],r=s[4]),t&&r!=="0"?`${t}=${n}:${parseInt(r)+1}`:e})}function Le(){if(_.env.NO_COLOR||_.env.FORCE_COLOR==="0"||_.env.FORCE_COLOR==="false")return!1;if(_.env.FORCE_COLOR||_.env.CLICOLOR_FORCE!==void 0)return!0}Ie.Command=Me;Ie.useColor=Le});var gt=G(N=>{var{Argument:mt}=ee(),{Command:Fe}=ht(),{CommanderError:Fn,InvalidArgumentError:pt}=J(),{Help:Hn}=xe(),{Option:ft}=Pe();N.program=new Fe;N.createCommand=i=>new Fe(i);N.createOption=(i,e)=>new ft(i,e);N.createArgument=(i,e)=>new mt(i,e);N.Command=Fe;N.Option=ft;N.Argument=mt;N.Help=Hn;N.CommanderError=Fn;N.InvalidArgumentError=pt;N.InvalidOptionArgumentError=pt});var wt=An(gt(),1),{program:_r,createCommand:Cr,createArgument:vr,createOption:Ar,CommanderError:Or,InvalidArgumentError:Rr,InvalidOptionArgumentError:Sr,Command:$t,Argument:xr,Option:Tr,Help:Er}=wt.default;import{existsSync as sr,readFileSync as or,writeFileSync as tt}from"node:fs";import{resolve as q,dirname as ar}from"node:path";import{fileURLToPath as lr}from"node:url";import{DefaultAzureCredential as Un}from"@azure/identity";import*as vt from"azure-devops-node-api";import{BearerCredentialHandler as qn}from"azure-devops-node-api/handlers/bearertoken.js";var F="\x1B[0m",He="\x1B[2m",yt="\x1B[36m",Vn="\x1B[32m",Wn="\x1B[33m",Gn="\x1B[31m",bt="\x1B[1m",_t=!1;function Ct(i){_t=i}function Y(){return He+new Date().toISOString().slice(11,19)+F}function v(i){console.log(`${Y()} ${yt}\u2139${F} ${i}`)}function S(i){console.log(`${Y()} ${Vn}\u2714${F} ${i}`)}function R(i){console.log(`${Y()} ${Wn}\u26A0${F} ${i}`)}function ne(i){console.error(`${Y()} ${Gn}\u2716${F} ${i}`)}function $(i){_t&&console.log(`${Y()} ${He}\xB7 ${i}${F}`)}function Ve(i){console.log(`
28
- ${bt}${yt}\u25B8 ${i}${F}`)}function U(i,e){console.log(` ${He}${i}:${F} ${bt}${e}${F}`)}var Bn="499b84ac-1321-427f-aa17-267ca6975798";async function At(){let i=process.env.SYSTEM_ACCESSTOKEN;if(i)return $("Using SYSTEM_ACCESSTOKEN from Azure Pipelines environment"),i;try{$("Requesting token for Azure DevOps resource via DefaultAzureCredential\u2026");let t=await new Un().getToken(`${Bn}/.default`);return $("Token acquired successfully"),t.token}catch(e){let t=e instanceof Error?e.message:String(e);throw new Error(`Failed to obtain Azure DevOps token. Set SYSTEM_ACCESSTOKEN in Azure Pipelines, or configure environment credentials (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET), or log in with \`az login\`.
29
- ${t}`,{cause:e})}}async function Ot(i,e){$(`Connecting to ${i}\u2026`);let t=new qn(e),n=new vt.WebApi(i,t),r=await n.getGitApi(),s=await n.getBuildApi(),o=await n.getCoreApi();return{gitApi:r,buildApi:s,coreApi:o}}var B=new Map;async function We(i){if(!B.has(i)){let e=await At(),t=await Ot(i,e);B.set(i,t)}return B.get(i).gitApi}async function Rt(i){if(!B.has(i)){let e=await At(),t=await Ot(i,e);B.set(i,t)}return B.get(i).buildApi}import{readFileSync as Xn}from"node:fs";import{resolve as Nt,dirname as Qn}from"node:path";import{fileURLToPath as ei}from"node:url";import{DefaultAzureCredential as Jn}from"@azure/identity";var V=class extends Error{constructor(e){super(e),this.name="NonRetryableError"}},jn={maxAttempts:4,baseDelayMs:2e3,maxDelayMs:3e4};function zn(i){return new Promise(e=>setTimeout(e,i))}async function x(i,e,t){let{maxAttempts:n,baseDelayMs:r,maxDelayMs:s}={...jn,...t};for(let o=1;o<=n;o++)try{return await e()}catch(l){if(l instanceof V)throw l;let h=l instanceof Error?l.message:String(l);if(o===n)throw ne(`${i} failed after ${n} attempts: ${h}`),l;let u=Math.min(r*2**(o-1),s);R(`${i} failed (attempt ${o}/${n}), retrying in ${(u/1e3).toFixed(1)}s\u2026 \u2014 ${h}`),await zn(u)}throw new Error("unreachable")}var Yn="https://graph.microsoft.com/.default",Kn="https://graph.microsoft.com/v1.0";async function St(){try{return(await new Jn().getToken(Yn)).token}catch(i){let e=i instanceof Error?i.message:String(i);throw new Error(`Failed to get Microsoft Graph token. Configure environment credentials (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET), or log in with \`az login\`.
30
- ${e}`,{cause:i})}}async function Zn(i,e){let t=await fetch(e,{headers:{Authorization:`Bearer ${i}`}});if(!t.ok){let n=await t.text();throw t.status>=400&&t.status<500?new V(`Graph API ${t.status}: ${n}`):new Error(`Graph API ${t.status}: ${n}`)}return await t.json()}async function xt(i,e){let t=[],n=`${Kn}/users/${encodeURIComponent(e)}/directReports?$select=mail,userPrincipalName,displayName&$top=999`;for(;n;){let r=await x(`Fetch direct reports for ${e}`,()=>Zn(i,n));for(let s of r.value){let o=s.mail?.toLowerCase(),l=s.userPrincipalName?.toLowerCase();o&&t.push(o),l&&l!==o&&t.push(l)}n=r["@odata.nextLink"]}return t}async function Tt(i){v(`Fetching direct reports for ${i} from Microsoft Graph\u2026`);let e=await St(),t=await xt(e,i);S(`Found ${t.length} direct reports for ${i}`);for(let n of t)$(` ${n}`);return t}async function Et(i){v(`Fetching full org tree under ${i} from Microsoft Graph\u2026`);let e=await St(),t=10,n=[],r=[i.toLowerCase()],s=[i],o=new Set;for(;s.length>0;){let l=s.filter(a=>!o.has(a));for(let a of l)o.add(a);if(l.length===0)break;$(` Processing ${l.length} users (concurrency: ${t})\u2026`);let h=[];for(let a=0;a<l.length;a+=t){let u=l.slice(a,a+t),d=await Promise.all(u.map(async c=>{try{let m=await xt(e,c);return $(` ${c} \u2192 ${m.length} direct reports`),{upn:c,reports:m}}catch(m){if(m instanceof V&&m.message.includes("404"))return R(` ${c} \u2014 not found in directory, keeping as member`),{upn:c,reports:[c]};throw m}}));for(let{upn:c,reports:m}of d){m.length>0&&!(m.length===1&&m[0]===c)&&r.push(c.toLowerCase());for(let f of m)n.push(f),h.push(f)}}s=h}return S(`Found ${n.length} total org members under ${i} (${r.length} managers)`),{members:n,managers:r}}function Dt(i){let e=i.match(/https?:\/\/(?:[^@]+@)?dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/\s]+)/);if(e)return{orgUrl:`https://dev.azure.com/${e[1]}`,project:e[2],repository:e[3]};let t=i.match(/https?:\/\/(?:[^@]+@)?([^.]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/\s]+)/);if(t)return{orgUrl:`https://dev.azure.com/${t[1]}`,project:t[2],repository:t[3]};let n=i.match(/ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\/([^/\s]+)/);if(n)return{orgUrl:`https://dev.azure.com/${n[1]}`,project:n[2],repository:n[3]};let r=i.match(/vs-ssh\.visualstudio\.com:v3\/([^/]+)\/([^/]+)\/([^/\s]+)/);return r?{orgUrl:`https://dev.azure.com/${r[1]}`,project:r[2],repository:r[3]}:null}var ie=[{label:"XS",maxChanges:10},{label:"S",maxChanges:40},{label:"M",maxChanges:100},{label:"L",maxChanges:400},{label:"XL",maxChanges:1e3}];function re(i){return i?.uniqueName?.toLowerCase()??""}function Pt(i,e,t,n){return{totalConflicts:[...i.approved,...i.needingReview,...i.waitingOnAuthor].filter(o=>o.hasMergeConflict).length,mergeRestarted:e,mergeRestartFailed:t,repoStats:n}}function Ge(i,e,t,n){let r=[...e.approved,...e.needingReview,...e.waitingOnAuthor];return{repoLabel:i,approved:e.approved.length,needingReview:e.needingReview.length,waitingOnAuthor:e.waitingOnAuthor.length,conflicts:r.filter(s=>s.hasMergeConflict).length,mergeRestarted:t,mergeRestartFailed:n}}var kt=[{label:"\u26A0\uFE0F Aging",minDays:7},{label:"\u{1F534} Stale",minDays:14},{label:"\u{1F480} Abandoned",minDays:30}];function ti(i){let e=i?Nt(i):Nt(Qn(ei(import.meta.url)),"..","pr-review-config.json"),t=Xn(e,"utf-8");return JSON.parse(t)}function ni(i){if(!i.repositories||i.repositories.length===0)throw new Error("Config must specify 'repositories' (array of repository objects with a 'url' field).");return i.repositories.map(e=>{let t=Dt(e.url);if(!t)throw new Error(`Invalid ADO repository URL: ${e.url}`);return{...t,skipRestartMerge:e.skipRestartMerge??!1,patterns:{ignore:e.patterns?.ignore??[],labels:e.patterns?.labels??{}}}})}async function ii(i){let e=new Set((i.teamMembers??[]).map(n=>n.toLowerCase())),t=new Set;if(i.orgManager){let n=await Et(i.orgManager);for(let r of n.members)e.add(r);if(e.add(i.orgManager.toLowerCase()),i.ignoreManagers)for(let r of n.managers)t.add(r.toLowerCase())}if(i.manager){let n=await Tt(i.manager);for(let r of n)e.add(r);e.add(i.manager.toLowerCase()),i.ignoreManagers&&t.add(i.manager.toLowerCase())}return{teamMembers:e,ignoredUsers:t}}function ri(i){if(i.quantifier?.enabled===!1)return;let e=i.quantifier?.excludedPatterns??[],t=i.quantifier?.thresholds?i.quantifier.thresholds.map(n=>({label:n.label,maxChanges:n.maxChanges})):ie;return{enabled:!0,excludedPatterns:e,thresholds:t}}function si(i){return i.staleness?.enabled===!1?{enabled:!1,thresholds:[]}:{enabled:!0,thresholds:i.staleness?.thresholds?i.staleness.thresholds.map(t=>({label:t.label,minDays:t.minDays})).sort((t,n)=>n.minDays-t.minDays):kt.slice().sort((t,n)=>n.minDays-t.minDays)}}function oi(i){if(!(!i.autoNudge||i.autoNudge.enabled===!1))return{enabled:!0,minStalenessLevel:i.autoNudge.minStalenessLevel,cooldownDays:i.autoNudge.cooldownDays??7,commentTemplate:i.autoNudge.commentTemplate??"\u23F0 This PR has been waiting for review for {{days}} days. Reviewers: {{reviewers}}. Please take a look!",dryRun:i.autoNudge.dryRun??!1,historyFile:i.autoNudge.historyFile??".pr-nudge-history.json"}}async function Mt(i){let e=ti(i),t=ni(e),{teamMembers:n,ignoredUsers:r}=await ii(e),s=new Set((e.botUsers??[]).map(m=>m.toLowerCase())),o=new Set((e.aiBotUsers??[]).map(m=>m.toLowerCase())),l=ri(e),h=e.restartMergeAfterDays??30,a=si(e),u=e.notifications,d=e.webhook,c=oi(e);return{repos:t,teamMembers:n,ignoredUsers:r,botUsers:s,aiBotUsers:o,quantifier:l,restartMergeAfterDays:h,staleness:a,notifications:u,webhook:d,autoNudge:c}}import{PullRequestStatus as ui}from"azure-devops-node-api/interfaces/GitInterfaces.js";import{BuildResult as le,BuildStatus as ue}from"azure-devops-node-api/interfaces/BuildInterfaces.js";import{LineDiffBlockChangeType as se,VersionControlChangeType as Lt}from"azure-devops-node-api/interfaces/GitInterfaces.js";import ai from"picomatch";function oe(i,e=ie){let t=[...e].sort((n,r)=>n.maxChanges-r.maxChanges);for(let n of t)if(i<=n.maxChanges)return n.label;return t[t.length-1].label}function li(i,e){if(e.length===0)return!1;let t=i.replace(/^\//,"");return e.some(n=>n(t))}function It(i){let e=0,t=0;for(let n of i){let r=n.changeType??se.None;r===se.Add?e+=n.modifiedLinesCount??0:r===se.Delete?t+=n.originalLinesCount??0:r===se.Edit&&(e+=n.modifiedLinesCount??0,t+=n.originalLinesCount??0)}return{added:e,deleted:t}}async function Ft(i,e,t,n,r){let s=r.excludedPatterns.map(w=>ai(w,{dot:!0})),o=await x(`Fetch iterations for PR #${n}`,()=>i.getPullRequestIterations(e,n,t));if(!o||o.length===0)return{linesAdded:0,linesDeleted:0,totalChanges:0,label:oe(0,r.thresholds)};let l=o[o.length-1],h=l.id,a=[],u=0,d=100;for(;;){let w=await x(`Fetch iteration changes for PR #${n} iter ${h}`,()=>i.getPullRequestIterationChanges(e,n,h,t,d,u)),E=w.changeEntries??[];for(let M of E){let L=M.item?.path??"",W=M.originalPath;L&&!li(L,s)&&a.push({path:L,originalPath:W??void 0,changeType:M.changeType??0})}if((w.nextSkip??0)===0&&(w.nextTop??0)===0||(u=w.nextSkip??u+d,E.length===0))break}if(a.length===0)return{linesAdded:0,linesDeleted:0,totalChanges:0,label:oe(0,r.thresholds)};let c=l.sourceRefCommit?.commitId,m=l.targetRefCommit?.commitId;if(!c||!m){$(` PR #${n} \u2014 no commit refs, using file count as proxy`);let w=a.length;return{linesAdded:w,linesDeleted:0,totalChanges:w,label:oe(w,r.thresholds)}}let f=a.map(w=>{let E=(w.changeType&Lt.Add)!==0,M=(w.changeType&Lt.Delete)!==0;return{originalPath:E?void 0:w.originalPath??w.path,path:M?void 0:w.path}}),g=0,p=0,C=10,A=0;for(let w=0;w<f.length;w+=C){let E=f.slice(w,w+C),M={baseVersionCommit:m,targetVersionCommit:c,fileDiffParams:E};try{let L=await i.getFileDiffs(M,t,e);for(let W of L){let{added:be,deleted:_e}=It(W.lineDiffBlocks??[]);g+=be,p+=_e}}catch{for(let L of E)try{let W={baseVersionCommit:m,targetVersionCommit:c,fileDiffParams:[L]},be=await i.getFileDiffs(W,t,e);for(let _e of be){let{added:gn,deleted:wn}=It(_e.lineDiffBlocks??[]);g+=gn,p+=wn}}catch{A++}}}A>0&&$(` PR #${n} \u2014 skipped ${A} files (not found at specified version)`);let O=g+p,b=oe(O,r.thresholds);return $(` PR #${n} \u2014 +${g} -${p} = ${O} (${b})`),{linesAdded:g,linesDeleted:p,totalChanges:O,label:b}}async function ae(i,e,t){let n=new Array(i.length),r=0;async function s(){for(;r<i.length;){let l=r++;n[l]=await t(i[l])}}let o=Array.from({length:Math.min(e,i.length)},()=>s());return await Promise.all(o),n}import Ht from"picomatch";function Vt(i,e,t){if(Object.keys(t).length===0)return[];let n=e.map(o=>Ht(o,{dot:!0})),r=i.map(o=>o.replace(/^\//,"")).filter(o=>!n.some(l=>l(o)));if(r.length===0)return[];let s=[];for(let[o,l]of Object.entries(t)){let h=l.map(a=>Ht(a,{dot:!0}));r.some(a=>h.some(u=>u(a)))&&s.push(o)}return s}function ci(i){let e=[],t=0,n=0;for(let r of i){if(r.isDraft){t++,$(` #${r.pullRequestId} \u2014 draft, skipping`);continue}if((r.labels??[]).map(o=>o.name??"").some(o=>o.toUpperCase()==="NO-MERGE")){n++,$(` #${r.pullRequestId} \u2014 NO-MERGE label, skipping`);continue}e.push(r)}return t>0&&$(`Skipped ${t} draft PRs`),n>0&&$(`Skipped ${n} NO-MERGE PRs`),e}async function di(i,e,t,n){let r=await x(`Fetch iterations for PR #${n} (file patterns)`,()=>i.getPullRequestIterations(e,n,t));if(!r||r.length===0)return[];let o=r[r.length-1].id;if(o==null)return[];let l=[],h=0,a=100;for(;;){let u=await x(`Fetch iteration changes for PR #${n} iter ${o} (file patterns)`,()=>i.getPullRequestIterationChanges(e,n,o,t,a,h));for(let d of u.changeEntries??[]){let c=d.item?.path??"";c&&l.push(c)}if((u.nextSkip??0)===0&&(u.nextTop??0)===0||(h=u.nextSkip??h+a,(u.changeEntries??[]).length===0))break}return l}function hi(i,e){if(i===ue.InProgress)return"inProgress";if(i===ue.NotStarted)return"notStarted";switch(e){case le.Succeeded:return"succeeded";case le.Failed:return"failed";case le.PartiallySucceeded:return"partiallySucceeded";case le.Canceled:return"canceled";default:return"none"}}async function mi(i,e,t,n){try{let r=`refs/pull/${n}/merge`,s=await x(`Fetch builds for PR #${n}`,()=>i.getBuilds(t,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,10,void 0,void 0,void 0,void 0,r,void 0,e,"TfsGit"));if(!s||s.length===0)return;let o=new Map;for(let c of s){let m=c.definition?.id??0;o.has(m)||o.set(m,c)}let l=[],h=0,a=0,u=0,d=0;for(let c of o.values()){let m=hi(c.status,c.result);switch(l.push({id:c.id??0,name:c.definition?.name??"Unknown",status:ue[c.status??ue.None]??"None",result:m}),m){case"succeeded":h++;break;case"failed":a++;break;case"inProgress":case"notStarted":u++;break;default:d++;break}}return{total:l.length,succeeded:h,failed:a,inProgress:u,other:d,runs:l}}catch(r){let s=r instanceof Error?r.message:String(r);$(` #${n} \u2014 failed to fetch pipeline status: ${s}`);return}}async function Wt(i,e,t,n,r,s={ignore:[],labels:{}},o){let l;try{let c=new URL(n);c.hostname.endsWith(".visualstudio.com")?l=`https://dev.azure.com/${c.hostname.replace(".visualstudio.com","")}`:l=n.replace(/\/$/,"")}catch{l=n.replace(/\/$/,"")}let h=await x("Fetch pull requests",()=>i.getPullRequests(e,{status:ui.Active},t));$(`API returned ${h.length} active pull requests`);let a;if(o)try{a=(await x("Resolve repository GUID",()=>i.getRepository(e,t))).id}catch(c){let m=c instanceof Error?c.message:String(c);$(`Failed to resolve repository GUID for ${e}: ${m}`)}let u=ci(h);v(`Fetching threads for ${u.length} PRs in ${t}/${e} (concurrency: ${10})\u2026`);let d=await ae(u,10,async c=>{let m=c.pullRequestId;$(` #${m} \u2014 fetching threads\u2026`);let g=(await x(`Fetch threads for PR #${m}`,()=>i.getThreads(e,m,t))).map(w=>({id:w.id??0,publishedDate:new Date(w.publishedDate??0),comments:(w.comments??[]).filter(E=>!E.isDeleted).map(E=>({authorUniqueName:re(E.author),publishedDate:new Date(E.publishedDate??0)}))})),p=(c.reviewers??[]).map(w=>({displayName:w.displayName??"",uniqueName:re(w),vote:w.vote??0})),C=`${l}/${t}/_git/${e}/pullrequest/${m}`,A=(c.labels??[]).map(w=>w.name??""),O=[];if(Object.keys(s.labels).length>0){let w=await di(i,e,t,m);O=Vt(w,s.ignore,s.labels),O.length>0&&$(` #${m} \u2014 detected labels: ${O.join(", ")}`)}let b=o&&a?await mi(o,a,t,m):void 0;return{id:m,title:c.title??"(no title)",author:c.createdBy?.displayName??"Unknown",authorUniqueName:re(c.createdBy),url:C,createdDate:new Date(c.creationDate??0),reviewers:p,threads:g,labels:A,detectedLabels:O,mergeStatus:c.mergeStatus??0,lastSourcePushDate:c.lastMergeSourceCommit?.committer?.date?new Date(c.lastMergeSourceCommit.committer.date):void 0,size:r?await Ft(i,e,t,m,r):void 0,description:c.description??void 0,sourceBranch:c.sourceRefName??void 0,targetBranch:c.targetRefName??void 0,pipelineStatus:b}});return $(`${d.length} PRs remain after filtering`),d}async function Gt(i,e,t,n){for(let r of n)if(r.detectedLabels.length!==0){for(let s of r.detectedLabels)if(!r.labels.some(o=>o.toLowerCase()===s.toLowerCase()))try{await x(`Add label '${s}' to PR #${r.id}`,()=>i.createPullRequestLabel({name:s},e,r.id,t)),r.labels.push(s),$(` #${r.id} \u2014 added label '${s}'`)}catch(o){let l=o instanceof Error?o.message:String(o);$(` #${r.id} \u2014 failed to add label '${s}': ${l}`)}}}var pi=1440*60*1e3,fi=["TF401398","TF401027"],gi=["TF401027"];async function Ut(i,e,t,n,r,s=new Date){if(r<0)return $("Restart merge is disabled (restartMergeAfterDays < 0)"),{restarted:0,failed:0,restartedPrIds:[]};let o=new Date(s.getTime()-r*pi),l=n.filter(d=>d.createdDate<o);if(l.length===0)return $("No PRs older than the restart-merge threshold"),{restarted:0,failed:0,restartedPrIds:[]};v(`Restarting merge for ${l.length} PR(s) older than ${r} days\u2026`);let h=0,a=0,u=[];for(let d of l)try{await x(`Restart merge for PR #${d.id}`,async()=>{try{return await i.updatePullRequest({mergeStatus:1},e,d.id,t)}catch(c){let m=c instanceof Error?c.message:String(c);throw fi.some(f=>m.includes(f))?new V(m):c}}),$(` #${d.id} "${d.title}" \u2014 merge restarted`),h++,u.push(d.id)}catch(c){let m=c instanceof Error?c.message:String(c);if(R(` #${d.id} "${d.title}" \u2014 failed to restart merge: ${m}`),a++,gi.some(f=>m.includes(f))){R("Stopping restart-merge for this repository due to permission error"),a+=l.length-l.indexOf(d)-1;break}}return S(`Restarted merge for ${h}/${l.length} PR(s)`),{restarted:h,failed:a,restartedPrIds:u}}import{PullRequestAsyncStatus as Ue}from"azure-devops-node-api/interfaces/GitInterfaces.js";var wi=["build","[bot]","team foundation","microsoft.visualstudio.com"],$i=["dependabot[bot]","renovate[bot]","github-actions[bot]","snyk-bot","greenkeeper[bot]","depfu[bot]","imgbot[bot]","allcontributors[bot]"],qt=["github copilot","copilot[bot]","claude","codex"];function Be(i,e=new Set,t){let n=i.toLowerCase();return!!(e.has(n)||wi.some(r=>n.includes(r))||t&&e.has(t.toLowerCase()))}function ce(i,e=new Set,t){let n=i.toLowerCase();if(e.has(n)||qt.some(r=>n.includes(r)))return!0;if(t){let r=t.toLowerCase();if(e.has(r)||qt.some(s=>r.includes(s)))return!0}return!1}function de(i,e=new Set,t,n=new Set){let r=i.toLowerCase();return $i.some(s=>r.includes(s))||Be(r,e,t)||ce(r,n,t)}function yi(i,e=new Set,t){return ce(i,e,t)}function qe(i,e,t=new Set,n,r=new Set){if(yi(e,r,n))switch(i){case"approved":return"APPROVE";case"needingReview":return"REVIEW";case"waitingOnAuthor":return"PENDING"}if(de(e,t,n,r))return"APPROVE";switch(i){case"approved":return"APPROVE";case"needingReview":return"REVIEW";case"waitingOnAuthor":return"PENDING"}}function je(i,e=new Set,t=new Set){let n=i.authorUniqueName,r=[];for(let s of i.threads)for(let o of s.comments)Be(o.authorUniqueName,e)||ce(o.authorUniqueName,t)||r.push({date:o.publishedDate,isAuthor:o.authorUniqueName===n});return i.lastSourcePushDate&&r.push({date:i.lastSourcePushDate,isAuthor:!0}),r}function Bt(i,e=new Set,t,n=new Set,r=new Set,s=new Set){let o=[],l=[],h=[];for(let a of i){if(n.has(a.authorUniqueName)){$(` #${a.id} "${a.title}" \u2014 author ${a.authorUniqueName} is ignored, skipping`);continue}let u=e.size===0||e.has(a.authorUniqueName);if(a.reviewers.some(b=>b.vote>=5&&!Be(b.uniqueName,r,b.displayName)&&!ce(b.uniqueName,s,b.displayName))){let b=a.mergeStatus===Ue.Conflicts;$(` #${a.id} "${a.title}" \u2014 approved`),o.push({id:a.id,title:a.title,author:a.author,url:a.url,createdDate:a.createdDate,hasMergeConflict:b,isTeamMember:u,action:qe("approved",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,pipelineStatus:a.pipelineStatus});continue}let c=je(a,r,s),m=c.filter(b=>b.isAuthor).sort((b,w)=>b.date.getTime()-w.date.getTime()),f=c.filter(b=>!b.isAuthor).sort((b,w)=>b.date.getTime()-w.date.getTime()),g=m.length>0?m[m.length-1]:null,p=f.length>0?f[f.length-1]:null,C=!1;if(g&&p?C=g.date.getTime()>p.date.getTime():(g&&!p||!g&&!p)&&(C=!0),!C){let b=a.mergeStatus===Ue.Conflicts;$(` #${a.id} "${a.title}" \u2014 reviewer acted last`),h.push({id:a.id,title:a.title,author:a.author,url:a.url,lastReviewerActivityDate:p.date,hasMergeConflict:b,isTeamMember:u,action:qe("waitingOnAuthor",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,pipelineStatus:a.pipelineStatus});continue}let A;p?A=m.find(w=>w.date.getTime()>p.date.getTime())?.date??a.createdDate:A=a.createdDate;let O=a.mergeStatus===Ue.Conflicts;$(` #${a.id} "${a.title}" \u2014 needs review (waiting since ${A.toISOString()}${O?", has conflicts":""})`),l.push({id:a.id,title:a.title,author:a.author,url:a.url,waitingSince:A,hasMergeConflict:O,isTeamMember:u,action:qe("needingReview",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,reviewerNames:a.reviewers.map(b=>b.displayName),pipelineStatus:a.pipelineStatus})}return $(`${o.length} approved PRs`),$(`${h.length} PRs waiting on author`),o.sort((a,u)=>a.createdDate.getTime()-u.createdDate.getTime()),l.sort((a,u)=>a.waitingSince.getTime()-u.waitingSince.getTime()),h.sort((a,u)=>a.lastReviewerActivityDate.getTime()-u.lastReviewerActivityDate.getTime()),{approved:o,needingReview:l,waitingOnAuthor:h}}function jt(i){let e=i.flatMap(r=>r.approved),t=i.flatMap(r=>r.needingReview),n=i.flatMap(r=>r.waitingOnAuthor);return e.sort((r,s)=>r.createdDate.getTime()-s.createdDate.getTime()),t.sort((r,s)=>r.waitingSince.getTime()-s.waitingSince.getTime()),n.sort((r,s)=>r.lastReviewerActivityDate.getTime()-s.lastReviewerActivityDate.getTime()),{approved:e,needingReview:t,waitingOnAuthor:n}}function D(i,e,t=new Date){if(e.length===0)return null;let n=t.getTime()-i.getTime(),r=Math.floor(n/(1e3*60*60*24));for(let s of e)if(r>=s.minDays)return s.label;return null}function he(i,e=new Date){let t=e.getTime()-i.getTime(),n=Math.floor(t/(1e3*60*60*24)),r=Math.floor(t/(1e3*60*60)),s=Math.floor(t/(1e3*60)),o;return n>3?o="high":n>1?o="medium":o="low",{days:n,hours:r,minutes:s,urgency:o}}function me(i){return i==="XS"||i==="S"?"low":i==="M"?"medium":"high"}function pe(i,e){let{approved:t,needingReview:n,waitingOnAuthor:r}=i,s=t.length+n.length+r.length,o=`Total: ${s} open PR${s===1?"":"s"} \u2014 ${t.length} approved, ${n.length} needing review, ${r.length} waiting on author`;return e&&(o+=`, ${e.totalConflicts} with conflicts`,(e.mergeRestarted>0||e.mergeRestartFailed>0)&&(o+=`, ${e.mergeRestarted} merge restarted`,e.mergeRestartFailed>0&&(o+=` (${e.mergeRestartFailed} failed)`))),o}function Z(i){return i?i.failed>0?`\u{1F534} ${i.failed}/${i.total} failed`:i.inProgress>0?`\u{1F7E1} ${i.inProgress}/${i.total} running`:i.succeeded===i.total?`\u{1F7E2} ${i.total}/${i.total} passed`:`\u26AA ${i.total} pipeline(s)`:""}function zt(i,e=new Date){let t=he(i,e),n=t.urgency==="high"?"\u{1F534}":t.urgency==="medium"?"\u{1F7E1}":"\u{1F7E2}",r;return t.days>0?r=`${t.days} day${t.days===1?"":"s"} ago`:t.hours>0?r=`${t.hours} hour${t.hours===1?"":"s"} ago`:r=`${t.minutes} minute${t.minutes===1?"":"s"} ago`,`${n} ${r}`}function Jt(i){let e=me(i.label);return`${e==="low"?"\u{1F7E2}":e==="medium"?"\u{1F7E1}":"\u{1F534}"} ${i.label}`}function Yt(i){switch(i){case"APPROVE":return"\u{1F7E2} APPROVE";case"REVIEW":return"\u{1F50D} REVIEW";case"PENDING":return"\u23F3 PENDING"}}function Kt(i){return!i||i.length===0?"":" "+i.map(e=>`\`${H(e)}\``).join(" ")}function H(i){return i.replace(/[\r\n]+/g," ").trim().replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/\|/g,"\\|")}function ze(i,e,t,n,r=!1){if(i.length===0)return`_${t}_
27
+ `)}),this}_outputHelpIfRequested(e){let t=this._getHelpOption();t&&e.find(r=>t.is(r))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function dt(i){return i.map(e=>{if(!e.startsWith("--inspect"))return e;let t,n="127.0.0.1",r="9229",s;return(s=e.match(/^(--inspect(-brk)?)$/))!==null?t=s[1]:(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(t=s[1],/^\d+$/.test(s[3])?r=s[3]:n=s[3]):(s=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(t=s[1],n=s[3],r=s[4]),t&&r!=="0"?`${t}=${n}:${parseInt(r)+1}`:e})}function Le(){if(C.env.NO_COLOR||C.env.FORCE_COLOR==="0"||C.env.FORCE_COLOR==="false")return!1;if(C.env.FORCE_COLOR||C.env.CLICOLOR_FORCE!==void 0)return!0}Ie.Command=Me;Ie.useColor=Le});var gt=W(M=>{var{Argument:mt}=ne(),{Command:Fe}=ht(),{CommanderError:Hn,InvalidArgumentError:pt}=K(),{Help:Vn}=xe(),{Option:ft}=Pe();M.program=new Fe;M.createCommand=i=>new Fe(i);M.createOption=(i,e)=>new ft(i,e);M.createArgument=(i,e)=>new mt(i,e);M.Command=Fe;M.Option=ft;M.Argument=mt;M.Help=Vn;M.CommanderError=Hn;M.InvalidArgumentError=pt;M.InvalidOptionArgumentError=pt});var wt=Sn(gt(),1),{program:Cr,createCommand:vr,createArgument:Ar,createOption:Sr,CommanderError:Or,InvalidArgumentError:Rr,InvalidOptionArgumentError:xr,Command:$t,Argument:Tr,Option:Er,Help:Dr}=wt.default;import{existsSync as or,readFileSync as ar,writeFileSync as tt}from"node:fs";import{resolve as B,dirname as lr}from"node:path";import{fileURLToPath as ur}from"node:url";import{DefaultAzureCredential as Bn}from"@azure/identity";import*as vt from"azure-devops-node-api";import{BearerCredentialHandler as qn}from"azure-devops-node-api/handlers/bearertoken.js";var H="\x1B[0m",He="\x1B[2m",yt="\x1B[36m",Un="\x1B[32m",Wn="\x1B[33m",Gn="\x1B[31m",bt="\x1B[1m",_t=!1;function Ct(i){_t=i}function Z(){return He+new Date().toISOString().slice(11,19)+H}function S(i){console.log(`${Z()} ${yt}\u2139${H} ${i}`)}function x(i){console.log(`${Z()} ${Un}\u2714${H} ${i}`)}function O(i){console.log(`${Z()} ${Wn}\u26A0${H} ${i}`)}function re(i){console.error(`${Z()} ${Gn}\u2716${H} ${i}`)}function $(i){_t&&console.log(`${Z()} ${He}\xB7 ${i}${H}`)}function Ve(i){console.log(`
28
+ ${bt}${yt}\u25B8 ${i}${H}`)}function G(i,e){console.log(` ${He}${i}:${H} ${bt}${e}${H}`)}var jn="499b84ac-1321-427f-aa17-267ca6975798";async function At(){let i=process.env.SYSTEM_ACCESSTOKEN;if(i)return $("Using SYSTEM_ACCESSTOKEN from Azure Pipelines environment"),i;try{$("Requesting token for Azure DevOps resource via DefaultAzureCredential\u2026");let t=await new Bn().getToken(`${jn}/.default`);return $("Token acquired successfully"),t.token}catch(e){let t=e instanceof Error?e.message:String(e);throw new Error(`Failed to obtain Azure DevOps token. Set SYSTEM_ACCESSTOKEN in Azure Pipelines, or configure environment credentials (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET), or log in with \`az login\`.
29
+ ${t}`,{cause:e})}}async function St(i,e){$(`Connecting to ${i}\u2026`);let t=new qn(e),n=new vt.WebApi(i,t),r=await n.getGitApi(),s=await n.getBuildApi(),o=await n.getCoreApi();return{gitApi:r,buildApi:s,coreApi:o}}var q=new Map;async function Ue(i){if(!q.has(i)){let e=await At(),t=await St(i,e);q.set(i,t)}return q.get(i).gitApi}async function Ot(i){if(!q.has(i)){let e=await At(),t=await St(i,e);q.set(i,t)}return q.get(i).buildApi}import{readFileSync as Qn}from"node:fs";import{resolve as Nt,dirname as ei}from"node:path";import{fileURLToPath as ti}from"node:url";import{DefaultAzureCredential as Yn}from"@azure/identity";var V=class extends Error{constructor(e){super(e),this.name="NonRetryableError"}},zn={maxAttempts:4,baseDelayMs:2e3,maxDelayMs:3e4};function Jn(i){return new Promise(e=>setTimeout(e,i))}async function E(i,e,t){let{maxAttempts:n,baseDelayMs:r,maxDelayMs:s}={...zn,...t};for(let o=1;o<=n;o++)try{return await e()}catch(l){if(l instanceof V)throw l;let h=l instanceof Error?l.message:String(l);if(o===n)throw re(`${i} failed after ${n} attempts: ${h}`),l;let a=Math.min(r*2**(o-1),s);O(`${i} failed (attempt ${o}/${n}), retrying in ${(a/1e3).toFixed(1)}s\u2026 \u2014 ${h}`),await Jn(a)}throw new Error("unreachable")}var Kn="https://graph.microsoft.com/.default",Zn="https://graph.microsoft.com/v1.0";async function Rt(){try{return(await new Yn().getToken(Kn)).token}catch(i){let e=i instanceof Error?i.message:String(i);throw new Error(`Failed to get Microsoft Graph token. Configure environment credentials (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET), or log in with \`az login\`.
30
+ ${e}`,{cause:i})}}async function Xn(i,e){let t=await fetch(e,{headers:{Authorization:`Bearer ${i}`}});if(!t.ok){let n=await t.text();throw t.status>=400&&t.status<500?new V(`Graph API ${t.status}: ${n}`):new Error(`Graph API ${t.status}: ${n}`)}return await t.json()}async function xt(i,e){let t=[],n=`${Zn}/users/${encodeURIComponent(e)}/directReports?$select=mail,userPrincipalName,displayName&$top=999`;for(;n;){let r=await E(`Fetch direct reports for ${e}`,()=>Xn(i,n));for(let s of r.value){let o=s.mail?.toLowerCase(),l=s.userPrincipalName?.toLowerCase();o&&t.push(o),l&&l!==o&&t.push(l)}n=r["@odata.nextLink"]}return t}async function Tt(i){S(`Fetching direct reports for ${i} from Microsoft Graph\u2026`);let e=await Rt(),t=await xt(e,i);x(`Found ${t.length} direct reports for ${i}`);for(let n of t)$(` ${n}`);return t}async function Et(i){S(`Fetching full org tree under ${i} from Microsoft Graph\u2026`);let e=await Rt(),t=10,n=[],r=[i.toLowerCase()],s=[i],o=new Set;for(;s.length>0;){let l=s.filter(u=>!o.has(u));for(let u of l)o.add(u);if(l.length===0)break;$(` Processing ${l.length} users (concurrency: ${t})\u2026`);let h=[];for(let u=0;u<l.length;u+=t){let a=l.slice(u,u+t),d=await Promise.all(a.map(async c=>{try{let m=await xt(e,c);return $(` ${c} \u2192 ${m.length} direct reports`),{upn:c,reports:m}}catch(m){if(m instanceof V&&m.message.includes("404"))return O(` ${c} \u2014 not found in directory, keeping as member`),{upn:c,reports:[c]};throw m}}));for(let{upn:c,reports:m}of d){m.length>0&&!(m.length===1&&m[0]===c)&&r.push(c.toLowerCase());for(let p of m)n.push(p),h.push(p)}}s=h}return x(`Found ${n.length} total org members under ${i} (${r.length} managers)`),{members:n,managers:r}}function Dt(i){let e=i.match(/https?:\/\/(?:[^@]+@)?dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/\s]+)/);if(e)return{orgUrl:`https://dev.azure.com/${e[1]}`,project:e[2],repository:e[3]};let t=i.match(/https?:\/\/(?:[^@]+@)?([^.]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/\s]+)/);if(t)return{orgUrl:`https://dev.azure.com/${t[1]}`,project:t[2],repository:t[3]};let n=i.match(/ssh\.dev\.azure\.com:v3\/([^/]+)\/([^/]+)\/([^/\s]+)/);if(n)return{orgUrl:`https://dev.azure.com/${n[1]}`,project:n[2],repository:n[3]};let r=i.match(/vs-ssh\.visualstudio\.com:v3\/([^/]+)\/([^/]+)\/([^/\s]+)/);return r?{orgUrl:`https://dev.azure.com/${r[1]}`,project:r[2],repository:r[3]}:null}var se=[{label:"XS",maxChanges:10},{label:"S",maxChanges:40},{label:"M",maxChanges:100},{label:"L",maxChanges:400},{label:"XL",maxChanges:1e3}];function oe(i){return i?.uniqueName?.toLowerCase()??""}function Pt(i,e,t,n){return{totalConflicts:[...i.approved,...i.needingReview,...i.waitingOnAuthor].filter(o=>o.hasMergeConflict).length,mergeRestarted:e,mergeRestartFailed:t,repoStats:n}}function We(i,e,t,n){let r=[...e.approved,...e.needingReview,...e.waitingOnAuthor];return{repoLabel:i,approved:e.approved.length,needingReview:e.needingReview.length,waitingOnAuthor:e.waitingOnAuthor.length,conflicts:r.filter(s=>s.hasMergeConflict).length,mergeRestarted:t,mergeRestartFailed:n}}var kt=[{label:"\u26A0\uFE0F Aging",minDays:7},{label:"\u{1F534} Stale",minDays:14},{label:"\u{1F480} Abandoned",minDays:30}];function ni(i){let e=i?Nt(i):Nt(ei(ti(import.meta.url)),"..","pr-review-config.json"),t=Qn(e,"utf-8");return JSON.parse(t)}function ii(i){if(!i.repositories||i.repositories.length===0)throw new Error("Config must specify 'repositories' (array of repository objects with a 'url' field).");return i.repositories.map(e=>{let t=Dt(e.url);if(!t)throw new Error(`Invalid ADO repository URL: ${e.url}`);return{...t,skipRestartMerge:e.skipRestartMerge??!1,patterns:{ignore:e.patterns?.ignore??[],labels:e.patterns?.labels??{}}}})}async function ri(i){let e=new Set((i.teamMembers??[]).map(n=>n.toLowerCase())),t=new Set;if(i.orgManager){let n=await Et(i.orgManager);for(let r of n.members)e.add(r);if(e.add(i.orgManager.toLowerCase()),i.ignoreManagers)for(let r of n.managers)t.add(r.toLowerCase())}if(i.manager){let n=await Tt(i.manager);for(let r of n)e.add(r);e.add(i.manager.toLowerCase()),i.ignoreManagers&&t.add(i.manager.toLowerCase())}return{teamMembers:e,ignoredUsers:t}}function si(i){if(i.quantifier?.enabled===!1)return;let e=i.quantifier?.excludedPatterns??[],t=i.quantifier?.thresholds?i.quantifier.thresholds.map(n=>({label:n.label,maxChanges:n.maxChanges})):se;return{enabled:!0,excludedPatterns:e,thresholds:t}}function oi(i){return i.staleness?.enabled===!1?{enabled:!1,thresholds:[]}:{enabled:!0,thresholds:i.staleness?.thresholds?i.staleness.thresholds.map(t=>({label:t.label,minDays:t.minDays})).sort((t,n)=>n.minDays-t.minDays):kt.slice().sort((t,n)=>n.minDays-t.minDays)}}function ai(i){if(!(!i.autoNudge||i.autoNudge.enabled===!1))return{enabled:!0,minStalenessLevel:i.autoNudge.minStalenessLevel,cooldownDays:i.autoNudge.cooldownDays??7,commentTemplate:i.autoNudge.commentTemplate??"\u23F0 This PR has been waiting for review for {{days}} days. Reviewers: {{reviewers}}. Please take a look!",dryRun:i.autoNudge.dryRun??!1,historyFile:i.autoNudge.historyFile??".pr-nudge-history.json"}}async function Mt(i){let e=ni(i),t=ii(e),{teamMembers:n,ignoredUsers:r}=await ri(e),s=new Set((e.botUsers??[]).map(p=>p.toLowerCase())),o=new Set((e.aiBotUsers??[]).map(p=>p.toLowerCase())),l=new Set((e.starredUsers??[]).map(p=>p.toLowerCase())),h=si(e),u=e.restartMergeAfterDays??30,a=oi(e),d=e.notifications,c=e.webhook,m=ai(e);return{repos:t,teamMembers:n,ignoredUsers:r,botUsers:s,aiBotUsers:o,starredUsers:l,quantifier:h,restartMergeAfterDays:u,staleness:a,notifications:d,webhook:c,autoNudge:m}}import{PullRequestStatus as ci}from"azure-devops-node-api/interfaces/GitInterfaces.js";import{BuildResult as ce,BuildStatus as de}from"azure-devops-node-api/interfaces/BuildInterfaces.js";import{LineDiffBlockChangeType as ae,VersionControlChangeType as Lt}from"azure-devops-node-api/interfaces/GitInterfaces.js";import li from"picomatch";function le(i,e=se){let t=[...e].sort((n,r)=>n.maxChanges-r.maxChanges);for(let n of t)if(i<=n.maxChanges)return n.label;return t[t.length-1].label}function ui(i,e){if(e.length===0)return!1;let t=i.replace(/^\//,"");return e.some(n=>n(t))}function It(i){let e=0,t=0;for(let n of i){let r=n.changeType??ae.None;r===ae.Add?e+=n.modifiedLinesCount??0:r===ae.Delete?t+=n.originalLinesCount??0:r===ae.Edit&&(e+=n.modifiedLinesCount??0,t+=n.originalLinesCount??0)}return{added:e,deleted:t}}async function Ft(i,e,t,n,r){let s=r.excludedPatterns.map(w=>li(w,{dot:!0})),o=await E(`Fetch iterations for PR #${n}`,()=>i.getPullRequestIterations(e,n,t));if(!o||o.length===0)return{linesAdded:0,linesDeleted:0,totalChanges:0,label:le(0,r.thresholds)};let l=o[o.length-1],h=l.id,u=[],a=0,d=100;for(;;){let w=await E(`Fetch iteration changes for PR #${n} iter ${h}`,()=>i.getPullRequestIterationChanges(e,n,h,t,d,a)),y=w.changeEntries??[];for(let T of y){let I=T.item?.path??"",U=T.originalPath;I&&!ui(I,s)&&u.push({path:I,originalPath:U??void 0,changeType:T.changeType??0})}if((w.nextSkip??0)===0&&(w.nextTop??0)===0||(a=w.nextSkip??a+d,y.length===0))break}if(u.length===0)return{linesAdded:0,linesDeleted:0,totalChanges:0,label:le(0,r.thresholds)};let c=l.sourceRefCommit?.commitId,m=l.targetRefCommit?.commitId;if(!c||!m){$(` PR #${n} \u2014 no commit refs, using file count as proxy`);let w=u.length;return{linesAdded:w,linesDeleted:0,totalChanges:w,label:le(w,r.thresholds)}}let p=u.map(w=>{let y=(w.changeType&Lt.Add)!==0,T=(w.changeType&Lt.Delete)!==0;return{originalPath:y?void 0:w.originalPath??w.path,path:T?void 0:w.path}}),g=0,f=0,A=10,b=0;for(let w=0;w<p.length;w+=A){let y=p.slice(w,w+A),T={baseVersionCommit:m,targetVersionCommit:c,fileDiffParams:y};try{let I=await i.getFileDiffs(T,t,e);for(let U of I){let{added:z,deleted:J}=It(U.lineDiffBlocks??[]);g+=z,f+=J}}catch{for(let I of y)try{let U={baseVersionCommit:m,targetVersionCommit:c,fileDiffParams:[I]},z=await i.getFileDiffs(U,t,e);for(let J of z){let{added:wn,deleted:$n}=It(J.lineDiffBlocks??[]);g+=wn,f+=$n}}catch{b++}}}b>0&&$(` PR #${n} \u2014 skipped ${b} files (not found at specified version)`);let v=g+f,R=le(v,r.thresholds);return $(` PR #${n} \u2014 +${g} -${f} = ${v} (${R})`),{linesAdded:g,linesDeleted:f,totalChanges:v,label:R}}async function ue(i,e,t){let n=new Array(i.length),r=0;async function s(){for(;r<i.length;){let l=r++;n[l]=await t(i[l])}}let o=Array.from({length:Math.min(e,i.length)},()=>s());return await Promise.all(o),n}import Ht from"picomatch";function Vt(i,e,t){if(Object.keys(t).length===0)return[];let n=e.map(o=>Ht(o,{dot:!0})),r=i.map(o=>o.replace(/^\//,"")).filter(o=>!n.some(l=>l(o)));if(r.length===0)return[];let s=[];for(let[o,l]of Object.entries(t)){let h=l.map(u=>Ht(u,{dot:!0}));r.some(u=>h.some(a=>a(u)))&&s.push(o)}return s}function di(i){let e=[],t=0,n=0;for(let r of i){if(r.isDraft){t++,$(` #${r.pullRequestId} \u2014 draft, skipping`);continue}if((r.labels??[]).map(o=>o.name??"").some(o=>o.toUpperCase()==="NO-MERGE")){n++,$(` #${r.pullRequestId} \u2014 NO-MERGE label, skipping`);continue}e.push(r)}return t>0&&$(`Skipped ${t} draft PRs`),n>0&&$(`Skipped ${n} NO-MERGE PRs`),e}async function hi(i,e,t,n){let r=await E(`Fetch iterations for PR #${n} (file patterns)`,()=>i.getPullRequestIterations(e,n,t));if(!r||r.length===0)return[];let o=r[r.length-1].id;if(o==null)return[];let l=[],h=0,u=100;for(;;){let a=await E(`Fetch iteration changes for PR #${n} iter ${o} (file patterns)`,()=>i.getPullRequestIterationChanges(e,n,o,t,u,h));for(let d of a.changeEntries??[]){let c=d.item?.path??"";c&&l.push(c)}if((a.nextSkip??0)===0&&(a.nextTop??0)===0||(h=a.nextSkip??h+u,(a.changeEntries??[]).length===0))break}return l}function mi(i,e){if(i===de.InProgress)return"inProgress";if(i===de.NotStarted)return"notStarted";switch(e){case ce.Succeeded:return"succeeded";case ce.Failed:return"failed";case ce.PartiallySucceeded:return"partiallySucceeded";case ce.Canceled:return"canceled";default:return"none"}}async function pi(i,e,t,n){try{let r=`refs/pull/${n}/merge`,s=await E(`Fetch builds for PR #${n}`,()=>i.getBuilds(t,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,10,void 0,void 0,void 0,void 0,r,void 0,e,"TfsGit"));if(!s||s.length===0)return;let o=new Map;for(let c of s){let m=c.definition?.id??0;o.has(m)||o.set(m,c)}let l=[],h=0,u=0,a=0,d=0;for(let c of o.values()){let m=mi(c.status,c.result);switch(l.push({id:c.id??0,name:c.definition?.name??"Unknown",status:de[c.status??de.None]??"None",result:m}),m){case"succeeded":h++;break;case"failed":u++;break;case"inProgress":case"notStarted":a++;break;default:d++;break}}return{total:l.length,succeeded:h,failed:u,inProgress:a,other:d,runs:l}}catch(r){let s=r instanceof Error?r.message:String(r);$(` #${n} \u2014 failed to fetch pipeline status: ${s}`);return}}async function Ut(i,e,t,n,r,s={ignore:[],labels:{}},o){let l;try{let c=new URL(n);c.hostname.endsWith(".visualstudio.com")?l=`https://dev.azure.com/${c.hostname.replace(".visualstudio.com","")}`:l=n.replace(/\/$/,"")}catch{l=n.replace(/\/$/,"")}let h=await E("Fetch pull requests",()=>i.getPullRequests(e,{status:ci.Active},t));$(`API returned ${h.length} active pull requests`);let u;if(o)try{u=(await E("Resolve repository GUID",()=>i.getRepository(e,t))).id}catch(c){let m=c instanceof Error?c.message:String(c);$(`Failed to resolve repository GUID for ${e}: ${m}`)}let a=di(h);S(`Fetching threads for ${a.length} PRs in ${t}/${e} (concurrency: ${10})\u2026`);let d=await ue(a,10,async c=>{let m=c.pullRequestId;$(` #${m} \u2014 fetching threads\u2026`);let g=(await E(`Fetch threads for PR #${m}`,()=>i.getThreads(e,m,t))).map(w=>({id:w.id??0,publishedDate:new Date(w.publishedDate??0),comments:(w.comments??[]).filter(y=>!y.isDeleted).map(y=>({authorUniqueName:oe(y.author),publishedDate:new Date(y.publishedDate??0)}))})),f=(c.reviewers??[]).map(w=>({displayName:w.displayName??"",uniqueName:oe(w),vote:w.vote??0})),A=`${l}/${t}/_git/${e}/pullrequest/${m}`,b=(c.labels??[]).map(w=>w.name??""),v=[];if(Object.keys(s.labels).length>0){let w=await hi(i,e,t,m);v=Vt(w,s.ignore,s.labels),v.length>0&&$(` #${m} \u2014 detected labels: ${v.join(", ")}`)}let R=o&&u?await pi(o,u,t,m):void 0;return{id:m,title:c.title??"(no title)",author:c.createdBy?.displayName??"Unknown",authorUniqueName:oe(c.createdBy),url:A,createdDate:new Date(c.creationDate??0),reviewers:f,threads:g,labels:b,detectedLabels:v,mergeStatus:c.mergeStatus??0,lastSourcePushDate:c.lastMergeSourceCommit?.committer?.date?new Date(c.lastMergeSourceCommit.committer.date):void 0,size:r?await Ft(i,e,t,m,r):void 0,description:c.description??void 0,sourceBranch:c.sourceRefName??void 0,targetBranch:c.targetRefName??void 0,pipelineStatus:R}});return $(`${d.length} PRs remain after filtering`),d}async function Wt(i,e,t,n){for(let r of n)if(r.detectedLabels.length!==0){for(let s of r.detectedLabels)if(!r.labels.some(o=>o.toLowerCase()===s.toLowerCase()))try{await E(`Add label '${s}' to PR #${r.id}`,()=>i.createPullRequestLabel({name:s},e,r.id,t)),r.labels.push(s),$(` #${r.id} \u2014 added label '${s}'`)}catch(o){let l=o instanceof Error?o.message:String(o);$(` #${r.id} \u2014 failed to add label '${s}': ${l}`)}}}var fi=1440*60*1e3,gi=["TF401398","TF401027"],wi=["TF401027"];async function Gt(i,e,t,n,r,s=new Date){if(r<0)return $("Restart merge is disabled (restartMergeAfterDays < 0)"),{restarted:0,failed:0,restartedPrIds:[]};let o=new Date(s.getTime()-r*fi),l=n.filter(d=>d.createdDate<o);if(l.length===0)return $("No PRs older than the restart-merge threshold"),{restarted:0,failed:0,restartedPrIds:[]};S(`Restarting merge for ${l.length} PR(s) older than ${r} days\u2026`);let h=0,u=0,a=[];for(let d of l)try{await E(`Restart merge for PR #${d.id}`,async()=>{try{return await i.updatePullRequest({mergeStatus:1},e,d.id,t)}catch(c){let m=c instanceof Error?c.message:String(c);throw gi.some(p=>m.includes(p))?new V(m):c}}),$(` #${d.id} "${d.title}" \u2014 merge restarted`),h++,a.push(d.id)}catch(c){let m=c instanceof Error?c.message:String(c);if(O(` #${d.id} "${d.title}" \u2014 failed to restart merge: ${m}`),u++,wi.some(p=>m.includes(p))){O("Stopping restart-merge for this repository due to permission error"),u+=l.length-l.indexOf(d)-1;break}}return x(`Restarted merge for ${h}/${l.length} PR(s)`),{restarted:h,failed:u,restartedPrIds:a}}import{PullRequestAsyncStatus as Ge}from"azure-devops-node-api/interfaces/GitInterfaces.js";var $i=["build","[bot]","team foundation","microsoft.visualstudio.com"],yi=["dependabot[bot]","renovate[bot]","github-actions[bot]","snyk-bot","greenkeeper[bot]","depfu[bot]","imgbot[bot]","allcontributors[bot]"],Bt=["github copilot","copilot[bot]","claude","codex"];function qe(i,e=new Set,t){let n=i.toLowerCase();return!!(e.has(n)||$i.some(r=>n.includes(r))||t&&e.has(t.toLowerCase()))}function he(i,e=new Set,t){let n=i.toLowerCase();if(e.has(n)||Bt.some(r=>n.includes(r)))return!0;if(t){let r=t.toLowerCase();if(e.has(r)||Bt.some(s=>r.includes(s)))return!0}return!1}function me(i,e=new Set,t,n=new Set){let r=i.toLowerCase();return yi.some(s=>r.includes(s))||qe(r,e,t)||he(r,n,t)}function bi(i,e=new Set,t){return he(i,e,t)}function Be(i,e,t=new Set,n,r=new Set){if(bi(e,r,n))switch(i){case"approved":return"APPROVE";case"needingReview":return"REVIEW";case"waitingOnAuthor":return"PENDING"}if(me(e,t,n,r))return"APPROVE";switch(i){case"approved":return"APPROVE";case"needingReview":return"REVIEW";case"waitingOnAuthor":return"PENDING"}}function je(i,e=new Set,t=new Set){let n=i.authorUniqueName,r=[];for(let s of i.threads)for(let o of s.comments)qe(o.authorUniqueName,e)||he(o.authorUniqueName,t)||r.push({date:o.publishedDate,isAuthor:o.authorUniqueName===n});return i.lastSourcePushDate&&r.push({date:i.lastSourcePushDate,isAuthor:!0}),r}function qt(i,e=new Set,t,n=new Set,r=new Set,s=new Set,o=new Set){let l=[],h=[],u=[];for(let a of i){if(n.has(a.authorUniqueName)){$(` #${a.id} "${a.title}" \u2014 author ${a.authorUniqueName} is ignored, skipping`);continue}let d=e.size===0||e.has(a.authorUniqueName),c=o.has(a.authorUniqueName);if(a.reviewers.some(y=>y.vote>=5&&!qe(y.uniqueName,r,y.displayName)&&!he(y.uniqueName,s,y.displayName))){let y=a.mergeStatus===Ge.Conflicts;$(` #${a.id} "${a.title}" \u2014 approved`),l.push({id:a.id,title:a.title,author:a.author,url:a.url,createdDate:a.createdDate,hasMergeConflict:y,isTeamMember:d,isStarred:c,action:Be("approved",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,pipelineStatus:a.pipelineStatus});continue}let p=je(a,r,s),g=p.filter(y=>y.isAuthor).sort((y,T)=>y.date.getTime()-T.date.getTime()),f=p.filter(y=>!y.isAuthor).sort((y,T)=>y.date.getTime()-T.date.getTime()),A=g.length>0?g[g.length-1]:null,b=f.length>0?f[f.length-1]:null,v=!1;if(A&&b?v=A.date.getTime()>b.date.getTime():(A&&!b||!A&&!b)&&(v=!0),!v){let y=a.mergeStatus===Ge.Conflicts;$(` #${a.id} "${a.title}" \u2014 reviewer acted last`),u.push({id:a.id,title:a.title,author:a.author,url:a.url,lastReviewerActivityDate:b.date,hasMergeConflict:y,isTeamMember:d,isStarred:c,action:Be("waitingOnAuthor",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,pipelineStatus:a.pipelineStatus});continue}let R;b?R=g.find(T=>T.date.getTime()>b.date.getTime())?.date??a.createdDate:R=a.createdDate;let w=a.mergeStatus===Ge.Conflicts;$(` #${a.id} "${a.title}" \u2014 needs review (waiting since ${R.toISOString()}${w?", has conflicts":""})`),h.push({id:a.id,title:a.title,author:a.author,url:a.url,waitingSince:R,hasMergeConflict:w,isTeamMember:d,isStarred:c,action:Be("needingReview",a.authorUniqueName,r,a.author,s),repository:t,size:a.size,detectedLabels:a.detectedLabels.length>0?a.detectedLabels:void 0,reviewerNames:a.reviewers.map(y=>y.displayName),pipelineStatus:a.pipelineStatus})}return $(`${l.length} approved PRs`),$(`${u.length} PRs waiting on author`),l.sort((a,d)=>a.createdDate.getTime()-d.createdDate.getTime()),h.sort((a,d)=>a.waitingSince.getTime()-d.waitingSince.getTime()),u.sort((a,d)=>a.lastReviewerActivityDate.getTime()-d.lastReviewerActivityDate.getTime()),{approved:l,needingReview:h,waitingOnAuthor:u}}function jt(i){let e=i.flatMap(r=>r.approved),t=i.flatMap(r=>r.needingReview),n=i.flatMap(r=>r.waitingOnAuthor);return e.sort((r,s)=>r.createdDate.getTime()-s.createdDate.getTime()),t.sort((r,s)=>r.waitingSince.getTime()-s.waitingSince.getTime()),n.sort((r,s)=>r.lastReviewerActivityDate.getTime()-s.lastReviewerActivityDate.getTime()),{approved:e,needingReview:t,waitingOnAuthor:n}}function P(i,e,t=new Date){if(e.length===0)return null;let n=t.getTime()-i.getTime(),r=Math.floor(n/(1e3*60*60*24));for(let s of e)if(r>=s.minDays)return s.label;return null}function pe(i,e=new Date){let t=e.getTime()-i.getTime(),n=Math.floor(t/(1e3*60*60*24)),r=Math.floor(t/(1e3*60*60)),s=Math.floor(t/(1e3*60)),o;return n>3?o="high":n>1?o="medium":o="low",{days:n,hours:r,minutes:s,urgency:o}}function fe(i){return i==="XS"||i==="S"?"low":i==="M"?"medium":"high"}function ge(i,e){let{approved:t,needingReview:n,waitingOnAuthor:r}=i,s=t.length+n.length+r.length,o=`Total: ${s} open PR${s===1?"":"s"} \u2014 ${t.length} approved, ${n.length} needing review, ${r.length} waiting on author`;return e&&(o+=`, ${e.totalConflicts} with conflicts`,(e.mergeRestarted>0||e.mergeRestartFailed>0)&&(o+=`, ${e.mergeRestarted} merge restarted`,e.mergeRestartFailed>0&&(o+=` (${e.mergeRestartFailed} failed)`))),o}function Q(i){return i?i.failed>0?`\u{1F534} ${i.failed}/${i.total} failed`:i.inProgress>0?`\u{1F7E1} ${i.inProgress}/${i.total} running`:i.succeeded===i.total?`\u{1F7E2} ${i.total}/${i.total} passed`:`\u26AA ${i.total} pipeline(s)`:""}function zt(i,e=new Date){let t=pe(i,e),n=t.urgency==="high"?"\u{1F534}":t.urgency==="medium"?"\u{1F7E1}":"\u{1F7E2}",r;return t.days>0?r=`${t.days} day${t.days===1?"":"s"} ago`:t.hours>0?r=`${t.hours} hour${t.hours===1?"":"s"} ago`:r=`${t.minutes} minute${t.minutes===1?"":"s"} ago`,`${n} ${r}`}function Jt(i){let e=fe(i.label);return`${e==="low"?"\u{1F7E2}":e==="medium"?"\u{1F7E1}":"\u{1F534}"} ${i.label}`}function Yt(i){switch(i){case"APPROVE":return"\u{1F7E2} APPROVE";case"REVIEW":return"\u{1F50D} REVIEW";case"PENDING":return"\u23F3 PENDING"}}function Kt(i){return!i||i.length===0?"":" "+i.map(e=>`\`${L(e)}\``).join(" ")}function L(i){return i.replace(/[\r\n]+/g," ").trim().replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/\|/g,"\\|")}function Zt(i,e){return e?`\u2B50 ${i}`:i}function ze(i,e,t,n,r=!1){if(i.length===0)return`_${t}_
31
31
 
32
- `;let s=i.some(u=>u.size!=null),o=i.some(u=>u.stalenessBadge),l=i.some(u=>u.pipelineStatus!=null);if(r){let u=["PR","Repository","Author","Action"];s&&u.push("Size"),l&&u.push("Pipelines"),o&&u.push("Staleness"),u.push(e);let d=`| ${u.join(" | ")} |
33
- |${u.map(()=>"---").join("|")}|
34
- `;for(let c of i){let m=c.hasMergeConflict?" \u274C":"",f=H(c.title),g=H(c.author),p=H(c.repository??"Unknown"),C=Kt(c.detectedLabels),A=`[#${c.id} - ${f}](${c.url})${m}${C}`,O=zt(c.dateColumn,n),b=Yt(c.action),w=s?` ${c.size?Jt(c.size):""} |`:"",E=l?` ${Z(c.pipelineStatus)} |`:"",M=o?` ${c.stalenessBadge??""} |`:"";d+=`| ${A} | ${p} | ${g} | ${b} |${w}${E}${M} ${O} |
32
+ `;let s=i.some(a=>a.size!=null),o=i.some(a=>a.stalenessBadge),l=i.some(a=>a.pipelineStatus!=null);if(r){let a=["PR","Repository","Author","Action"];s&&a.push("Size"),l&&a.push("Pipelines"),o&&a.push("Staleness"),a.push(e);let d=`| ${a.join(" | ")} |
33
+ |${a.map(()=>"---").join("|")}|
34
+ `;for(let c of i){let m=c.hasMergeConflict?" \u274C":"",p=L(c.title),g=L(Zt(c.author,c.isStarred)),f=L(c.repository??"Unknown"),A=Kt(c.detectedLabels),b=`[#${c.id} - ${p}](${c.url})${m}${A}`,v=zt(c.dateColumn,n),R=Yt(c.action),w=s?` ${c.size?Jt(c.size):""} |`:"",y=l?` ${Q(c.pipelineStatus)} |`:"",T=o?` ${c.stalenessBadge??""} |`:"";d+=`| ${b} | ${f} | ${g} | ${R} |${w}${y}${T} ${v} |
35
35
  `}return d+`
36
- `}let h=["PR","Author","Action"];s&&h.push("Size"),l&&h.push("Pipelines"),o&&h.push("Staleness"),h.push(e);let a=`| ${h.join(" | ")} |
36
+ `}let h=["PR","Author","Action"];s&&h.push("Size"),l&&h.push("Pipelines"),o&&h.push("Staleness"),h.push(e);let u=`| ${h.join(" | ")} |
37
37
  |${h.map(()=>"---").join("|")}|
38
- `;for(let u of i){let d=u.hasMergeConflict?" \u274C":"",c=H(u.title),m=H(u.author),f=Kt(u.detectedLabels),g=`[#${u.id} - ${c}](${u.url})${d}${f}`,p=zt(u.dateColumn,n),C=Yt(u.action),A=s?` ${u.size?Jt(u.size):""} |`:"",O=l?` ${Z(u.pipelineStatus)} |`:"",b=o?` ${u.stalenessBadge??""} |`:"";a+=`| ${g} | ${m} | ${C} |${A}${O}${b} ${p} |
39
- `}return a+`
40
- `}function bi(i){return i.every(t=>t.isTeamMember)?{team:i,community:[]}:{team:i.filter(t=>t.isTeamMember),community:i.filter(t=>!t.isTeamMember)}}function Je(i,e,t,n,r,s,o=!1){let l=`## ${i}
38
+ `;for(let a of i){let d=a.hasMergeConflict?" \u274C":"",c=L(a.title),m=L(Zt(a.author,a.isStarred)),p=Kt(a.detectedLabels),g=`[#${a.id} - ${c}](${a.url})${d}${p}`,f=zt(a.dateColumn,n),A=Yt(a.action),b=s?` ${a.size?Jt(a.size):""} |`:"",v=l?` ${Q(a.pipelineStatus)} |`:"",R=o?` ${a.stalenessBadge??""} |`:"";u+=`| ${g} | ${m} | ${A} |${b}${v}${R} ${f} |
39
+ `}return u+`
40
+ `}function _i(i){return i.every(t=>t.isTeamMember)?{team:i,community:[]}:{team:i.filter(t=>t.isTeamMember),community:i.filter(t=>!t.isTeamMember)}}function Je(i,e,t,n,r,s,o=!1){let l=`## ${i}
41
41
 
42
- `,{team:h,community:a}=bi(e);return a.length>0?(l+=`### Team PRs
42
+ `,{team:h,community:u}=_i(e);return u.length>0?(l+=`### Team PRs
43
43
 
44
44
  `,l+=ze(h.map(t),n,"No team PRs.",s,o),l+=`### Community Contributions
45
45
 
46
- `,l+=ze(a.map(t),n,"No community PRs.",s,o)):l+=ze(e.map(t),n,r,s,o),l}function _i(i){let e=`## \u{1F4CA} Statistics per Repository
46
+ `,l+=ze(u.map(t),n,"No community PRs.",s,o)):l+=ze(e.map(t),n,r,s,o),l}function Ci(i){let e=`## \u{1F4CA} Statistics per Repository
47
47
 
48
48
  `;e+=`| Repository | Open PRs | \u2705 Approved | \u{1F440} Needs Review | \u270D\uFE0F Waiting on Author | \u274C Conflicts | \u{1F504} Merge Restarted |
49
49
  `,e+=`|---|---|---|---|---|---|---|
50
- `;for(let t of i){let n=t.approved+t.needingReview+t.waitingOnAuthor,r=t.mergeRestarted>0?t.mergeRestartFailed>0?`${t.mergeRestarted} (${t.mergeRestartFailed} failed)`:`${t.mergeRestarted}`:"0";e+=`| ${H(t.repoLabel)} | ${n} | ${t.approved} | ${t.needingReview} | ${t.waitingOnAuthor} | ${t.conflicts} | ${r} |
50
+ `;for(let t of i){let n=t.approved+t.needingReview+t.waitingOnAuthor,r=t.mergeRestarted>0?t.mergeRestartFailed>0?`${t.mergeRestarted} (${t.mergeRestartFailed} failed)`:`${t.mergeRestarted}`:"0";e+=`| ${L(t.repoLabel)} | ${n} | ${t.approved} | ${t.needingReview} | ${t.waitingOnAuthor} | ${t.conflicts} | ${r} |
51
51
  `}return e+`
52
- `}function X(i){return i<1?"< 1 day":`${i} day${i===1?"":"s"}`}function Ci(i){let e=`## \u{1F4C8} Review Metrics
52
+ `}function ee(i){return i<1?"< 1 day":`${i} day${i===1?"":"s"}`}function vi(i){let e=`## \u{1F4C8} Review Metrics
53
53
 
54
54
  `;if(e+=`### Summary
55
55
 
56
56
  `,e+=`| Metric | Value |
57
57
  |---|---|
58
58
  `,e+=`| Total open PRs | ${i.aggregate.totalPrs} |
59
- `,e+=`| Median PR age | ${X(i.aggregate.medianAgeInDays)} |
60
- `,e+=`| Avg time to first review | ${i.aggregate.avgTimeToFirstReviewInDays!==null?X(i.aggregate.avgTimeToFirstReviewInDays):"N/A"} |
59
+ `,e+=`| Median PR age | ${ee(i.aggregate.medianAgeInDays)} |
60
+ `,e+=`| Avg time to first review | ${i.aggregate.avgTimeToFirstReviewInDays!==null?ee(i.aggregate.avgTimeToFirstReviewInDays):"N/A"} |
61
61
  `,e+=`| Avg review rounds | ${i.aggregate.avgReviewRounds} |
62
62
  `,e+=`| PRs with no review activity | ${i.aggregate.prsWithNoReviewActivity} |
63
63
 
@@ -65,15 +65,15 @@ ${e}`,{cause:i})}}async function Zn(i,e){let t=await fetch(e,{headers:{Authoriza
65
65
 
66
66
  `,e+=`| Author | Open PRs | Avg Age | Avg Rounds | Fastest Review |
67
67
  |---|---|---|---|---|
68
- `;for(let t of i.perAuthor){let n=t.fastestReviewInDays!==null?X(t.fastestReviewInDays):"N/A";e+=`| ${H(t.author)} | ${t.openPrCount} | ${X(t.avgAgeInDays)} | ${t.avgReviewRounds} | ${n} |
68
+ `;for(let t of i.perAuthor){let n=t.fastestReviewInDays!==null?ee(t.fastestReviewInDays):"N/A",r=t.isStarred?`\u2B50 ${L(t.author)}`:L(t.author);e+=`| ${r} | ${t.openPrCount} | ${ee(t.avgAgeInDays)} | ${t.avgReviewRounds} | ${n} |
69
69
  `}e+=`
70
- `}return e}function vi(i){if(i.length===0)return"";let e=`## \u{1F465} Reviewer Workload
70
+ `}return e}function Ai(i){if(i.length===0)return"";let e=`## \u{1F465} Reviewer Workload
71
71
 
72
72
  `;e+=`| Reviewer | Assigned | Pending | Completed | Avg Response | Load |
73
73
  |---|---|---|---|---|---|
74
- `;for(let t of i){let n=t.avgResponseTimeInDays!==null?X(t.avgResponseTimeInDays):"N/A";e+=`| ${H(t.displayName)} | ${t.assignedPrCount} | ${t.pendingReviewCount} | ${t.completedReviewCount} | ${n} | ${t.loadIndicator} |
74
+ `;for(let t of i){let n=t.avgResponseTimeInDays!==null?ee(t.avgResponseTimeInDays):"N/A",r=t.isStarred?`\u2B50 ${L(t.displayName)}`:L(t.displayName);e+=`| ${r} | ${t.assignedPrCount} | ${t.pendingReviewCount} | ${t.completedReviewCount} | ${n} | ${t.loadIndicator} |
75
75
  `}return e+`
76
- `}function Ai(i){let e=`## \u{1F517} PR Dependencies
76
+ `}function Si(i){let e=`## \u{1F517} PR Dependencies
77
77
 
78
78
  `;if(i.chains.length>0){e+=`### Dependency Chains
79
79
 
@@ -87,31 +87,31 @@ ${e}`,{cause:i})}}async function Zn(i,e){let t=await fetch(e,{headers:{Authoriza
87
87
  `,e+=`|----|-----------|--------|
88
88
  `;for(let t of i.dependencies)i.blockedPrIds.includes(t.fromPrId)&&(e+=`| #${t.fromPrId} | #${t.toPrId} | ${t.details} |
89
89
  `);e+=`
90
- `}return e}function fe(i){switch(i){case"elite":return"\u{1F7E2} Elite";case"high":return"\u{1F7E2} High";case"medium":return"\u{1F7E1} Medium";case"low":return"\u{1F534} Low"}}function ge(i){return i===null?"\u2014":i===0?"\u2192 stable":i>0?`\u2197\uFE0F +${i}`:`\u2198\uFE0F ${i}`}function Oi(i){let e=i.current,t=`## \u{1F4C8} DORA Metrics
90
+ `}return e}function we(i){switch(i){case"elite":return"\u{1F7E2} Elite";case"high":return"\u{1F7E2} High";case"medium":return"\u{1F7E1} Medium";case"low":return"\u{1F534} Low"}}function $e(i){return i===null?"\u2014":i===0?"\u2192 stable":i>0?`\u2197\uFE0F +${i}`:`\u2198\uFE0F ${i}`}function Oi(i){let e=i.current,t=`## \u{1F4C8} DORA Metrics
91
91
 
92
92
  `;return t+=`| Metric | Value | Rating | Trend |
93
93
  `,t+=`|--------|-------|--------|-------|
94
- `,t+=`| Change Lead Time | ${e.changeLeadTime.medianDays} days | ${fe(e.changeLeadTime.rating)} | ${ge(i.deltas.changeLeadTime)} |
95
- `,t+=`| Deployment Frequency | ${e.deploymentFrequency.perWeek}/week | ${fe(e.deploymentFrequency.rating)} | ${ge(i.deltas.deploymentFrequency)} |
96
- `,t+=`| Change Failure Rate | ${e.changeFailureRate.percentage}% | ${fe(e.changeFailureRate.rating)} | ${ge(i.deltas.changeFailureRate)} |
97
- `,t+=`| Mean Time to Restore | ${e.meanTimeToRestore.medianHours}h | ${fe(e.meanTimeToRestore.rating)} | ${ge(i.deltas.meanTimeToRestore)} |
94
+ `,t+=`| Change Lead Time | ${e.changeLeadTime.medianDays} days | ${we(e.changeLeadTime.rating)} | ${$e(i.deltas.changeLeadTime)} |
95
+ `,t+=`| Deployment Frequency | ${e.deploymentFrequency.perWeek}/week | ${we(e.deploymentFrequency.rating)} | ${$e(i.deltas.deploymentFrequency)} |
96
+ `,t+=`| Change Failure Rate | ${e.changeFailureRate.percentage}% | ${we(e.changeFailureRate.rating)} | ${$e(i.deltas.changeFailureRate)} |
97
+ `,t+=`| Mean Time to Restore | ${e.meanTimeToRestore.medianHours}h | ${we(e.meanTimeToRestore.rating)} | ${$e(i.deltas.meanTimeToRestore)} |
98
98
  `,t+=`
99
- `,t}function Zt(i){let{analysis:e,multiRepo:t,stats:n,staleness:r,metrics:s,workload:o,dependencyGraph:l,doraTrend:h}=i,a=new Date,{approved:u,needingReview:d,waitingOnAuthor:c}=e,m=r?.enabled!==!1?r?.thresholds??[]:[],f=`_Last updated: ${a.toISOString()}_
99
+ `,t}function Xt(i){let{analysis:e,multiRepo:t,stats:n,staleness:r,metrics:s,workload:o,dependencyGraph:l,doraTrend:h}=i,u=new Date,{approved:a,needingReview:d,waitingOnAuthor:c}=e,m=r?.enabled!==!1?r?.thresholds??[]:[],p=`_Last updated: ${u.toISOString()}_
100
100
 
101
- `;return f+=Je("\u2705 Approved",u,g=>({...g,dateColumn:g.createdDate,stalenessBadge:D(g.createdDate,m,a)}),"Created","No approved PRs.",a,t),f+=Je("\u{1F440} PRs Needing Review",d,g=>({...g,dateColumn:g.waitingSince,stalenessBadge:D(g.waitingSince,m,a)}),"Waiting for feedback","No PRs currently need review.",a,t),f+=Je("\u270D\uFE0F Waiting on Author",c,g=>({...g,dateColumn:g.lastReviewerActivityDate,stalenessBadge:D(g.lastReviewerActivityDate,m,a)}),"Last reviewer activity","No PRs waiting on author.",a,t),n?.repoStats&&n.repoStats.length>1&&(f+=_i(n.repoStats)),s&&(f+=Ci(s)),o&&o.length>0&&(f+=vi(o)),l&&l.dependencies.length>0&&(f+=Ai(l)),h&&(f+=Oi(h)),f+=`_${pe(e,n)}._
102
- `,f}var y="\x1B[0m",P="\x1B[2m",T="\x1B[1m",we="\x1B[31m",$e="\x1B[32m",ye="\x1B[33m",j="\x1B[36m",Ri="\x1B[37m",Qt="\x1B[41m",Si="\x1B[42m",en="\x1B[43m";function xi(i,e){return`\x1B]8;;${e}\x1B\\${i}\x1B]8;;\x1B\\`}function Ti(i,e){let t=he(i,e),n;return t.days>0?n=`${t.days}d`:t.hours>0?n=`${t.hours}h`:n=`${t.minutes}m`,t.urgency==="high"?{color:we,label:n}:t.urgency==="medium"?{color:ye,label:n}:{color:$e,label:n}}function Ze(i,e){return`${i}${T} ${e} ${y}`}function Ei(i){return i?` ${we}\u26A0 conflict${y}`:""}function Di(i){if(!i)return"";let e=me(i.label);return` ${e==="low"?$e:e==="medium"?ye:we}${T}${i.label}${y}`}function Pi(i,e){let t=i.replace(/\x1b\][^\x1b]*\x1b\\|\x1b\[[0-9;]*m/g,""),n=e-t.length;return n>0?i+" ".repeat(n):i}function Ke(i,e){return i.length>e?i.slice(0,e-1)+"\u2026":i}function ki(i){switch(i){case"APPROVE":return`${$e}${T}APPROVE${y}`;case"REVIEW":return`${ye}${T}REVIEW${y}`;case"PENDING":return`${P}PENDING${y}`}}function Xt(i,e,t,n,r,s,o,l,h,a,u,d){let{color:c,label:m}=Ti(r,o),f=`${c}${T}${m}${y}`,g=`${P}#${i}${y}`,p=Ke(e.replace(/[\r\n]+/g," ").trim(),60),C=xi(`${g} ${Ri}${p}${y}`,n),A=`${P}${Ke(t,20)}${y}`,O=Ei(s),b=Di(h),w=ki(l),E=a&&a.length>0?" "+a.map(W=>`${P}[${W}]${y}`).join(" "):"",M=u?` ${ye}${u}${y}`:"",L=d?` ${Z(d)}`:"";return` ${f} ${Pi(C,80)} ${A}${b} ${w}${O}${L}${M}${E}`}function Ye(i,e,t,n,r,s){let o=[];if(o.push(`
101
+ `;return p+=Je("\u2705 Approved",a,g=>({...g,dateColumn:g.createdDate,stalenessBadge:P(g.createdDate,m,u)}),"Created","No approved PRs.",u,t),p+=Je("\u{1F440} PRs Needing Review",d,g=>({...g,dateColumn:g.waitingSince,stalenessBadge:P(g.waitingSince,m,u)}),"Waiting for feedback","No PRs currently need review.",u,t),p+=Je("\u270D\uFE0F Waiting on Author",c,g=>({...g,dateColumn:g.lastReviewerActivityDate,stalenessBadge:P(g.lastReviewerActivityDate,m,u)}),"Last reviewer activity","No PRs waiting on author.",u,t),n?.repoStats&&n.repoStats.length>1&&(p+=Ci(n.repoStats)),s&&(p+=vi(s)),o&&o.length>0&&(p+=Ai(o)),l&&l.dependencies.length>0&&(p+=Si(l)),h&&(p+=Oi(h)),p+=`_${ge(e,n)}._
102
+ `,p}var _="\x1B[0m",k="\x1B[2m",D="\x1B[1m",ye="\x1B[31m",be="\x1B[32m",_e="\x1B[33m",j="\x1B[36m",Ri="\x1B[37m",en="\x1B[41m",xi="\x1B[42m",tn="\x1B[43m";function Ti(i,e){return`\x1B]8;;${e}\x1B\\${i}\x1B]8;;\x1B\\`}function Ei(i,e){let t=pe(i,e),n;return t.days>0?n=`${t.days}d`:t.hours>0?n=`${t.hours}h`:n=`${t.minutes}m`,t.urgency==="high"?{color:ye,label:n}:t.urgency==="medium"?{color:_e,label:n}:{color:be,label:n}}function Ze(i,e){return`${i}${D} ${e} ${_}`}function Di(i){return i?` ${ye}\u26A0 conflict${_}`:""}function Pi(i){if(!i)return"";let e=fe(i.label);return` ${e==="low"?be:e==="medium"?_e:ye}${D}${i.label}${_}`}function ki(i,e){let t=i.replace(/\x1b\][^\x1b]*\x1b\\|\x1b\[[0-9;]*m/g,""),n=e-t.length;return n>0?i+" ".repeat(n):i}function Ke(i,e){return i.length>e?i.slice(0,e-1)+"\u2026":i}function Ni(i){switch(i){case"APPROVE":return`${be}${D}APPROVE${_}`;case"REVIEW":return`${_e}${D}REVIEW${_}`;case"PENDING":return`${k}PENDING${_}`}}function Qt(i,e,t,n,r,s,o,l,h,u,a,d,c){let{color:m,label:p}=Ei(r,o),g=`${m}${D}${p}${_}`,f=`${k}#${i}${_}`,A=Ke(e.replace(/[\r\n]+/g," ").trim(),60),b=Ti(`${f} ${Ri}${A}${_}`,n),R=`${k}${c?"\u2B50 ":""}${Ke(t,20)}${_}`,w=Di(s),y=Pi(h),T=Ni(l),I=u&&u.length>0?" "+u.map(J=>`${k}[${J}]${_}`).join(" "):"",U=a?` ${_e}${a}${_}`:"",z=d?` ${Q(d)}`:"";return` ${g} ${ki(b,80)} ${R}${y} ${T}${w}${z}${U}${I}`}function Ye(i,e,t,n,r,s){let o=[];if(o.push(`
103
103
  ${Ze(e,`${i} (${t.length})`)}
104
- `),t.length===0)return o.push(` ${P}No PRs${y}
104
+ `),t.length===0)return o.push(` ${k}No PRs${_}
105
105
  `),o.join(`
106
- `);if(s){let l=new Map;for(let h of t){let a=s(h)??"Unknown";l.has(a)||l.set(a,[]),l.get(a).push(h)}for(let[h,a]of l){o.push(` ${T}${j}\u{1F4C2} ${h}${y}`);for(let u of a){let{id:d,title:c,author:m,url:f,date:g,hasMergeConflict:p,action:C,size:A,detectedLabels:O,stalenessBadge:b,pipelineStatus:w}=n(u);o.push(Xt(d,c,m,f,g,p,r,C,A,O,b,w))}o.push("")}}else{for(let l of t){let{id:h,title:a,author:u,url:d,date:c,hasMergeConflict:m,action:f,size:g,detectedLabels:p,stalenessBadge:C,pipelineStatus:A}=n(l);o.push(Xt(h,a,u,d,c,m,r,f,g,p,C,A))}o.push("")}return o.join(`
107
- `)}function Ni(i){let e=[];return e.push(`
108
- ${Ze(en,"\u{1F4C8} Review Metrics")}
109
- `),e.push(` ${P}Median PR age:${y} ${T}${i.aggregate.medianAgeInDays}d${y} ${P}Avg first review:${y} ${T}${i.aggregate.avgTimeToFirstReviewInDays??"N/A"}d${y} ${P}Avg rounds:${y} ${T}${i.aggregate.avgReviewRounds}${y} ${P}No review:${y} ${T}${i.aggregate.prsWithNoReviewActivity}${y}`),e.push(""),e.join(`
110
- `)}function Mi(i){if(i.length===0)return"";let e=[];e.push(`
111
- ${Ze(Qt,"\u{1F465} Top Reviewer Bottlenecks")}
112
- `);let t=i.slice(0,5);for(let n of t){let r=n.avgResponseTimeInDays!==null?`${n.avgResponseTimeInDays}d avg`:"no response";e.push(` ${n.loadIndicator} ${T}${n.displayName}${y} \u2014 ${n.pendingReviewCount} pending / ${n.assignedPrCount} assigned (${r})`)}return e.push(""),e.join(`
113
- `)}function tn(i){let{analysis:e,repoLabel:t,multiRepo:n=!1,stats:r,staleness:s,metrics:o,workload:l,dependencyGraph:h}=i,a=new Date,{approved:u,needingReview:d,waitingOnAuthor:c}=e,m=s?.enabled!==!1?s?.thresholds??[]:[],f=[];f.push(""),f.push(`${T}${j} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${y}`),f.push(`${T}${j} \u2502 \u{1F4CB} PR Review Dashboard \u2502${y}`),f.push(`${T}${j} \u2502 ${y}${P}${Ke(t,42)}${y}${T}${j}${" ".repeat(Math.max(0,42-t.length))}\u2502${y}`),f.push(`${T}${j} \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${y}`),f.push("");let g=n?p=>p.repository:void 0;return f.push(Ye("\u2705 Approved",Si,u,p=>({id:p.id,title:p.title,author:p.author,url:p.url,date:p.createdDate,hasMergeConflict:p.hasMergeConflict,action:p.action,size:p.size,detectedLabels:p.detectedLabels,stalenessBadge:D(p.createdDate,m,a),pipelineStatus:p.pipelineStatus}),a,g)),f.push(Ye("\u{1F440} Needing Review",en,d,p=>({id:p.id,title:p.title,author:p.author,url:p.url,date:p.waitingSince,hasMergeConflict:p.hasMergeConflict,action:p.action,size:p.size,detectedLabels:p.detectedLabels,stalenessBadge:D(p.waitingSince,m,a),pipelineStatus:p.pipelineStatus}),a,g)),f.push(Ye("\u270D\uFE0F Waiting on Author",Qt,c,p=>({id:p.id,title:p.title,author:p.author,url:p.url,date:p.lastReviewerActivityDate,hasMergeConflict:p.hasMergeConflict,action:p.action,size:p.size,detectedLabels:p.detectedLabels,stalenessBadge:D(p.lastReviewerActivityDate,m,a),pipelineStatus:p.pipelineStatus}),a,g)),o&&f.push(Ni(o)),l&&l.length>0&&f.push(Mi(l)),h&&h.dependencies.length>0&&f.push(Li(h)),f.push(` ${P}${pe(e,r)}${y}`),f.push(` ${P}Updated: ${a.toLocaleString()}${y}`),f.push(""),f.join(`
114
- `)}function Li(i){let e=[];e.push(` ${T}\u{1F517} PR Dependencies${y}`),e.push(` ${P}${i.chains.length} chain(s), ${i.blockedPrIds.length} blocked PR(s), ${i.dependencies.length} dependency link(s)${y}`);for(let t of i.chains.slice(0,5)){let n=t.prIds.map(s=>`#${s}`).join(" \u2192 "),r=t.status==="blocked"?`${we}\u26A0\uFE0F blocked${y}`:`${$e}\u2705 ready${y}`;e.push(` Chain ${t.chainId}: ${n} ${r}`)}return i.chains.length>5&&e.push(` ${P}... and ${i.chains.length-5} more chain(s)${y}`),e.push(""),e.join(`
115
- `)}function nn(i,e){return Math.abs(e.getTime()-i.getTime())/(1e3*60*60*24)}function Ii(i){if(i.length===0)return 0;let e=[...i].sort((n,r)=>n-r),t=Math.floor(e.length/2);return e.length%2!==0?e[t]:(e[t-1]+e[t])/2}function Fi(i,e,t){let n=je(i,e),r=n.filter(d=>!d.isAuthor).sort((d,c)=>d.date.getTime()-c.date.getTime()),s=nn(i.createdDate,t),o=r.length>0?nn(i.createdDate,r[0].date):null,l=n.sort((d,c)=>d.date.getTime()-c.date.getTime()),h=0,a=!1;for(let d of l)d.isAuthor?a=!0:a&&(h++,a=!1);let u=l.length>0?l[l.length-1].date:i.createdDate;return{prId:i.id,title:i.title,author:i.author,url:i.url,ageInDays:Math.round(s*10)/10,timeToFirstReviewInDays:o!==null?Math.round(o*10)/10:null,reviewRounds:h,lastActivityDate:u}}function Xe(i,e=new Set,t=new Date){let n=i.map(d=>Fi(d,e,t)),r=n.map(d=>d.ageInDays),s=n.map(d=>d.timeToFirstReviewInDays).filter(d=>d!==null),o=n.map(d=>d.reviewRounds),l=n.filter(d=>d.timeToFirstReviewInDays===null).length,h={medianAgeInDays:Math.round(Ii(r)*10)/10,avgTimeToFirstReviewInDays:s.length>0?Math.round(s.reduce((d,c)=>d+c,0)/s.length*10)/10:null,avgReviewRounds:o.length>0?Math.round(o.reduce((d,c)=>d+c,0)/o.length*10)/10:0,prsWithNoReviewActivity:l,totalPrs:i.length},a=new Map;for(let d of n)a.has(d.author)||a.set(d.author,[]),a.get(d.author).push(d);let u=[];for(let[d,c]of a){let m=c.map(p=>p.ageInDays),f=c.map(p=>p.reviewRounds),g=c.map(p=>p.timeToFirstReviewInDays).filter(p=>p!==null);u.push({author:d,openPrCount:c.length,avgAgeInDays:Math.round(m.reduce((p,C)=>p+C,0)/m.length*10)/10,avgReviewRounds:Math.round(f.reduce((p,C)=>p+C,0)/f.length*10)/10,fastestReviewInDays:g.length>0?Math.round(Math.min(...g)*10)/10:null})}return u.sort((d,c)=>c.openPrCount-d.openPrCount),{perPr:n,aggregate:h,perAuthor:u}}var Hi={light:{maxPending:10,maxAvgResponseDays:2},medium:{maxPending:20,maxAvgResponseDays:4}};function Vi(i,e,t){let n=r=>e!==null&&e>r;return i>t.medium.maxPending||n(t.medium.maxAvgResponseDays)?"\u{1F534}":i>t.light.maxPending||n(t.light.maxAvgResponseDays)?"\u{1F7E1}":"\u{1F7E2}"}function Qe(i,e,t=new Set,n=Hi,r=new Set){let s=new Set(e.needingReview.map(h=>h.id)),o=new Map;for(let h of i)if(!de(h.authorUniqueName,t,h.author,r))for(let a of h.reviewers){if(de(a.uniqueName,t,a.displayName,r))continue;let u=a.uniqueName.toLowerCase();o.has(u)||o.set(u,{displayName:a.displayName,assignedPrCount:0,pendingReviewCount:0,completedReviewCount:0,responseTimes:[]});let d=o.get(u);d.assignedPrCount++,a.vote>=5?d.completedReviewCount++:s.has(h.id)&&d.pendingReviewCount++;let c=h.threads.flatMap(m=>m.comments).filter(m=>m.authorUniqueName.toLowerCase()===u).sort((m,f)=>m.publishedDate.getTime()-f.publishedDate.getTime());if(c.length>0){let m=(c[0].publishedDate.getTime()-h.createdDate.getTime())/864e5;m>=0&&d.responseTimes.push(m)}}let l=[];for(let[h,a]of o){let u=a.responseTimes.length>0?Math.round(a.responseTimes.reduce((d,c)=>d+c,0)/a.responseTimes.length*10)/10:null;l.push({reviewer:h,displayName:a.displayName,assignedPrCount:a.assignedPrCount,pendingReviewCount:a.pendingReviewCount,completedReviewCount:a.completedReviewCount,avgResponseTimeInDays:u,loadIndicator:Vi(a.pendingReviewCount,u,n)})}return l.sort((h,a)=>a.pendingReviewCount-h.pendingReviewCount),l}function rn(i,e){let t=e?` ${e}`:"";return`[#${i.id} - ${i.title}](${i.url}) \u2014 ${i.author}${t}`}function Wi(i,e,t,n){let r=t?.enabled!==!1?t?.thresholds??[]:[],o=[{type:"TextBlock",text:`\u{1F4CB} PR Review Summary \u2014 ${i.approved.length+i.needingReview.length+i.waitingOnAuthor.length} open PRs`,size:"Large",weight:"Bolder"},{type:"TextBlock",text:`\u2705 ${i.approved.length} approved | \u{1F440} ${i.needingReview.length} needing review | \u270D\uFE0F ${i.waitingOnAuthor.length} waiting on author | \u274C ${e.totalConflicts} conflicts`,wrap:!0,spacing:"Small"}],l=h=>!n||n.includes(h);if(l("needingReview")&&i.needingReview.length>0){o.push({type:"TextBlock",text:`**\u{1F440} PRs Needing Review (${i.needingReview.length})**`,separator:!0,spacing:"Medium"});let h=i.needingReview.slice(0,15);for(let a of h){let u=D(a.waitingSince,r);o.push({type:"TextBlock",text:rn(a,u),wrap:!0,spacing:"Small"})}i.needingReview.length>15&&o.push({type:"TextBlock",text:`_\u2026and ${i.needingReview.length-15} more_`,spacing:"Small"})}if(l("waitingOnAuthor")&&i.waitingOnAuthor.length>0){o.push({type:"TextBlock",text:`**\u270D\uFE0F Waiting on Author (${i.waitingOnAuthor.length})**`,separator:!0,spacing:"Medium"});let h=i.waitingOnAuthor.slice(0,10);for(let a of h){let u=D(a.lastReviewerActivityDate,r);o.push({type:"TextBlock",text:rn(a,u),wrap:!0,spacing:"Small"})}i.waitingOnAuthor.length>10&&o.push({type:"TextBlock",text:`_\u2026and ${i.waitingOnAuthor.length-10} more_`,spacing:"Small"})}return l("approved")&&i.approved.length>0&&(o.push({type:"TextBlock",text:`**\u2705 Approved (${i.approved.length})**`,separator:!0,spacing:"Medium"}),o.push({type:"TextBlock",text:`${i.approved.length} PRs approved and ready to merge.`,spacing:"Small"})),{type:"message",attachments:[{contentType:"application/vnd.microsoft.card.adaptive",content:{type:"AdaptiveCard",$schema:"http://adaptivecards.io/schemas/adaptive-card.json",version:"1.4",body:o}}]}}async function sn(i,e,t,n){let r=Wi(i,e,n,t.filters?.sections);try{let s=await fetch(t.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});s.ok?S("Teams notification sent successfully"):R(`Teams notification failed: ${s.status} ${s.statusText}`)}catch(s){let o=s instanceof Error?s.message:String(s);R(`Teams notification failed: ${o}`)}}async function et(i,e,t,n){if(!t.teams?.webhookUrl){$("No notification webhooks configured, skipping");return}v("Sending Teams notification\u2026"),await sn(i,e,t.teams,n)}import{writeFileSync as Gi}from"node:fs";function on(i,e,t){let n=i.reduce((a,u)=>a+u.analysis.approved.length+u.analysis.needingReview.length+u.analysis.waitingOnAuthor.length,0),r,s=i.filter(a=>a.metrics).map(a=>a.metrics);if(s.length>0){let a=s.map(u=>u.aggregate);r={medianAgeInDays:a.reduce((u,d)=>u+d.medianAgeInDays,0)/a.length,avgTimeToFirstReviewInDays:Ui(a.map(u=>u.avgTimeToFirstReviewInDays)),avgReviewRounds:a.reduce((u,d)=>u+d.avgReviewRounds,0)/a.length,prsWithNoReviewActivity:a.reduce((u,d)=>u+d.prsWithNoReviewActivity,0),totalPrs:a.reduce((u,d)=>u+d.totalPrs,0)}}let o,l=i.filter(a=>a.staleness).map(a=>a.staleness);if(l.length>0){o={};for(let a of l)for(let[u,d]of Object.entries(a))o[u]=(o[u]??0)+d}let h={totalPrs:n,metrics:r,staleness:o};return{generatedAt:(t??new Date).toISOString(),version:e,repositories:i,aggregate:h}}async function an(i,e){let t=JSON.stringify(i,null,2);e==="-"?process.stdout.write(t+`
116
- `):(Gi(e,t,"utf-8"),S(`JSON report written to ${e}`))}async function ln(i,e){let t=e.method??"POST";try{let n=await fetch(e.url,{method:t,headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(i)});n.ok?S(`Webhook ${t} to ${e.url} succeeded (${n.status})`):R(`Webhook ${t} to ${e.url} returned ${n.status}: ${n.statusText}`)}catch(n){let r=n instanceof Error?n.message:String(n);R(`Webhook ${t} to ${e.url} failed: ${r}`)}}function Ui(i){let e=i.filter(t=>t!==null);return e.length===0?null:e.reduce((t,n)=>t+n,0)/e.length}import{readFileSync as qi,writeFileSync as Bi,existsSync as ji}from"node:fs";import{resolve as un}from"node:path";function zi(i){let e=un(i);if(!ji(e))return{entries:[]};try{let t=qi(e,"utf-8"),n=JSON.parse(t);return n&&Array.isArray(n.entries)?n:{entries:[]}}catch{return R(`Failed to parse nudge history at ${e}, starting fresh`),{entries:[]}}}function Ji(i,e){let t=un(i);Bi(t,JSON.stringify(e,null,2),"utf-8")}function Yi(i,e,t,n,r=new Date){let s=new Map;for(let h of n.entries)s.set(`${h.repoUrl}:${h.prId}`,h);let o=e.thresholds,l=-1;return t.minStalenessLevel&&(l=o.findIndex(h=>h.label===t.minStalenessLevel)),i.filter(h=>{let a=D(h.waitingSince,o,r);if(!a)return!1;if(l>=0){let c=o.findIndex(m=>m.label===a);if(c<0||c>l)return!1}let u=`${h.url}:${h.id}`,d=s.get(u);if(d){let c=new Date(d.lastNudgedAt);if((r.getTime()-c.getTime())/(1e3*60*60*24)<t.cooldownDays)return!1}return!0})}function Ki(i,e,t){return e.commentTemplate.replace(/\{\{days\}\}/g,String(t)).replace(/\{\{reviewers\}\}/g,i.reviewerNames?.join(", ")??"Reviewers").replace(/\{\{title\}\}/g,i.title).replace(/\{\{author\}\}/g,i.author)}function Zi(i){let e=i.match(/^(https:\/\/dev\.azure\.com\/[^/]+)\/([^/]+)\/_git\/([^/]+)/);return e?{orgUrl:e[1],project:e[2],repoName:e[3]}:null}async function Xi(i,e,t,n,r){let s=`${i}/${e}/_apis/git/repositories/${t}/pullRequests/${n}/threads?api-version=7.1`,l=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({comments:[{content:r,commentType:1}],status:"active"})});if(!l.ok)throw new Error(`ADO API returned ${l.status}: ${l.statusText}`)}async function cn(i,e,t,n=new Date){let r=zi(t.historyFile),s=Yi(i.needingReview,e,t,r,n),o={nudged:0,skipped:0,errors:0};if(s.length===0)return v("Auto-nudge: no PRs eligible for nudging"),o;v(`Auto-nudge: ${s.length} PR(s) eligible for nudging`);for(let l of s){let h=n.getTime()-l.waitingSince.getTime(),a=Math.floor(h/(1e3*60*60*24)),u=Ki(l,t,a);if(t.dryRun){v(` [DRY RUN] Would nudge #${l.id} "${l.title}" (${a} days)`),o.nudged++;continue}let d=Zi(l.url);if(!d){R(` #${l.id} \u2014 could not parse ADO URL: ${l.url}`),o.errors++;continue}try{await Xi(d.orgUrl,d.project,d.repoName,l.id,u),S(` #${l.id} "${l.title}" \u2014 nudged (${a} days)`),o.nudged++;let c=r.entries.findIndex(f=>f.repoUrl===l.url&&f.prId===l.id),m={prId:l.id,repoUrl:l.url,lastNudgedAt:n.toISOString(),nudgeCount:c>=0?r.entries[c].nudgeCount+1:1};c>=0?r.entries[c]=m:r.entries.push(m)}catch(c){let m=c instanceof Error?c.message:String(c);R(` #${l.id} "${l.title}" \u2014 nudge failed: ${m}`),o.errors++}}return t.dryRun||Ji(t.historyFile,r),v(`Auto-nudge: ${o.nudged} nudged, ${o.skipped} skipped, ${o.errors} errors`),o}import{readFileSync as Qi}from"node:fs";import{resolve as dn,dirname as er}from"node:path";import{fileURLToPath as tr}from"node:url";var nr=er(tr(import.meta.url));function ir(){let i=[dn(nr,"template.html"),dn(process.cwd(),"src","reporting","html-report","template.html")];for(let e of i)try{return Qi(e,"utf-8")}catch{}throw new Error(`HTML template not found. Searched: ${i.join(", ")}`)}var rr="{{DATA_PLACEHOLDER}}";function hn(i){let e=ir(),t=JSON.stringify(i);return e.replace(rr,t)}var ur={$schema:"https://raw.githubusercontent.com/Meir017/ado-pr-review-needed/main/pr-review-config.schema.json",repositories:[{url:"https://dev.azure.com/{org}/{project}/_git/{repo}"}],orgManager:null,teamMembers:[],ignoreManagers:!1};function nt(){let i=q(ar(lr(import.meta.url)),"..","package.json");try{return JSON.parse(or(i,"utf-8")).version??"0.0.0"}catch{return"0.0.0"}}function pn(){let i=q("pr-review-config.json");sr(i)&&(R(`Config file already exists: ${i}`),v("Remove or rename the existing file and try again."),process.exit(1)),tt(i,JSON.stringify(ur,null,2)+`
117
- `,"utf-8"),S(`Created template config: ${i}`),v("Edit the file to add your Azure DevOps repository URLs and team members.")}function cr(i,e){let t=Xe(i.prs,e.botUsers),n=Qe(i.prs,i.analysis,e.botUsers),r;if(e.staleness.enabled){r={};let s=[...i.analysis.approved.map(o=>o.createdDate),...i.analysis.needingReview.map(o=>o.waitingSince),...i.analysis.waitingOnAuthor.map(o=>o.lastReviewerActivityDate)];for(let o of s){let l=D(o,e.staleness.thresholds);l&&(r[l]=(r[l]??0)+1)}}return{repoLabel:i.repoLabel,analysis:i.analysis,metrics:t,workload:n,staleness:r,stats:Ge(i.repoLabel,i.analysis,i.restarted,i.restartFailed)}}async function dr(i,e,t,n,r){if(r.length===0)return;let s=new Set(r),o=n.filter(l=>s.has(l.id));v(`Refreshing merge status for ${o.length} restarted PR(s)\u2026`);for(let l of o)try{let h=await x(`Refresh merge status for PR #${l.id}`,()=>i.getPullRequestById(l.id,t));h.mergeStatus!==void 0&&(l.mergeStatus=h.mergeStatus)}catch(h){let a=h instanceof Error?h.message:String(h);R(` #${l.id} \u2014 failed to refresh merge status: ${a}`)}}async function hr(i){let{repo:e,isMultiRepo:t,restartMergeAfterDays:n,quantifierConfig:r,teamMembers:s,ignoredUsers:o,botUsers:l,aiBotUsers:h}=i,a=`${e.project}/${e.repository}`;v(`Fetching open PRs from ${a}\u2026`);let u=Date.now(),d=r;r&&e.patterns.ignore.length>0&&(d={...r,excludedPatterns:[...r.excludedPatterns,...e.patterns.ignore]});let c=await We(e.orgUrl),m=await Rt(e.orgUrl),f=await Wt(c,e.repository,e.project,e.orgUrl,d,e.patterns,m);S(`Fetched ${f.length} candidate PRs from ${a} (${Date.now()-u}ms)`),await Gt(c,e.repository,e.project,f);let g=e.skipRestartMerge?-1:n;e.skipRestartMerge&&$(`Skipping restart-merge for ${a} (configured per repository)`);let p=await Ut(c,e.repository,e.project,f,g);await dr(c,e.repository,e.project,f,p.restartedPrIds);let C=Bt(f,s,t?a:void 0,o,l,h);return{repoLabel:a,prs:f,analysis:C,restarted:p.restarted,restartFailed:p.failed}}async function mn(i){v("Loading configuration\u2026");let e=await Mt(i),t=e.repos,n=t.length>1;v("Authenticating to Azure DevOps\u2026");let r=Date.now(),s=[...new Set(t.map(p=>p.orgUrl))];for(let p of s)await We(p);S(`Authenticated to ${s.join(", ")} (${Date.now()-r}ms)`);let o=0,l=0,h=0;v(`Processing ${t.length} repo(s) (concurrency: ${10})\u2026`);let a=await ae(t,10,p=>hr({repo:p,isMultiRepo:n,restartMergeAfterDays:e.restartMergeAfterDays,quantifierConfig:e.quantifier,teamMembers:e.teamMembers,ignoredUsers:e.ignoredUsers,botUsers:e.botUsers,aiBotUsers:e.aiBotUsers}));for(let p of a)o+=p.prs.length,l+=p.restarted,h+=p.restartFailed;let u=jt(a.map(p=>p.analysis)),d=a.map(p=>Ge(p.repoLabel,p.analysis,p.restarted,p.restartFailed)),c=Pt(u,l,h,d),m=a.flatMap(p=>p.prs),f=Xe(m,e.botUsers),g=Qe(m,u,e.botUsers);return{multiConfig:e,repos:t,isMultiRepo:n,results:a,merged:u,stats:c,allPrs:m,metrics:f,workload:g,totalPrs:o,totalRestarted:l,totalRestartFailed:h}}async function fn(i){Ct(i.verbose);let e=i.format??"markdown";if(e==="terminal"){let{multiConfig:c,repos:m,isMultiRepo:f,merged:g,stats:p,metrics:C,workload:A}=await mn(i.config),O=f?`${m.length} repositories`:`${m[0].project}/${m[0].repository}`,b=tn({analysis:g,repoLabel:O,multiRepo:f,stats:p,staleness:c.staleness,metrics:C,workload:A});console.log(b),c.notifications&&await et(g,p,c.notifications,c.staleness);return}Ve("PR Review Needed");let{multiConfig:t,repos:n,isMultiRepo:r,results:s,merged:o,stats:l,metrics:h,workload:a,totalPrs:u}=await mn(i.config);for(let c of s)S(`${c.repoLabel}: ${c.analysis.approved.length} approved, ${c.analysis.needingReview.length} needing review, ${c.analysis.waitingOnAuthor.length} waiting on author`);if(e==="json"||e==="html"){let c=s.map(g=>cr(g,t)),m=on(c,nt());if(e==="html"){v("Generating HTML report\u2026");let g=hn(m),p=i.output==="pr-review-summary.md"?"pr-review-summary.html":i.output;tt(q(p),g,"utf-8"),S(`HTML report written to ${q(p)}`)}else{v("Generating JSON report\u2026");let g=i.output==="pr-review-summary.md"?"pr-review-summary.json":i.output;await an(m,q(g))}let f=i.webhookUrl?{url:i.webhookUrl}:t.webhook;f&&await ln(m,f)}else{v("Generating markdown\u2026");let c=Zt({analysis:o,multiRepo:r,stats:l,staleness:t.staleness,metrics:h,workload:a}),m=q(i.output);tt(m,c,"utf-8"),S(`Output written to ${m}`)}Ve("Summary"),U("Repositories",n.length),U("PRs analyzed",u),U("Approved",o.approved.length),U("Needing review",o.needingReview.length),U("Waiting on author",o.waitingOnAuthor.length),U("Output file",q(i.output)),console.log(),i.notify!==!1&&t.notifications&&await et(o,l,t.notifications,t.staleness);let d=t.autoNudge;d&&i.nudge!==!1&&(i.dryRun&&(d.dryRun=!0),await cn(o,t.staleness,d))}process.removeAllListeners("warning");process.on("warning",i=>{(i.name!=="DeprecationWarning"||i.code!=="DEP0169")&&console.warn(i)});var it=new $t().name("pr-review-needed").description("Generates a markdown summary of Azure DevOps PRs needing review").version(nt());it.command("setup").description("Generate a template pr-review-config.json in the current directory").action(()=>{pn()});it.command("run").description("Analyze PRs and generate a markdown summary or dashboard").option("--output <path>","Output file path","pr-review-summary.md").option("--config <path>","Path to a custom config file").option("--format <type>","Output format: markdown, json, html, terminal","markdown").option("--webhook-url <url>","Send JSON report to webhook URL").option("--verbose","Enable debug logging",!1).option("--notify","Send notifications (default: true if webhooks configured)").option("--no-notify","Disable notifications").option("--nudge","Send nudge comments on stale PRs (default: true if configured)").option("--no-nudge","Disable auto-nudge comments").option("--dry-run","Log actions without making changes",!1).action(async i=>{await fn(i)});it.parseAsync(process.argv).catch(i=>{ne(i instanceof Error?i.message:String(i)),process.exit(1)});
106
+ `);if(s){let l=new Map;for(let h of t){let u=s(h)??"Unknown";l.has(u)||l.set(u,[]),l.get(u).push(h)}for(let[h,u]of l){o.push(` ${D}${j}\u{1F4C2} ${h}${_}`);for(let a of u){let{id:d,title:c,author:m,url:p,date:g,hasMergeConflict:f,action:A,size:b,detectedLabels:v,stalenessBadge:R,pipelineStatus:w,isStarred:y}=n(a);o.push(Qt(d,c,m,p,g,f,r,A,b,v,R,w,y))}o.push("")}}else{for(let l of t){let{id:h,title:u,author:a,url:d,date:c,hasMergeConflict:m,action:p,size:g,detectedLabels:f,stalenessBadge:A,pipelineStatus:b,isStarred:v}=n(l);o.push(Qt(h,u,a,d,c,m,r,p,g,f,A,b,v))}o.push("")}return o.join(`
107
+ `)}function Mi(i){let e=[];return e.push(`
108
+ ${Ze(tn,"\u{1F4C8} Review Metrics")}
109
+ `),e.push(` ${k}Median PR age:${_} ${D}${i.aggregate.medianAgeInDays}d${_} ${k}Avg first review:${_} ${D}${i.aggregate.avgTimeToFirstReviewInDays??"N/A"}d${_} ${k}Avg rounds:${_} ${D}${i.aggregate.avgReviewRounds}${_} ${k}No review:${_} ${D}${i.aggregate.prsWithNoReviewActivity}${_}`),e.push(""),e.join(`
110
+ `)}function Li(i){if(i.length===0)return"";let e=[];e.push(`
111
+ ${Ze(en,"\u{1F465} Top Reviewer Bottlenecks")}
112
+ `);let t=i.slice(0,5);for(let n of t){let r=n.avgResponseTimeInDays!==null?`${n.avgResponseTimeInDays}d avg`:"no response",s=n.isStarred?"\u2B50 ":"";e.push(` ${n.loadIndicator} ${D}${s}${n.displayName}${_} \u2014 ${n.pendingReviewCount} pending / ${n.assignedPrCount} assigned (${r})`)}return e.push(""),e.join(`
113
+ `)}function nn(i){let{analysis:e,repoLabel:t,multiRepo:n=!1,stats:r,staleness:s,metrics:o,workload:l,dependencyGraph:h}=i,u=new Date,{approved:a,needingReview:d,waitingOnAuthor:c}=e,m=s?.enabled!==!1?s?.thresholds??[]:[],p=[];p.push(""),p.push(`${D}${j} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${_}`),p.push(`${D}${j} \u2502 \u{1F4CB} PR Review Dashboard \u2502${_}`),p.push(`${D}${j} \u2502 ${_}${k}${Ke(t,42)}${_}${D}${j}${" ".repeat(Math.max(0,42-t.length))}\u2502${_}`),p.push(`${D}${j} \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${_}`),p.push("");let g=n?f=>f.repository:void 0;return p.push(Ye("\u2705 Approved",xi,a,f=>({id:f.id,title:f.title,author:f.author,url:f.url,date:f.createdDate,hasMergeConflict:f.hasMergeConflict,action:f.action,size:f.size,detectedLabels:f.detectedLabels,stalenessBadge:P(f.createdDate,m,u),pipelineStatus:f.pipelineStatus,isStarred:f.isStarred}),u,g)),p.push(Ye("\u{1F440} Needing Review",tn,d,f=>({id:f.id,title:f.title,author:f.author,url:f.url,date:f.waitingSince,hasMergeConflict:f.hasMergeConflict,action:f.action,size:f.size,detectedLabels:f.detectedLabels,stalenessBadge:P(f.waitingSince,m,u),pipelineStatus:f.pipelineStatus,isStarred:f.isStarred}),u,g)),p.push(Ye("\u270D\uFE0F Waiting on Author",en,c,f=>({id:f.id,title:f.title,author:f.author,url:f.url,date:f.lastReviewerActivityDate,hasMergeConflict:f.hasMergeConflict,action:f.action,size:f.size,detectedLabels:f.detectedLabels,stalenessBadge:P(f.lastReviewerActivityDate,m,u),pipelineStatus:f.pipelineStatus,isStarred:f.isStarred}),u,g)),o&&p.push(Mi(o)),l&&l.length>0&&p.push(Li(l)),h&&h.dependencies.length>0&&p.push(Ii(h)),p.push(` ${k}${ge(e,r)}${_}`),p.push(` ${k}Updated: ${u.toLocaleString()}${_}`),p.push(""),p.join(`
114
+ `)}function Ii(i){let e=[];e.push(` ${D}\u{1F517} PR Dependencies${_}`),e.push(` ${k}${i.chains.length} chain(s), ${i.blockedPrIds.length} blocked PR(s), ${i.dependencies.length} dependency link(s)${_}`);for(let t of i.chains.slice(0,5)){let n=t.prIds.map(s=>`#${s}`).join(" \u2192 "),r=t.status==="blocked"?`${ye}\u26A0\uFE0F blocked${_}`:`${be}\u2705 ready${_}`;e.push(` Chain ${t.chainId}: ${n} ${r}`)}return i.chains.length>5&&e.push(` ${k}... and ${i.chains.length-5} more chain(s)${_}`),e.push(""),e.join(`
115
+ `)}function rn(i,e){return Math.abs(e.getTime()-i.getTime())/(1e3*60*60*24)}function Fi(i){if(i.length===0)return 0;let e=[...i].sort((n,r)=>n-r),t=Math.floor(e.length/2);return e.length%2!==0?e[t]:(e[t-1]+e[t])/2}function Hi(i,e,t){let n=je(i,e),r=n.filter(d=>!d.isAuthor).sort((d,c)=>d.date.getTime()-c.date.getTime()),s=rn(i.createdDate,t),o=r.length>0?rn(i.createdDate,r[0].date):null,l=n.sort((d,c)=>d.date.getTime()-c.date.getTime()),h=0,u=!1;for(let d of l)d.isAuthor?u=!0:u&&(h++,u=!1);let a=l.length>0?l[l.length-1].date:i.createdDate;return{prId:i.id,title:i.title,author:i.author,url:i.url,ageInDays:Math.round(s*10)/10,timeToFirstReviewInDays:o!==null?Math.round(o*10)/10:null,reviewRounds:h,lastActivityDate:a}}function Xe(i,e=new Set,t=new Date,n=new Set){let r=i.map(m=>Hi(m,e,t)),s=r.map(m=>m.ageInDays),o=r.map(m=>m.timeToFirstReviewInDays).filter(m=>m!==null),l=r.map(m=>m.reviewRounds),h=r.filter(m=>m.timeToFirstReviewInDays===null).length,u={medianAgeInDays:Math.round(Fi(s)*10)/10,avgTimeToFirstReviewInDays:o.length>0?Math.round(o.reduce((m,p)=>m+p,0)/o.length*10)/10:null,avgReviewRounds:l.length>0?Math.round(l.reduce((m,p)=>m+p,0)/l.length*10)/10:0,prsWithNoReviewActivity:h,totalPrs:i.length},a=new Map,d=new Map;for(let m of i)d.set(m.author,m.authorUniqueName);for(let m of r)a.has(m.author)||a.set(m.author,[]),a.get(m.author).push(m);let c=[];for(let[m,p]of a){let g=p.map(b=>b.ageInDays),f=p.map(b=>b.reviewRounds),A=p.map(b=>b.timeToFirstReviewInDays).filter(b=>b!==null);c.push({author:m,isStarred:n.has(d.get(m)??""),openPrCount:p.length,avgAgeInDays:Math.round(g.reduce((b,v)=>b+v,0)/g.length*10)/10,avgReviewRounds:Math.round(f.reduce((b,v)=>b+v,0)/f.length*10)/10,fastestReviewInDays:A.length>0?Math.round(Math.min(...A)*10)/10:null})}return c.sort((m,p)=>p.openPrCount-m.openPrCount),{perPr:r,aggregate:u,perAuthor:c}}var Vi={light:{maxPending:10,maxAvgResponseDays:2},medium:{maxPending:20,maxAvgResponseDays:4}};function Ui(i,e,t){let n=r=>e!==null&&e>r;return i>t.medium.maxPending||n(t.medium.maxAvgResponseDays)?"\u{1F534}":i>t.light.maxPending||n(t.light.maxAvgResponseDays)?"\u{1F7E1}":"\u{1F7E2}"}function Qe(i,e,t=new Set,n=Vi,r=new Set,s=new Set){let o=new Set(e.needingReview.map(u=>u.id)),l=new Map;for(let u of i)if(!me(u.authorUniqueName,t,u.author,r))for(let a of u.reviewers){if(me(a.uniqueName,t,a.displayName,r))continue;let d=a.uniqueName.toLowerCase();l.has(d)||l.set(d,{displayName:a.displayName,assignedPrCount:0,pendingReviewCount:0,completedReviewCount:0,responseTimes:[]});let c=l.get(d);c.assignedPrCount++,a.vote>=5?c.completedReviewCount++:o.has(u.id)&&c.pendingReviewCount++;let m=u.threads.flatMap(p=>p.comments).filter(p=>p.authorUniqueName.toLowerCase()===d).sort((p,g)=>p.publishedDate.getTime()-g.publishedDate.getTime());if(m.length>0){let p=(m[0].publishedDate.getTime()-u.createdDate.getTime())/864e5;p>=0&&c.responseTimes.push(p)}}let h=[];for(let[u,a]of l){let d=a.responseTimes.length>0?Math.round(a.responseTimes.reduce((c,m)=>c+m,0)/a.responseTimes.length*10)/10:null;h.push({reviewer:u,displayName:a.displayName,isStarred:s.has(u),assignedPrCount:a.assignedPrCount,pendingReviewCount:a.pendingReviewCount,completedReviewCount:a.completedReviewCount,avgResponseTimeInDays:d,loadIndicator:Ui(a.pendingReviewCount,d,n)})}return h.sort((u,a)=>a.pendingReviewCount-u.pendingReviewCount),h}function sn(i,e){let t=e?` ${e}`:"",n=i.isStarred?"\u2B50 ":"";return`[#${i.id} - ${i.title}](${i.url}) \u2014 ${n}${i.author}${t}`}function Wi(i,e,t,n){let r=t?.enabled!==!1?t?.thresholds??[]:[],o=[{type:"TextBlock",text:`\u{1F4CB} PR Review Summary \u2014 ${i.approved.length+i.needingReview.length+i.waitingOnAuthor.length} open PRs`,size:"Large",weight:"Bolder"},{type:"TextBlock",text:`\u2705 ${i.approved.length} approved | \u{1F440} ${i.needingReview.length} needing review | \u270D\uFE0F ${i.waitingOnAuthor.length} waiting on author | \u274C ${e.totalConflicts} conflicts`,wrap:!0,spacing:"Small"}],l=h=>!n||n.includes(h);if(l("needingReview")&&i.needingReview.length>0){o.push({type:"TextBlock",text:`**\u{1F440} PRs Needing Review (${i.needingReview.length})**`,separator:!0,spacing:"Medium"});let h=i.needingReview.slice(0,15);for(let u of h){let a=P(u.waitingSince,r);o.push({type:"TextBlock",text:sn(u,a),wrap:!0,spacing:"Small"})}i.needingReview.length>15&&o.push({type:"TextBlock",text:`_\u2026and ${i.needingReview.length-15} more_`,spacing:"Small"})}if(l("waitingOnAuthor")&&i.waitingOnAuthor.length>0){o.push({type:"TextBlock",text:`**\u270D\uFE0F Waiting on Author (${i.waitingOnAuthor.length})**`,separator:!0,spacing:"Medium"});let h=i.waitingOnAuthor.slice(0,10);for(let u of h){let a=P(u.lastReviewerActivityDate,r);o.push({type:"TextBlock",text:sn(u,a),wrap:!0,spacing:"Small"})}i.waitingOnAuthor.length>10&&o.push({type:"TextBlock",text:`_\u2026and ${i.waitingOnAuthor.length-10} more_`,spacing:"Small"})}return l("approved")&&i.approved.length>0&&(o.push({type:"TextBlock",text:`**\u2705 Approved (${i.approved.length})**`,separator:!0,spacing:"Medium"}),o.push({type:"TextBlock",text:`${i.approved.length} PRs approved and ready to merge.`,spacing:"Small"})),{type:"message",attachments:[{contentType:"application/vnd.microsoft.card.adaptive",content:{type:"AdaptiveCard",$schema:"http://adaptivecards.io/schemas/adaptive-card.json",version:"1.4",body:o}}]}}async function on(i,e,t,n){let r=Wi(i,e,n,t.filters?.sections);try{let s=await fetch(t.webhookUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});s.ok?x("Teams notification sent successfully"):O(`Teams notification failed: ${s.status} ${s.statusText}`)}catch(s){let o=s instanceof Error?s.message:String(s);O(`Teams notification failed: ${o}`)}}async function et(i,e,t,n){if(!t.teams?.webhookUrl){$("No notification webhooks configured, skipping");return}S("Sending Teams notification\u2026"),await on(i,e,t.teams,n)}import{writeFileSync as Gi}from"node:fs";function an(i,e,t){let n=i.reduce((u,a)=>u+a.analysis.approved.length+a.analysis.needingReview.length+a.analysis.waitingOnAuthor.length,0),r,s=i.filter(u=>u.metrics).map(u=>u.metrics);if(s.length>0){let u=s.map(a=>a.aggregate);r={medianAgeInDays:u.reduce((a,d)=>a+d.medianAgeInDays,0)/u.length,avgTimeToFirstReviewInDays:Bi(u.map(a=>a.avgTimeToFirstReviewInDays)),avgReviewRounds:u.reduce((a,d)=>a+d.avgReviewRounds,0)/u.length,prsWithNoReviewActivity:u.reduce((a,d)=>a+d.prsWithNoReviewActivity,0),totalPrs:u.reduce((a,d)=>a+d.totalPrs,0)}}let o,l=i.filter(u=>u.staleness).map(u=>u.staleness);if(l.length>0){o={};for(let u of l)for(let[a,d]of Object.entries(u))o[a]=(o[a]??0)+d}let h={totalPrs:n,metrics:r,staleness:o};return{generatedAt:(t??new Date).toISOString(),version:e,repositories:i,aggregate:h}}async function ln(i,e){let t=JSON.stringify(i,null,2);e==="-"?process.stdout.write(t+`
116
+ `):(Gi(e,t,"utf-8"),x(`JSON report written to ${e}`))}async function un(i,e){let t=e.method??"POST";try{let n=await fetch(e.url,{method:t,headers:{"Content-Type":"application/json",...e.headers},body:JSON.stringify(i)});n.ok?x(`Webhook ${t} to ${e.url} succeeded (${n.status})`):O(`Webhook ${t} to ${e.url} returned ${n.status}: ${n.statusText}`)}catch(n){let r=n instanceof Error?n.message:String(n);O(`Webhook ${t} to ${e.url} failed: ${r}`)}}function Bi(i){let e=i.filter(t=>t!==null);return e.length===0?null:e.reduce((t,n)=>t+n,0)/e.length}import{readFileSync as qi,writeFileSync as ji,existsSync as zi}from"node:fs";import{resolve as cn}from"node:path";function Ji(i){let e=cn(i);if(!zi(e))return{entries:[]};try{let t=qi(e,"utf-8"),n=JSON.parse(t);return n&&Array.isArray(n.entries)?n:{entries:[]}}catch{return O(`Failed to parse nudge history at ${e}, starting fresh`),{entries:[]}}}function Yi(i,e){let t=cn(i);ji(t,JSON.stringify(e,null,2),"utf-8")}function Ki(i,e,t,n,r=new Date){let s=new Map;for(let h of n.entries)s.set(`${h.repoUrl}:${h.prId}`,h);let o=e.thresholds,l=-1;return t.minStalenessLevel&&(l=o.findIndex(h=>h.label===t.minStalenessLevel)),i.filter(h=>{let u=P(h.waitingSince,o,r);if(!u)return!1;if(l>=0){let c=o.findIndex(m=>m.label===u);if(c<0||c>l)return!1}let a=`${h.url}:${h.id}`,d=s.get(a);if(d){let c=new Date(d.lastNudgedAt);if((r.getTime()-c.getTime())/(1e3*60*60*24)<t.cooldownDays)return!1}return!0})}function Zi(i,e,t){return e.commentTemplate.replace(/\{\{days\}\}/g,String(t)).replace(/\{\{reviewers\}\}/g,i.reviewerNames?.join(", ")??"Reviewers").replace(/\{\{title\}\}/g,i.title).replace(/\{\{author\}\}/g,i.author)}function Xi(i){let e=i.match(/^(https:\/\/dev\.azure\.com\/[^/]+)\/([^/]+)\/_git\/([^/]+)/);return e?{orgUrl:e[1],project:e[2],repoName:e[3]}:null}async function Qi(i,e,t,n,r){let s=`${i}/${e}/_apis/git/repositories/${t}/pullRequests/${n}/threads?api-version=7.1`,l=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({comments:[{content:r,commentType:1}],status:"active"})});if(!l.ok)throw new Error(`ADO API returned ${l.status}: ${l.statusText}`)}async function dn(i,e,t,n=new Date){let r=Ji(t.historyFile),s=Ki(i.needingReview,e,t,r,n),o={nudged:0,skipped:0,errors:0};if(s.length===0)return S("Auto-nudge: no PRs eligible for nudging"),o;S(`Auto-nudge: ${s.length} PR(s) eligible for nudging`);for(let l of s){let h=n.getTime()-l.waitingSince.getTime(),u=Math.floor(h/(1e3*60*60*24)),a=Zi(l,t,u);if(t.dryRun){S(` [DRY RUN] Would nudge #${l.id} "${l.title}" (${u} days)`),o.nudged++;continue}let d=Xi(l.url);if(!d){O(` #${l.id} \u2014 could not parse ADO URL: ${l.url}`),o.errors++;continue}try{await Qi(d.orgUrl,d.project,d.repoName,l.id,a),x(` #${l.id} "${l.title}" \u2014 nudged (${u} days)`),o.nudged++;let c=r.entries.findIndex(p=>p.repoUrl===l.url&&p.prId===l.id),m={prId:l.id,repoUrl:l.url,lastNudgedAt:n.toISOString(),nudgeCount:c>=0?r.entries[c].nudgeCount+1:1};c>=0?r.entries[c]=m:r.entries.push(m)}catch(c){let m=c instanceof Error?c.message:String(c);O(` #${l.id} "${l.title}" \u2014 nudge failed: ${m}`),o.errors++}}return t.dryRun||Yi(t.historyFile,r),S(`Auto-nudge: ${o.nudged} nudged, ${o.skipped} skipped, ${o.errors} errors`),o}import{readFileSync as er}from"node:fs";import{resolve as hn,dirname as tr}from"node:path";import{fileURLToPath as nr}from"node:url";var ir=tr(nr(import.meta.url));function rr(){let i=[hn(ir,"template.html"),hn(process.cwd(),"src","reporting","html-report","template.html")];for(let e of i)try{return er(e,"utf-8")}catch{}throw new Error(`HTML template not found. Searched: ${i.join(", ")}`)}var sr="{{DATA_PLACEHOLDER}}";function mn(i){let e=rr(),t=JSON.stringify(i);return e.replace(sr,t)}var cr={$schema:"https://raw.githubusercontent.com/Meir017/ado-pr-review-needed/main/pr-review-config.schema.json",repositories:[{url:"https://dev.azure.com/{org}/{project}/_git/{repo}"}],orgManager:null,teamMembers:[],ignoreManagers:!1};function nt(){let i=B(lr(ur(import.meta.url)),"..","package.json");try{return JSON.parse(ar(i,"utf-8")).version??"0.0.0"}catch{return"0.0.0"}}function fn(){let i=B("pr-review-config.json");or(i)&&(O(`Config file already exists: ${i}`),S("Remove or rename the existing file and try again."),process.exit(1)),tt(i,JSON.stringify(cr,null,2)+`
117
+ `,"utf-8"),x(`Created template config: ${i}`),S("Edit the file to add your Azure DevOps repository URLs and team members.")}function dr(i,e){let t=Xe(i.prs,e.botUsers,void 0,e.starredUsers),n=Qe(i.prs,i.analysis,e.botUsers,void 0,e.aiBotUsers,e.starredUsers),r;if(e.staleness.enabled){r={};let s=[...i.analysis.approved.map(o=>o.createdDate),...i.analysis.needingReview.map(o=>o.waitingSince),...i.analysis.waitingOnAuthor.map(o=>o.lastReviewerActivityDate)];for(let o of s){let l=P(o,e.staleness.thresholds);l&&(r[l]=(r[l]??0)+1)}}return{repoLabel:i.repoLabel,analysis:i.analysis,metrics:t,workload:n,staleness:r,stats:We(i.repoLabel,i.analysis,i.restarted,i.restartFailed)}}async function hr(i,e,t,n,r){if(r.length===0)return;let s=new Set(r),o=n.filter(l=>s.has(l.id));S(`Refreshing merge status for ${o.length} restarted PR(s)\u2026`);for(let l of o)try{let h=await E(`Refresh merge status for PR #${l.id}`,()=>i.getPullRequestById(l.id,t));h.mergeStatus!==void 0&&(l.mergeStatus=h.mergeStatus)}catch(h){let u=h instanceof Error?h.message:String(h);O(` #${l.id} \u2014 failed to refresh merge status: ${u}`)}}async function mr(i){let{repo:e,isMultiRepo:t,restartMergeAfterDays:n,quantifierConfig:r,teamMembers:s,ignoredUsers:o,botUsers:l,aiBotUsers:h}=i,u=`${e.project}/${e.repository}`;S(`Fetching open PRs from ${u}\u2026`);let a=Date.now(),d=r;r&&e.patterns.ignore.length>0&&(d={...r,excludedPatterns:[...r.excludedPatterns,...e.patterns.ignore]});let c=await Ue(e.orgUrl),m=await Ot(e.orgUrl),p=await Ut(c,e.repository,e.project,e.orgUrl,d,e.patterns,m);x(`Fetched ${p.length} candidate PRs from ${u} (${Date.now()-a}ms)`),await Wt(c,e.repository,e.project,p);let g=e.skipRestartMerge?-1:n;e.skipRestartMerge&&$(`Skipping restart-merge for ${u} (configured per repository)`);let f=await Gt(c,e.repository,e.project,p,g);await hr(c,e.repository,e.project,p,f.restartedPrIds);let A=qt(p,s,t?u:void 0,o,l,h,i.starredUsers);return{repoLabel:u,prs:p,analysis:A,restarted:f.restarted,restartFailed:f.failed}}async function pn(i){S("Loading configuration\u2026");let e=await Mt(i),t=e.repos,n=t.length>1;S("Authenticating to Azure DevOps\u2026");let r=Date.now(),s=[...new Set(t.map(f=>f.orgUrl))];for(let f of s)await Ue(f);x(`Authenticated to ${s.join(", ")} (${Date.now()-r}ms)`);let o=0,l=0,h=0;S(`Processing ${t.length} repo(s) (concurrency: ${10})\u2026`);let u=await ue(t,10,f=>mr({repo:f,isMultiRepo:n,restartMergeAfterDays:e.restartMergeAfterDays,quantifierConfig:e.quantifier,teamMembers:e.teamMembers,ignoredUsers:e.ignoredUsers,botUsers:e.botUsers,aiBotUsers:e.aiBotUsers,starredUsers:e.starredUsers}));for(let f of u)o+=f.prs.length,l+=f.restarted,h+=f.restartFailed;let a=jt(u.map(f=>f.analysis)),d=u.map(f=>We(f.repoLabel,f.analysis,f.restarted,f.restartFailed)),c=Pt(a,l,h,d),m=u.flatMap(f=>f.prs),p=Xe(m,e.botUsers,void 0,e.starredUsers),g=Qe(m,a,e.botUsers,void 0,e.aiBotUsers,e.starredUsers);return{multiConfig:e,repos:t,isMultiRepo:n,results:u,merged:a,stats:c,allPrs:m,metrics:p,workload:g,totalPrs:o,totalRestarted:l,totalRestartFailed:h}}async function gn(i){Ct(i.verbose);let e=i.format??"markdown";if(e==="terminal"){let{multiConfig:c,repos:m,isMultiRepo:p,merged:g,stats:f,metrics:A,workload:b}=await pn(i.config),v=p?`${m.length} repositories`:`${m[0].project}/${m[0].repository}`,R=nn({analysis:g,repoLabel:v,multiRepo:p,stats:f,staleness:c.staleness,metrics:A,workload:b});console.log(R),c.notifications&&await et(g,f,c.notifications,c.staleness);return}Ve("PR Review Needed");let{multiConfig:t,repos:n,isMultiRepo:r,results:s,merged:o,stats:l,metrics:h,workload:u,totalPrs:a}=await pn(i.config);for(let c of s)x(`${c.repoLabel}: ${c.analysis.approved.length} approved, ${c.analysis.needingReview.length} needing review, ${c.analysis.waitingOnAuthor.length} waiting on author`);if(e==="json"||e==="html"){let c=s.map(g=>dr(g,t)),m=an(c,nt());if(e==="html"){S("Generating HTML report\u2026");let g=mn(m),f=i.output==="pr-review-summary.md"?"pr-review-summary.html":i.output;tt(B(f),g,"utf-8"),x(`HTML report written to ${B(f)}`)}else{S("Generating JSON report\u2026");let g=i.output==="pr-review-summary.md"?"pr-review-summary.json":i.output;await ln(m,B(g))}let p=i.webhookUrl?{url:i.webhookUrl}:t.webhook;p&&await un(m,p)}else{S("Generating markdown\u2026");let c=Xt({analysis:o,multiRepo:r,stats:l,staleness:t.staleness,metrics:h,workload:u}),m=B(i.output);tt(m,c,"utf-8"),x(`Output written to ${m}`)}Ve("Summary"),G("Repositories",n.length),G("PRs analyzed",a),G("Approved",o.approved.length),G("Needing review",o.needingReview.length),G("Waiting on author",o.waitingOnAuthor.length),G("Output file",B(i.output)),console.log(),i.notify!==!1&&t.notifications&&await et(o,l,t.notifications,t.staleness);let d=t.autoNudge;d&&i.nudge!==!1&&(i.dryRun&&(d.dryRun=!0),await dn(o,t.staleness,d))}process.removeAllListeners("warning");process.on("warning",i=>{(i.name!=="DeprecationWarning"||i.code!=="DEP0169")&&console.warn(i)});var it=new $t().name("pr-review-needed").description("Generates a markdown summary of Azure DevOps PRs needing review").version(nt());it.command("setup").description("Generate a template pr-review-config.json in the current directory").action(()=>{fn()});it.command("run").description("Analyze PRs and generate a markdown summary or dashboard").option("--output <path>","Output file path","pr-review-summary.md").option("--config <path>","Path to a custom config file").option("--format <type>","Output format: markdown, json, html, terminal","markdown").option("--webhook-url <url>","Send JSON report to webhook URL").option("--verbose","Enable debug logging",!1).option("--notify","Send notifications (default: true if webhooks configured)").option("--no-notify","Disable notifications").option("--nudge","Send nudge comments on stale PRs (default: true if configured)").option("--no-nudge","Disable auto-nudge comments").option("--dry-run","Log actions without making changes",!1).action(async i=>{await gn(i)});it.parseAsync(process.argv).catch(i=>{re(i instanceof Error?i.message:String(i)),process.exit(1)});
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "@meirblachman/pr-review-needed",
3
- "version": "0.1.22",
4
- "description": "Generates a markdown summary of Azure DevOps PRs needing review",
5
- "type": "module",
6
- "bin": {
7
- "pr-review-needed": "dist/index.min.js"
8
- },
9
- "files": [
10
- "dist/index.min.js"
11
- ],
12
- "repository": {
13
- "type": "git",
14
- "url": "https://github.com/meir017/ado-pr-review-needed.git"
15
- },
16
- "publishConfig": {
17
- "registry": "https://registry.npmjs.org",
18
- "access": "public"
19
- },
20
- "scripts": {
21
- "build": "tsc",
22
- "bundle": "esbuild dist/index.js --bundle --minify --platform=node --format=esm --target=node22 --outfile=dist/index.min.js --banner:js=\"#!/usr/bin/env node\" --external:@azure/identity --external:azure-devops-node-api --external:picomatch",
23
- "prepublishOnly": "npm run build && npm run bundle",
24
- "start": "tsx src/index.ts run",
25
- "lint": "eslint src/",
26
- "test": "vitest run"
27
- },
28
- "dependencies": {
29
- "@azure/identity": "^4.6.0",
30
- "azure-devops-node-api": "^15.1.2",
31
- "commander": "^14.0.3",
32
- "picomatch": "^4.0.3"
33
- },
34
- "engines": {
35
- "node": ">=22.0.0"
36
- },
37
- "devDependencies": {
38
- "@eslint/js": "^10.0.1",
39
- "@types/node": "^25.2.3",
40
- "@types/picomatch": "^4.0.2",
41
- "@vitest/coverage-v8": "^4.0.18",
42
- "esbuild": "^0.27.3",
43
- "eslint": "^10.0.0",
44
- "tsx": "^4.19.0",
45
- "typescript": "^5.7.0",
46
- "typescript-eslint": "^8.56.0",
47
- "vitest": "^4.0.18"
48
- }
49
- }
1
+ {
2
+ "name": "@meirblachman/pr-review-needed",
3
+ "version": "0.1.24",
4
+ "description": "Generates a markdown summary of Azure DevOps PRs needing review",
5
+ "type": "module",
6
+ "bin": {
7
+ "pr-review-needed": "dist/index.min.js"
8
+ },
9
+ "files": [
10
+ "dist/index.min.js"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/Meir017/ado-pr-review-needed.git"
15
+ },
16
+ "publishConfig": {
17
+ "registry": "https://registry.npmjs.org",
18
+ "access": "public"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "bundle": "esbuild dist/index.js --bundle --minify --platform=node --format=esm --target=node24 --outfile=dist/index.min.js --banner:js=\"#!/usr/bin/env node\" --external:@azure/identity --external:azure-devops-node-api --external:picomatch",
23
+ "prepublishOnly": "npm run build && npm run bundle",
24
+ "start": "tsx src/index.ts run",
25
+ "lint": "eslint src/",
26
+ "test": "vitest run"
27
+ },
28
+ "dependencies": {
29
+ "@azure/identity": "^4.6.0",
30
+ "azure-devops-node-api": "^15.1.2",
31
+ "commander": "^14.0.3",
32
+ "picomatch": "^4.0.3"
33
+ },
34
+ "engines": {
35
+ "node": ">=24.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/js": "^10.0.1",
39
+ "@types/node": "^25.2.3",
40
+ "@types/picomatch": "^4.0.2",
41
+ "@vitest/coverage-v8": "^4.0.18",
42
+ "esbuild": "^0.27.3",
43
+ "eslint": "^10.0.0",
44
+ "tsx": "^4.19.0",
45
+ "typescript": "^5.7.0",
46
+ "typescript-eslint": "^8.56.0",
47
+ "vitest": "^4.0.18"
48
+ }
49
+ }