{"id":38058005,"url":"https://github.com/lpgera/dirigera","last_synced_at":"2026-01-16T20:26:54.506Z","repository":{"id":64534380,"uuid":"575953959","full_name":"lpgera/dirigera","owner":"lpgera","description":"An unofficial JavaScript/TypeScript client library for IKEA's DIRIGERA smart home hub","archived":false,"fork":false,"pushed_at":"2025-12-20T18:53:00.000Z","size":313,"stargazers_count":75,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-12-22T09:09:38.049Z","etag":null,"topics":["dirigera","ikea","iot","javascript","nodejs","smarthome","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/dirigera","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lpgera.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-12-08T17:10:53.000Z","updated_at":"2025-12-20T18:53:03.000Z","dependencies_parsed_at":"2024-01-13T20:24:08.381Z","dependency_job_id":"0672130e-9d93-418a-851f-fd57123128a1","html_url":"https://github.com/lpgera/dirigera","commit_stats":{"total_commits":65,"total_committers":1,"mean_commits":65.0,"dds":0.0,"last_synced_commit":"db7fbff3ee63f729abd764816b4d03f684854d7f"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/lpgera/dirigera","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpgera%2Fdirigera","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpgera%2Fdirigera/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpgera%2Fdirigera/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpgera%2Fdirigera/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lpgera","download_url":"https://codeload.github.com/lpgera/dirigera/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpgera%2Fdirigera/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dirigera","ikea","iot","javascript","nodejs","smarthome","typescript"],"created_at":"2026-01-16T20:26:54.306Z","updated_at":"2026-01-16T20:26:54.491Z","avatar_url":"https://github.com/lpgera.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Dirigera\n\nAn unofficial TypeScript client library for IKEA's DIRIGERA smart home hub.\n\nThe library is based on reverse-engineering the communication with the DIRIGERA hub. Changes to the hub's firmware may\nbreak functionality. Some of the type definitions are incomplete, and some of the methods are not tested. Feedback and\ncontributions are welcome!\n\n- [Quick start](#quick-start)\n- [CLI](#cli)\n  - [Help](#help)\n  - [Authentication](#authentication)\n  - [Dump](#dump)\n- [Library](#library)\n  - [Client](#client)\n  - [Hub](#hub)\n  - [Devices](#devices)\n    - [Air purifiers](#air-purifiers)\n    - [Blinds](#blinds)\n    - [Controllers](#controllers)\n    - [Environment sensors](#environment-sensors)\n    - [Lights](#lights)\n    - [Light sensors](#light-sensors)\n    - [Motion sensors](#motion-sensors)\n    - [Occupancy sensors](#occupancy-sensors)\n    - [Outlets](#outlets)\n    - [Open/close sensors](#openclose-sensors)\n    - [Repeaters](#repeaters)\n    - [Speakers](#speakers)\n    - [Water sensors](#water-sensors)\n  - [Device sets](#device-sets)\n  - [Rooms](#rooms)\n  - [Scenes](#scenes)\n  - [Music](#music)\n  - [Users](#users)\n  - [Update events](#update-events)\n- [Troubleshooting](#troubleshooting)\n\n## Quick start\n\n1. Execute `npx dirigera authenticate` in your terminal and follow the instructions.\n2. Save the obtained access token.\n3. [Optional] To get your device IDs, dump your Dirigera system's information as a JSON:\n   `npx dirigera dump --access-token \u003cYOUR_ACCESS_TOKEN\u003e`\n4. Install the library as a dependency: `npm i dirigera`\n5. Create a client instance in your code with the access token:\n\n   ```typescript\n   import { createDirigeraClient } from 'dirigera'\n\n   const client = await createDirigeraClient({\n     accessToken: 'YOUR_ACCESS_TOKEN',\n   })\n   ```\n\n6. You are ready to control your devices!\n   ```typescript\n   await client.lights.setIsOn({\n     id: 'YOUR_DEVICE_ID',\n     isOn: true,\n   })\n   ```\n\n## CLI\n\n### Help\n\n```bash\nnpx dirigera help [command]\n```\n\n### Authentication\n\nTo be able to communicate with your DIRIGERA hub, you have to obtain an access token by pairing with it.\n\nUse the following command to do this via the CLI:\n\n```bash\nnpx dirigera authenticate\n```\n\nYou'll be prompted to press the action button on the bottom of the gateway within 60 seconds. If the pairing is\nsuccessful, an access token will be printed on your console.\n\nStore the access token in a secure place, and never share it with anyone outside your household!\n\n### Dump\n\nUse the following command to dump a JSON from your gateway. This can be useful for adding support of new devices to the\nlibrary or to debug issues that may arise from device or gateway firmware changes.\n\n```bash\nnpx dirigera dump --access-token YOUR_ACCESS_TOKEN\n```\n\n## Library\n\n### Client\n\nYou can rely on mDNS discovery to connect to the gateway without specifying an IP address.\n\n```typescript\nconst client = await createDirigeraClient({\n  accessToken: 'YOUR_ACCESS_TOKEN',\n})\n```\n\nAlternatively, if mDNS discovery fails, it's possible to explicitly set the IP address.\n\n```typescript\nconst client = await createDirigeraClient({\n  gatewayIP: 'YOUR_GATEWAY_IP',\n  accessToken: 'YOUR_ACCESS_TOKEN',\n})\n```\n\nIf you want to authenticate without using the CLI, you can use the following method:\n\n```typescript\nconst client = await createDirigeraClient()\n\nconst accessToken = await client.authenticate() // You have to press the action button on the gateway after this\n```\n\nTo get every device, room, scene, etc. in a single object:\n\n```typescript\nconst home = await client.home()\n```\n\n### [Hub](./src/api/hub.ts)\n\n```typescript\nconst hubStatus = await client.hub.status()\n\nawait client.hub.checkFirmwareUpdate()\n\nawait client.hub.installFirmwareUpdate()\n```\n\n### [Devices](./src/api/devices.ts)\n\nGeneric device API.\n\n```typescript\nconst devices = await client.devices.list()\n\nconst device = await client.devices.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.devices.setCustomName({\n  id: 'YOUR_DEVICE_ID',\n  customName: 'A_CUSTOM_NAME',\n})\n\n// low level method to set attributes, use device type specific apis if possible\n// some attributes may not be combined with each other and require separate setAttributes calls\nawait client.devices.setAttributes({\n  id: 'YOUR_DEVICE_ID',\n  attributes: {\n    // ...\n  },\n  transitionTime: 5000, // optional, in milliseconds\n})\n\nawait client.devices.startIdentifying({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.devices.stopIdentifying({\n  id: 'YOUR_DEVICE_ID',\n})\n```\n\n#### [Air purifiers](./src/api/airPurifiers.ts)\n\n```typescript\nconst airPurifiers = await client.airPurifiers.list()\n\nconst airPurifier = await client.airPurifiers.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.airPurifiers.setFanMode({\n  id: 'YOUR_DEVICE_ID',\n  fanMode: 'auto', // 'auto' | 'low' | 'medium' | 'high' | 'off'\n})\n\nawait client.airPurifiers.setMotorState({\n  id: 'YOUR_DEVICE_ID',\n  motorState: 0, // between 0 and 50\n})\n\nawait client.airPurifiers.setChildLock({\n  id: 'YOUR_DEVICE_ID',\n  childLock: true,\n})\n\nawait client.airPurifiers.setStatusLight({\n  id: 'YOUR_DEVICE_ID',\n  statusLight: true,\n})\n```\n\n#### [Blinds](./src/api/blinds.ts)\n\nNot tested, feedback required.\n\n```typescript\nconst blinds = await client.blinds.list()\n\nconst blind = await client.blinds.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.blinds.setCurrentLevel({\n  id: 'YOUR_DEVICE_ID',\n  blindsCurrentLevel: 0,\n})\n\nawait client.blinds.setTargetLevel({\n  id: 'YOUR_DEVICE_ID',\n  blindsTargetLevel: 60,\n})\n\nawait client.blinds.setState({\n  id: 'YOUR_DEVICE_ID',\n  blindsState: 'stopped', // 'stopped' | 'up' | 'down'\n})\n```\n\n#### [Controllers](./src/api/controllers.ts)\n\nSome controllers, such as the BILRESA remote appear as multiple devices.\n\n```typescript\nconst controllers = await client.controllers.list()\n\nconst controller = await client.controllers.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\n// Set the control mode of a BILRESA remote.\n// The scroll wheel version supports 'light' and 'speaker' modes, the dual button version supports all four modes.\nawait client.controllers.setControlMode({\n  id: 'YOUR_DEVICE_ID',\n  controlMode: 'light', // 'light' | 'speaker' | 'blind' | 'shortcut'\n})\n```\n\n#### [Environment sensors](./src/api/environmentSensors.ts)\n\nSupports VINDSTYRKA, TIMMERFLOTTE and ALPSTUGA sensors. The available attributes vary between models.\n\nThe TIMMERFLOTTE sensor appears as two devices, one measures temperature, the other measures relative humidity.\n\n```typescript\nconst environmentSensors = await client.environmentSensors.list()\n\nconst environmentSensor = await client.environmentSensors.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nconst { currentTemperature, currentRH, currentPM25, vocIndex } =\n  environmentSensor.attributes\n\n// The ALPSTUGA screen can be turned on and off\nawait client.devices.setAttributes({\n  id: 'YOUR_DEVICE_ID',\n  attributes: {\n    isOn: false,\n  },\n})\n```\n\n#### [Lights](./src/api/lights.ts)\n\n```typescript\nconst lights = await client.lights.list()\n\nconst light = await client.lights.get({ id: 'YOUR_DEVICE_ID' })\n\nawait client.lights.setIsOn({\n  id: 'YOUR_DEVICE_ID',\n  isOn: true,\n})\n\nawait client.lights.setLightLevel({\n  id: 'YOUR_DEVICE_ID',\n  lightLevel: 50, // between 1 and 100\n  transitionTime: 5000, // optional, in milliseconds\n})\n\nawait client.lights.setLightColor({\n  id: 'YOUR_DEVICE_ID',\n  colorHue: 260, // between 0 and 359\n  colorSaturation: 0.8, // between 0 and 1\n})\n\nawait client.lights.setLightTemperature({\n  id: 'YOUR_DEVICE_ID',\n  colorTemperature: 2700, // between colorTemperatureMax and colorTemperatureMin\n})\n\nawait client.lights.setStartupOnOff({\n  id: 'YOUR_DEVICE_ID',\n  startupOnOff: 'startOn', // 'startOn' | 'startPrevious' | 'startToggle'\n})\n```\n\n#### [Light sensors](./src/api/lightSensors.ts)\n\nThe VALLHORN motion sensor has a light sensor built-in.\n\n```typescript\nconst lightSensors = await client.lightSensors.list()\n\nconst lightSensor = await client.lightSensors.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nconst { illuminance } = lightSensor.attributes\n```\n\n#### [Motion sensors](./src/api/motionSensors.ts)\n\n```typescript\nconst motionSensors = await client.motionSensors.list()\n\nconst motionSensor = await client.motionSensors.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.motionSensors.setOnDuration({\n  id: 'YOUR_DEVICE_ID',\n  onDuration: 300, // in seconds, between 60 and 86400\n})\n\nawait client.motionSensors.setScheduleOn({\n  id: 'YOUR_DEVICE_ID',\n  scheduleOn: true,\n})\n\nawait client.motionSensors.setSchedule({\n  id: 'YOUR_DEVICE_ID',\n  schedule: {\n    onCondition: {\n      time: '22:00',\n    },\n    offCondition: {\n      time: '06:00',\n    },\n  },\n})\n\nawait client.motionSensors.setSchedule({\n  id: 'YOUR_DEVICE_ID',\n  schedule: {\n    onCondition: {\n      time: 'sunset',\n      offset: 60, // in minutes\n    },\n    offCondition: {\n      time: 'sunrise',\n      offset: -60, // in minutes\n    },\n  },\n})\n```\n\n#### [Occupancy sensors](./src/api/occupancySensors.ts)\n\nThe MYGGSPRAY sensor introduced a new device type called occupancy sensor. It works the same way as motion sensors:\n\n```typescript\nconst occupancySensors = await client.occupancySensors.list()\n\n// For other available methods, see the motion sensors above.\n```\n\n#### [Outlets](./src/api/outlets.ts)\n\n```typescript\nconst outlets = await client.outlets.list()\n\nconst outlet = await client.outlets.get({ id: 'YOUR_DEVICE_ID' })\n\nawait client.outlets.setIsOn({\n  id: 'YOUR_DEVICE_ID',\n  isOn: true,\n})\n\nawait client.outlets.setStartupOnOff({\n  id: 'YOUR_DEVICE_ID',\n  startupOnOff: 'startOn', // 'startOn' | 'startPrevious' | 'startToggle'\n})\n\nawait client.outlet.setStatusLight({\n  id: 'YOUR_DEVICE_ID',\n  statusLight: true, // true disables the status light, false enables it ¯\\_(ツ)_/¯\n})\n\nawait client.outlet.setChildLock({\n  id: 'YOUR_DEVICE_ID',\n  childLock: true,\n})\n\nawait client.outlet.resetEnergyConsumption({\n  id: 'YOUR_DEVICE_ID',\n})\n```\n\n#### [Open/close sensors](./src/api/openCloseSensors.ts)\n\n```typescript\nconst openCloseSensors = await client.openCloseSensors.list()\n\nconst openCloseSensor = await client.openCloseSensors.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nconst { isOpen, batteryPercentage } = openCloseSensor.attributes\n```\n\n#### [Repeaters](./src/api/repeaters.ts)\n\n```typescript\nconst repeaters = await client.repeaters.list()\n\nconst repeater = await client.repeaters.get({\n  id: 'YOUR_DEVICE_ID',\n})\n```\n\n#### [Speakers](./src/api/speakers.ts)\n\n```typescript\nconst speakers = await client.speakers.list()\n\nconst speaker = await client.speakers.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nawait client.speakers.setVolume({\n  id: 'YOUR_DEVICE_ID',\n  volume: 20, // between 0 and 100\n})\n\nawait client.speakers.setPlayback({\n  id: 'YOUR_DEVICE_ID',\n  playback: 'playbackPaused', // 'playbackPlaying' | 'playbackPaused' | 'playbackNext' | 'playbackPrevious'\n})\n```\n\n#### [Water sensors](./src/api/waterSensors.ts)\n\n```typescript\nconst waterSensors = await client.waterSensors.list()\n\nconst waterSensor = await client.waterSensors.get({\n  id: 'YOUR_DEVICE_ID',\n})\n\nconst { waterLeakDetected, batteryPercentage } = waterSensor.attributes\n```\n\n### [Device sets](./src/api/deviceSets.ts)\n\nFor a list of available icons check out [DeviceSet.ts](./src/types/DeviceSet.ts).\n\n```typescript\nconst deviceSets = await client.deviceSets.list()\n\nawait client.deviceSets.setIsOn({\n  id: 'YOUR_DEVICE_SET_ID',\n  isOn: true,\n})\n\nconst { id } = await client.deviceSets.create({\n  name: 'A_CUSTOM_NAME',\n  icon: 'lighting_chandelier',\n})\n\nawait client.deviceSets.delete({\n  id: 'YOUR_DEVICE_SET_ID',\n})\n\nawait client.deviceSets.update({\n  id: 'YOUR_DEVICE_SET_ID',\n  name: 'A_NEW_CUSTOM_NAME',\n  icon: 'lighting_cone_pendant',\n})\n\nawait client.deviceSets.updateConfiguration({\n  id: 'YOUR_DEVICE_SET_ID',\n  deviceIds: ['YOUR_DEVICE_ID'],\n  roomId: 'YOUR_ROOM_ID', // optional\n  remoteLinkIds: ['YOUR_REMOTE_ID'], // optional\n})\n\n// some attributes may not be combined with each other and require separate setAttributes calls\nawait client.deviceSets.setAttributes({\n  id: 'YOUR_DEVICE_SET_ID',\n  attributes: {\n    // ...\n  },\n  transitionTime: 5000, // optional, in milliseconds\n})\n```\n\n### [Rooms](./src/api/rooms.ts)\n\nFor a list of available colors and icons check out [Room.ts](./src/types/Room.ts).\n\n```typescript\nconst rooms = await client.rooms.list()\n\nconst room = await client.rooms.get({\n  id: 'YOUR_ROOM_ID',\n})\n\nconst { id } = await client.rooms.create({\n  name: 'A_CUSTOM_NAME',\n  icon: 'rooms_arm_chair',\n  color: 'ikea_green_no_65',\n})\n\nawait client.rooms.delete({\n  id: 'YOUR_ROOM_ID',\n})\n\nawait client.rooms.update({\n  id: 'YOUR_ROOM_ID',\n  name: 'A_NEW_CUSTOM_NAME',\n  icon: 'rooms_bathtub',\n  color: 'ikea_yellow_no_24',\n})\n\nawait client.rooms.moveDevices({\n  id: 'YOUR_ROOM_ID',\n  deviceIds: ['YOUR_DEVICE_ID'],\n})\n\nawait client.rooms.setIsOn({\n  id: 'YOUR_ROOM_ID',\n  deviceType: 'outlet', // optional filter by device type\n  isOn: true,\n})\n\n// some attributes may not be combined with each other and require separate setAttributes calls\nawait client.rooms.setAttributes({\n  id: 'YOUR_ROOM_ID',\n  deviceType: 'light', // optional filter by device type\n  attributes: {\n    // ...\n  },\n  transitionTime: 5000, // optional\n})\n```\n\n### [Scenes](./src/api/scenes.ts)\n\nScenes are a very powerful way to set up automations. Scenes can be triggered by using the application, at a scheduled\ntime, at sunset/sunrise, by a button press on a shortcut controller or by a device event, such as an open/close sensor\nbeing triggered. Scenes can optionally also be ended at a scheduled time, a duration after they are triggered or at\nsunrise/sunset. The actions can set the attributes of devices or device sets, such as turning on a light.\n\nFor a list of available icons check out [Scene.ts](./src/types/Scene.ts).\n\n```typescript\nconst scenes = await client.scenes.list()\n\nconst scene = await client.scenes.get({\n  id: 'YOUR_SCENE_ID',\n})\n\nawait client.scenes.trigger({\n  id: 'YOUR_SCENE_ID',\n})\n\nawait client.scenes.undo({\n  id: 'YOUR_SCENE_ID',\n})\n\n// simple scene, triggerable from app\nconst { id } = await client.scenes.create({\n  info: {\n    name: 'A_CUSTOM_NAME',\n    icon: 'scenes_arrive_home',\n  },\n  type: 'userScene',\n  actions: [\n    {\n      type: 'device',\n      enabled: true,\n      deviceId: 'YOUR_DEVICE_ID',\n      attributes: {\n        // ...\n      },\n    },\n  ],\n})\n\n// triggered and ended by time schedule\nconst { id: timeTriggerSceneId } = await client.scenes.create({\n  info: {\n    name: 'A_CUSTOM_NAME',\n    icon: 'scenes_arrive_home',\n  },\n  type: 'userScene',\n  triggers: [\n    {\n      type: 'time',\n      trigger: {\n        days: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], // optional, defaults to every day\n        time: '8:00',\n      },\n      // optional\n      endTriggerEvent: {\n        type: 'time',\n        trigger: {\n          time: '20:00',\n        },\n      },\n    },\n  ],\n  actions: [\n    {\n      type: 'device',\n      enabled: true,\n      deviceId: 'YOUR_DEVICE_ID',\n      attributes: {\n        // ...\n      },\n    },\n  ],\n})\n\nawait client.scenese.delete({\n  id: 'YOUR_SCENE_ID',\n})\n\nawait client.scenes.update({\n  id: 'YOUR_SCENE_ID',\n  // ... all the fields from the create method\n})\n```\n\n### [Music](./src/api/music.ts)\n\n```typescript\nconst music = await client.music.get()\n```\n\n### [Users](./src/api/users.ts)\n\n```typescript\nconst users = await client.users.list()\n\nconst currentUser = await client.users.getCurrentUser()\n\nawait client.users.setCurrentUserName({\n  name: 'NEW_NAME',\n})\n\nawait client.users.delete({\n  id: 'YOUR_USER_ID',\n})\n```\n\n### Update events\n\nThe gateway publishes events via a WebSocket. You can listen for these events with the following method:\n\n```typescript\nclient.startListeningForUpdates(async (updateEvent) =\u003e {\n  console.log(JSON.stringify(updateEvent))\n})\n```\n\nFor a list of available event types, check out [Event.ts](./src/types/event/Event.ts).\n\n## Troubleshooting\n\n\u003cdetails\u003e\n  \u003csummary\u003eError: self-signed certificate in certificate chain\u003c/summary\u003e\n\nThe DIRIGERA hub uses a self-signed certificate for HTTPS. By default this library verifies the certificate, which may\ncause issues if it changes on the hub for any reason. If you encounter this error you can disable the certificate\nverification by:\n\n- Adding the `--no-reject-unauthorized` flag when running the CLI commands.\n- Adding the `rejectUnauthorized: false` option when creating the client instance using `createDirigeraClient`.\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpgera%2Fdirigera","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flpgera%2Fdirigera","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpgera%2Fdirigera/lists"}