docs: async function installExtension(extension, dir) {
    if (extension.slice(-4) !== '.xpi') {
      throw Error('Path ath is not a xpi file: ' + extension);
    }
  
    let archive = await zip.load(extension);
    if (!archive.has('manifest.json')) {
      throw new AddonFormatError(`Couldn't find manifest.json in ${extension}`);
    }
  
    let buf = await archive.getFile('manifest.json');
    let {applications} =
        /** @type {{applications:{gecko:{id:string}}}} */(
            JSON.parse(buf.toString('utf8')));
    if (!(applications && applications.gecko && applications.gecko.id)) {
      throw new AddonFormatError(`Could not find add-on ID for ${extension}`);
    }
  
    await io.copy(extension, `${path.join(dir, applications.gecko.id)}.xpi`);
    return applications.gecko.id;
  }