@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,100 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: SECURITY.AGENT.POLICY
5
+ TAG: SECURITY.POLICY.AGENT.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=scroll
15
+
16
+ 5WH:
17
+ WHAT = Policy agent — enforces LEEWAY policy bundles across the codebase
18
+ WHY = Governance requires consistent enforcement of named policy sets
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/security/policy-agent.js
21
+ WHEN = 2026
22
+ HOW = Loads policy bundles from .leeway/policies.json, evaluates against file metadata
23
+
24
+ AGENTS:
25
+ POLICY
26
+ AUDIT
27
+ PERMISSION
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join } from 'node:path';
35
+
36
+ const DEFAULT_POLICIES = {
37
+ NO_SECRETS_IN_CODE: { description: 'No hardcoded secrets or credentials', enforced: true },
38
+ HEADERS_REQUIRED: { description: 'All code files must have LEEWAY headers', enforced: true },
39
+ TAGS_REQUIRED: { description: 'All code files must have valid TAGs', enforced: true },
40
+ NO_CIRCULAR_DEPS: { description: 'No circular module dependencies', enforced: true },
41
+ NAMING_CONVENTIONS: { description: 'Files must follow naming conventions', enforced: false },
42
+ PLACEMENT_RULES: { description: 'Files must be in correct directories', enforced: false },
43
+ };
44
+
45
+ /**
46
+ * PolicyAgent enforces named LEEWAY policy bundles.
47
+ */
48
+ export class PolicyAgent {
49
+ constructor(options = {}) {
50
+ this.rootDir = options.rootDir || process.cwd();
51
+ this.policies = { ...DEFAULT_POLICIES };
52
+ }
53
+
54
+ /**
55
+ * Load policies from .leeway/policies.json (merges with defaults).
56
+ */
57
+ async loadPolicies() {
58
+ const policyPath = join(this.rootDir, '.leeway', 'policies.json');
59
+ try {
60
+ const raw = await readFile(policyPath, 'utf8');
61
+ const loaded = JSON.parse(raw);
62
+ this.policies = { ...DEFAULT_POLICIES, ...loaded };
63
+ } catch {
64
+ // Use defaults
65
+ }
66
+ return this.policies;
67
+ }
68
+
69
+ /**
70
+ * Get all currently active (enforced) policies.
71
+ * @returns {string[]}
72
+ */
73
+ getActivePolicies() {
74
+ return Object.entries(this.policies)
75
+ .filter(([, p]) => p.enforced)
76
+ .map(([name]) => name);
77
+ }
78
+
79
+ /**
80
+ * Check if a specific policy is active.
81
+ *
82
+ * @param {string} policyName
83
+ * @returns {boolean}
84
+ */
85
+ isPolicyActive(policyName) {
86
+ return this.policies[policyName]?.enforced === true;
87
+ }
88
+
89
+ /**
90
+ * List all policies with their enforcement status.
91
+ * @returns {object}
92
+ */
93
+ listPolicies() {
94
+ return Object.entries(this.policies).map(([name, data]) => ({
95
+ name,
96
+ description: data.description,
97
+ enforced: data.enforced,
98
+ }));
99
+ }
100
+ }
@@ -0,0 +1,83 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: SECURITY.AGENT.PRIVACY
5
+ TAG: SECURITY.PRIVACY.AGENT.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=user-x
15
+
16
+ 5WH:
17
+ WHAT = Privacy agent — checks privacy and data handling declarations in code
18
+ WHY = Systems handling personal data must declare their data handling intent
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/security/privacy-agent.js
21
+ WHEN = 2026
22
+ HOW = Scans for PII patterns in logs and data structures, checks for privacy declarations
23
+
24
+ AGENTS:
25
+ PRIVACY
26
+ POLICY
27
+ SECRET
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ const PII_PATTERNS = [
34
+ { id: 'email_log', label: 'Email in log output', pattern: /(?:console\.|log\.|logger\.)[a-z]+\([^)]*[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-z]+/i },
35
+ { id: 'phone_inline', label: 'Phone number pattern', pattern: /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/ },
36
+ { id: 'ssn_pattern', label: 'SSN-like pattern', pattern: /\b\d{3}-\d{2}-\d{4}\b/ },
37
+ { id: 'pii_in_logs', label: 'PII field logged', pattern: /(?:log|print|console)\.[a-z]+\([^)]*(?:password|ssn|social_security|credit_card|dob|date_of_birth)/i },
38
+ ];
39
+
40
+ /**
41
+ * PrivacyAgent checks for privacy violations and PII exposure risks.
42
+ */
43
+ export class PrivacyAgent {
44
+ constructor(options = {}) {
45
+ this.patterns = options.patterns || PII_PATTERNS;
46
+ }
47
+
48
+ /**
49
+ * Scan content for privacy violations.
50
+ *
51
+ * @param {string} content
52
+ * @param {{ filePath?: string }} [options]
53
+ * @returns {{ compliant: boolean, findings: Finding[] }}
54
+ */
55
+ scanContent(content, options = {}) {
56
+ if (!content || typeof content !== 'string') {
57
+ return { compliant: true, findings: [] };
58
+ }
59
+
60
+ const findings = [];
61
+ const lines = content.split('\n');
62
+
63
+ for (let lineNum = 0; lineNum < lines.length; lineNum++) {
64
+ const line = lines[lineNum];
65
+ if (/^\s*\/\//.test(line) || /^\s*#/.test(line)) continue;
66
+
67
+ for (const { id, label, pattern } of this.patterns) {
68
+ if (pattern.test(line)) {
69
+ findings.push({
70
+ rule: id,
71
+ label,
72
+ line: lineNum + 1,
73
+ preview: line.trim().slice(0, 80),
74
+ file: options.filePath,
75
+ severity: 'high',
76
+ });
77
+ }
78
+ }
79
+ }
80
+
81
+ return { compliant: findings.length === 0, findings };
82
+ }
83
+ }
@@ -0,0 +1,103 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: SECURITY.AGENT.PROMPT
5
+ TAG: SECURITY.SCANNER.PROMPT.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=shield-alert
15
+
16
+ 5WH:
17
+ WHAT = Prompt security agent — scans prompt files and agent instructions for unsafe patterns
18
+ WHY = Malicious prompt injection can compromise AI agent behavior and expose sensitive operations
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/security/prompt-security-agent.js
21
+ WHEN = 2026
22
+ HOW = Pattern matching against known prompt injection techniques and unsafe instruction patterns
23
+
24
+ AGENTS:
25
+ PROMPT
26
+ POLICY
27
+ SECRET
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join } from 'node:path';
35
+
36
+ const INJECTION_PATTERNS = [
37
+ { id: 'ignore_instructions', label: 'Ignore instructions injection', pattern: /ignore\s+(?:all\s+)?(?:previous|above)\s+instructions/i },
38
+ { id: 'jailbreak_attempt', label: 'Jailbreak attempt', pattern: /(?:pretend|act as if|you are now|new mode|developer mode)/i },
39
+ { id: 'data_exfil', label: 'Data exfiltration attempt', pattern: /(?:send|email|post|upload)\s+(?:all|the|your)\s+(?:data|files|secrets|passwords|keys)/i },
40
+ { id: 'role_override', label: 'Role override attempt', pattern: /you\s+(?:must|shall|will)\s+(?:now\s+)?(?:act|behave|respond)\s+as/i },
41
+ { id: 'system_override', label: 'System prompt override', pattern: /\[SYSTEM\]|\{\{system\}\}|<system>/i },
42
+ { id: 'base64_injection', label: 'Encoded injection', pattern: /eval\s*\(\s*atob\s*\(|base64_decode\s*\(/ },
43
+ ];
44
+
45
+ /**
46
+ * PromptSecurityAgent scans prompt templates and agent instructions for injection risks.
47
+ */
48
+ export class PromptSecurityAgent {
49
+ constructor(options = {}) {
50
+ this.rootDir = options.rootDir || process.cwd();
51
+ this.patterns = options.patterns || INJECTION_PATTERNS;
52
+ }
53
+
54
+ /**
55
+ * Scan content for prompt injection patterns.
56
+ *
57
+ * @param {string} content
58
+ * @param {{ filePath?: string }} [options]
59
+ * @returns {{ safe: boolean, findings: Finding[] }}
60
+ */
61
+ scanContent(content, options = {}) {
62
+ if (!content || typeof content !== 'string') {
63
+ return { safe: true, findings: [] };
64
+ }
65
+
66
+ const findings = [];
67
+ const lines = content.split('\n');
68
+
69
+ for (let lineNum = 0; lineNum < lines.length; lineNum++) {
70
+ const line = lines[lineNum];
71
+ for (const { id, label, pattern } of this.patterns) {
72
+ if (pattern.test(line)) {
73
+ findings.push({
74
+ rule: id,
75
+ label,
76
+ line: lineNum + 1,
77
+ preview: line.trim().slice(0, 80),
78
+ file: options.filePath,
79
+ severity: 'critical',
80
+ });
81
+ }
82
+ }
83
+ }
84
+
85
+ return { safe: findings.length === 0, findings };
86
+ }
87
+
88
+ /**
89
+ * Scan a prompt file.
90
+ *
91
+ * @param {string} filePath
92
+ * @returns {Promise<{ safe: boolean, findings: Finding[] }>}
93
+ */
94
+ async scanFile(filePath) {
95
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
96
+ try {
97
+ const content = await readFile(fullPath, 'utf8');
98
+ return this.scanContent(content, { filePath });
99
+ } catch {
100
+ return { safe: true, findings: [], error: 'Cannot read file' };
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,108 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: SECURITY.AGENT.SCANNER
5
+ TAG: SECURITY.SCANNER.SECRET.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=eye-off
15
+
16
+ 5WH:
17
+ WHAT = Secret scan agent — looks for secrets and unsafe credential handling in source code
18
+ WHY = Committed secrets are a critical security vulnerability; this agent prevents them
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/security/secret-scan-agent.js
21
+ WHEN = 2026
22
+ HOW = Pattern matching against known secret formats, env var names, and credential patterns
23
+
24
+ AGENTS:
25
+ SECRET
26
+ POLICY
27
+ AUDIT
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join } from 'node:path';
35
+
36
+ const SECRET_PATTERNS = [
37
+ { id: 'api_key_inline', label: 'Inline API key', pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*['"`][a-zA-Z0-9\-_]{16,}['"`]/i },
38
+ { id: 'password_inline', label: 'Inline password', pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"`][^'"`\s]{8,}['"`]/i },
39
+ { id: 'secret_inline', label: 'Inline secret', pattern: /(?:secret|private[_-]?key)\s*[:=]\s*['"`][a-zA-Z0-9\-_+/]{16,}['"`]/i },
40
+ { id: 'token_inline', label: 'Inline token', pattern: /(?:token|auth[_-]?token)\s*[:=]\s*['"`][a-zA-Z0-9\-_.]{16,}['"`]/i },
41
+ { id: 'openai_key', label: 'OpenAI API key', pattern: /sk-[a-zA-Z0-9]{32,}/ },
42
+ { id: 'jwt_inline', label: 'Hardcoded JWT', pattern: /eyJ[a-zA-Z0-9\-_]+\.eyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+/ },
43
+ { id: 'aws_key', label: 'AWS access key', pattern: /AKIA[0-9A-Z]{16}/ },
44
+ { id: 'connection_string', label: 'Database connection string', pattern: /(?:mongodb|postgres|mysql|redis):\/\/[a-zA-Z0-9._%+\-]+:[a-zA-Z0-9._%+\-@]+\/[a-zA-Z0-9]+/ },
45
+ ];
46
+
47
+ /**
48
+ * SecretScanAgent scans source files for hardcoded secrets.
49
+ */
50
+ export class SecretScanAgent {
51
+ constructor(options = {}) {
52
+ this.rootDir = options.rootDir || process.cwd();
53
+ this.patterns = options.patterns || SECRET_PATTERNS;
54
+ }
55
+
56
+ /**
57
+ * Scan file content for secret patterns.
58
+ *
59
+ * @param {string} content
60
+ * @param {{ filePath?: string }} [options]
61
+ * @returns {{ clean: boolean, findings: Finding[] }}
62
+ */
63
+ scanContent(content, options = {}) {
64
+ if (!content || typeof content !== 'string') {
65
+ return { clean: true, findings: [] };
66
+ }
67
+
68
+ const findings = [];
69
+ const lines = content.split('\n');
70
+
71
+ for (let lineNum = 0; lineNum < lines.length; lineNum++) {
72
+ const line = lines[lineNum];
73
+
74
+ if (/^\s*\/\//.test(line) || /^\s*#/.test(line)) continue;
75
+ if (/process\.env\[/.test(line) || /process\.env\./.test(line)) continue;
76
+
77
+ for (const { id, label, pattern } of this.patterns) {
78
+ if (pattern.test(line)) {
79
+ findings.push({
80
+ rule: id,
81
+ label,
82
+ line: lineNum + 1,
83
+ preview: line.trim().slice(0, 80),
84
+ file: options.filePath,
85
+ });
86
+ }
87
+ }
88
+ }
89
+
90
+ return { clean: findings.length === 0, findings };
91
+ }
92
+
93
+ /**
94
+ * Scan a file for secrets.
95
+ *
96
+ * @param {string} filePath
97
+ * @returns {Promise<{ clean: boolean, findings: Finding[] }>}
98
+ */
99
+ async scanFile(filePath) {
100
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
101
+ try {
102
+ const content = await readFile(fullPath, 'utf8');
103
+ return this.scanContent(content, { filePath });
104
+ } catch {
105
+ return { clean: true, findings: [], error: 'Cannot read file' };
106
+ }
107
+ }
108
+ }
@@ -0,0 +1,105 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: SECURITY.AGENT.ACCESS
5
+ TAG: SECURITY.ACCESS.TOOL.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=key
15
+
16
+ 5WH:
17
+ WHAT = Tool access agent — ensures tools are called only through approved paths
18
+ WHY = Unapproved tool invocation paths create unauditable side effects and security gaps
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/security/tool-access-agent.js
21
+ WHEN = 2026
22
+ HOW = Validates tool call paths against an approved routes registry
23
+
24
+ AGENTS:
25
+ TOOL
26
+ POLICY
27
+ PERMISSION
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ /**
34
+ * ToolAccessAgent validates that tool invocations follow approved access paths.
35
+ */
36
+ export class ToolAccessAgent {
37
+ constructor(options = {}) {
38
+ this.approvedRoutes = options.approvedRoutes || new Map();
39
+ this.deniedRoutes = options.deniedRoutes || new Set();
40
+ }
41
+
42
+ /**
43
+ * Register an approved tool invocation route.
44
+ *
45
+ * @param {string} toolName
46
+ * @param {string[]} allowedCallers - Agent names permitted to call this tool
47
+ */
48
+ registerApprovedRoute(toolName, allowedCallers) {
49
+ this.approvedRoutes.set(toolName.toUpperCase(), allowedCallers.map(c => c.toUpperCase()));
50
+ }
51
+
52
+ /**
53
+ * Register a denied tool invocation route.
54
+ *
55
+ * @param {string} toolName
56
+ */
57
+ denyTool(toolName) {
58
+ this.deniedRoutes.add(toolName.toUpperCase());
59
+ }
60
+
61
+ /**
62
+ * Check if a tool invocation is allowed.
63
+ *
64
+ * @param {string} toolName
65
+ * @param {string} callerAgent
66
+ * @returns {{ allowed: boolean, reason: string }}
67
+ */
68
+ checkAccess(toolName, callerAgent) {
69
+ const tool = toolName.toUpperCase();
70
+ const caller = callerAgent.toUpperCase();
71
+
72
+ if (this.deniedRoutes.has(tool)) {
73
+ return { allowed: false, reason: `Tool "${toolName}" is explicitly denied` };
74
+ }
75
+
76
+ const approvedCallers = this.approvedRoutes.get(tool);
77
+ if (!approvedCallers) {
78
+ return { allowed: true, reason: `Tool "${toolName}" has no access restrictions` };
79
+ }
80
+
81
+ if (approvedCallers.includes('*') || approvedCallers.includes(caller)) {
82
+ return { allowed: true, reason: `Caller "${callerAgent}" is approved for tool "${toolName}"` };
83
+ }
84
+
85
+ return {
86
+ allowed: false,
87
+ reason: `Caller "${callerAgent}" is not in approved list for tool "${toolName}": [${approvedCallers.join(', ')}]`,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Validate a batch of tool invocations.
93
+ *
94
+ * @param {{ tool: string, caller: string }[]} invocations
95
+ * @returns {{ valid: boolean, violations: object[] }}
96
+ */
97
+ validateBatch(invocations) {
98
+ const violations = [];
99
+ for (const { tool, caller } of invocations) {
100
+ const result = this.checkAccess(tool, caller);
101
+ if (!result.allowed) violations.push({ tool, caller, reason: result.reason });
102
+ }
103
+ return { valid: violations.length === 0, violations };
104
+ }
105
+ }
@@ -0,0 +1,114 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.AUTHORITY.MAIN
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=shield
15
+
16
+ 5WH:
17
+ WHAT = Authority agent — declares allowed actions, denied actions, and execution scope per file/module
18
+ WHY = Governance requires explicit declaration of what each file is permitted to do
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/authority-agent.js
21
+ WHEN = 2026
22
+ HOW = Reads LEEWAY headers and .leeway/authority.json to validate action permissions
23
+
24
+ AGENTS:
25
+ AUTHORITY
26
+ POLICY
27
+ AUDIT
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join } from 'node:path';
35
+ import { parseHeader } from '../../core/header-parser.js';
36
+
37
+ const DEFAULT_AUTHORITY = {
38
+ allowedActions: ['read', 'write', 'transform', 'export'],
39
+ deniedActions: ['execute_shell', 'network_request', 'modify_secrets', 'delete_files'],
40
+ executionScope: 'module',
41
+ };
42
+
43
+ /**
44
+ * AuthorityAgent declares and validates what actions a file or module is permitted to perform.
45
+ */
46
+ export class AuthorityAgent {
47
+ constructor(options = {}) {
48
+ this.rootDir = options.rootDir || process.cwd();
49
+ this.authorityConfig = null;
50
+ }
51
+
52
+ /**
53
+ * Load the project-level authority configuration.
54
+ */
55
+ async loadConfig() {
56
+ const configPath = join(this.rootDir, '.leeway', 'authority.json');
57
+ try {
58
+ const raw = await readFile(configPath, 'utf8');
59
+ this.authorityConfig = JSON.parse(raw);
60
+ } catch {
61
+ this.authorityConfig = { default: DEFAULT_AUTHORITY };
62
+ }
63
+ return this.authorityConfig;
64
+ }
65
+
66
+ /**
67
+ * Get the authority declaration for a file.
68
+ *
69
+ * @param {string} filePath
70
+ * @returns {Promise<AuthorityDeclaration>}
71
+ */
72
+ async getFileAuthority(filePath) {
73
+ if (!this.authorityConfig) await this.loadConfig();
74
+
75
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
76
+ let content = '';
77
+ try {
78
+ content = await readFile(fullPath, 'utf8');
79
+ } catch {
80
+ return { file: filePath, status: 'error' };
81
+ }
82
+
83
+ const header = parseHeader(content);
84
+ const region = header?.region?.split('.')?.[0] || 'UNKNOWN';
85
+
86
+ const authority = this.authorityConfig[region]
87
+ || this.authorityConfig['default']
88
+ || DEFAULT_AUTHORITY;
89
+
90
+ return {
91
+ file: filePath,
92
+ region,
93
+ agents: header?.agents || [],
94
+ authority,
95
+ status: 'resolved',
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Check if a specific action is allowed for a file.
101
+ *
102
+ * @param {string} filePath
103
+ * @param {string} action
104
+ * @returns {Promise<boolean>}
105
+ */
106
+ async isActionAllowed(filePath, action) {
107
+ const decl = await this.getFileAuthority(filePath);
108
+ if (decl.status !== 'resolved') return false;
109
+
110
+ const { allowedActions, deniedActions } = decl.authority;
111
+ if (deniedActions.includes(action)) return false;
112
+ return allowedActions.includes(action) || allowedActions.includes('*');
113
+ }
114
+ }
@@ -0,0 +1,91 @@
1
+ /*
2
+ LEEWAY HEADER — DO NOT REMOVE
3
+
4
+ REGION: AI.AGENT.STANDARDS
5
+ TAG: AI.AGENT.DISCOVERY.PIPELINE
6
+
7
+ COLOR_ONION_HEX:
8
+ NEON=#39FF14
9
+ FLUO=#0DFF94
10
+ PASTEL=#C7FFD8
11
+
12
+ ICON_ASCII:
13
+ family=lucide
14
+ glyph=git-merge
15
+
16
+ 5WH:
17
+ WHAT = Discovery pipeline agent — ensures every artifact has the discovery chain metadata
18
+ WHY = LEEWAY applications must be visible to search engines, AI tools, and voice assistants
19
+ WHO = Rapid Web Development
20
+ WHERE = src/agents/standards/discovery-pipeline-agent.js
21
+ WHEN = 2026
22
+ HOW = Checks for Schema.org JSON-LD, OpenGraph, sitemap, and FAQ structured data presence
23
+
24
+ AGENTS:
25
+ DISCOVERY
26
+ SCHEMA
27
+ SITEMAP
28
+
29
+ LICENSE:
30
+ MIT
31
+ */
32
+
33
+ import { readFile } from 'node:fs/promises';
34
+ import { join, extname } from 'node:path';
35
+
36
+ const DISCOVERY_CHECKS = [
37
+ { id: 'jsonld', label: 'Schema.org JSON-LD', pattern: /<script[^>]+type="application\/ld\+json"/i },
38
+ { id: 'opengraph', label: 'OpenGraph meta tags', pattern: /<meta[^>]+property="og:/i },
39
+ { id: 'twitter_card', label: 'Twitter Card meta', pattern: /<meta[^>]+name="twitter:/i },
40
+ { id: 'canonical', label: 'Canonical URL', pattern: /<link[^>]+rel="canonical"/i },
41
+ { id: 'faq', label: 'FAQ structured data', pattern: /"@type"\s*:\s*"FAQPage"/i },
42
+ ];
43
+
44
+ /**
45
+ * DiscoveryPipelineAgent checks that HTML/JSX files include required discovery metadata.
46
+ */
47
+ export class DiscoveryPipelineAgent {
48
+ constructor(options = {}) {
49
+ this.rootDir = options.rootDir || process.cwd();
50
+ }
51
+
52
+ /**
53
+ * Check a file for discovery chain completeness.
54
+ *
55
+ * @param {string} filePath
56
+ * @returns {Promise<DiscoveryCheckResult>}
57
+ */
58
+ async checkFile(filePath) {
59
+ const ext = extname(filePath).toLowerCase();
60
+ const htmlLike = ['.html', '.htm', '.jsx', '.tsx', '.vue', '.svelte'];
61
+
62
+ if (!htmlLike.includes(ext)) {
63
+ return { file: filePath, applicable: false, reason: 'Not an HTML-like file' };
64
+ }
65
+
66
+ const fullPath = filePath.startsWith('/') ? filePath : join(this.rootDir, filePath);
67
+ let content = '';
68
+ try {
69
+ content = await readFile(fullPath, 'utf8');
70
+ } catch {
71
+ return { file: filePath, applicable: true, status: 'error' };
72
+ }
73
+
74
+ const checks = DISCOVERY_CHECKS.map(check => ({
75
+ ...check,
76
+ present: check.pattern.test(content),
77
+ }));
78
+
79
+ const presentCount = checks.filter(c => c.present).length;
80
+ const score = Math.round((presentCount / DISCOVERY_CHECKS.length) * 100);
81
+
82
+ return {
83
+ file: filePath,
84
+ applicable: true,
85
+ score,
86
+ checks,
87
+ missing: checks.filter(c => !c.present).map(c => c.label),
88
+ status: score === 100 ? 'complete' : score >= 60 ? 'partial' : 'incomplete',
89
+ };
90
+ }
91
+ }