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.
- package/README.md +32 -21
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +151 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.d.ts +14 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +353 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/bi-sync.d.ts +4 -0
- package/dist/commands/bi-sync.d.ts.map +1 -1
- package/dist/commands/bi-sync.js +51 -0
- package/dist/commands/bi-sync.js.map +1 -1
- package/dist/commands/cursor.d.ts +13 -0
- package/dist/commands/cursor.d.ts.map +1 -0
- package/dist/commands/cursor.js +310 -0
- package/dist/commands/cursor.js.map +1 -0
- package/dist/commands/go.d.ts.map +1 -1
- package/dist/commands/go.js +22 -19
- package/dist/commands/go.js.map +1 -1
- package/dist/commands/memory.d.ts +14 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +293 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/pro.d.ts +10 -0
- package/dist/commands/pro.d.ts.map +1 -0
- package/dist/commands/pro.js +113 -0
- package/dist/commands/pro.js.map +1 -0
- package/dist/commands/ram.d.ts +17 -0
- package/dist/commands/ram.d.ts.map +1 -0
- package/dist/commands/ram.js +303 -0
- package/dist/commands/ram.js.map +1 -0
- package/dist/commands/readme.js +8 -8
- package/dist/commands/readme.js.map +1 -1
- package/dist/commands/sixws.js +1 -1
- package/dist/commands/taf-log.d.ts +1 -0
- package/dist/commands/taf-log.d.ts.map +1 -1
- package/dist/commands/taf-log.js +53 -5
- package/dist/commands/taf-log.js.map +1 -1
- package/dist/commands/taf-stars.d.ts +8 -0
- package/dist/commands/taf-stars.d.ts.map +1 -0
- package/dist/commands/taf-stars.js +105 -0
- package/dist/commands/taf-stars.js.map +1 -0
- package/dist/commands/taf.d.ts +1 -0
- package/dist/commands/taf.d.ts.map +1 -1
- package/dist/commands/taf.js +9 -0
- package/dist/commands/taf.js.map +1 -1
- package/dist/compiler/faf-compiler.d.ts.map +1 -1
- package/dist/compiler/faf-compiler.js +24 -2
- package/dist/compiler/faf-compiler.js.map +1 -1
- package/dist/engines/v252-hybrid-engine.d.ts +1 -1
- package/dist/engines/v252-hybrid-engine.d.ts.map +1 -1
- package/dist/engines/v252-hybrid-engine.js +1 -1
- package/dist/engines/v252-hybrid-engine.js.map +1 -1
- package/dist/github/repo-selector.js +4 -4
- package/dist/github/repo-selector.js.map +1 -1
- package/dist/licensing/license-messages.d.ts +20 -0
- package/dist/licensing/license-messages.d.ts.map +1 -0
- package/dist/licensing/license-messages.js +77 -0
- package/dist/licensing/license-messages.js.map +1 -0
- package/dist/licensing/pro-gate.d.ts +54 -0
- package/dist/licensing/pro-gate.d.ts.map +1 -0
- package/dist/licensing/pro-gate.js +243 -0
- package/dist/licensing/pro-gate.js.map +1 -0
- package/dist/taf/index.d.ts +4 -0
- package/dist/taf/index.d.ts.map +1 -1
- package/dist/taf/index.js +16 -1
- package/dist/taf/index.js.map +1 -1
- package/dist/taf/star-badge.d.ts +32 -0
- package/dist/taf/star-badge.d.ts.map +1 -0
- package/dist/taf/star-badge.js +158 -0
- package/dist/taf/star-badge.js.map +1 -0
- package/dist/taf/star-rating.d.ts +30 -0
- package/dist/taf/star-rating.d.ts.map +1 -0
- package/dist/taf/star-rating.js +79 -0
- package/dist/taf/star-rating.js.map +1 -0
- package/dist/taf/test-output-parser.d.ts +42 -0
- package/dist/taf/test-output-parser.d.ts.map +1 -0
- package/dist/taf/test-output-parser.js +114 -0
- package/dist/taf/test-output-parser.js.map +1 -0
- package/dist/utils/agents-parser.d.ts +60 -0
- package/dist/utils/agents-parser.d.ts.map +1 -0
- package/dist/utils/agents-parser.js +325 -0
- package/dist/utils/agents-parser.js.map +1 -0
- package/dist/utils/cursorrules-parser.d.ts +56 -0
- package/dist/utils/cursorrules-parser.d.ts.map +1 -0
- package/dist/utils/cursorrules-parser.js +315 -0
- package/dist/utils/cursorrules-parser.js.map +1 -0
- package/dist/utils/memory-parser.d.ts +95 -0
- package/dist/utils/memory-parser.d.ts.map +1 -0
- package/dist/utils/memory-parser.js +408 -0
- package/dist/utils/memory-parser.js.map +1 -0
- package/package.json +1 -1
- 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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"}
|
package/dist/taf/index.d.ts
CHANGED
|
@@ -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
|
package/dist/taf/index.d.ts.map
CHANGED
|
@@ -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
|
package/dist/taf/index.js.map
CHANGED
|
@@ -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
|