@holdyourvoice/hyv 2.9.20 → 2.9.21
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 +41 -127
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5236,14 +5236,14 @@ var require_open = __commonJS({
|
|
|
5236
5236
|
}
|
|
5237
5237
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
5238
5238
|
if (options.wait) {
|
|
5239
|
-
return new Promise((
|
|
5239
|
+
return new Promise((resolve17, reject) => {
|
|
5240
5240
|
subprocess.once("error", reject);
|
|
5241
5241
|
subprocess.once("close", (exitCode) => {
|
|
5242
5242
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
5243
5243
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
5244
5244
|
return;
|
|
5245
5245
|
}
|
|
5246
|
-
|
|
5246
|
+
resolve17(subprocess);
|
|
5247
5247
|
});
|
|
5248
5248
|
});
|
|
5249
5249
|
}
|
|
@@ -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
|
|
|
@@ -5459,16 +5459,16 @@ function compareSemver(a, b) {
|
|
|
5459
5459
|
return 0;
|
|
5460
5460
|
}
|
|
5461
5461
|
function fetchLatestNpmVersion(timeoutMs = 8e3) {
|
|
5462
|
-
return new Promise((
|
|
5462
|
+
return new Promise((resolve17) => {
|
|
5463
5463
|
(0, import_child_process.execFile)(
|
|
5464
5464
|
"npm",
|
|
5465
5465
|
["view", "@holdyourvoice/hyv", "version"],
|
|
5466
5466
|
{ timeout: timeoutMs, encoding: "utf-8" },
|
|
5467
5467
|
(err, stdout) => {
|
|
5468
5468
|
if (err || !stdout?.trim())
|
|
5469
|
-
|
|
5469
|
+
resolve17(null);
|
|
5470
5470
|
else
|
|
5471
|
-
|
|
5471
|
+
resolve17(stdout.trim());
|
|
5472
5472
|
}
|
|
5473
5473
|
);
|
|
5474
5474
|
});
|
|
@@ -5533,7 +5533,7 @@ function escapeHtml(value) {
|
|
|
5533
5533
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5534
5534
|
}
|
|
5535
5535
|
function request(url, options = {}) {
|
|
5536
|
-
return new Promise((
|
|
5536
|
+
return new Promise((resolve17, reject) => {
|
|
5537
5537
|
const urlObj = new URL(url);
|
|
5538
5538
|
const isHttps = urlObj.protocol === "https:";
|
|
5539
5539
|
const client = isHttps ? https : http;
|
|
@@ -5554,9 +5554,9 @@ function request(url, options = {}) {
|
|
|
5554
5554
|
res.on("data", (chunk) => data += chunk);
|
|
5555
5555
|
res.on("end", () => {
|
|
5556
5556
|
try {
|
|
5557
|
-
|
|
5557
|
+
resolve17({ status: res.statusCode || 0, data: JSON.parse(data) });
|
|
5558
5558
|
} catch {
|
|
5559
|
-
|
|
5559
|
+
resolve17({ status: res.statusCode || 0, data });
|
|
5560
5560
|
}
|
|
5561
5561
|
});
|
|
5562
5562
|
});
|
|
@@ -5614,9 +5614,9 @@ async function authenticateWithLicense(licenseKey) {
|
|
|
5614
5614
|
}
|
|
5615
5615
|
async function authenticateWithBrowser() {
|
|
5616
5616
|
const server = http.createServer();
|
|
5617
|
-
const port = await new Promise((
|
|
5617
|
+
const port = await new Promise((resolve17) => {
|
|
5618
5618
|
server.listen(0, "127.0.0.1", () => {
|
|
5619
|
-
|
|
5619
|
+
resolve17(server.address().port);
|
|
5620
5620
|
});
|
|
5621
5621
|
});
|
|
5622
5622
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
@@ -5635,11 +5635,11 @@ async function authenticateWithBrowser() {
|
|
|
5635
5635
|
}
|
|
5636
5636
|
console.log(import_chalk2.default.cyan("\nOpening browser for authentication..."));
|
|
5637
5637
|
await (0, import_open.default)(assertSafeOAuthUrl(auth_url));
|
|
5638
|
-
const authData = await new Promise((
|
|
5638
|
+
const authData = await new Promise((resolve17, reject) => {
|
|
5639
5639
|
const timeout = setTimeout(() => {
|
|
5640
5640
|
server.close();
|
|
5641
5641
|
reject(new Error(
|
|
5642
|
-
'Authentication timeout \u2014 browser did not return to the local callback.\nThis usually means Windows Defender Firewall blocked the local server.\nFix: run in PowerShell as Admin:\n New-NetFirewallRule -DisplayName "hyv-cli" -Direction Inbound -LocalPort ' + port + " -Protocol TCP -Action Allow\nOr use
|
|
5642
|
+
'Authentication timeout \u2014 browser did not return to the local callback.\nThis usually means Windows Defender Firewall blocked the local server.\nFix: run in PowerShell as Admin:\n New-NetFirewallRule -DisplayName "hyv-cli" -Direction Inbound -LocalPort ' + port + " -Protocol TCP -Action Allow\nOr use a license key: hyv init <license-key>"
|
|
5643
5643
|
));
|
|
5644
5644
|
}, 12e4);
|
|
5645
5645
|
server.on("request", async (req, res) => {
|
|
@@ -5694,7 +5694,7 @@ async function authenticateWithBrowser() {
|
|
|
5694
5694
|
`);
|
|
5695
5695
|
clearTimeout(timeout);
|
|
5696
5696
|
server.close();
|
|
5697
|
-
|
|
5697
|
+
resolve17(data);
|
|
5698
5698
|
} catch (error) {
|
|
5699
5699
|
res.writeHead(500, { "Content-Type": "text/html" });
|
|
5700
5700
|
res.end(`<h1>Authentication failed</h1><p>${escapeHtml(error.message)}</p>`);
|
|
@@ -5712,7 +5712,7 @@ async function authenticateWithBrowser() {
|
|
|
5712
5712
|
return authData;
|
|
5713
5713
|
}
|
|
5714
5714
|
async function openAuthenticatedDashboard(opts = {}) {
|
|
5715
|
-
const nextPath = opts.next || "/
|
|
5715
|
+
const nextPath = opts.next || "/dashboard?tab=billing";
|
|
5716
5716
|
try {
|
|
5717
5717
|
const response = await authenticatedRequest(cliApiUrl("/cli/auth/web-handoff"), {
|
|
5718
5718
|
method: "POST",
|
|
@@ -5727,7 +5727,7 @@ async function openAuthenticatedDashboard(opts = {}) {
|
|
|
5727
5727
|
}
|
|
5728
5728
|
} catch {
|
|
5729
5729
|
}
|
|
5730
|
-
const billingUrl = nextPath === "/
|
|
5730
|
+
const billingUrl = nextPath === "/dashboard?tab=billing" ? DASHBOARD_BILLING_URL : assertSafeOpenUrl(`https://holdyourvoice.com${nextPath}`);
|
|
5731
5731
|
await (0, import_open.default)(billingUrl);
|
|
5732
5732
|
}
|
|
5733
5733
|
async function refreshToken(tokenOverride) {
|
|
@@ -5879,7 +5879,7 @@ async function request2(method, path28, body) {
|
|
|
5879
5879
|
if (res.status === 401)
|
|
5880
5880
|
throw new Error("your session expired. run: hyv init to sign in again.");
|
|
5881
5881
|
if (res.status === 403)
|
|
5882
|
-
throw new Error("you don't have access to this feature. check your plan at holdyourvoice.com/
|
|
5882
|
+
throw new Error("you don't have access to this feature. check your plan at holdyourvoice.com/dashboard?tab=billing");
|
|
5883
5883
|
if (!res.ok) {
|
|
5884
5884
|
throw new Error(`something went wrong (${res.status}). try again or contact support.`);
|
|
5885
5885
|
}
|
|
@@ -6360,8 +6360,7 @@ async function requirePaidFeature(feature) {
|
|
|
6360
6360
|
throw new Error("can't reach the server. check your internet connection and try again.");
|
|
6361
6361
|
}
|
|
6362
6362
|
const plan = (data.plan || "none").toLowerCase();
|
|
6363
|
-
|
|
6364
|
-
if (!data.plan || plan === "none" || plan === "free" || plan === "expired" || subStatus === "trialing" || subStatus === "none") {
|
|
6363
|
+
if (!data.plan || plan === "none" || plan === "free" || plan === "expired") {
|
|
6365
6364
|
throw new Error(FEATURE_MESSAGES[feature]);
|
|
6366
6365
|
}
|
|
6367
6366
|
}
|
|
@@ -11526,7 +11525,7 @@ function isInteractiveTTY() {
|
|
|
11526
11525
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
|
|
11527
11526
|
}
|
|
11528
11527
|
function briefPause(ms2 = 280) {
|
|
11529
|
-
return new Promise((
|
|
11528
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms2));
|
|
11530
11529
|
}
|
|
11531
11530
|
async function withSpinner(label, fn, opts = {}) {
|
|
11532
11531
|
const minMs = opts.minMs ?? 450;
|
|
@@ -11846,7 +11845,7 @@ function saveLocalProfile(name, content) {
|
|
|
11846
11845
|
return path14.join(os9.homedir(), ".hyv", "profiles", `${safe}.md`);
|
|
11847
11846
|
}
|
|
11848
11847
|
function fetchUrlText(url) {
|
|
11849
|
-
return new Promise((
|
|
11848
|
+
return new Promise((resolve17, reject) => {
|
|
11850
11849
|
let parsed;
|
|
11851
11850
|
try {
|
|
11852
11851
|
parsed = new URL(url);
|
|
@@ -11875,7 +11874,7 @@ function fetchUrlText(url) {
|
|
|
11875
11874
|
});
|
|
11876
11875
|
res.on("end", () => {
|
|
11877
11876
|
const text = data.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
11878
|
-
|
|
11877
|
+
resolve17(text.slice(0, 12e3));
|
|
11879
11878
|
});
|
|
11880
11879
|
}
|
|
11881
11880
|
);
|
|
@@ -11895,10 +11894,10 @@ async function collectSamplesFromLink(url) {
|
|
|
11895
11894
|
}
|
|
11896
11895
|
function askLine(prompt) {
|
|
11897
11896
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
11898
|
-
return new Promise((
|
|
11897
|
+
return new Promise((resolve17) => {
|
|
11899
11898
|
rl.question(prompt, (answer) => {
|
|
11900
11899
|
rl.close();
|
|
11901
|
-
|
|
11900
|
+
resolve17(answer.trim());
|
|
11902
11901
|
});
|
|
11903
11902
|
});
|
|
11904
11903
|
}
|
|
@@ -11907,11 +11906,11 @@ async function askMultiline(intro) {
|
|
|
11907
11906
|
console.log(import_chalk12.default.dim(" paste below, then type --- on its own line when done\n"));
|
|
11908
11907
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
11909
11908
|
const lines = [];
|
|
11910
|
-
return new Promise((
|
|
11909
|
+
return new Promise((resolve17) => {
|
|
11911
11910
|
rl.on("line", (line) => {
|
|
11912
11911
|
if (line.trim() === "---") {
|
|
11913
11912
|
rl.close();
|
|
11914
|
-
|
|
11913
|
+
resolve17(lines.join("\n").trim());
|
|
11915
11914
|
return;
|
|
11916
11915
|
}
|
|
11917
11916
|
lines.push(line);
|
|
@@ -12125,7 +12124,7 @@ async function stepSignup(profileName) {
|
|
|
12125
12124
|
}
|
|
12126
12125
|
const upgrade = await askYesNo(" open billing to upgrade?", false);
|
|
12127
12126
|
if (upgrade) {
|
|
12128
|
-
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/
|
|
12127
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/dashboard?tab=billing" }));
|
|
12129
12128
|
await briefPause();
|
|
12130
12129
|
}
|
|
12131
12130
|
markStepComplete("signup");
|
|
@@ -12149,7 +12148,7 @@ async function stepSignup(profileName) {
|
|
|
12149
12148
|
}
|
|
12150
12149
|
await syncProfileToAccount(profileName);
|
|
12151
12150
|
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
12152
|
-
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/
|
|
12151
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/dashboard?tab=billing" }));
|
|
12153
12152
|
await briefPause();
|
|
12154
12153
|
markStepComplete("signup");
|
|
12155
12154
|
console.log(import_chalk12.default.dim("\n you're signed in \u2014 pick a plan in billing, no second login.\n"));
|
|
@@ -12365,7 +12364,7 @@ __export(billing_upgrade_exports, {
|
|
|
12365
12364
|
});
|
|
12366
12365
|
async function openBillingUpgrade(opts = {}) {
|
|
12367
12366
|
const plan = opts.plan || "individual";
|
|
12368
|
-
const next = `/
|
|
12367
|
+
const next = `/dashboard?tab=billing&checkout=${plan}`;
|
|
12369
12368
|
const token = getToken();
|
|
12370
12369
|
if (!token) {
|
|
12371
12370
|
console.log(import_chalk14.default.cyan("\nSign in to upgrade \u2014 opening browser...\n"));
|
|
@@ -15769,103 +15768,18 @@ var import_chalk35 = __toESM(require_source());
|
|
|
15769
15768
|
|
|
15770
15769
|
// src/commands/init.ts
|
|
15771
15770
|
var import_chalk4 = __toESM(require_source());
|
|
15772
|
-
var nodeFs = __toESM(require("fs"));
|
|
15773
15771
|
var nodePath = __toESM(require("path"));
|
|
15774
|
-
var nodeOs = __toESM(require("os"));
|
|
15775
15772
|
init_config();
|
|
15776
15773
|
init_auth();
|
|
15777
15774
|
function configureMcpForDesktop() {
|
|
15778
|
-
const results = [];
|
|
15779
|
-
const home = nodeOs.homedir();
|
|
15780
|
-
const isWin = process.platform === "win32";
|
|
15781
|
-
const claudeDir = isWin ? nodePath.join(home, "AppData", "Roaming", "Claude") : nodePath.join(home, "Library", "Application Support", "Claude");
|
|
15782
|
-
const claudeConfig = nodePath.join(claudeDir, "claude_desktop_config.json");
|
|
15783
|
-
if (nodeFs.existsSync(claudeDir)) {
|
|
15784
|
-
try {
|
|
15785
|
-
let cfg = {};
|
|
15786
|
-
if (nodeFs.existsSync(claudeConfig))
|
|
15787
|
-
cfg = JSON.parse(nodeFs.readFileSync(claudeConfig, "utf-8"));
|
|
15788
|
-
if (!cfg.mcpServers)
|
|
15789
|
-
cfg.mcpServers = {};
|
|
15790
|
-
if (!cfg.mcpServers.hyv) {
|
|
15791
|
-
cfg.mcpServers.hyv = { command: "hyv", args: ["mcp"] };
|
|
15792
|
-
nodeFs.writeFileSync(claudeConfig, JSON.stringify(cfg, null, 2));
|
|
15793
|
-
results.push("Claude Desktop");
|
|
15794
|
-
}
|
|
15795
|
-
} catch {
|
|
15796
|
-
}
|
|
15797
|
-
}
|
|
15798
|
-
const claudeCodeDir = nodePath.join(home, ".claude", "commands");
|
|
15799
|
-
if (nodeFs.existsSync(nodePath.dirname(claudeCodeDir))) {
|
|
15800
|
-
try {
|
|
15801
|
-
nodeFs.mkdirSync(claudeCodeDir, { recursive: true });
|
|
15802
|
-
const cmdFile = nodePath.join(claudeCodeDir, "hyv.md");
|
|
15803
|
-
if (!nodeFs.existsSync(cmdFile)) {
|
|
15804
|
-
const src = findAgentFile("claude-code.md");
|
|
15805
|
-
if (src) {
|
|
15806
|
-
nodeFs.copyFileSync(src, cmdFile);
|
|
15807
|
-
results.push("Claude Code");
|
|
15808
|
-
}
|
|
15809
|
-
}
|
|
15810
|
-
} catch {
|
|
15811
|
-
}
|
|
15812
|
-
}
|
|
15813
|
-
const cursorDir = nodePath.join(home, ".cursor");
|
|
15814
|
-
if (nodeFs.existsSync(cursorDir)) {
|
|
15815
|
-
try {
|
|
15816
|
-
const rulesFile = nodePath.join(cursorDir, "rules", "hyv.md");
|
|
15817
|
-
nodeFs.mkdirSync(nodePath.dirname(rulesFile), { recursive: true });
|
|
15818
|
-
if (!nodeFs.existsSync(rulesFile)) {
|
|
15819
|
-
const src = findAgentFile("cursor.md");
|
|
15820
|
-
if (src) {
|
|
15821
|
-
nodeFs.copyFileSync(src, rulesFile);
|
|
15822
|
-
results.push("Cursor");
|
|
15823
|
-
}
|
|
15824
|
-
}
|
|
15825
|
-
} catch {
|
|
15826
|
-
}
|
|
15827
|
-
}
|
|
15828
|
-
const wsDir = isWin ? nodePath.join(home, "AppData", "Roaming", "Windsurf") : nodePath.join(home, ".windsurf");
|
|
15829
|
-
if (nodeFs.existsSync(wsDir)) {
|
|
15830
|
-
try {
|
|
15831
|
-
const rulesFile = nodePath.join(wsDir, "rules", "hyv.md");
|
|
15832
|
-
nodeFs.mkdirSync(nodePath.dirname(rulesFile), { recursive: true });
|
|
15833
|
-
if (!nodeFs.existsSync(rulesFile)) {
|
|
15834
|
-
const src = findAgentFile("windsurf.md");
|
|
15835
|
-
if (src) {
|
|
15836
|
-
nodeFs.copyFileSync(src, rulesFile);
|
|
15837
|
-
results.push("Windsurf");
|
|
15838
|
-
}
|
|
15839
|
-
}
|
|
15840
|
-
} catch {
|
|
15841
|
-
}
|
|
15842
|
-
}
|
|
15843
15775
|
try {
|
|
15844
|
-
const
|
|
15845
|
-
|
|
15846
|
-
const
|
|
15847
|
-
|
|
15848
|
-
const src = findAgentFile("chatgpt.md");
|
|
15849
|
-
if (src) {
|
|
15850
|
-
nodeFs.copyFileSync(src, instrFile);
|
|
15851
|
-
results.push("ChatGPT");
|
|
15852
|
-
}
|
|
15853
|
-
}
|
|
15776
|
+
const pkgDir = nodePath.resolve(__dirname, "..");
|
|
15777
|
+
const { integrateDetectedAgents } = require(nodePath.join(pkgDir, "scripts", "postinstall-lib"));
|
|
15778
|
+
const result = integrateDetectedAgents({ pkgDir, quiet: true, force: false });
|
|
15779
|
+
return result.configured || [];
|
|
15854
15780
|
} catch {
|
|
15781
|
+
return [];
|
|
15855
15782
|
}
|
|
15856
|
-
return results;
|
|
15857
|
-
}
|
|
15858
|
-
function findAgentFile(filename) {
|
|
15859
|
-
const candidates = [
|
|
15860
|
-
nodePath.join(nodePath.dirname(__filename || ""), "..", "agents", filename),
|
|
15861
|
-
nodePath.join(process.cwd(), "agents", filename),
|
|
15862
|
-
nodePath.join(nodeOs.homedir(), ".hyv", "agents", filename)
|
|
15863
|
-
];
|
|
15864
|
-
for (const p of candidates) {
|
|
15865
|
-
if (nodeFs.existsSync(p))
|
|
15866
|
-
return p;
|
|
15867
|
-
}
|
|
15868
|
-
return null;
|
|
15869
15783
|
}
|
|
15870
15784
|
function registerInitCommand(program3) {
|
|
15871
15785
|
program3.command("init").description("Authenticate with Hold Your Voice").argument("[license-key]", "License key (skip browser flow)").option("--no-browser", "Skip browser-based authentication").action(async (licenseKey, options) => {
|
|
@@ -17181,7 +17095,7 @@ function registerImportCommand(program3) {
|
|
|
17181
17095
|
});
|
|
17182
17096
|
}
|
|
17183
17097
|
function askQuestion(question) {
|
|
17184
|
-
return new Promise((
|
|
17098
|
+
return new Promise((resolve17) => {
|
|
17185
17099
|
const readline3 = require("readline");
|
|
17186
17100
|
const rl = readline3.createInterface({
|
|
17187
17101
|
input: process.stdin,
|
|
@@ -17190,7 +17104,7 @@ function askQuestion(question) {
|
|
|
17190
17104
|
rl.question(import_chalk13.default.cyan(` ${question}
|
|
17191
17105
|
> `), (answer) => {
|
|
17192
17106
|
rl.close();
|
|
17193
|
-
|
|
17107
|
+
resolve17(answer.trim());
|
|
17194
17108
|
});
|
|
17195
17109
|
});
|
|
17196
17110
|
}
|
|
@@ -17787,7 +17701,7 @@ async function testMcpStdioSubprocess() {
|
|
|
17787
17701
|
const entry = resolveCliEntry();
|
|
17788
17702
|
if (!entry)
|
|
17789
17703
|
return { ok: false };
|
|
17790
|
-
return new Promise((
|
|
17704
|
+
return new Promise((resolve17) => {
|
|
17791
17705
|
const child = (0, import_child_process4.spawn)(process.execPath, [entry, "mcp"], {
|
|
17792
17706
|
stdio: ["pipe", "pipe", "pipe"],
|
|
17793
17707
|
env: { ...process.env, HYV_POSTINSTALL_QUIET: "1" }
|
|
@@ -17803,7 +17717,7 @@ async function testMcpStdioSubprocess() {
|
|
|
17803
17717
|
child.kill();
|
|
17804
17718
|
} catch {
|
|
17805
17719
|
}
|
|
17806
|
-
|
|
17720
|
+
resolve17({ ok, toolCount });
|
|
17807
17721
|
};
|
|
17808
17722
|
const timeout = setTimeout(() => finish(false), 1e4);
|
|
17809
17723
|
const handleLine = (line) => {
|
|
@@ -18208,11 +18122,11 @@ async function confirmDestructiveWrite(options) {
|
|
|
18208
18122
|
const question = `
|
|
18209
18123
|
${label}
|
|
18210
18124
|
A .bak backup will be created. Proceed? [y/N] `;
|
|
18211
|
-
const answer = await new Promise((
|
|
18125
|
+
const answer = await new Promise((resolve17) => {
|
|
18212
18126
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
18213
18127
|
rl.question(question, (value) => {
|
|
18214
18128
|
rl.close();
|
|
18215
|
-
|
|
18129
|
+
resolve17(value.trim().toLowerCase());
|
|
18216
18130
|
});
|
|
18217
18131
|
});
|
|
18218
18132
|
return answer === "y" || answer === "yes";
|
|
@@ -18972,9 +18886,9 @@ var import_chalk30 = __toESM(require_source());
|
|
|
18972
18886
|
var PAGES = {
|
|
18973
18887
|
dashboard: "https://holdyourvoice.com/dashboard",
|
|
18974
18888
|
profiles: "https://holdyourvoice.com/dashboard?tab=profiles",
|
|
18975
|
-
pricing: "https://holdyourvoice.com/
|
|
18889
|
+
pricing: "https://holdyourvoice.com/dashboard?tab=billing",
|
|
18976
18890
|
settings: "https://holdyourvoice.com/dashboard",
|
|
18977
|
-
billing: "https://holdyourvoice.com/
|
|
18891
|
+
billing: "https://holdyourvoice.com/dashboard?tab=billing"
|
|
18978
18892
|
};
|
|
18979
18893
|
function registerOpenCommand(program3) {
|
|
18980
18894
|
program3.command("open").description("Open the web dashboard in your browser").option("--page <path>", "Page: dashboard, profiles, pricing, settings", "dashboard").option("--profile <name>", "Deep-link to a specific profile").option("--no-browser", "Print URL only, don't open").action(async (options) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdyourvoice/hyv",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.21",
|
|
4
4
|
"description": "Free local AI writing scan for cursor & claude. MCP server, 220+ pattern detection, voice profiles. npx @holdyourvoice/hyv welcome",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|