infracensus-collector 1.6.49 → 1.6.50

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 (93) hide show
  1. package/dist/a10-index.js +3 -3
  2. package/dist/{archive-JL3PBIFB.js → archive-VPL7477A.js} +3 -3
  3. package/dist/azure-index.js +8 -9
  4. package/dist/azure-index.js.map +1 -1
  5. package/dist/{chunk-QW4IV7RU.js → chunk-25IVLIWJ.js} +3 -3
  6. package/dist/{chunk-GWLM5SN4.js → chunk-2AK6XGNY.js} +4 -4
  7. package/dist/{chunk-33SGYN2R.js → chunk-36R3CWBW.js} +2 -2
  8. package/dist/{chunk-4AXMNCP5.js → chunk-4GWOGLPA.js} +224 -15
  9. package/dist/chunk-4GWOGLPA.js.map +7 -0
  10. package/dist/{chunk-5GC7E57R.js → chunk-BBCSA255.js} +4 -4
  11. package/dist/{chunk-AFNP65WK.js → chunk-F5W5LVQW.js} +13 -9
  12. package/dist/{chunk-AFNP65WK.js.map → chunk-F5W5LVQW.js.map} +2 -2
  13. package/dist/{chunk-E7ULEHSY.js → chunk-GXEWMGUU.js} +2 -2
  14. package/dist/{chunk-55BONS2H.js → chunk-HASNVXFK.js} +2 -2
  15. package/dist/{chunk-BX22TJP5.js → chunk-JJ7QXBD7.js} +2 -2
  16. package/dist/{chunk-6353EHLX.js → chunk-KUEOHURR.js} +6 -6
  17. package/dist/{chunk-6353EHLX.js.map → chunk-KUEOHURR.js.map} +2 -2
  18. package/dist/{chunk-S5YO2QWY.js → chunk-O5IX5BHJ.js} +4 -4
  19. package/dist/{chunk-TKAFSRRY.js → chunk-OQ6SPCYH.js} +51 -10
  20. package/dist/chunk-OQ6SPCYH.js.map +7 -0
  21. package/dist/{chunk-ADBI6AB3.js → chunk-R4SBDJJB.js} +6 -6
  22. package/dist/{chunk-3P4ICNUD.js → chunk-RBNDXA6S.js} +5 -5
  23. package/dist/{chunk-P3D7GCYX.js → chunk-RZDCYDRQ.js} +2 -2
  24. package/dist/{chunk-CIDEYM3V.js → chunk-TEDB4WMZ.js} +4 -4
  25. package/dist/{chunk-QOATERR5.js → chunk-UDVC6AFA.js} +2 -2
  26. package/dist/{chunk-NBHGLDIO.js → chunk-UOSACCJV.js} +8 -8
  27. package/dist/{chunk-CW3YCPEC.js → chunk-URNQQQIZ.js} +6 -2
  28. package/dist/{chunk-CW3YCPEC.js.map → chunk-URNQQQIZ.js.map} +2 -2
  29. package/dist/chunk-X5LDSD2G.js +1028 -0
  30. package/dist/chunk-X5LDSD2G.js.map +7 -0
  31. package/dist/{chunk-HFPJ4GJA.js → chunk-XAUFTICX.js} +2 -2
  32. package/dist/{chunk-SPXKN5I4.js → chunk-XUMICCGL.js} +186 -9
  33. package/dist/chunk-XUMICCGL.js.map +7 -0
  34. package/dist/cli.js +15 -12
  35. package/dist/cli.js.map +2 -2
  36. package/dist/{config-2SBXQ3HY.js → config-SF35AYXV.js} +11 -6
  37. package/dist/configimport-index.js +6 -7
  38. package/dist/configimport-index.js.map +1 -1
  39. package/dist/hyperv-index.js +8 -9
  40. package/dist/hyperv-index.js.map +1 -1
  41. package/dist/identity-index.js +8 -9
  42. package/dist/identity-index.js.map +1 -1
  43. package/dist/index.js +1607 -976
  44. package/dist/index.js.map +4 -4
  45. package/dist/{linux-7OIQNB4O.js → linux-3CBJ43HB.js} +10 -2
  46. package/dist/linux-3CBJ43HB.js.map +7 -0
  47. package/dist/{ocr-JELKMWFR.js → ocr-PU2J2GXY.js} +5 -5
  48. package/dist/pkgRoot-RBTKA7VA.js +9 -0
  49. package/dist/sdd-classify-worker-index.js +4 -4
  50. package/dist/sensitive-data-index.js +15 -15
  51. package/dist/{service-AFZPX4K7.js → service-O7ST4SZJ.js} +2 -2
  52. package/dist/smb-shares-index.js +15 -15
  53. package/dist/sql-index.js +8 -9
  54. package/dist/sql-index.js.map +1 -1
  55. package/dist/{status-Z76ZRIT6.js → status-WFVQHWN3.js} +14 -10
  56. package/dist/{tools-BTYQGJEB.js → tools-6QU4LGNM.js} +2 -2
  57. package/dist/vmware-index.js +8 -9
  58. package/dist/vmware-index.js.map +1 -1
  59. package/dist/voice-index.js +8 -9
  60. package/dist/voice-index.js.map +1 -1
  61. package/dist/{windows-2P76ECNN.js → windows-ZNTFTTMK.js} +6 -3
  62. package/dist/windows-ZNTFTTMK.js.map +7 -0
  63. package/package.json +1 -1
  64. package/dist/chunk-4AXMNCP5.js.map +0 -7
  65. package/dist/chunk-ONLYEEKO.js +0 -278
  66. package/dist/chunk-ONLYEEKO.js.map +0 -7
  67. package/dist/chunk-SPXKN5I4.js.map +0 -7
  68. package/dist/chunk-TKAFSRRY.js.map +0 -7
  69. package/dist/linux-7OIQNB4O.js.map +0 -7
  70. package/dist/pkgRoot-TT3C3BUM.js +0 -7
  71. package/dist/windows-2P76ECNN.js.map +0 -7
  72. /package/dist/{archive-JL3PBIFB.js.map → archive-VPL7477A.js.map} +0 -0
  73. /package/dist/{chunk-QW4IV7RU.js.map → chunk-25IVLIWJ.js.map} +0 -0
  74. /package/dist/{chunk-GWLM5SN4.js.map → chunk-2AK6XGNY.js.map} +0 -0
  75. /package/dist/{chunk-33SGYN2R.js.map → chunk-36R3CWBW.js.map} +0 -0
  76. /package/dist/{chunk-5GC7E57R.js.map → chunk-BBCSA255.js.map} +0 -0
  77. /package/dist/{chunk-E7ULEHSY.js.map → chunk-GXEWMGUU.js.map} +0 -0
  78. /package/dist/{chunk-55BONS2H.js.map → chunk-HASNVXFK.js.map} +0 -0
  79. /package/dist/{chunk-BX22TJP5.js.map → chunk-JJ7QXBD7.js.map} +0 -0
  80. /package/dist/{chunk-S5YO2QWY.js.map → chunk-O5IX5BHJ.js.map} +0 -0
  81. /package/dist/{chunk-ADBI6AB3.js.map → chunk-R4SBDJJB.js.map} +0 -0
  82. /package/dist/{chunk-3P4ICNUD.js.map → chunk-RBNDXA6S.js.map} +0 -0
  83. /package/dist/{chunk-P3D7GCYX.js.map → chunk-RZDCYDRQ.js.map} +0 -0
  84. /package/dist/{chunk-CIDEYM3V.js.map → chunk-TEDB4WMZ.js.map} +0 -0
  85. /package/dist/{chunk-QOATERR5.js.map → chunk-UDVC6AFA.js.map} +0 -0
  86. /package/dist/{chunk-NBHGLDIO.js.map → chunk-UOSACCJV.js.map} +0 -0
  87. /package/dist/{chunk-HFPJ4GJA.js.map → chunk-XAUFTICX.js.map} +0 -0
  88. /package/dist/{config-2SBXQ3HY.js.map → config-SF35AYXV.js.map} +0 -0
  89. /package/dist/{ocr-JELKMWFR.js.map → ocr-PU2J2GXY.js.map} +0 -0
  90. /package/dist/{pkgRoot-TT3C3BUM.js.map → pkgRoot-RBTKA7VA.js.map} +0 -0
  91. /package/dist/{service-AFZPX4K7.js.map → service-O7ST4SZJ.js.map} +0 -0
  92. /package/dist/{status-Z76ZRIT6.js.map → status-WFVQHWN3.js.map} +0 -0
  93. /package/dist/{tools-BTYQGJEB.js.map → tools-6QU4LGNM.js.map} +0 -0
