@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,207 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: CORE.SDK.PARSER
5
+ TAG: CORE.SDK.HEADER.PARSER
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=file-text
15
+
16
+ 5WH:
17
+ WHAT = Parses, validates, and builds LEEWAY identity headers from source files
18
+ WHY = Every LEEWAY-compliant file must begin with a structured identity header; this module reads and writes those headers
19
+ WHO = Rapid Web Development
20
+ WHERE = src/core/header-parser.js
21
+ WHEN = 2026
22
+ HOW = Pure JS string parsing, no regex over-engineering, line-by-line state machine
23
+
24
+ AGENTS:
25
+ HEADER
26
+ ASSESS
27
+ AUDIT
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ const HEADER_START = 'LEEWAY HEADER — DO NOT REMOVE';
34
+ const HEADER_END_MARKER = '*/';
35
+ const REQUIRED_FIELDS = ['REGION', 'TAG', '5WH', 'LICENSE'];
36
+ const REQUIRED_5WH = ['WHAT', 'WHY', 'WHO', 'WHERE', 'WHEN', 'HOW'];
37
+
38
+ /**
39
+ * Parse a LEEWAY header block from file content.
40
+ * Returns a structured object or null if no valid header found.
41
+ *
42
+ * @param {string} content - Raw file content
43
+ * @returns {{ region: string, tag: string, colorOnionHex: object, iconAscii: object, fiveWH: object, agents: string[], license: string } | null}
44
+ */
45
+ export function parseHeader(content) {
46
+ if (typeof content !== 'string') return null;
47
+
48
+ const startIdx = content.indexOf(HEADER_START);
49
+ if (startIdx === -1) return null;
50
+
51
+ const endIdx = content.indexOf(HEADER_END_MARKER, startIdx);
52
+ if (endIdx === -1) return null;
53
+
54
+ const block = content.slice(startIdx, endIdx).trim();
55
+ const lines = block.split('\n').map(l => l.trim()).filter(Boolean);
56
+
57
+ const result = {
58
+ region: null,
59
+ tag: null,
60
+ colorOnionHex: {},
61
+ iconAscii: {},
62
+ fiveWH: {},
63
+ agents: [],
64
+ license: null,
65
+ };
66
+
67
+ let section = null;
68
+
69
+ for (const line of lines) {
70
+ if (line === HEADER_START) continue;
71
+
72
+ if (line.startsWith('REGION:')) {
73
+ result.region = line.slice('REGION:'.length).trim();
74
+ section = null;
75
+ continue;
76
+ }
77
+ if (line.startsWith('TAG:')) {
78
+ result.tag = line.slice('TAG:'.length).trim();
79
+ section = null;
80
+ continue;
81
+ }
82
+ if (line === 'COLOR_ONION_HEX:') { section = 'color'; continue; }
83
+ if (line === 'ICON_ASCII:') { section = 'icon'; continue; }
84
+ if (line === '5WH:') { section = '5wh'; continue; }
85
+ if (line === 'AGENTS:') { section = 'agents'; continue; }
86
+ if (line === 'LICENSE:') { section = 'license'; continue; }
87
+
88
+ switch (section) {
89
+ case 'color': {
90
+ const [key, val] = line.split('=');
91
+ if (key && val) result.colorOnionHex[key.trim()] = val.trim();
92
+ break;
93
+ }
94
+ case 'icon': {
95
+ const [key, val] = line.split('=');
96
+ if (key && val) result.iconAscii[key.trim()] = val.trim();
97
+ break;
98
+ }
99
+ case '5wh': {
100
+ const eqIdx = line.indexOf('=');
101
+ if (eqIdx !== -1) {
102
+ const key = line.slice(0, eqIdx).trim();
103
+ const val = line.slice(eqIdx + 1).trim();
104
+ result.fiveWH[key] = val;
105
+ }
106
+ break;
107
+ }
108
+ case 'agents': {
109
+ if (line) result.agents.push(line.trim());
110
+ break;
111
+ }
112
+ case 'license': {
113
+ if (line) result.license = line.trim();
114
+ break;
115
+ }
116
+ }
117
+ }
118
+
119
+ return result;
120
+ }
121
+
122
+ /**
123
+ * Validate a parsed LEEWAY header object.
124
+ * Returns { valid: boolean, errors: string[] }
125
+ *
126
+ * @param {object} header - Result from parseHeader()
127
+ * @returns {{ valid: boolean, errors: string[] }}
128
+ */
129
+ export function validateHeader(header) {
130
+ const errors = [];
131
+
132
+ if (!header) {
133
+ return { valid: false, errors: ['No LEEWAY header found'] };
134
+ }
135
+
136
+ if (!header.region) errors.push('Missing REGION');
137
+ if (!header.tag) errors.push('Missing TAG');
138
+ if (!header.license) errors.push('Missing LICENSE');
139
+
140
+ for (const field of REQUIRED_5WH) {
141
+ if (!header.fiveWH[field]) {
142
+ errors.push(`Missing 5WH field: ${field}`);
143
+ }
144
+ }
145
+
146
+ if (header.tag) {
147
+ const tagParts = header.tag.split('.');
148
+ if (tagParts.length < 3) {
149
+ errors.push('TAG must follow DOMAIN.SUBDOMAIN.ASSET.PURPOSE format (minimum 3 parts)');
150
+ }
151
+ }
152
+
153
+ return { valid: errors.length === 0, errors };
154
+ }
155
+
156
+ /**
157
+ * Build a LEEWAY header comment block from a header config object.
158
+ *
159
+ * @param {object} config - Header fields
160
+ * @param {string} config.region
161
+ * @param {string} config.tag
162
+ * @param {object} [config.colorOnionHex]
163
+ * @param {object} [config.iconAscii]
164
+ * @param {object} config.fiveWH
165
+ * @param {string[]} [config.agents]
166
+ * @param {string} [config.license]
167
+ * @returns {string} - Complete header comment block
168
+ */
169
+ export function buildHeader(config) {
170
+ const {
171
+ region,
172
+ tag,
173
+ colorOnionHex = { NEON: '#39FF14', FLUO: '#0DFF94', PASTEL: '#C7FFD8' },
174
+ iconAscii = { family: 'lucide', glyph: 'file' },
175
+ fiveWH = {},
176
+ agents = [],
177
+ license = 'MIT',
178
+ } = config;
179
+
180
+ const colorLines = Object.entries(colorOnionHex).map(([k, v]) => `${k}=${v}`).join('\n');
181
+ const iconLines = Object.entries(iconAscii).map(([k, v]) => `${k}=${v}`).join('\n');
182
+ const wh5Lines = REQUIRED_5WH.map(k => `${k} = ${fiveWH[k] || '(not set)'}`).join('\n');
183
+ const agentLines = agents.join('\n');
184
+
185
+ return `/*
186
+ LEEWAY HEADER — DO NOT REMOVE
187
+
188
+ REGION: ${region}
189
+ TAG: ${tag}
190
+
191
+ COLOR_ONION_HEX:
192
+ ${colorLines}
193
+
194
+ ICON_ASCII:
195
+ ${iconLines}
196
+
197
+ 5WH:
198
+ ${wh5Lines}
199
+
200
+ AGENTS:
201
+ ${agentLines}
202
+
203
+ LICENSE:
204
+ ${license}
205
+ */
206
+ `;
207
+ }
@@ -0,0 +1,198 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: TEST.CORE.HEADER
5
+ TAG: TEST.UNIT.HEADER.PARSER
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=test-tube
15
+
16
+ 5WH:
17
+ WHAT = Unit tests for the LEEWAY header-parser core module
18
+ WHY = The header parser is foundational — every other module depends on it working correctly
19
+ WHO = Rapid Web Development
20
+ WHERE = src/core/header-parser.test.js
21
+ WHEN = 2026
22
+ HOW = Node.js built-in test runner (node:test) with assert
23
+
24
+ AGENTS:
25
+ AUDIT
26
+ ASSESS
27
+
28
+ LICENSE:
29
+ MIT
30
+ */
31
+
32
+ import { test, describe } from 'node:test';
33
+ import assert from 'node:assert/strict';
34
+ import { parseHeader, validateHeader, buildHeader } from './header-parser.js';
35
+
36
+ const SAMPLE_HEADER_CONTENT = `/*
37
+ LEEWAY HEADER — DO NOT REMOVE
38
+
39
+ REGION: UI.COMPONENT.NEXUS
40
+ TAG: UI.COMPONENT.NEXUS.BUTTON
41
+
42
+ COLOR_ONION_HEX:
43
+ NEON=#39FF14
44
+ FLUO=#0DFF94
45
+ PASTEL=#C7FFD8
46
+
47
+ ICON_ASCII:
48
+ family=lucide
49
+ glyph=layout-dashboard
50
+
51
+ 5WH:
52
+ WHAT = Nexus button component
53
+ WHY = Primary voice control interface
54
+ WHO = Rapid Web Development
55
+ WHERE = src/components/NexusButton.tsx
56
+ WHEN = 2026
57
+ HOW = React + Tailwind
58
+
59
+ AGENTS:
60
+ AZR
61
+ PHI3
62
+
63
+ LICENSE:
64
+ MIT
65
+ */
66
+
67
+ export function NexusButton() {}
68
+ `;
69
+
70
+ const NO_HEADER_CONTENT = `export function NexusButton() {}`;
71
+
72
+ describe('parseHeader', () => {
73
+ test('parses a valid LEEWAY header', () => {
74
+ const result = parseHeader(SAMPLE_HEADER_CONTENT);
75
+ assert.ok(result, 'Should return an object');
76
+ assert.equal(result.region, 'UI.COMPONENT.NEXUS');
77
+ assert.equal(result.tag, 'UI.COMPONENT.NEXUS.BUTTON');
78
+ assert.equal(result.license, 'MIT');
79
+ assert.deepEqual(result.agents, ['AZR', 'PHI3']);
80
+ });
81
+
82
+ test('returns null when no header is present', () => {
83
+ const result = parseHeader(NO_HEADER_CONTENT);
84
+ assert.equal(result, null);
85
+ });
86
+
87
+ test('returns null for non-string input', () => {
88
+ assert.equal(parseHeader(null), null);
89
+ assert.equal(parseHeader(undefined), null);
90
+ assert.equal(parseHeader(42), null);
91
+ });
92
+
93
+ test('parses 5WH fields correctly', () => {
94
+ const result = parseHeader(SAMPLE_HEADER_CONTENT);
95
+ assert.ok(result.fiveWH);
96
+ assert.equal(result.fiveWH.WHAT, 'Nexus button component');
97
+ assert.equal(result.fiveWH.WHY, 'Primary voice control interface');
98
+ assert.equal(result.fiveWH.WHO, 'Rapid Web Development');
99
+ assert.equal(result.fiveWH.WHEN, '2026');
100
+ });
101
+
102
+ test('parses color hex values', () => {
103
+ const result = parseHeader(SAMPLE_HEADER_CONTENT);
104
+ assert.equal(result.colorOnionHex.NEON, '#39FF14');
105
+ assert.equal(result.colorOnionHex.FLUO, '#0DFF94');
106
+ });
107
+
108
+ test('parses icon ascii fields', () => {
109
+ const result = parseHeader(SAMPLE_HEADER_CONTENT);
110
+ assert.equal(result.iconAscii.family, 'lucide');
111
+ assert.equal(result.iconAscii.glyph, 'layout-dashboard');
112
+ });
113
+ });
114
+
115
+ describe('validateHeader', () => {
116
+ test('validates a complete header as valid', () => {
117
+ const header = parseHeader(SAMPLE_HEADER_CONTENT);
118
+ const { valid, errors } = validateHeader(header);
119
+ assert.equal(valid, true);
120
+ assert.equal(errors.length, 0);
121
+ });
122
+
123
+ test('returns error for null header', () => {
124
+ const { valid, errors } = validateHeader(null);
125
+ assert.equal(valid, false);
126
+ assert.ok(errors.length > 0);
127
+ });
128
+
129
+ test('reports missing REGION', () => {
130
+ const { valid, errors } = validateHeader({ tag: 'UI.COMPONENT.X.Y', license: 'MIT', fiveWH: { WHAT: 'x', WHY: 'y', WHO: 'z', WHERE: 'a', WHEN: '2026', HOW: 'b' } });
131
+ assert.equal(valid, false);
132
+ assert.ok(errors.some(e => e.includes('REGION')));
133
+ });
134
+
135
+ test('reports missing 5WH fields', () => {
136
+ const { valid, errors } = validateHeader({ region: 'UI', tag: 'UI.X.Y', license: 'MIT', fiveWH: {} });
137
+ assert.equal(valid, false);
138
+ assert.ok(errors.some(e => e.includes('WHAT')));
139
+ });
140
+
141
+ test('reports invalid TAG format', () => {
142
+ const { valid, errors } = validateHeader({
143
+ region: 'UI',
144
+ tag: 'BADTAG',
145
+ license: 'MIT',
146
+ fiveWH: { WHAT: 'x', WHY: 'y', WHO: 'z', WHERE: 'a', WHEN: '2026', HOW: 'b' },
147
+ });
148
+ assert.equal(valid, false);
149
+ assert.ok(errors.some(e => e.toLowerCase().includes('tag')));
150
+ });
151
+ });
152
+
153
+ describe('buildHeader', () => {
154
+ test('builds a valid header string', () => {
155
+ const header = buildHeader({
156
+ region: 'UI.COMPONENT.TEST',
157
+ tag: 'UI.COMPONENT.TEST.MAIN',
158
+ fiveWH: {
159
+ WHAT: 'Test component',
160
+ WHY: 'For testing',
161
+ WHO: 'Test Author',
162
+ WHERE: 'src/test.js',
163
+ WHEN: '2026',
164
+ HOW: 'Node.js',
165
+ },
166
+ agents: ['ASSESS'],
167
+ license: 'MIT',
168
+ });
169
+
170
+ assert.ok(typeof header === 'string');
171
+ assert.ok(header.includes('LEEWAY HEADER — DO NOT REMOVE'));
172
+ assert.ok(header.includes('REGION: UI.COMPONENT.TEST'));
173
+ assert.ok(header.includes('TAG: UI.COMPONENT.TEST.MAIN'));
174
+ assert.ok(header.includes('MIT'));
175
+ assert.ok(header.includes('ASSESS'));
176
+ });
177
+
178
+ test('built header is parseable', () => {
179
+ const header = buildHeader({
180
+ region: 'CORE.SDK.TEST',
181
+ tag: 'CORE.SDK.TEST.UNIT',
182
+ fiveWH: {
183
+ WHAT: 'Test',
184
+ WHY: 'Testing',
185
+ WHO: 'Dev',
186
+ WHERE: 'test.js',
187
+ WHEN: '2026',
188
+ HOW: 'Node',
189
+ },
190
+ });
191
+
192
+ const content = header + '\nexport default {};';
193
+ const parsed = parseHeader(content);
194
+ assert.ok(parsed);
195
+ assert.equal(parsed.region, 'CORE.SDK.TEST');
196
+ assert.equal(parsed.tag, 'CORE.SDK.TEST.UNIT');
197
+ });
198
+ });
@@ -0,0 +1,137 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: CORE.SDK.CLASSIFIER
5
+ TAG: CORE.SDK.REGION.CLASSIFIER
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=map-pin
15
+
16
+ 5WH:
17
+ WHAT = Classifies files into LEEWAY system regions
18
+ WHY = Every file must belong to a named region that defines its role and layer in the system
19
+ WHO = Rapid Web Development
20
+ WHERE = src/core/region-classifier.js
21
+ WHEN = 2026
22
+ HOW = Path-based heuristics with configurable overrides
23
+
24
+ AGENTS:
25
+ REGION
26
+ ASSESS
27
+
28
+ LICENSE:
29
+ MIT
30
+ */
31
+
32
+ /**
33
+ * All recognized LEEWAY system regions with metadata.
34
+ */
35
+ export const REGIONS = {
36
+ UI: {
37
+ label: 'User Interface',
38
+ description: 'User interface components, pages, layouts, and styling',
39
+ color: '#39FF14',
40
+ paths: ['components', 'pages', 'layouts', 'ui', 'views', 'screens', 'styles', 'themes'],
41
+ },
42
+ CORE: {
43
+ label: 'Core System',
44
+ description: 'Core system logic, runtime, configuration, and SDK internals',
45
+ color: '#FF6B35',
46
+ paths: ['core', 'sdk', 'runtime', 'engine', 'config', 'lib'],
47
+ },
48
+ DATA: {
49
+ label: 'Data Storage',
50
+ description: 'Storage, database access, models, caches, and migrations',
51
+ color: '#4ECDC4',
52
+ paths: ['data', 'store', 'stores', 'db', 'database', 'models', 'migrations', 'cache'],
53
+ },
54
+ AI: {
55
+ label: 'AI Orchestration',
56
+ description: 'AI orchestration, models, prompts, agents, and memory',
57
+ color: '#A855F7',
58
+ paths: ['ai', 'agents', 'llm', 'ml', 'prompts', 'models', 'memory', 'orchestration'],
59
+ },
60
+ SEO: {
61
+ label: 'Search & Discovery',
62
+ description: 'SEO, structured data, sitemaps, and discovery metadata',
63
+ color: '#F59E0B',
64
+ paths: ['seo', 'discovery', 'schema', 'sitemap', 'metadata', 'structured-data'],
65
+ },
66
+ UTIL: {
67
+ label: 'Utilities',
68
+ description: 'Utility functions, formatters, helpers, and shared tools',
69
+ color: '#6B7280',
70
+ paths: ['utils', 'util', 'helpers', 'shared', 'common', 'tools'],
71
+ },
72
+ MCP: {
73
+ label: 'Multi-Component Processing',
74
+ description: 'MCP transport, endpoints, ports, processes, and manifests',
75
+ color: '#0EA5E9',
76
+ paths: ['mcp', 'transport', 'endpoints', 'ports', 'processes', 'manifests'],
77
+ },
78
+ SECURITY: {
79
+ label: 'Security',
80
+ description: 'Security, authentication, authorization, and policy enforcement',
81
+ color: '#EF4444',
82
+ paths: ['security', 'auth', 'authentication', 'authorization', 'policies', 'permissions'],
83
+ },
84
+ TEST: {
85
+ label: 'Testing',
86
+ description: 'Unit tests, integration tests, fixtures, and mocks',
87
+ color: '#10B981',
88
+ paths: ['test', 'tests', '__tests__', 'spec', 'specs', 'fixtures', 'mocks'],
89
+ },
90
+ DOCS: {
91
+ label: 'Documentation',
92
+ description: 'Standards documents, guides, schemas, and reports',
93
+ color: '#8B5CF6',
94
+ paths: ['docs', 'documentation', 'guides', 'reports', 'schemas', 'examples'],
95
+ },
96
+ };
97
+
98
+ /**
99
+ * Classify a file into a LEEWAY region based on its path.
100
+ *
101
+ * @param {string} filePath - Relative or absolute file path
102
+ * @returns {{ region: string, confidence: 'high' | 'medium' | 'low', metadata: object }}
103
+ */
104
+ export function classifyRegion(filePath) {
105
+ if (!filePath || typeof filePath !== 'string') {
106
+ return { region: 'CORE', confidence: 'low', metadata: REGIONS.CORE };
107
+ }
108
+
109
+ const path = filePath.toLowerCase().replace(/\\/g, '/');
110
+ const segments = path.split('/').filter(Boolean);
111
+
112
+ for (const [regionKey, regionData] of Object.entries(REGIONS)) {
113
+ for (const pattern of regionData.paths) {
114
+ if (segments.includes(pattern)) {
115
+ return {
116
+ region: regionKey,
117
+ confidence: 'high',
118
+ metadata: regionData,
119
+ };
120
+ }
121
+ }
122
+ }
123
+
124
+ for (const [regionKey, regionData] of Object.entries(REGIONS)) {
125
+ for (const pattern of regionData.paths) {
126
+ if (path.includes(pattern)) {
127
+ return {
128
+ region: regionKey,
129
+ confidence: 'medium',
130
+ metadata: regionData,
131
+ };
132
+ }
133
+ }
134
+ }
135
+
136
+ return { region: 'CORE', confidence: 'low', metadata: REGIONS.CORE };
137
+ }
@@ -0,0 +1,100 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: TEST.CORE.REGION
5
+ TAG: TEST.UNIT.REGION.CLASSIFIER
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=test-tube
15
+
16
+ 5WH:
17
+ WHAT = Unit tests for the LEEWAY region-classifier core module
18
+ WHY = Region classification determines where files belong; errors affect entire governance pipeline
19
+ WHO = Rapid Web Development
20
+ WHERE = src/core/region-classifier.test.js
21
+ WHEN = 2026
22
+ HOW = Node.js built-in test runner (node:test) with assert
23
+
24
+ AGENTS:
25
+ AUDIT
26
+
27
+ LICENSE:
28
+ MIT
29
+ */
30
+
31
+ import { test, describe } from 'node:test';
32
+ import assert from 'node:assert/strict';
33
+ import { classifyRegion, REGIONS } from './region-classifier.js';
34
+
35
+ describe('REGIONS', () => {
36
+ test('exports all required regions', () => {
37
+ const required = ['UI', 'CORE', 'DATA', 'AI', 'SEO', 'UTIL', 'MCP', 'SECURITY', 'TEST', 'DOCS'];
38
+ for (const r of required) {
39
+ assert.ok(REGIONS[r], `Should have region: ${r}`);
40
+ }
41
+ });
42
+
43
+ test('each region has required metadata', () => {
44
+ for (const [key, region] of Object.entries(REGIONS)) {
45
+ assert.ok(region.label, `${key} should have label`);
46
+ assert.ok(region.description, `${key} should have description`);
47
+ assert.ok(region.color, `${key} should have color`);
48
+ assert.ok(Array.isArray(region.paths), `${key} should have paths array`);
49
+ }
50
+ });
51
+ });
52
+
53
+ describe('classifyRegion', () => {
54
+ test('classifies UI component paths', () => {
55
+ const { region } = classifyRegion('src/components/NexusButton.tsx');
56
+ assert.equal(region, 'UI');
57
+ });
58
+
59
+ test('classifies AI agent paths', () => {
60
+ const { region } = classifyRegion('src/agents/assess-agent.js');
61
+ assert.equal(region, 'AI');
62
+ });
63
+
64
+ test('classifies DATA paths', () => {
65
+ const { region } = classifyRegion('src/data/userStore.js');
66
+ assert.equal(region, 'DATA');
67
+ });
68
+
69
+ test('classifies SECURITY paths', () => {
70
+ const { region } = classifyRegion('src/security/validator.js');
71
+ assert.equal(region, 'SECURITY');
72
+ });
73
+
74
+ test('classifies UTIL paths', () => {
75
+ const { region } = classifyRegion('src/utils/formatDate.js');
76
+ assert.equal(region, 'UTIL');
77
+ });
78
+
79
+ test('classifies DOCS paths', () => {
80
+ const { region } = classifyRegion('docs/standards.md');
81
+ assert.equal(region, 'DOCS');
82
+ });
83
+
84
+ test('returns CORE as fallback for unknown paths', () => {
85
+ const { region } = classifyRegion('unknown/something.js');
86
+ assert.equal(region, 'CORE');
87
+ });
88
+
89
+ test('handles null/empty paths gracefully', () => {
90
+ const { region } = classifyRegion(null);
91
+ assert.equal(region, 'CORE');
92
+ const { region: r2 } = classifyRegion('');
93
+ assert.equal(r2, 'CORE');
94
+ });
95
+
96
+ test('returns confidence level', () => {
97
+ const { confidence } = classifyRegion('src/components/Button.tsx');
98
+ assert.ok(['high', 'medium', 'low'].includes(confidence));
99
+ });
100
+ });