@techwavedev/agi-agent-kit 1.1.7 → 1.2.1

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.

Potentially problematic release.


This version of @techwavedev/agi-agent-kit might be problematic. Click here for more details.

Files changed (111) hide show
  1. package/CHANGELOG.md +82 -1
  2. package/README.md +190 -12
  3. package/bin/init.js +30 -2
  4. package/package.json +6 -3
  5. package/templates/base/AGENTS.md +54 -23
  6. package/templates/base/README.md +325 -0
  7. package/templates/base/directives/memory_integration.md +95 -0
  8. package/templates/base/execution/memory_manager.py +309 -0
  9. package/templates/base/execution/session_boot.py +218 -0
  10. package/templates/base/execution/session_init.py +320 -0
  11. package/templates/base/skill-creator/SKILL_skillcreator.md +23 -36
  12. package/templates/base/skill-creator/scripts/init_skill.py +18 -135
  13. package/templates/skills/ec/README.md +31 -0
  14. package/templates/skills/ec/aws/SKILL.md +1020 -0
  15. package/templates/skills/ec/aws/defaults.yaml +13 -0
  16. package/templates/skills/ec/aws/references/common_patterns.md +80 -0
  17. package/templates/skills/ec/aws/references/mcp_servers.md +98 -0
  18. package/templates/skills/ec/aws-terraform/SKILL.md +349 -0
  19. package/templates/skills/ec/aws-terraform/references/best_practices.md +394 -0
  20. package/templates/skills/ec/aws-terraform/references/checkov_reference.md +337 -0
  21. package/templates/skills/ec/aws-terraform/scripts/configure_mcp.py +150 -0
  22. package/templates/skills/ec/confluent-kafka/SKILL.md +655 -0
  23. package/templates/skills/ec/confluent-kafka/references/ansible_playbooks.md +792 -0
  24. package/templates/skills/ec/confluent-kafka/references/ec_deployment.md +579 -0
  25. package/templates/skills/ec/confluent-kafka/references/kraft_migration.md +490 -0
  26. package/templates/skills/ec/confluent-kafka/references/troubleshooting.md +778 -0
  27. package/templates/skills/ec/confluent-kafka/references/upgrade_7x_to_8x.md +488 -0
  28. package/templates/skills/ec/confluent-kafka/scripts/kafka_health_check.py +435 -0
  29. package/templates/skills/ec/confluent-kafka/scripts/upgrade_preflight.py +568 -0
  30. package/templates/skills/ec/confluent-kafka/scripts/validate_config.py +455 -0
  31. package/templates/skills/ec/consul/SKILL.md +427 -0
  32. package/templates/skills/ec/consul/references/acl_setup.md +168 -0
  33. package/templates/skills/ec/consul/references/ha_config.md +196 -0
  34. package/templates/skills/ec/consul/references/troubleshooting.md +267 -0
  35. package/templates/skills/ec/consul/references/upgrades.md +213 -0
  36. package/templates/skills/ec/consul/scripts/consul_health_report.py +530 -0
  37. package/templates/skills/ec/consul/scripts/consul_status.py +264 -0
  38. package/templates/skills/ec/consul/scripts/generate_values.py +170 -0
  39. package/templates/skills/ec/documentation/SKILL.md +351 -0
  40. package/templates/skills/ec/documentation/references/best_practices.md +201 -0
  41. package/templates/skills/ec/documentation/scripts/analyze_code.py +307 -0
  42. package/templates/skills/ec/documentation/scripts/detect_changes.py +460 -0
  43. package/templates/skills/ec/documentation/scripts/generate_changelog.py +312 -0
  44. package/templates/skills/ec/documentation/scripts/sync_docs.py +272 -0
  45. package/templates/skills/ec/documentation/scripts/update_skill_docs.py +366 -0
  46. package/templates/skills/ec/gitlab/SKILL.md +529 -0
  47. package/templates/skills/ec/gitlab/references/agent_installation.md +416 -0
  48. package/templates/skills/ec/gitlab/references/api_reference.md +508 -0
  49. package/templates/skills/ec/gitlab/references/gitops_flux.md +465 -0
  50. package/templates/skills/ec/gitlab/references/troubleshooting.md +518 -0
  51. package/templates/skills/ec/gitlab/scripts/generate_agent_values.py +329 -0
  52. package/templates/skills/ec/gitlab/scripts/gitlab_agent_status.py +414 -0
  53. package/templates/skills/ec/jira/SKILL.md +484 -0
  54. package/templates/skills/ec/jira/references/jql_reference.md +148 -0
  55. package/templates/skills/ec/jira/scripts/add_comment.py +91 -0
  56. package/templates/skills/ec/jira/scripts/bulk_log_work.py +124 -0
  57. package/templates/skills/ec/jira/scripts/create_ticket.py +162 -0
  58. package/templates/skills/ec/jira/scripts/get_ticket.py +191 -0
  59. package/templates/skills/ec/jira/scripts/jira_client.py +383 -0
  60. package/templates/skills/ec/jira/scripts/log_work.py +154 -0
  61. package/templates/skills/ec/jira/scripts/search_tickets.py +104 -0
  62. package/templates/skills/ec/jira/scripts/update_comment.py +67 -0
  63. package/templates/skills/ec/jira/scripts/update_ticket.py +161 -0
  64. package/templates/skills/ec/karpenter/SKILL.md +301 -0
  65. package/templates/skills/ec/karpenter/references/ec2nodeclasses.md +421 -0
  66. package/templates/skills/ec/karpenter/references/migration.md +396 -0
  67. package/templates/skills/ec/karpenter/references/nodepools.md +400 -0
  68. package/templates/skills/ec/karpenter/references/troubleshooting.md +359 -0
  69. package/templates/skills/ec/karpenter/scripts/generate_ec2nodeclass.py +187 -0
  70. package/templates/skills/ec/karpenter/scripts/generate_nodepool.py +245 -0
  71. package/templates/skills/ec/karpenter/scripts/karpenter_status.py +359 -0
  72. package/templates/skills/ec/opensearch/SKILL.md +720 -0
  73. package/templates/skills/ec/opensearch/references/ml_neural_search.md +576 -0
  74. package/templates/skills/ec/opensearch/references/operator.md +532 -0
  75. package/templates/skills/ec/opensearch/references/query_dsl.md +532 -0
  76. package/templates/skills/ec/opensearch/scripts/configure_mcp.py +148 -0
  77. package/templates/skills/ec/victoriametrics/SKILL.md +598 -0
  78. package/templates/skills/ec/victoriametrics/references/kubernetes.md +531 -0
  79. package/templates/skills/ec/victoriametrics/references/prometheus_migration.md +333 -0
  80. package/templates/skills/ec/victoriametrics/references/troubleshooting.md +442 -0
  81. package/templates/skills/knowledge/SKILLS_CATALOG.md +274 -4
  82. package/templates/skills/knowledge/intelligent-routing/SKILL.md +237 -164
  83. package/templates/skills/knowledge/parallel-agents/SKILL.md +345 -73
  84. package/templates/skills/knowledge/plugin-discovery/SKILL.md +582 -0
  85. package/templates/skills/knowledge/plugin-discovery/scripts/platform_setup.py +1083 -0
  86. package/templates/skills/knowledge/design-md/README.md +0 -34
  87. package/templates/skills/knowledge/design-md/SKILL.md +0 -193
  88. package/templates/skills/knowledge/design-md/examples/DESIGN.md +0 -154
  89. package/templates/skills/knowledge/notebooklm-mcp/SKILL.md +0 -71
  90. package/templates/skills/knowledge/notebooklm-mcp/assets/example_asset.txt +0 -24
  91. package/templates/skills/knowledge/notebooklm-mcp/references/api_reference.md +0 -34
  92. package/templates/skills/knowledge/notebooklm-mcp/scripts/example.py +0 -19
  93. package/templates/skills/knowledge/react-components/README.md +0 -36
  94. package/templates/skills/knowledge/react-components/SKILL.md +0 -53
  95. package/templates/skills/knowledge/react-components/examples/gold-standard-card.tsx +0 -80
  96. package/templates/skills/knowledge/react-components/package-lock.json +0 -231
  97. package/templates/skills/knowledge/react-components/package.json +0 -16
  98. package/templates/skills/knowledge/react-components/resources/architecture-checklist.md +0 -15
  99. package/templates/skills/knowledge/react-components/resources/component-template.tsx +0 -37
  100. package/templates/skills/knowledge/react-components/resources/stitch-api-reference.md +0 -14
  101. package/templates/skills/knowledge/react-components/resources/style-guide.json +0 -27
  102. package/templates/skills/knowledge/react-components/scripts/fetch-stitch.sh +0 -30
  103. package/templates/skills/knowledge/react-components/scripts/validate.js +0 -68
  104. package/templates/skills/knowledge/self-update/SKILL.md +0 -60
  105. package/templates/skills/knowledge/self-update/scripts/update_kit.py +0 -103
  106. package/templates/skills/knowledge/stitch-loop/README.md +0 -54
  107. package/templates/skills/knowledge/stitch-loop/SKILL.md +0 -235
  108. package/templates/skills/knowledge/stitch-loop/examples/SITE.md +0 -73
  109. package/templates/skills/knowledge/stitch-loop/examples/next-prompt.md +0 -25
  110. package/templates/skills/knowledge/stitch-loop/resources/baton-schema.md +0 -61
  111. package/templates/skills/knowledge/stitch-loop/resources/site-template.md +0 -104
