faf-cli 4.4.4 → 5.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 (93) hide show
  1. package/README.md +32 -21
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +151 -4
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/agents.d.ts +14 -0
  6. package/dist/commands/agents.d.ts.map +1 -0
  7. package/dist/commands/agents.js +353 -0
  8. package/dist/commands/agents.js.map +1 -0
  9. package/dist/commands/bi-sync.d.ts +4 -0
  10. package/dist/commands/bi-sync.d.ts.map +1 -1
  11. package/dist/commands/bi-sync.js +51 -0
  12. package/dist/commands/bi-sync.js.map +1 -1
  13. package/dist/commands/cursor.d.ts +13 -0
  14. package/dist/commands/cursor.d.ts.map +1 -0
  15. package/dist/commands/cursor.js +310 -0
  16. package/dist/commands/cursor.js.map +1 -0
  17. package/dist/commands/go.d.ts.map +1 -1
  18. package/dist/commands/go.js +22 -19
  19. package/dist/commands/go.js.map +1 -1
  20. package/dist/commands/memory.d.ts +14 -0
  21. package/dist/commands/memory.d.ts.map +1 -0
  22. package/dist/commands/memory.js +293 -0
  23. package/dist/commands/memory.js.map +1 -0
  24. package/dist/commands/pro.d.ts +10 -0
  25. package/dist/commands/pro.d.ts.map +1 -0
  26. package/dist/commands/pro.js +113 -0
  27. package/dist/commands/pro.js.map +1 -0
  28. package/dist/commands/ram.d.ts +17 -0
  29. package/dist/commands/ram.d.ts.map +1 -0
  30. package/dist/commands/ram.js +303 -0
  31. package/dist/commands/ram.js.map +1 -0
  32. package/dist/commands/readme.js +8 -8
  33. package/dist/commands/readme.js.map +1 -1
  34. package/dist/commands/sixws.js +1 -1
  35. package/dist/commands/taf-log.d.ts +1 -0
  36. package/dist/commands/taf-log.d.ts.map +1 -1
  37. package/dist/commands/taf-log.js +53 -5
  38. package/dist/commands/taf-log.js.map +1 -1
  39. package/dist/commands/taf-stars.d.ts +8 -0
  40. package/dist/commands/taf-stars.d.ts.map +1 -0
  41. package/dist/commands/taf-stars.js +105 -0
  42. package/dist/commands/taf-stars.js.map +1 -0
  43. package/dist/commands/taf.d.ts +1 -0
  44. package/dist/commands/taf.d.ts.map +1 -1
  45. package/dist/commands/taf.js +9 -0
  46. package/dist/commands/taf.js.map +1 -1
  47. package/dist/compiler/faf-compiler.d.ts.map +1 -1
  48. package/dist/compiler/faf-compiler.js +24 -2
  49. package/dist/compiler/faf-compiler.js.map +1 -1
  50. package/dist/engines/v252-hybrid-engine.d.ts +1 -1
  51. package/dist/engines/v252-hybrid-engine.d.ts.map +1 -1
  52. package/dist/engines/v252-hybrid-engine.js +1 -1
  53. package/dist/engines/v252-hybrid-engine.js.map +1 -1
  54. package/dist/github/repo-selector.js +4 -4
  55. package/dist/github/repo-selector.js.map +1 -1
  56. package/dist/licensing/license-messages.d.ts +20 -0
  57. package/dist/licensing/license-messages.d.ts.map +1 -0
  58. package/dist/licensing/license-messages.js +77 -0
  59. package/dist/licensing/license-messages.js.map +1 -0
  60. package/dist/licensing/pro-gate.d.ts +54 -0
  61. package/dist/licensing/pro-gate.d.ts.map +1 -0
  62. package/dist/licensing/pro-gate.js +243 -0
  63. package/dist/licensing/pro-gate.js.map +1 -0
  64. package/dist/taf/index.d.ts +4 -0
  65. package/dist/taf/index.d.ts.map +1 -1
  66. package/dist/taf/index.js +16 -1
  67. package/dist/taf/index.js.map +1 -1
  68. package/dist/taf/star-badge.d.ts +32 -0
  69. package/dist/taf/star-badge.d.ts.map +1 -0
  70. package/dist/taf/star-badge.js +158 -0
  71. package/dist/taf/star-badge.js.map +1 -0
  72. package/dist/taf/star-rating.d.ts +30 -0
  73. package/dist/taf/star-rating.d.ts.map +1 -0
  74. package/dist/taf/star-rating.js +79 -0
  75. package/dist/taf/star-rating.js.map +1 -0
  76. package/dist/taf/test-output-parser.d.ts +42 -0
  77. package/dist/taf/test-output-parser.d.ts.map +1 -0
  78. package/dist/taf/test-output-parser.js +114 -0
  79. package/dist/taf/test-output-parser.js.map +1 -0
  80. package/dist/utils/agents-parser.d.ts +60 -0
  81. package/dist/utils/agents-parser.d.ts.map +1 -0
  82. package/dist/utils/agents-parser.js +325 -0
  83. package/dist/utils/agents-parser.js.map +1 -0
  84. package/dist/utils/cursorrules-parser.d.ts +56 -0
  85. package/dist/utils/cursorrules-parser.d.ts.map +1 -0
  86. package/dist/utils/cursorrules-parser.js +315 -0
  87. package/dist/utils/cursorrules-parser.js.map +1 -0
  88. package/dist/utils/memory-parser.d.ts +95 -0
  89. package/dist/utils/memory-parser.d.ts.map +1 -0
  90. package/dist/utils/memory-parser.js +408 -0
  91. package/dist/utils/memory-parser.js.map +1 -0
  92. package/package.json +1 -1
  93. package/project.faf +12 -20
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * FAF Pro — User-facing messages
4
+ *
5
+ * All copy in one place. Warm tone, zero pressure.
6
+ *
7
+ * Tagline: Bi-sync is core. Tri-sync adds more.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MESSAGES = void 0;
11
+ exports.showTrialStarted = showTrialStarted;
12
+ exports.showTrialReminder = showTrialReminder;
13
+ exports.showTrialExpired = showTrialExpired;
14
+ exports.showLicenseActive = showLicenseActive;
15
+ const colors_1 = require("../fix-once/colors");
16
+ const championship_style_1 = require("../utils/championship-style");
17
+ // ---------------------------------------------------------------------------
18
+ // Raw message strings (testable without chalk)
19
+ // ---------------------------------------------------------------------------
20
+ exports.MESSAGES = {
21
+ tagline: 'Bi-sync is core. Tri-sync adds more.',
22
+ trialReminder: (days) => `tri-sync Pro: ${days} day${days === 1 ? '' : 's'} left in trial`,
23
+ trialExpired: 'Your tri-sync Pro trial has ended.',
24
+ licenseActivated: 'Pro activated! tri-sync is yours.',
25
+ alreadyLicensed: "You're already Pro!",
26
+ invalidKey: "That key doesn't look right. Format: FAF-PRO-XXXX-XXXX-XXXX",
27
+ };
28
+ // ---------------------------------------------------------------------------
29
+ // Formatted console output
30
+ // ---------------------------------------------------------------------------
31
+ function showTrialStarted() {
32
+ console.log();
33
+ console.log(championship_style_1.FAF_COLORS.fafOrange(` ${exports.MESSAGES.tagline}`));
34
+ console.log(colors_1.chalk.white(' What does it add? It adds RAM, and it auto-syncs with Claude\'s MEMORY.md'));
35
+ console.log();
36
+ console.log(colors_1.chalk.white(' You\'re using tri-sync right now.'));
37
+ console.log(colors_1.chalk.white(' It adds RAM to FAF — another sync, this time to Claude\'s session memory.'));
38
+ console.log();
39
+ console.log(colors_1.chalk.gray(' bi-sync = ROM (.faf) ↔ CLAUDE.md'));
40
+ console.log(colors_1.chalk.gray(' tri-sync = ROM ↔ CLAUDE.md ↔ RAM (Claude\'s session memory)'));
41
+ console.log();
42
+ console.log(colors_1.chalk.white(' bi-sync is also running right now. The stack, the config, the'));
43
+ console.log(colors_1.chalk.white(' languages — project.faf, exactly the same. Free for all devs, forever.'));
44
+ console.log(colors_1.chalk.white(' That\'s FAF — persistent project memory.'));
45
+ console.log();
46
+ console.log(colors_1.chalk.white(' tri-sync is a Pro feature. You\'re trying it free for 14 days.'));
47
+ console.log(colors_1.chalk.gray(' Let us know what you think.'));
48
+ console.log();
49
+ console.log(colors_1.chalk.gray(' Early-bird: $3/mo · $19/yr (normally $10/mo — 70% off)'));
50
+ console.log(colors_1.chalk.gray(' faf.one/pro when you\'re ready.'));
51
+ console.log();
52
+ }
53
+ function showTrialReminder(days) {
54
+ console.log(colors_1.chalk.gray(` ${championship_style_1.FAF_ICONS.precision} ${exports.MESSAGES.trialReminder(days)}`));
55
+ }
56
+ function showTrialExpired() {
57
+ console.log();
58
+ console.log(colors_1.chalk.yellow(`${championship_style_1.FAF_ICONS.precision} ${exports.MESSAGES.trialExpired}`));
59
+ console.log();
60
+ console.log(championship_style_1.FAF_COLORS.fafOrange(` ${exports.MESSAGES.tagline}`));
61
+ console.log(colors_1.chalk.white(' What does it add? It adds RAM, and it auto-syncs with Claude\'s MEMORY.md'));
62
+ console.log();
63
+ console.log(colors_1.chalk.white(' bi-sync is free — and always will be.'));
64
+ console.log(colors_1.chalk.white(' tri-sync adds RAM: your AI remembers across sessions.'));
65
+ console.log();
66
+ console.log(colors_1.chalk.gray(' Early-bird: $3/mo · $19/yr (normally $10/mo — 70% off)'));
67
+ console.log(colors_1.chalk.gray(' Lock in early-adopter pricing before it\'s gone.'));
68
+ console.log();
69
+ console.log(championship_style_1.FAF_COLORS.fafOrange(` ${championship_style_1.FAF_ICONS.trophy} faf.one/pro`));
70
+ console.log(colors_1.chalk.gray(' Run: faf pro activate <key>'));
71
+ console.log();
72
+ }
73
+ function showLicenseActive() {
74
+ // Silent on normal use — Pro users shouldn't see noise.
75
+ // Only shown from `faf pro status`.
76
+ }
77
+ //# sourceMappingURL=license-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"license-messages.js","sourceRoot":"","sources":["../../src/licensing/license-messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * FAF Pro Gate — Zero-Friction License System for tri-sync
3
+ *
4
+ * Gates: faf ram, faf tri-sync, faf bi-sync --ram/--all
5
+ * Model: PHPStan Pro — 14-day free trial, no signup, no credit card.
6
+ *
7
+ * Flow:
8
+ * User runs gated command
9
+ * → checkProAccess()
10
+ * → isLegacyDev()? → ALLOW
11
+ * → hasLicense()? → verify sig → ALLOW
12
+ * → hasTrial()? → verify sig → check expiry
13
+ * → within 14 days? → ALLOW (hint days left)
14
+ * → expired? → BLOCK (upgrade prompt)
15
+ * → no trial? → startTrial() → ALLOW
16
+ */
17
+ export interface TrialState {
18
+ startedAt: string;
19
+ expiresAt: string;
20
+ signature: string;
21
+ }
22
+ export interface LicenseState {
23
+ key: string;
24
+ activatedAt: string;
25
+ email?: string;
26
+ tier: string;
27
+ signature: string;
28
+ }
29
+ export type ProReason = 'licensed' | 'trial' | 'trial_expired' | 'no_trial' | 'legacy_dev';
30
+ export interface ProStatus {
31
+ allowed: boolean;
32
+ reason: ProReason;
33
+ daysLeft?: number;
34
+ justStarted?: boolean;
35
+ }
36
+ export interface ActivationResult {
37
+ success: boolean;
38
+ message: string;
39
+ }
40
+ export declare function isLegacyDev(): boolean;
41
+ export declare function startTrial(): TrialState;
42
+ export declare function activateLicense(key: string): ActivationResult;
43
+ export declare function checkProAccess(): ProStatus;
44
+ export declare function gateProFeature(): boolean;
45
+ export declare function getProStatus(): {
46
+ state: 'licensed' | 'trial' | 'trial_expired' | 'none' | 'legacy_dev';
47
+ daysLeft?: number;
48
+ key?: string;
49
+ tier?: string;
50
+ trialStarted?: string;
51
+ trialExpires?: string;
52
+ activatedAt?: string;
53
+ };
54
+ //# sourceMappingURL=pro-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pro-gate.d.ts","sourceRoot":"","sources":["../../src/licensing/pro-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA2BH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3F,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AA6CD,wBAAgB,WAAW,IAAI,OAAO,CAIrC;AAiBD,wBAAgB,UAAU,IAAI,UAAU,CAiBvC;AA0BD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAyB7D;AAMD,wBAAgB,cAAc,IAAI,SAAS,CAyB1C;AAMD,wBAAgB,cAAc,IAAI,OAAO,CAqBxC;AAMD,wBAAgB,YAAY,IAAI;IAC9B,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,eAAe,GAAG,MAAM,GAAG,YAAY,CAAC;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAmCA"}
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * FAF Pro Gate — Zero-Friction License System for tri-sync
4
+ *
5
+ * Gates: faf ram, faf tri-sync, faf bi-sync --ram/--all
6
+ * Model: PHPStan Pro — 14-day free trial, no signup, no credit card.
7
+ *
8
+ * Flow:
9
+ * User runs gated command
10
+ * → checkProAccess()
11
+ * → isLegacyDev()? → ALLOW
12
+ * → hasLicense()? → verify sig → ALLOW
13
+ * → hasTrial()? → verify sig → check expiry
14
+ * → within 14 days? → ALLOW (hint days left)
15
+ * → expired? → BLOCK (upgrade prompt)
16
+ * → no trial? → startTrial() → ALLOW
17
+ */
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.isLegacyDev = isLegacyDev;
23
+ exports.startTrial = startTrial;
24
+ exports.activateLicense = activateLicense;
25
+ exports.checkProAccess = checkProAccess;
26
+ exports.gateProFeature = gateProFeature;
27
+ exports.getProStatus = getProStatus;
28
+ const fs_1 = __importDefault(require("fs"));
29
+ const path_1 = __importDefault(require("path"));
30
+ const os_1 = __importDefault(require("os"));
31
+ const crypto_1 = __importDefault(require("crypto"));
32
+ const license_messages_1 = require("./license-messages");
33
+ // ---------------------------------------------------------------------------
34
+ // Paths
35
+ // ---------------------------------------------------------------------------
36
+ const FAF_DIR = path_1.default.join(os_1.default.homedir(), '.faf');
37
+ const TRIAL_PATH = path_1.default.join(FAF_DIR, 'trial.json');
38
+ const LICENSE_PATH = path_1.default.join(FAF_DIR, 'license.json');
39
+ const LEGACY_LICENSE_PATH = path_1.default.join(FAF_DIR, 'turbo-license.json');
40
+ // ---------------------------------------------------------------------------
41
+ // HMAC Signing (v1 — honest-user guard, not DRM)
42
+ // ---------------------------------------------------------------------------
43
+ const HMAC_SECRET = 'faf-pro-v1-honest-user';
44
+ function sign(payload) {
45
+ return crypto_1.default.createHmac('sha256', HMAC_SECRET).update(payload).digest('hex');
46
+ }
47
+ function verify(payload, signature) {
48
+ return sign(payload) === signature;
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // File helpers (sync for <10ms)
52
+ // ---------------------------------------------------------------------------
53
+ function ensureFafDir() {
54
+ if (!fs_1.default.existsSync(FAF_DIR)) {
55
+ fs_1.default.mkdirSync(FAF_DIR, { recursive: true });
56
+ }
57
+ }
58
+ function readJSON(filePath) {
59
+ try {
60
+ if (!fs_1.default.existsSync(filePath)) {
61
+ return null;
62
+ }
63
+ const raw = fs_1.default.readFileSync(filePath, 'utf-8');
64
+ return JSON.parse(raw);
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ function writeJSON(filePath, data) {
71
+ ensureFafDir();
72
+ fs_1.default.writeFileSync(filePath, JSON.stringify(data, null, 2));
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Legacy dev check
76
+ // ---------------------------------------------------------------------------
77
+ function isLegacyDev() {
78
+ const legacy = readJSON(LEGACY_LICENSE_PATH);
79
+ if (!legacy || !legacy.key) {
80
+ return false;
81
+ }
82
+ return legacy.key.startsWith('FAF-DEV0-');
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // Trial management
86
+ // ---------------------------------------------------------------------------
87
+ function readTrial() {
88
+ const trial = readJSON(TRIAL_PATH);
89
+ if (!trial) {
90
+ return null;
91
+ }
92
+ // Verify integrity
93
+ const payload = `${trial.startedAt}:${trial.expiresAt}`;
94
+ if (!verify(payload, trial.signature)) {
95
+ return null;
96
+ }
97
+ return trial;
98
+ }
99
+ function startTrial() {
100
+ const now = new Date();
101
+ const expires = new Date(now);
102
+ expires.setDate(expires.getDate() + 14);
103
+ const startedAt = now.toISOString();
104
+ const expiresAt = expires.toISOString();
105
+ const payload = `${startedAt}:${expiresAt}`;
106
+ const trial = {
107
+ startedAt,
108
+ expiresAt,
109
+ signature: sign(payload),
110
+ };
111
+ writeJSON(TRIAL_PATH, trial);
112
+ return trial;
113
+ }
114
+ function trialDaysLeft(trial) {
115
+ const now = Date.now();
116
+ const expires = new Date(trial.expiresAt).getTime();
117
+ const msLeft = expires - now;
118
+ return Math.max(0, Math.ceil(msLeft / (1000 * 60 * 60 * 24)));
119
+ }
120
+ // ---------------------------------------------------------------------------
121
+ // License management
122
+ // ---------------------------------------------------------------------------
123
+ const LICENSE_KEY_REGEX = /^FAF-PRO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
124
+ function readLicense() {
125
+ const license = readJSON(LICENSE_PATH);
126
+ if (!license) {
127
+ return null;
128
+ }
129
+ // Verify integrity
130
+ const payload = `${license.key}:${license.activatedAt}`;
131
+ if (!verify(payload, license.signature)) {
132
+ return null;
133
+ }
134
+ return license;
135
+ }
136
+ function activateLicense(key) {
137
+ const trimmed = key.trim().toUpperCase();
138
+ if (!LICENSE_KEY_REGEX.test(trimmed)) {
139
+ return { success: false, message: license_messages_1.MESSAGES.invalidKey };
140
+ }
141
+ // Check if already licensed
142
+ const existing = readLicense();
143
+ if (existing) {
144
+ return { success: false, message: license_messages_1.MESSAGES.alreadyLicensed };
145
+ }
146
+ const activatedAt = new Date().toISOString();
147
+ const payload = `${trimmed}:${activatedAt}`;
148
+ const license = {
149
+ key: trimmed,
150
+ activatedAt,
151
+ tier: 'pro',
152
+ signature: sign(payload),
153
+ };
154
+ writeJSON(LICENSE_PATH, license);
155
+ return { success: true, message: license_messages_1.MESSAGES.licenseActivated };
156
+ }
157
+ // ---------------------------------------------------------------------------
158
+ // Core gate check
159
+ // ---------------------------------------------------------------------------
160
+ function checkProAccess() {
161
+ // 1. Legacy dev — always allowed
162
+ if (isLegacyDev()) {
163
+ return { allowed: true, reason: 'legacy_dev' };
164
+ }
165
+ // 2. Active license
166
+ const license = readLicense();
167
+ if (license) {
168
+ return { allowed: true, reason: 'licensed' };
169
+ }
170
+ // 3. Active trial
171
+ const trial = readTrial();
172
+ if (trial) {
173
+ const days = trialDaysLeft(trial);
174
+ if (days > 0) {
175
+ return { allowed: true, reason: 'trial', daysLeft: days };
176
+ }
177
+ return { allowed: false, reason: 'trial_expired', daysLeft: 0 };
178
+ }
179
+ // 4. No trial yet — start one automatically
180
+ startTrial();
181
+ return { allowed: true, reason: 'trial', daysLeft: 14, justStarted: true };
182
+ }
183
+ // ---------------------------------------------------------------------------
184
+ // Gate wrapper — call before any Pro feature
185
+ // ---------------------------------------------------------------------------
186
+ function gateProFeature() {
187
+ const status = checkProAccess();
188
+ if (!status.allowed) {
189
+ if (status.reason === 'trial_expired') {
190
+ (0, license_messages_1.showTrialExpired)();
191
+ }
192
+ return false;
193
+ }
194
+ // Show contextual messages
195
+ if (status.reason === 'trial' && status.justStarted) {
196
+ (0, license_messages_1.showTrialStarted)();
197
+ }
198
+ else if (status.reason === 'trial') {
199
+ (0, license_messages_1.showTrialReminder)(status.daysLeft);
200
+ }
201
+ else if (status.reason === 'licensed') {
202
+ (0, license_messages_1.showLicenseActive)();
203
+ }
204
+ // legacy_dev — silent pass
205
+ return true;
206
+ }
207
+ // ---------------------------------------------------------------------------
208
+ // Status helpers (for `faf pro` command)
209
+ // ---------------------------------------------------------------------------
210
+ function getProStatus() {
211
+ if (isLegacyDev()) {
212
+ return { state: 'legacy_dev' };
213
+ }
214
+ const license = readLicense();
215
+ if (license) {
216
+ return {
217
+ state: 'licensed',
218
+ key: license.key,
219
+ tier: license.tier,
220
+ activatedAt: license.activatedAt,
221
+ };
222
+ }
223
+ const trial = readTrial();
224
+ if (trial) {
225
+ const days = trialDaysLeft(trial);
226
+ if (days > 0) {
227
+ return {
228
+ state: 'trial',
229
+ daysLeft: days,
230
+ trialStarted: trial.startedAt,
231
+ trialExpires: trial.expiresAt,
232
+ };
233
+ }
234
+ return {
235
+ state: 'trial_expired',
236
+ daysLeft: 0,
237
+ trialStarted: trial.startedAt,
238
+ trialExpires: trial.expiresAt,
239
+ };
240
+ }
241
+ return { state: 'none' };
242
+ }
243
+ //# sourceMappingURL=pro-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pro-gate.js","sourceRoot":"","sources":["../../src/licensing/pro-gate.ts"],"names":[],"mappings":"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"}
@@ -14,4 +14,8 @@ export { parseTAF, serializeTAF, createTAF, formatTAF, } from './parser';
14
14
  export { validateTAF, isTAFValid, } from './validator';
15
15
  export { calculateStats, calculateScoreContribution, getPassRateTrend, getFailurePatterns, } from './stats';
16
16
  export { appendTestRun, createMinimalRun, createDetailedRun, detectResult, calculateRecovery, getRecentRuns, getRunsInRange, updateFAFIntegration, } from './logger';
17
+ export { calculateStarRating, formatStarsDisplay, calculateStarRatingFromTAF, } from './star-rating';
18
+ export type { StarRating } from './star-rating';
19
+ export { renderStarBadgeSvg, generateStarBadge, } from './star-badge';
20
+ export { stripAnsi, parseJestOutput, parseVitestOutput, parseTestOutput, ParsedTestOutput, } from './test-output-parser';
17
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/taf/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,GACV,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,oBAAoB,GACrB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/taf/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,GACV,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
package/dist/taf/index.js CHANGED
@@ -25,7 +25,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
25
25
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.updateFAFIntegration = exports.getRunsInRange = exports.getRecentRuns = exports.calculateRecovery = exports.detectResult = exports.createDetailedRun = exports.createMinimalRun = exports.appendTestRun = exports.getFailurePatterns = exports.getPassRateTrend = exports.calculateScoreContribution = exports.calculateStats = exports.isTAFValid = exports.validateTAF = exports.formatTAF = exports.createTAF = exports.serializeTAF = exports.parseTAF = void 0;
28
+ exports.parseTestOutput = exports.parseVitestOutput = exports.parseJestOutput = exports.stripAnsi = exports.generateStarBadge = exports.renderStarBadgeSvg = exports.calculateStarRatingFromTAF = exports.formatStarsDisplay = exports.calculateStarRating = exports.updateFAFIntegration = exports.getRunsInRange = exports.getRecentRuns = exports.calculateRecovery = exports.detectResult = exports.createDetailedRun = exports.createMinimalRun = exports.appendTestRun = exports.getFailurePatterns = exports.getPassRateTrend = exports.calculateScoreContribution = exports.calculateStats = exports.isTAFValid = exports.validateTAF = exports.formatTAF = exports.createTAF = exports.serializeTAF = exports.parseTAF = void 0;
29
29
  // Types
30
30
  __exportStar(require("./types"), exports);
31
31
  // Parser functions
@@ -54,4 +54,19 @@ Object.defineProperty(exports, "calculateRecovery", { enumerable: true, get: fun
54
54
  Object.defineProperty(exports, "getRecentRuns", { enumerable: true, get: function () { return logger_1.getRecentRuns; } });
55
55
  Object.defineProperty(exports, "getRunsInRange", { enumerable: true, get: function () { return logger_1.getRunsInRange; } });
56
56
  Object.defineProperty(exports, "updateFAFIntegration", { enumerable: true, get: function () { return logger_1.updateFAFIntegration; } });
57
+ // Star rating functions
58
+ var star_rating_1 = require("./star-rating");
59
+ Object.defineProperty(exports, "calculateStarRating", { enumerable: true, get: function () { return star_rating_1.calculateStarRating; } });
60
+ Object.defineProperty(exports, "formatStarsDisplay", { enumerable: true, get: function () { return star_rating_1.formatStarsDisplay; } });
61
+ Object.defineProperty(exports, "calculateStarRatingFromTAF", { enumerable: true, get: function () { return star_rating_1.calculateStarRatingFromTAF; } });
62
+ // Star badge functions
63
+ var star_badge_1 = require("./star-badge");
64
+ Object.defineProperty(exports, "renderStarBadgeSvg", { enumerable: true, get: function () { return star_badge_1.renderStarBadgeSvg; } });
65
+ Object.defineProperty(exports, "generateStarBadge", { enumerable: true, get: function () { return star_badge_1.generateStarBadge; } });
66
+ // Test output parser (stdin auto-parse)
67
+ var test_output_parser_1 = require("./test-output-parser");
68
+ Object.defineProperty(exports, "stripAnsi", { enumerable: true, get: function () { return test_output_parser_1.stripAnsi; } });
69
+ Object.defineProperty(exports, "parseJestOutput", { enumerable: true, get: function () { return test_output_parser_1.parseJestOutput; } });
70
+ Object.defineProperty(exports, "parseVitestOutput", { enumerable: true, get: function () { return test_output_parser_1.parseVitestOutput; } });
71
+ Object.defineProperty(exports, "parseTestOutput", { enumerable: true, get: function () { return test_output_parser_1.parseTestOutput; } });
57
72
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/taf/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,0CAAwB;AAExB,mBAAmB;AACnB,mCAKkB;AAJhB,kGAAA,QAAQ,OAAA;AACR,sGAAA,YAAY,OAAA;AACZ,mGAAA,SAAS,OAAA;AACT,mGAAA,SAAS,OAAA;AAGX,uBAAuB;AACvB,yCAGqB;AAFnB,wGAAA,WAAW,OAAA;AACX,uGAAA,UAAU,OAAA;AAGZ,uBAAuB;AACvB,iCAKiB;AAJf,uGAAA,cAAc,OAAA;AACd,mHAAA,0BAA0B,OAAA;AAC1B,yGAAA,gBAAgB,OAAA;AAChB,2GAAA,kBAAkB,OAAA;AAGpB,mBAAmB;AACnB,mCASkB;AARhB,uGAAA,aAAa,OAAA;AACb,0GAAA,gBAAgB,OAAA;AAChB,2GAAA,iBAAiB,OAAA;AACjB,sGAAA,YAAY,OAAA;AACZ,2GAAA,iBAAiB,OAAA;AACjB,uGAAA,aAAa,OAAA;AACb,wGAAA,cAAc,OAAA;AACd,8GAAA,oBAAoB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/taf/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,0CAAwB;AAExB,mBAAmB;AACnB,mCAKkB;AAJhB,kGAAA,QAAQ,OAAA;AACR,sGAAA,YAAY,OAAA;AACZ,mGAAA,SAAS,OAAA;AACT,mGAAA,SAAS,OAAA;AAGX,uBAAuB;AACvB,yCAGqB;AAFnB,wGAAA,WAAW,OAAA;AACX,uGAAA,UAAU,OAAA;AAGZ,uBAAuB;AACvB,iCAKiB;AAJf,uGAAA,cAAc,OAAA;AACd,mHAAA,0BAA0B,OAAA;AAC1B,yGAAA,gBAAgB,OAAA;AAChB,2GAAA,kBAAkB,OAAA;AAGpB,mBAAmB;AACnB,mCASkB;AARhB,uGAAA,aAAa,OAAA;AACb,0GAAA,gBAAgB,OAAA;AAChB,2GAAA,iBAAiB,OAAA;AACjB,sGAAA,YAAY,OAAA;AACZ,2GAAA,iBAAiB,OAAA;AACjB,uGAAA,aAAa,OAAA;AACb,wGAAA,cAAc,OAAA;AACd,8GAAA,oBAAoB,OAAA;AAGtB,wBAAwB;AACxB,6CAIuB;AAHrB,kHAAA,mBAAmB,OAAA;AACnB,iHAAA,kBAAkB,OAAA;AAClB,yHAAA,0BAA0B,OAAA;AAI5B,uBAAuB;AACvB,2CAGsB;AAFpB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AAGnB,wCAAwC;AACxC,2DAM8B;AAL5B,+GAAA,SAAS,OAAA;AACT,qHAAA,eAAe,OAAA;AACf,uHAAA,iBAAiB,OAAA;AACjB,qHAAA,eAAe,OAAA"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * TAF Star Badge - SVG Renderer
3
+ *
4
+ * Black block + gold star polygon shapes.
5
+ * npm-safe: direct coordinates, no transform="scale(.1)" trick.
6
+ *
7
+ * Visual: black inverse block + gold fill = premium, classy
8
+ */
9
+ import { StarRating } from './star-rating';
10
+ export interface StarBadgeOptions {
11
+ tafPath?: string;
12
+ }
13
+ export interface StarBadgeResult {
14
+ success: boolean;
15
+ svg?: string;
16
+ rating?: StarRating;
17
+ error?: string;
18
+ }
19
+ /**
20
+ * Render star badge SVG — black block with gold stars.
21
+ *
22
+ * @param stars - Star count (0-5, 0.5 increments)
23
+ * @param label - Display text (e.g. "878/878")
24
+ * @param passedCount - Tests passed
25
+ * @param totalCount - Tests total
26
+ */
27
+ export declare function renderStarBadgeSvg(stars: number, label: string, passedCount: number, totalCount: number): string;
28
+ /**
29
+ * Generate star badge from .taf file.
30
+ */
31
+ export declare function generateStarBadge(options?: StarBadgeOptions): StarBadgeResult;
32
+ //# sourceMappingURL=star-badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-badge.d.ts","sourceRoot":"","sources":["../../src/taf/star-badge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAA8B,UAAU,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CA6CR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAyCjF"}
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /**
3
+ * TAF Star Badge - SVG Renderer
4
+ *
5
+ * Black block + gold star polygon shapes.
6
+ * npm-safe: direct coordinates, no transform="scale(.1)" trick.
7
+ *
8
+ * Visual: black inverse block + gold fill = premium, classy
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.renderStarBadgeSvg = renderStarBadgeSvg;
45
+ exports.generateStarBadge = generateStarBadge;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const parser_1 = require("./parser");
49
+ const star_rating_1 = require("./star-rating");
50
+ const GOLD = '#FFB800';
51
+ const DIM = '#555';
52
+ const BG = '#111';
53
+ /**
54
+ * 5-pointed star polygon path centered at (cx, cy) with given radius.
55
+ * Returns an SVG path data string.
56
+ */
57
+ function starPath(cx, cy, outerR, innerR) {
58
+ const points = [];
59
+ for (let i = 0; i < 10; i++) {
60
+ const angle = (Math.PI / 2) + (i * Math.PI / 5);
61
+ const r = i % 2 === 0 ? outerR : innerR;
62
+ const x = cx + r * Math.cos(angle);
63
+ const y = cy - r * Math.sin(angle);
64
+ points.push(`${x.toFixed(1)},${y.toFixed(1)}`);
65
+ }
66
+ return `M${points.join('L')}Z`;
67
+ }
68
+ /**
69
+ * Render star badge SVG — black block with gold stars.
70
+ *
71
+ * @param stars - Star count (0-5, 0.5 increments)
72
+ * @param label - Display text (e.g. "878/878")
73
+ * @param passedCount - Tests passed
74
+ * @param totalCount - Tests total
75
+ */
76
+ function renderStarBadgeSvg(stars, label, passedCount, totalCount) {
77
+ const height = 28;
78
+ const starSize = 8; // outer radius
79
+ const innerSize = 3.5; // inner radius
80
+ const starSpacing = 20;
81
+ const starStartX = 14;
82
+ const starCenterY = height / 2;
83
+ // Calculate widths
84
+ const starsBlockWidth = starStartX + 5 * starSpacing;
85
+ const charWidth = 6.5;
86
+ const textPadding = 8;
87
+ const labelWidth = Math.round(label.length * charWidth + textPadding * 2);
88
+ const totalWidth = starsBlockWidth + labelWidth;
89
+ const ariaLabel = `${stars} out of 5 stars: ${passedCount} of ${totalCount} tests passed`;
90
+ let starsSvg = '';
91
+ for (let i = 0; i < 5; i++) {
92
+ const cx = starStartX + i * starSpacing;
93
+ const d = starPath(cx, starCenterY, starSize, innerSize);
94
+ if (i + 1 <= Math.floor(stars)) {
95
+ // Full star — gold filled
96
+ starsSvg += ` <path d="${d}" fill="${GOLD}"/>\n`;
97
+ }
98
+ else if (i + 0.5 === stars) {
99
+ // Half star — left half gold, right half outline
100
+ const clipId = `half-${i}`;
101
+ starsSvg += ` <defs><clipPath id="${clipId}"><rect x="${cx - starSize}" y="${starCenterY - starSize}" width="${starSize}" height="${starSize * 2}"/></clipPath></defs>\n`;
102
+ starsSvg += ` <path d="${d}" fill="${DIM}" stroke="${DIM}" stroke-width="0.5"/>\n`;
103
+ starsSvg += ` <path d="${d}" fill="${GOLD}" clip-path="url(#${clipId})"/>\n`;
104
+ }
105
+ else {
106
+ // Empty star — dim outline
107
+ starsSvg += ` <path d="${d}" fill="none" stroke="${DIM}" stroke-width="1"/>\n`;
108
+ }
109
+ }
110
+ const textX = starsBlockWidth + labelWidth / 2;
111
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${height}" role="img" aria-label="${ariaLabel}">
112
+ <title>${ariaLabel}</title>
113
+ <rect width="${totalWidth}" height="${height}" rx="4" fill="${BG}"/>
114
+ ${starsSvg} <text x="${textX}" y="18" fill="#fff" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11" text-anchor="middle">${label}</text>
115
+ </svg>`;
116
+ }
117
+ /**
118
+ * Generate star badge from .taf file.
119
+ */
120
+ function generateStarBadge(options = {}) {
121
+ const tafPath = options.tafPath || path.join(process.cwd(), '.taf');
122
+ try {
123
+ if (!fs.existsSync(tafPath)) {
124
+ // No data — render empty stars
125
+ return {
126
+ success: true,
127
+ svg: renderStarBadgeSvg(0, 'no data', 0, 0),
128
+ rating: { stars: 0, display: '☆☆☆☆☆', label: '0.0 stars' },
129
+ };
130
+ }
131
+ const content = fs.readFileSync(tafPath, 'utf-8');
132
+ const taf = (0, parser_1.parseTAF)(content);
133
+ const rating = (0, star_rating_1.calculateStarRatingFromTAF)(taf);
134
+ if (!rating) {
135
+ return {
136
+ success: true,
137
+ svg: renderStarBadgeSvg(0, 'no data', 0, 0),
138
+ rating: { stars: 0, display: '☆☆☆☆☆', label: '0.0 stars' },
139
+ };
140
+ }
141
+ const latest = taf.test_history[taf.test_history.length - 1];
142
+ const passed = latest.tests.passed;
143
+ const total = latest.tests.total;
144
+ const label = `${passed}/${total}`;
145
+ return {
146
+ success: true,
147
+ svg: renderStarBadgeSvg(rating.stars, label, passed, total),
148
+ rating,
149
+ };
150
+ }
151
+ catch (error) {
152
+ return {
153
+ success: false,
154
+ error: error instanceof Error ? error.message : 'Failed to generate star badge',
155
+ };
156
+ }
157
+ }
158
+ //# sourceMappingURL=star-badge.js.map