@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,264 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script: consul_status.py
4
+ Purpose: Get comprehensive status of Consul cluster on Kubernetes
5
+
6
+ Usage:
7
+ python consul_status.py --namespace consul [--context <context>]
8
+
9
+ Arguments:
10
+ --namespace Kubernetes namespace where Consul is installed (default: consul)
11
+ --context Kubernetes context to use (optional)
12
+ --json Output in JSON format
13
+
14
+ Exit Codes:
15
+ 0 - Success
16
+ 1 - Invalid arguments
17
+ 2 - kubectl/cluster not accessible
18
+ 3 - Consul not found
19
+ """
20
+
21
+ import argparse
22
+ import json
23
+ import subprocess
24
+ import sys
25
+ from typing import Dict, Any, Optional
26
+
27
+
28
+ def run_kubectl(args: list, context: Optional[str] = None) -> tuple:
29
+ """Run kubectl command and return (success, output)."""
30
+ cmd = ["kubectl"]
31
+ if context:
32
+ cmd.extend(["--context", context])
33
+ cmd.extend(args)
34
+
35
+ try:
36
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
37
+ return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
38
+ except subprocess.TimeoutExpired:
39
+ return False, "", "Command timed out"
40
+ except Exception as e:
41
+ return False, "", str(e)
42
+
43
+
44
+ def get_bootstrap_token(namespace: str, context: Optional[str] = None) -> Optional[str]:
45
+ """Retrieve bootstrap ACL token from Kubernetes secret."""
46
+ cmd = ["kubectl"]
47
+ if context:
48
+ cmd.extend(["--context", context])
49
+ cmd.extend([
50
+ "get", "secret", "consul-bootstrap-acl-token",
51
+ "-n", namespace,
52
+ "-o", "jsonpath={.data.token}"
53
+ ])
54
+
55
+ try:
56
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
57
+ if result.returncode == 0 and result.stdout:
58
+ import base64
59
+ return base64.b64decode(result.stdout).decode('utf-8').strip()
60
+ except Exception:
61
+ pass
62
+ return None
63
+
64
+
65
+ def run_consul_cmd(namespace: str, cmd: str, context: Optional[str] = None, token: Optional[str] = None) -> tuple:
66
+ """Run consul command inside server pod with optional ACL token."""
67
+ consul_cmd = cmd.split()
68
+ if token:
69
+ consul_cmd.extend(["-token", token])
70
+
71
+ kubectl_args = [
72
+ "exec", "-n", namespace, "consul-server-0", "--",
73
+ "consul"
74
+ ] + consul_cmd
75
+ return run_kubectl(kubectl_args, context)
76
+
77
+
78
+ def get_pods_status(namespace: str, context: Optional[str] = None) -> Dict[str, Any]:
79
+ """Get status of Consul pods."""
80
+ success, output, _ = run_kubectl(
81
+ ["get", "pods", "-n", namespace, "-l", "app=consul",
82
+ "-o", "json"],
83
+ context
84
+ )
85
+
86
+ if not success:
87
+ return {"error": "Failed to get pods"}
88
+
89
+ try:
90
+ pods_data = json.loads(output)
91
+ pods = []
92
+ for pod in pods_data.get("items", []):
93
+ pod_info = {
94
+ "name": pod["metadata"]["name"],
95
+ "status": pod["status"]["phase"],
96
+ "ready": all(c.get("ready", False)
97
+ for c in pod["status"].get("containerStatuses", [])),
98
+ "restarts": sum(c.get("restartCount", 0)
99
+ for c in pod["status"].get("containerStatuses", [])),
100
+ "node": pod["spec"].get("nodeName", "unknown")
101
+ }
102
+ pods.append(pod_info)
103
+ return {"pods": pods, "total": len(pods)}
104
+ except json.JSONDecodeError:
105
+ return {"error": "Failed to parse pods JSON"}
106
+
107
+
108
+ def get_cluster_members(namespace: str, context: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
109
+ """Get Consul cluster members."""
110
+ success, output, error = run_consul_cmd(namespace, "members", context, token)
111
+
112
+ if not success:
113
+ return {"error": f"Failed to get members: {error}"}
114
+
115
+ members = []
116
+ lines = output.strip().split("\n")
117
+ for line in lines[1:]: # Skip header
118
+ parts = line.split()
119
+ if len(parts) >= 4:
120
+ members.append({
121
+ "name": parts[0],
122
+ "address": parts[1],
123
+ "status": parts[2],
124
+ "type": parts[3]
125
+ })
126
+
127
+ return {"members": members, "total": len(members)}
128
+
129
+
130
+ def get_raft_status(namespace: str, context: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
131
+ """Get Raft consensus status."""
132
+ success, output, error = run_consul_cmd(
133
+ namespace, "operator raft list-peers", context, token
134
+ )
135
+
136
+ if not success:
137
+ return {"error": f"Failed to get raft status: {error}"}
138
+
139
+ peers = []
140
+ leader = None
141
+ lines = output.strip().split("\n")
142
+ for line in lines[1:]: # Skip header
143
+ parts = line.split()
144
+ if len(parts) >= 4:
145
+ peer = {
146
+ "node": parts[0],
147
+ "id": parts[1] if len(parts) > 1 else "",
148
+ "address": parts[2] if len(parts) > 2 else "",
149
+ "state": parts[3] if len(parts) > 3 else "",
150
+ "voter": parts[4] if len(parts) > 4 else ""
151
+ }
152
+ peers.append(peer)
153
+ if peer["state"] == "leader":
154
+ leader = peer["node"]
155
+
156
+ return {"peers": peers, "leader": leader, "total": len(peers)}
157
+
158
+
159
+ def get_helm_info(namespace: str, context: Optional[str] = None) -> Dict[str, Any]:
160
+ """Get Helm release info."""
161
+ cmd = ["helm", "list", "-n", namespace, "-o", "json"]
162
+ if context:
163
+ cmd.extend(["--kube-context", context])
164
+
165
+ try:
166
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
167
+ if result.returncode == 0:
168
+ releases = json.loads(result.stdout)
169
+ for release in releases:
170
+ if release.get("name") == "consul":
171
+ return {
172
+ "name": release["name"],
173
+ "version": release.get("chart", ""),
174
+ "app_version": release.get("app_version", ""),
175
+ "status": release.get("status", ""),
176
+ "updated": release.get("updated", "")
177
+ }
178
+ return {"error": "Consul release not found"}
179
+ return {"error": result.stderr}
180
+ except Exception as e:
181
+ return {"error": str(e)}
182
+
183
+
184
+ def main():
185
+ parser = argparse.ArgumentParser(description="Get Consul cluster status")
186
+ parser.add_argument("--namespace", "-n", default="consul",
187
+ help="Kubernetes namespace (default: consul)")
188
+ parser.add_argument("--context", "-c", default=None,
189
+ help="Kubernetes context")
190
+ parser.add_argument("--json", action="store_true",
191
+ help="Output in JSON format")
192
+ args = parser.parse_args()
193
+
194
+ # Retrieve bootstrap token for ACL-enabled clusters
195
+ token = get_bootstrap_token(args.namespace, args.context)
196
+
197
+ status = {
198
+ "namespace": args.namespace,
199
+ "acl_token_found": token is not None,
200
+ "helm": get_helm_info(args.namespace, args.context),
201
+ "pods": get_pods_status(args.namespace, args.context),
202
+ "members": get_cluster_members(args.namespace, args.context, token),
203
+ "raft": get_raft_status(args.namespace, args.context, token)
204
+ }
205
+
206
+ if args.json:
207
+ print(json.dumps(status, indent=2))
208
+ else:
209
+ print(f"\n{'='*60}")
210
+ print(f"CONSUL STATUS - Namespace: {args.namespace}")
211
+ print(f"{'='*60}\n")
212
+
213
+ # Helm info
214
+ helm = status["helm"]
215
+ if "error" not in helm:
216
+ print(f"📦 Helm Release: {helm.get('name', 'N/A')}")
217
+ print(f" Chart: {helm.get('version', 'N/A')}")
218
+ print(f" App Version: {helm.get('app_version', 'N/A')}")
219
+ print(f" Status: {helm.get('status', 'N/A')}")
220
+ else:
221
+ print(f"❌ Helm: {helm['error']}")
222
+ print()
223
+
224
+ # Pods
225
+ pods = status["pods"]
226
+ if "error" not in pods:
227
+ print(f"🔵 Pods ({pods['total']} total):")
228
+ for pod in pods.get("pods", []):
229
+ icon = "✅" if pod["ready"] else "❌"
230
+ print(f" {icon} {pod['name']}: {pod['status']} (restarts: {pod['restarts']})")
231
+ else:
232
+ print(f"❌ Pods: {pods['error']}")
233
+ print()
234
+
235
+ # Raft
236
+ raft = status["raft"]
237
+ if "error" not in raft:
238
+ print(f"🗳️ Raft Consensus ({raft['total']} peers):")
239
+ print(f" Leader: {raft.get('leader', 'NONE')}")
240
+ for peer in raft.get("peers", []):
241
+ icon = "👑" if peer["state"] == "leader" else " "
242
+ print(f" {icon} {peer['node']}: {peer['state']}")
243
+ else:
244
+ print(f"❌ Raft: {raft['error']}")
245
+ print()
246
+
247
+ # Summary
248
+ healthy = (
249
+ "error" not in pods and
250
+ "error" not in raft and
251
+ raft.get("leader") is not None
252
+ )
253
+ print(f"{'='*60}")
254
+ if healthy:
255
+ print("✅ Cluster Status: HEALTHY")
256
+ else:
257
+ print("❌ Cluster Status: UNHEALTHY")
258
+ print(f"{'='*60}\n")
259
+
260
+ sys.exit(0)
261
+
262
+
263
+ if __name__ == "__main__":
264
+ main()
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script: generate_values.py
4
+ Purpose: Generate Consul Helm values file based on configuration options
5
+
6
+ Usage:
7
+ python generate_values.py --datacenter dc1 --replicas 3 [options]
8
+
9
+ Arguments:
10
+ --datacenter Datacenter name (required)
11
+ --replicas Number of server replicas (3 or 5)
12
+ --connect-inject Enable Connect sidecar injection
13
+ --acls Enable ACL system
14
+ --tls Enable TLS
15
+ --mesh-gateway Enable mesh gateway
16
+ --ingress-gateway Enable ingress gateway
17
+ --output Output file path (default: stdout)
18
+
19
+ Exit Codes:
20
+ 0 - Success
21
+ 1 - Invalid arguments
22
+ """
23
+
24
+ import argparse
25
+ import sys
26
+ import yaml
27
+
28
+
29
+ def generate_values(args) -> dict:
30
+ """Generate Consul Helm values based on arguments."""
31
+
32
+ values = {
33
+ "global": {
34
+ "name": "consul",
35
+ "datacenter": args.datacenter,
36
+ },
37
+ "server": {
38
+ "replicas": args.replicas,
39
+ "bootstrapExpect": args.replicas,
40
+ "resources": {
41
+ "requests": {
42
+ "memory": "200Mi",
43
+ "cpu": "100m"
44
+ },
45
+ "limits": {
46
+ "memory": "500Mi",
47
+ "cpu": "500m"
48
+ }
49
+ },
50
+ "storageClass": "gp3",
51
+ "storage": "10Gi"
52
+ },
53
+ "connectInject": {
54
+ "enabled": args.connect_inject,
55
+ "default": False
56
+ },
57
+ "controller": {
58
+ "enabled": args.connect_inject
59
+ }
60
+ }
61
+
62
+ # Server anti-affinity for HA
63
+ if args.replicas >= 3:
64
+ values["server"]["affinity"] = """
65
+ podAntiAffinity:
66
+ requiredDuringSchedulingIgnoredDuringExecution:
67
+ - labelSelector:
68
+ matchLabels:
69
+ app: consul
70
+ component: server
71
+ topologyKey: kubernetes.io/hostname"""
72
+
73
+ # ACLs
74
+ if args.acls:
75
+ values["global"]["acls"] = {
76
+ "manageSystemACLs": True
77
+ }
78
+
79
+ # TLS
80
+ if args.tls:
81
+ values["global"]["tls"] = {
82
+ "enabled": True,
83
+ "enableAutoEncrypt": True
84
+ }
85
+ values["global"]["gossipEncryption"] = {
86
+ "autoGenerate": True
87
+ }
88
+
89
+ # Mesh Gateway
90
+ if args.mesh_gateway:
91
+ values["meshGateway"] = {
92
+ "enabled": True,
93
+ "replicas": 2
94
+ }
95
+
96
+ # Ingress Gateway
97
+ if args.ingress_gateway:
98
+ values["ingressGateway"] = {
99
+ "enabled": True,
100
+ "defaults": {
101
+ "replicas": 2
102
+ }
103
+ }
104
+
105
+ # Scale resources for larger clusters
106
+ if args.replicas >= 5:
107
+ values["server"]["resources"]["requests"]["memory"] = "500Mi"
108
+ values["server"]["resources"]["requests"]["cpu"] = "200m"
109
+ values["server"]["resources"]["limits"]["memory"] = "1Gi"
110
+ values["server"]["resources"]["limits"]["cpu"] = "1000m"
111
+ values["server"]["storage"] = "20Gi"
112
+
113
+ return values
114
+
115
+
116
+ def main():
117
+ parser = argparse.ArgumentParser(
118
+ description="Generate Consul Helm values file"
119
+ )
120
+ parser.add_argument("--datacenter", "-d", required=True,
121
+ help="Datacenter name")
122
+ parser.add_argument("--replicas", "-r", type=int, default=3,
123
+ choices=[1, 3, 5],
124
+ help="Number of server replicas (default: 3)")
125
+ parser.add_argument("--connect-inject", action="store_true",
126
+ help="Enable Connect sidecar injection")
127
+ parser.add_argument("--acls", action="store_true",
128
+ help="Enable ACL system")
129
+ parser.add_argument("--tls", action="store_true",
130
+ help="Enable TLS")
131
+ parser.add_argument("--mesh-gateway", action="store_true",
132
+ help="Enable mesh gateway")
133
+ parser.add_argument("--ingress-gateway", action="store_true",
134
+ help="Enable ingress gateway")
135
+ parser.add_argument("--output", "-o", default=None,
136
+ help="Output file path (default: stdout)")
137
+
138
+ args = parser.parse_args()
139
+
140
+ # Validate
141
+ if args.replicas == 1:
142
+ print("⚠️ Warning: Single server mode is not suitable for production",
143
+ file=sys.stderr)
144
+
145
+ values = generate_values(args)
146
+
147
+ # Add header comment
148
+ output = f"""# Consul Helm Values
149
+ # Generated for datacenter: {args.datacenter}
150
+ # Replicas: {args.replicas}
151
+ # Features: {'ACLs ' if args.acls else ''}{'TLS ' if args.tls else ''}{'Connect ' if args.connect_inject else ''}
152
+ #
153
+ # Install with:
154
+ # helm install consul hashicorp/consul -n consul -f <this-file>
155
+ #
156
+ """
157
+ output += yaml.dump(values, default_flow_style=False, sort_keys=False)
158
+
159
+ if args.output:
160
+ with open(args.output, 'w') as f:
161
+ f.write(output)
162
+ print(f"✅ Values written to {args.output}")
163
+ else:
164
+ print(output)
165
+
166
+ sys.exit(0)
167
+
168
+
169
+ if __name__ == "__main__":
170
+ main()