@raishin/vanguard-frontier-agentic 1.3.0 → 1.4.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 (155) hide show
  1. package/README.md +23 -1
  2. package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/metadata.json +2 -1
  3. package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/metadata.json +2 -1
  4. package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/metadata.json +2 -1
  5. package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/metadata.json +2 -1
  6. package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/metadata.json +2 -1
  7. package/agents/kubernetes/kubernetes-psa-review-agent/metadata.json +2 -1
  8. package/agents/terraform/terraform-reviewer/AGENT.md +2 -1
  9. package/catalog/skill-manifest.json +414 -414
  10. package/package.json +23 -4
  11. package/schemas/AGENTS.md +14 -0
  12. package/schemas/agent.frontmatter.schema.json +89 -0
  13. package/schemas/agent.schema.json +8 -0
  14. package/schemas/skill.frontmatter.schema.json +95 -0
  15. package/scripts/apply-skill-allowed-tools.py +142 -0
  16. package/scripts/backfill-skill-metadata.py +410 -0
  17. package/scripts/export-marketplace-agents.mjs +175 -0
  18. package/skills/argocd/argo-rollouts-progressive-delivery-review/SKILL.md +3 -0
  19. package/skills/argocd/argocd-gitops-review/SKILL.md +3 -0
  20. package/skills/aws/aws-agentcore/SKILL.md +3 -0
  21. package/skills/aws/aws-api-edge-delivery-review/SKILL.md +3 -0
  22. package/skills/aws/aws-bedrock-agent-security-governor/SKILL.md +3 -0
  23. package/skills/aws/aws-change-impact-advisor/SKILL.md +3 -0
  24. package/skills/aws/aws-ci-cd-release-engineer/SKILL.md +3 -0
  25. package/skills/aws/aws-compliance-evidence-mapper/SKILL.md +3 -0
  26. package/skills/aws/aws-cost-anomaly-watch-coordinator/SKILL.md +3 -0
  27. package/skills/aws/aws-cost-optimization-governor/SKILL.md +3 -0
  28. package/skills/aws/aws-daily-operations-briefing-coordinator/SKILL.md +3 -0
  29. package/skills/aws/aws-data-protection-backup-steward/SKILL.md +3 -0
  30. package/skills/aws/aws-deployment-hotfix-operator/SKILL.md +3 -0
  31. package/skills/aws/aws-devops-agent-skill-designer/SKILL.md +3 -0
  32. package/skills/aws/aws-dynamodb-data-modeling-performance-review/SKILL.md +3 -0
  33. package/skills/aws/aws-ec2-compute-operations-steward/SKILL.md +3 -0
  34. package/skills/aws/aws-ecs-fargate-platform-operator/SKILL.md +3 -0
  35. package/skills/aws/aws-ecs-service-remediation-operator/SKILL.md +3 -0
  36. package/skills/aws/aws-eks-platform-operator/SKILL.md +3 -0
  37. package/skills/aws/aws-event-driven-architecture-review/SKILL.md +3 -0
  38. package/skills/aws/aws-generative-ai-developer/SKILL.md +3 -0
  39. package/skills/aws/aws-iac-change-safety-review/SKILL.md +3 -0
  40. package/skills/aws/aws-iac-patch-executor/SKILL.md +3 -0
  41. package/skills/aws/aws-iam-least-privilege-review/SKILL.md +3 -0
  42. package/skills/aws/aws-kms-secrets-lifecycle-steward/SKILL.md +3 -0
  43. package/skills/aws/aws-landing-zone-governor/SKILL.md +3 -0
  44. package/skills/aws/aws-live-deployment-guarded-operator/SKILL.md +3 -0
  45. package/skills/aws/aws-live-ecs-rollout-guard/SKILL.md +3 -0
  46. package/skills/aws/aws-live-iac-change-guard/SKILL.md +3 -0
  47. package/skills/aws/aws-live-pipeline-approval-operator/SKILL.md +3 -0
  48. package/skills/aws/aws-live-serverless-release-guard/SKILL.md +3 -0
  49. package/skills/aws/aws-maestro/SKILL.md +3 -0
  50. package/skills/aws/aws-migration-cutover-architect/SKILL.md +3 -0
  51. package/skills/aws/aws-network-architect/SKILL.md +3 -0
  52. package/skills/aws/aws-non-destructive-task-automation-advisor/SKILL.md +3 -0
  53. package/skills/aws/aws-observability-incident-responder/SKILL.md +3 -0
  54. package/skills/aws/aws-pipeline-fix-operator/SKILL.md +3 -0
  55. package/skills/aws/aws-private-ca-issuer-review/SKILL.md +3 -0
  56. package/skills/aws/aws-rds-aurora-performance-investigator/SKILL.md +3 -0
  57. package/skills/aws/aws-resilience-bcdr-review/SKILL.md +3 -0
  58. package/skills/aws/aws-s3-data-perimeter-governor/SKILL.md +3 -0
  59. package/skills/aws/aws-security-posture-hardening/SKILL.md +3 -0
  60. package/skills/aws/aws-serverless-production-readiness/SKILL.md +3 -0
  61. package/skills/aws/aws-serverless-rollout-corrector/SKILL.md +3 -0
  62. package/skills/aws/aws-solution-architect/SKILL.md +3 -0
  63. package/skills/aws/aws-ticket-triage-escalation-coordinator/SKILL.md +3 -0
  64. package/skills/azure/azure-ai-foundry-ops-governor/SKILL.md +3 -0
  65. package/skills/azure/azure-aks-platform-operator/SKILL.md +3 -0
  66. package/skills/azure/azure-app-service-production-readiness/SKILL.md +3 -0
  67. package/skills/azure/azure-cosmosdb-application-developer/SKILL.md +3 -0
  68. package/skills/azure/azure-cosmosdb-performance-investigator/SKILL.md +3 -0
  69. package/skills/azure/azure-cosmosdb-platform-operator/SKILL.md +3 -0
  70. package/skills/azure/azure-cost-estimation-review/SKILL.md +3 -0
  71. package/skills/azure/azure-cost-optimization-governor/SKILL.md +3 -0
  72. package/skills/azure/azure-entra-id-specialist/SKILL.md +3 -0
  73. package/skills/azure/azure-governance-policy-guardrails/SKILL.md +3 -0
  74. package/skills/azure/azure-identity-governance-review/SKILL.md +3 -0
  75. package/skills/azure/azure-key-vault-secret-lifecycle-auditor/SKILL.md +3 -0
  76. package/skills/azure/azure-keyvault-certificate-issuer-review/SKILL.md +3 -0
  77. package/skills/azure/azure-landing-zone-architect/SKILL.md +3 -0
  78. package/skills/azure/azure-live-aks-rollout-guard/SKILL.md +3 -0
  79. package/skills/azure/azure-live-app-service-slot-swap-guard/SKILL.md +3 -0
  80. package/skills/azure/azure-live-arm-deployment-stack-guard/SKILL.md +3 -0
  81. package/skills/azure/azure-live-cost-budget-action-guard/SKILL.md +3 -0
  82. package/skills/azure/azure-live-entra-role-assignment-guard/SKILL.md +3 -0
  83. package/skills/azure/azure-live-keyvault-rotation-purge-guard/SKILL.md +3 -0
  84. package/skills/azure/azure-live-pim-jit-activation-guard/SKILL.md +3 -0
  85. package/skills/azure/azure-maestro/SKILL.md +3 -0
  86. package/skills/azure/azure-migrate-landing-zone-cutover/SKILL.md +3 -0
  87. package/skills/azure/azure-network-topology-review/SKILL.md +3 -0
  88. package/skills/azure/azure-observability-investigator/SKILL.md +3 -0
  89. package/skills/azure/azure-platform-automation-devops/SKILL.md +3 -0
  90. package/skills/azure/azure-private-endpoint-adoption-planner/SKILL.md +3 -0
  91. package/skills/azure/azure-rbac-review/SKILL.md +3 -0
  92. package/skills/azure/azure-resilience-bcdr-review/SKILL.md +3 -0
  93. package/skills/azure/azure-resource-health-incident-triage/SKILL.md +3 -0
  94. package/skills/azure/azure-role-selector/SKILL.md +3 -0
  95. package/skills/azure/azure-security-posture-hardening/SKILL.md +3 -0
  96. package/skills/azure/azure-subscription-resource-organization/SKILL.md +3 -0
  97. package/skills/backstage/backstage-scaffolder-template-review/SKILL.md +3 -0
  98. package/skills/cert-manager/cert-manager-issuer-trust-review/SKILL.md +3 -0
  99. package/skills/cilium/cilium-network-policy-review/SKILL.md +3 -0
  100. package/skills/falco/falco-runtime-threat-rules-review/SKILL.md +3 -0
  101. package/skills/finops/finops-cloud-price-advisor/SKILL.md +3 -0
  102. package/skills/fluxcd/fluxcd-kustomization-helmrelease-review/SKILL.md +3 -0
  103. package/skills/istio/istio-ambient-mesh-review/SKILL.md +3 -0
  104. package/skills/kubernetes/external-secrets-operator-review/SKILL.md +3 -0
  105. package/skills/kubernetes/kubecost-chargeback-allocation-review/SKILL.md +3 -0
  106. package/skills/kubernetes/kubernetes-live-rbac-mutation-guard/SKILL.md +3 -0
  107. package/skills/kubernetes/kubernetes-maestro/SKILL.md +3 -0
  108. package/skills/kubernetes/kubernetes-pod-security-admission-review/SKILL.md +3 -0
  109. package/skills/kubernetes/kubernetes-pod-spec-review/SKILL.md +3 -0
  110. package/skills/kubernetes/kubernetes-rbac-review/SKILL.md +3 -0
  111. package/skills/kubernetes/kubernetes-workload-identity-review/SKILL.md +3 -0
  112. package/skills/kyverno/kyverno-policy-review/SKILL.md +3 -0
  113. package/skills/oci/oci-autonomous-database-architect/SKILL.md +3 -0
  114. package/skills/oci/oci-certificates-issuer-review/SKILL.md +3 -0
  115. package/skills/oci/oci-cloud-guard-responder/SKILL.md +3 -0
  116. package/skills/oci/oci-compute-instance-agent-operator/SKILL.md +3 -0
  117. package/skills/oci/oci-compute-platform-operator/SKILL.md +3 -0
  118. package/skills/oci/oci-cost-finops-analyst/SKILL.md +3 -0
  119. package/skills/oci/oci-database-platform-dba/SKILL.md +3 -0
  120. package/skills/oci/oci-dbtools-sql-analyst/SKILL.md +3 -0
  121. package/skills/oci/oci-devops-container-platform-engineer/SKILL.md +3 -0
  122. package/skills/oci/oci-exadata-database-architect/SKILL.md +3 -0
  123. package/skills/oci/oci-exadata-platform-architect/SKILL.md +3 -0
  124. package/skills/oci/oci-fusion-apps-environment-operator/SKILL.md +3 -0
  125. package/skills/oci/oci-goldengate-replication-operator/SKILL.md +3 -0
  126. package/skills/oci/oci-identity-access-governor/SKILL.md +3 -0
  127. package/skills/oci/oci-iot-digital-twin-engineer/SKILL.md +3 -0
  128. package/skills/oci/oci-limits-capacity-planner/SKILL.md +3 -0
  129. package/skills/oci/oci-live-autonomous-db-lifecycle-guard/SKILL.md +3 -0
  130. package/skills/oci/oci-live-cost-budget-runaway-guard/SKILL.md +3 -0
  131. package/skills/oci/oci-live-iam-policy-compartment-guard/SKILL.md +3 -0
  132. package/skills/oci/oci-live-network-security-rule-guard/SKILL.md +3 -0
  133. package/skills/oci/oci-live-oke-rollout-guard/SKILL.md +3 -0
  134. package/skills/oci/oci-live-resource-manager-stack-guard/SKILL.md +3 -0
  135. package/skills/oci/oci-live-vault-key-destruction-guard/SKILL.md +3 -0
  136. package/skills/oci/oci-load-balancer-traffic-engineer/SKILL.md +3 -0
  137. package/skills/oci/oci-maestro/SKILL.md +3 -0
  138. package/skills/oci/oci-migration-cutover-architect/SKILL.md +3 -0
  139. package/skills/oci/oci-multi-cloud-architect/SKILL.md +3 -0
  140. package/skills/oci/oci-mysql-heatwave-ai-specialist/SKILL.md +3 -0
  141. package/skills/oci/oci-network-architect/SKILL.md +3 -0
  142. package/skills/oci/oci-observability-incident-responder/SKILL.md +3 -0
  143. package/skills/oci/oci-recovery-service-operator/SKILL.md +3 -0
  144. package/skills/oci/oci-registry-artifact-governor/SKILL.md +3 -0
  145. package/skills/oci/oci-resource-search-inventory-analyst/SKILL.md +3 -0
  146. package/skills/oci/oci-security-compliance-reviewer/SKILL.md +3 -0
  147. package/skills/oci/oci-solution-architect/SKILL.md +3 -0
  148. package/skills/oci/oci-storage-backup-steward/SKILL.md +3 -0
  149. package/skills/oci/oci-support-incident-coordinator/SKILL.md +3 -0
  150. package/skills/oci/oracle-oci-mcp-grounded-advisor/SKILL.md +3 -0
  151. package/skills/opentelemetry/opentelemetry-collector-config-review/SKILL.md +3 -0
  152. package/skills/prometheus/prometheus-alerting-cardinality-review/SKILL.md +3 -0
  153. package/skills/sigstore/sigstore-cosign-supply-chain-review/SKILL.md +3 -0
  154. package/skills/terraform/terraform-maestro/SKILL.md +3 -0
  155. package/skills/velero/velero-backup-restore-guard/SKILL.md +3 -0
