@holdyourvoice/hyv 2.9.9 → 2.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/index.js +242 -190
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable CLI changes. Also mirrored to [holdyourvoice.com/changelog](https://holdyourvoice.com/changelog) for user-facing releases.
|
|
4
4
|
|
|
5
|
+
## [2.9.10] — 2026-06-12
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Data safety** — welcome profile sync no longer overwrites enriched dashboard profiles (keywords, signature, rules, flashcard onboarding)
|
|
9
|
+
- Local profile cache backs up to `.hyv.bak` before overwrite; refuses empty content replacing real data
|
|
10
|
+
- `hyv sync` skips empty server profile payloads instead of wiping local cache
|
|
11
|
+
|
|
5
12
|
## [2.9.9] — 2026-06-12
|
|
6
13
|
|
|
7
14
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -974,7 +974,7 @@ var require_command = __commonJS({
|
|
|
974
974
|
var EventEmitter = require("node:events").EventEmitter;
|
|
975
975
|
var childProcess = require("node:child_process");
|
|
976
976
|
var path26 = require("node:path");
|
|
977
|
-
var
|
|
977
|
+
var fs29 = 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();
|
|
@@ -1917,12 +1917,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1917
1917
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1918
1918
|
function findFile(baseDir, baseName) {
|
|
1919
1919
|
const localBin = path26.resolve(baseDir, baseName);
|
|
1920
|
-
if (
|
|
1920
|
+
if (fs29.existsSync(localBin))
|
|
1921
1921
|
return localBin;
|
|
1922
1922
|
if (sourceExt.includes(path26.extname(baseName)))
|
|
1923
1923
|
return void 0;
|
|
1924
1924
|
const foundExt = sourceExt.find(
|
|
1925
|
-
(ext) =>
|
|
1925
|
+
(ext) => fs29.existsSync(`${localBin}${ext}`)
|
|
1926
1926
|
);
|
|
1927
1927
|
if (foundExt)
|
|
1928
1928
|
return `${localBin}${foundExt}`;
|
|
@@ -1935,7 +1935,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1935
1935
|
if (this._scriptPath) {
|
|
1936
1936
|
let resolvedScriptPath;
|
|
1937
1937
|
try {
|
|
1938
|
-
resolvedScriptPath =
|
|
1938
|
+
resolvedScriptPath = fs29.realpathSync(this._scriptPath);
|
|
1939
1939
|
} catch (err) {
|
|
1940
1940
|
resolvedScriptPath = this._scriptPath;
|
|
1941
1941
|
}
|
|
@@ -4611,6 +4611,44 @@ var require_source = __commonJS({
|
|
|
4611
4611
|
}
|
|
4612
4612
|
});
|
|
4613
4613
|
|
|
4614
|
+
// src/lib/data-safety.ts
|
|
4615
|
+
function shouldReplaceCachedContent(existing, incoming) {
|
|
4616
|
+
const next = incoming.trim();
|
|
4617
|
+
if (!next) {
|
|
4618
|
+
return !existing?.trim();
|
|
4619
|
+
}
|
|
4620
|
+
return true;
|
|
4621
|
+
}
|
|
4622
|
+
function backupProfileFileIfExists(profilePath) {
|
|
4623
|
+
if (!fs.existsSync(profilePath)) {
|
|
4624
|
+
return false;
|
|
4625
|
+
}
|
|
4626
|
+
try {
|
|
4627
|
+
fs.copyFileSync(profilePath, `${profilePath}.hyv.bak`);
|
|
4628
|
+
return true;
|
|
4629
|
+
} catch {
|
|
4630
|
+
return false;
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
function safeWriteProfileFile(profilePath, content, existing) {
|
|
4634
|
+
if (!shouldReplaceCachedContent(existing, content)) {
|
|
4635
|
+
return { written: false, backedUp: false, reason: "empty-would-erase" };
|
|
4636
|
+
}
|
|
4637
|
+
if (existing !== null && existing === content) {
|
|
4638
|
+
return { written: false, backedUp: false, reason: "unchanged" };
|
|
4639
|
+
}
|
|
4640
|
+
const backedUp = backupProfileFileIfExists(profilePath);
|
|
4641
|
+
fs.writeFileSync(profilePath, content, { mode: 384 });
|
|
4642
|
+
return { written: true, backedUp };
|
|
4643
|
+
}
|
|
4644
|
+
var fs;
|
|
4645
|
+
var init_data_safety = __esm({
|
|
4646
|
+
"src/lib/data-safety.ts"() {
|
|
4647
|
+
"use strict";
|
|
4648
|
+
fs = __toESM(require("fs"));
|
|
4649
|
+
}
|
|
4650
|
+
});
|
|
4651
|
+
|
|
4614
4652
|
// src/lib/config.ts
|
|
4615
4653
|
function validateApiBase(raw) {
|
|
4616
4654
|
const trimmed = raw.replace(/\/$/, "");
|
|
@@ -4697,11 +4735,11 @@ function profilePathForName(name) {
|
|
|
4697
4735
|
function ensureHyvDir() {
|
|
4698
4736
|
const dirs = [HYV_DIR, PROFILES_DIR, CACHE_DIR, QUEUE_DIR];
|
|
4699
4737
|
for (const dir of dirs) {
|
|
4700
|
-
if (!
|
|
4701
|
-
|
|
4738
|
+
if (!fs2.existsSync(dir)) {
|
|
4739
|
+
fs2.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
4702
4740
|
} else {
|
|
4703
4741
|
try {
|
|
4704
|
-
|
|
4742
|
+
fs2.chmodSync(dir, 448);
|
|
4705
4743
|
} catch {
|
|
4706
4744
|
}
|
|
4707
4745
|
}
|
|
@@ -4709,33 +4747,33 @@ function ensureHyvDir() {
|
|
|
4709
4747
|
}
|
|
4710
4748
|
function appendSecureLine(filePath, line, dir) {
|
|
4711
4749
|
if (dir) {
|
|
4712
|
-
if (!
|
|
4713
|
-
|
|
4750
|
+
if (!fs2.existsSync(dir))
|
|
4751
|
+
fs2.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
4714
4752
|
else {
|
|
4715
4753
|
try {
|
|
4716
|
-
|
|
4754
|
+
fs2.chmodSync(dir, 448);
|
|
4717
4755
|
} catch {
|
|
4718
4756
|
}
|
|
4719
4757
|
}
|
|
4720
4758
|
}
|
|
4721
|
-
if (!
|
|
4722
|
-
|
|
4759
|
+
if (!fs2.existsSync(filePath)) {
|
|
4760
|
+
fs2.writeFileSync(filePath, line, { mode: 384 });
|
|
4723
4761
|
return;
|
|
4724
4762
|
}
|
|
4725
4763
|
try {
|
|
4726
|
-
|
|
4764
|
+
fs2.chmodSync(filePath, 384);
|
|
4727
4765
|
} catch {
|
|
4728
4766
|
}
|
|
4729
|
-
|
|
4767
|
+
fs2.appendFileSync(filePath, line);
|
|
4730
4768
|
}
|
|
4731
4769
|
function isInitialized() {
|
|
4732
|
-
return
|
|
4770
|
+
return fs2.existsSync(AUTH_FILE);
|
|
4733
4771
|
}
|
|
4734
4772
|
function readAuth() {
|
|
4735
4773
|
try {
|
|
4736
|
-
if (!
|
|
4774
|
+
if (!fs2.existsSync(AUTH_FILE))
|
|
4737
4775
|
return null;
|
|
4738
|
-
const data =
|
|
4776
|
+
const data = fs2.readFileSync(AUTH_FILE, "utf-8");
|
|
4739
4777
|
return JSON.parse(data);
|
|
4740
4778
|
} catch {
|
|
4741
4779
|
return null;
|
|
@@ -4743,13 +4781,13 @@ function readAuth() {
|
|
|
4743
4781
|
}
|
|
4744
4782
|
function writeAuth(auth) {
|
|
4745
4783
|
ensureHyvDir();
|
|
4746
|
-
|
|
4784
|
+
fs2.writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), { mode: 384 });
|
|
4747
4785
|
}
|
|
4748
4786
|
function readConfig() {
|
|
4749
4787
|
try {
|
|
4750
|
-
if (!
|
|
4788
|
+
if (!fs2.existsSync(CONFIG_FILE))
|
|
4751
4789
|
return {};
|
|
4752
|
-
const data =
|
|
4790
|
+
const data = fs2.readFileSync(CONFIG_FILE, "utf-8");
|
|
4753
4791
|
return JSON.parse(data);
|
|
4754
4792
|
} catch {
|
|
4755
4793
|
return {};
|
|
@@ -4757,7 +4795,7 @@ function readConfig() {
|
|
|
4757
4795
|
}
|
|
4758
4796
|
function writeConfig(config) {
|
|
4759
4797
|
ensureHyvDir();
|
|
4760
|
-
|
|
4798
|
+
fs2.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 384 });
|
|
4761
4799
|
}
|
|
4762
4800
|
function getToken() {
|
|
4763
4801
|
const auth = readAuth();
|
|
@@ -4773,9 +4811,9 @@ function getToken() {
|
|
|
4773
4811
|
}
|
|
4774
4812
|
function listCachedProfiles() {
|
|
4775
4813
|
try {
|
|
4776
|
-
if (!
|
|
4814
|
+
if (!fs2.existsSync(PROFILES_DIR))
|
|
4777
4815
|
return [];
|
|
4778
|
-
return
|
|
4816
|
+
return fs2.readdirSync(PROFILES_DIR).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
4779
4817
|
} catch {
|
|
4780
4818
|
return [];
|
|
4781
4819
|
}
|
|
@@ -4783,9 +4821,9 @@ function listCachedProfiles() {
|
|
|
4783
4821
|
function readCachedProfile(name) {
|
|
4784
4822
|
const profilePath = profilePathForName(name);
|
|
4785
4823
|
try {
|
|
4786
|
-
if (!
|
|
4824
|
+
if (!fs2.existsSync(profilePath))
|
|
4787
4825
|
return null;
|
|
4788
|
-
return
|
|
4826
|
+
return fs2.readFileSync(profilePath, "utf-8");
|
|
4789
4827
|
} catch (err) {
|
|
4790
4828
|
if (err.message?.includes("Invalid profile name"))
|
|
4791
4829
|
throw err;
|
|
@@ -4794,15 +4832,19 @@ function readCachedProfile(name) {
|
|
|
4794
4832
|
}
|
|
4795
4833
|
function writeCachedProfile(name, content) {
|
|
4796
4834
|
const profilePath = profilePathForName(name);
|
|
4797
|
-
|
|
4835
|
+
const existing = fs2.existsSync(profilePath) ? fs2.readFileSync(profilePath, "utf-8") : null;
|
|
4836
|
+
const result = safeWriteProfileFile(profilePath, content, existing);
|
|
4837
|
+
if (!result.written && result.reason === "empty-would-erase") {
|
|
4838
|
+
throw new Error("Refusing to replace profile with empty content");
|
|
4839
|
+
}
|
|
4798
4840
|
}
|
|
4799
4841
|
function getQueuedSignals() {
|
|
4800
4842
|
try {
|
|
4801
|
-
if (!
|
|
4843
|
+
if (!fs2.existsSync(QUEUE_DIR))
|
|
4802
4844
|
return [];
|
|
4803
|
-
const files =
|
|
4845
|
+
const files = fs2.readdirSync(QUEUE_DIR).filter((f) => f.endsWith(".json"));
|
|
4804
4846
|
return files.map((f) => {
|
|
4805
|
-
const data =
|
|
4847
|
+
const data = fs2.readFileSync(path.join(QUEUE_DIR, f), "utf-8");
|
|
4806
4848
|
return JSON.parse(data);
|
|
4807
4849
|
});
|
|
4808
4850
|
} catch {
|
|
@@ -4813,29 +4855,30 @@ function queueSignal(signal) {
|
|
|
4813
4855
|
ensureHyvDir();
|
|
4814
4856
|
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
|
4815
4857
|
const filePath = path.join(QUEUE_DIR, `${id}.json`);
|
|
4816
|
-
|
|
4858
|
+
fs2.writeFileSync(filePath, JSON.stringify(signal, null, 2), { mode: 384 });
|
|
4817
4859
|
}
|
|
4818
4860
|
function saveLastEditSession(session) {
|
|
4819
4861
|
ensureHyvDir();
|
|
4820
4862
|
const data = { ...session, saved_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4821
|
-
|
|
4863
|
+
fs2.writeFileSync(LAST_SESSION_FILE, JSON.stringify(data, null, 2), { mode: 384 });
|
|
4822
4864
|
}
|
|
4823
4865
|
function readLastEditSession() {
|
|
4824
4866
|
try {
|
|
4825
|
-
if (!
|
|
4867
|
+
if (!fs2.existsSync(LAST_SESSION_FILE))
|
|
4826
4868
|
return null;
|
|
4827
|
-
return JSON.parse(
|
|
4869
|
+
return JSON.parse(fs2.readFileSync(LAST_SESSION_FILE, "utf-8"));
|
|
4828
4870
|
} catch {
|
|
4829
4871
|
return null;
|
|
4830
4872
|
}
|
|
4831
4873
|
}
|
|
4832
|
-
var
|
|
4874
|
+
var fs2, path, os, HYV_DIR, AUTH_FILE, CONFIG_FILE, PROFILES_DIR, CACHE_DIR, QUEUE_DIR, LAST_SESSION_FILE, ALLOWED_API_HOSTS, ALLOWED_OAUTH_HOSTS, API_BASE, PROFILE_NAME_RE;
|
|
4833
4875
|
var init_config = __esm({
|
|
4834
4876
|
"src/lib/config.ts"() {
|
|
4835
4877
|
"use strict";
|
|
4836
|
-
|
|
4878
|
+
fs2 = __toESM(require("fs"));
|
|
4837
4879
|
path = __toESM(require("path"));
|
|
4838
4880
|
os = __toESM(require("os"));
|
|
4881
|
+
init_data_safety();
|
|
4839
4882
|
HYV_DIR = path.join(os.homedir(), ".hyv");
|
|
4840
4883
|
AUTH_FILE = path.join(HYV_DIR, "auth.json");
|
|
4841
4884
|
CONFIG_FILE = path.join(HYV_DIR, "config.json");
|
|
@@ -4860,11 +4903,11 @@ var init_config = __esm({
|
|
|
4860
4903
|
var require_is_docker = __commonJS({
|
|
4861
4904
|
"node_modules/is-docker/index.js"(exports2, module2) {
|
|
4862
4905
|
"use strict";
|
|
4863
|
-
var
|
|
4906
|
+
var fs29 = require("fs");
|
|
4864
4907
|
var isDocker;
|
|
4865
4908
|
function hasDockerEnv() {
|
|
4866
4909
|
try {
|
|
4867
|
-
|
|
4910
|
+
fs29.statSync("/.dockerenv");
|
|
4868
4911
|
return true;
|
|
4869
4912
|
} catch (_2) {
|
|
4870
4913
|
return false;
|
|
@@ -4872,7 +4915,7 @@ var require_is_docker = __commonJS({
|
|
|
4872
4915
|
}
|
|
4873
4916
|
function hasDockerCGroup() {
|
|
4874
4917
|
try {
|
|
4875
|
-
return
|
|
4918
|
+
return fs29.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
4876
4919
|
} catch (_2) {
|
|
4877
4920
|
return false;
|
|
4878
4921
|
}
|
|
@@ -4891,7 +4934,7 @@ var require_is_wsl = __commonJS({
|
|
|
4891
4934
|
"node_modules/is-wsl/index.js"(exports2, module2) {
|
|
4892
4935
|
"use strict";
|
|
4893
4936
|
var os12 = require("os");
|
|
4894
|
-
var
|
|
4937
|
+
var fs29 = require("fs");
|
|
4895
4938
|
var isDocker = require_is_docker();
|
|
4896
4939
|
var isWsl = () => {
|
|
4897
4940
|
if (process.platform !== "linux") {
|
|
@@ -4904,7 +4947,7 @@ var require_is_wsl = __commonJS({
|
|
|
4904
4947
|
return true;
|
|
4905
4948
|
}
|
|
4906
4949
|
try {
|
|
4907
|
-
return
|
|
4950
|
+
return fs29.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
|
|
4908
4951
|
} catch (_2) {
|
|
4909
4952
|
return false;
|
|
4910
4953
|
}
|
|
@@ -4945,7 +4988,7 @@ var require_open = __commonJS({
|
|
|
4945
4988
|
"node_modules/open/index.js"(exports2, module2) {
|
|
4946
4989
|
var path26 = require("path");
|
|
4947
4990
|
var childProcess = require("child_process");
|
|
4948
|
-
var { promises:
|
|
4991
|
+
var { promises: fs29, constants: fsConstants } = require("fs");
|
|
4949
4992
|
var isWsl = require_is_wsl();
|
|
4950
4993
|
var isDocker = require_is_docker();
|
|
4951
4994
|
var defineLazyProperty = require_define_lazy_prop();
|
|
@@ -4953,7 +4996,7 @@ var require_open = __commonJS({
|
|
|
4953
4996
|
var { platform, arch } = process;
|
|
4954
4997
|
var hasContainerEnv = () => {
|
|
4955
4998
|
try {
|
|
4956
|
-
|
|
4999
|
+
fs29.statSync("/run/.containerenv");
|
|
4957
5000
|
return true;
|
|
4958
5001
|
} catch {
|
|
4959
5002
|
return false;
|
|
@@ -4976,14 +5019,14 @@ var require_open = __commonJS({
|
|
|
4976
5019
|
const configFilePath = "/etc/wsl.conf";
|
|
4977
5020
|
let isConfigFileExists = false;
|
|
4978
5021
|
try {
|
|
4979
|
-
await
|
|
5022
|
+
await fs29.access(configFilePath, fsConstants.F_OK);
|
|
4980
5023
|
isConfigFileExists = true;
|
|
4981
5024
|
} catch {
|
|
4982
5025
|
}
|
|
4983
5026
|
if (!isConfigFileExists) {
|
|
4984
5027
|
return defaultMountPoint;
|
|
4985
5028
|
}
|
|
4986
|
-
const configContent = await
|
|
5029
|
+
const configContent = await fs29.readFile(configFilePath, { encoding: "utf8" });
|
|
4987
5030
|
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
4988
5031
|
if (!configMountPoint) {
|
|
4989
5032
|
return defaultMountPoint;
|
|
@@ -5083,7 +5126,7 @@ var require_open = __commonJS({
|
|
|
5083
5126
|
const isBundled = !__dirname || __dirname === "/";
|
|
5084
5127
|
let exeLocalXdgOpen = false;
|
|
5085
5128
|
try {
|
|
5086
|
-
await
|
|
5129
|
+
await fs29.access(localXdgOpenPath, fsConstants.X_OK);
|
|
5087
5130
|
exeLocalXdgOpen = true;
|
|
5088
5131
|
} catch {
|
|
5089
5132
|
}
|
|
@@ -5289,14 +5332,14 @@ function pkgRoot() {
|
|
|
5289
5332
|
// src/lib/ → cli/
|
|
5290
5333
|
];
|
|
5291
5334
|
for (const root of candidates) {
|
|
5292
|
-
if (
|
|
5335
|
+
if (fs3.existsSync(path2.join(root, "package.json")))
|
|
5293
5336
|
return root;
|
|
5294
5337
|
}
|
|
5295
5338
|
return path2.resolve(__dirname, "..");
|
|
5296
5339
|
}
|
|
5297
5340
|
function getCliVersion() {
|
|
5298
5341
|
try {
|
|
5299
|
-
const pkg = JSON.parse(
|
|
5342
|
+
const pkg = JSON.parse(fs3.readFileSync(path2.join(PKG_ROOT, "package.json"), "utf-8"));
|
|
5300
5343
|
return pkg.version || "unknown";
|
|
5301
5344
|
} catch {
|
|
5302
5345
|
return "unknown";
|
|
@@ -5304,8 +5347,8 @@ function getCliVersion() {
|
|
|
5304
5347
|
}
|
|
5305
5348
|
function getRulesVersion() {
|
|
5306
5349
|
try {
|
|
5307
|
-
if (
|
|
5308
|
-
return JSON.parse(
|
|
5350
|
+
if (fs3.existsSync(RULES_MANIFEST)) {
|
|
5351
|
+
return JSON.parse(fs3.readFileSync(RULES_MANIFEST, "utf-8")).version || "unknown";
|
|
5309
5352
|
}
|
|
5310
5353
|
} catch {
|
|
5311
5354
|
}
|
|
@@ -5343,11 +5386,11 @@ function fetchLatestNpmVersion(timeoutMs = 8e3) {
|
|
|
5343
5386
|
);
|
|
5344
5387
|
});
|
|
5345
5388
|
}
|
|
5346
|
-
var
|
|
5389
|
+
var fs3, path2, import_child_process, PKG_ROOT, RULES_MANIFEST;
|
|
5347
5390
|
var init_version = __esm({
|
|
5348
5391
|
"src/lib/version.ts"() {
|
|
5349
5392
|
"use strict";
|
|
5350
|
-
|
|
5393
|
+
fs3 = __toESM(require("fs"));
|
|
5351
5394
|
path2 = __toESM(require("path"));
|
|
5352
5395
|
import_child_process = require("child_process");
|
|
5353
5396
|
PKG_ROOT = pkgRoot();
|
|
@@ -5973,9 +6016,9 @@ function getDiskCachePath(slug) {
|
|
|
5973
6016
|
function loadFromDiskCache(slug) {
|
|
5974
6017
|
try {
|
|
5975
6018
|
const cachePath = getDiskCachePath(slug);
|
|
5976
|
-
if (!
|
|
6019
|
+
if (!fs4.existsSync(cachePath))
|
|
5977
6020
|
return null;
|
|
5978
|
-
const content =
|
|
6021
|
+
const content = fs4.readFileSync(cachePath, "utf-8");
|
|
5979
6022
|
const entry = JSON.parse(content);
|
|
5980
6023
|
if (!entry.data || !entry.timestamp)
|
|
5981
6024
|
return null;
|
|
@@ -5986,10 +6029,10 @@ function loadFromDiskCache(slug) {
|
|
|
5986
6029
|
}
|
|
5987
6030
|
function saveToDiskCache(slug, entry) {
|
|
5988
6031
|
try {
|
|
5989
|
-
if (!
|
|
5990
|
-
|
|
6032
|
+
if (!fs4.existsSync(DISK_CACHE_DIR)) {
|
|
6033
|
+
fs4.mkdirSync(DISK_CACHE_DIR, { recursive: true });
|
|
5991
6034
|
}
|
|
5992
|
-
|
|
6035
|
+
fs4.writeFileSync(getDiskCachePath(slug), JSON.stringify(entry), "utf-8");
|
|
5993
6036
|
} catch {
|
|
5994
6037
|
}
|
|
5995
6038
|
}
|
|
@@ -6007,13 +6050,13 @@ function buildMinimalProfile(slug, body) {
|
|
|
6007
6050
|
cadence: {}
|
|
6008
6051
|
};
|
|
6009
6052
|
}
|
|
6010
|
-
var
|
|
6053
|
+
var fs4, path4, os3, CACHE_TTL, memoryCache, DISK_CACHE_DIR;
|
|
6011
6054
|
var init_profile = __esm({
|
|
6012
6055
|
"src/lib/profile.ts"() {
|
|
6013
6056
|
"use strict";
|
|
6014
6057
|
init_api();
|
|
6015
6058
|
init_config();
|
|
6016
|
-
|
|
6059
|
+
fs4 = __toESM(require("fs"));
|
|
6017
6060
|
path4 = __toESM(require("path"));
|
|
6018
6061
|
os3 = __toESM(require("os"));
|
|
6019
6062
|
CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -6038,9 +6081,9 @@ function cachePathForSlug(slug) {
|
|
|
6038
6081
|
function loadProfileFromDiskCache(slug) {
|
|
6039
6082
|
try {
|
|
6040
6083
|
const cachePath = cachePathForSlug(slug);
|
|
6041
|
-
if (!
|
|
6084
|
+
if (!fs5.existsSync(cachePath))
|
|
6042
6085
|
return void 0;
|
|
6043
|
-
const entry = JSON.parse(
|
|
6086
|
+
const entry = JSON.parse(fs5.readFileSync(cachePath, "utf-8"));
|
|
6044
6087
|
if (entry?.data?.body)
|
|
6045
6088
|
return entry.data;
|
|
6046
6089
|
} catch {
|
|
@@ -6064,9 +6107,9 @@ function profileFromMarkdown(slug, body) {
|
|
|
6064
6107
|
function getProfileCacheAge(slug) {
|
|
6065
6108
|
try {
|
|
6066
6109
|
const cachePath = cachePathForSlug(slug);
|
|
6067
|
-
if (!
|
|
6110
|
+
if (!fs5.existsSync(cachePath))
|
|
6068
6111
|
return null;
|
|
6069
|
-
const entry = JSON.parse(
|
|
6112
|
+
const entry = JSON.parse(fs5.readFileSync(cachePath, "utf-8"));
|
|
6070
6113
|
return entry.timestamp || null;
|
|
6071
6114
|
} catch {
|
|
6072
6115
|
return null;
|
|
@@ -6074,9 +6117,9 @@ function getProfileCacheAge(slug) {
|
|
|
6074
6117
|
}
|
|
6075
6118
|
function listDiskCachedProfiles() {
|
|
6076
6119
|
try {
|
|
6077
|
-
if (!
|
|
6120
|
+
if (!fs5.existsSync(DISK_CACHE_DIR2))
|
|
6078
6121
|
return [];
|
|
6079
|
-
return
|
|
6122
|
+
return fs5.readdirSync(DISK_CACHE_DIR2).filter((f) => f.endsWith(".json")).map((f) => f.replace(".json", ""));
|
|
6080
6123
|
} catch {
|
|
6081
6124
|
return [];
|
|
6082
6125
|
}
|
|
@@ -6133,11 +6176,11 @@ function hasRichProfile(profile) {
|
|
|
6133
6176
|
return false;
|
|
6134
6177
|
return (profile.never_list?.length || 0) > 0 || (profile.learned_patterns?.length || 0) > 0 || (profile.drift_snapshot?.length || 0) > 0 || (profile.voice_rules?.length || 0) > 0;
|
|
6135
6178
|
}
|
|
6136
|
-
var
|
|
6179
|
+
var fs5, path5, os4, DISK_CACHE_DIR2;
|
|
6137
6180
|
var init_local_profile = __esm({
|
|
6138
6181
|
"src/lib/local-profile.ts"() {
|
|
6139
6182
|
"use strict";
|
|
6140
|
-
|
|
6183
|
+
fs5 = __toESM(require("fs"));
|
|
6141
6184
|
path5 = __toESM(require("path"));
|
|
6142
6185
|
os4 = __toESM(require("os"));
|
|
6143
6186
|
init_config();
|
|
@@ -6235,19 +6278,19 @@ var init_profile_parse = __esm({
|
|
|
6235
6278
|
function loadSupplementalPatterns() {
|
|
6236
6279
|
const p = path8.join(CACHE_DIR, "supplemental-rules.json");
|
|
6237
6280
|
try {
|
|
6238
|
-
if (!
|
|
6281
|
+
if (!fs8.existsSync(p))
|
|
6239
6282
|
return [];
|
|
6240
|
-
const data = JSON.parse(
|
|
6283
|
+
const data = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
6241
6284
|
return Array.isArray(data.patterns) ? data.patterns : [];
|
|
6242
6285
|
} catch {
|
|
6243
6286
|
return [];
|
|
6244
6287
|
}
|
|
6245
6288
|
}
|
|
6246
|
-
var
|
|
6289
|
+
var fs8, path8, BUNDLED_MANIFEST;
|
|
6247
6290
|
var init_rules_loader = __esm({
|
|
6248
6291
|
"src/lib/rules-loader.ts"() {
|
|
6249
6292
|
"use strict";
|
|
6250
|
-
|
|
6293
|
+
fs8 = __toESM(require("fs"));
|
|
6251
6294
|
path8 = __toESM(require("path"));
|
|
6252
6295
|
init_config();
|
|
6253
6296
|
BUNDLED_MANIFEST = path8.resolve(__dirname, "..", "..", "assets", "detection-rules.json");
|
|
@@ -7282,7 +7325,7 @@ function Ht(n7) {
|
|
|
7282
7325
|
return isNaN(n7) ? n7.charCodeAt(0) : parseInt(n7, 10);
|
|
7283
7326
|
}
|
|
7284
7327
|
function ps(n7) {
|
|
7285
|
-
return n7.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(
|
|
7328
|
+
return n7.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs9, de).replace(us, pe);
|
|
7286
7329
|
}
|
|
7287
7330
|
function ms(n7) {
|
|
7288
7331
|
return n7.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
|
|
@@ -7385,7 +7428,7 @@ function Ut(n7, t = {}) {
|
|
|
7385
7428
|
function es(n7, t = {}) {
|
|
7386
7429
|
return new I(n7, t).iterate();
|
|
7387
7430
|
}
|
|
7388
|
-
var import_node_url, import_node_path, import_node_url2, import_fs, xi, import_promises, import_node_events, import_node_stream, import_node_string_decoder, Gt, ce, ss, fe, ue, qt, de, pe, is, rs, ns, os5, hs, as, ls, cs,
|
|
7431
|
+
var import_node_url, import_node_path, import_node_url2, import_fs, xi, import_promises, import_node_events, import_node_stream, import_node_string_decoder, Gt, ce, ss, fe, ue, qt, de, pe, is, rs, ns, os5, hs, as, ls, cs, fs9, us, ds, at, Ss, lt, Es, we, ye, W, xs, be, vs, Ct, Cs, Ts, As, ks, Kt, Se, Ee, Q, tt, O, Rs, Os, Fs, Ds, Ms, Ns, _s, Ls, Ws, Ps, js, Is, zs, Bs, Us, $s, Gs, Hs, Ce, Te, Ae, xe, qs, A, Ks, Vs, Ys, Xs, Js, N, Zs, ke, Qs, ti, ve, ei, D, si, Oe, Vt, Fe, At, Re, ii, q, De, Tt, ri, ft, Ne, oi, hi, ai, G, H, K, kt, ut, Rt, _e, Ot, Le, P, et, v, dt, st, C, F, T, Yt, Ft, k, x, Xt, Jt, We, Zt, B, Qt, Dt, pt, Y, M, mt, li, ci, fi, ui, Mt, te, di, pi, V, vi, wt, Ue, $e, Ri, Oi, L, Ge, He, U, qe, Ke, X, Ve, _, gt, se, je, yt, j, Nt, Lt, Ie, Fi, ie, ze, bt, Be, _t, Wt, ne, Ye, R, Pt, jt, It, it, rt, St, Cr, Xe, Di, Mi, Ni, nt, _i, ot, oe, he, ae, Et, Li, zt, xt, vt, Pi, I, le, ji, Ii, zi, Bi, Ui, Ze;
|
|
7389
7432
|
var init_index_min = __esm({
|
|
7390
7433
|
"node_modules/glob/dist/esm/index.min.js"() {
|
|
7391
7434
|
import_node_url = require("node:url");
|
|
@@ -7437,7 +7480,7 @@ var init_index_min = __esm({
|
|
|
7437
7480
|
as = /\\\\/g;
|
|
7438
7481
|
ls = /\\{/g;
|
|
7439
7482
|
cs = /\\}/g;
|
|
7440
|
-
|
|
7483
|
+
fs9 = /\\,/g;
|
|
7441
7484
|
us = /\\./g;
|
|
7442
7485
|
ds = 1e5;
|
|
7443
7486
|
at = (n7) => {
|
|
@@ -10672,7 +10715,7 @@ function extractPdf(filePath) {
|
|
|
10672
10715
|
if (out.trim())
|
|
10673
10716
|
return out.trim();
|
|
10674
10717
|
}
|
|
10675
|
-
const raw = extractPdfRaw(
|
|
10718
|
+
const raw = extractPdfRaw(fs10.readFileSync(filePath));
|
|
10676
10719
|
if (raw.trim().length > 20)
|
|
10677
10720
|
return raw;
|
|
10678
10721
|
throw new Error("could not extract text from .pdf \u2014 try pasting the draft instead");
|
|
@@ -10695,10 +10738,10 @@ function extractSkillArchive(filePath) {
|
|
|
10695
10738
|
}
|
|
10696
10739
|
function extractTextFromFile(filePath) {
|
|
10697
10740
|
const resolved = path9.resolve(filePath);
|
|
10698
|
-
if (!
|
|
10741
|
+
if (!fs10.existsSync(resolved)) {
|
|
10699
10742
|
throw new Error(`file not found: ${resolved}`);
|
|
10700
10743
|
}
|
|
10701
|
-
const stat =
|
|
10744
|
+
const stat = fs10.statSync(resolved);
|
|
10702
10745
|
if (!stat.isFile()) {
|
|
10703
10746
|
throw new Error(`not a file: ${resolved}`);
|
|
10704
10747
|
}
|
|
@@ -10707,10 +10750,10 @@ function extractTextFromFile(filePath) {
|
|
|
10707
10750
|
case ".md":
|
|
10708
10751
|
case ".txt":
|
|
10709
10752
|
case ".markdown":
|
|
10710
|
-
return
|
|
10753
|
+
return fs10.readFileSync(resolved, "utf-8");
|
|
10711
10754
|
case ".html":
|
|
10712
10755
|
case ".htm":
|
|
10713
|
-
return stripHtml(
|
|
10756
|
+
return stripHtml(fs10.readFileSync(resolved, "utf-8"));
|
|
10714
10757
|
case ".docx":
|
|
10715
10758
|
return extractDocx(resolved);
|
|
10716
10759
|
case ".pdf":
|
|
@@ -10731,10 +10774,10 @@ function listDocumentsInDir(dirPath) {
|
|
|
10731
10774
|
}
|
|
10732
10775
|
function collectDocumentsFromPath(inputPath) {
|
|
10733
10776
|
const resolved = path9.resolve(inputPath.trim().replace(/^~(?=$|\/)/, os6.homedir()));
|
|
10734
|
-
if (!
|
|
10777
|
+
if (!fs10.existsSync(resolved)) {
|
|
10735
10778
|
throw new Error(`path not found: ${resolved}`);
|
|
10736
10779
|
}
|
|
10737
|
-
const stat =
|
|
10780
|
+
const stat = fs10.statSync(resolved);
|
|
10738
10781
|
const files = stat.isFile() ? [resolved] : listDocumentsInDir(resolved);
|
|
10739
10782
|
if (!files.length) {
|
|
10740
10783
|
throw new Error(
|
|
@@ -10762,17 +10805,17 @@ function readDraftInput(input) {
|
|
|
10762
10805
|
if (!trimmed)
|
|
10763
10806
|
throw new Error("empty draft");
|
|
10764
10807
|
const maybePath = path9.resolve(trimmed.replace(/^~(?=$|\/)/, os6.homedir()));
|
|
10765
|
-
if (
|
|
10808
|
+
if (fs10.existsSync(maybePath) && fs10.statSync(maybePath).isFile()) {
|
|
10766
10809
|
return { text: extractTextFromFile(maybePath), source: maybePath };
|
|
10767
10810
|
}
|
|
10768
10811
|
return { text: trimmed, source: "paste" };
|
|
10769
10812
|
}
|
|
10770
|
-
var import_child_process2,
|
|
10813
|
+
var import_child_process2, fs10, os6, path9, SUPPORTED_EXTENSIONS, SAMPLE_GLOB, GLOB_IGNORE;
|
|
10771
10814
|
var init_document_text = __esm({
|
|
10772
10815
|
"src/lib/document-text.ts"() {
|
|
10773
10816
|
"use strict";
|
|
10774
10817
|
import_child_process2 = require("child_process");
|
|
10775
|
-
|
|
10818
|
+
fs10 = __toESM(require("fs"));
|
|
10776
10819
|
os6 = __toESM(require("os"));
|
|
10777
10820
|
path9 = __toESM(require("path"));
|
|
10778
10821
|
init_index_min();
|
|
@@ -10849,21 +10892,21 @@ function runPipeline(text, profile, applyFixes = false) {
|
|
|
10849
10892
|
};
|
|
10850
10893
|
}
|
|
10851
10894
|
function readText(source) {
|
|
10852
|
-
const
|
|
10895
|
+
const fs29 = require("fs");
|
|
10853
10896
|
const path26 = require("path");
|
|
10854
10897
|
if (source === "-") {
|
|
10855
10898
|
if (process.stdin.isTTY) {
|
|
10856
10899
|
console.error("No input provided. Pipe content or specify a file.");
|
|
10857
10900
|
process.exit(1);
|
|
10858
10901
|
}
|
|
10859
|
-
return { text:
|
|
10902
|
+
return { text: fs29.readFileSync(0, "utf-8"), path: "stdin" };
|
|
10860
10903
|
}
|
|
10861
10904
|
const resolved = path26.resolve(source);
|
|
10862
|
-
if (!
|
|
10905
|
+
if (!fs29.existsSync(resolved)) {
|
|
10863
10906
|
console.error(`File not found: ${resolved}`);
|
|
10864
10907
|
process.exit(1);
|
|
10865
10908
|
}
|
|
10866
|
-
const stat =
|
|
10909
|
+
const stat = fs29.statSync(resolved);
|
|
10867
10910
|
if (stat.isDirectory()) {
|
|
10868
10911
|
console.error(`${resolved} is a directory, not a file.`);
|
|
10869
10912
|
process.exit(1);
|
|
@@ -11315,10 +11358,10 @@ var init_terminal_ui = __esm({
|
|
|
11315
11358
|
// src/lib/welcome-flow.ts
|
|
11316
11359
|
function readWelcomeState() {
|
|
11317
11360
|
try {
|
|
11318
|
-
if (!
|
|
11361
|
+
if (!fs14.existsSync(STATE_FILE)) {
|
|
11319
11362
|
return { completed_steps: [], updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
11320
11363
|
}
|
|
11321
|
-
return JSON.parse(
|
|
11364
|
+
return JSON.parse(fs14.readFileSync(STATE_FILE, "utf-8"));
|
|
11322
11365
|
} catch {
|
|
11323
11366
|
return { completed_steps: [], updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
11324
11367
|
}
|
|
@@ -11330,7 +11373,7 @@ function writeWelcomeState(patch) {
|
|
|
11330
11373
|
...patch,
|
|
11331
11374
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
11332
11375
|
};
|
|
11333
|
-
|
|
11376
|
+
fs14.writeFileSync(STATE_FILE, JSON.stringify(next, null, 2), { mode: 384 });
|
|
11334
11377
|
return next;
|
|
11335
11378
|
}
|
|
11336
11379
|
function markStepComplete(step) {
|
|
@@ -11781,7 +11824,7 @@ async function stepSignup(profileName) {
|
|
|
11781
11824
|
} else {
|
|
11782
11825
|
console.log(import_chalk12.default.dim("\n already signed in \u2014 syncing profile..."));
|
|
11783
11826
|
}
|
|
11784
|
-
const content =
|
|
11827
|
+
const content = fs14.readFileSync(
|
|
11785
11828
|
path13.join(os7.homedir(), ".hyv", "profiles", `${profileName}.md`),
|
|
11786
11829
|
"utf-8"
|
|
11787
11830
|
);
|
|
@@ -11794,7 +11837,12 @@ async function stepSignup(profileName) {
|
|
|
11794
11837
|
})
|
|
11795
11838
|
);
|
|
11796
11839
|
if (response.status === 200) {
|
|
11797
|
-
|
|
11840
|
+
const body = response.data;
|
|
11841
|
+
if (body.preserved) {
|
|
11842
|
+
console.log(import_chalk12.default.green(" \u2713 account linked \u2014 kept your existing server profile"));
|
|
11843
|
+
} else {
|
|
11844
|
+
console.log(import_chalk12.default.green(" \u2713 profile synced to your account"));
|
|
11845
|
+
}
|
|
11798
11846
|
} else {
|
|
11799
11847
|
const detail = response.data?.error;
|
|
11800
11848
|
console.log(import_chalk12.default.yellow(
|
|
@@ -11842,12 +11890,12 @@ function getMcpWelcomeResponse(args2) {
|
|
|
11842
11890
|
}
|
|
11843
11891
|
return buildWelcomeGuide({ profileName: args2.profile, forLlm: true });
|
|
11844
11892
|
}
|
|
11845
|
-
var import_chalk12,
|
|
11893
|
+
var import_chalk12, fs14, http2, https2, os7, path13, readline, WELCOME_TAGLINE, FLOW_STEPS, STATE_FILE;
|
|
11846
11894
|
var init_welcome_flow = __esm({
|
|
11847
11895
|
"src/lib/welcome-flow.ts"() {
|
|
11848
11896
|
"use strict";
|
|
11849
11897
|
import_chalk12 = __toESM(require_source());
|
|
11850
|
-
|
|
11898
|
+
fs14 = __toESM(require("fs"));
|
|
11851
11899
|
http2 = __toESM(require("http"));
|
|
11852
11900
|
https2 = __toESM(require("https"));
|
|
11853
11901
|
os7 = __toESM(require("os"));
|
|
@@ -12858,7 +12906,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
12858
12906
|
g.minimatch.escape = vi2.escape;
|
|
12859
12907
|
g.minimatch.unescape = Ei2.unescape;
|
|
12860
12908
|
});
|
|
12861
|
-
var
|
|
12909
|
+
var fs29 = R2((Wt2) => {
|
|
12862
12910
|
"use strict";
|
|
12863
12911
|
Object.defineProperty(Wt2, "__esModule", { value: true });
|
|
12864
12912
|
Wt2.LRUCache = void 0;
|
|
@@ -13827,7 +13875,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
|
|
|
13827
13875
|
};
|
|
13828
13876
|
Object.defineProperty(_2, "__esModule", { value: true });
|
|
13829
13877
|
_2.PathScurry = _2.Path = _2.PathScurryDarwin = _2.PathScurryPosix = _2.PathScurryWin32 = _2.PathScurryBase = _2.PathPosix = _2.PathWin32 = _2.PathBase = _2.ChildrenCache = _2.ResolveCache = void 0;
|
|
13830
|
-
var Qt2 =
|
|
13878
|
+
var Qt2 = fs29(), Yt2 = require("node:path"), yr = require("node:url"), pt2 = require("fs"), Sr = br(require("node:fs")), vr = pt2.realpathSync.native, Ht2 = require("node:fs/promises"), bs2 = Oe2(), mt2 = { lstatSync: pt2.lstatSync, readdir: pt2.readdir, readdirSync: pt2.readdirSync, readlinkSync: pt2.readlinkSync, realpathSync: vr, promises: { lstat: Ht2.lstat, readdir: Ht2.readdir, readlink: Ht2.readlink, realpath: Ht2.realpath } }, _s2 = (n7) => !n7 || n7 === mt2 || n7 === Sr ? mt2 : { ...mt2, ...n7, promises: { ...mt2.promises, ...n7.promises || {} } }, Os2 = /^\\\\\?\\([a-z]:)\\?$/i, Er = (n7) => n7.replace(/\//g, "\\").replace(Os2, "$1\\"), _r = /[\\\/]/, N2 = 0, xs2 = 1, Ts2 = 2, G2 = 4, Cs2 = 6, Rs2 = 8, Q2 = 10, As2 = 12, j2 = 15, dt2 = ~j2, xe2 = 16, ys2 = 32, gt2 = 64, W2 = 128, Vt2 = 256, Xt2 = 512, Ss2 = gt2 | W2 | Xt2, Or = 1023, Te2 = (n7) => n7.isFile() ? Rs2 : n7.isDirectory() ? G2 : n7.isSymbolicLink() ? Q2 : n7.isCharacterDevice() ? Ts2 : n7.isBlockDevice() ? Cs2 : n7.isSocket() ? As2 : n7.isFIFO() ? xs2 : N2, vs2 = new Qt2.LRUCache({ max: 2 ** 12 }), wt2 = (n7) => {
|
|
13831
13879
|
let t = vs2.get(n7);
|
|
13832
13880
|
if (t)
|
|
13833
13881
|
return t;
|
|
@@ -15522,7 +15570,7 @@ init_version();
|
|
|
15522
15570
|
|
|
15523
15571
|
// src/lib/queue-sync.ts
|
|
15524
15572
|
var import_chalk6 = __toESM(require_source());
|
|
15525
|
-
var
|
|
15573
|
+
var fs6 = __toESM(require("fs"));
|
|
15526
15574
|
var path6 = __toESM(require("path"));
|
|
15527
15575
|
init_config();
|
|
15528
15576
|
init_auth();
|
|
@@ -15532,13 +15580,13 @@ async function flushQueuedSignals() {
|
|
|
15532
15580
|
return { sent: 0, failed: 0 };
|
|
15533
15581
|
let sent = 0;
|
|
15534
15582
|
let failed = 0;
|
|
15535
|
-
if (!
|
|
15583
|
+
if (!fs6.existsSync(QUEUE_DIR))
|
|
15536
15584
|
return { sent: 0, failed: 0 };
|
|
15537
|
-
const files =
|
|
15585
|
+
const files = fs6.readdirSync(QUEUE_DIR).filter((f) => f.endsWith(".json"));
|
|
15538
15586
|
for (const file of files) {
|
|
15539
15587
|
const filePath = path6.join(QUEUE_DIR, file);
|
|
15540
15588
|
try {
|
|
15541
|
-
const signal = JSON.parse(
|
|
15589
|
+
const signal = JSON.parse(fs6.readFileSync(filePath, "utf-8"));
|
|
15542
15590
|
let ok = false;
|
|
15543
15591
|
if (signal.type === "reinforce") {
|
|
15544
15592
|
const res = await authenticatedRequest(cliApiUrl("/cli/learning/reinforce"), {
|
|
@@ -15559,7 +15607,7 @@ async function flushQueuedSignals() {
|
|
|
15559
15607
|
ok = res.status === 200;
|
|
15560
15608
|
}
|
|
15561
15609
|
if (ok) {
|
|
15562
|
-
|
|
15610
|
+
fs6.unlinkSync(filePath);
|
|
15563
15611
|
sent++;
|
|
15564
15612
|
} else {
|
|
15565
15613
|
failed++;
|
|
@@ -15716,7 +15764,7 @@ init_config();
|
|
|
15716
15764
|
init_auth();
|
|
15717
15765
|
init_access();
|
|
15718
15766
|
init_profile();
|
|
15719
|
-
var
|
|
15767
|
+
var fs7 = __toESM(require("fs"));
|
|
15720
15768
|
var path7 = __toESM(require("path"));
|
|
15721
15769
|
function registerSyncCommand(program3) {
|
|
15722
15770
|
program3.command("sync").description("Sync profiles and rules from server").option("--force", "Force re-download even if cache is fresh").action(async (options) => {
|
|
@@ -15736,17 +15784,21 @@ function registerSyncCommand(program3) {
|
|
|
15736
15784
|
ensureHyvDir();
|
|
15737
15785
|
let profileCount = 0;
|
|
15738
15786
|
for (const profile of data.profiles) {
|
|
15787
|
+
if (!profile.content?.trim()) {
|
|
15788
|
+
console.log(import_chalk8.default.yellow(` ! skipped empty profile cache: ${profile.name}`));
|
|
15789
|
+
continue;
|
|
15790
|
+
}
|
|
15739
15791
|
const cacheKey = toSafeProfileCacheKey(profile.slug || profile.name);
|
|
15740
15792
|
writeCachedProfile(cacheKey, profile.content);
|
|
15741
15793
|
profileCount++;
|
|
15742
15794
|
}
|
|
15743
15795
|
const rulesPath = path7.join(CACHE_DIR, "rules.md");
|
|
15744
|
-
|
|
15796
|
+
fs7.writeFileSync(rulesPath, data.rules, { mode: 384 });
|
|
15745
15797
|
const promptPath = path7.join(CACHE_DIR, "prompt-template.md");
|
|
15746
|
-
|
|
15798
|
+
fs7.writeFileSync(promptPath, data.prompt_template, { mode: 384 });
|
|
15747
15799
|
if (data.detection_rules) {
|
|
15748
15800
|
const rulesJson = path7.join(CACHE_DIR, "detection-rules.json");
|
|
15749
|
-
|
|
15801
|
+
fs7.writeFileSync(rulesJson, JSON.stringify(data.detection_rules, null, 2), { mode: 384 });
|
|
15750
15802
|
}
|
|
15751
15803
|
for (const profile of data.profiles) {
|
|
15752
15804
|
try {
|
|
@@ -15763,7 +15815,7 @@ function registerSyncCommand(program3) {
|
|
|
15763
15815
|
console.log(import_chalk8.default.yellow(` ! ${queueResult.failed} queued signal(s) could not send`));
|
|
15764
15816
|
}
|
|
15765
15817
|
const metaPath = path7.join(CACHE_DIR, "sync-meta.json");
|
|
15766
|
-
|
|
15818
|
+
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
15767
15819
|
synced_at: data.synced_at,
|
|
15768
15820
|
profile_count: profileCount,
|
|
15769
15821
|
plan: data.plan
|
|
@@ -15868,12 +15920,12 @@ Profile evolution: ${slug}
|
|
|
15868
15920
|
|
|
15869
15921
|
// src/commands/rewrite.ts
|
|
15870
15922
|
var import_chalk9 = __toESM(require_source());
|
|
15871
|
-
var
|
|
15923
|
+
var fs12 = __toESM(require("fs"));
|
|
15872
15924
|
var path11 = __toESM(require("path"));
|
|
15873
15925
|
init_pipeline();
|
|
15874
15926
|
|
|
15875
15927
|
// src/lib/prompt.ts
|
|
15876
|
-
var
|
|
15928
|
+
var fs11 = __toESM(require("fs"));
|
|
15877
15929
|
var path10 = __toESM(require("path"));
|
|
15878
15930
|
init_config();
|
|
15879
15931
|
init_signals();
|
|
@@ -15881,8 +15933,8 @@ init_profile_parse();
|
|
|
15881
15933
|
function loadPromptTemplate() {
|
|
15882
15934
|
const templatePath = path10.join(CACHE_DIR, "prompt-template.md");
|
|
15883
15935
|
try {
|
|
15884
|
-
if (
|
|
15885
|
-
return
|
|
15936
|
+
if (fs11.existsSync(templatePath)) {
|
|
15937
|
+
return fs11.readFileSync(templatePath, "utf-8");
|
|
15886
15938
|
}
|
|
15887
15939
|
} catch {
|
|
15888
15940
|
}
|
|
@@ -16070,7 +16122,7 @@ Draft: ${draftPath}`));
|
|
|
16070
16122
|
}
|
|
16071
16123
|
if (options.output) {
|
|
16072
16124
|
const outputPath = path11.resolve(options.output);
|
|
16073
|
-
|
|
16125
|
+
fs12.writeFileSync(outputPath, promptResult.prompt);
|
|
16074
16126
|
console.log(import_chalk9.default.green(`
|
|
16075
16127
|
\u2713 Prompt written to ${outputPath}`));
|
|
16076
16128
|
} else {
|
|
@@ -16090,7 +16142,7 @@ Draft: ${draftPath}`));
|
|
|
16090
16142
|
|
|
16091
16143
|
// src/commands/learning.ts
|
|
16092
16144
|
var import_chalk10 = __toESM(require_source());
|
|
16093
|
-
var
|
|
16145
|
+
var fs13 = __toESM(require("fs"));
|
|
16094
16146
|
var path12 = __toESM(require("path"));
|
|
16095
16147
|
|
|
16096
16148
|
// src/lib/diff.ts
|
|
@@ -16237,16 +16289,16 @@ function registerLearningCommands(program3) {
|
|
|
16237
16289
|
}
|
|
16238
16290
|
origPath = path12.resolve(original);
|
|
16239
16291
|
editPath = path12.resolve(edited);
|
|
16240
|
-
if (!
|
|
16292
|
+
if (!fs13.existsSync(origPath)) {
|
|
16241
16293
|
console.error(import_chalk10.default.red(`Original file not found: ${origPath}`));
|
|
16242
16294
|
process.exit(1);
|
|
16243
16295
|
}
|
|
16244
|
-
if (!
|
|
16296
|
+
if (!fs13.existsSync(editPath)) {
|
|
16245
16297
|
console.error(import_chalk10.default.red(`Edited file not found: ${editPath}`));
|
|
16246
16298
|
process.exit(1);
|
|
16247
16299
|
}
|
|
16248
|
-
origText =
|
|
16249
|
-
editText =
|
|
16300
|
+
origText = fs13.readFileSync(origPath, "utf-8");
|
|
16301
|
+
editText = fs13.readFileSync(editPath, "utf-8");
|
|
16250
16302
|
saveLastEditSession({
|
|
16251
16303
|
original_path: origPath,
|
|
16252
16304
|
edited_path: editPath,
|
|
@@ -16413,7 +16465,7 @@ function printProfileImpact(impact, data) {
|
|
|
16413
16465
|
|
|
16414
16466
|
// src/commands/onboarding.ts
|
|
16415
16467
|
var import_chalk13 = __toESM(require_source());
|
|
16416
|
-
var
|
|
16468
|
+
var fs15 = __toESM(require("fs"));
|
|
16417
16469
|
var path14 = __toESM(require("path"));
|
|
16418
16470
|
init_config();
|
|
16419
16471
|
init_auth();
|
|
@@ -16566,20 +16618,20 @@ Industry: ${industry}
|
|
|
16566
16618
|
}
|
|
16567
16619
|
async function createFromSamples(name, sampleDir, token) {
|
|
16568
16620
|
const dirPath = path14.resolve(sampleDir);
|
|
16569
|
-
if (!
|
|
16621
|
+
if (!fs15.existsSync(dirPath)) {
|
|
16570
16622
|
throw new Error(`Directory not found: ${dirPath}`);
|
|
16571
16623
|
}
|
|
16572
16624
|
console.log(import_chalk13.default.bold(`
|
|
16573
16625
|
Creating voice profile: ${name}`));
|
|
16574
16626
|
console.log(import_chalk13.default.dim(`Reading samples from: ${dirPath}
|
|
16575
16627
|
`));
|
|
16576
|
-
const files =
|
|
16628
|
+
const files = fs15.readdirSync(dirPath).filter((f) => f.endsWith(".md") || f.endsWith(".txt")).map((f) => path14.join(dirPath, f));
|
|
16577
16629
|
if (files.length === 0) {
|
|
16578
16630
|
throw new Error("No .md or .txt files found in directory");
|
|
16579
16631
|
}
|
|
16580
16632
|
const samples = [];
|
|
16581
16633
|
for (const file of files) {
|
|
16582
|
-
const text =
|
|
16634
|
+
const text = fs15.readFileSync(file, "utf-8");
|
|
16583
16635
|
if (text.trim().length > 0) {
|
|
16584
16636
|
samples.push({ path: file, text });
|
|
16585
16637
|
console.log(import_chalk13.default.dim(` \u2022 ${path14.basename(file)} (${words(text).length} words)`));
|
|
@@ -16654,11 +16706,11 @@ function registerImportCommand(program3) {
|
|
|
16654
16706
|
try {
|
|
16655
16707
|
assertSafeProfileName(name);
|
|
16656
16708
|
const filePath = path14.resolve(file);
|
|
16657
|
-
if (!
|
|
16709
|
+
if (!fs15.existsSync(filePath)) {
|
|
16658
16710
|
console.error(import_chalk13.default.red(`File not found: ${filePath}`));
|
|
16659
16711
|
process.exit(1);
|
|
16660
16712
|
}
|
|
16661
|
-
const content =
|
|
16713
|
+
const content = fs15.readFileSync(filePath, "utf-8");
|
|
16662
16714
|
ensureHyvDir();
|
|
16663
16715
|
writeCachedProfile(name, content);
|
|
16664
16716
|
console.log(import_chalk13.default.green(`
|
|
@@ -17029,7 +17081,7 @@ async function runHybridAnalysis(text, profile, opts = {}) {
|
|
|
17029
17081
|
|
|
17030
17082
|
// src/commands/history.ts
|
|
17031
17083
|
var import_chalk16 = __toESM(require_source());
|
|
17032
|
-
var
|
|
17084
|
+
var fs16 = __toESM(require("fs"));
|
|
17033
17085
|
var path15 = __toESM(require("path"));
|
|
17034
17086
|
init_config();
|
|
17035
17087
|
var HISTORY_DIR = path15.join(HYV_DIR, "history");
|
|
@@ -17043,9 +17095,9 @@ function logScan(entry) {
|
|
|
17043
17095
|
}
|
|
17044
17096
|
function readHistory() {
|
|
17045
17097
|
try {
|
|
17046
|
-
if (!
|
|
17098
|
+
if (!fs16.existsSync(HISTORY_FILE))
|
|
17047
17099
|
return [];
|
|
17048
|
-
const lines =
|
|
17100
|
+
const lines = fs16.readFileSync(HISTORY_FILE, "utf-8").trim().split("\n").filter(Boolean);
|
|
17049
17101
|
return lines.map((l) => JSON.parse(l));
|
|
17050
17102
|
} catch {
|
|
17051
17103
|
return [];
|
|
@@ -17077,8 +17129,8 @@ function registerHistoryCommand(program3) {
|
|
|
17077
17129
|
program3.command("history").description("Show past scan scores and track improvement").option("--limit <n>", "Number of entries to show", "20").option("--file <path>", "Filter by file path").option("--since <date>", "Show entries since (e.g., 7d, 1m, 2024-01-01)").option("--chart", "Show ASCII sparkline chart").option("--clear", "Clear history").option("--format <type>", "Output format (text, json)", "text").action(async (options) => {
|
|
17078
17130
|
try {
|
|
17079
17131
|
if (options.clear) {
|
|
17080
|
-
if (
|
|
17081
|
-
|
|
17132
|
+
if (fs16.existsSync(HISTORY_FILE)) {
|
|
17133
|
+
fs16.unlinkSync(HISTORY_FILE);
|
|
17082
17134
|
}
|
|
17083
17135
|
console.log(import_chalk16.default.green("\n\u2713 History cleared"));
|
|
17084
17136
|
return;
|
|
@@ -17244,7 +17296,7 @@ hyv scan ${filePath}`));
|
|
|
17244
17296
|
|
|
17245
17297
|
// src/commands/doctor.ts
|
|
17246
17298
|
var import_chalk18 = __toESM(require_source());
|
|
17247
|
-
var
|
|
17299
|
+
var fs18 = __toESM(require("fs"));
|
|
17248
17300
|
var path17 = __toESM(require("path"));
|
|
17249
17301
|
var os8 = __toESM(require("os"));
|
|
17250
17302
|
init_config();
|
|
@@ -17257,7 +17309,7 @@ init_version();
|
|
|
17257
17309
|
var import_child_process3 = require("child_process");
|
|
17258
17310
|
|
|
17259
17311
|
// src/lib/cli-entry.ts
|
|
17260
|
-
var
|
|
17312
|
+
var fs17 = __toESM(require("fs"));
|
|
17261
17313
|
var path16 = __toESM(require("path"));
|
|
17262
17314
|
function resolveCliEntry() {
|
|
17263
17315
|
const candidates = [
|
|
@@ -17265,7 +17317,7 @@ function resolveCliEntry() {
|
|
|
17265
17317
|
path16.resolve(__dirname, "index.js"),
|
|
17266
17318
|
path16.resolve(__dirname, "..", "dist", "index.js")
|
|
17267
17319
|
];
|
|
17268
|
-
return candidates.find((p) => p &&
|
|
17320
|
+
return candidates.find((p) => p && fs17.existsSync(p)) || null;
|
|
17269
17321
|
}
|
|
17270
17322
|
function mcpServerCommand() {
|
|
17271
17323
|
const entry = resolveCliEntry();
|
|
@@ -17362,9 +17414,9 @@ function claudeDesktopDir() {
|
|
|
17362
17414
|
}
|
|
17363
17415
|
function isOwnerOnlyFile(filePath) {
|
|
17364
17416
|
try {
|
|
17365
|
-
if (!
|
|
17417
|
+
if (!fs18.existsSync(filePath))
|
|
17366
17418
|
return true;
|
|
17367
|
-
const mode =
|
|
17419
|
+
const mode = fs18.statSync(filePath).mode & 511;
|
|
17368
17420
|
return (mode & 63) === 0;
|
|
17369
17421
|
} catch {
|
|
17370
17422
|
return false;
|
|
@@ -17372,9 +17424,9 @@ function isOwnerOnlyFile(filePath) {
|
|
|
17372
17424
|
}
|
|
17373
17425
|
function readMcpHyv(configFile) {
|
|
17374
17426
|
try {
|
|
17375
|
-
if (!
|
|
17427
|
+
if (!fs18.existsSync(configFile))
|
|
17376
17428
|
return false;
|
|
17377
|
-
const cfg = JSON.parse(
|
|
17429
|
+
const cfg = JSON.parse(fs18.readFileSync(configFile, "utf-8"));
|
|
17378
17430
|
return Boolean(cfg.mcpServers?.hyv);
|
|
17379
17431
|
} catch {
|
|
17380
17432
|
return false;
|
|
@@ -17395,28 +17447,28 @@ function registerDoctorCommand(program3) {
|
|
|
17395
17447
|
console.log(import_chalk18.default.dim("tip: run hyv welcome for free capabilities\n"));
|
|
17396
17448
|
console.log(import_chalk18.default.dim("checking cli installation..."));
|
|
17397
17449
|
const cliPath = process.argv[1];
|
|
17398
|
-
if (cliPath &&
|
|
17450
|
+
if (cliPath && fs18.existsSync(cliPath)) {
|
|
17399
17451
|
console.log(import_chalk18.default.green(" \u2713 cli installed"));
|
|
17400
17452
|
} else {
|
|
17401
17453
|
console.log(import_chalk18.default.red(" \u2717 cli not found"));
|
|
17402
17454
|
issues++;
|
|
17403
17455
|
}
|
|
17404
17456
|
console.log(import_chalk18.default.dim("checking .hyv directory..."));
|
|
17405
|
-
if (
|
|
17457
|
+
if (fs18.existsSync(HYV_DIR)) {
|
|
17406
17458
|
console.log(import_chalk18.default.green(" \u2713 .hyv directory exists"));
|
|
17407
17459
|
} else {
|
|
17408
17460
|
console.log(import_chalk18.default.yellow(" ! .hyv directory missing \u2014 creating..."));
|
|
17409
|
-
|
|
17461
|
+
fs18.mkdirSync(HYV_DIR, { recursive: true, mode: 448 });
|
|
17410
17462
|
fixed++;
|
|
17411
17463
|
}
|
|
17412
17464
|
console.log(import_chalk18.default.dim("checking cache..."));
|
|
17413
17465
|
const diskProfiles = listDiskCachedProfiles();
|
|
17414
17466
|
const syncMeta = path17.join(CACHE_DIR, "sync-meta.json");
|
|
17415
|
-
if (diskProfiles.length > 0 ||
|
|
17467
|
+
if (diskProfiles.length > 0 || fs18.existsSync(syncMeta)) {
|
|
17416
17468
|
console.log(import_chalk18.default.green(` \u2713 profile cache (${diskProfiles.length} full profile(s))`));
|
|
17417
|
-
if (
|
|
17469
|
+
if (fs18.existsSync(syncMeta)) {
|
|
17418
17470
|
try {
|
|
17419
|
-
const meta = JSON.parse(
|
|
17471
|
+
const meta = JSON.parse(fs18.readFileSync(syncMeta, "utf-8"));
|
|
17420
17472
|
console.log(import_chalk18.default.dim(` last sync: ${meta.synced_at || "unknown"}`));
|
|
17421
17473
|
} catch {
|
|
17422
17474
|
}
|
|
@@ -17425,8 +17477,8 @@ function registerDoctorCommand(program3) {
|
|
|
17425
17477
|
console.log(import_chalk18.default.dim(" - no full profile cache (free local engine still works)"));
|
|
17426
17478
|
}
|
|
17427
17479
|
console.log(import_chalk18.default.dim("checking file permissions..."));
|
|
17428
|
-
if (
|
|
17429
|
-
const hyvMode =
|
|
17480
|
+
if (fs18.existsSync(HYV_DIR)) {
|
|
17481
|
+
const hyvMode = fs18.statSync(HYV_DIR).mode & 511;
|
|
17430
17482
|
if ((hyvMode & 63) === 0) {
|
|
17431
17483
|
console.log(import_chalk18.default.green(" \u2713 .hyv directory permissions"));
|
|
17432
17484
|
} else {
|
|
@@ -17435,7 +17487,7 @@ function registerDoctorCommand(program3) {
|
|
|
17435
17487
|
issues++;
|
|
17436
17488
|
}
|
|
17437
17489
|
}
|
|
17438
|
-
if (
|
|
17490
|
+
if (fs18.existsSync(AUTH_FILE)) {
|
|
17439
17491
|
if (isOwnerOnlyFile(AUTH_FILE)) {
|
|
17440
17492
|
console.log(import_chalk18.default.green(" \u2713 auth.json permissions"));
|
|
17441
17493
|
} else {
|
|
@@ -17469,8 +17521,8 @@ function registerDoctorCommand(program3) {
|
|
|
17469
17521
|
}
|
|
17470
17522
|
console.log(import_chalk18.default.dim("checking voice profile..."));
|
|
17471
17523
|
const voiceMd = path17.join(HYV_DIR, "voice.md");
|
|
17472
|
-
const hasVoiceMd =
|
|
17473
|
-
const profileFiles =
|
|
17524
|
+
const hasVoiceMd = fs18.existsSync(voiceMd) && fs18.readFileSync(voiceMd, "utf-8").trim().length > 50;
|
|
17525
|
+
const profileFiles = fs18.existsSync(PROFILES_DIR) ? fs18.readdirSync(PROFILES_DIR).filter((f) => f.endsWith(".md") && f !== "voice.md") : [];
|
|
17474
17526
|
if (hasVoiceMd || profileFiles.length > 0 || diskProfiles.length > 0) {
|
|
17475
17527
|
if (hasVoiceMd)
|
|
17476
17528
|
console.log(import_chalk18.default.green(" \u2713 voice.md exists"));
|
|
@@ -17485,7 +17537,7 @@ function registerDoctorCommand(program3) {
|
|
|
17485
17537
|
console.log(import_chalk18.default.dim("checking agent configurations..."));
|
|
17486
17538
|
const cursorLegacyRule = path17.join(HOME, ".cursor", "rules", "hyv.md");
|
|
17487
17539
|
const cursorRule = path17.join(HOME, ".cursor", "rules", "hyv.mdc");
|
|
17488
|
-
if (
|
|
17540
|
+
if (fs18.existsSync(cursorLegacyRule) && fs18.existsSync(cursorRule)) {
|
|
17489
17541
|
console.log(import_chalk18.default.yellow(" ! stale cursor rule ~/.cursor/rules/hyv.md (use hyv.mdc)"));
|
|
17490
17542
|
console.log(import_chalk18.default.dim(" run: rm ~/.cursor/rules/hyv.md (or hyv doctor --fix-agents)"));
|
|
17491
17543
|
issues++;
|
|
@@ -17493,11 +17545,11 @@ function registerDoctorCommand(program3) {
|
|
|
17493
17545
|
const agentChecks = [
|
|
17494
17546
|
{ name: "claude desktop mcp", ok: readMcpHyv(path17.join(claudeDesktopDir(), "claude_desktop_config.json")) },
|
|
17495
17547
|
{ name: "cursor mcp", ok: readMcpHyv(path17.join(HOME, ".cursor", "mcp.json")) },
|
|
17496
|
-
{ name: "cursor rule", ok:
|
|
17497
|
-
{ name: "claude code command", ok:
|
|
17498
|
-
{ name: "claude code skill", ok:
|
|
17499
|
-
{ name: "codex agents", ok:
|
|
17500
|
-
{ name: "command code skill", ok:
|
|
17548
|
+
{ name: "cursor rule", ok: fs18.existsSync(cursorRule) },
|
|
17549
|
+
{ name: "claude code command", ok: fs18.existsSync(path17.join(HOME, ".claude", "commands", "hyv.md")) },
|
|
17550
|
+
{ name: "claude code skill", ok: fs18.existsSync(path17.join(HOME, ".claude", "skills", "hold-your-voice", "SKILL.md")) },
|
|
17551
|
+
{ name: "codex agents", ok: fs18.existsSync(path17.join(HOME, ".codex", "AGENTS.md")) && fs18.readFileSync(path17.join(HOME, ".codex", "AGENTS.md"), "utf-8").includes("hyv") },
|
|
17552
|
+
{ name: "command code skill", ok: fs18.existsSync(path17.join(HOME, ".commandcode", "skills", "hyv", "SKILL.md")) }
|
|
17501
17553
|
];
|
|
17502
17554
|
for (const agent of agentChecks) {
|
|
17503
17555
|
if (agent.ok) {
|
|
@@ -17631,7 +17683,7 @@ init_access();
|
|
|
17631
17683
|
init_config();
|
|
17632
17684
|
|
|
17633
17685
|
// src/lib/destructive-write.ts
|
|
17634
|
-
var
|
|
17686
|
+
var fs19 = __toESM(require("fs"));
|
|
17635
17687
|
var path18 = __toESM(require("path"));
|
|
17636
17688
|
var readline2 = __toESM(require("readline"));
|
|
17637
17689
|
var import_chalk20 = __toESM(require_source());
|
|
@@ -17658,8 +17710,8 @@ A .bak backup will be created. Proceed? [y/N] `;
|
|
|
17658
17710
|
}
|
|
17659
17711
|
function writeInPlaceWithBackup(filePath, content) {
|
|
17660
17712
|
const backupPath = filePath + ".bak";
|
|
17661
|
-
|
|
17662
|
-
|
|
17713
|
+
fs19.copyFileSync(filePath, backupPath);
|
|
17714
|
+
fs19.writeFileSync(filePath, content);
|
|
17663
17715
|
return backupPath;
|
|
17664
17716
|
}
|
|
17665
17717
|
function backupBasename(filePath) {
|
|
@@ -17757,19 +17809,19 @@ function registerCheckCommand(program3) {
|
|
|
17757
17809
|
const profile = await loadProfileForCommand(options.profile);
|
|
17758
17810
|
let inputText = text;
|
|
17759
17811
|
if (text === "-") {
|
|
17760
|
-
const
|
|
17812
|
+
const fs30 = require("fs");
|
|
17761
17813
|
if (process.stdin.isTTY) {
|
|
17762
17814
|
console.error(import_chalk22.default.red("No input provided. Pipe content or pass text as argument."));
|
|
17763
17815
|
process.exit(1);
|
|
17764
17816
|
}
|
|
17765
|
-
inputText =
|
|
17817
|
+
inputText = fs30.readFileSync(0, "utf-8");
|
|
17766
17818
|
}
|
|
17767
17819
|
if (!inputText.trim()) {
|
|
17768
17820
|
console.error(import_chalk22.default.red("No text provided."));
|
|
17769
17821
|
process.exit(1);
|
|
17770
17822
|
}
|
|
17771
|
-
const
|
|
17772
|
-
if (text !== "-" &&
|
|
17823
|
+
const fs29 = require("fs");
|
|
17824
|
+
if (text !== "-" && fs29.existsSync(text)) {
|
|
17773
17825
|
console.log(import_chalk22.default.yellow(`"${text}" looks like a file. Did you mean: hyv scan ${text}`));
|
|
17774
17826
|
process.exit(1);
|
|
17775
17827
|
}
|
|
@@ -17896,11 +17948,11 @@ function registerDiffCommand(program3) {
|
|
|
17896
17948
|
${result.changes.length} auto-fix${result.changes.length === 1 ? "" : "es"} available`));
|
|
17897
17949
|
console.log(import_chalk24.default.dim(` run: hyv fix ${file} -i to apply`));
|
|
17898
17950
|
if (options.apply && filePath !== "stdin") {
|
|
17899
|
-
const
|
|
17951
|
+
const fs29 = require("fs");
|
|
17900
17952
|
const path26 = require("path");
|
|
17901
17953
|
const backupPath = filePath + ".bak";
|
|
17902
|
-
|
|
17903
|
-
|
|
17954
|
+
fs29.copyFileSync(filePath, backupPath);
|
|
17955
|
+
fs29.writeFileSync(filePath, result.fixed);
|
|
17904
17956
|
console.log(import_chalk24.default.green(` \u2713 Applied. Backup: ${path26.basename(backupPath)}`));
|
|
17905
17957
|
}
|
|
17906
17958
|
} catch (error) {
|
|
@@ -18076,7 +18128,7 @@ function registerRulesCommand(program3) {
|
|
|
18076
18128
|
|
|
18077
18129
|
// src/commands/batch.ts
|
|
18078
18130
|
var import_chalk26 = __toESM(require_source());
|
|
18079
|
-
var
|
|
18131
|
+
var fs20 = __toESM(require("fs"));
|
|
18080
18132
|
var path19 = __toESM(require("path"));
|
|
18081
18133
|
init_pipeline();
|
|
18082
18134
|
init_local_profile();
|
|
@@ -18111,9 +18163,9 @@ No files matching: ${pattern}`));
|
|
|
18111
18163
|
const results = [];
|
|
18112
18164
|
for (const file of files) {
|
|
18113
18165
|
const absPath = path19.resolve(file);
|
|
18114
|
-
if (!
|
|
18166
|
+
if (!fs20.existsSync(absPath))
|
|
18115
18167
|
continue;
|
|
18116
|
-
const text =
|
|
18168
|
+
const text = fs20.readFileSync(absPath, "utf-8");
|
|
18117
18169
|
const result = runPipeline(text, profile, options.fix || false);
|
|
18118
18170
|
results.push({
|
|
18119
18171
|
file,
|
|
@@ -18179,7 +18231,7 @@ No files matching: ${pattern}`));
|
|
|
18179
18231
|
|
|
18180
18232
|
// src/commands/watch.ts
|
|
18181
18233
|
var import_chalk27 = __toESM(require_source());
|
|
18182
|
-
var
|
|
18234
|
+
var fs21 = __toESM(require("fs"));
|
|
18183
18235
|
var path20 = __toESM(require("path"));
|
|
18184
18236
|
init_pipeline();
|
|
18185
18237
|
init_local_profile();
|
|
@@ -18188,7 +18240,7 @@ function registerWatchCommand(program3) {
|
|
|
18188
18240
|
try {
|
|
18189
18241
|
const profile = await loadProfileForCommand(options.profile);
|
|
18190
18242
|
const absPath = path20.resolve(file);
|
|
18191
|
-
if (!
|
|
18243
|
+
if (!fs21.existsSync(absPath)) {
|
|
18192
18244
|
console.error(import_chalk27.default.red(`File not found: ${absPath}`));
|
|
18193
18245
|
process.exit(1);
|
|
18194
18246
|
}
|
|
@@ -18211,7 +18263,7 @@ watching ${absPath}`));
|
|
|
18211
18263
|
let lastScore = 0;
|
|
18212
18264
|
let ignoreWatchUntil = 0;
|
|
18213
18265
|
const runScan = () => {
|
|
18214
|
-
const text =
|
|
18266
|
+
const text = fs21.readFileSync(absPath, "utf-8");
|
|
18215
18267
|
const result = runPipeline(text, profile, options.command === "fix");
|
|
18216
18268
|
scanCount++;
|
|
18217
18269
|
const now = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
@@ -18253,7 +18305,7 @@ watching ${absPath}`));
|
|
|
18253
18305
|
console.log("");
|
|
18254
18306
|
};
|
|
18255
18307
|
runScan();
|
|
18256
|
-
|
|
18308
|
+
fs21.watch(absPath, (eventType) => {
|
|
18257
18309
|
if (eventType !== "change")
|
|
18258
18310
|
return;
|
|
18259
18311
|
if (Date.now() < ignoreWatchUntil)
|
|
@@ -18278,7 +18330,7 @@ watching ${absPath}`));
|
|
|
18278
18330
|
|
|
18279
18331
|
// src/commands/demo.ts
|
|
18280
18332
|
var import_chalk28 = __toESM(require_source());
|
|
18281
|
-
var
|
|
18333
|
+
var fs22 = __toESM(require("fs"));
|
|
18282
18334
|
var SAMPLES = {
|
|
18283
18335
|
linkedin: {
|
|
18284
18336
|
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.
|
|
@@ -18373,7 +18425,7 @@ function registerDemoCommand(program3) {
|
|
|
18373
18425
|
}
|
|
18374
18426
|
if (options.output) {
|
|
18375
18427
|
const outputPath = require("path").resolve(options.output);
|
|
18376
|
-
|
|
18428
|
+
fs22.writeFileSync(outputPath, sample.text);
|
|
18377
18429
|
console.log(import_chalk28.default.green(`
|
|
18378
18430
|
\u2713 Sample written to ${outputPath}`));
|
|
18379
18431
|
if (sample.patterns.length > 0) {
|
|
@@ -18440,22 +18492,22 @@ function registerOpenCommand(program3) {
|
|
|
18440
18492
|
init_welcome();
|
|
18441
18493
|
|
|
18442
18494
|
// src/lib/onboarding.ts
|
|
18443
|
-
var
|
|
18495
|
+
var fs23 = __toESM(require("fs"));
|
|
18444
18496
|
var path21 = __toESM(require("path"));
|
|
18445
18497
|
var os9 = __toESM(require("os"));
|
|
18446
18498
|
var hyvDir = path21.join(os9.homedir(), ".hyv");
|
|
18447
18499
|
var onboardingFile = path21.join(hyvDir, "onboarding-complete.json");
|
|
18448
18500
|
function hasCompletedOnboarding() {
|
|
18449
18501
|
try {
|
|
18450
|
-
return
|
|
18502
|
+
return fs23.existsSync(onboardingFile);
|
|
18451
18503
|
} catch {
|
|
18452
18504
|
return false;
|
|
18453
18505
|
}
|
|
18454
18506
|
}
|
|
18455
18507
|
function markOnboardingComplete(version) {
|
|
18456
|
-
if (!
|
|
18457
|
-
|
|
18458
|
-
|
|
18508
|
+
if (!fs23.existsSync(hyvDir))
|
|
18509
|
+
fs23.mkdirSync(hyvDir, { recursive: true });
|
|
18510
|
+
fs23.writeFileSync(
|
|
18459
18511
|
onboardingFile,
|
|
18460
18512
|
JSON.stringify({ version, completed_at: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
18461
18513
|
);
|
|
@@ -18463,13 +18515,13 @@ function markOnboardingComplete(version) {
|
|
|
18463
18515
|
|
|
18464
18516
|
// src/commands/welcome.ts
|
|
18465
18517
|
init_welcome_flow();
|
|
18466
|
-
var
|
|
18518
|
+
var fs24 = __toESM(require("fs"));
|
|
18467
18519
|
var path22 = __toESM(require("path"));
|
|
18468
18520
|
function registerWelcomeCommand(program3) {
|
|
18469
18521
|
const pkgVersion3 = (() => {
|
|
18470
18522
|
try {
|
|
18471
18523
|
const pkgPath3 = path22.resolve(__dirname, "..", "package.json");
|
|
18472
|
-
return JSON.parse(
|
|
18524
|
+
return JSON.parse(fs24.readFileSync(pkgPath3, "utf-8")).version;
|
|
18473
18525
|
} catch {
|
|
18474
18526
|
return "0.0.0";
|
|
18475
18527
|
}
|
|
@@ -18650,7 +18702,7 @@ Current: ${getEngineLabel()}
|
|
|
18650
18702
|
}
|
|
18651
18703
|
|
|
18652
18704
|
// src/mcp.ts
|
|
18653
|
-
var
|
|
18705
|
+
var fs25 = __toESM(require("fs"));
|
|
18654
18706
|
var path23 = __toESM(require("path"));
|
|
18655
18707
|
var os10 = __toESM(require("os"));
|
|
18656
18708
|
init_classifier();
|
|
@@ -18667,16 +18719,16 @@ var VOICE_MD = path23.join(os10.homedir(), ".hyv", "voice.md");
|
|
|
18667
18719
|
var MAX_RESPONSE_CHARS = 12e4;
|
|
18668
18720
|
var MAX_SCAN_FILE_BYTES = 2 * 1024 * 1024;
|
|
18669
18721
|
function readScanFile(filePath) {
|
|
18670
|
-
const cwdReal =
|
|
18671
|
-
const resolved =
|
|
18722
|
+
const cwdReal = fs25.realpathSync(process.cwd());
|
|
18723
|
+
const resolved = fs25.realpathSync(path23.resolve(filePath));
|
|
18672
18724
|
if (!resolved.startsWith(cwdReal + path23.sep) && resolved !== cwdReal) {
|
|
18673
18725
|
throw new Error(`file must be in the current working directory (${cwdReal})`);
|
|
18674
18726
|
}
|
|
18675
|
-
const stat =
|
|
18727
|
+
const stat = fs25.statSync(resolved);
|
|
18676
18728
|
if (stat.size > MAX_SCAN_FILE_BYTES) {
|
|
18677
18729
|
throw new Error(`file too large (max ${MAX_SCAN_FILE_BYTES} bytes)`);
|
|
18678
18730
|
}
|
|
18679
|
-
return
|
|
18731
|
+
return fs25.readFileSync(resolved, "utf-8");
|
|
18680
18732
|
}
|
|
18681
18733
|
function toolResultPayload(result) {
|
|
18682
18734
|
const isError = result.startsWith("Error:") || result.startsWith("Unknown tool:");
|
|
@@ -18688,7 +18740,7 @@ function toolResultPayload(result) {
|
|
|
18688
18740
|
var pkgPath = path23.resolve(__dirname, "..", "package.json");
|
|
18689
18741
|
var pkgVersion = (() => {
|
|
18690
18742
|
try {
|
|
18691
|
-
return JSON.parse(
|
|
18743
|
+
return JSON.parse(fs25.readFileSync(pkgPath, "utf-8")).version;
|
|
18692
18744
|
} catch {
|
|
18693
18745
|
return "2.7.1";
|
|
18694
18746
|
}
|
|
@@ -19269,7 +19321,7 @@ async function handleRequest(line) {
|
|
|
19269
19321
|
}
|
|
19270
19322
|
async function startMcpServer() {
|
|
19271
19323
|
const access = await getAccessState().catch(() => null);
|
|
19272
|
-
if (
|
|
19324
|
+
if (fs25.existsSync(VOICE_MD)) {
|
|
19273
19325
|
mcpLog("info", `voice profile: ${VOICE_MD}`);
|
|
19274
19326
|
} else {
|
|
19275
19327
|
mcpLog("info", "free local engine ready \u2014 no voice profile yet");
|
|
@@ -19302,7 +19354,7 @@ async function startMcpServer() {
|
|
|
19302
19354
|
|
|
19303
19355
|
// src/lib/mcp-setup.ts
|
|
19304
19356
|
var import_chalk32 = __toESM(require_source());
|
|
19305
|
-
var
|
|
19357
|
+
var fs26 = __toESM(require("fs"));
|
|
19306
19358
|
var path24 = __toESM(require("path"));
|
|
19307
19359
|
var os11 = __toESM(require("os"));
|
|
19308
19360
|
init_version();
|
|
@@ -19396,7 +19448,7 @@ async function runMcpSelfTest() {
|
|
|
19396
19448
|
failed++;
|
|
19397
19449
|
}
|
|
19398
19450
|
const voiceMd = path24.join(HOME2, ".hyv", "voice.md");
|
|
19399
|
-
if (
|
|
19451
|
+
if (fs26.existsSync(voiceMd)) {
|
|
19400
19452
|
console.log(import_chalk32.default.green(" \u2713 voice profile found"));
|
|
19401
19453
|
passed++;
|
|
19402
19454
|
} else {
|
|
@@ -19436,7 +19488,7 @@ async function runMcpSelfTest() {
|
|
|
19436
19488
|
}
|
|
19437
19489
|
|
|
19438
19490
|
// src/commands/export.ts
|
|
19439
|
-
var
|
|
19491
|
+
var fs27 = __toESM(require("fs"));
|
|
19440
19492
|
init_api();
|
|
19441
19493
|
var FORMATS = {
|
|
19442
19494
|
claude: {
|
|
@@ -19523,7 +19575,7 @@ async function exportCommand(format, opts) {
|
|
|
19523
19575
|
const prompt = fmt.wrap(detail.profile, detail.body);
|
|
19524
19576
|
if (opts.output) {
|
|
19525
19577
|
const outFile = opts.output.replace("{name}", profile.slug || profile.name);
|
|
19526
|
-
|
|
19578
|
+
fs27.writeFileSync(outFile, prompt);
|
|
19527
19579
|
results.push({ profile: profile.name, file: outFile });
|
|
19528
19580
|
} else {
|
|
19529
19581
|
results.push({ profile: profile.name, prompt });
|
|
@@ -19560,13 +19612,13 @@ async function exportCommand(format, opts) {
|
|
|
19560
19612
|
// src/index.ts
|
|
19561
19613
|
init_access();
|
|
19562
19614
|
init_welcome();
|
|
19563
|
-
var
|
|
19615
|
+
var fs28 = __toESM(require("fs"));
|
|
19564
19616
|
var path25 = __toESM(require("path"));
|
|
19565
19617
|
var program2 = new Command();
|
|
19566
19618
|
var pkgPath2 = path25.resolve(__dirname, "..", "package.json");
|
|
19567
19619
|
var pkgVersion2 = (() => {
|
|
19568
19620
|
try {
|
|
19569
|
-
return JSON.parse(
|
|
19621
|
+
return JSON.parse(fs28.readFileSync(pkgPath2, "utf-8")).version;
|
|
19570
19622
|
} catch {
|
|
19571
19623
|
return "2.7.1";
|
|
19572
19624
|
}
|
package/package.json
CHANGED