@holdyourvoice/hyv 2.9.12 → 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 +450 -342
- 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,
|
|
@@ -5979,7 +5981,8 @@ async function requirePaidFeature(feature) {
|
|
|
5979
5981
|
throw new Error("can't reach the server. check your internet connection and try again.");
|
|
5980
5982
|
}
|
|
5981
5983
|
const plan = (data.plan || "none").toLowerCase();
|
|
5982
|
-
|
|
5984
|
+
const subStatus = String(data.subscription_status || data.status || "").toLowerCase();
|
|
5985
|
+
if (!data.plan || plan === "none" || plan === "free" || plan === "expired" || subStatus === "trialing" || subStatus === "none") {
|
|
5983
5986
|
throw new Error(FEATURE_MESSAGES[feature]);
|
|
5984
5987
|
}
|
|
5985
5988
|
}
|
|
@@ -5994,7 +5997,7 @@ async function maybeShowLimitedModeHint(hasProfile) {
|
|
|
5994
5997
|
} else if (!access.authenticated) {
|
|
5995
5998
|
console.log(import_chalk5.default.dim("\n local mode \u2014 free scan engine. profiles + learning: hyv init"));
|
|
5996
5999
|
} else {
|
|
5997
|
-
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv
|
|
6000
|
+
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv upgrade"));
|
|
5998
6001
|
}
|
|
5999
6002
|
}
|
|
6000
6003
|
function formatModeLabel(access, hasFullProfile) {
|
|
@@ -6017,10 +6020,10 @@ var init_access = __esm({
|
|
|
6017
6020
|
init_auth();
|
|
6018
6021
|
init_api();
|
|
6019
6022
|
FEATURE_MESSAGES = {
|
|
6020
|
-
profiles: "syncing voice profiles from your account requires a paid plan. run: hyv
|
|
6021
|
-
learning: "the learning loop (reinforce, add) requires a paid plan. run: hyv
|
|
6022
|
-
premiumPrompts: "rich profile-aware rewrite prompts require a paid plan. run: hyv
|
|
6023
|
-
serverAnalysis: "server-assisted analysis requires a paid plan. run: hyv
|
|
6023
|
+
profiles: "syncing voice profiles from your account requires a paid plan. run: hyv upgrade",
|
|
6024
|
+
learning: "the learning loop (reinforce, add) requires a paid plan. run: hyv upgrade",
|
|
6025
|
+
premiumPrompts: "rich profile-aware rewrite prompts require a paid plan. run: hyv upgrade",
|
|
6026
|
+
serverAnalysis: "server-assisted analysis requires a paid plan. run: hyv upgrade"
|
|
6024
6027
|
};
|
|
6025
6028
|
localOnlyOverride = false;
|
|
6026
6029
|
cachedAccess = null;
|
|
@@ -11457,6 +11460,25 @@ var init_terminal_ui = __esm({
|
|
|
11457
11460
|
});
|
|
11458
11461
|
|
|
11459
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
|
+
}
|
|
11460
11482
|
function readWelcomeState() {
|
|
11461
11483
|
try {
|
|
11462
11484
|
if (!fs15.existsSync(STATE_FILE)) {
|
|
@@ -11793,8 +11815,28 @@ function formatScanResult(text, profile) {
|
|
|
11793
11815
|
}
|
|
11794
11816
|
async function stepName() {
|
|
11795
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
|
+
}
|
|
11796
11835
|
const name = await askLine(import_chalk12.default.cyan(" profile name (e.g. my-voice): "));
|
|
11797
|
-
|
|
11836
|
+
const safe = assertSafeProfileName(name);
|
|
11837
|
+
writeWelcomeState({ profile_name: safe });
|
|
11838
|
+
markStepComplete("name");
|
|
11839
|
+
return safe;
|
|
11798
11840
|
}
|
|
11799
11841
|
async function stepSamples(profileName) {
|
|
11800
11842
|
console.log(import_chalk12.default.bold("\nstep 2 \xB7 add writing samples\n"));
|
|
@@ -11858,6 +11900,8 @@ _Add pasted samples to train this profile._
|
|
|
11858
11900
|
console.log(import_chalk12.default.green(`
|
|
11859
11901
|
\u2713 profile saved`));
|
|
11860
11902
|
console.log(import_chalk12.default.dim(` ${saved}`));
|
|
11903
|
+
writeWelcomeState({ profile_name: profileName });
|
|
11904
|
+
markStepComplete("samples");
|
|
11861
11905
|
}
|
|
11862
11906
|
async function stepTest(profileName) {
|
|
11863
11907
|
console.log(import_chalk12.default.bold("\nstep 3 \xB7 test on a draft"));
|
|
@@ -11898,42 +11942,25 @@ async function stepTest(profileName) {
|
|
|
11898
11942
|
console.log(import_chalk12.default.dim(` try: hyv rewrite ${rewriteTarget} --profile ${profileName}`));
|
|
11899
11943
|
markStepComplete("test");
|
|
11900
11944
|
}
|
|
11901
|
-
async function
|
|
11902
|
-
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
console.log(" then unlock learning for " + import_chalk12.default.bold("$1 your first month") + " \u2014 profiles that");
|
|
11907
|
-
console.log(" get sharper every rewrite, hybrid rewrites, and your dashboard.\n");
|
|
11908
|
-
console.log(import_chalk12.default.dim(" free forever (no account): scan, fix, check, mcp"));
|
|
11909
|
-
console.log(import_chalk12.default.dim(" $1 first month: learning loop, rich rewrites, sync across devices\n"));
|
|
11910
|
-
const ready = await askYesNo(" create your free account now? ($1 first month to unlock everything)");
|
|
11911
|
-
if (!ready) {
|
|
11912
|
-
console.log(import_chalk12.default.dim("\n no rush \u2014 your profile stays on this machine."));
|
|
11913
|
-
console.log(import_chalk12.default.dim(" whenever you want backup + learning:"));
|
|
11914
|
-
console.log(import_chalk12.default.dim(" hyv init"));
|
|
11915
|
-
console.log(import_chalk12.default.dim(" hyv plan --upgrade ($1 first month)"));
|
|
11916
|
-
console.log(import_chalk12.default.dim(` ${PRICING_URL}
|
|
11917
|
-
`));
|
|
11918
|
-
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;
|
|
11919
11950
|
}
|
|
11920
11951
|
if (!isInitialized() || !getToken()) {
|
|
11921
|
-
console.log(import_chalk12.default.cyan("\n opening browser for
|
|
11922
|
-
await withSpinner("
|
|
11952
|
+
console.log(import_chalk12.default.cyan("\n opening browser for sign-in...\n"));
|
|
11953
|
+
await withSpinner("signing in\u2026", () => authenticateWithBrowser());
|
|
11923
11954
|
await briefPause();
|
|
11924
|
-
console.log(import_chalk12.default.green(" \u2713
|
|
11925
|
-
} else {
|
|
11926
|
-
console.log(import_chalk12.default.dim("\n already signed in \u2014 syncing profile..."));
|
|
11955
|
+
console.log(import_chalk12.default.green(" \u2713 signed in"));
|
|
11927
11956
|
}
|
|
11928
|
-
const content = fs15.readFileSync(
|
|
11929
|
-
path14.join(os8.homedir(), ".hyv", "profiles", `${profileName}.md`),
|
|
11930
|
-
"utf-8"
|
|
11931
|
-
);
|
|
11957
|
+
const content = fs15.readFileSync(profilePath, "utf-8");
|
|
11932
11958
|
try {
|
|
11933
11959
|
const response = await withSpinner(
|
|
11934
11960
|
"syncing profile\u2026",
|
|
11935
11961
|
() => authenticatedRequest(cliApiUrl("/cli/profiles/new"), {
|
|
11936
11962
|
method: "POST",
|
|
11963
|
+
timeout: PROFILE_SYNC_TIMEOUT_MS,
|
|
11937
11964
|
body: { name: profileName, content, source: "welcome" }
|
|
11938
11965
|
})
|
|
11939
11966
|
);
|
|
@@ -11944,27 +11971,100 @@ async function stepSignup(profileName) {
|
|
|
11944
11971
|
} else {
|
|
11945
11972
|
console.log(import_chalk12.default.green(" \u2713 profile synced to your account"));
|
|
11946
11973
|
}
|
|
11947
|
-
|
|
11948
|
-
const detail = response.data?.error;
|
|
11949
|
-
console.log(import_chalk12.default.yellow(
|
|
11950
|
-
` profile saved locally \u2014 retry \`hyv welcome\` when online${detail ? ` (${detail})` : ` (HTTP ${response.status})`}`
|
|
11951
|
-
));
|
|
11974
|
+
return true;
|
|
11952
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
|
+
));
|
|
11953
11980
|
} catch (err) {
|
|
11954
11981
|
console.log(import_chalk12.default.yellow(
|
|
11955
|
-
` profile saved locally \u2014 retry \`hyv
|
|
11982
|
+
` profile saved locally \u2014 retry \`hyv sync\` (${err?.message || "sync failed"})`
|
|
11956
11983
|
));
|
|
11957
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);
|
|
11958
12033
|
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
11959
|
-
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/
|
|
12034
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/app/billing" }));
|
|
11960
12035
|
await briefPause();
|
|
11961
12036
|
markStepComplete("signup");
|
|
11962
12037
|
console.log(import_chalk12.default.dim("\n you're signed in \u2014 pick a plan in billing, no second login.\n"));
|
|
11963
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
|
+
}
|
|
11964
12061
|
async function runInteractiveWelcome() {
|
|
11965
12062
|
recordEvent("welcome_interactive");
|
|
11966
12063
|
console.log("\n" + buildWelcomeHeader());
|
|
11967
12064
|
try {
|
|
12065
|
+
const shortcut = await maybeRunPaidWelcomeShortcut();
|
|
12066
|
+
if (shortcut)
|
|
12067
|
+
return;
|
|
11968
12068
|
const profileName = await stepName();
|
|
11969
12069
|
await stepSamples(profileName);
|
|
11970
12070
|
await stepTest(profileName);
|
|
@@ -11991,7 +12091,7 @@ function getMcpWelcomeResponse(args2) {
|
|
|
11991
12091
|
}
|
|
11992
12092
|
return buildWelcomeGuide({ profileName: args2.profile, forLlm: true });
|
|
11993
12093
|
}
|
|
11994
|
-
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;
|
|
11995
12095
|
var init_welcome_flow = __esm({
|
|
11996
12096
|
"src/lib/welcome-flow.ts"() {
|
|
11997
12097
|
"use strict";
|
|
@@ -12008,10 +12108,12 @@ var init_welcome_flow = __esm({
|
|
|
12008
12108
|
init_terminal_ui();
|
|
12009
12109
|
init_config();
|
|
12010
12110
|
init_auth();
|
|
12111
|
+
init_access();
|
|
12011
12112
|
init_scan();
|
|
12012
12113
|
init_free_paid();
|
|
12013
12114
|
init_telemetry();
|
|
12014
12115
|
init_document_text();
|
|
12116
|
+
PROFILE_SYNC_TIMEOUT_MS = 9e4;
|
|
12015
12117
|
WELCOME_TAGLINE = "Hold Your Voice \u2014 make your AI agents sound exactly like you.";
|
|
12016
12118
|
FLOW_STEPS = [
|
|
12017
12119
|
{ n: 1, key: "name", title: "name your profile", hint: "pick a short name \u2014 e.g. my-voice" },
|
|
@@ -12136,6 +12238,54 @@ In conclusion, the key to success is to empower your team with actionable insigh
|
|
|
12136
12238
|
}
|
|
12137
12239
|
});
|
|
12138
12240
|
|
|
12241
|
+
// src/lib/billing-upgrade.ts
|
|
12242
|
+
var billing_upgrade_exports = {};
|
|
12243
|
+
__export(billing_upgrade_exports, {
|
|
12244
|
+
openBillingUpgrade: () => openBillingUpgrade
|
|
12245
|
+
});
|
|
12246
|
+
async function openBillingUpgrade(opts = {}) {
|
|
12247
|
+
const plan = opts.plan || "individual";
|
|
12248
|
+
const next = `/app/billing?checkout=${plan}`;
|
|
12249
|
+
const token = getToken();
|
|
12250
|
+
if (!token) {
|
|
12251
|
+
console.log(import_chalk14.default.cyan("\nSign in to upgrade \u2014 opening browser...\n"));
|
|
12252
|
+
try {
|
|
12253
|
+
await authenticateWithBrowser();
|
|
12254
|
+
} catch {
|
|
12255
|
+
console.log(import_chalk14.default.yellow("Sign-in cancelled or failed."));
|
|
12256
|
+
console.log(import_chalk14.default.dim(`Visit ${DASHBOARD_BILLING_URL} after running hyv init`));
|
|
12257
|
+
return;
|
|
12258
|
+
}
|
|
12259
|
+
}
|
|
12260
|
+
const access = await getAccessState();
|
|
12261
|
+
if (access.hasPaidPlan) {
|
|
12262
|
+
console.log(import_chalk14.default.green(`
|
|
12263
|
+
\u2713 You already have a paid plan (${access.plan}).`));
|
|
12264
|
+
console.log(import_chalk14.default.dim("Manage billing: hyv plan --manage\n"));
|
|
12265
|
+
return;
|
|
12266
|
+
}
|
|
12267
|
+
console.log(import_chalk14.default.cyan("\nOpening billing in your dashboard ($1 first month)...\n"));
|
|
12268
|
+
try {
|
|
12269
|
+
await openAuthenticatedDashboard({ next });
|
|
12270
|
+
console.log(import_chalk14.default.green("\n\u2713 Dashboard opened \u2014 pick a plan in billing"));
|
|
12271
|
+
console.log(import_chalk14.default.dim("Checkout opens automatically when you arrive from the CLI."));
|
|
12272
|
+
} catch {
|
|
12273
|
+
console.log(import_chalk14.default.yellow("Could not open dashboard automatically."));
|
|
12274
|
+
console.log(import_chalk14.default.dim(`Visit https://holdyourvoice.com${next} after hyv init`));
|
|
12275
|
+
}
|
|
12276
|
+
}
|
|
12277
|
+
var import_chalk14;
|
|
12278
|
+
var init_billing_upgrade = __esm({
|
|
12279
|
+
"src/lib/billing-upgrade.ts"() {
|
|
12280
|
+
"use strict";
|
|
12281
|
+
import_chalk14 = __toESM(require_source());
|
|
12282
|
+
init_access();
|
|
12283
|
+
init_config();
|
|
12284
|
+
init_auth();
|
|
12285
|
+
init_free_paid();
|
|
12286
|
+
}
|
|
12287
|
+
});
|
|
12288
|
+
|
|
12139
12289
|
// node_modules/glob/dist/commonjs/index.min.js
|
|
12140
12290
|
var require_index_min = __commonJS({
|
|
12141
12291
|
"node_modules/glob/dist/commonjs/index.min.js"(exports2) {
|
|
@@ -15817,7 +15967,7 @@ function registerStatusCommand(program3) {
|
|
|
15817
15967
|
if (latest && current !== "unknown" && compareSemver(current, latest) < 0) {
|
|
15818
15968
|
console.log(import_chalk7.default.bold("\nUpdate"));
|
|
15819
15969
|
console.log(import_chalk7.default.cyan(` ${current} \u2192 ${latest} available`));
|
|
15820
|
-
console.log(import_chalk7.default.dim(" Run: hyv
|
|
15970
|
+
console.log(import_chalk7.default.dim(" Run: npm i -g @holdyourvoice/hyv@latest"));
|
|
15821
15971
|
}
|
|
15822
15972
|
console.log("");
|
|
15823
15973
|
});
|
|
@@ -16913,7 +17063,7 @@ function generateLocalProfileFromStats(name, stats) {
|
|
|
16913
17063
|
}
|
|
16914
17064
|
|
|
16915
17065
|
// src/commands/plan.ts
|
|
16916
|
-
var
|
|
17066
|
+
var import_chalk15 = __toESM(require_source());
|
|
16917
17067
|
init_config();
|
|
16918
17068
|
init_auth();
|
|
16919
17069
|
var import_open2 = __toESM(require_open());
|
|
@@ -16928,10 +17078,10 @@ function registerPlanCommand(program3) {
|
|
|
16928
17078
|
}
|
|
16929
17079
|
const token = getToken();
|
|
16930
17080
|
if (!token) {
|
|
16931
|
-
console.log(
|
|
16932
|
-
console.log(
|
|
17081
|
+
console.log(import_chalk15.default.yellow("\nNot authenticated \u2014 free tier still works.\n"));
|
|
17082
|
+
console.log(import_chalk15.default.dim(" hyv scan draft.md | hyv welcome | npx @holdyourvoice/hyv scan draft.md"));
|
|
16933
17083
|
printFreePaidMatrix({ compact: true });
|
|
16934
|
-
console.log(
|
|
17084
|
+
console.log(import_chalk15.default.dim(" Run `hyv init` for profiles + learning.\n"));
|
|
16935
17085
|
return;
|
|
16936
17086
|
}
|
|
16937
17087
|
if (options.upgrade) {
|
|
@@ -16944,20 +17094,20 @@ function registerPlanCommand(program3) {
|
|
|
16944
17094
|
await showPlan();
|
|
16945
17095
|
}
|
|
16946
17096
|
} catch (error) {
|
|
16947
|
-
console.error(
|
|
17097
|
+
console.error(import_chalk15.default.red(`
|
|
16948
17098
|
Error: ${error.message}`));
|
|
16949
17099
|
process.exit(1);
|
|
16950
17100
|
}
|
|
16951
17101
|
});
|
|
16952
17102
|
}
|
|
16953
17103
|
async function showPlan() {
|
|
16954
|
-
console.log(
|
|
17104
|
+
console.log(import_chalk15.default.bold("\nSubscription Plan\n"));
|
|
16955
17105
|
const response = await authenticatedRequest(
|
|
16956
17106
|
cliApiUrl("/cli/heartbeat"),
|
|
16957
17107
|
{ method: "GET" }
|
|
16958
17108
|
);
|
|
16959
17109
|
if (response.status !== 200) {
|
|
16960
|
-
console.log(
|
|
17110
|
+
console.log(import_chalk15.default.yellow("Could not fetch plan info."));
|
|
16961
17111
|
return;
|
|
16962
17112
|
}
|
|
16963
17113
|
const data = response.data;
|
|
@@ -16975,39 +17125,31 @@ async function showPlan() {
|
|
|
16975
17125
|
team: "$29/mo",
|
|
16976
17126
|
agency: "Custom"
|
|
16977
17127
|
};
|
|
16978
|
-
console.log(
|
|
16979
|
-
console.log(
|
|
16980
|
-
console.log(
|
|
17128
|
+
console.log(import_chalk15.default.dim("Plan:"), import_chalk15.default.bold(planNames[plan] || plan));
|
|
17129
|
+
console.log(import_chalk15.default.dim("Price:"), planPrices[plan] || "-");
|
|
17130
|
+
console.log(import_chalk15.default.dim("Status:"), data.subscription_status || "none");
|
|
16981
17131
|
if (license) {
|
|
16982
|
-
console.log(
|
|
17132
|
+
console.log(import_chalk15.default.dim("License:"), license.key_hint);
|
|
16983
17133
|
}
|
|
16984
17134
|
const access = await getAccessState();
|
|
16985
|
-
console.log(
|
|
16986
|
-
console.log(
|
|
17135
|
+
console.log(import_chalk15.default.bold("\nFree tier (always)"));
|
|
17136
|
+
console.log(import_chalk15.default.dim(" local scan, fix, check, mcp, all web tools \u2014 hyv welcome"));
|
|
16987
17137
|
if (plan === "none" || !access.hasPaidPlan) {
|
|
16988
|
-
console.log(
|
|
16989
|
-
console.log(
|
|
16990
|
-
console.log(
|
|
16991
|
-
console.log(
|
|
17138
|
+
console.log(import_chalk15.default.bold("\nUpgrade unlocks"));
|
|
17139
|
+
console.log(import_chalk15.default.dim(" profiles, learning loop, hybrid analysis, rich rewrites"));
|
|
17140
|
+
console.log(import_chalk15.default.dim(` ${PRICING_URL}`));
|
|
17141
|
+
console.log(import_chalk15.default.dim("\n hyv plan --upgrade | hyv plan --free for full matrix"));
|
|
16992
17142
|
} else {
|
|
16993
17143
|
console.log("\nManage your subscription:");
|
|
16994
|
-
console.log(
|
|
17144
|
+
console.log(import_chalk15.default.dim(" hyv plan --manage"));
|
|
16995
17145
|
}
|
|
16996
17146
|
}
|
|
16997
17147
|
async function upgradePlan() {
|
|
16998
|
-
|
|
16999
|
-
|
|
17000
|
-
await openAuthenticatedDashboard({ next: "/dashboard?tab=billing" });
|
|
17001
|
-
console.log(import_chalk14.default.green("\n\u2713 Dashboard opened \u2014 you're already signed in"));
|
|
17002
|
-
console.log(import_chalk14.default.dim("Pick a plan in billing. No second login."));
|
|
17003
|
-
} catch {
|
|
17004
|
-
console.log(import_chalk14.default.yellow("Could not open dashboard automatically."));
|
|
17005
|
-
console.log(import_chalk14.default.dim(`Visit ${DASHBOARD_BILLING_URL} after running hyv init`));
|
|
17006
|
-
console.log(import_chalk14.default.dim(`Or see plans: ${PRICING_URL}`));
|
|
17007
|
-
}
|
|
17148
|
+
const { openBillingUpgrade: openBillingUpgrade2 } = await Promise.resolve().then(() => (init_billing_upgrade(), billing_upgrade_exports));
|
|
17149
|
+
await openBillingUpgrade2({ plan: "individual" });
|
|
17008
17150
|
}
|
|
17009
17151
|
async function openBillingPortal() {
|
|
17010
|
-
console.log(
|
|
17152
|
+
console.log(import_chalk15.default.cyan("\nOpening billing portal...\n"));
|
|
17011
17153
|
const response = await authenticatedRequest(
|
|
17012
17154
|
cliApiUrl("/cli/subscribe/manage"),
|
|
17013
17155
|
{ method: "POST" }
|
|
@@ -17016,41 +17158,41 @@ async function openBillingPortal() {
|
|
|
17016
17158
|
const data = response.data;
|
|
17017
17159
|
const portalUrl = data.portal_url;
|
|
17018
17160
|
if (portalUrl) {
|
|
17019
|
-
console.log(
|
|
17161
|
+
console.log(import_chalk15.default.dim("Opening browser..."));
|
|
17020
17162
|
await (0, import_open2.default)(assertSafeOpenUrl(portalUrl));
|
|
17021
|
-
console.log(
|
|
17163
|
+
console.log(import_chalk15.default.green("\n\u2713 Billing portal opened"));
|
|
17022
17164
|
} else {
|
|
17023
|
-
console.log(
|
|
17165
|
+
console.log(import_chalk15.default.yellow("No portal URL received."));
|
|
17024
17166
|
}
|
|
17025
17167
|
} else {
|
|
17026
|
-
console.log(
|
|
17027
|
-
console.log(
|
|
17168
|
+
console.log(import_chalk15.default.yellow("Could not open billing portal."));
|
|
17169
|
+
console.log(import_chalk15.default.dim(`Visit ${DASHBOARD_BILLING_URL} to manage billing.`));
|
|
17028
17170
|
}
|
|
17029
17171
|
}
|
|
17030
17172
|
async function downgradePlan() {
|
|
17031
|
-
console.log(
|
|
17173
|
+
console.log(import_chalk15.default.yellow("\nDowngrade Plan\n"));
|
|
17032
17174
|
console.log("To downgrade your plan, please visit:");
|
|
17033
|
-
console.log(
|
|
17175
|
+
console.log(import_chalk15.default.dim(` ${DASHBOARD_BILLING_URL}`));
|
|
17034
17176
|
console.log("\nOr contact support at shashank@holdyourvoice.com");
|
|
17035
17177
|
}
|
|
17036
17178
|
|
|
17037
17179
|
// src/commands/scan.ts
|
|
17038
|
-
var
|
|
17180
|
+
var import_chalk18 = __toESM(require_source());
|
|
17039
17181
|
init_pipeline();
|
|
17040
17182
|
init_local_profile();
|
|
17041
17183
|
init_access();
|
|
17042
17184
|
|
|
17043
17185
|
// src/lib/output.ts
|
|
17044
|
-
var
|
|
17186
|
+
var import_chalk16 = __toESM(require_source());
|
|
17045
17187
|
var c = {
|
|
17046
|
-
dim: (s) =>
|
|
17047
|
-
bold: (s) =>
|
|
17048
|
-
accent: (s) =>
|
|
17049
|
-
green: (s) =>
|
|
17050
|
-
red: (s) =>
|
|
17051
|
-
yellow: (s) =>
|
|
17052
|
-
cyan: (s) =>
|
|
17053
|
-
white: (s) =>
|
|
17188
|
+
dim: (s) => import_chalk16.default.dim(s),
|
|
17189
|
+
bold: (s) => import_chalk16.default.bold(s),
|
|
17190
|
+
accent: (s) => import_chalk16.default.hex("#C4441A")(s),
|
|
17191
|
+
green: (s) => import_chalk16.default.green(s),
|
|
17192
|
+
red: (s) => import_chalk16.default.red(s),
|
|
17193
|
+
yellow: (s) => import_chalk16.default.yellow(s),
|
|
17194
|
+
cyan: (s) => import_chalk16.default.cyan(s),
|
|
17195
|
+
white: (s) => import_chalk16.default.white(s)
|
|
17054
17196
|
};
|
|
17055
17197
|
function logo() {
|
|
17056
17198
|
return `${c.bold("hold your ")}${c.accent("voice")}`;
|
|
@@ -17198,7 +17340,7 @@ async function runHybridAnalysis(text, profile, opts = {}) {
|
|
|
17198
17340
|
}
|
|
17199
17341
|
|
|
17200
17342
|
// src/commands/history.ts
|
|
17201
|
-
var
|
|
17343
|
+
var import_chalk17 = __toESM(require_source());
|
|
17202
17344
|
var fs17 = __toESM(require("fs"));
|
|
17203
17345
|
var path16 = __toESM(require("path"));
|
|
17204
17346
|
init_config();
|
|
@@ -17250,7 +17392,7 @@ function registerHistoryCommand(program3) {
|
|
|
17250
17392
|
if (fs17.existsSync(HISTORY_FILE)) {
|
|
17251
17393
|
fs17.unlinkSync(HISTORY_FILE);
|
|
17252
17394
|
}
|
|
17253
|
-
console.log(
|
|
17395
|
+
console.log(import_chalk17.default.green("\n\u2713 History cleared"));
|
|
17254
17396
|
return;
|
|
17255
17397
|
}
|
|
17256
17398
|
let entries = readHistory();
|
|
@@ -17264,14 +17406,14 @@ function registerHistoryCommand(program3) {
|
|
|
17264
17406
|
const limit = parseInt(options.limit, 10);
|
|
17265
17407
|
entries = entries.slice(-limit);
|
|
17266
17408
|
if (entries.length === 0) {
|
|
17267
|
-
console.log(
|
|
17409
|
+
console.log(import_chalk17.default.dim("\nNo scan history yet. Run hyv scan or hyv score to start tracking."));
|
|
17268
17410
|
return;
|
|
17269
17411
|
}
|
|
17270
17412
|
if (options.format === "json") {
|
|
17271
17413
|
console.log(JSON.stringify(entries, null, 2));
|
|
17272
17414
|
return;
|
|
17273
17415
|
}
|
|
17274
|
-
console.log(
|
|
17416
|
+
console.log(import_chalk17.default.bold(`
|
|
17275
17417
|
score history (last ${entries.length} scans)
|
|
17276
17418
|
`));
|
|
17277
17419
|
if (options.chart) {
|
|
@@ -17283,7 +17425,7 @@ function registerHistoryCommand(program3) {
|
|
|
17283
17425
|
if (min !== max) {
|
|
17284
17426
|
console.log(` ${min} \u2524`);
|
|
17285
17427
|
}
|
|
17286
|
-
console.log(
|
|
17428
|
+
console.log(import_chalk17.default.dim(` \u2514${"\u2500".repeat(sl.length + 1)}`));
|
|
17287
17429
|
console.log("");
|
|
17288
17430
|
}
|
|
17289
17431
|
const scores = entries.map((e) => e.score);
|
|
@@ -17296,22 +17438,22 @@ function registerHistoryCommand(program3) {
|
|
|
17296
17438
|
const firstAvg = firstHalf.reduce((s, e) => s + e.score, 0) / (firstHalf.length || 1);
|
|
17297
17439
|
const secondAvg = secondHalf.reduce((s, e) => s + e.score, 0) / (secondHalf.length || 1);
|
|
17298
17440
|
const trend = Math.round(secondAvg - firstAvg);
|
|
17299
|
-
const trendStr = trend > 0 ?
|
|
17300
|
-
console.log(
|
|
17301
|
-
console.log(
|
|
17302
|
-
console.log(
|
|
17441
|
+
const trendStr = trend > 0 ? import_chalk17.default.green(`\u2191 improving (+${trend})`) : trend < 0 ? import_chalk17.default.red(`\u2193 declining (${trend})`) : import_chalk17.default.dim("\u2192 stable");
|
|
17442
|
+
console.log(import_chalk17.default.dim(` avg: ${avg} best: ${best.score} worst: ${worst.score}`));
|
|
17443
|
+
console.log(import_chalk17.default.dim(` trend: ${trendStr}`));
|
|
17444
|
+
console.log(import_chalk17.default.bold("\n recent:\n"));
|
|
17303
17445
|
const recent = entries.slice(-10).reverse();
|
|
17304
17446
|
for (const entry of recent) {
|
|
17305
17447
|
const time = new Date(entry.timestamp).toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit" });
|
|
17306
|
-
const icon = entry.issues === 0 ?
|
|
17307
|
-
const score = entry.score < 60 ?
|
|
17308
|
-
const issues = entry.issues > 0 ?
|
|
17448
|
+
const icon = entry.issues === 0 ? import_chalk17.default.green("\u2713") : import_chalk17.default.red("\u25CF");
|
|
17449
|
+
const score = entry.score < 60 ? import_chalk17.default.red(`${entry.score}/100`) : entry.score < 80 ? import_chalk17.default.yellow(`${entry.score}/100`) : import_chalk17.default.green(`${entry.score}/100`);
|
|
17450
|
+
const issues = entry.issues > 0 ? import_chalk17.default.red(`${entry.issues} issues`) : import_chalk17.default.dim("clean");
|
|
17309
17451
|
const file = path16.basename(entry.file).slice(0, 25).padEnd(25);
|
|
17310
|
-
console.log(` ${
|
|
17452
|
+
console.log(` ${import_chalk17.default.dim(time)} ${icon} ${file} ${score} ${issues}`);
|
|
17311
17453
|
}
|
|
17312
17454
|
console.log("");
|
|
17313
17455
|
} catch (error) {
|
|
17314
|
-
console.error(
|
|
17456
|
+
console.error(import_chalk17.default.red(`Error: ${error.message}`));
|
|
17315
17457
|
process.exit(1);
|
|
17316
17458
|
}
|
|
17317
17459
|
});
|
|
@@ -17326,7 +17468,7 @@ function registerScanCommand(program3) {
|
|
|
17326
17468
|
const profile = await loadProfileForCommand(options.profile);
|
|
17327
17469
|
const { text, path: filePath } = readText(file);
|
|
17328
17470
|
if (!text.trim()) {
|
|
17329
|
-
console.warn(
|
|
17471
|
+
console.warn(import_chalk18.default.yellow("File is empty or contains only whitespace."));
|
|
17330
17472
|
process.exit(0);
|
|
17331
17473
|
}
|
|
17332
17474
|
const ignoreRules = options.ignore ? new Set(options.ignore.split(",").map((r) => r.trim())) : /* @__PURE__ */ new Set();
|
|
@@ -17369,26 +17511,26 @@ function registerScanCommand(program3) {
|
|
|
17369
17511
|
}, null, 2));
|
|
17370
17512
|
} else {
|
|
17371
17513
|
if (signals.length === 0) {
|
|
17372
|
-
console.log(
|
|
17514
|
+
console.log(import_chalk18.default.green(`
|
|
17373
17515
|
\u2713 No issues found in ${filePath}`));
|
|
17374
|
-
console.log(
|
|
17516
|
+
console.log(import_chalk18.default.dim(` score: ${score}/100`));
|
|
17375
17517
|
} else {
|
|
17376
|
-
console.log(
|
|
17518
|
+
console.log(import_chalk18.default.bold(`
|
|
17377
17519
|
hyv scan ${filePath}`));
|
|
17378
17520
|
if (profile) {
|
|
17379
|
-
console.log(
|
|
17521
|
+
console.log(import_chalk18.default.dim(` profile: ${profile.slug || profile.name}${hasRichProfile(profile) ? " (full)" : ""}`));
|
|
17380
17522
|
}
|
|
17381
17523
|
if (analysis.message) {
|
|
17382
|
-
console.log(
|
|
17524
|
+
console.log(import_chalk18.default.dim(` engine: ${analysis.message}`));
|
|
17383
17525
|
}
|
|
17384
17526
|
console.log("");
|
|
17385
17527
|
printGroupedSignals(signals, profile);
|
|
17386
|
-
console.log(
|
|
17528
|
+
console.log(import_chalk18.default.yellow(`
|
|
17387
17529
|
${signals.length} issues (${signals.filter((s) => s.severity === "red").length} red, ${signals.filter((s) => s.severity === "yellow").length} yellow)`));
|
|
17388
|
-
console.log(
|
|
17389
|
-
console.log(
|
|
17530
|
+
console.log(import_chalk18.default.dim(` score: ${score}/100`));
|
|
17531
|
+
console.log(import_chalk18.default.dim(`
|
|
17390
17532
|
fix: hyv fix ${file}`));
|
|
17391
|
-
console.log(
|
|
17533
|
+
console.log(import_chalk18.default.dim(` diff: hyv diff ${file}
|
|
17392
17534
|
`));
|
|
17393
17535
|
}
|
|
17394
17536
|
await maybeShowLimitedModeHint(!!profile);
|
|
@@ -17406,14 +17548,14 @@ hyv scan ${filePath}`));
|
|
|
17406
17548
|
process.exit(2);
|
|
17407
17549
|
}
|
|
17408
17550
|
} catch (error) {
|
|
17409
|
-
console.error(
|
|
17551
|
+
console.error(import_chalk18.default.red(`Error: ${error.message}`));
|
|
17410
17552
|
process.exit(1);
|
|
17411
17553
|
}
|
|
17412
17554
|
});
|
|
17413
17555
|
}
|
|
17414
17556
|
|
|
17415
17557
|
// src/commands/doctor.ts
|
|
17416
|
-
var
|
|
17558
|
+
var import_chalk19 = __toESM(require_source());
|
|
17417
17559
|
var fs19 = __toESM(require("fs"));
|
|
17418
17560
|
var path18 = __toESM(require("path"));
|
|
17419
17561
|
var os9 = __toESM(require("os"));
|
|
@@ -17579,112 +17721,112 @@ function readMcpHyv(configFile) {
|
|
|
17579
17721
|
}
|
|
17580
17722
|
function registerDoctorCommand(program3) {
|
|
17581
17723
|
program3.command("doctor").description("Diagnose CLI health: engine, cache, auth, agents").option("--fix-agents", "Re-run agent config copy (idempotent)").option("--verify-hosts", "Spawn MCP using each host config and report pass/fail").action(async (opts) => {
|
|
17582
|
-
console.log(
|
|
17724
|
+
console.log(import_chalk19.default.bold("\nhold your voice \u2014 doctor\n"));
|
|
17583
17725
|
let issues = 0;
|
|
17584
17726
|
let fixed = 0;
|
|
17585
|
-
console.log(
|
|
17727
|
+
console.log(import_chalk19.default.dim(`engine: ${getEngineLabel()} (node ${process.version})`));
|
|
17586
17728
|
if (isLocalOnlyMode()) {
|
|
17587
|
-
console.log(
|
|
17729
|
+
console.log(import_chalk19.default.yellow(" local-only mode: HYV_LOCAL_ONLY is set"));
|
|
17588
17730
|
}
|
|
17589
17731
|
const access = await getAccessState();
|
|
17590
17732
|
const profile = await loadProfileForCommand();
|
|
17591
|
-
console.log(
|
|
17592
|
-
console.log(
|
|
17593
|
-
console.log(
|
|
17733
|
+
console.log(import_chalk19.default.dim(`mode: ${formatModeLabel(access, hasRichProfile(profile))}`));
|
|
17734
|
+
console.log(import_chalk19.default.dim("tip: run hyv welcome for free capabilities\n"));
|
|
17735
|
+
console.log(import_chalk19.default.dim("checking cli installation..."));
|
|
17594
17736
|
const cliPath = process.argv[1];
|
|
17595
17737
|
if (cliPath && fs19.existsSync(cliPath)) {
|
|
17596
|
-
console.log(
|
|
17738
|
+
console.log(import_chalk19.default.green(" \u2713 cli installed"));
|
|
17597
17739
|
} else {
|
|
17598
|
-
console.log(
|
|
17740
|
+
console.log(import_chalk19.default.red(" \u2717 cli not found"));
|
|
17599
17741
|
issues++;
|
|
17600
17742
|
}
|
|
17601
|
-
console.log(
|
|
17743
|
+
console.log(import_chalk19.default.dim("checking .hyv directory..."));
|
|
17602
17744
|
if (fs19.existsSync(HYV_DIR)) {
|
|
17603
|
-
console.log(
|
|
17745
|
+
console.log(import_chalk19.default.green(" \u2713 .hyv directory exists"));
|
|
17604
17746
|
} else {
|
|
17605
|
-
console.log(
|
|
17747
|
+
console.log(import_chalk19.default.yellow(" ! .hyv directory missing \u2014 creating..."));
|
|
17606
17748
|
fs19.mkdirSync(HYV_DIR, { recursive: true, mode: 448 });
|
|
17607
17749
|
fixed++;
|
|
17608
17750
|
}
|
|
17609
|
-
console.log(
|
|
17751
|
+
console.log(import_chalk19.default.dim("checking cache..."));
|
|
17610
17752
|
const diskProfiles = listDiskCachedProfiles();
|
|
17611
17753
|
const syncMeta = path18.join(CACHE_DIR2, "sync-meta.json");
|
|
17612
17754
|
if (diskProfiles.length > 0 || fs19.existsSync(syncMeta)) {
|
|
17613
|
-
console.log(
|
|
17755
|
+
console.log(import_chalk19.default.green(` \u2713 profile cache (${diskProfiles.length} full profile(s))`));
|
|
17614
17756
|
if (fs19.existsSync(syncMeta)) {
|
|
17615
17757
|
try {
|
|
17616
17758
|
const meta = JSON.parse(fs19.readFileSync(syncMeta, "utf-8"));
|
|
17617
|
-
console.log(
|
|
17759
|
+
console.log(import_chalk19.default.dim(` last sync: ${meta.synced_at || "unknown"}`));
|
|
17618
17760
|
} catch {
|
|
17619
17761
|
}
|
|
17620
17762
|
}
|
|
17621
17763
|
} else {
|
|
17622
|
-
console.log(
|
|
17764
|
+
console.log(import_chalk19.default.dim(" - no full profile cache (free local engine still works)"));
|
|
17623
17765
|
}
|
|
17624
|
-
console.log(
|
|
17766
|
+
console.log(import_chalk19.default.dim("checking file permissions..."));
|
|
17625
17767
|
if (fs19.existsSync(HYV_DIR)) {
|
|
17626
17768
|
const hyvMode = fs19.statSync(HYV_DIR).mode & 511;
|
|
17627
17769
|
if ((hyvMode & 63) === 0) {
|
|
17628
|
-
console.log(
|
|
17770
|
+
console.log(import_chalk19.default.green(" \u2713 .hyv directory permissions"));
|
|
17629
17771
|
} else {
|
|
17630
|
-
console.log(
|
|
17631
|
-
console.log(
|
|
17772
|
+
console.log(import_chalk19.default.yellow(" ! .hyv directory is world/group accessible"));
|
|
17773
|
+
console.log(import_chalk19.default.dim(" run: chmod 700 ~/.hyv"));
|
|
17632
17774
|
issues++;
|
|
17633
17775
|
}
|
|
17634
17776
|
}
|
|
17635
17777
|
if (fs19.existsSync(AUTH_FILE)) {
|
|
17636
17778
|
if (isOwnerOnlyFile(AUTH_FILE)) {
|
|
17637
|
-
console.log(
|
|
17779
|
+
console.log(import_chalk19.default.green(" \u2713 auth.json permissions"));
|
|
17638
17780
|
} else {
|
|
17639
|
-
console.log(
|
|
17640
|
-
console.log(
|
|
17781
|
+
console.log(import_chalk19.default.yellow(" ! auth.json is world/group readable"));
|
|
17782
|
+
console.log(import_chalk19.default.dim(" run: chmod 600 ~/.hyv/auth.json"));
|
|
17641
17783
|
issues++;
|
|
17642
17784
|
}
|
|
17643
17785
|
}
|
|
17644
|
-
console.log(
|
|
17786
|
+
console.log(import_chalk19.default.dim("checking authentication..."));
|
|
17645
17787
|
if (isInitialized()) {
|
|
17646
17788
|
const auth = readAuth();
|
|
17647
17789
|
if (auth) {
|
|
17648
|
-
console.log(
|
|
17649
|
-
console.log(
|
|
17790
|
+
console.log(import_chalk19.default.green(" \u2713 authenticated"));
|
|
17791
|
+
console.log(import_chalk19.default.dim(` email: ${auth.user?.email || "unknown"}`));
|
|
17650
17792
|
const session = await checkSession();
|
|
17651
17793
|
if (session.valid) {
|
|
17652
|
-
console.log(
|
|
17653
|
-
console.log(
|
|
17794
|
+
console.log(import_chalk19.default.green(" \u2713 session valid"));
|
|
17795
|
+
console.log(import_chalk19.default.dim(` plan: ${session.plan || "none"}`));
|
|
17654
17796
|
} else {
|
|
17655
|
-
console.log(
|
|
17656
|
-
console.log(
|
|
17797
|
+
console.log(import_chalk19.default.red(" \u2717 session expired"));
|
|
17798
|
+
console.log(import_chalk19.default.dim(" run: hyv init"));
|
|
17657
17799
|
issues++;
|
|
17658
17800
|
}
|
|
17659
17801
|
} else {
|
|
17660
|
-
console.log(
|
|
17802
|
+
console.log(import_chalk19.default.red(" \u2717 auth data missing"));
|
|
17661
17803
|
issues++;
|
|
17662
17804
|
}
|
|
17663
17805
|
} else {
|
|
17664
|
-
console.log(
|
|
17665
|
-
console.log(
|
|
17806
|
+
console.log(import_chalk19.default.yellow(" ! not authenticated (free local scan works)"));
|
|
17807
|
+
console.log(import_chalk19.default.dim(" run: hyv init for profiles + learning"));
|
|
17666
17808
|
}
|
|
17667
|
-
console.log(
|
|
17809
|
+
console.log(import_chalk19.default.dim("checking voice profile..."));
|
|
17668
17810
|
const voiceMd = path18.join(HYV_DIR, "voice.md");
|
|
17669
17811
|
const hasVoiceMd = fs19.existsSync(voiceMd) && fs19.readFileSync(voiceMd, "utf-8").trim().length > 50;
|
|
17670
17812
|
const profileFiles = fs19.existsSync(PROFILES_DIR) ? fs19.readdirSync(PROFILES_DIR).filter((f) => f.endsWith(".md") && f !== "voice.md") : [];
|
|
17671
17813
|
if (hasVoiceMd || profileFiles.length > 0 || diskProfiles.length > 0) {
|
|
17672
17814
|
if (hasVoiceMd)
|
|
17673
|
-
console.log(
|
|
17815
|
+
console.log(import_chalk19.default.green(" \u2713 voice.md exists"));
|
|
17674
17816
|
if (profileFiles.length > 0)
|
|
17675
|
-
console.log(
|
|
17817
|
+
console.log(import_chalk19.default.green(` \u2713 ${profileFiles.length} markdown profile(s)`));
|
|
17676
17818
|
if (diskProfiles.length > 0)
|
|
17677
|
-
console.log(
|
|
17819
|
+
console.log(import_chalk19.default.green(` \u2713 ${diskProfiles.length} full cached profile(s)`));
|
|
17678
17820
|
} else {
|
|
17679
|
-
console.log(
|
|
17680
|
-
console.log(
|
|
17821
|
+
console.log(import_chalk19.default.yellow(" ! no voice profile (optional for free scan)"));
|
|
17822
|
+
console.log(import_chalk19.default.dim(" run: hyv new <name> or hyv init"));
|
|
17681
17823
|
}
|
|
17682
|
-
console.log(
|
|
17824
|
+
console.log(import_chalk19.default.dim("checking agent configurations..."));
|
|
17683
17825
|
const cursorLegacyRule = path18.join(HOME, ".cursor", "rules", "hyv.md");
|
|
17684
17826
|
const cursorRule = path18.join(HOME, ".cursor", "rules", "hyv.mdc");
|
|
17685
17827
|
if (fs19.existsSync(cursorLegacyRule) && fs19.existsSync(cursorRule)) {
|
|
17686
|
-
console.log(
|
|
17687
|
-
console.log(
|
|
17828
|
+
console.log(import_chalk19.default.yellow(" ! stale cursor rule ~/.cursor/rules/hyv.md (use hyv.mdc)"));
|
|
17829
|
+
console.log(import_chalk19.default.dim(" run: rm ~/.cursor/rules/hyv.md (or hyv doctor --fix-agents)"));
|
|
17688
17830
|
issues++;
|
|
17689
17831
|
}
|
|
17690
17832
|
const agMcpFile = path18.join(HOME, ".gemini", "config", "mcp_config.json");
|
|
@@ -17704,9 +17846,9 @@ function registerDoctorCommand(program3) {
|
|
|
17704
17846
|
];
|
|
17705
17847
|
for (const agent of agentChecks) {
|
|
17706
17848
|
if (agent.ok) {
|
|
17707
|
-
console.log(
|
|
17849
|
+
console.log(import_chalk19.default.green(` \u2713 ${agent.name}`));
|
|
17708
17850
|
} else {
|
|
17709
|
-
console.log(
|
|
17851
|
+
console.log(import_chalk19.default.dim(` - ${agent.name} not configured`));
|
|
17710
17852
|
}
|
|
17711
17853
|
}
|
|
17712
17854
|
if (opts.fixAgents) {
|
|
@@ -17714,84 +17856,84 @@ function registerDoctorCommand(program3) {
|
|
|
17714
17856
|
const pkgDir = path18.resolve(__dirname, "..");
|
|
17715
17857
|
const { setupAgents } = require(path18.join(pkgDir, "scripts", "postinstall-lib.js"));
|
|
17716
17858
|
const result = setupAgents({ pkgDir, quiet: true });
|
|
17717
|
-
console.log(
|
|
17859
|
+
console.log(import_chalk19.default.green(` \u2713 re-ran agent setup (${result.configured.join(", ") || "no changes"})`));
|
|
17718
17860
|
if (result.warnings.length) {
|
|
17719
|
-
console.log(
|
|
17861
|
+
console.log(import_chalk19.default.yellow(` notes: ${result.warnings.join("; ")}`));
|
|
17720
17862
|
}
|
|
17721
17863
|
fixed++;
|
|
17722
17864
|
} catch (err) {
|
|
17723
|
-
console.log(
|
|
17865
|
+
console.log(import_chalk19.default.yellow(` ! could not re-run agent setup: ${err.message}`));
|
|
17724
17866
|
}
|
|
17725
17867
|
}
|
|
17726
|
-
console.log(
|
|
17868
|
+
console.log(import_chalk19.default.dim("checking mcp server..."));
|
|
17727
17869
|
const claudeMcp = readMcpHyv(path18.join(claudeDesktopDir(), "claude_desktop_config.json"));
|
|
17728
17870
|
const cursorMcp = readMcpHyv(path18.join(HOME, ".cursor", "mcp.json"));
|
|
17729
17871
|
if (claudeMcp || cursorMcp) {
|
|
17730
17872
|
if (claudeMcp)
|
|
17731
|
-
console.log(
|
|
17873
|
+
console.log(import_chalk19.default.green(" \u2713 mcp configured for claude desktop"));
|
|
17732
17874
|
if (cursorMcp)
|
|
17733
|
-
console.log(
|
|
17875
|
+
console.log(import_chalk19.default.green(" \u2713 mcp configured for cursor"));
|
|
17734
17876
|
} else {
|
|
17735
|
-
console.log(
|
|
17877
|
+
console.log(import_chalk19.default.yellow(" ! mcp not configured \u2014 run: hyv doctor --fix-agents or hyv mcp --setup"));
|
|
17736
17878
|
issues++;
|
|
17737
17879
|
}
|
|
17738
17880
|
try {
|
|
17739
17881
|
const stdio = await testMcpStdioSubprocess();
|
|
17740
17882
|
if (stdio.ok && (stdio.toolCount || 0) >= 10) {
|
|
17741
|
-
console.log(
|
|
17883
|
+
console.log(import_chalk19.default.green(` \u2713 mcp stdio subprocess healthy (${stdio.toolCount} tools)`));
|
|
17742
17884
|
} else if (stdio.ok) {
|
|
17743
|
-
console.log(
|
|
17885
|
+
console.log(import_chalk19.default.yellow(` ! mcp stdio ok but only ${stdio.toolCount || 0} tools`));
|
|
17744
17886
|
issues++;
|
|
17745
17887
|
} else {
|
|
17746
|
-
console.log(
|
|
17747
|
-
console.log(
|
|
17888
|
+
console.log(import_chalk19.default.red(" \u2717 mcp stdio subprocess failed"));
|
|
17889
|
+
console.log(import_chalk19.default.dim(" run: hyv mcp --test"));
|
|
17748
17890
|
issues++;
|
|
17749
17891
|
}
|
|
17750
17892
|
} catch (err) {
|
|
17751
|
-
console.log(
|
|
17893
|
+
console.log(import_chalk19.default.red(` \u2717 mcp stdio probe failed: ${err.message}`));
|
|
17752
17894
|
issues++;
|
|
17753
17895
|
}
|
|
17754
17896
|
if (opts.verifyHosts) {
|
|
17755
|
-
console.log(
|
|
17897
|
+
console.log(import_chalk19.default.dim("verifying mcp hosts (spawns subprocess per config)..."));
|
|
17756
17898
|
try {
|
|
17757
17899
|
const pkgDir = path18.resolve(__dirname, "..");
|
|
17758
17900
|
const { verifyAgentHosts } = require(path18.join(pkgDir, "scripts", "verify-agent-hosts.js"));
|
|
17759
17901
|
const hosts = await verifyAgentHosts();
|
|
17760
17902
|
for (const host of hosts) {
|
|
17761
17903
|
if (host.kind === "manual") {
|
|
17762
|
-
console.log(
|
|
17904
|
+
console.log(import_chalk19.default.yellow(` \u25CB ${host.label} \u2014 ${host.detail}`));
|
|
17763
17905
|
continue;
|
|
17764
17906
|
}
|
|
17765
17907
|
if (host.ok) {
|
|
17766
|
-
console.log(
|
|
17908
|
+
console.log(import_chalk19.default.green(` \u2713 ${host.label}${host.detail ? ` (${host.detail})` : ""}`));
|
|
17767
17909
|
} else if (host.kind === "file") {
|
|
17768
|
-
console.log(
|
|
17910
|
+
console.log(import_chalk19.default.dim(` - ${host.label} \u2014 ${host.detail || "missing"}`));
|
|
17769
17911
|
} else {
|
|
17770
|
-
console.log(
|
|
17912
|
+
console.log(import_chalk19.default.red(` \u2717 ${host.label} \u2014 ${host.detail || "failed"}`));
|
|
17771
17913
|
issues++;
|
|
17772
17914
|
}
|
|
17773
17915
|
}
|
|
17774
17916
|
} catch (err) {
|
|
17775
|
-
console.log(
|
|
17917
|
+
console.log(import_chalk19.default.red(` \u2717 host verification failed: ${err.message}`));
|
|
17776
17918
|
issues++;
|
|
17777
17919
|
}
|
|
17778
17920
|
}
|
|
17779
17921
|
console.log("");
|
|
17780
17922
|
if (issues === 0 && fixed === 0) {
|
|
17781
|
-
console.log(
|
|
17923
|
+
console.log(import_chalk19.default.green("\u2713 everything looks good!"));
|
|
17782
17924
|
} else if (fixed > 0) {
|
|
17783
|
-
console.log(
|
|
17925
|
+
console.log(import_chalk19.default.green(`\u2713 fixed ${fixed} issue(s)`));
|
|
17784
17926
|
if (issues > 0)
|
|
17785
|
-
console.log(
|
|
17927
|
+
console.log(import_chalk19.default.yellow(`! ${issues} issue(s) remaining`));
|
|
17786
17928
|
} else {
|
|
17787
|
-
console.log(
|
|
17929
|
+
console.log(import_chalk19.default.yellow(`! ${issues} issue(s) found`));
|
|
17788
17930
|
}
|
|
17789
|
-
console.log(
|
|
17931
|
+
console.log(import_chalk19.default.dim("\nfree scan: hyv scan draft.md | full tour: hyv welcome\n"));
|
|
17790
17932
|
});
|
|
17791
17933
|
}
|
|
17792
17934
|
|
|
17793
17935
|
// src/commands/rename.ts
|
|
17794
|
-
var
|
|
17936
|
+
var import_chalk20 = __toESM(require_source());
|
|
17795
17937
|
init_config();
|
|
17796
17938
|
init_auth();
|
|
17797
17939
|
function registerRenameCommand(program3) {
|
|
@@ -17799,26 +17941,26 @@ function registerRenameCommand(program3) {
|
|
|
17799
17941
|
try {
|
|
17800
17942
|
const trimmedName = newName.trim();
|
|
17801
17943
|
if (!trimmedName) {
|
|
17802
|
-
console.log(
|
|
17803
|
-
console.log(
|
|
17944
|
+
console.log(import_chalk20.default.red("\nerror: what do you want to name your profile?\n"));
|
|
17945
|
+
console.log(import_chalk20.default.dim(' example: hyv rename "my brand voice"\n'));
|
|
17804
17946
|
process.exit(1);
|
|
17805
17947
|
return;
|
|
17806
17948
|
}
|
|
17807
17949
|
if (trimmedName.length > 100) {
|
|
17808
|
-
console.log(
|
|
17950
|
+
console.log(import_chalk20.default.red("\nerror: name is too long \u2014 keep it under 100 characters\n"));
|
|
17809
17951
|
process.exit(1);
|
|
17810
17952
|
return;
|
|
17811
17953
|
}
|
|
17812
17954
|
if (!/^[a-zA-Z0-9\s\-_'&.]+$/.test(trimmedName)) {
|
|
17813
|
-
console.log(
|
|
17814
|
-
console.log(
|
|
17955
|
+
console.log(import_chalk20.default.red("\nerror: name contains invalid characters\n"));
|
|
17956
|
+
console.log(import_chalk20.default.dim(" allowed: letters, numbers, spaces, hyphens, underscores, apostrophes\n"));
|
|
17815
17957
|
process.exit(1);
|
|
17816
17958
|
return;
|
|
17817
17959
|
}
|
|
17818
17960
|
const token = getToken();
|
|
17819
17961
|
if (!token) {
|
|
17820
|
-
console.log(
|
|
17821
|
-
console.log(
|
|
17962
|
+
console.log(import_chalk20.default.red("\nerror: you're not signed in yet\n"));
|
|
17963
|
+
console.log(import_chalk20.default.dim(" run: hyv init\n"));
|
|
17822
17964
|
process.exit(1);
|
|
17823
17965
|
return;
|
|
17824
17966
|
}
|
|
@@ -17834,16 +17976,16 @@ function registerRenameCommand(program3) {
|
|
|
17834
17976
|
);
|
|
17835
17977
|
if (response.status === 200) {
|
|
17836
17978
|
const data = response.data;
|
|
17837
|
-
console.log(
|
|
17979
|
+
console.log(import_chalk20.default.green(`
|
|
17838
17980
|
\u2713 profile renamed to ${data.profile?.name || trimmedName}
|
|
17839
17981
|
`));
|
|
17840
17982
|
} else {
|
|
17841
|
-
console.log(
|
|
17983
|
+
console.log(import_chalk20.default.red(`
|
|
17842
17984
|
error: server returned ${response.status}
|
|
17843
17985
|
`));
|
|
17844
17986
|
}
|
|
17845
17987
|
} catch (error) {
|
|
17846
|
-
console.error(
|
|
17988
|
+
console.error(import_chalk20.default.red(`
|
|
17847
17989
|
error: ${error.message}
|
|
17848
17990
|
`));
|
|
17849
17991
|
process.exit(1);
|
|
@@ -17852,7 +17994,7 @@ error: ${error.message}
|
|
|
17852
17994
|
}
|
|
17853
17995
|
|
|
17854
17996
|
// src/commands/fix.ts
|
|
17855
|
-
var
|
|
17997
|
+
var import_chalk22 = __toESM(require_source());
|
|
17856
17998
|
init_pipeline();
|
|
17857
17999
|
init_local_profile();
|
|
17858
18000
|
init_access();
|
|
@@ -17862,14 +18004,14 @@ init_config();
|
|
|
17862
18004
|
var fs20 = __toESM(require("fs"));
|
|
17863
18005
|
var path19 = __toESM(require("path"));
|
|
17864
18006
|
var readline2 = __toESM(require("readline"));
|
|
17865
|
-
var
|
|
18007
|
+
var import_chalk21 = __toESM(require_source());
|
|
17866
18008
|
async function confirmDestructiveWrite(options) {
|
|
17867
18009
|
if (options.yes)
|
|
17868
18010
|
return true;
|
|
17869
18011
|
const label = options.target ? `${options.action} (${options.target})` : options.action;
|
|
17870
18012
|
if (!process.stdin.isTTY) {
|
|
17871
|
-
console.error(
|
|
17872
|
-
console.error(
|
|
18013
|
+
console.error(import_chalk21.default.red("\nRefusing destructive write without confirmation (non-interactive)."));
|
|
18014
|
+
console.error(import_chalk21.default.dim(" Re-run with --yes to create .bak backups and proceed.\n"));
|
|
17873
18015
|
return false;
|
|
17874
18016
|
}
|
|
17875
18017
|
const question = `
|
|
@@ -17905,9 +18047,9 @@ function registerFixCommand(program3) {
|
|
|
17905
18047
|
if (options.format === "json") {
|
|
17906
18048
|
console.log(JSON.stringify({ file: filePath, autoFixes: 0, llmIssues: result.stats.needsLLM, changes: [] }));
|
|
17907
18049
|
} else {
|
|
17908
|
-
console.log(
|
|
18050
|
+
console.log(import_chalk22.default.green("\n\u2713 No auto-fixable issues found."));
|
|
17909
18051
|
if (result.stats.needsLLM > 0) {
|
|
17910
|
-
console.log(
|
|
18052
|
+
console.log(import_chalk22.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
17911
18053
|
}
|
|
17912
18054
|
}
|
|
17913
18055
|
return;
|
|
@@ -17921,16 +18063,16 @@ function registerFixCommand(program3) {
|
|
|
17921
18063
|
fixed: options.dryRun ? void 0 : result.fixed
|
|
17922
18064
|
}, null, 2));
|
|
17923
18065
|
} else {
|
|
17924
|
-
console.log(
|
|
18066
|
+
console.log(import_chalk22.default.dim(`
|
|
17925
18067
|
hyv fix ${filePath}
|
|
17926
18068
|
`));
|
|
17927
18069
|
for (const change of result.changes) {
|
|
17928
|
-
console.log(
|
|
18070
|
+
console.log(import_chalk22.default.dim(` Line ${change.line}: `) + import_chalk22.default.red(change.before) + import_chalk22.default.dim(" \u2192 ") + import_chalk22.default.green(change.after));
|
|
17929
18071
|
}
|
|
17930
|
-
console.log(
|
|
18072
|
+
console.log(import_chalk22.default.green(`
|
|
17931
18073
|
\u2713 ${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} applied`));
|
|
17932
18074
|
if (result.stats.needsLLM > 0) {
|
|
17933
|
-
console.log(
|
|
18075
|
+
console.log(import_chalk22.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
17934
18076
|
}
|
|
17935
18077
|
}
|
|
17936
18078
|
if (!options.dryRun) {
|
|
@@ -17944,7 +18086,7 @@ hyv fix ${filePath}
|
|
|
17944
18086
|
process.exit(1);
|
|
17945
18087
|
}
|
|
17946
18088
|
const backupPath = writeInPlaceWithBackup(filePath, result.fixed);
|
|
17947
|
-
console.log(
|
|
18089
|
+
console.log(import_chalk22.default.dim(` Written to ${filePath} (backup: ${backupBasename(filePath)})`));
|
|
17948
18090
|
saveLastEditSession({
|
|
17949
18091
|
original_path: filePath,
|
|
17950
18092
|
edited_path: filePath,
|
|
@@ -17952,7 +18094,7 @@ hyv fix ${filePath}
|
|
|
17952
18094
|
edited_text: result.fixed,
|
|
17953
18095
|
profile: options.profile
|
|
17954
18096
|
});
|
|
17955
|
-
console.log(
|
|
18097
|
+
console.log(import_chalk22.default.dim(" Tip: hyv reinforce --last to teach your profile from this edit"));
|
|
17956
18098
|
} else if (filePath === "stdin" || !options.inPlace) {
|
|
17957
18099
|
process.stdout.write("\n" + result.fixed + "\n");
|
|
17958
18100
|
if (filePath !== "stdin") {
|
|
@@ -17968,14 +18110,14 @@ hyv fix ${filePath}
|
|
|
17968
18110
|
}
|
|
17969
18111
|
await maybeShowLimitedModeHint(!!profile);
|
|
17970
18112
|
} catch (error) {
|
|
17971
|
-
console.error(
|
|
18113
|
+
console.error(import_chalk22.default.red(`Error: ${error.message}`));
|
|
17972
18114
|
process.exit(1);
|
|
17973
18115
|
}
|
|
17974
18116
|
});
|
|
17975
18117
|
}
|
|
17976
18118
|
|
|
17977
18119
|
// src/commands/check.ts
|
|
17978
|
-
var
|
|
18120
|
+
var import_chalk23 = __toESM(require_source());
|
|
17979
18121
|
init_pipeline();
|
|
17980
18122
|
init_local_profile();
|
|
17981
18123
|
init_access();
|
|
@@ -17987,18 +18129,18 @@ function registerCheckCommand(program3) {
|
|
|
17987
18129
|
if (text === "-") {
|
|
17988
18130
|
const fs31 = require("fs");
|
|
17989
18131
|
if (process.stdin.isTTY) {
|
|
17990
|
-
console.error(
|
|
18132
|
+
console.error(import_chalk23.default.red("No input provided. Pipe content or pass text as argument."));
|
|
17991
18133
|
process.exit(1);
|
|
17992
18134
|
}
|
|
17993
18135
|
inputText = fs31.readFileSync(0, "utf-8");
|
|
17994
18136
|
}
|
|
17995
18137
|
if (!inputText.trim()) {
|
|
17996
|
-
console.error(
|
|
18138
|
+
console.error(import_chalk23.default.red("No text provided."));
|
|
17997
18139
|
process.exit(1);
|
|
17998
18140
|
}
|
|
17999
18141
|
const fs30 = require("fs");
|
|
18000
18142
|
if (text !== "-" && fs30.existsSync(text)) {
|
|
18001
|
-
console.log(
|
|
18143
|
+
console.log(import_chalk23.default.yellow(`"${text}" looks like a file. Did you mean: hyv scan ${text}`));
|
|
18002
18144
|
process.exit(1);
|
|
18003
18145
|
}
|
|
18004
18146
|
const result = runPipeline(inputText, profile, false);
|
|
@@ -18022,30 +18164,30 @@ function registerCheckCommand(program3) {
|
|
|
18022
18164
|
}, null, 2));
|
|
18023
18165
|
} else {
|
|
18024
18166
|
if (result.stats.totalSignals === 0) {
|
|
18025
|
-
console.log(
|
|
18026
|
-
console.log(
|
|
18167
|
+
console.log(import_chalk23.default.green("\n\u2713 Clean \u2014 no AI patterns found."));
|
|
18168
|
+
console.log(import_chalk23.default.dim(` score: ${result.score}/100`));
|
|
18027
18169
|
} else {
|
|
18028
18170
|
console.log("");
|
|
18029
18171
|
printGroupedSignals(result.signalMap.signals.slice(0, 15), profile);
|
|
18030
18172
|
if (result.signalMap.signals.length > 15) {
|
|
18031
|
-
console.log(
|
|
18173
|
+
console.log(import_chalk23.default.dim(` ... and ${result.signalMap.signals.length - 15} more`));
|
|
18032
18174
|
}
|
|
18033
|
-
console.log(
|
|
18175
|
+
console.log(import_chalk23.default.yellow(`
|
|
18034
18176
|
${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow)`));
|
|
18035
|
-
console.log(
|
|
18177
|
+
console.log(import_chalk23.default.dim(` score: ${result.score}/100`));
|
|
18036
18178
|
}
|
|
18037
18179
|
await maybeShowLimitedModeHint(!!profile);
|
|
18038
18180
|
}
|
|
18039
18181
|
process.exit(result.stats.totalSignals > 0 ? 1 : 0);
|
|
18040
18182
|
} catch (error) {
|
|
18041
|
-
console.error(
|
|
18183
|
+
console.error(import_chalk23.default.red(`Error: ${error.message}`));
|
|
18042
18184
|
process.exit(1);
|
|
18043
18185
|
}
|
|
18044
18186
|
});
|
|
18045
18187
|
}
|
|
18046
18188
|
|
|
18047
18189
|
// src/commands/score.ts
|
|
18048
|
-
var
|
|
18190
|
+
var import_chalk24 = __toESM(require_source());
|
|
18049
18191
|
init_pipeline();
|
|
18050
18192
|
init_local_profile();
|
|
18051
18193
|
function registerScoreCommand(program3) {
|
|
@@ -18070,14 +18212,14 @@ function registerScoreCommand(program3) {
|
|
|
18070
18212
|
process.exit(1);
|
|
18071
18213
|
}
|
|
18072
18214
|
} catch (error) {
|
|
18073
|
-
console.error(
|
|
18215
|
+
console.error(import_chalk24.default.red(`Error: ${error.message}`));
|
|
18074
18216
|
process.exit(1);
|
|
18075
18217
|
}
|
|
18076
18218
|
});
|
|
18077
18219
|
}
|
|
18078
18220
|
|
|
18079
18221
|
// src/commands/diff.ts
|
|
18080
|
-
var
|
|
18222
|
+
var import_chalk25 = __toESM(require_source());
|
|
18081
18223
|
init_pipeline();
|
|
18082
18224
|
init_local_profile();
|
|
18083
18225
|
function registerDiffCommand(program3) {
|
|
@@ -18087,9 +18229,9 @@ function registerDiffCommand(program3) {
|
|
|
18087
18229
|
const { text, path: filePath } = readText(file);
|
|
18088
18230
|
const result = runPipeline(text, profile, true);
|
|
18089
18231
|
if (result.changes.length === 0) {
|
|
18090
|
-
console.log(
|
|
18232
|
+
console.log(import_chalk25.default.green("\n\u2713 No auto-fixable changes."));
|
|
18091
18233
|
if (result.stats.needsLLM > 0) {
|
|
18092
|
-
console.log(
|
|
18234
|
+
console.log(import_chalk25.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite`));
|
|
18093
18235
|
}
|
|
18094
18236
|
return;
|
|
18095
18237
|
}
|
|
@@ -18104,42 +18246,42 @@ function registerDiffCommand(program3) {
|
|
|
18104
18246
|
const originalLines = text.split("\n");
|
|
18105
18247
|
const fixedLines = result.fixed.split("\n");
|
|
18106
18248
|
const contextN = parseInt(options.context, 10);
|
|
18107
|
-
console.log(
|
|
18108
|
-
console.log(
|
|
18249
|
+
console.log(import_chalk25.default.dim(`--- ${filePath}`));
|
|
18250
|
+
console.log(import_chalk25.default.dim(`+++ ${filePath} (fixed)`));
|
|
18109
18251
|
for (const change of result.changes) {
|
|
18110
18252
|
const lineIdx = change.line - 1;
|
|
18111
18253
|
const start = Math.max(0, lineIdx - contextN);
|
|
18112
18254
|
const end = Math.min(originalLines.length, lineIdx + contextN + 1);
|
|
18113
|
-
console.log(
|
|
18255
|
+
console.log(import_chalk25.default.dim(`@@ -${start + 1},${end - start} +${start + 1},${end - start} @@`));
|
|
18114
18256
|
for (let i = start; i < end; i++) {
|
|
18115
18257
|
if (i === lineIdx) {
|
|
18116
|
-
console.log(
|
|
18117
|
-
console.log(
|
|
18258
|
+
console.log(import_chalk25.default.red(`-${originalLines[i]}`));
|
|
18259
|
+
console.log(import_chalk25.default.green(`+${fixedLines[i]}`));
|
|
18118
18260
|
} else {
|
|
18119
|
-
console.log(
|
|
18261
|
+
console.log(import_chalk25.default.dim(` ${originalLines[i]}`));
|
|
18120
18262
|
}
|
|
18121
18263
|
}
|
|
18122
18264
|
}
|
|
18123
|
-
console.log(
|
|
18265
|
+
console.log(import_chalk25.default.green(`
|
|
18124
18266
|
${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} available`));
|
|
18125
|
-
console.log(
|
|
18267
|
+
console.log(import_chalk25.default.dim(` run: hyv fix ${file} -i to apply`));
|
|
18126
18268
|
if (options.apply && filePath !== "stdin") {
|
|
18127
18269
|
const fs30 = require("fs");
|
|
18128
18270
|
const path27 = require("path");
|
|
18129
18271
|
const backupPath = filePath + ".bak";
|
|
18130
18272
|
fs30.copyFileSync(filePath, backupPath);
|
|
18131
18273
|
fs30.writeFileSync(filePath, result.fixed);
|
|
18132
|
-
console.log(
|
|
18274
|
+
console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${path27.basename(backupPath)}`));
|
|
18133
18275
|
}
|
|
18134
18276
|
} catch (error) {
|
|
18135
|
-
console.error(
|
|
18277
|
+
console.error(import_chalk25.default.red(`Error: ${error.message}`));
|
|
18136
18278
|
process.exit(1);
|
|
18137
18279
|
}
|
|
18138
18280
|
});
|
|
18139
18281
|
}
|
|
18140
18282
|
|
|
18141
18283
|
// src/commands/rules.ts
|
|
18142
|
-
var
|
|
18284
|
+
var import_chalk26 = __toESM(require_source());
|
|
18143
18285
|
init_config();
|
|
18144
18286
|
var RULE_CATALOG = [
|
|
18145
18287
|
// AI Overused Words
|
|
@@ -18233,7 +18375,7 @@ function registerRulesCommand(program3) {
|
|
|
18233
18375
|
for (const id of ids)
|
|
18234
18376
|
disabledRules.delete(id);
|
|
18235
18377
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
18236
|
-
console.log(
|
|
18378
|
+
console.log(import_chalk26.default.green(`
|
|
18237
18379
|
\u2713 Enabled: ${ids.join(", ")}`));
|
|
18238
18380
|
return;
|
|
18239
18381
|
}
|
|
@@ -18242,13 +18384,13 @@ function registerRulesCommand(program3) {
|
|
|
18242
18384
|
for (const id of ids)
|
|
18243
18385
|
disabledRules.add(id);
|
|
18244
18386
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
18245
|
-
console.log(
|
|
18387
|
+
console.log(import_chalk26.default.green(`
|
|
18246
18388
|
\u2713 Disabled: ${ids.join(", ")}`));
|
|
18247
18389
|
return;
|
|
18248
18390
|
}
|
|
18249
18391
|
if (options.reset) {
|
|
18250
18392
|
writeConfig({ ...config, disabled_rules: [] });
|
|
18251
|
-
console.log(
|
|
18393
|
+
console.log(import_chalk26.default.green("\n\u2713 All rules reset to default (enabled)"));
|
|
18252
18394
|
return;
|
|
18253
18395
|
}
|
|
18254
18396
|
let rules = [...RULE_CATALOG];
|
|
@@ -18276,34 +18418,34 @@ function registerRulesCommand(program3) {
|
|
|
18276
18418
|
}
|
|
18277
18419
|
console.log("");
|
|
18278
18420
|
for (const [cat, catRules] of categories) {
|
|
18279
|
-
console.log(
|
|
18421
|
+
console.log(import_chalk26.default.bold(` ${cat} rules (${catRules.length})
|
|
18280
18422
|
`));
|
|
18281
|
-
console.log(
|
|
18282
|
-
console.log(
|
|
18423
|
+
console.log(import_chalk26.default.dim(" ID Sev AutoFix Status"));
|
|
18424
|
+
console.log(import_chalk26.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
18283
18425
|
for (const rule of catRules) {
|
|
18284
|
-
const sev = rule.severity === "red" ?
|
|
18285
|
-
const fix = rule.autoFixable ?
|
|
18286
|
-
const enabled2 = disabledRules.has(rule.id) ?
|
|
18426
|
+
const sev = rule.severity === "red" ? import_chalk26.default.red("red") : import_chalk26.default.yellow("yel");
|
|
18427
|
+
const fix = rule.autoFixable ? import_chalk26.default.green(" \u2713") : import_chalk26.default.dim(" \u2717");
|
|
18428
|
+
const enabled2 = disabledRules.has(rule.id) ? import_chalk26.default.red(" \u2717 disabled") : import_chalk26.default.green(" \u2713 enabled");
|
|
18287
18429
|
const id = rule.id.padEnd(24);
|
|
18288
|
-
console.log(` ${
|
|
18430
|
+
console.log(` ${import_chalk26.default.dim(id)} ${sev} ${fix} ${enabled2}`);
|
|
18289
18431
|
}
|
|
18290
18432
|
console.log("");
|
|
18291
18433
|
}
|
|
18292
18434
|
const enabled = rules.filter((r) => !disabledRules.has(r.id)).length;
|
|
18293
18435
|
const disabled = rules.length - enabled;
|
|
18294
|
-
console.log(
|
|
18295
|
-
console.log(
|
|
18296
|
-
console.log(
|
|
18436
|
+
console.log(import_chalk26.default.dim(` ${rules.length} rules, ${enabled} enabled, ${disabled} disabled`));
|
|
18437
|
+
console.log(import_chalk26.default.dim(` toggle: hyv rules --disable <id>`));
|
|
18438
|
+
console.log(import_chalk26.default.dim(` reset: hyv rules --reset
|
|
18297
18439
|
`));
|
|
18298
18440
|
} catch (error) {
|
|
18299
|
-
console.error(
|
|
18441
|
+
console.error(import_chalk26.default.red(`Error: ${error.message}`));
|
|
18300
18442
|
process.exit(1);
|
|
18301
18443
|
}
|
|
18302
18444
|
});
|
|
18303
18445
|
}
|
|
18304
18446
|
|
|
18305
18447
|
// src/commands/batch.ts
|
|
18306
|
-
var
|
|
18448
|
+
var import_chalk27 = __toESM(require_source());
|
|
18307
18449
|
var fs21 = __toESM(require("fs"));
|
|
18308
18450
|
var path20 = __toESM(require("path"));
|
|
18309
18451
|
init_pipeline();
|
|
@@ -18312,13 +18454,13 @@ function registerBatchCommand(program3) {
|
|
|
18312
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) => {
|
|
18313
18455
|
try {
|
|
18314
18456
|
const profile = await loadProfileForCommand(options.profile);
|
|
18315
|
-
const
|
|
18316
|
-
const files =
|
|
18457
|
+
const { globSync } = require_index_min();
|
|
18458
|
+
const files = globSync(pattern, {
|
|
18317
18459
|
ignore: options.ignore ? options.ignore.split(",") : void 0,
|
|
18318
18460
|
nodir: true
|
|
18319
18461
|
});
|
|
18320
18462
|
if (files.length === 0) {
|
|
18321
|
-
console.log(
|
|
18463
|
+
console.log(import_chalk27.default.yellow(`
|
|
18322
18464
|
No files matching: ${pattern}`));
|
|
18323
18465
|
return;
|
|
18324
18466
|
}
|
|
@@ -18332,7 +18474,7 @@ No files matching: ${pattern}`));
|
|
|
18332
18474
|
process.exit(1);
|
|
18333
18475
|
}
|
|
18334
18476
|
if (options.format === "text") {
|
|
18335
|
-
console.log(
|
|
18477
|
+
console.log(import_chalk27.default.dim(`
|
|
18336
18478
|
scanning ${files.length} file${files.length === 1 ? "" : "s"}...
|
|
18337
18479
|
`));
|
|
18338
18480
|
}
|
|
@@ -18371,23 +18513,23 @@ No files matching: ${pattern}`));
|
|
|
18371
18513
|
}
|
|
18372
18514
|
} else {
|
|
18373
18515
|
for (const r of results) {
|
|
18374
|
-
const icon = r.issues > 0 ?
|
|
18375
|
-
const score = r.score < 60 ?
|
|
18376
|
-
const issueStr = r.issues > 0 ?
|
|
18516
|
+
const icon = r.issues > 0 ? import_chalk27.default.red("\u25CF") : import_chalk27.default.green("\u25CB");
|
|
18517
|
+
const score = r.score < 60 ? import_chalk27.default.red(r.score) : r.score < 80 ? import_chalk27.default.yellow(r.score) : import_chalk27.default.green(r.score);
|
|
18518
|
+
const issueStr = r.issues > 0 ? import_chalk27.default.red(`${r.issues} issues`) : import_chalk27.default.green("clean");
|
|
18377
18519
|
console.log(` ${icon} ${r.file.padEnd(40)} ${issueStr.padEnd(20)} score: ${score}`);
|
|
18378
18520
|
}
|
|
18379
18521
|
const withIssues = results.filter((r) => r.issues > 0).length;
|
|
18380
18522
|
const totalIssues = results.reduce((sum, r) => sum + r.issues, 0);
|
|
18381
18523
|
const worst = results.reduce((min, r) => r.score < min.score ? r : min, results[0]);
|
|
18382
|
-
console.log(
|
|
18524
|
+
console.log(import_chalk27.default.dim(`
|
|
18383
18525
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`));
|
|
18384
|
-
console.log(
|
|
18526
|
+
console.log(import_chalk27.default.dim(` ${results.length} files, ${withIssues} with issues, ${totalIssues} total issues`));
|
|
18385
18527
|
if (withIssues > 0) {
|
|
18386
|
-
console.log(
|
|
18528
|
+
console.log(import_chalk27.default.dim(` worst: ${worst.file} (${worst.score}/100)`));
|
|
18387
18529
|
}
|
|
18388
18530
|
if (options.fix && options.inPlace) {
|
|
18389
18531
|
const fixed = results.filter((r) => r.autoFixes > 0);
|
|
18390
|
-
console.log(
|
|
18532
|
+
console.log(import_chalk27.default.green(`
|
|
18391
18533
|
\u2713 ${fixed.reduce((sum, r) => sum + r.autoFixes, 0)} auto-fixes applied across ${fixed.length} files`));
|
|
18392
18534
|
}
|
|
18393
18535
|
}
|
|
@@ -18399,14 +18541,14 @@ No files matching: ${pattern}`));
|
|
|
18399
18541
|
if (belowThreshold)
|
|
18400
18542
|
process.exit(1);
|
|
18401
18543
|
} catch (error) {
|
|
18402
|
-
console.error(
|
|
18544
|
+
console.error(import_chalk27.default.red(`Error: ${error.message}`));
|
|
18403
18545
|
process.exit(1);
|
|
18404
18546
|
}
|
|
18405
18547
|
});
|
|
18406
18548
|
}
|
|
18407
18549
|
|
|
18408
18550
|
// src/commands/watch.ts
|
|
18409
|
-
var
|
|
18551
|
+
var import_chalk28 = __toESM(require_source());
|
|
18410
18552
|
var fs22 = __toESM(require("fs"));
|
|
18411
18553
|
var path21 = __toESM(require("path"));
|
|
18412
18554
|
init_pipeline();
|
|
@@ -18417,7 +18559,7 @@ function registerWatchCommand(program3) {
|
|
|
18417
18559
|
const profile = await loadProfileForCommand(options.profile);
|
|
18418
18560
|
const absPath = path21.resolve(file);
|
|
18419
18561
|
if (!fs22.existsSync(absPath)) {
|
|
18420
|
-
console.error(
|
|
18562
|
+
console.error(import_chalk28.default.red(`File not found: ${absPath}`));
|
|
18421
18563
|
process.exit(1);
|
|
18422
18564
|
}
|
|
18423
18565
|
if (options.command === "fix") {
|
|
@@ -18429,10 +18571,10 @@ function registerWatchCommand(program3) {
|
|
|
18429
18571
|
if (!confirmed)
|
|
18430
18572
|
process.exit(1);
|
|
18431
18573
|
}
|
|
18432
|
-
console.log(
|
|
18574
|
+
console.log(import_chalk28.default.dim(`
|
|
18433
18575
|
watching ${absPath}`));
|
|
18434
|
-
console.log(
|
|
18435
|
-
console.log(
|
|
18576
|
+
console.log(import_chalk28.default.dim(`command: ${options.command} debounce: ${options.debounce}ms`));
|
|
18577
|
+
console.log(import_chalk28.default.dim("ctrl+c to stop\n"));
|
|
18436
18578
|
let debounceTimer = null;
|
|
18437
18579
|
const debounceMs = parseInt(options.debounce, 10);
|
|
18438
18580
|
let scanCount = 0;
|
|
@@ -18443,38 +18585,38 @@ watching ${absPath}`));
|
|
|
18443
18585
|
const result = runPipeline(text, profile, options.command === "fix");
|
|
18444
18586
|
scanCount++;
|
|
18445
18587
|
const now = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
18446
|
-
console.log(
|
|
18588
|
+
console.log(import_chalk28.default.dim(`[${now}] saved \u2014 ${options.command}ing...`));
|
|
18447
18589
|
if (options.command === "score") {
|
|
18448
18590
|
const score = result.score;
|
|
18449
|
-
const color = score < 60 ?
|
|
18591
|
+
const color = score < 60 ? import_chalk28.default.red : score < 80 ? import_chalk28.default.yellow : import_chalk28.default.green;
|
|
18450
18592
|
console.log(` ${color(score + "/100")}`);
|
|
18451
18593
|
if (lastScore > 0 && score !== lastScore) {
|
|
18452
18594
|
const delta = score - lastScore;
|
|
18453
|
-
console.log(
|
|
18595
|
+
console.log(import_chalk28.default.dim(` ${delta > 0 ? "\u2191" : "\u2193"} ${Math.abs(delta)} from last scan`));
|
|
18454
18596
|
}
|
|
18455
18597
|
lastScore = score;
|
|
18456
18598
|
} else if (options.command === "fix") {
|
|
18457
18599
|
if (result.changes.length > 0) {
|
|
18458
18600
|
for (const change of result.changes) {
|
|
18459
|
-
console.log(
|
|
18601
|
+
console.log(import_chalk28.default.dim(` Line ${change.line}: `) + import_chalk28.default.red(change.before) + import_chalk28.default.dim(" \u2192 ") + import_chalk28.default.green(change.after));
|
|
18460
18602
|
}
|
|
18461
18603
|
ignoreWatchUntil = Date.now() + debounceMs + 200;
|
|
18462
18604
|
writeInPlaceWithBackup(absPath, result.fixed);
|
|
18463
|
-
console.log(
|
|
18605
|
+
console.log(import_chalk28.default.green(` \u2713 ${result.changes.length} auto-fixes applied`));
|
|
18464
18606
|
} else {
|
|
18465
|
-
console.log(
|
|
18607
|
+
console.log(import_chalk28.default.green(" \u2713 no auto-fixable issues"));
|
|
18466
18608
|
}
|
|
18467
18609
|
} else {
|
|
18468
18610
|
if (result.stats.totalSignals === 0) {
|
|
18469
|
-
console.log(
|
|
18611
|
+
console.log(import_chalk28.default.green(` \u2713 clean \u2014 score: ${result.score}/100`));
|
|
18470
18612
|
} else {
|
|
18471
|
-
console.log(
|
|
18613
|
+
console.log(import_chalk28.default.yellow(` ${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow) score: ${result.score}/100`));
|
|
18472
18614
|
for (const signal of result.signalMap.signals.slice(0, 3)) {
|
|
18473
|
-
const sev = signal.severity === "red" ?
|
|
18615
|
+
const sev = signal.severity === "red" ? import_chalk28.default.red("\u25CF") : import_chalk28.default.yellow("\u25CB");
|
|
18474
18616
|
console.log(` ${sev} line ${signal.line}: ${signal.id} \u2014 ${signal.suggestion}`);
|
|
18475
18617
|
}
|
|
18476
18618
|
if (result.signalMap.signals.length > 3) {
|
|
18477
|
-
console.log(
|
|
18619
|
+
console.log(import_chalk28.default.dim(` ... and ${result.signalMap.signals.length - 3} more`));
|
|
18478
18620
|
}
|
|
18479
18621
|
}
|
|
18480
18622
|
}
|
|
@@ -18491,21 +18633,21 @@ watching ${absPath}`));
|
|
|
18491
18633
|
debounceTimer = setTimeout(runScan, debounceMs);
|
|
18492
18634
|
});
|
|
18493
18635
|
process.on("SIGINT", () => {
|
|
18494
|
-
console.log(
|
|
18636
|
+
console.log(import_chalk28.default.dim(`
|
|
18495
18637
|
${scanCount} scans completed. exiting.`));
|
|
18496
18638
|
process.exit(0);
|
|
18497
18639
|
});
|
|
18498
18640
|
await new Promise(() => {
|
|
18499
18641
|
});
|
|
18500
18642
|
} catch (error) {
|
|
18501
|
-
console.error(
|
|
18643
|
+
console.error(import_chalk28.default.red(`Error: ${error.message}`));
|
|
18502
18644
|
process.exit(1);
|
|
18503
18645
|
}
|
|
18504
18646
|
});
|
|
18505
18647
|
}
|
|
18506
18648
|
|
|
18507
18649
|
// src/commands/demo.ts
|
|
18508
|
-
var
|
|
18650
|
+
var import_chalk29 = __toESM(require_source());
|
|
18509
18651
|
var fs23 = __toESM(require("fs"));
|
|
18510
18652
|
var SAMPLES = {
|
|
18511
18653
|
linkedin: {
|
|
@@ -18596,52 +18738,52 @@ function registerDemoCommand(program3) {
|
|
|
18596
18738
|
const style = options.clean ? "clean" : options.style;
|
|
18597
18739
|
const sample = SAMPLES[style];
|
|
18598
18740
|
if (!sample) {
|
|
18599
|
-
console.error(
|
|
18741
|
+
console.error(import_chalk29.default.red(`Unknown style: ${options.style}. Valid: ${Object.keys(SAMPLES).filter((k2) => k2 !== "clean").join(", ")}`));
|
|
18600
18742
|
process.exit(1);
|
|
18601
18743
|
}
|
|
18602
18744
|
if (options.output) {
|
|
18603
18745
|
const outputPath = require("path").resolve(options.output);
|
|
18604
18746
|
fs23.writeFileSync(outputPath, sample.text);
|
|
18605
|
-
console.log(
|
|
18747
|
+
console.log(import_chalk29.default.green(`
|
|
18606
18748
|
\u2713 Sample written to ${outputPath}`));
|
|
18607
18749
|
if (sample.patterns.length > 0) {
|
|
18608
|
-
console.log(
|
|
18750
|
+
console.log(import_chalk29.default.dim(` Contains ${sample.patterns.length} AI patterns: ${sample.patterns.slice(0, 5).join(", ")}...`));
|
|
18609
18751
|
}
|
|
18610
|
-
console.log(
|
|
18752
|
+
console.log(import_chalk29.default.dim(`
|
|
18611
18753
|
Scan it: hyv scan ${options.output}`));
|
|
18612
|
-
console.log(
|
|
18754
|
+
console.log(import_chalk29.default.dim(` Fix it: hyv fix ${options.output}`));
|
|
18613
18755
|
} else {
|
|
18614
|
-
console.log(
|
|
18756
|
+
console.log(import_chalk29.default.bold(`
|
|
18615
18757
|
\u2500\u2500\u2500 sample (${style}) \u2500\u2500\u2500
|
|
18616
18758
|
`));
|
|
18617
18759
|
console.log(sample.text);
|
|
18618
|
-
console.log(
|
|
18760
|
+
console.log(import_chalk29.default.dim(`
|
|
18619
18761
|
\u2500\u2500\u2500 end \u2500\u2500\u2500`));
|
|
18620
18762
|
if (sample.patterns.length > 0) {
|
|
18621
|
-
console.log(
|
|
18763
|
+
console.log(import_chalk29.default.dim(`
|
|
18622
18764
|
${sample.patterns.length} AI patterns embedded: ${sample.patterns.slice(0, 8).join(", ")}...`));
|
|
18623
18765
|
}
|
|
18624
|
-
console.log(
|
|
18766
|
+
console.log(import_chalk29.default.dim(`
|
|
18625
18767
|
Save to file: hyv demo --output demo.md`));
|
|
18626
|
-
console.log(
|
|
18627
|
-
console.log(
|
|
18768
|
+
console.log(import_chalk29.default.dim(` Scan it: hyv scan demo.md`));
|
|
18769
|
+
console.log(import_chalk29.default.dim(` Fix it: hyv fix demo.md
|
|
18628
18770
|
`));
|
|
18629
18771
|
}
|
|
18630
18772
|
} catch (error) {
|
|
18631
|
-
console.error(
|
|
18773
|
+
console.error(import_chalk29.default.red(`Error: ${error.message}`));
|
|
18632
18774
|
process.exit(1);
|
|
18633
18775
|
}
|
|
18634
18776
|
});
|
|
18635
18777
|
}
|
|
18636
18778
|
|
|
18637
18779
|
// src/commands/open.ts
|
|
18638
|
-
var
|
|
18780
|
+
var import_chalk30 = __toESM(require_source());
|
|
18639
18781
|
var PAGES = {
|
|
18640
18782
|
dashboard: "https://holdyourvoice.com/dashboard",
|
|
18641
18783
|
profiles: "https://holdyourvoice.com/dashboard?tab=profiles",
|
|
18642
|
-
pricing: "https://holdyourvoice.com/
|
|
18784
|
+
pricing: "https://holdyourvoice.com/app/billing",
|
|
18643
18785
|
settings: "https://holdyourvoice.com/dashboard",
|
|
18644
|
-
billing: "https://holdyourvoice.com/
|
|
18786
|
+
billing: "https://holdyourvoice.com/app/billing"
|
|
18645
18787
|
};
|
|
18646
18788
|
function registerOpenCommand(program3) {
|
|
18647
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) => {
|
|
@@ -18653,12 +18795,12 @@ function registerOpenCommand(program3) {
|
|
|
18653
18795
|
return;
|
|
18654
18796
|
}
|
|
18655
18797
|
const open3 = (await Promise.resolve().then(() => __toESM(require_open()))).default;
|
|
18656
|
-
console.log(
|
|
18798
|
+
console.log(import_chalk30.default.dim(`
|
|
18657
18799
|
Opening ${url}...`));
|
|
18658
18800
|
await open3(url);
|
|
18659
|
-
console.log(
|
|
18801
|
+
console.log(import_chalk30.default.green(" \u2713 Opened in browser\n"));
|
|
18660
18802
|
} catch (error) {
|
|
18661
|
-
console.error(
|
|
18803
|
+
console.error(import_chalk30.default.red(`Error: ${error.message}`));
|
|
18662
18804
|
process.exit(1);
|
|
18663
18805
|
}
|
|
18664
18806
|
});
|
|
@@ -18744,7 +18886,7 @@ function getWelcomeText(args2) {
|
|
|
18744
18886
|
}
|
|
18745
18887
|
|
|
18746
18888
|
// src/commands/content.ts
|
|
18747
|
-
var
|
|
18889
|
+
var import_chalk31 = __toESM(require_source());
|
|
18748
18890
|
init_free_paid();
|
|
18749
18891
|
var TEMPLATES = {
|
|
18750
18892
|
cursor: {
|
|
@@ -18818,62 +18960,28 @@ ${COMMUNITY_URL}`
|
|
|
18818
18960
|
function registerContentCommand(program3) {
|
|
18819
18961
|
program3.command("content").description("Blog outlines, CI snippets, and share templates").argument("[topic]", "cursor | agents | ci | share", "cursor").option("--list", "List available templates").action((topic, opts) => {
|
|
18820
18962
|
if (opts.list) {
|
|
18821
|
-
console.log(
|
|
18963
|
+
console.log(import_chalk31.default.bold("\nhyv content templates\n"));
|
|
18822
18964
|
for (const [key, t2] of Object.entries(TEMPLATES)) {
|
|
18823
|
-
console.log(
|
|
18965
|
+
console.log(import_chalk31.default.dim(` ${key}`) + ` \u2014 ${t2.title}`);
|
|
18824
18966
|
}
|
|
18825
18967
|
console.log("");
|
|
18826
18968
|
return;
|
|
18827
18969
|
}
|
|
18828
18970
|
const t = TEMPLATES[topic] || TEMPLATES.cursor;
|
|
18829
|
-
console.log(
|
|
18971
|
+
console.log(import_chalk31.default.bold(`
|
|
18830
18972
|
${t.title}
|
|
18831
18973
|
`));
|
|
18832
18974
|
console.log(t.body);
|
|
18833
|
-
console.log(
|
|
18975
|
+
console.log(import_chalk31.default.dim("\nBlog: https://holdyourvoice.com/blog\n"));
|
|
18834
18976
|
});
|
|
18835
18977
|
}
|
|
18836
18978
|
|
|
18837
18979
|
// src/commands/upgrade.ts
|
|
18838
|
-
|
|
18839
|
-
var import_child_process4 = require("child_process");
|
|
18840
|
-
init_version();
|
|
18980
|
+
init_billing_upgrade();
|
|
18841
18981
|
function registerUpgradeCommand(program3) {
|
|
18842
|
-
program3.command("upgrade").description("Upgrade to
|
|
18843
|
-
const
|
|
18844
|
-
|
|
18845
|
-
Current: ${getEngineLabel()}
|
|
18846
|
-
`));
|
|
18847
|
-
let latest = current;
|
|
18848
|
-
try {
|
|
18849
|
-
const out = (0, import_child_process4.execSync)("npm view @holdyourvoice/hyv version", { encoding: "utf-8", timeout: 15e3 });
|
|
18850
|
-
latest = out.trim();
|
|
18851
|
-
} catch {
|
|
18852
|
-
console.log(import_chalk31.default.yellow("Could not reach npm registry. Try: npm i -g @holdyourvoice/hyv@latest"));
|
|
18853
|
-
return;
|
|
18854
|
-
}
|
|
18855
|
-
const cmp = compareSemver(current, latest);
|
|
18856
|
-
if (cmp === 0) {
|
|
18857
|
-
console.log(import_chalk31.default.green("\u2713 You are on the latest version."));
|
|
18858
|
-
return;
|
|
18859
|
-
}
|
|
18860
|
-
if (cmp > 0) {
|
|
18861
|
-
console.log(import_chalk31.default.green(`\u2713 You are ahead of npm (published: ${latest}).`));
|
|
18862
|
-
return;
|
|
18863
|
-
}
|
|
18864
|
-
console.log(import_chalk31.default.cyan(`Update available: ${current} \u2192 ${latest}`));
|
|
18865
|
-
if (opts.check) {
|
|
18866
|
-
console.log(import_chalk31.default.dim("\nRun: hyv upgrade or npm i -g @holdyourvoice/hyv@latest\n"));
|
|
18867
|
-
return;
|
|
18868
|
-
}
|
|
18869
|
-
console.log(import_chalk31.default.dim("Installing..."));
|
|
18870
|
-
try {
|
|
18871
|
-
(0, import_child_process4.execSync)("npm i -g @holdyourvoice/hyv@latest", { stdio: "inherit" });
|
|
18872
|
-
console.log(import_chalk31.default.green("\n\u2713 Upgraded successfully. Restart your terminal.\n"));
|
|
18873
|
-
} catch {
|
|
18874
|
-
console.log(import_chalk31.default.red("\nUpgrade failed. Run manually: npm i -g @holdyourvoice/hyv@latest\n"));
|
|
18875
|
-
process.exit(1);
|
|
18876
|
-
}
|
|
18982
|
+
program3.command("upgrade").description("Upgrade to a paid plan (opens billing in your browser)").option("--plan <plan>", "Plan to checkout: individual or multiple", "individual").action(async (opts) => {
|
|
18983
|
+
const plan = opts.plan === "multiple" ? "multiple" : "individual";
|
|
18984
|
+
await openBillingUpgrade({ plan });
|
|
18877
18985
|
});
|
|
18878
18986
|
}
|
|
18879
18987
|
|