@holdyourvoice/hyv 2.9.23 → 2.9.25

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 CHANGED
@@ -973,7 +973,7 @@ var require_command = __commonJS({
973
973
  "node_modules/commander/lib/command.js"(exports2) {
974
974
  var EventEmitter = require("node:events").EventEmitter;
975
975
  var childProcess = require("node:child_process");
976
- var path28 = require("node:path");
976
+ var path29 = require("node:path");
977
977
  var fs31 = require("node:fs");
978
978
  var process2 = require("node:process");
979
979
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -1916,10 +1916,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1916
1916
  let launchWithNode = false;
1917
1917
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1918
1918
  function findFile(baseDir, baseName) {
1919
- const localBin = path28.resolve(baseDir, baseName);
1919
+ const localBin = path29.resolve(baseDir, baseName);
1920
1920
  if (fs31.existsSync(localBin))
1921
1921
  return localBin;
1922
- if (sourceExt.includes(path28.extname(baseName)))
1922
+ if (sourceExt.includes(path29.extname(baseName)))
1923
1923
  return void 0;
1924
1924
  const foundExt = sourceExt.find(
1925
1925
  (ext) => fs31.existsSync(`${localBin}${ext}`)
@@ -1939,17 +1939,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
1939
1939
  } catch (err) {
1940
1940
  resolvedScriptPath = this._scriptPath;
1941
1941
  }
1942
- executableDir = path28.resolve(
1943
- path28.dirname(resolvedScriptPath),
1942
+ executableDir = path29.resolve(
1943
+ path29.dirname(resolvedScriptPath),
1944
1944
  executableDir
1945
1945
  );
1946
1946
  }
1947
1947
  if (executableDir) {
1948
1948
  let localFile = findFile(executableDir, executableFile);
1949
1949
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1950
- const legacyName = path28.basename(
1950
+ const legacyName = path29.basename(
1951
1951
  this._scriptPath,
1952
- path28.extname(this._scriptPath)
1952
+ path29.extname(this._scriptPath)
1953
1953
  );
1954
1954
  if (legacyName !== this._name) {
1955
1955
  localFile = findFile(
@@ -1960,7 +1960,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1960
1960
  }
1961
1961
  executableFile = localFile || executableFile;
1962
1962
  }
1963
- launchWithNode = sourceExt.includes(path28.extname(executableFile));
1963
+ launchWithNode = sourceExt.includes(path29.extname(executableFile));
1964
1964
  let proc;
1965
1965
  if (process2.platform !== "win32") {
1966
1966
  if (launchWithNode) {
@@ -2817,7 +2817,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2817
2817
  * @return {Command}
2818
2818
  */
2819
2819
  nameFromFilename(filename) {
2820
- this._name = path28.basename(filename, path28.extname(filename));
2820
+ this._name = path29.basename(filename, path29.extname(filename));
2821
2821
  return this;
2822
2822
  }
2823
2823
  /**
@@ -2831,10 +2831,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2831
2831
  * @param {string} [path]
2832
2832
  * @return {(string|null|Command)}
2833
2833
  */
2834
- executableDir(path29) {
2835
- if (path29 === void 0)
2834
+ executableDir(path30) {
2835
+ if (path30 === void 0)
2836
2836
  return this._executableDir;
2837
- this._executableDir = path29;
2837
+ this._executableDir = path30;
2838
2838
  return this;
2839
2839
  }
2840
2840
  /**
@@ -3934,15 +3934,15 @@ var require_route = __commonJS({
3934
3934
  };
3935
3935
  }
3936
3936
  function wrapConversion(toModel, graph) {
3937
- const path28 = [graph[toModel].parent, toModel];
3937
+ const path29 = [graph[toModel].parent, toModel];
3938
3938
  let fn = conversions[graph[toModel].parent][toModel];
3939
3939
  let cur = graph[toModel].parent;
3940
3940
  while (graph[cur].parent) {
3941
- path28.unshift(graph[cur].parent);
3941
+ path29.unshift(graph[cur].parent);
3942
3942
  fn = link(conversions[graph[cur].parent][cur], fn);
3943
3943
  cur = graph[cur].parent;
3944
3944
  }
3945
- fn.conversion = path28;
3945
+ fn.conversion = path29;
3946
3946
  return fn;
3947
3947
  }
3948
3948
  module2.exports = function(fromModel) {
@@ -4381,14 +4381,14 @@ var require_templates = __commonJS({
4381
4381
  }
4382
4382
  return results;
4383
4383
  }
4384
- function buildStyle(chalk36, styles) {
4384
+ function buildStyle(chalk37, 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 = chalk36;
4391
+ let current = chalk37;
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 = (chalk36, temporary) => {
4403
+ module2.exports = (chalk37, 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(chalk36, styles)(string));
4413
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk37, 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(chalk36, styles)(chunk.join("")));
4419
+ chunks.push(buildStyle(chalk37, 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 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 = () => {
4467
+ const chalk38 = {};
4468
+ applyOptions(chalk38, options);
4469
+ chalk38.template = (...arguments_) => chalkTag(chalk38.template, ...arguments_);
4470
+ Object.setPrototypeOf(chalk38, Chalk.prototype);
4471
+ Object.setPrototypeOf(chalk38.template, chalk38);
4472
+ chalk38.template.constructor = () => {
4473
4473
  throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
4474
4474
  };
4475
- chalk37.template.Instance = ChalkClass;
4476
- return chalk37.template;
4475
+ chalk38.template.Instance = ChalkClass;
4476
+ return chalk38.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 = (chalk37, ...strings) => {
4587
+ var chalkTag = (chalk38, ...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(chalk37, parts.join(""));
4603
+ return template(chalk38, parts.join(""));
4604
4604
  };
4605
4605
  Object.defineProperties(Chalk.prototype, styles);
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;
4606
+ var chalk37 = Chalk();
4607
+ chalk37.supportsColor = stdoutColor;
4608
+ chalk37.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
4609
+ chalk37.stderr.supportsColor = stderrColor;
4610
+ module2.exports = chalk37;
4611
4611
  }
4612
4612
  });
4613
4613
 
@@ -5128,13 +5128,13 @@ var require_define_lazy_prop = __commonJS({
5128
5128
  // node_modules/open/index.js
5129
5129
  var require_open = __commonJS({
5130
5130
  "node_modules/open/index.js"(exports2, module2) {
5131
- var path28 = require("path");
5131
+ var path29 = require("path");
5132
5132
  var childProcess = require("child_process");
5133
5133
  var { promises: fs31, constants: fsConstants } = require("fs");
5134
5134
  var isWsl = require_is_wsl();
5135
5135
  var isDocker = require_is_docker();
5136
5136
  var defineLazyProperty = require_define_lazy_prop();
5137
- var localXdgOpenPath = path28.join(__dirname, "xdg-open");
5137
+ var localXdgOpenPath = path29.join(__dirname, "xdg-open");
5138
5138
  var { platform, arch } = process;
5139
5139
  var hasContainerEnv = () => {
5140
5140
  try {
@@ -5291,14 +5291,14 @@ var require_open = __commonJS({
5291
5291
  }
5292
5292
  const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
5293
5293
  if (options.wait) {
5294
- return new Promise((resolve17, reject) => {
5294
+ return new Promise((resolve18, reject) => {
5295
5295
  subprocess.once("error", reject);
5296
5296
  subprocess.once("close", (exitCode) => {
5297
5297
  if (!options.allowNonzeroExitCode && exitCode > 0) {
5298
5298
  reject(new Error(`Exited with code ${exitCode}`));
5299
5299
  return;
5300
5300
  }
5301
- resolve17(subprocess);
5301
+ resolve18(subprocess);
5302
5302
  });
5303
5303
  });
5304
5304
  }
@@ -5413,7 +5413,7 @@ function printFreePaidMatrix(opts = {}) {
5413
5413
  First month $1 \u2192 ${PRICING_URL}`));
5414
5414
  console.log(import_chalk.default.dim(" hyv init | hyv plan --upgrade\n"));
5415
5415
  }
5416
- var import_chalk, NPX_EXAMPLES, FREE_CLI_COMMANDS, PAID_FEATURES, FREE_WEB_TOOLS, COMMUNITY_URL, PRICING_URL, DASHBOARD_BILLING_URL;
5416
+ var import_chalk, NPX_EXAMPLES, FREE_CLI_COMMANDS, PAID_FEATURES, FREE_WEB_TOOLS, COMMUNITY_URL, X_URL, PRICING_URL, DASHBOARD_BILLING_URL;
5417
5417
  var init_free_paid = __esm({
5418
5418
  "src/lib/free-paid.ts"() {
5419
5419
  "use strict";
@@ -5460,6 +5460,7 @@ var init_free_paid = __esm({
5460
5460
  { name: "Blog", url: "https://holdyourvoice.com/blog" }
5461
5461
  ];
5462
5462
  COMMUNITY_URL = "https://holdyourvoice.com/community";
5463
+ X_URL = "https://x.com/istupidpreneur";
5463
5464
  PRICING_URL = "https://holdyourvoice.com/#pricing";
5464
5465
  DASHBOARD_BILLING_URL = "https://holdyourvoice.com/dashboard?tab=billing";
5465
5466
  }
@@ -5514,16 +5515,16 @@ function compareSemver(a, b) {
5514
5515
  return 0;
5515
5516
  }
5516
5517
  function fetchLatestNpmVersion(timeoutMs = 8e3) {
5517
- return new Promise((resolve17) => {
5518
+ return new Promise((resolve18) => {
5518
5519
  (0, import_child_process.execFile)(
5519
5520
  "npm",
5520
5521
  ["view", "@holdyourvoice/hyv", "version"],
5521
5522
  { timeout: timeoutMs, encoding: "utf-8" },
5522
5523
  (err, stdout) => {
5523
5524
  if (err || !stdout?.trim())
5524
- resolve17(null);
5525
+ resolve18(null);
5525
5526
  else
5526
- resolve17(stdout.trim());
5527
+ resolve18(stdout.trim());
5527
5528
  }
5528
5529
  );
5529
5530
  });
@@ -5588,7 +5589,7 @@ function escapeHtml(value) {
5588
5589
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5589
5590
  }
5590
5591
  function request(url, options = {}) {
5591
- return new Promise((resolve17, reject) => {
5592
+ return new Promise((resolve18, reject) => {
5592
5593
  const urlObj = new URL(url);
5593
5594
  const isHttps = urlObj.protocol === "https:";
5594
5595
  const client = isHttps ? https : http;
@@ -5609,9 +5610,9 @@ function request(url, options = {}) {
5609
5610
  res.on("data", (chunk) => data += chunk);
5610
5611
  res.on("end", () => {
5611
5612
  try {
5612
- resolve17({ status: res.statusCode || 0, data: JSON.parse(data) });
5613
+ resolve18({ status: res.statusCode || 0, data: JSON.parse(data) });
5613
5614
  } catch {
5614
- resolve17({ status: res.statusCode || 0, data });
5615
+ resolve18({ status: res.statusCode || 0, data });
5615
5616
  }
5616
5617
  });
5617
5618
  });
@@ -5669,9 +5670,9 @@ async function authenticateWithLicense(licenseKey) {
5669
5670
  }
5670
5671
  async function authenticateWithBrowser() {
5671
5672
  const server = http.createServer();
5672
- const port = await new Promise((resolve17) => {
5673
+ const port = await new Promise((resolve18) => {
5673
5674
  server.listen(0, "127.0.0.1", () => {
5674
- resolve17(server.address().port);
5675
+ resolve18(server.address().port);
5675
5676
  });
5676
5677
  });
5677
5678
  const redirectUri = `http://127.0.0.1:${port}/callback`;
@@ -5690,7 +5691,7 @@ async function authenticateWithBrowser() {
5690
5691
  }
5691
5692
  console.log(import_chalk2.default.cyan("\nOpening browser for authentication..."));
5692
5693
  await (0, import_open.default)(assertSafeOAuthUrl(auth_url));
5693
- const authData = await new Promise((resolve17, reject) => {
5694
+ const authData = await new Promise((resolve18, reject) => {
5694
5695
  const timeout = setTimeout(() => {
5695
5696
  server.close();
5696
5697
  reject(new Error(
@@ -5749,7 +5750,7 @@ async function authenticateWithBrowser() {
5749
5750
  `);
5750
5751
  clearTimeout(timeout);
5751
5752
  server.close();
5752
- resolve17(data);
5753
+ resolve18(data);
5753
5754
  } catch (error) {
5754
5755
  res.writeHead(500, { "Content-Type": "text/html" });
5755
5756
  res.end(`<h1>Authentication failed</h1><p>${escapeHtml(error.message)}</p>`);
@@ -5911,11 +5912,11 @@ var init_telemetry = __esm({
5911
5912
  });
5912
5913
 
5913
5914
  // src/lib/api.ts
5914
- async function request2(method, path28, body) {
5915
+ async function request2(method, path29, body) {
5915
5916
  const token = await getValidToken();
5916
5917
  if (!token)
5917
5918
  throw new Error("you're not signed in yet. run: hyv init");
5918
- const url = `${API_BASE}${path28}`;
5919
+ const url = `${API_BASE}${path29}`;
5919
5920
  const opts = {
5920
5921
  method,
5921
5922
  headers: {
@@ -5940,11 +5941,11 @@ async function request2(method, path28, body) {
5940
5941
  }
5941
5942
  return res.json();
5942
5943
  }
5943
- function apiGet(path28) {
5944
- return request2("GET", path28);
5944
+ function apiGet(path29) {
5945
+ return request2("GET", path29);
5945
5946
  }
5946
- function apiPost(path28, body) {
5947
- return request2("POST", path28, body);
5947
+ function apiPost(path29, body) {
5948
+ return request2("POST", path29, body);
5948
5949
  }
5949
5950
  var init_api = __esm({
5950
5951
  "src/lib/api.ts"() {
@@ -6419,6 +6420,19 @@ async function requirePaidFeature(feature) {
6419
6420
  throw new Error(FEATURE_MESSAGES[feature]);
6420
6421
  }
6421
6422
  }
6423
+ async function maybeShowScanAttribution(jsonMode) {
6424
+ if (jsonMode)
6425
+ return;
6426
+ if (process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true")
6427
+ return;
6428
+ if (isLocalOnlyMode())
6429
+ return;
6430
+ const access = await getAccessState();
6431
+ if (access.hasPaidPlan)
6432
+ return;
6433
+ console.log(import_chalk5.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"));
6434
+ console.log(import_chalk5.default.dim("powered by holdyourvoice.com \xB7 remove this with a profile \u2192 hyv init"));
6435
+ }
6422
6436
  async function maybeShowLimitedModeHint(hasProfile) {
6423
6437
  if (isLocalOnlyMode())
6424
6438
  return;
@@ -11167,7 +11181,7 @@ function runPipeline(text, profile, applyFixes = false) {
11167
11181
  }
11168
11182
  function readText(source) {
11169
11183
  const fs31 = require("fs");
11170
- const path28 = require("path");
11184
+ const path29 = require("path");
11171
11185
  if (source === "-") {
11172
11186
  if (process.stdin.isTTY) {
11173
11187
  console.error("No input provided. Pipe content or specify a file.");
@@ -11175,7 +11189,7 @@ function readText(source) {
11175
11189
  }
11176
11190
  return { text: fs31.readFileSync(0, "utf-8"), path: "stdin" };
11177
11191
  }
11178
- const resolved = path28.resolve(source);
11192
+ const resolved = path29.resolve(source);
11179
11193
  if (!fs31.existsSync(resolved)) {
11180
11194
  console.error(`File not found: ${resolved}`);
11181
11195
  process.exit(1);
@@ -11580,7 +11594,7 @@ function isInteractiveTTY() {
11580
11594
  return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
11581
11595
  }
11582
11596
  function briefPause(ms2 = 280) {
11583
- return new Promise((resolve17) => setTimeout(resolve17, ms2));
11597
+ return new Promise((resolve18) => setTimeout(resolve18, ms2));
11584
11598
  }
11585
11599
  async function withSpinner(label, fn, opts = {}) {
11586
11600
  const minMs = opts.minMs ?? 450;
@@ -11900,7 +11914,7 @@ function saveLocalProfile(name, content) {
11900
11914
  return path14.join(os9.homedir(), ".hyv", "profiles", `${safe}.md`);
11901
11915
  }
11902
11916
  function fetchUrlText(url) {
11903
- return new Promise((resolve17, reject) => {
11917
+ return new Promise((resolve18, reject) => {
11904
11918
  let parsed;
11905
11919
  try {
11906
11920
  parsed = new URL(url);
@@ -11929,7 +11943,7 @@ function fetchUrlText(url) {
11929
11943
  });
11930
11944
  res.on("end", () => {
11931
11945
  const text = data.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
11932
- resolve17(text.slice(0, 12e3));
11946
+ resolve18(text.slice(0, 12e3));
11933
11947
  });
11934
11948
  }
11935
11949
  );
@@ -11949,10 +11963,10 @@ async function collectSamplesFromLink(url) {
11949
11963
  }
11950
11964
  function askLine(prompt) {
11951
11965
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
11952
- return new Promise((resolve17) => {
11966
+ return new Promise((resolve18) => {
11953
11967
  rl.question(prompt, (answer) => {
11954
11968
  rl.close();
11955
- resolve17(answer.trim());
11969
+ resolve18(answer.trim());
11956
11970
  });
11957
11971
  });
11958
11972
  }
@@ -11961,11 +11975,11 @@ async function askMultiline(intro) {
11961
11975
  console.log(import_chalk12.default.dim(" paste below, then type --- on its own line when done\n"));
11962
11976
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
11963
11977
  const lines = [];
11964
- return new Promise((resolve17) => {
11978
+ return new Promise((resolve18) => {
11965
11979
  rl.on("line", (line) => {
11966
11980
  if (line.trim() === "---") {
11967
11981
  rl.close();
11968
- resolve17(lines.join("\n").trim());
11982
+ resolve18(lines.join("\n").trim());
11969
11983
  return;
11970
11984
  }
11971
11985
  lines.push(line);
@@ -15819,7 +15833,7 @@ var {
15819
15833
  } = import_index.default;
15820
15834
 
15821
15835
  // src/index.ts
15822
- var import_chalk35 = __toESM(require_source());
15836
+ var import_chalk36 = __toESM(require_source());
15823
15837
 
15824
15838
  // src/commands/init.ts
15825
15839
  var import_chalk4 = __toESM(require_source());
@@ -17171,7 +17185,7 @@ function registerImportCommand(program3) {
17171
17185
  });
17172
17186
  }
17173
17187
  function askQuestion(question) {
17174
- return new Promise((resolve17) => {
17188
+ return new Promise((resolve18) => {
17175
17189
  const readline3 = require("readline");
17176
17190
  const rl = readline3.createInterface({
17177
17191
  input: process.stdin,
@@ -17180,7 +17194,7 @@ function askQuestion(question) {
17180
17194
  rl.question(import_chalk13.default.cyan(` ${question}
17181
17195
  > `), (answer) => {
17182
17196
  rl.close();
17183
- resolve17(answer.trim());
17197
+ resolve18(answer.trim());
17184
17198
  });
17185
17199
  });
17186
17200
  }
@@ -17719,6 +17733,7 @@ hyv scan ${filePath}`));
17719
17733
  if (options.format !== "json") {
17720
17734
  printScanShareHint(score, signals.length);
17721
17735
  }
17736
+ await maybeShowScanAttribution(options.format === "json");
17722
17737
  recordEvent("scan_complete", {
17723
17738
  score,
17724
17739
  issues: signals.length,
@@ -17752,6 +17767,18 @@ var import_child_process4 = require("child_process");
17752
17767
  // src/lib/cli-entry.ts
17753
17768
  var fs18 = __toESM(require("fs"));
17754
17769
  var path17 = __toESM(require("path"));
17770
+
17771
+ // src/lib/mcp-stdio.ts
17772
+ function isMcpStdioMode(opts) {
17773
+ if (opts?.stdio)
17774
+ return true;
17775
+ if (process.env.HYV_MCP_STDIO === "1" || process.env.HYV_MCP_STDIO === "true")
17776
+ return true;
17777
+ return !process.stdout.isTTY;
17778
+ }
17779
+ var MCP_SERVER_ARGS = ["mcp", "--stdio"];
17780
+
17781
+ // src/lib/cli-entry.ts
17755
17782
  function resolveCliEntry() {
17756
17783
  const candidates = [
17757
17784
  path17.resolve(process.argv[1] || ""),
@@ -17763,9 +17790,9 @@ function resolveCliEntry() {
17763
17790
  function mcpServerCommand() {
17764
17791
  const entry = resolveCliEntry();
17765
17792
  if (entry) {
17766
- return { command: process.execPath, args: [entry, "mcp"] };
17793
+ return { command: process.execPath, args: [entry, ...MCP_SERVER_ARGS] };
17767
17794
  }
17768
- return { command: "hyv", args: ["mcp"] };
17795
+ return { command: "hyv", args: [...MCP_SERVER_ARGS] };
17769
17796
  }
17770
17797
  function mcpServerSnippet() {
17771
17798
  const { command, args: args2 } = mcpServerCommand();
@@ -17777,10 +17804,10 @@ async function testMcpStdioSubprocess() {
17777
17804
  const entry = resolveCliEntry();
17778
17805
  if (!entry)
17779
17806
  return { ok: false };
17780
- return new Promise((resolve17) => {
17781
- const child = (0, import_child_process4.spawn)(process.execPath, [entry, "mcp"], {
17807
+ return new Promise((resolve18) => {
17808
+ const child = (0, import_child_process4.spawn)(process.execPath, [entry, "mcp", "--stdio"], {
17782
17809
  stdio: ["pipe", "pipe", "pipe"],
17783
- env: { ...process.env, HYV_POSTINSTALL_QUIET: "1" }
17810
+ env: { ...process.env, HYV_POSTINSTALL_QUIET: "1", HYV_MCP_STDIO: "1" }
17784
17811
  });
17785
17812
  let buffer = "";
17786
17813
  let settled = false;
@@ -17793,7 +17820,7 @@ async function testMcpStdioSubprocess() {
17793
17820
  child.kill();
17794
17821
  } catch {
17795
17822
  }
17796
- resolve17({ ok, toolCount });
17823
+ resolve18({ ok, toolCount });
17797
17824
  };
17798
17825
  const timeout = setTimeout(() => finish(false), 1e4);
17799
17826
  const handleLine = (line) => {
@@ -18198,11 +18225,11 @@ async function confirmDestructiveWrite(options) {
18198
18225
  const question = `
18199
18226
  ${label}
18200
18227
  A .bak backup will be created. Proceed? [y/N] `;
18201
- const answer = await new Promise((resolve17) => {
18228
+ const answer = await new Promise((resolve18) => {
18202
18229
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
18203
18230
  rl.question(question, (value) => {
18204
18231
  rl.close();
18205
- resolve17(value.trim().toLowerCase());
18232
+ resolve18(value.trim().toLowerCase());
18206
18233
  });
18207
18234
  });
18208
18235
  return answer === "y" || answer === "yes";
@@ -18448,11 +18475,11 @@ function registerDiffCommand(program3) {
18448
18475
  console.log(import_chalk25.default.dim(` run: hyv fix ${file} -i to apply`));
18449
18476
  if (options.apply && filePath !== "stdin") {
18450
18477
  const fs31 = require("fs");
18451
- const path28 = require("path");
18478
+ const path29 = require("path");
18452
18479
  const backupPath = filePath + ".bak";
18453
18480
  fs31.copyFileSync(filePath, backupPath);
18454
18481
  fs31.writeFileSync(filePath, result.fixed);
18455
- console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${path28.basename(backupPath)}`));
18482
+ console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${path29.basename(backupPath)}`));
18456
18483
  }
18457
18484
  } catch (error) {
18458
18485
  console.error(import_chalk25.default.red(`Error: ${error.message}`));
@@ -19145,16 +19172,17 @@ More: hyv content ci`
19145
19172
  },
19146
19173
  share: {
19147
19174
  title: "Share your voice fingerprint",
19148
- body: `Social post template:
19175
+ body: `Social post template (X / LinkedIn):
19149
19176
 
19150
19177
  I run my AI drafts through @holdyourvoice/hyv before they ship.
19151
19178
 
19152
- Free local scan caught [N] patterns in 2 seconds \u2014 no API, offline.
19179
+ Free local scan caught 34 patterns in 2 seconds \u2014 score 0/100. no API, offline.
19153
19180
 
19154
19181
  Cursor/Claude agents can call hyv mcp tools directly.
19155
19182
 
19156
19183
  Try: npx @holdyourvoice/hyv welcome
19157
19184
 
19185
+ ${X_URL}
19158
19186
  ${COMMUNITY_URL}`
19159
19187
  }
19160
19188
  };
@@ -19186,9 +19214,148 @@ function registerUpgradeCommand(program3) {
19186
19214
  });
19187
19215
  }
19188
19216
 
19217
+ // src/commands/share.ts
19218
+ var import_chalk33 = __toESM(require_source());
19219
+ var path24 = __toESM(require("path"));
19220
+ init_pipeline();
19221
+ init_local_profile();
19222
+ init_telemetry();
19223
+ init_signals();
19224
+ var { createCanvas, registerFont } = (() => {
19225
+ try {
19226
+ return require("canvas");
19227
+ } catch {
19228
+ console.error(import_chalk33.default.red("canvas package is required. install it: npm install canvas"));
19229
+ process.exit(1);
19230
+ }
19231
+ })();
19232
+ var CARD_W = 1200;
19233
+ var CARD_H = 630;
19234
+ function scoreColor(score) {
19235
+ if (score < 50)
19236
+ return "#ef4444";
19237
+ if (score < 75)
19238
+ return "#f59e0b";
19239
+ return "#22c55e";
19240
+ }
19241
+ function topPatternPills(signals) {
19242
+ const counts = /* @__PURE__ */ new Map();
19243
+ for (const s of signals) {
19244
+ counts.set(s.id, (counts.get(s.id) || 0) + 1);
19245
+ }
19246
+ return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([id, count]) => ({ id, count }));
19247
+ }
19248
+ function drawCard(ctx, rawScore, fixedScore, topPatterns, fileName, hasFixes) {
19249
+ const w = CARD_W, h = CARD_H;
19250
+ ctx.fillStyle = "#0a0a0a";
19251
+ ctx.fillRect(0, 0, w, h);
19252
+ ctx.fillStyle = "#888";
19253
+ ctx.font = '14px "Menlo", "Courier New", monospace';
19254
+ ctx.fillText("hold your voice", 40, 50);
19255
+ const scoreMain = hasFixes ? `${rawScore} \u2192 ${fixedScore}` : `${rawScore}/100`;
19256
+ ctx.fillStyle = scoreColor(rawScore);
19257
+ ctx.font = 'bold 80px "Menlo", "Courier New", monospace';
19258
+ ctx.textAlign = "center";
19259
+ ctx.fillText(scoreMain, w / 2, h / 2 - 20);
19260
+ ctx.fillStyle = "#888";
19261
+ ctx.font = '16px "Menlo", "Courier New", monospace';
19262
+ ctx.fillText(hasFixes ? "raw \u2192 after local fixes" : "voice score", w / 2, h / 2 + 30);
19263
+ if (topPatterns.length > 0) {
19264
+ let pillX = w / 2 - topPatterns.length * 90 / 2;
19265
+ if (topPatterns.length === 1)
19266
+ pillX = w / 2 - 80;
19267
+ else if (topPatterns.length === 2)
19268
+ pillX = w / 2 - 130;
19269
+ for (const p of topPatterns) {
19270
+ const label = `[${p.id}]`;
19271
+ ctx.fillStyle = "#222";
19272
+ const tw = ctx.measureText ? ctx.measureText(label).width + 24 : 160;
19273
+ const pillW = Math.max(tw, 100);
19274
+ roundRect(ctx, pillX - 4, h / 2 + 60, pillW, 32, 6);
19275
+ ctx.fillStyle = "#222";
19276
+ ctx.fill();
19277
+ ctx.fillStyle = "#ccc";
19278
+ ctx.font = '13px "Menlo", "Courier New", monospace';
19279
+ ctx.textAlign = "left";
19280
+ ctx.fillText(label, pillX + 12, h / 2 + 82);
19281
+ pillX += pillW + 12;
19282
+ }
19283
+ }
19284
+ ctx.fillStyle = "#555";
19285
+ ctx.font = '13px "Menlo", "Courier New", monospace';
19286
+ ctx.textAlign = "left";
19287
+ ctx.fillText(fileName, 40, h - 30);
19288
+ ctx.fillStyle = "#555";
19289
+ ctx.font = '13px "Menlo", "Courier New", monospace';
19290
+ ctx.textAlign = "right";
19291
+ ctx.fillText("holdyourvoice.com", w - 40, h - 30);
19292
+ }
19293
+ function roundRect(ctx, x2, y, w, h, r) {
19294
+ ctx.beginPath();
19295
+ ctx.moveTo(x2 + r, y);
19296
+ ctx.lineTo(x2 + w - r, y);
19297
+ ctx.quadraticCurveTo(x2 + w, y, x2 + w, y + r);
19298
+ ctx.lineTo(x2 + w, y + h - r);
19299
+ ctx.quadraticCurveTo(x2 + w, y + h, x2 + w - r, y + h);
19300
+ ctx.lineTo(x2 + r, y + h);
19301
+ ctx.quadraticCurveTo(x2, y + h, x2, y + h - r);
19302
+ ctx.lineTo(x2, y + r);
19303
+ ctx.quadraticCurveTo(x2, y, x2 + r, y);
19304
+ ctx.closePath();
19305
+ }
19306
+ function registerShareCommand(program3) {
19307
+ program3.command("share").description("Generate a shareable score card PNG from a scan").argument("<file>", "File to scan (or - for stdin)").option("--open", "Open the image after generation").option("--profile <name>", "Voice profile for scan context").action(async (file, options) => {
19308
+ try {
19309
+ const profile = await loadProfileForCommand(options.profile);
19310
+ const { text, path: filePath } = readText(file);
19311
+ if (!text.trim()) {
19312
+ console.warn(import_chalk33.default.yellow("File is empty or contains only whitespace."));
19313
+ process.exit(0);
19314
+ }
19315
+ const analysis = await runHybridAnalysis(text, profile, {
19316
+ profileSlug: options.profile || profile?.slug
19317
+ });
19318
+ const rawScore = analysis.mode === "hybrid" ? analysis.score : calculateScore(text, analysis.signalMap.signals);
19319
+ const pipelineResult = runPipeline(text, profile, true);
19320
+ const fixedScore = pipelineResult.autoFixResult.changed ? (() => {
19321
+ const fixedSignalMap = extractSignals(pipelineResult.autoFixResult.fixed, profile);
19322
+ return calculateScore(pipelineResult.autoFixResult.fixed, fixedSignalMap.signals);
19323
+ })() : null;
19324
+ const topPatterns = topPatternPills(analysis.signalMap.signals);
19325
+ const canvas = createCanvas(CARD_W, CARD_H);
19326
+ const ctx = canvas.getContext("2d");
19327
+ const displayName = filePath === "stdin" ? "unnamed draft" : path24.basename(filePath);
19328
+ drawCard(ctx, rawScore, fixedScore, topPatterns, displayName, pipelineResult.autoFixResult.changed);
19329
+ const ts2 = Date.now();
19330
+ const outName = `hyv-score-${ts2}.png`;
19331
+ const outPath = path24.resolve(process.cwd(), outName);
19332
+ const buf = canvas.toBuffer("image/png");
19333
+ require("fs").writeFileSync(outPath, buf);
19334
+ console.log(import_chalk33.default.green(`
19335
+ score card saved \u2192 ./${outName}`));
19336
+ const rawStr = String(rawScore);
19337
+ const afterStr = pipelineResult.autoFixResult.changed ? ` after hyv. ${fixedScore}` : ".";
19338
+ const tweetText = `my ai draft scored ${rawStr}${afterStr} holdyourvoice.com`;
19339
+ const tweetUrl = `https://x.com/intent/tweet?text=${encodeURIComponent(tweetText)}`;
19340
+ console.log(import_chalk33.default.dim(`share it: ${tweetUrl}`));
19341
+ if (options.open) {
19342
+ try {
19343
+ const open3 = require_open();
19344
+ await open3(outPath);
19345
+ } catch {
19346
+ }
19347
+ }
19348
+ recordEvent("share_complete", { score: rawScore, fileName: displayName });
19349
+ } catch (error) {
19350
+ console.error(import_chalk33.default.red(`Error: ${error.message}`));
19351
+ process.exit(1);
19352
+ }
19353
+ });
19354
+ }
19355
+
19189
19356
  // src/mcp.ts
19190
19357
  var fs27 = __toESM(require("fs"));
19191
- var path25 = __toESM(require("path"));
19358
+ var path26 = __toESM(require("path"));
19192
19359
  var os13 = __toESM(require("os"));
19193
19360
  init_classifier();
19194
19361
  init_autofix();
@@ -19201,28 +19368,28 @@ init_telemetry();
19201
19368
  init_access();
19202
19369
 
19203
19370
  // src/lib/mcp-integrate.ts
19204
- var import_chalk33 = __toESM(require_source());
19371
+ var import_chalk34 = __toESM(require_source());
19205
19372
  var fs26 = __toESM(require("fs"));
19206
19373
  var os12 = __toESM(require("os"));
19207
- var path24 = __toESM(require("path"));
19374
+ var path25 = __toESM(require("path"));
19208
19375
  init_version();
19209
19376
  init_welcome_flow();
19210
19377
  init_config();
19211
19378
  init_local_profile();
19212
19379
  function resolveCliRoot() {
19213
19380
  const candidates = [
19214
- path24.resolve(__dirname, ".."),
19215
- path24.resolve(__dirname, "..", "..")
19381
+ path25.resolve(__dirname, ".."),
19382
+ path25.resolve(__dirname, "..", "..")
19216
19383
  ];
19217
19384
  for (const root of candidates) {
19218
- if (fs26.existsSync(path24.join(root, "scripts", "postinstall-lib.js"))) {
19385
+ if (fs26.existsSync(path25.join(root, "scripts", "postinstall-lib.js"))) {
19219
19386
  return root;
19220
19387
  }
19221
19388
  }
19222
19389
  return candidates[0];
19223
19390
  }
19224
19391
  function loadPostinstallLib() {
19225
- return require(path24.join(resolveCliRoot(), "scripts", "postinstall-lib.js"));
19392
+ return require(path25.join(resolveCliRoot(), "scripts", "postinstall-lib.js"));
19226
19393
  }
19227
19394
  function runMcpAutoIntegrate(opts = {}) {
19228
19395
  const { integrateDetectedAgents } = loadPostinstallLib();
@@ -19265,7 +19432,7 @@ function buildOnboardingStatusLines() {
19265
19432
  function formatChatGptConnectorGuide() {
19266
19433
  const lib = loadPostinstallLib();
19267
19434
  const mcpCmd = lib.resolveHyvMcpCommand(resolveCliRoot());
19268
- const guidePath = path24.join(os12.homedir(), ".chatgpt", "hyv-mcp-connector.txt");
19435
+ const guidePath = path25.join(os12.homedir(), ".chatgpt", "hyv-mcp-connector.txt");
19269
19436
  const lines = [
19270
19437
  "### ChatGPT Desktop \u2014 RECOMMENDED: Path A (remote OAuth)",
19271
19438
  "",
@@ -19295,7 +19462,7 @@ function formatChatGptConnectorGuide() {
19295
19462
  "2. Settings \u2192 Connectors \u2192 Add connector",
19296
19463
  "3. Name: **hold your voice**",
19297
19464
  "4. Command: **hyv** (or absolute path below if connector fails)",
19298
- "5. Arguments: **mcp**",
19465
+ "5. Arguments: **mcp --stdio**",
19299
19466
  "",
19300
19467
  "If the connector fails to start, use absolute paths:",
19301
19468
  ` command: ${mcpCmd.command}`,
@@ -19400,75 +19567,75 @@ function printMcpIntegrateReport(result, opts = {}) {
19400
19567
  const configuredIds = new Set(
19401
19568
  result.configured.map((label) => agentIdForConfiguredLabel(label)).filter(Boolean)
19402
19569
  );
19403
- console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp integration\n"));
19404
- console.log(import_chalk33.default.dim(` ${getEngineLabel()}
19570
+ console.log(import_chalk34.default.bold("\nhold your voice \u2014 mcp integration\n"));
19571
+ console.log(import_chalk34.default.dim(` ${getEngineLabel()}
19405
19572
  `));
19406
19573
  const welcome = readWelcomeState();
19407
19574
  const profiles = listLocalProfileNames2();
19408
19575
  if (profiles.length > 0) {
19409
- console.log(import_chalk33.default.dim(` voice profiles: ${profiles.join(", ")}`));
19576
+ console.log(import_chalk34.default.dim(` voice profiles: ${profiles.join(", ")}`));
19410
19577
  } else {
19411
- console.log(import_chalk33.default.yellow(" no voice profile yet \u2014 mcp still works (free scan). finish onboarding in terminal or in-chat via hyv_welcome"));
19578
+ console.log(import_chalk34.default.yellow(" no voice profile yet \u2014 mcp still works (free scan). finish onboarding in terminal or in-chat via hyv_welcome"));
19412
19579
  }
19413
19580
  if (welcome.completed_steps?.length) {
19414
- console.log(import_chalk33.default.dim(` welcome progress: ${welcome.completed_steps.join(", ")}`));
19581
+ console.log(import_chalk34.default.dim(` welcome progress: ${welcome.completed_steps.join(", ")}`));
19415
19582
  }
19416
19583
  console.log("");
19417
19584
  if (result.detected.length === 0) {
19418
- console.log(import_chalk33.default.yellow(" no supported ai apps detected on this machine."));
19419
- console.log(import_chalk33.default.dim("\n install cursor, claude desktop, chatgpt desktop, or another supported app,"));
19420
- console.log(import_chalk33.default.dim(" then run hyv mcp again \u2014 or hyv doctor --fix-agents to configure everything."));
19421
- console.log(import_chalk33.default.dim("\n in chatgpt/claude/cursor: call hyv_welcome to onboard without the terminal."));
19422
- console.log(import_chalk33.default.dim(" chatgpt desktop (paid): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
19423
- console.log(import_chalk33.default.dim(" full steps: hyv mcp --setup-chatgpt\n"));
19585
+ console.log(import_chalk34.default.yellow(" no supported ai apps detected on this machine."));
19586
+ console.log(import_chalk34.default.dim("\n install cursor, claude desktop, chatgpt desktop, or another supported app,"));
19587
+ console.log(import_chalk34.default.dim(" then run hyv mcp again \u2014 or hyv doctor --fix-agents to configure everything."));
19588
+ console.log(import_chalk34.default.dim("\n in chatgpt/claude/cursor: call hyv_welcome to onboard without the terminal."));
19589
+ console.log(import_chalk34.default.dim(" chatgpt desktop (paid): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
19590
+ console.log(import_chalk34.default.dim(" full steps: hyv mcp --setup-chatgpt\n"));
19424
19591
  return;
19425
19592
  }
19426
- console.log(import_chalk33.default.bold("detected apps"));
19593
+ console.log(import_chalk34.default.bold("detected apps"));
19427
19594
  for (const app of result.detected) {
19428
19595
  const justConfigured = configuredIds.has(app.id);
19429
19596
  const integrated = isAgentIntegrated(app.id) || justConfigured;
19430
- const mark = app.integration === "manual" ? import_chalk33.default.yellow("\u25CB") : integrated ? import_chalk33.default.green("\u2713") : import_chalk33.default.cyan("\u2192");
19597
+ const mark = app.integration === "manual" ? import_chalk34.default.yellow("\u25CB") : integrated ? import_chalk34.default.green("\u2713") : import_chalk34.default.cyan("\u2192");
19431
19598
  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";
19432
19599
  console.log(` ${mark} ${app.label} \u2014 ${status}`);
19433
- console.log(import_chalk33.default.dim(` ${app.reason} \xB7 ${app.integration}`));
19600
+ console.log(import_chalk34.default.dim(` ${app.reason} \xB7 ${app.integration}`));
19434
19601
  }
19435
19602
  if (result.configured.length > 0) {
19436
- console.log(import_chalk33.default.green(`
19603
+ console.log(import_chalk34.default.green(`
19437
19604
  wired hyv into: ${result.configured.join(", ")}`));
19438
19605
  }
19439
19606
  if (result.warnings.length > 0) {
19440
- console.log(import_chalk33.default.yellow("\n notes:"));
19607
+ console.log(import_chalk34.default.yellow("\n notes:"));
19441
19608
  for (const warning of result.warnings) {
19442
- console.log(import_chalk33.default.yellow(` ! ${warning}`));
19609
+ console.log(import_chalk34.default.yellow(` ! ${warning}`));
19443
19610
  }
19444
19611
  }
19445
19612
  const mcpApps = result.detected.filter((a) => a.integration === "mcp");
19446
19613
  const manualApps = result.detected.filter((a) => a.integration === "manual");
19447
- console.log(import_chalk33.default.bold("\nnext steps"));
19448
- console.log(import_chalk33.default.dim(" in this app: hyv_welcome (onboarding) \xB7 hyv_mcp_setup (status/refresh) \xB7 hyv_demo (try a scan)"));
19614
+ console.log(import_chalk34.default.bold("\nnext steps"));
19615
+ console.log(import_chalk34.default.dim(" in this app: hyv_welcome (onboarding) \xB7 hyv_mcp_setup (status/refresh) \xB7 hyv_demo (try a scan)"));
19449
19616
  if (mcpApps.length > 0) {
19450
- console.log(import_chalk33.default.dim(" restart apps that use mcp (cursor, claude desktop, antigravity, opencode)"));
19617
+ console.log(import_chalk34.default.dim(" restart apps that use mcp (cursor, claude desktop, antigravity, opencode)"));
19451
19618
  }
19452
19619
  if (manualApps.length > 0) {
19453
- console.log(import_chalk33.default.dim(" chatgpt (recommended): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
19454
- console.log(import_chalk33.default.dim(" chatgpt (free fallback): settings \u2192 connectors \u2192 command hyv, arguments mcp"));
19455
- console.log(import_chalk33.default.dim(" full steps: hyv mcp --setup-chatgpt"));
19620
+ console.log(import_chalk34.default.dim(" chatgpt (recommended): developer mode \u2192 new app \u2192 https://holdyourvoice.com/mcp + oauth"));
19621
+ console.log(import_chalk34.default.dim(" chatgpt (free fallback): settings \u2192 connectors \u2192 command hyv, arguments mcp"));
19622
+ console.log(import_chalk34.default.dim(" full steps: hyv mcp --setup-chatgpt"));
19456
19623
  }
19457
- console.log(import_chalk33.default.dim(" refresh stale configs after upgrade: hyv mcp --force"));
19458
- console.log(import_chalk33.default.dim(" verify: hyv mcp --test"));
19459
- console.log(import_chalk33.default.dim(" all hosts: hyv doctor --verify-hosts\n"));
19624
+ console.log(import_chalk34.default.dim(" refresh stale configs after upgrade: hyv mcp --force"));
19625
+ console.log(import_chalk34.default.dim(" verify: hyv mcp --test"));
19626
+ console.log(import_chalk34.default.dim(" all hosts: hyv doctor --verify-hosts\n"));
19460
19627
  }
19461
19628
 
19462
19629
  // src/mcp.ts
19463
19630
  init_mcp_profile_hydrate();
19464
19631
  init_profile();
19465
- var VOICE_MD = path25.join(os13.homedir(), ".hyv", "voice.md");
19632
+ var VOICE_MD = path26.join(os13.homedir(), ".hyv", "voice.md");
19466
19633
  var MAX_RESPONSE_CHARS = 12e4;
19467
19634
  var MAX_SCAN_FILE_BYTES = 2 * 1024 * 1024;
19468
19635
  function readScanFile(filePath) {
19469
19636
  const cwdReal = fs27.realpathSync(process.cwd());
19470
- const resolved = fs27.realpathSync(path25.resolve(filePath));
19471
- if (!resolved.startsWith(cwdReal + path25.sep) && resolved !== cwdReal) {
19637
+ const resolved = fs27.realpathSync(path26.resolve(filePath));
19638
+ if (!resolved.startsWith(cwdReal + path26.sep) && resolved !== cwdReal) {
19472
19639
  throw new Error(`file must be in the current working directory (${cwdReal})`);
19473
19640
  }
19474
19641
  const stat = fs27.statSync(resolved);
@@ -19484,7 +19651,7 @@ function toolResultPayload(result) {
19484
19651
  ...isError ? { isError: true } : {}
19485
19652
  };
19486
19653
  }
19487
- var pkgPath = path25.resolve(__dirname, "..", "package.json");
19654
+ var pkgPath = path26.resolve(__dirname, "..", "package.json");
19488
19655
  var pkgVersion = (() => {
19489
19656
  try {
19490
19657
  return JSON.parse(fs27.readFileSync(pkgPath, "utf-8")).version;
@@ -20087,7 +20254,7 @@ async function startMcpServer() {
20087
20254
  const access = await getAccessState().catch(() => null);
20088
20255
  const config = (() => {
20089
20256
  try {
20090
- return JSON.parse(fs27.readFileSync(path25.join(os13.homedir(), ".hyv", "config.json"), "utf-8"));
20257
+ return JSON.parse(fs27.readFileSync(path26.join(os13.homedir(), ".hyv", "config.json"), "utf-8"));
20091
20258
  } catch {
20092
20259
  return {};
20093
20260
  }
@@ -20144,83 +20311,83 @@ async function startMcpServer() {
20144
20311
  }
20145
20312
 
20146
20313
  // src/lib/mcp-setup.ts
20147
- var import_chalk34 = __toESM(require_source());
20314
+ var import_chalk35 = __toESM(require_source());
20148
20315
  var fs28 = __toESM(require("fs"));
20149
- var path26 = __toESM(require("path"));
20316
+ var path27 = __toESM(require("path"));
20150
20317
  var os14 = __toESM(require("os"));
20151
20318
  init_version();
20152
20319
  var HOME2 = os14.homedir();
20153
20320
  var IS_WIN2 = process.platform === "win32";
20154
20321
  function claudeDesktopConfigPath() {
20155
20322
  if (IS_WIN2)
20156
- return path26.join(HOME2, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
20323
+ return path27.join(HOME2, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
20157
20324
  if (process.platform === "linux")
20158
- return path26.join(HOME2, ".config", "Claude", "claude_desktop_config.json");
20159
- return path26.join(HOME2, "Library", "Application Support", "Claude", "claude_desktop_config.json");
20325
+ return path27.join(HOME2, ".config", "Claude", "claude_desktop_config.json");
20326
+ return path27.join(HOME2, "Library", "Application Support", "Claude", "claude_desktop_config.json");
20160
20327
  }
20161
20328
  function printMcpSetup() {
20162
- console.log(import_chalk34.default.bold("\nhold your voice \u2014 mcp setup\n"));
20163
- console.log(import_chalk34.default.dim(` ${getEngineLabel()}
20329
+ console.log(import_chalk35.default.bold("\nhold your voice \u2014 mcp setup\n"));
20330
+ console.log(import_chalk35.default.dim(` ${getEngineLabel()}
20164
20331
  `));
20165
- console.log(import_chalk34.default.bold("Claude Desktop"));
20166
- console.log(import_chalk34.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
20167
- console.log(import_chalk34.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
20168
- console.log(import_chalk34.default.dim(` Config: ${claudeDesktopConfigPath()}
20332
+ console.log(import_chalk35.default.bold("Claude Desktop"));
20333
+ console.log(import_chalk35.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
20334
+ console.log(import_chalk35.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
20335
+ console.log(import_chalk35.default.dim(` Config: ${claudeDesktopConfigPath()}
20169
20336
  `));
20170
- console.log(import_chalk34.default.bold("Cursor"));
20171
- console.log(import_chalk34.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
20172
- console.log(import_chalk34.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
20173
- console.log(import_chalk34.default.bold("Claude Code"));
20174
- console.log(import_chalk34.default.dim(" Command: ~/.claude/commands/hyv.md"));
20175
- console.log(import_chalk34.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
20176
- console.log(import_chalk34.default.bold("Windsurf"));
20177
- console.log(import_chalk34.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
20178
- console.log(import_chalk34.default.bold("Codex"));
20179
- console.log(import_chalk34.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
20180
- console.log(import_chalk34.default.bold("Command Code"));
20181
- console.log(import_chalk34.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
20182
- console.log(import_chalk34.default.bold("ChatGPT Desktop (manual connector)"));
20183
- console.log(import_chalk34.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
20184
- console.log(import_chalk34.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp"));
20185
- console.log(import_chalk34.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
20186
- console.log(import_chalk34.default.dim(" hyv mcp --setup-chatgpt"));
20337
+ console.log(import_chalk35.default.bold("Cursor"));
20338
+ console.log(import_chalk35.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
20339
+ console.log(import_chalk35.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
20340
+ console.log(import_chalk35.default.bold("Claude Code"));
20341
+ console.log(import_chalk35.default.dim(" Command: ~/.claude/commands/hyv.md"));
20342
+ console.log(import_chalk35.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
20343
+ console.log(import_chalk35.default.bold("Windsurf"));
20344
+ console.log(import_chalk35.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
20345
+ console.log(import_chalk35.default.bold("Codex"));
20346
+ console.log(import_chalk35.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
20347
+ console.log(import_chalk35.default.bold("Command Code"));
20348
+ console.log(import_chalk35.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
20349
+ console.log(import_chalk35.default.bold("ChatGPT Desktop (manual connector)"));
20350
+ console.log(import_chalk35.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
20351
+ console.log(import_chalk35.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp --stdio"));
20352
+ console.log(import_chalk35.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
20353
+ console.log(import_chalk35.default.dim(" hyv mcp --setup-chatgpt"));
20187
20354
  if (IS_WIN2) {
20188
- console.log(import_chalk34.default.dim(" Windows (Lenovo/Win11 often Restricted): if blocked use:"));
20189
- console.log(import_chalk34.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv ..."'));
20190
- console.log(import_chalk34.default.dim(" Diagnose: Get-ExecutionPolicy -List"));
20191
- console.log(import_chalk34.default.dim(" Permanent fix: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20192
- console.log(import_chalk34.default.dim(" For connectors: use full path printed in the .txt (node + .js)"));
20355
+ console.log(import_chalk35.default.dim(" Windows (Lenovo/Win11 often Restricted): if blocked use:"));
20356
+ console.log(import_chalk35.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv ..."'));
20357
+ console.log(import_chalk35.default.dim(" Diagnose: Get-ExecutionPolicy -List"));
20358
+ console.log(import_chalk35.default.dim(" Permanent fix: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20359
+ console.log(import_chalk35.default.dim(" For connectors: use full path printed in the .txt (node + .js)"));
20193
20360
  }
20194
20361
  console.log("");
20195
- console.log(import_chalk34.default.bold("Antigravity"));
20196
- console.log(import_chalk34.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
20197
- console.log(import_chalk34.default.bold("OpenCode"));
20198
- console.log(import_chalk34.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
20199
- console.log(import_chalk34.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
20200
- console.log(import_chalk34.default.bold("Auto-configure"));
20201
- console.log(import_chalk34.default.dim(" hyv mcp (detect installed apps + wire mcp into them)"));
20202
- console.log(import_chalk34.default.dim(" hyv mcp --force (refresh configs after hyv upgrade)"));
20203
- console.log(import_chalk34.default.dim(" hyv doctor --fix-agents (configure all apps, not just detected)"));
20204
- console.log(import_chalk34.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
20205
- console.log(import_chalk34.default.bold("In-chat (no terminal)"));
20206
- console.log(import_chalk34.default.dim(" hyv_mcp_setup \u2014 status, integrate, or chatgpt connector steps"));
20207
- console.log(import_chalk34.default.dim(" hyv_welcome \u2014 finish onboarding inside Cursor/Claude/ChatGPT\n"));
20208
- console.log(import_chalk34.default.bold("Verify"));
20209
- console.log(import_chalk34.default.dim(" hyv mcp --test"));
20210
- console.log(import_chalk34.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
20362
+ console.log(import_chalk35.default.bold("Antigravity"));
20363
+ console.log(import_chalk35.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
20364
+ console.log(import_chalk35.default.bold("OpenCode"));
20365
+ console.log(import_chalk35.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
20366
+ console.log(import_chalk35.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
20367
+ console.log(import_chalk35.default.bold("Auto-configure"));
20368
+ console.log(import_chalk35.default.dim(" hyv mcp (detect installed apps + wire mcp into them)"));
20369
+ console.log(import_chalk35.default.dim(" hyv mcp --force (refresh configs after hyv upgrade)"));
20370
+ console.log(import_chalk35.default.dim(" hyv doctor --fix-agents (configure all apps, not just detected)"));
20371
+ console.log(import_chalk35.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
20372
+ console.log(import_chalk35.default.bold("In-chat (no terminal)"));
20373
+ console.log(import_chalk35.default.dim(" hyv_mcp_setup \u2014 status, integrate, or chatgpt connector steps"));
20374
+ console.log(import_chalk35.default.dim(" hyv_welcome \u2014 finish onboarding inside Cursor/Claude/ChatGPT\n"));
20375
+ console.log(import_chalk35.default.bold("Verify"));
20376
+ console.log(import_chalk35.default.dim(" hyv mcp --test"));
20377
+ console.log(import_chalk35.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
20211
20378
  }
20212
20379
  async function runMcpSelfTest() {
20213
- console.log(import_chalk34.default.bold("\nhold your voice \u2014 mcp self-test\n"));
20214
- console.log(import_chalk34.default.dim(` ${getEngineLabel()}
20380
+ console.log(import_chalk35.default.bold("\nhold your voice \u2014 mcp self-test\n"));
20381
+ console.log(import_chalk35.default.dim(` ${getEngineLabel()}
20215
20382
  `));
20216
20383
  let passed = 0;
20217
20384
  let failed = 0;
20218
20385
  const tools = getMcpToolNames();
20219
20386
  if (tools.length >= 10) {
20220
- console.log(import_chalk34.default.green(` \u2713 ${tools.length} MCP tools registered`));
20387
+ console.log(import_chalk35.default.green(` \u2713 ${tools.length} MCP tools registered`));
20221
20388
  passed++;
20222
20389
  } else {
20223
- console.log(import_chalk34.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
20390
+ console.log(import_chalk35.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
20224
20391
  failed++;
20225
20392
  }
20226
20393
  const required = [
@@ -20234,89 +20401,89 @@ async function runMcpSelfTest() {
20234
20401
  ];
20235
20402
  for (const name of required) {
20236
20403
  if (tools.includes(name)) {
20237
- console.log(import_chalk34.default.green(` \u2713 tool: ${name}`));
20404
+ console.log(import_chalk35.default.green(` \u2713 tool: ${name}`));
20238
20405
  passed++;
20239
20406
  } else {
20240
- console.log(import_chalk34.default.red(` \u2717 missing tool: ${name}`));
20407
+ console.log(import_chalk35.default.red(` \u2717 missing tool: ${name}`));
20241
20408
  failed++;
20242
20409
  }
20243
20410
  }
20244
20411
  try {
20245
20412
  const welcome = await invokeMcpTool("hyv_welcome", {});
20246
20413
  if (welcome.includes("Hold Your Voice") || welcome.includes("hold your voice")) {
20247
- console.log(import_chalk34.default.green(" \u2713 hyv_welcome responds"));
20414
+ console.log(import_chalk35.default.green(" \u2713 hyv_welcome responds"));
20248
20415
  passed++;
20249
20416
  } else {
20250
- console.log(import_chalk34.default.red(" \u2717 hyv_welcome unexpected output"));
20417
+ console.log(import_chalk35.default.red(" \u2717 hyv_welcome unexpected output"));
20251
20418
  failed++;
20252
20419
  }
20253
20420
  } catch (e) {
20254
- console.log(import_chalk34.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
20421
+ console.log(import_chalk35.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
20255
20422
  failed++;
20256
20423
  }
20257
20424
  try {
20258
20425
  const setup = await invokeMcpTool("hyv_mcp_setup", { action: "status" });
20259
20426
  if (setup.includes("HYV MCP status") && setup.includes("hyv_welcome")) {
20260
- console.log(import_chalk34.default.green(" \u2713 hyv_mcp_setup responds"));
20427
+ console.log(import_chalk35.default.green(" \u2713 hyv_mcp_setup responds"));
20261
20428
  passed++;
20262
20429
  } else {
20263
- console.log(import_chalk34.default.red(" \u2717 hyv_mcp_setup unexpected output"));
20430
+ console.log(import_chalk35.default.red(" \u2717 hyv_mcp_setup unexpected output"));
20264
20431
  failed++;
20265
20432
  }
20266
20433
  } catch (e) {
20267
- console.log(import_chalk34.default.red(` \u2717 hyv_mcp_setup failed: ${e.message}`));
20434
+ console.log(import_chalk35.default.red(` \u2717 hyv_mcp_setup failed: ${e.message}`));
20268
20435
  failed++;
20269
20436
  }
20270
20437
  try {
20271
20438
  const demo = await invokeMcpTool("hyv_demo", {});
20272
20439
  if (demo.includes("Score") || demo.includes("issues")) {
20273
- console.log(import_chalk34.default.green(" \u2713 hyv_demo pipeline works"));
20440
+ console.log(import_chalk35.default.green(" \u2713 hyv_demo pipeline works"));
20274
20441
  passed++;
20275
20442
  } else {
20276
- console.log(import_chalk34.default.red(" \u2717 hyv_demo unexpected output"));
20443
+ console.log(import_chalk35.default.red(" \u2717 hyv_demo unexpected output"));
20277
20444
  failed++;
20278
20445
  }
20279
20446
  } catch (e) {
20280
- console.log(import_chalk34.default.red(` \u2717 hyv_demo failed: ${e.message}`));
20447
+ console.log(import_chalk35.default.red(` \u2717 hyv_demo failed: ${e.message}`));
20281
20448
  failed++;
20282
20449
  }
20283
- const voiceMd = path26.join(HOME2, ".hyv", "voice.md");
20450
+ const voiceMd = path27.join(HOME2, ".hyv", "voice.md");
20284
20451
  if (fs28.existsSync(voiceMd)) {
20285
- console.log(import_chalk34.default.green(" \u2713 voice profile found"));
20452
+ console.log(import_chalk35.default.green(" \u2713 voice profile found"));
20286
20453
  passed++;
20287
20454
  } else {
20288
- console.log(import_chalk34.default.dim(" - no voice.md (free local engine still works)"));
20455
+ console.log(import_chalk35.default.dim(" - no voice.md (free local engine still works)"));
20289
20456
  }
20290
20457
  if (getDemoText().length > 100) {
20291
- console.log(import_chalk34.default.green(" \u2713 demo content available"));
20458
+ console.log(import_chalk35.default.green(" \u2713 demo content available"));
20292
20459
  passed++;
20293
20460
  } else {
20294
- console.log(import_chalk34.default.red(" \u2717 demo content missing"));
20461
+ console.log(import_chalk35.default.red(" \u2717 demo content missing"));
20295
20462
  failed++;
20296
20463
  }
20297
20464
  try {
20298
20465
  const stdio = await testMcpStdioSubprocess();
20299
20466
  if (stdio.ok && (stdio.toolCount || 0) >= 10) {
20300
- console.log(import_chalk34.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
20467
+ console.log(import_chalk35.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
20301
20468
  passed++;
20302
20469
  } else if (stdio.ok) {
20303
- console.log(import_chalk34.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
20470
+ console.log(import_chalk35.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
20304
20471
  failed++;
20305
20472
  } else {
20306
- console.log(import_chalk34.default.red(" \u2717 stdio MCP subprocess failed"));
20473
+ console.log(import_chalk35.default.red(" \u2717 stdio MCP subprocess failed"));
20307
20474
  failed++;
20308
20475
  }
20309
20476
  } catch (e) {
20310
- console.log(import_chalk34.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
20477
+ console.log(import_chalk35.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
20311
20478
  failed++;
20312
20479
  }
20313
20480
  console.log("");
20314
20481
  if (failed === 0) {
20315
- console.log(import_chalk34.default.green(`\u2713 all checks passed (${passed})`));
20316
- console.log(import_chalk34.default.dim("\nStart server: hyv mcp\n"));
20482
+ console.log(import_chalk35.default.green(`\u2713 all checks passed (${passed})`));
20483
+ console.log(import_chalk35.default.dim("\nStart server: hyv mcp\n"));
20317
20484
  return true;
20318
20485
  }
20319
- console.log(import_chalk34.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
20486
+ console.log(import_chalk35.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
20320
20487
  return false;
20321
20488
  }
20322
20489
 
@@ -20446,9 +20613,9 @@ async function exportCommand(format, opts) {
20446
20613
  init_access();
20447
20614
  init_welcome();
20448
20615
  var fs30 = __toESM(require("fs"));
20449
- var path27 = __toESM(require("path"));
20616
+ var path28 = __toESM(require("path"));
20450
20617
  var program2 = new Command();
20451
- var pkgPath2 = path27.resolve(__dirname, "..", "package.json");
20618
+ var pkgPath2 = path28.resolve(__dirname, "..", "package.json");
20452
20619
  var pkgVersion2 = (() => {
20453
20620
  try {
20454
20621
  return JSON.parse(fs30.readFileSync(pkgPath2, "utf-8")).version;
@@ -20484,7 +20651,8 @@ registerOpenCommand(program2);
20484
20651
  registerWelcomeCommand(program2);
20485
20652
  registerContentCommand(program2);
20486
20653
  registerUpgradeCommand(program2);
20487
- program2.command("mcp").description("Detect installed apps, configure MCP, and start the MCP server").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", "Force re-configure MCP even if already integrated").action(async (opts) => {
20654
+ registerShareCommand(program2);
20655
+ program2.command("mcp").description("Detect installed apps, configure MCP, and start the MCP server").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", "Force re-configure MCP even if already integrated").option("--stdio", "Stdio MCP mode \u2014 no stdout banners (auto when stdout is piped)").action(async (opts) => {
20488
20656
  if (opts.setup) {
20489
20657
  printMcpSetup();
20490
20658
  return;
@@ -20497,57 +20665,72 @@ program2.command("mcp").description("Detect installed apps, configure MCP, and s
20497
20665
  if (opts.setupChatgpt) {
20498
20666
  const home = require("os").homedir();
20499
20667
  const guide = require("path").join(home, ".chatgpt", "hyv-mcp-connector.txt");
20500
- console.log(import_chalk35.default.bold("\nhold your voice \u2014 chatgpt desktop setup\n"));
20501
- console.log(import_chalk35.default.bold("=== RECOMMENDED \u2014 PATH A: remote oauth (paid hyv users) ==="));
20502
- console.log(import_chalk35.default.dim(" No local install. OAuth runs in ChatGPT's browser \u2014 no Windows firewall issues.\n"));
20503
- console.log(import_chalk35.default.dim(" Requires: paid HYV plan + ChatGPT Desktop\n"));
20504
- console.log(import_chalk35.default.dim(" 1. In ChatGPT: Settings \u2192 turn ") + import_chalk35.default.cyan("Developer mode") + import_chalk35.default.dim(" ON"));
20505
- console.log(import_chalk35.default.dim(" (Accept the elevated risk warning \u2014 expected, not a HYV bug)"));
20506
- console.log(import_chalk35.default.dim(" 2. Settings \u2192 Apps \u2192 ") + import_chalk35.default.cyan("New App"));
20507
- console.log(import_chalk35.default.dim(" 3. Fill in:"));
20508
- console.log(import_chalk35.default.dim(" Name: ") + import_chalk35.default.cyan("hold your voice"));
20509
- console.log(import_chalk35.default.dim(" Description: ") + import_chalk35.default.cyan("Scans writing for AI patterns and voice drift"));
20510
- 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"));
20511
- console.log(import_chalk35.default.dim(" Authentication: ") + import_chalk35.default.cyan("OAuth"));
20512
- console.log(import_chalk35.default.dim(" Checkbox: ") + import_chalk35.default.cyan('"I understand and want to continue"'));
20513
- console.log(import_chalk35.default.dim(" 4. Save \u2192 complete OAuth sign-in to holdyourvoice.com"));
20514
- console.log(import_chalk35.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20515
- console.log(import_chalk35.default.dim(" Cloud app setup: ") + import_chalk35.default.cyan("https://holdyourvoice.com/app/api/mcp"));
20516
- console.log(import_chalk35.default.dim(" Wiki guide: ") + import_chalk35.default.cyan("https://holdyourvoice.com/wiki/use-hyv-in-chatgpt\n"));
20517
- console.log(import_chalk35.default.bold("=== FALLBACK \u2014 PATH B: local connector (free users only) ==="));
20518
- console.log(import_chalk35.default.dim(" Only if you do not have a paid HYV plan. Requires Node.js 18+.\n"));
20519
- console.log(import_chalk35.default.dim(" 1. Install hyv: ") + import_chalk35.default.cyan("npm i -g @holdyourvoice/hyv@latest && hyv welcome"));
20520
- 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)"));
20521
- console.log(import_chalk35.default.dim(" 3. Add connector:"));
20522
- console.log(import_chalk35.default.dim(" Name: ") + import_chalk35.default.cyan("hold your voice"));
20523
- console.log(import_chalk35.default.dim(" Command: ") + import_chalk35.default.cyan("hyv") + import_chalk35.default.dim(" (full path on Windows if needed)"));
20524
- console.log(import_chalk35.default.dim(" Arguments: ") + import_chalk35.default.cyan("mcp"));
20525
- console.log(import_chalk35.default.dim(" 4. Save, restart ChatGPT Desktop"));
20526
- console.log(import_chalk35.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20527
- console.log(import_chalk35.default.dim(" If connector fails to start, use full paths from:"));
20528
- console.log(import_chalk35.default.cyan(" " + guide));
20529
- console.log(import_chalk35.default.dim(""));
20530
- console.log(import_chalk35.default.dim('Windows tip: If you get "running scripts is disabled", use:'));
20531
- console.log(import_chalk35.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv mcp --setup-chatgpt"'));
20532
- console.log(import_chalk35.default.dim(" Fix once: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20533
- console.log(import_chalk35.default.dim(" In ChatGPT connector use the FULL path from the connector .txt file\n"));
20534
- console.log(import_chalk35.default.bold('=== not seeing "New App"? ==='));
20535
- console.log(import_chalk35.default.dim(" \u2022 Turn Developer mode ON in ChatGPT settings \u2014 Path A needs it"));
20536
- console.log(import_chalk35.default.dim(" \u2022 If you only see Connectors, you are on Path B (free fallback)"));
20537
- console.log(import_chalk35.default.dim(" \u2022 Browser ChatGPT cannot use MCP \u2014 desktop app only\n"));
20668
+ console.log(import_chalk36.default.bold("\nhold your voice \u2014 chatgpt desktop setup\n"));
20669
+ console.log(import_chalk36.default.bold("=== RECOMMENDED \u2014 PATH A: remote oauth (paid hyv users) ==="));
20670
+ console.log(import_chalk36.default.dim(" No local install. OAuth runs in ChatGPT's browser \u2014 no Windows firewall issues.\n"));
20671
+ console.log(import_chalk36.default.dim(" Requires: paid HYV plan + ChatGPT Desktop\n"));
20672
+ console.log(import_chalk36.default.dim(" 1. In ChatGPT: Settings \u2192 turn ") + import_chalk36.default.cyan("Developer mode") + import_chalk36.default.dim(" ON"));
20673
+ console.log(import_chalk36.default.dim(" (Accept the elevated risk warning \u2014 expected, not a HYV bug)"));
20674
+ console.log(import_chalk36.default.dim(" 2. Settings \u2192 Apps \u2192 ") + import_chalk36.default.cyan("New App"));
20675
+ console.log(import_chalk36.default.dim(" 3. Fill in:"));
20676
+ console.log(import_chalk36.default.dim(" Name: ") + import_chalk36.default.cyan("hold your voice"));
20677
+ console.log(import_chalk36.default.dim(" Description: ") + import_chalk36.default.cyan("Scans writing for AI patterns and voice drift"));
20678
+ console.log(import_chalk36.default.dim(" Connection: ") + import_chalk36.default.cyan("Server URL") + import_chalk36.default.dim(" \u2192 ") + import_chalk36.default.cyan("https://holdyourvoice.com/mcp"));
20679
+ console.log(import_chalk36.default.dim(" Authentication: ") + import_chalk36.default.cyan("OAuth"));
20680
+ console.log(import_chalk36.default.dim(" Checkbox: ") + import_chalk36.default.cyan('"I understand and want to continue"'));
20681
+ console.log(import_chalk36.default.dim(" 4. Save \u2192 complete OAuth sign-in to holdyourvoice.com"));
20682
+ console.log(import_chalk36.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20683
+ console.log(import_chalk36.default.dim(" Cloud app setup: ") + import_chalk36.default.cyan("https://holdyourvoice.com/app/api/mcp"));
20684
+ console.log(import_chalk36.default.dim(" Wiki guide: ") + import_chalk36.default.cyan("https://holdyourvoice.com/wiki/use-hyv-in-chatgpt\n"));
20685
+ console.log(import_chalk36.default.bold("=== FALLBACK \u2014 PATH B: local connector (free users only) ==="));
20686
+ console.log(import_chalk36.default.dim(" Only if you do not have a paid HYV plan. Requires Node.js 18+.\n"));
20687
+ console.log(import_chalk36.default.dim(" 1. Install hyv: ") + import_chalk36.default.cyan("npm i -g @holdyourvoice/hyv@latest && hyv welcome"));
20688
+ console.log(import_chalk36.default.dim(" 2. In ChatGPT: ") + import_chalk36.default.cyan("Settings \u2192 Connectors") + import_chalk36.default.dim(" (or https://chatgpt.com/#settings/Connectors)"));
20689
+ console.log(import_chalk36.default.dim(" 3. Add connector:"));
20690
+ console.log(import_chalk36.default.dim(" Name: ") + import_chalk36.default.cyan("hold your voice"));
20691
+ console.log(import_chalk36.default.dim(" Command: ") + import_chalk36.default.cyan("hyv") + import_chalk36.default.dim(" (full path on Windows if needed)"));
20692
+ console.log(import_chalk36.default.dim(" Arguments: ") + import_chalk36.default.cyan("mcp --stdio"));
20693
+ console.log(import_chalk36.default.dim(" 4. Save, restart ChatGPT Desktop"));
20694
+ console.log(import_chalk36.default.dim(' 5. Test: "scan this with hold your voice"\n'));
20695
+ console.log(import_chalk36.default.dim(" If connector fails to start, use full paths from:"));
20696
+ console.log(import_chalk36.default.cyan(" " + guide));
20697
+ console.log(import_chalk36.default.dim(""));
20698
+ console.log(import_chalk36.default.dim('Windows tip: If you get "running scripts is disabled", use:'));
20699
+ console.log(import_chalk36.default.cyan(' powershell -ExecutionPolicy Bypass -Command "hyv mcp --setup-chatgpt"'));
20700
+ console.log(import_chalk36.default.dim(" Fix once: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"));
20701
+ console.log(import_chalk36.default.dim(" In ChatGPT connector use the FULL path from the connector .txt file\n"));
20702
+ console.log(import_chalk36.default.bold('=== not seeing "New App"? ==='));
20703
+ console.log(import_chalk36.default.dim(" \u2022 Turn Developer mode ON in ChatGPT settings \u2014 Path A needs it"));
20704
+ console.log(import_chalk36.default.dim(" \u2022 If you only see Connectors, you are on Path B (free fallback)"));
20705
+ console.log(import_chalk36.default.dim(" \u2022 Browser ChatGPT cannot use MCP \u2014 desktop app only\n"));
20538
20706
  if (require("fs").existsSync(guide)) {
20539
- console.log(import_chalk35.default.dim(` Full connector paths written to: ${guide}`));
20707
+ console.log(import_chalk36.default.dim(` Full connector paths written to: ${guide}`));
20540
20708
  } else {
20541
- console.log(import_chalk35.default.dim(" Run hyv doctor --fix-agents to write " + guide));
20709
+ console.log(import_chalk36.default.dim(" Run hyv doctor --fix-agents to write " + guide));
20542
20710
  }
20543
20711
  console.log("");
20544
20712
  return;
20545
20713
  }
20546
- console.log(import_chalk35.default.bold("\nhold your voice \u2014 detecting and configuring mcp...\n"));
20714
+ if (isMcpStdioMode(opts)) {
20715
+ await startMcpServer();
20716
+ return;
20717
+ }
20718
+ const err = (msg) => process.stderr.write(msg + "\n");
20719
+ err(import_chalk36.default.bold("\nhold your voice \u2014 detecting and configuring mcp...\n"));
20547
20720
  const result = runMcpAutoIntegrate({ force: Boolean(opts.force) });
20721
+ const reportLines = [];
20722
+ const origLog = console.log;
20723
+ console.log = (...args2) => {
20724
+ reportLines.push(args2.map(String).join(" "));
20725
+ };
20548
20726
  printMcpIntegrateReport(result, { force: Boolean(opts.force) });
20549
- console.log(import_chalk35.default.dim("\nstarting MCP server (press Ctrl+C to stop)...\n"));
20550
- startMcpServer();
20727
+ console.log = origLog;
20728
+ for (const line of reportLines)
20729
+ err(line);
20730
+ err(import_chalk36.default.green.bold("\n\u2713 hold your voice \u2014 mcp setup complete\n"));
20731
+ err(import_chalk36.default.dim(" restart cursor / claude desktop if they were open during setup"));
20732
+ err(import_chalk36.default.dim("\nstarting MCP server (press Ctrl+C to stop) \u2014 JSON-RPC on stdout...\n"));
20733
+ await startMcpServer();
20551
20734
  });
20552
20735
  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) => {
20553
20736
  await exportCommand(format, opts);