@holdyourvoice/hyv 2.9.14 → 2.9.15
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 +11 -0
- package/agents/chatgpt.md +12 -1
- package/agents/cursor.md +3 -1
- package/agents/generic.md +10 -1
- package/dist/index.js +890 -411
- package/package.json +1 -1
- package/scripts/postinstall-lib.js +333 -25
package/dist/index.js
CHANGED
|
@@ -973,8 +973,8 @@ 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
|
|
977
|
-
var
|
|
976
|
+
var path28 = require("node:path");
|
|
977
|
+
var fs31 = require("node:fs");
|
|
978
978
|
var process2 = require("node:process");
|
|
979
979
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
980
980
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1916,13 +1916,13 @@ 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 =
|
|
1920
|
-
if (
|
|
1919
|
+
const localBin = path28.resolve(baseDir, baseName);
|
|
1920
|
+
if (fs31.existsSync(localBin))
|
|
1921
1921
|
return localBin;
|
|
1922
|
-
if (sourceExt.includes(
|
|
1922
|
+
if (sourceExt.includes(path28.extname(baseName)))
|
|
1923
1923
|
return void 0;
|
|
1924
1924
|
const foundExt = sourceExt.find(
|
|
1925
|
-
(ext) =>
|
|
1925
|
+
(ext) => fs31.existsSync(`${localBin}${ext}`)
|
|
1926
1926
|
);
|
|
1927
1927
|
if (foundExt)
|
|
1928
1928
|
return `${localBin}${foundExt}`;
|
|
@@ -1935,21 +1935,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1935
1935
|
if (this._scriptPath) {
|
|
1936
1936
|
let resolvedScriptPath;
|
|
1937
1937
|
try {
|
|
1938
|
-
resolvedScriptPath =
|
|
1938
|
+
resolvedScriptPath = fs31.realpathSync(this._scriptPath);
|
|
1939
1939
|
} catch (err) {
|
|
1940
1940
|
resolvedScriptPath = this._scriptPath;
|
|
1941
1941
|
}
|
|
1942
|
-
executableDir =
|
|
1943
|
-
|
|
1942
|
+
executableDir = path28.resolve(
|
|
1943
|
+
path28.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 = path28.basename(
|
|
1951
1951
|
this._scriptPath,
|
|
1952
|
-
|
|
1952
|
+
path28.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(path28.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 = path28.basename(filename, path28.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(path29) {
|
|
2835
|
+
if (path29 === void 0)
|
|
2836
2836
|
return this._executableDir;
|
|
2837
|
-
this._executableDir =
|
|
2837
|
+
this._executableDir = path29;
|
|
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 path28 = [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
|
+
path28.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 = path28;
|
|
3946
3946
|
return fn;
|
|
3947
3947
|
}
|
|
3948
3948
|
module2.exports = function(fromModel) {
|
|
@@ -4182,7 +4182,7 @@ var require_has_flag = __commonJS({
|
|
|
4182
4182
|
var require_supports_color = __commonJS({
|
|
4183
4183
|
"node_modules/supports-color/index.js"(exports2, module2) {
|
|
4184
4184
|
"use strict";
|
|
4185
|
-
var
|
|
4185
|
+
var os15 = require("os");
|
|
4186
4186
|
var tty = require("tty");
|
|
4187
4187
|
var hasFlag = require_has_flag();
|
|
4188
4188
|
var { env } = process;
|
|
@@ -4230,7 +4230,7 @@ var require_supports_color = __commonJS({
|
|
|
4230
4230
|
return min;
|
|
4231
4231
|
}
|
|
4232
4232
|
if (process.platform === "win32") {
|
|
4233
|
-
const osRelease =
|
|
4233
|
+
const osRelease = os15.release().split(".");
|
|
4234
4234
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
4235
4235
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
4236
4236
|
}
|
|
@@ -4381,14 +4381,14 @@ var require_templates = __commonJS({
|
|
|
4381
4381
|
}
|
|
4382
4382
|
return results;
|
|
4383
4383
|
}
|
|
4384
|
-
function buildStyle(
|
|
4384
|
+
function buildStyle(chalk35, 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 = chalk35;
|
|
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 = (chalk35, 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(chalk35, 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(chalk35, 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 chalk36 = {};
|
|
4468
|
+
applyOptions(chalk36, options);
|
|
4469
|
+
chalk36.template = (...arguments_) => chalkTag(chalk36.template, ...arguments_);
|
|
4470
|
+
Object.setPrototypeOf(chalk36, Chalk.prototype);
|
|
4471
|
+
Object.setPrototypeOf(chalk36.template, chalk36);
|
|
4472
|
+
chalk36.template.constructor = () => {
|
|
4473
4473
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
4474
4474
|
};
|
|
4475
|
-
|
|
4476
|
-
return
|
|
4475
|
+
chalk36.template.Instance = ChalkClass;
|
|
4476
|
+
return chalk36.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 = (chalk36, ...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(chalk36, parts.join(""));
|
|
4604
4604
|
};
|
|
4605
4605
|
Object.defineProperties(Chalk.prototype, styles);
|
|
4606
|
-
var
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
module2.exports =
|
|
4606
|
+
var chalk35 = Chalk();
|
|
4607
|
+
chalk35.supportsColor = stdoutColor;
|
|
4608
|
+
chalk35.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
4609
|
+
chalk35.stderr.supportsColor = stderrColor;
|
|
4610
|
+
module2.exports = chalk35;
|
|
4611
4611
|
}
|
|
4612
4612
|
});
|
|
4613
4613
|
|
|
@@ -4990,11 +4990,11 @@ var init_config = __esm({
|
|
|
4990
4990
|
var require_is_docker = __commonJS({
|
|
4991
4991
|
"node_modules/is-docker/index.js"(exports2, module2) {
|
|
4992
4992
|
"use strict";
|
|
4993
|
-
var
|
|
4993
|
+
var fs31 = require("fs");
|
|
4994
4994
|
var isDocker;
|
|
4995
4995
|
function hasDockerEnv() {
|
|
4996
4996
|
try {
|
|
4997
|
-
|
|
4997
|
+
fs31.statSync("/.dockerenv");
|
|
4998
4998
|
return true;
|
|
4999
4999
|
} catch (_2) {
|
|
5000
5000
|
return false;
|
|
@@ -5002,7 +5002,7 @@ var require_is_docker = __commonJS({
|
|
|
5002
5002
|
}
|
|
5003
5003
|
function hasDockerCGroup() {
|
|
5004
5004
|
try {
|
|
5005
|
-
return
|
|
5005
|
+
return fs31.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
5006
5006
|
} catch (_2) {
|
|
5007
5007
|
return false;
|
|
5008
5008
|
}
|
|
@@ -5020,21 +5020,21 @@ var require_is_docker = __commonJS({
|
|
|
5020
5020
|
var require_is_wsl = __commonJS({
|
|
5021
5021
|
"node_modules/is-wsl/index.js"(exports2, module2) {
|
|
5022
5022
|
"use strict";
|
|
5023
|
-
var
|
|
5024
|
-
var
|
|
5023
|
+
var os15 = require("os");
|
|
5024
|
+
var fs31 = require("fs");
|
|
5025
5025
|
var isDocker = require_is_docker();
|
|
5026
5026
|
var isWsl = () => {
|
|
5027
5027
|
if (process.platform !== "linux") {
|
|
5028
5028
|
return false;
|
|
5029
5029
|
}
|
|
5030
|
-
if (
|
|
5030
|
+
if (os15.release().toLowerCase().includes("microsoft")) {
|
|
5031
5031
|
if (isDocker()) {
|
|
5032
5032
|
return false;
|
|
5033
5033
|
}
|
|
5034
5034
|
return true;
|
|
5035
5035
|
}
|
|
5036
5036
|
try {
|
|
5037
|
-
return
|
|
5037
|
+
return fs31.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
|
|
5038
5038
|
} catch (_2) {
|
|
5039
5039
|
return false;
|
|
5040
5040
|
}
|
|
@@ -5073,17 +5073,17 @@ var require_define_lazy_prop = __commonJS({
|
|
|
5073
5073
|
// node_modules/open/index.js
|
|
5074
5074
|
var require_open = __commonJS({
|
|
5075
5075
|
"node_modules/open/index.js"(exports2, module2) {
|
|
5076
|
-
var
|
|
5076
|
+
var path28 = require("path");
|
|
5077
5077
|
var childProcess = require("child_process");
|
|
5078
|
-
var { promises:
|
|
5078
|
+
var { promises: fs31, constants: fsConstants } = require("fs");
|
|
5079
5079
|
var isWsl = require_is_wsl();
|
|
5080
5080
|
var isDocker = require_is_docker();
|
|
5081
5081
|
var defineLazyProperty = require_define_lazy_prop();
|
|
5082
|
-
var localXdgOpenPath =
|
|
5082
|
+
var localXdgOpenPath = path28.join(__dirname, "xdg-open");
|
|
5083
5083
|
var { platform, arch } = process;
|
|
5084
5084
|
var hasContainerEnv = () => {
|
|
5085
5085
|
try {
|
|
5086
|
-
|
|
5086
|
+
fs31.statSync("/run/.containerenv");
|
|
5087
5087
|
return true;
|
|
5088
5088
|
} catch {
|
|
5089
5089
|
return false;
|
|
@@ -5106,14 +5106,14 @@ var require_open = __commonJS({
|
|
|
5106
5106
|
const configFilePath = "/etc/wsl.conf";
|
|
5107
5107
|
let isConfigFileExists = false;
|
|
5108
5108
|
try {
|
|
5109
|
-
await
|
|
5109
|
+
await fs31.access(configFilePath, fsConstants.F_OK);
|
|
5110
5110
|
isConfigFileExists = true;
|
|
5111
5111
|
} catch {
|
|
5112
5112
|
}
|
|
5113
5113
|
if (!isConfigFileExists) {
|
|
5114
5114
|
return defaultMountPoint;
|
|
5115
5115
|
}
|
|
5116
|
-
const configContent = await
|
|
5116
|
+
const configContent = await fs31.readFile(configFilePath, { encoding: "utf8" });
|
|
5117
5117
|
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
5118
5118
|
if (!configMountPoint) {
|
|
5119
5119
|
return defaultMountPoint;
|
|
@@ -5213,7 +5213,7 @@ var require_open = __commonJS({
|
|
|
5213
5213
|
const isBundled = !__dirname || __dirname === "/";
|
|
5214
5214
|
let exeLocalXdgOpen = false;
|
|
5215
5215
|
try {
|
|
5216
|
-
await
|
|
5216
|
+
await fs31.access(localXdgOpenPath, fsConstants.X_OK);
|
|
5217
5217
|
exeLocalXdgOpen = true;
|
|
5218
5218
|
} catch {
|
|
5219
5219
|
}
|
|
@@ -5236,14 +5236,14 @@ var require_open = __commonJS({
|
|
|
5236
5236
|
}
|
|
5237
5237
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
5238
5238
|
if (options.wait) {
|
|
5239
|
-
return new Promise((
|
|
5239
|
+
return new Promise((resolve16, reject) => {
|
|
5240
5240
|
subprocess.once("error", reject);
|
|
5241
5241
|
subprocess.once("close", (exitCode) => {
|
|
5242
5242
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
5243
5243
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
5244
5244
|
return;
|
|
5245
5245
|
}
|
|
5246
|
-
|
|
5246
|
+
resolve16(subprocess);
|
|
5247
5247
|
});
|
|
5248
5248
|
});
|
|
5249
5249
|
}
|
|
@@ -5459,16 +5459,16 @@ function compareSemver(a, b) {
|
|
|
5459
5459
|
return 0;
|
|
5460
5460
|
}
|
|
5461
5461
|
function fetchLatestNpmVersion(timeoutMs = 8e3) {
|
|
5462
|
-
return new Promise((
|
|
5462
|
+
return new Promise((resolve16) => {
|
|
5463
5463
|
(0, import_child_process.execFile)(
|
|
5464
5464
|
"npm",
|
|
5465
5465
|
["view", "@holdyourvoice/hyv", "version"],
|
|
5466
5466
|
{ timeout: timeoutMs, encoding: "utf-8" },
|
|
5467
5467
|
(err, stdout) => {
|
|
5468
5468
|
if (err || !stdout?.trim())
|
|
5469
|
-
|
|
5469
|
+
resolve16(null);
|
|
5470
5470
|
else
|
|
5471
|
-
|
|
5471
|
+
resolve16(stdout.trim());
|
|
5472
5472
|
}
|
|
5473
5473
|
);
|
|
5474
5474
|
});
|
|
@@ -5533,7 +5533,7 @@ function escapeHtml(value) {
|
|
|
5533
5533
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5534
5534
|
}
|
|
5535
5535
|
function request(url, options = {}) {
|
|
5536
|
-
return new Promise((
|
|
5536
|
+
return new Promise((resolve16, reject) => {
|
|
5537
5537
|
const urlObj = new URL(url);
|
|
5538
5538
|
const isHttps = urlObj.protocol === "https:";
|
|
5539
5539
|
const client = isHttps ? https : http;
|
|
@@ -5554,9 +5554,9 @@ function request(url, options = {}) {
|
|
|
5554
5554
|
res.on("data", (chunk) => data += chunk);
|
|
5555
5555
|
res.on("end", () => {
|
|
5556
5556
|
try {
|
|
5557
|
-
|
|
5557
|
+
resolve16({ status: res.statusCode || 0, data: JSON.parse(data) });
|
|
5558
5558
|
} catch {
|
|
5559
|
-
|
|
5559
|
+
resolve16({ status: res.statusCode || 0, data });
|
|
5560
5560
|
}
|
|
5561
5561
|
});
|
|
5562
5562
|
});
|
|
@@ -5614,9 +5614,9 @@ async function authenticateWithLicense(licenseKey) {
|
|
|
5614
5614
|
}
|
|
5615
5615
|
async function authenticateWithBrowser() {
|
|
5616
5616
|
const server = http.createServer();
|
|
5617
|
-
const port = await new Promise((
|
|
5617
|
+
const port = await new Promise((resolve16) => {
|
|
5618
5618
|
server.listen(0, "127.0.0.1", () => {
|
|
5619
|
-
|
|
5619
|
+
resolve16(server.address().port);
|
|
5620
5620
|
});
|
|
5621
5621
|
});
|
|
5622
5622
|
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
@@ -5635,7 +5635,7 @@ async function authenticateWithBrowser() {
|
|
|
5635
5635
|
}
|
|
5636
5636
|
console.log(import_chalk2.default.cyan("\nOpening browser for authentication..."));
|
|
5637
5637
|
await (0, import_open.default)(assertSafeOAuthUrl(auth_url));
|
|
5638
|
-
const authData = await new Promise((
|
|
5638
|
+
const authData = await new Promise((resolve16, reject) => {
|
|
5639
5639
|
const timeout = setTimeout(() => {
|
|
5640
5640
|
server.close();
|
|
5641
5641
|
reject(new Error("Authentication timeout. Please try again."));
|
|
@@ -5692,7 +5692,7 @@ async function authenticateWithBrowser() {
|
|
|
5692
5692
|
`);
|
|
5693
5693
|
clearTimeout(timeout);
|
|
5694
5694
|
server.close();
|
|
5695
|
-
|
|
5695
|
+
resolve16(data);
|
|
5696
5696
|
} catch (error) {
|
|
5697
5697
|
res.writeHead(500, { "Content-Type": "text/html" });
|
|
5698
5698
|
res.end(`<h1>Authentication failed</h1><p>${escapeHtml(error.message)}</p>`);
|
|
@@ -5854,17 +5854,11 @@ var init_telemetry = __esm({
|
|
|
5854
5854
|
});
|
|
5855
5855
|
|
|
5856
5856
|
// src/lib/api.ts
|
|
5857
|
-
|
|
5858
|
-
__export(api_exports, {
|
|
5859
|
-
apiGet: () => apiGet,
|
|
5860
|
-
apiPost: () => apiPost,
|
|
5861
|
-
requireSubscription: () => requireSubscription
|
|
5862
|
-
});
|
|
5863
|
-
async function request2(method, path27, body) {
|
|
5857
|
+
async function request2(method, path28, body) {
|
|
5864
5858
|
const token = await getValidToken();
|
|
5865
5859
|
if (!token)
|
|
5866
5860
|
throw new Error("you're not signed in yet. run: hyv init");
|
|
5867
|
-
const url = `${API_BASE}${
|
|
5861
|
+
const url = `${API_BASE}${path28}`;
|
|
5868
5862
|
const opts = {
|
|
5869
5863
|
method,
|
|
5870
5864
|
headers: {
|
|
@@ -5889,15 +5883,11 @@ async function request2(method, path27, body) {
|
|
|
5889
5883
|
}
|
|
5890
5884
|
return res.json();
|
|
5891
5885
|
}
|
|
5892
|
-
function apiGet(
|
|
5893
|
-
return request2("GET",
|
|
5894
|
-
}
|
|
5895
|
-
function apiPost(path27, body) {
|
|
5896
|
-
return request2("POST", path27, body);
|
|
5886
|
+
function apiGet(path28) {
|
|
5887
|
+
return request2("GET", path28);
|
|
5897
5888
|
}
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
await requirePaidFeature2("profiles");
|
|
5889
|
+
function apiPost(path28, body) {
|
|
5890
|
+
return request2("POST", path28, body);
|
|
5901
5891
|
}
|
|
5902
5892
|
var init_api = __esm({
|
|
5903
5893
|
"src/lib/api.ts"() {
|
|
@@ -5907,130 +5897,6 @@ var init_api = __esm({
|
|
|
5907
5897
|
}
|
|
5908
5898
|
});
|
|
5909
5899
|
|
|
5910
|
-
// src/lib/access.ts
|
|
5911
|
-
var access_exports = {};
|
|
5912
|
-
__export(access_exports, {
|
|
5913
|
-
formatModeLabel: () => formatModeLabel,
|
|
5914
|
-
getAccessState: () => getAccessState,
|
|
5915
|
-
isLocalOnlyMode: () => isLocalOnlyMode,
|
|
5916
|
-
maybeShowLimitedModeHint: () => maybeShowLimitedModeHint,
|
|
5917
|
-
requirePaidFeature: () => requirePaidFeature,
|
|
5918
|
-
setLocalOnlyMode: () => setLocalOnlyMode
|
|
5919
|
-
});
|
|
5920
|
-
function setLocalOnlyMode(enabled) {
|
|
5921
|
-
localOnlyOverride = enabled;
|
|
5922
|
-
}
|
|
5923
|
-
function isLocalOnlyMode() {
|
|
5924
|
-
if (localOnlyOverride)
|
|
5925
|
-
return true;
|
|
5926
|
-
const env = process.env.HYV_LOCAL_ONLY;
|
|
5927
|
-
return env === "1" || env === "true";
|
|
5928
|
-
}
|
|
5929
|
-
async function getAccessState() {
|
|
5930
|
-
if (isLocalOnlyMode()) {
|
|
5931
|
-
return { authenticated: false, hasPaidPlan: false, plan: "local", localOnly: true };
|
|
5932
|
-
}
|
|
5933
|
-
const now = Date.now();
|
|
5934
|
-
if (cachedAccess && now - cachedAccess.at < ACCESS_CACHE_MS) {
|
|
5935
|
-
return cachedAccess.state;
|
|
5936
|
-
}
|
|
5937
|
-
const token = getToken();
|
|
5938
|
-
if (!token) {
|
|
5939
|
-
const state = { authenticated: false, hasPaidPlan: false, plan: "none", localOnly: false };
|
|
5940
|
-
cachedAccess = { state, at: now };
|
|
5941
|
-
return state;
|
|
5942
|
-
}
|
|
5943
|
-
try {
|
|
5944
|
-
const session = await checkSession();
|
|
5945
|
-
const plan = (session.plan || "none").toLowerCase();
|
|
5946
|
-
const subStatus = String(session.subscription_status || "").toLowerCase();
|
|
5947
|
-
const activeSubscription = !subStatus || ["active", "past_due", "trialing"].includes(subStatus);
|
|
5948
|
-
const hasPaidPlan = session.valid && activeSubscription && plan !== "none" && plan !== "free" && plan !== "expired" && plan !== "unknown" && plan !== "pending";
|
|
5949
|
-
const state = {
|
|
5950
|
-
authenticated: session.valid,
|
|
5951
|
-
hasPaidPlan,
|
|
5952
|
-
plan: session.plan || "none",
|
|
5953
|
-
localOnly: false
|
|
5954
|
-
};
|
|
5955
|
-
cachedAccess = { state, at: now };
|
|
5956
|
-
return state;
|
|
5957
|
-
} catch {
|
|
5958
|
-
const state = { authenticated: !!token, hasPaidPlan: false, plan: "unknown", localOnly: false };
|
|
5959
|
-
cachedAccess = { state, at: now };
|
|
5960
|
-
return state;
|
|
5961
|
-
}
|
|
5962
|
-
}
|
|
5963
|
-
async function requirePaidFeature(feature) {
|
|
5964
|
-
if (isLocalOnlyMode()) {
|
|
5965
|
-
throw new Error(
|
|
5966
|
-
`${FEATURE_MESSAGES[feature]} (local-only mode is on \u2014 unset HYV_LOCAL_ONLY or remove --local-only)`
|
|
5967
|
-
);
|
|
5968
|
-
}
|
|
5969
|
-
const token = getToken();
|
|
5970
|
-
if (!token) {
|
|
5971
|
-
throw new Error(`you're not signed in yet. run: hyv init \u2014 then ${FEATURE_MESSAGES[feature]}`);
|
|
5972
|
-
}
|
|
5973
|
-
let data;
|
|
5974
|
-
try {
|
|
5975
|
-
data = await apiGet("/cli/heartbeat");
|
|
5976
|
-
} catch (err) {
|
|
5977
|
-
const msg = err.message || "";
|
|
5978
|
-
if (msg.includes("not signed in") || msg.includes("session expired") || msg.includes("don't have access")) {
|
|
5979
|
-
throw err;
|
|
5980
|
-
}
|
|
5981
|
-
throw new Error("can't reach the server. check your internet connection and try again.");
|
|
5982
|
-
}
|
|
5983
|
-
const plan = (data.plan || "none").toLowerCase();
|
|
5984
|
-
const subStatus = String(data.subscription_status || data.status || "").toLowerCase();
|
|
5985
|
-
if (!data.plan || plan === "none" || plan === "free" || plan === "expired" || subStatus === "trialing" || subStatus === "none") {
|
|
5986
|
-
throw new Error(FEATURE_MESSAGES[feature]);
|
|
5987
|
-
}
|
|
5988
|
-
}
|
|
5989
|
-
async function maybeShowLimitedModeHint(hasProfile) {
|
|
5990
|
-
if (isLocalOnlyMode())
|
|
5991
|
-
return;
|
|
5992
|
-
const access = await getAccessState();
|
|
5993
|
-
if (access.hasPaidPlan)
|
|
5994
|
-
return;
|
|
5995
|
-
if (hasProfile) {
|
|
5996
|
-
console.log(import_chalk5.default.dim("\n using cached profile (local). sync for latest: hyv sync"));
|
|
5997
|
-
} else if (!access.authenticated) {
|
|
5998
|
-
console.log(import_chalk5.default.dim("\n local mode \u2014 free scan engine. profiles + learning: hyv init"));
|
|
5999
|
-
} else {
|
|
6000
|
-
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv upgrade"));
|
|
6001
|
-
}
|
|
6002
|
-
}
|
|
6003
|
-
function formatModeLabel(access, hasFullProfile) {
|
|
6004
|
-
if (access.localOnly)
|
|
6005
|
-
return "local-only (forced)";
|
|
6006
|
-
if (access.hasPaidPlan && hasFullProfile)
|
|
6007
|
-
return "full profile (paid)";
|
|
6008
|
-
if (hasFullProfile)
|
|
6009
|
-
return "cached profile (local)";
|
|
6010
|
-
if (access.authenticated)
|
|
6011
|
-
return "local engine (free)";
|
|
6012
|
-
return "local engine (free, not signed in)";
|
|
6013
|
-
}
|
|
6014
|
-
var import_chalk5, FEATURE_MESSAGES, localOnlyOverride, cachedAccess, ACCESS_CACHE_MS;
|
|
6015
|
-
var init_access = __esm({
|
|
6016
|
-
"src/lib/access.ts"() {
|
|
6017
|
-
"use strict";
|
|
6018
|
-
import_chalk5 = __toESM(require_source());
|
|
6019
|
-
init_config();
|
|
6020
|
-
init_auth();
|
|
6021
|
-
init_api();
|
|
6022
|
-
FEATURE_MESSAGES = {
|
|
6023
|
-
profiles: "syncing voice profiles from your account requires a paid plan. run: hyv upgrade",
|
|
6024
|
-
learning: "the learning loop (reinforce, add) requires a paid plan. run: hyv upgrade",
|
|
6025
|
-
premiumPrompts: "rich profile-aware rewrite prompts require a paid plan. run: hyv upgrade",
|
|
6026
|
-
serverAnalysis: "server-assisted analysis requires a paid plan. run: hyv upgrade"
|
|
6027
|
-
};
|
|
6028
|
-
localOnlyOverride = false;
|
|
6029
|
-
cachedAccess = null;
|
|
6030
|
-
ACCESS_CACHE_MS = 3e4;
|
|
6031
|
-
}
|
|
6032
|
-
});
|
|
6033
|
-
|
|
6034
5900
|
// src/lib/profile.ts
|
|
6035
5901
|
async function loadFullProfile(slug, opts = {}) {
|
|
6036
5902
|
const includeSamples = opts.includeSamples !== false;
|
|
@@ -6242,8 +6108,12 @@ function countLearnedPatterns(slug) {
|
|
|
6242
6108
|
async function loadProfileForCommand(name, opts = {}) {
|
|
6243
6109
|
const config = readConfig();
|
|
6244
6110
|
const candidates = [];
|
|
6245
|
-
if (name)
|
|
6111
|
+
if (name) {
|
|
6246
6112
|
candidates.push(name);
|
|
6113
|
+
const normalized = toSafeProfileCacheKey(name);
|
|
6114
|
+
if (normalized !== name)
|
|
6115
|
+
candidates.push(normalized);
|
|
6116
|
+
}
|
|
6247
6117
|
if (config.default_profile)
|
|
6248
6118
|
candidates.push(config.default_profile);
|
|
6249
6119
|
if (config.profile)
|
|
@@ -6294,6 +6164,250 @@ var init_local_profile = __esm({
|
|
|
6294
6164
|
}
|
|
6295
6165
|
});
|
|
6296
6166
|
|
|
6167
|
+
// src/lib/mcp-profile-hydrate.ts
|
|
6168
|
+
var mcp_profile_hydrate_exports = {};
|
|
6169
|
+
__export(mcp_profile_hydrate_exports, {
|
|
6170
|
+
ensureMcpProfilesHydrated: () => ensureMcpProfilesHydrated,
|
|
6171
|
+
formatMcpProfilesList: () => formatMcpProfilesList,
|
|
6172
|
+
normalizeProfileSlug: () => normalizeProfileSlug
|
|
6173
|
+
});
|
|
6174
|
+
function normalizeProfileSlug(name) {
|
|
6175
|
+
return toSafeProfileCacheKey(name);
|
|
6176
|
+
}
|
|
6177
|
+
async function ensureMcpProfilesHydrated(opts = {}) {
|
|
6178
|
+
if (process.env.VITEST) {
|
|
6179
|
+
return { ok: true, synced: [], skipped: true };
|
|
6180
|
+
}
|
|
6181
|
+
if (!getToken()) {
|
|
6182
|
+
return { ok: true, synced: [], skipped: true };
|
|
6183
|
+
}
|
|
6184
|
+
const now = Date.now();
|
|
6185
|
+
if (!opts.force && now - lastHydrateAt < HYDRATE_TTL_MS) {
|
|
6186
|
+
return { ok: true, synced: [], skipped: true };
|
|
6187
|
+
}
|
|
6188
|
+
if (hydrateInFlight && !opts.force) {
|
|
6189
|
+
return hydrateInFlight;
|
|
6190
|
+
}
|
|
6191
|
+
hydrateInFlight = runHydrate().then((result) => {
|
|
6192
|
+
lastHydrateAt = Date.now();
|
|
6193
|
+
return result;
|
|
6194
|
+
}).finally(() => {
|
|
6195
|
+
hydrateInFlight = null;
|
|
6196
|
+
});
|
|
6197
|
+
return hydrateInFlight;
|
|
6198
|
+
}
|
|
6199
|
+
async function runHydrate() {
|
|
6200
|
+
const synced = [];
|
|
6201
|
+
try {
|
|
6202
|
+
const data = await apiGet("/cli/profiles");
|
|
6203
|
+
const profiles = data.profiles || [];
|
|
6204
|
+
if (profiles.length === 0) {
|
|
6205
|
+
return { ok: true, synced: [] };
|
|
6206
|
+
}
|
|
6207
|
+
let defaultSlug;
|
|
6208
|
+
for (const row of profiles) {
|
|
6209
|
+
const slug = normalizeProfileSlug(row.slug || row.name);
|
|
6210
|
+
if (row.is_default)
|
|
6211
|
+
defaultSlug = slug;
|
|
6212
|
+
try {
|
|
6213
|
+
const detail = await apiGet(`/cli/profiles/${encodeURIComponent(slug)}`);
|
|
6214
|
+
const content = (detail.content || "").trim();
|
|
6215
|
+
if (content) {
|
|
6216
|
+
writeCachedProfile(slug, content);
|
|
6217
|
+
if (!synced.includes(slug))
|
|
6218
|
+
synced.push(slug);
|
|
6219
|
+
}
|
|
6220
|
+
await loadFullProfile(slug, {
|
|
6221
|
+
forceRefresh: true,
|
|
6222
|
+
serverUpdatedAt: row.updated_at || detail.updated_at
|
|
6223
|
+
});
|
|
6224
|
+
} catch {
|
|
6225
|
+
}
|
|
6226
|
+
}
|
|
6227
|
+
const config = readConfig();
|
|
6228
|
+
const localNames = /* @__PURE__ */ new Set([...listCachedProfiles(), ...listDiskCachedProfiles()]);
|
|
6229
|
+
const shouldSetDefault = defaultSlug && (!config.default_profile || !localNames.has(config.default_profile));
|
|
6230
|
+
if (shouldSetDefault && defaultSlug) {
|
|
6231
|
+
writeConfig({ ...config, default_profile: defaultSlug, profile: defaultSlug });
|
|
6232
|
+
}
|
|
6233
|
+
return { ok: true, synced, defaultProfile: defaultSlug || config.default_profile };
|
|
6234
|
+
} catch (err) {
|
|
6235
|
+
const message = err instanceof Error ? err.message : "profile sync failed";
|
|
6236
|
+
return { ok: false, synced, error: message };
|
|
6237
|
+
}
|
|
6238
|
+
}
|
|
6239
|
+
function formatMcpProfilesList(hydrate) {
|
|
6240
|
+
const config = readConfig();
|
|
6241
|
+
const local = [.../* @__PURE__ */ new Set([...listCachedProfiles(), ...listDiskCachedProfiles()])].sort();
|
|
6242
|
+
const active = config.default_profile || config.profile;
|
|
6243
|
+
const lines = ["### Voice profiles (MCP-ready)"];
|
|
6244
|
+
if (active && local.includes(active)) {
|
|
6245
|
+
lines.push(`Active default: **${active}** \u2014 hyv_scan / hyv_rewrite / hyv_clean use this unless you pass \`profile\`.`);
|
|
6246
|
+
} else if (local.length === 1) {
|
|
6247
|
+
lines.push(`Active default: **${local[0]}** (only local profile).`);
|
|
6248
|
+
} else if (local.length > 1) {
|
|
6249
|
+
lines.push("No default set \u2014 pass `profile` on tools, or run `hyv init` + create a default in the dashboard.");
|
|
6250
|
+
}
|
|
6251
|
+
if (local.length > 0) {
|
|
6252
|
+
lines.push("");
|
|
6253
|
+
lines.push("Local (ready for MCP tools now):");
|
|
6254
|
+
for (const name of local) {
|
|
6255
|
+
const mark = name === active ? " (default)" : "";
|
|
6256
|
+
lines.push(` \u2022 ${name}${mark}`);
|
|
6257
|
+
}
|
|
6258
|
+
} else {
|
|
6259
|
+
lines.push("");
|
|
6260
|
+
lines.push("No local profiles yet.");
|
|
6261
|
+
}
|
|
6262
|
+
if (!getToken()) {
|
|
6263
|
+
lines.push("");
|
|
6264
|
+
lines.push("Account profiles (dashboard / web): run **`hyv init`** once on this machine \u2014 MCP will auto-download them here.");
|
|
6265
|
+
lines.push("Terminal welcome (`hyv welcome`) saves locally immediately; no init needed for that path.");
|
|
6266
|
+
return lines.join("\n");
|
|
6267
|
+
}
|
|
6268
|
+
if (hydrate?.synced?.length) {
|
|
6269
|
+
lines.push("");
|
|
6270
|
+
lines.push(`Just synced from your account: ${hydrate.synced.join(", ")}`);
|
|
6271
|
+
} else if (hydrate?.error) {
|
|
6272
|
+
lines.push("");
|
|
6273
|
+
lines.push(`Account sync note: ${hydrate.error}`);
|
|
6274
|
+
} else if (local.length === 0 && hydrate?.skipped) {
|
|
6275
|
+
lines.push("");
|
|
6276
|
+
lines.push("Signed in \u2014 checking account\u2026 if profiles exist on holdyourvoice.com, they load automatically.");
|
|
6277
|
+
}
|
|
6278
|
+
lines.push("");
|
|
6279
|
+
lines.push("Same profile everywhere: build in **dashboard** or **`hyv welcome`**, then use MCP tools with no extra setup (after `hyv init` for dashboard-only profiles).");
|
|
6280
|
+
return lines.join("\n");
|
|
6281
|
+
}
|
|
6282
|
+
var lastHydrateAt, hydrateInFlight, HYDRATE_TTL_MS;
|
|
6283
|
+
var init_mcp_profile_hydrate = __esm({
|
|
6284
|
+
"src/lib/mcp-profile-hydrate.ts"() {
|
|
6285
|
+
"use strict";
|
|
6286
|
+
init_config();
|
|
6287
|
+
init_api();
|
|
6288
|
+
init_profile();
|
|
6289
|
+
init_local_profile();
|
|
6290
|
+
lastHydrateAt = 0;
|
|
6291
|
+
hydrateInFlight = null;
|
|
6292
|
+
HYDRATE_TTL_MS = 5 * 60 * 1e3;
|
|
6293
|
+
}
|
|
6294
|
+
});
|
|
6295
|
+
|
|
6296
|
+
// src/lib/access.ts
|
|
6297
|
+
function setLocalOnlyMode(enabled) {
|
|
6298
|
+
localOnlyOverride = enabled;
|
|
6299
|
+
}
|
|
6300
|
+
function isLocalOnlyMode() {
|
|
6301
|
+
if (localOnlyOverride)
|
|
6302
|
+
return true;
|
|
6303
|
+
const env = process.env.HYV_LOCAL_ONLY;
|
|
6304
|
+
return env === "1" || env === "true";
|
|
6305
|
+
}
|
|
6306
|
+
async function getAccessState() {
|
|
6307
|
+
if (isLocalOnlyMode()) {
|
|
6308
|
+
return { authenticated: false, hasPaidPlan: false, plan: "local", localOnly: true };
|
|
6309
|
+
}
|
|
6310
|
+
const now = Date.now();
|
|
6311
|
+
if (cachedAccess && now - cachedAccess.at < ACCESS_CACHE_MS) {
|
|
6312
|
+
return cachedAccess.state;
|
|
6313
|
+
}
|
|
6314
|
+
const token = getToken();
|
|
6315
|
+
if (!token) {
|
|
6316
|
+
const state = { authenticated: false, hasPaidPlan: false, plan: "none", localOnly: false };
|
|
6317
|
+
cachedAccess = { state, at: now };
|
|
6318
|
+
return state;
|
|
6319
|
+
}
|
|
6320
|
+
try {
|
|
6321
|
+
const session = await checkSession();
|
|
6322
|
+
const plan = (session.plan || "none").toLowerCase();
|
|
6323
|
+
const subStatus = String(session.subscription_status || "").toLowerCase();
|
|
6324
|
+
const activeSubscription = !subStatus || ["active", "past_due", "trialing"].includes(subStatus);
|
|
6325
|
+
const hasPaidPlan = session.valid && activeSubscription && plan !== "none" && plan !== "free" && plan !== "expired" && plan !== "unknown" && plan !== "pending";
|
|
6326
|
+
const state = {
|
|
6327
|
+
authenticated: session.valid,
|
|
6328
|
+
hasPaidPlan,
|
|
6329
|
+
plan: session.plan || "none",
|
|
6330
|
+
localOnly: false
|
|
6331
|
+
};
|
|
6332
|
+
cachedAccess = { state, at: now };
|
|
6333
|
+
return state;
|
|
6334
|
+
} catch {
|
|
6335
|
+
const state = { authenticated: !!token, hasPaidPlan: false, plan: "unknown", localOnly: false };
|
|
6336
|
+
cachedAccess = { state, at: now };
|
|
6337
|
+
return state;
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
async function requirePaidFeature(feature) {
|
|
6341
|
+
if (isLocalOnlyMode()) {
|
|
6342
|
+
throw new Error(
|
|
6343
|
+
`${FEATURE_MESSAGES[feature]} (local-only mode is on \u2014 unset HYV_LOCAL_ONLY or remove --local-only)`
|
|
6344
|
+
);
|
|
6345
|
+
}
|
|
6346
|
+
const token = getToken();
|
|
6347
|
+
if (!token) {
|
|
6348
|
+
throw new Error(`you're not signed in yet. run: hyv init \u2014 then ${FEATURE_MESSAGES[feature]}`);
|
|
6349
|
+
}
|
|
6350
|
+
let data;
|
|
6351
|
+
try {
|
|
6352
|
+
data = await apiGet("/cli/heartbeat");
|
|
6353
|
+
} catch (err) {
|
|
6354
|
+
const msg = err.message || "";
|
|
6355
|
+
if (msg.includes("not signed in") || msg.includes("session expired") || msg.includes("don't have access")) {
|
|
6356
|
+
throw err;
|
|
6357
|
+
}
|
|
6358
|
+
throw new Error("can't reach the server. check your internet connection and try again.");
|
|
6359
|
+
}
|
|
6360
|
+
const plan = (data.plan || "none").toLowerCase();
|
|
6361
|
+
const subStatus = String(data.subscription_status || data.status || "").toLowerCase();
|
|
6362
|
+
if (!data.plan || plan === "none" || plan === "free" || plan === "expired" || subStatus === "trialing" || subStatus === "none") {
|
|
6363
|
+
throw new Error(FEATURE_MESSAGES[feature]);
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
async function maybeShowLimitedModeHint(hasProfile) {
|
|
6367
|
+
if (isLocalOnlyMode())
|
|
6368
|
+
return;
|
|
6369
|
+
const access = await getAccessState();
|
|
6370
|
+
if (access.hasPaidPlan)
|
|
6371
|
+
return;
|
|
6372
|
+
if (hasProfile) {
|
|
6373
|
+
console.log(import_chalk5.default.dim("\n using cached profile (local). sync for latest: hyv sync"));
|
|
6374
|
+
} else if (!access.authenticated) {
|
|
6375
|
+
console.log(import_chalk5.default.dim("\n local mode \u2014 free scan engine. profiles + learning: hyv init"));
|
|
6376
|
+
} else {
|
|
6377
|
+
console.log(import_chalk5.default.dim("\n local mode \u2014 upgrade for full profiles + learning: hyv upgrade"));
|
|
6378
|
+
}
|
|
6379
|
+
}
|
|
6380
|
+
function formatModeLabel(access, hasFullProfile) {
|
|
6381
|
+
if (access.localOnly)
|
|
6382
|
+
return "local-only (forced)";
|
|
6383
|
+
if (access.hasPaidPlan && hasFullProfile)
|
|
6384
|
+
return "full profile (paid)";
|
|
6385
|
+
if (hasFullProfile)
|
|
6386
|
+
return "cached profile (local)";
|
|
6387
|
+
if (access.authenticated)
|
|
6388
|
+
return "local engine (free)";
|
|
6389
|
+
return "local engine (free, not signed in)";
|
|
6390
|
+
}
|
|
6391
|
+
var import_chalk5, FEATURE_MESSAGES, localOnlyOverride, cachedAccess, ACCESS_CACHE_MS;
|
|
6392
|
+
var init_access = __esm({
|
|
6393
|
+
"src/lib/access.ts"() {
|
|
6394
|
+
"use strict";
|
|
6395
|
+
import_chalk5 = __toESM(require_source());
|
|
6396
|
+
init_config();
|
|
6397
|
+
init_auth();
|
|
6398
|
+
init_api();
|
|
6399
|
+
FEATURE_MESSAGES = {
|
|
6400
|
+
profiles: "syncing voice profiles from your account requires a paid plan. run: hyv upgrade",
|
|
6401
|
+
learning: "the learning loop (reinforce, add) requires a paid plan. run: hyv upgrade",
|
|
6402
|
+
premiumPrompts: "rich profile-aware rewrite prompts require a paid plan. run: hyv upgrade",
|
|
6403
|
+
serverAnalysis: "server-assisted analysis requires a paid plan. run: hyv upgrade"
|
|
6404
|
+
};
|
|
6405
|
+
localOnlyOverride = false;
|
|
6406
|
+
cachedAccess = null;
|
|
6407
|
+
ACCESS_CACHE_MS = 3e4;
|
|
6408
|
+
}
|
|
6409
|
+
});
|
|
6410
|
+
|
|
6297
6411
|
// src/lib/profile-parse.ts
|
|
6298
6412
|
function parseAnchorsFromBody(body) {
|
|
6299
6413
|
const anchors = [];
|
|
@@ -7432,7 +7546,7 @@ function ps(n7) {
|
|
|
7432
7546
|
return n7.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs10, de).replace(us, pe);
|
|
7433
7547
|
}
|
|
7434
7548
|
function ms(n7) {
|
|
7435
|
-
return n7.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(
|
|
7549
|
+
return n7.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os7, ",").replace(hs, ".");
|
|
7436
7550
|
}
|
|
7437
7551
|
function me(n7) {
|
|
7438
7552
|
if (!n7)
|
|
@@ -7532,7 +7646,7 @@ function Ut(n7, t = {}) {
|
|
|
7532
7646
|
function es(n7, t = {}) {
|
|
7533
7647
|
return new I(n7, t).iterate();
|
|
7534
7648
|
}
|
|
7535
|
-
var import_node_url, import_node_path, import_node_url2, import_fs, xi, import_promises, import_node_events, import_node_stream, import_node_string_decoder, Gt, ce, ss, fe, ue, qt, de, pe, is, rs, ns,
|
|
7649
|
+
var import_node_url, import_node_path, import_node_url2, import_fs, xi, import_promises, import_node_events, import_node_stream, import_node_string_decoder, Gt, ce, ss, fe, ue, qt, de, pe, is, rs, ns, os7, hs, as, ls, cs, fs10, us, ds, at, Ss, lt, Es, we, ye, W, xs, be, vs, Ct, Cs, Ts, As, ks, Kt, Se, Ee, Q, tt, O, Rs, Os, Fs, Ds, Ms, Ns, _s, Ls, Ws, Ps, js, Is, zs, Bs, Us, $s, Gs, Hs, Ce, Te, Ae, xe, qs, A, Ks, Vs, Ys, Xs, Js, N, Zs, ke, Qs, ti, ve, ei, D, si, Oe, Vt, Fe, At, Re, ii, q, De, Tt, ri, ft, Ne, oi, hi, ai, G, H, K, kt, ut, Rt, _e, Ot, Le, P, et, v, dt, st, C, F, T, Yt, Ft, k, x, Xt, Jt, We, Zt, B, Qt, Dt, pt, Y, M, mt, li, ci, fi, ui, Mt, te, di, pi, V, vi, wt, Ue, $e, Ri, Oi, L, Ge, He, U, qe, Ke, X, Ve, _, gt, se, je, yt, j, Nt, Lt, Ie, Fi, ie, ze, bt, Be, _t, Wt, ne, Ye, R, Pt, jt, It, it, rt, St, Cr, Xe, Di, Mi, Ni, nt, _i, ot, oe, he, ae, Et, Li, zt, xt, vt, Pi, I, le, ji, Ii, zi, Bi, Ui, Ze;
|
|
7536
7650
|
var init_index_min = __esm({
|
|
7537
7651
|
"node_modules/glob/dist/esm/index.min.js"() {
|
|
7538
7652
|
import_node_url = require("node:url");
|
|
@@ -7579,7 +7693,7 @@ var init_index_min = __esm({
|
|
|
7579
7693
|
is = new RegExp(fe, "g");
|
|
7580
7694
|
rs = new RegExp(ue, "g");
|
|
7581
7695
|
ns = new RegExp(qt, "g");
|
|
7582
|
-
|
|
7696
|
+
os7 = new RegExp(de, "g");
|
|
7583
7697
|
hs = new RegExp(pe, "g");
|
|
7584
7698
|
as = /\\\\/g;
|
|
7585
7699
|
ls = /\\{/g;
|
|
@@ -10740,18 +10854,18 @@ function stripXmlText(xml) {
|
|
|
10740
10854
|
}
|
|
10741
10855
|
function commandExists(cmd) {
|
|
10742
10856
|
try {
|
|
10743
|
-
(0,
|
|
10857
|
+
(0, import_child_process3.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
10744
10858
|
return true;
|
|
10745
10859
|
} catch {
|
|
10746
10860
|
return false;
|
|
10747
10861
|
}
|
|
10748
10862
|
}
|
|
10749
10863
|
function unzipList(filePath) {
|
|
10750
|
-
const out = (0,
|
|
10864
|
+
const out = (0, import_child_process3.execFileSync)("unzip", ["-Z1", filePath], { encoding: "utf-8", maxBuffer: 5e6 });
|
|
10751
10865
|
return out.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
10752
10866
|
}
|
|
10753
10867
|
function unzipExtract(filePath, entry) {
|
|
10754
|
-
return (0,
|
|
10868
|
+
return (0, import_child_process3.execFileSync)("unzip", ["-p", filePath, entry], {
|
|
10755
10869
|
encoding: "utf-8",
|
|
10756
10870
|
maxBuffer: 1e7
|
|
10757
10871
|
});
|
|
@@ -10759,7 +10873,7 @@ function unzipExtract(filePath, entry) {
|
|
|
10759
10873
|
function extractDocx(filePath) {
|
|
10760
10874
|
if (process.platform === "darwin") {
|
|
10761
10875
|
try {
|
|
10762
|
-
const out = (0,
|
|
10876
|
+
const out = (0, import_child_process3.execFileSync)("textutil", ["-convert", "txt", "-stdout", filePath], {
|
|
10763
10877
|
encoding: "utf-8",
|
|
10764
10878
|
maxBuffer: 1e7
|
|
10765
10879
|
});
|
|
@@ -10802,7 +10916,7 @@ function extractPdfRaw(buffer) {
|
|
|
10802
10916
|
function extractPdf(filePath) {
|
|
10803
10917
|
if (process.platform === "darwin") {
|
|
10804
10918
|
try {
|
|
10805
|
-
const out = (0,
|
|
10919
|
+
const out = (0, import_child_process3.execFileSync)("textutil", ["-convert", "txt", "-stdout", filePath], {
|
|
10806
10920
|
encoding: "utf-8",
|
|
10807
10921
|
maxBuffer: 1e7
|
|
10808
10922
|
});
|
|
@@ -10812,7 +10926,7 @@ function extractPdf(filePath) {
|
|
|
10812
10926
|
}
|
|
10813
10927
|
}
|
|
10814
10928
|
if (commandExists("pdftotext")) {
|
|
10815
|
-
const out = (0,
|
|
10929
|
+
const out = (0, import_child_process3.execFileSync)("pdftotext", ["-layout", "-enc", "UTF-8", filePath, "-"], {
|
|
10816
10930
|
encoding: "utf-8",
|
|
10817
10931
|
maxBuffer: 1e7
|
|
10818
10932
|
});
|
|
@@ -10877,7 +10991,7 @@ function listDocumentsInDir(dirPath) {
|
|
|
10877
10991
|
}).filter(isSupportedDocument);
|
|
10878
10992
|
}
|
|
10879
10993
|
function collectDocumentsFromPath(inputPath) {
|
|
10880
|
-
const resolved = path10.resolve(inputPath.trim().replace(/^~(?=$|\/)/,
|
|
10994
|
+
const resolved = path10.resolve(inputPath.trim().replace(/^~(?=$|\/)/, os8.homedir()));
|
|
10881
10995
|
if (!fs11.existsSync(resolved)) {
|
|
10882
10996
|
throw new Error(`path not found: ${resolved}`);
|
|
10883
10997
|
}
|
|
@@ -10908,19 +11022,19 @@ function readDraftInput(input) {
|
|
|
10908
11022
|
const trimmed = input.trim();
|
|
10909
11023
|
if (!trimmed)
|
|
10910
11024
|
throw new Error("empty draft");
|
|
10911
|
-
const maybePath = path10.resolve(trimmed.replace(/^~(?=$|\/)/,
|
|
11025
|
+
const maybePath = path10.resolve(trimmed.replace(/^~(?=$|\/)/, os8.homedir()));
|
|
10912
11026
|
if (fs11.existsSync(maybePath) && fs11.statSync(maybePath).isFile()) {
|
|
10913
11027
|
return { text: extractTextFromFile(maybePath), source: maybePath };
|
|
10914
11028
|
}
|
|
10915
11029
|
return { text: trimmed, source: "paste" };
|
|
10916
11030
|
}
|
|
10917
|
-
var
|
|
11031
|
+
var import_child_process3, fs11, os8, path10, SUPPORTED_EXTENSIONS, SAMPLE_GLOB, GLOB_IGNORE;
|
|
10918
11032
|
var init_document_text = __esm({
|
|
10919
11033
|
"src/lib/document-text.ts"() {
|
|
10920
11034
|
"use strict";
|
|
10921
|
-
|
|
11035
|
+
import_child_process3 = require("child_process");
|
|
10922
11036
|
fs11 = __toESM(require("fs"));
|
|
10923
|
-
|
|
11037
|
+
os8 = __toESM(require("os"));
|
|
10924
11038
|
path10 = __toESM(require("path"));
|
|
10925
11039
|
init_index_min();
|
|
10926
11040
|
SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -10996,21 +11110,21 @@ function runPipeline(text, profile, applyFixes = false) {
|
|
|
10996
11110
|
};
|
|
10997
11111
|
}
|
|
10998
11112
|
function readText(source) {
|
|
10999
|
-
const
|
|
11000
|
-
const
|
|
11113
|
+
const fs31 = require("fs");
|
|
11114
|
+
const path28 = require("path");
|
|
11001
11115
|
if (source === "-") {
|
|
11002
11116
|
if (process.stdin.isTTY) {
|
|
11003
11117
|
console.error("No input provided. Pipe content or specify a file.");
|
|
11004
11118
|
process.exit(1);
|
|
11005
11119
|
}
|
|
11006
|
-
return { text:
|
|
11120
|
+
return { text: fs31.readFileSync(0, "utf-8"), path: "stdin" };
|
|
11007
11121
|
}
|
|
11008
|
-
const resolved =
|
|
11009
|
-
if (!
|
|
11122
|
+
const resolved = path28.resolve(source);
|
|
11123
|
+
if (!fs31.existsSync(resolved)) {
|
|
11010
11124
|
console.error(`File not found: ${resolved}`);
|
|
11011
11125
|
process.exit(1);
|
|
11012
11126
|
}
|
|
11013
|
-
const stat =
|
|
11127
|
+
const stat = fs31.statSync(resolved);
|
|
11014
11128
|
if (stat.isDirectory()) {
|
|
11015
11129
|
console.error(`${resolved} is a directory, not a file.`);
|
|
11016
11130
|
process.exit(1);
|
|
@@ -11410,7 +11524,7 @@ function isInteractiveTTY() {
|
|
|
11410
11524
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY && !process.env.CI);
|
|
11411
11525
|
}
|
|
11412
11526
|
function briefPause(ms2 = 280) {
|
|
11413
|
-
return new Promise((
|
|
11527
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms2));
|
|
11414
11528
|
}
|
|
11415
11529
|
async function withSpinner(label, fn, opts = {}) {
|
|
11416
11530
|
const minMs = opts.minMs ?? 450;
|
|
@@ -11461,10 +11575,10 @@ var init_terminal_ui = __esm({
|
|
|
11461
11575
|
|
|
11462
11576
|
// src/lib/welcome-flow.ts
|
|
11463
11577
|
function localProfilePath(name) {
|
|
11464
|
-
return path14.join(
|
|
11578
|
+
return path14.join(os9.homedir(), ".hyv", "profiles", `${name}.md`);
|
|
11465
11579
|
}
|
|
11466
11580
|
function listLocalProfileNames() {
|
|
11467
|
-
const profilesDir = path14.join(
|
|
11581
|
+
const profilesDir = path14.join(os9.homedir(), ".hyv", "profiles");
|
|
11468
11582
|
if (!fs15.existsSync(profilesDir))
|
|
11469
11583
|
return [];
|
|
11470
11584
|
return fs15.readdirSync(profilesDir).filter((entry) => entry.endsWith(".md")).map((entry) => entry.slice(0, -3));
|
|
@@ -11725,10 +11839,10 @@ function saveLocalProfile(name, content) {
|
|
|
11725
11839
|
writeWelcomeState({ profile_name: safe });
|
|
11726
11840
|
markStepComplete("name");
|
|
11727
11841
|
markStepComplete("samples");
|
|
11728
|
-
return path14.join(
|
|
11842
|
+
return path14.join(os9.homedir(), ".hyv", "profiles", `${safe}.md`);
|
|
11729
11843
|
}
|
|
11730
11844
|
function fetchUrlText(url) {
|
|
11731
|
-
return new Promise((
|
|
11845
|
+
return new Promise((resolve16, reject) => {
|
|
11732
11846
|
let parsed;
|
|
11733
11847
|
try {
|
|
11734
11848
|
parsed = new URL(url);
|
|
@@ -11757,7 +11871,7 @@ function fetchUrlText(url) {
|
|
|
11757
11871
|
});
|
|
11758
11872
|
res.on("end", () => {
|
|
11759
11873
|
const text = data.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
11760
|
-
|
|
11874
|
+
resolve16(text.slice(0, 12e3));
|
|
11761
11875
|
});
|
|
11762
11876
|
}
|
|
11763
11877
|
);
|
|
@@ -11777,10 +11891,10 @@ async function collectSamplesFromLink(url) {
|
|
|
11777
11891
|
}
|
|
11778
11892
|
function askLine(prompt) {
|
|
11779
11893
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
11780
|
-
return new Promise((
|
|
11894
|
+
return new Promise((resolve16) => {
|
|
11781
11895
|
rl.question(prompt, (answer) => {
|
|
11782
11896
|
rl.close();
|
|
11783
|
-
|
|
11897
|
+
resolve16(answer.trim());
|
|
11784
11898
|
});
|
|
11785
11899
|
});
|
|
11786
11900
|
}
|
|
@@ -11789,11 +11903,11 @@ async function askMultiline(intro) {
|
|
|
11789
11903
|
console.log(import_chalk12.default.dim(" paste below, then type --- on its own line when done\n"));
|
|
11790
11904
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
11791
11905
|
const lines = [];
|
|
11792
|
-
return new Promise((
|
|
11906
|
+
return new Promise((resolve16) => {
|
|
11793
11907
|
rl.on("line", (line) => {
|
|
11794
11908
|
if (line.trim() === "---") {
|
|
11795
11909
|
rl.close();
|
|
11796
|
-
|
|
11910
|
+
resolve16(lines.join("\n").trim());
|
|
11797
11911
|
return;
|
|
11798
11912
|
}
|
|
11799
11913
|
lines.push(line);
|
|
@@ -12091,7 +12205,7 @@ function getMcpWelcomeResponse(args2) {
|
|
|
12091
12205
|
}
|
|
12092
12206
|
return buildWelcomeGuide({ profileName: args2.profile, forLlm: true });
|
|
12093
12207
|
}
|
|
12094
|
-
var import_chalk12, fs15, http2, https2,
|
|
12208
|
+
var import_chalk12, fs15, http2, https2, os9, path14, readline, PROFILE_SYNC_TIMEOUT_MS, WELCOME_TAGLINE, FLOW_STEPS, STATE_FILE;
|
|
12095
12209
|
var init_welcome_flow = __esm({
|
|
12096
12210
|
"src/lib/welcome-flow.ts"() {
|
|
12097
12211
|
"use strict";
|
|
@@ -12099,7 +12213,7 @@ var init_welcome_flow = __esm({
|
|
|
12099
12213
|
fs15 = __toESM(require("fs"));
|
|
12100
12214
|
http2 = __toESM(require("http"));
|
|
12101
12215
|
https2 = __toESM(require("https"));
|
|
12102
|
-
|
|
12216
|
+
os9 = __toESM(require("os"));
|
|
12103
12217
|
path14 = __toESM(require("path"));
|
|
12104
12218
|
readline = __toESM(require("readline"));
|
|
12105
12219
|
init_pipeline();
|
|
@@ -12121,7 +12235,7 @@ var init_welcome_flow = __esm({
|
|
|
12121
12235
|
{ n: 3, key: "test", title: "test on a draft", hint: "optional \u2014 scan or rewrite a draft" },
|
|
12122
12236
|
{ n: 4, key: "signup", title: "save & unlock", hint: "signup syncs your profile and unlocks learning" }
|
|
12123
12237
|
];
|
|
12124
|
-
STATE_FILE = path14.join(
|
|
12238
|
+
STATE_FILE = path14.join(os9.homedir(), ".hyv", "welcome-state.json");
|
|
12125
12239
|
}
|
|
12126
12240
|
});
|
|
12127
12241
|
|
|
@@ -13157,15 +13271,15 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
13157
13271
|
g.minimatch.escape = vi2.escape;
|
|
13158
13272
|
g.minimatch.unescape = Ei2.unescape;
|
|
13159
13273
|
});
|
|
13160
|
-
var
|
|
13274
|
+
var fs31 = R2((Wt2) => {
|
|
13161
13275
|
"use strict";
|
|
13162
13276
|
Object.defineProperty(Wt2, "__esModule", { value: true });
|
|
13163
13277
|
Wt2.LRUCache = void 0;
|
|
13164
13278
|
var er = typeof performance == "object" && performance && typeof performance.now == "function" ? performance : Date, as2 = /* @__PURE__ */ new Set(), ge2 = typeof process == "object" && process ? process : {}, ls2 = (n7, t, e, s) => {
|
|
13165
13279
|
typeof ge2.emitWarning == "function" ? ge2.emitWarning(n7, t, e, s) : console.error(`[${e}] ${t}: ${n7}`);
|
|
13166
|
-
}, Lt2 = globalThis.AbortController,
|
|
13280
|
+
}, Lt2 = globalThis.AbortController, os15 = globalThis.AbortSignal;
|
|
13167
13281
|
if (typeof Lt2 > "u") {
|
|
13168
|
-
|
|
13282
|
+
os15 = class {
|
|
13169
13283
|
onabort;
|
|
13170
13284
|
_onabort = [];
|
|
13171
13285
|
reason;
|
|
@@ -13177,7 +13291,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
13177
13291
|
constructor() {
|
|
13178
13292
|
t();
|
|
13179
13293
|
}
|
|
13180
|
-
signal = new
|
|
13294
|
+
signal = new os15();
|
|
13181
13295
|
abort(e) {
|
|
13182
13296
|
if (!this.signal.aborted) {
|
|
13183
13297
|
this.signal.reason = e, this.signal.aborted = true;
|
|
@@ -14126,7 +14240,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
14126
14240
|
};
|
|
14127
14241
|
Object.defineProperty(_2, "__esModule", { value: true });
|
|
14128
14242
|
_2.PathScurry = _2.Path = _2.PathScurryDarwin = _2.PathScurryPosix = _2.PathScurryWin32 = _2.PathScurryBase = _2.PathPosix = _2.PathWin32 = _2.PathBase = _2.ChildrenCache = _2.ResolveCache = void 0;
|
|
14129
|
-
var Qt2 =
|
|
14243
|
+
var Qt2 = fs31(), Yt2 = require("node:path"), yr = require("node:url"), pt2 = require("fs"), Sr = br(require("node:fs")), vr = pt2.realpathSync.native, Ht2 = require("node:fs/promises"), bs2 = Oe2(), mt2 = { lstatSync: pt2.lstatSync, readdir: pt2.readdir, readdirSync: pt2.readdirSync, readlinkSync: pt2.readlinkSync, realpathSync: vr, promises: { lstat: Ht2.lstat, readdir: Ht2.readdir, readlink: Ht2.readlink, realpath: Ht2.realpath } }, _s2 = (n7) => !n7 || n7 === mt2 || n7 === Sr ? mt2 : { ...mt2, ...n7, promises: { ...mt2.promises, ...n7.promises || {} } }, Os2 = /^\\\\\?\\([a-z]:)\\?$/i, Er = (n7) => n7.replace(/\//g, "\\").replace(Os2, "$1\\"), _r = /[\\\/]/, N2 = 0, xs2 = 1, Ts2 = 2, G2 = 4, Cs2 = 6, Rs2 = 8, Q2 = 10, As2 = 12, j2 = 15, dt2 = ~j2, xe2 = 16, ys2 = 32, gt2 = 64, W2 = 128, Vt2 = 256, Xt2 = 512, Ss2 = gt2 | W2 | Xt2, Or = 1023, Te2 = (n7) => n7.isFile() ? Rs2 : n7.isDirectory() ? G2 : n7.isSymbolicLink() ? Q2 : n7.isCharacterDevice() ? Ts2 : n7.isBlockDevice() ? Cs2 : n7.isSocket() ? As2 : n7.isFIFO() ? xs2 : N2, vs2 = new Qt2.LRUCache({ max: 2 ** 12 }), wt2 = (n7) => {
|
|
14130
14244
|
let t = vs2.get(n7);
|
|
14131
14245
|
if (t)
|
|
14132
14246
|
return t;
|
|
@@ -15645,7 +15759,7 @@ var {
|
|
|
15645
15759
|
} = import_index.default;
|
|
15646
15760
|
|
|
15647
15761
|
// src/index.ts
|
|
15648
|
-
var
|
|
15762
|
+
var import_chalk34 = __toESM(require_source());
|
|
15649
15763
|
|
|
15650
15764
|
// src/commands/init.ts
|
|
15651
15765
|
var import_chalk4 = __toESM(require_source());
|
|
@@ -15791,10 +15905,19 @@ function registerInitCommand(program3) {
|
|
|
15791
15905
|
if (authData.license_key) {
|
|
15792
15906
|
console.log(import_chalk4.default.dim(` License: ${authData.license_key.slice(0, 12)}...`));
|
|
15793
15907
|
}
|
|
15908
|
+
try {
|
|
15909
|
+
const { ensureMcpProfilesHydrated: ensureMcpProfilesHydrated2 } = await Promise.resolve().then(() => (init_mcp_profile_hydrate(), mcp_profile_hydrate_exports));
|
|
15910
|
+
const hydrated = await ensureMcpProfilesHydrated2({ force: true });
|
|
15911
|
+
if (hydrated.synced?.length) {
|
|
15912
|
+
console.log(import_chalk4.default.green(`
|
|
15913
|
+
\u2713 MCP profiles ready: ${hydrated.synced.join(", ")}`));
|
|
15914
|
+
}
|
|
15915
|
+
} catch {
|
|
15916
|
+
}
|
|
15794
15917
|
const mcpResults = configureMcpForDesktop();
|
|
15795
15918
|
const { printPaidUnlockReminder: printPaidUnlockReminder2 } = await Promise.resolve().then(() => (init_marketing_hints(), marketing_hints_exports));
|
|
15796
15919
|
console.log("\nNext steps:");
|
|
15797
|
-
console.log(import_chalk4.default.dim(" 1.
|
|
15920
|
+
console.log(import_chalk4.default.dim(" 1. Voice profile: hyv welcome (or use dashboard \u2014 MCP syncs after init)"));
|
|
15798
15921
|
console.log(import_chalk4.default.dim(" 2. Scan a draft: hyv scan draft.md"));
|
|
15799
15922
|
console.log(import_chalk4.default.dim(" 3. Rewrite with voice: hyv rewrite draft.md"));
|
|
15800
15923
|
printPaidUnlockReminder2();
|
|
@@ -16018,6 +16141,8 @@ init_profile();
|
|
|
16018
16141
|
init_profile_meta();
|
|
16019
16142
|
var fs8 = __toESM(require("fs"));
|
|
16020
16143
|
var path8 = __toESM(require("path"));
|
|
16144
|
+
var os6 = __toESM(require("os"));
|
|
16145
|
+
var import_child_process2 = require("child_process");
|
|
16021
16146
|
function registerSyncCommand(program3) {
|
|
16022
16147
|
program3.command("sync").description("Sync profiles and rules from server").option("--force", "Force re-download even if cache is fresh").action(async (options) => {
|
|
16023
16148
|
try {
|
|
@@ -16105,7 +16230,15 @@ function registerSyncCommand(program3) {
|
|
|
16105
16230
|
process.exit(1);
|
|
16106
16231
|
}
|
|
16107
16232
|
});
|
|
16108
|
-
program3.command("profiles").description("List voice profiles").option("--verbose", "Show learned patterns, drift, anchors").option("--history <name>", "Show profile evolution for a slug").action(async (options) => {
|
|
16233
|
+
program3.command("profiles").description("List, edit, or delete voice profiles").option("--verbose", "Show learned patterns, drift, anchors").option("--history <name>", "Show profile evolution for a slug").option("--delete <name>", "Delete a profile (server + local cache)").option("--edit <name>", "Open a local profile in your $EDITOR").action(async (options) => {
|
|
16234
|
+
if (options.delete) {
|
|
16235
|
+
await deleteProfileByName(options.delete);
|
|
16236
|
+
return;
|
|
16237
|
+
}
|
|
16238
|
+
if (options.edit) {
|
|
16239
|
+
await editLocalProfile(options.edit);
|
|
16240
|
+
return;
|
|
16241
|
+
}
|
|
16109
16242
|
if (options.history) {
|
|
16110
16243
|
await showProfileHistory(options.history);
|
|
16111
16244
|
return;
|
|
@@ -16151,6 +16284,58 @@ ${profiles.length} profile(s) cached.`));
|
|
|
16151
16284
|
await program3.parseAsync(["node", "hyv", "sync", "--force"]);
|
|
16152
16285
|
});
|
|
16153
16286
|
}
|
|
16287
|
+
async function deleteProfileByName(name) {
|
|
16288
|
+
const token = getToken();
|
|
16289
|
+
const localKey = toSafeProfileCacheKey(name);
|
|
16290
|
+
const localPath = path8.join(os6.homedir(), ".hyv", "profiles", `${localKey}.md`);
|
|
16291
|
+
if (token) {
|
|
16292
|
+
try {
|
|
16293
|
+
const res = await authenticatedRequest(cliApiUrl("/cli/profiles/delete"), {
|
|
16294
|
+
method: "POST",
|
|
16295
|
+
body: { slug_or_id: name }
|
|
16296
|
+
});
|
|
16297
|
+
if (res.status !== 200) {
|
|
16298
|
+
const err = res.data?.error || `delete failed (HTTP ${res.status})`;
|
|
16299
|
+
console.log(import_chalk8.default.red(`
|
|
16300
|
+
${err}
|
|
16301
|
+
`));
|
|
16302
|
+
process.exit(1);
|
|
16303
|
+
}
|
|
16304
|
+
console.log(import_chalk8.default.green(`
|
|
16305
|
+
\u2713 deleted "${name}" from your account
|
|
16306
|
+
`));
|
|
16307
|
+
} catch (err) {
|
|
16308
|
+
console.log(import_chalk8.default.red(`
|
|
16309
|
+
${err.message || "delete failed"}
|
|
16310
|
+
`));
|
|
16311
|
+
process.exit(1);
|
|
16312
|
+
}
|
|
16313
|
+
} else {
|
|
16314
|
+
console.log(import_chalk8.default.yellow("\n not signed in \u2014 deleting local profile only\n"));
|
|
16315
|
+
}
|
|
16316
|
+
if (fs8.existsSync(localPath)) {
|
|
16317
|
+
fs8.unlinkSync(localPath);
|
|
16318
|
+
console.log(import_chalk8.default.dim(` removed ${localPath}`));
|
|
16319
|
+
}
|
|
16320
|
+
}
|
|
16321
|
+
async function editLocalProfile(name) {
|
|
16322
|
+
const localKey = toSafeProfileCacheKey(name);
|
|
16323
|
+
const localPath = path8.join(os6.homedir(), ".hyv", "profiles", `${localKey}.md`);
|
|
16324
|
+
if (!fs8.existsSync(localPath)) {
|
|
16325
|
+
console.log(import_chalk8.default.yellow(`
|
|
16326
|
+
no local profile at ${localPath}`));
|
|
16327
|
+
console.log(import_chalk8.default.dim(" run `hyv sync` or `hyv welcome` first\n"));
|
|
16328
|
+
process.exit(1);
|
|
16329
|
+
}
|
|
16330
|
+
const editor = process.env.EDITOR || process.env.VISUAL || (process.platform === "win32" ? "notepad" : "nano");
|
|
16331
|
+
const result = (0, import_child_process2.spawnSync)(editor, [localPath], { stdio: "inherit", shell: process.platform === "win32" });
|
|
16332
|
+
if (result.status !== 0) {
|
|
16333
|
+
process.exit(result.status || 1);
|
|
16334
|
+
}
|
|
16335
|
+
console.log(import_chalk8.default.green(`
|
|
16336
|
+
\u2713 saved ${localPath}`));
|
|
16337
|
+
console.log(import_chalk8.default.dim(" sync to account: hyv sync\n"));
|
|
16338
|
+
}
|
|
16154
16339
|
async function showProfileHistory(slug) {
|
|
16155
16340
|
const { authenticatedRequest: authenticatedRequest2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
16156
16341
|
const token = getToken();
|
|
@@ -16990,7 +17175,7 @@ function registerImportCommand(program3) {
|
|
|
16990
17175
|
});
|
|
16991
17176
|
}
|
|
16992
17177
|
function askQuestion(question) {
|
|
16993
|
-
return new Promise((
|
|
17178
|
+
return new Promise((resolve16) => {
|
|
16994
17179
|
const readline3 = require("readline");
|
|
16995
17180
|
const rl = readline3.createInterface({
|
|
16996
17181
|
input: process.stdin,
|
|
@@ -16999,7 +17184,7 @@ function askQuestion(question) {
|
|
|
16999
17184
|
rl.question(import_chalk13.default.cyan(` ${question}
|
|
17000
17185
|
> `), (answer) => {
|
|
17001
17186
|
rl.close();
|
|
17002
|
-
|
|
17187
|
+
resolve16(answer.trim());
|
|
17003
17188
|
});
|
|
17004
17189
|
});
|
|
17005
17190
|
}
|
|
@@ -17558,7 +17743,7 @@ hyv scan ${filePath}`));
|
|
|
17558
17743
|
var import_chalk19 = __toESM(require_source());
|
|
17559
17744
|
var fs19 = __toESM(require("fs"));
|
|
17560
17745
|
var path18 = __toESM(require("path"));
|
|
17561
|
-
var
|
|
17746
|
+
var os10 = __toESM(require("os"));
|
|
17562
17747
|
init_config();
|
|
17563
17748
|
init_auth();
|
|
17564
17749
|
init_access();
|
|
@@ -17566,7 +17751,7 @@ init_local_profile();
|
|
|
17566
17751
|
init_version();
|
|
17567
17752
|
|
|
17568
17753
|
// src/lib/mcp-stdio-test.ts
|
|
17569
|
-
var
|
|
17754
|
+
var import_child_process4 = require("child_process");
|
|
17570
17755
|
|
|
17571
17756
|
// src/lib/cli-entry.ts
|
|
17572
17757
|
var fs18 = __toESM(require("fs"));
|
|
@@ -17596,8 +17781,8 @@ async function testMcpStdioSubprocess() {
|
|
|
17596
17781
|
const entry = resolveCliEntry();
|
|
17597
17782
|
if (!entry)
|
|
17598
17783
|
return { ok: false };
|
|
17599
|
-
return new Promise((
|
|
17600
|
-
const child = (0,
|
|
17784
|
+
return new Promise((resolve16) => {
|
|
17785
|
+
const child = (0, import_child_process4.spawn)(process.execPath, [entry, "mcp"], {
|
|
17601
17786
|
stdio: ["pipe", "pipe", "pipe"],
|
|
17602
17787
|
env: { ...process.env, HYV_POSTINSTALL_QUIET: "1" }
|
|
17603
17788
|
});
|
|
@@ -17612,7 +17797,7 @@ async function testMcpStdioSubprocess() {
|
|
|
17612
17797
|
child.kill();
|
|
17613
17798
|
} catch {
|
|
17614
17799
|
}
|
|
17615
|
-
|
|
17800
|
+
resolve16({ ok, toolCount });
|
|
17616
17801
|
};
|
|
17617
17802
|
const timeout = setTimeout(() => finish(false), 1e4);
|
|
17618
17803
|
const handleLine = (line) => {
|
|
@@ -17663,7 +17848,7 @@ async function testMcpStdioSubprocess() {
|
|
|
17663
17848
|
}
|
|
17664
17849
|
|
|
17665
17850
|
// src/commands/doctor.ts
|
|
17666
|
-
var HOME =
|
|
17851
|
+
var HOME = os10.homedir();
|
|
17667
17852
|
var IS_WIN = process.platform === "win32";
|
|
17668
17853
|
function claudeDesktopDir() {
|
|
17669
17854
|
if (IS_WIN)
|
|
@@ -17874,7 +18059,7 @@ function registerDoctorCommand(program3) {
|
|
|
17874
18059
|
if (cursorMcp)
|
|
17875
18060
|
console.log(import_chalk19.default.green(" \u2713 mcp configured for cursor"));
|
|
17876
18061
|
} else {
|
|
17877
|
-
console.log(import_chalk19.default.yellow(" ! mcp not configured \u2014 run: hyv
|
|
18062
|
+
console.log(import_chalk19.default.yellow(" ! mcp not configured \u2014 run: hyv mcp (auto-detect) or hyv doctor --fix-agents"));
|
|
17878
18063
|
issues++;
|
|
17879
18064
|
}
|
|
17880
18065
|
try {
|
|
@@ -18017,11 +18202,11 @@ async function confirmDestructiveWrite(options) {
|
|
|
18017
18202
|
const question = `
|
|
18018
18203
|
${label}
|
|
18019
18204
|
A .bak backup will be created. Proceed? [y/N] `;
|
|
18020
|
-
const answer = await new Promise((
|
|
18205
|
+
const answer = await new Promise((resolve16) => {
|
|
18021
18206
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
18022
18207
|
rl.question(question, (value) => {
|
|
18023
18208
|
rl.close();
|
|
18024
|
-
|
|
18209
|
+
resolve16(value.trim().toLowerCase());
|
|
18025
18210
|
});
|
|
18026
18211
|
});
|
|
18027
18212
|
return answer === "y" || answer === "yes";
|
|
@@ -18127,19 +18312,19 @@ function registerCheckCommand(program3) {
|
|
|
18127
18312
|
const profile = await loadProfileForCommand(options.profile);
|
|
18128
18313
|
let inputText = text;
|
|
18129
18314
|
if (text === "-") {
|
|
18130
|
-
const
|
|
18315
|
+
const fs32 = require("fs");
|
|
18131
18316
|
if (process.stdin.isTTY) {
|
|
18132
18317
|
console.error(import_chalk23.default.red("No input provided. Pipe content or pass text as argument."));
|
|
18133
18318
|
process.exit(1);
|
|
18134
18319
|
}
|
|
18135
|
-
inputText =
|
|
18320
|
+
inputText = fs32.readFileSync(0, "utf-8");
|
|
18136
18321
|
}
|
|
18137
18322
|
if (!inputText.trim()) {
|
|
18138
18323
|
console.error(import_chalk23.default.red("No text provided."));
|
|
18139
18324
|
process.exit(1);
|
|
18140
18325
|
}
|
|
18141
|
-
const
|
|
18142
|
-
if (text !== "-" &&
|
|
18326
|
+
const fs31 = require("fs");
|
|
18327
|
+
if (text !== "-" && fs31.existsSync(text)) {
|
|
18143
18328
|
console.log(import_chalk23.default.yellow(`"${text}" looks like a file. Did you mean: hyv scan ${text}`));
|
|
18144
18329
|
process.exit(1);
|
|
18145
18330
|
}
|
|
@@ -18266,12 +18451,12 @@ function registerDiffCommand(program3) {
|
|
|
18266
18451
|
${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} available`));
|
|
18267
18452
|
console.log(import_chalk25.default.dim(` run: hyv fix ${file} -i to apply`));
|
|
18268
18453
|
if (options.apply && filePath !== "stdin") {
|
|
18269
|
-
const
|
|
18270
|
-
const
|
|
18454
|
+
const fs31 = require("fs");
|
|
18455
|
+
const path28 = require("path");
|
|
18271
18456
|
const backupPath = filePath + ".bak";
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${
|
|
18457
|
+
fs31.copyFileSync(filePath, backupPath);
|
|
18458
|
+
fs31.writeFileSync(filePath, result.fixed);
|
|
18459
|
+
console.log(import_chalk25.default.green(` \u2713 Applied. Backup: ${path28.basename(backupPath)}`));
|
|
18275
18460
|
}
|
|
18276
18461
|
} catch (error) {
|
|
18277
18462
|
console.error(import_chalk25.default.red(`Error: ${error.message}`));
|
|
@@ -18812,8 +18997,8 @@ init_welcome();
|
|
|
18812
18997
|
// src/lib/onboarding.ts
|
|
18813
18998
|
var fs24 = __toESM(require("fs"));
|
|
18814
18999
|
var path22 = __toESM(require("path"));
|
|
18815
|
-
var
|
|
18816
|
-
var hyvDir = path22.join(
|
|
19000
|
+
var os11 = __toESM(require("os"));
|
|
19001
|
+
var hyvDir = path22.join(os11.homedir(), ".hyv");
|
|
18817
19002
|
var onboardingFile = path22.join(hyvDir, "onboarding-complete.json");
|
|
18818
19003
|
function hasCompletedOnboarding() {
|
|
18819
19004
|
try {
|
|
@@ -18986,9 +19171,9 @@ function registerUpgradeCommand(program3) {
|
|
|
18986
19171
|
}
|
|
18987
19172
|
|
|
18988
19173
|
// src/mcp.ts
|
|
18989
|
-
var
|
|
18990
|
-
var
|
|
18991
|
-
var
|
|
19174
|
+
var fs27 = __toESM(require("fs"));
|
|
19175
|
+
var path25 = __toESM(require("path"));
|
|
19176
|
+
var os13 = __toESM(require("os"));
|
|
18992
19177
|
init_classifier();
|
|
18993
19178
|
init_autofix();
|
|
18994
19179
|
init_validator();
|
|
@@ -18996,23 +19181,262 @@ init_pipeline();
|
|
|
18996
19181
|
init_signals();
|
|
18997
19182
|
init_local_profile();
|
|
18998
19183
|
init_welcome();
|
|
18999
|
-
init_config();
|
|
19000
19184
|
init_telemetry();
|
|
19001
19185
|
init_access();
|
|
19002
|
-
|
|
19186
|
+
|
|
19187
|
+
// src/lib/mcp-integrate.ts
|
|
19188
|
+
var import_chalk32 = __toESM(require_source());
|
|
19189
|
+
var fs26 = __toESM(require("fs"));
|
|
19190
|
+
var os12 = __toESM(require("os"));
|
|
19191
|
+
var path24 = __toESM(require("path"));
|
|
19192
|
+
init_version();
|
|
19193
|
+
init_welcome_flow();
|
|
19194
|
+
init_config();
|
|
19195
|
+
init_local_profile();
|
|
19196
|
+
function resolveCliRoot() {
|
|
19197
|
+
const candidates = [
|
|
19198
|
+
path24.resolve(__dirname, ".."),
|
|
19199
|
+
path24.resolve(__dirname, "..", "..")
|
|
19200
|
+
];
|
|
19201
|
+
for (const root of candidates) {
|
|
19202
|
+
if (fs26.existsSync(path24.join(root, "scripts", "postinstall-lib.js"))) {
|
|
19203
|
+
return root;
|
|
19204
|
+
}
|
|
19205
|
+
}
|
|
19206
|
+
return candidates[0];
|
|
19207
|
+
}
|
|
19208
|
+
function loadPostinstallLib() {
|
|
19209
|
+
return require(path24.join(resolveCliRoot(), "scripts", "postinstall-lib.js"));
|
|
19210
|
+
}
|
|
19211
|
+
function runMcpAutoIntegrate(opts = {}) {
|
|
19212
|
+
const { integrateDetectedAgents } = loadPostinstallLib();
|
|
19213
|
+
return integrateDetectedAgents({
|
|
19214
|
+
pkgDir: resolveCliRoot(),
|
|
19215
|
+
quiet: true,
|
|
19216
|
+
force: Boolean(opts.force)
|
|
19217
|
+
});
|
|
19218
|
+
}
|
|
19219
|
+
function listLocalProfileNames2() {
|
|
19220
|
+
return [.../* @__PURE__ */ new Set([...listCachedProfiles(), ...listDiskCachedProfiles()])].sort();
|
|
19221
|
+
}
|
|
19222
|
+
function buildOnboardingStatusLines() {
|
|
19223
|
+
const lines = [];
|
|
19224
|
+
const welcome = readWelcomeState();
|
|
19225
|
+
const profiles = listLocalProfileNames2();
|
|
19226
|
+
const onboarded = hasCompletedOnboarding();
|
|
19227
|
+
const config = readConfig();
|
|
19228
|
+
const active = config.default_profile || config.profile;
|
|
19229
|
+
if (profiles.length > 0) {
|
|
19230
|
+
const activeNote = active && profiles.includes(active) ? ` (default: ${active})` : "";
|
|
19231
|
+
lines.push(`voice profiles (MCP-ready): ${profiles.join(", ")}${activeNote}`);
|
|
19232
|
+
} else {
|
|
19233
|
+
lines.push("voice profiles: none on this machine yet");
|
|
19234
|
+
lines.push("dashboard profile \u2192 run `hyv init` once; terminal `hyv welcome` \u2192 saved locally automatically");
|
|
19235
|
+
}
|
|
19236
|
+
if (welcome.profile_name) {
|
|
19237
|
+
lines.push(`welcome progress: profile name "${welcome.profile_name}"`);
|
|
19238
|
+
}
|
|
19239
|
+
if (welcome.completed_steps?.length) {
|
|
19240
|
+
const done = welcome.completed_steps.map((key) => FLOW_STEPS.find((s) => s.key === key)?.title || key).join(", ");
|
|
19241
|
+
lines.push(`welcome steps done: ${done}`);
|
|
19242
|
+
} else if (!onboarded) {
|
|
19243
|
+
lines.push("welcome steps: not started (or only partial)");
|
|
19244
|
+
}
|
|
19245
|
+
lines.push("free without profile: hyv_scan, hyv_demo, hyv_fix, hyv_check work offline");
|
|
19246
|
+
lines.push("with profile: hyv_rewrite, hyv_validate, hyv_clean use your voice rules");
|
|
19247
|
+
return lines;
|
|
19248
|
+
}
|
|
19249
|
+
function formatChatGptConnectorGuide() {
|
|
19250
|
+
const lib = loadPostinstallLib();
|
|
19251
|
+
const mcpCmd = lib.resolveHyvMcpCommand(resolveCliRoot());
|
|
19252
|
+
const guidePath = path24.join(os12.homedir(), ".chatgpt", "hyv-mcp-connector.txt");
|
|
19253
|
+
const lines = [
|
|
19254
|
+
"### ChatGPT Desktop connector (manual \u2014 no auto-config file)",
|
|
19255
|
+
"",
|
|
19256
|
+
"1. Open ChatGPT **desktop** app (browser chat cannot use local MCP)",
|
|
19257
|
+
"2. Settings \u2192 Connectors \u2192 Add connector",
|
|
19258
|
+
"3. Name: **hold your voice**",
|
|
19259
|
+
"4. Command: **hyv**",
|
|
19260
|
+
"5. Arguments: **mcp**",
|
|
19261
|
+
"",
|
|
19262
|
+
"If the connector fails to start, use absolute paths:",
|
|
19263
|
+
` command: ${mcpCmd.command}`,
|
|
19264
|
+
` arguments: ${mcpCmd.args.join(" ")}`,
|
|
19265
|
+
"",
|
|
19266
|
+
"6. Save, restart ChatGPT Desktop",
|
|
19267
|
+
'7. Ask: "run hyv_welcome" or "scan this draft with hold your voice"',
|
|
19268
|
+
""
|
|
19269
|
+
];
|
|
19270
|
+
if (fs26.existsSync(guidePath)) {
|
|
19271
|
+
lines.push(`Full guide on disk: ${guidePath}`);
|
|
19272
|
+
} else {
|
|
19273
|
+
lines.push("Run `hyv mcp` or `hyv doctor --fix-agents` to write the guide file.");
|
|
19274
|
+
}
|
|
19275
|
+
return lines.join("\n");
|
|
19276
|
+
}
|
|
19277
|
+
function buildMcpAgentStatus() {
|
|
19278
|
+
const {
|
|
19279
|
+
detectInstalledAgents,
|
|
19280
|
+
isAgentIntegrated,
|
|
19281
|
+
resolveHyvMcpCommand
|
|
19282
|
+
} = loadPostinstallLib();
|
|
19283
|
+
const home = os12.homedir();
|
|
19284
|
+
const detected = detectInstalledAgents(home);
|
|
19285
|
+
const mcpCmd = resolveHyvMcpCommand(resolveCliRoot());
|
|
19286
|
+
const lines = [
|
|
19287
|
+
"### HYV MCP status",
|
|
19288
|
+
"",
|
|
19289
|
+
`mcp server command: ${mcpCmd.command} ${mcpCmd.args.join(" ")}`,
|
|
19290
|
+
"",
|
|
19291
|
+
...buildOnboardingStatusLines().map((l) => `- ${l}`),
|
|
19292
|
+
""
|
|
19293
|
+
];
|
|
19294
|
+
if (detected.length === 0) {
|
|
19295
|
+
lines.push("### Installed apps");
|
|
19296
|
+
lines.push("- none detected \u2014 install Cursor, Claude Desktop, ChatGPT Desktop, etc.");
|
|
19297
|
+
lines.push("- then run `hyv mcp` in terminal or call hyv_mcp_setup with action=integrate");
|
|
19298
|
+
lines.push("");
|
|
19299
|
+
lines.push(formatChatGptConnectorGuide());
|
|
19300
|
+
return lines.join("\n");
|
|
19301
|
+
}
|
|
19302
|
+
lines.push("### Installed apps");
|
|
19303
|
+
for (const app of detected) {
|
|
19304
|
+
const integrated = isAgentIntegrated(app.id, home);
|
|
19305
|
+
const status = app.integration === "manual" ? integrated ? "guide written" : "add connector manually" : integrated ? "integrated" : "needs setup";
|
|
19306
|
+
lines.push(`- ${app.label}: ${status} (${app.integration})`);
|
|
19307
|
+
}
|
|
19308
|
+
lines.push("");
|
|
19309
|
+
lines.push("### In this chat (no terminal needed)");
|
|
19310
|
+
lines.push("- Which profile is active \u2192 hyv_profiles");
|
|
19311
|
+
lines.push("- New or partial setup \u2192 hyv_welcome (steps 1\u20134, or mode=extract_prompt for voice from chat)");
|
|
19312
|
+
lines.push("- Refresh app configs \u2192 hyv_mcp_setup with action=integrate (force=true after hyv upgrade)");
|
|
19313
|
+
lines.push("- ChatGPT connector steps \u2192 hyv_mcp_setup with action=chatgpt");
|
|
19314
|
+
lines.push("- Test free scan \u2192 hyv_demo or hyv_scan on any draft");
|
|
19315
|
+
return lines.join("\n");
|
|
19316
|
+
}
|
|
19317
|
+
function formatMcpIntegrateReportText(result, opts = {}) {
|
|
19318
|
+
const { agentIdForConfiguredLabel, isAgentIntegrated } = loadPostinstallLib();
|
|
19319
|
+
const configuredIds = new Set(
|
|
19320
|
+
result.configured.map((label) => agentIdForConfiguredLabel(label)).filter(Boolean)
|
|
19321
|
+
);
|
|
19322
|
+
const lines = [
|
|
19323
|
+
"### HYV MCP integration",
|
|
19324
|
+
"",
|
|
19325
|
+
...buildOnboardingStatusLines().map((l) => `- ${l}`),
|
|
19326
|
+
""
|
|
19327
|
+
];
|
|
19328
|
+
if (result.detected.length === 0) {
|
|
19329
|
+
lines.push("No supported AI apps detected on this machine.");
|
|
19330
|
+
lines.push("Install Cursor, Claude Desktop, Windsurf, or ChatGPT Desktop, then run integrate again.");
|
|
19331
|
+
lines.push("");
|
|
19332
|
+
lines.push(formatChatGptConnectorGuide());
|
|
19333
|
+
return lines.join("\n");
|
|
19334
|
+
}
|
|
19335
|
+
lines.push("### Apps");
|
|
19336
|
+
for (const app of result.detected) {
|
|
19337
|
+
const justConfigured = configuredIds.has(app.id);
|
|
19338
|
+
const integrated = isAgentIntegrated(app.id) || justConfigured;
|
|
19339
|
+
const status = app.integration === "manual" ? "manual connector" : justConfigured ? opts.force ? "updated now" : "configured now" : integrated ? "integrated" : "needs setup";
|
|
19340
|
+
lines.push(`- ${app.label}: ${status}`);
|
|
19341
|
+
}
|
|
19342
|
+
if (result.configured.length > 0) {
|
|
19343
|
+
lines.push("");
|
|
19344
|
+
lines.push(`Wired: ${result.configured.join(", ")}`);
|
|
19345
|
+
}
|
|
19346
|
+
if (result.warnings.length > 0) {
|
|
19347
|
+
lines.push("");
|
|
19348
|
+
lines.push("Notes:");
|
|
19349
|
+
for (const warning of result.warnings) {
|
|
19350
|
+
lines.push(`- ${warning}`);
|
|
19351
|
+
}
|
|
19352
|
+
}
|
|
19353
|
+
lines.push("");
|
|
19354
|
+
lines.push("Restart MCP hosts (Cursor, Claude Desktop, Antigravity, OpenCode) after config changes.");
|
|
19355
|
+
if (result.detected.some((a) => a.integration === "manual")) {
|
|
19356
|
+
lines.push("");
|
|
19357
|
+
lines.push(formatChatGptConnectorGuide());
|
|
19358
|
+
}
|
|
19359
|
+
return lines.join("\n");
|
|
19360
|
+
}
|
|
19361
|
+
function printMcpIntegrateReport(result, opts = {}) {
|
|
19362
|
+
const { agentIdForConfiguredLabel, isAgentIntegrated } = loadPostinstallLib();
|
|
19363
|
+
const configuredIds = new Set(
|
|
19364
|
+
result.configured.map((label) => agentIdForConfiguredLabel(label)).filter(Boolean)
|
|
19365
|
+
);
|
|
19366
|
+
console.log(import_chalk32.default.bold("\nhold your voice \u2014 mcp integration\n"));
|
|
19367
|
+
console.log(import_chalk32.default.dim(` ${getEngineLabel()}
|
|
19368
|
+
`));
|
|
19369
|
+
const welcome = readWelcomeState();
|
|
19370
|
+
const profiles = listLocalProfileNames2();
|
|
19371
|
+
if (profiles.length > 0) {
|
|
19372
|
+
console.log(import_chalk32.default.dim(` voice profiles: ${profiles.join(", ")}`));
|
|
19373
|
+
} else {
|
|
19374
|
+
console.log(import_chalk32.default.yellow(" no voice profile yet \u2014 mcp still works (free scan). finish onboarding in terminal or in-chat via hyv_welcome"));
|
|
19375
|
+
}
|
|
19376
|
+
if (welcome.completed_steps?.length) {
|
|
19377
|
+
console.log(import_chalk32.default.dim(` welcome progress: ${welcome.completed_steps.join(", ")}`));
|
|
19378
|
+
}
|
|
19379
|
+
console.log("");
|
|
19380
|
+
if (result.detected.length === 0) {
|
|
19381
|
+
console.log(import_chalk32.default.yellow(" no supported ai apps detected on this machine."));
|
|
19382
|
+
console.log(import_chalk32.default.dim("\n install cursor, claude desktop, chatgpt desktop, or another supported app,"));
|
|
19383
|
+
console.log(import_chalk32.default.dim(" then run hyv mcp again \u2014 or hyv doctor --fix-agents to configure everything."));
|
|
19384
|
+
console.log(import_chalk32.default.dim("\n in chatgpt/claude/cursor: call hyv_welcome to onboard without the terminal."));
|
|
19385
|
+
console.log(import_chalk32.default.dim(" chatgpt desktop: hyv mcp --setup-chatgpt\n"));
|
|
19386
|
+
return;
|
|
19387
|
+
}
|
|
19388
|
+
console.log(import_chalk32.default.bold("detected apps"));
|
|
19389
|
+
for (const app of result.detected) {
|
|
19390
|
+
const justConfigured = configuredIds.has(app.id);
|
|
19391
|
+
const integrated = isAgentIntegrated(app.id) || justConfigured;
|
|
19392
|
+
const mark = app.integration === "manual" ? import_chalk32.default.yellow("\u25CB") : integrated ? import_chalk32.default.green("\u2713") : import_chalk32.default.cyan("\u2192");
|
|
19393
|
+
const status = app.integration === "manual" ? "manual connector \u2014 see ~/.chatgpt/hyv-mcp-connector.txt" : justConfigured ? opts.force ? "updated now" : "configured now" : integrated ? "integrated" : "needs setup";
|
|
19394
|
+
console.log(` ${mark} ${app.label} \u2014 ${status}`);
|
|
19395
|
+
console.log(import_chalk32.default.dim(` ${app.reason} \xB7 ${app.integration}`));
|
|
19396
|
+
}
|
|
19397
|
+
if (result.configured.length > 0) {
|
|
19398
|
+
console.log(import_chalk32.default.green(`
|
|
19399
|
+
wired hyv into: ${result.configured.join(", ")}`));
|
|
19400
|
+
}
|
|
19401
|
+
if (result.warnings.length > 0) {
|
|
19402
|
+
console.log(import_chalk32.default.yellow("\n notes:"));
|
|
19403
|
+
for (const warning of result.warnings) {
|
|
19404
|
+
console.log(import_chalk32.default.yellow(` ! ${warning}`));
|
|
19405
|
+
}
|
|
19406
|
+
}
|
|
19407
|
+
const mcpApps = result.detected.filter((a) => a.integration === "mcp");
|
|
19408
|
+
const manualApps = result.detected.filter((a) => a.integration === "manual");
|
|
19409
|
+
console.log(import_chalk32.default.bold("\nnext steps"));
|
|
19410
|
+
console.log(import_chalk32.default.dim(" in this app: hyv_welcome (onboarding) \xB7 hyv_mcp_setup (status/refresh) \xB7 hyv_demo (try a scan)"));
|
|
19411
|
+
if (mcpApps.length > 0) {
|
|
19412
|
+
console.log(import_chalk32.default.dim(" restart apps that use mcp (cursor, claude desktop, antigravity, opencode)"));
|
|
19413
|
+
}
|
|
19414
|
+
if (manualApps.length > 0) {
|
|
19415
|
+
console.log(import_chalk32.default.dim(" chatgpt: settings \u2192 connectors \u2192 command hyv, arguments mcp"));
|
|
19416
|
+
console.log(import_chalk32.default.dim(" full steps: hyv mcp --setup-chatgpt"));
|
|
19417
|
+
}
|
|
19418
|
+
console.log(import_chalk32.default.dim(" refresh stale configs after upgrade: hyv mcp --force"));
|
|
19419
|
+
console.log(import_chalk32.default.dim(" verify: hyv mcp --test"));
|
|
19420
|
+
console.log(import_chalk32.default.dim(" all hosts: hyv doctor --verify-hosts\n"));
|
|
19421
|
+
}
|
|
19422
|
+
|
|
19423
|
+
// src/mcp.ts
|
|
19424
|
+
init_mcp_profile_hydrate();
|
|
19425
|
+
init_profile();
|
|
19426
|
+
var VOICE_MD = path25.join(os13.homedir(), ".hyv", "voice.md");
|
|
19003
19427
|
var MAX_RESPONSE_CHARS = 12e4;
|
|
19004
19428
|
var MAX_SCAN_FILE_BYTES = 2 * 1024 * 1024;
|
|
19005
19429
|
function readScanFile(filePath) {
|
|
19006
|
-
const cwdReal =
|
|
19007
|
-
const resolved =
|
|
19008
|
-
if (!resolved.startsWith(cwdReal +
|
|
19430
|
+
const cwdReal = fs27.realpathSync(process.cwd());
|
|
19431
|
+
const resolved = fs27.realpathSync(path25.resolve(filePath));
|
|
19432
|
+
if (!resolved.startsWith(cwdReal + path25.sep) && resolved !== cwdReal) {
|
|
19009
19433
|
throw new Error(`file must be in the current working directory (${cwdReal})`);
|
|
19010
19434
|
}
|
|
19011
|
-
const stat =
|
|
19435
|
+
const stat = fs27.statSync(resolved);
|
|
19012
19436
|
if (stat.size > MAX_SCAN_FILE_BYTES) {
|
|
19013
19437
|
throw new Error(`file too large (max ${MAX_SCAN_FILE_BYTES} bytes)`);
|
|
19014
19438
|
}
|
|
19015
|
-
return
|
|
19439
|
+
return fs27.readFileSync(resolved, "utf-8");
|
|
19016
19440
|
}
|
|
19017
19441
|
function toolResultPayload(result) {
|
|
19018
19442
|
const isError = result.startsWith("Error:") || result.startsWith("Unknown tool:");
|
|
@@ -19021,20 +19445,22 @@ function toolResultPayload(result) {
|
|
|
19021
19445
|
...isError ? { isError: true } : {}
|
|
19022
19446
|
};
|
|
19023
19447
|
}
|
|
19024
|
-
var pkgPath =
|
|
19448
|
+
var pkgPath = path25.resolve(__dirname, "..", "package.json");
|
|
19025
19449
|
var pkgVersion = (() => {
|
|
19026
19450
|
try {
|
|
19027
|
-
return JSON.parse(
|
|
19451
|
+
return JSON.parse(fs27.readFileSync(pkgPath, "utf-8")).version;
|
|
19028
19452
|
} catch {
|
|
19029
19453
|
return "2.7.1";
|
|
19030
19454
|
}
|
|
19031
19455
|
})();
|
|
19032
|
-
async function resolveProfile(slug
|
|
19033
|
-
|
|
19034
|
-
|
|
19035
|
-
|
|
19036
|
-
|
|
19037
|
-
|
|
19456
|
+
async function resolveProfile(slug) {
|
|
19457
|
+
await ensureMcpProfilesHydrated();
|
|
19458
|
+
let profile = await loadProfileForCommand(slug, { allowServerFetch: true });
|
|
19459
|
+
if (!profile && slug) {
|
|
19460
|
+
try {
|
|
19461
|
+
profile = await loadFullProfile(normalizeProfileSlug(slug), { forceRefresh: true });
|
|
19462
|
+
} catch {
|
|
19463
|
+
}
|
|
19038
19464
|
}
|
|
19039
19465
|
return profile;
|
|
19040
19466
|
}
|
|
@@ -19134,27 +19560,8 @@ async function toolScan(args2) {
|
|
|
19134
19560
|
}
|
|
19135
19561
|
}
|
|
19136
19562
|
async function toolProfiles(_args) {
|
|
19137
|
-
const
|
|
19138
|
-
|
|
19139
|
-
return "Cached profiles (local):\n" + local.map((p) => ` \u2022 ${p}`).join("\n");
|
|
19140
|
-
}
|
|
19141
|
-
try {
|
|
19142
|
-
const { apiGet: apiGet2 } = await Promise.resolve().then(() => (init_api(), api_exports));
|
|
19143
|
-
const data = await apiGet2("/cli/profiles");
|
|
19144
|
-
const profiles = data.profiles || [];
|
|
19145
|
-
if (profiles.length === 0) {
|
|
19146
|
-
return "No voice profiles found. Free local scan works without a profile. Run: hyv init";
|
|
19147
|
-
}
|
|
19148
|
-
return profiles.map(
|
|
19149
|
-
(p) => `${p.name}${p.is_default ? " (default)" : ""}${p.keywords?.length ? " \u2014 " + p.keywords.slice(0, 3).join(", ") : ""}`
|
|
19150
|
-
).join("\n");
|
|
19151
|
-
} catch (err) {
|
|
19152
|
-
const msg = err.message || "";
|
|
19153
|
-
if (msg.includes("session expired") || msg.includes("not signed in")) {
|
|
19154
|
-
return "Not signed in. Free local scan/fix/check work offline. Run `hyv init` for profiles.";
|
|
19155
|
-
}
|
|
19156
|
-
return `Cached profiles: none. Free local engine ready. (${msg})`;
|
|
19157
|
-
}
|
|
19563
|
+
const hydrate = await ensureMcpProfilesHydrated();
|
|
19564
|
+
return formatMcpProfilesList(hydrate);
|
|
19158
19565
|
}
|
|
19159
19566
|
async function toolValidate(args2) {
|
|
19160
19567
|
const text = args2.text || "";
|
|
@@ -19262,6 +19669,22 @@ function toolListFreeTools() {
|
|
|
19262
19669
|
function toolDemo() {
|
|
19263
19670
|
return getDemoText();
|
|
19264
19671
|
}
|
|
19672
|
+
function toolMcpSetup(args2 = {}) {
|
|
19673
|
+
const action = (args2.action || "status").toLowerCase();
|
|
19674
|
+
const force = Boolean(args2.force);
|
|
19675
|
+
switch (action) {
|
|
19676
|
+
case "status":
|
|
19677
|
+
return buildMcpAgentStatus();
|
|
19678
|
+
case "integrate": {
|
|
19679
|
+
const result = runMcpAutoIntegrate({ force });
|
|
19680
|
+
return formatMcpIntegrateReportText(result, { force });
|
|
19681
|
+
}
|
|
19682
|
+
case "chatgpt":
|
|
19683
|
+
return formatChatGptConnectorGuide();
|
|
19684
|
+
default:
|
|
19685
|
+
return `Error: unknown action "${args2.action}". Use status, integrate, or chatgpt.`;
|
|
19686
|
+
}
|
|
19687
|
+
}
|
|
19265
19688
|
async function toolAnalyze(args2) {
|
|
19266
19689
|
const text = args2.text || "";
|
|
19267
19690
|
if (!text.trim())
|
|
@@ -19356,6 +19779,23 @@ async function toolClean(args2) {
|
|
|
19356
19779
|
}
|
|
19357
19780
|
}
|
|
19358
19781
|
var TOOLS = [
|
|
19782
|
+
{
|
|
19783
|
+
name: "hyv_mcp_setup",
|
|
19784
|
+
description: "MCP host setup without terminal: status of installed apps, auto-integrate configs, or ChatGPT Desktop connector steps. Works with or without a voice profile \u2014 use hyv_welcome for onboarding.",
|
|
19785
|
+
inputSchema: {
|
|
19786
|
+
type: "object",
|
|
19787
|
+
properties: {
|
|
19788
|
+
action: {
|
|
19789
|
+
type: "string",
|
|
19790
|
+
description: "status (default) | integrate (wire hyv into Cursor/Claude/etc.) | chatgpt (desktop connector steps)"
|
|
19791
|
+
},
|
|
19792
|
+
force: {
|
|
19793
|
+
type: "boolean",
|
|
19794
|
+
description: "Refresh MCP configs even when already integrated (e.g. after hyv upgrade)"
|
|
19795
|
+
}
|
|
19796
|
+
}
|
|
19797
|
+
}
|
|
19798
|
+
},
|
|
19359
19799
|
{
|
|
19360
19800
|
name: "hyv_welcome",
|
|
19361
19801
|
description: "Profile-first onboarding: name \u2192 samples \u2192 test draft \u2192 signup. Call when the user is new. Use step (1-4) for one step, mode extract_prompt for chat voice extraction.",
|
|
@@ -19478,7 +19918,7 @@ var TOOLS = [
|
|
|
19478
19918
|
},
|
|
19479
19919
|
{
|
|
19480
19920
|
name: "hyv_profiles",
|
|
19481
|
-
description: "List
|
|
19921
|
+
description: "List voice profiles ready for MCP tools (local + account after hyv init). Shows active default. Call before hyv_rewrite/hyv_clean if unsure which profile to use.",
|
|
19482
19922
|
inputSchema: { type: "object", properties: {} }
|
|
19483
19923
|
},
|
|
19484
19924
|
{
|
|
@@ -19503,14 +19943,15 @@ var PROMPTS = [
|
|
|
19503
19943
|
];
|
|
19504
19944
|
var HYV_STATUS_PROMPT = `Use hold your voice MCP tools:
|
|
19505
19945
|
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19946
|
+
0. MCP setup \u2192 hyv_mcp_setup (status | integrate | chatgpt). Profiles \u2192 hyv_profiles (lists MCP-ready profiles).
|
|
19947
|
+
1. Profiles work automatically: terminal \`hyv welcome\` saves locally; dashboard profiles need \`hyv init\` once on this machine (MCP auto-syncs).
|
|
19948
|
+
2. New onboarding in chat \u2192 hyv_welcome. Step 2: mode=extract_prompt. Save markdown \u2192 hyv import or dashboard.
|
|
19949
|
+
3. Writing (use active profile from hyv_profiles): hyv_scan \u2192 hyv_fix / hyv_rewrite \u2192 hyv_validate. Optional profile= slug.
|
|
19950
|
+
4. Paid extras \u2192 hyv init + hyv plan --upgrade (signup last).
|
|
19511
19951
|
|
|
19512
19952
|
Keep the answer compact.`;
|
|
19513
19953
|
var TOOL_HANDLERS = {
|
|
19954
|
+
hyv_mcp_setup: toolMcpSetup,
|
|
19514
19955
|
hyv_welcome: toolWelcome,
|
|
19515
19956
|
hyv_list_free_tools: () => toolListFreeTools(),
|
|
19516
19957
|
hyv_demo: () => toolDemo(),
|
|
@@ -19605,14 +20046,31 @@ async function handleRequest(line) {
|
|
|
19605
20046
|
}
|
|
19606
20047
|
async function startMcpServer() {
|
|
19607
20048
|
const access = await getAccessState().catch(() => null);
|
|
19608
|
-
|
|
20049
|
+
const config = (() => {
|
|
20050
|
+
try {
|
|
20051
|
+
return JSON.parse(fs27.readFileSync(path25.join(os13.homedir(), ".hyv", "config.json"), "utf-8"));
|
|
20052
|
+
} catch {
|
|
20053
|
+
return {};
|
|
20054
|
+
}
|
|
20055
|
+
})();
|
|
20056
|
+
const defaultProfile = config.default_profile || config.profile;
|
|
20057
|
+
if (defaultProfile) {
|
|
20058
|
+
mcpLog("info", `default profile: ${defaultProfile}`);
|
|
20059
|
+
} else if (fs27.existsSync(VOICE_MD)) {
|
|
19609
20060
|
mcpLog("info", `voice profile: ${VOICE_MD}`);
|
|
19610
20061
|
} else {
|
|
19611
|
-
mcpLog("info", "free local engine ready \u2014 no voice profile yet");
|
|
20062
|
+
mcpLog("info", "free local engine ready \u2014 no voice profile yet (hyv_profiles / hyv init)");
|
|
19612
20063
|
}
|
|
19613
20064
|
if (access) {
|
|
19614
20065
|
mcpLog("info", `mode: ${access.hasPaidPlan ? "paid" : "free local"}${access.authenticated ? "" : " (not signed in)"}`);
|
|
19615
20066
|
}
|
|
20067
|
+
ensureMcpProfilesHydrated().then((r) => {
|
|
20068
|
+
if (r.synced?.length)
|
|
20069
|
+
mcpLog("info", `synced account profiles: ${r.synced.join(", ")}`);
|
|
20070
|
+
else if (r.error)
|
|
20071
|
+
mcpLog("info", `account profile sync skipped: ${r.error}`);
|
|
20072
|
+
}).catch(() => {
|
|
20073
|
+
});
|
|
19616
20074
|
let buffer = "";
|
|
19617
20075
|
process.stdin.setEncoding("utf-8");
|
|
19618
20076
|
let requestChain = Promise.resolve();
|
|
@@ -19637,150 +20095,176 @@ async function startMcpServer() {
|
|
|
19637
20095
|
}
|
|
19638
20096
|
|
|
19639
20097
|
// src/lib/mcp-setup.ts
|
|
19640
|
-
var
|
|
19641
|
-
var
|
|
19642
|
-
var
|
|
19643
|
-
var
|
|
20098
|
+
var import_chalk33 = __toESM(require_source());
|
|
20099
|
+
var fs28 = __toESM(require("fs"));
|
|
20100
|
+
var path26 = __toESM(require("path"));
|
|
20101
|
+
var os14 = __toESM(require("os"));
|
|
19644
20102
|
init_version();
|
|
19645
|
-
var HOME2 =
|
|
20103
|
+
var HOME2 = os14.homedir();
|
|
19646
20104
|
var IS_WIN2 = process.platform === "win32";
|
|
19647
20105
|
function claudeDesktopConfigPath() {
|
|
19648
20106
|
if (IS_WIN2)
|
|
19649
|
-
return
|
|
20107
|
+
return path26.join(HOME2, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
|
|
19650
20108
|
if (process.platform === "linux")
|
|
19651
|
-
return
|
|
19652
|
-
return
|
|
20109
|
+
return path26.join(HOME2, ".config", "Claude", "claude_desktop_config.json");
|
|
20110
|
+
return path26.join(HOME2, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
19653
20111
|
}
|
|
19654
20112
|
function printMcpSetup() {
|
|
19655
|
-
console.log(
|
|
19656
|
-
console.log(
|
|
20113
|
+
console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp setup\n"));
|
|
20114
|
+
console.log(import_chalk33.default.dim(` ${getEngineLabel()}
|
|
19657
20115
|
`));
|
|
19658
|
-
console.log(
|
|
19659
|
-
console.log(
|
|
19660
|
-
console.log(
|
|
19661
|
-
console.log(
|
|
20116
|
+
console.log(import_chalk33.default.bold("Claude Desktop"));
|
|
20117
|
+
console.log(import_chalk33.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
|
|
20118
|
+
console.log(import_chalk33.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
|
|
20119
|
+
console.log(import_chalk33.default.dim(` Config: ${claudeDesktopConfigPath()}
|
|
19662
20120
|
`));
|
|
19663
|
-
console.log(
|
|
19664
|
-
console.log(
|
|
19665
|
-
console.log(
|
|
19666
|
-
console.log(
|
|
19667
|
-
console.log(
|
|
19668
|
-
console.log(
|
|
19669
|
-
console.log(
|
|
19670
|
-
console.log(
|
|
19671
|
-
console.log(
|
|
19672
|
-
console.log(
|
|
19673
|
-
console.log(
|
|
19674
|
-
console.log(
|
|
19675
|
-
console.log(
|
|
19676
|
-
console.log(
|
|
19677
|
-
console.log(
|
|
19678
|
-
console.log(
|
|
19679
|
-
console.log(
|
|
19680
|
-
console.log(
|
|
19681
|
-
console.log(
|
|
19682
|
-
console.log(
|
|
19683
|
-
console.log(
|
|
19684
|
-
console.log(
|
|
19685
|
-
console.log(
|
|
19686
|
-
console.log(
|
|
19687
|
-
console.log(
|
|
19688
|
-
console.log(
|
|
19689
|
-
console.log(
|
|
19690
|
-
console.log(
|
|
20121
|
+
console.log(import_chalk33.default.bold("Cursor"));
|
|
20122
|
+
console.log(import_chalk33.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
|
|
20123
|
+
console.log(import_chalk33.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
|
|
20124
|
+
console.log(import_chalk33.default.bold("Claude Code"));
|
|
20125
|
+
console.log(import_chalk33.default.dim(" Command: ~/.claude/commands/hyv.md"));
|
|
20126
|
+
console.log(import_chalk33.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
|
|
20127
|
+
console.log(import_chalk33.default.bold("Windsurf"));
|
|
20128
|
+
console.log(import_chalk33.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
|
|
20129
|
+
console.log(import_chalk33.default.bold("Codex"));
|
|
20130
|
+
console.log(import_chalk33.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
|
|
20131
|
+
console.log(import_chalk33.default.bold("Command Code"));
|
|
20132
|
+
console.log(import_chalk33.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
|
|
20133
|
+
console.log(import_chalk33.default.bold("ChatGPT Desktop (manual connector)"));
|
|
20134
|
+
console.log(import_chalk33.default.dim(" Settings \u2192 Connectors \u2192 add connector"));
|
|
20135
|
+
console.log(import_chalk33.default.dim(" Name: hold your voice | Command: hyv | Arguments: mcp"));
|
|
20136
|
+
console.log(import_chalk33.default.dim(" Guide: ~/.chatgpt/hyv-mcp-connector.txt (after hyv doctor --fix-agents)"));
|
|
20137
|
+
console.log(import_chalk33.default.dim(" hyv mcp --setup-chatgpt\n"));
|
|
20138
|
+
console.log(import_chalk33.default.bold("Antigravity"));
|
|
20139
|
+
console.log(import_chalk33.default.dim(" MCP: ~/.gemini/config/mcp_config.json \u2192 mcpServers.hyv (auto via postinstall)\n"));
|
|
20140
|
+
console.log(import_chalk33.default.bold("OpenCode"));
|
|
20141
|
+
console.log(import_chalk33.default.dim(" MCP: ~/.config/opencode/opencode.jsonc \u2192 mcp.hyv (auto via postinstall)"));
|
|
20142
|
+
console.log(import_chalk33.default.dim(" Rules: ~/.config/opencode/AGENTS.md\n"));
|
|
20143
|
+
console.log(import_chalk33.default.bold("Auto-configure"));
|
|
20144
|
+
console.log(import_chalk33.default.dim(" hyv mcp (detect installed apps + wire mcp into them)"));
|
|
20145
|
+
console.log(import_chalk33.default.dim(" hyv mcp --force (refresh configs after hyv upgrade)"));
|
|
20146
|
+
console.log(import_chalk33.default.dim(" hyv doctor --fix-agents (configure all apps, not just detected)"));
|
|
20147
|
+
console.log(import_chalk33.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
|
|
20148
|
+
console.log(import_chalk33.default.bold("In-chat (no terminal)"));
|
|
20149
|
+
console.log(import_chalk33.default.dim(" hyv_mcp_setup \u2014 status, integrate, or chatgpt connector steps"));
|
|
20150
|
+
console.log(import_chalk33.default.dim(" hyv_welcome \u2014 finish onboarding inside Cursor/Claude/ChatGPT\n"));
|
|
20151
|
+
console.log(import_chalk33.default.bold("Verify"));
|
|
20152
|
+
console.log(import_chalk33.default.dim(" hyv mcp --test"));
|
|
20153
|
+
console.log(import_chalk33.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
|
|
19691
20154
|
}
|
|
19692
20155
|
async function runMcpSelfTest() {
|
|
19693
|
-
console.log(
|
|
19694
|
-
console.log(
|
|
20156
|
+
console.log(import_chalk33.default.bold("\nhold your voice \u2014 mcp self-test\n"));
|
|
20157
|
+
console.log(import_chalk33.default.dim(` ${getEngineLabel()}
|
|
19695
20158
|
`));
|
|
19696
20159
|
let passed = 0;
|
|
19697
20160
|
let failed = 0;
|
|
19698
20161
|
const tools = getMcpToolNames();
|
|
19699
20162
|
if (tools.length >= 10) {
|
|
19700
|
-
console.log(
|
|
20163
|
+
console.log(import_chalk33.default.green(` \u2713 ${tools.length} MCP tools registered`));
|
|
19701
20164
|
passed++;
|
|
19702
20165
|
} else {
|
|
19703
|
-
console.log(
|
|
20166
|
+
console.log(import_chalk33.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
|
|
19704
20167
|
failed++;
|
|
19705
20168
|
}
|
|
19706
|
-
const required = [
|
|
20169
|
+
const required = [
|
|
20170
|
+
"hyv_mcp_setup",
|
|
20171
|
+
"hyv_welcome",
|
|
20172
|
+
"hyv_scan",
|
|
20173
|
+
"hyv_analyze",
|
|
20174
|
+
"hyv_clean",
|
|
20175
|
+
"hyv_validate",
|
|
20176
|
+
"hyv_list_free_tools"
|
|
20177
|
+
];
|
|
19707
20178
|
for (const name of required) {
|
|
19708
20179
|
if (tools.includes(name)) {
|
|
19709
|
-
console.log(
|
|
20180
|
+
console.log(import_chalk33.default.green(` \u2713 tool: ${name}`));
|
|
19710
20181
|
passed++;
|
|
19711
20182
|
} else {
|
|
19712
|
-
console.log(
|
|
20183
|
+
console.log(import_chalk33.default.red(` \u2717 missing tool: ${name}`));
|
|
19713
20184
|
failed++;
|
|
19714
20185
|
}
|
|
19715
20186
|
}
|
|
19716
20187
|
try {
|
|
19717
20188
|
const welcome = await invokeMcpTool("hyv_welcome", {});
|
|
19718
20189
|
if (welcome.includes("Hold Your Voice") || welcome.includes("hold your voice")) {
|
|
19719
|
-
console.log(
|
|
20190
|
+
console.log(import_chalk33.default.green(" \u2713 hyv_welcome responds"));
|
|
19720
20191
|
passed++;
|
|
19721
20192
|
} else {
|
|
19722
|
-
console.log(
|
|
20193
|
+
console.log(import_chalk33.default.red(" \u2717 hyv_welcome unexpected output"));
|
|
19723
20194
|
failed++;
|
|
19724
20195
|
}
|
|
19725
20196
|
} catch (e) {
|
|
19726
|
-
console.log(
|
|
20197
|
+
console.log(import_chalk33.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
|
|
20198
|
+
failed++;
|
|
20199
|
+
}
|
|
20200
|
+
try {
|
|
20201
|
+
const setup = await invokeMcpTool("hyv_mcp_setup", { action: "status" });
|
|
20202
|
+
if (setup.includes("HYV MCP status") && setup.includes("hyv_welcome")) {
|
|
20203
|
+
console.log(import_chalk33.default.green(" \u2713 hyv_mcp_setup responds"));
|
|
20204
|
+
passed++;
|
|
20205
|
+
} else {
|
|
20206
|
+
console.log(import_chalk33.default.red(" \u2717 hyv_mcp_setup unexpected output"));
|
|
20207
|
+
failed++;
|
|
20208
|
+
}
|
|
20209
|
+
} catch (e) {
|
|
20210
|
+
console.log(import_chalk33.default.red(` \u2717 hyv_mcp_setup failed: ${e.message}`));
|
|
19727
20211
|
failed++;
|
|
19728
20212
|
}
|
|
19729
20213
|
try {
|
|
19730
20214
|
const demo = await invokeMcpTool("hyv_demo", {});
|
|
19731
20215
|
if (demo.includes("Score") || demo.includes("issues")) {
|
|
19732
|
-
console.log(
|
|
20216
|
+
console.log(import_chalk33.default.green(" \u2713 hyv_demo pipeline works"));
|
|
19733
20217
|
passed++;
|
|
19734
20218
|
} else {
|
|
19735
|
-
console.log(
|
|
20219
|
+
console.log(import_chalk33.default.red(" \u2717 hyv_demo unexpected output"));
|
|
19736
20220
|
failed++;
|
|
19737
20221
|
}
|
|
19738
20222
|
} catch (e) {
|
|
19739
|
-
console.log(
|
|
20223
|
+
console.log(import_chalk33.default.red(` \u2717 hyv_demo failed: ${e.message}`));
|
|
19740
20224
|
failed++;
|
|
19741
20225
|
}
|
|
19742
|
-
const voiceMd =
|
|
19743
|
-
if (
|
|
19744
|
-
console.log(
|
|
20226
|
+
const voiceMd = path26.join(HOME2, ".hyv", "voice.md");
|
|
20227
|
+
if (fs28.existsSync(voiceMd)) {
|
|
20228
|
+
console.log(import_chalk33.default.green(" \u2713 voice profile found"));
|
|
19745
20229
|
passed++;
|
|
19746
20230
|
} else {
|
|
19747
|
-
console.log(
|
|
20231
|
+
console.log(import_chalk33.default.dim(" - no voice.md (free local engine still works)"));
|
|
19748
20232
|
}
|
|
19749
20233
|
if (getDemoText().length > 100) {
|
|
19750
|
-
console.log(
|
|
20234
|
+
console.log(import_chalk33.default.green(" \u2713 demo content available"));
|
|
19751
20235
|
passed++;
|
|
19752
20236
|
} else {
|
|
19753
|
-
console.log(
|
|
20237
|
+
console.log(import_chalk33.default.red(" \u2717 demo content missing"));
|
|
19754
20238
|
failed++;
|
|
19755
20239
|
}
|
|
19756
20240
|
try {
|
|
19757
20241
|
const stdio = await testMcpStdioSubprocess();
|
|
19758
20242
|
if (stdio.ok && (stdio.toolCount || 0) >= 10) {
|
|
19759
|
-
console.log(
|
|
20243
|
+
console.log(import_chalk33.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
|
|
19760
20244
|
passed++;
|
|
19761
20245
|
} else if (stdio.ok) {
|
|
19762
|
-
console.log(
|
|
20246
|
+
console.log(import_chalk33.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
|
|
19763
20247
|
failed++;
|
|
19764
20248
|
} else {
|
|
19765
|
-
console.log(
|
|
20249
|
+
console.log(import_chalk33.default.red(" \u2717 stdio MCP subprocess failed"));
|
|
19766
20250
|
failed++;
|
|
19767
20251
|
}
|
|
19768
20252
|
} catch (e) {
|
|
19769
|
-
console.log(
|
|
20253
|
+
console.log(import_chalk33.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
|
|
19770
20254
|
failed++;
|
|
19771
20255
|
}
|
|
19772
20256
|
console.log("");
|
|
19773
20257
|
if (failed === 0) {
|
|
19774
|
-
console.log(
|
|
19775
|
-
console.log(
|
|
20258
|
+
console.log(import_chalk33.default.green(`\u2713 all checks passed (${passed})`));
|
|
20259
|
+
console.log(import_chalk33.default.dim("\nStart server: hyv mcp\n"));
|
|
19776
20260
|
return true;
|
|
19777
20261
|
}
|
|
19778
|
-
console.log(
|
|
20262
|
+
console.log(import_chalk33.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
|
|
19779
20263
|
return false;
|
|
19780
20264
|
}
|
|
19781
20265
|
|
|
19782
20266
|
// src/commands/export.ts
|
|
19783
|
-
var
|
|
20267
|
+
var fs29 = __toESM(require("fs"));
|
|
19784
20268
|
init_api();
|
|
19785
20269
|
var FORMATS = {
|
|
19786
20270
|
claude: {
|
|
@@ -19867,7 +20351,7 @@ async function exportCommand(format, opts) {
|
|
|
19867
20351
|
const prompt = fmt.wrap(detail.profile, detail.body);
|
|
19868
20352
|
if (opts.output) {
|
|
19869
20353
|
const outFile = opts.output.replace("{name}", profile.slug || profile.name);
|
|
19870
|
-
|
|
20354
|
+
fs29.writeFileSync(outFile, prompt);
|
|
19871
20355
|
results.push({ profile: profile.name, file: outFile });
|
|
19872
20356
|
} else {
|
|
19873
20357
|
results.push({ profile: profile.name, prompt });
|
|
@@ -19904,13 +20388,13 @@ async function exportCommand(format, opts) {
|
|
|
19904
20388
|
// src/index.ts
|
|
19905
20389
|
init_access();
|
|
19906
20390
|
init_welcome();
|
|
19907
|
-
var
|
|
19908
|
-
var
|
|
20391
|
+
var fs30 = __toESM(require("fs"));
|
|
20392
|
+
var path27 = __toESM(require("path"));
|
|
19909
20393
|
var program2 = new Command();
|
|
19910
|
-
var pkgPath2 =
|
|
20394
|
+
var pkgPath2 = path27.resolve(__dirname, "..", "package.json");
|
|
19911
20395
|
var pkgVersion2 = (() => {
|
|
19912
20396
|
try {
|
|
19913
|
-
return JSON.parse(
|
|
20397
|
+
return JSON.parse(fs30.readFileSync(pkgPath2, "utf-8")).version;
|
|
19914
20398
|
} catch {
|
|
19915
20399
|
return "2.7.1";
|
|
19916
20400
|
}
|
|
@@ -19943,7 +20427,7 @@ registerOpenCommand(program2);
|
|
|
19943
20427
|
registerWelcomeCommand(program2);
|
|
19944
20428
|
registerContentCommand(program2);
|
|
19945
20429
|
registerUpgradeCommand(program2);
|
|
19946
|
-
program2.command("mcp").description("
|
|
20430
|
+
program2.command("mcp").description("Detect local AI apps, wire hyv MCP into them, or start stdio server for hosts").option("--setup", "Show MCP setup for Claude Desktop, Cursor, Windsurf, Codex").option("--test", "Run MCP health check (tools, profile, stdio)").option("--setup-chatgpt", "Show ChatGPT connector setup instructions").option("--force", "Refresh MCP configs even when already integrated (e.g. after hyv upgrade)").option("--stdio", "Start MCP stdio server (used by Cursor, Claude Desktop, etc.)").option("--integrate-only", "Detect and configure apps without starting stdio server").action(async (opts) => {
|
|
19947
20431
|
if (opts.setup) {
|
|
19948
20432
|
printMcpSetup();
|
|
19949
20433
|
return;
|
|
@@ -19954,26 +20438,21 @@ program2.command("mcp").description("Start MCP server (for Claude Desktop and ot
|
|
|
19954
20438
|
return;
|
|
19955
20439
|
}
|
|
19956
20440
|
if (opts.setupChatgpt) {
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
console.log(
|
|
19960
|
-
console.log("ChatGPT
|
|
19961
|
-
console.log(import_chalk33.default.dim(" 1. Install hyv: ") + import_chalk33.default.cyan("npm i -g @holdyourvoice/hyv@latest && hyv welcome"));
|
|
19962
|
-
console.log(import_chalk33.default.dim(" 2. Open ") + import_chalk33.default.cyan("https://chatgpt.com/#settings/Connectors"));
|
|
19963
|
-
console.log(import_chalk33.default.dim(" 3. Add connector"));
|
|
19964
|
-
console.log(import_chalk33.default.dim(" 4. Name: ") + import_chalk33.default.cyan("hold your voice"));
|
|
19965
|
-
console.log(import_chalk33.default.dim(" 5. Command: ") + import_chalk33.default.cyan("hyv"));
|
|
19966
|
-
console.log(import_chalk33.default.dim(" 6. Arguments: ") + import_chalk33.default.cyan("mcp"));
|
|
19967
|
-
console.log(import_chalk33.default.dim(" 7. Save, restart ChatGPT Desktop, ask: scan this with hold your voice"));
|
|
19968
|
-
console.log("");
|
|
19969
|
-
if (require("fs").existsSync(guide)) {
|
|
19970
|
-
console.log(import_chalk33.default.dim(`Full guide written to: ${guide}`));
|
|
19971
|
-
} else {
|
|
19972
|
-
console.log(import_chalk33.default.dim("Run hyv doctor --fix-agents to write ~/.chatgpt/hyv-mcp-connector.txt"));
|
|
19973
|
-
}
|
|
19974
|
-
console.log(import_chalk33.default.dim("\nBrowser chatgpt cannot use local MCP \u2014 desktop app only."));
|
|
20441
|
+
console.log(import_chalk34.default.bold("\nhold your voice \u2014 chatgpt desktop mcp setup\n"));
|
|
20442
|
+
console.log(formatChatGptConnectorGuide());
|
|
20443
|
+
console.log(import_chalk34.default.dim("\nBrowser chatgpt cannot use local MCP \u2014 desktop app only."));
|
|
20444
|
+
console.log(import_chalk34.default.dim("In ChatGPT chat: call hyv_mcp_setup or hyv_welcome \u2014 no terminal needed.\n"));
|
|
19975
20445
|
return;
|
|
19976
20446
|
}
|
|
20447
|
+
const wantsIntegrate = Boolean(opts.integrateOnly || process.stdin.isTTY);
|
|
20448
|
+
if (wantsIntegrate) {
|
|
20449
|
+
const integrateOpts = { force: Boolean(opts.force) };
|
|
20450
|
+
const result = runMcpAutoIntegrate(integrateOpts);
|
|
20451
|
+
printMcpIntegrateReport(result, integrateOpts);
|
|
20452
|
+
if (!opts.stdio)
|
|
20453
|
+
return;
|
|
20454
|
+
console.log(import_chalk34.default.dim("starting stdio mcp server for local testing (ctrl+c to stop)\u2026\n"));
|
|
20455
|
+
}
|
|
19977
20456
|
startMcpServer();
|
|
19978
20457
|
});
|
|
19979
20458
|
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) => {
|