guardrail-core 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 (189) hide show
  1. package/dist/__tests__/autopilot.test.d.ts +7 -0
  2. package/dist/__tests__/autopilot.test.d.ts.map +1 -0
  3. package/dist/__tests__/autopilot.test.js +156 -0
  4. package/dist/__tests__/tier-config.test.d.ts +9 -0
  5. package/dist/__tests__/tier-config.test.d.ts.map +1 -0
  6. package/dist/__tests__/tier-config.test.js +230 -0
  7. package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
  8. package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
  9. package/dist/__tests__/utils/hash-inline.test.js +62 -0
  10. package/dist/__tests__/utils/hash.test.d.ts +3 -0
  11. package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
  12. package/dist/__tests__/utils/hash.test.js +95 -0
  13. package/dist/__tests__/utils/simple.test.d.ts +1 -0
  14. package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
  15. package/dist/__tests__/utils/simple.test.js +10 -0
  16. package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
  17. package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
  18. package/dist/__tests__/utils/utils-simple.test.js +6 -0
  19. package/dist/__tests__/utils/utils.test.d.ts +15 -0
  20. package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
  21. package/dist/__tests__/utils/utils.test.js +172 -0
  22. package/dist/autopilot/autopilot-runner.d.ts +33 -0
  23. package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
  24. package/dist/autopilot/autopilot-runner.js +479 -0
  25. package/dist/autopilot/index.d.ts +6 -0
  26. package/dist/autopilot/index.d.ts.map +1 -0
  27. package/dist/autopilot/index.js +25 -0
  28. package/dist/autopilot/types.d.ts +102 -0
  29. package/dist/autopilot/types.d.ts.map +1 -0
  30. package/dist/autopilot/types.js +18 -0
  31. package/dist/cache/index.d.ts +7 -0
  32. package/dist/cache/index.d.ts.map +1 -0
  33. package/dist/cache/index.js +22 -0
  34. package/dist/cache/redis-cache.d.ts +145 -0
  35. package/dist/cache/redis-cache.d.ts.map +1 -0
  36. package/dist/cache/redis-cache.js +459 -0
  37. package/dist/ci/github-actions.d.ts +77 -0
  38. package/dist/ci/github-actions.d.ts.map +1 -0
  39. package/dist/ci/github-actions.js +277 -0
  40. package/dist/ci/index.d.ts +12 -0
  41. package/dist/ci/index.d.ts.map +1 -0
  42. package/dist/ci/index.js +27 -0
  43. package/dist/ci/pre-commit.d.ts +65 -0
  44. package/dist/ci/pre-commit.d.ts.map +1 -0
  45. package/dist/ci/pre-commit.js +286 -0
  46. package/dist/entitlements.d.ts +149 -0
  47. package/dist/entitlements.d.ts.map +1 -0
  48. package/dist/entitlements.js +464 -0
  49. package/dist/env.d.ts +113 -0
  50. package/dist/env.d.ts.map +1 -0
  51. package/dist/env.js +204 -0
  52. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
  53. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
  54. package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
  55. package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
  56. package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
  57. package/dist/fix-packs/generate-fix-packs.js +505 -0
  58. package/dist/fix-packs/index.d.ts +8 -0
  59. package/dist/fix-packs/index.d.ts.map +1 -0
  60. package/dist/fix-packs/index.js +23 -0
  61. package/dist/fix-packs/types.d.ts +113 -0
  62. package/dist/fix-packs/types.d.ts.map +1 -0
  63. package/dist/fix-packs/types.js +71 -0
  64. package/dist/index.d.ts +13 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +28 -0
  67. package/dist/metrics/prometheus.d.ts +99 -0
  68. package/dist/metrics/prometheus.d.ts.map +1 -0
  69. package/dist/metrics/prometheus.js +306 -0
  70. package/dist/quota-ledger.d.ts +119 -0
  71. package/dist/quota-ledger.d.ts.map +1 -0
  72. package/dist/quota-ledger.js +462 -0
  73. package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
  74. package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
  75. package/dist/rbac/__tests__/permissions.test.js +350 -0
  76. package/dist/rbac/index.d.ts +9 -0
  77. package/dist/rbac/index.d.ts.map +1 -0
  78. package/dist/rbac/index.js +32 -0
  79. package/dist/rbac/permissions.d.ts +71 -0
  80. package/dist/rbac/permissions.d.ts.map +1 -0
  81. package/dist/rbac/permissions.js +247 -0
  82. package/dist/rbac/types.d.ts +69 -0
  83. package/dist/rbac/types.d.ts.map +1 -0
  84. package/dist/rbac/types.js +213 -0
  85. package/dist/tier-config.d.ts +203 -0
  86. package/dist/tier-config.d.ts.map +1 -0
  87. package/dist/tier-config.js +675 -0
  88. package/dist/types.d.ts +365 -0
  89. package/dist/types.d.ts.map +1 -0
  90. package/dist/types.js +5 -0
  91. package/dist/utils.d.ts +36 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +127 -0
  94. package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
  95. package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
  96. package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
  97. package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
  98. package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
  99. package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
  100. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
  101. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
  102. package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
  103. package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
  104. package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
  105. package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
  106. package/dist/verified-autofix/format-validator.d.ts +101 -0
  107. package/dist/verified-autofix/format-validator.d.ts.map +1 -0
  108. package/dist/verified-autofix/format-validator.js +446 -0
  109. package/dist/verified-autofix/index.d.ts +14 -0
  110. package/dist/verified-autofix/index.d.ts.map +1 -0
  111. package/dist/verified-autofix/index.js +39 -0
  112. package/dist/verified-autofix/pipeline.d.ts +68 -0
  113. package/dist/verified-autofix/pipeline.d.ts.map +1 -0
  114. package/dist/verified-autofix/pipeline.js +330 -0
  115. package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
  116. package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
  117. package/dist/verified-autofix/repo-fingerprint.js +396 -0
  118. package/dist/verified-autofix/workspace.d.ts +83 -0
  119. package/dist/verified-autofix/workspace.d.ts.map +1 -0
  120. package/dist/verified-autofix/workspace.js +454 -0
  121. package/dist/verified-autofix.d.ts +182 -0
  122. package/dist/verified-autofix.d.ts.map +1 -0
  123. package/dist/verified-autofix.js +1021 -0
  124. package/dist/visualization/dependency-graph.d.ts +79 -0
  125. package/dist/visualization/dependency-graph.d.ts.map +1 -0
  126. package/dist/visualization/dependency-graph.js +399 -0
  127. package/dist/visualization/index.d.ts +5 -0
  128. package/dist/visualization/index.d.ts.map +1 -0
  129. package/dist/visualization/index.js +20 -0
  130. package/package.json +29 -0
  131. package/src/__tests__/autopilot.test.ts +196 -0
  132. package/src/__tests__/tier-config.test.ts +289 -0
  133. package/src/__tests__/utils/hash-inline.test.ts +76 -0
  134. package/src/__tests__/utils/hash.test.ts +119 -0
  135. package/src/__tests__/utils/simple.test.ts +10 -0
  136. package/src/__tests__/utils/utils-simple.test.ts +5 -0
  137. package/src/__tests__/utils/utils.test.ts +203 -0
  138. package/src/autopilot/autopilot-runner.ts +503 -0
  139. package/src/autopilot/index.ts +6 -0
  140. package/src/autopilot/types.ts +119 -0
  141. package/src/cache/index.ts +7 -0
  142. package/src/cache/redis-cache.d.ts +155 -0
  143. package/src/cache/redis-cache.d.ts.map +1 -0
  144. package/src/cache/redis-cache.ts +517 -0
  145. package/src/ci/github-actions.ts +335 -0
  146. package/src/ci/index.ts +12 -0
  147. package/src/ci/pre-commit.ts +338 -0
  148. package/src/db/usage-schema.prisma +114 -0
  149. package/src/entitlements.ts +570 -0
  150. package/src/env.d.ts +68 -0
  151. package/src/env.d.ts.map +1 -0
  152. package/src/env.ts +247 -0
  153. package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
  154. package/src/fix-packs/generate-fix-packs.ts +577 -0
  155. package/src/fix-packs/index.ts +8 -0
  156. package/src/fix-packs/types.ts +206 -0
  157. package/src/index.d.ts +7 -0
  158. package/src/index.d.ts.map +1 -0
  159. package/src/index.ts +12 -0
  160. package/src/metrics/prometheus.d.ts +104 -0
  161. package/src/metrics/prometheus.d.ts.map +1 -0
  162. package/src/metrics/prometheus.ts +446 -0
  163. package/src/quota-ledger.ts +548 -0
  164. package/src/rbac/__tests__/permissions.test.ts +446 -0
  165. package/src/rbac/index.ts +46 -0
  166. package/src/rbac/permissions.ts +301 -0
  167. package/src/rbac/types.ts +298 -0
  168. package/src/tier-config.json +157 -0
  169. package/src/tier-config.ts +815 -0
  170. package/src/types.d.ts +365 -0
  171. package/src/types.d.ts.map +1 -0
  172. package/src/types.ts +441 -0
  173. package/src/utils.d.ts +36 -0
  174. package/src/utils.d.ts.map +1 -0
  175. package/src/utils.ts +140 -0
  176. package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
  177. package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
  178. package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
  179. package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
  180. package/src/verified-autofix/format-validator.ts +517 -0
  181. package/src/verified-autofix/index.ts +63 -0
  182. package/src/verified-autofix/pipeline.ts +403 -0
  183. package/src/verified-autofix/repo-fingerprint.ts +459 -0
  184. package/src/verified-autofix/workspace.ts +531 -0
  185. package/src/verified-autofix.ts +1187 -0
  186. package/src/visualization/dependency-graph.d.ts +85 -0
  187. package/src/visualization/dependency-graph.d.ts.map +1 -0
  188. package/src/visualization/dependency-graph.ts +495 -0
  189. package/src/visualization/index.ts +5 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Entitlements System - SINGLE SOURCE OF TRUTH
