@holdyourvoice/hyv 2.8.8 → 2.8.9
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 +12 -0
- package/README.md +25 -2
- package/dist/index.js +592 -444
- package/package.json +3 -2
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 path24 = require("node:path");
|
|
977
|
+
var fs25 = 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 = path24.resolve(baseDir, baseName);
|
|
1920
|
+
if (fs25.existsSync(localBin))
|
|
1921
1921
|
return localBin;
|
|
1922
|
-
if (sourceExt.includes(
|
|
1922
|
+
if (sourceExt.includes(path24.extname(baseName)))
|
|
1923
1923
|
return void 0;
|
|
1924
1924
|
const foundExt = sourceExt.find(
|
|
1925
|
-
(ext) =>
|
|
1925
|
+
(ext) => fs25.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 = fs25.realpathSync(this._scriptPath);
|
|
1939
1939
|
} catch (err) {
|
|
1940
1940
|
resolvedScriptPath = this._scriptPath;
|
|
1941
1941
|
}
|
|
1942
|
-
executableDir =
|
|
1943
|
-
|
|
1942
|
+
executableDir = path24.resolve(
|
|
1943
|
+
path24.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 = path24.basename(
|
|
1951
1951
|
this._scriptPath,
|
|
1952
|
-
|
|
1952
|
+
path24.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(path24.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 = path24.basename(filename, path24.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(path25) {
|
|
2835
|
+
if (path25 === void 0)
|
|
2836
2836
|
return this._executableDir;
|
|
2837
|
-
this._executableDir =
|
|
2837
|
+
this._executableDir = path25;
|
|
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 path24 = [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
|
+
path24.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 = path24;
|
|
3946
3946
|
return fn;
|
|
3947
3947
|
}
|
|
3948
3948
|
module2.exports = function(fromModel) {
|
|
@@ -4381,14 +4381,14 @@ var require_templates = __commonJS({
|
|
|
4381
4381
|
}
|
|
4382
4382
|
return results;
|
|
4383
4383
|
}
|
|
4384
|
-
function buildStyle(
|
|
4384
|
+
function buildStyle(chalk32, 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 = chalk32;
|
|
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 = (chalk32, 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(chalk32, 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(chalk32, 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 chalk33 = {};
|
|
4468
|
+
applyOptions(chalk33, options);
|
|
4469
|
+
chalk33.template = (...arguments_) => chalkTag(chalk33.template, ...arguments_);
|
|
4470
|
+
Object.setPrototypeOf(chalk33, Chalk.prototype);
|
|
4471
|
+
Object.setPrototypeOf(chalk33.template, chalk33);
|
|
4472
|
+
chalk33.template.constructor = () => {
|
|
4473
4473
|
throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
|
|
4474
4474
|
};
|
|
4475
|
-
|
|
4476
|
-
return
|
|
4475
|
+
chalk33.template.Instance = ChalkClass;
|
|
4476
|
+
return chalk33.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 = (chalk33, ...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(chalk33, parts.join(""));
|
|
4604
4604
|
};
|
|
4605
4605
|
Object.defineProperties(Chalk.prototype, styles);
|
|
4606
|
-
var
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
module2.exports =
|
|
4606
|
+
var chalk32 = Chalk();
|
|
4607
|
+
chalk32.supportsColor = stdoutColor;
|
|
4608
|
+
chalk32.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
4609
|
+
chalk32.stderr.supportsColor = stderrColor;
|
|
4610
|
+
module2.exports = chalk32;
|
|
4611
4611
|
}
|
|
4612
4612
|
});
|
|
4613
4613
|
|
|
@@ -4834,11 +4834,11 @@ var init_config = __esm({
|
|
|
4834
4834
|
var require_is_docker = __commonJS({
|
|
4835
4835
|
"node_modules/is-docker/index.js"(exports2, module2) {
|
|
4836
4836
|
"use strict";
|
|
4837
|
-
var
|
|
4837
|
+
var fs25 = require("fs");
|
|
4838
4838
|
var isDocker;
|
|
4839
4839
|
function hasDockerEnv() {
|
|
4840
4840
|
try {
|
|
4841
|
-
|
|
4841
|
+
fs25.statSync("/.dockerenv");
|
|
4842
4842
|
return true;
|
|
4843
4843
|
} catch (_) {
|
|
4844
4844
|
return false;
|
|
@@ -4846,7 +4846,7 @@ var require_is_docker = __commonJS({
|
|
|
4846
4846
|
}
|
|
4847
4847
|
function hasDockerCGroup() {
|
|
4848
4848
|
try {
|
|
4849
|
-
return
|
|
4849
|
+
return fs25.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
4850
4850
|
} catch (_) {
|
|
4851
4851
|
return false;
|
|
4852
4852
|
}
|
|
@@ -4865,7 +4865,7 @@ var require_is_wsl = __commonJS({
|
|
|
4865
4865
|
"node_modules/is-wsl/index.js"(exports2, module2) {
|
|
4866
4866
|
"use strict";
|
|
4867
4867
|
var os9 = require("os");
|
|
4868
|
-
var
|
|
4868
|
+
var fs25 = require("fs");
|
|
4869
4869
|
var isDocker = require_is_docker();
|
|
4870
4870
|
var isWsl = () => {
|
|
4871
4871
|
if (process.platform !== "linux") {
|
|
@@ -4878,7 +4878,7 @@ var require_is_wsl = __commonJS({
|
|
|
4878
4878
|
return true;
|
|
4879
4879
|
}
|
|
4880
4880
|
try {
|
|
4881
|
-
return
|
|
4881
|
+
return fs25.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
|
|
4882
4882
|
} catch (_) {
|
|
4883
4883
|
return false;
|
|
4884
4884
|
}
|
|
@@ -4917,17 +4917,17 @@ var require_define_lazy_prop = __commonJS({
|
|
|
4917
4917
|
// node_modules/open/index.js
|
|
4918
4918
|
var require_open = __commonJS({
|
|
4919
4919
|
"node_modules/open/index.js"(exports2, module2) {
|
|
4920
|
-
var
|
|
4920
|
+
var path24 = require("path");
|
|
4921
4921
|
var childProcess = require("child_process");
|
|
4922
|
-
var { promises:
|
|
4922
|
+
var { promises: fs25, constants: fsConstants } = require("fs");
|
|
4923
4923
|
var isWsl = require_is_wsl();
|
|
4924
4924
|
var isDocker = require_is_docker();
|
|
4925
4925
|
var defineLazyProperty = require_define_lazy_prop();
|
|
4926
|
-
var localXdgOpenPath =
|
|
4926
|
+
var localXdgOpenPath = path24.join(__dirname, "xdg-open");
|
|
4927
4927
|
var { platform, arch } = process;
|
|
4928
4928
|
var hasContainerEnv = () => {
|
|
4929
4929
|
try {
|
|
4930
|
-
|
|
4930
|
+
fs25.statSync("/run/.containerenv");
|
|
4931
4931
|
return true;
|
|
4932
4932
|
} catch {
|
|
4933
4933
|
return false;
|
|
@@ -4950,14 +4950,14 @@ var require_open = __commonJS({
|
|
|
4950
4950
|
const configFilePath = "/etc/wsl.conf";
|
|
4951
4951
|
let isConfigFileExists = false;
|
|
4952
4952
|
try {
|
|
4953
|
-
await
|
|
4953
|
+
await fs25.access(configFilePath, fsConstants.F_OK);
|
|
4954
4954
|
isConfigFileExists = true;
|
|
4955
4955
|
} catch {
|
|
4956
4956
|
}
|
|
4957
4957
|
if (!isConfigFileExists) {
|
|
4958
4958
|
return defaultMountPoint;
|
|
4959
4959
|
}
|
|
4960
|
-
const configContent = await
|
|
4960
|
+
const configContent = await fs25.readFile(configFilePath, { encoding: "utf8" });
|
|
4961
4961
|
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
4962
4962
|
if (!configMountPoint) {
|
|
4963
4963
|
return defaultMountPoint;
|
|
@@ -5057,7 +5057,7 @@ var require_open = __commonJS({
|
|
|
5057
5057
|
const isBundled = !__dirname || __dirname === "/";
|
|
5058
5058
|
let exeLocalXdgOpen = false;
|
|
5059
5059
|
try {
|
|
5060
|
-
await
|
|
5060
|
+
await fs25.access(localXdgOpenPath, fsConstants.X_OK);
|
|
5061
5061
|
exeLocalXdgOpen = true;
|
|
5062
5062
|
} catch {
|
|
5063
5063
|
}
|
|
@@ -5244,6 +5244,33 @@ var init_version = __esm({
|
|
|
5244
5244
|
}
|
|
5245
5245
|
});
|
|
5246
5246
|
|
|
5247
|
+
// src/lib/auth-refresh.ts
|
|
5248
|
+
function tokenExpiresAtMs(expiresAt) {
|
|
5249
|
+
if (!expiresAt)
|
|
5250
|
+
return null;
|
|
5251
|
+
const ms = new Date(expiresAt).getTime();
|
|
5252
|
+
return Number.isFinite(ms) ? ms : null;
|
|
5253
|
+
}
|
|
5254
|
+
function shouldRefreshToken(expiresAt, now = Date.now()) {
|
|
5255
|
+
const expiresMs = tokenExpiresAtMs(expiresAt);
|
|
5256
|
+
if (expiresMs === null)
|
|
5257
|
+
return false;
|
|
5258
|
+
return expiresMs <= now + REFRESH_LEAD_MS;
|
|
5259
|
+
}
|
|
5260
|
+
function isTokenExpired(expiresAt, now = Date.now()) {
|
|
5261
|
+
const expiresMs = tokenExpiresAtMs(expiresAt);
|
|
5262
|
+
if (expiresMs === null)
|
|
5263
|
+
return false;
|
|
5264
|
+
return expiresMs < now;
|
|
5265
|
+
}
|
|
5266
|
+
var REFRESH_LEAD_MS;
|
|
5267
|
+
var init_auth_refresh = __esm({
|
|
5268
|
+
"src/lib/auth-refresh.ts"() {
|
|
5269
|
+
"use strict";
|
|
5270
|
+
REFRESH_LEAD_MS = 5 * 60 * 1e3;
|
|
5271
|
+
}
|
|
5272
|
+
});
|
|
5273
|
+
|
|
5247
5274
|
// src/lib/auth.ts
|
|
5248
5275
|
var auth_exports = {};
|
|
5249
5276
|
__export(auth_exports, {
|
|
@@ -5252,8 +5279,14 @@ __export(auth_exports, {
|
|
|
5252
5279
|
authenticatedRequest: () => authenticatedRequest,
|
|
5253
5280
|
checkSession: () => checkSession,
|
|
5254
5281
|
getValidToken: () => getValidToken,
|
|
5255
|
-
refreshToken: () => refreshToken
|
|
5282
|
+
refreshToken: () => refreshToken,
|
|
5283
|
+
verifyOAuthState: () => verifyOAuthState
|
|
5256
5284
|
});
|
|
5285
|
+
function verifyOAuthState(received, expected) {
|
|
5286
|
+
if (!received || !expected || received !== expected) {
|
|
5287
|
+
throw new Error("OAuth state mismatch \u2014 possible CSRF attempt");
|
|
5288
|
+
}
|
|
5289
|
+
}
|
|
5257
5290
|
function escapeHtml(value) {
|
|
5258
5291
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
5259
5292
|
}
|
|
@@ -5300,16 +5333,12 @@ async function getValidToken() {
|
|
|
5300
5333
|
const auth = readAuth();
|
|
5301
5334
|
if (!auth?.token)
|
|
5302
5335
|
return null;
|
|
5303
|
-
if (auth.expires_at) {
|
|
5304
|
-
const
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
return getToken();
|
|
5310
|
-
if (expires.getTime() < Date.now())
|
|
5311
|
-
return null;
|
|
5312
|
-
}
|
|
5336
|
+
if (shouldRefreshToken(auth.expires_at)) {
|
|
5337
|
+
const ok = await refreshToken(auth.token);
|
|
5338
|
+
if (ok)
|
|
5339
|
+
return getToken();
|
|
5340
|
+
if (isTokenExpired(auth.expires_at))
|
|
5341
|
+
return null;
|
|
5313
5342
|
}
|
|
5314
5343
|
return auth.token;
|
|
5315
5344
|
}
|
|
@@ -5382,12 +5411,14 @@ async function authenticateWithBrowser() {
|
|
|
5382
5411
|
reject(new Error("Invalid callback parameters"));
|
|
5383
5412
|
return;
|
|
5384
5413
|
}
|
|
5385
|
-
|
|
5414
|
+
try {
|
|
5415
|
+
verifyOAuthState(state, expectedState);
|
|
5416
|
+
} catch (stateErr) {
|
|
5386
5417
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
5387
5418
|
res.end("<h1>Authentication failed</h1><p>Invalid OAuth state.</p>");
|
|
5388
5419
|
clearTimeout(timeout);
|
|
5389
5420
|
server.close();
|
|
5390
|
-
reject(
|
|
5421
|
+
reject(stateErr);
|
|
5391
5422
|
return;
|
|
5392
5423
|
}
|
|
5393
5424
|
try {
|
|
@@ -5481,6 +5512,7 @@ var init_auth = __esm({
|
|
|
5481
5512
|
import_open = __toESM(require_open());
|
|
5482
5513
|
init_config();
|
|
5483
5514
|
init_version();
|
|
5515
|
+
init_auth_refresh();
|
|
5484
5516
|
}
|
|
5485
5517
|
});
|
|
5486
5518
|
|
|
@@ -5641,11 +5673,11 @@ __export(api_exports, {
|
|
|
5641
5673
|
apiPost: () => apiPost,
|
|
5642
5674
|
requireSubscription: () => requireSubscription
|
|
5643
5675
|
});
|
|
5644
|
-
async function request2(method,
|
|
5676
|
+
async function request2(method, path24, body) {
|
|
5645
5677
|
const token = await getValidToken();
|
|
5646
5678
|
if (!token)
|
|
5647
5679
|
throw new Error("you're not signed in yet. run: hyv init");
|
|
5648
|
-
const url = `${API_BASE}${
|
|
5680
|
+
const url = `${API_BASE}${path24}`;
|
|
5649
5681
|
const opts = {
|
|
5650
5682
|
method,
|
|
5651
5683
|
headers: {
|
|
@@ -5670,11 +5702,11 @@ async function request2(method, path23, body) {
|
|
|
5670
5702
|
}
|
|
5671
5703
|
return res.json();
|
|
5672
5704
|
}
|
|
5673
|
-
function apiGet(
|
|
5674
|
-
return request2("GET",
|
|
5705
|
+
function apiGet(path24) {
|
|
5706
|
+
return request2("GET", path24);
|
|
5675
5707
|
}
|
|
5676
|
-
function apiPost(
|
|
5677
|
-
return request2("POST",
|
|
5708
|
+
function apiPost(path24, body) {
|
|
5709
|
+
return request2("POST", path24, body);
|
|
5678
5710
|
}
|
|
5679
5711
|
async function requireSubscription() {
|
|
5680
5712
|
const { requirePaidFeature: requirePaidFeature2 } = await Promise.resolve().then(() => (init_access(), access_exports));
|
|
@@ -7246,26 +7278,26 @@ function runPipeline(text, profile, applyFixes = false) {
|
|
|
7246
7278
|
};
|
|
7247
7279
|
}
|
|
7248
7280
|
function readText(source) {
|
|
7249
|
-
const
|
|
7250
|
-
const
|
|
7281
|
+
const fs25 = require("fs");
|
|
7282
|
+
const path24 = require("path");
|
|
7251
7283
|
if (source === "-") {
|
|
7252
7284
|
if (process.stdin.isTTY) {
|
|
7253
7285
|
console.error("No input provided. Pipe content or specify a file.");
|
|
7254
7286
|
process.exit(1);
|
|
7255
7287
|
}
|
|
7256
|
-
return { text:
|
|
7288
|
+
return { text: fs25.readFileSync(0, "utf-8"), path: "stdin" };
|
|
7257
7289
|
}
|
|
7258
|
-
const resolved =
|
|
7259
|
-
if (!
|
|
7290
|
+
const resolved = path24.resolve(source);
|
|
7291
|
+
if (!fs25.existsSync(resolved)) {
|
|
7260
7292
|
console.error(`File not found: ${resolved}`);
|
|
7261
7293
|
process.exit(1);
|
|
7262
7294
|
}
|
|
7263
|
-
const stat =
|
|
7295
|
+
const stat = fs25.statSync(resolved);
|
|
7264
7296
|
if (stat.isDirectory()) {
|
|
7265
7297
|
console.error(`${resolved} is a directory, not a file.`);
|
|
7266
7298
|
process.exit(1);
|
|
7267
7299
|
}
|
|
7268
|
-
return { text:
|
|
7300
|
+
return { text: fs25.readFileSync(resolved, "utf-8"), path: resolved };
|
|
7269
7301
|
}
|
|
7270
7302
|
var init_pipeline = __esm({
|
|
7271
7303
|
"src/lib/pipeline.ts"() {
|
|
@@ -8273,7 +8305,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
8273
8305
|
g.minimatch.escape = vi.escape;
|
|
8274
8306
|
g.minimatch.unescape = Ei.unescape;
|
|
8275
8307
|
});
|
|
8276
|
-
var
|
|
8308
|
+
var fs25 = R((Wt) => {
|
|
8277
8309
|
"use strict";
|
|
8278
8310
|
Object.defineProperty(Wt, "__esModule", { value: true });
|
|
8279
8311
|
Wt.LRUCache = void 0;
|
|
@@ -9242,7 +9274,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
9242
9274
|
};
|
|
9243
9275
|
Object.defineProperty(_, "__esModule", { value: true });
|
|
9244
9276
|
_.PathScurry = _.Path = _.PathScurryDarwin = _.PathScurryPosix = _.PathScurryWin32 = _.PathScurryBase = _.PathPosix = _.PathWin32 = _.PathBase = _.ChildrenCache = _.ResolveCache = void 0;
|
|
9245
|
-
var Qt =
|
|
9277
|
+
var Qt = fs25(), Yt = require("node:path"), yr = require("node:url"), pt = require("fs"), Sr = br(require("node:fs")), vr = pt.realpathSync.native, Ht = require("node:fs/promises"), bs = Oe(), mt = { lstatSync: pt.lstatSync, readdir: pt.readdir, readdirSync: pt.readdirSync, readlinkSync: pt.readlinkSync, realpathSync: vr, promises: { lstat: Ht.lstat, readdir: Ht.readdir, readlink: Ht.readlink, realpath: Ht.realpath } }, _s = (n) => !n || n === mt || n === Sr ? mt : { ...mt, ...n, promises: { ...mt.promises, ...n.promises || {} } }, Os = /^\\\\\?\\([a-z]:)\\?$/i, Er = (n) => n.replace(/\//g, "\\").replace(Os, "$1\\"), _r = /[\\\/]/, N = 0, xs = 1, Ts = 2, G = 4, Cs = 6, Rs = 8, Q = 10, As = 12, j = 15, dt = ~j, xe = 16, ys = 32, gt = 64, W = 128, Vt = 256, Xt = 512, Ss = gt | W | Xt, Or = 1023, Te = (n) => n.isFile() ? Rs : n.isDirectory() ? G : n.isSymbolicLink() ? Q : n.isCharacterDevice() ? Ts : n.isBlockDevice() ? Cs : n.isSocket() ? As : n.isFIFO() ? xs : N, vs = new Qt.LRUCache({ max: 2 ** 12 }), wt = (n) => {
|
|
9246
9278
|
let t = vs.get(n);
|
|
9247
9279
|
if (t)
|
|
9248
9280
|
return t;
|
|
@@ -10761,7 +10793,7 @@ var {
|
|
|
10761
10793
|
} = import_index.default;
|
|
10762
10794
|
|
|
10763
10795
|
// src/index.ts
|
|
10764
|
-
var
|
|
10796
|
+
var import_chalk31 = __toESM(require_source());
|
|
10765
10797
|
|
|
10766
10798
|
// src/commands/init.ts
|
|
10767
10799
|
var import_chalk4 = __toESM(require_source());
|
|
@@ -12454,8 +12486,8 @@ function registerImportCommand(program3) {
|
|
|
12454
12486
|
}
|
|
12455
12487
|
function askQuestion(question) {
|
|
12456
12488
|
return new Promise((resolve14) => {
|
|
12457
|
-
const
|
|
12458
|
-
const rl =
|
|
12489
|
+
const readline2 = require("readline");
|
|
12490
|
+
const rl = readline2.createInterface({
|
|
12459
12491
|
input: process.stdin,
|
|
12460
12492
|
output: process.stdout
|
|
12461
12493
|
});
|
|
@@ -13040,28 +13072,137 @@ hyv scan ${filePath}`));
|
|
|
13040
13072
|
|
|
13041
13073
|
// src/commands/doctor.ts
|
|
13042
13074
|
var import_chalk16 = __toESM(require_source());
|
|
13043
|
-
var
|
|
13044
|
-
var
|
|
13075
|
+
var fs14 = __toESM(require("fs"));
|
|
13076
|
+
var path15 = __toESM(require("path"));
|
|
13045
13077
|
var os5 = __toESM(require("os"));
|
|
13046
13078
|
init_config();
|
|
13047
13079
|
init_auth();
|
|
13048
13080
|
init_access();
|
|
13049
13081
|
init_local_profile();
|
|
13050
13082
|
init_version();
|
|
13083
|
+
|
|
13084
|
+
// src/lib/mcp-stdio-test.ts
|
|
13085
|
+
var import_child_process2 = require("child_process");
|
|
13086
|
+
|
|
13087
|
+
// src/lib/cli-entry.ts
|
|
13088
|
+
var fs13 = __toESM(require("fs"));
|
|
13089
|
+
var path14 = __toESM(require("path"));
|
|
13090
|
+
function resolveCliEntry() {
|
|
13091
|
+
const candidates = [
|
|
13092
|
+
path14.resolve(process.argv[1] || ""),
|
|
13093
|
+
path14.resolve(__dirname, "index.js"),
|
|
13094
|
+
path14.resolve(__dirname, "..", "dist", "index.js")
|
|
13095
|
+
];
|
|
13096
|
+
return candidates.find((p) => p && fs13.existsSync(p)) || null;
|
|
13097
|
+
}
|
|
13098
|
+
function mcpServerCommand() {
|
|
13099
|
+
const entry = resolveCliEntry();
|
|
13100
|
+
if (entry) {
|
|
13101
|
+
return { command: process.execPath, args: [entry, "mcp"] };
|
|
13102
|
+
}
|
|
13103
|
+
return { command: "hyv", args: ["mcp"] };
|
|
13104
|
+
}
|
|
13105
|
+
function mcpServerSnippet() {
|
|
13106
|
+
const { command, args: args2 } = mcpServerCommand();
|
|
13107
|
+
return JSON.stringify({ command, args: args2 }, null, 2);
|
|
13108
|
+
}
|
|
13109
|
+
|
|
13110
|
+
// src/lib/mcp-stdio-test.ts
|
|
13111
|
+
async function testMcpStdioSubprocess() {
|
|
13112
|
+
const entry = resolveCliEntry();
|
|
13113
|
+
if (!entry)
|
|
13114
|
+
return { ok: false };
|
|
13115
|
+
return new Promise((resolve14) => {
|
|
13116
|
+
const child = (0, import_child_process2.spawn)(process.execPath, [entry, "mcp"], {
|
|
13117
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13118
|
+
env: { ...process.env, HYV_POSTINSTALL_QUIET: "1" }
|
|
13119
|
+
});
|
|
13120
|
+
let buffer = "";
|
|
13121
|
+
let settled = false;
|
|
13122
|
+
const finish = (ok, toolCount) => {
|
|
13123
|
+
if (settled)
|
|
13124
|
+
return;
|
|
13125
|
+
settled = true;
|
|
13126
|
+
clearTimeout(timeout);
|
|
13127
|
+
try {
|
|
13128
|
+
child.kill();
|
|
13129
|
+
} catch {
|
|
13130
|
+
}
|
|
13131
|
+
resolve14({ ok, toolCount });
|
|
13132
|
+
};
|
|
13133
|
+
const timeout = setTimeout(() => finish(false), 1e4);
|
|
13134
|
+
const handleLine = (line) => {
|
|
13135
|
+
const trimmed = line.trim();
|
|
13136
|
+
if (!trimmed.startsWith("{"))
|
|
13137
|
+
return;
|
|
13138
|
+
try {
|
|
13139
|
+
const msg = JSON.parse(trimmed);
|
|
13140
|
+
if (msg.id === 2 && Array.isArray(msg.result?.tools) && msg.result.tools.length > 0) {
|
|
13141
|
+
finish(true, msg.result.tools.length);
|
|
13142
|
+
}
|
|
13143
|
+
} catch {
|
|
13144
|
+
}
|
|
13145
|
+
};
|
|
13146
|
+
child.stdout.on("data", (chunk) => {
|
|
13147
|
+
buffer += chunk.toString();
|
|
13148
|
+
const lines = buffer.split("\n");
|
|
13149
|
+
buffer = lines.pop() || "";
|
|
13150
|
+
for (const line of lines)
|
|
13151
|
+
handleLine(line);
|
|
13152
|
+
});
|
|
13153
|
+
child.on("error", () => finish(false));
|
|
13154
|
+
child.on("exit", () => {
|
|
13155
|
+
if (!settled) {
|
|
13156
|
+
handleLine(buffer);
|
|
13157
|
+
finish(buffer.includes("hyv_scan"));
|
|
13158
|
+
}
|
|
13159
|
+
});
|
|
13160
|
+
setTimeout(() => {
|
|
13161
|
+
const send2 = (payload) => {
|
|
13162
|
+
child.stdin.write(`${JSON.stringify(payload)}
|
|
13163
|
+
`);
|
|
13164
|
+
};
|
|
13165
|
+
send2({
|
|
13166
|
+
jsonrpc: "2.0",
|
|
13167
|
+
id: 1,
|
|
13168
|
+
method: "initialize",
|
|
13169
|
+
params: {
|
|
13170
|
+
protocolVersion: "2024-11-05",
|
|
13171
|
+
capabilities: {},
|
|
13172
|
+
clientInfo: { name: "hyv-self-test", version: "1.0" }
|
|
13173
|
+
}
|
|
13174
|
+
});
|
|
13175
|
+
send2({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
13176
|
+
send2({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
|
|
13177
|
+
}, 500);
|
|
13178
|
+
});
|
|
13179
|
+
}
|
|
13180
|
+
|
|
13181
|
+
// src/commands/doctor.ts
|
|
13051
13182
|
var HOME = os5.homedir();
|
|
13052
13183
|
var IS_WIN = process.platform === "win32";
|
|
13053
13184
|
function claudeDesktopDir() {
|
|
13054
13185
|
if (IS_WIN)
|
|
13055
|
-
return
|
|
13186
|
+
return path15.join(HOME, "AppData", "Roaming", "Claude");
|
|
13056
13187
|
if (process.platform === "linux")
|
|
13057
|
-
return
|
|
13058
|
-
return
|
|
13188
|
+
return path15.join(HOME, ".config", "Claude");
|
|
13189
|
+
return path15.join(HOME, "Library", "Application Support", "Claude");
|
|
13190
|
+
}
|
|
13191
|
+
function isOwnerOnlyFile(filePath) {
|
|
13192
|
+
try {
|
|
13193
|
+
if (!fs14.existsSync(filePath))
|
|
13194
|
+
return true;
|
|
13195
|
+
const mode = fs14.statSync(filePath).mode & 511;
|
|
13196
|
+
return (mode & 63) === 0;
|
|
13197
|
+
} catch {
|
|
13198
|
+
return false;
|
|
13199
|
+
}
|
|
13059
13200
|
}
|
|
13060
13201
|
function readMcpHyv(configFile) {
|
|
13061
13202
|
try {
|
|
13062
|
-
if (!
|
|
13203
|
+
if (!fs14.existsSync(configFile))
|
|
13063
13204
|
return false;
|
|
13064
|
-
const cfg = JSON.parse(
|
|
13205
|
+
const cfg = JSON.parse(fs14.readFileSync(configFile, "utf-8"));
|
|
13065
13206
|
return Boolean(cfg.mcpServers?.hyv);
|
|
13066
13207
|
} catch {
|
|
13067
13208
|
return false;
|
|
@@ -13082,28 +13223,28 @@ function registerDoctorCommand(program3) {
|
|
|
13082
13223
|
console.log(import_chalk16.default.dim("tip: run hyv welcome for free capabilities\n"));
|
|
13083
13224
|
console.log(import_chalk16.default.dim("checking cli installation..."));
|
|
13084
13225
|
const cliPath = process.argv[1];
|
|
13085
|
-
if (cliPath &&
|
|
13226
|
+
if (cliPath && fs14.existsSync(cliPath)) {
|
|
13086
13227
|
console.log(import_chalk16.default.green(" \u2713 cli installed"));
|
|
13087
13228
|
} else {
|
|
13088
13229
|
console.log(import_chalk16.default.red(" \u2717 cli not found"));
|
|
13089
13230
|
issues++;
|
|
13090
13231
|
}
|
|
13091
13232
|
console.log(import_chalk16.default.dim("checking .hyv directory..."));
|
|
13092
|
-
if (
|
|
13233
|
+
if (fs14.existsSync(HYV_DIR)) {
|
|
13093
13234
|
console.log(import_chalk16.default.green(" \u2713 .hyv directory exists"));
|
|
13094
13235
|
} else {
|
|
13095
13236
|
console.log(import_chalk16.default.yellow(" ! .hyv directory missing \u2014 creating..."));
|
|
13096
|
-
|
|
13237
|
+
fs14.mkdirSync(HYV_DIR, { recursive: true, mode: 448 });
|
|
13097
13238
|
fixed++;
|
|
13098
13239
|
}
|
|
13099
13240
|
console.log(import_chalk16.default.dim("checking cache..."));
|
|
13100
13241
|
const diskProfiles = listDiskCachedProfiles();
|
|
13101
|
-
const syncMeta =
|
|
13102
|
-
if (diskProfiles.length > 0 ||
|
|
13242
|
+
const syncMeta = path15.join(CACHE_DIR, "sync-meta.json");
|
|
13243
|
+
if (diskProfiles.length > 0 || fs14.existsSync(syncMeta)) {
|
|
13103
13244
|
console.log(import_chalk16.default.green(` \u2713 profile cache (${diskProfiles.length} full profile(s))`));
|
|
13104
|
-
if (
|
|
13245
|
+
if (fs14.existsSync(syncMeta)) {
|
|
13105
13246
|
try {
|
|
13106
|
-
const meta = JSON.parse(
|
|
13247
|
+
const meta = JSON.parse(fs14.readFileSync(syncMeta, "utf-8"));
|
|
13107
13248
|
console.log(import_chalk16.default.dim(` last sync: ${meta.synced_at || "unknown"}`));
|
|
13108
13249
|
} catch {
|
|
13109
13250
|
}
|
|
@@ -13111,6 +13252,26 @@ function registerDoctorCommand(program3) {
|
|
|
13111
13252
|
} else {
|
|
13112
13253
|
console.log(import_chalk16.default.dim(" - no full profile cache (free local engine still works)"));
|
|
13113
13254
|
}
|
|
13255
|
+
console.log(import_chalk16.default.dim("checking file permissions..."));
|
|
13256
|
+
if (fs14.existsSync(HYV_DIR)) {
|
|
13257
|
+
const hyvMode = fs14.statSync(HYV_DIR).mode & 511;
|
|
13258
|
+
if ((hyvMode & 63) === 0) {
|
|
13259
|
+
console.log(import_chalk16.default.green(" \u2713 .hyv directory permissions"));
|
|
13260
|
+
} else {
|
|
13261
|
+
console.log(import_chalk16.default.yellow(" ! .hyv directory is world/group accessible"));
|
|
13262
|
+
console.log(import_chalk16.default.dim(" run: chmod 700 ~/.hyv"));
|
|
13263
|
+
issues++;
|
|
13264
|
+
}
|
|
13265
|
+
}
|
|
13266
|
+
if (fs14.existsSync(AUTH_FILE)) {
|
|
13267
|
+
if (isOwnerOnlyFile(AUTH_FILE)) {
|
|
13268
|
+
console.log(import_chalk16.default.green(" \u2713 auth.json permissions"));
|
|
13269
|
+
} else {
|
|
13270
|
+
console.log(import_chalk16.default.yellow(" ! auth.json is world/group readable"));
|
|
13271
|
+
console.log(import_chalk16.default.dim(" run: chmod 600 ~/.hyv/auth.json"));
|
|
13272
|
+
issues++;
|
|
13273
|
+
}
|
|
13274
|
+
}
|
|
13114
13275
|
console.log(import_chalk16.default.dim("checking authentication..."));
|
|
13115
13276
|
if (isInitialized()) {
|
|
13116
13277
|
const auth = readAuth();
|
|
@@ -13135,9 +13296,9 @@ function registerDoctorCommand(program3) {
|
|
|
13135
13296
|
console.log(import_chalk16.default.dim(" run: hyv init for profiles + learning"));
|
|
13136
13297
|
}
|
|
13137
13298
|
console.log(import_chalk16.default.dim("checking voice profile..."));
|
|
13138
|
-
const voiceMd =
|
|
13139
|
-
const hasVoiceMd =
|
|
13140
|
-
const profileFiles =
|
|
13299
|
+
const voiceMd = path15.join(HYV_DIR, "voice.md");
|
|
13300
|
+
const hasVoiceMd = fs14.existsSync(voiceMd) && fs14.readFileSync(voiceMd, "utf-8").trim().length > 50;
|
|
13301
|
+
const profileFiles = fs14.existsSync(PROFILES_DIR) ? fs14.readdirSync(PROFILES_DIR).filter((f) => f.endsWith(".md") && f !== "voice.md") : [];
|
|
13141
13302
|
if (hasVoiceMd || profileFiles.length > 0 || diskProfiles.length > 0) {
|
|
13142
13303
|
if (hasVoiceMd)
|
|
13143
13304
|
console.log(import_chalk16.default.green(" \u2713 voice.md exists"));
|
|
@@ -13150,14 +13311,21 @@ function registerDoctorCommand(program3) {
|
|
|
13150
13311
|
console.log(import_chalk16.default.dim(" run: hyv new <name> or hyv init"));
|
|
13151
13312
|
}
|
|
13152
13313
|
console.log(import_chalk16.default.dim("checking agent configurations..."));
|
|
13314
|
+
const cursorLegacyRule = path15.join(HOME, ".cursor", "rules", "hyv.md");
|
|
13315
|
+
const cursorRule = path15.join(HOME, ".cursor", "rules", "hyv.mdc");
|
|
13316
|
+
if (fs14.existsSync(cursorLegacyRule) && fs14.existsSync(cursorRule)) {
|
|
13317
|
+
console.log(import_chalk16.default.yellow(" ! stale cursor rule ~/.cursor/rules/hyv.md (use hyv.mdc)"));
|
|
13318
|
+
console.log(import_chalk16.default.dim(" run: rm ~/.cursor/rules/hyv.md (or hyv doctor --fix-agents)"));
|
|
13319
|
+
issues++;
|
|
13320
|
+
}
|
|
13153
13321
|
const agentChecks = [
|
|
13154
|
-
{ name: "claude desktop mcp", ok: readMcpHyv(
|
|
13155
|
-
{ name: "cursor mcp", ok: readMcpHyv(
|
|
13156
|
-
{ name: "cursor rule", ok:
|
|
13157
|
-
{ name: "claude code command", ok:
|
|
13158
|
-
{ name: "claude code skill", ok:
|
|
13159
|
-
{ name: "codex agents", ok:
|
|
13160
|
-
{ name: "command code skill", ok:
|
|
13322
|
+
{ name: "claude desktop mcp", ok: readMcpHyv(path15.join(claudeDesktopDir(), "claude_desktop_config.json")) },
|
|
13323
|
+
{ name: "cursor mcp", ok: readMcpHyv(path15.join(HOME, ".cursor", "mcp.json")) },
|
|
13324
|
+
{ name: "cursor rule", ok: fs14.existsSync(cursorRule) },
|
|
13325
|
+
{ name: "claude code command", ok: fs14.existsSync(path15.join(HOME, ".claude", "commands", "hyv.md")) },
|
|
13326
|
+
{ name: "claude code skill", ok: fs14.existsSync(path15.join(HOME, ".claude", "skills", "hold-your-voice", "SKILL.md")) },
|
|
13327
|
+
{ name: "codex agents", ok: fs14.existsSync(path15.join(HOME, ".codex", "AGENTS.md")) && fs14.readFileSync(path15.join(HOME, ".codex", "AGENTS.md"), "utf-8").includes("hyv") },
|
|
13328
|
+
{ name: "command code skill", ok: fs14.existsSync(path15.join(HOME, ".commandcode", "skills", "hyv", "SKILL.md")) }
|
|
13161
13329
|
];
|
|
13162
13330
|
for (const agent of agentChecks) {
|
|
13163
13331
|
if (agent.ok) {
|
|
@@ -13168,8 +13336,8 @@ function registerDoctorCommand(program3) {
|
|
|
13168
13336
|
}
|
|
13169
13337
|
if (opts.fixAgents) {
|
|
13170
13338
|
try {
|
|
13171
|
-
const pkgDir =
|
|
13172
|
-
const { setupAgents } = require(
|
|
13339
|
+
const pkgDir = path15.resolve(__dirname, "..");
|
|
13340
|
+
const { setupAgents } = require(path15.join(pkgDir, "scripts", "postinstall-lib.js"));
|
|
13173
13341
|
const result = setupAgents({ pkgDir, quiet: true });
|
|
13174
13342
|
console.log(import_chalk16.default.green(` \u2713 re-ran agent setup (${result.configured.join(", ") || "no changes"})`));
|
|
13175
13343
|
if (result.warnings.length) {
|
|
@@ -13181,8 +13349,8 @@ function registerDoctorCommand(program3) {
|
|
|
13181
13349
|
}
|
|
13182
13350
|
}
|
|
13183
13351
|
console.log(import_chalk16.default.dim("checking mcp server..."));
|
|
13184
|
-
const claudeMcp = readMcpHyv(
|
|
13185
|
-
const cursorMcp = readMcpHyv(
|
|
13352
|
+
const claudeMcp = readMcpHyv(path15.join(claudeDesktopDir(), "claude_desktop_config.json"));
|
|
13353
|
+
const cursorMcp = readMcpHyv(path15.join(HOME, ".cursor", "mcp.json"));
|
|
13186
13354
|
if (claudeMcp || cursorMcp) {
|
|
13187
13355
|
if (claudeMcp)
|
|
13188
13356
|
console.log(import_chalk16.default.green(" \u2713 mcp configured for claude desktop"));
|
|
@@ -13192,6 +13360,22 @@ function registerDoctorCommand(program3) {
|
|
|
13192
13360
|
console.log(import_chalk16.default.yellow(" ! mcp not configured \u2014 run: hyv doctor --fix-agents or hyv mcp --setup"));
|
|
13193
13361
|
issues++;
|
|
13194
13362
|
}
|
|
13363
|
+
try {
|
|
13364
|
+
const stdio = await testMcpStdioSubprocess();
|
|
13365
|
+
if (stdio.ok && (stdio.toolCount || 0) >= 10) {
|
|
13366
|
+
console.log(import_chalk16.default.green(` \u2713 mcp stdio subprocess healthy (${stdio.toolCount} tools)`));
|
|
13367
|
+
} else if (stdio.ok) {
|
|
13368
|
+
console.log(import_chalk16.default.yellow(` ! mcp stdio ok but only ${stdio.toolCount || 0} tools`));
|
|
13369
|
+
issues++;
|
|
13370
|
+
} else {
|
|
13371
|
+
console.log(import_chalk16.default.red(" \u2717 mcp stdio subprocess failed"));
|
|
13372
|
+
console.log(import_chalk16.default.dim(" run: hyv mcp --test"));
|
|
13373
|
+
issues++;
|
|
13374
|
+
}
|
|
13375
|
+
} catch (err) {
|
|
13376
|
+
console.log(import_chalk16.default.red(` \u2717 mcp stdio probe failed: ${err.message}`));
|
|
13377
|
+
issues++;
|
|
13378
|
+
}
|
|
13195
13379
|
console.log("");
|
|
13196
13380
|
if (issues === 0 && fixed === 0) {
|
|
13197
13381
|
console.log(import_chalk16.default.green("\u2713 everything looks good!"));
|
|
@@ -13268,15 +13452,51 @@ error: ${error.message}
|
|
|
13268
13452
|
}
|
|
13269
13453
|
|
|
13270
13454
|
// src/commands/fix.ts
|
|
13271
|
-
var
|
|
13272
|
-
var fs14 = __toESM(require("fs"));
|
|
13273
|
-
var path15 = __toESM(require("path"));
|
|
13455
|
+
var import_chalk19 = __toESM(require_source());
|
|
13274
13456
|
init_pipeline();
|
|
13275
13457
|
init_local_profile();
|
|
13276
13458
|
init_access();
|
|
13277
13459
|
init_config();
|
|
13460
|
+
|
|
13461
|
+
// src/lib/destructive-write.ts
|
|
13462
|
+
var fs15 = __toESM(require("fs"));
|
|
13463
|
+
var path16 = __toESM(require("path"));
|
|
13464
|
+
var readline = __toESM(require("readline"));
|
|
13465
|
+
var import_chalk18 = __toESM(require_source());
|
|
13466
|
+
async function confirmDestructiveWrite(options) {
|
|
13467
|
+
if (options.yes)
|
|
13468
|
+
return true;
|
|
13469
|
+
const label = options.target ? `${options.action} (${options.target})` : options.action;
|
|
13470
|
+
if (!process.stdin.isTTY) {
|
|
13471
|
+
console.error(import_chalk18.default.red("\nRefusing destructive write without confirmation (non-interactive)."));
|
|
13472
|
+
console.error(import_chalk18.default.dim(" Re-run with --yes to create .bak backups and proceed.\n"));
|
|
13473
|
+
return false;
|
|
13474
|
+
}
|
|
13475
|
+
const question = `
|
|
13476
|
+
${label}
|
|
13477
|
+
A .bak backup will be created. Proceed? [y/N] `;
|
|
13478
|
+
const answer = await new Promise((resolve14) => {
|
|
13479
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
13480
|
+
rl.question(question, (value) => {
|
|
13481
|
+
rl.close();
|
|
13482
|
+
resolve14(value.trim().toLowerCase());
|
|
13483
|
+
});
|
|
13484
|
+
});
|
|
13485
|
+
return answer === "y" || answer === "yes";
|
|
13486
|
+
}
|
|
13487
|
+
function writeInPlaceWithBackup(filePath, content) {
|
|
13488
|
+
const backupPath = filePath + ".bak";
|
|
13489
|
+
fs15.copyFileSync(filePath, backupPath);
|
|
13490
|
+
fs15.writeFileSync(filePath, content);
|
|
13491
|
+
return backupPath;
|
|
13492
|
+
}
|
|
13493
|
+
function backupBasename(filePath) {
|
|
13494
|
+
return path16.basename(filePath) + ".bak";
|
|
13495
|
+
}
|
|
13496
|
+
|
|
13497
|
+
// src/commands/fix.ts
|
|
13278
13498
|
function registerFixCommand(program3) {
|
|
13279
|
-
program3.command("fix").description("Apply auto-fixes (word swaps, connector removals) without an LLM").argument("<file>", "File to fix (or - for stdin)").option("--dry-run", "Show changes without writing").option("-i, --in-place", "Write fixes back to the file").option("--profile <name>", "Voice profile for never-list checks").option("--ignore <rules>", "Comma-separated rule IDs to skip").option("--format <type>", "Output format (text or json)", "text").action(async (file, options) => {
|
|
13499
|
+
program3.command("fix").description("Apply auto-fixes (word swaps, connector removals) without an LLM").argument("<file>", "File to fix (or - for stdin)").option("--dry-run", "Show changes without writing").option("-i, --in-place", "Write fixes back to the file").option("-y, --yes", "Confirm in-place write without prompting (creates .bak backup)").option("--profile <name>", "Voice profile for never-list checks").option("--ignore <rules>", "Comma-separated rule IDs to skip").option("--format <type>", "Output format (text or json)", "text").action(async (file, options) => {
|
|
13280
13500
|
try {
|
|
13281
13501
|
const profile = await loadProfileForCommand(options.profile);
|
|
13282
13502
|
const { text, path: filePath } = readText(file);
|
|
@@ -13285,9 +13505,9 @@ function registerFixCommand(program3) {
|
|
|
13285
13505
|
if (options.format === "json") {
|
|
13286
13506
|
console.log(JSON.stringify({ file: filePath, autoFixes: 0, llmIssues: result.stats.needsLLM, changes: [] }));
|
|
13287
13507
|
} else {
|
|
13288
|
-
console.log(
|
|
13508
|
+
console.log(import_chalk19.default.green("\n\u2713 No auto-fixable issues found."));
|
|
13289
13509
|
if (result.stats.needsLLM > 0) {
|
|
13290
|
-
console.log(
|
|
13510
|
+
console.log(import_chalk19.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
13291
13511
|
}
|
|
13292
13512
|
}
|
|
13293
13513
|
return;
|
|
@@ -13301,24 +13521,30 @@ function registerFixCommand(program3) {
|
|
|
13301
13521
|
fixed: options.dryRun ? void 0 : result.fixed
|
|
13302
13522
|
}, null, 2));
|
|
13303
13523
|
} else {
|
|
13304
|
-
console.log(
|
|
13524
|
+
console.log(import_chalk19.default.dim(`
|
|
13305
13525
|
hyv fix ${filePath}
|
|
13306
13526
|
`));
|
|
13307
13527
|
for (const change of result.changes) {
|
|
13308
|
-
console.log(
|
|
13528
|
+
console.log(import_chalk19.default.dim(` Line ${change.line}: `) + import_chalk19.default.red(change.before) + import_chalk19.default.dim(" \u2192 ") + import_chalk19.default.green(change.after));
|
|
13309
13529
|
}
|
|
13310
|
-
console.log(
|
|
13530
|
+
console.log(import_chalk19.default.green(`
|
|
13311
13531
|
\u2713 ${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} applied`));
|
|
13312
13532
|
if (result.stats.needsLLM > 0) {
|
|
13313
|
-
console.log(
|
|
13533
|
+
console.log(import_chalk19.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite \u2014 run: hyv rewrite ${file}`));
|
|
13314
13534
|
}
|
|
13315
13535
|
}
|
|
13316
13536
|
if (!options.dryRun) {
|
|
13317
13537
|
if (options.inPlace && filePath !== "stdin") {
|
|
13318
|
-
const
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13538
|
+
const confirmed = await confirmDestructiveWrite({
|
|
13539
|
+
yes: options.yes,
|
|
13540
|
+
action: "Apply auto-fixes in-place",
|
|
13541
|
+
target: filePath
|
|
13542
|
+
});
|
|
13543
|
+
if (!confirmed) {
|
|
13544
|
+
process.exit(1);
|
|
13545
|
+
}
|
|
13546
|
+
const backupPath = writeInPlaceWithBackup(filePath, result.fixed);
|
|
13547
|
+
console.log(import_chalk19.default.dim(` Written to ${filePath} (backup: ${backupBasename(filePath)})`));
|
|
13322
13548
|
saveLastEditSession({
|
|
13323
13549
|
original_path: filePath,
|
|
13324
13550
|
edited_path: filePath,
|
|
@@ -13326,7 +13552,7 @@ hyv fix ${filePath}
|
|
|
13326
13552
|
edited_text: result.fixed,
|
|
13327
13553
|
profile: options.profile
|
|
13328
13554
|
});
|
|
13329
|
-
console.log(
|
|
13555
|
+
console.log(import_chalk19.default.dim(" Tip: hyv reinforce --last to teach your profile from this edit"));
|
|
13330
13556
|
} else if (filePath === "stdin" || !options.inPlace) {
|
|
13331
13557
|
process.stdout.write("\n" + result.fixed + "\n");
|
|
13332
13558
|
if (filePath !== "stdin") {
|
|
@@ -13342,14 +13568,14 @@ hyv fix ${filePath}
|
|
|
13342
13568
|
}
|
|
13343
13569
|
await maybeShowLimitedModeHint(!!profile);
|
|
13344
13570
|
} catch (error) {
|
|
13345
|
-
console.error(
|
|
13571
|
+
console.error(import_chalk19.default.red(`Error: ${error.message}`));
|
|
13346
13572
|
process.exit(1);
|
|
13347
13573
|
}
|
|
13348
13574
|
});
|
|
13349
13575
|
}
|
|
13350
13576
|
|
|
13351
13577
|
// src/commands/check.ts
|
|
13352
|
-
var
|
|
13578
|
+
var import_chalk20 = __toESM(require_source());
|
|
13353
13579
|
init_pipeline();
|
|
13354
13580
|
init_local_profile();
|
|
13355
13581
|
init_access();
|
|
@@ -13359,20 +13585,20 @@ function registerCheckCommand(program3) {
|
|
|
13359
13585
|
const profile = await loadProfileForCommand(options.profile);
|
|
13360
13586
|
let inputText = text;
|
|
13361
13587
|
if (text === "-") {
|
|
13362
|
-
const
|
|
13588
|
+
const fs26 = require("fs");
|
|
13363
13589
|
if (process.stdin.isTTY) {
|
|
13364
|
-
console.error(
|
|
13590
|
+
console.error(import_chalk20.default.red("No input provided. Pipe content or pass text as argument."));
|
|
13365
13591
|
process.exit(1);
|
|
13366
13592
|
}
|
|
13367
|
-
inputText =
|
|
13593
|
+
inputText = fs26.readFileSync(0, "utf-8");
|
|
13368
13594
|
}
|
|
13369
13595
|
if (!inputText.trim()) {
|
|
13370
|
-
console.error(
|
|
13596
|
+
console.error(import_chalk20.default.red("No text provided."));
|
|
13371
13597
|
process.exit(1);
|
|
13372
13598
|
}
|
|
13373
|
-
const
|
|
13374
|
-
if (text !== "-" &&
|
|
13375
|
-
console.log(
|
|
13599
|
+
const fs25 = require("fs");
|
|
13600
|
+
if (text !== "-" && fs25.existsSync(text)) {
|
|
13601
|
+
console.log(import_chalk20.default.yellow(`"${text}" looks like a file. Did you mean: hyv scan ${text}`));
|
|
13376
13602
|
process.exit(1);
|
|
13377
13603
|
}
|
|
13378
13604
|
const result = runPipeline(inputText, profile, false);
|
|
@@ -13396,30 +13622,30 @@ function registerCheckCommand(program3) {
|
|
|
13396
13622
|
}, null, 2));
|
|
13397
13623
|
} else {
|
|
13398
13624
|
if (result.stats.totalSignals === 0) {
|
|
13399
|
-
console.log(
|
|
13400
|
-
console.log(
|
|
13625
|
+
console.log(import_chalk20.default.green("\n\u2713 Clean \u2014 no AI patterns found."));
|
|
13626
|
+
console.log(import_chalk20.default.dim(` score: ${result.score}/100`));
|
|
13401
13627
|
} else {
|
|
13402
13628
|
console.log("");
|
|
13403
13629
|
printGroupedSignals(result.signalMap.signals.slice(0, 15), profile);
|
|
13404
13630
|
if (result.signalMap.signals.length > 15) {
|
|
13405
|
-
console.log(
|
|
13631
|
+
console.log(import_chalk20.default.dim(` ... and ${result.signalMap.signals.length - 15} more`));
|
|
13406
13632
|
}
|
|
13407
|
-
console.log(
|
|
13633
|
+
console.log(import_chalk20.default.yellow(`
|
|
13408
13634
|
${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow)`));
|
|
13409
|
-
console.log(
|
|
13635
|
+
console.log(import_chalk20.default.dim(` score: ${result.score}/100`));
|
|
13410
13636
|
}
|
|
13411
13637
|
await maybeShowLimitedModeHint(!!profile);
|
|
13412
13638
|
}
|
|
13413
13639
|
process.exit(result.stats.totalSignals > 0 ? 1 : 0);
|
|
13414
13640
|
} catch (error) {
|
|
13415
|
-
console.error(
|
|
13641
|
+
console.error(import_chalk20.default.red(`Error: ${error.message}`));
|
|
13416
13642
|
process.exit(1);
|
|
13417
13643
|
}
|
|
13418
13644
|
});
|
|
13419
13645
|
}
|
|
13420
13646
|
|
|
13421
13647
|
// src/commands/score.ts
|
|
13422
|
-
var
|
|
13648
|
+
var import_chalk21 = __toESM(require_source());
|
|
13423
13649
|
init_pipeline();
|
|
13424
13650
|
init_local_profile();
|
|
13425
13651
|
function registerScoreCommand(program3) {
|
|
@@ -13444,14 +13670,14 @@ function registerScoreCommand(program3) {
|
|
|
13444
13670
|
process.exit(1);
|
|
13445
13671
|
}
|
|
13446
13672
|
} catch (error) {
|
|
13447
|
-
console.error(
|
|
13673
|
+
console.error(import_chalk21.default.red(`Error: ${error.message}`));
|
|
13448
13674
|
process.exit(1);
|
|
13449
13675
|
}
|
|
13450
13676
|
});
|
|
13451
13677
|
}
|
|
13452
13678
|
|
|
13453
13679
|
// src/commands/diff.ts
|
|
13454
|
-
var
|
|
13680
|
+
var import_chalk22 = __toESM(require_source());
|
|
13455
13681
|
init_pipeline();
|
|
13456
13682
|
init_local_profile();
|
|
13457
13683
|
function registerDiffCommand(program3) {
|
|
@@ -13461,9 +13687,9 @@ function registerDiffCommand(program3) {
|
|
|
13461
13687
|
const { text, path: filePath } = readText(file);
|
|
13462
13688
|
const result = runPipeline(text, profile, true);
|
|
13463
13689
|
if (result.changes.length === 0) {
|
|
13464
|
-
console.log(
|
|
13690
|
+
console.log(import_chalk22.default.green("\n\u2713 No auto-fixable changes."));
|
|
13465
13691
|
if (result.stats.needsLLM > 0) {
|
|
13466
|
-
console.log(
|
|
13692
|
+
console.log(import_chalk22.default.dim(` ${result.stats.needsLLM} issues need LLM rewrite`));
|
|
13467
13693
|
}
|
|
13468
13694
|
return;
|
|
13469
13695
|
}
|
|
@@ -13478,42 +13704,42 @@ function registerDiffCommand(program3) {
|
|
|
13478
13704
|
const originalLines = text.split("\n");
|
|
13479
13705
|
const fixedLines = result.fixed.split("\n");
|
|
13480
13706
|
const contextN = parseInt(options.context, 10);
|
|
13481
|
-
console.log(
|
|
13482
|
-
console.log(
|
|
13707
|
+
console.log(import_chalk22.default.dim(`--- ${filePath}`));
|
|
13708
|
+
console.log(import_chalk22.default.dim(`+++ ${filePath} (fixed)`));
|
|
13483
13709
|
for (const change of result.changes) {
|
|
13484
13710
|
const lineIdx = change.line - 1;
|
|
13485
13711
|
const start = Math.max(0, lineIdx - contextN);
|
|
13486
13712
|
const end = Math.min(originalLines.length, lineIdx + contextN + 1);
|
|
13487
|
-
console.log(
|
|
13713
|
+
console.log(import_chalk22.default.dim(`@@ -${start + 1},${end - start} +${start + 1},${end - start} @@`));
|
|
13488
13714
|
for (let i = start; i < end; i++) {
|
|
13489
13715
|
if (i === lineIdx) {
|
|
13490
|
-
console.log(
|
|
13491
|
-
console.log(
|
|
13716
|
+
console.log(import_chalk22.default.red(`-${originalLines[i]}`));
|
|
13717
|
+
console.log(import_chalk22.default.green(`+${fixedLines[i]}`));
|
|
13492
13718
|
} else {
|
|
13493
|
-
console.log(
|
|
13719
|
+
console.log(import_chalk22.default.dim(` ${originalLines[i]}`));
|
|
13494
13720
|
}
|
|
13495
13721
|
}
|
|
13496
13722
|
}
|
|
13497
|
-
console.log(
|
|
13723
|
+
console.log(import_chalk22.default.green(`
|
|
13498
13724
|
${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} available`));
|
|
13499
|
-
console.log(
|
|
13725
|
+
console.log(import_chalk22.default.dim(` run: hyv fix ${file} -i to apply`));
|
|
13500
13726
|
if (options.apply && filePath !== "stdin") {
|
|
13501
|
-
const
|
|
13502
|
-
const
|
|
13727
|
+
const fs25 = require("fs");
|
|
13728
|
+
const path24 = require("path");
|
|
13503
13729
|
const backupPath = filePath + ".bak";
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
console.log(
|
|
13730
|
+
fs25.copyFileSync(filePath, backupPath);
|
|
13731
|
+
fs25.writeFileSync(filePath, result.fixed);
|
|
13732
|
+
console.log(import_chalk22.default.green(` \u2713 Applied. Backup: ${path24.basename(backupPath)}`));
|
|
13507
13733
|
}
|
|
13508
13734
|
} catch (error) {
|
|
13509
|
-
console.error(
|
|
13735
|
+
console.error(import_chalk22.default.red(`Error: ${error.message}`));
|
|
13510
13736
|
process.exit(1);
|
|
13511
13737
|
}
|
|
13512
13738
|
});
|
|
13513
13739
|
}
|
|
13514
13740
|
|
|
13515
13741
|
// src/commands/rules.ts
|
|
13516
|
-
var
|
|
13742
|
+
var import_chalk23 = __toESM(require_source());
|
|
13517
13743
|
init_config();
|
|
13518
13744
|
var RULE_CATALOG = [
|
|
13519
13745
|
// AI Overused Words
|
|
@@ -13607,7 +13833,7 @@ function registerRulesCommand(program3) {
|
|
|
13607
13833
|
for (const id of ids)
|
|
13608
13834
|
disabledRules.delete(id);
|
|
13609
13835
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
13610
|
-
console.log(
|
|
13836
|
+
console.log(import_chalk23.default.green(`
|
|
13611
13837
|
\u2713 Enabled: ${ids.join(", ")}`));
|
|
13612
13838
|
return;
|
|
13613
13839
|
}
|
|
@@ -13616,13 +13842,13 @@ function registerRulesCommand(program3) {
|
|
|
13616
13842
|
for (const id of ids)
|
|
13617
13843
|
disabledRules.add(id);
|
|
13618
13844
|
writeConfig({ ...config, disabled_rules: [...disabledRules] });
|
|
13619
|
-
console.log(
|
|
13845
|
+
console.log(import_chalk23.default.green(`
|
|
13620
13846
|
\u2713 Disabled: ${ids.join(", ")}`));
|
|
13621
13847
|
return;
|
|
13622
13848
|
}
|
|
13623
13849
|
if (options.reset) {
|
|
13624
13850
|
writeConfig({ ...config, disabled_rules: [] });
|
|
13625
|
-
console.log(
|
|
13851
|
+
console.log(import_chalk23.default.green("\n\u2713 All rules reset to default (enabled)"));
|
|
13626
13852
|
return;
|
|
13627
13853
|
}
|
|
13628
13854
|
let rules = [...RULE_CATALOG];
|
|
@@ -13650,40 +13876,40 @@ function registerRulesCommand(program3) {
|
|
|
13650
13876
|
}
|
|
13651
13877
|
console.log("");
|
|
13652
13878
|
for (const [cat, catRules] of categories) {
|
|
13653
|
-
console.log(
|
|
13879
|
+
console.log(import_chalk23.default.bold(` ${cat} rules (${catRules.length})
|
|
13654
13880
|
`));
|
|
13655
|
-
console.log(
|
|
13656
|
-
console.log(
|
|
13881
|
+
console.log(import_chalk23.default.dim(" ID Sev AutoFix Status"));
|
|
13882
|
+
console.log(import_chalk23.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
13657
13883
|
for (const rule of catRules) {
|
|
13658
|
-
const sev = rule.severity === "red" ?
|
|
13659
|
-
const fix = rule.autoFixable ?
|
|
13660
|
-
const enabled2 = disabledRules.has(rule.id) ?
|
|
13884
|
+
const sev = rule.severity === "red" ? import_chalk23.default.red("red") : import_chalk23.default.yellow("yel");
|
|
13885
|
+
const fix = rule.autoFixable ? import_chalk23.default.green(" \u2713") : import_chalk23.default.dim(" \u2717");
|
|
13886
|
+
const enabled2 = disabledRules.has(rule.id) ? import_chalk23.default.red(" \u2717 disabled") : import_chalk23.default.green(" \u2713 enabled");
|
|
13661
13887
|
const id = rule.id.padEnd(24);
|
|
13662
|
-
console.log(` ${
|
|
13888
|
+
console.log(` ${import_chalk23.default.dim(id)} ${sev} ${fix} ${enabled2}`);
|
|
13663
13889
|
}
|
|
13664
13890
|
console.log("");
|
|
13665
13891
|
}
|
|
13666
13892
|
const enabled = rules.filter((r) => !disabledRules.has(r.id)).length;
|
|
13667
13893
|
const disabled = rules.length - enabled;
|
|
13668
|
-
console.log(
|
|
13669
|
-
console.log(
|
|
13670
|
-
console.log(
|
|
13894
|
+
console.log(import_chalk23.default.dim(` ${rules.length} rules, ${enabled} enabled, ${disabled} disabled`));
|
|
13895
|
+
console.log(import_chalk23.default.dim(` toggle: hyv rules --disable <id>`));
|
|
13896
|
+
console.log(import_chalk23.default.dim(` reset: hyv rules --reset
|
|
13671
13897
|
`));
|
|
13672
13898
|
} catch (error) {
|
|
13673
|
-
console.error(
|
|
13899
|
+
console.error(import_chalk23.default.red(`Error: ${error.message}`));
|
|
13674
13900
|
process.exit(1);
|
|
13675
13901
|
}
|
|
13676
13902
|
});
|
|
13677
13903
|
}
|
|
13678
13904
|
|
|
13679
13905
|
// src/commands/batch.ts
|
|
13680
|
-
var
|
|
13681
|
-
var
|
|
13682
|
-
var
|
|
13906
|
+
var import_chalk24 = __toESM(require_source());
|
|
13907
|
+
var fs16 = __toESM(require("fs"));
|
|
13908
|
+
var path17 = __toESM(require("path"));
|
|
13683
13909
|
init_pipeline();
|
|
13684
13910
|
init_local_profile();
|
|
13685
13911
|
function registerBatchCommand(program3) {
|
|
13686
|
-
program3.command("batch").description("Scan or fix multiple files matching a glob").argument("<pattern>", 'Glob pattern (e.g., "posts/**/*.md")').option("--fix", "Apply auto-fixes (default: scan only)").option("-i, --in-place", "Write fixes back to files").option("-y, --yes", "Confirm destructive in-place fixes without prompting").option("--threshold <n>", "Fail if any file score < threshold").option("--fail-on-hit", "Exit
|
|
13912
|
+
program3.command("batch").description("Scan or fix multiple files matching a glob").argument("<pattern>", 'Glob pattern (e.g., "posts/**/*.md")').option("--fix", "Apply auto-fixes (default: scan only)").option("-i, --in-place", "Write fixes back to files").option("-y, --yes", "Confirm destructive in-place fixes without prompting").option("--threshold <n>", "Fail if any file score < threshold").option("--fail-on-hit", "Exit with code 2 if any file has issues").option("--sort <field>", "Sort by: issues, score, name", "issues").option("--format <type>", "Output format (text, json, csv)", "text").option("--profile <name>", "Voice profile").option("--ignore <patterns>", "Comma-separated glob ignores").action(async (pattern, options) => {
|
|
13687
13913
|
try {
|
|
13688
13914
|
const profile = await loadProfileForCommand(options.profile);
|
|
13689
13915
|
const glob = require_index_min();
|
|
@@ -13692,26 +13918,30 @@ function registerBatchCommand(program3) {
|
|
|
13692
13918
|
nodir: true
|
|
13693
13919
|
});
|
|
13694
13920
|
if (files.length === 0) {
|
|
13695
|
-
console.log(
|
|
13921
|
+
console.log(import_chalk24.default.yellow(`
|
|
13696
13922
|
No files matching: ${pattern}`));
|
|
13697
13923
|
return;
|
|
13698
13924
|
}
|
|
13699
|
-
if (options.fix && options.inPlace
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13925
|
+
if (options.fix && options.inPlace) {
|
|
13926
|
+
const confirmed = await confirmDestructiveWrite({
|
|
13927
|
+
yes: options.yes,
|
|
13928
|
+
action: `Apply auto-fixes in-place to ${files.length} file(s)`,
|
|
13929
|
+
target: pattern
|
|
13930
|
+
});
|
|
13931
|
+
if (!confirmed)
|
|
13932
|
+
process.exit(1);
|
|
13703
13933
|
}
|
|
13704
13934
|
if (options.format === "text") {
|
|
13705
|
-
console.log(
|
|
13935
|
+
console.log(import_chalk24.default.dim(`
|
|
13706
13936
|
scanning ${files.length} file${files.length === 1 ? "" : "s"}...
|
|
13707
13937
|
`));
|
|
13708
13938
|
}
|
|
13709
13939
|
const results = [];
|
|
13710
13940
|
for (const file of files) {
|
|
13711
|
-
const absPath =
|
|
13712
|
-
if (!
|
|
13941
|
+
const absPath = path17.resolve(file);
|
|
13942
|
+
if (!fs16.existsSync(absPath))
|
|
13713
13943
|
continue;
|
|
13714
|
-
const text =
|
|
13944
|
+
const text = fs16.readFileSync(absPath, "utf-8");
|
|
13715
13945
|
const result = runPipeline(text, profile, options.fix || false);
|
|
13716
13946
|
results.push({
|
|
13717
13947
|
file,
|
|
@@ -13722,9 +13952,7 @@ No files matching: ${pattern}`));
|
|
|
13722
13952
|
autoFixes: result.changes.length
|
|
13723
13953
|
});
|
|
13724
13954
|
if (options.fix && options.inPlace && result.changes.length > 0) {
|
|
13725
|
-
|
|
13726
|
-
fs15.copyFileSync(absPath, backupPath);
|
|
13727
|
-
fs15.writeFileSync(absPath, result.fixed);
|
|
13955
|
+
writeInPlaceWithBackup(absPath, result.fixed);
|
|
13728
13956
|
}
|
|
13729
13957
|
}
|
|
13730
13958
|
if (options.sort === "score") {
|
|
@@ -13743,23 +13971,23 @@ No files matching: ${pattern}`));
|
|
|
13743
13971
|
}
|
|
13744
13972
|
} else {
|
|
13745
13973
|
for (const r of results) {
|
|
13746
|
-
const icon = r.issues > 0 ?
|
|
13747
|
-
const score = r.score < 60 ?
|
|
13748
|
-
const issueStr = r.issues > 0 ?
|
|
13974
|
+
const icon = r.issues > 0 ? import_chalk24.default.red("\u25CF") : import_chalk24.default.green("\u25CB");
|
|
13975
|
+
const score = r.score < 60 ? import_chalk24.default.red(r.score) : r.score < 80 ? import_chalk24.default.yellow(r.score) : import_chalk24.default.green(r.score);
|
|
13976
|
+
const issueStr = r.issues > 0 ? import_chalk24.default.red(`${r.issues} issues`) : import_chalk24.default.green("clean");
|
|
13749
13977
|
console.log(` ${icon} ${r.file.padEnd(40)} ${issueStr.padEnd(20)} score: ${score}`);
|
|
13750
13978
|
}
|
|
13751
13979
|
const withIssues = results.filter((r) => r.issues > 0).length;
|
|
13752
13980
|
const totalIssues = results.reduce((sum, r) => sum + r.issues, 0);
|
|
13753
13981
|
const worst = results.reduce((min, r) => r.score < min.score ? r : min, results[0]);
|
|
13754
|
-
console.log(
|
|
13982
|
+
console.log(import_chalk24.default.dim(`
|
|
13755
13983
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`));
|
|
13756
|
-
console.log(
|
|
13984
|
+
console.log(import_chalk24.default.dim(` ${results.length} files, ${withIssues} with issues, ${totalIssues} total issues`));
|
|
13757
13985
|
if (withIssues > 0) {
|
|
13758
|
-
console.log(
|
|
13986
|
+
console.log(import_chalk24.default.dim(` worst: ${worst.file} (${worst.score}/100)`));
|
|
13759
13987
|
}
|
|
13760
13988
|
if (options.fix && options.inPlace) {
|
|
13761
13989
|
const fixed = results.filter((r) => r.autoFixes > 0);
|
|
13762
|
-
console.log(
|
|
13990
|
+
console.log(import_chalk24.default.green(`
|
|
13763
13991
|
\u2713 ${fixed.reduce((sum, r) => sum + r.autoFixes, 0)} auto-fixes applied across ${fixed.length} files`));
|
|
13764
13992
|
}
|
|
13765
13993
|
}
|
|
@@ -13771,108 +13999,114 @@ No files matching: ${pattern}`));
|
|
|
13771
13999
|
if (belowThreshold)
|
|
13772
14000
|
process.exit(1);
|
|
13773
14001
|
} catch (error) {
|
|
13774
|
-
console.error(
|
|
14002
|
+
console.error(import_chalk24.default.red(`Error: ${error.message}`));
|
|
13775
14003
|
process.exit(1);
|
|
13776
14004
|
}
|
|
13777
14005
|
});
|
|
13778
14006
|
}
|
|
13779
14007
|
|
|
13780
14008
|
// src/commands/watch.ts
|
|
13781
|
-
var
|
|
13782
|
-
var
|
|
13783
|
-
var
|
|
14009
|
+
var import_chalk25 = __toESM(require_source());
|
|
14010
|
+
var fs17 = __toESM(require("fs"));
|
|
14011
|
+
var path18 = __toESM(require("path"));
|
|
13784
14012
|
init_pipeline();
|
|
13785
14013
|
init_local_profile();
|
|
13786
14014
|
function registerWatchCommand(program3) {
|
|
13787
14015
|
program3.command("watch").description("Watch a file and re-scan on every save").argument("<file>", "File to watch").option("--command <cmd>", "What to run on change: scan, score, fix", "scan").option("--debounce <ms>", "Delay after save before scanning", "300").option("--notify", "OS notification when issues found").option("-y, --yes", "Confirm destructive auto-fix writes without prompting").option("--profile <name>", "Voice profile").action(async (file, options) => {
|
|
13788
14016
|
try {
|
|
13789
14017
|
const profile = await loadProfileForCommand(options.profile);
|
|
13790
|
-
const absPath =
|
|
13791
|
-
if (!
|
|
13792
|
-
console.error(
|
|
14018
|
+
const absPath = path18.resolve(file);
|
|
14019
|
+
if (!fs17.existsSync(absPath)) {
|
|
14020
|
+
console.error(import_chalk25.default.red(`File not found: ${absPath}`));
|
|
13793
14021
|
process.exit(1);
|
|
13794
14022
|
}
|
|
13795
|
-
if (options.command === "fix"
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
14023
|
+
if (options.command === "fix") {
|
|
14024
|
+
const confirmed = await confirmDestructiveWrite({
|
|
14025
|
+
yes: options.yes,
|
|
14026
|
+
action: "Auto-fix on every save",
|
|
14027
|
+
target: absPath
|
|
14028
|
+
});
|
|
14029
|
+
if (!confirmed)
|
|
14030
|
+
process.exit(1);
|
|
13799
14031
|
}
|
|
13800
|
-
console.log(
|
|
14032
|
+
console.log(import_chalk25.default.dim(`
|
|
13801
14033
|
watching ${absPath}`));
|
|
13802
|
-
console.log(
|
|
13803
|
-
console.log(
|
|
14034
|
+
console.log(import_chalk25.default.dim(`command: ${options.command} debounce: ${options.debounce}ms`));
|
|
14035
|
+
console.log(import_chalk25.default.dim("ctrl+c to stop\n"));
|
|
13804
14036
|
let debounceTimer = null;
|
|
13805
14037
|
const debounceMs = parseInt(options.debounce, 10);
|
|
13806
14038
|
let scanCount = 0;
|
|
13807
14039
|
let lastScore = 0;
|
|
14040
|
+
let ignoreWatchUntil = 0;
|
|
13808
14041
|
const runScan = () => {
|
|
13809
|
-
const text =
|
|
14042
|
+
const text = fs17.readFileSync(absPath, "utf-8");
|
|
13810
14043
|
const result = runPipeline(text, profile, options.command === "fix");
|
|
13811
14044
|
scanCount++;
|
|
13812
14045
|
const now = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
13813
|
-
console.log(
|
|
14046
|
+
console.log(import_chalk25.default.dim(`[${now}] saved \u2014 ${options.command}ing...`));
|
|
13814
14047
|
if (options.command === "score") {
|
|
13815
14048
|
const score = result.score;
|
|
13816
|
-
const color = score < 60 ?
|
|
14049
|
+
const color = score < 60 ? import_chalk25.default.red : score < 80 ? import_chalk25.default.yellow : import_chalk25.default.green;
|
|
13817
14050
|
console.log(` ${color(score + "/100")}`);
|
|
13818
14051
|
if (lastScore > 0 && score !== lastScore) {
|
|
13819
14052
|
const delta = score - lastScore;
|
|
13820
|
-
console.log(
|
|
14053
|
+
console.log(import_chalk25.default.dim(` ${delta > 0 ? "\u2191" : "\u2193"} ${Math.abs(delta)} from last scan`));
|
|
13821
14054
|
}
|
|
13822
14055
|
lastScore = score;
|
|
13823
14056
|
} else if (options.command === "fix") {
|
|
13824
14057
|
if (result.changes.length > 0) {
|
|
13825
14058
|
for (const change of result.changes) {
|
|
13826
|
-
console.log(
|
|
14059
|
+
console.log(import_chalk25.default.dim(` Line ${change.line}: `) + import_chalk25.default.red(change.before) + import_chalk25.default.dim(" \u2192 ") + import_chalk25.default.green(change.after));
|
|
13827
14060
|
}
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
console.log(import_chalk24.default.green(` \u2713 ${result.changes.length} auto-fixes applied`));
|
|
14061
|
+
ignoreWatchUntil = Date.now() + debounceMs + 200;
|
|
14062
|
+
writeInPlaceWithBackup(absPath, result.fixed);
|
|
14063
|
+
console.log(import_chalk25.default.green(` \u2713 ${result.changes.length} auto-fixes applied`));
|
|
13832
14064
|
} else {
|
|
13833
|
-
console.log(
|
|
14065
|
+
console.log(import_chalk25.default.green(" \u2713 no auto-fixable issues"));
|
|
13834
14066
|
}
|
|
13835
14067
|
} else {
|
|
13836
14068
|
if (result.stats.totalSignals === 0) {
|
|
13837
|
-
console.log(
|
|
14069
|
+
console.log(import_chalk25.default.green(` \u2713 clean \u2014 score: ${result.score}/100`));
|
|
13838
14070
|
} else {
|
|
13839
|
-
console.log(
|
|
14071
|
+
console.log(import_chalk25.default.yellow(` ${result.stats.totalSignals} issues (${result.stats.red} red, ${result.stats.yellow} yellow) score: ${result.score}/100`));
|
|
13840
14072
|
for (const signal of result.signalMap.signals.slice(0, 3)) {
|
|
13841
|
-
const sev = signal.severity === "red" ?
|
|
14073
|
+
const sev = signal.severity === "red" ? import_chalk25.default.red("\u25CF") : import_chalk25.default.yellow("\u25CB");
|
|
13842
14074
|
console.log(` ${sev} line ${signal.line}: ${signal.id} \u2014 ${signal.suggestion}`);
|
|
13843
14075
|
}
|
|
13844
14076
|
if (result.signalMap.signals.length > 3) {
|
|
13845
|
-
console.log(
|
|
14077
|
+
console.log(import_chalk25.default.dim(` ... and ${result.signalMap.signals.length - 3} more`));
|
|
13846
14078
|
}
|
|
13847
14079
|
}
|
|
13848
14080
|
}
|
|
13849
14081
|
console.log("");
|
|
13850
14082
|
};
|
|
13851
14083
|
runScan();
|
|
13852
|
-
|
|
14084
|
+
fs17.watch(absPath, (eventType) => {
|
|
13853
14085
|
if (eventType !== "change")
|
|
13854
14086
|
return;
|
|
14087
|
+
if (Date.now() < ignoreWatchUntil)
|
|
14088
|
+
return;
|
|
13855
14089
|
if (debounceTimer)
|
|
13856
14090
|
clearTimeout(debounceTimer);
|
|
13857
14091
|
debounceTimer = setTimeout(runScan, debounceMs);
|
|
13858
14092
|
});
|
|
13859
14093
|
process.on("SIGINT", () => {
|
|
13860
|
-
console.log(
|
|
14094
|
+
console.log(import_chalk25.default.dim(`
|
|
13861
14095
|
${scanCount} scans completed. exiting.`));
|
|
13862
14096
|
process.exit(0);
|
|
13863
14097
|
});
|
|
13864
14098
|
await new Promise(() => {
|
|
13865
14099
|
});
|
|
13866
14100
|
} catch (error) {
|
|
13867
|
-
console.error(
|
|
14101
|
+
console.error(import_chalk25.default.red(`Error: ${error.message}`));
|
|
13868
14102
|
process.exit(1);
|
|
13869
14103
|
}
|
|
13870
14104
|
});
|
|
13871
14105
|
}
|
|
13872
14106
|
|
|
13873
14107
|
// src/commands/demo.ts
|
|
13874
|
-
var
|
|
13875
|
-
var
|
|
14108
|
+
var import_chalk26 = __toESM(require_source());
|
|
14109
|
+
var fs18 = __toESM(require("fs"));
|
|
13876
14110
|
var SAMPLES = {
|
|
13877
14111
|
linkedin: {
|
|
13878
14112
|
text: `In today's fast-paced digital landscape, it's important to note that leveraging the right tools is not just nice to have, but essential for success. Let's delve into the holistic approach that will transform your workflow.
|
|
@@ -13962,46 +14196,46 @@ function registerDemoCommand(program3) {
|
|
|
13962
14196
|
const style = options.clean ? "clean" : options.style;
|
|
13963
14197
|
const sample = SAMPLES[style];
|
|
13964
14198
|
if (!sample) {
|
|
13965
|
-
console.error(
|
|
14199
|
+
console.error(import_chalk26.default.red(`Unknown style: ${options.style}. Valid: ${Object.keys(SAMPLES).filter((k) => k !== "clean").join(", ")}`));
|
|
13966
14200
|
process.exit(1);
|
|
13967
14201
|
}
|
|
13968
14202
|
if (options.output) {
|
|
13969
14203
|
const outputPath = require("path").resolve(options.output);
|
|
13970
|
-
|
|
13971
|
-
console.log(
|
|
14204
|
+
fs18.writeFileSync(outputPath, sample.text);
|
|
14205
|
+
console.log(import_chalk26.default.green(`
|
|
13972
14206
|
\u2713 Sample written to ${outputPath}`));
|
|
13973
14207
|
if (sample.patterns.length > 0) {
|
|
13974
|
-
console.log(
|
|
14208
|
+
console.log(import_chalk26.default.dim(` Contains ${sample.patterns.length} AI patterns: ${sample.patterns.slice(0, 5).join(", ")}...`));
|
|
13975
14209
|
}
|
|
13976
|
-
console.log(
|
|
14210
|
+
console.log(import_chalk26.default.dim(`
|
|
13977
14211
|
Scan it: hyv scan ${options.output}`));
|
|
13978
|
-
console.log(
|
|
14212
|
+
console.log(import_chalk26.default.dim(` Fix it: hyv fix ${options.output}`));
|
|
13979
14213
|
} else {
|
|
13980
|
-
console.log(
|
|
14214
|
+
console.log(import_chalk26.default.bold(`
|
|
13981
14215
|
\u2500\u2500\u2500 sample (${style}) \u2500\u2500\u2500
|
|
13982
14216
|
`));
|
|
13983
14217
|
console.log(sample.text);
|
|
13984
|
-
console.log(
|
|
14218
|
+
console.log(import_chalk26.default.dim(`
|
|
13985
14219
|
\u2500\u2500\u2500 end \u2500\u2500\u2500`));
|
|
13986
14220
|
if (sample.patterns.length > 0) {
|
|
13987
|
-
console.log(
|
|
14221
|
+
console.log(import_chalk26.default.dim(`
|
|
13988
14222
|
${sample.patterns.length} AI patterns embedded: ${sample.patterns.slice(0, 8).join(", ")}...`));
|
|
13989
14223
|
}
|
|
13990
|
-
console.log(
|
|
14224
|
+
console.log(import_chalk26.default.dim(`
|
|
13991
14225
|
Save to file: hyv demo --output demo.md`));
|
|
13992
|
-
console.log(
|
|
13993
|
-
console.log(
|
|
14226
|
+
console.log(import_chalk26.default.dim(` Scan it: hyv scan demo.md`));
|
|
14227
|
+
console.log(import_chalk26.default.dim(` Fix it: hyv fix demo.md
|
|
13994
14228
|
`));
|
|
13995
14229
|
}
|
|
13996
14230
|
} catch (error) {
|
|
13997
|
-
console.error(
|
|
14231
|
+
console.error(import_chalk26.default.red(`Error: ${error.message}`));
|
|
13998
14232
|
process.exit(1);
|
|
13999
14233
|
}
|
|
14000
14234
|
});
|
|
14001
14235
|
}
|
|
14002
14236
|
|
|
14003
14237
|
// src/commands/open.ts
|
|
14004
|
-
var
|
|
14238
|
+
var import_chalk27 = __toESM(require_source());
|
|
14005
14239
|
var PAGES = {
|
|
14006
14240
|
dashboard: "https://holdyourvoice.com/dashboard",
|
|
14007
14241
|
profiles: "https://holdyourvoice.com/dashboard",
|
|
@@ -14018,12 +14252,12 @@ function registerOpenCommand(program3) {
|
|
|
14018
14252
|
return;
|
|
14019
14253
|
}
|
|
14020
14254
|
const open3 = (await Promise.resolve().then(() => __toESM(require_open()))).default;
|
|
14021
|
-
console.log(
|
|
14255
|
+
console.log(import_chalk27.default.dim(`
|
|
14022
14256
|
Opening ${url}...`));
|
|
14023
14257
|
await open3(url);
|
|
14024
|
-
console.log(
|
|
14258
|
+
console.log(import_chalk27.default.green(" \u2713 Opened in browser\n"));
|
|
14025
14259
|
} catch (error) {
|
|
14026
|
-
console.error(
|
|
14260
|
+
console.error(import_chalk27.default.red(`Error: ${error.message}`));
|
|
14027
14261
|
process.exit(1);
|
|
14028
14262
|
}
|
|
14029
14263
|
});
|
|
@@ -14033,35 +14267,35 @@ function registerOpenCommand(program3) {
|
|
|
14033
14267
|
init_welcome();
|
|
14034
14268
|
|
|
14035
14269
|
// src/lib/onboarding.ts
|
|
14036
|
-
var
|
|
14037
|
-
var
|
|
14270
|
+
var fs19 = __toESM(require("fs"));
|
|
14271
|
+
var path19 = __toESM(require("path"));
|
|
14038
14272
|
var os6 = __toESM(require("os"));
|
|
14039
|
-
var hyvDir =
|
|
14040
|
-
var onboardingFile =
|
|
14273
|
+
var hyvDir = path19.join(os6.homedir(), ".hyv");
|
|
14274
|
+
var onboardingFile = path19.join(hyvDir, "onboarding-complete.json");
|
|
14041
14275
|
function hasCompletedOnboarding() {
|
|
14042
14276
|
try {
|
|
14043
|
-
return
|
|
14277
|
+
return fs19.existsSync(onboardingFile);
|
|
14044
14278
|
} catch {
|
|
14045
14279
|
return false;
|
|
14046
14280
|
}
|
|
14047
14281
|
}
|
|
14048
14282
|
function markOnboardingComplete(version) {
|
|
14049
|
-
if (!
|
|
14050
|
-
|
|
14051
|
-
|
|
14283
|
+
if (!fs19.existsSync(hyvDir))
|
|
14284
|
+
fs19.mkdirSync(hyvDir, { recursive: true });
|
|
14285
|
+
fs19.writeFileSync(
|
|
14052
14286
|
onboardingFile,
|
|
14053
14287
|
JSON.stringify({ version, completed_at: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
14054
14288
|
);
|
|
14055
14289
|
}
|
|
14056
14290
|
|
|
14057
14291
|
// src/commands/welcome.ts
|
|
14058
|
-
var
|
|
14059
|
-
var
|
|
14292
|
+
var fs20 = __toESM(require("fs"));
|
|
14293
|
+
var path20 = __toESM(require("path"));
|
|
14060
14294
|
function registerWelcomeCommand(program3) {
|
|
14061
14295
|
const pkgVersion3 = (() => {
|
|
14062
14296
|
try {
|
|
14063
|
-
const pkgPath3 =
|
|
14064
|
-
return JSON.parse(
|
|
14297
|
+
const pkgPath3 = path20.resolve(__dirname, "..", "package.json");
|
|
14298
|
+
return JSON.parse(fs20.readFileSync(pkgPath3, "utf-8")).version;
|
|
14065
14299
|
} catch {
|
|
14066
14300
|
return "0.0.0";
|
|
14067
14301
|
}
|
|
@@ -14085,7 +14319,7 @@ function getWelcomeText() {
|
|
|
14085
14319
|
}
|
|
14086
14320
|
|
|
14087
14321
|
// src/commands/content.ts
|
|
14088
|
-
var
|
|
14322
|
+
var import_chalk28 = __toESM(require_source());
|
|
14089
14323
|
init_free_paid();
|
|
14090
14324
|
var TEMPLATES = {
|
|
14091
14325
|
cursor: {
|
|
@@ -14159,68 +14393,68 @@ ${COMMUNITY_URL}`
|
|
|
14159
14393
|
function registerContentCommand(program3) {
|
|
14160
14394
|
program3.command("content").description("Blog outlines, CI snippets, and share templates").argument("[topic]", "cursor | agents | ci | share", "cursor").option("--list", "List available templates").action((topic, opts) => {
|
|
14161
14395
|
if (opts.list) {
|
|
14162
|
-
console.log(
|
|
14396
|
+
console.log(import_chalk28.default.bold("\nhyv content templates\n"));
|
|
14163
14397
|
for (const [key, t2] of Object.entries(TEMPLATES)) {
|
|
14164
|
-
console.log(
|
|
14398
|
+
console.log(import_chalk28.default.dim(` ${key}`) + ` \u2014 ${t2.title}`);
|
|
14165
14399
|
}
|
|
14166
14400
|
console.log("");
|
|
14167
14401
|
return;
|
|
14168
14402
|
}
|
|
14169
14403
|
const t = TEMPLATES[topic] || TEMPLATES.cursor;
|
|
14170
|
-
console.log(
|
|
14404
|
+
console.log(import_chalk28.default.bold(`
|
|
14171
14405
|
${t.title}
|
|
14172
14406
|
`));
|
|
14173
14407
|
console.log(t.body);
|
|
14174
|
-
console.log(
|
|
14408
|
+
console.log(import_chalk28.default.dim("\nBlog: https://holdyourvoice.com/blog\n"));
|
|
14175
14409
|
});
|
|
14176
14410
|
}
|
|
14177
14411
|
|
|
14178
14412
|
// src/commands/upgrade.ts
|
|
14179
|
-
var
|
|
14180
|
-
var
|
|
14413
|
+
var import_chalk29 = __toESM(require_source());
|
|
14414
|
+
var import_child_process3 = require("child_process");
|
|
14181
14415
|
init_version();
|
|
14182
14416
|
function registerUpgradeCommand(program3) {
|
|
14183
14417
|
program3.command("upgrade").description("Upgrade to the latest @holdyourvoice/hyv").option("--check", "Only check if an update is available").action(async (opts) => {
|
|
14184
14418
|
const current = getCliVersion();
|
|
14185
|
-
console.log(
|
|
14419
|
+
console.log(import_chalk29.default.dim(`
|
|
14186
14420
|
Current: ${getEngineLabel()}
|
|
14187
14421
|
`));
|
|
14188
14422
|
let latest = current;
|
|
14189
14423
|
try {
|
|
14190
|
-
const out = (0,
|
|
14424
|
+
const out = (0, import_child_process3.execSync)("npm view @holdyourvoice/hyv version", { encoding: "utf-8", timeout: 15e3 });
|
|
14191
14425
|
latest = out.trim();
|
|
14192
14426
|
} catch {
|
|
14193
|
-
console.log(
|
|
14427
|
+
console.log(import_chalk29.default.yellow("Could not reach npm registry. Try: npm i -g @holdyourvoice/hyv@latest"));
|
|
14194
14428
|
return;
|
|
14195
14429
|
}
|
|
14196
14430
|
const cmp = compareSemver(current, latest);
|
|
14197
14431
|
if (cmp === 0) {
|
|
14198
|
-
console.log(
|
|
14432
|
+
console.log(import_chalk29.default.green("\u2713 You are on the latest version."));
|
|
14199
14433
|
return;
|
|
14200
14434
|
}
|
|
14201
14435
|
if (cmp > 0) {
|
|
14202
|
-
console.log(
|
|
14436
|
+
console.log(import_chalk29.default.green(`\u2713 You are ahead of npm (published: ${latest}).`));
|
|
14203
14437
|
return;
|
|
14204
14438
|
}
|
|
14205
|
-
console.log(
|
|
14439
|
+
console.log(import_chalk29.default.cyan(`Update available: ${current} \u2192 ${latest}`));
|
|
14206
14440
|
if (opts.check) {
|
|
14207
|
-
console.log(
|
|
14441
|
+
console.log(import_chalk29.default.dim("\nRun: hyv upgrade or npm i -g @holdyourvoice/hyv@latest\n"));
|
|
14208
14442
|
return;
|
|
14209
14443
|
}
|
|
14210
|
-
console.log(
|
|
14444
|
+
console.log(import_chalk29.default.dim("Installing..."));
|
|
14211
14445
|
try {
|
|
14212
|
-
(0,
|
|
14213
|
-
console.log(
|
|
14446
|
+
(0, import_child_process3.execSync)("npm i -g @holdyourvoice/hyv@latest", { stdio: "inherit" });
|
|
14447
|
+
console.log(import_chalk29.default.green("\n\u2713 Upgraded successfully. Restart your terminal.\n"));
|
|
14214
14448
|
} catch {
|
|
14215
|
-
console.log(
|
|
14449
|
+
console.log(import_chalk29.default.red("\nUpgrade failed. Run manually: npm i -g @holdyourvoice/hyv@latest\n"));
|
|
14216
14450
|
process.exit(1);
|
|
14217
14451
|
}
|
|
14218
14452
|
});
|
|
14219
14453
|
}
|
|
14220
14454
|
|
|
14221
14455
|
// src/mcp.ts
|
|
14222
|
-
var
|
|
14223
|
-
var
|
|
14456
|
+
var fs21 = __toESM(require("fs"));
|
|
14457
|
+
var path21 = __toESM(require("path"));
|
|
14224
14458
|
var os7 = __toESM(require("os"));
|
|
14225
14459
|
init_classifier();
|
|
14226
14460
|
init_autofix();
|
|
@@ -14232,20 +14466,20 @@ init_welcome();
|
|
|
14232
14466
|
init_config();
|
|
14233
14467
|
init_telemetry();
|
|
14234
14468
|
init_access();
|
|
14235
|
-
var VOICE_MD =
|
|
14469
|
+
var VOICE_MD = path21.join(os7.homedir(), ".hyv", "voice.md");
|
|
14236
14470
|
var MAX_RESPONSE_CHARS = 12e4;
|
|
14237
14471
|
var MAX_SCAN_FILE_BYTES = 2 * 1024 * 1024;
|
|
14238
14472
|
function readScanFile(filePath) {
|
|
14239
|
-
const cwdReal =
|
|
14240
|
-
const resolved =
|
|
14241
|
-
if (!resolved.startsWith(cwdReal +
|
|
14473
|
+
const cwdReal = fs21.realpathSync(process.cwd());
|
|
14474
|
+
const resolved = fs21.realpathSync(path21.resolve(filePath));
|
|
14475
|
+
if (!resolved.startsWith(cwdReal + path21.sep) && resolved !== cwdReal) {
|
|
14242
14476
|
throw new Error(`file must be in the current working directory (${cwdReal})`);
|
|
14243
14477
|
}
|
|
14244
|
-
const stat =
|
|
14478
|
+
const stat = fs21.statSync(resolved);
|
|
14245
14479
|
if (stat.size > MAX_SCAN_FILE_BYTES) {
|
|
14246
14480
|
throw new Error(`file too large (max ${MAX_SCAN_FILE_BYTES} bytes)`);
|
|
14247
14481
|
}
|
|
14248
|
-
return
|
|
14482
|
+
return fs21.readFileSync(resolved, "utf-8");
|
|
14249
14483
|
}
|
|
14250
14484
|
function toolResultPayload(result) {
|
|
14251
14485
|
const isError = result.startsWith("Error:") || result.startsWith("Unknown tool:");
|
|
@@ -14254,10 +14488,10 @@ function toolResultPayload(result) {
|
|
|
14254
14488
|
...isError ? { isError: true } : {}
|
|
14255
14489
|
};
|
|
14256
14490
|
}
|
|
14257
|
-
var pkgPath =
|
|
14491
|
+
var pkgPath = path21.resolve(__dirname, "..", "package.json");
|
|
14258
14492
|
var pkgVersion = (() => {
|
|
14259
14493
|
try {
|
|
14260
|
-
return JSON.parse(
|
|
14494
|
+
return JSON.parse(fs21.readFileSync(pkgPath, "utf-8")).version;
|
|
14261
14495
|
} catch {
|
|
14262
14496
|
return "2.7.1";
|
|
14263
14497
|
}
|
|
@@ -14831,7 +15065,7 @@ async function handleRequest(line) {
|
|
|
14831
15065
|
}
|
|
14832
15066
|
async function startMcpServer() {
|
|
14833
15067
|
const access = await getAccessState().catch(() => null);
|
|
14834
|
-
if (
|
|
15068
|
+
if (fs21.existsSync(VOICE_MD)) {
|
|
14835
15069
|
mcpLog("info", `voice profile: ${VOICE_MD}`);
|
|
14836
15070
|
} else {
|
|
14837
15071
|
mcpLog("info", "free local engine ready \u2014 no voice profile yet");
|
|
@@ -14863,228 +15097,142 @@ async function startMcpServer() {
|
|
|
14863
15097
|
}
|
|
14864
15098
|
|
|
14865
15099
|
// src/lib/mcp-setup.ts
|
|
14866
|
-
var
|
|
14867
|
-
var
|
|
14868
|
-
var
|
|
15100
|
+
var import_chalk30 = __toESM(require_source());
|
|
15101
|
+
var fs22 = __toESM(require("fs"));
|
|
15102
|
+
var path22 = __toESM(require("path"));
|
|
14869
15103
|
var os8 = __toESM(require("os"));
|
|
14870
|
-
var import_child_process3 = require("child_process");
|
|
14871
15104
|
init_version();
|
|
14872
15105
|
var HOME2 = os8.homedir();
|
|
14873
15106
|
var IS_WIN2 = process.platform === "win32";
|
|
14874
15107
|
function claudeDesktopConfigPath() {
|
|
14875
15108
|
if (IS_WIN2)
|
|
14876
|
-
return
|
|
15109
|
+
return path22.join(HOME2, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
|
|
14877
15110
|
if (process.platform === "linux")
|
|
14878
|
-
return
|
|
14879
|
-
return
|
|
14880
|
-
}
|
|
14881
|
-
function mcpSnippet() {
|
|
14882
|
-
const entry = [
|
|
14883
|
-
path21.resolve(process.argv[1] || ""),
|
|
14884
|
-
path21.resolve(__dirname, "index.js"),
|
|
14885
|
-
path21.resolve(__dirname, "..", "dist", "index.js")
|
|
14886
|
-
].find((p) => p && fs21.existsSync(p));
|
|
14887
|
-
if (entry) {
|
|
14888
|
-
return JSON.stringify({ command: process.execPath, args: [entry, "mcp"] }, null, 2);
|
|
14889
|
-
}
|
|
14890
|
-
return JSON.stringify({ command: "hyv", args: ["mcp"] }, null, 2);
|
|
15111
|
+
return path22.join(HOME2, ".config", "Claude", "claude_desktop_config.json");
|
|
15112
|
+
return path22.join(HOME2, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
14891
15113
|
}
|
|
14892
15114
|
function printMcpSetup() {
|
|
14893
|
-
console.log(
|
|
14894
|
-
console.log(
|
|
15115
|
+
console.log(import_chalk30.default.bold("\nhold your voice \u2014 mcp setup\n"));
|
|
15116
|
+
console.log(import_chalk30.default.dim(` ${getEngineLabel()}
|
|
14895
15117
|
`));
|
|
14896
|
-
console.log(
|
|
14897
|
-
console.log(
|
|
14898
|
-
console.log(
|
|
14899
|
-
console.log(
|
|
15118
|
+
console.log(import_chalk30.default.bold("Claude Desktop"));
|
|
15119
|
+
console.log(import_chalk30.default.dim(" Add to claude_desktop_config.json \u2192 mcpServers.hyv:"));
|
|
15120
|
+
console.log(import_chalk30.default.cyan(` ${mcpServerSnippet().split("\n").join("\n ")}`));
|
|
15121
|
+
console.log(import_chalk30.default.dim(` Config: ${claudeDesktopConfigPath()}
|
|
14900
15122
|
`));
|
|
14901
|
-
console.log(
|
|
14902
|
-
console.log(
|
|
14903
|
-
console.log(
|
|
14904
|
-
console.log(
|
|
14905
|
-
console.log(
|
|
14906
|
-
console.log(
|
|
14907
|
-
console.log(
|
|
14908
|
-
console.log(
|
|
14909
|
-
console.log(
|
|
14910
|
-
console.log(
|
|
14911
|
-
console.log(
|
|
14912
|
-
console.log(
|
|
14913
|
-
console.log(
|
|
14914
|
-
console.log(
|
|
14915
|
-
console.log(
|
|
14916
|
-
console.log(
|
|
14917
|
-
console.log(
|
|
14918
|
-
console.log(
|
|
14919
|
-
console.log(
|
|
14920
|
-
console.log(
|
|
14921
|
-
}
|
|
14922
|
-
async function testMcpStdioSubprocess() {
|
|
14923
|
-
const candidates = [
|
|
14924
|
-
path21.resolve(process.argv[1] || ""),
|
|
14925
|
-
path21.resolve(__dirname, "index.js"),
|
|
14926
|
-
path21.resolve(__dirname, "..", "dist", "index.js")
|
|
14927
|
-
];
|
|
14928
|
-
const entry = candidates.find((p) => p && fs21.existsSync(p));
|
|
14929
|
-
if (!entry)
|
|
14930
|
-
return { ok: false };
|
|
14931
|
-
return new Promise((resolve14) => {
|
|
14932
|
-
const child = (0, import_child_process3.spawn)(process.execPath, [entry, "mcp"], {
|
|
14933
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
14934
|
-
env: { ...process.env, HYV_POSTINSTALL_QUIET: "1" }
|
|
14935
|
-
});
|
|
14936
|
-
let buffer = "";
|
|
14937
|
-
let settled = false;
|
|
14938
|
-
const finish = (ok, toolCount) => {
|
|
14939
|
-
if (settled)
|
|
14940
|
-
return;
|
|
14941
|
-
settled = true;
|
|
14942
|
-
clearTimeout(timeout);
|
|
14943
|
-
try {
|
|
14944
|
-
child.kill();
|
|
14945
|
-
} catch {
|
|
14946
|
-
}
|
|
14947
|
-
resolve14({ ok, toolCount });
|
|
14948
|
-
};
|
|
14949
|
-
const timeout = setTimeout(() => finish(false), 1e4);
|
|
14950
|
-
const handleLine = (line) => {
|
|
14951
|
-
const trimmed = line.trim();
|
|
14952
|
-
if (!trimmed.startsWith("{"))
|
|
14953
|
-
return;
|
|
14954
|
-
try {
|
|
14955
|
-
const msg = JSON.parse(trimmed);
|
|
14956
|
-
if (msg.id === 2 && Array.isArray(msg.result?.tools) && msg.result.tools.length > 0) {
|
|
14957
|
-
finish(true, msg.result.tools.length);
|
|
14958
|
-
}
|
|
14959
|
-
} catch {
|
|
14960
|
-
}
|
|
14961
|
-
};
|
|
14962
|
-
child.stdout.on("data", (chunk) => {
|
|
14963
|
-
buffer += chunk.toString();
|
|
14964
|
-
const lines = buffer.split("\n");
|
|
14965
|
-
buffer = lines.pop() || "";
|
|
14966
|
-
for (const line of lines)
|
|
14967
|
-
handleLine(line);
|
|
14968
|
-
});
|
|
14969
|
-
child.on("error", () => finish(false));
|
|
14970
|
-
child.on("exit", () => {
|
|
14971
|
-
if (!settled) {
|
|
14972
|
-
handleLine(buffer);
|
|
14973
|
-
finish(buffer.includes("hyv_scan"));
|
|
14974
|
-
}
|
|
14975
|
-
});
|
|
14976
|
-
setTimeout(() => {
|
|
14977
|
-
const send2 = (payload) => {
|
|
14978
|
-
child.stdin.write(`${JSON.stringify(payload)}
|
|
14979
|
-
`);
|
|
14980
|
-
};
|
|
14981
|
-
send2({
|
|
14982
|
-
jsonrpc: "2.0",
|
|
14983
|
-
id: 1,
|
|
14984
|
-
method: "initialize",
|
|
14985
|
-
params: {
|
|
14986
|
-
protocolVersion: "2024-11-05",
|
|
14987
|
-
capabilities: {},
|
|
14988
|
-
clientInfo: { name: "hyv-self-test", version: "1.0" }
|
|
14989
|
-
}
|
|
14990
|
-
});
|
|
14991
|
-
send2({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
14992
|
-
send2({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
|
|
14993
|
-
}, 500);
|
|
14994
|
-
});
|
|
15123
|
+
console.log(import_chalk30.default.bold("Cursor"));
|
|
15124
|
+
console.log(import_chalk30.default.dim(" MCP: ~/.cursor/mcp.json \u2192 mcpServers.hyv (same JSON as above)"));
|
|
15125
|
+
console.log(import_chalk30.default.dim(" Rule: ~/.cursor/rules/hyv.mdc (alwaysApply \u2014 auto via postinstall)\n"));
|
|
15126
|
+
console.log(import_chalk30.default.bold("Claude Code"));
|
|
15127
|
+
console.log(import_chalk30.default.dim(" Command: ~/.claude/commands/hyv.md"));
|
|
15128
|
+
console.log(import_chalk30.default.dim(" Skill: ~/.claude/skills/hold-your-voice/SKILL.md\n"));
|
|
15129
|
+
console.log(import_chalk30.default.bold("Windsurf"));
|
|
15130
|
+
console.log(import_chalk30.default.dim(" Rule: ~/.windsurf/rules/hyv.md (trigger: always_on)\n"));
|
|
15131
|
+
console.log(import_chalk30.default.bold("Codex"));
|
|
15132
|
+
console.log(import_chalk30.default.dim(" Instructions: ~/.codex/AGENTS.md (merged on install)\n"));
|
|
15133
|
+
console.log(import_chalk30.default.bold("Command Code"));
|
|
15134
|
+
console.log(import_chalk30.default.dim(" Skill: ~/.commandcode/skills/hyv/SKILL.md\n"));
|
|
15135
|
+
console.log(import_chalk30.default.bold("ChatGPT"));
|
|
15136
|
+
console.log(import_chalk30.default.dim(" hyv mcp --setup-chatgpt\n"));
|
|
15137
|
+
console.log(import_chalk30.default.bold("Auto-configure"));
|
|
15138
|
+
console.log(import_chalk30.default.dim(" hyv doctor --fix-agents"));
|
|
15139
|
+
console.log(import_chalk30.default.dim(" HYV_AUTO_CONFIGURE_AGENTS=0 npm i -g @holdyourvoice/hyv (skip)\n"));
|
|
15140
|
+
console.log(import_chalk30.default.bold("Verify"));
|
|
15141
|
+
console.log(import_chalk30.default.dim(" hyv mcp --test"));
|
|
15142
|
+
console.log(import_chalk30.default.dim(" HYV_TELEMETRY=1 hyv mcp (optional usage logging to ~/.hyv/telemetry/)\n"));
|
|
14995
15143
|
}
|
|
14996
15144
|
async function runMcpSelfTest() {
|
|
14997
|
-
console.log(
|
|
14998
|
-
console.log(
|
|
15145
|
+
console.log(import_chalk30.default.bold("\nhold your voice \u2014 mcp self-test\n"));
|
|
15146
|
+
console.log(import_chalk30.default.dim(` ${getEngineLabel()}
|
|
14999
15147
|
`));
|
|
15000
15148
|
let passed = 0;
|
|
15001
15149
|
let failed = 0;
|
|
15002
15150
|
const tools = getMcpToolNames();
|
|
15003
15151
|
if (tools.length >= 10) {
|
|
15004
|
-
console.log(
|
|
15152
|
+
console.log(import_chalk30.default.green(` \u2713 ${tools.length} MCP tools registered`));
|
|
15005
15153
|
passed++;
|
|
15006
15154
|
} else {
|
|
15007
|
-
console.log(
|
|
15155
|
+
console.log(import_chalk30.default.red(` \u2717 expected 10+ tools, got ${tools.length}`));
|
|
15008
15156
|
failed++;
|
|
15009
15157
|
}
|
|
15010
15158
|
const required = ["hyv_welcome", "hyv_scan", "hyv_analyze", "hyv_clean", "hyv_validate", "hyv_list_free_tools"];
|
|
15011
15159
|
for (const name of required) {
|
|
15012
15160
|
if (tools.includes(name)) {
|
|
15013
|
-
console.log(
|
|
15161
|
+
console.log(import_chalk30.default.green(` \u2713 tool: ${name}`));
|
|
15014
15162
|
passed++;
|
|
15015
15163
|
} else {
|
|
15016
|
-
console.log(
|
|
15164
|
+
console.log(import_chalk30.default.red(` \u2717 missing tool: ${name}`));
|
|
15017
15165
|
failed++;
|
|
15018
15166
|
}
|
|
15019
15167
|
}
|
|
15020
15168
|
try {
|
|
15021
15169
|
const welcome = await invokeMcpTool("hyv_welcome", {});
|
|
15022
15170
|
if (welcome.includes("Hold Your Voice") || welcome.includes("hold your voice")) {
|
|
15023
|
-
console.log(
|
|
15171
|
+
console.log(import_chalk30.default.green(" \u2713 hyv_welcome responds"));
|
|
15024
15172
|
passed++;
|
|
15025
15173
|
} else {
|
|
15026
|
-
console.log(
|
|
15174
|
+
console.log(import_chalk30.default.red(" \u2717 hyv_welcome unexpected output"));
|
|
15027
15175
|
failed++;
|
|
15028
15176
|
}
|
|
15029
15177
|
} catch (e) {
|
|
15030
|
-
console.log(
|
|
15178
|
+
console.log(import_chalk30.default.red(` \u2717 hyv_welcome failed: ${e.message}`));
|
|
15031
15179
|
failed++;
|
|
15032
15180
|
}
|
|
15033
15181
|
try {
|
|
15034
15182
|
const demo = await invokeMcpTool("hyv_demo", {});
|
|
15035
15183
|
if (demo.includes("Score") || demo.includes("issues")) {
|
|
15036
|
-
console.log(
|
|
15184
|
+
console.log(import_chalk30.default.green(" \u2713 hyv_demo pipeline works"));
|
|
15037
15185
|
passed++;
|
|
15038
15186
|
} else {
|
|
15039
|
-
console.log(
|
|
15187
|
+
console.log(import_chalk30.default.red(" \u2717 hyv_demo unexpected output"));
|
|
15040
15188
|
failed++;
|
|
15041
15189
|
}
|
|
15042
15190
|
} catch (e) {
|
|
15043
|
-
console.log(
|
|
15191
|
+
console.log(import_chalk30.default.red(` \u2717 hyv_demo failed: ${e.message}`));
|
|
15044
15192
|
failed++;
|
|
15045
15193
|
}
|
|
15046
|
-
const voiceMd =
|
|
15047
|
-
if (
|
|
15048
|
-
console.log(
|
|
15194
|
+
const voiceMd = path22.join(HOME2, ".hyv", "voice.md");
|
|
15195
|
+
if (fs22.existsSync(voiceMd)) {
|
|
15196
|
+
console.log(import_chalk30.default.green(" \u2713 voice profile found"));
|
|
15049
15197
|
passed++;
|
|
15050
15198
|
} else {
|
|
15051
|
-
console.log(
|
|
15199
|
+
console.log(import_chalk30.default.dim(" - no voice.md (free local engine still works)"));
|
|
15052
15200
|
}
|
|
15053
15201
|
if (getDemoText().length > 100) {
|
|
15054
|
-
console.log(
|
|
15202
|
+
console.log(import_chalk30.default.green(" \u2713 demo content available"));
|
|
15055
15203
|
passed++;
|
|
15056
15204
|
} else {
|
|
15057
|
-
console.log(
|
|
15205
|
+
console.log(import_chalk30.default.red(" \u2717 demo content missing"));
|
|
15058
15206
|
failed++;
|
|
15059
15207
|
}
|
|
15060
15208
|
try {
|
|
15061
15209
|
const stdio = await testMcpStdioSubprocess();
|
|
15062
15210
|
if (stdio.ok && (stdio.toolCount || 0) >= 10) {
|
|
15063
|
-
console.log(
|
|
15211
|
+
console.log(import_chalk30.default.green(` \u2713 stdio MCP subprocess responds (${stdio.toolCount} tools)`));
|
|
15064
15212
|
passed++;
|
|
15065
15213
|
} else if (stdio.ok) {
|
|
15066
|
-
console.log(
|
|
15214
|
+
console.log(import_chalk30.default.yellow(` ! stdio MCP subprocess ok but only ${stdio.toolCount || 0} tools`));
|
|
15067
15215
|
failed++;
|
|
15068
15216
|
} else {
|
|
15069
|
-
console.log(
|
|
15217
|
+
console.log(import_chalk30.default.red(" \u2717 stdio MCP subprocess failed"));
|
|
15070
15218
|
failed++;
|
|
15071
15219
|
}
|
|
15072
15220
|
} catch (e) {
|
|
15073
|
-
console.log(
|
|
15221
|
+
console.log(import_chalk30.default.red(` \u2717 stdio MCP subprocess failed: ${e.message}`));
|
|
15074
15222
|
failed++;
|
|
15075
15223
|
}
|
|
15076
15224
|
console.log("");
|
|
15077
15225
|
if (failed === 0) {
|
|
15078
|
-
console.log(
|
|
15079
|
-
console.log(
|
|
15226
|
+
console.log(import_chalk30.default.green(`\u2713 all checks passed (${passed})`));
|
|
15227
|
+
console.log(import_chalk30.default.dim("\nStart server: hyv mcp\n"));
|
|
15080
15228
|
return true;
|
|
15081
15229
|
}
|
|
15082
|
-
console.log(
|
|
15230
|
+
console.log(import_chalk30.default.yellow(`! ${failed} check(s) failed, ${passed} passed`));
|
|
15083
15231
|
return false;
|
|
15084
15232
|
}
|
|
15085
15233
|
|
|
15086
15234
|
// src/commands/export.ts
|
|
15087
|
-
var
|
|
15235
|
+
var fs23 = __toESM(require("fs"));
|
|
15088
15236
|
init_api();
|
|
15089
15237
|
var FORMATS = {
|
|
15090
15238
|
claude: {
|
|
@@ -15171,7 +15319,7 @@ async function exportCommand(format, opts) {
|
|
|
15171
15319
|
const prompt = fmt.wrap(detail.profile, detail.body);
|
|
15172
15320
|
if (opts.output) {
|
|
15173
15321
|
const outFile = opts.output.replace("{name}", profile.slug || profile.name);
|
|
15174
|
-
|
|
15322
|
+
fs23.writeFileSync(outFile, prompt);
|
|
15175
15323
|
results.push({ profile: profile.name, file: outFile });
|
|
15176
15324
|
} else {
|
|
15177
15325
|
results.push({ profile: profile.name, prompt });
|
|
@@ -15208,13 +15356,13 @@ async function exportCommand(format, opts) {
|
|
|
15208
15356
|
// src/index.ts
|
|
15209
15357
|
init_access();
|
|
15210
15358
|
init_welcome();
|
|
15211
|
-
var
|
|
15212
|
-
var
|
|
15359
|
+
var fs24 = __toESM(require("fs"));
|
|
15360
|
+
var path23 = __toESM(require("path"));
|
|
15213
15361
|
var program2 = new Command();
|
|
15214
|
-
var pkgPath2 =
|
|
15362
|
+
var pkgPath2 = path23.resolve(__dirname, "..", "package.json");
|
|
15215
15363
|
var pkgVersion2 = (() => {
|
|
15216
15364
|
try {
|
|
15217
|
-
return JSON.parse(
|
|
15365
|
+
return JSON.parse(fs24.readFileSync(pkgPath2, "utf-8")).version;
|
|
15218
15366
|
} catch {
|
|
15219
15367
|
return "2.7.1";
|
|
15220
15368
|
}
|
|
@@ -15258,15 +15406,15 @@ program2.command("mcp").description("Start MCP server (for Claude Desktop and ot
|
|
|
15258
15406
|
return;
|
|
15259
15407
|
}
|
|
15260
15408
|
if (opts.setupChatgpt) {
|
|
15261
|
-
console.log(
|
|
15409
|
+
console.log(import_chalk31.default.bold("\nhold your voice \u2014 chatgpt setup\n"));
|
|
15262
15410
|
console.log("To connect HYV to ChatGPT:");
|
|
15263
|
-
console.log(
|
|
15264
|
-
console.log(
|
|
15265
|
-
console.log(
|
|
15266
|
-
console.log(
|
|
15411
|
+
console.log(import_chalk31.default.dim(" 1. Go to ") + import_chalk31.default.cyan("https://chatgpt.com/#settings/Connectors"));
|
|
15412
|
+
console.log(import_chalk31.default.dim(" 2. Add a new connector"));
|
|
15413
|
+
console.log(import_chalk31.default.dim(" 3. For local MCP, use: ") + import_chalk31.default.cyan("hyv mcp"));
|
|
15414
|
+
console.log(import_chalk31.default.dim(" 4. ChatGPT Desktop supports stdio MCP servers"));
|
|
15267
15415
|
console.log("");
|
|
15268
|
-
console.log(
|
|
15269
|
-
console.log(
|
|
15416
|
+
console.log(import_chalk31.default.dim("Note: The remote HTTP MCP endpoint is not yet available."));
|
|
15417
|
+
console.log(import_chalk31.default.dim("Use the local stdio MCP server with Claude Desktop or Claude Code instead."));
|
|
15270
15418
|
return;
|
|
15271
15419
|
}
|
|
15272
15420
|
startMcpServer();
|