@64mb/freelens-power 1.4.0 → 1.6.0

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 (107) hide show
  1. package/README.md +7 -4
  2. package/out/main/ai-ipc.js +34 -3
  3. package/out/main/ai-ipc.js.map +1 -1
  4. package/out/main/common/power-logs-limits.js +227 -0
  5. package/out/main/common/power-logs-limits.js.map +1 -0
  6. package/out/main/common/power-logs.js +32 -0
  7. package/out/main/common/power-logs.js.map +1 -0
  8. package/out/main/common/resource-search.js +61 -0
  9. package/out/main/common/resource-search.js.map +1 -0
  10. package/out/main/common/store/logs-preferences-store.js +45 -0
  11. package/out/main/common/store/logs-preferences-store.js.map +1 -0
  12. package/out/main/common/store/monitoring-preferences-store.js +5 -0
  13. package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
  14. package/out/main/dashboard-icon-cache.js +1 -1
  15. package/out/main/index.js +6 -0
  16. package/out/main/index.js.map +1 -1
  17. package/out/main/power-logs-budget.js +126 -0
  18. package/out/main/power-logs-budget.js.map +1 -0
  19. package/out/main/power-logs-child.js +86 -0
  20. package/out/main/power-logs-child.js.map +1 -0
  21. package/out/main/power-logs-database.js +179 -0
  22. package/out/main/power-logs-database.js.map +1 -0
  23. package/out/main/power-logs-ipc.js +275 -0
  24. package/out/main/power-logs-ipc.js.map +1 -0
  25. package/out/main/power-logs-query-child.js +23 -0
  26. package/out/main/power-logs-query-child.js.map +1 -0
  27. package/out/main/power-logs-query.js +127 -0
  28. package/out/main/power-logs-query.js.map +1 -0
  29. package/out/main/power-logs-worker.js +215 -0
  30. package/out/main/power-logs-worker.js.map +1 -0
  31. package/out/main/resource-search-database.js +209 -0
  32. package/out/main/resource-search-database.js.map +1 -0
  33. package/out/main/resource-search-worker.js +56 -0
  34. package/out/main/resource-search-worker.js.map +1 -0
  35. package/out/main/resource-search.js +155 -0
  36. package/out/main/resource-search.js.map +1 -0
  37. package/out/renderer/ai-logs-sql.js +27 -0
  38. package/out/renderer/ai-logs-sql.js.map +1 -0
  39. package/out/renderer/ai-message.js +48 -27
  40. package/out/renderer/ai-message.js.map +1 -1
  41. package/out/renderer/ai-terminal-context.js +50 -40
  42. package/out/renderer/ai-terminal-context.js.map +1 -1
  43. package/out/renderer/ai.js +15 -2
  44. package/out/renderer/ai.js.map +1 -1
  45. package/out/renderer/appearance.js +2 -1
  46. package/out/renderer/appearance.js.map +1 -1
  47. package/out/renderer/gateway-relationships-client.js +107 -0
  48. package/out/renderer/gateway-relationships-client.js.map +1 -0
  49. package/out/renderer/index.js +67 -29
  50. package/out/renderer/index.js.map +1 -1
  51. package/out/renderer/power-log-json.js +29 -0
  52. package/out/renderer/power-log-json.js.map +1 -0
  53. package/out/renderer/power-logs-client.js +35 -0
  54. package/out/renderer/power-logs-client.js.map +1 -0
  55. package/out/renderer/power-logs-collector.js +316 -0
  56. package/out/renderer/power-logs-collector.js.map +1 -0
  57. package/out/renderer/power-logs-entrypoints.js +201 -0
  58. package/out/renderer/power-logs-entrypoints.js.map +1 -0
  59. package/out/renderer/power-logs-sql-row.js +52 -0
  60. package/out/renderer/power-logs-sql-row.js.map +1 -0
  61. package/out/renderer/power-logs-transport.js +122 -0
  62. package/out/renderer/power-logs-transport.js.map +1 -0
  63. package/out/renderer/power-logs.css.js +116 -0
  64. package/out/renderer/power-logs.css.js.map +1 -0
  65. package/out/renderer/power-logs.js +1352 -0
  66. package/out/renderer/power-logs.js.map +1 -0
  67. package/out/renderer/preferences/logs-preferences.js +93 -0
  68. package/out/renderer/preferences/logs-preferences.js.map +1 -0
  69. package/out/renderer/preferences/monitoring-preferences.js +10 -0
  70. package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
  71. package/out/renderer/preferences/preferences.js +24 -10
  72. package/out/renderer/preferences/preferences.js.map +1 -1
  73. package/out/renderer/resource-relationships.css.js +1 -1
  74. package/out/renderer/resource-relationships.css.js.map +1 -1
  75. package/out/renderer/resource-relationships.js +46 -8
  76. package/out/renderer/resource-relationships.js.map +1 -1
  77. package/out/renderer/resource-search-client.js +116 -0
  78. package/out/renderer/resource-search-client.js.map +1 -0
  79. package/out/renderer/resource-search-discovery.js +79 -0
  80. package/out/renderer/resource-search-discovery.js.map +1 -0
  81. package/out/renderer/resource-search-model.js +2 -1
  82. package/out/renderer/resource-search-model.js.map +1 -1
  83. package/out/renderer/resource-search-routing.js +78 -0
  84. package/out/renderer/resource-search-routing.js.map +1 -0
  85. package/out/renderer/resource-search-sync.js +199 -0
  86. package/out/renderer/resource-search-sync.js.map +1 -0
  87. package/out/renderer/resource-search.js +279 -54
  88. package/out/renderer/resource-search.js.map +1 -1
  89. package/out/renderer/src/common/gateway-relationships.js +122 -0
  90. package/out/renderer/src/common/gateway-relationships.js.map +1 -0
  91. package/out/renderer/src/common/power-log-parser.js +114 -0
  92. package/out/renderer/src/common/power-log-parser.js.map +1 -0
  93. package/out/renderer/src/common/power-logs-ai.js +56 -0
  94. package/out/renderer/src/common/power-logs-ai.js.map +1 -0
  95. package/out/renderer/src/common/power-logs-limits.js +227 -0
  96. package/out/renderer/src/common/power-logs-limits.js.map +1 -0
  97. package/out/renderer/src/common/power-logs.js +32 -0
  98. package/out/renderer/src/common/power-logs.js.map +1 -0
  99. package/out/renderer/src/common/resource-relationships.js +8 -0
  100. package/out/renderer/src/common/resource-relationships.js.map +1 -1
  101. package/out/renderer/src/common/resource-search.js +6 -0
  102. package/out/renderer/src/common/resource-search.js.map +1 -0
  103. package/out/renderer/src/common/store/logs-preferences-store.js +45 -0
  104. package/out/renderer/src/common/store/logs-preferences-store.js.map +1 -0
  105. package/out/renderer/src/common/store/monitoring-preferences-store.js +5 -0
  106. package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
  107. package/package.json +8 -2
