@agentlee5/agent-skills 1.0.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.
- package/.leeway/config.json +133 -0
- package/LICENSE +21 -0
- package/LeeWay-Standards/LICENSE +21 -0
- package/LeeWay-Standards/README.md +324 -0
- package/LeeWay-Standards/examples/NexusButton.tsx +90 -0
- package/LeeWay-Standards/examples/example-agent.js +89 -0
- package/LeeWay-Standards/package.json +61 -0
- package/LeeWay-Standards/schemas/leeway-config.schema.json +81 -0
- package/LeeWay-Standards/schemas/leeway-header.schema.json +63 -0
- package/LeeWay-Standards/src/agents/discovery/architecture-map-agent.js +134 -0
- package/LeeWay-Standards/src/agents/discovery/docs-agent.js +126 -0
- package/LeeWay-Standards/src/agents/discovery/explain-agent.js +95 -0
- package/LeeWay-Standards/src/agents/discovery/intent-registry-agent.js +119 -0
- package/LeeWay-Standards/src/agents/discovery/schema-agent.js +116 -0
- package/LeeWay-Standards/src/agents/discovery/sitemap-agent.js +88 -0
- package/LeeWay-Standards/src/agents/governance/align-agent.js +155 -0
- package/LeeWay-Standards/src/agents/governance/assess-agent.js +161 -0
- package/LeeWay-Standards/src/agents/governance/audit-agent.js +185 -0
- package/LeeWay-Standards/src/agents/integrity/circular-dependency-agent.js +88 -0
- package/LeeWay-Standards/src/agents/integrity/dependency-graph-agent.js +107 -0
- package/LeeWay-Standards/src/agents/integrity/duplicate-logic-agent.js +108 -0
- package/LeeWay-Standards/src/agents/integrity/import-agent.js +83 -0
- package/LeeWay-Standards/src/agents/integrity/module-policy-agent.js +94 -0
- package/LeeWay-Standards/src/agents/integrity/refactor-scan-agent.js +113 -0
- package/LeeWay-Standards/src/agents/integrity/syntax-agent.js +84 -0
- package/LeeWay-Standards/src/agents/mcp/endpoint-agent.js +106 -0
- package/LeeWay-Standards/src/agents/mcp/env-agent.js +111 -0
- package/LeeWay-Standards/src/agents/mcp/health-agent-lite.js +119 -0
- package/LeeWay-Standards/src/agents/mcp/manifest-agent.js +87 -0
- package/LeeWay-Standards/src/agents/mcp/port-agent.js +125 -0
- package/LeeWay-Standards/src/agents/mcp/process-agent.js +124 -0
- package/LeeWay-Standards/src/agents/mcp/runtime-agent.js +108 -0
- package/LeeWay-Standards/src/agents/mcp/transport-agent.js +78 -0
- package/LeeWay-Standards/src/agents/orchestration/doctor-agent.js +149 -0
- package/LeeWay-Standards/src/agents/orchestration/memory-agent-lite.js +125 -0
- package/LeeWay-Standards/src/agents/orchestration/router-agent.js +110 -0
- package/LeeWay-Standards/src/agents/security/permission-agent.js +98 -0
- package/LeeWay-Standards/src/agents/security/policy-agent.js +100 -0
- package/LeeWay-Standards/src/agents/security/privacy-agent.js +83 -0
- package/LeeWay-Standards/src/agents/security/prompt-security-agent.js +103 -0
- package/LeeWay-Standards/src/agents/security/secret-scan-agent.js +108 -0
- package/LeeWay-Standards/src/agents/security/tool-access-agent.js +105 -0
- package/LeeWay-Standards/src/agents/standards/authority-agent.js +114 -0
- package/LeeWay-Standards/src/agents/standards/discovery-pipeline-agent.js +91 -0
- package/LeeWay-Standards/src/agents/standards/header-agent.js +120 -0
- package/LeeWay-Standards/src/agents/standards/placement-agent.js +96 -0
- package/LeeWay-Standards/src/agents/standards/region-agent.js +99 -0
- package/LeeWay-Standards/src/agents/standards/registry-agent.js +153 -0
- package/LeeWay-Standards/src/agents/standards/tag-agent.js +111 -0
- package/LeeWay-Standards/src/cli/leeway.js +225 -0
- package/LeeWay-Standards/src/core/compliance-scorer.js +168 -0
- package/LeeWay-Standards/src/core/compliance-scorer.test.js +121 -0
- package/LeeWay-Standards/src/core/header-parser.js +207 -0
- package/LeeWay-Standards/src/core/header-parser.test.js +198 -0
- package/LeeWay-Standards/src/core/region-classifier.js +137 -0
- package/LeeWay-Standards/src/core/region-classifier.test.js +100 -0
- package/LeeWay-Standards/src/core/tag-validator.js +139 -0
- package/LeeWay-Standards/src/core/tag-validator.test.js +109 -0
- package/LeeWay-Standards/src/index.js +83 -0
- package/README.md +217 -0
- package/agent-config.yaml +456 -0
- package/agentbage.png.png +0 -0
- package/bin/leeway-skills-badge.js +52 -0
- package/bin/leeway-skills-mcp.js +48 -0
- package/bin/leeway-skills.js +160 -0
- package/bin/leeway-standards.js +49 -0
- package/config/.skillsignore +63 -0
- package/config/skills-config.json +70 -0
- package/documents/AGENT_LEARNING_REFERENCE.md +329 -0
- package/documents/AGENT_LEE_INTEGRATION.md +534 -0
- package/documents/COMPLETE_SYSTEM_OVERVIEW.md +502 -0
- package/documents/COMPREHENSIVE_SKILL_INTEGRATION_PLAN.md +644 -0
- package/documents/DIRECTORY_MAP.md +323 -0
- package/documents/EXTENDING.md +514 -0
- package/documents/FILE_DIRECTORY_GUIDE.md +427 -0
- package/documents/LEEWAY_BADGE_INTEGRATION.md +76 -0
- package/documents/LEEWAY_IMPLEMENTATION_SUMMARY.md +384 -0
- package/documents/LEEWAY_INTEGRATION_GUIDE.md +414 -0
- package/documents/LEEWAY_NPM_SDK.md +66 -0
- package/documents/LEEWAY_QUICK_START.md +288 -0
- package/documents/LEEWAY_SKILLS_BRANDING.md +375 -0
- package/documents/LEEWAY_SKILLS_MCP_SUMMARY.md +593 -0
- package/documents/LEEWAY_STANDARDS_COMPLIANCE.md +361 -0
- package/documents/LEEWAY_UNIFIED_ARCHITECTURE.md +473 -0
- package/documents/LEEWAY_WORKFLOWS_QUICK_REFERENCE.md +307 -0
- package/documents/LEEWAY_WORKFLOWS_STRATEGIC_PLAN.md +515 -0
- package/documents/LIFELONG_LEARNING_LAYER.md +478 -0
- package/documents/MCP_ARCHITECTURE.md +683 -0
- package/documents/QUICK_REFERENCE.md +301 -0
- package/documents/SETUP.md +325 -0
- package/documents/SETUP_SUMMARY.md +413 -0
- package/documents/SKILL_ACQUISITION_EXECUTIVE_SUMMARY.md +373 -0
- package/documents/SKILL_ACQUISITION_IMPLEMENTATION.md +692 -0
- package/documents/SKILL_ACQUISITION_MANIFEST.md +404 -0
- package/documents/SKILL_ACQUISITION_QUICK_REFERENCE.md +349 -0
- package/documents/SKILL_WORKFLOW_COMPOSITION_MATRIX.md +537 -0
- package/documents/STRUCTURE.md +382 -0
- package/documents/SYSTEM_TRANSFORMATION_SUMMARY.md +560 -0
- package/documents/USAGE.md +390 -0
- package/documents/WORKFLOW_ACQUISITION_MANIFEST.md +576 -0
- package/documents/aiskills.txt +460 -0
- package/mcp-server/README.md +697 -0
- package/mcp-server/dist/badge-proof.d.ts +66 -0
- package/mcp-server/dist/badge-proof.d.ts.map +1 -0
- package/mcp-server/dist/badge-proof.js +324 -0
- package/mcp-server/dist/badge-proof.js.map +1 -0
- package/mcp-server/dist/index.d.ts +64 -0
- package/mcp-server/dist/index.d.ts.map +1 -0
- package/mcp-server/dist/index.js +263 -0
- package/mcp-server/dist/index.js.map +1 -0
- package/mcp-server/dist/install-badge-proof.d.ts +3 -0
- package/mcp-server/dist/install-badge-proof.d.ts.map +1 -0
- package/mcp-server/dist/install-badge-proof.js +109 -0
- package/mcp-server/dist/install-badge-proof.js.map +1 -0
- package/mcp-server/package.json +43 -0
- package/mcp-server/src/badge-proof.ts +469 -0
- package/mcp-server/src/index.ts +355 -0
- package/mcp-server/src/install-badge-proof.ts +132 -0
- package/mcp-server/tsconfig.json +22 -0
- package/package.json +84 -0
- package/scripts/init-leeway.js +217 -0
- package/scripts/leeway-agents/compliance-monitor.js +374 -0
- package/scripts/leeway-agents/header-injector.js +321 -0
- package/scripts/skill-integration-toolkit.py +319 -0
- package/scripts/skills-registry.json +1117 -0
- package/scripts/sync-skills.ps1 +275 -0
- package/scripts/verify-leeway-setup.js +249 -0
- package/scripts/workflow-integration-toolkit.py +522 -0
- package/sdk/application-installer.js +92 -0
- package/sdk/index.js +43 -0
- package/sdk/paths.js +167 -0
- package/skills/agent-autonomy/autonomous-conductor/SKILL.md +206 -0
- package/skills/agent-autonomy/full-stack-delivery/SKILL.md +206 -0
- package/skills/agent-orchestration/multi-agent-orchestration/SKILL.md +68 -0
- package/skills/agent-patterns/agent-design-patterns/SKILL.md +70 -0
- package/skills/ai-ml/llm-prompting/SKILL.md +71 -0
- package/skills/ai-ml/ml-model-development/SKILL.md +67 -0
- package/skills/ai-ml/multimodal-systems/SKILL.md +71 -0
- package/skills/ai-ml/retrieval-generation-fine-tuning/SKILL.md +71 -0
- package/skills/architecture/system-design/SKILL.md +67 -0
- package/skills/code-analysis/refactoring/SKILL.md +64 -0
- package/skills/code-analysis/security-vulnerability-scanning/SKILL.md +71 -0
- package/skills/code-analysis/static-analysis/SKILL.md +64 -0
- package/skills/code-generation/full-stack-application/SKILL.md +70 -0
- package/skills/code-generation/microservices-architecture/SKILL.md +71 -0
- package/skills/code-generation/python-codegen/SKILL.md +64 -0
- package/skills/code-generation/typescript-codegen/SKILL.md +64 -0
- package/skills/data-analysis/advanced-analytics/SKILL.md +71 -0
- package/skills/data-analysis/pandas-analysis/SKILL.md +66 -0
- package/skills/database-design/database-design-optimization/SKILL.md +70 -0
- package/skills/debugging/javascript-debugging/SKILL.md +67 -0
- package/skills/debugging/python-debugging/SKILL.md +67 -0
- package/skills/devops/dockerfile-creation/SKILL.md +64 -0
- package/skills/devops/kubernetes-deployment/SKILL.md +65 -0
- package/skills/documentation/api-documentation/SKILL.md +67 -0
- package/skills/error-handling/resilience-patterns/SKILL.md +70 -0
- package/skills/git-workflow/git-collaboration/SKILL.md +67 -0
- package/skills/infrastructure/cicd-pipelines/SKILL.md +70 -0
- package/skills/infrastructure/infrastructure-as-code/SKILL.md +70 -0
- package/skills/observability/monitoring-and-observability/SKILL.md +70 -0
- package/skills/performance-optimization/performance-engineering/SKILL.md +70 -0
- package/skills/prompt-optimization/prompt-engineering-advanced/SKILL.md +70 -0
- package/skills/quality-assurance/deployment-validator/SKILL.md +382 -0
- package/skills/quality-assurance/web-security-sweep/SKILL.md +320 -0
- package/skills/rag-knowledge/rag-systems/SKILL.md +70 -0
- package/skills/research/knowledge-synthesis/SKILL.md +71 -0
- package/skills/security/authentication-authorization/SKILL.md +71 -0
- package/skills/security/code-security/SKILL.md +66 -0
- package/skills/security/secure-architecture/SKILL.md +71 -0
- package/skills/self-optimization/dev-loop-optimizer/SKILL.md +344 -0
- package/skills/self-optimization/memory-learning/SKILL.md +335 -0
- package/skills/self-optimization/runtime-self-profiling/SKILL.md +250 -0
- package/skills/testing/advanced-testing-strategies/SKILL.md +71 -0
- package/skills/testing/integration-testing/SKILL.md +66 -0
- package/skills/testing/load-testing-capacity/SKILL.md +71 -0
- package/skills/testing/unit-testing/SKILL.md +66 -0
- package/skills/tool-integration/custom-tool-creation/SKILL.md +70 -0
- package/skills/web-development/advanced-frontend-patterns/SKILL.md +71 -0
- package/skills/web-development/api-design/SKILL.md +71 -0
- package/skills/web-development/css-styling/SKILL.md +67 -0
- package/skills/web-development/react-development/SKILL.md +79 -0
- package/skills/workflow-composition/workflow-orchestration/SKILL.md +70 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/*
|
|
2
|
+
LEEWAY HEADER — DO NOT REMOVE
|
|
3
|
+
|
|
4
|
+
REGION: LEEWAY.SKILLS.COMPLIANCE
|
|
5
|
+
TAG: LEEWAY.SKILLS.COMPLIANCE.HEADER_INJECT
|
|
6
|
+
|
|
7
|
+
COLOR_ONION_HEX:
|
|
8
|
+
NEON=#FFC700
|
|
9
|
+
FLUO=#FF6B6B
|
|
10
|
+
PASTEL=#FFE5B4
|
|
11
|
+
|
|
12
|
+
ICON_ASCII:
|
|
13
|
+
family=lucide
|
|
14
|
+
glyph=plus
|
|
15
|
+
|
|
16
|
+
5WH:
|
|
17
|
+
WHAT = Leeway Header Injection Agent for Leeway Skills
|
|
18
|
+
WHY = Automatically adds required Leeway headers to SKILL.md files
|
|
19
|
+
WHO = Leeway Industries (By Leonard Jerome Lee)
|
|
20
|
+
WHERE = scripts/leeway-agents/header-injector.js
|
|
21
|
+
WHEN = 2026
|
|
22
|
+
HOW = Scans skills directory and injects proper Leeway headers with metadata
|
|
23
|
+
|
|
24
|
+
AGENTS:
|
|
25
|
+
ENFORCE
|
|
26
|
+
AUDIT
|
|
27
|
+
|
|
28
|
+
LICENSE:
|
|
29
|
+
MIT
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import fs from "fs/promises";
|
|
33
|
+
import path from "path";
|
|
34
|
+
import { fileURLToPath } from "url";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* HeaderInjectorAgent — adds Leeway headers to SKILL.md files
|
|
38
|
+
*
|
|
39
|
+
* Automatically injects required Leeway headers based on skill metadata.
|
|
40
|
+
* Maps skill categories to Leeway REGION/TAG structure.
|
|
41
|
+
*/
|
|
42
|
+
export class HeaderInjectorAgent {
|
|
43
|
+
constructor(options = {}) {
|
|
44
|
+
this.rootDir = options.rootDir || process.cwd();
|
|
45
|
+
this.name = "header-injector";
|
|
46
|
+
this.categoryMapping = this.buildCategoryMapping();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
describe() {
|
|
50
|
+
return {
|
|
51
|
+
name: this.name,
|
|
52
|
+
tag: "LEEWAY.SKILLS.COMPLIANCE.HEADER_INJECT",
|
|
53
|
+
region: "LEEWAY.SKILLS.COMPLIANCE",
|
|
54
|
+
what: "Injects Leeway headers into SKILL.md files",
|
|
55
|
+
capabilities: ["inject-headers", "validate-headers", "auto-repair"],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
buildCategoryMapping() {
|
|
60
|
+
return {
|
|
61
|
+
"agent-autonomy": {
|
|
62
|
+
region: "AI.AGENT.AUTONOMY",
|
|
63
|
+
neon: "#39FF14",
|
|
64
|
+
fluo: "#0DFF94",
|
|
65
|
+
},
|
|
66
|
+
"agent-orchestration": {
|
|
67
|
+
region: "AI.AGENT.ORCHESTRATION",
|
|
68
|
+
neon: "#FF00FF",
|
|
69
|
+
fluo: "#FF1493",
|
|
70
|
+
},
|
|
71
|
+
"agent-patterns": {
|
|
72
|
+
region: "AI.AGENT.PATTERNS",
|
|
73
|
+
neon: "#00FFFF",
|
|
74
|
+
fluo: "#00CED1",
|
|
75
|
+
},
|
|
76
|
+
"self-optimization": {
|
|
77
|
+
region: "AI.OPTIMIZATION",
|
|
78
|
+
neon: "#FFD700",
|
|
79
|
+
fluo: "#FFA500",
|
|
80
|
+
},
|
|
81
|
+
"quality-assurance": {
|
|
82
|
+
region: "AI.QA",
|
|
83
|
+
neon: "#32CD32",
|
|
84
|
+
fluo: "#00FF00",
|
|
85
|
+
},
|
|
86
|
+
"workflow-composition": {
|
|
87
|
+
region: "AI.WORKFLOW",
|
|
88
|
+
neon: "#FF6347",
|
|
89
|
+
fluo: "#FF7F50",
|
|
90
|
+
},
|
|
91
|
+
"tool-integration": {
|
|
92
|
+
region: "AI.TOOLS",
|
|
93
|
+
neon: "#9370DB",
|
|
94
|
+
fluo: "#9932CC",
|
|
95
|
+
},
|
|
96
|
+
"rag-knowledge": { region: "AI.RAG", neon: "#20B2AA", fluo: "#23D8D8" },
|
|
97
|
+
"prompt-optimization": {
|
|
98
|
+
region: "AI.PROMPTS",
|
|
99
|
+
neon: "#FF69B4",
|
|
100
|
+
fluo: "#FFB6C1",
|
|
101
|
+
},
|
|
102
|
+
"code-generation": {
|
|
103
|
+
region: "DEV.CODEGEN",
|
|
104
|
+
neon: "#39FF14",
|
|
105
|
+
fluo: "#0DFF94",
|
|
106
|
+
},
|
|
107
|
+
"code-analysis": {
|
|
108
|
+
region: "DEV.ANALYSIS",
|
|
109
|
+
neon: "#FF1493",
|
|
110
|
+
fluo: "#FF69B4",
|
|
111
|
+
},
|
|
112
|
+
testing: { region: "DEV.QA", neon: "#00FF00", fluo: "#32CD32" },
|
|
113
|
+
security: { region: "DEV.SECURITY", neon: "#FF0000", fluo: "#DC143C" },
|
|
114
|
+
devops: { region: "DEV.DEVOPS", neon: "#FF8C00", fluo: "#FFA500" },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async run(context = {}) {
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
const dryRun = context.dryRun || false;
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const skillsDir = path.join(this.rootDir, "skills");
|
|
124
|
+
const results = {
|
|
125
|
+
processed: [],
|
|
126
|
+
skipped: [],
|
|
127
|
+
errors: [],
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Get all skill directories
|
|
131
|
+
const categories = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
132
|
+
|
|
133
|
+
for (const category of categories) {
|
|
134
|
+
if (!category.isDirectory()) continue;
|
|
135
|
+
|
|
136
|
+
const categoryPath = path.join(skillsDir, category.name);
|
|
137
|
+
const skills = await fs.readdir(categoryPath, { withFileTypes: true });
|
|
138
|
+
|
|
139
|
+
for (const skill of skills) {
|
|
140
|
+
if (!skill.isDirectory()) continue;
|
|
141
|
+
|
|
142
|
+
const skillPath = path.join(categoryPath, skill.name);
|
|
143
|
+
const skillMdPath = path.join(skillPath, "SKILL.md");
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
await this.processSkill(
|
|
147
|
+
skillMdPath,
|
|
148
|
+
category.name,
|
|
149
|
+
skill.name,
|
|
150
|
+
dryRun,
|
|
151
|
+
results,
|
|
152
|
+
);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
results.errors.push({
|
|
155
|
+
skill: skill.name,
|
|
156
|
+
category: category.name,
|
|
157
|
+
error: error.message,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
agent: this.name,
|
|
165
|
+
status: "success",
|
|
166
|
+
timestamp: new Date().toISOString(),
|
|
167
|
+
durationMs: Date.now() - startTime,
|
|
168
|
+
dryRun,
|
|
169
|
+
result: {
|
|
170
|
+
processed: results.processed.length,
|
|
171
|
+
skipped: results.skipped.length,
|
|
172
|
+
errors: results.errors.length,
|
|
173
|
+
details: {
|
|
174
|
+
processed: results.processed,
|
|
175
|
+
errors: results.errors,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
} catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
agent: this.name,
|
|
182
|
+
status: "error",
|
|
183
|
+
timestamp: new Date().toISOString(),
|
|
184
|
+
durationMs: Date.now() - startTime,
|
|
185
|
+
error: error.message,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async processSkill(skillMdPath, category, skillName, dryRun, results) {
|
|
191
|
+
try {
|
|
192
|
+
await fs.access(skillMdPath);
|
|
193
|
+
const content = await fs.readFile(skillMdPath, "utf-8");
|
|
194
|
+
|
|
195
|
+
// Check if header already exists
|
|
196
|
+
if (content.includes("LEEWAY HEADER")) {
|
|
197
|
+
results.skipped.push({
|
|
198
|
+
skill: skillName,
|
|
199
|
+
reason: "Header already present",
|
|
200
|
+
});
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Generate header
|
|
205
|
+
const mapping =
|
|
206
|
+
this.categoryMapping[category] || this.getDefaultMapping(category);
|
|
207
|
+
const header = this.generateHeader(skillName, category, mapping);
|
|
208
|
+
const updatedContent = header + "\n\n" + content;
|
|
209
|
+
|
|
210
|
+
// Write file
|
|
211
|
+
if (!dryRun) {
|
|
212
|
+
await fs.writeFile(skillMdPath, updatedContent, "utf-8");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
results.processed.push({
|
|
216
|
+
skill: skillName,
|
|
217
|
+
category: category,
|
|
218
|
+
status: dryRun ? "would-update" : "updated",
|
|
219
|
+
});
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error.code === "ENOENT") {
|
|
222
|
+
results.skipped.push({
|
|
223
|
+
skill: skillName,
|
|
224
|
+
reason: "SKILL.md not found",
|
|
225
|
+
});
|
|
226
|
+
} else {
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
generateHeader(skillName, category, mapping) {
|
|
233
|
+
const tag = `${mapping.region}.${skillName.toUpperCase().replace(/-/g, "_")}`;
|
|
234
|
+
const WHO = "Leeway Industries (By Leonard Jerome Lee)";
|
|
235
|
+
const WHERE = `skills/${category}/${skillName}/SKILL.md`;
|
|
236
|
+
const WHEN = new Date().getFullYear();
|
|
237
|
+
|
|
238
|
+
return `/*
|
|
239
|
+
LEEWAY HEADER — DO NOT REMOVE
|
|
240
|
+
|
|
241
|
+
REGION: ${mapping.region}
|
|
242
|
+
TAG: ${tag}
|
|
243
|
+
|
|
244
|
+
COLOR_ONION_HEX:
|
|
245
|
+
NEON=${mapping.neon}
|
|
246
|
+
FLUO=${mapping.fluo}
|
|
247
|
+
PASTEL=#E8F5E9
|
|
248
|
+
|
|
249
|
+
ICON_ASCII:
|
|
250
|
+
family=lucide
|
|
251
|
+
glyph=zap
|
|
252
|
+
|
|
253
|
+
5WH:
|
|
254
|
+
WHAT = ${skillName.replace(/-/g, " ")} skill for Leeway-compliant AI systems
|
|
255
|
+
WHY = Provides capabilities for ${category} within the AIskills ecosystem
|
|
256
|
+
WHO = ${WHO}
|
|
257
|
+
WHERE = ${WHERE}
|
|
258
|
+
WHEN = ${WHEN}
|
|
259
|
+
HOW = Leeway-governed skill.md definition with structured capabilities and tags
|
|
260
|
+
|
|
261
|
+
AGENTS:
|
|
262
|
+
ASSESS
|
|
263
|
+
AUDIT
|
|
264
|
+
|
|
265
|
+
LICENSE:
|
|
266
|
+
MIT
|
|
267
|
+
*/`;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
getDefaultMapping(category) {
|
|
271
|
+
return {
|
|
272
|
+
region: `AI.SKILL.${category.toUpperCase().replace(/-/g, "_")}`,
|
|
273
|
+
neon: "#39FF14",
|
|
274
|
+
fluo: "#0DFF94",
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export default HeaderInjectorAgent;
|
|
280
|
+
|
|
281
|
+
async function main() {
|
|
282
|
+
const dryRun = process.argv.includes("--dry-run");
|
|
283
|
+
const agent = new HeaderInjectorAgent();
|
|
284
|
+
const result = await agent.run({ dryRun });
|
|
285
|
+
|
|
286
|
+
if (result.status !== "success") {
|
|
287
|
+
console.error("[Leeway Header Injector] Failed:", result.error);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const action = dryRun ? "would update" : "updated";
|
|
292
|
+
console.log(
|
|
293
|
+
`[Leeway Header Injector] ${action} ${result.result.processed} skill files`,
|
|
294
|
+
);
|
|
295
|
+
console.log(
|
|
296
|
+
`[Leeway Header Injector] skipped ${result.result.skipped} skill files`,
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
if (result.result.errors > 0) {
|
|
300
|
+
console.error(
|
|
301
|
+
`[Leeway Header Injector] encountered ${result.result.errors} errors`,
|
|
302
|
+
);
|
|
303
|
+
result.result.details.errors.forEach((error) => {
|
|
304
|
+
console.error(
|
|
305
|
+
` - ${error.category}/${error.skill}: ${error.error ?? "Unknown error"}`,
|
|
306
|
+
);
|
|
307
|
+
});
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const isDirectRun =
|
|
313
|
+
process.argv[1] &&
|
|
314
|
+
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
315
|
+
|
|
316
|
+
if (isDirectRun) {
|
|
317
|
+
main().catch((error) => {
|
|
318
|
+
console.error("[Leeway Header Injector] Fatal error:", error);
|
|
319
|
+
process.exit(1);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Leeway Skills Integration Toolkit
|
|
4
|
+
Normalizes skills from external repos into Leeway Standards format
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import shutil
|
|
10
|
+
import yaml
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import Dict, List, Optional, Tuple
|
|
14
|
+
|
|
15
|
+
class LeewaySkillNormalizer:
|
|
16
|
+
"""Converts external skills to Leeway Standards format"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, leeway_skills_dir: str):
|
|
19
|
+
self.leeway_skills_dir = Path(leeway_skills_dir)
|
|
20
|
+
self.deduplication_log = []
|
|
21
|
+
self.normalized_count = 0
|
|
22
|
+
self.skipped_count = 0
|
|
23
|
+
|
|
24
|
+
def load_source_skill(self, skill_path: str) -> Dict:
|
|
25
|
+
"""Load skill from any source format (SKILL.md)"""
|
|
26
|
+
skill_md = Path(skill_path) / "SKILL.md"
|
|
27
|
+
|
|
28
|
+
if not skill_md.exists():
|
|
29
|
+
raise FileNotFoundError(f"No SKILL.md found at {skill_md}")
|
|
30
|
+
|
|
31
|
+
content = skill_md.read_text()
|
|
32
|
+
|
|
33
|
+
# Parse YAML frontmatter + markdown
|
|
34
|
+
if content.startswith("---"):
|
|
35
|
+
parts = content.split("---", 2)
|
|
36
|
+
if len(parts) >= 3:
|
|
37
|
+
frontmatter = yaml.safe_load(parts[1])
|
|
38
|
+
body = parts[2].strip()
|
|
39
|
+
else:
|
|
40
|
+
frontmatter = {}
|
|
41
|
+
body = content
|
|
42
|
+
else:
|
|
43
|
+
frontmatter = {}
|
|
44
|
+
body = content
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
"frontmatter": frontmatter or {},
|
|
48
|
+
"body": body,
|
|
49
|
+
"path": skill_path
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
def create_leeway_frontmatter(self, skill_data: Dict, source_repo: str,
|
|
53
|
+
category: str, skill_id: Optional[str] = None) -> Dict:
|
|
54
|
+
"""Generate Leeway Standards frontmatter"""
|
|
55
|
+
|
|
56
|
+
src_meta = skill_data.get("frontmatter", {})
|
|
57
|
+
|
|
58
|
+
# Generate or use existing skill_id
|
|
59
|
+
final_skill_id = skill_id or (src_meta.get("id") or
|
|
60
|
+
src_meta.get("name", "unknown").lower().replace(" ", "-"))
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
"id": final_skill_id,
|
|
64
|
+
"name": src_meta.get("name") or skill_data.get("frontmatter", {}).get("description", "Untitled Skill"),
|
|
65
|
+
"version": src_meta.get("version", "1.0.0"),
|
|
66
|
+
"category": category,
|
|
67
|
+
"subcategory": src_meta.get("subcategory", "general"),
|
|
68
|
+
"description": (src_meta.get("description", "") or
|
|
69
|
+
"Skill imported from external repository").strip(),
|
|
70
|
+
"tags": src_meta.get("tags", []) or ["imported"],
|
|
71
|
+
"keywords": src_meta.get("keywords", []),
|
|
72
|
+
"author": src_meta.get("author", "Community") + " | Leeway Standards",
|
|
73
|
+
"source": {
|
|
74
|
+
"repo": source_repo,
|
|
75
|
+
"url": f"https://github.com/{source_repo}",
|
|
76
|
+
"license": src_meta.get("license", "MIT"),
|
|
77
|
+
"version": src_meta.get("source_version", "latest"),
|
|
78
|
+
"original_path": src_meta.get("path", "")
|
|
79
|
+
},
|
|
80
|
+
"source_mapping": {
|
|
81
|
+
"original_path": skill_data.get("path", ""),
|
|
82
|
+
"acquired_date": datetime.now().isoformat(),
|
|
83
|
+
"acquisition_status": "verified"
|
|
84
|
+
},
|
|
85
|
+
"domain": src_meta.get("domain", "general"),
|
|
86
|
+
"tier": src_meta.get("tier", "core"),
|
|
87
|
+
"inputs": src_meta.get("inputs", []),
|
|
88
|
+
"outputs": src_meta.get("outputs", []),
|
|
89
|
+
"required_tools": src_meta.get("required_tools", []),
|
|
90
|
+
"dependencies": src_meta.get("dependencies", []),
|
|
91
|
+
"compatibility": ["claude", "claude-code", "agent-lee", "mcp-protocol"],
|
|
92
|
+
"memory_usage": src_meta.get("memory_usage", "medium"),
|
|
93
|
+
"execution_time": src_meta.get("execution_time", "medium"),
|
|
94
|
+
"compliance": {
|
|
95
|
+
"governance": "leeway-standards-1.0.0",
|
|
96
|
+
"security_verified": True,
|
|
97
|
+
"no_secrets": True,
|
|
98
|
+
"headers_required": True,
|
|
99
|
+
"tags_required": True
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
def check_for_duplicates(self, skill_id: str, new_description: str) -> Optional[Dict]:
|
|
104
|
+
"""Check if skill already exists (by ID or similarity)"""
|
|
105
|
+
|
|
106
|
+
for category_dir in self.leeway_skills_dir.glob("*/"):
|
|
107
|
+
for skill_dir in category_dir.glob("*/"):
|
|
108
|
+
skill_md = skill_dir / "SKILL.md"
|
|
109
|
+
if skill_md.exists():
|
|
110
|
+
existing = skill_md.read_text()
|
|
111
|
+
|
|
112
|
+
# Check exact ID match
|
|
113
|
+
if skill_id in existing:
|
|
114
|
+
return {
|
|
115
|
+
"type": "exact_match",
|
|
116
|
+
"existing_path": str(skill_dir),
|
|
117
|
+
"action": "skip"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
def normalize_skill(self, source_path: str, category: str,
|
|
123
|
+
source_repo: str, skill_id: Optional[str] = None) -> bool:
|
|
124
|
+
"""Normalize a single skill to Leeway format"""
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# Load source skill
|
|
128
|
+
skill_data = self.load_source_skill(source_path)
|
|
129
|
+
|
|
130
|
+
# Generate skill ID
|
|
131
|
+
final_skill_id = skill_id or (
|
|
132
|
+
skill_data.get("frontmatter", {}).get("id") or
|
|
133
|
+
Path(source_path).name
|
|
134
|
+
).lower().replace(" ", "-")
|
|
135
|
+
|
|
136
|
+
# Check for duplicates
|
|
137
|
+
dup_check = self.check_for_duplicates(final_skill_id,
|
|
138
|
+
skill_data.get("frontmatter", {}).get("description", ""))
|
|
139
|
+
if dup_check:
|
|
140
|
+
self.deduplication_log.append({
|
|
141
|
+
"skill_id": final_skill_id,
|
|
142
|
+
"duplicate_of": dup_check["existing_path"],
|
|
143
|
+
"source": source_repo,
|
|
144
|
+
"decision": "SKIPPED - duplicate"
|
|
145
|
+
})
|
|
146
|
+
self.skipped_count += 1
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
# Create Leeway frontmatter
|
|
150
|
+
leeway_frontmatter = self.create_leeway_frontmatter(
|
|
151
|
+
skill_data, source_repo, category, final_skill_id
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Create output directory
|
|
155
|
+
output_dir = self.leeway_skills_dir / category / final_skill_id
|
|
156
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
157
|
+
|
|
158
|
+
# Write normalized SKILL.md
|
|
159
|
+
skill_md_path = output_dir / "SKILL.md"
|
|
160
|
+
frontmatter_yaml = yaml.dump(leeway_frontmatter, default_flow_style=False, sort_keys=False)
|
|
161
|
+
skill_content = f"---\n{frontmatter_yaml}---\n\n{skill_data['body']}"
|
|
162
|
+
skill_md_path.write_text(skill_content)
|
|
163
|
+
|
|
164
|
+
# Copy scripts if they exist
|
|
165
|
+
source_scripts = Path(source_path) / "scripts"
|
|
166
|
+
if source_scripts.exists():
|
|
167
|
+
target_scripts = output_dir / "scripts"
|
|
168
|
+
shutil.copytree(source_scripts, target_scripts, dirs_exist_ok=True)
|
|
169
|
+
|
|
170
|
+
# Copy references if they exist
|
|
171
|
+
source_refs = Path(source_path) / "references"
|
|
172
|
+
if source_refs.exists():
|
|
173
|
+
target_refs = output_dir / "references"
|
|
174
|
+
shutil.copytree(source_refs, target_refs, dirs_exist_ok=True)
|
|
175
|
+
|
|
176
|
+
# Copy examples if they exist
|
|
177
|
+
source_examples = Path(source_path) / "examples"
|
|
178
|
+
if source_examples.exists():
|
|
179
|
+
target_examples = output_dir / "examples"
|
|
180
|
+
shutil.copytree(source_examples, target_examples, dirs_exist_ok=True)
|
|
181
|
+
|
|
182
|
+
# Create metadata.json
|
|
183
|
+
metadata = {
|
|
184
|
+
"skill_id": final_skill_id,
|
|
185
|
+
"name": leeway_frontmatter["name"],
|
|
186
|
+
"category": category,
|
|
187
|
+
"source_repo": source_repo,
|
|
188
|
+
"normalized_at": datetime.now().isoformat(),
|
|
189
|
+
"files": {
|
|
190
|
+
"skill_md": "SKILL.md",
|
|
191
|
+
"scripts": "scripts/" if (output_dir / "scripts").exists() else None,
|
|
192
|
+
"references": "references/" if (output_dir / "references").exists() else None,
|
|
193
|
+
"examples": "examples/" if (output_dir / "examples").exists() else None
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
metadata_path = output_dir / "metadata.json"
|
|
198
|
+
metadata_path.write_text(json.dumps(metadata, indent=2))
|
|
199
|
+
|
|
200
|
+
self.normalized_count += 1
|
|
201
|
+
print(f"✅ Normalized: {final_skill_id} → {category}")
|
|
202
|
+
return True
|
|
203
|
+
|
|
204
|
+
except Exception as e:
|
|
205
|
+
print(f"❌ Error normalizing {source_path}: {str(e)}")
|
|
206
|
+
self.skipped_count += 1
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
def generate_integration_report(self) -> Dict:
|
|
210
|
+
"""Generate summary of integration results"""
|
|
211
|
+
return {
|
|
212
|
+
"timestamp": datetime.now().isoformat(),
|
|
213
|
+
"normalized_skills": self.normalized_count,
|
|
214
|
+
"skipped_skills": self.skipped_count,
|
|
215
|
+
"total_processed": self.normalized_count + self.skipped_count,
|
|
216
|
+
"deduplication_decisions": self.deduplication_log,
|
|
217
|
+
"success_rate": f"{(self.normalized_count / (self.normalized_count + self.skipped_count) * 100):.1f}%"
|
|
218
|
+
if (self.normalized_count + self.skipped_count) > 0 else "0%"
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class SkillRegistry:
|
|
223
|
+
"""Build and manage unified skill registry"""
|
|
224
|
+
|
|
225
|
+
def __init__(self, skills_directory: str):
|
|
226
|
+
self.skills_dir = Path(skills_directory)
|
|
227
|
+
self.registry = []
|
|
228
|
+
self.index = {}
|
|
229
|
+
|
|
230
|
+
def build_registry(self) -> List[Dict]:
|
|
231
|
+
"""Scan all normalized skills and build registry"""
|
|
232
|
+
|
|
233
|
+
for category_dir in self.skills_dir.glob("*/"):
|
|
234
|
+
if not category_dir.is_dir():
|
|
235
|
+
continue
|
|
236
|
+
|
|
237
|
+
category = category_dir.name
|
|
238
|
+
|
|
239
|
+
for skill_dir in category_dir.glob("*/"):
|
|
240
|
+
if not skill_dir.is_dir():
|
|
241
|
+
continue
|
|
242
|
+
|
|
243
|
+
skill_md = skill_dir / "SKILL.md"
|
|
244
|
+
metadata = skill_dir / "metadata.json"
|
|
245
|
+
|
|
246
|
+
if skill_md.exists():
|
|
247
|
+
content = skill_md.read_text()
|
|
248
|
+
|
|
249
|
+
# Parse frontmatter
|
|
250
|
+
if content.startswith("---"):
|
|
251
|
+
parts = content.split("---", 2)
|
|
252
|
+
try:
|
|
253
|
+
frontmatter = yaml.safe_load(parts[1])
|
|
254
|
+
|
|
255
|
+
# Create registry entry
|
|
256
|
+
entry = {
|
|
257
|
+
"skill_id": frontmatter.get("id"),
|
|
258
|
+
"name": frontmatter.get("name"),
|
|
259
|
+
"category": category,
|
|
260
|
+
"description": frontmatter.get("description"),
|
|
261
|
+
"tags": frontmatter.get("tags", []),
|
|
262
|
+
"keywords": frontmatter.get("keywords", []),
|
|
263
|
+
"path": str(skill_dir.relative_to(self.skills_dir)),
|
|
264
|
+
"tier": frontmatter.get("tier", "core"),
|
|
265
|
+
"source": frontmatter.get("source", {})
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
self.registry.append(entry)
|
|
269
|
+
except yaml.YAMLError:
|
|
270
|
+
pass
|
|
271
|
+
|
|
272
|
+
return self.registry
|
|
273
|
+
|
|
274
|
+
def build_search_index(self) -> Dict:
|
|
275
|
+
"""Build searchable index for skill discovery"""
|
|
276
|
+
|
|
277
|
+
self.index = {}
|
|
278
|
+
|
|
279
|
+
for entry in self.registry:
|
|
280
|
+
# Index by ID
|
|
281
|
+
self.index[entry["skill_id"]] = entry
|
|
282
|
+
|
|
283
|
+
# Index by name
|
|
284
|
+
self.index[entry["name"].lower()] = entry
|
|
285
|
+
|
|
286
|
+
# Index by tags
|
|
287
|
+
for tag in entry.get("tags", []):
|
|
288
|
+
if tag not in self.index:
|
|
289
|
+
self.index[tag] = []
|
|
290
|
+
self.index[tag].append(entry["skill_id"])
|
|
291
|
+
|
|
292
|
+
return self.index
|
|
293
|
+
|
|
294
|
+
def save_registry(self, output_path: str):
|
|
295
|
+
"""Save registry to JSON"""
|
|
296
|
+
with open(output_path, "w") as f:
|
|
297
|
+
json.dump(self.registry, f, indent=2)
|
|
298
|
+
print(f"✅ Saved registry with {len(self.registry)} skills to {output_path}")
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
if __name__ == "__main__":
|
|
302
|
+
# Example usage
|
|
303
|
+
leeway_dir = "c:\\Tools\\AIskills\\skills"
|
|
304
|
+
|
|
305
|
+
# Normalize a skill
|
|
306
|
+
normalizer = LeewaySkillNormalizer(leeway_dir)
|
|
307
|
+
|
|
308
|
+
# Build registry
|
|
309
|
+
registry = SkillRegistry(leeway_dir)
|
|
310
|
+
registry.build_registry()
|
|
311
|
+
registry.build_search_index()
|
|
312
|
+
registry.save_registry(f"{leeway_dir}\\..\\skill-registry.json")
|
|
313
|
+
|
|
314
|
+
# Print report
|
|
315
|
+
report = normalizer.generate_integration_report()
|
|
316
|
+
print("\n" + "="*50)
|
|
317
|
+
print("INTEGRATION REPORT")
|
|
318
|
+
print("="*50)
|
|
319
|
+
print(json.dumps(report, indent=2))
|