@holdyourvoice/hyv 2.9.11 → 2.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.js +398 -316
- package/package.json +3 -1
- package/scripts/install.ps1 +89 -0
- package/scripts/install.sh +155 -0
- package/scripts/postinstall-lib.js +163 -7
- package/scripts/postinstall.js +1 -0
package/dist/index.js
CHANGED
|
@@ -5385,7 +5385,7 @@ var init_free_paid = __esm({
|
|
|
5385
5385
|
"Rich profile-aware rewrite prompts (hyv rewrite)",
|
|
5386
5386
|
"Hybrid server analysis (hyv scan --server, MCP hyv_analyze)",
|
|
5387
5387
|
"Multiple profiles + team voices (Team plan)",
|
|
5388
|
-
"Dashboard at holdyourvoice.com/
|
|
5388
|
+
"Dashboard at holdyourvoice.com/dashboard"
|
|
5389
5389
|
];
|
|
5390
5390
|
FREE_WEB_TOOLS = [
|
|
5391
5391
|
{ name: "All free tools", url: "https://holdyourvoice.com/tools" },
|
|
@@ -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/dashboard?tab=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 || "/dashboard?tab=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 === "/app/billing" ? DASHBOARD_BILLING_URL : assertSafeOpenUrl(`https://holdyourvoice.com${nextPath}`);
|
|
5728
|
+
const billingUrl = nextPath === "/dashboard?tab=billing" || 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/dashboard?tab=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,7 @@ async function getAccessState() {
|
|
|
5943
5943
|
try {
|
|
5944
5944
|
const session = await checkSession();
|
|
5945
5945
|
const plan = (session.plan || "none").toLowerCase();
|
|
5946
|
-
const hasPaidPlan = session.valid && plan !== "none" && plan !== "free";
|
|
5946
|
+
const hasPaidPlan = session.valid && plan !== "none" && plan !== "free" && plan !== "expired" && plan !== "unknown";
|
|
5947
5947
|
const state = {
|
|
5948
5948
|
authenticated: session.valid,
|
|
5949
5949
|
hasPaidPlan,
|
|
@@ -5979,7 +5979,8 @@ async function requirePaidFeature(feature) {
|
|
|
5979
5979
|
throw new Error("can't reach the server. check your internet connection and try again.");
|
|
5980
5980
|
}
|
|
5981
5981
|
const plan = (data.plan || "none").toLowerCase();
|
|
5982
|
-
|
|
5982
|
+
const subStatus = String(data.subscription_status || data.status || "").toLowerCase();
|
|
5983
|
+
if (!data.plan || plan === "none" || plan === "free" || plan === "expired" || subStatus === "trialing" || subStatus === "none") {
|
|
5983
5984
|
throw new Error(FEATURE_MESSAGES[feature]);
|
|
5984
5985
|
}
|
|
5985
5986
|
}
|
|
@@ -5994,7 +5995,7 @@ async function maybeShowLimitedModeHint(hasProfile) {
|
|
|
5994
5995
|
} else if (!access.authenticated) {
|
|
5995
5996
|
console.log(import_chalk5.default.dim("\n local mode \u2014 free scan engine. profiles + learning: hyv init"));
|
|
5996
5997
|
} else {
|
|
5997
|
-
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv
|
|
5998
|
+
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv upgrade"));
|
|
5998
5999
|
}
|
|
5999
6000
|
}
|
|
6000
6001
|
function formatModeLabel(access, hasFullProfile) {
|
|
@@ -6017,10 +6018,10 @@ var init_access = __esm({
|
|
|
6017
6018
|
init_auth();
|
|
6018
6019
|
init_api();
|
|
6019
6020
|
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
|
|
6021
|
+
profiles: "syncing voice profiles from your account requires a paid plan. run: hyv upgrade",
|
|
6022
|
+
learning: "the learning loop (reinforce, add) requires a paid plan. run: hyv upgrade",
|
|
6023
|
+
premiumPrompts: "rich profile-aware rewrite prompts require a paid plan. run: hyv upgrade",
|
|
6024
|
+
serverAnalysis: "server-assisted analysis requires a paid plan. run: hyv upgrade"
|
|
6024
6025
|
};
|
|
6025
6026
|
localOnlyOverride = false;
|
|
6026
6027
|
cachedAccess = null;
|
|
@@ -11956,7 +11957,7 @@ async function stepSignup(profileName) {
|
|
|
11956
11957
|
));
|
|
11957
11958
|
}
|
|
11958
11959
|
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
11959
|
-
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/
|
|
11960
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/dashboard?tab=billing" }));
|
|
11960
11961
|
await briefPause();
|
|
11961
11962
|
markStepComplete("signup");
|
|
11962
11963
|
console.log(import_chalk12.default.dim("\n you're signed in \u2014 pick a plan in billing, no second login.\n"));
|
|
@@ -12136,6 +12137,54 @@ In conclusion, the key to success is to empower your team with actionable insigh
|
|
|
12136
12137
|
}
|
|
12137
12138
|
});
|
|
12138
12139
|
|
|
12140
|
+
// src/lib/billing-upgrade.ts
|
|
12141
|
+
var billing_upgrade_exports = {};
|
|
12142
|
+
__export(billing_upgrade_exports, {
|
|
12143
|
+
openBillingUpgrade: () => openBillingUpgrade
|
|
12144
|
+
});
|
|
12145
|
+
async function openBillingUpgrade(opts = {}) {
|
|
12146
|
+
const plan = opts.plan || "individual";
|
|
12147
|
+
const next = `/dashboard?tab=billing&checkout=${plan}`;
|
|
12148
|
+
const token = getToken();
|
|
12149
|
+
if (!token) {
|
|
12150
|
+
console.log(import_chalk14.default.cyan("\nSign in to upgrade \u2014 opening browser...\n"));
|
|
12151
|
+
try {
|
|
12152
|
+
await authenticateWithBrowser();
|
|
12153
|
+
} catch {
|
|
12154
|
+
console.log(import_chalk14.default.yellow("Sign-in cancelled or failed."));
|
|
12155
|
+
console.log(import_chalk14.default.dim(`Visit ${DASHBOARD_BILLING_URL} after running hyv init`));
|
|
12156
|
+
return;
|
|
12157
|
+
}
|
|
12158
|
+
}
|
|
12159
|
+
const access = await getAccessState();
|
|
12160
|
+
if (access.hasPaidPlan) {
|
|
12161
|
+
console.log(import_chalk14.default.green(`
|
|
12162
|
+
\u2713 You already have a paid plan (${access.plan}).`));
|
|
12163
|
+
console.log(import_chalk14.default.dim("Manage billing: hyv plan --manage\n"));
|
|
12164
|
+
return;
|
|
12165
|
+
}
|
|
12166
|
+
console.log(import_chalk14.default.cyan("\nOpening billing in your dashboard ($1 first month)...\n"));
|
|
12167
|
+
try {
|
|
12168
|
+
await openAuthenticatedDashboard({ next });
|
|
12169
|
+
console.log(import_chalk14.default.green("\n\u2713 Dashboard opened \u2014 pick a plan in billing"));
|
|
12170
|
+
console.log(import_chalk14.default.dim("Checkout opens automatically when you arrive from the CLI."));
|
|
12171
|
+
} catch {
|
|
12172
|
+
console.log(import_chalk14.default.yellow("Could not open dashboard automatically."));
|
|
12173
|
+
console.log(import_chalk14.default.dim(`Visit https://holdyourvoice.com${next} after hyv init`));
|
|
12174
|
+
}
|
|
12175
|
+
}
|
|
12176
|
+
var import_chalk14;
|
|
12177
|
+
var init_billing_upgrade = __esm({
|
|
12178
|
+
"src/lib/billing-upgrade.ts"() {
|
|
12179
|
+
"use strict";
|
|
12180
|
+
import_chalk14 = __toESM(require_source());
|
|
12181
|
+
init_access();
|
|
12182
|
+
init_config();
|
|
12183
|
+
init_auth();
|
|
12184
|
+
init_free_paid();
|
|
12185
|
+
}
|
|
12186
|
+
});
|
|
12187
|
+
|
|
12139
12188
|
// node_modules/glob/dist/commonjs/index.min.js
|
|
12140
12189
|
var require_index_min = __commonJS({
|
|
12141
12190
|
"node_modules/glob/dist/commonjs/index.min.js"(exports2) {
|
|
@@ -15624,7 +15673,7 @@ function registerInitCommand(program3) {
|
|
|
15624
15673
|
} else if (options?.browser === false) {
|
|
15625
15674
|
console.log(import_chalk4.default.red("License key required when --no-browser is set."));
|
|
15626
15675
|
console.log("\nUsage: hyv init <license-key>");
|
|
15627
|
-
console.log("\nGenerate a license key at: https://holdyourvoice.com/
|
|
15676
|
+
console.log("\nGenerate a license key at: https://holdyourvoice.com/dashboard");
|
|
15628
15677
|
process.exit(1);
|
|
15629
15678
|
} else {
|
|
15630
15679
|
authData = await authenticateWithBrowser();
|
|
@@ -15817,7 +15866,7 @@ function registerStatusCommand(program3) {
|
|
|
15817
15866
|
if (latest && current !== "unknown" && compareSemver(current, latest) < 0) {
|
|
15818
15867
|
console.log(import_chalk7.default.bold("\nUpdate"));
|
|
15819
15868
|
console.log(import_chalk7.default.cyan(` ${current} \u2192 ${latest} available`));
|
|
15820
|
-
console.log(import_chalk7.default.dim(" Run: hyv
|
|
15869
|
+
console.log(import_chalk7.default.dim(" Run: npm i -g @holdyourvoice/hyv@latest"));
|
|
15821
15870
|
}
|
|
15822
15871
|
console.log("");
|
|
15823
15872
|
});
|
|
@@ -16913,7 +16962,7 @@ function generateLocalProfileFromStats(name, stats) {
|
|
|
16913
16962
|
}
|
|
16914
16963
|
|
|
16915
16964
|
// src/commands/plan.ts
|
|
16916
|
-
var
|
|
16965
|
+
var import_chalk15 = __toESM(require_source());
|
|
16917
16966
|
init_config();
|
|
16918
16967
|
init_auth();
|
|
16919
16968
|
var import_open2 = __toESM(require_open());
|
|
@@ -16928,10 +16977,10 @@ function registerPlanCommand(program3) {
|
|
|
16928
16977
|
}
|
|
16929
16978
|
const token = getToken();
|
|
16930
16979
|
if (!token) {
|
|
16931
|
-
console.log(
|
|
16932
|
-
console.log(
|
|
16980
|
+
console.log(import_chalk15.default.yellow("\nNot authenticated \u2014 free tier still works.\n"));
|
|
16981
|
+
console.log(import_chalk15.default.dim(" hyv scan draft.md | hyv welcome | npx @holdyourvoice/hyv scan draft.md"));
|
|
16933
16982
|
printFreePaidMatrix({ compact: true });
|
|
16934
|
-
console.log(
|
|
16983
|
+
console.log(import_chalk15.default.dim(" Run `hyv init` for profiles + learning.\n"));
|
|
16935
16984
|
return;
|
|
16936
16985
|
}
|
|
16937
16986
|
if (options.upgrade) {
|
|
@@ -16944,20 +16993,20 @@ function registerPlanCommand(program3) {
|
|
|
16944
16993
|
await showPlan();
|
|
16945
16994
|
}
|
|
16946
16995
|
} catch (error) {
|
|
16947
|
-
console.error(
|
|
16996
|
+
console.error(import_chalk15.default.red(`
|
|
16948
16997
|
Error: ${error.message}`));
|
|
16949
16998
|
process.exit(1);
|
|
16950
16999
|
}
|
|
16951
17000
|
});
|
|
16952
17001
|
}
|
|
16953
17002
|
async function showPlan() {
|
|
16954
|
-
console.log(
|
|
17003
|
+
console.log(import_chalk15.default.bold("\nSubscription Plan\n"));
|
|
16955
17004
|
const response = await authenticatedRequest(
|
|
16956
17005
|
cliApiUrl("/cli/heartbeat"),
|
|
16957
17006
|
{ method: "GET" }
|
|
16958
17007
|
);
|
|
16959
17008
|
if (response.status !== 200) {
|
|
16960
|
-
console.log(
|
|
17009
|
+
console.log(import_chalk15.default.yellow("Could not fetch plan info."));
|
|
16961
17010
|
return;
|
|
16962
17011
|
}
|
|
16963
17012
|
const data = response.data;
|
|
@@ -16975,39 +17024,31 @@ async function showPlan() {
|
|
|
16975
17024
|
team: "$29/mo",
|
|
16976
17025
|
agency: "Custom"
|
|
16977
17026
|
};
|
|
16978
|
-
console.log(
|
|
16979
|
-
console.log(
|
|
16980
|
-
console.log(
|
|
17027
|
+
console.log(import_chalk15.default.dim("Plan:"), import_chalk15.default.bold(planNames[plan] || plan));
|
|
17028
|
+
console.log(import_chalk15.default.dim("Price:"), planPrices[plan] || "-");
|
|
17029
|
+
console.log(import_chalk15.default.dim("Status:"), data.subscription_status || "none");
|
|
16981
17030
|
if (license) {
|
|
16982
|
-
console.log(
|
|
17031
|
+
console.log(import_chalk15.default.dim("License:"), license.key_hint);
|
|
16983
17032
|
}
|
|
16984
17033
|
const access = await getAccessState();
|
|
16985
|
-
console.log(
|
|
16986
|
-
console.log(
|
|
17034
|
+
console.log(import_chalk15.default.bold("\nFree tier (always)"));
|
|
17035
|
+
console.log(import_chalk15.default.dim(" local scan, fix, check, mcp, all web tools \u2014 hyv welcome"));
|
|
16987
17036
|
if (plan === "none" || !access.hasPaidPlan) {
|
|
16988
|
-
console.log(
|
|
16989
|
-
console.log(
|
|
16990
|
-
console.log(
|
|
16991
|
-
console.log(
|
|
17037
|
+
console.log(import_chalk15.default.bold("\nUpgrade unlocks"));
|
|
17038
|
+
console.log(import_chalk15.default.dim(" profiles, learning loop, hybrid analysis, rich rewrites"));
|
|
17039
|
+
console.log(import_chalk15.default.dim(` ${PRICING_URL}`));
|
|
17040
|
+
console.log(import_chalk15.default.dim("\n hyv plan --upgrade | hyv plan --free for full matrix"));
|
|
16992
17041
|
} else {
|
|
16993
17042
|
console.log("\nManage your subscription:");
|
|
16994
|
-
console.log(
|
|
17043
|
+
console.log(import_chalk15.default.dim(" hyv plan --manage"));
|
|
16995
17044
|
}
|
|
16996
17045
|
}
|
|
16997
17046
|
async function upgradePlan() {
|
|
16998
|
-
|
|
16999
|
-
|
|
17000
|
-
await openAuthenticatedDashboard({ next: "/app/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
|
-
}
|
|
17047
|
+
const { openBillingUpgrade: openBillingUpgrade2 } = await Promise.resolve().then(() => (init_billing_upgrade(), billing_upgrade_exports));
|
|
17048
|
+
await openBillingUpgrade2({ plan: "individual" });
|
|
17008
17049
|
}
|
|
17009
17050
|
async function openBillingPortal() {
|
|
17010
|
-
console.log(
|
|
17051
|
+
console.log(import_chalk15.default.cyan("\nOpening billing portal...\n"));
|
|
17011
17052
|
const response = await authenticatedRequest(
|
|
17012
17053
|
cliApiUrl("/cli/subscribe/manage"),
|
|
17013
17054
|
{ method: "POST" }
|
|
@@ -17016,41 +17057,41 @@ async function openBillingPortal() {
|
|
|
17016
17057
|
const data = response.data;
|
|
17017
17058
|
const portalUrl = data.portal_url;
|
|
17018
17059
|
if (portalUrl) {
|
|
17019
|
-
console.log(
|
|
17060
|
+
console.log(import_chalk15.default.dim("Opening browser..."));
|
|
17020
17061
|
await (0, import_open2.default)(assertSafeOpenUrl(portalUrl));
|
|
17021
|
-
console.log(
|
|
17062
|
+
console.log(import_chalk15.default.green("\n\u2713 Billing portal opened"));
|
|
17022
17063
|
} else {
|
|
17023
|
-
console.log(
|
|
17064
|
+
console.log(import_chalk15.default.yellow("No portal URL received."));
|
|
17024
17065
|
}
|
|
17025
17066
|
} else {
|
|
17026
|
-
console.log(
|
|
17027
|
-
console.log(
|
|
17067
|
+
console.log(import_chalk15.default.yellow("Could not open billing portal."));
|
|
17068
|
+
console.log(import_chalk15.default.dim(`Visit ${DASHBOARD_BILLING_URL} to manage billing.`));
|
|
17028
17069
|
}
|
|
17029
17070
|
}
|
|
17030
17071
|
async function downgradePlan() {
|
|
17031
|
-
console.log(
|
|
17072
|
+
console.log(import_chalk15.default.yellow("\nDowngrade Plan\n"));
|
|
17032
17073
|
console.log("To downgrade your plan, please visit:");
|
|
17033
|
-
console.log(
|
|
17074
|
+
console.log(import_chalk15.default.dim(` ${DASHBOARD_BILLING_URL}`));
|
|
17034
17075
|
console.log("\nOr contact support at shashank@holdyourvoice.com");
|
|
17035
17076
|
}
|
|
17036
17077
|
|
|
17037
17078
|
// src/commands/scan.ts
|
|
17038
|
-
var
|
|
17079
|
+
var import_chalk18 = __toESM(require_source());
|
|
17039
17080
|
init_pipeline();
|
|
17040
17081
|
init_local_profile();
|
|
17041
17082
|
init_access();
|
|
17042
17083
|
|
|
17043
17084
|
// src/lib/output.ts
|
|
17044
|
-
var
|
|
17085
|
+
var import_chalk16 = __toESM(require_source());
|
|
17045
17086
|
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) =>
|
|
17087
|
+
dim: (s) => import_chalk16.default.dim(s),
|
|
17088
|
+
bold: (s) => import_chalk16.default.bold(s),
|
|
17089
|
+
accent: (s) => import_chalk16.default.hex("#C4441A")(s),
|
|
17090
|
+
green: (s) => import_chalk16.default.green(s),
|
|
17091
|
+
red: (s) => import_chalk16.default.red(s),
|
|
17092
|
+
yellow: (s) => import_chalk16.default.yellow(s),
|
|
17093
|
+
cyan: (s) => import_chalk16.default.cyan(s),
|
|
17094
|
+
white: (s) => import_chalk16.default.white(s)
|
|
17054
17095
|
};
|
|
17055
17096
|
function logo() {
|
|
17056
17097
|
return `${c.bold("hold your ")}${c.accent("voice")}`;
|
|
@@ -17198,7 +17239,7 @@ async function runHybridAnalysis(text, profile, opts = {}) {
|
|
|
17198
17239
|
}
|
|
17199
17240
|
|
|
17200
17241
|
// src/commands/history.ts
|
|
17201
|
-
var
|
|
17242
|
+
var import_chalk17 = __toESM(require_source());
|
|
17202
17243
|
var fs17 = __toESM(require("fs"));
|
|
17203
17244
|
var path16 = __toESM(require("path"));
|
|
17204
17245
|
init_config();
|
|
@@ -17250,7 +17291,7 @@ function registerHistoryCommand(program3) {
|
|
|
17250
17291
|
if (fs17.existsSync(HISTORY_FILE)) {
|
|
17251
17292
|
fs17.unlinkSync(HISTORY_FILE);
|
|
17252
17293
|
}
|
|
17253
|
-
console.log(
|
|
17294
|
+
console.log(import_chalk17.default.green("\n\u2713 History cleared"));
|
|
17254
17295
|
return;
|
|
17255
17296
|
}
|
|
17256
17297
|
let entries = readHistory();
|
|
@@ -17264,14 +17305,14 @@ function registerHistoryCommand(program3) {
|
|
|
17264
17305
|
const limit = parseInt(options.limit, 10);
|
|
17265
17306
|
entries = entries.slice(-limit);
|
|
17266
17307
|
if (entries.length === 0) {
|
|
17267
|
-
console.log(
|
|
17308
|
+
console.log(import_chalk17.default.dim("\nNo scan history yet. Run hyv scan or hyv score to start tracking."));
|
|
17268
17309
|
return;
|
|
17269
17310
|
}
|
|
17270
17311
|
if (options.format === "json") {
|
|
17271
17312
|
console.log(JSON.stringify(entries, null, 2));
|
|
17272
17313
|
return;
|
|
17273
17314
|
}
|
|
17274
|
-
console.log(
|
|
17315
|
+
console.log(import_chalk17.default.bold(`
|
|
17275
17316
|
score history (last ${entries.length} scans)
|
|
17276
17317
|
`));
|
|
17277
17318
|
if (options.chart) {
|
|
@@ -17283,7 +17324,7 @@ function registerHistoryCommand(program3) {
|
|
|
17283
17324
|
if (min !== max) {
|
|
17284
17325
|
console.log(` ${min} \u2524`);
|
|
17285
17326
|
}
|
|
17286
|
-
console.log(
|
|
17327
|
+
console.log(import_chalk17.default.dim(` \u2514${"\u2500".repeat(sl.length + 1)}`));
|
|
17287
17328
|
console.log("");
|
|
17288
17329
|
}
|
|
17289
17330
|
const scores = entries.map((e) => e.score);
|
|
@@ -17296,22 +17337,22 @@ function registerHistoryCommand(program3) {
|
|
|
17296
17337
|
const firstAvg = firstHalf.reduce((s, e) => s + e.score, 0) / (firstHalf.length || 1);
|
|
17297
17338
|
const secondAvg = secondHalf.reduce((s, e) => s + e.score, 0) / (secondHalf.length || 1);
|
|
17298
17339
|
const trend = Math.round(secondAvg - firstAvg);
|
|
17299
|
-
const trendStr = trend > 0 ?
|
|
17300
|
-
console.log(
|
|
17301
|
-
console.log(
|
|
17302
|
-
console.log(
|
|
17340
|
+
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");
|
|
17341
|
+
console.log(import_chalk17.default.dim(` avg: ${avg} best: ${best.score} worst: ${worst.score}`));
|
|
17342
|
+
console.log(import_chalk17.default.dim(` trend: ${trendStr}`));
|
|
17343
|
+
console.log(import_chalk17.default.bold("\n recent:\n"));
|
|
17303
17344
|
const recent = entries.slice(-10).reverse();
|
|
17304
17345
|
for (const entry of recent) {
|
|
17305
17346
|
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 ?
|
|
17347
|
+
const icon = entry.issues === 0 ? import_chalk17.default.green("\u2713") : import_chalk17.default.red("\u25CF");
|
|
17348
|
+
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`);
|
|
17349
|
+
const issues = entry.issues > 0 ? import_chalk17.default.red(`${entry.issues} issues`) : import_chalk17.default.dim("clean");
|
|
17309
17350
|
const file = path16.basename(entry.file).slice(0, 25).padEnd(25);
|
|
17310
|
-
console.log(` ${
|
|
17351
|
+
console.log(` ${import_chalk17.default.dim(time)} ${icon} ${file} ${score} ${issues}`);
|
|
17311
17352
|
}
|
|
17312
17353
|
console.log("");
|
|
17313
17354
|
} catch (error) {
|
|
17314
|
-
console.error(
|
|
17355
|
+
console.error(import_chalk17.default.red(`Error: ${error.message}`));
|
|
17315
17356
|
process.exit(1);
|
|
17316
17357
|
}
|
|
17317
17358
|
});
|
|
@@ -17326,7 +17367,7 @@ function registerScanCommand(program3) {
|
|
|
17326
17367
|
const profile = await loadProfileForCommand(options.profile);
|
|
17327
17368
|
const { text, path: filePath } = readText(file);
|
|
17328
17369
|
if (!text.trim()) {
|
|
17329
|
-
console.warn(
|
|
17370
|
+
console.warn(import_chalk18.default.yellow("File is empty or contains only whitespace."));
|
|
17330
17371
|
process.exit(0);
|
|
17331
17372
|
}
|
|
17332
17373
|
const ignoreRules = options.ignore ? new Set(options.ignore.split(",").map((r) => r.trim())) : /* @__PURE__ */ new Set();
|
|
@@ -17369,26 +17410,26 @@ function registerScanCommand(program3) {
|
|
|
17369
17410
|
}, null, 2));
|
|
17370
17411
|
} else {
|
|
17371
17412
|
if (signals.length === 0) {
|
|
17372
|
-
console.log(
|
|
17413
|
+
console.log(import_chalk18.default.green(`
|
|
17373
17414
|
\u2713 No issues found in ${filePath}`));
|
|
17374
|
-
console.log(
|
|
17415
|
+
console.log(import_chalk18.default.dim(` score: ${score}/100`));
|
|
17375
17416
|
} else {
|
|
17376
|
-
console.log(
|
|
17417
|
+
console.log(import_chalk18.default.bold(`
|
|
17377
17418
|
hyv scan ${filePath}`));
|
|
17378
17419
|
if (profile) {
|
|
17379
|
-
console.log(
|
|
17420
|
+
console.log(import_chalk18.default.dim(` profile: ${profile.slug || profile.name}${hasRichProfile(profile) ? " (full)" : ""}`));
|
|
17380
17421
|
}
|
|
17381
17422
|
if (analysis.message) {
|
|
17382
|
-
console.log(
|
|
17423
|
+
console.log(import_chalk18.default.dim(` engine: ${analysis.message}`));
|
|
17383
17424
|
}
|
|
17384
17425
|
console.log("");
|
|
17385
17426
|
printGroupedSignals(signals, profile);
|
|
17386
|
-
console.log(
|
|
17427
|
+
console.log(import_chalk18.default.yellow(`
|
|
17387
17428
|
${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(
|
|
17429
|
+
console.log(import_chalk18.default.dim(` score: ${score}/100`));
|
|
17430
|
+
console.log(import_chalk18.default.dim(`
|
|
17390
17431
|
fix: hyv fix ${file}`));
|
|
17391
|
-
console.log(
|
|
17432
|
+
console.log(import_chalk18.default.dim(` diff: hyv diff ${file}
|
|
17392
17433
|
`));
|
|
17393
17434
|
}
|
|
17394
17435
|
await maybeShowLimitedModeHint(!!profile);
|
|
@@ -17406,14 +17447,14 @@ hyv scan ${filePath}`));
|
|
|
17406
17447
|
process.exit(2);
|
|
17407
17448
|
}
|
|
17408
17449
|
} catch (error) {
|
|
17409
|
-
console.error(
|
|
17450
|
+
console.error(import_chalk18.default.red(`Error: ${error.message}`));
|
|
17410
17451
|
process.exit(1);
|
|
17411
17452
|
}
|
|
17412
17453
|
});
|
|
17413
17454
|
}
|
|
17414
17455
|
|
|
17415
17456
|
// src/commands/doctor.ts
|
|
17416
|
-
var
|
|
17457
|
+
var import_chalk19 = __toESM(require_source());
|
|
17417
17458
|
var fs19 = __toESM(require("fs"));
|
|
17418
17459
|
var path18 = __toESM(require("path"));
|
|
17419
17460
|
var os9 = __toESM(require("os"));
|
|
@@ -17530,6 +17571,33 @@ function claudeDesktopDir() {
|
|
|
17530
17571
|
return path18.join(HOME, ".config", "Claude");
|
|
17531
17572
|
return path18.join(HOME, "Library", "Application Support", "Claude");
|
|
17532
17573
|
}
|
|
17574
|
+
function windsurfRulePath() {
|
|
17575
|
+
const dirs = [
|
|
17576
|
+
path18.join(HOME, ".windsurf"),
|
|
17577
|
+
IS_WIN ? path18.join(HOME, "AppData", "Roaming", "Windsurf") : path18.join(HOME, "Library", "Application Support", "Windsurf")
|
|
17578
|
+
];
|
|
17579
|
+
for (const dir of dirs) {
|
|
17580
|
+
const file = path18.join(dir, "rules", "hyv.md");
|
|
17581
|
+
if (fs19.existsSync(file))
|
|
17582
|
+
return file;
|
|
17583
|
+
}
|
|
17584
|
+
return null;
|
|
17585
|
+
}
|
|
17586
|
+
function opencodeAgentsPath() {
|
|
17587
|
+
return path18.join(HOME, ".config", "opencode", "AGENTS.md");
|
|
17588
|
+
}
|
|
17589
|
+
function readOpencodeHyv() {
|
|
17590
|
+
const file = path18.join(HOME, ".config", "opencode", "opencode.jsonc");
|
|
17591
|
+
if (!fs19.existsSync(file))
|
|
17592
|
+
return false;
|
|
17593
|
+
try {
|
|
17594
|
+
const raw = fs19.readFileSync(file, "utf-8").replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
|
17595
|
+
const cfg = JSON.parse(raw);
|
|
17596
|
+
return Boolean(cfg.mcp?.hyv);
|
|
17597
|
+
} catch {
|
|
17598
|
+
return false;
|
|
17599
|
+
}
|
|
17600
|
+
}
|
|
17533
17601
|
function isOwnerOnlyFile(filePath) {
|
|
17534
17602
|
try {
|
|
17535
17603
|
if (!fs19.existsSync(filePath))
|
|
@@ -17551,129 +17619,135 @@ function readMcpHyv(configFile) {
|
|
|
17551
17619
|
}
|
|
17552
17620
|
}
|
|
17553
17621
|
function registerDoctorCommand(program3) {
|
|
17554
|
-
program3.command("doctor").description("Diagnose CLI health: engine, cache, auth, agents").option("--fix-agents", "Re-run agent config copy (idempotent)").action(async (opts) => {
|
|
17555
|
-
console.log(
|
|
17622
|
+
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) => {
|
|
17623
|
+
console.log(import_chalk19.default.bold("\nhold your voice \u2014 doctor\n"));
|
|
17556
17624
|
let issues = 0;
|
|
17557
17625
|
let fixed = 0;
|
|
17558
|
-
console.log(
|
|
17626
|
+
console.log(import_chalk19.default.dim(`engine: ${getEngineLabel()} (node ${process.version})`));
|
|
17559
17627
|
if (isLocalOnlyMode()) {
|
|
17560
|
-
console.log(
|
|
17628
|
+
console.log(import_chalk19.default.yellow(" local-only mode: HYV_LOCAL_ONLY is set"));
|
|
17561
17629
|
}
|
|
17562
17630
|
const access = await getAccessState();
|
|
17563
17631
|
const profile = await loadProfileForCommand();
|
|
17564
|
-
console.log(
|
|
17565
|
-
console.log(
|
|
17566
|
-
console.log(
|
|
17632
|
+
console.log(import_chalk19.default.dim(`mode: ${formatModeLabel(access, hasRichProfile(profile))}`));
|
|
17633
|
+
console.log(import_chalk19.default.dim("tip: run hyv welcome for free capabilities\n"));
|
|
17634
|
+
console.log(import_chalk19.default.dim("checking cli installation..."));
|
|
17567
17635
|
const cliPath = process.argv[1];
|
|
17568
17636
|
if (cliPath && fs19.existsSync(cliPath)) {
|
|
17569
|
-
console.log(
|
|
17637
|
+
console.log(import_chalk19.default.green(" \u2713 cli installed"));
|
|
17570
17638
|
} else {
|
|
17571
|
-
console.log(
|
|
17639
|
+
console.log(import_chalk19.default.red(" \u2717 cli not found"));
|
|
17572
17640
|
issues++;
|
|
17573
17641
|
}
|
|
17574
|
-
console.log(
|
|
17642
|
+
console.log(import_chalk19.default.dim("checking .hyv directory..."));
|
|
17575
17643
|
if (fs19.existsSync(HYV_DIR)) {
|
|
17576
|
-
console.log(
|
|
17644
|
+
console.log(import_chalk19.default.green(" \u2713 .hyv directory exists"));
|
|
17577
17645
|
} else {
|
|
17578
|
-
console.log(
|
|
17646
|
+
console.log(import_chalk19.default.yellow(" ! .hyv directory missing \u2014 creating..."));
|
|
17579
17647
|
fs19.mkdirSync(HYV_DIR, { recursive: true, mode: 448 });
|
|
17580
17648
|
fixed++;
|
|
17581
17649
|
}
|
|
17582
|
-
console.log(
|
|
17650
|
+
console.log(import_chalk19.default.dim("checking cache..."));
|
|
17583
17651
|
const diskProfiles = listDiskCachedProfiles();
|
|
17584
17652
|
const syncMeta = path18.join(CACHE_DIR2, "sync-meta.json");
|
|
17585
17653
|
if (diskProfiles.length > 0 || fs19.existsSync(syncMeta)) {
|
|
17586
|
-
console.log(
|
|
17654
|
+
console.log(import_chalk19.default.green(` \u2713 profile cache (${diskProfiles.length} full profile(s))`));
|
|
17587
17655
|
if (fs19.existsSync(syncMeta)) {
|
|
17588
17656
|
try {
|
|
17589
17657
|
const meta = JSON.parse(fs19.readFileSync(syncMeta, "utf-8"));
|
|
17590
|
-
console.log(
|
|
17658
|
+
console.log(import_chalk19.default.dim(` last sync: ${meta.synced_at || "unknown"}`));
|
|
17591
17659
|
} catch {
|
|
17592
17660
|
}
|
|
17593
17661
|
}
|
|
17594
17662
|
} else {
|
|
17595
|
-
console.log(
|
|
17663
|
+
console.log(import_chalk19.default.dim(" - no full profile cache (free local engine still works)"));
|
|
17596
17664
|
}
|
|
17597
|
-
console.log(
|
|
17665
|
+
console.log(import_chalk19.default.dim("checking file permissions..."));
|
|
17598
17666
|
if (fs19.existsSync(HYV_DIR)) {
|
|
17599
17667
|
const hyvMode = fs19.statSync(HYV_DIR).mode & 511;
|
|
17600
17668
|
if ((hyvMode & 63) === 0) {
|
|
17601
|
-
console.log(
|
|
17669
|
+
console.log(import_chalk19.default.green(" \u2713 .hyv directory permissions"));
|
|
17602
17670
|
} else {
|
|
17603
|
-
console.log(
|
|
17604
|
-
console.log(
|
|
17671
|
+
console.log(import_chalk19.default.yellow(" ! .hyv directory is world/group accessible"));
|
|
17672
|
+
console.log(import_chalk19.default.dim(" run: chmod 700 ~/.hyv"));
|
|
17605
17673
|
issues++;
|
|
17606
17674
|
}
|
|
17607
17675
|
}
|
|
17608
17676
|
if (fs19.existsSync(AUTH_FILE)) {
|
|
17609
17677
|
if (isOwnerOnlyFile(AUTH_FILE)) {
|
|
17610
|
-
console.log(
|
|
17678
|
+
console.log(import_chalk19.default.green(" \u2713 auth.json permissions"));
|
|
17611
17679
|
} else {
|
|
17612
|
-
console.log(
|
|
17613
|
-
console.log(
|
|
17680
|
+
console.log(import_chalk19.default.yellow(" ! auth.json is world/group readable"));
|
|
17681
|
+
console.log(import_chalk19.default.dim(" run: chmod 600 ~/.hyv/auth.json"));
|
|
17614
17682
|
issues++;
|
|
17615
17683
|
}
|
|
17616
17684
|
}
|
|
17617
|
-
console.log(
|
|
17685
|
+
console.log(import_chalk19.default.dim("checking authentication..."));
|
|
17618
17686
|
if (isInitialized()) {
|
|
17619
17687
|
const auth = readAuth();
|
|
17620
17688
|
if (auth) {
|
|
17621
|
-
console.log(
|
|
17622
|
-
console.log(
|
|
17689
|
+
console.log(import_chalk19.default.green(" \u2713 authenticated"));
|
|
17690
|
+
console.log(import_chalk19.default.dim(` email: ${auth.user?.email || "unknown"}`));
|
|
17623
17691
|
const session = await checkSession();
|
|
17624
17692
|
if (session.valid) {
|
|
17625
|
-
console.log(
|
|
17626
|
-
console.log(
|
|
17693
|
+
console.log(import_chalk19.default.green(" \u2713 session valid"));
|
|
17694
|
+
console.log(import_chalk19.default.dim(` plan: ${session.plan || "none"}`));
|
|
17627
17695
|
} else {
|
|
17628
|
-
console.log(
|
|
17629
|
-
console.log(
|
|
17696
|
+
console.log(import_chalk19.default.red(" \u2717 session expired"));
|
|
17697
|
+
console.log(import_chalk19.default.dim(" run: hyv init"));
|
|
17630
17698
|
issues++;
|
|
17631
17699
|
}
|
|
17632
17700
|
} else {
|
|
17633
|
-
console.log(
|
|
17701
|
+
console.log(import_chalk19.default.red(" \u2717 auth data missing"));
|
|
17634
17702
|
issues++;
|
|
17635
17703
|
}
|
|
17636
17704
|
} else {
|
|
17637
|
-
console.log(
|
|
17638
|
-
console.log(
|
|
17705
|
+
console.log(import_chalk19.default.yellow(" ! not authenticated (free local scan works)"));
|
|
17706
|
+
console.log(import_chalk19.default.dim(" run: hyv init for profiles + learning"));
|
|
17639
17707
|
}
|
|
17640
|
-
console.log(
|
|
17708
|
+
console.log(import_chalk19.default.dim("checking voice profile..."));
|
|
17641
17709
|
const voiceMd = path18.join(HYV_DIR, "voice.md");
|
|
17642
17710
|
const hasVoiceMd = fs19.existsSync(voiceMd) && fs19.readFileSync(voiceMd, "utf-8").trim().length > 50;
|
|
17643
17711
|
const profileFiles = fs19.existsSync(PROFILES_DIR) ? fs19.readdirSync(PROFILES_DIR).filter((f) => f.endsWith(".md") && f !== "voice.md") : [];
|
|
17644
17712
|
if (hasVoiceMd || profileFiles.length > 0 || diskProfiles.length > 0) {
|
|
17645
17713
|
if (hasVoiceMd)
|
|
17646
|
-
console.log(
|
|
17714
|
+
console.log(import_chalk19.default.green(" \u2713 voice.md exists"));
|
|
17647
17715
|
if (profileFiles.length > 0)
|
|
17648
|
-
console.log(
|
|
17716
|
+
console.log(import_chalk19.default.green(` \u2713 ${profileFiles.length} markdown profile(s)`));
|
|
17649
17717
|
if (diskProfiles.length > 0)
|
|
17650
|
-
console.log(
|
|
17718
|
+
console.log(import_chalk19.default.green(` \u2713 ${diskProfiles.length} full cached profile(s)`));
|
|
17651
17719
|
} else {
|
|
17652
|
-
console.log(
|
|
17653
|
-
console.log(
|
|
17720
|
+
console.log(import_chalk19.default.yellow(" ! no voice profile (optional for free scan)"));
|
|
17721
|
+
console.log(import_chalk19.default.dim(" run: hyv new <name> or hyv init"));
|
|
17654
17722
|
}
|
|
17655
|
-
console.log(
|
|
17723
|
+
console.log(import_chalk19.default.dim("checking agent configurations..."));
|
|
17656
17724
|
const cursorLegacyRule = path18.join(HOME, ".cursor", "rules", "hyv.md");
|
|
17657
17725
|
const cursorRule = path18.join(HOME, ".cursor", "rules", "hyv.mdc");
|
|
17658
17726
|
if (fs19.existsSync(cursorLegacyRule) && fs19.existsSync(cursorRule)) {
|
|
17659
|
-
console.log(
|
|
17660
|
-
console.log(
|
|
17727
|
+
console.log(import_chalk19.default.yellow(" ! stale cursor rule ~/.cursor/rules/hyv.md (use hyv.mdc)"));
|
|
17728
|
+
console.log(import_chalk19.default.dim(" run: rm ~/.cursor/rules/hyv.md (or hyv doctor --fix-agents)"));
|
|
17661
17729
|
issues++;
|
|
17662
17730
|
}
|
|
17731
|
+
const agMcpFile = path18.join(HOME, ".gemini", "config", "mcp_config.json");
|
|
17663
17732
|
const agentChecks = [
|
|
17664
17733
|
{ name: "claude desktop mcp", ok: readMcpHyv(path18.join(claudeDesktopDir(), "claude_desktop_config.json")) },
|
|
17665
17734
|
{ name: "cursor mcp", ok: readMcpHyv(path18.join(HOME, ".cursor", "mcp.json")) },
|
|
17666
17735
|
{ name: "cursor rule", ok: fs19.existsSync(cursorRule) },
|
|
17736
|
+
{ name: "antigravity mcp", ok: readMcpHyv(agMcpFile) },
|
|
17737
|
+
{ name: "opencode mcp", ok: readOpencodeHyv() },
|
|
17738
|
+
{ name: "opencode agents", ok: fs19.existsSync(opencodeAgentsPath()) && fs19.readFileSync(opencodeAgentsPath(), "utf-8").includes("hyv") },
|
|
17739
|
+
{ name: "windsurf rule", ok: Boolean(windsurfRulePath()) },
|
|
17667
17740
|
{ name: "claude code command", ok: fs19.existsSync(path18.join(HOME, ".claude", "commands", "hyv.md")) },
|
|
17668
17741
|
{ name: "claude code skill", ok: fs19.existsSync(path18.join(HOME, ".claude", "skills", "hold-your-voice", "SKILL.md")) },
|
|
17669
17742
|
{ name: "codex agents", ok: fs19.existsSync(path18.join(HOME, ".codex", "AGENTS.md")) && fs19.readFileSync(path18.join(HOME, ".codex", "AGENTS.md"), "utf-8").includes("hyv") },
|
|
17670
|
-
{ name: "command code skill", ok: fs19.existsSync(path18.join(HOME, ".commandcode", "skills", "hyv", "SKILL.md")) }
|
|
17743
|
+
{ name: "command code skill", ok: fs19.existsSync(path18.join(HOME, ".commandcode", "skills", "hyv", "SKILL.md")) },
|
|
17744
|
+
{ name: "chatgpt connector guide", ok: fs19.existsSync(path18.join(HOME, ".chatgpt", "hyv-mcp-connector.txt")) }
|
|
17671
17745
|
];
|
|
17672
17746
|
for (const agent of agentChecks) {
|
|
17673
17747
|
if (agent.ok) {
|
|
17674
|
-
console.log(
|
|
17748
|
+
console.log(import_chalk19.default.green(` \u2713 ${agent.name}`));
|
|
17675
17749
|
} else {
|
|
17676
|
-
console.log(
|
|
17750
|
+
console.log(import_chalk19.default.dim(` - ${agent.name} not configured`));
|
|
17677
17751
|
}
|
|
17678
17752
|
}
|
|
17679
17753
|
if (opts.fixAgents) {
|
|
@@ -17681,59 +17755,84 @@ function registerDoctorCommand(program3) {
|
|
|
17681
17755
|
const pkgDir = path18.resolve(__dirname, "..");
|
|
17682
17756
|
const { setupAgents } = require(path18.join(pkgDir, "scripts", "postinstall-lib.js"));
|
|
17683
17757
|
const result = setupAgents({ pkgDir, quiet: true });
|
|
17684
|
-
console.log(
|
|
17758
|
+
console.log(import_chalk19.default.green(` \u2713 re-ran agent setup (${result.configured.join(", ") || "no changes"})`));
|
|
17685
17759
|
if (result.warnings.length) {
|
|
17686
|
-
console.log(
|
|
17760
|
+
console.log(import_chalk19.default.yellow(` notes: ${result.warnings.join("; ")}`));
|
|
17687
17761
|
}
|
|
17688
17762
|
fixed++;
|
|
17689
17763
|
} catch (err) {
|
|
17690
|
-
console.log(
|
|
17764
|
+
console.log(import_chalk19.default.yellow(` ! could not re-run agent setup: ${err.message}`));
|
|
17691
17765
|
}
|
|
17692
17766
|
}
|
|
17693
|
-
console.log(
|
|
17767
|
+
console.log(import_chalk19.default.dim("checking mcp server..."));
|
|
17694
17768
|
const claudeMcp = readMcpHyv(path18.join(claudeDesktopDir(), "claude_desktop_config.json"));
|
|
17695
17769
|
const cursorMcp = readMcpHyv(path18.join(HOME, ".cursor", "mcp.json"));
|
|
17696
17770
|
if (claudeMcp || cursorMcp) {
|
|
17697
17771
|
if (claudeMcp)
|
|
17698
|
-
console.log(
|
|
17772
|
+
console.log(import_chalk19.default.green(" \u2713 mcp configured for claude desktop"));
|
|
17699
17773
|
if (cursorMcp)
|
|
17700
|
-
console.log(
|
|
17774
|
+
console.log(import_chalk19.default.green(" \u2713 mcp configured for cursor"));
|
|
17701
17775
|
} else {
|
|
17702
|
-
console.log(
|
|
17776
|
+
console.log(import_chalk19.default.yellow(" ! mcp not configured \u2014 run: hyv doctor --fix-agents or hyv mcp --setup"));
|
|
17703
17777
|
issues++;
|
|
17704
17778
|
}
|
|
17705
17779
|
try {
|
|
17706
17780
|
const stdio = await testMcpStdioSubprocess();
|
|
17707
17781
|
if (stdio.ok && (stdio.toolCount || 0) >= 10) {
|
|
17708
|
-
console.log(
|
|
17782
|
+
console.log(import_chalk19.default.green(` \u2713 mcp stdio subprocess healthy (${stdio.toolCount} tools)`));
|
|
17709
17783
|
} else if (stdio.ok) {
|
|
17710
|
-
console.log(
|
|
17784
|
+
console.log(import_chalk19.default.yellow(` ! mcp stdio ok but only ${stdio.toolCount || 0} tools`));
|
|
17711
17785
|
issues++;
|
|
17712
17786
|
} else {
|
|
17713
|
-
console.log(
|
|
17714
|
-
console.log(
|
|
17787
|
+
console.log(import_chalk19.default.red(" \u2717 mcp stdio subprocess failed"));
|
|
17788
|
+
console.log(import_chalk19.default.dim(" run: hyv mcp --test"));
|
|
17715
17789
|
issues++;
|
|
17716
17790
|
}
|
|
17717
17791
|
} catch (err) {
|
|
17718
|
-
console.log(
|
|
17792
|
+
console.log(import_chalk19.default.red(` \u2717 mcp stdio probe failed: ${err.message}`));
|
|
17719
17793
|
issues++;
|
|
17720
17794
|
}
|
|
17795
|
+
if (opts.verifyHosts) {
|
|
17796
|
+
console.log(import_chalk19.default.dim("verifying mcp hosts (spawns subprocess per config)..."));
|
|
17797
|
+
try {
|
|
17798
|
+
const pkgDir = path18.resolve(__dirname, "..");
|
|
17799
|
+
const { verifyAgentHosts } = require(path18.join(pkgDir, "scripts", "verify-agent-hosts.js"));
|
|
17800
|
+
const hosts = await verifyAgentHosts();
|
|
17801
|
+
for (const host of hosts) {
|
|
17802
|
+
if (host.kind === "manual") {
|
|
17803
|
+
console.log(import_chalk19.default.yellow(` \u25CB ${host.label} \u2014 ${host.detail}`));
|
|
17804
|
+
continue;
|
|
17805
|
+
}
|
|
17806
|
+
if (host.ok) {
|
|
17807
|
+
console.log(import_chalk19.default.green(` \u2713 ${host.label}${host.detail ? ` (${host.detail})` : ""}`));
|
|
17808
|
+
} else if (host.kind === "file") {
|
|
17809
|
+
console.log(import_chalk19.default.dim(` - ${host.label} \u2014 ${host.detail || "missing"}`));
|
|
17810
|
+
} else {
|
|
17811
|
+
console.log(import_chalk19.default.red(` \u2717 ${host.label} \u2014 ${host.detail || "failed"}`));
|
|
17812
|
+
issues++;
|
|
17813
|
+
}
|
|
17814
|
+
}
|
|
17815
|
+
} catch (err) {
|
|
17816
|
+
console.log(import_chalk19.default.red(` \u2717 host verification failed: ${err.message}`));
|
|
17817
|
+
issues++;
|
|
17818
|
+
}
|
|
17819
|
+
}
|
|
17721
17820
|
console.log("");
|
|
17722
17821
|
if (issues === 0 && fixed === 0) {
|
|
17723
|
-
console.log(
|
|
17822
|
+
console.log(import_chalk19.default.green("\u2713 everything looks good!"));
|
|
17724
17823
|
} else if (fixed > 0) {
|
|
17725
|
-
console.log(
|
|
17824
|
+
console.log(import_chalk19.default.green(`\u2713 fixed ${fixed} issue(s)`));
|
|
17726
17825
|
if (issues > 0)
|
|
17727
|
-
console.log(
|
|
17826
|
+
console.log(import_chalk19.default.yellow(`! ${issues} issue(s) remaining`));
|
|
17728
17827
|
} else {
|
|
17729
|
-
console.log(
|
|
17828
|
+
console.log(import_chalk19.default.yellow(`! ${issues} issue(s) found`));
|
|
17730
17829
|
}
|
|
17731
|
-
console.log(
|
|
17830
|
+
console.log(import_chalk19.default.dim("\nfree scan: hyv scan draft.md | full tour: hyv welcome\n"));
|
|
17732
17831
|
});
|
|
17733
17832
|
}
|
|
17734
17833
|
|
|
17735
17834
|
// src/commands/rename.ts
|
|
17736
|
-
var
|
|
17835
|
+
var import_chalk20 = __toESM(require_source());
|
|
17737
17836
|
init_config();
|
|
17738
17837
|
init_auth();
|
|
17739
17838
|
function registerRenameCommand(program3) {
|
|
@@ -17741,26 +17840,26 @@ function registerRenameCommand(program3) {
|
|
|
17741
17840
|
try {
|
|
17742
17841
|
const trimmedName = newName.trim();
|
|
17743
17842
|
if (!trimmedName) {
|
|
17744
|
-
console.log(
|
|
17745
|
-
console.log(
|
|
17843
|
+
console.log(import_chalk20.default.red("\nerror: what do you want to name your profile?\n"));
|
|
17844
|
+
console.log(import_chalk20.default.dim(' example: hyv rename "my brand voice"\n'));
|
|
17746
17845
|
process.exit(1);
|
|
17747
17846
|
return;
|
|
17748
17847
|
}
|
|
17749
17848
|
if (trimmedName.length > 100) {
|
|
17750
|
-
console.log(
|
|
17849
|
+
console.log(import_chalk20.default.red("\nerror: name is too long \u2014 keep it under 100 characters\n"));
|
|
17751
17850
|
process.exit(1);
|
|
17752
17851
|
return;
|
|
17753
17852
|
}
|
|
17754
17853
|
if (!/^[a-zA-Z0-9\s\-_'&.]+$/.test(trimmedName)) {
|
|
17755
|
-
console.log(
|
|
17756
|
-
console.log(
|
|
17854
|
+
console.log(import_chalk20.default.red("\nerror: name contains invalid characters\n"));
|
|
17855
|
+
console.log(import_chalk20.default.dim(" allowed: letters, numbers, spaces, hyphens, underscores, apostrophes\n"));
|
|
17757
17856
|
process.exit(1);
|
|
17758
17857
|
return;
|
|
17759
17858
|
}
|
|
17760
17859
|
const token = getToken();
|
|
17761
17860
|
if (!token) {
|
|
17762
|
-
console.log(
|
|
17763
|
-
console.log(
|
|
17861
|
+
console.log(import_chalk20.default.red("\nerror: you're not signed in yet\n"));
|
|
17862
|
+
console.log(import_chalk20.default.dim(" run: hyv init\n"));
|
|
17764
17863
|
process.exit(1);
|
|
17765
17864
|
return;
|
|
17766
17865
|
}
|
|
@@ -17776,16 +17875,16 @@ function registerRenameCommand(program3) {
|
|
|
17776
17875
|
);
|
|
17777
17876
|
if (response.status === 200) {
|
|
17778
17877
|
const data = response.data;
|
|
17779
|
-
console.log(
|
|
17878
|
+
console.log(import_chalk20.default.green(`
|
|
17780
17879
|
\u2713 profile renamed to ${data.profile?.name || trimmedName}
|
|
17781
17880
|
`));
|
|
17782
17881
|
} else {
|
|
17783
|
-
console.log(
|
|
17882
|
+
console.log(import_chalk20.default.red(`
|
|
17784
17883
|
error: server returned ${response.status}
|
|
17785
17884
|
`));
|
|
17786
17885
|
}
|
|
17787
17886
|
} catch (error) {
|
|
17788
|
-
console.error(
|
|
17887
|
+
console.error(import_chalk20.default.red(`
|
|
17789
17888
|
error: ${error.message}
|
|
17790
17889
|
`));
|
|
17791
17890
|
process.exit(1);
|
|
@@ -17794,7 +17893,7 @@ error: ${error.message}
|
|
|
17794
17893
|
}
|
|
17795
17894
|
|
|
17796
17895
|
// src/commands/fix.ts
|
|
17797
|
-
var
|
|
17896
|
+
var import_chalk22 = __toESM(require_source());
|
|
17798
17897
|
init_pipeline();
|
|
17799
17898
|
init_local_profile();
|
|
17800
17899
|
init_access();
|
|
@@ -17804,14 +17903,14 @@ init_config();
|
|
|
17804
17903
|
var fs20 = __toESM(require("fs"));
|
|
17805
17904
|
var path19 = __toESM(require("path"));
|
|
17806
17905
|
var readline2 = __toESM(require("readline"));
|
|
17807
|
-
var
|
|
17906
|
+
var import_chalk21 = __toESM(require_source());
|
|
17808
17907
|
async function confirmDestructiveWrite(options) {
|
|
17809
17908
|
if (options.yes)
|
|
17810
17909
|
return true;
|
|
17811
17910
|
const label = options.target ? `${options.action} (${options.target})` : options.action;
|
|
17812
17911
|
if (!process.stdin.isTTY) {
|
|
17813
|
-
console.error(
|
|
17814
|
-
console.error(
|
|
17912
|
+
console.error(import_chalk21.default.red("\nRefusing destructive write without confirmation (non-interactive)."));
|
|
17913
|
+
console.error(import_chalk21.default.dim(" Re-run with --yes to create .bak backups and proceed.\n"));
|
|
17815
17914
|
return false;
|
|
17816
17915
|
}
|
|
17817
17916
|
const question = `
|
|
@@ -17847,9 +17946,9 @@ function registerFixCommand(program3) {
|
|
|
17847
17946
|
if (options.format === "json") {
|
|
17848
17947
|
console.log(JSON.stringify({ file: filePath, autoFixes: 0, llmIssues: result.stats.needsLLM, changes: [] }));
|
|
17849
17948
|
} else {
|
|
17850
|
-
console.log(
|
|
17949
|
+
console.log(import_chalk22.default.green("\n\u2713 No auto-fixable issues found."));
|
|
17851
17950
|
if (result.stats.needsLLM > 0) {
|
|
17852
|
-
console.log(
|
|
17951
|
+
console.log(import_chalk22.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
17853
17952
|
}
|
|
17854
17953
|
}
|
|
17855
17954
|
return;
|
|
@@ -17863,16 +17962,16 @@ function registerFixCommand(program3) {
|
|
|
17863
17962
|
fixed: options.dryRun ? void 0 : result.fixed
|
|
17864
17963
|
}, null, 2));
|
|
17865
17964
|
} else {
|
|
17866
|
-
console.log(
|
|
17965
|
+
console.log(import_chalk22.default.dim(`
|
|
17867
17966
|
hyv fix ${filePath}
|
|
17868
17967
|
`));
|
|
17869
17968
|
for (const change of result.changes) {
|
|
17870
|
-
console.log(
|
|
17969
|
+
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));
|
|
17871
17970
|
}
|
|
17872
|
-
console.log(
|
|
17971
|
+
console.log(import_chalk22.default.green(`
|
|
17873
17972
|
\u2713 ${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} applied`));
|
|
17874
17973
|
if (result.stats.needsLLM > 0) {
|
|
17875
|
-
console.log(
|
|
17974
|
+
console.log(import_chalk22.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
17876
17975
|
}
|
|
17877
17976
|
}
|
|
17878
17977
|
if (!options.dryRun) {
|
|
@@ -17886,7 +17985,7 @@ hyv fix ${filePath}
|
|
|
17886
17985
|
process.exit(1);
|
|
17887
17986
|
}
|
|
17888
17987
|
const backupPath = writeInPlaceWithBackup(filePath, result.fixed);
|
|
17889
|
-
console.log(
|
|
17988
|
+
console.log(import_chalk22.default.dim(` Written to ${filePath} (backup: ${backupBasename(filePath)})`));
|
|
17890
17989
|
saveLastEditSession({
|
|
17891
17990
|
original_path: filePath,
|
|
17892
17991
|
edited_path: filePath,
|
|
@@ -17894,7 +17993,7 @@ hyv fix ${filePath}
|
|
|
17894
17993
|
edited_text: result.fixed,
|
|
17895
17994
|
profile: options.profile
|
|
17896
17995
|
});
|
|
17897
|
-
console.log(
|
|
17996
|
+
console.log(import_chalk22.default.dim(" Tip: hyv reinforce --last to teach your profile from this edit"));
|
|
17898
17997
|
} else if (filePath === "stdin" || !options.inPlace) {
|
|
17899
17998
|
process.stdout.write("\n" + result.fixed + "\n");
|
|
17900
17999
|
if (filePath !== "stdin") {
|
|
@@ -17910,14 +18009,14 @@ hyv fix ${filePath}
|
|
|
17910
18009
|
}
|
|
17911
18010
|
await maybeShowLimitedModeHint(!!profile);
|
|
17912
18011
|
} catch (error) {
|
|
17913
|
-
console.error(
|
|
18012
|
+
console.error(import_chalk22.default.red(`Error: ${error.message}`));
|
|
17914
18013
|
process.exit(1);
|
|
17915
18014
|
}
|
|
17916
18015
|
});
|
|
17917
18016
|
}
|
|
17918
18017
|
|
|
17919
18018
|
// src/commands/check.ts
|
|
17920
|
-
var
|
|
18019
|
+
var import_chalk23 = __toESM(require_source());
|
|
17921
18020
|
init_pipeline();
|
|
17922
18021
|
init_local_profile();
|
|
17923
18022
|
init_access();
|
|
@@ -17929,18 +18028,18 @@ function registerCheckCommand(program3) {
|
|
|
17929
18028
|
if (text === "-") {
|
|
17930
18029
|
const fs31 = require("fs");
|
|
17931
18030
|
if (process.stdin.isTTY) {
|
|
17932
|
-
console.error(
|
|
18031
|
+
console.error(import_chalk23.default.red("No input provided. Pipe content or pass text as argument."));
|
|
17933
18032
|
process.exit(1);
|
|
17934
18033
|
}
|
|
17935
18034
|
inputText = fs31.readFileSync(0, "utf-8");
|
|
17936
18035
|
}
|
|
17937
18036
|
if (!inputText.trim()) {
|
|
17938
|
-
console.error(
|
|
18037
|
+
console.error(import_chalk23.default.red("No text provided."));
|
|
17939
18038
|
process.exit(1);
|
|
17940
18039
|
}
|
|
17941
18040
|
const fs30 = require("fs");
|
|
17942
18041
|
if (text !== "-" && fs30.existsSync(text)) {
|
|
17943
|
-
console.log(
|
|
18042
|
+
console.log(import_chalk23.default.yellow(`"${text}" looks like a file. Did you mean: hyv scan ${text}`));
|
|
17944
18043
|
process.exit(1);
|
|
17945
18044
|
}
|
|
17946
18045
|
const result = runPipeline(inputText, profile, false);
|
|
@@ -17964,30 +18063,30 @@ function registerCheckCommand(program3) {
|
|
|
17964
18063
|
}, null, 2));
|
|
17965
18064
|
} else {
|
|
17966
18065
|
if (result.stats.totalSignals === 0) {
|
|
17967
|
-
console.log(
|
|
17968
|
-
console.log(
|
|
18066
|
+
console.log(import_chalk23.default.green("\n\u2713 Clean \u2014 no AI patterns found."));
|
|
18067
|
+
console.log(import_chalk23.default.dim(` score: ${result.score}/100`));
|
|
17969
18068
|
} else {
|
|
17970
18069
|
console.log("");
|
|
17971
18070
|
printGroupedSignals(result.signalMap.signals.slice(0, 15), profile);
|
|
17972
18071
|
if (result.signalMap.signals.length > 15) {
|
|
17973
|
-
console.log(
|
|
18072
|
+
console.log(import_chalk23.default.dim(` ... and ${result.signalMap.signals.length - 15} more`));
|
|
17974
18073
|
}
|
|
17975
|
-
console.log(
|
|
18074
|
+
console.log(import_chalk23.default.yellow(`
|
|
17976
18075
|
${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow)`));
|
|
17977
|
-
console.log(
|
|
18076
|
+
console.log(import_chalk23.default.dim(` score: ${result.score}/100`));
|
|
17978
18077
|
}
|
|
17979
18078
|
await maybeShowLimitedModeHint(!!profile);
|
|
17980
18079
|
}
|
|
17981
18080
|
process.exit(result.stats.totalSignals > 0 ? 1 : 0);
|
|
17982
18081
|
} catch (error) {
|
|
17983
|
-
console.error(
|
|
18082
|
+
console.error(import_chalk23.default.red(`Error: ${error.message}`));
|
|
17984
18083
|
process.exit(1);
|
|
17985
18084
|
}
|
|
17986
18085
|
});
|
|
17987
18086
|
}
|
|
17988
18087
|
|
|
17989
18088
|
// src/commands/score.ts
|
|
17990
|
-
var
|
|
18089
|
+
var import_chalk24 = __toESM(require_source());
|
|
17991
18090
|
init_pipeline();
|
|
17992
18091
|
init_local_profile();
|
|
17993
18092
|
function registerScoreCommand(program3) {
|
|
@@ -18012,14 +18111,14 @@ function registerScoreCommand(program3) {
|
|
|
18012
18111
|
process.exit(1);
|
|
18013
18112
|
}
|
|
18014
18113
|
} catch (error) {
|
|
18015
|
-
console.error(
|
|
18114
|
+
console.error(import_chalk24.default.red(`Error: ${error.message}`));
|
|
18016
18115
|
process.exit(1);
|
|
18017
18116
|
}
|
|
18018
18117
|
});
|
|
18019
18118
|
}
|
|
18020
18119
|
|
|
18021
18120
|
// src/commands/diff.ts
|
|
18022
|
-
var
|
|
18121
|
+
var import_chalk25 = __toESM(require_source());
|
|
18023
18122
|
init_pipeline();
|
|
18024
18123
|
init_local_profile();
|
|
18025
18124
|
function registerDiffCommand(program3) {
|
|
@@ -18029,9 +18128,9 @@ function registerDiffCommand(program3) {
|
|
|
18029
18128
|
const { text, path: filePath } = readText(file);
|
|
18030
18129
|
const result = runPipeline(text, profile, true);
|
|
18031
18130
|
if (result.changes.length === 0) {
|
|
18032
|
-
console.log(
|
|
18131
|
+
console.log(import_chalk25.default.green("\n\u2713 No auto-fixable changes."));
|
|
18033
18132
|
if (result.stats.needsLLM > 0) {
|
|
18034
|
-
console.log(
|
|
18133
|
+
console.log(import_chalk25.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite`));
|
|
18035
18134
|
}
|
|
18036
18135
|
return;
|
|
18037
18136
|
}
|
|
@@ -18046,42 +18145,42 @@ function registerDiffCommand(program3) {
|
|
|
18046
18145
|
const originalLines = text.split("\n");
|
|
18047
18146
|
const fixedLines = result.fixed.split("\n");
|
|
18048
18147
|
const contextN = parseInt(options.context, 10);
|
|
18049
|
-
console.log(
|
|
18050
|
-
console.log(
|
|
18148
|
+
console.log(import_chalk25.default.dim(`--- ${filePath}`));
|
|
18149
|
+
console.log(import_chalk25.default.dim(`+++ ${filePath} (fixed)`));
|
|
18051
18150
|
for (const change of result.changes) {
|
|
18052
18151
|
const lineIdx = change.line - 1;
|
|
18053
18152
|
const start = Math.max(0, lineIdx - contextN);
|
|
18054
18153
|
const end = Math.min(originalLines.length, lineIdx + contextN + 1);
|
|
18055
|
-
console.log(
|
|
18154
|
+
console.log(import_chalk25.default.dim(`@@ -${start + 1},${end - start} +${start + 1},${end - start} @@`));
|
|
18056
18155
|
for (let i = start; i < end; i++) {
|
|
18057
18156
|
if (i === lineIdx) {
|
|
18058
|
-
console.log(
|
|
18059
|
-
console.log(
|
|
18157
|
+
console.log(import_chalk25.default.red(`-${originalLines[i]}`));
|
|
18158
|
+
console.log(import_chalk25.default.green(`+${fixedLines[i]}`));
|
|
18060
18159
|
} else {
|
|
18061
|
-
console.log(
|
|
18160
|
+
console.log(import_chalk25.default.dim(` ${originalLines[i]}`));
|
|
18062
18161
|
}
|
|
18063
18162
|
}
|
|
18064
18163
|
}
|
|
18065
|
-
console.log(
|
|
18164
|
+
console.log(import_chalk25.default.green(`
|
|
18066
18165
|
${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} available`));
|
|
18067
|
-
console.log(
|
|
18166
|
+
console.log(import_chalk25.default.dim(` run: hyv fix ${file} -i to apply`));
|
|
18068
18167
|
if (options.apply && filePath !== "stdin") {
|
|
18069
18168
|
const fs30 = require("fs");
|
|
18070
18169
|
const path27 = require("path");
|
|
18071
18170
|
const backupPath = filePath + ".bak";
|
|
18072
18171
|
fs30.copyFileSync(filePath, backupPath);
|
|
18073
18172
|
fs30.writeFileSync(filePath, result.fixed);
|
|
18074
|
-
console.log(
|
|
18173
|
+
console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${path27.basename(backupPath)}`));
|
|
18075
18174
|
}
|
|
18076
18175
|
} catch (error) {
|
|
18077
|
-
console.error(
|
|
18176
|
+
console.error(import_chalk25.default.red(`Error: ${error.message}`));
|
|
18078
18177
|
process.exit(1);
|
|
18079
18178
|
}
|
|
18080
18179
|
});
|
|
18081
18180
|
}
|
|
18082
18181
|
|
|
18083
18182
|
// src/commands/rules.ts
|
|
18084
|
-
var
|
|
18183
|
+
var import_chalk26 = __toESM(require_source());
|
|
18085
18184
|
init_config();
|
|
18086
18185
|
var RULE_CATALOG = [
|
|
18087
18186
|
// AI Overused Words
|
|
@@ -18175,7 +18274,7 @@ function registerRulesCommand(program3) {
|
|
|
18175
18274
|
for (const id of ids)
|
|
18176
18275
|
disabledRules.delete(id);
|
|
18177
18276
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
18178
|
-
console.log(
|
|
18277
|
+
console.log(import_chalk26.default.green(`
|
|
18179
18278
|
\u2713 Enabled: ${ids.join(", ")}`));
|
|
18180
18279
|
return;
|
|
18181
18280
|
}
|
|
@@ -18184,13 +18283,13 @@ function registerRulesCommand(program3) {
|
|
|
18184
18283
|
for (const id of ids)
|
|
18185
18284
|
disabledRules.add(id);
|
|
18186
18285
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
18187
|
-
console.log(
|
|
18286
|
+
console.log(import_chalk26.default.green(`
|
|
18188
18287
|
\u2713 Disabled: ${ids.join(", ")}`));
|
|
18189
18288
|
return;
|
|
18190
18289
|
}
|
|
18191
18290
|
if (options.reset) {
|
|
18192
18291
|
writeConfig({ ...config, disabled_rules: [] });
|
|
18193
|
-
console.log(
|
|
18292
|
+
console.log(import_chalk26.default.green("\n\u2713 All rules reset to default (enabled)"));
|
|
18194
18293
|
return;
|
|
18195
18294
|
}
|
|
18196
18295
|
let rules = [...RULE_CATALOG];
|
|
@@ -18218,34 +18317,34 @@ function registerRulesCommand(program3) {
|
|
|
18218
18317
|
}
|
|
18219
18318
|
console.log("");
|
|
18220
18319
|
for (const [cat, catRules] of categories) {
|
|
18221
|
-
console.log(
|
|
18320
|
+
console.log(import_chalk26.default.bold(` ${cat} rules (${catRules.length})
|
|
18222
18321
|
`));
|
|
18223
|
-
console.log(
|
|
18224
|
-
console.log(
|
|
18322
|
+
console.log(import_chalk26.default.dim(" ID Sev AutoFix Status"));
|
|
18323
|
+
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"));
|
|
18225
18324
|
for (const rule of catRules) {
|
|
18226
|
-
const sev = rule.severity === "red" ?
|
|
18227
|
-
const fix = rule.autoFixable ?
|
|
18228
|
-
const enabled2 = disabledRules.has(rule.id) ?
|
|
18325
|
+
const sev = rule.severity === "red" ? import_chalk26.default.red("red") : import_chalk26.default.yellow("yel");
|
|
18326
|
+
const fix = rule.autoFixable ? import_chalk26.default.green(" \u2713") : import_chalk26.default.dim(" \u2717");
|
|
18327
|
+
const enabled2 = disabledRules.has(rule.id) ? import_chalk26.default.red(" \u2717 disabled") : import_chalk26.default.green(" \u2713 enabled");
|
|
18229
18328
|
const id = rule.id.padEnd(24);
|
|
18230
|
-
console.log(` ${
|
|
18329
|
+
console.log(` ${import_chalk26.default.dim(id)} ${sev} ${fix} ${enabled2}`);
|
|
18231
18330
|
}
|
|
18232
18331
|
console.log("");
|
|
18233
18332
|
}
|
|
18234
18333
|
const enabled = rules.filter((r) => !disabledRules.has(r.id)).length;
|
|
18235
18334
|
const disabled = rules.length - enabled;
|
|
18236
|
-
console.log(
|
|
18237
|
-
console.log(
|
|
18238
|
-
console.log(
|
|
18335
|
+
console.log(import_chalk26.default.dim(` ${rules.length} rules, ${enabled} enabled, ${disabled} disabled`));
|
|
18336
|
+
console.log(import_chalk26.default.dim(` toggle: hyv rules --disable <id>`));
|
|
18337
|
+
console.log(import_chalk26.default.dim(` reset: hyv rules --reset
|
|
18239
18338
|
`));
|
|
18240
18339
|
} catch (error) {
|
|
18241
|
-
console.error(
|
|
18340
|
+
console.error(import_chalk26.default.red(`Error: ${error.message}`));
|
|
18242
18341
|
process.exit(1);
|
|
18243
18342
|
}
|
|
18244
18343
|
});
|
|
18245
18344
|
}
|
|
18246
18345
|
|
|
18247
18346
|
// src/commands/batch.ts
|
|
18248
|
-
var
|
|
18347
|
+
var import_chalk27 = __toESM(require_source());
|
|
18249
18348
|
var fs21 = __toESM(require("fs"));
|
|
18250
18349
|
var path20 = __toESM(require("path"));
|
|
18251
18350
|
init_pipeline();
|
|
@@ -18260,7 +18359,7 @@ function registerBatchCommand(program3) {
|
|
|
18260
18359
|
nodir: true
|
|
18261
18360
|
});
|
|
18262
18361
|
if (files.length === 0) {
|
|
18263
|
-
console.log(
|
|
18362
|
+
console.log(import_chalk27.default.yellow(`
|
|
18264
18363
|
No files matching: ${pattern}`));
|
|
18265
18364
|
return;
|
|
18266
18365
|
}
|
|
@@ -18274,7 +18373,7 @@ No files matching: ${pattern}`));
|
|
|
18274
18373
|
process.exit(1);
|
|
18275
18374
|
}
|
|
18276
18375
|
if (options.format === "text") {
|
|
18277
|
-
console.log(
|
|
18376
|
+
console.log(import_chalk27.default.dim(`
|
|
18278
18377
|
scanning ${files.length} file${files.length === 1 ? "" : "s"}...
|
|
18279
18378
|
`));
|
|
18280
18379
|
}
|
|
@@ -18313,23 +18412,23 @@ No files matching: ${pattern}`));
|
|
|
18313
18412
|
}
|
|
18314
18413
|
} else {
|
|
18315
18414
|
for (const r of results) {
|
|
18316
|
-
const icon = r.issues > 0 ?
|
|
18317
|
-
const score = r.score < 60 ?
|
|
18318
|
-
const issueStr = r.issues > 0 ?
|
|
18415
|
+
const icon = r.issues > 0 ? import_chalk27.default.red("\u25CF") : import_chalk27.default.green("\u25CB");
|
|
18416
|
+
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);
|
|
18417
|
+
const issueStr = r.issues > 0 ? import_chalk27.default.red(`${r.issues} issues`) : import_chalk27.default.green("clean");
|
|
18319
18418
|
console.log(` ${icon} ${r.file.padEnd(40)} ${issueStr.padEnd(20)} score: ${score}`);
|
|
18320
18419
|
}
|
|
18321
18420
|
const withIssues = results.filter((r) => r.issues > 0).length;
|
|
18322
18421
|
const totalIssues = results.reduce((sum, r) => sum + r.issues, 0);
|
|
18323
18422
|
const worst = results.reduce((min, r) => r.score < min.score ? r : min, results[0]);
|
|
18324
|
-
console.log(
|
|
18423
|
+
console.log(import_chalk27.default.dim(`
|
|
18325
18424
|
\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`));
|
|
18326
|
-
console.log(
|
|
18425
|
+
console.log(import_chalk27.default.dim(` ${results.length} files, ${withIssues} with issues, ${totalIssues} total issues`));
|
|
18327
18426
|
if (withIssues > 0) {
|
|
18328
|
-
console.log(
|
|
18427
|
+
console.log(import_chalk27.default.dim(` worst: ${worst.file} (${worst.score}/100)`));
|
|
18329
18428
|
}
|
|
18330
18429
|
if (options.fix && options.inPlace) {
|
|
18331
18430
|
const fixed = results.filter((r) => r.autoFixes > 0);
|
|
18332
|
-
console.log(
|
|
18431
|
+
console.log(import_chalk27.default.green(`
|
|
18333
18432
|
\u2713 ${fixed.reduce((sum, r) => sum + r.autoFixes, 0)} auto-fixes applied across ${fixed.length} files`));
|
|
18334
18433
|
}
|
|
18335
18434
|
}
|
|
@@ -18341,14 +18440,14 @@ No files matching: ${pattern}`));
|
|
|
18341
18440
|
if (belowThreshold)
|
|
18342
18441
|
process.exit(1);
|
|
18343
18442
|
} catch (error) {
|
|
18344
|
-
console.error(
|
|
18443
|
+
console.error(import_chalk27.default.red(`Error: ${error.message}`));
|
|
18345
18444
|
process.exit(1);
|
|
18346
18445
|
}
|
|
18347
18446
|
});
|
|
18348
18447
|
}
|
|
18349
18448
|
|
|
18350
18449
|
// src/commands/watch.ts
|
|
18351
|
-
var
|
|
18450
|
+
var import_chalk28 = __toESM(require_source());
|
|
18352
18451
|
var fs22 = __toESM(require("fs"));
|
|
18353
18452
|
var path21 = __toESM(require("path"));
|
|
18354
18453
|
init_pipeline();
|
|
@@ -18359,7 +18458,7 @@ function registerWatchCommand(program3) {
|
|
|
18359
18458
|
const profile = await loadProfileForCommand(options.profile);
|
|
18360
18459
|
const absPath = path21.resolve(file);
|
|
18361
18460
|
if (!fs22.existsSync(absPath)) {
|
|
18362
|
-
console.error(
|
|
18461
|
+
console.error(import_chalk28.default.red(`File not found: ${absPath}`));
|
|
18363
18462
|
process.exit(1);
|
|
18364
18463
|
}
|
|
18365
18464
|
if (options.command === "fix") {
|
|
@@ -18371,10 +18470,10 @@ function registerWatchCommand(program3) {
|
|
|
18371
18470
|
if (!confirmed)
|
|
18372
18471
|
process.exit(1);
|
|
18373
18472
|
}
|
|
18374
|
-
console.log(
|
|
18473
|
+
console.log(import_chalk28.default.dim(`
|
|
18375
18474
|
watching ${absPath}`));
|
|
18376
|
-
console.log(
|
|
18377
|
-
console.log(
|
|
18475
|
+
console.log(import_chalk28.default.dim(`command: ${options.command} debounce: ${options.debounce}ms`));
|
|
18476
|
+
console.log(import_chalk28.default.dim("ctrl+c to stop\n"));
|
|
18378
18477
|
let debounceTimer = null;
|
|
18379
18478
|
const debounceMs = parseInt(options.debounce, 10);
|
|
18380
18479
|
let scanCount = 0;
|
|
@@ -18385,38 +18484,38 @@ watching ${absPath}`));
|
|
|
18385
18484
|
const result = runPipeline(text, profile, options.command === "fix");
|
|
18386
18485
|
scanCount++;
|
|
18387
18486
|
const now = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
18388
|
-
console.log(
|
|
18487
|
+
console.log(import_chalk28.default.dim(`[${now}] saved \u2014 ${options.command}ing...`));
|
|
18389
18488
|
if (options.command === "score") {
|
|
18390
18489
|
const score = result.score;
|
|
18391
|
-
const color = score < 60 ?
|
|
18490
|
+
const color = score < 60 ? import_chalk28.default.red : score < 80 ? import_chalk28.default.yellow : import_chalk28.default.green;
|
|
18392
18491
|
console.log(` ${color(score + "/100")}`);
|
|
18393
18492
|
if (lastScore > 0 && score !== lastScore) {
|
|
18394
18493
|
const delta = score - lastScore;
|
|
18395
|
-
console.log(
|
|
18494
|
+
console.log(import_chalk28.default.dim(` ${delta > 0 ? "\u2191" : "\u2193"} ${Math.abs(delta)} from last scan`));
|
|
18396
18495
|
}
|
|
18397
18496
|
lastScore = score;
|
|
18398
18497
|
} else if (options.command === "fix") {
|
|
18399
18498
|
if (result.changes.length > 0) {
|
|
18400
18499
|
for (const change of result.changes) {
|
|
18401
|
-
console.log(
|
|
18500
|
+
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));
|
|
18402
18501
|
}
|
|
18403
18502
|
ignoreWatchUntil = Date.now() + debounceMs + 200;
|
|
18404
18503
|
writeInPlaceWithBackup(absPath, result.fixed);
|
|
18405
|
-
console.log(
|
|
18504
|
+
console.log(import_chalk28.default.green(` \u2713 ${result.changes.length} auto-fixes applied`));
|
|
18406
18505
|
} else {
|
|
18407
|
-
console.log(
|
|
18506
|
+
console.log(import_chalk28.default.green(" \u2713 no auto-fixable issues"));
|
|
18408
18507
|
}
|
|
18409
18508
|
} else {
|
|
18410
18509
|
if (result.stats.totalSignals === 0) {
|
|
18411
|
-
console.log(
|
|
18510
|
+
console.log(import_chalk28.default.green(` \u2713 clean \u2014 score: ${result.score}/100`));
|
|
18412
18511
|
} else {
|
|
18413
|
-
console.log(
|
|
18512
|
+
console.log(import_chalk28.default.yellow(` ${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow) score: ${result.score}/100`));
|
|
18414
18513
|
for (const signal of result.signalMap.signals.slice(0, 3)) {
|
|
18415
|
-
const sev = signal.severity === "red" ?
|
|
18514
|
+
const sev = signal.severity === "red" ? import_chalk28.default.red("\u25CF") : import_chalk28.default.yellow("\u25CB");
|
|
18416
18515
|
console.log(` ${sev} line ${signal.line}: ${signal.id} \u2014 ${signal.suggestion}`);
|
|
18417
18516
|
}
|
|
18418
18517
|
if (result.signalMap.signals.length > 3) {
|
|
18419
|
-
console.log(
|
|
18518
|
+
console.log(import_chalk28.default.dim(` ... and ${result.signalMap.signals.length - 3} more`));
|
|
18420
18519
|
}
|
|
18421
18520
|
}
|
|
18422
18521
|
}
|
|
@@ -18433,21 +18532,21 @@ watching ${absPath}`));
|
|
|
18433
18532
|
debounceTimer = setTimeout(runScan, debounceMs);
|
|
18434
18533
|
});
|
|
18435
18534
|
process.on("SIGINT", () => {
|
|
18436
|
-
console.log(
|
|
18535
|
+
console.log(import_chalk28.default.dim(`
|
|
18437
18536
|
${scanCount} scans completed. exiting.`));
|
|
18438
18537
|
process.exit(0);
|
|
18439
18538
|
});
|
|
18440
18539
|
await new Promise(() => {
|
|
18441
18540
|
});
|
|
18442
18541
|
} catch (error) {
|
|
18443
|
-
console.error(
|
|
18542
|
+
console.error(import_chalk28.default.red(`Error: ${error.message}`));
|
|
18444
18543
|
process.exit(1);
|
|
18445
18544
|
}
|
|
18446
18545
|
});
|
|
18447
18546
|
}
|
|
18448
18547
|
|
|
18449
18548
|
// src/commands/demo.ts
|
|
18450
|
-
var
|
|
18549
|
+
var import_chalk29 = __toESM(require_source());
|
|
18451
18550
|
var fs23 = __toESM(require("fs"));
|
|
18452
18551
|
var SAMPLES = {
|
|
18453
18552
|
linkedin: {
|
|
@@ -18538,52 +18637,52 @@ function registerDemoCommand(program3) {
|
|
|
18538
18637
|
const style = options.clean ? "clean" : options.style;
|
|
18539
18638
|
const sample = SAMPLES[style];
|
|
18540
18639
|
if (!sample) {
|
|
18541
|
-
console.error(
|
|
18640
|
+
console.error(import_chalk29.default.red(`Unknown style: ${options.style}. Valid: ${Object.keys(SAMPLES).filter((k2) => k2 !== "clean").join(", ")}`));
|
|
18542
18641
|
process.exit(1);
|
|
18543
18642
|
}
|
|
18544
18643
|
if (options.output) {
|
|
18545
18644
|
const outputPath = require("path").resolve(options.output);
|
|
18546
18645
|
fs23.writeFileSync(outputPath, sample.text);
|
|
18547
|
-
console.log(
|
|
18646
|
+
console.log(import_chalk29.default.green(`
|
|
18548
18647
|
\u2713 Sample written to ${outputPath}`));
|
|
18549
18648
|
if (sample.patterns.length > 0) {
|
|
18550
|
-
console.log(
|
|
18649
|
+
console.log(import_chalk29.default.dim(` Contains ${sample.patterns.length} AI patterns: ${sample.patterns.slice(0, 5).join(", ")}...`));
|
|
18551
18650
|
}
|
|
18552
|
-
console.log(
|
|
18651
|
+
console.log(import_chalk29.default.dim(`
|
|
18553
18652
|
Scan it: hyv scan ${options.output}`));
|
|
18554
|
-
console.log(
|
|
18653
|
+
console.log(import_chalk29.default.dim(` Fix it: hyv fix ${options.output}`));
|
|
18555
18654
|
} else {
|
|
18556
|
-
console.log(
|
|
18655
|
+
console.log(import_chalk29.default.bold(`
|
|
18557
18656
|
\u2500\u2500\u2500 sample (${style}) \u2500\u2500\u2500
|
|
18558
18657
|
`));
|
|
18559
18658
|
console.log(sample.text);
|
|
18560
|
-
console.log(
|
|
18659
|
+
console.log(import_chalk29.default.dim(`
|
|
18561
18660
|
\u2500\u2500\u2500 end \u2500\u2500\u2500`));
|
|
18562
18661
|
if (sample.patterns.length > 0) {
|
|
18563
|
-
console.log(
|
|
18662
|
+
console.log(import_chalk29.default.dim(`
|
|
18564
18663
|
${sample.patterns.length} AI patterns embedded: ${sample.patterns.slice(0, 8).join(", ")}...`));
|
|
18565
18664
|
}
|
|
18566
|
-
console.log(
|
|
18665
|
+
console.log(import_chalk29.default.dim(`
|
|
18567
18666
|
Save to file: hyv demo --output demo.md`));
|
|
18568
|
-
console.log(
|
|
18569
|
-
console.log(
|
|
18667
|
+
console.log(import_chalk29.default.dim(` Scan it: hyv scan demo.md`));
|
|
18668
|
+
console.log(import_chalk29.default.dim(` Fix it: hyv fix demo.md
|
|
18570
18669
|
`));
|
|
18571
18670
|
}
|
|
18572
18671
|
} catch (error) {
|
|
18573
|
-
console.error(
|
|
18672
|
+
console.error(import_chalk29.default.red(`Error: ${error.message}`));
|
|
18574
18673
|
process.exit(1);
|
|
18575
18674
|
}
|
|
18576
18675
|
});
|
|
18577
18676
|
}
|
|
18578
18677
|
|
|
18579
18678
|
// src/commands/open.ts
|
|
18580
|
-
var
|
|
18679
|
+
var import_chalk30 = __toESM(require_source());
|
|
18581
18680
|
var PAGES = {
|
|
18582
|
-
dashboard: "https://holdyourvoice.com/
|
|
18583
|
-
profiles: "https://holdyourvoice.com/
|
|
18584
|
-
pricing: "https://holdyourvoice.com/
|
|
18585
|
-
settings: "https://holdyourvoice.com/
|
|
18586
|
-
billing: "https://holdyourvoice.com/
|
|
18681
|
+
dashboard: "https://holdyourvoice.com/dashboard",
|
|
18682
|
+
profiles: "https://holdyourvoice.com/dashboard?tab=profiles",
|
|
18683
|
+
pricing: "https://holdyourvoice.com/dashboard?tab=billing",
|
|
18684
|
+
settings: "https://holdyourvoice.com/dashboard",
|
|
18685
|
+
billing: "https://holdyourvoice.com/dashboard?tab=billing"
|
|
18587
18686
|
};
|
|
18588
18687
|
function registerOpenCommand(program3) {
|
|
18589
18688
|
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) => {
|
|
@@ -18595,12 +18694,12 @@ function registerOpenCommand(program3) {
|
|
|
18595
18694
|
return;
|
|
18596
18695
|
}
|
|
18597
18696
|
const open3 = (await Promise.resolve().then(() => __toESM(require_open()))).default;
|
|
18598
|
-
console.log(
|
|
18697
|
+
console.log(import_chalk30.default.dim(`
|
|
18599
18698
|
Opening ${url}...`));
|
|
18600
18699
|
await open3(url);
|
|
18601
|
-
console.log(
|
|
18700
|
+
console.log(import_chalk30.default.green(" \u2713 Opened in browser\n"));
|
|
18602
18701
|
} catch (error) {
|
|
18603
|
-
console.error(
|
|
18702
|
+
console.error(import_chalk30.default.red(`Error: ${error.message}`));
|
|
18604
18703
|
process.exit(1);
|
|
18605
18704
|
}
|
|
18606
18705
|
});
|
|
@@ -18686,7 +18785,7 @@ function getWelcomeText(args2) {
|
|
|
18686
18785
|
}
|
|
18687
18786
|
|
|
18688
18787
|
// src/commands/content.ts
|
|
18689
|
-
var
|
|
18788
|
+
var import_chalk31 = __toESM(require_source());
|
|
18690
18789
|
init_free_paid();
|
|
18691
18790
|
var TEMPLATES = {
|
|
18692
18791
|
cursor: {
|
|
@@ -18760,62 +18859,28 @@ ${COMMUNITY_URL}`
|
|
|
18760
18859
|
function registerContentCommand(program3) {
|
|
18761
18860
|
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) => {
|
|
18762
18861
|
if (opts.list) {
|
|
18763
|
-
console.log(
|
|
18862
|
+
console.log(import_chalk31.default.bold("\nhyv content templates\n"));
|
|
18764
18863
|
for (const [key, t2] of Object.entries(TEMPLATES)) {
|
|
18765
|
-
console.log(
|
|
18864
|
+
console.log(import_chalk31.default.dim(` ${key}`) + ` \u2014 ${t2.title}`);
|
|
18766
18865
|
}
|
|
18767
18866
|
console.log("");
|
|
18768
18867
|
return;
|
|
18769
18868
|
}
|
|
18770
18869
|
const t = TEMPLATES[topic] || TEMPLATES.cursor;
|
|
18771
|
-
console.log(
|
|
18870
|
+
console.log(import_chalk31.default.bold(`
|
|
18772
18871
|
${t.title}
|
|
18773
18872
|
`));
|
|
18774
18873
|
console.log(t.body);
|
|
18775
|
-
console.log(
|
|
18874
|
+
console.log(import_chalk31.default.dim("\nBlog: https://holdyourvoice.com/blog\n"));
|
|
18776
18875
|
});
|
|
18777
18876
|
}
|
|
18778
18877
|
|
|
18779
18878
|
// src/commands/upgrade.ts
|
|
18780
|
-
|
|
18781
|
-
var import_child_process4 = require("child_process");
|
|
18782
|
-
init_version();
|
|
18879
|
+
init_billing_upgrade();
|
|
18783
18880
|
function registerUpgradeCommand(program3) {
|
|
18784
|
-
program3.command("upgrade").description("Upgrade to
|
|
18785
|
-
const
|
|
18786
|
-
|
|
18787
|
-
Current: ${getEngineLabel()}
|
|
18788
|
-
`));
|
|
18789
|
-
let latest = current;
|
|
18790
|
-
try {
|
|
18791
|
-
const out = (0, import_child_process4.execSync)("npm view @holdyourvoice/hyv version", { encoding: "utf-8", timeout: 15e3 });
|
|
18792
|
-
latest = out.trim();
|
|
18793
|
-
} catch {
|
|
18794
|
-
console.log(import_chalk31.default.yellow("Could not reach npm registry. Try: npm i -g @holdyourvoice/hyv@latest"));
|
|
18795
|
-
return;
|
|
18796
|
-
}
|
|
18797
|
-
const cmp = compareSemver(current, latest);
|
|
18798
|
-
if (cmp === 0) {
|
|
18799
|
-
console.log(import_chalk31.default.green("\u2713 You are on the latest version."));
|
|
18800
|
-
return;
|
|
18801
|
-
}
|
|
18802
|
-
if (cmp > 0) {
|
|
18803
|
-
console.log(import_chalk31.default.green(`\u2713 You are ahead of npm (published: ${latest}).`));
|
|
18804
|
-
return;
|
|
18805
|
-
}
|
|
18806
|
-
console.log(import_chalk31.default.cyan(`Update available: ${current} \u2192 ${latest}`));
|
|
18807
|
-
if (opts.check) {
|
|
18808
|
-
console.log(import_chalk31.default.dim("\nRun: hyv upgrade or npm i -g @holdyourvoice/hyv@latest\n"));
|
|
18809
|
-
return;
|
|
18810
|
-
}
|
|
18811
|
-
console.log(import_chalk31.default.dim("Installing..."));
|
|
18812
|
-
try {
|
|
18813
|
-
(0, import_child_process4.execSync)("npm i -g @holdyourvoice/hyv@latest", { stdio: "inherit" });
|
|
18814
|
-
console.log(import_chalk31.default.green("\n\u2713 Upgraded successfully. Restart your terminal.\n"));
|
|
18815
|
-
} catch {
|
|
18816
|
-
console.log(import_chalk31.default.red("\nUpgrade failed. Run manually: npm i -g @holdyourvoice/hyv@latest\n"));
|
|
18817
|
-
process.exit(1);
|
|
18818
|
-
}
|
|
18881
|
+
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) => {
|
|
18882
|
+
const plan = opts.plan === "multiple" ? "multiple" : "individual";
|
|
18883
|
+
await openBillingUpgrade({ plan });
|
|
18819
18884
|
});
|
|
18820
18885
|
}
|
|
18821
18886
|
|
|
@@ -19506,8 +19571,16 @@ function printMcpSetup() {
|
|
|
19506
19571
|
console.log(import_chalk32.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
|
|
19507
19572
|
console.log(import_chalk32.default.bold("Command Code"));
|
|
19508
19573
|
console.log(import_chalk32.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
|
|
19509
|
-
console.log(import_chalk32.default.bold("ChatGPT"));
|
|
19574
|
+
console.log(import_chalk32.default.bold("ChatGPT Desktop (manual connector)"));
|
|
19575
|
+
console.log(import_chalk32.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
|
|
19576
|
+
console.log(import_chalk32.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp"));
|
|
19577
|
+
console.log(import_chalk32.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
|
|
19510
19578
|
console.log(import_chalk32.default.dim(" hyv mcp --setup-chatgpt\n"));
|
|
19579
|
+
console.log(import_chalk32.default.bold("Antigravity"));
|
|
19580
|
+
console.log(import_chalk32.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
|
|
19581
|
+
console.log(import_chalk32.default.bold("OpenCode"));
|
|
19582
|
+
console.log(import_chalk32.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
|
|
19583
|
+
console.log(import_chalk32.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
|
|
19511
19584
|
console.log(import_chalk32.default.bold("Auto-configure"));
|
|
19512
19585
|
console.log(import_chalk32.default.dim(" hyv doctor --fix-agents"));
|
|
19513
19586
|
console.log(import_chalk32.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
|
|
@@ -19680,7 +19753,7 @@ async function exportCommand(format, opts) {
|
|
|
19680
19753
|
} else {
|
|
19681
19754
|
console.log(`
|
|
19682
19755
|
${c.red("\u2717")} no voice profiles found`);
|
|
19683
|
-
console.log(` ${c.dim("create one at")} ${c.cyan("https://holdyourvoice.com/
|
|
19756
|
+
console.log(` ${c.dim("create one at")} ${c.cyan("https://holdyourvoice.com/dashboard")}`);
|
|
19684
19757
|
}
|
|
19685
19758
|
process.exit(1);
|
|
19686
19759
|
return;
|
|
@@ -19780,15 +19853,24 @@ program2.command("mcp").description("Start MCP server (for Claude Desktop and ot
|
|
|
19780
19853
|
return;
|
|
19781
19854
|
}
|
|
19782
19855
|
if (opts.setupChatgpt) {
|
|
19783
|
-
|
|
19784
|
-
|
|
19785
|
-
console.log(import_chalk33.default.
|
|
19786
|
-
console.log(
|
|
19787
|
-
console.log(import_chalk33.default.dim("
|
|
19788
|
-
console.log(import_chalk33.default.dim("
|
|
19856
|
+
const home = require("os").homedir();
|
|
19857
|
+
const guide = require("path").join(home, ".chatgpt", "hyv-mcp-connector.txt");
|
|
19858
|
+
console.log(import_chalk33.default.bold("\nhold your voice \u2014 chatgpt desktop mcp setup\n"));
|
|
19859
|
+
console.log("ChatGPT has no auto-config file. Add this connector once in the desktop app:\n");
|
|
19860
|
+
console.log(import_chalk33.default.dim(" 1. Install hyv: ") + import_chalk33.default.cyan("npm i -g @holdyourvoice/hyv@latest && hyv welcome"));
|
|
19861
|
+
console.log(import_chalk33.default.dim(" 2. Open ") + import_chalk33.default.cyan("https://chatgpt.com/#settings/Connectors"));
|
|
19862
|
+
console.log(import_chalk33.default.dim(" 3. Add connector"));
|
|
19863
|
+
console.log(import_chalk33.default.dim(" 4. Name: ") + import_chalk33.default.cyan("hold your voice"));
|
|
19864
|
+
console.log(import_chalk33.default.dim(" 5. Command: ") + import_chalk33.default.cyan("hyv"));
|
|
19865
|
+
console.log(import_chalk33.default.dim(" 6. Arguments: ") + import_chalk33.default.cyan("mcp"));
|
|
19866
|
+
console.log(import_chalk33.default.dim(" 7. Save, restart ChatGPT Desktop, ask: scan this with hold your voice"));
|
|
19789
19867
|
console.log("");
|
|
19790
|
-
|
|
19791
|
-
|
|
19868
|
+
if (require("fs").existsSync(guide)) {
|
|
19869
|
+
console.log(import_chalk33.default.dim(`Full guide written to: ${guide}`));
|
|
19870
|
+
} else {
|
|
19871
|
+
console.log(import_chalk33.default.dim("Run hyv doctor --fix-agents to write ~/.chatgpt/hyv-mcp-connector.txt"));
|
|
19872
|
+
}
|
|
19873
|
+
console.log(import_chalk33.default.dim("\nBrowser chatgpt cannot use local MCP \u2014 desktop app only."));
|
|
19792
19874
|
return;
|
|
19793
19875
|
}
|
|
19794
19876
|
startMcpServer();
|