From liongard
Handles Liongard systems data from inspections: details, dataprints for JMESPath evaluation, asset inventory, identity/device profiles. Includes fields and API patterns.
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin liongardThis skill uses the workspace's default tool permissions.
Systems are the entities discovered during Liongard inspections. When a launchpoint runs an inspection, it discovers systems such as servers, firewalls, cloud services, user accounts, domain controllers, and other infrastructure components. Each system contains detailed configuration data captured at the time of inspection, providing a historical record of the IT environment.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Analyzes BMad project state from catalog CSV, configs, artifacts, and query to recommend next skills or answer questions. Useful for help requests, 'what next', or starting BMad.
Systems are the entities discovered during Liongard inspections. When a launchpoint runs an inspection, it discovers systems such as servers, firewalls, cloud services, user accounts, domain controllers, and other infrastructure components. Each system contains detailed configuration data captured at the time of inspection, providing a historical record of the IT environment.
| Field | Type | Description |
|---|---|---|
ID | int | Unique system identifier |
Name | string | System display name |
InspectorID | int | Inspector that discovered this system |
InspectorName | string | Inspector display name |
LaunchpointID | int | Launchpoint that produced this system |
LaunchpointName | string | Launchpoint display name |
EnvironmentID | int | Parent environment |
EnvironmentName | string | Environment display name |
Status | string | Active, Inactive, Error |
LastInspection | datetime | Last successful inspection timestamp |
SystemType | string | Type classification (Server, Firewall, etc.) |
CreatedOn | datetime | First discovery timestamp |
UpdatedOn | datetime | Last update timestamp |
| Field | Type | Description |
|---|---|---|
DetailCount | int | Number of detail records available |
DetectionCount | int | Number of detections for this system |
Tags | array | User-assigned tags |
GET /api/v1/systems?page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
Response:
{
"Data": [
{
"ID": 10001,
"Name": "DC01.acme.local",
"InspectorID": 100,
"InspectorName": "Active Directory",
"LaunchpointID": 5001,
"LaunchpointName": "Acme Corp - Active Directory",
"EnvironmentID": 1234,
"EnvironmentName": "Acme Corporation",
"Status": "Active",
"LastInspection": "2024-02-15T02:15:00Z",
"SystemType": "Domain Controller",
"CreatedOn": "2023-06-01T10:30:00Z",
"UpdatedOn": "2024-02-15T02:15:00Z"
}
],
"TotalRows": 2500,
"HasMoreRows": true,
"CurrentPage": 1,
"TotalPages": 25,
"PageSize": 100
}
GET /api/v1/systems?environmentId={environmentId}&page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
GET /api/v1/systems?inspectorId={inspectorId}&page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
GET /api/v1/systems?launchpointId={launchpointId}&page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
GET /api/v1/systems/{systemId}
X-ROAR-API-KEY: {api_key}
Response:
{
"ID": 10001,
"Name": "DC01.acme.local",
"InspectorID": 100,
"InspectorName": "Active Directory",
"LaunchpointID": 5001,
"LaunchpointName": "Acme Corp - Active Directory",
"EnvironmentID": 1234,
"EnvironmentName": "Acme Corporation",
"Status": "Active",
"LastInspection": "2024-02-15T02:15:00Z",
"SystemType": "Domain Controller",
"DetailCount": 45,
"DetectionCount": 2,
"CreatedOn": "2023-06-01T10:30:00Z",
"UpdatedOn": "2024-02-15T02:15:00Z"
}
System details contain the raw configuration data captured during inspections. This is the actual IT documentation data -- user lists, firewall rules, backup statuses, license counts, security settings, and more. Details are stored as structured JSON and can be queried using JMESPath expressions via the dataprints API.
GET /api/v1/systems/{systemId}/detail
X-ROAR-API-KEY: {api_key}
Response (example for Active Directory system):
{
"SystemID": 10001,
"InspectionDate": "2024-02-15T02:15:00Z",
"Data": {
"DomainName": "acme.local",
"FunctionalLevel": "Windows2016Domain",
"DomainControllers": [
{
"Name": "DC01",
"IPAddress": "10.0.1.10",
"OperatingSystem": "Windows Server 2022",
"FSMORoles": ["PDCEmulator", "RIDMaster"]
},
{
"Name": "DC02",
"IPAddress": "10.0.1.11",
"OperatingSystem": "Windows Server 2022",
"FSMORoles": ["InfrastructureMaster"]
}
],
"Users": {
"TotalCount": 150,
"EnabledCount": 142,
"DisabledCount": 8,
"LockedOutCount": 0
},
"Groups": {
"TotalCount": 85,
"SecurityGroups": 60,
"DistributionGroups": 25
},
"GroupPolicyObjects": {
"TotalCount": 12,
"LinkedCount": 10,
"UnlinkedCount": 2
},
"PasswordPolicy": {
"MinimumLength": 12,
"ComplexityEnabled": true,
"MaxAge": 90,
"MinAge": 1,
"HistoryCount": 24,
"LockoutThreshold": 5,
"LockoutDuration": 30
}
}
}
System details maintain historical snapshots for comparison:
GET /api/v1/systems/{systemId}/detail?date=2024-01-15
X-ROAR-API-KEY: {api_key}
Dataprints provide a way to extract specific data from system details using JMESPath expressions. Instead of fetching the entire system detail and parsing it client-side, you can use dataprints to query exactly the data you need.
POST /api/v2/dataprints-evaluate-systemdetailid
X-ROAR-API-KEY: {api_key}
Content-Type: application/json
{
"SystemDetailID": 10001,
"Expression": "Data.Users.TotalCount"
}
Response:
{
"Result": 150
}
Get all domain controller names:
{
"SystemDetailID": 10001,
"Expression": "Data.DomainControllers[*].Name"
}
Response:
{
"Result": ["DC01", "DC02"]
}
Get users with specific criteria:
{
"SystemDetailID": 10001,
"Expression": "Data.DomainControllers[?OperatingSystem=='Windows Server 2022'].Name"
}
Extract nested configuration:
{
"SystemDetailID": 10001,
"Expression": "Data.PasswordPolicy.{MinLength: MinimumLength, Complexity: ComplexityEnabled, MaxAge: MaxAge}"
}
Response:
{
"Result": {
"MinLength": 12,
"Complexity": true,
"MaxAge": 90
}
}
| Expression | Description |
|---|---|
Data.Field | Direct field access |
Data.Array[0] | First array element |
Data.Array[*].Name | All Name values from array |
Data.Array[?Status=='Active'] | Filter array elements |
Data.{a: Field1, b: Field2} | Multi-select hash |
| `Data.Array | length(@)` |
| `Data.Array[*].Name | sort(@)` |
Data.Array[?Age > \30`]` | Numeric comparison |
Asset Inventory aggregates user identities discovered across all inspections:
GET /api/v2/inventory/identities?page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
Response:
{
"Data": [
{
"ID": "identity-uuid-1234",
"DisplayName": "John Smith",
"Email": "john.smith@acme.com",
"EnvironmentID": 1234,
"Sources": [
{
"Inspector": "Active Directory",
"SystemID": 10001,
"Username": "jsmith",
"Status": "Enabled"
},
{
"Inspector": "Microsoft 365",
"SystemID": 10050,
"Username": "john.smith@acme.com",
"LicenseAssigned": true
}
],
"LastSeen": "2024-02-15T02:15:00Z"
}
],
"TotalRows": 500,
"HasMoreRows": true,
"CurrentPage": 1,
"TotalPages": 5,
"PageSize": 100
}
GET /api/v2/inventory/identities/{identityId}
X-ROAR-API-KEY: {api_key}
Asset Inventory also aggregates device information:
GET /api/v2/inventory/devices?page=1&pageSize=100
X-ROAR-API-KEY: {api_key}
Response:
{
"Data": [
{
"ID": "device-uuid-5678",
"Hostname": "SERVER-DC01",
"EnvironmentID": 1234,
"IPAddresses": ["10.0.1.10"],
"OperatingSystem": "Windows Server 2022",
"Sources": [
{
"Inspector": "Active Directory",
"SystemID": 10001,
"Role": "Domain Controller"
},
{
"Inspector": "VMware vSphere",
"SystemID": 10100,
"VMName": "DC01-VM"
}
],
"LastSeen": "2024-02-15T02:15:00Z"
}
],
"TotalRows": 800,
"HasMoreRows": true,
"CurrentPage": 1,
"TotalPages": 8,
"PageSize": 100
}
GET /api/v2/inventory/devices/{deviceId}
X-ROAR-API-KEY: {api_key}
async function getEnvironmentSystems(environmentId) {
const systems = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await fetch(
`https://${instance}.app.liongard.com/api/v1/systems?environmentId=${environmentId}&page=${page}&pageSize=500`,
{
headers: { 'X-ROAR-API-KEY': process.env.LIONGARD_API_KEY }
}
);
const data = await response.json();
systems.push(...data.Data);
hasMore = data.HasMoreRows;
page++;
}
return systems;
}
async function getPasswordPolicy(systemDetailId) {
const response = await fetch(
`https://${instance}.app.liongard.com/api/v2/dataprints-evaluate-systemdetailid`,
{
method: 'POST',
headers: {
'X-ROAR-API-KEY': process.env.LIONGARD_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
SystemDetailID: systemDetailId,
Expression: 'Data.PasswordPolicy'
})
}
);
return response.json();
}
| Code | Message | Resolution |
|---|---|---|
| 400 | Invalid system ID | Verify system exists |
| 401 | Unauthorized | Check API key |
| 404 | System not found | Confirm system ID |
| 404 | System detail not found | System may not have been inspected yet |
| 422 | Invalid JMESPath expression | Check expression syntax |
| 429 | Rate limited | Wait and retry (300 req/min) |
| Error | Cause | Fix |
|---|---|---|
| Invalid expression | Syntax error in JMESPath | Validate expression syntax |
| Null result | Path doesn't exist in data | Check available data fields |
| Type mismatch | Comparing incompatible types | Verify field types |
System (SystemID)
|
+-- Inspector (InspectorID)
+-- Launchpoint (LaunchpointID)
+-- Environment (EnvironmentID)
|
+-- System Details
| +-- Raw Configuration Data (JSON)
| +-- Historical Snapshots
| +-- Dataprints (JMESPath queries)
|
+-- Detections (DetectionID)
|
+-- Asset Inventory
+-- Identity Profiles
+-- Device Profiles