@holdyourvoice/hyv 2.9.15 → 2.9.17

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 CHANGED
@@ -20,7 +20,7 @@ npx @holdyourvoice/hyv scan draft.md
20
20
  curl -fsSL https://holdyourvoice.com/install.sh | bash
21
21
 
22
22
  # windows (powershell)
23
- irm https://holdyourvoice.com/install.ps1 | iex
23
+ powershell -ExecutionPolicy Bypass -c "irm https://holdyourvoice.com/install.ps1 | iex"
24
24
  ```
25
25
 
26
26
  Already have node 18+?
package/dist/index.js CHANGED
@@ -4381,14 +4381,14 @@ var require_templates = __commonJS({
4381
4381
  }
4382
4382
  return results;
4383
4383
  }
4384
- function buildStyle(chalk35, styles) {
4384
+ function buildStyle(chalk36, styles) {
4385
4385
  const enabled = {};
4386
4386
  for (const layer of styles) {
4387
4387
  for (const style of layer.styles) {
4388
4388
  enabled[style[0]] = layer.inverse ? null : style.slice(1);
4389
4389
  }
4390
4390
  }
4391
- let current = chalk35;
4391
+ let current = chalk36;
4392
4392
  for (const [styleName, styles2] of Object.entries(enabled)) {
4393
4393
  if (!Array.isArray(styles2)) {
4394
4394
  continue;
@@ -4400,7 +4400,7 @@ var require_templates = __commonJS({
4400
4400
  }
4401
4401
  return current;
4402
4402
  }
4403
- module2.exports = (chalk35, temporary) => {
4403
+ module2.exports = (chalk36, temporary) => {
4404
4404
  const styles = [];
4405
4405
  const chunks = [];
4406
4406
  let chunk = [];
@@ -4410,13 +4410,13 @@ var require_templates = __commonJS({
4410
4410
  } else if (style) {
4411
4411
  const string = chunk.join("");
4412
4412
  chunk = [];
4413
- chunks.push(styles.length === 0 ? string : buildStyle(chalk35, styles)(string));
4413
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk36, styles)(string));
4414
4414
  styles.push({ inverse, styles: parseStyle(style) });
4415
4415
  } else if (close) {
4416
4416
  if (styles.length === 0) {
4417
4417
  throw new Error("Found extraneous } in Chalk template literal");
4418
4418
  }
4419
- chunks.push(buildStyle(chalk35, styles)(chunk.join("")));
4419
+ chunks.push(buildStyle(chalk36, styles)(chunk.join("")));
4420
4420
  chunk = [];
4421
4421
  styles.pop();
4422
4422
  } else {
@@ -4464,16 +4464,16 @@ var require_source = __commonJS({
4464
4464
  }
4465
4465
  };
4466
4466
  var chalkFactory = (options) => {
4467
- const chalk36 = {};
4468
- applyOptions(chalk36, options);
4469
- chalk36.template = (...arguments_) => chalkTag(chalk36.template, ...arguments_);
4470
- Object.setPrototypeOf(chalk36, Chalk.prototype);
4471
- Object.setPrototypeOf(chalk36.template, chalk36);
4472
- chalk36.template.constructor = () => {
4467
+ const chalk37 = {};
4468
+ applyOptions(chalk37, options);
4469
+ chalk37.template = (...arguments_) => chalkTag(chalk37.template, ...arguments_);
4470
+ Object.setPrototypeOf(chalk37, Chalk.prototype);
4471
+ Object.setPrototypeOf(chalk37.template, chalk37);
4472
+ chalk37.template.constructor = () => {
4473
4473
  throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
4474
4474
  };
4475
- chalk36.template.Instance = ChalkClass;
4476
- return chalk36.template;
4475
+ chalk37.template.Instance = ChalkClass;
4476
+ return chalk37.template;
4477
4477
  };
4478
4478
  function Chalk(options) {
4479
4479
  return chalkFactory(options);
@@ -4584,7 +4584,7 @@ var require_source = __commonJS({
4584
4584
  return openAll + string + closeAll;
4585
4585
  };
4586
4586
  var template;
4587
- var chalkTag = (chalk36, ...strings) => {
4587
+ var chalkTag = (chalk37, ...strings) => {
4588
4588
  const [firstString] = strings;
4589
4589
  if (!isArray(firstString) || !isArray(firstString.raw)) {
4590
4590
  return strings.join(" ");
@@ -4600,14 +4600,14 @@ var require_source = __commonJS({
4600
4600
  if (template === void 0) {
4601
4601
  template = require_templates();
4602
4602
  }
4603
- return template(chalk36, parts.join(""));
4603
+ return template(chalk37, parts.join(""));
4604
4604
  };
4605
4605
  Object.defineProperties(Chalk.prototype, styles);
4606
- var chalk35 = Chalk();
4607
- chalk35.supportsColor = stdoutColor;
4608
- chalk35.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
4609
- chalk35.stderr.supportsColor = stderrColor;
4610
- module2.exports = chalk35;
4606
+ var chalk36 = Chalk();
4607
+ chalk36.supportsColor = stdoutColor;
4608
+ chalk36.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
4609
+ chalk36.stderr.supportsColor = stderrColor;
4610
+ module2.exports = chalk36;
4611
4611
  }
4612
4612
  });
4613
4613
 
@@ -5638,7 +5638,9 @@ async function authenticateWithBrowser() {
5638
5638
  const authData = await new Promise((resolve16, reject) => {
5639
5639
  const timeout = setTimeout(() => {
5640
5640
  server.close();
5641
- reject(new Error("Authentication timeout. Please try again."));
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 the manual API key path: hyv init --api-key <key>"
5643
+ ));
5642
5644
  }, 12e4);
5643
5645
  server.on("request", async (req, res) => {
5644
5646
  const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
@@ -11741,13 +11743,14 @@ function buildWelcomeGuide(opts = {}) {
11741
11743
  lines.push("");
11742
11744
  }
11743
11745
  lines.push("start in terminal:");
11744
- lines.push(" hyv welcome walk through all 4 steps");
11746
+ lines.push(" hyv welcome walk through all 4 steps (auto-configures mcp)");
11745
11747
  lines.push(" hyv welcome --guide show this guide (for agents / scripts)");
11746
11748
  lines.push("");
11747
11749
  lines.push("or jump in:");
11748
11750
  lines.push(" hyv import <name> <file.md> save a profile");
11749
11751
  lines.push(" hyv scan draft.md test a draft");
11750
11752
  lines.push(" hyv init signup when ready");
11753
+ lines.push(" hyv mcp --setup view all mcp configs");
11751
11754
  lines.push("");
11752
11755
  return lines.join("\n");
11753
11756
  }
@@ -11758,6 +11761,7 @@ function buildWelcomeHeader(opts = {}) {
11758
11761
  "",
11759
11762
  " hyv welcome set up your voice (4 steps)",
11760
11763
  " hyv scan test any draft free",
11764
+ " mcp auto-configured for your installed apps",
11761
11765
  ""
11762
11766
  ].join("\n");
11763
11767
  }
@@ -12186,7 +12190,8 @@ async function runInteractiveWelcome() {
12186
12190
  console.log(import_chalk12.default.green("done \u2014 your voice profile is ready.\n"));
12187
12191
  console.log(import_chalk12.default.dim(" hyv scan draft.md"));
12188
12192
  console.log(import_chalk12.default.dim(` hyv rewrite draft.md --profile ${profileName}`));
12189
- console.log(import_chalk12.default.dim(" hyv mcp --setup\n"));
12193
+ console.log(import_chalk12.default.dim(" mcp auto-configured for your installed apps"));
12194
+ console.log(import_chalk12.default.dim(" hyv mcp --setup (view all configs)\n"));
12190
12195
  } catch (err) {
12191
12196
  console.error(import_chalk12.default.red(`