package/dist/a10-index.js CHANGED
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-EFV5GUNE.js";
5
5
  import {
6
6
  requireEntitlementToScan
7
- } from "./chunk-6353EHLX.js";
7
+ } from "./chunk-KUEOHURR.js";
8
+ import "./chunk-OQ6SPCYH.js";
8
9
  import {
9
10
  ROUTES
10
- } from "./chunk-4AXMNCP5.js";
11
- import "./chunk-CW3YCPEC.js";
11
+ } from "./chunk-4GWOGLPA.js";
12
12
 
13
13
  // src/a10-index.ts
14
14
  var LEVEL_RANK = { debug: 10, info: 20, warn: 30, error: 40 };
@@ -2,12 +2,12 @@ import {
2
2
  extensionKind,
3
3
  extractOpenXml,
4
4
  extractPlainText
5
- } from "./chunk-5GC7E57R.js";
5
+ } from "./chunk-BBCSA255.js";
6
6
  import {
7
7
  checkEntryPath,
8
8
  checkEntrySize
9
9
  } from "./chunk-Q6I7N4PU.js";
10
- import "./chunk-4AXMNCP5.js";
10
+ import "./chunk-4GWOGLPA.js";
11
11
 
12
12
  // src/sensitiveData/archive.ts
13
13
  import { unzipSync } from "fflate";
@@ -68,4 +68,4 @@ function extractArchive(bytes) {
68
68
  export {
69
69
  extractArchive
70
70
  };
71
- //# sourceMappingURL=archive-JL3PBIFB.js.map
71
+ //# sourceMappingURL=archive-VPL7477A.js.map
@@ -2,20 +2,19 @@ import {
2
2
  ArmClient,
3
3
  buildAzureInventory,
4
4
  listAccessibleSubscriptions
5
- } from "./chunk-P3D7GCYX.js";
5
+ } from "./chunk-RZDCYDRQ.js";
6
6
  import "./chunk-JGHHEJI5.js";
7
7
  import {
8
8
  pushAzureInventory
9
- } from "./chunk-GWLM5SN4.js";
10
- import "./chunk-E7ULEHSY.js";
11
- import {
12
- loadAzureConfig
13
- } from "./chunk-TKAFSRRY.js";
9
+ } from "./chunk-2AK6XGNY.js";
10
+ import "./chunk-GXEWMGUU.js";
14
11
  import {
15
12
  requireEntitlementToScan
16
- } from "./chunk-6353EHLX.js";
17
- import "./chunk-4AXMNCP5.js";
18
- import "./chunk-CW3YCPEC.js";
13
+ } from "./chunk-KUEOHURR.js";
14
+ import {
15
+ loadAzureConfig
16
+ } from "./chunk-OQ6SPCYH.js";
17
+ import "./chunk-4GWOGLPA.js";
19
18
 
20
19
  // src/azure-index.ts