@@ -0,0 +1,122 @@
1
+ //#region src/common/gateway-relationships.ts
2
+ var GROUP = "gateway.networking.k8s.io";
3
+ function conditions(items, generation, types = ["Accepted", "ResolvedRefs"]) {
4
+ return types.map((type) => {
5
+ const condition = items?.find((item) => item.type === type);
6
+ const stale = generation !== void 0 && condition?.observedGeneration !== generation;
7
+ return `${type}: ${condition ? `${condition.status}${condition.reason ? ` (${condition.reason})` : ""}${stale ? " · stale/unknown generation" : ""}` : "unknown"}`;
8
+ }).join(" · ");
9
+ }
10
+ function grantEvidence(route, backend, inventory) {
11
+ const namespace = backend.namespace ?? route.metadata.namespace;
12
+ if (namespace === route.metadata.namespace) return "same-namespace backend";
13
+ if (!inventory.grants || inventory.grantNamespaces && !inventory.grantNamespaces.includes(namespace ?? "")) return "cross-namespace ReferenceGrant unknown";
14
+ return inventory.grants.some((grant) => grant.metadata.namespace === namespace && grant.spec?.from?.some((from) => from.group === GROUP && from.kind === route.kind && from.namespace === route.metadata.namespace) && grant.spec?.to?.some((to) => to.group === "" && to.kind === "Service" && (!to.name || to.name === backend.name))) ? "cross-namespace ReferenceGrant permits backend" : "cross-namespace backend not permitted by observed ReferenceGrants";
15
+ }
16
+ function attachment(route, gateway, listener, inventory) {
17
+ const kinds = listener.allowedRoutes?.kinds;
18
+ if (kinds && !kinds.some((kind) => (kind.group ?? GROUP) === GROUP && kind.kind === route.kind)) return "listener rejects route kind";
19
+ if (!kinds) {
20
+ if (!{
21
+ HTTP: ["HTTPRoute", "GRPCRoute"],
22
+ HTTPS: ["HTTPRoute", "GRPCRoute"],
23
+ TCP: ["TCPRoute"],
24
+ TLS: ["TLSRoute"],
25
+ UDP: ["UDPRoute"]
26
+ }[listener.protocol]?.includes(route.kind)) return "listener rejects route kind or protocol support unknown";
27
+ }
28
+ const ns = listener.allowedRoutes?.namespaces;
29
+ if (!ns || !ns.from || ns.from === "Same") return route.metadata.namespace === gateway.metadata.namespace ? "allowedRoutes permits namespace" : "allowedRoutes rejects namespace";
30
+ if (ns.from === "All") return "allowedRoutes permits all namespaces";
31
+ if (ns.from !== "Selector") return "allowedRoutes namespace unknown";
32
+ const namespace = inventory.namespaces?.find((item) => item.metadata.name === route.metadata.namespace);
33
+ if (!namespace) return "allowedRoutes namespace selector unknown";
34
+ const labels = namespace.metadata.labels ?? {};
35
+ return Object.entries(ns.selector?.matchLabels ?? {}).every(([key, value]) => labels[key] === value) && (ns.selector?.matchExpressions ?? []).every(({ key, operator, values = [] }) => {
36
+ if (operator === "In") return labels[key] !== void 0 && values.includes(labels[key]);
37
+ if (operator === "NotIn") return labels[key] === void 0 || !values.includes(labels[key]);
38
+ if (operator === "Exists") return labels[key] !== void 0;
39
+ if (operator === "DoesNotExist") return labels[key] === void 0;
40
+ return false;
41
+ }) ? "allowedRoutes namespace selector matches" : "allowedRoutes namespace selector rejects";
42
+ }
43
+ function gatewayRelationships(service, inventory) {
44
+ const nodes = [];
45
+ const edges = [];
46
+ let omitted = 0;
47
+ const add = (object, suffix = "", detail = "", evidence) => {
48
+ const id = `gateway-api/${object.kind}/${object.metadata.namespace ?? ""}/${object.metadata.name}${suffix}`;
49
+ if (!nodes.some((node) => node.id === id)) nodes.push({
50
+ id,
51
+ kind: object.kind,
52
+ name: `${object.metadata.name}${suffix}`,
53
+ role: "upstream",
54
+ tone: "neutral",
55
+ detail,
56
+ evidence,
57
+ selfLink: object.selfLink
58
+ });
59
+ return id;
60
+ };
61
+ const routes = inventory.objects.filter((object) => [
62
+ "HTTPRoute",
63
+ "GRPCRoute",
64
+ "TCPRoute",
65
+ "TLSRoute",
66
+ "UDPRoute"
67
+ ].includes(object.kind) && object.spec?.rules?.some((rule) => rule.backendRefs?.some((backend) => (backend.group ?? "") === "" && (backend.kind ?? "Service") === "Service" && backend.name === service.metadata.name && (backend.namespace ?? object.metadata.namespace) === service.metadata.namespace)));
68
+ for (const route of routes.slice(0, 5)) {
69
+ const backends = route.spec?.rules?.flatMap((rule) => rule.backendRefs ?? []).filter((backend) => (backend.group ?? "") === "" && (backend.kind ?? "Service") === "Service" && backend.name === service.metadata.name && (backend.namespace ?? route.metadata.namespace) === service.metadata.namespace) ?? [];
70
+ const summaries = route.spec?.rules?.flatMap((rule) => rule.matches?.map((match) => match.path?.value ?? [match.method?.service, match.method?.method].filter(Boolean).join("/")) ?? []) ?? [];
71
+ const routeId = add(route, "", [
72
+ ...route.spec?.hostnames ?? [],
73
+ ...summaries,
74
+ ...backends.map((backend) => `weight ${backend.weight ?? 1} · ${grantEvidence(route, backend, inventory)}`)
75
+ ].join(" · "));
76
+ edges.push({
77
+ from: routeId,
78
+ to: "service",
79
+ label: "backend reference (not reachability)"
80
+ });
81
+ const parents = (route.spec?.parentRefs ?? []).filter((parent) => (parent.group ?? GROUP) === GROUP && (parent.kind ?? "Gateway") === "Gateway");
82
+ omitted += Math.max(0, parents.length - 5);
83
+ for (const parent of parents.slice(0, 5)) {
84
+ const gateway = inventory.objects.find((object) => object.kind === "Gateway" && object.metadata.name === parent.name && object.metadata.namespace === (parent.namespace ?? route.metadata.namespace));
85
+ if (!gateway) continue;
86
+ const status = route.status?.parents?.filter((item) => (item.parentRef.group ?? GROUP) === GROUP && (item.parentRef.kind ?? "Gateway") === "Gateway" && item.parentRef.name === parent.name && (item.parentRef.namespace ?? route.metadata.namespace) === (parent.namespace ?? route.metadata.namespace) && item.parentRef.sectionName === parent.sectionName && item.parentRef.port === parent.port);
87
+ const listeners = (gateway.spec?.listeners ?? []).filter((item) => (!parent.sectionName || parent.sectionName === item.name) && (!parent.port || parent.port === item.port));
88
+ omitted += Math.max(0, listeners.length - 5);
89
+ for (const listener of listeners.slice(0, 5)) {
90
+ const listenerStatus = gateway.status?.listeners?.find((item) => item.name === listener.name);
91
+ const id = add(gateway, `/${listener.name}`, `${listener.protocol}:${listener.port}`, [`Listener ${conditions(listenerStatus?.conditions, gateway.metadata.generation, [
92
+ "Accepted",
93
+ "ResolvedRefs",
94
+ "Programmed"
95
+ ])}`, `Gateway ${conditions(gateway.status?.conditions, gateway.metadata.generation, ["Accepted", "Programmed"])}`]);
96
+ edges.push({
97
+ from: id,
98
+ to: routeId,
99
+ label: "parent reference",
100
+ evidence: `${attachment(route, gateway, listener, inventory)} · ${status?.length ? status.map((item) => `${item.controllerName ?? "unknown controller"}: ${conditions(item.conditions, route.metadata.generation)}`).join(" · ") : "parent reference · acceptance unknown"}`
101
+ });
102
+ const gatewayClass = inventory.objects.find((object) => object.kind === "GatewayClass" && object.metadata.name === gateway.spec?.gatewayClassName);
103
+ if (gatewayClass) edges.push({
104
+ from: add(gatewayClass, "", conditions(gatewayClass.status?.conditions, gatewayClass.metadata.generation, ["Accepted"])),
105
+ to: id,
106
+ label: "class reference"
107
+ });
108
+ }
109
+ }
110
+ }
111
+ const order = (kind) => kind === "GatewayClass" ? 0 : kind === "Gateway" ? 1 : 2;
112
+ nodes.sort((a, b) => order(a.kind) - order(b.kind));
113
+ return {
114
+ nodes,
115
+ edges,
116
+ omitted: omitted + Math.max(0, routes.length - 5)
117
+ };
118
+ }
119
+ //#endregion
120
+ exports.gatewayRelationships = gatewayRelationships;
121
+
122
+ //# sourceMappingURL=gateway-relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-relationships.js","names":[],"sources":["../../../../src/common/gateway-relationships.ts"],"sourcesContent":["import type { RelationshipEdge, RelationshipNode } from \"./resource-relationships\";\n\nconst GROUP = \"gateway.networking.k8s.io\";\ninterface Condition {\n type: string;\n status: string;\n reason?: string;\n observedGeneration?: number;\n}\ninterface Reference {\n name: string;\n namespace?: string;\n group?: string;\n kind?: string;\n sectionName?: string;\n port?: number;\n weight?: number;\n}\ninterface Listener {\n name: string;\n port: number;\n protocol: string;\n allowedRoutes?: {\n kinds?: { group?: string; kind: string }[];\n namespaces?: {\n from?: string;\n selector?: {\n matchLabels?: Record<string, string>;\n matchExpressions?: { key: string; operator: string; values?: string[] }[];\n };\n };\n };\n}\nexport interface GatewayObject {\n apiVersion?: string;\n kind: string;\n selfLink?: string;\n metadata: { name?: string; namespace?: string; uid?: string; generation?: number; labels?: Record<string, string> };\n spec?: {\n gatewayClassName?: string;\n listeners?: Listener[];\n parentRefs?: Reference[];\n hostnames?: string[];\n rules?: {\n backendRefs?: Reference[];\n matches?: { path?: { value?: string }; method?: { service?: string; method?: string } }[];\n }[];\n from?: { group: string; kind: string; namespace: string }[];\n to?: { group: string; kind: string; name?: string }[];\n };\n status?: {\n conditions?: Condition[];\n listeners?: { name: string; conditions?: Condition[] }[];\n parents?: { parentRef: Reference; controllerName?: string; conditions?: Condition[] }[];\n };\n}\nexport interface GatewayInventory {\n objects: GatewayObject[];\n grants?: GatewayObject[];\n grantNamespaces?: string[];\n namespaces?: GatewayObject[];\n gaps: string[];\n}\nfunction conditions(items: Condition[] | undefined, generation?: number, types = [\"Accepted\", \"ResolvedRefs\"]) {\n return types\n .map((type) => {\n const condition = items?.find((item) => item.type === type);\n const stale = generation !== undefined && condition?.observedGeneration !== generation;\n return `${type}: ${condition ? `${condition.status}${condition.reason ? ` (${condition.reason})` : \"\"}${stale ? \" · stale/unknown generation\" : \"\"}` : \"unknown\"}`;\n })\n .join(\" · \");\n}\nfunction grantEvidence(route: GatewayObject, backend: Reference, inventory: GatewayInventory) {\n const namespace = backend.namespace ?? route.metadata.namespace;\n if (namespace === route.metadata.namespace) return \"same-namespace backend\";\n if (!inventory.grants || (inventory.grantNamespaces && !inventory.grantNamespaces.includes(namespace ?? \"\")))\n return \"cross-namespace ReferenceGrant unknown\";\n const granted = inventory.grants.some(\n (grant) =>\n grant.metadata.namespace === namespace &&\n grant.spec?.from?.some(\n (from) => from.group === GROUP && from.kind === route.kind && from.namespace === route.metadata.namespace,\n ) &&\n grant.spec?.to?.some((to) => to.group === \"\" && to.kind === \"Service\" && (!to.name || to.name === backend.name)),\n );\n return granted\n ? \"cross-namespace ReferenceGrant permits backend\"\n : \"cross-namespace backend not permitted by observed ReferenceGrants\";\n}\nfunction attachment(route: GatewayObject, gateway: GatewayObject, listener: Listener, inventory: GatewayInventory) {\n const kinds = listener.allowedRoutes?.kinds;\n if (kinds && !kinds.some((kind) => (kind.group ?? GROUP) === GROUP && kind.kind === route.kind))\n return \"listener rejects route kind\";\n if (!kinds) {\n const supported: Record<string, string[]> = {\n HTTP: [\"HTTPRoute\", \"GRPCRoute\"],\n HTTPS: [\"HTTPRoute\", \"GRPCRoute\"],\n TCP: [\"TCPRoute\"],\n TLS: [\"TLSRoute\"],\n UDP: [\"UDPRoute\"],\n };\n if (!supported[listener.protocol]?.includes(route.kind))\n return \"listener rejects route kind or protocol support unknown\";\n }\n const ns = listener.allowedRoutes?.namespaces;\n if (!ns || !ns.from || ns.from === \"Same\")\n return route.metadata.namespace === gateway.metadata.namespace\n ? \"allowedRoutes permits namespace\"\n : \"allowedRoutes rejects namespace\";\n if (ns.from === \"All\") return \"allowedRoutes permits all namespaces\";\n if (ns.from !== \"Selector\") return \"allowedRoutes namespace unknown\";\n const namespace = inventory.namespaces?.find((item) => item.metadata.name === route.metadata.namespace);\n if (!namespace) return \"allowedRoutes namespace selector unknown\";\n const labels = namespace.metadata.labels ?? {};\n const selected =\n Object.entries(ns.selector?.matchLabels ?? {}).every(([key, value]) => labels[key] === value) &&\n (ns.selector?.matchExpressions ?? []).every(({ key, operator, values = [] }) => {\n if (operator === \"In\") return labels[key] !== undefined && values.includes(labels[key]);\n if (operator === \"NotIn\") return labels[key] === undefined || !values.includes(labels[key]);\n if (operator === \"Exists\") return labels[key] !== undefined;\n if (operator === \"DoesNotExist\") return labels[key] === undefined;\n return false;\n });\n return selected ? \"allowedRoutes namespace selector matches\" : \"allowedRoutes namespace selector rejects\";\n}\nexport function gatewayRelationships(\n service: { metadata: { name?: string; namespace?: string } },\n inventory: GatewayInventory,\n) {\n const nodes: RelationshipNode[] = [];\n const edges: RelationshipEdge[] = [];\n let omitted = 0;\n const add = (object: GatewayObject, suffix = \"\", detail = \"\", evidence?: string[]) => {\n const id = `gateway-api/${object.kind}/${object.metadata.namespace ?? \"\"}/${object.metadata.name}${suffix}`;\n if (!nodes.some((node) => node.id === id))\n nodes.push({\n id,\n kind: object.kind,\n name: `${object.metadata.name}${suffix}`,\n role: \"upstream\",\n tone: \"neutral\",\n detail,\n evidence,\n selfLink: object.selfLink,\n });\n return id;\n };\n const routes = inventory.objects.filter(\n (object) =>\n [\"HTTPRoute\", \"GRPCRoute\", \"TCPRoute\", \"TLSRoute\", \"UDPRoute\"].includes(object.kind) &&\n object.spec?.rules?.some((rule) =>\n rule.backendRefs?.some(\n (backend) =>\n (backend.group ?? \"\") === \"\" &&\n (backend.kind ?? \"Service\") === \"Service\" &&\n backend.name === service.metadata.name &&\n (backend.namespace ?? object.metadata.namespace) === service.metadata.namespace,\n ),\n ),\n );\n for (const route of routes.slice(0, 5)) {\n const backends =\n route.spec?.rules\n ?.flatMap((rule) => rule.backendRefs ?? [])\n .filter(\n (backend) =>\n (backend.group ?? \"\") === \"\" &&\n (backend.kind ?? \"Service\") === \"Service\" &&\n backend.name === service.metadata.name &&\n (backend.namespace ?? route.metadata.namespace) === service.metadata.namespace,\n ) ?? [];\n const summaries =\n route.spec?.rules?.flatMap(\n (rule) =>\n rule.matches?.map(\n (match) => match.path?.value ?? [match.method?.service, match.method?.method].filter(Boolean).join(\"/\"),\n ) ?? [],\n ) ?? [];\n const routeId = add(\n route,\n \"\",\n [\n ...(route.spec?.hostnames ?? []),\n ...summaries,\n ...backends.map((backend) => `weight ${backend.weight ?? 1} · ${grantEvidence(route, backend, inventory)}`),\n ].join(\" · \"),\n );\n edges.push({ from: routeId, to: \"service\", label: \"backend reference (not reachability)\" });\n const parents = (route.spec?.parentRefs ?? []).filter(\n (parent) => (parent.group ?? GROUP) === GROUP && (parent.kind ?? \"Gateway\") === \"Gateway\",\n );\n omitted += Math.max(0, parents.length - 5);\n for (const parent of parents.slice(0, 5)) {\n const gateway = inventory.objects.find(\n (object) =>\n object.kind === \"Gateway\" &&\n object.metadata.name === parent.name &&\n object.metadata.namespace === (parent.namespace ?? route.metadata.namespace),\n );\n if (!gateway) continue;\n const status = route.status?.parents?.filter(\n (item) =>\n (item.parentRef.group ?? GROUP) === GROUP &&\n (item.parentRef.kind ?? \"Gateway\") === \"Gateway\" &&\n item.parentRef.name === parent.name &&\n (item.parentRef.namespace ?? route.metadata.namespace) === (parent.namespace ?? route.metadata.namespace) &&\n item.parentRef.sectionName === parent.sectionName &&\n item.parentRef.port === parent.port,\n );\n const listeners = (gateway.spec?.listeners ?? []).filter(\n (item) =>\n (!parent.sectionName || parent.sectionName === item.name) && (!parent.port || parent.port === item.port),\n );\n omitted += Math.max(0, listeners.length - 5);\n for (const listener of listeners.slice(0, 5)) {\n const listenerStatus = gateway.status?.listeners?.find((item) => item.name === listener.name);\n const id = add(gateway, `/${listener.name}`, `${listener.protocol}:${listener.port}`, [\n `Listener ${conditions(listenerStatus?.conditions, gateway.metadata.generation, [\"Accepted\", \"ResolvedRefs\", \"Programmed\"])}`,\n `Gateway ${conditions(gateway.status?.conditions, gateway.metadata.generation, [\"Accepted\", \"Programmed\"])}`,\n ]);\n edges.push({\n from: id,\n to: routeId,\n label: \"parent reference\",\n evidence: `${attachment(route, gateway, listener, inventory)} · ${status?.length ? status.map((item) => `${item.controllerName ?? \"unknown controller\"}: ${conditions(item.conditions, route.metadata.generation)}`).join(\" · \") : \"parent reference · acceptance unknown\"}`,\n });\n const gatewayClass = inventory.objects.find(\n (object) => object.kind === \"GatewayClass\" && object.metadata.name === gateway.spec?.gatewayClassName,\n );\n if (gatewayClass)\n edges.push({\n from: add(\n gatewayClass,\n \"\",\n conditions(gatewayClass.status?.conditions, gatewayClass.metadata.generation, [\"Accepted\"]),\n ),\n to: id,\n label: \"class reference\",\n });\n }\n }\n }\n const order = (kind: string) => (kind === \"GatewayClass\" ? 0 : kind === \"Gateway\" ? 1 : 2);\n nodes.sort((a, b) => order(a.kind) - order(b.kind));\n return { nodes, edges, omitted: omitted + Math.max(0, routes.length - 5) };\n}\n"],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ const require_power_logs = require("./power-logs.js");
2
+ //#region src/common/power-log-parser.ts
3
+ var ansi = /\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\))/g;
4
+ var levels = {
5
+ trace: "trace",
6
+ debug: "debug",
7
+ info: "info",
8
+ information: "info",
9
+ warn: "warn",
10
+ warning: "warn",
11
+ error: "error",
12
+ fatal: "fatal",
13
+ critical: "fatal",
14
+ panic: "fatal"
15
+ };
16
+ var pinoLevels = /* @__PURE__ */ new Map([
17
+ [10, "trace"],
18
+ [20, "debug"],
19
+ [30, "info"],
20
+ [40, "warn"],
21
+ [50, "error"],
22
+ [60, "fatal"]
23
+ ]);
24
+ function parseLogLine(line, source) {
25
+ let message = line.replace(ansi, "").replace(/\r$/, "").replace(/\x00/g, "");
26
+ let timestamp = null;
27
+ const prefix = /^(\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,9})?(?:Z|[+-]\d\d:\d\d))\s/.exec(message);
28
+ if (prefix) {
29
+ const value = Date.parse(prefix[1]);
30
+ if (Number.isFinite(value)) timestamp = value;
31
+ message = message.slice(prefix[0].length);
32
+ }
33
+ let fieldsJson = null;
34
+ let level = "unknown";
35
+ try {
36
+ const fields = JSON.parse(message);
37
+ if (fields && typeof fields === "object" && !Array.isArray(fields)) {
38
+ const object = fields;
39
+ const rawLevel = object.level ?? object.severity ?? object.loglevel ?? object.log_level;
40
+ if (typeof rawLevel === "string") level = levels[rawLevel.toLowerCase()] ?? "unknown";
41
+ else if (typeof rawLevel === "number") level = pinoLevels.get(rawLevel) ?? "unknown";
42
+ const rawMessage = object.message ?? object.msg ?? object.text;
43
+ if (typeof rawMessage === "string") message = rawMessage.replace(ansi, "").replace(/\x00/g, "");
44
+ const serialized = JSON.stringify(fields);
45
+ if (Buffer.byteLength(serialized) <= require_power_logs.POWER_LOGS_LIMITS.recordBytes / 2) fieldsJson = serialized;
46
+ }
47
+ } catch {}
48
+ if (level === "unknown") {
49
+ const match = /(?:^|[\s\[])\b(trace|debug|info|warn(?:ing)?|error|fatal|critical|panic)\b[\s\]:-]?/i.exec(message);
50
+ if (match) level = levels[match[1].toLowerCase()] ?? "unknown";
51
+ }
52
+ const record = {
53
+ timestamp,
54
+ pod: source.pod,
55
+ podUid: source.podUid,
56
+ container: source.container,
57
+ level,
58
+ message,
59
+ fieldsJson,
60
+ previous: source.previous === true
61
+ };
62
+ const serializedBytes = () => Buffer.byteLength(JSON.stringify(record));
63
+ if (serializedBytes() > require_power_logs.POWER_LOGS_LIMITS.recordBytes && record.fieldsJson !== null) {
64
+ record.fieldsJson = null;
65
+ record.message += " [structured fields omitted]";
66
+ }
67
+ if (serializedBytes() > require_power_logs.POWER_LOGS_LIMITS.recordBytes) {
68
+ const characters = Array.from(record.message);
69
+ let low = 0;
70
+ let high = characters.length;
71
+ while (low < high) {
72
+ const middle = Math.ceil((low + high) / 2);
73
+ record.message = `${characters.slice(0, middle).join("")} [truncated]`;
74
+ if (serializedBytes() <= require_power_logs.POWER_LOGS_LIMITS.recordBytes) low = middle;
75
+ else high = middle - 1;
76
+ }
77
+ record.message = `${characters.slice(0, low).join("")} [truncated]`;
78
+ }
79
+ return record;
80
+ }
81
+ var LogLineDecoder = class {
82
+ decoder = new TextDecoder();
83
+ pending = "";
84
+ dropping = false;
85
+ truncated = false;
86
+ push(chunk, final = false) {
87
+ const text = typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: !final });
88
+ const lines = [];
89
+ for (const part of text.split(/(?<=\n)/)) {
90
+ const ended = part.endsWith("\n");
91
+ if (!this.dropping) this.pending += part;
92
+ if (Buffer.byteLength(this.pending) > require_power_logs.POWER_LOGS_LIMITS.recordBytes) {
93
+ this.pending = "";
94
+ this.dropping = true;
95
+ this.truncated = true;
96
+ }
97
+ if (ended) {
98
+ if (!this.dropping) lines.push(this.pending.replace(/\r?\n$/, ""));
99
+ this.pending = "";
100
+ this.dropping = false;
101
+ }
102
+ }
103
+ if (final && this.pending && !this.dropping) {
104
+ lines.push(this.pending);
105
+ this.pending = "";
106
+ }
107
+ return lines;
108
+ }
109
+ };
110
+ //#endregion
111
+ exports.LogLineDecoder = LogLineDecoder;
112
+ exports.parseLogLine = parseLogLine;
113
+
114
+ //# sourceMappingURL=power-log-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-log-parser.js","names":[],"sources":["../../../../src/common/power-log-parser.ts"],"sourcesContent":["import { type LogLevel, type LogRecord, type LogSource, POWER_LOGS_LIMITS } from \"./power-logs\";\n\nconst ansi = /\\x1b(?:\\[[0-?]*[ -/]*[@-~]|\\][^\\x07]*(?:\\x07|\\x1b\\\\))/g;\nconst levels: Record<string, LogLevel> = {\n trace: \"trace\",\n debug: \"debug\",\n info: \"info\",\n information: \"info\",\n warn: \"warn\",\n warning: \"warn\",\n error: \"error\",\n fatal: \"fatal\",\n critical: \"fatal\",\n panic: \"fatal\",\n};\nconst pinoLevels = new Map<number, LogLevel>([\n [10, \"trace\"],\n [20, \"debug\"],\n [30, \"info\"],\n [40, \"warn\"],\n [50, \"error\"],\n [60, \"fatal\"],\n]);\nexport function parseLogLine(line: string, source: LogSource): LogRecord {\n let message = line.replace(ansi, \"\").replace(/\\r$/, \"\").replace(/\\x00/g, \"\");\n let timestamp: number | null = null;\n const prefix = /^(\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.\\d{1,9})?(?:Z|[+-]\\d\\d:\\d\\d))\\s/.exec(message);\n if (prefix) {\n const value = Date.parse(prefix[1]);\n if (Number.isFinite(value)) timestamp = value;\n message = message.slice(prefix[0].length);\n }\n let fieldsJson: string | null = null;\n let level: LogLevel = \"unknown\";\n try {\n const fields: unknown = JSON.parse(message);\n if (fields && typeof fields === \"object\" && !Array.isArray(fields)) {\n const object = fields as Record<string, unknown>;\n const rawLevel = object.level ?? object.severity ?? object.loglevel ?? object.log_level;\n if (typeof rawLevel === \"string\") level = levels[rawLevel.toLowerCase()] ?? \"unknown\";\n else if (typeof rawLevel === \"number\") level = pinoLevels.get(rawLevel) ?? \"unknown\";\n const rawMessage = object.message ?? object.msg ?? object.text;\n if (typeof rawMessage === \"string\") message = rawMessage.replace(ansi, \"\").replace(/\\x00/g, \"\");\n const serialized = JSON.stringify(fields);\n if (Buffer.byteLength(serialized) <= POWER_LOGS_LIMITS.recordBytes / 2) fieldsJson = serialized;\n }\n } catch {\n /* malformed structured lines remain plain text */\n }\n if (level === \"unknown\") {\n const match = /(?:^|[\\s\\[])\\b(trace|debug|info|warn(?:ing)?|error|fatal|critical|panic)\\b[\\s\\]:-]?/i.exec(message);\n if (match) level = levels[match[1].toLowerCase()] ?? \"unknown\";\n }\n const record: LogRecord = {\n timestamp,\n pod: source.pod,\n podUid: source.podUid,\n container: source.container,\n level,\n message,\n fieldsJson,\n previous: source.previous === true,\n };\n const serializedBytes = () => Buffer.byteLength(JSON.stringify(record));\n if (serializedBytes() > POWER_LOGS_LIMITS.recordBytes && record.fieldsJson !== null) {\n record.fieldsJson = null;\n record.message += \" [structured fields omitted]\";\n }\n if (serializedBytes() > POWER_LOGS_LIMITS.recordBytes) {\n const characters = Array.from(record.message);\n let low = 0;\n let high = characters.length;\n while (low < high) {\n const middle = Math.ceil((low + high) / 2);\n record.message = `${characters.slice(0, middle).join(\"\")} [truncated]`;\n if (serializedBytes() <= POWER_LOGS_LIMITS.recordBytes) low = middle;\n else high = middle - 1;\n }\n record.message = `${characters.slice(0, low).join(\"\")} [truncated]`;\n }\n return record;\n}\n\nexport class LogLineDecoder {\n private decoder = new TextDecoder();\n private pending = \"\";\n private dropping = false;\n truncated = false;\n push(chunk: Uint8Array | string, final = false): string[] {\n const text = typeof chunk === \"string\" ? chunk : this.decoder.decode(chunk, { stream: !final });\n const lines: string[] = [];\n for (const part of text.split(/(?<=\\n)/)) {\n const ended = part.endsWith(\"\\n\");\n if (!this.dropping) this.pending += part;\n if (Buffer.byteLength(this.pending) > POWER_LOGS_LIMITS.recordBytes) {\n this.pending = \"\";\n this.dropping = true;\n this.truncated = true;\n }\n if (ended) {\n if (!this.dropping) lines.push(this.pending.replace(/\\r?\\n$/, \"\"));\n this.pending = \"\";\n this.dropping = false;\n }\n }\n if (final && this.pending && !this.dropping) {\n lines.push(this.pending);\n this.pending = \"\";\n }\n return lines;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ const require_ai_terminal_context = require("./ai-terminal-context.js");
2
+ //#region src/common/power-logs-ai.ts
3
+ var sensitive = (key) => /(?:password|passwd|token|secret|authorization|credential|apikey|privatekey|clientkeydata|clientcertificatedata)/i.test(key.replace(/[^a-z0-9]/gi, ""));
4
+ function project(value, depth = 0) {
5
+ if (depth > 8) return "[nested content omitted]";
6
+ if (typeof value === "string") {
7
+ try {
8
+ const parsed = JSON.parse(value);
9
+ if (parsed !== null && (typeof parsed === "object" || typeof parsed === "string")) return project(parsed, depth + 1);
10
+ } catch {}
11
+ return require_ai_terminal_context.redactAiTerminalText(value);
12
+ }
13
+ if (Array.isArray(value)) return value.slice(0, 100).map((item) => project(item, depth + 1));
14
+ if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).slice(0, 100).map(([key, item]) => [key, sensitive(key) ? "[REDACTED]" : project(item, depth + 1)]));
15
+ return value;
16
+ }
17
+ function powerLogLineEvidence(target, record) {
18
+ const { timestamp, pod, podUid, container, level, message, fieldsJson, previous } = record;
19
+ return JSON.stringify(project({
20
+ observedAt: (/* @__PURE__ */ new Date()).toISOString(),
21
+ target,
22
+ line: {
23
+ timestamp,
24
+ pod,
25
+ podUid,
26
+ container,
27
+ level,
28
+ message,
29
+ fieldsJson,
30
+ previous
31
+ }
32
+ }), null, 2).slice(0, 6e3);
33
+ }
34
+ function powerLogQueryEvidence(capture, sql, result) {
35
+ const rows = result.rows.slice(0, 30).map((row) => row.map((value, index) => ({
36
+ column: result.columns[index],
37
+ value: sensitive(result.columns[index]) ? "[REDACTED]" : value
38
+ })));
39
+ return JSON.stringify(project({
40
+ observedAt: (/* @__PURE__ */ new Date()).toISOString(),
41
+ capture: {
42
+ target: capture.target,
43
+ createdAt: capture.createdAt,
44
+ state: capture.state,
45
+ notes: capture.notes
46
+ },
47
+ sql,
48
+ rows,
49
+ truncated: result.truncated || result.rows.length > 30
50
+ }), null, 2).slice(0, 6e3);
51
+ }
52
+ //#endregion
53
+ exports.powerLogLineEvidence = powerLogLineEvidence;
54
+ exports.powerLogQueryEvidence = powerLogQueryEvidence;
55
+
56
+ //# sourceMappingURL=power-logs-ai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-logs-ai.js","names":[],"sources":["../../../../src/common/power-logs-ai.ts"],"sourcesContent":["import { redactAiTerminalText } from \"./ai-terminal-context\";\n\nimport type { LogCapture, LogQueryResult, LogRecord, LogTarget } from \"./power-logs\";\n\nconst sensitive = (key: string) =>\n /(?:password|passwd|token|secret|authorization|credential|apikey|privatekey|clientkeydata|clientcertificatedata)/i.test(\n key.replace(/[^a-z0-9]/gi, \"\"),\n );\n\nfunction project(value: unknown, depth = 0): unknown {\n if (depth > 8) return \"[nested content omitted]\";\n if (typeof value === \"string\") {\n try {\n const parsed = JSON.parse(value);\n if (parsed !== null && (typeof parsed === \"object\" || typeof parsed === \"string\"))\n return project(parsed, depth + 1);\n } catch {\n /* plain text uses the shared redactor */\n }\n return redactAiTerminalText(value);\n }\n if (Array.isArray(value)) return value.slice(0, 100).map((item) => project(item, depth + 1));\n if (value && typeof value === \"object\")\n return Object.fromEntries(\n Object.entries(value)\n .slice(0, 100)\n .map(([key, item]) => [key, sensitive(key) ? \"[REDACTED]\" : project(item, depth + 1)]),\n );\n return value;\n}\n\nexport function powerLogLineEvidence(target: LogTarget | undefined, record: LogRecord): string {\n const { timestamp, pod, podUid, container, level, message, fieldsJson, previous } = record;\n return JSON.stringify(\n project({\n observedAt: new Date().toISOString(),\n target,\n line: { timestamp, pod, podUid, container, level, message, fieldsJson, previous },\n }),\n null,\n 2,\n ).slice(0, 6000);\n}\n\nexport function powerLogQueryEvidence(capture: LogCapture, sql: string, result: LogQueryResult): string {\n const rows = result.rows.slice(0, 30).map((row) =>\n row.map((value, index) => ({\n column: result.columns[index],\n value: sensitive(result.columns[index]) ? \"[REDACTED]\" : value,\n })),\n );\n return JSON.stringify(\n project({\n observedAt: new Date().toISOString(),\n capture: { target: capture.target, createdAt: capture.createdAt, state: capture.state, notes: capture.notes },\n sql,\n rows,\n truncated: result.truncated || result.rows.length > 30,\n }),\n null,\n 2,\n ).slice(0, 6000);\n}\n"],"mappings":";;AAIA,IAAM,aAAa,QACjB,mHAAmH,KACjH,IAAI,QAAQ,eAAe,EAAE,CAC/B;AAEF,SAAS,QAAQ,OAAgB,QAAQ,GAAY;CACnD,IAAI,QAAQ,GAAG,OAAO;CACtB,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI;GACF,MAAM,SAAS,KAAK,MAAM,KAAK;GAC/B,IAAI,WAAW,SAAS,OAAO,WAAW,YAAY,OAAO,WAAW,WACtE,OAAO,QAAQ,QAAQ,QAAQ,CAAC;EACpC,QAAQ,CAER;EACA,OAAO,4BAAA,qBAAqB,KAAK;CACnC;CACA,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,SAAS,QAAQ,MAAM,QAAQ,CAAC,CAAC;CAC3F,IAAI,SAAS,OAAO,UAAU,UAC5B,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAClB,MAAM,GAAG,GAAG,CAAC,CACb,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,GAAG,IAAI,eAAe,QAAQ,MAAM,QAAQ,CAAC,CAAC,CAAC,CACzF;CACF,OAAO;AACT;AAEA,SAAgB,qBAAqB,QAA+B,QAA2B;CAC7F,MAAM,EAAE,WAAW,KAAK,QAAQ,WAAW,OAAO,SAAS,YAAY,aAAa;CACpF,OAAO,KAAK,UACV,QAAQ;EACN,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;EACnC;EACA,MAAM;GAAE;GAAW;GAAK;GAAQ;GAAW;GAAO;GAAS;GAAY;EAAS;CAClF,CAAC,GACD,MACA,CACF,CAAC,CAAC,MAAM,GAAG,GAAI;AACjB;AAEA,SAAgB,sBAAsB,SAAqB,KAAa,QAAgC;CACtG,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,QACzC,IAAI,KAAK,OAAO,WAAW;EACzB,QAAQ,OAAO,QAAQ;EACvB,OAAO,UAAU,OAAO,QAAQ,MAAM,IAAI,eAAe;CAC3D,EAAE,CACJ;CACA,OAAO,KAAK,UACV,QAAQ;EACN,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY;EACnC,SAAS;GAAE,QAAQ,QAAQ;GAAQ,WAAW,QAAQ;GAAW,OAAO,QAAQ;GAAO,OAAO,QAAQ;EAAM;EAC5G;EACA;EACA,WAAW,OAAO,aAAa,OAAO,KAAK,SAAS;CACtD,CAAC,GACD,MACA,CACF,CAAC,CAAC,MAAM,GAAG,GAAI;AACjB"}
@@ -0,0 +1,227 @@
1
+ const require_power_logs = require("./power-logs.js");
2
+ //#region src/common/power-logs-limits.ts
3
+ var KiB = 1024;
4
+ var MiB = KiB * KiB;
5
+ var LOG_LIMIT_FIELDS = [
6
+ {
7
+ key: "liveRows",
8
+ label: "Buffered rows",
9
+ unit: "rows",
10
+ group: "Live logs",
11
+ min: 1,
12
+ max: 1e6,
13
+ step: 1e3
14
+ },
15
+ {
16
+ key: "liveBytes",
17
+ label: "Buffer size",
18
+ unit: "MiB",
19
+ group: "Live logs",
20
+ min: KiB,
21
+ max: 1024 * MiB,
22
+ step: MiB,
23
+ scale: MiB
24
+ },
25
+ {
26
+ key: "batchRows",
27
+ label: "Batch rows",
28
+ unit: "rows",
29
+ group: "Live logs",
30
+ min: 1,
31
+ max: 1e5,
32
+ step: 100
33
+ },
34
+ {
35
+ key: "batchBytes",
36
+ label: "Batch size",
37
+ unit: "MiB",
38
+ group: "Live logs",
39
+ min: KiB,
40
+ max: 64 * MiB,
41
+ step: MiB,
42
+ scale: MiB
43
+ },
44
+ {
45
+ key: "recordBytes",
46
+ label: "Record size",
47
+ unit: "KiB",
48
+ group: "Live logs",
49
+ min: KiB,
50
+ max: 16 * MiB,
51
+ step: KiB,
52
+ scale: KiB
53
+ },
54
+ {
55
+ key: "historyLines",
56
+ label: "Lines per source",
57
+ unit: "lines",
58
+ group: "History",
59
+ min: 1,
60
+ max: 1e6,
61
+ step: 1e3
62
+ },
63
+ {
64
+ key: "historyBytes",
65
+ label: "Bytes per source",
66
+ unit: "MiB",
67
+ group: "History",
68
+ min: KiB,
69
+ max: 256 * MiB,
70
+ step: MiB,
71
+ scale: MiB
72
+ },
73
+ {
74
+ key: "historyConcurrency",
75
+ label: "Parallel requests",
76
+ unit: "requests",
77
+ group: "History",
78
+ min: 1,
79
+ max: 32,
80
+ step: 1
81
+ },
82
+ {
83
+ key: "captureBytes",
84
+ label: "Capture size",
85
+ unit: "MiB",
86
+ group: "Captures",
87
+ min: KiB,
88
+ max: 4096 * MiB,
89
+ step: MiB,
90
+ scale: MiB
91
+ },
92
+ {
93
+ key: "captureRows",
94
+ label: "Rows per capture",
95
+ unit: "rows",
96
+ group: "Captures",
97
+ min: 1,
98
+ max: 1e7,
99
+ step: 1e4
100
+ },
101
+ {
102
+ key: "captures",
103
+ label: "Retained captures",
104
+ unit: "captures",
105
+ group: "Captures",
106
+ min: 1,
107
+ max: 100,
108
+ step: 1
109
+ },
110
+ {
111
+ key: "sources",
112
+ label: "Sources per capture",
113
+ unit: "sources",
114
+ group: "Captures",
115
+ min: 1,
116
+ max: 2e3,
117
+ step: 10
118
+ },
119
+ {
120
+ key: "captureSourceLines",
121
+ label: "Lines per source",
122
+ unit: "lines",
123
+ group: "Captures",
124
+ min: 1,
125
+ max: 1e6,
126
+ step: 1e3
127
+ },
128
+ {
129
+ key: "captureSourceBytes",
130
+ label: "Bytes per source",
131
+ unit: "MiB",
132
+ group: "Captures",
133
+ min: KiB,
134
+ max: 256 * MiB,
135
+ step: MiB,
136
+ scale: MiB
137
+ },
138
+ {
139
+ key: "ttlMs",
140
+ label: "Retention",
141
+ unit: "minutes",
142
+ group: "Captures",
143
+ min: 6e4,
144
+ max: 10080 * 6e4,
145
+ step: 6e4,
146
+ scale: 6e4
147
+ },
148
+ {
149
+ key: "resultRows",
150
+ label: "Result rows",
151
+ unit: "rows",
152
+ group: "SQL results",
153
+ min: 1,
154
+ max: 1e5,
155
+ step: 100
156
+ },
157
+ {
158
+ key: "resultBytes",
159
+ label: "Result size",
160
+ unit: "MiB",
161
+ group: "SQL results",
162
+ min: KiB,
163
+ max: 64 * MiB,
164
+ step: MiB,
165
+ scale: MiB
166
+ },
167
+ {
168
+ key: "queryMs",
169
+ label: "Query timeout",
170
+ unit: "seconds",
171
+ group: "SQL results",
172
+ min: 1e3,
173
+ max: 3e5,
174
+ step: 1e3,
175
+ scale: 1e3
176
+ },
177
+ {
178
+ key: "requestsPerSecond",
179
+ label: "Request rate",
180
+ unit: "requests/s",
181
+ group: "Throughput",
182
+ min: 1,
183
+ max: 100,
184
+ step: 1
185
+ },
186
+ {
187
+ key: "bytesPerSecond",
188
+ label: "Data rate",
189
+ unit: "MiB/s",
190
+ group: "Throughput",
191
+ min: KiB,
192
+ max: 256 * MiB,
193
+ step: MiB,
194
+ scale: MiB
195
+ },
196
+ {
197
+ key: "liveConcurrency",
198
+ label: "Parallel streams",
199
+ unit: "streams",
200
+ group: "Throughput",
201
+ min: 1,
202
+ max: 64,
203
+ step: 1
204
+ }
205
+ ];
206
+ function normalizePowerLogsLimits(input) {
207
+ const values = input !== null && typeof input === "object" ? input : {};
208
+ const normalized = { ...require_power_logs.POWER_LOGS_DEFAULT_LIMITS };
209
+ for (const field of LOG_LIMIT_FIELDS) {
210
+ const value = values[field.key];
211
+ if (typeof value === "number" && Number.isFinite(value)) normalized[field.key] = Math.max(field.min, Math.min(field.max, Math.trunc(value)));
212
+ }
213
+ normalized.batchBytes = Math.max(normalized.batchBytes, normalized.recordBytes + 3);
214
+ normalized.captureSourceBytes = Math.max(normalized.captureSourceBytes, normalized.recordBytes);
215
+ return normalized;
216
+ }
217
+ function applyPowerLogsLimits(input) {
218
+ const normalized = normalizePowerLogsLimits(input);
219
+ Object.assign(require_power_logs.POWER_LOGS_LIMITS, normalized);
220
+ return normalized;
221
+ }
222
+ //#endregion
223
+ exports.LOG_LIMIT_FIELDS = LOG_LIMIT_FIELDS;
224
+ exports.applyPowerLogsLimits = applyPowerLogsLimits;
225
+ exports.normalizePowerLogsLimits = normalizePowerLogsLimits;
226
+
227
+ //# sourceMappingURL=power-logs-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-logs-limits.js","names":[],"sources":["../../../../src/common/power-logs-limits.ts"],"sourcesContent":["import {\n POWER_LOGS_DEFAULT_LIMITS,\n POWER_LOGS_LIMITS,\n type PowerLogsLimitKey,\n type PowerLogsLimits,\n} from \"./power-logs\";\n\nexport interface LogLimitField {\n key: PowerLogsLimitKey;\n label: string;\n unit: string;\n group: \"Live logs\" | \"History\" | \"Captures\" | \"SQL results\" | \"Throughput\";\n min: number;\n max: number;\n step: number;\n scale?: number;\n}\n\nconst KiB = 1024;\nconst MiB = KiB * KiB;\n\nexport const LOG_LIMIT_FIELDS: readonly LogLimitField[] = [\n { key: \"liveRows\", label: \"Buffered rows\", unit: \"rows\", group: \"Live logs\", min: 1, max: 1000000, step: 1000 },\n {\n key: \"liveBytes\",\n label: \"Buffer size\",\n unit: \"MiB\",\n group: \"Live logs\",\n min: KiB,\n max: 1024 * MiB,\n step: MiB,\n scale: MiB,\n },\n { key: \"batchRows\", label: \"Batch rows\", unit: \"rows\", group: \"Live logs\", min: 1, max: 100000, step: 100 },\n {\n key: \"batchBytes\",\n label: \"Batch size\",\n unit: \"MiB\",\n group: \"Live logs\",\n min: KiB,\n max: 64 * MiB,\n step: MiB,\n scale: MiB,\n },\n {\n key: \"recordBytes\",\n label: \"Record size\",\n unit: \"KiB\",\n group: \"Live logs\",\n min: KiB,\n max: 16 * MiB,\n step: KiB,\n scale: KiB,\n },\n { key: \"historyLines\", label: \"Lines per source\", unit: \"lines\", group: \"History\", min: 1, max: 1000000, step: 1000 },\n {\n key: \"historyBytes\",\n label: \"Bytes per source\",\n unit: \"MiB\",\n group: \"History\",\n min: KiB,\n max: 256 * MiB,\n step: MiB,\n scale: MiB,\n },\n {\n key: \"historyConcurrency\",\n label: \"Parallel requests\",\n unit: \"requests\",\n group: \"History\",\n min: 1,\n max: 32,\n step: 1,\n },\n {\n key: \"captureBytes\",\n label: \"Capture size\",\n unit: \"MiB\",\n group: \"Captures\",\n min: KiB,\n max: 4096 * MiB,\n step: MiB,\n scale: MiB,\n },\n {\n key: \"captureRows\",\n label: \"Rows per capture\",\n unit: \"rows\",\n group: \"Captures\",\n min: 1,\n max: 10000000,\n step: 10000,\n },\n { key: \"captures\", label: \"Retained captures\", unit: \"captures\", group: \"Captures\", min: 1, max: 100, step: 1 },\n { key: \"sources\", label: \"Sources per capture\", unit: \"sources\", group: \"Captures\", min: 1, max: 2000, step: 10 },\n {\n key: \"captureSourceLines\",\n label: \"Lines per source\",\n unit: \"lines\",\n group: \"Captures\",\n min: 1,\n max: 1000000,\n step: 1000,\n },\n {\n key: \"captureSourceBytes\",\n label: \"Bytes per source\",\n unit: \"MiB\",\n group: \"Captures\",\n min: KiB,\n max: 256 * MiB,\n step: MiB,\n scale: MiB,\n },\n {\n key: \"ttlMs\",\n label: \"Retention\",\n unit: \"minutes\",\n group: \"Captures\",\n min: 60000,\n max: 7 * 24 * 60 * 60000,\n step: 60000,\n scale: 60000,\n },\n { key: \"resultRows\", label: \"Result rows\", unit: \"rows\", group: \"SQL results\", min: 1, max: 100000, step: 100 },\n {\n key: \"resultBytes\",\n label: \"Result size\",\n unit: \"MiB\",\n group: \"SQL results\",\n min: KiB,\n max: 64 * MiB,\n step: MiB,\n scale: MiB,\n },\n {\n key: \"queryMs\",\n label: \"Query timeout\",\n unit: \"seconds\",\n group: \"SQL results\",\n min: 1000,\n max: 300000,\n step: 1000,\n scale: 1000,\n },\n {\n key: \"requestsPerSecond\",\n label: \"Request rate\",\n unit: \"requests/s\",\n group: \"Throughput\",\n min: 1,\n max: 100,\n step: 1,\n },\n {\n key: \"bytesPerSecond\",\n label: \"Data rate\",\n unit: \"MiB/s\",\n group: \"Throughput\",\n min: KiB,\n max: 256 * MiB,\n step: MiB,\n scale: MiB,\n },\n { key: \"liveConcurrency\", label: \"Parallel streams\", unit: \"streams\", group: \"Throughput\", min: 1, max: 64, step: 1 },\n];\n\nexport function normalizePowerLogsLimits(input: unknown): PowerLogsLimits {\n const values = input !== null && typeof input === \"object\" ? (input as Record<string, unknown>) : {};\n const normalized: PowerLogsLimits = { ...POWER_LOGS_DEFAULT_LIMITS };\n for (const field of LOG_LIMIT_FIELDS) {\n const value = values[field.key];\n if (typeof value === \"number\" && Number.isFinite(value)) {\n normalized[field.key] = Math.max(field.min, Math.min(field.max, Math.trunc(value)));\n }\n }\n normalized.batchBytes = Math.max(normalized.batchBytes, normalized.recordBytes + 3);\n normalized.captureSourceBytes = Math.max(normalized.captureSourceBytes, normalized.recordBytes);\n return normalized;\n}\n\nexport function applyPowerLogsLimits(input: unknown): PowerLogsLimits {\n const normalized = normalizePowerLogsLimits(input);\n Object.assign(POWER_LOGS_LIMITS, normalized);\n return normalized;\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ //#region src/common/power-logs.ts
2
+ var POWER_LOGS_CHANNEL = "freelens-power:logs";
3
+ var POWER_LOGS_DEFAULT_LIMITS = {
4
+ liveRows: 1e4,
5
+ liveBytes: 16 * 1024 * 1024,
6
+ batchRows: 1e3,
7
+ batchBytes: 2 * 1024 * 1024,
8
+ recordBytes: 64 * 1024,
9
+ captureBytes: 256 * 1024 * 1024,
10
+ captureRows: 1e6,
11
+ captures: 3,
12
+ sources: 200,
13
+ resultRows: 1e3,
14
+ resultBytes: 2 * 1024 * 1024,
15
+ queryMs: 15e3,
16
+ ttlMs: 3600 * 1e3,
17
+ historyLines: 1e3,
18
+ historyBytes: 1024 * 1024,
19
+ captureSourceLines: 1e4,
20
+ captureSourceBytes: 8 * 1024 * 1024,
21
+ requestsPerSecond: 2,
22
+ bytesPerSecond: 1024 * 1024,
23
+ historyConcurrency: 2,
24
+ liveConcurrency: 4
25
+ };
26
+ var POWER_LOGS_LIMITS = { ...POWER_LOGS_DEFAULT_LIMITS };
27
+ //#endregion
28
+ exports.POWER_LOGS_CHANNEL = POWER_LOGS_CHANNEL;
29
+ exports.POWER_LOGS_DEFAULT_LIMITS = POWER_LOGS_DEFAULT_LIMITS;
30
+ exports.POWER_LOGS_LIMITS = POWER_LOGS_LIMITS;
31
+
32
+ //# sourceMappingURL=power-logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-logs.js","names":[],"sources":["../../../../src/common/power-logs.ts"],"sourcesContent":["export const POWER_LOGS_CHANNEL = \"freelens-power:logs\";\nexport const POWER_LOGS_DEFAULT_LIMITS = {\n liveRows: 10000,\n liveBytes: 16 * 1024 * 1024,\n batchRows: 1000,\n batchBytes: 2 * 1024 * 1024,\n recordBytes: 64 * 1024,\n captureBytes: 256 * 1024 * 1024,\n captureRows: 1000000,\n captures: 3,\n sources: 200,\n resultRows: 1000,\n resultBytes: 2 * 1024 * 1024,\n queryMs: 15000,\n ttlMs: 60 * 60 * 1000,\n historyLines: 1000,\n historyBytes: 1024 * 1024,\n captureSourceLines: 10000,\n captureSourceBytes: 8 * 1024 * 1024,\n requestsPerSecond: 2,\n bytesPerSecond: 1024 * 1024,\n historyConcurrency: 2,\n liveConcurrency: 4,\n} as const;\n\nexport type PowerLogsLimitKey = keyof typeof POWER_LOGS_DEFAULT_LIMITS;\nexport type PowerLogsLimits = { [Key in PowerLogsLimitKey]: number };\nexport const POWER_LOGS_LIMITS: PowerLogsLimits = { ...POWER_LOGS_DEFAULT_LIMITS };\n\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\" | \"unknown\";\nexport type LogWorkloadKind = \"Pod\" | \"Deployment\" | \"DaemonSet\" | \"StatefulSet\" | \"ReplicaSet\" | \"Job\" | \"CronJob\";\nexport interface LogTarget {\n kind: LogWorkloadKind;\n namespace: string;\n name: string;\n uid: string;\n}\nexport interface LogSource {\n namespace: string;\n pod: string;\n podUid: string;\n container: string;\n previous?: boolean;\n}\nexport interface LogRecord {\n timestamp: number | null;\n pod: string;\n podUid: string;\n container: string;\n level: LogLevel;\n message: string;\n fieldsJson: string | null;\n previous?: boolean;\n}\nexport interface LogCapture {\n id: string;\n target: LogTarget;\n createdAt: number;\n expiresAt: number;\n state: \"collecting\" | \"ready\" | \"partial\";\n rows: number;\n bytes: number;\n notes: string[];\n}\nexport type LogCell = string | number | boolean | null;\nexport interface LogQueryResult {\n error?: string;\n columns: string[];\n rows: LogCell[][];\n truncated: boolean;\n elapsedMs: number;\n}\nexport interface LogPartition {\n clusterId: string;\n contextId: string;\n}\nexport type LogRequest = LogPartition &\n (\n | { operation: \"permit\"; lane: \"start\" | \"bytes\"; bytes?: number }\n | { operation: \"stream-open\"; streamId: string; follow: boolean }\n | { operation: \"stream-close\" | \"stream-renew\"; streamId: string }\n | { operation: \"create\"; target: LogTarget }\n | { operation: \"append\"; captureId: string; records: LogRecord[] }\n | { operation: \"finish\"; captureId: string; partial: boolean; notes: string[] }\n | { operation: \"list\" }\n | { operation: \"delete\"; captureId: string }\n | { operation: \"query\"; captureId: string; queryId: string; sql: string }\n | { operation: \"cancel\"; queryId: string }\n | { operation: \"export\"; captureId: string }\n );\n"],"mappings":";AAAA,IAAa,qBAAqB;AAClC,IAAa,4BAA4B;CACvC,UAAU;CACV,WAAW,KAAK,OAAO;CACvB,WAAW;CACX,YAAY,IAAI,OAAO;CACvB,aAAa,KAAK;CAClB,cAAc,MAAM,OAAO;CAC3B,aAAa;CACb,UAAU;CACV,SAAS;CACT,YAAY;CACZ,aAAa,IAAI,OAAO;CACxB,SAAS;CACT,OAAO,OAAU;CACjB,cAAc;CACd,cAAc,OAAO;CACrB,oBAAoB;CACpB,oBAAoB,IAAI,OAAO;CAC/B,mBAAmB;CACnB,gBAAgB,OAAO;CACvB,oBAAoB;CACpB,iBAAiB;AACnB;AAIA,IAAa,oBAAqC,EAAE,GAAG,0BAA0B"}