@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/CHANGELOG.md +7 -0
- package/dist/index.js +425 -242
- package/package.json +3 -2
- package/scripts/postinstall-lib.js +2 -2
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
|
|
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 =
|
|
1919
|
+
const localBin = path29.resolve(baseDir, baseName);
|
|
1920
1920
|
if (fs31.existsSync(localBin))
|
|
1921
1921
|
return localBin;
|
|
1922
|
-
if (sourceExt.includes(
|
|
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 =
|
|
1943
|
-
|
|
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 =
|
|
1950
|
+
const legacyName = path29.basename(
|
|
1951
1951
|
this._scriptPath,
|
|
1952
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
2835
|
-
if (
|
|
2834
|
+
executableDir(path30) {
|
|
2835
|
+
if (path30 === void 0)
|
|
2836
2836
|
return this._executableDir;
|
|
2837
|
-
this._executableDir =
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 = (
|
|
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(
|
|
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(
|
|
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
|
|
4468
|
-
applyOptions(
|
|
4469
|
-
|
|
4470
|
-
Object.setPrototypeOf(
|
|
4471
|
-
Object.setPrototypeOf(
|
|
4472
|
-
|
|
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
|
-
|
|
4476
|
-
return
|
|
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 = (
|
|
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(
|
|
4603
|
+
return template(chalk38, parts.join(""));
|
|
4604
4604
|
};
|
|
4605
4605
|
Object.defineProperties(Chalk.prototype, styles);
|
|
4606
|
-
var
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
module2.exports =
|
|
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
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
5525
|
+
resolve18(null);
|
|
5525
5526
|
else
|
|
5526
|
-
|
|
5527
|
+
resolve18(stdout.trim());
|
|
5527
5528
|
}
|
|
5528
5529
|
);
|
|
5529
5530
|
});
|
|
@@ -5588,7 +5589,7 @@ function escapeHtml(value) {
|
|
|
5588
5589
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5589
5590
|
}
|
|
5590
5591
|
function request(url, options = {}) {
|
|
5591
|
-
return new Promise((
|
|
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
|
-
|
|
5613
|
+
resolve18({ status: res.statusCode || 0, data: JSON.parse(data) });
|
|
5613
5614
|
} catch {
|
|
5614
|
-
|
|
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((
|
|
5673
|
+
const port = await new Promise((resolve18) => {
|
|
5673
5674
|
server.listen(0, "127.0.0.1", () => {
|
|
5674
|
-
|
|
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((
|
|
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
|
-
|
|
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,
|
|
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}${
|
|
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(
|
|
5944
|
-
return request2("GET",
|
|
5944
|
+
function apiGet(path29) {
|
|
5945
|
+
return request2("GET", path29);
|
|
5945
5946
|
}
|
|
5946
|
-
function apiPost(
|
|
5947
|
-
return request2("POST",
|
|
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
|
|
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 =
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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((
|
|
11966
|
+
return new Promise((resolve18) => {
|
|
11953
11967
|
rl.question(prompt, (answer) => {
|
|
11954
11968
|
rl.close();
|
|
11955
|
-
|
|
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((
|
|
11978
|
+
return new Promise((resolve18) => {
|
|
11965
11979
|
rl.on("line", (line) => {
|
|
11966
11980
|
if (line.trim() === "---") {
|
|
11967
11981
|
rl.close();
|
|
11968
|
-
|
|
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
|
|
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((
|
|
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
|
-
|
|
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,
|
|
17793
|
+
return { command: process.execPath, args: [entry, ...MCP_SERVER_ARGS] };
|
|
17767
17794
|
}
|
|
17768
|
-
return { command: "hyv", args: [
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
|
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: ${
|
|
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
|
|
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
|
|
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
|
|
19371
|
+
var import_chalk34 = __toESM(require_source());
|
|
19205
19372
|
var fs26 = __toESM(require("fs"));
|
|
19206
19373
|
var os12 = __toESM(require("os"));
|
|
19207
|
-
var
|
|
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
|
-
|
|
19215
|
-
|
|
19381
|
+
path25.resolve(__dirname, ".."),
|
|
19382
|
+
path25.resolve(__dirname, "..", "..")
|
|
19216
19383
|
];
|
|
19217
19384
|
for (const root of candidates) {
|
|
19218
|
-
if (fs26.existsSync(
|
|
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(
|
|
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 =
|
|
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(
|
|
19404
|
-
console.log(
|
|
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(
|
|
19576
|
+
console.log(import_chalk34.default.dim(` voice profiles: ${profiles.join(", ")}`));
|
|
19410
19577
|
} else {
|
|
19411
|
-
console.log(
|
|
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(
|
|
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(
|
|
19419
|
-
console.log(
|
|
19420
|
-
console.log(
|
|
19421
|
-
console.log(
|
|
19422
|
-
console.log(
|
|
19423
|
-
console.log(
|
|
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(
|
|
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" ?
|
|
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(
|
|
19600
|
+
console.log(import_chalk34.default.dim(` ${app.reason} \xB7 ${app.integration}`));
|
|
19434
19601
|
}
|
|
19435
19602
|
if (result.configured.length > 0) {
|
|
19436
|
-
console.log(
|
|
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(
|
|
19607
|
+
console.log(import_chalk34.default.yellow("\n notes:"));
|
|
19441
19608
|
for (const warning of result.warnings) {
|
|
19442
|
-
console.log(
|
|
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(
|
|
19448
|
-
console.log(
|
|
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(
|
|
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(
|
|
19454
|
-
console.log(
|
|
19455
|
-
console.log(
|
|
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(
|
|
19458
|
-
console.log(
|
|
19459
|
-
console.log(
|
|
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 =
|
|
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(
|
|
19471
|
-
if (!resolved.startsWith(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 =
|
|
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(
|
|
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
|
|
20314
|
+
var import_chalk35 = __toESM(require_source());
|
|
20148
20315
|
var fs28 = __toESM(require("fs"));
|
|
20149
|
-
var
|
|
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
|
|
20323
|
+
return path27.join(HOME2, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
|
|
20157
20324
|
if (process.platform === "linux")
|
|
20158
|
-
return
|
|
20159
|
-
return
|
|
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(
|
|
20163
|
-
console.log(
|
|
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(
|
|
20166
|
-
console.log(
|
|
20167
|
-
console.log(
|
|
20168
|
-
console.log(
|
|
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(
|
|
20171
|
-
console.log(
|
|
20172
|
-
console.log(
|
|
20173
|
-
console.log(
|
|
20174
|
-
console.log(
|
|
20175
|
-
console.log(
|
|
20176
|
-
console.log(
|
|
20177
|
-
console.log(
|
|
20178
|
-
console.log(
|
|
20179
|
-
console.log(
|
|
20180
|
-
console.log(
|
|
20181
|
-
console.log(
|
|
20182
|
-
console.log(
|
|
20183
|
-
console.log(
|
|
20184
|
-
console.log(
|
|
20185
|
-
console.log(
|
|
20186
|
-
console.log(
|
|
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(
|
|
20189
|
-
console.log(
|
|
20190
|
-
console.log(
|
|
20191
|
-
console.log(
|
|
20192
|
-
console.log(
|
|
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(
|
|
20196
|
-
console.log(
|
|
20197
|
-
console.log(
|
|
20198
|
-
console.log(
|
|
20199
|
-
console.log(
|
|
20200
|
-
console.log(
|
|
20201
|
-
console.log(
|
|
20202
|
-
console.log(
|
|
20203
|
-
console.log(
|
|
20204
|
-
console.log(
|
|
20205
|
-
console.log(
|
|
20206
|
-
console.log(
|
|
20207
|
-
console.log(
|
|
20208
|
-
console.log(
|
|
20209
|
-
console.log(
|
|
20210
|
-
console.log(
|
|
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(
|
|
20214
|
-
console.log(
|
|
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(
|
|
20387
|
+
console.log(import_chalk35.default.green(` \u2713 ${tools.length} MCP tools registered`));
|
|
20221
20388
|
passed++;
|
|
20222
20389
|
} else {
|
|
20223
|
-
console.log(
|
|
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(
|
|
20404
|
+
console.log(import_chalk35.default.green(` \u2713 tool: ${name}`));
|
|
20238
20405
|
passed++;
|
|
20239
20406
|
} else {
|
|
20240
|
-
console.log(
|
|
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(
|
|
20414
|
+
console.log(import_chalk35.default.green(" \u2713 hyv_welcome responds"));
|
|
20248
20415
|
passed++;
|
|
20249
20416
|
} else {
|
|
20250
|
-
console.log(
|
|
20417
|
+
console.log(import_chalk35.default.red(" \u2717 hyv_welcome unexpected output"));
|
|
20251
20418
|
failed++;
|
|
20252
20419
|
}
|
|
20253
20420
|
} catch (e) {
|
|
20254
|
-
console.log(
|
|
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(
|
|
20427
|
+
console.log(import_chalk35.default.green(" \u2713 hyv_mcp_setup responds"));
|
|
20261
20428
|
passed++;
|
|
20262
20429
|
} else {
|
|
20263
|
-
console.log(
|
|
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(
|
|
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(
|
|
20440
|
+
console.log(import_chalk35.default.green(" \u2713 hyv_demo pipeline works"));
|
|
20274
20441
|
passed++;
|
|
20275
20442
|
} else {
|
|
20276
|
-
console.log(
|
|
20443
|
+
console.log(import_chalk35.default.red(" \u2717 hyv_demo unexpected output"));
|
|
20277
20444
|
failed++;
|
|
20278
20445
|
}
|
|
20279
20446
|
} catch (e) {
|
|
20280
|
-
console.log(
|
|
20447
|
+
console.log(import_chalk35.default.red(` \u2717 hyv_demo failed: ${e.message}`));
|
|
20281
20448
|
failed++;
|
|
20282
20449
|
}
|
|
20283
|
-
const voiceMd =
|
|
20450
|
+
const voiceMd = path27.join(HOME2, ".hyv", "voice.md");
|
|
20284
20451
|
if (fs28.existsSync(voiceMd)) {
|
|
20285
|
-
console.log(
|
|
20452
|
+
console.log(import_chalk35.default.green(" \u2713 voice profile found"));
|
|
20286
20453
|
passed++;
|
|
20287
20454
|
} else {
|
|
20288
|
-
console.log(
|
|
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(
|
|
20458
|
+
console.log(import_chalk35.default.green(" \u2713 demo content available"));
|
|
20292
20459
|
passed++;
|
|
20293
20460
|
} else {
|
|
20294
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
20473
|
+
console.log(import_chalk35.default.red(" \u2717 stdio MCP subprocess failed"));
|
|
20307
20474
|
failed++;
|
|
20308
20475
|
}
|
|
20309
20476
|
} catch (e) {
|
|
20310
|
-
console.log(
|
|
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(
|
|
20316
|
-
console.log(
|
|
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(
|
|
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
|
|
20616
|
+
var path28 = __toESM(require("path"));
|
|
20450
20617
|
var program2 = new Command();
|
|
20451
|
-
var pkgPath2 =
|
|
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
|
|
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(
|
|
20501
|
-
console.log(
|
|
20502
|
-
console.log(
|
|
20503
|
-
console.log(
|
|
20504
|
-
console.log(
|
|
20505
|
-
console.log(
|
|
20506
|
-
console.log(
|
|
20507
|
-
console.log(
|
|
20508
|
-
console.log(
|
|
20509
|
-
console.log(
|
|
20510
|
-
console.log(
|
|
20511
|
-
console.log(
|
|
20512
|
-
console.log(
|
|
20513
|
-
console.log(
|
|
20514
|
-
console.log(
|
|
20515
|
-
console.log(
|
|
20516
|
-
console.log(
|
|
20517
|
-
console.log(
|
|
20518
|
-
console.log(
|
|
20519
|
-
console.log(
|
|
20520
|
-
console.log(
|
|
20521
|
-
console.log(
|
|
20522
|
-
console.log(
|
|
20523
|
-
console.log(
|
|
20524
|
-
console.log(
|
|
20525
|
-
console.log(
|
|
20526
|
-
console.log(
|
|
20527
|
-
console.log(
|
|
20528
|
-
console.log(
|
|
20529
|
-
console.log(
|
|
20530
|
-
console.log(
|
|
20531
|
-
console.log(
|
|
20532
|
-
console.log(
|
|
20533
|
-
console.log(
|
|
20534
|
-
console.log(
|
|
20535
|
-
console.log(
|
|
20536
|
-
console.log(
|
|
20537
|
-
console.log(
|
|
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(
|
|
20707
|
+
console.log(import_chalk36.default.dim(` Full connector paths written to: ${guide}`));
|
|
20540
20708
|
} else {
|
|
20541
|
-
console.log(
|
|
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
|
-
|
|
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
|
|
20550
|
-
|
|
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);
|