fraim 2.0.177 → 2.0.180

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 (77) hide show
  1. package/dist/src/ai-hub/desktop-main.js +2 -2
  2. package/dist/src/ai-hub/server.js +50 -1
  3. package/dist/src/api/admin/payments.js +33 -0
  4. package/dist/src/api/admin/sales-leads.js +21 -0
  5. package/dist/src/api/payment/create-session.js +338 -0
  6. package/dist/src/api/payment/dashboard-link.js +149 -0
  7. package/dist/src/api/payment/session-details.js +31 -0
  8. package/dist/src/api/payment/webhook.js +587 -0
  9. package/dist/src/api/personas/me.js +29 -0
  10. package/dist/src/api/pricing/get-config.js +25 -0
  11. package/dist/src/api/sales/contact.js +44 -0
  12. package/dist/src/cli/commands/add-provider.js +74 -61
  13. package/dist/src/cli/commands/add-surface.js +128 -0
  14. package/dist/src/cli/commands/login.js +5 -69
  15. package/dist/src/cli/commands/setup.js +27 -347
  16. package/dist/src/cli/distribution/marketplace-bundles.js +580 -0
  17. package/dist/src/cli/fraim.js +2 -0
  18. package/dist/src/cli/mcp/ide-formats.js +5 -3
  19. package/dist/src/cli/mcp/mcp-server-registry.js +10 -3
  20. package/dist/src/cli/providers/local-provider-registry.js +2 -3
  21. package/dist/src/cli/setup/auto-mcp-setup.js +9 -32
  22. package/dist/src/cli/setup/ide-detector.js +34 -14
  23. package/dist/src/config/persona-capability-bundles.js +17 -13
  24. package/dist/src/db/payment-repository.js +61 -0
  25. package/dist/src/first-run/session-service.js +2 -2
  26. package/dist/src/fraim/config-loader.js +11 -0
  27. package/dist/src/fraim/db-service.js +2387 -0
  28. package/dist/src/fraim/issues.js +152 -0
  29. package/dist/src/fraim/template-processor.js +184 -0
  30. package/dist/src/fraim/utils/request-utils.js +23 -0
  31. package/dist/src/local-mcp-server/stdio-server.js +28 -4
  32. package/dist/src/local-mcp-server/usage-collector.js +24 -0
  33. package/dist/src/middleware/auth.js +266 -0
  34. package/dist/src/middleware/cors-config.js +111 -0
  35. package/dist/src/middleware/logger.js +116 -0
  36. package/dist/src/middleware/rate-limit.js +110 -0
  37. package/dist/src/middleware/reject-query-api-key.js +45 -0
  38. package/dist/src/middleware/security-headers.js +41 -0
  39. package/dist/src/middleware/telemetry.js +134 -0
  40. package/dist/src/models/payment.js +2 -0
  41. package/dist/src/routes/analytics.js +1447 -0
  42. package/dist/src/routes/app-routes.js +32 -0
  43. package/dist/src/routes/auth-routes.js +505 -0
  44. package/dist/src/routes/oauth-routes.js +325 -0
  45. package/dist/src/routes/payment-routes.js +186 -0
  46. package/dist/src/routes/persona-catalog-routes.js +84 -0
  47. package/dist/src/services/admin-service.js +229 -0
  48. package/dist/src/services/audit-log-persistence.js +60 -0
  49. package/dist/src/services/audit-log.js +69 -0
  50. package/dist/src/services/cookie-service.js +129 -0
  51. package/dist/src/services/dashboard-access.js +27 -0
  52. package/dist/src/services/demo-seed-service.js +139 -0
  53. package/dist/src/services/email-code.js +23 -0
  54. package/dist/src/services/email-service-clean.js +782 -0
  55. package/dist/src/services/email-service.js +951 -0
  56. package/dist/src/services/installer-service.js +131 -0
  57. package/dist/src/services/mcp-oauth-store.js +33 -0
  58. package/dist/src/services/mcp-service.js +823 -0
  59. package/dist/src/services/oauth-helpers.js +127 -0
  60. package/dist/src/services/org-service.js +89 -0
  61. package/dist/src/services/persona-entitlement-service.js +288 -0
  62. package/dist/src/services/provider-service.js +215 -0
  63. package/dist/src/services/registry-service.js +628 -0
  64. package/dist/src/services/session-service.js +86 -0
  65. package/dist/src/services/trial-reminder-service.js +120 -0
  66. package/dist/src/services/usage-analytics-service.js +419 -0
  67. package/dist/src/services/workspace-identity.js +21 -0
  68. package/dist/src/types/analytics.js +2 -0
  69. package/dist/src/utils/payment-calculator.js +52 -0
  70. package/extensions/office-word/favicon.ico +0 -0
  71. package/extensions/office-word/icon-64.png +0 -0
  72. package/extensions/office-word/manifest.xml +33 -0
  73. package/extensions/office-word/taskpane.html +242 -0
  74. package/package.json +14 -3
  75. package/public/ai-hub/index.html +14 -2
  76. package/public/ai-hub/script.js +340 -66
  77. package/public/ai-hub/styles.css +83 -0
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.securityHeaders = securityHeaders;
4
+ const DEFAULT_CSP = [
5
+ "default-src 'self'",
6
+ // Inline scripts are used by the analytics/installer dashboard; keep them.
7
+ // Third-party CDNs are explicitly listed rather than wildcarded.
8
+ "script-src 'self' 'unsafe-inline' https://js.stripe.com https://cdn.jsdelivr.net",
9
+ "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
10
+ "img-src 'self' data: https:",
11
+ "font-src 'self' https://fonts.gstatic.com data:",
12
+ "connect-src 'self' https://api.stripe.com",
13
+ "frame-src 'self' https://js.stripe.com https://hooks.stripe.com",
14
+ "frame-ancestors 'self'",
15
+ "base-uri 'self'",
16
+ "form-action 'self' https://checkout.stripe.com"
17
+ ].join('; ');
18
+ function securityHeaders(options = {}) {
19
+ const enableHsts = options.enableHsts !== false;
20
+ const csp = options.contentSecurityPolicy === undefined
21
+ ? DEFAULT_CSP
22
+ : options.contentSecurityPolicy;
23
+ return function securityHeadersMiddleware(req, res, next) {
24
+ // Trust-proxy aware: req.secure is true if X-Forwarded-Proto is https
25
+ // and Express has been told to trust the upstream (see fraim-mcp-server.ts).
26
+ if (enableHsts && req.secure) {
27
+ res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
28
+ }
29
+ res.setHeader('X-Content-Type-Options', 'nosniff');
30
+ res.setHeader('X-Frame-Options', 'SAMEORIGIN');
31
+ res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
32
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
33
+ res.setHeader('Cross-Origin-Resource-Policy', 'same-site');
34
+ res.setHeader('X-Permitted-Cross-Domain-Policies', 'none');
35
+ res.setHeader('X-DNS-Prefetch-Control', 'off');
36
+ if (csp) {
37
+ res.setHeader('Content-Security-Policy', csp);
38
+ }
39
+ next();
40
+ };
41
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TelemetryMiddleware = void 0;
4
+ class TelemetryMiddleware {
5
+ constructor(sessionManager) {
6
+ this.sessionManager = sessionManager;
7
+ }
8
+ parseSessionId(req) {
9
+ const fromHeader = Array.isArray(req.headers['x-fraim-session-id'])
10
+ ? req.headers['x-fraim-session-id'][0]
11
+ : req.headers['x-fraim-session-id'];
12
+ if (typeof fromHeader === 'string' && fromHeader.trim().length > 0) {
13
+ return fromHeader.trim();
14
+ }
15
+ const fromParams = req.body?.params?.sessionId;
16
+ if (typeof fromParams === 'string' && fromParams.trim().length > 0) {
17
+ return fromParams.trim();
18
+ }
19
+ const fromArgs = req.body?.params?.arguments?.sessionId;
20
+ if (typeof fromArgs === 'string' && fromArgs.trim().length > 0) {
21
+ return fromArgs.trim();
22
+ }
23
+ return undefined;
24
+ }
25
+ /**
26
+ * Middleware to enforce Session Handshake and track activity
27
+ */
28
+ async handle(req, res, next) {
29
+ try {
30
+ // 1. Standard MCP Lifecycle & Discovery methods (Initialize, List Tools/Resources/Prompts, etc.)
31
+ const exemptMethods = [
32
+ 'initialize',
33
+ 'notifications/initialized',
34
+ 'tools/list',
35
+ 'resources/list',
36
+ 'prompts/list',
37
+ 'prompts/get',
38
+ 'logging/setLevel'
39
+ ];
40
+ if (req.body && exemptMethods.includes(req.body.method)) {
41
+ return next();
42
+ }
43
+ // 2. FRAIM Bootstrap/Discovery Tools that don't need an active session
44
+ if (req.body && req.body.method === 'tools/call') {
45
+ const toolName = req.body.params?.name;
46
+ const safeTools = [
47
+ 'fraim_connect',
48
+ 'list_fraim_jobs'
49
+ ];
50
+ if (toolName && safeTools.includes(toolName)) {
51
+ return next();
52
+ }
53
+ }
54
+ // Skip for non-authenticated or exempt paths (GET only).
55
+ // Issue #359 - /api/auth/* and /api/account/* are human-session lifecycle
56
+ // endpoints (called by auth-bootstrap.js on every page load); they happen
57
+ // BEFORE any agent has fraim_connect'd, so they MUST be exempt from the
58
+ // telemetry session-active gate. Without this, /api/auth/session returns 400
59
+ // for every signed-in browser, which redirects users back to sign-in.
60
+ // Issue #563 - /api/org/* serves the org-cache sync performed by the
61
+ // `fraim sync` CLI, which runs outside any MCP session (same lifecycle
62
+ // position as /api/registry/sync). Auth still applies; only the
63
+ // session-active gate is exempted.
64
+ const exemptPaths = ['/health', '/admin', '/api/registry/sync', '/api/registry/github-workflows', '/api/registry/topology/personalized', '/api/registry/topology/usage-heatmap', '/api/org/', '/api/manager/', '/api/payment/', '/api/sales/', '/api/signup', '/api/providers', '/api/analytics', '/analytics', '/api/auth/', '/api/account/'];
65
+ if (exemptPaths.some(p => req.path.startsWith(p))) {
66
+ return next();
67
+ }
68
+ const apiKey = req.apiKeyData?.key;
69
+ if (!apiKey)
70
+ return next(); // Auth middleware handles 401 earlier
71
+ const sessionId = this.parseSessionId(req);
72
+ const localVersionFromHeader = Array.isArray(req.headers['x-fraim-local-version'])
73
+ ? req.headers['x-fraim-local-version'][0]
74
+ : req.headers['x-fraim-local-version'];
75
+ const localVersion = req.localMcpVersion ||
76
+ (typeof localVersionFromHeader === 'string' ? localVersionFromHeader : 'unknown');
77
+ const isProxiedAgentCall = typeof localVersion === 'string' && localVersion !== 'unknown';
78
+ // Enforce explicit session id for local proxy agent traffic.
79
+ if (isProxiedAgentCall && !sessionId) {
80
+ return res.status(400).json({
81
+ jsonrpc: '2.0',
82
+ error: {
83
+ code: -32600,
84
+ message: `Missing Session ID. REQUIRED ACTION:
85
+ 1. Call 'fraim_connect' first
86
+ 2. Capture the returned sessionId
87
+ 3. Include that sessionId on every subsequent FRAIM tool call (params.sessionId or params.arguments.sessionId).`
88
+ },
89
+ id: req.body?.id || null
90
+ });
91
+ }
92
+ // Check Session
93
+ const isActive = await this.sessionManager.updateActivity(apiKey, sessionId);
94
+ if (!isActive) {
95
+ const sessionStartGuidance = isProxiedAgentCall
96
+ ? `Session Not Started. REQUIRED ACTION: Call 'fraim_connect' tool first, then include the returned sessionId on every subsequent FRAIM tool call.`
97
+ : `Session Not Started. REQUIRED ACTION: Call 'fraim_connect' tool first with these parameters:
98
+
99
+ {
100
+ "agent": {
101
+ "name": "YourAgentName",
102
+ "model": "your-model-name"
103
+ },
104
+ "machine": {
105
+ "hostname": "use os.hostname()",
106
+ "platform": "use process.platform"
107
+ },
108
+ "repo": {
109
+ "url": "git remote URL",
110
+ "owner": "repo owner",
111
+ "name": "repo name"
112
+ }
113
+ }
114
+
115
+ After successful fraim_connect, all other FRAIM tools will work. This is required for telemetry and session management.`;
116
+ return res.status(400).json({
117
+ jsonrpc: '2.0',
118
+ error: {
119
+ code: -32600,
120
+ message: sessionStartGuidance
121
+ },
122
+ id: req.body?.id || null
123
+ });
124
+ }
125
+ console.log(`Telemetry active for ${apiKey}`);
126
+ return next();
127
+ }
128
+ catch (error) {
129
+ console.error('Telemetry middleware error:', error);
130
+ return next(error);
131
+ }
132
+ }
133
+ }
134
+ exports.TelemetryMiddleware = TelemetryMiddleware;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });