@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.
Files changed (182) hide show
  1. package/.leeway/config.json +133 -0
  2. package/LICENSE +21 -0
  3. package/LeeWay-Standards/LICENSE +21 -0
  4. package/LeeWay-Standards/README.md +324 -0
  5. package/LeeWay-Standards/examples/NexusButton.tsx +90 -0
  6. package/LeeWay-Standards/examples/example-agent.js +89 -0
  7. package/LeeWay-Standards/package.json +61 -0
  8. package/LeeWay-Standards/schemas/leeway-config.schema.json +81 -0
  9. package/LeeWay-Standards/schemas/leeway-header.schema.json +63 -0
  10. package/LeeWay-Standards/src/agents/discovery/architecture-map-agent.js +134 -0
  11. package/LeeWay-Standards/src/agents/discovery/docs-agent.js +126 -0
  12. package/LeeWay-Standards/src/agents/discovery/explain-agent.js +95 -0
  13. package/LeeWay-Standards/src/agents/discovery/intent-registry-agent.js +119 -0
  14. package/LeeWay-Standards/src/agents/discovery/schema-agent.js +116 -0
  15. package/LeeWay-Standards/src/agents/discovery/sitemap-agent.js +88 -0
  16. package/LeeWay-Standards/src/agents/governance/align-agent.js +155 -0
  17. package/LeeWay-Standards/src/agents/governance/assess-agent.js +161 -0
  18. package/LeeWay-Standards/src/agents/governance/audit-agent.js +185 -0
  19. package/LeeWay-Standards/src/agents/integrity/circular-dependency-agent.js +88 -0
  20. package/LeeWay-Standards/src/agents/integrity/dependency-graph-agent.js +107 -0
  21. package/LeeWay-Standards/src/agents/integrity/duplicate-logic-agent.js +108 -0
  22. package/LeeWay-Standards/src/agents/integrity/import-agent.js +83 -0
  23. package/LeeWay-Standards/src/agents/integrity/module-policy-agent.js +94 -0
  24. package/LeeWay-Standards/src/agents/integrity/refactor-scan-agent.js +113 -0
  25. package/LeeWay-Standards/src/agents/integrity/syntax-agent.js +84 -0
  26. package/LeeWay-Standards/src/agents/mcp/endpoint-agent.js +106 -0
  27. package/LeeWay-Standards/src/agents/mcp/env-agent.js +111 -0
  28. package/LeeWay-Standards/src/agents/mcp/health-agent-lite.js +119 -0
  29. package/LeeWay-Standards/src/agents/mcp/manifest-agent.js +87 -0
  30. package/LeeWay-Standards/src/agents/mcp/port-agent.js +125 -0
  31. package/LeeWay-Standards/src/agents/mcp/process-agent.js +124 -0
  32. package/LeeWay-Standards/src/agents/mcp/runtime-agent.js +108 -0
  33. package/LeeWay-Standards/src/agents/mcp/transport-agent.js +78 -0
  34. package/LeeWay-Standards/src/agents/orchestration/doctor-agent.js +149 -0
  35. package/LeeWay-Standards/src/agents/orchestration/memory-agent-lite.js +125 -0
  36. package/LeeWay-Standards/src/agents/orchestration/router-agent.js +110 -0
  37. package/LeeWay-Standards/src/agents/security/permission-agent.js +98 -0
  38. package/LeeWay-Standards/src/agents/security/policy-agent.js +100 -0
  39. package/LeeWay-Standards/src/agents/security/privacy-agent.js +83 -0
  40. package/LeeWay-Standards/src/agents/security/prompt-security-agent.js +103 -0
  41. package/LeeWay-Standards/src/agents/security/secret-scan-agent.js +108 -0
  42. package/LeeWay-Standards/src/agents/security/tool-access-agent.js +105 -0
  43. package/LeeWay-Standards/src/agents/standards/authority-agent.js +114 -0
  44. package/LeeWay-Standards/src/agents/standards/discovery-pipeline-agent.js +91 -0
  45. package/LeeWay-Standards/src/agents/standards/header-agent.js +120 -0
  46. package/LeeWay-Standards/src/agents/standards/placement-agent.js +96 -0
  47. package/LeeWay-Standards/src/agents/standards/region-agent.js +99 -0
  48. package/LeeWay-Standards/src/agents/standards/registry-agent.js +153 -0
  49. package/LeeWay-Standards/src/agents/standards/tag-agent.js +111 -0
  50. package/LeeWay-Standards/src/cli/leeway.js +225 -0
  51. package/LeeWay-Standards/src/core/compliance-scorer.js +168 -0
  52. package/LeeWay-Standards/src/core/compliance-scorer.test.js +121 -0
  53. package/LeeWay-Standards/src/core/header-parser.js +207 -0
  54. package/LeeWay-Standards/src/core/header-parser.test.js +198 -0
  55. package/LeeWay-Standards/src/core/region-classifier.js +137 -0
  56. package/LeeWay-Standards/src/core/region-classifier.test.js +100 -0
  57. package/LeeWay-Standards/src/core/tag-validator.js +139 -0
  58. package/LeeWay-Standards/src/core/tag-validator.test.js +109 -0
  59. package/LeeWay-Standards/src/index.js +83 -0
  60. package/README.md +217 -0
  61. package/agent-config.yaml +456 -0
  62. package/agentbage.png.png +0 -0
  63. package/bin/leeway-skills-badge.js +52 -0
  64. package/bin/leeway-skills-mcp.js +48 -0
  65. package/bin/leeway-skills.js +160 -0
  66. package/bin/leeway-standards.js +49 -0
  67. package/config/.skillsignore +63 -0
  68. package/config/skills-config.json +70 -0
  69. package/documents/AGENT_LEARNING_REFERENCE.md +329 -0
  70. package/documents/AGENT_LEE_INTEGRATION.md +534 -0
  71. package/documents/COMPLETE_SYSTEM_OVERVIEW.md +502 -0
  72. package/documents/COMPREHENSIVE_SKILL_INTEGRATION_PLAN.md +644 -0
  73. package/documents/DIRECTORY_MAP.md +323 -0
  74. package/documents/EXTENDING.md +514 -0
  75. package/documents/FILE_DIRECTORY_GUIDE.md +427 -0
  76. package/documents/LEEWAY_BADGE_INTEGRATION.md +76 -0
  77. package/documents/LEEWAY_IMPLEMENTATION_SUMMARY.md +384 -0
  78. package/documents/LEEWAY_INTEGRATION_GUIDE.md +414 -0
  79. package/documents/LEEWAY_NPM_SDK.md +66 -0
  80. package/documents/LEEWAY_QUICK_START.md +288 -0
  81. package/documents/LEEWAY_SKILLS_BRANDING.md +375 -0
  82. package/documents/LEEWAY_SKILLS_MCP_SUMMARY.md +593 -0
  83. package/documents/LEEWAY_STANDARDS_COMPLIANCE.md +361 -0
  84. package/documents/LEEWAY_UNIFIED_ARCHITECTURE.md +473 -0
  85. package/documents/LEEWAY_WORKFLOWS_QUICK_REFERENCE.md +307 -0
  86. package/documents/LEEWAY_WORKFLOWS_STRATEGIC_PLAN.md +515 -0
  87. package/documents/LIFELONG_LEARNING_LAYER.md +478 -0
  88. package/documents/MCP_ARCHITECTURE.md +683 -0
  89. package/documents/QUICK_REFERENCE.md +301 -0
  90. package/documents/SETUP.md +325 -0
  91. package/documents/SETUP_SUMMARY.md +413 -0
  92. package/documents/SKILL_ACQUISITION_EXECUTIVE_SUMMARY.md +373 -0
  93. package/documents/SKILL_ACQUISITION_IMPLEMENTATION.md +692 -0
  94. package/documents/SKILL_ACQUISITION_MANIFEST.md +404 -0
  95. package/documents/SKILL_ACQUISITION_QUICK_REFERENCE.md +349 -0
  96. package/documents/SKILL_WORKFLOW_COMPOSITION_MATRIX.md +537 -0
  97. package/documents/STRUCTURE.md +382 -0
  98. package/documents/SYSTEM_TRANSFORMATION_SUMMARY.md +560 -0
  99. package/documents/USAGE.md +390 -0
  100. package/documents/WORKFLOW_ACQUISITION_MANIFEST.md +576 -0
  101. package/documents/aiskills.txt +460 -0
  102. package/mcp-server/README.md +697 -0
  103. package/mcp-server/dist/badge-proof.d.ts +66 -0
  104. package/mcp-server/dist/badge-proof.d.ts.map +1 -0
  105. package/mcp-server/dist/badge-proof.js +324 -0
  106. package/mcp-server/dist/badge-proof.js.map +1 -0
  107. package/mcp-server/dist/index.d.ts +64 -0
  108. package/mcp-server/dist/index.d.ts.map +1 -0
  109. package/mcp-server/dist/index.js +263 -0
  110. package/mcp-server/dist/index.js.map +1 -0
  111. package/mcp-server/dist/install-badge-proof.d.ts +3 -0
  112. package/mcp-server/dist/install-badge-proof.d.ts.map +1 -0
  113. package/mcp-server/dist/install-badge-proof.js +109 -0
  114. package/mcp-server/dist/install-badge-proof.js.map +1 -0
  115. package/mcp-server/package.json +43 -0
  116. package/mcp-server/src/badge-proof.ts +469 -0
  117. package/mcp-server/src/index.ts +355 -0
  118. package/mcp-server/src/install-badge-proof.ts +132 -0
  119. package/mcp-server/tsconfig.json +22 -0
  120. package/package.json +84 -0
  121. package/scripts/init-leeway.js +217 -0
  122. package/scripts/leeway-agents/compliance-monitor.js +374 -0
  123. package/scripts/leeway-agents/header-injector.js +321 -0
  124. package/scripts/skill-integration-toolkit.py +319 -0
  125. package/scripts/skills-registry.json +1117 -0
  126. package/scripts/sync-skills.ps1 +275 -0
  127. package/scripts/verify-leeway-setup.js +249 -0
  128. package/scripts/workflow-integration-toolkit.py +522 -0
  129. package/sdk/application-installer.js +92 -0
  130. package/sdk/index.js +43 -0
  131. package/sdk/paths.js +167 -0
  132. package/skills/agent-autonomy/autonomous-conductor/SKILL.md +206 -0
  133. package/skills/agent-autonomy/full-stack-delivery/SKILL.md +206 -0
  134. package/skills/agent-orchestration/multi-agent-orchestration/SKILL.md +68 -0
  135. package/skills/agent-patterns/agent-design-patterns/SKILL.md +70 -0
  136. package/skills/ai-ml/llm-prompting/SKILL.md +71 -0
  137. package/skills/ai-ml/ml-model-development/SKILL.md +67 -0
  138. package/skills/ai-ml/multimodal-systems/SKILL.md +71 -0
  139. package/skills/ai-ml/retrieval-generation-fine-tuning/SKILL.md +71 -0
  140. package/skills/architecture/system-design/SKILL.md +67 -0
  141. package/skills/code-analysis/refactoring/SKILL.md +64 -0
  142. package/skills/code-analysis/security-vulnerability-scanning/SKILL.md +71 -0
  143. package/skills/code-analysis/static-analysis/SKILL.md +64 -0
  144. package/skills/code-generation/full-stack-application/SKILL.md +70 -0
  145. package/skills/code-generation/microservices-architecture/SKILL.md +71 -0
  146. package/skills/code-generation/python-codegen/SKILL.md +64 -0
  147. package/skills/code-generation/typescript-codegen/SKILL.md +64 -0
  148. package/skills/data-analysis/advanced-analytics/SKILL.md +71 -0
  149. package/skills/data-analysis/pandas-analysis/SKILL.md +66 -0
  150. package/skills/database-design/database-design-optimization/SKILL.md +70 -0
  151. package/skills/debugging/javascript-debugging/SKILL.md +67 -0
  152. package/skills/debugging/python-debugging/SKILL.md +67 -0
  153. package/skills/devops/dockerfile-creation/SKILL.md +64 -0
  154. package/skills/devops/kubernetes-deployment/SKILL.md +65 -0
  155. package/skills/documentation/api-documentation/SKILL.md +67 -0
  156. package/skills/error-handling/resilience-patterns/SKILL.md +70 -0
  157. package/skills/git-workflow/git-collaboration/SKILL.md +67 -0
  158. package/skills/infrastructure/cicd-pipelines/SKILL.md +70 -0
  159. package/skills/infrastructure/infrastructure-as-code/SKILL.md +70 -0
  160. package/skills/observability/monitoring-and-observability/SKILL.md +70 -0
  161. package/skills/performance-optimization/performance-engineering/SKILL.md +70 -0
  162. package/skills/prompt-optimization/prompt-engineering-advanced/SKILL.md +70 -0
  163. package/skills/quality-assurance/deployment-validator/SKILL.md +382 -0
  164. package/skills/quality-assurance/web-security-sweep/SKILL.md +320 -0
  165. package/skills/rag-knowledge/rag-systems/SKILL.md +70 -0
  166. package/skills/research/knowledge-synthesis/SKILL.md +71 -0
  167. package/skills/security/authentication-authorization/SKILL.md +71 -0
  168. package/skills/security/code-security/SKILL.md +66 -0
  169. package/skills/security/secure-architecture/SKILL.md +71 -0
  170. package/skills/self-optimization/dev-loop-optimizer/SKILL.md +344 -0
  171. package/skills/self-optimization/memory-learning/SKILL.md +335 -0
  172. package/skills/self-optimization/runtime-self-profiling/SKILL.md +250 -0
  173. package/skills/testing/advanced-testing-strategies/SKILL.md +71 -0
  174. package/skills/testing/integration-testing/SKILL.md +66 -0
  175. package/skills/testing/load-testing-capacity/SKILL.md +71 -0
  176. package/skills/testing/unit-testing/SKILL.md +66 -0
  177. package/skills/tool-integration/custom-tool-creation/SKILL.md +70 -0
  178. package/skills/web-development/advanced-frontend-patterns/SKILL.md +71 -0
  179. package/skills/web-development/api-design/SKILL.md +71 -0
  180. package/skills/web-development/css-styling/SKILL.md +67 -0
  181. package/skills/web-development/react-development/SKILL.md +79 -0
  182. 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))