12192
12197
  ${err.message || "welcome flow stopped"}
@@ -12318,6 +12323,7 @@ function buildWelcomeMessage(opts = {}) {
12318
12323
  lines.push(" set up your voice");
12319
12324
  lines.push(" hyv welcome");
12320
12325
  lines.push("");
12326
+ lines.push(" mcp auto-configured for your installed apps");
12321
12327
  lines.push(` unlock learning \u2192 ${PRICING_URL}`);
12322
12328
  lines.push("");
12323
12329
  return lines.join("\n");
@@ -15759,7 +15765,7 @@ var {
15759
15765
  } = import_index.default;
15760
15766
 
15761
15767
  // src/index.ts
15762
- var import_chalk34 = __toESM(require_source());
15768
+ var import_chalk35 = __toESM(require_source());
15763
15769
 
15764
15770
  // src/commands/init.ts
15765
15771
  var import_chalk4 = __toESM(require_source());
@@ -18992,6 +18998,7 @@ function registerOpenCommand(program3) {
18992
18998
  }
18993
18999
 
18994
19000
  // src/commands/welcome.ts
19001
+ var import_chalk31 = __toESM(require_source());
18995
19002
  init_welcome();
18996
19003
 
18997
19004
  // src/lib/onboarding.ts
@@ -19020,6 +19027,20 @@ function markOnboardingComplete(version) {
19020
19027
  init_welcome_flow();
19021
19028
  var fs25 = __toESM(require("fs"));
19022
19029
  var path23 = __toESM(require("path"));
19030
+ function runBackgroundMcpSetup() {
19031
+ const pkgDir = path23.resolve(__dirname, "..");
19032
+ const postinstallLib = path23.join(pkgDir, "scripts", "postinstall-lib.js");
19033
+ if (!fs25.existsSync(postinstallLib))
19034
+ return;
19035
+ try {
19036
+ const { setupAgents } = require(postinstallLib);
19037
+ const result = setupAgents({ pkgDir, quiet: true });
19038
+ if (result.configured.length > 0) {
19039
+ console.log(import_chalk31.default.dim(` \u2713 mcp auto-configured: ${result.configured.join(", ")}`));
19040
+ }
19041
+ } catch {
19042
+ }
19043
+ }
19023
19044
  function registerWelcomeCommand(program3) {
19024
19045
  const pkgVersion3 = (() => {
19025
19046
  try {
@@ -19029,10 +19050,15 @@ function registerWelcomeCommand(program3) {
19029
19050
  return "0.0.0";
19030
19051
  }
19031
19052
  })();
19032
- program3.command("welcome").description("Set up your voice: name \u2192 samples \u2192 test \u2192 signup").option("--guide", "Show LLM/terminal guide (no prompts)").option("--extract-prompt [name]", "Print chat extraction prompt for agents").option("--step <n>", "Show guide for step 1\u20134", (v2) => parseInt(v2, 10)).option("--no-demo", "Skip sample scan line in guide mode").option("--quiet", "Suppress output").action(async (opts) => {
19033
- if (opts.quiet)
19053
+ program3.command("welcome").description("Set up your voice: name \u2192 samples \u2192 test \u2192 signup").option("--guide", "Show LLM/terminal guide (no prompts)").option("--extract-prompt [name]", "Print chat extraction prompt for agents").option("--step <n>", "Show guide for step 1\u20134", (v2) => parseInt(v2, 10)).option("--no-demo", "Skip sample scan line in guide mode").option("--skip-mcp", "Skip automatic MCP setup for IDE agents").option("--quiet", "Suppress output").action(async (opts) => {
19054
+ if (opts.quiet) {
19055
+ if (!opts.skipMcp)
19056
+ runBackgroundMcpSetup();
19034
19057
  return;
19058
+ }
19035
19059
  const fromPostinstall = process.env.HYV_POSTINSTALL_ONBOARDING === "1";
19060
+ if (!opts.skipMcp && !fromPostinstall)
19061
+ runBackgroundMcpSetup();
19036
19062
  if (opts.extractPrompt !== void 0) {
19037
19063
  const name = typeof opts.extractPrompt === "string" ? opts.extractPrompt : "my-voice";
19038
19064
  console.log("\n" + buildVoiceExtractionPrompt(name) + "\n");
@@ -19071,7 +19097,7 @@ function getWelcomeText(args2) {
19071
19097
  }
19072
19098
 
19073
19099
  // src/commands/content.ts
19074
- var import_chalk31 = __toESM(require_source());
19100
+ var import_chalk32 = __toESM(require_source());
19075
19101
  init_free_paid();
19076
19102
  var TEMPLATES = {
19077
19103
  cursor: {
@@ -19145,19 +19171,19 @@ ${COMMUNITY_URL}`
19145
19171
  function registerContentCommand(program3) {
19146
19172
  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) => {
19147
19173
  if (opts.list) {
19148
- console.log(import_chalk31.default.bold("\nhyv content templates\n"));
19174
+ console.log(import_chalk32.default.bold("\nhyv content templates\n"));
19149
19175
  for (const [key, t2] of Object.entries(TEMPLATES)) {
19150
- console.log(import_chalk31.default.dim(` ${key}`) + ` \u2014 ${t2.title}`);
19176
+ console.log(import_chalk32.default.dim(` ${key}`) + ` \u2014 ${t2.title}`);
19151
19177
  }
19152
19178
  console.log("");
19153
19179
  return;
19154
19180
  }
19155
19181
  const t = TEMPLATES[topic] || TEMPLATES.cursor;
19156
- console.log(import_chalk31.default.bold(`
19182
+ console.log(import_chalk32.default.bold(`
19157
19183
  ${t.title}
19158
19184
  `));
19159
19185
  console.log(t.body);
19160
- console.log(import_chalk31.default.dim("\nBlog: https://holdyourvoice.com/blog\n"));
19186
+ console.log(import_chalk32.default.dim("\nBlog: https://holdyourvoice.com/blog\n"));
19161
19187
  });
19162
19188
  }
19163
19189
 
@@ -19185,7 +19211,7 @@ init_telemetry();
19185
19211
  init_access();
19186
19212
 
19187
19213
  // src/lib/mcp-integrate.ts
19188
- var import_chalk32 = __toESM(require_source());
19214
+ var import_chalk33 = __toESM(require_source());
19189
19215
  var fs26 = __toESM(require("fs"));
19190
19216
  var os12 = __toESM(require("os"));
19191
19217
  var path24 = __toESM(require("path"));
@@ -19358,67 +19384,6 @@ function formatMcpIntegrateReportText(result, opts = {}) {
19358
19384
  }
19359
19385
  return lines.join("\n");
19360
19386
  }
19361
- function printMcpIntegrateReport(result, opts = {}) {
19362
- const { agentIdForConfiguredLabel, isAgentIntegrated } = loadPostinstallLib();
19363
- const configuredIds = new Set(
19364
- result.configured.map((label) => agentIdForConfiguredLabel(label)).filter(Boolean)
19365
- );
19366
- console.log(import_chalk32.default.bold("\nhold your voice \u2014 mcp integration\n"));
19367
- console.log(import_chalk32.default.dim(` ${getEngineLabel()}
19368
- `));
19369
- const welcome = readWelcomeState();
19370
- const profiles = listLocalProfileNames2();
19371
- if (profiles.length > 0) {
19372
- console.log(import_chalk32.default.dim(` voice profiles: ${profiles.join(", ")}`));
19373
- } else {
19374
- console.log(import_chalk32.default.yellow(" no voice profile yet \u2014 mcp still works (free scan). finish onboarding in terminal or in-chat via hyv_welcome"));
19375
- }
19376
- if (welcome.completed_steps?.length) {
19377
- console.log(import_chalk32.default.dim(` welcome progress: ${welcome.completed_steps.join(", ")}`));
19378
- }
19379
- console.log("");
19380
- if (result.detected.length === 0) {
19381
- console.log(import_chalk32.default.yellow(" no supported ai apps detected on this machine."));
19382
- console.log(import_chalk32.default.dim("\n install cursor, claude desktop, chatgpt desktop, or another supported app,"));
19383
- console.log(import_chalk32.default.dim(" then run hyv mcp again \u2014 or hyv doctor --fix-agents to configure everything."));
19384
- console.log(import_chalk32.default.dim("\n in chatgpt/claude/cursor: call hyv_welcome to onboard without the terminal."));
19385
- console.log(import_chalk32.default.dim(" chatgpt desktop: hyv mcp --setup-chatgpt\n"));
19386
- return;
19387
- }
19388
- console.log(import_chalk32.default.bold("detected apps"));
19389
- for (const app of result.detected) {
19390
- const justConfigured = configuredIds.has(app.id);
19391
- const integrated = isAgentIntegrated(app.id) || justConfigured;
19392
- const mark = app.integration === "manual" ? import_chalk32.default.yellow("\u25CB") : integrated ? import_chalk32.default.green("\u2713") : import_chalk32.default.cyan("\u2192");
19393
- const status = app.integration === "manual" ? "manual connector \u2014 see ~/.chatgpt/hyv-mcp-connector.txt" : justConfigured ? opts.force ? "updated now" : "configured now" : integrated ? "integrated" : "needs setup";
19394
- console.log(` ${mark} ${app.label} \u2014 ${status}`);
19395
- console.log(import_chalk32.default.dim(` ${app.reason} \xB7 ${app.integration}`));
19396
- }
19397
- if (result.configured.length > 0) {
19398
- console.log(import_chalk32.default.green(`
19399
- wired hyv into: ${result.configured.join(", ")}`));
19400
- }
19401
- if (result.warnings.length > 0) {
19402
- console.log(import_chalk32.default.yellow("\n notes:"));
19403
- for (const warning of result.warnings) {
19404
- console.log(import_chalk32.default.yellow(` ! ${warning}`));
19405
- }
19406
- }
19407
- const mcpApps = result.detected.filter((a) => a.integration === "mcp");
19408
- const manualApps = result.detected.filter((a) => a.integration === "manual");
19409
- console.log(import_chalk32.default.bold("\nnext steps"));
19410
- console.log(import_chalk32.default.dim(" in this app: hyv_welcome (onboarding) \xB7 hyv_mcp_setup (status/refresh) \xB7 hyv_demo (try a scan)"));
19411
- if (mcpApps.length > 0) {
19412
- console.log(import_chalk32.default.dim(" restart apps that use mcp (cursor, claude desktop, antigravity, opencode)"));
19413
- }
19414
- if (manualApps.length > 0) {
19415
- console.log(import_chalk32.default.dim(" chatgpt: settings \u2192 connectors \u2192 command hyv, arguments mcp"));
19416
- console.log(import_chalk32.default.dim(" full steps: hyv mcp --setup-chatgpt"));
19417
- }
19418
- console.log(import_chalk32.default.dim(" refresh stale configs after upgrade: hyv mcp --force"));
19419
- console.log(import_chalk32.default.dim(" verify: hyv mcp --test"));
19420
- console.log(import_chalk32.default.dim(" all hosts: hyv doctor --verify-hosts\n"));
19421
- }
19422
19387
 
19423
19388
  // src/mcp.ts
19424
19389
  init_mcp_profile_hydrate();
@@ -20095,7 +20060,7 @@ async function startMcpServer() {
20095
20060
  }
20096
20061
 
20097
20062
  // src/lib/mcp-setup.ts
20098
- var import_chalk33 = __toESM(require_source());
20063
+ var import_chalk34 = __toESM(require_source());
20099
20064
  var fs28 = __toESM(require("fs"));
20100
20065
  var path26 = __toESM(require("path"));
20101
20066
  var os14 = __toESM(require("os"));
@@ -20110,60 +20075,68 @@ function claudeDesktopConfigPath() {
20110
20075
  return path26.join(HOME2, "Library", "Application Support", "Claude", "claude_desktop_config.json");
20111
20076
  }
20112
20077
  function printMcpSetup() {
20113
- console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp setup\n"));
20114
- console.log(import_chalk33.default.dim(` ${getEngineLabel()}
20078
+ console.log(import_chalk34.default.bold("\nhold your voice \u2014 mcp setup\n"));
20079
+ console.log(import_chalk34.default.dim(` ${getEngineLabel()}
20115
20080
  `));
20116
- console.log(import_chalk33.default.bold("Claude Desktop"));
20117
- console.log(import_chalk33.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
20118
- console.log(import_chalk33.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
20119
- console.log(import_chalk33.default.dim(` Config: ${claudeDesktopConfigPath()}
20081
+ console.log(import_chalk34.default.bold("Claude Desktop"));
20082
+ console.log(import_chalk34.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
20083
+ console.log(import_chalk34.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
20084
+ console.log(import_chalk34.default.dim(` Config: ${claudeDesktopConfigPath()}
20120
20085
  `));
20121
- console.log(import_chalk33.default.bold("Cursor"));
20122
- console.log(import_chalk33.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
20123
- console.log(import_chalk33.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
20124
- console.log(import_chalk33.default.bold("Claude Code"));
20125
- console.log(import_chalk33.default.dim(" Command: ~/.claude/commands/hyv.md"));
20126
- console.log(import_chalk33.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
20127
- console.log(import_chalk33.default.bold("Windsurf"));
20128
- console.log(import_chalk33.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
20129
- console.log(import_chalk33.default.bold("Codex"));
20130
- console.log(import_chalk33.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
20131
- console.log(import_chalk33.default.bold("Command Code"));
20132
- console.log(import_chalk33.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
20133
- console.log(import_chalk33.default.bold("ChatGPT Desktop (manual connector)"));
20134
- console.log(import_chalk33.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
20135
- console.log(import_chalk33.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp"));
20136
- console.log(import_chalk33.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
20137
- console.log(import_chalk33.default.dim(" hyv mcp --setup-chatgpt\n"));
20138
- console.log(import_chalk33.default.bold("Antigravity"));
20139
- console.log(import_chalk33.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
20140
- console.log(import_chalk33.default.bold("OpenCode"));
20141
- console.log(import_chalk33.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
20142
- console.log(import_chalk33.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
20143
- console.log(import_chalk33.default.bold("Auto-configure"));
20144
- console.log(import_chalk33.default.dim(" hyv mcp (detect installed apps + wire mcp into them)"));
20145
- console.log(import_chalk33.default.dim(" hyv mcp --force (refresh configs after hyv upgrade)"));
20146
- console.log(import_chalk33.default.dim(" hyv doctor --fix-agents (configure all apps, not just detected)"));
20147
- console.log(import_chalk33.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
20148
- console.log(import_chalk33.default.bold("In-chat (no terminal)"));
20149
- console.log(import_chalk33.default.dim(" hyv_mcp_setup \u2014 status, integrate, or chatgpt connector steps"));
20150
- console.log(import_chalk33.default.dim(" hyv_welcome \u2014 finish onboarding inside Cursor/Claude/ChatGPT\n"));
20151
- console.log(import_chalk33.default.bold("Verify"));
20152
- console.log(import_chalk33.default.dim(" hyv mcp --test"));
20153
- console.log(import_chalk33.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
20086
+ console.log(import_chalk34.default.bold("Cursor"));
20087
+ console.log(import_chalk34.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
20088
+ console.log(import_chalk34.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
20089
+ console.log(import_chalk34.default.bold("Claude Code"));
20090
+ console.log(import_chalk34.default.dim(" Command: ~/.claude/commands/hyv.md"));
20091
+ console.log(import_chalk34.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
20092
+ console.log(import_chalk34.default.bold("Windsurf"));
20093
+ console.log(import_chalk34.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
20094
+ console.log(import_chalk34.default.bold("Codex"));
20095
+ console.log(import_chalk34.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
20096
+ console.log(import_chalk34.default.bold("Command Code"));
20097
+ console.log(import_chalk34.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
20098
+ console.log(import_chalk34.default.bold("ChatGPT Desktop (manual connector)"));
20099
+ console.log(import_chalk34.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
20100
+ console.log(import_chalk34.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp"));
20101
+ console.log(import_chalk34.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
20102
+ console.log(import_chalk34.default.dim(" hyv mcp --setup-chatgpt"));
20103
+ if (IS_WIN2) {
20104
+ console.log(import_chalk34.default.dim(" Windows (Lenovo/Win11 often Restricted): if blocked use:"));
20105
+ console.log(import_chalk34.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv ..."'));
20106
+ console.log(import_chalk34.default.dim(" Diagnose: Get-ExecutionPolicy -List"));
20107
+ console.log(import_chalk34.default.dim(" Permanent fix: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20108
+ console.log(import_chalk34.default.dim(" For connectors: use full path printed in the .txt (node + .js)"));
20109
+ }
20110
+ console.log("");
20111
+ console.log(import_chalk34.default.bold("Antigravity"));
20112
+ console.log(import_chalk34.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
20113
+ console.log(import_chalk34.default.bold("OpenCode"));
20114
+ console.log(import_chalk34.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
20115
+ console.log(import_chalk34.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
20116
+ console.log(import_chalk34.default.bold("Auto-configure"));
20117
+ console.log(import_chalk34.default.dim(" hyv mcp (detect installed apps + wire mcp into them)"));
20118
+ console.log(import_chalk34.default.dim(" hyv mcp --force (refresh configs after hyv upgrade)"));
20119
+ console.log(import_chalk34.default.dim(" hyv doctor --fix-agents (configure all apps, not just detected)"));
20120
+ console.log(import_chalk34.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
20121
+ console.log(import_chalk34.default.bold("In-chat (no terminal)"));
20122
+ console.log(import_chalk34.default.dim(" hyv_mcp_setup \u2014 status, integrate, or chatgpt connector steps"));
20123
+ console.log(import_chalk34.default.dim(" hyv_welcome \u2014 finish onboarding inside Cursor/Claude/ChatGPT\n"));
20124
+ console.log(import_chalk34.default.bold("Verify"));
20125
+ console.log(import_chalk34.default.dim(" hyv mcp --test"));
20126
+ console.log(import_chalk34.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
20154
20127
  }
20155
20128
  async function runMcpSelfTest() {
20156
- console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp self-test\n"));
20157
- console.log(import_chalk33.default.dim(` ${getEngineLabel()}
20129
+ console.log(import_chalk34.default.bold("\nhold your voice \u2014 mcp self-test\n"));
20130
+ console.log(import_chalk34.default.dim(` ${getEngineLabel()}
20158
20131
  `));
20159
20132
  let passed = 0;
20160
20133
  let failed = 0;
20161
20134
  const tools = getMcpToolNames();
20162
20135
  if (tools.length >= 10) {
20163
- console.log(import_chalk33.default.green(` \u2713 ${tools.length} MCP tools registered`));
20136
+ console.log(import_chalk34.default.green(` \u2713 ${tools.length} MCP tools registered`));
20164
20137
  passed++;
20165
20138
  } else {
20166
- console.log(import_chalk33.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
20139
+ console.log(import_chalk34.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
20167
20140
  failed++;
20168
20141
  }
20169
20142
  const required = [
@@ -20177,89 +20150,89 @@ async function runMcpSelfTest() {
20177
20150
  ];
20178
20151
  for (const name of required) {
20179
20152
  if (tools.includes(name)) {
20180
- console.log(import_chalk33.default.green(` \u2713 tool: ${name}`));
20153
+ console.log(import_chalk34.default.green(` \u2713 tool: ${name}`));
20181
20154
  passed++;
20182
20155
  } else {
20183
- console.log(import_chalk33.default.red(` \u2717 missing tool: ${name}`));
20156
+ console.log(import_chalk34.default.red(` \u2717 missing tool: ${name}`));
20184
20157
  failed++;
20185
20158
  }
20186
20159
  }
20187
20160
  try {
20188
20161
  const welcome = await invokeMcpTool("hyv_welcome", {});
20189
20162
  if (welcome.includes("Hold Your Voice") || welcome.includes("hold your voice")) {
20190
- console.log(import_chalk33.default.green(" \u2713 hyv_welcome responds"));
20163
+ console.log(import_chalk34.default.green(" \u2713 hyv_welcome responds"));
20191
20164
  passed++;
20192
20165
  } else {
20193
- console.log(import_chalk33.default.red(" \u2717 hyv_welcome unexpected output"));
20166
+ console.log(import_chalk34.default.red(" \u2717 hyv_welcome unexpected output"));
20194
20167
  failed++;
20195
20168
  }
20196
20169
  } catch (e) {
20197
- console.log(import_chalk33.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
20170
+ console.log(import_chalk34.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
20198
20171
  failed++;
20199
20172
  }
20200
20173
  try {
20201
20174
  const setup = await invokeMcpTool("hyv_mcp_setup", { action: "status" });
20202
20175
  if (setup.includes("HYV MCP status") && setup.includes("hyv_welcome")) {
20203
- console.log(import_chalk33.default.green(" \u2713 hyv_mcp_setup responds"));
20176
+ console.log(import_chalk34.default.green(" \u2713 hyv_mcp_setup responds"));
20204
20177
  passed++;
20205
20178
  } else {
20206
- console.log(import_chalk33.default.red(" \u2717 hyv_mcp_setup unexpected output"));
20179
+ console.log(import_chalk34.default.red(" \u2717 hyv_mcp_setup unexpected output"));
20207
20180
  failed++;
20208
20181
  }
20209
20182
  } catch (e) {
20210
- console.log(import_chalk33.default.red(` \u2717 hyv_mcp_setup failed: ${e.message}`));
20183
+ console.log(import_chalk34.default.red(` \u2717 hyv_mcp_setup failed: ${e.message}`));
20211
20184
  failed++;
20212
20185
  }
20213
20186
  try {
20214
20187
  const demo = await invokeMcpTool("hyv_demo", {});
20215
20188
  if (demo.includes("Score") || demo.includes("issues")) {
20216
- console.log(import_chalk33.default.green(" \u2713 hyv_demo pipeline works"));
20189
+ console.log(import_chalk34.default.green(" \u2713 hyv_demo pipeline works"));
20217
20190
  passed++;
20218
20191
  } else {
20219
- console.log(import_chalk33.default.red(" \u2717 hyv_demo unexpected output"));
20192
+ console.log(import_chalk34.default.red(" \u2717 hyv_demo unexpected output"));
20220
20193
  failed++;
20221
20194
  }
20222
20195
  } catch (e) {
20223
- console.log(import_chalk33.default.red(` \u2717 hyv_demo failed: ${e.message}`));
20196
+ console.log(import_chalk34.default.red(` \u2717 hyv_demo failed: ${e.message}`));
20224
20197
  failed++;
20225
20198
  }
20226
20199
  const voiceMd = path26.join(HOME2, ".hyv", "voice.md");
20227
20200
  if (fs28.existsSync(voiceMd)) {
20228
- console.log(import_chalk33.default.green(" \u2713 voice profile found"));
20201
+ console.log(import_chalk34.default.green(" \u2713 voice profile found"));
20229
20202
  passed++;
20230
20203
  } else {
20231
- console.log(import_chalk33.default.dim(" - no voice.md (free local engine still works)"));
20204
+ console.log(import_chalk34.default.dim(" - no voice.md (free local engine still works)"));
20232
20205
  }
20233
20206
  if (getDemoText().length > 100) {
20234
- console.log(import_chalk33.default.green(" \u2713 demo content available"));
20207
+ console.log(import_chalk34.default.green(" \u2713 demo content available"));
20235
20208
  passed++;
20236
20209
  } else {
20237
- console.log(import_chalk33.default.red(" \u2717 demo content missing"));
20210
+ console.log(import_chalk34.default.red(" \u2717 demo content missing"));
20238
20211
  failed++;
20239
20212
  }
20240
20213
  try {
20241
20214
  const stdio = await testMcpStdioSubprocess();
20242
20215
  if (stdio.ok && (stdio.toolCount || 0) >= 10) {
20243
- console.log(import_chalk33.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
20216
+ console.log(import_chalk34.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
20244
20217
  passed++;
20245
20218
  } else if (stdio.ok) {
20246
- console.log(import_chalk33.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
20219
+ console.log(import_chalk34.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
20247
20220
  failed++;
20248
20221
  } else {
20249
- console.log(import_chalk33.default.red(" \u2717 stdio MCP subprocess failed"));
20222
+ console.log(import_chalk34.default.red(" \u2717 stdio MCP subprocess failed"));
20250
20223
  failed++;
20251
20224
  }
20252
20225
  } catch (e) {
20253
- console.log(import_chalk33.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
20226
+ console.log(import_chalk34.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
20254
20227
  failed++;
20255
20228
  }
20256
20229
  console.log("");
20257
20230
  if (failed === 0) {
20258
- console.log(import_chalk33.default.green(`\u2713 all checks passed (${passed})`));
20259
- console.log(import_chalk33.default.dim("\nStart server: hyv mcp\n"));
20231
+ console.log(import_chalk34.default.green(`\u2713 all checks passed (${passed})`));
20232
+ console.log(import_chalk34.default.dim("\nStart server: hyv mcp\n"));
20260
20233
  return true;
20261
20234
  }
20262
- console.log(import_chalk33.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
20235
+ console.log(import_chalk34.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
20263
20236
  return false;
20264
20237
  }
20265
20238
 
@@ -20427,7 +20400,7 @@ registerOpenCommand(program2);
20427
20400
  registerWelcomeCommand(program2);
20428
20401
  registerContentCommand(program2);
20429
20402
  registerUpgradeCommand(program2);
20430
- program2.command("mcp").description("Detect local AI apps, wire hyv MCP into them, or start stdio server for hosts").option("--setup", "Show MCP setup for Claude Desktop, Cursor, Windsurf, Codex").option("--test", "Run MCP health check (tools, profile, stdio)").option("--setup-chatgpt", "Show ChatGPT connector setup instructions").option("--force", "Refresh MCP configs even when already integrated (e.g. after hyv upgrade)").option("--stdio", "Start MCP stdio server (used by Cursor, Claude Desktop, etc.)").option("--integrate-only", "Detect and configure apps without starting stdio server").action(async (opts) => {
20403
+ program2.command("mcp").description("Start MCP server (for Claude Desktop and other MCP hosts)").option("--setup", "Show MCP setup for Claude Desktop, Cursor, Windsurf, Codex").option("--test", "Run MCP health check (tools, profile, stdio)").option("--setup-chatgpt", "Show ChatGPT connector setup instructions").action(async (opts) => {
20431
20404
  if (opts.setup) {
20432
20405
  printMcpSetup();
20433
20406
  return;
@@ -20438,21 +20411,59 @@ program2.command("mcp").description("Detect local AI apps, wire hyv MCP into the
20438
20411
  return;
20439
20412
  }
20440
20413
  if (opts.setupChatgpt) {
20441
- console.log(import_chalk34.default.bold("\nhold your voice \u2014 chatgpt desktop mcp setup\n"));
20442
- console.log(formatChatGptConnectorGuide());
20443
- console.log(import_chalk34.default.dim("\nBrowser chatgpt cannot use local MCP \u2014 desktop app only."));
20444
- console.log(import_chalk34.default.dim("In ChatGPT chat: call hyv_mcp_setup or hyv_welcome \u2014 no terminal needed.\n"));
20414
+ const home = require("os").homedir();
20415
+ const guide = require("path").join(home, ".chatgpt", "hyv-mcp-connector.txt");
20416
+ console.log(import_chalk35.default.bold("\nhold your voice \u2014 chatgpt desktop setup\n"));
20417
+ console.log(import_chalk35.default.bold("=== which setup do i have? ===\n"));
20418
+ console.log(import_chalk35.default.dim(' If you see "New App" with a Server URL field:'));
20419
+ console.log(import_chalk35.default.dim(" \u2192 Developer mode is ON \u2192 use PATH A (remote, below)"));
20420
+ console.log(import_chalk35.default.dim(' If you see "Connectors" with Command/Arguments fields:'));
20421
+ console.log(import_chalk35.default.dim(" \u2192 use PATH B (local, below)"));
20422
+ console.log(import_chalk35.default.dim(" Neither? Turn Developer mode ON in ChatGPT settings.\n"));
20423
+ console.log(import_chalk35.default.bold("=== PATH A \u2014 remote mcp (Developer mode \u2192 New App) ==="));
20424
+ console.log(import_chalk35.default.dim(" Requires: paid HYV plan + ChatGPT Desktop + Developer mode ON\n"));
20425
+ console.log(import_chalk35.default.dim(" 1. In ChatGPT: Settings \u2192 turn ") + import_chalk35.default.cyan("Developer mode") + import_chalk35.default.dim(" ON"));
20426
+ console.log(import_chalk35.default.dim(" (Accept the elevated risk warning \u2014 expected, not a HYV bug)"));
20427
+ console.log(import_chalk35.default.dim(" 2. Settings \u2192 Apps \u2192 ") + import_chalk35.default.cyan("New App"));
20428
+ console.log(import_chalk35.default.dim(" 3. Fill in:"));
20429
+ console.log(import_chalk35.default.dim(" Name: ") + import_chalk35.default.cyan("hold your voice"));
20430
+ console.log(import_chalk35.default.dim(" Description: ") + import_chalk35.default.cyan("Scans writing for AI patterns and voice drift"));
20431
+ console.log(import_chalk35.default.dim(" Connection: ") + import_chalk35.default.cyan("Server URL") + import_chalk35.default.dim(" \u2192 ") + import_chalk35.default.cyan("https://holdyourvoice.com/mcp"));
20432
+ console.log(import_chalk35.default.dim(" Authentication: ") + import_chalk35.default.cyan("OAuth"));
20433
+ console.log(import_chalk35.default.dim(" Checkbox: ") + import_chalk35.default.cyan('"I understand and want to continue"'));
20434
+ console.log(import_chalk35.default.dim(" 4. Save \u2192 complete OAuth sign-in to holdyourvoice.com"));
20435
+ console.log(import_chalk35.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20436
+ console.log(import_chalk35.default.dim(" Cloud app setup: ") + import_chalk35.default.cyan("https://holdyourvoice.com/app/api/mcp"));
20437
+ console.log(import_chalk35.default.dim(" Wiki guide: ") + import_chalk35.default.cyan("https://holdyourvoice.com/wiki/use-hyv-in-chatgpt\n"));
20438
+ console.log(import_chalk35.default.bold("=== PATH B \u2014 local connector (Connectors \u2192 Command/Arguments) ==="));
20439
+ console.log(import_chalk35.default.dim(" Requires: Node.js 18+ + ChatGPT Desktop (free offline scan)\n"));
20440
+ console.log(import_chalk35.default.dim(" 1. Install hyv: ") + import_chalk35.default.cyan("npm i -g @holdyourvoice/hyv@latest && hyv welcome"));
20441
+ console.log(import_chalk35.default.dim(" 2. In ChatGPT: ") + import_chalk35.default.cyan("Settings \u2192 Connectors") + import_chalk35.default.dim(" (or https://chatgpt.com/#settings/Connectors)"));
20442
+ console.log(import_chalk35.default.dim(" 3. Add connector:"));
20443
+ console.log(import_chalk35.default.dim(" Name: ") + import_chalk35.default.cyan("hold your voice"));
20444
+ console.log(import_chalk35.default.dim(" Command: ") + import_chalk35.default.cyan("hyv") + import_chalk35.default.dim(" (full path on Windows if needed)"));
20445
+ console.log(import_chalk35.default.dim(" Arguments: ") + import_chalk35.default.cyan("mcp"));
20446
+ console.log(import_chalk35.default.dim(" 4. Save, restart ChatGPT Desktop"));
20447
+ console.log(import_chalk35.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20448
+ console.log(import_chalk35.default.dim(" If connector fails to start, use full paths from:"));
20449
+ console.log(import_chalk35.default.cyan(" " + guide));
20450
+ console.log(import_chalk35.default.dim(""));
20451
+ console.log(import_chalk35.default.dim('Windows tip: If you get "running scripts is disabled", use:'));
20452
+ console.log(import_chalk35.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv mcp --setup-chatgpt"'));
20453
+ console.log(import_chalk35.default.dim(" Fix once: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20454
+ console.log(import_chalk35.default.dim(" In ChatGPT connector use the FULL path from the connector .txt file\n"));
20455
+ console.log(import_chalk35.default.bold("=== not seeing either UI? ==="));
20456
+ console.log(import_chalk35.default.dim(" \u2022 Turn Developer mode ON in ChatGPT settings for New App"));
20457
+ console.log(import_chalk35.default.dim(" \u2022 Connectors may require ChatGPT Plus"));
20458
+ console.log(import_chalk35.default.dim(" \u2022 Browser ChatGPT cannot use either path \u2014 desktop app only\n"));
20459
+ if (require("fs").existsSync(guide)) {
20460
+ console.log(import_chalk35.default.dim(` Full connector paths written to: ${guide}`));
20461
+ } else {
20462
+ console.log(import_chalk35.default.dim(" Run hyv doctor --fix-agents to write " + guide));
20463
+ }
20464
+ console.log("");
20445
20465
  return;
20446
20466
  }
20447
- const wantsIntegrate = Boolean(opts.integrateOnly || process.stdin.isTTY);
20448
- if (wantsIntegrate) {
20449
- const integrateOpts = { force: Boolean(opts.force) };
20450
- const result = runMcpAutoIntegrate(integrateOpts);
20451
- printMcpIntegrateReport(result, integrateOpts);
20452
- if (!opts.stdio)
20453
- return;
20454
- console.log(import_chalk34.default.dim("starting stdio mcp server for local testing (ctrl+c to stop)\u2026\n"));
20455
- }
20456
20467
  startMcpServer();
20457
20468
  });
20458
20469
  program2.command("export").description("Export voice profile for LLMs").argument("[format]", "Export format (claude, chatgpt, generic, cursor)", "claude").option("--output <file>", "Write to file instead of stdout").option("--json", "Output as JSON").action(async (format, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holdyourvoice/hyv",
3
- "version": "2.9.15",
3
+ "version": "2.9.17",
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": {
@@ -68,7 +68,16 @@ function Install-Hyv {
68
68
  throw 'npm not found after node install'
69
69
  }
70
70
  Write-Log 'installing hold your voice...'
71
- npm i -g $HyvPkg
71
+ try {
72
+ npm i -g $HyvPkg
73
+ } catch {
74
+ if ($_.Exception.Message -match 'ExecutionPolicy|scripts is disabled') {
75
+ Write-Log 'PowerShell execution policy blocked npm — retrying with Bypass...'
76
+ powershell -ExecutionPolicy Bypass -Command "npm i -g $HyvPkg"
77
+ } else {
78
+ throw
79
+ }
80
+ }
72
81
  Refresh-Path
73
82
  if (Get-Command hyv -ErrorAction SilentlyContinue) {
74
83
  Write-Log 'running hyv welcome...'
@@ -81,6 +90,9 @@ function Install-Hyv {
81
90
  Write-Host ''
82
91
  Write-Host 'hold your voice — installer'
83
92
  Write-Host ''
93
+ Write-Host ' Note: If you see an "execution policy" error, re-run using:'
94
+ Write-Host ' powershell -ExecutionPolicy Bypass -c "irm https://holdyourvoice.com/install.ps1 | iex"'
95
+ Write-Host ''
84
96
  Ensure-Node
85
97
  if ($EnsureNodeOnly) { exit 0 }
86
98
  Install-Hyv
@@ -674,23 +674,53 @@ function setupAgents({
674
674
  fs.mkdirSync(cgDir, { recursive: true });
675
675
  const mcpCmd = resolveHyvMcpCommand(pkgDir);
676
676
  const connectorGuide = [
677
- 'hold your voice — chatgpt desktop mcp connector',
677
+ 'hold your voice — chatgpt desktop setup (two paths)',
678
678
  '',
679
- 'chatgpt has no auto-config file. add this connector once in the chatgpt desktop app:',
679
+ '=== which setup do i have? ===',
680
680
  '',
681
- '1. open chatgpt desktop (not the browser)',
682
- '2. settings connectorsadd connector',
683
- '3. name: hold your voice',
684
- '4. command: hyv',
685
- '5. arguments: mcp',
681
+ ' If you see "New App" with a Server URL field:',
682
+ ' Developer mode is ON use PATH A (remote)',
683
+ ' If you see "Connectors" with Command/Arguments fields:',
684
+ ' use PATH B (local)',
686
685
  '',
687
- 'if the connector fails to start, use absolute paths instead:',
688
- ` command: ${mcpCmd.command}`,
689
- ` arguments: ${mcpCmd.args.join(' ')}`,
686
+ '=== PATH A remote mcp (Developer mode New App) ===',
687
+ ' Requires: paid HYV plan + ChatGPT Desktop',
690
688
  '',
691
- 'then restart chatgpt desktop and ask: scan this with hold your voice',
689
+ ' 1. In ChatGPT: Settings turn Developer mode ON',
690
+ ' (Accept the elevated risk warning — expected, not a HYV bug)',
691
+ ' 2. Settings → Apps → New App',
692
+ ' 3. Fill in:',
693
+ ' Name: hold your voice',
694
+ ' Description: Scans writing for AI patterns and voice drift',
695
+ ' Connection: Server URL → https://holdyourvoice.com/mcp',
696
+ ' Authentication: OAuth',
697
+ ' Checkbox: "I understand and want to continue"',
698
+ ' 4. Save → complete OAuth sign-in to holdyourvoice.com',
699
+ ' 5. Test: "scan this with hold your voice"',
692
700
  '',
693
- 'more help: hyv mcp --setup-chatgpt',
701
+ ' Cloud app setup: https://holdyourvoice.com/app/api/mcp',
702
+ ' Wiki guide: https://holdyourvoice.com/wiki/use-hyv-in-chatgpt',
703
+ '',
704
+ '=== PATH B — local connector (Connectors → Command/Arguments) ===',
705
+ ' Requires: Node.js 18+ (free offline scan)',
706
+ '',
707
+ ' 1. Install hyv: npm i -g @holdyourvoice/hyv@latest && hyv welcome',
708
+ ' 2. In ChatGPT: Settings → Connectors (or https://chatgpt.com/#settings/Connectors)',
709
+ ' 3. Add connector:',
710
+ ` Name: hold your voice`,
711
+ ` Command: ${mcpCmd.command}`,
712
+ ` Arguments: ${mcpCmd.args.join(' ')}`,
713
+ ' 4. Save, restart ChatGPT Desktop',
714
+ ' 5. Test: "scan this with hold your voice"',
715
+ '',
716
+ ' If connector fails to start, use the absolute paths above.',
717
+ '',
718
+ '=== not seeing either UI? ===',
719
+ ' • Turn Developer mode ON in ChatGPT settings for New App',
720
+ ' • Connectors may require ChatGPT Plus',
721
+ ' • Browser ChatGPT cannot use either path — desktop app only',
722
+ '',
723
+ 'More help: hyv mcp --setup-chatgpt',
694
724
  '',
695
725
  ].join('\n');
696
726
  const guideFile = path.join(cgDir, 'hyv-mcp-connector.txt');
@@ -21,6 +21,12 @@ print(' ✓ hold your voice installed — free local scan ready');
21
21
  print(' next: hyv welcome | hyv scan draft.md | hyv mcp --setup');
22
22
  print(' no node yet? curl -fsSL https://holdyourvoice.com/install.sh | bash');
23
23
  print('');
24
+ if (process.platform === 'win32') {
25
+ print(' Windows: if you get "scripts is disabled", run in PowerShell:');
26
+ print(' Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser');
27
+ print(' Or use: powershell -ExecutionPolicy Bypass -Command "hyv ..."');
28
+ print('');
29
+ }
24
30
 
25
31
  const { configured, warnings } = setupAgents({ pkgDir, quiet });
26
32