@holdyourvoice/hyv 2.9.5 → 2.9.7
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 +127 -186
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4612,40 +4612,6 @@ var require_source = __commonJS({
|
|
|
4612
4612
|
});
|
|
4613
4613
|
|
|
4614
4614
|
// src/lib/config.ts
|
|
4615
|
-
var config_exports = {};
|
|
4616
|
-
__export(config_exports, {
|
|
4617
|
-
API_BASE: () => API_BASE,
|
|
4618
|
-
AUTH_FILE: () => AUTH_FILE,
|
|
4619
|
-
CACHE_DIR: () => CACHE_DIR,
|
|
4620
|
-
CONFIG_FILE: () => CONFIG_FILE,
|
|
4621
|
-
HYV_DIR: () => HYV_DIR,
|
|
4622
|
-
LAST_SESSION_FILE: () => LAST_SESSION_FILE,
|
|
4623
|
-
PROFILES_DIR: () => PROFILES_DIR,
|
|
4624
|
-
QUEUE_DIR: () => QUEUE_DIR,
|
|
4625
|
-
appendSecureLine: () => appendSecureLine,
|
|
4626
|
-
assertSafeOAuthUrl: () => assertSafeOAuthUrl,
|
|
4627
|
-
assertSafeOpenUrl: () => assertSafeOpenUrl2,
|
|
4628
|
-
assertSafeProfileName: () => assertSafeProfileName,
|
|
4629
|
-
clearAuth: () => clearAuth,
|
|
4630
|
-
clearQueuedSignals: () => clearQueuedSignals,
|
|
4631
|
-
cliApiUrl: () => cliApiUrl,
|
|
4632
|
-
ensureHyvDir: () => ensureHyvDir,
|
|
4633
|
-
getQueuedSignals: () => getQueuedSignals,
|
|
4634
|
-
getToken: () => getToken,
|
|
4635
|
-
isInitialized: () => isInitialized,
|
|
4636
|
-
listCachedProfiles: () => listCachedProfiles,
|
|
4637
|
-
profilePathForName: () => profilePathForName,
|
|
4638
|
-
queueSignal: () => queueSignal,
|
|
4639
|
-
readAuth: () => readAuth,
|
|
4640
|
-
readCachedProfile: () => readCachedProfile,
|
|
4641
|
-
readConfig: () => readConfig,
|
|
4642
|
-
readLastEditSession: () => readLastEditSession,
|
|
4643
|
-
saveLastEditSession: () => saveLastEditSession,
|
|
4644
|
-
writeAuth: () => writeAuth,
|
|
4645
|
-
writeCachedProfile: () => writeCachedProfile,
|
|
4646
|
-
writeConfig: () => writeConfig,
|
|
4647
|
-
writeSecureFile: () => writeSecureFile
|
|
4648
|
-
});
|
|
4649
4615
|
function validateApiBase(raw) {
|
|
4650
4616
|
const trimmed = raw.replace(/\/$/, "");
|
|
4651
4617
|
let parsed;
|
|
@@ -4666,7 +4632,7 @@ function cliApiUrl(apiPath) {
|
|
|
4666
4632
|
const p = apiPath.startsWith("/") ? apiPath : `/${apiPath}`;
|
|
4667
4633
|
return `${API_BASE}${p}`;
|
|
4668
4634
|
}
|
|
4669
|
-
function
|
|
4635
|
+
function assertSafeOpenUrl(url) {
|
|
4670
4636
|
let parsed;
|
|
4671
4637
|
try {
|
|
4672
4638
|
parsed = new URL(url);
|
|
@@ -4714,6 +4680,10 @@ function assertSafeProfileName(name) {
|
|
|
4714
4680
|
}
|
|
4715
4681
|
return normalized;
|
|
4716
4682
|
}
|
|
4683
|
+
function toSafeProfileCacheKey(name) {
|
|
4684
|
+
const normalized = String(name || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4685
|
+
return assertSafeProfileName(normalized || "profile");
|
|
4686
|
+
}
|
|
4717
4687
|
function profilePathForName(name) {
|
|
4718
4688
|
const safe = assertSafeProfileName(name);
|
|
4719
4689
|
ensureHyvDir();
|
|
@@ -4737,10 +4707,6 @@ function ensureHyvDir() {
|
|
|
4737
4707
|
}
|
|
4738
4708
|
}
|
|
4739
4709
|
}
|
|
4740
|
-
function writeSecureFile(filePath, content) {
|
|
4741
|
-
ensureHyvDir();
|
|
4742
|
-
fs.writeFileSync(filePath, content, { mode: 384 });
|
|
4743
|
-
}
|
|
4744
4710
|
function appendSecureLine(filePath, line, dir) {
|
|
4745
4711
|
if (dir) {
|
|
4746
4712
|
if (!fs.existsSync(dir))
|
|
@@ -4779,11 +4745,6 @@ function writeAuth(auth) {
|
|
|
4779
4745
|
ensureHyvDir();
|
|
4780
4746
|
fs.writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { mode: 384 });
|
|
4781
4747
|
}
|
|
4782
|
-
function clearAuth() {
|
|
4783
|
-
if (fs.existsSync(AUTH_FILE)) {
|
|
4784
|
-
fs.unlinkSync(AUTH_FILE);
|
|
4785
|
-
}
|
|
4786
|
-
}
|
|
4787
4748
|
function readConfig() {
|
|
4788
4749
|
try {
|
|
4789
4750
|
if (!fs.existsSync(CONFIG_FILE))
|
|
@@ -4854,17 +4815,6 @@ function queueSignal(signal) {
|
|
|
4854
4815
|
const filePath = path.join(QUEUE_DIR, `${id}.json`);
|
|
4855
4816
|
fs.writeFileSync(filePath, JSON.stringify(signal, null, 2), { mode: 384 });
|
|
4856
4817
|
}
|
|
4857
|
-
function clearQueuedSignals() {
|
|
4858
|
-
try {
|
|
4859
|
-
if (!fs.existsSync(QUEUE_DIR))
|
|
4860
|
-
return;
|
|
4861
|
-
const files = fs.readdirSync(QUEUE_DIR).filter((f) => f.endsWith(".json"));
|
|
4862
|
-
for (const f of files) {
|
|
4863
|
-
fs.unlinkSync(path.join(QUEUE_DIR, f));
|
|
4864
|
-
}
|
|
4865
|
-
} catch {
|
|
4866
|
-
}
|
|
4867
|
-
}
|
|
4868
4818
|
function saveLastEditSession(session) {
|
|
4869
4819
|
ensureHyvDir();
|
|
4870
4820
|
const data = { ...session, saved_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
@@ -5245,6 +5195,91 @@ var require_open = __commonJS({
|
|
|
5245
5195
|
}
|
|
5246
5196
|
});
|
|
5247
5197
|
|
|
5198
|
+
// src/lib/free-paid.ts
|
|
5199
|
+
function printFreePaidMatrix(opts = {}) {
|
|
5200
|
+
if (opts.compact) {
|
|
5201
|
+
console.log(import_chalk.default.bold("\nFree forever (local)"));
|
|
5202
|
+
console.log(import_chalk.default.dim(" scan, fix, check, score, diff, mcp, all web tools"));
|
|
5203
|
+
console.log(import_chalk.default.bold("\nPaid power"));
|
|
5204
|
+
console.log(import_chalk.default.dim(" profiles, learning, hybrid analysis, rich rewrites"));
|
|
5205
|
+
console.log(import_chalk.default.dim(` ${PRICING_URL} | hyv plan --upgrade
|
|
5206
|
+
`));
|
|
5207
|
+
return;
|
|
5208
|
+
}
|
|
5209
|
+
console.log(import_chalk.default.bold("\n\u2500\u2500 Free forever (no account) \u2500\u2500\n"));
|
|
5210
|
+
console.log(import_chalk.default.dim("CLI (offline):"));
|
|
5211
|
+
for (const line of FREE_CLI_COMMANDS) {
|
|
5212
|
+
console.log(import_chalk.default.dim(" \u2022 ") + line);
|
|
5213
|
+
}
|
|
5214
|
+
console.log(import_chalk.default.dim("\nTry without installing:"));
|
|
5215
|
+
for (const line of NPX_EXAMPLES) {
|
|
5216
|
+
console.log(import_chalk.default.cyan(` ${line}`));
|
|
5217
|
+
}
|
|
5218
|
+
console.log(import_chalk.default.dim("\nWeb tools (30+ free):"));
|
|
5219
|
+
for (const t of FREE_WEB_TOOLS.slice(0, 8)) {
|
|
5220
|
+
console.log(import_chalk.default.dim(` \u2022 ${t.name}`) + import_chalk.default.cyan(` \u2014 ${t.url}`));
|
|
5221
|
+
}
|
|
5222
|
+
console.log(import_chalk.default.dim(` \u2022 \u2026and more \u2014 ${FREE_WEB_TOOLS[0].url}`));
|
|
5223
|
+
console.log(import_chalk.default.bold("\n\u2500\u2500 Paid unlocks \u2500\u2500\n"));
|
|
5224
|
+
for (const line of PAID_FEATURES) {
|
|
5225
|
+
console.log(import_chalk.default.dim(" \u2022 ") + line);
|
|
5226
|
+
}
|
|
5227
|
+
console.log(import_chalk.default.dim(`
|
|
5228
|
+
First month $1 \u2192 ${PRICING_URL}`));
|
|
5229
|
+
console.log(import_chalk.default.dim(" hyv init | hyv plan --upgrade\n"));
|
|
5230
|
+
}
|
|
5231
|
+
var import_chalk, NPX_EXAMPLES, FREE_CLI_COMMANDS, PAID_FEATURES, FREE_WEB_TOOLS, COMMUNITY_URL, PRICING_URL, DASHBOARD_BILLING_URL;
|
|
5232
|
+
var init_free_paid = __esm({
|
|
5233
|
+
"src/lib/free-paid.ts"() {
|
|
5234
|
+
"use strict";
|
|
5235
|
+
import_chalk = __toESM(require_source());
|
|
5236
|
+
NPX_EXAMPLES = [
|
|
5237
|
+
"npx @holdyourvoice/hyv welcome",
|
|
5238
|
+
"npx @holdyourvoice/hyv scan draft.md",
|
|
5239
|
+
"npx @holdyourvoice/hyv fix draft.md",
|
|
5240
|
+
"npx @holdyourvoice/hyv init",
|
|
5241
|
+
"npx @holdyourvoice/hyv mcp"
|
|
5242
|
+
];
|
|
5243
|
+
FREE_CLI_COMMANDS = [
|
|
5244
|
+
"hyv scan / fix / check / score / diff / batch / watch",
|
|
5245
|
+
"hyv rules / history / demo / doctor / upgrade",
|
|
5246
|
+
"hyv export (local profile markdown)",
|
|
5247
|
+
"hyv mcp \u2014 agent tools (hyv_scan, hyv_clean, hyv_analyze, \u2026)",
|
|
5248
|
+
"hyv welcome / hyv free \u2014 full capability tour",
|
|
5249
|
+
"hyv content \u2014 blog & share templates",
|
|
5250
|
+
"hyv plan --free \u2014 see what paid unlocks"
|
|
5251
|
+
];
|
|
5252
|
+
PAID_FEATURES = [
|
|
5253
|
+
"Voice profiles synced from your account (never-list, anchors, learned patterns)",
|
|
5254
|
+
"Learning loop: hyv reinforce, hyv add \u2014 profile gets sharper every week",
|
|
5255
|
+
"Rich profile-aware rewrite prompts (hyv rewrite)",
|
|
5256
|
+
"Hybrid server analysis (hyv scan --server, MCP hyv_analyze)",
|
|
5257
|
+
"Multiple profiles + team voices (Team plan)",
|
|
5258
|
+
"Dashboard at holdyourvoice.com/app"
|
|
5259
|
+
];
|
|
5260
|
+
FREE_WEB_TOOLS = [
|
|
5261
|
+
{ name: "All free tools", url: "https://holdyourvoice.com/tools" },
|
|
5262
|
+
{ name: "Headline Analyzer", url: "https://holdyourvoice.com/tools/headline-analyzer" },
|
|
5263
|
+
{ name: "Brand Voice Analyzer", url: "https://holdyourvoice.com/tools/brand-voice-analyzer" },
|
|
5264
|
+
{ name: "AI Writing Analyzer", url: "https://holdyourvoice.com/tools/ai-writing-analyzer" },
|
|
5265
|
+
{ name: "Voice Audit (AI score)", url: "https://holdyourvoice.com/tools/voice-audit" },
|
|
5266
|
+
{ name: "Readability Checker", url: "https://holdyourvoice.com/tools/readability-checker" },
|
|
5267
|
+
{ name: "Email Subject Scorer", url: "https://holdyourvoice.com/tools/email-subject-scorer" },
|
|
5268
|
+
{ name: "Customer Persona Builder", url: "https://holdyourvoice.com/tools/customer-persona-builder" },
|
|
5269
|
+
{ name: "Brand Positioning Template", url: "https://holdyourvoice.com/tools/brand-positioning-template" },
|
|
5270
|
+
{ name: "Value Proposition Generator", url: "https://holdyourvoice.com/tools/value-proposition-generator" },
|
|
5271
|
+
{ name: "Grammar Checker", url: "https://holdyourvoice.com/tools/grammar-checker" },
|
|
5272
|
+
{ name: "Paraphrasing Tool", url: "https://holdyourvoice.com/tools/paraphrasing-tool" },
|
|
5273
|
+
{ name: "Tagline Generator", url: "https://holdyourvoice.com/tools/tagline-generator" },
|
|
5274
|
+
{ name: "Public voice profiles", url: "https://holdyourvoice.com/profiles" },
|
|
5275
|
+
{ name: "Blog", url: "https://holdyourvoice.com/blog" }
|
|
5276
|
+
];
|
|
5277
|
+
COMMUNITY_URL = "https://holdyourvoice.com/community";
|
|
5278
|
+
PRICING_URL = "https://holdyourvoice.com/#pricing";
|
|
5279
|
+
DASHBOARD_BILLING_URL = "https://holdyourvoice.com/app/billing";
|
|
5280
|
+
}
|
|
5281
|
+
});
|
|
5282
|
+
|
|
5248
5283
|
// src/lib/version.ts
|
|
5249
5284
|
function pkgRoot() {
|
|
5250
5285
|
const candidates = [
|
|
@@ -5468,7 +5503,7 @@ async function authenticateWithBrowser() {
|
|
|
5468
5503
|
server.close();
|
|
5469
5504
|
throw new Error("Authentication server did not return OAuth state");
|
|
5470
5505
|
}
|
|
5471
|
-
console.log(
|
|
5506
|
+
console.log(import_chalk2.default.cyan("\nOpening browser for authentication..."));
|
|
5472
5507
|
await (0, import_open.default)(assertSafeOAuthUrl(auth_url));
|
|
5473
5508
|
const authData = await new Promise((resolve15, reject) => {
|
|
5474
5509
|
const timeout = setTimeout(() => {
|
|
@@ -5545,20 +5580,23 @@ async function authenticateWithBrowser() {
|
|
|
5545
5580
|
return authData;
|
|
5546
5581
|
}
|
|
5547
5582
|
async function openAuthenticatedDashboard(opts = {}) {
|
|
5548
|
-
const
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5583
|
+
const nextPath = opts.next || "/app/billing";
|
|
5584
|
+
try {
|
|
5585
|
+
const response = await authenticatedRequest(cliApiUrl("/cli/auth/web-handoff"), {
|
|
5586
|
+
method: "POST",
|
|
5587
|
+
body: { next: nextPath }
|
|
5588
|
+
});
|
|
5589
|
+
if (response.status === 200) {
|
|
5590
|
+
const { url } = response.data;
|
|
5591
|
+
if (url) {
|
|
5592
|
+
await (0, import_open.default)(assertSafeOpenUrl(url));
|
|
5593
|
+
return;
|
|
5594
|
+
}
|
|
5552
5595
|
}
|
|
5553
|
-
}
|
|
5554
|
-
if (response.status !== 200) {
|
|
5555
|
-
throw new Error("Could not open dashboard \u2014 try https://holdyourvoice.com/dashboard");
|
|
5556
|
-
}
|
|
5557
|
-
const { url } = response.data;
|
|
5558
|
-
if (!url) {
|
|
5559
|
-
throw new Error("Dashboard handoff URL missing");
|
|
5596
|
+
} catch {
|
|
5560
5597
|
}
|
|
5561
|
-
|
|
5598
|
+
const billingUrl = nextPath === "/app/billing" ? DASHBOARD_BILLING_URL : assertSafeOpenUrl(`https://holdyourvoice.com${nextPath}`);
|
|
5599
|
+
await (0, import_open.default)(billingUrl);
|
|
5562
5600
|
}
|
|
5563
5601
|
async function refreshToken(tokenOverride) {
|
|
5564
5602
|
const token = tokenOverride || readAuth()?.token;
|
|
@@ -5604,116 +5642,21 @@ async function checkSession() {
|
|
|
5604
5642
|
return { valid: false };
|
|
5605
5643
|
}
|
|
5606
5644
|
}
|
|
5607
|
-
var http, https,
|
|
5645
|
+
var http, https, import_chalk2, import_open;
|
|
5608
5646
|
var init_auth = __esm({
|
|
5609
5647
|
"src/lib/auth.ts"() {
|
|
5610
5648
|
"use strict";
|
|
5611
5649
|
http = __toESM(require("http"));
|
|
5612
5650
|
https = __toESM(require("https"));
|
|
5613
|
-
|
|
5651
|
+
import_chalk2 = __toESM(require_source());
|
|
5614
5652
|
import_open = __toESM(require_open());
|
|
5615
5653
|
init_config();
|
|
5654
|
+
init_free_paid();
|
|
5616
5655
|
init_version();
|
|
5617
5656
|
init_auth_refresh();
|
|
5618
5657
|
}
|
|
5619
5658
|
});
|
|
5620
5659
|
|
|
5621
|
-
// src/lib/free-paid.ts
|
|
5622
|
-
var free_paid_exports = {};
|
|
5623
|
-
__export(free_paid_exports, {
|
|
5624
|
-
COMMUNITY_URL: () => COMMUNITY_URL,
|
|
5625
|
-
DASHBOARD_BILLING_URL: () => DASHBOARD_BILLING_URL,
|
|
5626
|
-
FREE_CLI_COMMANDS: () => FREE_CLI_COMMANDS,
|
|
5627
|
-
FREE_WEB_TOOLS: () => FREE_WEB_TOOLS,
|
|
5628
|
-
NPX_EXAMPLES: () => NPX_EXAMPLES,
|
|
5629
|
-
PAID_FEATURES: () => PAID_FEATURES,
|
|
5630
|
-
PRICING_URL: () => PRICING_URL,
|
|
5631
|
-
printFreePaidMatrix: () => printFreePaidMatrix
|
|
5632
|
-
});
|
|
5633
|
-
function printFreePaidMatrix(opts = {}) {
|
|
5634
|
-
if (opts.compact) {
|
|
5635
|
-
console.log(import_chalk2.default.bold("\nFree forever (local)"));
|
|
5636
|
-
console.log(import_chalk2.default.dim(" scan, fix, check, score, diff, mcp, all web tools"));
|
|
5637
|
-
console.log(import_chalk2.default.bold("\nPaid power"));
|
|
5638
|
-
console.log(import_chalk2.default.dim(" profiles, learning, hybrid analysis, rich rewrites"));
|
|
5639
|
-
console.log(import_chalk2.default.dim(` ${PRICING_URL} | hyv plan --upgrade
|
|
5640
|
-
`));
|
|
5641
|
-
return;
|
|
5642
|
-
}
|
|
5643
|
-
console.log(import_chalk2.default.bold("\n\u2500\u2500 Free forever (no account) \u2500\u2500\n"));
|
|
5644
|
-
console.log(import_chalk2.default.dim("CLI (offline):"));
|
|
5645
|
-
for (const line of FREE_CLI_COMMANDS) {
|
|
5646
|
-
console.log(import_chalk2.default.dim(" \u2022 ") + line);
|
|
5647
|
-
}
|
|
5648
|
-
console.log(import_chalk2.default.dim("\nTry without installing:"));
|
|
5649
|
-
for (const line of NPX_EXAMPLES) {
|
|
5650
|
-
console.log(import_chalk2.default.cyan(` ${line}`));
|
|
5651
|
-
}
|
|
5652
|
-
console.log(import_chalk2.default.dim("\nWeb tools (30+ free):"));
|
|
5653
|
-
for (const t of FREE_WEB_TOOLS.slice(0, 8)) {
|
|
5654
|
-
console.log(import_chalk2.default.dim(` \u2022 ${t.name}`) + import_chalk2.default.cyan(` \u2014 ${t.url}`));
|
|
5655
|
-
}
|
|
5656
|
-
console.log(import_chalk2.default.dim(` \u2022 \u2026and more \u2014 ${FREE_WEB_TOOLS[0].url}`));
|
|
5657
|
-
console.log(import_chalk2.default.bold("\n\u2500\u2500 Paid unlocks \u2500\u2500\n"));
|
|
5658
|
-
for (const line of PAID_FEATURES) {
|
|
5659
|
-
console.log(import_chalk2.default.dim(" \u2022 ") + line);
|
|
5660
|
-
}
|
|
5661
|
-
console.log(import_chalk2.default.dim(`
|
|
5662
|
-
First month $1 \u2192 ${PRICING_URL}`));
|
|
5663
|
-
console.log(import_chalk2.default.dim(" hyv init | hyv plan --upgrade\n"));
|
|
5664
|
-
}
|
|
5665
|
-
var import_chalk2, NPX_EXAMPLES, FREE_CLI_COMMANDS, PAID_FEATURES, FREE_WEB_TOOLS, COMMUNITY_URL, PRICING_URL, DASHBOARD_BILLING_URL;
|
|
5666
|
-
var init_free_paid = __esm({
|
|
5667
|
-
"src/lib/free-paid.ts"() {
|
|
5668
|
-
"use strict";
|
|
5669
|
-
import_chalk2 = __toESM(require_source());
|
|
5670
|
-
NPX_EXAMPLES = [
|
|
5671
|
-
"npx @holdyourvoice/hyv welcome",
|
|
5672
|
-
"npx @holdyourvoice/hyv scan draft.md",
|
|
5673
|
-
"npx @holdyourvoice/hyv fix draft.md",
|
|
5674
|
-
"npx @holdyourvoice/hyv init",
|
|
5675
|
-
"npx @holdyourvoice/hyv mcp"
|
|
5676
|
-
];
|
|
5677
|
-
FREE_CLI_COMMANDS = [
|
|
5678
|
-
"hyv scan / fix / check / score / diff / batch / watch",
|
|
5679
|
-
"hyv rules / history / demo / doctor / upgrade",
|
|
5680
|
-
"hyv export (local profile markdown)",
|
|
5681
|
-
"hyv mcp \u2014 agent tools (hyv_scan, hyv_clean, hyv_analyze, \u2026)",
|
|
5682
|
-
"hyv welcome / hyv free \u2014 full capability tour",
|
|
5683
|
-
"hyv content \u2014 blog & share templates",
|
|
5684
|
-
"hyv plan --free \u2014 see what paid unlocks"
|
|
5685
|
-
];
|
|
5686
|
-
PAID_FEATURES = [
|
|
5687
|
-
"Voice profiles synced from your account (never-list, anchors, learned patterns)",
|
|
5688
|
-
"Learning loop: hyv reinforce, hyv add \u2014 profile gets sharper every week",
|
|
5689
|
-
"Rich profile-aware rewrite prompts (hyv rewrite)",
|
|
5690
|
-
"Hybrid server analysis (hyv scan --server, MCP hyv_analyze)",
|
|
5691
|
-
"Multiple profiles + team voices (Team plan)",
|
|
5692
|
-
"Dashboard at holdyourvoice.com/dashboard"
|
|
5693
|
-
];
|
|
5694
|
-
FREE_WEB_TOOLS = [
|
|
5695
|
-
{ name: "All free tools", url: "https://holdyourvoice.com/tools" },
|
|
5696
|
-
{ name: "Headline Analyzer", url: "https://holdyourvoice.com/tools/headline-analyzer" },
|
|
5697
|
-
{ name: "Brand Voice Analyzer", url: "https://holdyourvoice.com/tools/brand-voice-analyzer" },
|
|
5698
|
-
{ name: "AI Writing Analyzer", url: "https://holdyourvoice.com/tools/ai-writing-analyzer" },
|
|
5699
|
-
{ name: "Voice Audit (AI score)", url: "https://holdyourvoice.com/tools/voice-audit" },
|
|
5700
|
-
{ name: "Readability Checker", url: "https://holdyourvoice.com/tools/readability-checker" },
|
|
5701
|
-
{ name: "Email Subject Scorer", url: "https://holdyourvoice.com/tools/email-subject-scorer" },
|
|
5702
|
-
{ name: "Customer Persona Builder", url: "https://holdyourvoice.com/tools/customer-persona-builder" },
|
|
5703
|
-
{ name: "Brand Positioning Template", url: "https://holdyourvoice.com/tools/brand-positioning-template" },
|
|
5704
|
-
{ name: "Value Proposition Generator", url: "https://holdyourvoice.com/tools/value-proposition-generator" },
|
|
5705
|
-
{ name: "Grammar Checker", url: "https://holdyourvoice.com/tools/grammar-checker" },
|
|
5706
|
-
{ name: "Paraphrasing Tool", url: "https://holdyourvoice.com/tools/paraphrasing-tool" },
|
|
5707
|
-
{ name: "Tagline Generator", url: "https://holdyourvoice.com/tools/tagline-generator" },
|
|
5708
|
-
{ name: "Public voice profiles", url: "https://holdyourvoice.com/profiles" },
|
|
5709
|
-
{ name: "Blog", url: "https://holdyourvoice.com/blog" }
|
|
5710
|
-
];
|
|
5711
|
-
COMMUNITY_URL = "https://holdyourvoice.com/community";
|
|
5712
|
-
PRICING_URL = "https://holdyourvoice.com/#pricing";
|
|
5713
|
-
DASHBOARD_BILLING_URL = "https://holdyourvoice.com/app/billing";
|
|
5714
|
-
}
|
|
5715
|
-
});
|
|
5716
|
-
|
|
5717
5660
|
// src/lib/marketing-hints.ts
|
|
5718
5661
|
var marketing_hints_exports = {};
|
|
5719
5662
|
__export(marketing_hints_exports, {
|
|
@@ -11853,22 +11796,17 @@ async function stepSignup(profileName) {
|
|
|
11853
11796
|
if (response.status === 200) {
|
|
11854
11797
|
console.log(import_chalk12.default.green(" \u2713 profile synced to your account"));
|
|
11855
11798
|
} else {
|
|
11856
|
-
|
|
11799
|
+
const detail = response.data?.error;
|
|
11800
|
+
console.log(import_chalk12.default.yellow(
|
|
11801
|
+
` profile saved locally \u2014 sync with \`hyv sync\`${detail ? ` (${detail})` : ` (HTTP ${response.status})`}`
|
|
11802
|
+
));
|
|
11857
11803
|
}
|
|
11858
|
-
} catch {
|
|
11859
|
-
console.log(import_chalk12.default.yellow(
|
|
11860
|
-
}
|
|
11861
|
-
try {
|
|
11862
|
-
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
11863
|
-
await withSpinner("opening dashboard\u2026", () => openAuthenticatedDashboard({ next: "/app/billing" }));
|
|
11864
|
-
await briefPause();
|
|
11865
|
-
} catch {
|
|
11866
|
-
const { DASHBOARD_BILLING_URL: DASHBOARD_BILLING_URL2 } = await Promise.resolve().then(() => (init_free_paid(), free_paid_exports));
|
|
11867
|
-
const { assertSafeOpenUrl: assertSafeOpenUrl3 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
11868
|
-
const { default: open3 } = await Promise.resolve().then(() => __toESM(require_open()));
|
|
11869
|
-
console.log(import_chalk12.default.yellow(" handoff unavailable \u2014 opening billing (sign in if prompted)..."));
|
|
11870
|
-
await open3(assertSafeOpenUrl3(DASHBOARD_BILLING_URL2));
|
|
11804
|
+
} catch (err) {
|
|
11805
|
+
console.log(import_chalk12.default.yellow(` profile saved locally \u2014 run \`hyv sync\` (${err?.message || "sync failed"})`));
|
|
11871
11806
|
}
|
|
11807
|
+
console.log(import_chalk12.default.cyan("\n opening billing in your dashboard ($1 first month)..."));
|
|
11808
|
+
await withSpinner("opening billing\u2026", () => openAuthenticatedDashboard({ next: "/app/billing" }));
|
|
11809
|
+
await briefPause();
|
|
11872
11810
|
markStepComplete("signup");
|
|
11873
11811
|
console.log(import_chalk12.default.dim("\n you're signed in \u2014 pick a plan in billing, no second login.\n"));
|
|
11874
11812
|
}
|
|
@@ -15796,7 +15734,8 @@ function registerSyncCommand(program3) {
|
|
|
15796
15734
|
ensureHyvDir();
|
|
15797
15735
|
let profileCount = 0;
|
|
15798
15736
|
for (const profile of data.profiles) {
|
|
15799
|
-
|
|
15737
|
+
const cacheKey = toSafeProfileCacheKey(profile.slug || profile.name);
|
|
15738
|
+
writeCachedProfile(cacheKey, profile.content);
|
|
15800
15739
|
profileCount++;
|
|
15801
15740
|
}
|
|
15802
15741
|
const rulesPath = path7.join(CACHE_DIR, "rules.md");
|
|
@@ -15809,7 +15748,8 @@ function registerSyncCommand(program3) {
|
|
|
15809
15748
|
}
|
|
15810
15749
|
for (const profile of data.profiles) {
|
|
15811
15750
|
try {
|
|
15812
|
-
|
|
15751
|
+
const cacheKey = toSafeProfileCacheKey(profile.slug || profile.name);
|
|
15752
|
+
await loadFullProfile(cacheKey, { forceRefresh: true });
|
|
15813
15753
|
} catch {
|
|
15814
15754
|
}
|
|
15815
15755
|
}
|
|
@@ -16918,7 +16858,7 @@ async function openBillingPortal() {
|
|
|
16918
16858
|
const portalUrl = data.portal_url;
|
|
16919
16859
|
if (portalUrl) {
|
|
16920
16860
|
console.log(import_chalk14.default.dim("Opening browser..."));
|
|
16921
|
-
await (0, import_open2.default)(
|
|
16861
|
+
await (0, import_open2.default)(assertSafeOpenUrl(portalUrl));
|
|
16922
16862
|
console.log(import_chalk14.default.green("\n\u2713 Billing portal opened"));
|
|
16923
16863
|
} else {
|
|
16924
16864
|
console.log(import_chalk14.default.yellow("No portal URL received."));
|
|
@@ -18480,10 +18420,11 @@ function registerDemoCommand(program3) {
|
|
|
18480
18420
|
// src/commands/open.ts
|
|
18481
18421
|
var import_chalk29 = __toESM(require_source());
|
|
18482
18422
|
var PAGES = {
|
|
18483
|
-
dashboard: "https://holdyourvoice.com/
|
|
18484
|
-
profiles: "https://holdyourvoice.com/
|
|
18423
|
+
dashboard: "https://holdyourvoice.com/app",
|
|
18424
|
+
profiles: "https://holdyourvoice.com/app",
|
|
18485
18425
|
pricing: "https://holdyourvoice.com/app/billing",
|
|
18486
|
-
settings: "https://holdyourvoice.com/
|
|
18426
|
+
settings: "https://holdyourvoice.com/app/settings",
|
|
18427
|
+
billing: "https://holdyourvoice.com/app/billing"
|
|
18487
18428
|
};
|
|
18488
18429
|
function registerOpenCommand(program3) {
|
|
18489
18430
|
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