fridayy 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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/bin/fridayy.js +12 -0
  4. package/dist/adapters/base.d.ts +40 -0
  5. package/dist/adapters/base.d.ts.map +1 -0
  6. package/dist/adapters/base.js +7 -0
  7. package/dist/adapters/base.js.map +1 -0
  8. package/dist/adapters/manual/adapter.d.ts +18 -0
  9. package/dist/adapters/manual/adapter.d.ts.map +1 -0
  10. package/dist/adapters/manual/adapter.js +52 -0
  11. package/dist/adapters/manual/adapter.js.map +1 -0
  12. package/dist/adapters/nodejs/adapter.d.ts +19 -0
  13. package/dist/adapters/nodejs/adapter.d.ts.map +1 -0
  14. package/dist/adapters/nodejs/adapter.js +135 -0
  15. package/dist/adapters/nodejs/adapter.js.map +1 -0
  16. package/dist/adapters/nodejs/ast-scanner.d.ts +21 -0
  17. package/dist/adapters/nodejs/ast-scanner.d.ts.map +1 -0
  18. package/dist/adapters/nodejs/ast-scanner.js +102 -0
  19. package/dist/adapters/nodejs/ast-scanner.js.map +1 -0
  20. package/dist/adapters/openapi/adapter.d.ts +22 -0
  21. package/dist/adapters/openapi/adapter.d.ts.map +1 -0
  22. package/dist/adapters/openapi/adapter.js +271 -0
  23. package/dist/adapters/openapi/adapter.js.map +1 -0
  24. package/dist/adapters/openapi/parser.d.ts +30 -0
  25. package/dist/adapters/openapi/parser.d.ts.map +1 -0
  26. package/dist/adapters/openapi/parser.js +136 -0
  27. package/dist/adapters/openapi/parser.js.map +1 -0
  28. package/dist/adapters/openapi/request-builder.d.ts +13 -0
  29. package/dist/adapters/openapi/request-builder.d.ts.map +1 -0
  30. package/dist/adapters/openapi/request-builder.js +83 -0
  31. package/dist/adapters/openapi/request-builder.js.map +1 -0
  32. package/dist/adapters/registry.d.ts +28 -0
  33. package/dist/adapters/registry.d.ts.map +1 -0
  34. package/dist/adapters/registry.js +46 -0
  35. package/dist/adapters/registry.js.map +1 -0
  36. package/dist/adapters/rest/adapter.d.ts +18 -0
  37. package/dist/adapters/rest/adapter.d.ts.map +1 -0
  38. package/dist/adapters/rest/adapter.js +41 -0
  39. package/dist/adapters/rest/adapter.js.map +1 -0
  40. package/dist/adapters/rest/executor.d.ts +19 -0
  41. package/dist/adapters/rest/executor.d.ts.map +1 -0
  42. package/dist/adapters/rest/executor.js +101 -0
  43. package/dist/adapters/rest/executor.js.map +1 -0
  44. package/dist/cli/commands/config.d.ts +7 -0
  45. package/dist/cli/commands/config.d.ts.map +1 -0
  46. package/dist/cli/commands/config.js +92 -0
  47. package/dist/cli/commands/config.js.map +1 -0
  48. package/dist/cli/commands/doctor.d.ts +7 -0
  49. package/dist/cli/commands/doctor.d.ts.map +1 -0
  50. package/dist/cli/commands/doctor.js +126 -0
  51. package/dist/cli/commands/doctor.js.map +1 -0
  52. package/dist/cli/commands/generate.d.ts +7 -0
  53. package/dist/cli/commands/generate.d.ts.map +1 -0
  54. package/dist/cli/commands/generate.js +58 -0
  55. package/dist/cli/commands/generate.js.map +1 -0
  56. package/dist/cli/commands/init.d.ts +7 -0
  57. package/dist/cli/commands/init.d.ts.map +1 -0
  58. package/dist/cli/commands/init.js +54 -0
  59. package/dist/cli/commands/init.js.map +1 -0
  60. package/dist/cli/commands/review.d.ts +7 -0
  61. package/dist/cli/commands/review.d.ts.map +1 -0
  62. package/dist/cli/commands/review.js +151 -0
  63. package/dist/cli/commands/review.js.map +1 -0
  64. package/dist/cli/commands/scan.d.ts +7 -0
  65. package/dist/cli/commands/scan.d.ts.map +1 -0
  66. package/dist/cli/commands/scan.js +77 -0
  67. package/dist/cli/commands/scan.js.map +1 -0
  68. package/dist/cli/commands/start.d.ts +7 -0
  69. package/dist/cli/commands/start.d.ts.map +1 -0
  70. package/dist/cli/commands/start.js +54 -0
  71. package/dist/cli/commands/start.js.map +1 -0
  72. package/dist/cli/commands/tools.d.ts +7 -0
  73. package/dist/cli/commands/tools.d.ts.map +1 -0
  74. package/dist/cli/commands/tools.js +48 -0
  75. package/dist/cli/commands/tools.js.map +1 -0
  76. package/dist/cli/index.d.ts +8 -0
  77. package/dist/cli/index.d.ts.map +1 -0
  78. package/dist/cli/index.js +42 -0
  79. package/dist/cli/index.js.map +1 -0
  80. package/dist/cli/ui/banner.d.ts +6 -0
  81. package/dist/cli/ui/banner.d.ts.map +1 -0
  82. package/dist/cli/ui/banner.js +20 -0
  83. package/dist/cli/ui/banner.js.map +1 -0
  84. package/dist/cli/ui/logger.d.ts +12 -0
  85. package/dist/cli/ui/logger.d.ts.map +1 -0
  86. package/dist/cli/ui/logger.js +13 -0
  87. package/dist/cli/ui/logger.js.map +1 -0
  88. package/dist/cli/ui/tables.d.ts +9 -0
  89. package/dist/cli/ui/tables.d.ts.map +1 -0
  90. package/dist/cli/ui/tables.js +72 -0
  91. package/dist/cli/ui/tables.js.map +1 -0
  92. package/dist/config/config-manager.d.ts +37 -0
  93. package/dist/config/config-manager.d.ts.map +1 -0
  94. package/dist/config/config-manager.js +129 -0
  95. package/dist/config/config-manager.js.map +1 -0
  96. package/dist/config/defaults.d.ts +8 -0
  97. package/dist/config/defaults.d.ts.map +1 -0
  98. package/dist/config/defaults.js +37 -0
  99. package/dist/config/defaults.js.map +1 -0
  100. package/dist/core/authentication/manager.d.ts +20 -0
  101. package/dist/core/authentication/manager.d.ts.map +1 -0
  102. package/dist/core/authentication/manager.js +71 -0
  103. package/dist/core/authentication/manager.js.map +1 -0
  104. package/dist/core/authentication/secret-resolver.d.ts +39 -0
  105. package/dist/core/authentication/secret-resolver.d.ts.map +1 -0
  106. package/dist/core/authentication/secret-resolver.js +89 -0
  107. package/dist/core/authentication/secret-resolver.js.map +1 -0
  108. package/dist/core/discovery/index.d.ts +5 -0
  109. package/dist/core/discovery/index.d.ts.map +1 -0
  110. package/dist/core/discovery/index.js +5 -0
  111. package/dist/core/discovery/index.js.map +1 -0
  112. package/dist/core/discovery/project-scanner.d.ts +20 -0
  113. package/dist/core/discovery/project-scanner.d.ts.map +1 -0
  114. package/dist/core/discovery/project-scanner.js +174 -0
  115. package/dist/core/discovery/project-scanner.js.map +1 -0
  116. package/dist/core/permissions/classifier.d.ts +25 -0
  117. package/dist/core/permissions/classifier.d.ts.map +1 -0
  118. package/dist/core/permissions/classifier.js +92 -0
  119. package/dist/core/permissions/classifier.js.map +1 -0
  120. package/dist/core/permissions/enforcer.d.ts +24 -0
  121. package/dist/core/permissions/enforcer.d.ts.map +1 -0
  122. package/dist/core/permissions/enforcer.js +71 -0
  123. package/dist/core/permissions/enforcer.js.map +1 -0
  124. package/dist/core/schema/json-schema.d.ts +29 -0
  125. package/dist/core/schema/json-schema.d.ts.map +1 -0
  126. package/dist/core/schema/json-schema.js +129 -0
  127. package/dist/core/schema/json-schema.js.map +1 -0
  128. package/dist/core/schema/types.d.ts +187 -0
  129. package/dist/core/schema/types.d.ts.map +1 -0
  130. package/dist/core/schema/types.js +6 -0
  131. package/dist/core/schema/types.js.map +1 -0
  132. package/dist/core/tool-generator/description-builder.d.ts +15 -0
  133. package/dist/core/tool-generator/description-builder.d.ts.map +1 -0
  134. package/dist/core/tool-generator/description-builder.js +32 -0
  135. package/dist/core/tool-generator/description-builder.js.map +1 -0
  136. package/dist/core/tool-generator/generator.d.ts +21 -0
  137. package/dist/core/tool-generator/generator.d.ts.map +1 -0
  138. package/dist/core/tool-generator/generator.js +61 -0
  139. package/dist/core/tool-generator/generator.js.map +1 -0
  140. package/dist/core/tool-generator/name-sanitizer.d.ts +21 -0
  141. package/dist/core/tool-generator/name-sanitizer.d.ts.map +1 -0
  142. package/dist/core/tool-generator/name-sanitizer.js +84 -0
  143. package/dist/core/tool-generator/name-sanitizer.js.map +1 -0
  144. package/dist/core/validation/config-schema.d.ts +1458 -0
  145. package/dist/core/validation/config-schema.d.ts.map +1 -0
  146. package/dist/core/validation/config-schema.js +137 -0
  147. package/dist/core/validation/config-schema.js.map +1 -0
  148. package/dist/core/validation/validator.d.ts +28 -0
  149. package/dist/core/validation/validator.d.ts.map +1 -0
  150. package/dist/core/validation/validator.js +108 -0
  151. package/dist/core/validation/validator.js.map +1 -0
  152. package/dist/index.d.ts +38 -0
  153. package/dist/index.d.ts.map +1 -0
  154. package/dist/index.js +38 -0
  155. package/dist/index.js.map +1 -0
  156. package/dist/mcp/prompts/prompt-registry.d.ts +28 -0
  157. package/dist/mcp/prompts/prompt-registry.d.ts.map +1 -0
  158. package/dist/mcp/prompts/prompt-registry.js +65 -0
  159. package/dist/mcp/prompts/prompt-registry.js.map +1 -0
  160. package/dist/mcp/resources/resource-registry.d.ts +26 -0
  161. package/dist/mcp/resources/resource-registry.d.ts.map +1 -0
  162. package/dist/mcp/resources/resource-registry.js +87 -0
  163. package/dist/mcp/resources/resource-registry.js.map +1 -0
  164. package/dist/mcp/server/fridayy-server.d.ts +38 -0
  165. package/dist/mcp/server/fridayy-server.d.ts.map +1 -0
  166. package/dist/mcp/server/fridayy-server.js +143 -0
  167. package/dist/mcp/server/fridayy-server.js.map +1 -0
  168. package/dist/mcp/tools/tool-handler.d.ts +29 -0
  169. package/dist/mcp/tools/tool-handler.d.ts.map +1 -0
  170. package/dist/mcp/tools/tool-handler.js +206 -0
  171. package/dist/mcp/tools/tool-handler.js.map +1 -0
  172. package/dist/mcp/tools/tool-registry.d.ts +20 -0
  173. package/dist/mcp/tools/tool-registry.d.ts.map +1 -0
  174. package/dist/mcp/tools/tool-registry.js +38 -0
  175. package/dist/mcp/tools/tool-registry.js.map +1 -0
  176. package/dist/security/allowlist.d.ts +10 -0
  177. package/dist/security/allowlist.d.ts.map +1 -0
  178. package/dist/security/allowlist.js +30 -0
  179. package/dist/security/allowlist.js.map +1 -0
  180. package/dist/security/audit-logger.d.ts +35 -0
  181. package/dist/security/audit-logger.d.ts.map +1 -0
  182. package/dist/security/audit-logger.js +52 -0
  183. package/dist/security/audit-logger.js.map +1 -0
  184. package/dist/security/rate-limiter.d.ts +28 -0
  185. package/dist/security/rate-limiter.d.ts.map +1 -0
  186. package/dist/security/rate-limiter.js +64 -0
  187. package/dist/security/rate-limiter.js.map +1 -0
  188. package/dist/security/sanitizer.d.ts +17 -0
  189. package/dist/security/sanitizer.d.ts.map +1 -0
  190. package/dist/security/sanitizer.js +70 -0
  191. package/dist/security/sanitizer.js.map +1 -0
  192. package/package.json +77 -0
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Fridayy - Discovery Exports
3
+ */
4
+ export * from './project-scanner.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/discovery/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Fridayy - Discovery Exports
3
+ */
4
+ export * from './project-scanner.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/discovery/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Fridayy - Project Scanner & Capability Discovery
3
+ * Analyzes projects, repositories, and APIs to detect capabilities, specs, and auth mechanisms.
4
+ */
5
+ import { ScanResult } from '../schema/types.js';
6
+ import { AdapterRegistry } from '../../adapters/registry.js';
7
+ export declare class ProjectScanner {
8
+ private adapterRegistry;
9
+ private openApiParser;
10
+ private nodeJsScanner;
11
+ constructor(adapterRegistry?: AdapterRegistry);
12
+ /**
13
+ * Scans a root directory and returns comprehensive capability detection results.
14
+ */
15
+ scan(rootDir?: string): Promise<ScanResult>;
16
+ private findOpenApiFiles;
17
+ private countEndpoints;
18
+ }
19
+ export declare const defaultProjectScanner: ProjectScanner;
20
+ //# sourceMappingURL=project-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-scanner.d.ts","sourceRoot":"","sources":["../../../src/core/discovery/project-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAIrF,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,aAAa,CAAuB;gBAEhC,eAAe,GAAE,eAAwC;IAIrE;;OAEG;IACU,IAAI,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAyGvE,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,cAAc;CAcvB;AAED,eAAO,MAAM,qBAAqB,gBAAuB,CAAC"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Fridayy - Project Scanner & Capability Discovery
3
+ * Analyzes projects, repositories, and APIs to detect capabilities, specs, and auth mechanisms.
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { defaultAdapterRegistry } from '../../adapters/registry.js';
8
+ import { OpenApiParser } from '../../adapters/openapi/parser.js';
9
+ import { NodeJsScanner } from '../../adapters/nodejs/ast-scanner.js';
10
+ export class ProjectScanner {
11
+ adapterRegistry;
12
+ openApiParser = new OpenApiParser();
13
+ nodeJsScanner = new NodeJsScanner();
14
+ constructor(adapterRegistry = defaultAdapterRegistry) {
15
+ this.adapterRegistry = adapterRegistry;
16
+ }
17
+ /**
18
+ * Scans a root directory and returns comprehensive capability detection results.
19
+ */
20
+ async scan(rootDir = process.cwd()) {
21
+ const absRoot = path.resolve(rootDir);
22
+ // 1. Scan for OpenAPI files
23
+ const openApiFiles = this.findOpenApiFiles(absRoot);
24
+ const hasOpenApi = openApiFiles.length > 0;
25
+ const openApiSpecsDetails = [];
26
+ const authSchemesDetected = new Set();
27
+ let totalEndpoints = 0;
28
+ for (const relFile of openApiFiles) {
29
+ try {
30
+ const parsed = await this.openApiParser.parse(relFile, absRoot);
31
+ const opCount = this.countEndpoints(parsed.paths);
32
+ totalEndpoints += opCount;
33
+ openApiSpecsDetails.push({
34
+ path: relFile,
35
+ version: parsed.version,
36
+ title: parsed.title,
37
+ endpointsCount: opCount
38
+ });
39
+ // Collect security schemes
40
+ if (parsed.securityDefinitions) {
41
+ for (const [schemeName, schemeDef] of Object.entries(parsed.securityDefinitions)) {
42
+ authSchemesDetected.add(schemeName);
43
+ }
44
+ }
45
+ }
46
+ catch {
47
+ // Skip unparseable specs
48
+ }
49
+ }
50
+ // 2. Scan for Node.js routes & frameworks
51
+ const pkgJsonPath = path.join(absRoot, 'package.json');
52
+ let hasNodeJs = false;
53
+ let nodeJsFramework = 'none';
54
+ if (fs.existsSync(pkgJsonPath)) {
55
+ hasNodeJs = true;
56
+ try {
57
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
58
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
59
+ if (allDeps.express)
60
+ nodeJsFramework = 'express';
61
+ else if (allDeps.fastify)
62
+ nodeJsFramework = 'fastify';
63
+ else if (allDeps.koa)
64
+ nodeJsFramework = 'koa';
65
+ else if (allDeps['@nestjs/core'])
66
+ nodeJsFramework = 'nestjs';
67
+ else
68
+ nodeJsFramework = 'custom';
69
+ }
70
+ catch {
71
+ nodeJsFramework = 'custom';
72
+ }
73
+ }
74
+ const discoveredRoutes = await this.nodeJsScanner.scanDirectory(absRoot, 100);
75
+ if (discoveredRoutes.length > 0 && !hasOpenApi) {
76
+ totalEndpoints += discoveredRoutes.length;
77
+ }
78
+ // 3. Formulate recommended configuration
79
+ const projectName = path.basename(absRoot);
80
+ const recommendedConfig = {
81
+ name: projectName,
82
+ version: '1.0.0',
83
+ source: hasOpenApi
84
+ ? {
85
+ type: 'openapi',
86
+ path: openApiFiles[0]
87
+ }
88
+ : hasNodeJs && discoveredRoutes.length > 0
89
+ ? {
90
+ type: 'nodejs',
91
+ rootDir: './'
92
+ }
93
+ : {
94
+ type: 'openapi',
95
+ path: './openapi.yaml'
96
+ },
97
+ server: {
98
+ name: `${projectName}-mcp`,
99
+ version: '1.0.0',
100
+ transport: 'stdio'
101
+ },
102
+ security: {
103
+ requireApprovalForDestructive: true,
104
+ autoApproveRead: true,
105
+ autoApproveWrite: false
106
+ }
107
+ };
108
+ return {
109
+ hasOpenApi,
110
+ openApiFiles,
111
+ hasNodeJs,
112
+ nodeJsFramework,
113
+ discoveredEndpointsCount: totalEndpoints,
114
+ authSchemesDetected: Array.from(authSchemesDetected),
115
+ recommendedConfig,
116
+ details: {
117
+ openApiSpecs: openApiSpecsDetails,
118
+ routes: discoveredRoutes
119
+ }
120
+ };
121
+ }
122
+ findOpenApiFiles(rootDir) {
123
+ const candidates = [
124
+ 'openapi.yaml',
125
+ 'openapi.yml',
126
+ 'openapi.json',
127
+ 'swagger.yaml',
128
+ 'swagger.yml',
129
+ 'swagger.json',
130
+ 'api/openapi.yaml',
131
+ 'api/openapi.json',
132
+ 'docs/openapi.yaml',
133
+ 'docs/openapi.json'
134
+ ];
135
+ const found = [];
136
+ for (const rel of candidates) {
137
+ if (fs.existsSync(path.join(rootDir, rel))) {
138
+ found.push(rel);
139
+ }
140
+ }
141
+ // Also search root for any *.openapi.json or *.swagger.yaml
142
+ try {
143
+ const files = fs.readdirSync(rootDir);
144
+ for (const file of files) {
145
+ if ((file.includes('openapi') || file.includes('swagger')) && !found.includes(file)) {
146
+ const ext = path.extname(file).toLowerCase();
147
+ if (['.json', '.yaml', '.yml'].includes(ext)) {
148
+ found.push(file);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ catch {
154
+ // ignore
155
+ }
156
+ return found;
157
+ }
158
+ countEndpoints(paths) {
159
+ let count = 0;
160
+ const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
161
+ for (const pathItem of Object.values(paths)) {
162
+ if (pathItem && typeof pathItem === 'object') {
163
+ for (const m of methods) {
164
+ if (pathItem[m]) {
165
+ count++;
166
+ }
167
+ }
168
+ }
169
+ }
170
+ return count;
171
+ }
172
+ }
173
+ export const defaultProjectScanner = new ProjectScanner();
174
+ //# sourceMappingURL=project-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-scanner.js","sourceRoot":"","sources":["../../../src/core/discovery/project-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Fridayy - Permission Classifier & Risk Assessment Engine
3
+ * Classifies API endpoints into READ, WRITE, and DESTRUCTIVE with risk scoring.
4
+ */
5
+ import { ToolRiskLevel, ToolApprovalStatus, ToolPermissions, FridayyConfig } from '../schema/types.js';
6
+ export interface ClassificationContext {
7
+ method?: string;
8
+ path?: string;
9
+ operationId?: string;
10
+ name?: string;
11
+ summary?: string;
12
+ description?: string;
13
+ tags?: string[];
14
+ }
15
+ export interface ClassificationResult {
16
+ permissions: ToolPermissions;
17
+ risk: ToolRiskLevel;
18
+ status: ToolApprovalStatus;
19
+ reason: string;
20
+ }
21
+ /**
22
+ * Classifies an operation based on HTTP method, path, operationId, and naming keywords.
23
+ */
24
+ export declare function classifyOperation(ctx: ClassificationContext, config?: FridayyConfig): ClassificationResult;
25
+ //# sourceMappingURL=classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../../src/core/permissions/classifier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,aAAa,EACd,MAAM,oBAAoB,CAAC;AAqB5B,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,eAAe,CAAC;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,qBAAqB,EAC1B,MAAM,CAAC,EAAE,aAAa,GACrB,oBAAoB,CAqEtB"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Fridayy - Permission Classifier & Risk Assessment Engine
3
+ * Classifies API endpoints into READ, WRITE, and DESTRUCTIVE with risk scoring.
4
+ */
5
+ const DESTRUCTIVE_KEYWORDS = [
6
+ 'delete',
7
+ 'remove',
8
+ 'destroy',
9
+ 'purge',
10
+ 'erase',
11
+ 'drop',
12
+ 'truncate',
13
+ 'kill',
14
+ 'terminate',
15
+ 'wipe',
16
+ 'reset',
17
+ 'cancel',
18
+ 'revoke',
19
+ 'uninstall',
20
+ 'expire',
21
+ 'block'
22
+ ];
23
+ /**
24
+ * Classifies an operation based on HTTP method, path, operationId, and naming keywords.
25
+ */
26
+ export function classifyOperation(ctx, config) {
27
+ const method = (ctx.method || 'GET').toUpperCase();
28
+ const fullText = [
29
+ ctx.name || '',
30
+ ctx.operationId || '',
31
+ ctx.path || '',
32
+ ctx.summary || '',
33
+ ctx.description || ''
34
+ ]
35
+ .join(' ')
36
+ .toLowerCase();
37
+ // 1. Check for DESTRUCTIVE operations
38
+ const isDeleteMethod = method === 'DELETE';
39
+ const hasDestructiveKeyword = DESTRUCTIVE_KEYWORDS.some(kw => {
40
+ // Word boundary or underscore boundary check
41
+ const regex = new RegExp(`\\b${kw}\\b|_${kw}_|^${kw}_|_${kw}$`, 'i');
42
+ return regex.test(fullText);
43
+ });
44
+ if (isDeleteMethod || hasDestructiveKeyword) {
45
+ const isExplicitlyApproved = false;
46
+ return {
47
+ permissions: {
48
+ type: 'DESTRUCTIVE',
49
+ read: false,
50
+ write: true,
51
+ destructive: true,
52
+ requiresConfirmation: true
53
+ },
54
+ risk: 'high',
55
+ status: isExplicitlyApproved ? 'APPROVED' : 'BLOCKED',
56
+ reason: isDeleteMethod
57
+ ? 'DELETE HTTP method carries destructive risk.'
58
+ : `Operation contains destructive action keyword: "${hasDestructiveKeyword}".`
59
+ };
60
+ }
61
+ // 2. Check for READ operations
62
+ if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS') {
63
+ const autoApproveRead = config?.security?.autoApproveRead ?? true;
64
+ return {
65
+ permissions: {
66
+ type: 'READ',
67
+ read: true,
68
+ write: false,
69
+ destructive: false,
70
+ requiresConfirmation: false
71
+ },
72
+ risk: 'low',
73
+ status: autoApproveRead ? 'APPROVED' : 'PENDING',
74
+ reason: `${method} HTTP method is a safe read-only operation.`
75
+ };
76
+ }
77
+ // 3. WRITE operations (POST, PUT, PATCH)
78
+ const autoApproveWrite = config?.security?.autoApproveWrite ?? false;
79
+ return {
80
+ permissions: {
81
+ type: 'WRITE',
82
+ read: false,
83
+ write: true,
84
+ destructive: false,
85
+ requiresConfirmation: false
86
+ },
87
+ risk: 'medium',
88
+ status: autoApproveWrite ? 'APPROVED' : 'PENDING',
89
+ reason: `${method} HTTP method mutates server state (WRITE operation).`
90
+ };
91
+ }
92
+ //# sourceMappingURL=classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../../src/core/permissions/classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Fridayy - Permission & Security Enforcer
3
+ * Enforces permission gates, status checks, and access rules for MCP tool invocation.
4
+ */
5
+ import { FridayyToolDefinition, FridayyConfig } from '../schema/types.js';
6
+ export declare class PermissionDeniedError extends Error {
7
+ readonly code: string;
8
+ readonly toolName: string;
9
+ readonly details?: any;
10
+ constructor(message: string, toolName: string, code?: string, details?: any);
11
+ }
12
+ export declare class PermissionEnforcer {
13
+ private config?;
14
+ constructor(config?: FridayyConfig);
15
+ /**
16
+ * Checks if a tool should be visible and exposable to MCP clients.
17
+ */
18
+ isToolExposed(tool: FridayyToolDefinition): boolean;
19
+ /**
20
+ * Enforces permissions before executing a tool. Throws PermissionDeniedError if execution is not allowed.
21
+ */
22
+ validateExecution(tool: FridayyToolDefinition): void;
23
+ }
24
+ //# sourceMappingURL=enforcer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforcer.d.ts","sourceRoot":"","sources":["../../../src/core/permissions/enforcer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE1E,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,OAAO,CAAC,EAAE,GAAG,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,SAAsB,EAAE,OAAO,CAAC,EAAE,GAAG;CAOzF;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,CAAgB;gBAEnB,MAAM,CAAC,EAAE,aAAa;IAIlC;;OAEG;IACI,aAAa,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO;IAsB1D;;OAEG;IACI,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;CAyD5D"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Fridayy - Permission & Security Enforcer
3
+ * Enforces permission gates, status checks, and access rules for MCP tool invocation.
4
+ */
5
+ export class PermissionDeniedError extends Error {
6
+ code;
7
+ toolName;
8
+ details;
9
+ constructor(message, toolName, code = 'PERMISSION_DENIED', details) {
10
+ super(message);
11
+ this.name = 'PermissionDeniedError';
12
+ this.code = code;
13
+ this.toolName = toolName;
14
+ this.details = details;
15
+ }
16
+ }
17
+ export class PermissionEnforcer {
18
+ config;
19
+ constructor(config) {
20
+ this.config = config;
21
+ }
22
+ /**
23
+ * Checks if a tool should be visible and exposable to MCP clients.
24
+ */
25
+ isToolExposed(tool) {
26
+ // 1. Must be APPROVED
27
+ if (tool.status !== 'APPROVED') {
28
+ return false;
29
+ }
30
+ // 2. Check allowlist / denylist from config
31
+ const toolName = tool.name;
32
+ const allowlist = this.config?.security?.allowlist;
33
+ const denylist = this.config?.security?.denylist;
34
+ if (denylist && denylist.includes(toolName)) {
35
+ return false;
36
+ }
37
+ if (allowlist && allowlist.length > 0 && !allowlist.includes(toolName) && !allowlist.includes('*')) {
38
+ return false;
39
+ }
40
+ return true;
41
+ }
42
+ /**
43
+ * Enforces permissions before executing a tool. Throws PermissionDeniedError if execution is not allowed.
44
+ */
45
+ validateExecution(tool) {
46
+ // Check status
47
+ if (tool.status === 'BLOCKED') {
48
+ throw new PermissionDeniedError(`Tool "${tool.name}" is BLOCKED. Destructive operations require explicit developer approval via 'fridayy review'.`, tool.name, 'TOOL_BLOCKED', { status: tool.status, permissions: tool.permissions });
49
+ }
50
+ if (tool.status === 'REJECTED') {
51
+ throw new PermissionDeniedError(`Tool "${tool.name}" is REJECTED and cannot be executed.`, tool.name, 'TOOL_REJECTED', { status: tool.status });
52
+ }
53
+ if (tool.status === 'PENDING') {
54
+ throw new PermissionDeniedError(`Tool "${tool.name}" is PENDING developer review. Run 'fridayy review' to approve it before invoking.`, tool.name, 'TOOL_PENDING_APPROVAL', { status: tool.status });
55
+ }
56
+ if (tool.status !== 'APPROVED') {
57
+ throw new PermissionDeniedError(`Tool "${tool.name}" has invalid status "${tool.status}" and cannot be executed.`, tool.name, 'TOOL_NOT_APPROVED');
58
+ }
59
+ // Denylist check
60
+ const denylist = this.config?.security?.denylist;
61
+ if (denylist && denylist.includes(tool.name)) {
62
+ throw new PermissionDeniedError(`Tool "${tool.name}" is explicitly denylisted in fridayy configuration.`, tool.name, 'TOOL_DENYLISTED');
63
+ }
64
+ // Allowlist check
65
+ const allowlist = this.config?.security?.allowlist;
66
+ if (allowlist && allowlist.length > 0 && !allowlist.includes(tool.name) && !allowlist.includes('*')) {
67
+ throw new PermissionDeniedError(`Tool "${tool.name}" is not included in the security allowlist.`, tool.name, 'TOOL_NOT_ALLOWLISTED');
68
+ }
69
+ }
70
+ }
71
+ //# sourceMappingURL=enforcer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforcer.js","sourceRoot":"","sources":["../../../src/core/permissions/enforcer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Fridayy - JSON Schema Unifier and Normalizer
3
+ * Combines OpenAPI/REST path, query, header parameters and request bodies
4
+ * into a single unified JSON Schema for standard MCP tools.
5
+ */
6
+ import { ParameterDefinition, RequestBodyDefinition } from './types.js';
7
+ export interface UnifySchemaOptions {
8
+ parameters?: {
9
+ path?: ParameterDefinition[];
10
+ query?: ParameterDefinition[];
11
+ header?: ParameterDefinition[];
12
+ cookie?: ParameterDefinition[];
13
+ };
14
+ requestBody?: RequestBodyDefinition;
15
+ }
16
+ /**
17
+ * Normalizes an OpenAPI / JSON Schema type object into standard JSON Schema Draft-7 / 2020-12
18
+ */
19
+ export declare function normalizeSchema(rawSchema: any): Record<string, any>;
20
+ /**
21
+ * Unifies all parameters and request body into a top-level MCP Tool inputSchema object.
22
+ */
23
+ export declare function buildUnifiedInputSchema(options: UnifySchemaOptions): {
24
+ type: 'object';
25
+ properties: Record<string, any>;
26
+ required: string[];
27
+ additionalProperties?: boolean;
28
+ };
29
+ //# sourceMappingURL=json-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../../src/core/schema/json-schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,mBAAmB,EAAE,CAAC;QAC7B,KAAK,CAAC,EAAE,mBAAmB,EAAE,CAAC;QAC9B,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;QAC/B,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;KAChC,CAAC;IACF,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAmCnE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG;IACpE,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CA0FA"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Fridayy - JSON Schema Unifier and Normalizer
3
+ * Combines OpenAPI/REST path, query, header parameters and request bodies
4
+ * into a single unified JSON Schema for standard MCP tools.
5
+ */
6
+ /**
7
+ * Normalizes an OpenAPI / JSON Schema type object into standard JSON Schema Draft-7 / 2020-12
8
+ */
9
+ export function normalizeSchema(rawSchema) {
10
+ if (!rawSchema || typeof rawSchema !== 'object') {
11
+ return { type: 'string' };
12
+ }
13
+ const schema = { ...rawSchema };
14
+ // Handle nullable
15
+ if (schema.nullable && schema.type) {
16
+ if (typeof schema.type === 'string') {
17
+ schema.type = [schema.type, 'null'];
18
+ }
19
+ delete schema.nullable;
20
+ }
21
+ // Handle recursive objects
22
+ if (schema.type === 'object' && schema.properties) {
23
+ const normalizedProps = {};
24
+ for (const [key, prop] of Object.entries(schema.properties)) {
25
+ normalizedProps[key] = normalizeSchema(prop);
26
+ }
27
+ schema.properties = normalizedProps;
28
+ }
29
+ // Handle arrays
30
+ if (schema.type === 'array' && schema.items) {
31
+ schema.items = normalizeSchema(schema.items);
32
+ }
33
+ // Clean up non-standard OpenAPI properties from tool input schema
34
+ delete schema.xml;
35
+ delete schema.externalDocs;
36
+ delete schema.example;
37
+ return schema;
38
+ }
39
+ /**
40
+ * Unifies all parameters and request body into a top-level MCP Tool inputSchema object.
41
+ */
42
+ export function buildUnifiedInputSchema(options) {
43
+ const properties = {};
44
+ const requiredFields = new Set();
45
+ // 1. Process Path Parameters
46
+ if (options.parameters?.path) {
47
+ for (const param of options.parameters.path) {
48
+ const propSchema = normalizeSchema(param.schema);
49
+ if (param.description && !propSchema.description) {
50
+ propSchema.description = param.description;
51
+ }
52
+ properties[param.name] = propSchema;
53
+ // Path parameters are always required
54
+ requiredFields.add(param.name);
55
+ }
56
+ }
57
+ // 2. Process Query Parameters
58
+ if (options.parameters?.query) {
59
+ for (const param of options.parameters.query) {
60
+ const propSchema = normalizeSchema(param.schema);
61
+ if (param.description && !propSchema.description) {
62
+ propSchema.description = param.description;
63
+ }
64
+ properties[param.name] = propSchema;
65
+ if (param.required) {
66
+ requiredFields.add(param.name);
67
+ }
68
+ }
69
+ }
70
+ // 3. Process Header Parameters (skip standard auth headers to avoid exposing secrets)
71
+ if (options.parameters?.header) {
72
+ for (const param of options.parameters.header) {
73
+ const lower = param.name.toLowerCase();
74
+ if (lower === 'authorization' || lower === 'x-api-key') {
75
+ continue;
76
+ }
77
+ const propSchema = normalizeSchema(param.schema);
78
+ if (param.description && !propSchema.description) {
79
+ propSchema.description = param.description;
80
+ }
81
+ properties[param.name] = propSchema;
82
+ if (param.required) {
83
+ requiredFields.add(param.name);
84
+ }
85
+ }
86
+ }
87
+ // 4. Process Request Body
88
+ if (options.requestBody && options.requestBody.schema) {
89
+ const bodySchema = normalizeSchema(options.requestBody.schema);
90
+ if (bodySchema.type === 'object' && bodySchema.properties) {
91
+ // Flatten top-level properties if they don't collide with path/query params
92
+ for (const [propName, propVal] of Object.entries(bodySchema.properties)) {
93
+ if (!properties[propName]) {
94
+ properties[propName] = propVal;
95
+ if (Array.isArray(bodySchema.required) && bodySchema.required.includes(propName)) {
96
+ if (options.requestBody.required) {
97
+ requiredFields.add(propName);
98
+ }
99
+ }
100
+ }
101
+ else {
102
+ // If collision, put into a nested body object
103
+ properties['body'] = bodySchema;
104
+ if (options.requestBody.required) {
105
+ requiredFields.add('body');
106
+ }
107
+ break;
108
+ }
109
+ }
110
+ }
111
+ else {
112
+ // Primitive or array body
113
+ properties['body'] = {
114
+ ...bodySchema,
115
+ description: options.requestBody.description || 'Request payload'
116
+ };
117
+ if (options.requestBody.required) {
118
+ requiredFields.add('body');
119
+ }
120
+ }
121
+ }
122
+ return {
123
+ type: 'object',
124
+ properties,
125
+ required: Array.from(requiredFields),
126
+ additionalProperties: false
127
+ };
128
+ }
129
+ //# sourceMappingURL=json-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/core/schema/json-schema.ts"],"names":[],"mappings":"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"}