@@ -0,0 +1,410 @@
1
+ #!/usr/bin/env python3
2
+ """Backfill `metadata.updated` and `metadata.category` on every SKILL.md.
3
+
4
+ `updated` is derived from the last git commit date that touched the SKILL.md.
5
+ `category` is classified deterministically from the skill name using a keyword
6
+ rules table with a fixed precedence order.
7
+
8
+ Usage:
9
+ python3 scripts/backfill-skill-metadata.py --dry-run
10
+ python3 scripts/backfill-skill-metadata.py
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import re
17
+ import subprocess
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ ROOT = Path(__file__).resolve().parents[1]
22
+ SKILLS_DIR = ROOT / "skills"
23
+
24
+ # Precedence order: earlier categories win when multiple keyword groups match.
25
+ # security > networking > resilience > observability > delivery > compliance
26
+ # > finops > ai > data > platform
27
+ CATEGORY_RULES: list[tuple[str, list[str]]] = [
28
+ (
29
+ "security",
30
+ [
31
+ "iam", "rbac", "secret", "kms", "vault", "perimeter", "policy",
32
+ "psa", "pod-security", "guard", "supply-chain", "falco", "cosign",
33
+ "sigstore", "kyverno", "security", "hardening", "cert-manager",
34
+ "certificate", "private-ca", "issuer", "trust", "workload-identity",
35
+ "entra", "pim", "external-secrets", "keyvault", "key-vault",
36
+ "ambient-mesh", "network-policy", "rotation", "purge", "destruction",
37
+ "cloud-guard", "threat",
38
+ ],
39
+ ),
40
+ (
41
+ "networking",
42
+ [
43
+ "network", "mesh", "cilium", "istio", "vpc", "endpoint", "topology",
44
+ "load-balancer", "traffic", "private-endpoint", "api-edge", "edge",
45
+ ],
46
+ ),
47
+ (
48
+ "resilience",
49
+ [
50
+ "backup", "recovery", "bcdr", "resilience", "velero",
51
+ "data-protection", "restore",
52
+ ],
53
+ ),
54
+ (
55
+ "observability",
56
+ [
57
+ "observability", "monitor", "incident", "responder", "investigator",
58
+ "prometheus", "opentelemetry", "alerting", "resource-health",
59
+ "triage", "health",
60
+ ],
61
+ ),
62
+ (
63
+ "delivery",
64
+ [
65
+ "ci-cd", "release", "pipeline", "rollout", "deployment", "gitops",
66
+ "argocd", "argo-rollouts", "flux", "scaffolder", "registry",
67
+ "rollout-corrector", "hotfix", "slot-swap", "approval", "devops",
68
+ "platform-automation", "agent-skill-designer", "stack-guard",
69
+ "iac", "arm-deployment", "resource-manager-stack", "migration",
70
+ "cutover", "fix-operator", "patch-executor", "change-impact",
71
+ "change-safety", "deployment-stack",
72
+ ],
73
+ ),
74
+ (
75
+ "compliance",
76
+ [
77
+ "compliance", "evidence", "audit", "governance", "landing-zone",
78
+ "guardrail", "subscription-resource", "identity-governance",
79
+ "role-selector", "entra-id-specialist", "access-governor",
80
+ "limits-capacity", "resource-search", "ticket-triage",
81
+ ],
82
+ ),
83
+ (
84
+ "finops",
85
+ [
86
+ "cost", "finops", "budget", "kubecost", "anomaly", "price",
87
+ "chargeback", "estimation",
88
+ ],
89
+ ),
90
+ (
91
+ "ai",
92
+ [
93
+ "bedrock", "agentcore", "generative", "ai-foundry", "heatwave-ai",
94
+ "iot-digital-twin", "maestro", "grounded-advisor",
95
+ ],
96
+ ),
97
+ (
98
+ "data",
99
+ [
100
+ "rds", "dynamodb", "cosmos", "aurora", "database", "dba",
101
+ "autonomous-db", "autonomous-database", "exadata", "goldengate",
102
+ "mysql", "dbtools", "sql-analyst", "fusion-apps",
103
+ ],
104
+ ),
105
+ ]
106
+
107
+ # Keywords whose presence forces a re-route override. Some names contain
108
+ # substrings that would mismatch precedence; codify hard overrides here.
109
+ HARD_OVERRIDES: list[tuple[re.Pattern, str]] = [
110
+ # Solution / network / multi-cloud architects are platform/networking design
111
+ (re.compile(r"network-architect$"), "networking"),
112
+ (re.compile(r"network-topology"), "networking"),
113
+ (re.compile(r"multi-cloud-architect$"), "platform"),
114
+ (re.compile(r"solution-architect$"), "platform"),
115
+ (re.compile(r"landing-zone"), "compliance"),
116
+ (re.compile(r"governance-policy-guardrails$"), "compliance"),
117
+ # Live-guard skills with policy/iam/rbac stay security
118
+ (re.compile(r"iam-policy-compartment-guard$"), "security"),
119
+ (re.compile(r"rbac-mutation-guard$"), "security"),
120
+ (re.compile(r"role-assignment-guard$"), "security"),
121
+ (re.compile(r"pim-jit-activation-guard$"), "security"),
122
+ (re.compile(r"vault-key-destruction-guard$"), "security"),
123
+ (re.compile(r"keyvault-rotation-purge-guard$"), "security"),
124
+ (re.compile(r"network-security-rule-guard$"), "security"),
125
+ # Cost-budget guards remain finops despite "guard"
126
+ (re.compile(r"cost-budget-runaway-guard$"), "finops"),
127
+ (re.compile(r"cost-budget-action-guard$"), "finops"),
128
+ # Live IaC change guards are delivery
129
+ (re.compile(r"iac-change-guard$"), "delivery"),
130
+ (re.compile(r"resource-manager-stack-guard$"), "delivery"),
131
+ (re.compile(r"arm-deployment-stack-guard$"), "delivery"),
132
+ # Rollout / deployment guards are delivery
133
+ (re.compile(r"rollout-guard$"), "delivery"),
134
+ (re.compile(r"deployment-guarded-operator$"), "delivery"),
135
+ (re.compile(r"pipeline-approval-operator$"), "delivery"),
136
+ (re.compile(r"serverless-release-guard$"), "delivery"),
137
+ (re.compile(r"slot-swap-guard$"), "delivery"),
138
+ (re.compile(r"app-service-production-readiness$"), "platform"),
139
+ (re.compile(r"app-service.*$"), "platform"),
140
+ (re.compile(r"serverless-production-readiness$"), "platform"),
141
+ (re.compile(r"event-driven-architecture-review$"), "platform"),
142
+ # AKS / EKS / OKE / ECS / Fargate platform operators
143
+ (re.compile(r"aks-platform-operator$"), "platform"),
144
+ (re.compile(r"eks-platform-operator$"), "platform"),
145
+ (re.compile(r"oke.*$"), "platform"),
146
+ (re.compile(r"ecs-fargate-platform-operator$"), "platform"),
147
+ (re.compile(r"ecs-service-remediation-operator$"), "platform"),
148
+ (re.compile(r"compute-platform-operator$"), "platform"),
149
+ (re.compile(r"compute-instance-agent-operator$"), "platform"),
150
+ (re.compile(r"ec2-compute-operations-steward$"), "platform"),
151
+ (re.compile(r"cosmosdb-platform-operator$"), "platform"),
152
+ (re.compile(r"container-platform-engineer$"), "platform"),
153
+ (re.compile(r"environment-operator$"), "platform"),
154
+ # Cosmos / DB performance/dev/audit are data
155
+ (re.compile(r"cosmosdb-application-developer$"), "data"),
156
+ (re.compile(r"cosmosdb-performance-investigator$"), "data"),
157
+ (re.compile(r"keyvault-secret-lifecycle-auditor$"), "security"),
158
+ (re.compile(r"key-vault-secret-lifecycle-auditor$"), "security"),
159
+ (re.compile(r"keyvault-certificate-issuer-review$"), "security"),
160
+ # Pod spec review = platform
161
+ (re.compile(r"pod-spec-review$"), "platform"),
162
+ # Backstage scaffolder = delivery
163
+ (re.compile(r"scaffolder-template-review$"), "delivery"),
164
+ # OCI registry = delivery
165
+ (re.compile(r"registry-artifact-governor$"), "delivery"),
166
+ # Storage backup steward = resilience
167
+ (re.compile(r"storage-backup-steward$"), "resilience"),
168
+ (re.compile(r"data-protection-backup-steward$"), "resilience"),
169
+ (re.compile(r"recovery-service-operator$"), "resilience"),
170
+ # Observability investigators
171
+ (re.compile(r"observability-investigator$"), "observability"),
172
+ (re.compile(r"observability-incident-responder$"), "observability"),
173
+ (re.compile(r"resource-health-incident-triage$"), "observability"),
174
+ (re.compile(r"support-incident-coordinator$"), "observability"),
175
+ (re.compile(r"daily-operations-briefing-coordinator$"), "observability"),
176
+ (re.compile(r"performance-investigator$"), "observability"),
177
+ (re.compile(r"rds-aurora-performance-investigator$"), "data"),
178
+ # Maestros are routing skills — bucket as ai (router/judgment)
179
+ (re.compile(r"-maestro$"), "ai"),
180
+ (re.compile(r"^terraform-maestro$"), "delivery"),
181
+ # Migration cutover architects = delivery
182
+ (re.compile(r"migration-cutover-architect$"), "delivery"),
183
+ (re.compile(r"migrate-landing-zone-cutover$"), "delivery"),
184
+ # Skill designer
185
+ (re.compile(r"agent-skill-designer$"), "delivery"),
186
+ # Identity / RBAC reviews
187
+ (re.compile(r"rbac-review$"), "security"),
188
+ (re.compile(r"identity-governance-review$"), "compliance"),
189
+ (re.compile(r"identity-access-governor$"), "compliance"),
190
+ (re.compile(r"entra-id-specialist$"), "security"),
191
+ # Generative AI dev
192
+ (re.compile(r"generative-ai-developer$"), "ai"),
193
+ (re.compile(r"ai-foundry-ops-governor$"), "ai"),
194
+ (re.compile(r"heatwave-ai-specialist$"), "ai"),
195
+ (re.compile(r"iot-digital-twin-engineer$"), "ai"),
196
+ (re.compile(r"agentcore$"), "ai"),
197
+ (re.compile(r"oracle-oci-mcp-grounded-advisor$"), "ai"),
198
+ (re.compile(r"bedrock-agent-security-governor$"), "security"),
199
+ # Network architect / load balancer
200
+ (re.compile(r"load-balancer-traffic-engineer$"), "networking"),
201
+ (re.compile(r"private-endpoint-adoption-planner$"), "networking"),
202
+ (re.compile(r"api-edge-delivery-review$"), "networking"),
203
+ # Cost
204
+ (re.compile(r"cost-anomaly-watch-coordinator$"), "finops"),
205
+ (re.compile(r"cost-optimization-governor$"), "finops"),
206
+ (re.compile(r"cost-finops-analyst$"), "finops"),
207
+ (re.compile(r"cost-estimation-review$"), "finops"),
208
+ (re.compile(r"cloud-price-advisor$"), "finops"),
209
+ (re.compile(r"chargeback-allocation-review$"), "finops"),
210
+ # Compliance / security posture
211
+ (re.compile(r"security-posture-hardening$"), "security"),
212
+ (re.compile(r"compliance-evidence-mapper$"), "compliance"),
213
+ (re.compile(r"security-compliance-reviewer$"), "compliance"),
214
+ (re.compile(r"cloud-guard-responder$"), "security"),
215
+ # Resilience
216
+ (re.compile(r"resilience-bcdr-review$"), "resilience"),
217
+ # Subscription / governance
218
+ (re.compile(r"subscription-resource-organization$"), "compliance"),
219
+ (re.compile(r"governance-policy-guardrails$"), "compliance"),
220
+ (re.compile(r"limits-capacity-planner$"), "platform"),
221
+ (re.compile(r"resource-search-inventory-analyst$"), "platform"),
222
+ # Platform automation / DevOps
223
+ (re.compile(r"platform-automation-devops$"), "delivery"),
224
+ (re.compile(r"ci-cd-release-engineer$"), "delivery"),
225
+ (re.compile(r"non-destructive-task-automation-advisor$"), "delivery"),
226
+ (re.compile(r"ticket-triage-escalation-coordinator$"), "observability"),
227
+ # Pipeline / hotfix / serverless rollout corrector
228
+ (re.compile(r"pipeline-fix-operator$"), "delivery"),
229
+ (re.compile(r"deployment-hotfix-operator$"), "delivery"),
230
+ (re.compile(r"serverless-rollout-corrector$"), "delivery"),
231
+ (re.compile(r"iac-patch-executor$"), "delivery"),
232
+ (re.compile(r"iac-change-safety-review$"), "delivery"),
233
+ (re.compile(r"change-impact-advisor$"), "delivery"),
234
+ # DynamoDB / RDS modeling = data
235
+ (re.compile(r"dynamodb-data-modeling-performance-review$"), "data"),
236
+ (re.compile(r"dbtools-sql-analyst$"), "data"),
237
+ (re.compile(r"goldengate-replication-operator$"), "data"),
238
+ (re.compile(r"database-platform-dba$"), "data"),
239
+ (re.compile(r"autonomous-database-architect$"), "data"),
240
+ (re.compile(r"autonomous-db-lifecycle-guard$"), "data"),
241
+ (re.compile(r"exadata-platform-architect$"), "platform"),
242
+ (re.compile(r"exadata-database-architect$"), "data"),
243
+ (re.compile(r"fusion-apps-environment-operator$"), "platform"),
244
+ # Architects (broad)
245
+ (re.compile(r"^aws-solution-architect$"), "platform"),
246
+ (re.compile(r"^oci-solution-architect$"), "platform"),
247
+ (re.compile(r"^oci-multi-cloud-architect$"), "platform"),
248
+ (re.compile(r"^azure-landing-zone-architect$"), "compliance"),
249
+ (re.compile(r"^aws-landing-zone-governor$"), "compliance"),
250
+ (re.compile(r"^aws-network-architect$"), "networking"),
251
+ (re.compile(r"^oci-network-architect$"), "networking"),
252
+ ]
253
+
254
+
255
+ def classify(skill_name: str) -> str:
256
+ # Apply hard overrides first.
257
+ for pat, cat in HARD_OVERRIDES:
258
+ if pat.search(skill_name):
259
+ return cat
260
+
261
+ name_l = skill_name.lower()
262
+ for cat, keywords in CATEGORY_RULES:
263
+ for kw in keywords:
264
+ # match whole word-ish on hyphen boundaries
265
+ if kw in name_l:
266
+ return cat
267
+ return "platform"
268
+
269
+
270
+ def git_last_date(path: Path) -> str | None:
271
+ try:
272
+ out = subprocess.check_output(
273
+ ["git", "log", "-1", "--format=%cs", "--", str(path)],
274
+ cwd=ROOT,
275
+ text=True,
276
+ ).strip()
277
+ if out and re.match(r"^\d{4}-\d{2}-\d{2}$", out):
278
+ return out
279
+ except subprocess.CalledProcessError:
280
+ return None
281
+ return None
282
+
283
+
284
+ def find_frontmatter_bounds(text: str) -> tuple[int, int] | None:
285
+ """Return (start_after_open_fence, end_before_close_fence) line indices."""
286
+ lines = text.splitlines(keepends=True)
287
+ if not lines or lines[0].rstrip("\n") != "---":
288
+ return None
289
+ for i in range(1, len(lines)):
290
+ if lines[i].rstrip("\n") == "---":
291
+ return (1, i)
292
+ return None
293
+
294
+
295
+ def update_skill_md(path: Path, dry_run: bool) -> tuple[bool, str, str | None, str | None]:
296
+ """Returns (changed, skill_name, applied_updated, applied_category)."""
297
+ text = path.read_text(encoding="utf-8")
298
+ bounds = find_frontmatter_bounds(text)
299
+ if bounds is None:
300
+ return (False, path.parent.name, None, None)
301
+
302
+ lines = text.splitlines(keepends=True)
303
+ fm_start, fm_end = bounds # fm_end is the closing '---' index
304
+
305
+ # Locate metadata block
306
+ meta_idx = None
307
+ for i in range(fm_start, fm_end):
308
+ if lines[i].startswith("metadata:"):
309
+ meta_idx = i
310
+ break
311
+ if meta_idx is None:
312
+ return (False, path.parent.name, None, None)
313
+
314
+ # Find end of metadata block (next non-indented line within frontmatter)
315
+ meta_block_end = fm_end
316
+ for i in range(meta_idx + 1, fm_end):
317
+ line = lines[i]
318
+ if line.strip() == "":
319
+ continue
320
+ if not (line.startswith(" ") or line.startswith("\t")):
321
+ meta_block_end = i
322
+ break
323
+
324
+ meta_lines = lines[meta_idx + 1 : meta_block_end]
325
+
326
+ has_updated = any(
327
+ re.match(r"^\s+updated\s*:", ln) for ln in meta_lines
328
+ )
329
+ has_category = any(
330
+ re.match(r"^\s+category\s*:", ln) for ln in meta_lines
331
+ )
332
+
333
+ skill_name = path.parent.name
334
+ new_updated = None
335
+ new_category = None
336
+ insertions: list[str] = []
337
+
338
+ if not has_updated:
339
+ date = git_last_date(path) or "2026-05-05"
340
+ new_updated = date
341
+ insertions.append(f' updated: "{date}"\n')
342
+
343
+ if not has_category:
344
+ # Read declared name from frontmatter if available; fall back to dir
345
+ name_in_fm = None
346
+ for i in range(fm_start, fm_end):
347
+ m = re.match(r"^name:\s*(.+)$", lines[i].rstrip("\n"))
348
+ if m:
349
+ name_in_fm = m.group(1).strip().strip('"').strip("'")
350
+ break
351
+ cat = classify(name_in_fm or skill_name)
352
+ new_category = cat
353
+ insertions.append(f" category: {cat}\n")
354
+
355
+ if not insertions:
356
+ return (False, skill_name, None, None)
357
+
358
+ # Insert after the last existing metadata sub-line (keep ordering stable).
359
+ # Find the last non-blank line within meta_lines.
360
+ insert_at = meta_block_end
361
+ # walk back over trailing blank lines
362
+ while insert_at - 1 > meta_idx and lines[insert_at - 1].strip() == "":
363
+ insert_at -= 1
364
+
365
+ new_lines = lines[:insert_at] + insertions + lines[insert_at:]
366
+
367
+ if not dry_run:
368
+ path.write_text("".join(new_lines), encoding="utf-8")
369
+
370
+ return (True, skill_name, new_updated, new_category)
371
+
372
+
373
+ def main() -> int:
374
+ ap = argparse.ArgumentParser()
375
+ ap.add_argument("--dry-run", action="store_true")
376
+ args = ap.parse_args()
377
+
378
+ skill_files = sorted(SKILLS_DIR.glob("*/*/SKILL.md"))
379
+ if not skill_files:
380
+ print("ERROR: no SKILL.md files found", file=sys.stderr)
381
+ return 2
382
+
383
+ changed = 0
384
+ cat_counts: dict[str, int] = {}
385
+ rows: list[tuple[str, str | None, str | None]] = []
386
+
387
+ for sf in skill_files:
388
+ ch, name, upd, cat = update_skill_md(sf, args.dry_run)
389
+ if ch:
390
+ changed += 1
391
+ if cat:
392
+ cat_counts[cat] = cat_counts.get(cat, 0) + 1
393
+ rows.append((name, upd, cat))
394
+
395
+ mode = "DRY-RUN" if args.dry_run else "APPLIED"
396
+ print(f"{mode}: {changed} of {len(skill_files)} SKILL.md files updated")
397
+ print("Category distribution:")
398
+ for c in sorted(cat_counts):
399
+ print(f" {c}: {cat_counts[c]}")
400
+
401
+ if args.dry_run:
402
+ print("\nPer-skill assignments:")
403
+ for name, upd, cat in rows:
404
+ print(f" {name}: updated={upd} category={cat}")
405
+
406
+ return 0
407
+
408
+
409
+ if __name__ == "__main__":
410
+ sys.exit(main())
@@ -43,6 +43,53 @@ const PLATFORM_ALIASES = {
43
43
  kirocli: "kiro-cli",
44
44
  };
45
45
 
46
+ const SKILLS_PLATFORM_CONFIG = {
47
+ "claude-code": ".claude/skills",
48
+ copilot: ".github/skills",
49
+ gemini: ".gemini/skills",
50
+ };
51
+
52
+ /**
53
+ * Platforms that will NEVER support skill bundling because they have no native
54
+ * skill primitive. The value is an explicit notice that replaces the generic
55
+ * "not yet supported" fallback for these platforms.
56
+ *
57
+ * Design rationale: docs/cross-harness-skills.md
58
+ * Cursor — uses Project Rules (.cursor/rules/*.mdc), not skills.
59
+ * Kiro — uses Steering files (.kiro/steering/*.md), not skills.
60
+ * Both mismatches are large enough that skill export is intentionally omitted
61
+ * as a permanent design decision, not a pending TODO.
62
+ */
63
+ const SKIP_SKILLS_PLATFORM_NOTICES = {
64
+ cursor:
65
+ "[vfa] Skill export is not supported on Cursor. Cursor uses Project Rules " +
66
+ "(.cursor/rules/*.mdc), not skills. The semantics (style guides, glob-based " +
67
+ "triggers) differ significantly from our multi-section operating playbooks; " +
68
+ "this is a permanent design decision, not a pending TODO. " +
69
+ "See docs/cross-harness-skills.md for the full rationale.\n",
70
+ kiro:
71
+ "[vfa] Skill export is not supported on Kiro. Kiro uses Steering files " +
72
+ "(.kiro/steering/*.md), not skills. Steering is single-file guidance with " +
73
+ "plural-by-default inclusion; our SKILL packages bundle scripts/ and " +
74
+ "references/ siblings that Steering cannot accommodate. " +
75
+ "This is a permanent design decision, not a pending TODO. " +
76
+ "See docs/cross-harness-skills.md for the full rationale.\n",
77
+ "kiro-ide":
78
+ "[vfa] Skill export is not supported on Kiro. Kiro uses Steering files " +
79
+ "(.kiro/steering/*.md), not skills. Steering is single-file guidance with " +
80
+ "plural-by-default inclusion; our SKILL packages bundle scripts/ and " +
81
+ "references/ siblings that Steering cannot accommodate. " +
82
+ "This is a permanent design decision, not a pending TODO. " +
83
+ "See docs/cross-harness-skills.md for the full rationale.\n",
84
+ "kiro-cli":
85
+ "[vfa] Skill export is not supported on Kiro. Kiro uses Steering files " +
86
+ "(.kiro/steering/*.md), not skills. Steering is single-file guidance with " +
87
+ "plural-by-default inclusion; our SKILL packages bundle scripts/ and " +
88
+ "references/ siblings that Steering cannot accommodate. " +
89
+ "This is a permanent design decision, not a pending TODO. " +
90
+ "See docs/cross-harness-skills.md for the full rationale.\n",
91
+ };
92
+
46
93
  function usage(exitCode = 0) {
47
94
  const message = `
48
95
  Export selected marketplace agents into a consumer repository.
@@ -61,12 +108,21 @@ Roles:
61
108
  cloud-security-engineer, cloud-platform-engineer, cloud-dba,
62
109
  cloud-finops-analyst, cloud-solutions-architect, cloud-devops-engineer
63
110
 
111
+ Companion skills:
112
+ By default, when --platform supports skill bundling (claude-code, copilot, gemini),
113
+ each agent's same-named SKILL.md companion is also exported into the
114
+ platform skill directory (e.g. <repo>/.claude/skills/, <repo>/.github/skills/,
115
+ or <repo>/.gemini/skills/).
116
+ Pairing rule: agent id '<name>-agent' bundles skill '<name>' if it exists.
117
+ Use --no-skills to export agents only.
118
+
64
119
  Examples:
65
120
  vfa-export-agents --list
66
121
  vfa-export-agents --list-roles
67
122
  vfa-export-agents --platform claude-code --agents azure-cosmosdb-platform-operator-agent
68
123
  vfa-export-agents --platform claude-code --role cloud-security-engineer
69
124
  vfa-export-agents --platform claude-code --role cloud-security-engineer --provider azure
125
+ vfa-export-agents --platform claude-code --all --no-skills --repo /path/to/project
70
126
  vfa-export-agents --platform kiro --agents azure-cosmosdb-platform-operator-agent --repo ../consumer-repo
71
127
  vfa-export-agents --platform copilot --all --repo /path/to/project --force
72
128
  `.trim();
@@ -85,6 +141,7 @@ function parseArgs(argv) {
85
141
  platform: null,
86
142
  role: null,
87
143
  provider: null,
144
+ noSkills: false,
88
145
  };
89
146
 
90
147
  for (let i = 0; i < argv.length; i += 1) {
@@ -106,6 +163,10 @@ function parseArgs(argv) {
106
163
  args.all = true;
107
164
  continue;
108
165
  }
166
+ if (arg === "--no-skills") {
167
+ args.noSkills = true;
168
+ continue;
169
+ }
109
170
  if (arg === "--repo") {
110
171
  args.repo = path.resolve(argv[++i] ?? "");
111
172
  continue;
@@ -161,6 +222,7 @@ function loadAgents() {
161
222
  provider: metadata.provider,
162
223
  summary: metadata.summary,
163
224
  harness_variants: metadata.harness_variants ?? {},
225
+ companion_skills: Array.isArray(metadata.companion_skills) ? metadata.companion_skills : undefined,
164
226
  metadataPath,
165
227
  };
166
228
  });
@@ -197,6 +259,76 @@ function assertWithin(parent, child, label) {
197
259
  }
198
260
  }
199
261
 
262
+ function loadSkills() {
263
+ const skillsRoot = path.join(repoRoot, "skills");
264
+ if (!fs.existsSync(skillsRoot)) return new Map();
265
+ const byName = new Map();
266
+ for (const provider of fs.readdirSync(skillsRoot, { withFileTypes: true })) {
267
+ if (!provider.isDirectory()) continue;
268
+ const providerDir = path.join(skillsRoot, provider.name);
269
+ for (const skill of fs.readdirSync(providerDir, { withFileTypes: true })) {
270
+ if (!skill.isDirectory()) continue;
271
+ const skillDir = path.join(providerDir, skill.name);
272
+ if (fs.existsSync(path.join(skillDir, "SKILL.md"))) {
273
+ byName.set(skill.name, skillDir);
274
+ }
275
+ }
276
+ }
277
+ return byName;
278
+ }
279
+
280
+ function copySkillTree(sourceDir, destDir, force) {
281
+ assertWithin(repoRoot, sourceDir, "read skill source");
282
+ for (const entry of fs.readdirSync(sourceDir, { withFileTypes: true })) {
283
+ const src = path.join(sourceDir, entry.name);
284
+ const dst = path.join(destDir, entry.name);
285
+ if (entry.isSymbolicLink()) {
286
+ throw new Error(`Refusing to copy symbolic link in skill tree: ${src}`);
287
+ }
288
+ if (entry.isDirectory()) {
289
+ copySkillTree(src, dst, force);
290
+ continue;
291
+ }
292
+ if (!entry.isFile()) continue;
293
+ if (!force && fs.existsSync(dst)) {
294
+ throw new Error(`Refusing to overwrite existing file without --force: ${dst}`);
295
+ }
296
+ fs.mkdirSync(path.dirname(dst), { recursive: true });
297
+ fs.copyFileSync(src, dst);
298
+ }
299
+ }
300
+
301
+ function resolveCompanionSkills(selectedAgents, skillsByName, role, includeAll) {
302
+ const skillNames = new Set();
303
+ if (includeAll) {
304
+ for (const name of skillsByName.keys()) skillNames.add(name);
305
+ }
306
+ if (role && Array.isArray(role.skills)) {
307
+ for (const id of role.skills) skillNames.add(id);
308
+ }
309
+ const orphans = [];
310
+ for (const agent of selectedAgents) {
311
+ // Prefer explicit companion_skills if declared (even if empty — that means intentional no-pair)
312
+ if (Array.isArray(agent.companion_skills)) {
313
+ for (const skillId of agent.companion_skills) {
314
+ if (skillsByName.has(skillId)) skillNames.add(skillId);
315
+ }
316
+ // companion_skills: [] is intentional no-pair — do NOT count as orphan
317
+ continue;
318
+ }
319
+ // Fall back to name-stripping convention
320
+ const skillName = agent.id.endsWith("-agent")
321
+ ? agent.id.slice(0, -"-agent".length)
322
+ : agent.id;
323
+ if (skillsByName.has(skillName)) {
324
+ skillNames.add(skillName);
325
+ } else if (!role) {
326
+ orphans.push(agent.id);
327
+ }
328
+ }
329
+ return { skillNames: [...skillNames].sort(), orphans };
330
+ }
331
+
200
332
  function copyFile(source, destination, force) {
201
333
  const sourceStat = fs.lstatSync(source);
202
334
  if (sourceStat.isSymbolicLink()) {
@@ -292,9 +424,11 @@ function main() {
292
424
  const platform = ensurePlatform(args.platform);
293
425
 
294
426
  let selectedAgents;
427
+ let selectedRole = null;
295
428
  if (args.role) {
296
429
  const rolesData = loadRoles();
297
430
  const role = Object.hasOwn(rolesData.roles, args.role) ? rolesData.roles[args.role] : undefined;
431
+ selectedRole = role;
298
432
  if (!role) {
299
433
  const validRoles = Object.keys(rolesData.roles).join(", ");
300
434
  throw new Error(`Unknown role: ${args.role}. Valid roles: ${validRoles}`);
@@ -353,6 +487,47 @@ function main() {
353
487
  `installed\t${operation.agentId}\t${operation.variantKey}\t${path.relative(args.repo, operation.dest)}`
354
488
  );
355
489
  }
490
+
491
+ const skillsDestRoot = SKILLS_PLATFORM_CONFIG[platform];
492
+ if (args.noSkills) {
493
+ process.stderr.write(`[vfa] --no-skills: companion skills not bundled.\n`);
494
+ } else if (!skillsDestRoot) {
495
+ const specificNotice = SKIP_SKILLS_PLATFORM_NOTICES[platform];
496
+ if (specificNotice) {
497
+ process.stderr.write(specificNotice);
498
+ } else {
499
+ process.stderr.write(
500
+ `[vfa] Note: skills bundling is not yet supported on platform '${platform}'. ` +
501
+ `Agents exported only. Pass --no-skills to silence.\n`
502
+ );
503
+ }
504
+ } else {
505
+ const skillsByName = loadSkills();
506
+ const { skillNames, orphans } = resolveCompanionSkills(
507
+ selectedAgents,
508
+ skillsByName,
509
+ selectedRole,
510
+ args.all
511
+ );
512
+ let bundled = 0;
513
+ for (const skillName of skillNames) {
514
+ const sourceDir = skillsByName.get(skillName);
515
+ if (!sourceDir) continue;
516
+ const destDir = path.join(args.repo, skillsDestRoot, skillName);
517
+ assertWithin(args.repo, destDir, "write skill destination");
518
+ copySkillTree(sourceDir, destDir, args.force);
519
+ console.log(`installed\tskill:${skillName}\t${platform}\t${path.relative(args.repo, destDir)}`);
520
+ bundled += 1;
521
+ }
522
+ process.stderr.write(
523
+ `[vfa] Bundled ${bundled} companion skill(s) alongside ${selectedAgents.length} agent(s)` +
524
+ (orphans.length ? ` (no-skill agents: ${orphans.length})` : "") +
525
+ `. Use --no-skills to opt out.\n`
526
+ );
527
+ if (orphans.length && orphans.length <= 10) {
528
+ process.stderr.write(`[vfa] Agents without companion skill: ${orphans.join(", ")}\n`);
529
+ }
530
+ }
356
531
  }
357
532
 
358
533
  try {
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  name: argo-rollouts-progressive-delivery-review
3
3
  description: Use this skill when reviewing Argo Rollouts progressive delivery configuration. Trigger when the user asks about canary or blue-green Rollout strategy correctness, AnalysisTemplate success/failure conditions, traffic weighting provider alignment, canaryService isolation, PDB deadlock risk with Rollout maxSurge settings, automated rollback posture, or manual vs automated promotion configuration.
4
+ allowed-tools: Read Grep Glob
4
5
  metadata:
5
6
  author: "github: Raishin"
6
7
  version: "0.1.0"
8
+ updated: "2026-05-05"
9
+ category: delivery
7
10
  ---
8
11
 
9
12
  # Argo Rollouts Progressive Delivery Review
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  name: argocd-gitops-review
3
3
  description: Use this skill for Argo CD GitOps review across Application, AppProject, ApplicationSet, sync windows, RBAC, sync impersonation, and Argo CD Agent multi-cluster topologies. Trigger when the user asks whether an Argo CD configuration is safe for production, whether automated sync should be enabled, whether prune+selfHeal is appropriate, whether AppProject scope is too wide, or how to enforce least-privilege sync identity.
4
+ allowed-tools: Read Grep Glob
4
5
  metadata:
5
6
  author: "github: Raishin"
6
7
  version: "0.1.0"
8
+ updated: "2026-05-05"
9
+ category: delivery
7
10
  ---
8
11
 
9
12
  # Argo CD GitOps Review