21
20
  var LEVEL_RANK = { debug: 10, info: 20, warn: 30, error: 40 };
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/azure-index.ts"],
4
4
  "sourcesContent": ["/**\r\n * Azure Cloud Posture (CSPM) collector CLI entry point.\r\n *\r\n * pnpm azure-scan inventory every subscription the configured ARM\r\n * service principal can see (or the AZURE_SUBSCRIPTIONS\r\n * allow-list, if set) and push each to /ingest/azure\r\n * pnpm azure-scan:dry inventory and print a summary WITHOUT pushing\r\n * tsx src/azure-index.ts --dry-run (equivalent to azure-scan:dry)\r\n *\r\n * ONE service principal (ARM app registration, OAuth2 client-credentials) that\r\n * may see MANY subscriptions \u2014 unlike identity-index.ts's \"one Graph app\r\n * registration = one cloud org\", this loops {@link listAccessibleSubscriptions}\r\n * and builds + pushes ONE AzureInventory PER subscription, each versioned\r\n * independently on the control plane by subscriptionId. A gather that 403s on a\r\n * missing role/unregistered resource provider degrades that ONE signal\r\n * gracefully within a single subscription's build (see azure/plugin.ts); only a\r\n * failure to acquire a token or list subscriptions at all fails the whole run.\r\n *\r\n * Ctrl-C (SIGINT) triggers a cooperative AbortSignal so in-flight requests stop.\r\n */\r\nimport { loadAzureConfig } from \"./config.js\";\r\nimport { pushAzureInventory } from \"./core/push.js\";\r\nimport { ArmClient } from \"./azure/arm.js\";\r\nimport { buildAzureInventory, listAccessibleSubscriptions, type AzureStamp } from \"./azure/plugin.js\";\r\nimport type { Logger } from \"./core/runner.js\";\r\nimport type { AzureInventory } from \"@netdoc/collector-contract\";\r\nimport { requireEntitlementToScan } from \"./entitlement/index.js\";\r\n\r\nconst LEVEL_RANK = { debug: 10, info: 20, warn: 30, error: 40 } as const;\r\n\r\nfunction makeLogger(minLevel: keyof typeof LEVEL_RANK = \"info\"): Logger {\r\n const min = LEVEL_RANK[minLevel];\r\n return (level, msg, meta) => {\r\n if (LEVEL_RANK[level] < min) return;\r\n const line = `${new Date().toISOString()} ${level.toUpperCase().padEnd(5)} ${msg}`;\r\n const out = level === \"error\" ? console.error : level === \"warn\" ? console.warn : console.log;\r\n if (meta !== undefined) out(line, meta);\r\n else out(line);\r\n };\r\n}\r\n\r\nfunction errMsg(err: unknown): string {\r\n return err instanceof Error ? err.message : String(err);\r\n}\r\n\r\nfunction printSummary(inv: AzureInventory, log: Logger): void {\r\n log(\"info\", \"=== DRY RUN \u2014 AzureInventory NOT pushed ===\");\r\n log(\"info\", `subscription : ${inv.subscription.name} (${inv.subscriptionId})`);\r\n log(\"info\", `tenant : ${inv.tenantId}`);\r\n log(\"info\", `directory tenant : ${inv.tenantDirId}`);\r\n log(\"info\", `capturedAt : ${inv.capturedAt}`);\r\n log(\"info\", `state : ${inv.subscription.state}`);\r\n log(\r\n \"info\",\r\n `management group : ${inv.subscription.managementGroupName ?? inv.subscription.managementGroupId ?? \"not observed\"}`,\r\n );\r\n log(\"info\", `resources : ${inv.resources.length}`);\r\n // `hasRiskyInbound` is true when SOME inbound Allow rule names an any-source\r\n // prefix; it says nothing about which port that rule opens, so an NSG fronting\r\n // a public web server (443 from the internet, exactly as intended) sets it.\r\n // Reporting that count as \"risky\" told the operator about an exposure this\r\n // payload cannot substantiate \u2014 the per-port verdict belongs to the control\r\n // plane's audit engine, which reads the rules shipped alongside the flag.\r\n const internetFacingNsgs = inv.network.filter((n) => n.kind === \"nsg\" && n.hasRiskyInbound).length;\r\n log(\"info\", `network entities : ${inv.network.length} (${internetFacingNsgs} NSG(s) with any-source inbound)`);\r\n log(\"info\", `rbac assignments : ${inv.rbac.length} (${inv.rbac.filter((r) => r.isPrivileged).length} privileged)`);\r\n if (inv.defender) {\r\n log(\r\n \"info\",\r\n `defender : secureScore=${inv.defender.secureScore ?? \"?\"} ` +\r\n `${Object.keys(inv.defender.planCoverage).length} plan(s), ${inv.defender.recommendations.length} recommendation(s)`,\r\n );\r\n } else {\r\n log(\"info\", \"defender : not observed (missing Microsoft.Security role/RP registration?)\");\r\n }\r\n const nonCompliant = inv.policy.filter((p) => p.complianceState === \"NonCompliant\").length;\r\n log(\"info\", `policy : ${inv.policy.length} assignment(s) (${nonCompliant} non-compliant)`);\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const argv = process.argv.slice(2);\r\n const dryRun = argv.includes(\"--dry-run\");\r\n const debug = argv.includes(\"--debug\") || process.env.LOG_LEVEL === \"debug\";\r\n const log = makeLogger(debug ? \"debug\" : \"info\");\r\n\r\n const config = loadAzureConfig();\r\n\r\n // \u2500\u2500 PAID-LICENCE GATE \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\u2500\u2500\u2500\u2500\u2500\u2500\r\n //\r\n // BEFORE the client is built and before a credential leaves this process.\r\n // `core/planRefusal.ts` named this exact path as the one its own refusal\r\n // handling could not save: \"a refusal is learned at PUSH \u2014 which for a\r\n // one-shot `netdoc-collector scan azure` is after the collector has already\r\n // logged into the customer's Azure subscriptions and read their whole inventory\". Asking\r\n // first is what closes it.\r\n //\r\n // `--dry-run` IS GATED TOO, deliberately. A dry run still authenticates to\r\n // the customer's appliance and reads their estate; it merely declines to\r\n // upload it. The connection is the thing an unentitled tenant must not make.\r\n await requireEntitlementToScan(config, log, \"the one-shot Azure Cloud Posture scan\");\r\n\r\n\r\n const controller = new AbortController();\r\n const onSigint = (): void => {\r\n log(\"warn\", \"SIGINT received \u2014 shutting down\u2026\");\r\n controller.abort();\r\n };\r\n process.on(\"SIGINT\", onSigint);\r\n\r\n log(\"info\", `Azure Cloud Posture (CSPM) collector starting (dryRun=${dryRun}) \u2014 ARM tenant ${config.azureTenantId}`);\r\n\r\n try {\r\n const client = new ArmClient(\r\n {\r\n tenantId: config.azureTenantId,\r\n clientId: config.azureClientId,\r\n clientSecret: config.azureClientSecret,\r\n signal: controller.signal,\r\n },\r\n log,\r\n );\r\n\r\n const subs = await listAccessibleSubscriptions(client, config.azureSubscriptions);\r\n log(\r\n \"info\",\r\n `found ${subs.length} accessible subscription(s): ${subs.map((s) => `${s.displayName} (${s.subscriptionId})`).join(\", \")}`,\r\n );\r\n\r\n for (const sub of subs) {\r\n const stamp: AzureStamp = {\r\n collectorId: config.collectorId,\r\n tenantId: config.tenantId,\r\n siteId: config.siteId,\r\n tenantDirId: config.azureTenantId,\r\n };\r\n const inventory = await buildAzureInventory(client, sub, stamp, log);\r\n\r\n if (dryRun) {\r\n printSummary(inventory, log);\r\n continue;\r\n }\r\n\r\n log(\"info\", `pushing Azure inventory for subscription ${sub.subscriptionId} to ${config.controlPlaneUrl}`);\r\n const result = await pushAzureInventory(\r\n inventory,\r\n { controlPlaneUrl: config.controlPlaneUrl, apiKey: config.apiKey },\r\n log,\r\n controller.signal,\r\n );\r\n log(\"info\", `=== PUSH OK (subscription ${sub.subscriptionId}) ===`);\r\n if (result.snapshotId) log(\"info\", `snapshotId : ${result.snapshotId}`);\r\n if (result.version !== undefined) log(\"info\", `version : ${result.version}`);\r\n }\r\n } finally {\r\n process.off(\"SIGINT\", onSigint);\r\n }\r\n}\r\n\r\nmain().catch((err) => {\r\n console.error(`${new Date().toISOString()} ERROR ${errMsg(err)}`);\r\n process.exitCode = 1;\r\n});\r\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,13 +5,13 @@ function isServiceVerb(word) {
5
5
  }