3
+ *
4
+ * This module is the canonical entitlements implementation for Guardrail.
5
+ * It handles feature access, usage limits, tier enforcement, and seat management.
6
+ *
7
+ * IMPORTANT: This TypeScript file is compiled to dist/entitlements.js
8
+ * DO NOT create separate entitlements.js files elsewhere in the codebase.
9
+ * All consumers (API, CLI, etc.) should import from @guardrail/core.
10
+ */
11
+ import { Feature, SEAT_PRICING, SeatPricing, TIER_CONFIG, Tier, TierConfig, calculateEffectiveSeats, canAddMember, formatSeatInfo, getMinimumTierForFeature, getTierConfig, isValidTier, validateSeatReduction } from './tier-config';
12
+ export type { Feature, SeatPricing, Tier, TierConfig };
13
+ export { SEAT_PRICING, TIER_CONFIG, calculateEffectiveSeats, canAddMember, formatSeatInfo, getMinimumTierForFeature, getTierConfig, isValidTier, validateSeatReduction };
14
+ export interface UsageRecord {
15
+ tier: Tier;
16
+ userId?: string;
17
+ email?: string;
18
+ periodStart: string;
19
+ periodEnd: string;
20
+ usage: {
21
+ scans: number;
22
+ realityRuns: number;
23
+ aiAgentRuns: number;
24
+ gateRuns: number;
25
+ fixRuns: number;
26
+ };
27
+ lastUpdated: string;
28
+ lastServerSync?: string;
29
+ pendingSync?: boolean;
30
+ }
31
+ export interface EntitlementCheck {
32
+ allowed: boolean;
33
+ reason?: string;
34
+ usage?: number;
35
+ limit?: number;
36
+ upgradePrompt?: string;
37
+ source?: 'server' | 'cache' | 'local' | 'offline';
38
+ }
39
+ export interface SeatCheck {
40
+ allowed: boolean;
41
+ reason?: string;
42
+ effectiveSeats: number;
43
+ baseSeats: number;
44
+ purchasedSeats: number;
45
+ currentMembers: number;
46
+ }
47
+ export interface OrganizationSeats {
48
+ tier: Tier;
49
+ baseSeats: number;
50
+ purchasedExtraSeats: number;
51
+ effectiveSeats: number;
52
+ currentMembers: number;
53
+ seatPricing: SeatPricing;
54
+ }
55
+ export declare class EntitlementsManager {
56
+ private configDir;
57
+ private usageFile;
58
+ private licenseFile;
59
+ constructor();
60
+ /**
61
+ * Get current tier from license file or environment
62
+ */
63
+ getCurrentTier(): Promise<Tier>;
64
+ /**
65
+ * Validate API key against server and return tier
66
+ *
67
+ * SECURITY: Tier is determined server-side only.
68
+ * The API key string contains NO tier information.
69
+ */
70
+ private validateApiKeyWithServer;
71
+ /**
72
+ * Check if a feature is available for the current tier
73
+ */
74
+ checkFeature(feature: Feature): Promise<EntitlementCheck>;
75
+ /**
76
+ * Check usage limits
77
+ */
78
+ checkLimit(limitType: 'scans' | 'realityRuns' | 'aiAgentRuns'): Promise<EntitlementCheck>;
79
+ /**
80
+ * Track usage
81
+ */
82
+ trackUsage(type: 'scans' | 'realityRuns' | 'aiAgentRuns' | 'gateRuns' | 'fixRuns', count?: number): Promise<void>;
83
+ /**
84
+ * Enforce feature access (throws if not allowed)
85
+ */
86
+ enforceFeature(feature: Feature): Promise<void>;
87
+ /**
88
+ * Enforce usage limits (throws if exceeded)
89
+ */
90
+ enforceLimit(limitType: 'scans' | 'realityRuns' | 'aiAgentRuns'): Promise<void>;
91
+ /**
92
+ * Check if a member can be added to an organization
93
+ */
94
+ checkSeatLimit(tier: Tier, currentMemberCount: number, purchasedExtraSeats?: number): SeatCheck;
95
+ /**
96
+ * Get organization seat information
97
+ */
98
+ getOrganizationSeats(tier: Tier, purchasedExtraSeats: number, currentMembers: number): OrganizationSeats;
99
+ /**
100
+ * Validate seat reduction before processing
101
+ */
102
+ validateSeatReduction(currentMemberCount: number, currentPurchasedSeats: number, newPurchasedSeats: number, tier: Tier): {
103
+ safe: boolean;
104
+ requiresAction: boolean;
105
+ excessMembers: number;
106
+ message: string;
107
+ };
108
+ /**
109
+ * Get usage for current billing period
110
+ */
111
+ getUsage(): Promise<UsageRecord>;
112
+ /**
113
+ * Get tier configuration
114
+ */
115
+ getTierConfig(tier: Tier): TierConfig;
116
+ /**
117
+ * Get all tier configurations
118
+ */
119
+ getAllTiers(): Record<Tier, TierConfig>;
120
+ /**
121
+ * Get usage summary for display
122
+ */
123
+ getUsageSummary(): Promise<string>;
124
+ /**
125
+ * Format upgrade prompt for CLI output
126
+ */
127
+ formatUpgradePrompt(currentTier: Tier, requiredTier: Tier | null, feature: Feature): string;
128
+ /**
129
+ * Format limit exceeded prompt
130
+ */
131
+ formatLimitUpgradePrompt(currentTier: Tier, limitType: string, current: number, limit: number): string;
132
+ private isNewBillingPeriod;
133
+ private createNewUsageRecord;
134
+ private ensureConfigDir;
135
+ private saveUsage;
136
+ private readLicense;
137
+ private progressBar;
138
+ }
139
+ export declare const entitlements: EntitlementsManager;
140
+ export declare const checkFeature: (feature: Feature) => Promise<EntitlementCheck>;
141
+ export declare const checkLimit: (limitType: "scans" | "realityRuns" | "aiAgentRuns") => Promise<EntitlementCheck>;
142
+ export declare const enforceFeature: (feature: Feature) => Promise<void>;
143
+ export declare const enforceLimit: (limitType: "scans" | "realityRuns" | "aiAgentRuns") => Promise<void>;
144
+ export declare const trackUsage: (type: "scans" | "realityRuns" | "aiAgentRuns" | "gateRuns" | "fixRuns", count?: number) => Promise<void>;
145
+ export declare const getCurrentTier: () => Promise<"free" | "starter" | "pro" | "compliance" | "enterprise" | "unlimited">;
146
+ export declare const getUsageSummary: () => Promise<string>;
147
+ export declare const checkSeatLimit: (tier: Tier, currentMemberCount: number, purchasedExtraSeats?: number) => SeatCheck;
148
+ export declare const getOrganizationSeats: (tier: Tier, purchasedExtraSeats: number, currentMembers: number) => OrganizationSeats;
149
+ //# sourceMappingURL=entitlements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitlements.d.ts","sourceRoot":"","sources":["../src/entitlements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,464 @@
1
+ "use strict";
2
+ /**
3
+ * Entitlements System - SINGLE SOURCE OF TRUTH
4
+ *
5
+ * This module is the canonical entitlements implementation for Guardrail.
6
+ * It handles feature access, usage limits, tier enforcement, and seat management.
7
+ *
8
+ * IMPORTANT: This TypeScript file is compiled to dist/entitlements.js
9
+ * DO NOT create separate entitlements.js files elsewhere in the codebase.
10
+ * All consumers (API, CLI, etc.) should import from @guardrail/core.
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.getOrganizationSeats = exports.checkSeatLimit = exports.getUsageSummary = exports.getCurrentTier = exports.trackUsage = exports.enforceLimit = exports.enforceFeature = exports.checkLimit = exports.checkFeature = exports.entitlements = exports.EntitlementsManager = exports.validateSeatReduction = exports.isValidTier = exports.getTierConfig = exports.getMinimumTierForFeature = exports.formatSeatInfo = exports.canAddMember = exports.calculateEffectiveSeats = exports.TIER_CONFIG = exports.SEAT_PRICING = void 0;
47
+ const fs = __importStar(require("fs"));
48
+ const os = __importStar(require("os"));
49
+ const path = __importStar(require("path"));
50
+ const tier_config_1 = require("./tier-config");
51
+ Object.defineProperty(exports, "SEAT_PRICING", { enumerable: true, get: function () { return tier_config_1.SEAT_PRICING; } });
52
+ Object.defineProperty(exports, "TIER_CONFIG", { enumerable: true, get: function () { return tier_config_1.TIER_CONFIG; } });
53
+ Object.defineProperty(exports, "calculateEffectiveSeats", { enumerable: true, get: function () { return tier_config_1.calculateEffectiveSeats; } });
54
+ Object.defineProperty(exports, "canAddMember", { enumerable: true, get: function () { return tier_config_1.canAddMember; } });
55
+ Object.defineProperty(exports, "formatSeatInfo", { enumerable: true, get: function () { return tier_config_1.formatSeatInfo; } });
56
+ Object.defineProperty(exports, "getMinimumTierForFeature", { enumerable: true, get: function () { return tier_config_1.getMinimumTierForFeature; } });
57
+ Object.defineProperty(exports, "getTierConfig", { enumerable: true, get: function () { return tier_config_1.getTierConfig; } });
58
+ Object.defineProperty(exports, "isValidTier", { enumerable: true, get: function () { return tier_config_1.isValidTier; } });
59
+ Object.defineProperty(exports, "validateSeatReduction", { enumerable: true, get: function () { return tier_config_1.validateSeatReduction; } });
60
+ // ============================================================================
61
+ // ENTITLEMENTS MANAGER
62
+ // ============================================================================
63
+ class EntitlementsManager {
64
+ configDir;
65
+ usageFile;
66
+ licenseFile;
67
+ constructor() {
68
+ this.configDir = path.join(os.homedir(), '.guardrail');
69
+ this.usageFile = path.join(this.configDir, 'usage.json');
70
+ this.licenseFile = path.join(this.configDir, 'license.json');
71
+ }
72
+ /**
73
+ * Get current tier from license file or environment
74
+ */
75
+ async getCurrentTier() {
76
+ // Skip entitlements check if explicitly disabled
77
+ if (process.env['GUARDRAIL_SKIP_ENTITLEMENTS'] === '1') {
78
+ return 'unlimited';
79
+ }
80
+ // Check environment override (for CI/testing)
81
+ if (process.env['GUARDRAIL_TIER']) {
82
+ return process.env['GUARDRAIL_TIER'];
83
+ }
84
+ // Check for license file
85
+ try {
86
+ const license = await this.readLicense();
87
+ if (license?.tier && (0, tier_config_1.isValidTier)(license.tier)) {
88
+ // Check expiration
89
+ if (license.expiresAt && new Date(license.expiresAt) < new Date()) {
90
+ return 'free';
91
+ }
92
+ return license.tier;
93
+ }
94
+ }
95
+ catch {
96
+ // No license file
97
+ }
98
+ // Check for API key - validate against server (NO local tier parsing)
99
+ const apiKey = process.env['GUARDRAIL_API_KEY'];
100
+ if (apiKey) {
101
+ const tier = await this.validateApiKeyWithServer(apiKey);
102
+ if (tier)
103
+ return tier;
104
+ }
105
+ return 'free';
106
+ }
107
+ /**
108
+ * Validate API key against server and return tier
109
+ *
110
+ * SECURITY: Tier is determined server-side only.
111
+ * The API key string contains NO tier information.
112
+ */
113
+ async validateApiKeyWithServer(apiKey) {
114
+ const apiUrl = process.env['GUARDRAIL_API_URL'] || 'https://api.getguardrail.io';
115
+ try {
116
+ const response = await fetch(`${apiUrl}/api/api-keys/validate`, {
117
+ method: 'POST',
118
+ headers: {
119
+ 'Content-Type': 'application/json',
120
+ },
121
+ body: JSON.stringify({ apiKey }),
122
+ });
123
+ if (!response.ok) {
124
+ return null;
125
+ }
126
+ const result = await response.json();
127
+ if (result.valid && result.tier && (0, tier_config_1.isValidTier)(result.tier)) {
128
+ return result.tier;
129
+ }
130
+ }
131
+ catch {
132
+ // Network error or server unavailable - fall back to free tier
133
+ }
134
+ return null;
135
+ }
136
+ /**
137
+ * Check if a feature is available for the current tier
138
+ */
139
+ async checkFeature(feature) {
140
+ const tier = await this.getCurrentTier();
141
+ const config = tier_config_1.TIER_CONFIG[tier];
142
+ // Unlimited tier has all features
143
+ if (tier === 'unlimited' || config.features.includes(feature)) {
144
+ return { allowed: true };
145
+ }
146
+ // Find the minimum tier that has this feature
147
+ const requiredTier = (0, tier_config_1.getMinimumTierForFeature)(feature);
148
+ return {
149
+ allowed: false,
150
+ reason: `'${feature}' requires ${requiredTier || 'higher'} tier`,
151
+ upgradePrompt: this.formatUpgradePrompt(tier, requiredTier, feature),
152
+ };
153
+ }
154
+ /**
155
+ * Check usage limits
156
+ */
157
+ async checkLimit(limitType) {
158
+ const tier = await this.getCurrentTier();
159
+ const config = tier_config_1.TIER_CONFIG[tier];
160
+ const usage = await this.getUsage();
161
+ const limitMap = {
162
+ scans: 'scansPerMonth',
163
+ realityRuns: 'realityRunsPerMonth',
164
+ aiAgentRuns: 'aiAgentRunsPerMonth',
165
+ };
166
+ const limitKey = limitMap[limitType];
167
+ const limit = config.limits[limitKey];
168
+ const current = usage.usage[limitType] || 0;
169
+ // Handle unlimited (-1)
170
+ if (limit === -1 || current < limit) {
171
+ return {
172
+ allowed: true,
173
+ usage: current,
174
+ limit: limit === -1 ? -1 : limit,
175
+ source: 'local',
176
+ };
177
+ }
178
+ return {
179
+ allowed: false,
180
+ reason: `Monthly ${limitType} limit reached (${current}/${limit})`,
181
+ usage: current,
182
+ limit,
183
+ upgradePrompt: this.formatLimitUpgradePrompt(tier, limitType, current, limit),
184
+ source: 'local',
185
+ };
186
+ }
187
+ /**
188
+ * Track usage
189
+ */
190
+ async trackUsage(type, count = 1) {
191
+ const usage = await this.getUsage();
192
+ usage.usage[type] = (usage.usage[type] || 0) + count;
193
+ usage.lastUpdated = new Date().toISOString();
194
+ await this.saveUsage(usage);
195
+ }
196
+ /**
197
+ * Enforce feature access (throws if not allowed)
198
+ */
199
+ async enforceFeature(feature) {
200
+ const check = await this.checkFeature(feature);
201
+ if (!check.allowed) {
202
+ const error = new Error(check.reason);
203
+ error.code = 'FEATURE_NOT_AVAILABLE';
204
+ error.upgradePrompt = check.upgradePrompt;
205
+ error.feature = feature;
206
+ throw error;
207
+ }
208
+ }
209
+ /**
210
+ * Enforce usage limits (throws if exceeded)
211
+ */
212
+ async enforceLimit(limitType) {
213
+ const check = await this.checkLimit(limitType);
214
+ if (!check.allowed) {
215
+ const error = new Error(check.reason);
216
+ error.code = 'LIMIT_EXCEEDED';
217
+ error.upgradePrompt = check.upgradePrompt;
218
+ error.usage = check.usage;
219
+ error.limit = check.limit;
220
+ throw error;
221
+ }
222
+ }
223
+ // ============================================================================
224
+ // SEAT MANAGEMENT
225
+ // ============================================================================
226
+ /**
227
+ * Check if a member can be added to an organization
228
+ */
229
+ checkSeatLimit(tier, currentMemberCount, purchasedExtraSeats = 0) {
230
+ const config = tier_config_1.TIER_CONFIG[tier];
231
+ const baseSeats = config.limits.teamMembers;
232
+ const result = (0, tier_config_1.canAddMember)(tier, currentMemberCount, purchasedExtraSeats);
233
+ return {
234
+ allowed: result.allowed,
235
+ reason: result.reason,
236
+ effectiveSeats: result.effectiveSeats === Infinity ? -1 : result.effectiveSeats,
237
+ baseSeats: baseSeats === -1 ? -1 : baseSeats,
238
+ purchasedSeats: purchasedExtraSeats,
239
+ currentMembers: currentMemberCount,
240
+ };
241
+ }
242
+ /**
243
+ * Get organization seat information
244
+ */
245
+ getOrganizationSeats(tier, purchasedExtraSeats, currentMembers) {
246
+ const config = tier_config_1.TIER_CONFIG[tier];
247
+ const baseSeats = config.limits.teamMembers;
248
+ const effectiveSeats = (0, tier_config_1.calculateEffectiveSeats)(tier, purchasedExtraSeats);
249
+ return {
250
+ tier,
251
+ baseSeats: baseSeats === -1 ? -1 : baseSeats,
252
+ purchasedExtraSeats,
253
+ effectiveSeats: effectiveSeats === Infinity ? -1 : effectiveSeats,
254
+ currentMembers,
255
+ seatPricing: tier_config_1.SEAT_PRICING[tier],
256
+ };
257
+ }
258
+ /**
259
+ * Validate seat reduction before processing
260
+ */
261
+ validateSeatReduction(currentMemberCount, currentPurchasedSeats, newPurchasedSeats, tier) {
262
+ const currentEffective = (0, tier_config_1.calculateEffectiveSeats)(tier, currentPurchasedSeats);
263
+ const newEffective = (0, tier_config_1.calculateEffectiveSeats)(tier, newPurchasedSeats);
264
+ return (0, tier_config_1.validateSeatReduction)(currentMemberCount, currentEffective === Infinity ? -1 : currentEffective, newEffective === Infinity ? -1 : newEffective);
265
+ }
266
+ // ============================================================================
267
+ // USAGE MANAGEMENT
268
+ // ============================================================================
269
+ /**
270
+ * Get usage for current billing period
271
+ */
272
+ async getUsage() {
273
+ try {
274
+ await this.ensureConfigDir();
275
+ const content = await fs.promises.readFile(this.usageFile, 'utf8');
276
+ const usage = JSON.parse(content);
277
+ // Check if we need to reset for new period
278
+ if (this.isNewBillingPeriod(usage.periodStart)) {
279
+ return this.createNewUsageRecord();
280
+ }
281
+ return usage;
282
+ }
283
+ catch {
284
+ return this.createNewUsageRecord();
285
+ }
286
+ }
287
+ /**
288
+ * Get tier configuration
289
+ */
290
+ getTierConfig(tier) {
291
+ return tier_config_1.TIER_CONFIG[tier];
292
+ }
293
+ /**
294
+ * Get all tier configurations
295
+ */
296
+ getAllTiers() {
297
+ return tier_config_1.TIER_CONFIG;
298
+ }
299
+ /**
300
+ * Get usage summary for display
301
+ */
302
+ async getUsageSummary() {
303
+ const tier = await this.getCurrentTier();
304
+ const config = tier_config_1.TIER_CONFIG[tier];
305
+ const usage = await this.getUsage();
306
+ const formatLimit = (current, limit) => {
307
+ if (limit === -1)
308
+ return `${current} (unlimited)`;
309
+ const pct = Math.round((current / limit) * 100);
310
+ const bar = this.progressBar(pct);
311
+ return `${current}/${limit} ${bar} ${pct}%`;
312
+ };
313
+ let summary = '\n';
314
+ summary += `📊 Usage Summary (${config.name} tier)\n`;
315
+ summary += '─'.repeat(50) + '\n';
316
+ summary += `Scans: ${formatLimit(usage.usage.scans, config.limits.scansPerMonth)}\n`;
317
+ summary += `Reality Runs: ${formatLimit(usage.usage.realityRuns, config.limits.realityRunsPerMonth)}\n`;
318
+ summary += `AI Agent: ${formatLimit(usage.usage.aiAgentRuns, config.limits.aiAgentRunsPerMonth)}\n`;
319
+ summary += `Team Seats: ${(0, tier_config_1.formatSeatInfo)(tier)}\n`;
320
+ summary += '─'.repeat(50) + '\n';
321
+ summary += `Period: ${usage.periodStart.split('T')[0]} to ${usage.periodEnd.split('T')[0]}\n`;
322
+ return summary;
323
+ }
324
+ // ============================================================================
325
+ // UPGRADE PROMPTS
326
+ // ============================================================================
327
+ /**
328
+ * Format upgrade prompt for CLI output
329
+ */
330
+ formatUpgradePrompt(currentTier, requiredTier, feature) {
331
+ const required = requiredTier ? tier_config_1.TIER_CONFIG[requiredTier] : null;
332
+ let prompt = '\n';
333
+ prompt += '╭─────────────────────────────────────────────────────────────╮\n';
334
+ prompt += '│ ⚡ UPGRADE REQUIRED │\n';
335
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
336
+ prompt += `│ Feature: ${feature.padEnd(48)}│\n`;
337
+ prompt += `│ Your tier: ${currentTier.padEnd(46)}│\n`;
338
+ if (required) {
339
+ prompt += `│ Required: ${requiredTier} ($${required.price}/month)`.padEnd(62) + '│\n';
340
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
341
+ prompt += `│ ${required.name} includes:`.padEnd(62) + '│\n';
342
+ // Show key features of required tier
343
+ const keyFeatures = required.features.slice(0, 5);
344
+ for (const f of keyFeatures) {
345
+ prompt += `│ ✓ ${f}`.padEnd(62) + '│\n';
346
+ }
347
+ }
348
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
349
+ prompt += '│ → guardrail upgrade │\n';
350
+ prompt += '│ → https://getguardrail.io/pricing │\n';
351
+ prompt += '╰─────────────────────────────────────────────────────────────╯\n';
352
+ return prompt;
353
+ }
354
+ /**
355
+ * Format limit exceeded prompt
356
+ */
357
+ formatLimitUpgradePrompt(currentTier, limitType, current, limit) {
358
+ const config = tier_config_1.TIER_CONFIG[currentTier];
359
+ const nextConfig = tier_config_1.TIER_CONFIG[config.upsell.nextTier];
360
+ let prompt = '\n';
361
+ prompt += '╭─────────────────────────────────────────────────────────────╮\n';
362
+ prompt += '│ ⚠️ MONTHLY LIMIT REACHED │\n';
363
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
364
+ prompt += `│ ${limitType}: ${current}/${limit} used this month`.padEnd(62) + '│\n';
365
+ prompt += `│ Your tier: ${currentTier} ($${config.price}/month)`.padEnd(62) + '│\n';
366
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
367
+ prompt += `│ ${config.upsell.message}`.substring(0, 58).padEnd(62) + '│\n';
368
+ if (nextConfig && config.upsell.nextTier !== 'unlimited') {
369
+ const nextLimitMap = {
370
+ scans: 'scansPerMonth',
371
+ realityRuns: 'realityRunsPerMonth',
372
+ aiAgentRuns: 'aiAgentRunsPerMonth',
373
+ };
374
+ const nextLimit = nextConfig.limits[nextLimitMap[limitType] || 'scansPerMonth'];
375
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
376
+ prompt += `│ ${nextConfig.name} ($${nextConfig.price}/mo): ${nextLimit === -1 ? 'Unlimited' : nextLimit} ${limitType}/month`.padEnd(62) + '│\n';
377
+ }
378
+ prompt += '├─────────────────────────────────────────────────────────────┤\n';
379
+ prompt += '│ → guardrail upgrade │\n';
380
+ prompt += '│ → https://getguardrail.io/pricing │\n';
381
+ prompt += '╰─────────────────────────────────────────────────────────────╯\n';
382
+ return prompt;
383
+ }
384
+ // ============================================================================
385
+ // PRIVATE HELPERS
386
+ // ============================================================================
387
+ isNewBillingPeriod(periodStart) {
388
+ const start = new Date(periodStart);
389
+ const now = new Date();
390
+ // Monthly billing period
391
+ const nextPeriod = new Date(start);
392
+ nextPeriod.setMonth(nextPeriod.getMonth() + 1);
393
+ return now >= nextPeriod;
394
+ }
395
+ createNewUsageRecord() {
396
+ const now = new Date();
397
+ const periodEnd = new Date(now);
398
+ periodEnd.setMonth(periodEnd.getMonth() + 1);
399
+ return {
400
+ tier: 'free',
401
+ periodStart: now.toISOString(),
402
+ periodEnd: periodEnd.toISOString(),
403
+ usage: {
404
+ scans: 0,
405
+ realityRuns: 0,
406
+ aiAgentRuns: 0,
407
+ gateRuns: 0,
408
+ fixRuns: 0,
409
+ },
410
+ lastUpdated: now.toISOString(),
411
+ };
412
+ }
413
+ async ensureConfigDir() {
414
+ try {
415
+ await fs.promises.mkdir(this.configDir, { recursive: true });
416
+ }
417
+ catch {
418
+ // Directory exists
419
+ }
420
+ }
421
+ async saveUsage(usage) {
422
+ await this.ensureConfigDir();
423
+ await fs.promises.writeFile(this.usageFile, JSON.stringify(usage, null, 2));
424
+ }
425
+ async readLicense() {
426
+ try {
427
+ const content = await fs.promises.readFile(this.licenseFile, 'utf8');
428
+ return JSON.parse(content);
429
+ }
430
+ catch {
431
+ return null;
432
+ }
433
+ }
434
+ progressBar(percent) {
435
+ const filled = Math.min(10, Math.round(percent / 10));
436
+ const empty = 10 - filled;
437
+ const color = percent >= 90 ? '🔴' : percent >= 70 ? '🟡' : '🟢';
438
+ return `[${color.repeat(filled)}${'░'.repeat(empty)}]`;
439
+ }
440
+ }
441
+ exports.EntitlementsManager = EntitlementsManager;
442
+ // ============================================================================
443
+ // SINGLETON EXPORT
444
+ // ============================================================================
445
+ exports.entitlements = new EntitlementsManager();
446
+ // Convenience exports
447
+ const checkFeature = (feature) => exports.entitlements.checkFeature(feature);
448
+ exports.checkFeature = checkFeature;
449
+ const checkLimit = (limitType) => exports.entitlements.checkLimit(limitType);
450
+ exports.checkLimit = checkLimit;
451
+ const enforceFeature = (feature) => exports.entitlements.enforceFeature(feature);
452
+ exports.enforceFeature = enforceFeature;
453
+ const enforceLimit = (limitType) => exports.entitlements.enforceLimit(limitType);
454
+ exports.enforceLimit = enforceLimit;
455
+ const trackUsage = (type, count) => exports.entitlements.trackUsage(type, count);
456
+ exports.trackUsage = trackUsage;
457
+ const getCurrentTier = () => exports.entitlements.getCurrentTier();
458
+ exports.getCurrentTier = getCurrentTier;
459
+ const getUsageSummary = () => exports.entitlements.getUsageSummary();
460
+ exports.getUsageSummary = getUsageSummary;
461
+ const checkSeatLimit = (tier, currentMemberCount, purchasedExtraSeats) => exports.entitlements.checkSeatLimit(tier, currentMemberCount, purchasedExtraSeats);
462
+ exports.checkSeatLimit = checkSeatLimit;
463
+ const getOrganizationSeats = (tier, purchasedExtraSeats, currentMembers) => exports.entitlements.getOrganizationSeats(tier, purchasedExtraSeats, currentMembers);
464
+ exports.getOrganizationSeats = getOrganizationSeats;