@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,120 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.HEADER.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=file-plus
15
+
16
+ 5WH:
17
+ WHAT = Header agent — inserts and repairs LEEWAY headers in source files
18
+ WHY = All LEEWAY files must have a valid identity header; this agent enforces that rule
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/header-agent.js
21
+ WHEN = 2026
22
+ HOW = Reads files, detects missing or malformed headers, inserts or repairs as needed
23
+
24
+ AGENTS:
25
+ HEADER
26
+ ASSESS
27
+ ALIGN
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile, writeFile } from 'node:fs/promises';
34
+ import { join } from 'node:path';
35
+ import { parseHeader, validateHeader, buildHeader } from '../../core/header-parser.js';
36
+ import { inferTag } from '../../core/tag-validator.js';
37
+ import { classifyRegion } from '../../core/region-classifier.js';
38
+
39
+ /**
40
+ * HeaderAgent inserts and repairs LEEWAY headers in source files.
41
+ */
42
+ export class HeaderAgent {
43
+ constructor(options = {}) {
44
+ this.rootDir = options.rootDir || process.cwd();
45
+ this.dryRun = options.dryRun !== false;
46
+ this.author = options.author || 'LEEWAY Header Agent';
47
+ }
48
+
49
+ /**
50
+ * Process a single file — insert header if missing, repair if invalid.
51
+ *
52
+ * @param {string} filePath - Absolute or relative file path
53
+ * @returns {Promise<{ file: string, action: string, dryRun: boolean }>}
54
+ */
55
+ async processFile(filePath) {
56
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
57
+ const relPath = filePath.startsWith('/') ? filePath.replace(this.rootDir + '/', '') : filePath;
58
+
59
+ let content;
60
+ try {
61
+ content = await readFile(fullPath, 'utf8');
62
+ } catch (err) {
63
+ return { file: relPath, action: 'error', reason: err.message };
64
+ }
65
+
66
+ const header = parseHeader(content);
67
+
68
+ if (!header) {
69
+ return this._insertHeader(fullPath, relPath, content);
70
+ }
71
+
72
+ const { valid, errors } = validateHeader(header);
73
+ if (!valid) {
74
+ return { file: relPath, action: 'needs_repair', errors, dryRun: this.dryRun };
75
+ }
76
+
77
+ return { file: relPath, action: 'valid', dryRun: this.dryRun };
78
+ }
79
+
80
+ async _insertHeader(fullPath, relPath, content) {
81
+ const regionResult = classifyRegion(relPath);
82
+ const tag = inferTag(relPath);
83
+ const fileName = relPath.split('/').pop().replace(/\.[^.]+$/, '');
84
+
85
+ const headerBlock = buildHeader({
86
+ region: regionResult.region,
87
+ tag,
88
+ fiveWH: {
89
+ WHAT: `${fileName} module`,
90
+ WHY: `${regionResult.metadata.description}`,
91
+ WHO: this.author,
92
+ WHERE: relPath,
93
+ WHEN: new Date().getFullYear().toString(),
94
+ HOW: 'Auto-inserted by LEEWAY header-agent',
95
+ },
96
+ agents: ['ASSESS', 'ALIGN', 'AUDIT'],
97
+ license: 'MIT',
98
+ });
99
+
100
+ if (!this.dryRun) {
101
+ await writeFile(fullPath, headerBlock + '\n' + content, 'utf8');
102
+ }
103
+
104
+ return { file: relPath, action: 'header_inserted', dryRun: this.dryRun };
105
+ }
106
+
107
+ /**
108
+ * Process multiple files.
109
+ *
110
+ * @param {string[]} filePaths
111
+ * @returns {Promise<object[]>}
112
+ */
113
+ async processFiles(filePaths) {
114
+ const results = [];
115
+ for (const fp of filePaths) {
116
+ results.push(await this.processFile(fp));
117
+ }
118
+ return results;
119
+ }
120
+ }
@@ -0,0 +1,96 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.PLACEMENT.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=folder-check
15
+
16
+ 5WH:
17
+ WHAT = Placement agent — checks file placement against LEEWAY directory structure rules
18
+ WHY = Files in wrong directories break discoverability and architecture legibility
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/placement-agent.js
21
+ WHEN = 2026
22
+ HOW = Compares declared REGION against expected directory paths, reports misplacements
23
+
24
+ AGENTS:
25
+ PLACEMENT
26
+ ASSESS
27
+ AUDIT
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join, dirname } from 'node:path';
35
+ import { parseHeader } from '../../core/header-parser.js';
36
+ import { classifyRegion } from '../../core/region-classifier.js';
37
+
38
+ const REGION_EXPECTED_DIRS = {
39
+ UI: ['src/components', 'src/pages', 'src/layouts', 'src/ui', 'src/views', 'src/screens'],
40
+ CORE: ['src/core', 'src/sdk', 'src/lib', 'src/runtime', 'src/engine'],
41
+ DATA: ['src/data', 'src/store', 'src/stores', 'src/db', 'src/models'],
42
+ AI: ['src/ai', 'src/agents', 'src/llm', 'src/ml', 'src/prompts'],
43
+ SEO: ['src/seo', 'src/discovery', 'src/schema', 'src/sitemap'],
44
+ UTIL: ['src/utils', 'src/util', 'src/helpers', 'src/shared'],
45
+ MCP: ['src/mcp', 'src/transport', 'src/endpoints'],
46
+ SECURITY: ['src/security', 'src/auth', 'src/authorization'],
47
+ TEST: ['src/tests', 'src/__tests__', 'test', 'tests', '__tests__'],
48
+ DOCS: ['docs', 'documentation', 'guides'],
49
+ };
50
+
51
+ /**
52
+ * PlacementAgent validates that files are in the correct LEEWAY directories.
53
+ */
54
+ export class PlacementAgent {
55
+ constructor(options = {}) {
56
+ this.rootDir = options.rootDir || process.cwd();
57
+ }
58
+
59
+ /**
60
+ * Check placement of a file.
61
+ *
62
+ * @param {string} filePath
63
+ * @returns {Promise<PlacementResult>}
64
+ */
65
+ async checkFile(filePath) {
66
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
67
+ const relPath = filePath.startsWith('/') ? filePath.replace(this.rootDir + '/', '') : filePath;
68
+ const normalizedPath = relPath.replace(/\\/g, '/');
69
+
70
+ let content = '';
71
+ try {
72
+ content = await readFile(fullPath, 'utf8');
73
+ } catch {
74
+ return { file: relPath, status: 'error' };
75
+ }
76
+
77
+ const header = parseHeader(content);
78
+ const declaredRegion = header?.region?.split('.')?.[0];
79
+ const { region: inferredRegion, confidence } = classifyRegion(relPath);
80
+
81
+ const regionToCheck = declaredRegion || inferredRegion;
82
+ const expectedDirs = REGION_EXPECTED_DIRS[regionToCheck] || [];
83
+ const isCorrectlyPlaced = expectedDirs.length === 0
84
+ || expectedDirs.some(dir => normalizedPath.startsWith(dir.replace(/^\//, '')));
85
+
86
+ return {
87
+ file: relPath,
88
+ declaredRegion,
89
+ inferredRegion,
90
+ confidence,
91
+ expectedDirectories: expectedDirs,
92
+ status: isCorrectlyPlaced ? 'correct' : 'misplaced',
93
+ suggestion: isCorrectlyPlaced ? null : `Move to one of: ${expectedDirs.slice(0, 3).join(', ')}`,
94
+ };
95
+ }
96
+ }
@@ -0,0 +1,99 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.REGION.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=map
15
+
16
+ 5WH:
17
+ WHAT = Region agent — assigns REGION correctly to files based on path and content
18
+ WHY = Files must belong to the correct system region for governance and discoverability
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/region-agent.js
21
+ WHEN = 2026
22
+ HOW = Path analysis and content scanning to determine the most appropriate region
23
+
24
+ AGENTS:
25
+ REGION
26
+ ASSESS
27
+
28
+ LICENSE:
29
+ MIT
30
+ */
31
+
32
+ import { readFile } from 'node:fs/promises';
33
+ import { join } from 'node:path';
34
+ import { classifyRegion, REGIONS } from '../../core/region-classifier.js';
35
+ import { parseHeader } from '../../core/header-parser.js';
36
+
37
+ /**
38
+ * RegionAgent assigns and validates LEEWAY REGION values.
39
+ */
40
+ export class RegionAgent {
41
+ constructor(options = {}) {
42
+ this.rootDir = options.rootDir || process.cwd();
43
+ }
44
+
45
+ /**
46
+ * Analyze a file and determine its correct REGION.
47
+ *
48
+ * @param {string} filePath
49
+ * @returns {Promise<RegionAnalysis>}
50
+ */
51
+ async analyzeFile(filePath) {
52
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
53
+ const relPath = filePath.startsWith('/') ? filePath.replace(this.rootDir + '/', '') : filePath;
54
+
55
+ let content = '';
56
+ try {
57
+ content = await readFile(fullPath, 'utf8');
58
+ } catch {
59
+ return { file: relPath, status: 'error' };
60
+ }
61
+
62
+ const header = parseHeader(content);
63
+ const { region: inferredRegion, confidence, metadata } = classifyRegion(relPath);
64
+
65
+ if (!header) {
66
+ return {
67
+ file: relPath,
68
+ status: 'no_header',
69
+ inferredRegion,
70
+ confidence,
71
+ description: metadata.description,
72
+ };
73
+ }
74
+
75
+ const declaredRegion = header.region ? header.region.split('.')[0] : null;
76
+ const mismatch = declaredRegion && declaredRegion !== inferredRegion && confidence === 'high';
77
+
78
+ return {
79
+ file: relPath,
80
+ status: mismatch ? 'region_mismatch' : 'valid',
81
+ declaredRegion: header.region,
82
+ inferredRegion,
83
+ confidence,
84
+ description: metadata.description,
85
+ mismatch,
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Get a summary of all available regions.
91
+ * @returns {object}
92
+ */
93
+ getRegionMap() {
94
+ return Object.entries(REGIONS).reduce((acc, [key, val]) => {
95
+ acc[key] = { label: val.label, description: val.description, color: val.color };
96
+ return acc;
97
+ }, {});
98
+ }
99
+ }
@@ -0,0 +1,153 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.REGISTRY.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=database
15
+
16
+ 5WH:
17
+ WHAT = Registry agent — updates tag registry, file registry, and system map
18
+ WHY = A LEEWAY system needs a queryable registry of all files and their identities
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/registry-agent.js
21
+ WHEN = 2026
22
+ HOW = Walks codebase, reads LEEWAY headers, writes to .leeway/registry.json
23
+
24
+ AGENTS:
25
+ REGISTRY
26
+ ASSESS
27
+ AUDIT
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readdir, readFile, writeFile, mkdir } from 'node:fs/promises';
34
+ import { join, relative, extname } from 'node:path';
35
+ import { parseHeader } from '../../core/header-parser.js';
36
+
37
+ const SKIP_DIRS = new Set(['.git', 'node_modules', 'dist', 'build', '.next', '.cache', 'coverage']);
38
+ const CODE_EXTENSIONS = new Set(['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs']);
39
+
40
+ /**
41
+ * RegistryAgent builds and updates the LEEWAY file and tag registries.
42
+ */
43
+ export class RegistryAgent {
44
+ constructor(options = {}) {
45
+ this.rootDir = options.rootDir || process.cwd();
46
+ this.registryDir = join(this.rootDir, '.leeway');
47
+ this.registryPath = join(this.registryDir, 'registry.json');
48
+ }
49
+
50
+ /**
51
+ * Build the registry from the current codebase.
52
+ * @returns {Promise<Registry>}
53
+ */
54
+ async build() {
55
+ const registry = {
56
+ version: '1.0.1',
57
+ built: new Date().toISOString(),
58
+ rootDir: this.rootDir,
59
+ files: {},
60
+ tags: {},
61
+ regions: {},
62
+ };
63
+
64
+ await this._walk(this.rootDir, registry);
65
+ return registry;
66
+ }
67
+
68
+ /**
69
+ * Build and persist the registry to .leeway/registry.json
70
+ * @returns {Promise<Registry>}
71
+ */
72
+ async buildAndSave() {
73
+ const registry = await this.build();
74
+
75
+ try {
76
+ await mkdir(this.registryDir, { recursive: true });
77
+ await writeFile(this.registryPath, JSON.stringify(registry, null, 2), 'utf8');
78
+ registry.savedTo = this.registryPath;
79
+ } catch (err) {
80
+ registry.saveError = err.message;
81
+ }
82
+
83
+ return registry;
84
+ }
85
+
86
+ /**
87
+ * Load the existing registry from disk.
88
+ * @returns {Promise<Registry | null>}
89
+ */
90
+ async load() {
91
+ try {
92
+ const raw = await readFile(this.registryPath, 'utf8');
93
+ return JSON.parse(raw);
94
+ } catch {
95
+ return null;
96
+ }
97
+ }
98
+
99
+ async _walk(dir, registry, depth = 0) {
100
+ if (depth > 10) return;
101
+
102
+ let entries;
103
+ try {
104
+ entries = await readdir(dir, { withFileTypes: true });
105
+ } catch {
106
+ return;
107
+ }
108
+
109
+ for (const entry of entries) {
110
+ if (SKIP_DIRS.has(entry.name)) continue;
111
+ const fullPath = join(dir, entry.name);
112
+ const relPath = relative(this.rootDir, fullPath);
113
+
114
+ if (entry.isDirectory()) {
115
+ await this._walk(fullPath, registry, depth + 1);
116
+ } else if (entry.isFile() && CODE_EXTENSIONS.has(extname(entry.name))) {
117
+ await this._indexFile(fullPath, relPath, registry);
118
+ }
119
+ }
120
+ }
121
+
122
+ async _indexFile(fullPath, relPath, registry) {
123
+ let content;
124
+ try {
125
+ content = await readFile(fullPath, 'utf8');
126
+ } catch {
127
+ return;
128
+ }
129
+
130
+ const header = parseHeader(content);
131
+ const entry = {
132
+ path: relPath,
133
+ hasHeader: !!header,
134
+ region: header?.region || null,
135
+ tag: header?.tag || null,
136
+ agents: header?.agents || [],
137
+ license: header?.license || null,
138
+ fiveWH: header?.fiveWH || {},
139
+ };
140
+
141
+ registry.files[relPath] = entry;
142
+
143
+ if (header?.tag) {
144
+ if (!registry.tags[header.tag]) registry.tags[header.tag] = [];
145
+ registry.tags[header.tag].push(relPath);
146
+ }
147
+
148
+ if (header?.region) {
149
+ const regionKey = header.region.split('.')[0];
150
+ registry.regions[regionKey] = (registry.regions[regionKey] || 0) + 1;
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,111 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.TAG.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=tag
15
+
16
+ 5WH:
17
+ WHAT = Tag agent — infers TAG values from file path, purpose, and role
18
+ WHY = Every file needs an accurate TAG for the system to be machine-searchable
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/tag-agent.js
21
+ WHEN = 2026
22
+ HOW = Uses path heuristics and file content analysis to suggest optimal TAGs
23
+
24
+ AGENTS:
25
+ TAG
26
+ ASSESS
27
+
28
+ LICENSE:
29
+ MIT
30
+ */
31
+
32
+ import { readFile } from 'node:fs/promises';
33
+ import { join, extname } from 'node:path';
34
+ import { validateTag, inferTag } from '../../core/tag-validator.js';
35
+ import { parseHeader } from '../../core/header-parser.js';
36
+
37
+ /**
38
+ * TagAgent infers and validates LEEWAY TAG values for files.
39
+ */
40
+ export class TagAgent {
41
+ constructor(options = {}) {
42
+ this.rootDir = options.rootDir || process.cwd();
43
+ }
44
+
45
+ /**
46
+ * Analyze a file and suggest or validate its TAG.
47
+ *
48
+ * @param {string} filePath
49
+ * @returns {Promise<TagAnalysis>}
50
+ */
51
+ async analyzeFile(filePath) {
52
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
53
+ const relPath = filePath.startsWith('/') ? filePath.replace(this.rootDir + '/', '') : filePath;
54
+
55
+ let content = '';
56
+ try {
57
+ content = await readFile(fullPath, 'utf8');
58
+ } catch {
59
+ return { file: relPath, status: 'error', reason: 'Cannot read file' };
60
+ }
61
+
62
+ const header = parseHeader(content);
63
+ const suggestedTag = inferTag(relPath, this._extractContext(content));
64
+
65
+ if (!header) {
66
+ return {
67
+ file: relPath,
68
+ status: 'no_header',
69
+ suggestedTag,
70
+ currentTag: null,
71
+ };
72
+ }
73
+
74
+ if (!header.tag) {
75
+ return {
76
+ file: relPath,
77
+ status: 'missing_tag',
78
+ suggestedTag,
79
+ currentTag: null,
80
+ };
81
+ }
82
+
83
+ const { valid, errors } = validateTag(header.tag);
84
+ return {
85
+ file: relPath,
86
+ status: valid ? 'valid' : 'invalid_tag',
87
+ currentTag: header.tag,
88
+ suggestedTag: valid ? header.tag : suggestedTag,
89
+ errors: valid ? [] : errors,
90
+ };
91
+ }
92
+
93
+ _extractContext(content) {
94
+ const lines = content.split('\n').slice(0, 30).join(' ');
95
+ const purposeMatch = lines.match(/(?:export|function|class|const)\s+([A-Za-z][A-Za-z0-9]+)/);
96
+ return { purpose: purposeMatch ? purposeMatch[1] : 'MAIN' };
97
+ }
98
+
99
+ /**
100
+ * Analyze multiple files.
101
+ * @param {string[]} filePaths
102
+ * @returns {Promise<TagAnalysis[]>}
103
+ */
104
+ async analyzeFiles(filePaths) {
105
+ const results = [];
106
+ for (const fp of filePaths) {
107
+ results.push(await this.analyzeFile(fp));
108
+ }
109
+ return results;
110
+ }
111
+ }