6
6
  async function runService(verb) {
7
7
  if (process.platform === "win32") {
8
- const win = await import("./windows-2P76ECNN.js");
8
+ const win = await import("./windows-ZNTFTTMK.js");
9
9
  if (verb === "install") return win.windowsInstall();
10
10
  if (verb === "uninstall") return win.windowsUninstall();
11
11
  return win.windowsStatus();
12
12
  }
13
13
  if (process.platform === "linux") {
14
- const linux = await import("./linux-7OIQNB4O.js");
14
+ const linux = await import("./linux-3CBJ43HB.js");
15
15
  if (verb === "install") return linux.linuxInstall();
16
16
  if (verb === "uninstall") return linux.linuxUninstall();
17
17
  return linux.linuxStatus();
@@ -25,4 +25,4 @@ export {
25
25
  isServiceVerb,
26
26
  runService
27
27
  };
28
- //# sourceMappingURL=chunk-QW4IV7RU.js.map
28
+ //# sourceMappingURL=chunk-25IVLIWJ.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isPlanRefusal,
3
3
  planRefusalFrom
4
- } from "./chunk-E7ULEHSY.js";
4
+ } from "./chunk-GXEWMGUU.js";
5
5
  import {
6
6
  COLLECTOR_AUTH_HEADER,
7
7
  IngestResult,
@@ -10,7 +10,7 @@ import {
10
10
  SnapshotUploadCloseResult,
11
11
  SnapshotUploadOpenResult,
12
12
  collectorBearer
13
- } from "./chunk-6353EHLX.js";
13
+ } from "./chunk-KUEOHURR.js";
14
14
  import {
15
15
  ApiError,
16
16
  CertReportResult,
@@ -19,7 +19,7 @@ import {
19
19
  SddRunBatchResult,
20
20
  SddRunCloseResult,
21
21
  SddRunOpenResult
22
- } from "./chunk-4AXMNCP5.js";
22
+ } from "./chunk-4GWOGLPA.js";
23
23
 
24
24
  // src/core/snapshotChunks.ts
25
25
  var CHUNK_THRESHOLD_BYTES = 1048576;
@@ -552,4 +552,4 @@ export {
552
552
  pushSddBatch,
553
553
  pushSddRunClose
554
554
  };
555
- //# sourceMappingURL=chunk-GWLM5SN4.js.map
555
+ //# sourceMappingURL=chunk-2AK6XGNY.js.map
@@ -16,7 +16,7 @@ import {
16
16
  IdentityIngestBody,
17
17
  M365Licensing,
18
18
  M365Workload
19
- } from "./chunk-4AXMNCP5.js";
19
+ } from "./chunk-4GWOGLPA.js";
20
20
 
21
21
  // src/identity/graph.ts
