@holdyourvoice/hyv 2.9.13 → 2.9.14
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/dist/index.js +147 -46
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5406,7 +5406,7 @@ var init_free_paid = __esm({
|
|
|
5406
5406
|
];
|
|
5407
5407
|
COMMUNITY_URL = "https://holdyourvoice.com/community";
|
|
5408
5408
|
PRICING_URL = "https://holdyourvoice.com/#pricing";
|
|
5409
|
-
DASHBOARD_BILLING_URL = "https://holdyourvoice.com/
|
|
5409
|
+
DASHBOARD_BILLING_URL = "https://holdyourvoice.com/app/billing";
|
|
5410
5410
|
}
|
|
5411
5411
|
});
|
|
5412
5412
|
|
|
@@ -5710,7 +5710,7 @@ async function authenticateWithBrowser() {
|
|
|
5710
5710
|
return authData;
|
|
5711
5711
|
}
|
|
5712
5712
|
async function openAuthenticatedDashboard(opts = {}) {
|
|
5713
|
-
const nextPath = opts.next || "/
|
|
5713
|
+
const nextPath = opts.next || "/app/billing";
|
|
5714
5714
|
try {
|
|
5715
5715
|
const response = await authenticatedRequest(cliApiUrl("/cli/auth/web-handoff"), {
|
|
5716
5716
|
method: "POST",
|
|
@@ -5725,7 +5725,7 @@ async function openAuthenticatedDashboard(opts = {}) {
|
|
|
5725
5725
|
}
|
|
5726
5726
|
} catch {
|
|
5727
5727
|
}
|
|
5728
|
-
const billingUrl = nextPath === "/
|
|
5728
|
+
const billingUrl = nextPath === "/app/billing" ? DASHBOARD_BILLING_URL : assertSafeOpenUrl(`https://holdyourvoice.com${nextPath}`);
|
|
5729
5729
|
await (0, import_open.default)(billingUrl);
|
|
5730
5730
|
}
|
|
5731
5731
|
async function refreshToken(tokenOverride) {
|
|
@@ -5883,7 +5883,7 @@ async function request2(method, path27, body) {
|
|
|
5883
5883
|
if (res.status === 401)
|
|
5884
5884
|
throw new Error("your session expired. run: hyv init to sign in again.");
|
|
5885
5885
|
if (res.status === 403)
|
|
5886
|
-
throw new Error("you don't have access to this feature. check your plan at holdyourvoice.com/
|
|
5886
|
+
throw new Error("you don't have access to this feature. check your plan at holdyourvoice.com/app/billing");
|
|
5887
5887
|
if (!res.ok) {
|
|
5888
5888
|
throw new Error(`something went wrong (${res.status}). try again or contact support.`);
|
|
5889
5889
|
}
|
|
@@ -5943,7 +5943,9 @@ async function getAccessState() {
|
|
|
5943
5943
|
try {
|
|
5944
5944
|
const session = await checkSession();
|
|
5945
5945
|
const plan = (session.plan || "none").toLowerCase();
|
|
5946
|
-
const
|
|
5946
|
+
const subStatus = String(session.subscription_status || "").toLowerCase();
|
|
5947
|
+
const activeSubscription = !subStatus || ["active", "past_due", "trialing"].includes(subStatus);
|
|
5948
|
+
const hasPaidPlan = session.valid && activeSubscription && plan !== "none" && plan !== "free" && plan !== "expired" && plan !== "unknown" && plan !== "pending";
|
|
5947
5949
|
const state = {
|
|
5948
5950
|
authenticated: session.valid,
|
|
5949
5951
|
hasPaidPlan,
|
|
@@ -11458,6 +11460,25 @@ var init_terminal_ui = __esm({
|
|
|
11458
11460
|
});
|
|
11459
11461
|
|
|
11460
11462
|
// src/lib/welcome-flow.ts
|
|
11463
|
+
function localProfilePath(name) {
|
|
11464
|
+
return path14.join(os8.homedir(), ".hyv", "profiles", `${name}.md`);
|
|
11465
|
+
}
|
|
11466
|
+
function listLocalProfileNames() {
|
|
11467
|
+
const profilesDir = path14.join(os8.homedir(), ".hyv", "profiles");
|
|
11468
|
+
if (!fs15.existsSync(profilesDir))
|
|
11469
|
+
return [];
|
|
11470
|
+
return fs15.readdirSync(profilesDir).filter((entry) => entry.endsWith(".md")).map((entry) => entry.slice(0, -3));
|
|
11471
|
+
}
|
|
11472
|
+
function formatPlanLabel(plan) {
|
|
11473
|
+
const labels = {
|
|
11474
|
+
individual: "Individual",
|
|
11475
|
+
multiple: "Multiple",
|
|
11476
|
+
solo: "Solo",
|
|
11477
|
+
team: "Team",
|
|
11478
|
+
agency: "Agency"
|
|
11479
|
+
};
|
|
11480
|
+
return labels[plan.toLowerCase()] || plan;
|
|
11481
|
+
}
|
|
11461
11482
|
function readWelcomeState() {
|
|
11462
11483
|
try {
|
|
11463
11484
|
if (!fs15.existsSync(STATE_FILE)) {
|
|
@@ -11794,8 +11815,28 @@ function formatScanResult(text, profile) {
|
|
|
11794
11815
|
}
|
|
11795
11816
|
async function stepName() {
|
|
11796
11817
|
console.log(import_chalk12.default.bold("\nstep 1 \xB7 name your profile\n"));
|
|
11818
|
+
const state = readWelcomeState();
|
|
11819
|
+
const existing = listLocalProfileNames();
|
|
11820
|
+
if (state.profile_name && existing.includes(state.profile_name)) {
|
|
11821
|
+
const reuse = await askYesNo(` reuse profile "${state.profile_name}"?`, true);
|
|
11822
|
+
if (reuse) {
|
|
11823
|
+
markStepComplete("name");
|
|
11824
|
+
return state.profile_name;
|
|
11825
|
+
}
|
|
11826
|
+
} else if (existing.length === 1) {
|
|
11827
|
+
const only = existing[0];
|
|
11828
|
+
const reuse = await askYesNo(` reuse existing profile "${only}"?`, true);
|
|
11829
|
+
if (reuse) {
|
|
11830
|
+
writeWelcomeState({ profile_name: only });
|
|
11831
|
+
markStepComplete("name");
|
|
11832
|
+
return only;
|
|
11833
|
+
}
|
|
11834
|
+
}
|
|
11797
11835
|
const name = await askLine(import_chalk12.default.cyan(" profile name (e.g. my-voice): "));
|
|
11798
|
-
|
|
11836
|
+
const safe = assertSafeProfileName(name);
|
|
11837
|
+
writeWelcomeState({ profile_name: safe });
|
|
11838
|
+
markStepComplete("name");
|
|
11839
|
+
return safe;
|
|
11799
11840
|
}
|
|
11800
11841
|
async function stepSamples(profileName) {
|
|
11801
11842
|
console.log(import_chalk12.default.bold("\nstep 2 \xB7 add writing samples\n"));
|
|
@@ -11859,6 +11900,8 @@ _Add pasted samples to train this profile._
|
|
|
11859
11900
|
console.log(import_chalk12.default.green(`
|
|
11860
11901
|
\u2713 profile saved`));
|
|
11861
11902
|
console.log(import_chalk12.default.dim(` ${saved}`));
|
|
11903
|
+
writeWelcomeState({ profile_name: profileName });
|
|
11904
|
+
markStepComplete("samples");
|
|
11862
11905
|
}
|
|
11863
11906
|
async function stepTest(profileName) {
|
|
11864
11907
|
console.log(import_chalk12.default.bold("\nstep 3 \xB7 test on a draft"));
|
|
@@ -11899,42 +11942,25 @@ async function stepTest(profileName) {
|
|
|
11899
11942
|
console.log(import_chalk12.default.dim(` try: hyv rewrite ${rewriteTarget} --profile ${profileName}`));
|
|
11900
11943
|
markStepComplete("test");
|
|
11901
11944
|
}
|
|
11902
|
-
async function
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
console.log(" then unlock learning for " + import_chalk12.default.bold("$1 your first month") + " \u2014 profiles that");
|
|
11908
|
-
console.log(" get sharper every rewrite, hybrid rewrites, and your dashboard.\n");
|
|
11909
|
-
console.log(import_chalk12.default.dim(" free forever (no account): scan, fix, check, mcp"));
|
|
11910
|
-
console.log(import_chalk12.default.dim(" $1 first month: learning loop, rich rewrites, sync across devices\n"));
|
|
11911
|
-
const ready = await askYesNo(" create your free account now? ($1 first month to unlock everything)");
|
|
11912
|
-
if (!ready) {
|
|
11913
|
-
console.log(import_chalk12.default.dim("\n no rush \u2014 your profile stays on this machine."));
|
|
11914
|
-
console.log(import_chalk12.default.dim(" whenever you want backup + learning:"));
|
|
11915
|
-
console.log(import_chalk12.default.dim(" hyv init"));
|
|
11916
|
-
console.log(import_chalk12.default.dim(" hyv plan --upgrade ($1 first month)"));
|
|
11917
|
-
console.log(import_chalk12.default.dim(` ${PRICING_URL}
|
|
11918
|
-
`));
|
|
11919
|
-
return;
|
|
11945
|
+
async function syncProfileToAccount(profileName) {
|
|
11946
|
+
const profilePath = localProfilePath(profileName);
|
|
11947
|
+
if (!fs15.existsSync(profilePath)) {
|
|
11948
|
+
console.log(import_chalk12.default.yellow(` no local profile at ${profilePath}`));
|
|
11949
|
+
return false;
|
|
11920
11950
|
}
|
|
11921
11951
|
if (!isInitialized() || !getToken()) {
|
|
11922
|
-
console.log(import_chalk12.default.cyan("\n opening browser for
|
|
11923
|
-
await withSpinner("
|
|
11952
|
+
console.log(import_chalk12.default.cyan("\n opening browser for sign-in...\n"));
|
|
11953
|
+
await withSpinner("signing in\u2026", () => authenticateWithBrowser());
|
|
11924
11954
|
await briefPause();
|
|
11925
|
-
console.log(import_chalk12.default.green(" \u2713
|
|
11926
|
-
} else {
|
|
11927
|
-
console.log(import_chalk12.default.dim("\n already signed in \u2014 syncing profile..."));
|
|
11955
|
+
console.log(import_chalk12.default.green(" \u2713 signed in"));
|
|
11928
11956
|
}
|
|
11929
|
-
const content = fs15.readFileSync(
|
|
11930
|
-
path14.join(os8.homedir(), ".hyv", "profiles", `${profileName}.md`),
|
|
11931
|
-
"utf-8"
|
|
11932
|
-
);
|
|
11957
|
+
const content = fs15.readFileSync(profilePath, "utf-8");
|
|
11933
11958
|
try {
|
|
11934
11959
|
const response = await withSpinner(
|
|
11935
11960
|
"syncing profile\u2026",
|
|
11936
11961
|
() => authenticatedRequest(cliApiUrl("/cli/profiles/new"), {
|
|
11937
11962
|
method: "POST",
|
|
11963
|
+
timeout: PROFILE_SYNC_TIMEOUT_MS,
|
|
11938
11964
|
body: { name: profileName, content, source: "welcome" }
|
|
11939
11965
|
})
|
|
11940
11966
|
);
|
|
@@ -11945,27 +11971,100 @@ async function stepSignup(profileName) {
|
|
|
11945
11971
|
} else {
|
|
11946
11972
|
console.log(import_chalk12.default.green(" \u2713 profile synced to your account"));
|
|
11947
11973
|
}
|
|
11948
|
-
|
|
11949
|
-
const detail = response.data?.error;
|
|
11950
|
-
console.log(import_chalk12.default.yellow(
|
|
11951
|
-
` profile saved locally \u2014 retry \`hyv welcome\` when online${detail ? ` (${detail})` : ` (HTTP ${response.status})`}`
|
|
11952
|
-
));
|
|
11974
|
+
return true;
|
|
11953
11975
|
}
|
|
11976
|
+
const detail = response.data?.error;
|
|
11977
|
+
console.log(import_chalk12.default.yellow(
|
|
11978
|
+
` profile saved locally \u2014 retry \`hyv sync\`${detail ? ` (${detail})` : ` (HTTP ${response.status})`}`
|
|
11979
|
+
));
|
|
11954
11980
|
} catch (err) {
|
|
11955
11981
|
console.log(import_chalk12.default.yellow(
|
|
11956
|
-
` profile saved locally \u2014 retry \`hyv
|
|
11982
|
+
` profile saved locally \u2014 retry \`hyv sync\` (${err?.message || "sync failed"})`
|
|
11957
11983
|
));
|
|
11958
11984
|
}
|
|
11985
|
+
return false;
|
|
11986
|
+
}
|
|
11987
|
+
async function stepSignup(profileName) {
|
|
11988
|
+
console.log(import_chalk12.default.bold("\nstep 4 \xB7 save & unlock\n"));
|
|
11989
|
+
const access = await getAccessState();
|
|
11990
|
+
if (access.hasPaidPlan) {
|
|
11991
|
+
console.log(` you're on ${import_chalk12.default.bold(formatPlanLabel(access.plan))} \u2014 learning, sync, and dashboard are unlocked.`);
|
|
11992
|
+
console.log(import_chalk12.default.dim("\n syncing your local profile to your account..."));
|
|
11993
|
+
await syncProfileToAccount(profileName);
|
|
11994
|
+
markStepComplete("signup");
|
|
11995
|
+
console.log(import_chalk12.default.dim("\n run `hyv scan draft.md` or `hyv sync` anytime.\n"));
|
|
11996
|
+
return;
|
|
11997
|
+
}
|
|
11998
|
+
console.log(" your profile works on this machine. scan anything, anytime \u2014 free forever.");
|
|
11999
|
+
console.log("");
|
|
12000
|
+
if (access.authenticated) {
|
|
12001
|
+
console.log(" you're signed in. sync this profile, or upgrade for learning + rich rewrites.");
|
|
12002
|
+
console.log(import_chalk12.default.dim("\n free forever: scan, fix, check, mcp"));
|
|
12003
|
+
console.log(import_chalk12.default.dim(" paid: learning loop, hybrid rewrites, sync across devices\n"));
|
|
12004
|
+
const syncNow = await askYesNo(" sync profile to your account now?", true);
|
|
12005
|
+
if (syncNow) {
|
|
12006
|
+
await syncProfileToAccount(profileName);
|
|
12007
|
+
}
|
|
12008
|
+
const upgrade = await askYesNo(" open billing to upgrade?", false);
|
|
12009
|
+
if (upgrade) {
|
|
12010
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/app/billing" }));
|
|
12011
|
+
await briefPause();
|
|
12012
|
+
}
|
|
12013
|
+
markStepComplete("signup");
|
|
12014
|
+
console.log(import_chalk12.default.dim("\n upgrade anytime: `hyv plan --upgrade`\n"));
|
|
12015
|
+
return;
|
|
12016
|
+
}
|
|
12017
|
+
console.log(" create a free account to back it up and sync everywhere.");
|
|
12018
|
+
console.log(" then unlock learning for " + import_chalk12.default.bold("$1 your first month") + " \u2014 profiles that");
|
|
12019
|
+
console.log(" get sharper every rewrite, hybrid rewrites, and your dashboard.\n");
|
|
12020
|
+
console.log(import_chalk12.default.dim(" free forever (no account): scan, fix, check, mcp"));
|
|
12021
|
+
console.log(import_chalk12.default.dim(" $1 first month: learning loop, rich rewrites, sync across devices\n"));
|
|
12022
|
+
const ready = await askYesNo(" create your free account now? ($1 first month to unlock everything)");
|
|
12023
|
+
if (!ready) {
|
|
12024
|
+
console.log(import_chalk12.default.dim("\n no rush \u2014 your profile stays on this machine."));
|
|
12025
|
+
console.log(import_chalk12.default.dim(" whenever you want backup + learning:"));
|
|
12026
|
+
console.log(import_chalk12.default.dim(" hyv init"));
|
|
12027
|
+
console.log(import_chalk12.default.dim(" hyv plan --upgrade ($1 first month)"));
|
|
12028
|
+
console.log(import_chalk12.default.dim(` ${PRICING_URL}
|
|
12029
|
+
`));
|
|
12030
|
+
return;
|
|
12031
|
+
}
|
|
12032
|
+
await syncProfileToAccount(profileName);
|
|
11959
12033
|
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
11960
|
-
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/
|
|
12034
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/app/billing" }));
|
|
11961
12035
|
await briefPause();
|
|
11962
12036
|
markStepComplete("signup");
|
|
11963
12037
|
console.log(import_chalk12.default.dim("\n you're signed in \u2014 pick a plan in billing, no second login.\n"));
|
|
11964
12038
|
}
|
|
12039
|
+
async function maybeRunPaidWelcomeShortcut() {
|
|
12040
|
+
const access = await getAccessState();
|
|
12041
|
+
if (!access.authenticated || !access.hasPaidPlan)
|
|
12042
|
+
return null;
|
|
12043
|
+
const state = readWelcomeState();
|
|
12044
|
+
const profiles = listLocalProfileNames();
|
|
12045
|
+
const profileName = state.profile_name && profiles.includes(state.profile_name) ? state.profile_name : profiles[0];
|
|
12046
|
+
if (!profileName)
|
|
12047
|
+
return null;
|
|
12048
|
+
console.log(import_chalk12.default.green(`
|
|
12049
|
+
${formatPlanLabel(access.plan)} plan active \u2014 profile "${profileName}" ready.`));
|
|
12050
|
+
const resync = await askYesNo(" sync profile to your account now?", true);
|
|
12051
|
+
if (resync) {
|
|
12052
|
+
await syncProfileToAccount(profileName);
|
|
12053
|
+
}
|
|
12054
|
+
markStepComplete("signup");
|
|
12055
|
+
console.log(import_chalk12.default.green("\ndone \u2014 your voice profile is ready.\n"));
|
|
12056
|
+
console.log(import_chalk12.default.dim(" hyv scan draft.md"));
|
|
12057
|
+
console.log(import_chalk12.default.dim(` hyv rewrite draft.md --profile ${profileName}`));
|
|
12058
|
+
console.log(import_chalk12.default.dim(" hyv mcp --setup\n"));
|
|
12059
|
+
return profileName;
|
|
12060
|
+
}
|
|
11965
12061
|
async function runInteractiveWelcome() {
|
|
11966
12062
|
recordEvent("welcome_interactive");
|
|
11967
12063
|
console.log("\n" + buildWelcomeHeader());
|
|
11968
12064
|
try {
|
|
12065
|
+
const shortcut = await maybeRunPaidWelcomeShortcut();
|
|
12066
|
+
if (shortcut)
|
|
12067
|
+
return;
|
|
11969
12068
|
const profileName = await stepName();
|
|
11970
12069
|
await stepSamples(profileName);
|
|
11971
12070
|
await stepTest(profileName);
|
|
@@ -11992,7 +12091,7 @@ function getMcpWelcomeResponse(args2) {
|
|
|
11992
12091
|
}
|
|
11993
12092
|
return buildWelcomeGuide({ profileName: args2.profile, forLlm: true });
|
|
11994
12093
|
}
|
|
11995
|
-
var import_chalk12, fs15, http2, https2, os8, path14, readline, WELCOME_TAGLINE, FLOW_STEPS, STATE_FILE;
|
|
12094
|
+
var import_chalk12, fs15, http2, https2, os8, path14, readline, PROFILE_SYNC_TIMEOUT_MS, WELCOME_TAGLINE, FLOW_STEPS, STATE_FILE;
|
|
11996
12095
|
var init_welcome_flow = __esm({
|
|
11997
12096
|
"src/lib/welcome-flow.ts"() {
|
|
11998
12097
|
"use strict";
|
|
@@ -12009,10 +12108,12 @@ var init_welcome_flow = __esm({
|
|
|
12009
12108
|
init_terminal_ui();
|
|
12010
12109
|
init_config();
|
|
12011
12110
|
init_auth();
|
|
12111
|
+
init_access();
|
|
12012
12112
|
init_scan();
|
|
12013
12113
|
init_free_paid();
|
|
12014
12114
|
init_telemetry();
|
|
12015
12115
|
init_document_text();
|
|
12116
|
+
PROFILE_SYNC_TIMEOUT_MS = 9e4;
|
|
12016
12117
|
WELCOME_TAGLINE = "Hold Your Voice \u2014 make your AI agents sound exactly like you.";
|
|
12017
12118
|
FLOW_STEPS = [
|
|
12018
12119
|
{ n: 1, key: "name", title: "name your profile", hint: "pick a short name \u2014 e.g. my-voice" },
|
|
@@ -12144,7 +12245,7 @@ __export(billing_upgrade_exports, {
|
|
|
12144
12245
|
});
|
|
12145
12246
|
async function openBillingUpgrade(opts = {}) {
|
|
12146
12247
|
const plan = opts.plan || "individual";
|
|
12147
|
-
const next = `/
|
|
12248
|
+
const next = `/app/billing?checkout=${plan}`;
|
|
12148
12249
|
const token = getToken();
|
|
12149
12250
|
if (!token) {
|
|
12150
12251
|
console.log(import_chalk14.default.cyan("\nSign in to upgrade \u2014 opening browser...\n"));
|
|
@@ -18353,8 +18454,8 @@ function registerBatchCommand(program3) {
|
|
|
18353
18454
|
program3.command("batch").description("Scan or fix multiple files matching a glob").argument("<pattern>", 'Glob pattern (e.g., "posts/**/*.md")').option("--fix", "Apply auto-fixes (default: scan only)").option("-i, --in-place", "Write fixes back to files").option("-y, --yes", "Confirm destructive in-place fixes without prompting").option("--threshold <n>", "Fail if any file score < threshold").option("--fail-on-hit", "Exit with code 2 if any file has issues").option("--sort <field>", "Sort by: issues, score, name", "issues").option("--format <type>", "Output format (text, json, csv)", "text").option("--profile <name>", "Voice profile").option("--ignore <patterns>", "Comma-separated glob ignores").action(async (pattern, options) => {
|
|
18354
18455
|
try {
|
|
18355
18456
|
const profile = await loadProfileForCommand(options.profile);
|
|
18356
|
-
const
|
|
18357
|
-
const files =
|
|
18457
|
+
const { globSync } = require_index_min();
|
|
18458
|
+
const files = globSync(pattern, {
|
|
18358
18459
|
ignore: options.ignore ? options.ignore.split(",") : void 0,
|
|
18359
18460
|
nodir: true
|
|
18360
18461
|
});
|
|
@@ -18680,9 +18781,9 @@ var import_chalk30 = __toESM(require_source());
|
|
|
18680
18781
|
var PAGES = {
|
|
18681
18782
|
dashboard: "https://holdyourvoice.com/dashboard",
|
|
18682
18783
|
profiles: "https://holdyourvoice.com/dashboard?tab=profiles",
|
|
18683
|
-
pricing: "https://holdyourvoice.com/
|
|
18784
|
+
pricing: "https://holdyourvoice.com/app/billing",
|
|
18684
18785
|
settings: "https://holdyourvoice.com/dashboard",
|
|
18685
|
-
billing: "https://holdyourvoice.com/
|
|
18786
|
+
billing: "https://holdyourvoice.com/app/billing"
|
|
18686
18787
|
};
|
|
18687
18788
|
function registerOpenCommand(program3) {
|
|
18688
18789
|
program3.command("open").description("Open the web dashboard in your browser").option("--page <path>", "Page: dashboard, profiles, pricing, settings", "dashboard").option("--profile <name>", "Deep-link to a specific profile").option("--no-browser", "Print URL only, don't open").action(async (options) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdyourvoice/hyv",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.14",
|
|
4
4
|
"description": "Free local AI writing scan for cursor & claude. MCP server, 220+ pattern detection, voice profiles. npx @holdyourvoice/hyv welcome",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@types/node": "^20.19.42",
|
|
51
51
|
"esbuild": "^0.20.0",
|
|
52
52
|
"typescript": "^5.3.3",
|
|
53
|
-
"vitest": "^
|
|
53
|
+
"vitest": "^2.0.0"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
56
|
"node": ">=18"
|