@@ -0,0 +1,414 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script: gitlab_agent_status.py
4
+ Purpose: Check GitLab agent health and generate status report
5
+
6
+ Usage:
7
+ python gitlab_agent_status.py --namespace gitlab-agent \
8
+ --gitlab-url https://gitlab.example.com \
9
+ --project-id 123 \
10
+ --output reports/gitlab/
11
+
12
+ Arguments:
13
+ --namespace, -n Kubernetes namespace (default: gitlab-agent)
14
+ --gitlab-url GitLab instance URL (or GITLAB_HOST env var)
15
+ --project-id GitLab project ID (or PROJECT_ID env var)
16
+ --agent-id Specific agent ID (optional, checks all if omitted)
17
+ --output, -o Output directory for reports (default: current)
18
+ --format, -f Output format: json, markdown, or both (default: both)
19
+
20
+ Exit Codes:
21
+ 0 - Success, all agents healthy
22
+ 1 - Invalid arguments
23
+ 2 - Connection error
24
+ 3 - Unhealthy agents detected
25
+ 4 - Processing error
26
+
27
+ Environment Variables:
28
+ GITLAB_HOST - GitLab hostname
29
+ GITLAB_TOKEN - GitLab personal/project access token
30
+ PROJECT_ID - Default project ID
31
+ KUBECONFIG - Kubernetes config path
32
+ """
33
+
34
+ import argparse
35
+ import json
36
+ import os
37
+ import subprocess
38
+ import sys
39
+ from datetime import datetime
40
+ from pathlib import Path
41
+
42
+
43
+ def run_kubectl(args: list) -> tuple:
44
+ """Run kubectl command and return (success, output)"""
45
+ try:
46
+ result = subprocess.run(
47
+ ["kubectl"] + args,
48
+ capture_output=True,
49
+ text=True,
50
+ timeout=30
51
+ )
52
+ return result.returncode == 0, result.stdout.strip()
53
+ except subprocess.TimeoutExpired:
54
+ return False, "Command timed out"
55
+ except FileNotFoundError:
56
+ return False, "kubectl not found"
57
+
58
+
59
+ def get_agent_pods(namespace: str) -> dict:
60
+ """Get agent pod status from Kubernetes"""
61
+ success, output = run_kubectl([
62
+ "get", "pods", "-n", namespace,
63
+ "-l", "app.kubernetes.io/name=gitlab-agent",
64
+ "-o", "json"
65
+ ])
66
+
67
+ if not success:
68
+ return {"error": output, "pods": []}
69
+
70
+ try:
71
+ data = json.loads(output)
72
+ pods = []
73
+ for item in data.get("items", []):
74
+ pod = {
75
+ "name": item["metadata"]["name"],
76
+ "status": item["status"]["phase"],
77
+ "ready": all(
78
+ c.get("ready", False)
79
+ for c in item["status"].get("containerStatuses", [])
80
+ ),
81
+ "restarts": sum(
82
+ c.get("restartCount", 0)
83
+ for c in item["status"].get("containerStatuses", [])
84
+ ),
85
+ "node": item["spec"].get("nodeName", "unknown"),
86
+ "image": item["spec"]["containers"][0]["image"] if item["spec"].get("containers") else "unknown"
87
+ }
88
+ pods.append(pod)
89
+ return {"error": None, "pods": pods}
90
+ except json.JSONDecodeError as e:
91
+ return {"error": f"JSON parse error: {e}", "pods": []}
92
+
93
+
94
+ def get_agent_logs(namespace: str, lines: int = 50) -> str:
95
+ """Get recent agent logs"""
96
+ success, output = run_kubectl([
97
+ "logs", "-n", namespace,
98
+ "-l", "app.kubernetes.io/name=gitlab-agent",
99
+ "--tail", str(lines)
100
+ ])
101
+ return output if success else f"Error getting logs: {output}"
102
+
103
+
104
+ def get_helm_status(namespace: str) -> dict:
105
+ """Get Helm release status"""
106
+ try:
107
+ result = subprocess.run(
108
+ ["helm", "list", "-n", namespace, "-o", "json"],
109
+ capture_output=True,
110
+ text=True,
111
+ timeout=30
112
+ )
113
+ if result.returncode != 0:
114
+ return {"error": result.stderr, "releases": []}
115
+
116
+ releases = json.loads(result.stdout)
117
+ return {"error": None, "releases": releases}
118
+ except Exception as e:
119
+ return {"error": str(e), "releases": []}
120
+
121
+
122
+ def get_gitlab_agents(gitlab_url: str, token: str, project_id: str) -> dict:
123
+ """Get agents from GitLab API"""
124
+ import urllib.request
125
+ import ssl
126
+
127
+ url = f"{gitlab_url}/api/v4/projects/{project_id}/cluster_agents"
128
+
129
+ # Create request with token
130
+ req = urllib.request.Request(url)
131
+ req.add_header("PRIVATE-TOKEN", token)
132
+
133
+ # Allow self-signed certs (common in on-prem)
134
+ ctx = ssl.create_default_context()
135
+ ctx.check_hostname = False
136
+ ctx.verify_mode = ssl.CERT_NONE
137
+
138
+ try:
139
+ with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
140
+ data = json.loads(response.read().decode())
141
+ return {"error": None, "agents": data}
142
+ except urllib.error.HTTPError as e:
143
+ return {"error": f"HTTP {e.code}: {e.reason}", "agents": []}
144
+ except urllib.error.URLError as e:
145
+ return {"error": f"Connection error: {e.reason}", "agents": []}
146
+ except Exception as e:
147
+ return {"error": str(e), "agents": []}
148
+
149
+
150
+ def get_agent_tokens(gitlab_url: str, token: str, project_id: str, agent_id: int) -> dict:
151
+ """Get tokens for an agent from GitLab API"""
152
+ import urllib.request
153
+ import ssl
154
+
155
+ url = f"{gitlab_url}/api/v4/projects/{project_id}/cluster_agents/{agent_id}/tokens"
156
+
157
+ req = urllib.request.Request(url)
158
+ req.add_header("PRIVATE-TOKEN", token)
159
+
160
+ ctx = ssl.create_default_context()
161
+ ctx.check_hostname = False
162
+ ctx.verify_mode = ssl.CERT_NONE
163
+
164
+ try:
165
+ with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
166
+ data = json.loads(response.read().decode())
167
+ return {"error": None, "tokens": data}
168
+ except Exception as e:
169
+ return {"error": str(e), "tokens": []}
170
+
171
+
172
+ def generate_report(data: dict, output_format: str, output_dir: str):
173
+ """Generate status report in requested format(s)"""
174
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
175
+ output_path = Path(output_dir)
176
+ output_path.mkdir(parents=True, exist_ok=True)
177
+
178
+ if output_format in ("json", "both"):
179
+ json_file = output_path / f"gitlab_agent_status_{timestamp}.json"
180
+ with open(json_file, "w") as f:
181
+ json.dump(data, f, indent=2, default=str)
182
+ print(f"JSON report: {json_file}")
183
+
184
+ if output_format in ("markdown", "both"):
185
+ md_file = output_path / f"gitlab_agent_status_{timestamp}.md"
186
+ md_content = generate_markdown(data)
187
+ with open(md_file, "w") as f:
188
+ f.write(md_content)
189
+ print(f"Markdown report: {md_file}")
190
+
191
+
192
+ def generate_markdown(data: dict) -> str:
193
+ """Generate markdown report from data"""
194
+ lines = [
195
+ f"# GitLab Agent Status Report",
196
+ f"",
197
+ f"**Generated:** {data['timestamp']}",
198
+ f"**Environment:** {data['environment']}",
199
+ f"",
200
+ ]
201
+
202
+ # Summary
203
+ healthy = data.get("healthy", False)
204
+ status_emoji = "✅" if healthy else "❌"
205
+ lines.append(f"## Summary: {status_emoji} {'Healthy' if healthy else 'Issues Detected'}")
206
+ lines.append("")
207
+
208
+ # Kubernetes Status
209
+ lines.append("## Kubernetes Status")
210
+ lines.append("")
211
+ k8s = data.get("kubernetes", {})
212
+ pods = k8s.get("pods", {}).get("pods", [])
213
+
214
+ if pods:
215
+ lines.append("| Pod | Status | Ready | Restarts | Node |")
216
+ lines.append("|-----|--------|-------|----------|------|")
217
+ for pod in pods:
218
+ ready = "✅" if pod["ready"] else "❌"
219
+ lines.append(f"| {pod['name']} | {pod['status']} | {ready} | {pod['restarts']} | {pod['node']} |")
220
+ else:
221
+ lines.append("No agent pods found.")
222
+ lines.append("")
223
+
224
+ # Helm Status
225
+ helm = k8s.get("helm", {}).get("releases", [])
226
+ if helm:
227
+ lines.append("### Helm Release")
228
+ lines.append("")
229
+ for release in helm:
230
+ lines.append(f"- **Name:** {release.get('name')}")
231
+ lines.append(f"- **Chart:** {release.get('chart')}")
232
+ lines.append(f"- **Status:** {release.get('status')}")
233
+ lines.append(f"- **Revision:** {release.get('revision')}")
234
+ lines.append("")
235
+
236
+ # GitLab API Status
237
+ lines.append("## GitLab API Status")
238
+ lines.append("")
239
+ gitlab = data.get("gitlab", {})
240
+ agents = gitlab.get("agents", {}).get("agents", [])
241
+
242
+ if agents:
243
+ lines.append("### Registered Agents")
244
+ lines.append("")
245
+ lines.append("| ID | Name | Created |")
246
+ lines.append("|----|------|---------|")
247
+ for agent in agents:
248
+ lines.append(f"| {agent['id']} | {agent['name']} | {agent.get('created_at', 'N/A')} |")
249
+ lines.append("")
250
+
251
+ # Tokens
252
+ tokens = gitlab.get("tokens", [])
253
+ if tokens:
254
+ lines.append("### Agent Tokens")
255
+ lines.append("")
256
+ lines.append("| Agent | Token ID | Name | Status | Created |")
257
+ lines.append("|-------|----------|------|--------|---------|")
258
+ for token_info in tokens:
259
+ for token in token_info.get("tokens", []):
260
+ lines.append(f"| {token_info['agent_id']} | {token['id']} | {token['name']} | {token['status']} | {token.get('created_at', 'N/A')} |")
261
+ else:
262
+ api_error = gitlab.get("agents", {}).get("error")
263
+ if api_error:
264
+ lines.append(f"**Error:** {api_error}")
265
+ else:
266
+ lines.append("No agents found.")
267
+ lines.append("")
268
+
269
+ # Issues
270
+ issues = data.get("issues", [])
271
+ if issues:
272
+ lines.append("## Issues Detected")
273
+ lines.append("")
274
+ for issue in issues:
275
+ lines.append(f"- ⚠️ {issue}")
276
+ lines.append("")
277
+
278
+ # Recent Logs
279
+ lines.append("## Recent Logs")
280
+ lines.append("")
281
+ lines.append("```")
282
+ logs = data.get("kubernetes", {}).get("logs", "No logs available")
283
+ lines.append(logs[-3000:] if len(logs) > 3000 else logs) # Limit log size
284
+ lines.append("```")
285
+
286
+ return "\n".join(lines)
287
+
288
+
289
+ def main():
290
+ parser = argparse.ArgumentParser(
291
+ description="Check GitLab agent health and generate status report",
292
+ formatter_class=argparse.RawDescriptionHelpFormatter,
293
+ epilog=__doc__
294
+ )
295
+ parser.add_argument(
296
+ "--namespace", "-n",
297
+ default="gitlab-agent",
298
+ help="Kubernetes namespace (default: gitlab-agent)"
299
+ )
300
+ parser.add_argument(
301
+ "--gitlab-url",
302
+ default=os.environ.get("GITLAB_HOST", ""),
303
+ help="GitLab instance URL"
304
+ )
305
+ parser.add_argument(
306
+ "--project-id",
307
+ default=os.environ.get("PROJECT_ID", ""),
308
+ help="GitLab project ID"
309
+ )
310
+ parser.add_argument(
311
+ "--agent-id",
312
+ help="Specific agent ID (optional)"
313
+ )
314
+ parser.add_argument(
315
+ "--output", "-o",
316
+ default=".",
317
+ help="Output directory (default: current)"
318
+ )
319
+ parser.add_argument(
320
+ "--format", "-f",
321
+ choices=["json", "markdown", "both"],
322
+ default="both",
323
+ help="Output format (default: both)"
324
+ )
325
+
326
+ args = parser.parse_args()
327
+
328
+ # Get GitLab token from environment
329
+ gitlab_token = os.environ.get("GITLAB_TOKEN", "")
330
+
331
+ # Normalize GitLab URL
332
+ gitlab_url = args.gitlab_url
333
+ if gitlab_url and not gitlab_url.startswith("http"):
334
+ gitlab_url = f"https://{gitlab_url}"
335
+
336
+ # Collect data
337
+ data = {
338
+ "timestamp": datetime.now().isoformat(),
339
+ "environment": {
340
+ "namespace": args.namespace,
341
+ "gitlab_url": gitlab_url,
342
+ "project_id": args.project_id
343
+ },
344
+ "kubernetes": {},
345
+ "gitlab": {},
346
+ "issues": [],
347
+ "healthy": True
348
+ }
349
+
350
+ print(f"Checking GitLab agent status in namespace: {args.namespace}")
351
+
352
+ # Kubernetes checks
353
+ print(" - Checking pods...")
354
+ data["kubernetes"]["pods"] = get_agent_pods(args.namespace)
355
+
356
+ print(" - Checking Helm release...")
357
+ data["kubernetes"]["helm"] = get_helm_status(args.namespace)
358
+
359
+ print(" - Getting recent logs...")
360
+ data["kubernetes"]["logs"] = get_agent_logs(args.namespace)
361
+
362
+ # GitLab API checks (if configured)
363
+ if gitlab_url and gitlab_token and args.project_id:
364
+ print(f" - Checking GitLab API ({gitlab_url})...")
365
+ data["gitlab"]["agents"] = get_gitlab_agents(gitlab_url, gitlab_token, args.project_id)
366
+
367
+ # Get tokens for each agent
368
+ agents = data["gitlab"]["agents"].get("agents", [])
369
+ data["gitlab"]["tokens"] = []
370
+ for agent in agents:
371
+ token_data = get_agent_tokens(gitlab_url, gitlab_token, args.project_id, agent["id"])
372
+ token_data["agent_id"] = agent["id"]
373
+ data["gitlab"]["tokens"].append(token_data)
374
+ else:
375
+ print(" - Skipping GitLab API (missing URL, token, or project ID)")
376
+
377
+ # Analyze for issues
378
+ pods = data["kubernetes"]["pods"].get("pods", [])
379
+ if not pods:
380
+ data["issues"].append("No agent pods found in namespace")
381
+ data["healthy"] = False
382
+ else:
383
+ for pod in pods:
384
+ if pod["status"] != "Running":
385
+ data["issues"].append(f"Pod {pod['name']} is {pod['status']}")
386
+ data["healthy"] = False
387
+ if not pod["ready"]:
388
+ data["issues"].append(f"Pod {pod['name']} is not ready")
389
+ data["healthy"] = False
390
+ if pod["restarts"] > 5:
391
+ data["issues"].append(f"Pod {pod['name']} has {pod['restarts']} restarts")
392
+
393
+ # Check for errors in logs
394
+ logs = data["kubernetes"].get("logs", "")
395
+ if '"level":"error"' in logs or '"level":"warn"' in logs:
396
+ data["issues"].append("Errors or warnings found in agent logs")
397
+
398
+ # Generate report
399
+ generate_report(data, args.format, args.output)
400
+
401
+ # Print summary
402
+ print("")
403
+ if data["healthy"]:
404
+ print("✅ All agents healthy")
405
+ sys.exit(0)
406
+ else:
407
+ print("❌ Issues detected:")
408
+ for issue in data["issues"]:
409
+ print(f" - {issue}")
410
+ sys.exit(3)
411
+
412
+
413
+ if __name__ == "__main__":
414
+ main()