22
22
  var noopLog = () => {
@@ -1136,4 +1136,4 @@ export {
1136
1136
  GraphClient,
1137
1137
  buildIdentityInventory
1138
1138
  };
1139
- //# sourceMappingURL=chunk-33SGYN2R.js.map
1139
+ //# sourceMappingURL=chunk-36R3CWBW.js.map
@@ -2398,6 +2398,10 @@ var ROUTES = {
2398
2398
  // ?siteId=&id= (&version=N optional)
2399
2399
  deviceOverride: `${API_BASE}/inventory/device/override`,
2400
2400
  // POST upsert | DELETE ?deviceId= (WRITE)
2401
+ // Manual upstream parent per device (0229) — what dependency-aware alert
2402
+ // suppression walks before LLDP/CDP-inferred parents.
2403
+ deviceParent: `${API_BASE}/inventory/device/parent`,
2404
+ // GET ?siteId= -> DeviceParentsResponse | PUT SetDeviceParentBody | DELETE ?deviceId= (WRITE)
2401
2405
  deviceClassRules: `${API_BASE}/inventory/class-rules`,
2402
2406
  // GET list | POST upsert | DELETE ?id= (ADMIN)
2403
2407
  snapshots: `${API_BASE}/inventory/snapshots`,
@@ -2462,6 +2466,23 @@ var ROUTES = {
2462
2466
  // POST RevokeCollectorBody (session ADMIN) — 0139 tombstone: key dead, row and history kept
2463
2467
  collectorUiAuth: `${API_BASE}/collector/ui-auth`,
2464
2468
  // POST CollectorUiAuthBody (collector key) — the localhost UI's login, verified against an ACTIVE account of the key's own tenant
2469
+ // Collector self-update (0226). The collector asks which build this plane
2470
+ // ships with and whether it may update itself; the portal flips the switch.
2471
+ // POST like every other collector config pull (collectorMonitorTargets,
2472
+ // collectorSites) — the key rides the Bearer header, never a query string.
2473
+ collectorUpdatePolicy: `${API_BASE}/collector/update-policy`,
2474
+ // POST (collector key) -> CollectorUpdatePolicy
2475
+ collectorSelfUpdate: `${API_BASE}/collectors/self-update`,
2476
+ // PUT SetCollectorSelfUpdateBody (session ADMIN) -> SetCollectorSelfUpdateResult
2477
+ // Portal schedule editor (0227). Edits are QUEUED here and delivered on the
2478
+ // jobs/next poll (`ClaimedJobResponse.scheduleEdits`); the collector applies
2479
+ // them with its local console's own code and acknowledges on its status
2480
+ // report (`CollectorReportedState.scheduleEditAcks`). The plane never owns a
2481
+ // schedule — it only carries a request to the host that does.
2482
+ collectorSchedules: `${API_BASE}/collectors/schedules`,
2483
+ // GET ?collectorId= (session ADMIN) -> CollectorSchedulesResponse
2484
+ collectorScheduleEdits: `${API_BASE}/collectors/schedule-edits`,
2485
+ // POST SubmitScheduleEditBody (session ADMIN) -> SubmitScheduleEditResult
2465
2486
  // `credentialSets: ${API_BASE}/credential-sets` stood here until 2026-09-01.
2466
2487
  // Credentials live on the collector host now, encrypted under an OS-native
2467
2488
  // key; there is no route to store one here and there must never be another.
@@ -2704,6 +2725,9 @@ var ROUTES = {
2704
2725
  // POST ?siteId= (session, WRITE)
2705
2726
  topologyInferredReview: `${API_BASE}/topology/inferred/review`,
2706
2727
  // POST ?siteId= {id,state} (session, WRITE)
2728
+ // Pinned diagram layouts (0228): per (site, view), shared by the tenant.
2729
+ diagramLayout: `${API_BASE}/topology/layout`,
2730
+ // GET ?siteId=&viewKey= -> DiagramLayoutResponse | PUT PutDiagramLayoutBody | DELETE ?siteId=&viewKey= (WRITE)
2707
2731
  // The Assistant's seven routes (`/assistant/chat`, `/capabilities`, `/search`,
2708
2732
  // `/conversations`, `/conversation`, `/usage`) stood here until 2026-10-02,
2709
2733
  // when the module was retired. See RETIRED_MODULE_KEYS in entitlement.ts.
@@ -2739,6 +2763,9 @@ var ROUTES = {
2739
2763
  // broken feature that never fires.
2740
2764
  metricBaselines: `${API_BASE}/metrics/baselines`,
2741
2765
  // GET ?siteId=[&interface=] (session, READ)
2766
+ // The rows `metrics/alerting.ts` evaluates (metric_thresholds, 0100).
2767
+ metricThresholds: `${API_BASE}/metrics/thresholds`,
2768
+ // GET [?siteId=] -> MetricThresholdsResponse | POST CreateMetricThresholdBody | PUT UpdateMetricThresholdBody | DELETE ?id= (WRITE)
2742
2769
  alertWindows: `${API_BASE}/alert-windows`,
2743
2770
  // GET [?siteId=] (READ) | POST (WRITE) | DELETE ?id= (WRITE)
2744
2771
  // Logical (L3) network view + path trace (spec §5).
@@ -3095,8 +3122,47 @@ var ROUTES = {
3095
3122
  // GET ?planId= (session, CONFIG) — the full plan incl. commands
3096
3123
  advisorPlanReview: `${API_BASE}/advisor/plan/review`,
3097
3124
  // POST {planId,reviewState,notes?} (session, CONFIG)
3098
- advisorPlanExport: `${API_BASE}/advisor/plan/export`
3125
+ advisorPlanExport: `${API_BASE}/advisor/plan/export`,
3099
3126
  // GET ?planId= (session, CONFIG) — MOP as Markdown
3127
+ // ── Source of Truth (docs/design/source-of-truth.md, 2026-10-07) ─────────────
3128
+ // No new module key: every route below rides an existing gate.
3129
+ // F1 Approved Baseline — config-management (M_CONFIG_MGMT). No route here returns config text.
3130
+ baseline: `${API_BASE}/baseline`,
3131
+ // GET ?siteId= (session, READ, M_CONFIG_MGMT) — active snapshot + config baselines and deviation counts by status/severity
3132
+ baselineSnapshot: `${API_BASE}/baseline/snapshot`,
3133
+ // POST BaselineSnapshotBody (session, ADMIN, M_CONFIG_MGMT full) — approve a snapshot as the site's baseline
3134
+ baselineConfig: `${API_BASE}/baseline/config`,
3135
+ // POST BaselineConfigBody (session, ADMIN, M_CONFIG_MGMT full) — approve a device's config revision
3136
+ baselineClear: `${API_BASE}/baseline/clear`,
3137
+ // DELETE ?siteId=&kind=&deviceId= (session, ADMIN, M_CONFIG_MGMT full) — deactivate a baseline (row kept)
3138
+ baselineRebaseline: `${API_BASE}/baseline/rebaseline`,
3139
+ // POST BaselineRebaselineBody (session, ADMIN, M_CONFIG_MGMT full) — re-point at the newest snapshot, close accepted items
3140
+ baselineDeviations: `${API_BASE}/baseline/deviations`,
3141
+ // GET ?siteId=&status=&severity=&category= (session, READ, M_CONFIG_MGMT) — the deviation queue
3142
+ baselineDeviationAction: `${API_BASE}/baseline/deviations/action`,
3143
+ // POST BaselineDeviationActionBody (session, WRITE, M_CONFIG_MGMT full) — acknowledge / accept / reopen
3144
+ // F2 NetBox — documentation (M_DOCUMENTATION); writes at "full". Cloud-direct + CSV fallback.
3145
+ netboxSettings: `${API_BASE}/integrations/netbox`,
3146
+ // GET (session, READ) token masked | PUT NetboxSettingsBody | DELETE (session, ADMIN, documentation full)
3147
+ netboxTest: `${API_BASE}/integrations/netbox/test`,
3148
+ // POST (session, ADMIN, documentation full) — GET /api/status/ on the saved NetBox, 8 s timeout
3149
+ netboxPreview: `${API_BASE}/integrations/netbox/preview`,
3150
+ // POST NetboxPreviewBody (session, ADMIN, documentation full) — dry run: create/update/unchanged per object type
3151
+ netboxPush: `${API_BASE}/integrations/netbox/push`,
3152
+ // POST NetboxPushBody (session, ADMIN, documentation full) — bounded push; repeat while a cursor is returned
3153
+ netboxImport: `${API_BASE}/integrations/netbox/import`,
3154
+ // POST NetboxImportBody (session, ADMIN, documentation full) — NetBox sites/prefixes → sites/site_networks
3155
+ netboxRuns: `${API_BASE}/integrations/netbox/runs`,
3156
+ // GET (session, READ, M_DOCUMENTATION) — preview/push/import run log
3157
+ netboxCsv: `${API_BASE}/integrations/netbox/csv`,
3158
+ // GET ?siteId=&object= (session, READ, M_DOCUMENTATION) — NetBox bulk-import CSV (text/csv)
3159
+ // F3 Lifecycle data — lifecycle (M_LIFECYCLE).
3160
+ lifecycleEoxRefresh: `${API_BASE}/lifecycle/eox-refresh`,
3161
+ // POST LifecycleEoxRefreshBody (session, ADMIN, M_LIFECYCLE) — Cisco EoX by this tenant's own PIDs, ≤20 per call, cached
3162
+ // F4a Azure network diagram — network-diagrams (M_DIAGRAMS). Tenant-wide like /azure.
3163
+ azureNetworkDiagram: `${API_BASE}/azure/network-diagram`
3164
+ // GET ?subscriptionId= (session, READ, M_DIAGRAMS) — subscriptions/VNets/subnets/NSGs/gateways + edges, capped
3165
+ // ── end Source of Truth ──────────────────────────────────────────────────────
3100
3166
  };
3101
3167
  var PLANE_ENVIRONMENTS = ["stage", "production"];
3102
3168
  var PlaneEnvironment = z18.enum(PLANE_ENVIRONMENTS);
@@ -4018,12 +4084,79 @@ var CollectorInstance = z18.object({
4018
4084
  sealingKey: SealingPublicKey.nullable().optional()
4019
4085
  });
4020
4086
  var ClaimedJob = ScanJob.nullable();
4087
+ var EditableScanSchedule = z18.object({
4088
+ name: z18.string().min(1).max(200),
4089
+ enabled: z18.boolean().default(true),
4090
+ siteId: z18.string().min(1),
4091
+ domain: ScanDomain.default("network"),
4092
+ targets: z18.array(z18.string().min(1)).max(500).default([]),
4093
+ domainTarget: DomainScanTarget.optional(),
4094
+ localCredentialSetId: z18.string().min(1).max(200).optional(),
4095
+ timing: ScheduleTiming
4096
+ }).strict().refine(
4097
+ (s) => s.domain !== "network" || s.targets.length > 0,
4098
+ "a network scan schedule needs at least one target"
4099
+ );
4100
+ var ScheduleEditOp = z18.enum(["create", "update", "delete", "setEnabled"]);
4101
+ function scheduleEditIssue(e) {
4102
+ const hasId = typeof e.scheduleId === "string" && e.scheduleId.length > 0;
4103
+ switch (e.op) {
4104
+ case "create":
4105
+ if (hasId) return "a create carries no scheduleId; the collector assigns one";
4106
+ return e.schedule === void 0 ? "a create needs the schedule" : null;
4107
+ case "update":
4108
+ if (!hasId) return "an update needs the scheduleId";
4109
+ return e.schedule === void 0 ? "an update needs the whole schedule" : null;
4110
+ case "delete":
4111
+ return hasId ? null : "a delete needs the scheduleId";
4112
+ case "setEnabled":
4113
+ if (!hasId) return "setEnabled needs the scheduleId";
4114
+ return e.enabled === void 0 ? "setEnabled needs enabled" : null;
4115
+ }
4116
+ }
4117
+ var scheduleEditFields = {
4118
+ op: ScheduleEditOp,
4119
+ /** The collector's own schedule id. Absent on a create. */
4120
+ scheduleId: z18.string().min(1).max(200).optional(),
4121
+ /** The full definition, on create and update. */
4122
+ schedule: EditableScanSchedule.optional(),
4123
+ /** The new state, on setEnabled. */
4124
+ enabled: z18.boolean().optional()
4125
+ };
4126
+ var ScheduleEditFields = z18.object({
4127
+ /** Plane-side id (collector_schedule_edits.id); what the ack names. */
4128
+ id: z18.string().min(1).max(200),
4129
+ ...scheduleEditFields,
4130
+ createdAt: z18.string(),
4131
+ /** Who asked — the portal user's email, for the collector's local log. */
4132
+ createdBy: z18.string().max(320)
4133
+ });
4134
+ var ScheduleEdit = ScheduleEditFields.superRefine((e, ctx) => {
4135
+ const issue = scheduleEditIssue(e);
4136
+ if (issue) ctx.addIssue({ code: z18.ZodIssueCode.custom, message: issue });
4137
+ });
4138
+ var ScheduleEditAck = z18.object({
4139
+ id: z18.string().min(1).max(200),
4140
+ outcome: z18.enum(["applied", "rejected"]),
4141
+ /** On an applied create, the id the collector minted. */
4142
+ scheduleId: z18.string().min(1).max(200).optional(),
4143
+ /** The local validation message on a rejection — never a credential. */
4144
+ error: z18.string().max(500).nullable().default(null)
4145
+ }).strict();
4021
4146
  var ClaimedJobResponse = z18.object({
4022
4147
  job: ClaimedJob,
4023
4148
  /** In-app restart signal (migration 0093): when present and NEWER than the
4024
4149
  * daemon's own start time, the collector re-execs. Rides on the existing poll
4025
4150
  * so no extra endpoint is needed. Null/absent = no restart pending. */
4026
- restartRequestedAt: z18.string().datetime().nullable().default(null)
4151
+ restartRequestedAt: z18.string().datetime().nullable().default(null),
4152
+ /**
4153
+ * Pending portal schedule edits for this collector, oldest first (0227).
4154
+ * Absent means none (read it as `?? []`): optional so a plane that predates
4155
+ * it still parses and the plane's existing responses need not change, and
4156
+ * `.catch(undefined)` so an edit this build cannot read (a future op) costs
4157
+ * the edits, never the job claimed on the same poll.
4158
+ */
4159
+ scheduleEdits: z18.array(ScheduleEdit).max(50).optional().catch(void 0)
4027
4160
  });
4028
4161
  var ScanJobStatusBody = z18.object({
4029
4162
  jobId: z18.string().min(1),
@@ -4128,7 +4261,21 @@ var ReportedSchedule = z18.object({
4128
4261
  /** Next fire time, jitter already applied. Null when disabled or frozen out. */
4129
4262
  nextRunAt: z18.string().nullable(),
4130
4263
  lastRunAt: z18.string().nullable(),
4131
- lastStatus: ReportedRunStatus
4264
+ lastStatus: ReportedRunStatus,
4265
+ /** Editor fields (0227) — absent from a collector before the portal editor. */
4266
+ targets: z18.array(z18.string().min(1)).max(500).optional(),
4267
+ domainTarget: DomainScanTarget.optional(),
4268
+ localCredentialSetId: z18.string().min(1).max(200).optional(),
4269
+ /** The whole timing block: windows, blackouts, jitter, policies. */
4270
+ timing: ScheduleTiming.optional()
4271
+ }).strict();
4272
+ var SelfUpdateOutcome = z18.enum(["updated", "failed", "skipped-disabled", "skipped-busy"]);
4273
+ var CollectorSelfUpdateAttempt = z18.object({
4274
+ at: z18.string(),
4275
+ fromVersion: z18.string().min(1).max(40),
4276
+ toVersion: z18.string().min(1).max(40),
4277
+ outcome: SelfUpdateOutcome,
4278
+ reason: z18.string().max(500).nullable().default(null)
4132
4279
  }).strict();
4133
4280
  var CollectorReportedState = z18.object({
4134
4281
  /** When the collector built this report (its own clock). */
@@ -4210,7 +4357,17 @@ var CollectorReportedState = z18.object({
4210
4357
  * "ignore disabled, ignore null, take the minimum" — three chances to get a
4211
4358
  * different answer from the collector that actually owns the timers.
4212
4359
  */
4213
- nextRunAt: z18.string().nullable()
4360
+ nextRunAt: z18.string().nullable(),
4361
+ /**
4362
+ * The collector's most recent self-update attempt (0226), or null when it
4363
+ * has never tried. Optional so a report from an older collector parses.
4364
+ */
4365
+ lastSelfUpdate: CollectorSelfUpdateAttempt.nullable().optional(),
4366
+ /**
4367
+ * What became of each portal schedule edit delivered on the poll (0227).
4368
+ * Absent or empty when there is nothing to acknowledge.
4369
+ */
4370
+ scheduleEditAcks: z18.array(ScheduleEditAck).max(100).optional()
4214
4371
  }).strict();
4215
4372
  var CollectorStatusReportResult = z18.object({ ok: z18.literal(true) });
4216
4373
  var CollectorEntitlementResult = z18.object({
@@ -4386,7 +4543,14 @@ var Collector = z18.object({
4386
4543
  *
4387
4544
  * Defaulted so a control plane that predates the field still parses.
4388
4545
  */
4389
- instances: z18.array(CollectorInstance).default([])
4546
+ instances: z18.array(CollectorInstance).default([]),
4547
+ /**
4548
+ * collectors.self_update_enabled (0226). Absent reads as TRUE — the column's
4549
+ * own default — so a plane that predates the field still parses.
4550
+ */
4551
+ selfUpdateEnabled: z18.boolean().optional(),
4552
+ /** collectors.last_self_update (0226): the last attempt it reported, or null. */
4553
+ lastSelfUpdate: CollectorSelfUpdateAttempt.nullable().optional()
4390
4554
  });
4391
4555
  var CollectorInstall = z18.object({
4392
4556
  downloadUrl: z18.string().nullable().default(null),
@@ -7172,6 +7336,7 @@ var MonitorTargetsResponse = z18.object({
7172
7336
  /** Suggested seconds between probe sweeps (the collector may clamp). */
7173
7337
  intervalMs: z18.number().int().positive()
7174
7338
  });
7339
+ var ProbeMethod = z18.enum(["icmp", "tcp"]);
7175
7340
  var MonitorResult = z18.object({
7176
7341
  deviceId: z18.string(),
7177
7342
  siteId: z18.string(),
@@ -7179,7 +7344,15 @@ var MonitorResult = z18.object({
7179
7344
  up: z18.boolean(),
7180
7345
  /** Round-trip of the successful TCP connect, ms; null when down/unknown. */
7181
7346
  latencyMs: z18.number().nonnegative().nullable(),
7182
- checkedAt: z18.string().datetime()
7347
+ checkedAt: z18.string().datetime(),
7348
+ /**
7349
+ * How the probe that decided `up` was made (ICMP echo first, TCP connect as
7350
+ * the fallback where ICMP is filtered or unavailable to the process). Absent
7351
+ * from a collector before ICMP probing, which only ever used TCP.
7352
+ */
7353
+ method: ProbeMethod.optional(),
7354
+ /** Round-trip of that probe, ms; null when down. Absent from older collectors. */
7355
+ rttMs: z18.number().nonnegative().nullable().optional()
7183
7356
  });
7184
7357
  var MonitorReportBody = z18.object({
7185
7358
  results: z18.array(MonitorResult)
@@ -7195,7 +7368,9 @@ var LiveMonitorDevice = z18.object({
7195
7368
  ip: z18.string(),
7196
7369
  status: LiveStatus,
7197
7370
  latencyMs: z18.number().nonnegative().nullable(),
7198
- checkedAt: z18.string().datetime()
7371
+ checkedAt: z18.string().datetime(),
7372
+ /** The last probe's method; null/absent when unknown (an older collector or plane). */
7373
+ method: ProbeMethod.nullable().optional()
7199
7374
  });
7200
7375
  var LiveMonitorResponse = z18.object({
7201
7376
  generatedAt: z18.string().datetime(),
@@ -7261,7 +7436,14 @@ var Alert = z18.object({
7261
7436
  message: z18.string(),
7262
7437
  /** How many channels accepted delivery (2xx). */
7263
7438
  delivered: z18.number().int().nonnegative(),
7264
- createdAt: z18.string()
7439
+ createdAt: z18.string(),
7440
+ /**
7441
+ * Dependency-aware suppression (0229): the upstream device whose outage
7442
+ * explains this one. Set on a `device_down` recorded while its parent was
7443
+ * also down — kept in the feed for the record, not sent to any channel.
7444
+ * Null or absent for every other alert, and from a plane before 0229.
7445
+ */
7446
+ suppressedByDeviceId: z18.string().nullable().optional()
7265
7447
  });
7266
7448
  var AlertsResponse = z18.object({ alerts: z18.array(Alert) });
7267
7449
  var AuditEntry = z18.object({
@@ -7361,6 +7543,7 @@ var CreateReportScheduleResult = z18.object({ ok: z18.literal(true), id: z18.str
7361
7543
  var RunReportScheduleBody = z18.object({ id: z18.string() });
7362
7544
  var RunReportScheduleResult = z18.object({ ok: z18.boolean(), detail: z18.string() });
7363
7545
  var AssetCategory = z18.enum(["server", "network", "appliance", "other"]);
7546
+ var LifecycleAssetSource = z18.enum(["manual", "derived", "cisco-eox", "endoflife.date"]);
7364
7547
  var IsoDate = z18.string().regex(/^\d{4}-\d{2}-\d{2}$/, "date must be YYYY-MM-DD");
7365
7548
  var LifecycleAsset = z18.object({
7366
7549
  id: z18.string(),
@@ -7378,10 +7561,15 @@ var LifecycleAsset = z18.object({
7378
7561
  endOfSale: z18.string().nullable(),
7379
7562
  endOfLife: z18.string().nullable(),
7380
7563
  endOfSupport: z18.string().nullable(),
7381
- source: z18.enum(["manual", "derived"]),
7564
+ /** Widened 2026-10-07 (Source of Truth F3). An unknown value from a newer
7565
+ * plane reads as "derived" rather than failing the whole list. */
7566
+ source: LifecycleAssetSource.catch("derived"),
7382
7567
  notes: z18.string().nullable(),
7383
7568
  createdAt: z18.string(),
7384
- updatedAt: z18.string()
7569
+ updatedAt: z18.string(),
7570
+ /** ISO date the hardware warranty ends — separate from `supportEnd` (a
7571
+ * support contract). Null = not recorded; absent on an older plane. */
7572
+ warrantyEnd: z18.string().nullable().default(null)
7385
7573
  });
7386
7574
  var LifecycleAssetsResponse = z18.object({ assets: z18.array(LifecycleAsset) });
7387
7575
  var CreateLifecycleAssetBody = z18.object({
@@ -7400,7 +7588,9 @@ var CreateLifecycleAssetBody = z18.object({
7400
7588
  endOfSale: IsoDate.nullish(),
7401
7589
  endOfLife: IsoDate.nullish(),
7402
7590
  endOfSupport: IsoDate.nullish(),
7403
- notes: z18.string().max(2e3).nullish()
7591
+ notes: z18.string().max(2e3).nullish(),
7592
+ /** Hardware warranty end (Source of Truth F3) — separate from supportEnd. */
7593
+ warrantyEnd: IsoDate.nullish()
7404
7594
  });
7405
7595
  var CreateLifecycleAssetResult = z18.object({ ok: z18.literal(true), id: z18.string() });
7406
7596
  var ImportLifecycleAssetsBody = z18.object({
@@ -7419,7 +7609,9 @@ var LifecycleEventType = z18.enum([
7419
7609
  "end_of_life",
7420
7610
  "end_of_support",
7421
7611
  "krbtgt_rotation",
7422
- "contract_renewal"
7612
+ "contract_renewal",
7613
+ /** Hardware warranty end (asset_lifecycle.warranty_end) — Source of Truth F3. */
7614
+ "warranty_end"
7423
7615
  ]);
7424
7616
  var LifecycleEvent = z18.object({
7425
7617
  id: z18.string(),
@@ -7561,7 +7753,13 @@ var RetrackCertificateResult = z18.object({ ok: z18.literal(true) });
7561
7753
  var DeriveLifecycleResult = z18.object({
7562
7754
  ok: z18.literal(true),
7563
7755
  created: z18.number().int().nonnegative(),
7564
- matched: z18.number().int().nonnegative()
7756
+ matched: z18.number().int().nonnegative(),
7757
+ /** Of `matched`, how many came from the tenant's Cisco EoX cache (F3). */
7758
+ eoxMatched: z18.number().int().nonnegative().default(0),
7759
+ /** OS end-of-support rows written from the KB's endoflife.date entries (F3). */
7760
+ osRows: z18.number().int().nonnegative().default(0),
7761
+ /** Curated rows with an EoX answer left for the next pass (per-pass upgrade cap). */
7762
+ upgradesRemaining: z18.number().int().nonnegative().default(0)
7565
7763
  });
7566
7764
  var EolLookupResponse = z18.object({
7567
7765
  match: z18.object({
@@ -7569,7 +7767,13 @@ var EolLookupResponse = z18.object({
7569
7767
  family: z18.string(),
7570
7768
  endOfSale: z18.string().nullable(),
7571
7769
  endOfLife: z18.string().nullable(),
7572
- endOfSupport: z18.string().nullable()
7770
+ endOfSupport: z18.string().nullable(),
7771
+ /** Source label — a vendor bulletin name or "vendor EoL page" (F3). */
7772
+ source: z18.string().nullable().default(null),
7773
+ /** Curated dates are approximate; a Cisco EoX hit is not. */
7774
+ approximate: z18.boolean().default(true),
7775
+ /** Which table answered: the curated reference or the tenant's EoX cache. */
7776
+ origin: z18.enum(["curated", "cisco-eox"]).default("curated")
7573
7777
  }).nullable()
7574
7778
  });
7575
7779
  var CertChangeKind = z18.enum(["new", "rotated", "reissued", "unchanged"]);
@@ -12724,10 +12928,15 @@ export {
12724
12928
  DomainScanTarget,
12725
12929
  CredentialSetKind,
12726
12930
  isIpv4Target,
12931
+ scheduleEditIssue,
12932
+ scheduleEditFields,
12933
+ ScheduleEditFields,
12727
12934
  ClaimedJobResponse,
12728
12935
  ScanJobStatusResult,
12729
12936
  VaultProtection,
12730
12937
  ReportedRunStatus,
12938
+ ReportedSchedule,
12939
+ CollectorSelfUpdateAttempt,
12731
12940
  CollectorEntitlementResult,
12732
12941
  CollectorIdentityResult,
12733
12942
  CollectorSitesResult,
@@ -12798,4 +13007,4 @@ export {
12798
13007
  SddRunCloseResult,
12799
13008
  ApiError
12800
13009
  };
12801
- //# sourceMappingURL=chunk-4AXMNCP5.js.map
13010
+ //# sourceMappingURL=chunk-4GWOGLPA.js.map