brew-tui 0.1.0 → 0.2.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 +2 -0
- package/build/{brewbar-installer-CPCOE3MI.js → brewbar-installer-4Z2WE57I.js} +27 -5
- package/build/{chunk-P6PTN4HR.js → chunk-KXDTKY3E.js} +85 -47
- package/build/chunk-UBHTQL7T.js +76 -0
- package/build/{history-logger-LQT622M2.js → history-logger-65UF2R6F.js} +4 -3
- package/build/index.js +207 -115
- package/package.json +2 -2
- package/build/brewbar-installer-CPCOE3MI.js.map +0 -1
- package/build/chunk-3BK3B53S.js +0 -55
- package/build/chunk-3BK3B53S.js.map +0 -1
- package/build/chunk-P6PTN4HR.js.map +0 -1
- package/build/history-logger-LQT622M2.js.map +0 -1
- package/build/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/brewbar-installer.ts"],"sourcesContent":["import { rm, access } from 'node:fs/promises';\nimport { createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { t } from '../i18n/index.js';\nimport { verifyPro } from './license/pro-guard.js';\n\nconst execFileAsync = promisify(execFile);\nconst BREWBAR_APP_PATH = '/Applications/BrewBar.app';\nconst DOWNLOAD_URL = 'https://github.com/MoLinesGitHub/Brew-TUI/releases/latest/download/BrewBar.app.zip';\nconst TMP_ZIP = '/tmp/BrewBar.app.zip';\n\nexport async function isBrewBarInstalled(): Promise<boolean> {\n try {\n await access(BREWBAR_APP_PATH);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function installBrewBar(force = false): Promise<void> {\n // macOS only\n if (process.platform !== 'darwin') {\n throw new Error(t('cli_brewbarMacOnly'));\n }\n\n // Pro check\n if (!verifyPro()) {\n throw new Error(t('cli_brewbarProRequired'));\n }\n\n // Already installed check\n if (!force && await isBrewBarInstalled()) {\n throw new Error(t('cli_brewbarAlreadyInstalled'));\n }\n\n console.log(t('cli_brewbarInstalling'));\n\n // Download zip\n const res = await fetch(DOWNLOAD_URL);\n if (!res.ok || !res.body) {\n throw new Error(t('cli_brewbarDownloadFailed', { error: `HTTP ${res.status}` }));\n }\n\n // Write to tmp file\n const fileStream = createWriteStream(TMP_ZIP);\n await pipeline(res.body as any, fileStream);\n\n // Remove old app if force reinstall\n if (force && await isBrewBarInstalled()) {\n await rm(BREWBAR_APP_PATH, { recursive: true, force: true });\n }\n\n // Unzip to /Applications\n try {\n await execFileAsync('ditto', ['-xk', TMP_ZIP, '/Applications/']);\n } catch (err) {\n throw new Error(t('cli_brewbarDownloadFailed', { error: err instanceof Error ? err.message : String(err) }));\n } finally {\n // Clean up tmp zip\n await rm(TMP_ZIP, { force: true }).catch(() => {});\n }\n}\n\nexport async function uninstallBrewBar(): Promise<void> {\n if (!await isBrewBarInstalled()) {\n throw new Error(t('cli_brewbarNotInstalled'));\n }\n\n await rm(BREWBAR_APP_PATH, { recursive: true, force: true });\n}\n"],"mappings":";;;;;;AAAA,SAAS,IAAI,cAAc;AAC3B,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAI1B,IAAM,gBAAgB,UAAU,QAAQ;AACxC,IAAM,mBAAmB;AACzB,IAAM,eAAe;AACrB,IAAM,UAAU;AAEhB,eAAsB,qBAAuC;AAC3D,MAAI;AACF,UAAM,OAAO,gBAAgB;AAC7B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,eAAe,QAAQ,OAAsB;AAEjE,MAAI,QAAQ,aAAa,UAAU;AACjC,UAAM,IAAI,MAAM,EAAE,oBAAoB,CAAC;AAAA,EACzC;AAGA,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,IAAI,MAAM,EAAE,wBAAwB,CAAC;AAAA,EAC7C;AAGA,MAAI,CAAC,SAAS,MAAM,mBAAmB,GAAG;AACxC,UAAM,IAAI,MAAM,EAAE,6BAA6B,CAAC;AAAA,EAClD;AAEA,UAAQ,IAAI,EAAE,uBAAuB,CAAC;AAGtC,QAAM,MAAM,MAAM,MAAM,YAAY;AACpC,MAAI,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM;AACxB,UAAM,IAAI,MAAM,EAAE,6BAA6B,EAAE,OAAO,QAAQ,IAAI,MAAM,GAAG,CAAC,CAAC;AAAA,EACjF;AAGA,QAAM,aAAa,kBAAkB,OAAO;AAC5C,QAAM,SAAS,IAAI,MAAa,UAAU;AAG1C,MAAI,SAAS,MAAM,mBAAmB,GAAG;AACvC,UAAM,GAAG,kBAAkB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC7D;AAGA,MAAI;AACF,UAAM,cAAc,SAAS,CAAC,OAAO,SAAS,gBAAgB,CAAC;AAAA,EACjE,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,EAAE,6BAA6B,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC,CAAC;AAAA,EAC7G,UAAE;AAEA,UAAM,GAAG,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnD;AACF;AAEA,eAAsB,mBAAkC;AACtD,MAAI,CAAC,MAAM,mBAAmB,GAAG;AAC/B,UAAM,IAAI,MAAM,EAAE,yBAAyB,CAAC;AAAA,EAC9C;AAEA,QAAM,GAAG,kBAAkB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7D;","names":[]}
|
package/build/chunk-3BK3B53S.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HISTORY_PATH,
|
|
3
|
-
ensureDataDirs,
|
|
4
|
-
requirePro
|
|
5
|
-
} from "./chunk-P6PTN4HR.js";
|
|
6
|
-
|
|
7
|
-
// src/lib/history/history-logger.ts
|
|
8
|
-
import { readFile, writeFile, rename } from "fs/promises";
|
|
9
|
-
var MAX_ENTRIES = 1e3;
|
|
10
|
-
async function loadHistory() {
|
|
11
|
-
requirePro();
|
|
12
|
-
try {
|
|
13
|
-
const raw = await readFile(HISTORY_PATH, "utf-8");
|
|
14
|
-
const file = JSON.parse(raw);
|
|
15
|
-
const entries = file.entries;
|
|
16
|
-
return Array.isArray(entries) ? entries : [];
|
|
17
|
-
} catch {
|
|
18
|
-
return [];
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
async function saveHistory(entries) {
|
|
22
|
-
await ensureDataDirs();
|
|
23
|
-
const file = { version: 1, entries };
|
|
24
|
-
const tmp = HISTORY_PATH + ".tmp";
|
|
25
|
-
await writeFile(tmp, JSON.stringify(file, null, 2), "utf-8");
|
|
26
|
-
await rename(tmp, HISTORY_PATH);
|
|
27
|
-
}
|
|
28
|
-
async function appendEntry(action, packageName, success, error = null) {
|
|
29
|
-
requirePro();
|
|
30
|
-
const entries = await loadHistory();
|
|
31
|
-
const entry = {
|
|
32
|
-
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
33
|
-
action,
|
|
34
|
-
packageName,
|
|
35
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36
|
-
success,
|
|
37
|
-
error
|
|
38
|
-
};
|
|
39
|
-
entries.unshift(entry);
|
|
40
|
-
if (entries.length > MAX_ENTRIES) {
|
|
41
|
-
entries.length = MAX_ENTRIES;
|
|
42
|
-
}
|
|
43
|
-
await saveHistory(entries);
|
|
44
|
-
}
|
|
45
|
-
async function clearHistory() {
|
|
46
|
-
requirePro();
|
|
47
|
-
await saveHistory([]);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
loadHistory,
|
|
52
|
-
appendEntry,
|
|
53
|
-
clearHistory
|
|
54
|
-
};
|
|
55
|
-
//# sourceMappingURL=chunk-3BK3B53S.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/history/history-logger.ts"],"sourcesContent":["import { readFile, writeFile, rename } from 'node:fs/promises';\nimport { HISTORY_PATH, ensureDataDirs } from '../data-dir.js';\nimport { requirePro } from '../license/pro-guard.js';\nimport type { HistoryEntry, HistoryFile, HistoryAction } from './types.js';\n\nconst MAX_ENTRIES = 1000;\n\nexport async function loadHistory(): Promise<HistoryEntry[]> {\n requirePro();\n\n try {\n const raw = await readFile(HISTORY_PATH, 'utf-8');\n const file = JSON.parse(raw) as HistoryFile;\n const entries = file.entries;\n return Array.isArray(entries) ? entries : [];\n } catch {\n return [];\n }\n}\n\nasync function saveHistory(entries: HistoryEntry[]): Promise<void> {\n await ensureDataDirs();\n const file: HistoryFile = { version: 1, entries };\n const tmp = HISTORY_PATH + '.tmp';\n await writeFile(tmp, JSON.stringify(file, null, 2), 'utf-8');\n await rename(tmp, HISTORY_PATH);\n}\n\nexport async function appendEntry(\n action: HistoryAction,\n packageName: string | null,\n success: boolean,\n error: string | null = null,\n): Promise<void> {\n requirePro();\n const entries = await loadHistory();\n\n const entry: HistoryEntry = {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n action,\n packageName,\n timestamp: new Date().toISOString(),\n success,\n error,\n };\n\n entries.unshift(entry);\n\n if (entries.length > MAX_ENTRIES) {\n entries.length = MAX_ENTRIES;\n }\n\n await saveHistory(entries);\n}\n\nexport async function clearHistory(): Promise<void> {\n requirePro();\n await saveHistory([]);\n}\n"],"mappings":";;;;;;;AAAA,SAAS,UAAU,WAAW,cAAc;AAK5C,IAAM,cAAc;AAEpB,eAAsB,cAAuC;AAC3D,aAAW;AAEX,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,cAAc,OAAO;AAChD,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,UAAM,UAAU,KAAK;AACrB,WAAO,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC;AAAA,EAC7C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAe,YAAY,SAAwC;AACjE,QAAM,eAAe;AACrB,QAAM,OAAoB,EAAE,SAAS,GAAG,QAAQ;AAChD,QAAM,MAAM,eAAe;AAC3B,QAAM,UAAU,KAAK,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO;AAC3D,QAAM,OAAO,KAAK,YAAY;AAChC;AAEA,eAAsB,YACpB,QACA,aACA,SACA,QAAuB,MACR;AACf,aAAW;AACX,QAAM,UAAU,MAAM,YAAY;AAElC,QAAM,QAAsB;AAAA,IAC1B,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,IAC3D;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAAA,IACA;AAAA,EACF;AAEA,UAAQ,QAAQ,KAAK;AAErB,MAAI,QAAQ,SAAS,aAAa;AAChC,YAAQ,SAAS;AAAA,EACnB;AAEA,QAAM,YAAY,OAAO;AAC3B;AAEA,eAAsB,eAA8B;AAClD,aAAW;AACX,QAAM,YAAY,CAAC,CAAC;AACtB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n/index.ts","../src/i18n/en.ts","../src/i18n/es.ts","../src/lib/data-dir.ts","../src/lib/license/license-manager.ts","../src/lib/license/polar-api.ts","../src/stores/license-store.ts","../src/lib/license/anti-debug.ts","../src/lib/license/anti-tamper.ts","../src/lib/license/canary.ts","../src/lib/license/integrity.ts","../src/lib/license/pro-guard.ts"],"sourcesContent":["import { create } from 'zustand';\nimport en from './en.js';\nimport es from './es.js';\nimport type { Translations, TranslationKey } from './en.js';\n\nexport type Locale = 'en' | 'es';\n\nconst locales: Record<Locale, Translations> = { en, es };\n\nfunction isLocale(s: string): s is Locale {\n return s === 'en' || s === 'es';\n}\n\nfunction detectLocale(): Locale {\n const flag = process.argv.find((a) => a.startsWith('--lang='));\n if (flag) {\n const code = flag.split('=')[1];\n if (code && isLocale(code)) return code;\n }\n const env = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_MESSAGES ?? '';\n const prefix = env.split(/[_.]/)[0] ?? '';\n if (isLocale(prefix)) return prefix;\n return 'en';\n}\n\n// ── Locale store ──\ninterface LocaleState {\n locale: Locale;\n setLocale: (locale: Locale) => void;\n}\n\nexport const useLocaleStore = create<LocaleState>((set) => ({\n locale: detectLocale(),\n setLocale: (locale) => set({ locale }),\n}));\n\n// ── Translation function ──\nexport function t(key: TranslationKey, values?: Record<string, string | number>): string {\n const locale = useLocaleStore.getState().locale;\n let text: string = locales[locale][key] ?? locales['en'][key] ?? key;\n if (values) {\n for (const [k, v] of Object.entries(values)) {\n text = text.replaceAll(`{{${k}}}`, String(v));\n }\n }\n return text;\n}\n\n// ── Plural helper ──\nexport function tp(baseKey: string, count: number, values?: Record<string, string | number>): string {\n const suffix = count === 1 ? '_one' : '_other';\n return t(`${baseKey}${suffix}` as TranslationKey, { count, ...values });\n}\n\nexport type { TranslationKey, Translations };\n","const en = {\n // ── App chrome ──\n app_title: 'Brew-TUI',\n pro_badge: 'PRO',\n app_version: 'Brew-TUI v{{version}}',\n\n // ── View labels (header tab bar) ──\n view_dashboard: 'Dashboard',\n view_installed: 'Installed',\n view_search: 'Search',\n view_outdated: 'Outdated',\n view_packageInfo: 'Pkg Info',\n view_services: 'Services',\n view_doctor: 'Doctor',\n view_profiles: 'Profiles',\n view_smartCleanup: 'Cleanup',\n view_history: 'History',\n view_securityAudit: 'Security',\n view_account: 'Account',\n\n // ── Keyboard hint actions ──\n hint_navigate: 'navigate',\n hint_next: 'next',\n hint_quit: 'quit',\n hint_filter: 'filter',\n hint_info: 'info',\n hint_toggle: 'toggle',\n hint_typeToSearch: 'type to search',\n hint_install: 'install',\n hint_uninstall: 'uninstall',\n hint_upgrade: 'upgrade',\n hint_upgradeAll: 'upgrade all',\n hint_back: 'back',\n hint_start: 'start',\n hint_stop: 'stop',\n hint_restart: 'restart',\n hint_refresh: 'refresh',\n hint_new: 'new',\n hint_details: 'details',\n hint_import: 'import',\n hint_delete: 'delete',\n hint_clean: 'clean',\n hint_all: 'all',\n hint_search: 'search',\n hint_clear: 'clear',\n hint_scan: 'scan',\n hint_expand: 'expand',\n hint_cancel: 'cancel',\n hint_force: 'force uninstall (ignore deps)',\n hint_rescan: 'rescan',\n hint_deactivate: 'deactivate',\n hint_importProfile: 'import this profile',\n hint_lang: 'lang',\n hint_replay: 'replay',\n hint_edit: 'edit',\n hint_pin: 'pin/unpin',\n\n // ── Loading / progress ──\n loading_default: 'Loading...',\n loading_fetchingBrew: 'Fetching Homebrew data...',\n loading_installed: 'Loading installed packages...',\n loading_outdated: 'Checking for outdated packages...',\n loading_services: 'Loading services...',\n loading_doctor: 'Running brew doctor... (this may take a moment)',\n loading_profiles: 'Loading profiles...',\n loading_cleanup: 'Analyzing packages... (checking disk usage)',\n loading_history: 'Loading history...',\n loading_security: 'Scanning packages against OSV vulnerability database...',\n loading_searching: 'Searching...',\n loading_package: 'Loading {{name}}...',\n\n // ── Confirm dialog ──\n confirm_yes: '[Y]es',\n confirm_no: '[N]o',\n\n // ── Error ──\n error_prefix: 'Error: ',\n\n // ── Common ──\n common_andMore: '...and {{count}} more',\n common_exit: '(exit {{code}})',\n common_yes: 'yes',\n common_no: 'no',\n\n // ── Relative time ──\n time_justNow: 'just now',\n time_minutesAgo: '{{n}}m ago',\n time_hoursAgo: '{{n}}h ago',\n time_daysAgo: '{{n}}d ago',\n time_monthsAgo: '{{n}}mo ago',\n\n // ── Badges ──\n badge_outdated: 'outdated',\n badge_pinned: 'pinned',\n badge_kegOnly: 'keg-only',\n badge_dep: 'dep',\n badge_installed: 'installed',\n badge_deprecated: 'deprecated',\n badge_ok: 'ok',\n badge_fail: 'fail',\n badge_error: 'error',\n\n // ── Dashboard ──\n dashboard_overview: 'Overview',\n dashboard_formulae: 'Formulae',\n dashboard_casks: 'Casks',\n dashboard_outdated: 'Outdated',\n dashboard_services: 'Services',\n dashboard_systemInfo: 'System Info',\n dashboard_homebrew: 'Homebrew:',\n dashboard_prefix: 'Prefix:',\n dashboard_updated: 'Updated:',\n dashboard_outdatedPackages: 'Outdated Packages',\n dashboard_serviceErrors: 'Service Errors',\n\n // ── Installed ──\n installed_formulaeCount: 'Formulae ({{count}})',\n installed_casksCount: 'Casks ({{count}})',\n installed_filterDisplay: 'Filter: \"{{query}}\" ({{count}} matches)',\n installed_noPackages: 'No packages found',\n installed_confirmUninstall: 'Uninstall {{name}}?',\n\n // ── Search ──\n search_placeholder: 'Search Homebrew packages... (enter to search)',\n search_resultsFor: 'Results for',\n search_escToClear: '(esc to clear)',\n search_installing: 'Installing package...',\n search_installComplete: 'Installation complete!',\n search_confirmInstall: 'Install {{name}}?',\n search_formulaeHeader: '=== Formulae ({{count}})',\n search_casksHeader: '=== Casks ({{count}})',\n search_noResults: 'No results found',\n\n // ── Outdated ──\n outdated_title: 'Outdated Packages ({{count}})',\n outdated_upgrading: 'Upgrading...',\n outdated_upgradeComplete: 'Upgrade complete!',\n outdated_pressRefresh: '(press r to refresh)',\n outdated_upToDate: 'Everything is up to date!',\n outdated_confirmAll: 'Upgrade all {{count}} packages?',\n outdated_confirmSingle: 'Upgrade {{name}}?',\n outdated_pinned: '[pinned]',\n\n // ── Package Info ──\n pkgInfo_noPackage: 'No package selected. Go to Installed and press Enter on a package.',\n pkgInfo_notFound: 'Package not found',\n pkgInfo_installing: 'Installing {{name}}...',\n pkgInfo_uninstalling: 'Uninstalling {{name}}...',\n pkgInfo_upgrading: 'Upgrading {{name}}...',\n pkgInfo_done: 'Done!',\n pkgInfo_confirmInstall: 'install {{name}}?',\n pkgInfo_confirmUninstall: 'uninstall {{name}}?',\n pkgInfo_confirmUpgrade: 'upgrade {{name}}?',\n pkgInfo_details: 'Details',\n pkgInfo_homepage: 'Homepage:',\n pkgInfo_license: 'License:',\n pkgInfo_tap: 'Tap:',\n pkgInfo_stable: 'Stable:',\n pkgInfo_installed: 'Installed:',\n pkgInfo_bottle: 'Bottle:',\n pkgInfo_onRequest: 'On request:',\n pkgInfo_noDependency: 'no (dependency)',\n pkgInfo_dependencies: 'Dependencies ({{count}})',\n pkgInfo_caveats: 'Caveats',\n\n // ── Services ──\n services_title: 'Homebrew Services',\n services_titleCount: 'Homebrew Services ({{count}})',\n services_noServices: 'No services found',\n services_name: 'Name',\n services_status: 'Status',\n services_user: 'User',\n services_processing: 'Processing...',\n services_confirmStop: 'Stop service {{name}}?',\n services_confirmRestart: 'Restart service {{name}}?',\n\n // ── Doctor ──\n doctor_title: 'Homebrew Doctor',\n doctor_clean: 'Your system is ready to brew.',\n doctor_warningsNotCaptured: 'Doctor finished with warnings but none were captured.',\n\n // ── Profiles ──\n profiles_title: 'Package Profiles ({{count}})',\n profiles_importTitle: 'Importing profile...',\n profiles_importComplete: 'Import complete. Press any key.',\n profiles_createName: 'Create Profile \\u2014 Name:',\n profiles_namePlaceholder: 'e.g. work, personal, project-x',\n profiles_createDesc: 'Create Profile \"{{name}}\" \\u2014 Description:',\n profiles_descPlaceholder: 'Brief description of this setup',\n profiles_created: 'Created: {{date}}',\n profiles_formulaeCount: 'Formulae ({{count}})',\n profiles_casksCount: 'Casks ({{count}})',\n profiles_confirmDelete: 'Delete profile \"{{name}}\"?',\n profiles_noProfiles: 'No profiles saved yet.',\n profiles_press: 'Press',\n profiles_exportHint: 'to export your current setup as a profile.',\n profiles_editName: 'Edit Profile \\u2014 Name:',\n profiles_editDesc: 'Edit Profile \"{{name}}\" \\u2014 Description:',\n\n // ── Smart Cleanup ──\n cleanup_title: 'Smart Cleanup',\n cleanup_cleaning: 'Cleaning up...',\n cleanup_complete: 'Cleanup complete! Press r to re-analyze.',\n cleanup_orphans: 'Orphans',\n cleanup_reclaimable: 'Reclaimable',\n cleanup_selected: 'Selected',\n cleanup_confirmUninstall: 'Uninstall {{count}} packages?',\n cleanup_confirmForce: 'Some packages have dependencies. Force uninstall {{count}} packages? (ignores dependencies)',\n cleanup_depError: 'Some packages could not be removed due to dependencies.',\n cleanup_systemClean: 'No orphaned packages found. Your system is clean!',\n\n // ── History ──\n history_title: 'Action History ({{count}})',\n history_filterLabel: 'filter: {{filter}}',\n history_searchPlaceholder: 'Search packages...',\n history_confirmClear: 'Clear all {{count}} history entries?',\n history_noEntries: 'No history entries',\n history_noEntriesFor: 'No history entries for \"{{filter}}\"',\n history_all: '(all)',\n history_actionInstall: 'install',\n history_actionUninstall: 'uninstall',\n history_actionUpgrade: 'upgrade',\n history_actionUpgradeAll: 'upgrade-all',\n history_confirmReplay: 'Re-run: {{action}} {{name}}?',\n history_replayAll: 'Re-run: upgrade all packages?',\n\n // ── Security Audit ──\n security_title: 'Security Audit',\n security_scanned: 'Scanned',\n security_vulnerable: 'Vulnerable',\n security_critical: 'Critical',\n security_high: 'High',\n security_medium: 'Medium',\n security_noVulns: 'No known vulnerabilities found in your installed packages!',\n security_fixedIn: 'Fixed in: {{version}}',\n security_confirmUpgrade: 'Upgrade {{name}} to fix vulnerabilities?',\n\n // ── Account ──\n account_title: 'Account & License',\n account_confirmDeactivate: 'Deactivate your Pro license on this machine?',\n account_statusLabel: 'Status:',\n account_pro: '[Pro]',\n account_free: '[Free]',\n account_expired: '[Expired]',\n account_validating: '[Validating...]',\n account_emailLabel: 'Email:',\n account_nameLabel: 'Name:',\n account_planLabel: 'Plan:',\n account_monthlyPrice: '9\\u20AC/month',\n account_yearlyPrice: '49\\u20AC/year',\n account_keyLabel: 'Key:',\n account_expiresLabel: 'Expires:',\n account_activatedLabel: 'Activated:',\n account_upgradeTitle: 'Upgrade to Brew-TUI Pro',\n account_unlockDesc: 'Unlock Profiles, Smart Cleanup, History, Security Audit, and BrewBar (macOS menu bar companion).',\n account_pricing: '9\\u20AC/month or 49\\u20AC/year',\n account_runActivate: 'Run:',\n account_activateCmd: 'brew-tui activate <key>',\n account_licenseExpired: 'Your license has expired. Renew to continue using Pro features.',\n account_deactivating: 'Deactivating...',\n\n // ── Upgrade Prompt ──\n upgrade_proFeature: '{{title}} \\u2014 Pro Feature',\n upgrade_profiles: 'Package Profiles',\n upgrade_profilesDesc: 'Export and import your Homebrew setup across machines. Save named profiles for work, personal, or project-specific configurations.',\n upgrade_cleanup: 'Smart Cleanup',\n upgrade_cleanupDesc: 'Find orphaned packages, analyze disk usage per package, and reclaim disk space with one-click intelligent cleanup.',\n upgrade_history: 'Action History',\n upgrade_historyDesc: 'Track every install, uninstall, and upgrade with timestamps. Search and filter your package management history.',\n upgrade_security: 'Security Audit',\n upgrade_securityDesc: 'Scan installed packages against known vulnerabilities (CVEs). See severity levels, affected versions, and available fixes.',\n upgrade_pricing: '9\\u20AC/month or 49\\u20AC/year',\n upgrade_activateWith: 'Activate with:',\n upgrade_activateCmd: 'brew-tui activate <your-license-key>',\n upgrade_proLabel: 'Brew-TUI Pro \\u2014 9\\u20AC/month or 49\\u20AC/year \\u2014 Includes BrewBar for macOS',\n\n // ── Progress Log ──\n progress_noOutput: 'No output yet',\n\n // ── Search Input ──\n searchInput_placeholder: 'Type to filter...',\n\n // ── Profile Manager ──\n profileMgr_tapping: 'Tapping {{name}}...',\n profileMgr_installing: 'Installing {{name}}...',\n profileMgr_installingCask: 'Installing cask {{name}}...',\n profileMgr_importDone: 'Done! Installed {{count}} packages.',\n\n // ── CLI ──\n cli_usageActivate: 'Usage: brew-tui activate <license-key>',\n cli_activated: '\\u2714 Pro activated for {{email}}',\n cli_plan: ' Plan: {{plan}}',\n cli_expires: ' Expires: {{date}}',\n cli_activationFailed: '\\u2718 Activation failed: {{error}}',\n cli_noLicense: 'No active license found.',\n cli_deactivated: '\\u2714 License deactivated.',\n cli_planFree: 'Plan: Free',\n cli_planPro: 'Plan: Pro',\n cli_confirmDeactivate: 'Deactivate your Pro license on this machine? (y/N): ',\n cli_deactivateCancelled: 'Deactivation cancelled.',\n cli_upgradeHint: 'Run `brew-tui activate <key>` to upgrade to Pro.',\n cli_email: 'Email: {{email}}',\n cli_status: 'Status: {{status}}',\n cli_rateLimited: 'Too many activation attempts. Try again in {{minutes}} minutes.',\n cli_cooldown: 'Please wait before trying again.',\n cli_brewbarInstalling: 'Downloading BrewBar...',\n cli_brewbarInstalled: '\\u2714 BrewBar installed to /Applications/BrewBar.app',\n cli_brewbarAlreadyInstalled: 'BrewBar is already installed. Use --force to reinstall.',\n cli_brewbarUninstalled: '\\u2714 BrewBar removed from /Applications.',\n cli_brewbarNotInstalled: 'BrewBar is not installed.',\n cli_brewbarProRequired: '\\u2718 BrewBar requires a Pro license.\\n Run: brew-tui activate <key>',\n cli_brewbarMacOnly: '\\u2718 BrewBar is only available on macOS.',\n cli_brewbarDownloadFailed: '\\u2718 Failed to download BrewBar: {{error}}',\n\n // ── License degradation (Layer 15) ──\n license_offlineWarning: 'Your license has not been validated for {{days}} days. Please connect to the internet.',\n\n // ── Plurals ──\n plural_vulns_one: '({{count}} vuln)',\n plural_vulns_other: '({{count}} vulns)',\n plural_warnings_one: '{{count}} warning',\n plural_warnings_other: '{{count}} warnings',\n\n // ── Scroll indicators ──\n scroll_moreAbove: '\\u2191 {{count}} more',\n scroll_moreBelow: '\\u2193 {{count}} more',\n};\n\nexport default en;\nexport type Translations = { [K in keyof typeof en]: string };\nexport type TranslationKey = keyof typeof en;\n","import type { Translations } from './en.js';\n\nconst es: Translations = {\n // ── App chrome ──\n app_title: 'Brew-TUI',\n pro_badge: 'PRO',\n app_version: 'Brew-TUI v{{version}}',\n\n // ── View labels (header tab bar) ──\n view_dashboard: 'Inicio',\n view_installed: 'Instalados',\n view_search: 'Buscar',\n view_outdated: 'Desactual.',\n view_packageInfo: 'Info Paq.',\n view_services: 'Servicios',\n view_doctor: 'Doctor',\n view_profiles: 'Perfiles',\n view_smartCleanup: 'Limpieza',\n view_history: 'Historial',\n view_securityAudit: 'Seguridad',\n view_account: 'Cuenta',\n\n // ── Keyboard hint actions ──\n hint_navigate: 'navegar',\n hint_next: 'siguiente',\n hint_quit: 'salir',\n hint_filter: 'filtrar',\n hint_info: 'info',\n hint_toggle: 'cambiar',\n hint_typeToSearch: 'escriba para buscar',\n hint_install: 'instalar',\n hint_uninstall: 'desinstalar',\n hint_upgrade: 'actualizar',\n hint_upgradeAll: 'actualizar todo',\n hint_back: 'volver',\n hint_start: 'iniciar',\n hint_stop: 'detener',\n hint_restart: 'reiniciar',\n hint_refresh: 'refrescar',\n hint_new: 'nuevo',\n hint_details: 'detalles',\n hint_import: 'importar',\n hint_delete: 'eliminar',\n hint_clean: 'limpiar',\n hint_all: 'todo',\n hint_search: 'buscar',\n hint_clear: 'borrar',\n hint_scan: 'escanear',\n hint_expand: 'expandir',\n hint_cancel: 'cancelar',\n hint_force: 'forzar (ignorar deps)',\n hint_rescan: 're-escanear',\n hint_deactivate: 'desactivar',\n hint_importProfile: 'importar este perfil',\n hint_lang: 'idioma',\n hint_replay: 'repetir',\n hint_edit: 'editar',\n hint_pin: 'fijar/desfijar',\n\n // ── Loading / progress ──\n loading_default: 'Cargando...',\n loading_fetchingBrew: 'Obteniendo datos de Homebrew...',\n loading_installed: 'Cargando paquetes instalados...',\n loading_outdated: 'Buscando paquetes desactualizados...',\n loading_services: 'Cargando servicios...',\n loading_doctor: 'Ejecutando brew doctor... (puede tardar un momento)',\n loading_profiles: 'Cargando perfiles...',\n loading_cleanup: 'Analizando paquetes... (verificando uso de disco)',\n loading_history: 'Cargando historial...',\n loading_security: 'Escaneando paquetes en la base de datos de vulnerabilidades OSV...',\n loading_searching: 'Buscando...',\n loading_package: 'Cargando {{name}}...',\n\n // ── Confirm dialog ──\n confirm_yes: '[S]\\u00ED',\n confirm_no: '[N]o',\n\n // ── Error ──\n error_prefix: 'Error: ',\n\n // ── Common ──\n common_andMore: '...y {{count}} m\\u00E1s',\n common_exit: '(salida {{code}})',\n common_yes: 's\\u00ED',\n common_no: 'no',\n\n // ── Relative time ──\n time_justNow: 'ahora',\n time_minutesAgo: 'hace {{n}}m',\n time_hoursAgo: 'hace {{n}}h',\n time_daysAgo: 'hace {{n}}d',\n time_monthsAgo: 'hace {{n}}me',\n\n // ── Badges ──\n badge_outdated: 'desactualizado',\n badge_pinned: 'fijado',\n badge_kegOnly: 'keg-only',\n badge_dep: 'dep',\n badge_installed: 'instalado',\n badge_deprecated: 'obsoleto',\n badge_ok: 'ok',\n badge_fail: 'fallo',\n badge_error: 'error',\n\n // ── Dashboard ──\n dashboard_overview: 'Resumen',\n dashboard_formulae: 'Formulae',\n dashboard_casks: 'Casks',\n dashboard_outdated: 'Desactualizados',\n dashboard_services: 'Servicios',\n dashboard_systemInfo: 'Info del Sistema',\n dashboard_homebrew: 'Homebrew:',\n dashboard_prefix: 'Prefijo:',\n dashboard_updated: 'Actualizado:',\n dashboard_outdatedPackages: 'Paquetes Desactualizados',\n dashboard_serviceErrors: 'Errores de Servicios',\n\n // ── Installed ──\n installed_formulaeCount: 'Formulae ({{count}})',\n installed_casksCount: 'Casks ({{count}})',\n installed_filterDisplay: 'Filtro: \"{{query}}\" ({{count}} coincidencias)',\n installed_noPackages: 'No se encontraron paquetes',\n installed_confirmUninstall: '\\u00BFDesinstalar {{name}}?',\n\n // ── Search ──\n search_placeholder: 'Buscar paquetes Homebrew... (enter para buscar)',\n search_resultsFor: 'Resultados para',\n search_escToClear: '(esc para limpiar)',\n search_installing: 'Instalando paquete...',\n search_installComplete: '\\u00A1Instalaci\\u00F3n completa!',\n search_confirmInstall: '\\u00BFInstalar {{name}}?',\n search_formulaeHeader: '=== Formulae ({{count}})',\n search_casksHeader: '=== Casks ({{count}})',\n search_noResults: 'Sin resultados',\n\n // ── Outdated ──\n outdated_title: 'Paquetes Desactualizados ({{count}})',\n outdated_upgrading: 'Actualizando...',\n outdated_upgradeComplete: '\\u00A1Actualizaci\\u00F3n completa!',\n outdated_pressRefresh: '(presiona r para refrescar)',\n outdated_upToDate: '\\u00A1Todo est\\u00E1 al d\\u00EDa!',\n outdated_confirmAll: '\\u00BFActualizar los {{count}} paquetes?',\n outdated_confirmSingle: '\\u00BFActualizar {{name}}?',\n outdated_pinned: '[fijado]',\n\n // ── Package Info ──\n pkgInfo_noPackage: 'Ning\\u00FAn paquete seleccionado. Ve a Instalados y presiona Enter en un paquete.',\n pkgInfo_notFound: 'Paquete no encontrado',\n pkgInfo_installing: 'Instalando {{name}}...',\n pkgInfo_uninstalling: 'Desinstalando {{name}}...',\n pkgInfo_upgrading: 'Actualizando {{name}}...',\n pkgInfo_done: '\\u00A1Listo!',\n pkgInfo_confirmInstall: '\\u00BFinstalar {{name}}?',\n pkgInfo_confirmUninstall: '\\u00BFdesinstalar {{name}}?',\n pkgInfo_confirmUpgrade: '\\u00BFactualizar {{name}}?',\n pkgInfo_details: 'Detalles',\n pkgInfo_homepage: 'Web:',\n pkgInfo_license: 'Licencia:',\n pkgInfo_tap: 'Tap:',\n pkgInfo_stable: 'Estable:',\n pkgInfo_installed: 'Instalado:',\n pkgInfo_bottle: 'Bottle:',\n pkgInfo_onRequest: 'Por solicitud:',\n pkgInfo_noDependency: 'no (dependencia)',\n pkgInfo_dependencies: 'Dependencias ({{count}})',\n pkgInfo_caveats: 'Advertencias',\n\n // ── Services ──\n services_title: 'Servicios Homebrew',\n services_titleCount: 'Servicios Homebrew ({{count}})',\n services_noServices: 'No se encontraron servicios',\n services_name: 'Nombre',\n services_status: 'Estado',\n services_user: 'Usuario',\n services_processing: 'Procesando...',\n services_confirmStop: '\\u00BFDetener servicio {{name}}?',\n services_confirmRestart: '\\u00BFReiniciar servicio {{name}}?',\n\n // ── Doctor ──\n doctor_title: 'Homebrew Doctor',\n doctor_clean: 'Tu sistema est\\u00E1 listo para brew.',\n doctor_warningsNotCaptured: 'Doctor termin\\u00F3 con advertencias pero no se capturaron.',\n\n // ── Profiles ──\n profiles_title: 'Perfiles de Paquetes ({{count}})',\n profiles_importTitle: 'Importando perfil...',\n profiles_importComplete: 'Importaci\\u00F3n completa. Presiona cualquier tecla.',\n profiles_createName: 'Crear Perfil \\u2014 Nombre:',\n profiles_namePlaceholder: 'ej. trabajo, personal, proyecto-x',\n profiles_createDesc: 'Crear Perfil \"{{name}}\" \\u2014 Descripci\\u00F3n:',\n profiles_descPlaceholder: 'Breve descripci\\u00F3n de esta configuraci\\u00F3n',\n profiles_created: 'Creado: {{date}}',\n profiles_formulaeCount: 'Formulae ({{count}})',\n profiles_casksCount: 'Casks ({{count}})',\n profiles_confirmDelete: '\\u00BFEliminar perfil \"{{name}}\"?',\n profiles_noProfiles: 'A\\u00FAn no hay perfiles guardados.',\n profiles_press: 'Presiona',\n profiles_exportHint: 'para exportar tu configuraci\\u00F3n actual como perfil.',\n profiles_editName: 'Editar Perfil \\u2014 Nombre:',\n profiles_editDesc: 'Editar Perfil \"{{name}}\" \\u2014 Descripci\\u00F3n:',\n\n // ── Smart Cleanup ──\n cleanup_title: 'Limpieza Inteligente',\n cleanup_cleaning: 'Limpiando...',\n cleanup_complete: '\\u00A1Limpieza completa! Presiona r para re-analizar.',\n cleanup_orphans: 'Hu\\u00E9rfanos',\n cleanup_reclaimable: 'Recuperable',\n cleanup_selected: 'Seleccionados',\n cleanup_confirmUninstall: '\\u00BFDesinstalar {{count}} paquetes?',\n cleanup_confirmForce: 'Algunos paquetes tienen dependencias. \\u00BFForzar desinstalaci\\u00F3n de {{count}} paquetes? (ignora dependencias)',\n cleanup_depError: 'Algunos paquetes no pudieron eliminarse por dependencias.',\n cleanup_systemClean: '\\u00A1No se encontraron paquetes hu\\u00E9rfanos. Tu sistema est\\u00E1 limpio!',\n\n // ── History ──\n history_title: 'Historial de Acciones ({{count}})',\n history_filterLabel: 'filtro: {{filter}}',\n history_searchPlaceholder: 'Buscar paquetes...',\n history_confirmClear: '\\u00BFBorrar las {{count}} entradas del historial?',\n history_noEntries: 'Sin entradas en el historial',\n history_noEntriesFor: 'Sin entradas en el historial para \"{{filter}}\"',\n history_all: '(todos)',\n history_actionInstall: 'instalar',\n history_actionUninstall: 'desinstalar',\n history_actionUpgrade: 'actualizar',\n history_actionUpgradeAll: 'actualizar-todo',\n history_confirmReplay: '\\u00BFRe-ejecutar: {{action}} {{name}}?',\n history_replayAll: '\\u00BFRe-ejecutar: actualizar todos los paquetes?',\n\n // ── Security Audit ──\n security_title: 'Auditor\\u00EDa de Seguridad',\n security_scanned: 'Escaneados',\n security_vulnerable: 'Vulnerables',\n security_critical: 'Cr\\u00EDticos',\n security_high: 'Altos',\n security_medium: 'Medios',\n security_noVulns: '\\u00A1No se encontraron vulnerabilidades conocidas en tus paquetes instalados!',\n security_fixedIn: 'Corregido en: {{version}}',\n security_confirmUpgrade: '\\u00BFActualizar {{name}} para corregir vulnerabilidades?',\n\n // ── Account ──\n account_title: 'Cuenta y Licencia',\n account_confirmDeactivate: '\\u00BFDesactivar tu licencia Pro en esta m\\u00E1quina?',\n account_statusLabel: 'Estado:',\n account_pro: '[Pro]',\n account_free: '[Gratis]',\n account_expired: '[Expirada]',\n account_validating: '[Validando...]',\n account_emailLabel: 'Email:',\n account_nameLabel: 'Nombre:',\n account_planLabel: 'Plan:',\n account_monthlyPrice: '9\\u20AC/mes',\n account_yearlyPrice: '49\\u20AC/a\\u00F1o',\n account_keyLabel: 'Clave:',\n account_expiresLabel: 'Expira:',\n account_activatedLabel: 'Activado:',\n account_upgradeTitle: 'Actualiza a Brew-TUI Pro',\n account_unlockDesc: 'Desbloquea Perfiles, Limpieza Inteligente, Historial, Auditor\\u00EDa de Seguridad y BrewBar (barra de men\\u00FA macOS).',\n account_pricing: '9\\u20AC/mes o 49\\u20AC/a\\u00F1o',\n account_runActivate: 'Ejecuta:',\n account_activateCmd: 'brew-tui activate <clave>',\n account_licenseExpired: 'Tu licencia ha expirado. Renueva para seguir usando las funciones Pro.',\n account_deactivating: 'Desactivando...',\n\n // ── Upgrade Prompt ──\n upgrade_proFeature: '{{title}} \\u2014 Funci\\u00F3n Pro',\n upgrade_profiles: 'Perfiles de Paquetes',\n upgrade_profilesDesc: 'Exporta e importa tu configuraci\\u00F3n de Homebrew entre m\\u00E1quinas. Guarda perfiles con nombre para trabajo, personal o proyectos espec\\u00EDficos.',\n upgrade_cleanup: 'Limpieza Inteligente',\n upgrade_cleanupDesc: 'Encuentra paquetes hu\\u00E9rfanos, analiza uso de disco por paquete y recupera espacio con limpieza inteligente de un clic.',\n upgrade_history: 'Historial de Acciones',\n upgrade_historyDesc: 'Rastrea cada instalaci\\u00F3n, desinstalaci\\u00F3n y actualizaci\\u00F3n con marcas de tiempo. Busca y filtra tu historial de gesti\\u00F3n de paquetes.',\n upgrade_security: 'Auditor\\u00EDa de Seguridad',\n upgrade_securityDesc: 'Escanea paquetes instalados contra vulnerabilidades conocidas (CVEs). Ve niveles de severidad, versiones afectadas y correcciones disponibles.',\n upgrade_pricing: '9\\u20AC/mes o 49\\u20AC/a\\u00F1o',\n upgrade_activateWith: 'Activa con:',\n upgrade_activateCmd: 'brew-tui activate <tu-clave-de-licencia>',\n upgrade_proLabel: 'Brew-TUI Pro \\u2014 9\\u20AC/mes o 49\\u20AC/a\\u00F1o \\u2014 Incluye BrewBar para macOS',\n\n // ── Progress Log ──\n progress_noOutput: 'Sin salida a\\u00FAn',\n\n // ── Search Input ──\n searchInput_placeholder: 'Escriba para filtrar...',\n\n // ── Profile Manager ──\n profileMgr_tapping: 'A\\u00F1adiendo tap {{name}}...',\n profileMgr_installing: 'Instalando {{name}}...',\n profileMgr_installingCask: 'Instalando cask {{name}}...',\n profileMgr_importDone: '\\u00A1Listo! {{count}} paquetes instalados.',\n\n // ── CLI ──\n cli_usageActivate: 'Uso: brew-tui activate <clave-de-licencia>',\n cli_activated: '\\u2714 Pro activado para {{email}}',\n cli_plan: ' Plan: {{plan}}',\n cli_expires: ' Expira: {{date}}',\n cli_activationFailed: '\\u2718 Activaci\\u00F3n fallida: {{error}}',\n cli_noLicense: 'No se encontr\\u00F3 licencia activa.',\n cli_deactivated: '\\u2714 Licencia desactivada.',\n cli_planFree: 'Plan: Gratis',\n cli_planPro: 'Plan: Pro',\n cli_confirmDeactivate: '\\u00BFDesactivar tu licencia Pro en esta m\\u00E1quina? (s/N): ',\n cli_deactivateCancelled: 'Desactivaci\\u00F3n cancelada.',\n cli_upgradeHint: 'Ejecuta `brew-tui activate <clave>` para actualizar a Pro.',\n cli_email: 'Email: {{email}}',\n cli_status: 'Estado: {{status}}',\n cli_rateLimited: 'Demasiados intentos de activaci\\u00F3n. Int\\u00E9ntalo en {{minutes}} minutos.',\n cli_cooldown: 'Por favor espera antes de intentar de nuevo.',\n cli_brewbarInstalling: 'Descargando BrewBar...',\n cli_brewbarInstalled: '\\u2714 BrewBar instalado en /Applications/BrewBar.app',\n cli_brewbarAlreadyInstalled: 'BrewBar ya est\\u00E1 instalado. Usa --force para reinstalar.',\n cli_brewbarUninstalled: '\\u2714 BrewBar eliminado de /Applications.',\n cli_brewbarNotInstalled: 'BrewBar no est\\u00E1 instalado.',\n cli_brewbarProRequired: '\\u2718 BrewBar requiere una licencia Pro.\\n Ejecuta: brew-tui activate <clave>',\n cli_brewbarMacOnly: '\\u2718 BrewBar solo est\\u00E1 disponible en macOS.',\n cli_brewbarDownloadFailed: '\\u2718 Error al descargar BrewBar: {{error}}',\n\n // ── License degradation (Layer 15) ──\n license_offlineWarning: 'Tu licencia no se ha validado en {{days}} d\\u00EDas. Por favor con\\u00E9ctate a internet.',\n\n // ── Plurals ──\n plural_vulns_one: '({{count}} vuln)',\n plural_vulns_other: '({{count}} vulns)',\n plural_warnings_one: '{{count}} advertencia',\n plural_warnings_other: '{{count}} advertencias',\n\n // ── Scroll indicators ──\n scroll_moreAbove: '\\u2191 {{count}} m\\u00E1s',\n scroll_moreBelow: '\\u2193 {{count}} m\\u00E1s',\n};\n\nexport default es;\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\n\nexport const DATA_DIR = join(homedir(), '.brew-tui');\nexport const PROFILES_DIR = join(DATA_DIR, 'profiles');\nexport const LICENSE_PATH = join(DATA_DIR, 'license.json');\nexport const HISTORY_PATH = join(DATA_DIR, 'history.json');\n\nexport async function ensureDataDirs(): Promise<void> {\n await mkdir(DATA_DIR, { recursive: true });\n await mkdir(PROFILES_DIR, { recursive: true });\n}\n","import { readFile, writeFile, rm } from 'node:fs/promises';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'node:crypto';\nimport { LICENSE_PATH, ensureDataDirs } from '../data-dir.js';\nimport { activateLicense as apiActivate, validateLicense as apiValidate, deactivateLicense as apiDeactivate } from './polar-api.js';\nimport { t } from '../../i18n/index.js';\nimport type { LicenseData, LicenseFile } from './types.js';\n\nconst REVALIDATION_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24h\nconst GRACE_PERIOD_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\n// ── Layer 18: Client-side rate limiting on activations ──\nconst ACTIVATION_COOLDOWN_MS = 30_000; // 30 seconds between attempts\nconst MAX_ATTEMPTS = 5;\nconst LOCKOUT_MS = 15 * 60 * 1000; // 15 min lockout after max attempts\n\ninterface ActivationTracker {\n attempts: number;\n lastAttempt: number;\n lockedUntil: number;\n}\n\nconst tracker: ActivationTracker = {\n attempts: 0,\n lastAttempt: 0,\n lockedUntil: 0,\n};\n\nfunction checkRateLimit(): void {\n const now = Date.now();\n\n // Check lockout\n if (now < tracker.lockedUntil) {\n const remaining = Math.ceil((tracker.lockedUntil - now) / 60000);\n throw new Error(t('cli_rateLimited', { minutes: remaining }));\n }\n\n // Check cooldown\n if (now - tracker.lastAttempt < ACTIVATION_COOLDOWN_MS) {\n throw new Error(t('cli_cooldown'));\n }\n}\n\nfunction recordAttempt(success: boolean): void {\n const now = Date.now();\n tracker.lastAttempt = now;\n\n if (success) {\n tracker.attempts = 0;\n return;\n }\n\n tracker.attempts++;\n if (tracker.attempts >= MAX_ATTEMPTS) {\n tracker.lockedUntil = now + LOCKOUT_MS;\n tracker.attempts = 0;\n }\n}\n\n// AES-256-GCM encryption secret — derived key via scrypt\nconst ENCRYPTION_SECRET = 'brew-tui-license-aes256gcm-v1';\nconst SCRYPT_SALT = 'brew-tui-salt-v1';\n\n// Derived once at module load — inputs are constants so repeated derivation\n// just blocks the event loop unnecessarily (scryptSync default N=16384).\nconst _derivedKey: Buffer = scryptSync(ENCRYPTION_SECRET, SCRYPT_SALT, 32);\n\nfunction deriveEncryptionKey(): Buffer {\n return _derivedKey;\n}\n\nfunction encryptLicenseData(data: LicenseData): { encrypted: string; iv: string; tag: string } {\n const key = deriveEncryptionKey();\n const iv = randomBytes(12); // 96-bit IV for GCM\n const cipher = createCipheriv('aes-256-gcm', key, iv);\n\n const plaintext = JSON.stringify(data);\n const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf-8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n\n return {\n encrypted: ciphertext.toString('base64'),\n iv: iv.toString('base64'),\n tag: tag.toString('base64'),\n };\n}\n\nfunction decryptLicenseData(encrypted: string, iv: string, tag: string): LicenseData {\n const key = deriveEncryptionKey();\n const decipher = createDecipheriv(\n 'aes-256-gcm',\n key,\n Buffer.from(iv, 'base64'),\n );\n decipher.setAuthTag(Buffer.from(tag, 'base64'));\n\n const plaintext = Buffer.concat([\n decipher.update(Buffer.from(encrypted, 'base64')),\n decipher.final(),\n ]);\n\n return JSON.parse(plaintext.toString('utf-8')) as LicenseData;\n}\n\nexport async function loadLicense(): Promise<LicenseData | null> {\n try {\n const raw = await readFile(LICENSE_PATH, 'utf-8');\n const file = JSON.parse(raw) as LicenseFile;\n\n // New encrypted format\n if (file.encrypted && file.iv && file.tag) {\n const data = decryptLicenseData(file.encrypted, file.iv, file.tag);\n return data;\n }\n\n // Legacy unencrypted format — migrate to encrypted on read\n if (file.license) {\n const data = file.license;\n // Re-save in encrypted format\n await saveLicense(data);\n return data;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function saveLicense(data: LicenseData): Promise<void> {\n await ensureDataDirs();\n const { encrypted, iv, tag } = encryptLicenseData(data);\n const file: LicenseFile = { version: 1, encrypted, iv, tag };\n await writeFile(LICENSE_PATH, JSON.stringify(file, null, 2), { encoding: 'utf-8', mode: 0o600 });\n}\n\nexport async function clearLicense(): Promise<void> {\n try {\n await rm(LICENSE_PATH);\n } catch { /* file may not exist */ }\n}\n\nexport function isExpired(license: LicenseData): boolean {\n if (!license.expiresAt) return false;\n return new Date(license.expiresAt).getTime() < Date.now();\n}\n\nexport function needsRevalidation(license: LicenseData): boolean {\n const lastValidated = new Date(license.lastValidatedAt).getTime();\n if (isNaN(lastValidated)) return true; // corrupted date → force revalidation\n return Date.now() - lastValidated > REVALIDATION_INTERVAL_MS;\n}\n\nexport function isWithinGracePeriod(license: LicenseData): boolean {\n const lastValidated = new Date(license.lastValidatedAt).getTime();\n if (isNaN(lastValidated)) return false; // corrupted date → no grace\n return Date.now() - lastValidated < GRACE_PERIOD_MS;\n}\n\n// ── Layer 15: Gradual degradation after extended offline ──\n\nexport type DegradationLevel = 'none' | 'warning' | 'limited' | 'expired';\n\n/**\n * Returns the degradation level based on time since last server validation.\n * - 0-7 days: none (full access)\n * - 7-14 days: warning (shows a notice but still works)\n * - 14-30 days: limited (some features disabled)\n * - 30+ days: expired (all Pro features disabled)\n */\nexport function getDegradationLevel(license: LicenseData): DegradationLevel {\n const lastValidated = new Date(license.lastValidatedAt).getTime();\n if (isNaN(lastValidated)) return 'expired'; // corrupted date → deny access\n const elapsed = Date.now() - lastValidated;\n if (elapsed < 0) return 'none'; // clock skew: future timestamp → treat as fresh\n const days = elapsed / (24 * 60 * 60 * 1000);\n\n if (days <= 7) return 'none';\n if (days <= 14) return 'warning';\n if (days <= 30) return 'limited';\n return 'expired';\n}\n\n// Layer 10: License key format validation\nfunction validateLicenseKey(key: string): void {\n // LemonSqueezy keys are UUID-like: 8-4-4-4-12 hex chars or similar\n // Reject obviously invalid keys to avoid unnecessary API calls\n if (key.length < 10 || key.length > 100) {\n throw new Error('Invalid license key format');\n }\n // Only allow alphanumeric, hyphens, underscores\n if (!/^[\\w-]+$/.test(key)) {\n throw new Error('Invalid license key format');\n }\n}\n\nexport async function activate(key: string): Promise<LicenseData> {\n validateLicenseKey(key);\n checkRateLimit();\n\n let success = false;\n try {\n const res = await apiActivate(key);\n\n if (!res.activated) {\n throw new Error(res.error ?? 'Activation failed');\n }\n\n const license: LicenseData = {\n key,\n instanceId: res.instance.id,\n status: 'active',\n customerEmail: res.meta.customer_email,\n customerName: res.meta.customer_name,\n plan: 'pro',\n activatedAt: new Date().toISOString(),\n expiresAt: res.license_key.expires_at,\n lastValidatedAt: new Date().toISOString(),\n };\n\n await saveLicense(license);\n success = true;\n return license;\n } finally {\n recordAttempt(success);\n }\n}\n\n/**\n * Revalidate the license against the server.\n * This also serves as Layer 19 (telemetry): each validation call\n * allows LemonSqueezy to track activation count, last-seen timestamp,\n * and detect if the activation limit is exceeded (license sharing).\n */\nexport async function revalidate(license: LicenseData): Promise<boolean> {\n try {\n const res = await apiValidate(license.key, license.instanceId);\n\n if (res.valid) {\n const updated: LicenseData = {\n ...license,\n lastValidatedAt: new Date().toISOString(),\n status: 'active',\n expiresAt: res.license_key.expires_at,\n };\n await saveLicense(updated);\n return true;\n }\n\n await saveLicense({ ...license, status: 'expired' });\n return false;\n } catch {\n // Network error: check grace period\n return isWithinGracePeriod(license);\n }\n}\n\nexport async function deactivate(license: LicenseData): Promise<void> {\n try {\n await apiDeactivate(license.key, license.instanceId);\n } catch { /* best effort */ }\n await clearLicense();\n}\n","import { hostname } from 'node:os';\nimport type { LemonSqueezyActivateResponse, LemonSqueezyValidateResponse } from './types.js';\n\nconst BASE_URL = 'https://api.polar.sh/v1/customer-portal/license-keys';\n\n// ── CONFIGURE: Replace with your Polar organization ID ──\n// Found at: polar.sh/dashboard → Settings → General\nexport const POLAR_ORGANIZATION_ID = 'b8f245c0-d116-4457-92fb-1bda47139f82';\n\n// Layer 11: API URL validation\nfunction validateApiUrl(url: string): void {\n const parsed = new URL(url);\n if (parsed.protocol !== 'https:') {\n throw new Error('HTTPS required for license API');\n }\n if (!parsed.hostname.endsWith('polar.sh')) {\n throw new Error('Invalid API host');\n }\n}\n\n// Raw Polar response shapes\ninterface PolarActivation {\n id: string; // activation_id\n license_key: {\n status: string;\n expires_at: string | null;\n };\n}\n\ninterface PolarValidated {\n id: string;\n status: string; // 'granted' | 'revoked' | 'disabled'\n expires_at: string | null;\n customer: {\n email: string | null;\n name: string | null;\n };\n activation: { id: string } | null;\n}\n\nasync function post<T>(endpoint: string, body: Record<string, unknown>, expectEmpty = false): Promise<T> {\n const url = `${BASE_URL}/${endpoint}`;\n validateApiUrl(url);\n\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n let message = `Request failed with status ${res.status}`;\n try {\n const errBody = await res.json() as { detail?: string; error?: string; message?: string };\n if (typeof errBody.detail === 'string') message = errBody.detail;\n else if (typeof errBody.error === 'string') message = errBody.error;\n else if (typeof errBody.message === 'string') message = errBody.message;\n } catch {\n // non-JSON error body — use generic message above\n }\n throw new Error(message);\n }\n\n if (expectEmpty || res.status === 204) return undefined as T;\n return res.json() as Promise<T>;\n}\n\nexport async function activateLicense(key: string): Promise<LemonSqueezyActivateResponse> {\n const activation = await post<PolarActivation>('activate', {\n key,\n organization_id: POLAR_ORGANIZATION_ID,\n label: hostname(),\n });\n\n // Polar's activate response doesn't include customer info — fetch it via validate\n let customerEmail = '';\n let customerName = '';\n try {\n const validated = await post<PolarValidated>('validate', {\n key,\n organization_id: POLAR_ORGANIZATION_ID,\n activation_id: activation.id,\n });\n customerEmail = validated.customer?.email ?? '';\n customerName = validated.customer?.name ?? '';\n } catch {\n // customer info is non-critical — activation still succeeds\n }\n\n return {\n activated: true,\n error: null,\n instance: { id: activation.id },\n license_key: {\n id: 0,\n status: activation.license_key.status,\n key,\n activation_limit: 0,\n activations_count: 0,\n expires_at: activation.license_key.expires_at,\n },\n meta: { customer_email: customerEmail, customer_name: customerName },\n };\n}\n\nexport async function validateLicense(key: string, instanceId: string): Promise<LemonSqueezyValidateResponse> {\n const res = await post<PolarValidated>('validate', {\n key,\n organization_id: POLAR_ORGANIZATION_ID,\n activation_id: instanceId,\n });\n\n const notExpired = res.expires_at === null || new Date(res.expires_at) > new Date();\n const valid = res.status === 'granted' && notExpired;\n\n return {\n valid,\n error: valid ? null : `License ${res.status}`,\n license_key: {\n id: 0,\n status: res.status,\n key,\n expires_at: res.expires_at,\n },\n instance: { id: instanceId },\n };\n}\n\nexport async function deactivateLicense(key: string, instanceId: string): Promise<void> {\n await post<void>(\n 'deactivate',\n { key, organization_id: POLAR_ORGANIZATION_ID, activation_id: instanceId },\n true,\n );\n}\n","import { create } from 'zustand';\nimport type { LicenseData, LicenseStatus } from '../lib/license/types.js';\nimport * as manager from '../lib/license/license-manager.js';\nimport { getDegradationLevel } from '../lib/license/license-manager.js';\nimport type { DegradationLevel } from '../lib/license/license-manager.js';\nimport { ensureDataDirs } from '../lib/data-dir.js';\n\nconst REVALIDATION_CHECK_MS = 60 * 60 * 1000; // Check every hour\n\n// Module-level flag: prevents concurrent revalidation calls (initial + interval overlap)\nlet _revalidating = false;\n\ninterface LicenseState {\n status: LicenseStatus;\n license: LicenseData | null;\n error: string | null;\n degradation: DegradationLevel;\n\n initialize: () => Promise<void>;\n activate: (key: string) => Promise<boolean>;\n deactivate: () => Promise<void>;\n isPro: () => boolean;\n}\n\nexport const useLicenseStore = create<LicenseState>((set, get) => ({\n status: 'free',\n license: null,\n error: null,\n degradation: 'none',\n\n initialize: async () => {\n await ensureDataDirs();\n const license = await manager.loadLicense();\n\n if (!license) {\n set({ status: 'free', license: null, degradation: 'none' });\n return;\n }\n\n if (manager.isExpired(license)) {\n set({ status: 'expired', license, degradation: 'expired' });\n return;\n }\n\n // Layer 15: Check degradation level based on offline time\n const level = getDegradationLevel(license);\n if (level === 'expired') {\n set({ status: 'expired', license, degradation: 'expired' });\n return;\n }\n\n // Set Pro immediately (warning/limited still shown as pro, but pro-guard checks degradation)\n set({ status: 'pro', license, degradation: level });\n\n if (manager.needsRevalidation(license) && !_revalidating) {\n _revalidating = true;\n try {\n const valid = await manager.revalidate(license);\n if (!valid) {\n set({ status: 'expired', license: { ...license, status: 'expired' } });\n } else {\n const updated = await manager.loadLicense();\n if (updated) set({ license: updated });\n }\n } finally {\n _revalidating = false;\n }\n }\n\n // Periodically re-check license validity during the session\n setInterval(async () => {\n const current = get().license;\n if (!current || get().status !== 'pro') return;\n if (!manager.needsRevalidation(current)) return;\n if (_revalidating) return;\n _revalidating = true;\n try {\n const valid = await manager.revalidate(current);\n if (!valid) {\n set({ status: 'expired', license: { ...current, status: 'expired' } });\n } else {\n const updated = await manager.loadLicense();\n if (updated) set({ license: updated });\n }\n } finally {\n _revalidating = false;\n }\n }, REVALIDATION_CHECK_MS).unref();\n },\n\n activate: async (key) => {\n set({ error: null });\n try {\n const license = await manager.activate(key);\n set({ status: 'pro', license });\n return true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n set({ error: msg });\n return false;\n }\n },\n\n deactivate: async () => {\n const { license } = get();\n if (license) {\n await manager.deactivate(license);\n }\n set({ status: 'free', license: null, error: null });\n },\n\n isPro: () => get().status === 'pro',\n}));\n","import inspector from 'node:inspector';\n\n/**\n * Detect if a debugger/inspector is attached.\n * If detected, Pro features are disabled as a precaution.\n * Exempted in test/CI environments to prevent false-positives when\n * running vitest with --inspect-brk or inside CI pipelines.\n */\nexport function isDebuggerAttached(): boolean {\n // Never block test or CI runs — vitest may itself use inspector\n if (process.env.VITEST || process.env.CI) return false;\n\n // Node.js inspector protocol active\n if (inspector.url()) return true;\n\n // Debug flags in process arguments\n if (process.execArgv.some((a) => a.includes('--inspect') || a.includes('--debug'))) return true;\n\n // Debug environment variables\n if (process.env.NODE_OPTIONS?.includes('--inspect')) return true;\n\n return false;\n}\n","import { useLicenseStore } from '../../stores/license-store.js';\n\n// Store references to the original functions at module load time\nconst _originalIsPro = useLicenseStore.getState().isPro;\nconst _originalGetState = useLicenseStore.getState;\n\n/**\n * Verify that the license store's isPro function hasn't been replaced\n * with a function that always returns true.\n */\nexport function verifyStoreIntegrity(): boolean {\n const state = useLicenseStore.getState();\n\n // Check 1: isPro function reference hasn't changed\n if (state.isPro !== _originalIsPro) return false;\n\n // Check 2: getState itself hasn't been replaced\n if (useLicenseStore.getState !== _originalGetState) return false;\n\n // Check 3: If status is 'free', isPro() must return false\n // (catches patches that make isPro() always return true regardless of status)\n if (state.status === 'free' && state.isPro()) return false;\n\n return true;\n}\n","/**\n * Canary functions for detecting license bypass attempts.\n *\n * These functions LOOK like they gate Pro features but are actually\n * trap checks. They should always return false in normal operation.\n * If they return true, it means someone patched the code to bypass\n * license checks indiscriminately.\n */\n\n// Looks like a Pro check but should NEVER be true in production\n// If someone does a global find-replace to make all license checks return true,\n// this will also return true, triggering the tamper detection.\nlet _canaryTripped = false;\n\nexport function isProUnlocked(): boolean {\n // This function name looks like a legitimate license gate.\n // If someone patches it to return true, we detect the tamper.\n return false;\n}\n\nexport function hasProAccess(): boolean {\n // Another decoy. Should always return false.\n return false;\n}\n\nexport function isLicenseValid(): boolean {\n // Decoy #3\n return false;\n}\n\n/**\n * Check if any canary has been tripped (patched to return true).\n * If so, the binary has been tampered with.\n */\nexport function checkCanaries(): boolean {\n // If ANY of these return true, someone did a blanket patch\n if (isProUnlocked()) { _canaryTripped = true; return false; }\n if (hasProAccess()) { _canaryTripped = true; return false; }\n if (isLicenseValid()) { _canaryTripped = true; return false; }\n return !_canaryTripped;\n}\n","import { readFileSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { fileURLToPath } from 'node:url';\n\n// Hash captured at module-load time (earliest possible moment in this process).\n// This detects file modification that occurs AFTER the module has already been\n// loaded into the process — i.e. an attacker who patches the file on-disk while\n// the TUI is running. It does NOT detect patches applied before or during\n// module load. For that, a signed bundle with an external manifest would be required.\nlet _baselineHash: string | null = null;\n\nfunction _captureBaseline(): string | null {\n try {\n const bundlePath = fileURLToPath(import.meta.url);\n const content = readFileSync(bundlePath, 'utf-8');\n return createHash('sha256').update(content).digest('hex');\n } catch {\n return null;\n }\n}\n\n// Capture immediately at module load — do not defer.\n_baselineHash = _captureBaseline();\n\n/**\n * Detect on-disk modification of the running bundle after process start.\n * Returns false only if the file was verifiably changed since module load.\n * Fails open (returns true) if the file cannot be read.\n */\nexport function checkBundleIntegrity(): boolean {\n if (_baselineHash === null) {\n // Could not establish baseline (dev mode / permissions) — fail open\n return true;\n }\n try {\n const bundlePath = fileURLToPath(import.meta.url);\n const content = readFileSync(bundlePath, 'utf-8');\n const current = createHash('sha256').update(content).digest('hex');\n return current === _baselineHash;\n } catch {\n return true; // Can't re-read — fail open\n }\n}\n","import { useLicenseStore } from '../../stores/license-store.js';\nimport { isDebuggerAttached } from './anti-debug.js';\nimport { verifyStoreIntegrity } from './anti-tamper.js';\nimport { checkCanaries } from './canary.js';\nimport { checkBundleIntegrity } from './integrity.js';\nimport { getDegradationLevel } from './license-manager.js';\n\n// ── Layer 14: Obfuscated secondary verification ──\n// Secondary verification using indirect property access.\n// Resists simple string-search bypass (searching for \"status\" or \"pro\").\nconst _S = String.fromCharCode(115, 116, 97, 116, 117, 115); // \"status\"\nconst _P = String.fromCharCode(112, 114, 111); // \"pro\"\n\nexport function _verify(): boolean {\n const state = useLicenseStore.getState();\n return (state as unknown as Record<string, unknown>)[_S] === _P;\n}\n\n/**\n * Multi-layered Pro license verification. Call this inside Pro feature logic\n * (not just at the view gate) as a defense-in-depth check.\n * Combines direct store check, bundle integrity, debugger detection,\n * obfuscated indirect check, store integrity, canary checks, and\n * degradation level.\n * Returns true if Pro, false otherwise.\n */\nexport function verifyPro(): boolean {\n if (isDebuggerAttached()) return false;\n if (!checkBundleIntegrity()) return false;\n if (!verifyStoreIntegrity()) return false;\n if (!checkCanaries()) return false;\n\n const directCheck = useLicenseStore.getState().status === 'pro';\n const indirectCheck = _verify();\n\n // Both must agree — if someone patched one, the other catches it\n if (!directCheck || !indirectCheck) return false;\n\n // Layer 15: Check degradation level (time-bomb for extended offline)\n const license = useLicenseStore.getState().license;\n if (license) {\n const level = getDegradationLevel(license);\n if (level === 'expired' || level === 'limited') return false;\n }\n\n return true;\n}\n\n/**\n * Throws if not Pro. Use in critical Pro-only operations.\n */\nexport function requirePro(): void {\n if (!verifyPro()) {\n throw new Error('Pro license required');\n }\n}\n"],"mappings":"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","names":["create","create"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|