@holdyourvoice/hyv 2.4.4 → 2.4.5

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/README.md CHANGED
@@ -94,14 +94,6 @@ the onboarding walks you through questions about your writing style, audience, a
94
94
  |----------|-------------|
95
95
  | `HYV_API_URL` | API base URL (default: `https://holdyourvoice.com`) |
96
96
 
97
- ```bash
98
- # Staging
99
- HYV_API_URL=https://staging.holdyourvoice.com hyv init
100
-
101
- # Local dev
102
- HYV_API_URL=http://localhost:3000 hyv init
103
- ```
104
-
105
97
  ## license
106
98
 
107
99
  UNLICENSED — [holdyourvoice.com](https://holdyourvoice.com)
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 EventEmitter2 = require("node:events").EventEmitter;
975
975
  var childProcess = require("node:child_process");
976
- var path14 = require("node:path");
977
- var fs14 = require("node:fs");
976
+ var path13 = require("node:path");
977
+ var fs13 = 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 = path14.resolve(baseDir, baseName);
1920
- if (fs14.existsSync(localBin))
1919
+ const localBin = path13.resolve(baseDir, baseName);
1920
+ if (fs13.existsSync(localBin))
1921
1921
  return localBin;
1922
- if (sourceExt.includes(path14.extname(baseName)))
1922
+ if (sourceExt.includes(path13.extname(baseName)))
1923
1923
  return void 0;
1924
1924
  const foundExt = sourceExt.find(
1925
- (ext2) => fs14.existsSync(`${localBin}${ext2}`)
1925
+ (ext2) => fs13.existsSync(`${localBin}${ext2}`)
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 = fs14.realpathSync(this._scriptPath);
1938
+ resolvedScriptPath = fs13.realpathSync(this._scriptPath);
1939
1939
  } catch (err) {
1940
1940
  resolvedScriptPath = this._scriptPath;
1941
1941
  }
1942
- executableDir = path14.resolve(
1943
- path14.dirname(resolvedScriptPath),
1942
+ executableDir = path13.resolve(
1943
+ path13.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 = path14.basename(
1950
+ const legacyName = path13.basename(
1951
1951
  this._scriptPath,
1952
- path14.extname(this._scriptPath)
1952
+ path13.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(path14.extname(executableFile));
1963
+ launchWithNode = sourceExt.includes(path13.extname(executableFile));
1964
1964
  let proc2;
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 = path14.basename(filename, path14.extname(filename));
2820
+ this._name = path13.basename(filename, path13.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(path15) {
2835
- if (path15 === void 0)
2834
+ executableDir(path14) {
2835
+ if (path14 === void 0)
2836
2836
  return this._executableDir;
2837
- this._executableDir = path15;
2837
+ this._executableDir = path14;
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 path14 = [graph[toModel].parent, toModel];
3937
+ const path13 = [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
- path14.unshift(graph[cur].parent);
3941
+ path13.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 = path14;
3945
+ fn.conversion = path13;
3946
3946
  return fn;
3947
3947
  }
3948
3948
  module2.exports = function(fromModel) {
@@ -4727,11 +4727,11 @@ var init_config = __esm({
4727
4727
  var require_is_docker = __commonJS({
4728
4728
  "node_modules/is-docker/index.js"(exports2, module2) {
4729
4729
  "use strict";
4730
- var fs14 = require("fs");
4730
+ var fs13 = require("fs");
4731
4731
  var isDocker;
4732
4732
  function hasDockerEnv() {
4733
4733
  try {
4734
- fs14.statSync("/.dockerenv");
4734
+ fs13.statSync("/.dockerenv");
4735
4735
  return true;
4736
4736
  } catch (_) {
4737
4737
  return false;
@@ -4739,7 +4739,7 @@ var require_is_docker = __commonJS({
4739
4739
  }
4740
4740
  function hasDockerCGroup() {
4741
4741
  try {
4742
- return fs14.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
4742
+ return fs13.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
4743
4743
  } catch (_) {
4744
4744
  return false;
4745
4745
  }
@@ -4758,7 +4758,7 @@ var require_is_wsl = __commonJS({
4758
4758
  "node_modules/is-wsl/index.js"(exports2, module2) {
4759
4759
  "use strict";
4760
4760
  var os5 = require("os");
4761
- var fs14 = require("fs");
4761
+ var fs13 = require("fs");
4762
4762
  var isDocker = require_is_docker();
4763
4763
  var isWsl = () => {
4764
4764
  if (process.platform !== "linux") {
@@ -4771,7 +4771,7 @@ var require_is_wsl = __commonJS({
4771
4771
  return true;
4772
4772
  }
4773
4773
  try {
4774
- return fs14.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
4774
+ return fs13.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
4775
4775
  } catch (_) {
4776
4776
  return false;
4777
4777
  }
@@ -4810,17 +4810,17 @@ var require_define_lazy_prop = __commonJS({
4810
4810
  // node_modules/open/index.js
4811
4811
  var require_open = __commonJS({
4812
4812
  "node_modules/open/index.js"(exports2, module2) {
4813
- var path14 = require("path");
4813
+ var path13 = require("path");
4814
4814
  var childProcess = require("child_process");
4815
- var { promises: fs14, constants: fsConstants } = require("fs");
4815
+ var { promises: fs13, constants: fsConstants } = require("fs");
4816
4816
  var isWsl = require_is_wsl();
4817
4817
  var isDocker = require_is_docker();
4818
4818
  var defineLazyProperty = require_define_lazy_prop();
4819
- var localXdgOpenPath = path14.join(__dirname, "xdg-open");
4819
+ var localXdgOpenPath = path13.join(__dirname, "xdg-open");
4820
4820
  var { platform, arch } = process;
4821
4821
  var hasContainerEnv = () => {
4822
4822
  try {
4823
- fs14.statSync("/run/.containerenv");
4823
+ fs13.statSync("/run/.containerenv");
4824
4824
  return true;
4825
4825
  } catch {
4826
4826
  return false;
@@ -4843,14 +4843,14 @@ var require_open = __commonJS({
4843
4843
  const configFilePath = "/etc/wsl.conf";
4844
4844
  let isConfigFileExists = false;
4845
4845
  try {
4846
- await fs14.access(configFilePath, fsConstants.F_OK);
4846
+ await fs13.access(configFilePath, fsConstants.F_OK);
4847
4847
  isConfigFileExists = true;
4848
4848
  } catch {
4849
4849
  }
4850
4850
  if (!isConfigFileExists) {
4851
4851
  return defaultMountPoint;
4852
4852
  }
4853
- const configContent = await fs14.readFile(configFilePath, { encoding: "utf8" });
4853
+ const configContent = await fs13.readFile(configFilePath, { encoding: "utf8" });
4854
4854
  const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
4855
4855
  if (!configMountPoint) {
4856
4856
  return defaultMountPoint;
@@ -4950,7 +4950,7 @@ var require_open = __commonJS({
4950
4950
  const isBundled = !__dirname || __dirname === "/";
4951
4951
  let exeLocalXdgOpen = false;
4952
4952
  try {
4953
- await fs14.access(localXdgOpenPath, fsConstants.X_OK);
4953
+ await fs13.access(localXdgOpenPath, fsConstants.X_OK);
4954
4954
  exeLocalXdgOpen = true;
4955
4955
  } catch {
4956
4956
  }
@@ -4973,14 +4973,14 @@ var require_open = __commonJS({
4973
4973
  }
4974
4974
  const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
4975
4975
  if (options.wait) {
4976
- return new Promise((resolve6, reject) => {
4976
+ return new Promise((resolve5, reject) => {
4977
4977
  subprocess.once("error", reject);
4978
4978
  subprocess.once("close", (exitCode) => {
4979
4979
  if (!options.allowNonzeroExitCode && exitCode > 0) {
4980
4980
  reject(new Error(`Exited with code ${exitCode}`));
4981
4981
  return;
4982
4982
  }
4983
- resolve6(subprocess);
4983
+ resolve5(subprocess);
4984
4984
  });
4985
4985
  });
4986
4986
  }
@@ -5227,11 +5227,11 @@ __export(api_exports, {
5227
5227
  apiPost: () => apiPost,
5228
5228
  requireSubscription: () => requireSubscription
5229
5229
  });
5230
- async function request2(method, path14, body) {
5230
+ async function request2(method, path13, body) {
5231
5231
  const token = getToken();
5232
5232
  if (!token)
5233
5233
  throw new Error("you're not signed in yet. run: hyv init");
5234
- const url = `${API_BASE}${path14}`;
5234
+ const url = `${API_BASE}${path13}`;
5235
5235
  const opts = {
5236
5236
  method,
5237
5237
  headers: {
@@ -5257,11 +5257,11 @@ async function request2(method, path14, body) {
5257
5257
  }
5258
5258
  return res.json();
5259
5259
  }
5260
- function apiGet(path14) {
5261
- return request2("GET", path14);
5260
+ function apiGet(path13) {
5261
+ return request2("GET", path13);
5262
5262
  }
5263
- function apiPost(path14, body) {
5264
- return request2("POST", path14, body);
5263
+ function apiPost(path13, body) {
5264
+ return request2("POST", path13, body);
5265
5265
  }
5266
5266
  async function requireSubscription() {
5267
5267
  let data;
@@ -8524,10 +8524,10 @@ var init_esm4 = __esm({
8524
8524
  * Return a void Promise that resolves once the stream ends.
8525
8525
  */
8526
8526
  async promise() {
8527
- return new Promise((resolve6, reject) => {
8527
+ return new Promise((resolve5, reject) => {
8528
8528
  this.on(DESTROYED, () => reject(new Error("stream destroyed")));
8529
8529
  this.on("error", (er) => reject(er));
8530
- this.on("end", () => resolve6());
8530
+ this.on("end", () => resolve5());
8531
8531
  });
8532
8532
  }
8533
8533
  /**
@@ -8551,7 +8551,7 @@ var init_esm4 = __esm({
8551
8551
  return Promise.resolve({ done: false, value: res });
8552
8552
  if (this[EOF])
8553
8553
  return stop();
8554
- let resolve6;
8554
+ let resolve5;
8555
8555
  let reject;
8556
8556
  const onerr = (er) => {
8557
8557
  this.off("data", ondata);
@@ -8565,19 +8565,19 @@ var init_esm4 = __esm({
8565
8565
  this.off("end", onend);
8566
8566
  this.off(DESTROYED, ondestroy);
8567
8567
  this.pause();
8568
- resolve6({ value, done: !!this[EOF] });
8568
+ resolve5({ value, done: !!this[EOF] });
8569
8569
  };
8570
8570
  const onend = () => {
8571
8571
  this.off("error", onerr);
8572
8572
  this.off("data", ondata);
8573
8573
  this.off(DESTROYED, ondestroy);
8574
8574
  stop();
8575
- resolve6({ done: true, value: void 0 });
8575
+ resolve5({ done: true, value: void 0 });
8576
8576
  };
8577
8577
  const ondestroy = () => onerr(new Error("stream destroyed"));
8578
8578
  return new Promise((res2, rej) => {
8579
8579
  reject = rej;
8580
- resolve6 = res2;
8580
+ resolve5 = res2;
8581
8581
  this.once(DESTROYED, ondestroy);
8582
8582
  this.once("error", onerr);
8583
8583
  this.once("end", onend);
@@ -8956,12 +8956,12 @@ var init_esm5 = __esm({
8956
8956
  /**
8957
8957
  * Get the Path object referenced by the string path, resolved from this Path
8958
8958
  */
8959
- resolve(path14) {
8960
- if (!path14) {
8959
+ resolve(path13) {
8960
+ if (!path13) {
8961
8961
  return this;
8962
8962
  }
8963
- const rootPath = this.getRootString(path14);
8964
- const dir = path14.substring(rootPath.length);
8963
+ const rootPath = this.getRootString(path13);
8964
+ const dir = path13.substring(rootPath.length);
8965
8965
  const dirParts = dir.split(this.splitSep);
8966
8966
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
8967
8967
  return result;
@@ -9565,9 +9565,9 @@ var init_esm5 = __esm({
9565
9565
  if (this.#asyncReaddirInFlight) {
9566
9566
  await this.#asyncReaddirInFlight;
9567
9567
  } else {
9568
- let resolve6 = () => {
9568
+ let resolve5 = () => {
9569
9569
  };
9570
- this.#asyncReaddirInFlight = new Promise((res) => resolve6 = res);
9570
+ this.#asyncReaddirInFlight = new Promise((res) => resolve5 = res);
9571
9571
  try {
9572
9572
  for (const e of await this.#fs.promises.readdir(fullpath, {
9573
9573
  withFileTypes: true
@@ -9580,7 +9580,7 @@ var init_esm5 = __esm({
9580
9580
  children.provisional = 0;
9581
9581
  }
9582
9582
  this.#asyncReaddirInFlight = void 0;
9583
- resolve6();
9583
+ resolve5();
9584
9584
  }
9585
9585
  return children.slice(0, children.provisional);
9586
9586
  }
@@ -9713,8 +9713,8 @@ var init_esm5 = __esm({
9713
9713
  /**
9714
9714
  * @internal
9715
9715
  */
9716
- getRootString(path14) {
9717
- return import_node_path.win32.parse(path14).root;
9716
+ getRootString(path13) {
9717
+ return import_node_path.win32.parse(path13).root;
9718
9718
  }
9719
9719
  /**
9720
9720
  * @internal
@@ -9760,8 +9760,8 @@ var init_esm5 = __esm({
9760
9760
  /**
9761
9761
  * @internal
9762
9762
  */
9763
- getRootString(path14) {
9764
- return path14.startsWith("/") ? "/" : "";
9763
+ getRootString(path13) {
9764
+ return path13.startsWith("/") ? "/" : "";
9765
9765
  }
9766
9766
  /**
9767
9767
  * @internal
@@ -9810,8 +9810,8 @@ var init_esm5 = __esm({
9810
9810
  *
9811
9811
  * @internal
9812
9812
  */
9813
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs14 = defaultFS } = {}) {
9814
- this.#fs = fsFromOption(fs14);
9813
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs13 = defaultFS } = {}) {
9814
+ this.#fs = fsFromOption(fs13);
9815
9815
  if (cwd instanceof URL || cwd.startsWith("file://")) {
9816
9816
  cwd = (0, import_node_url.fileURLToPath)(cwd);
9817
9817
  }
@@ -9850,11 +9850,11 @@ var init_esm5 = __esm({
9850
9850
  /**
9851
9851
  * Get the depth of a provided path, string, or the cwd
9852
9852
  */
9853
- depth(path14 = this.cwd) {
9854
- if (typeof path14 === "string") {
9855
- path14 = this.cwd.resolve(path14);
9853
+ depth(path13 = this.cwd) {
9854
+ if (typeof path13 === "string") {
9855
+ path13 = this.cwd.resolve(path13);
9856
9856
  }
9857
- return path14.depth();
9857
+ return path13.depth();
9858
9858
  }
9859
9859
  /**
9860
9860
  * Return the cache of child entries. Exposed so subclasses can create
@@ -10341,9 +10341,9 @@ var init_esm5 = __esm({
10341
10341
  process2();
10342
10342
  return results;
10343
10343
  }
10344
- chdir(path14 = this.cwd) {
10344
+ chdir(path13 = this.cwd) {
10345
10345
  const oldCwd = this.cwd;
10346
- this.cwd = typeof path14 === "string" ? this.cwd.resolve(path14) : path14;
10346
+ this.cwd = typeof path13 === "string" ? this.cwd.resolve(path13) : path13;
10347
10347
  this.cwd[setAsCwd](oldCwd);
10348
10348
  }
10349
10349
  };
@@ -10369,8 +10369,8 @@ var init_esm5 = __esm({
10369
10369
  /**
10370
10370
  * @internal
10371
10371
  */
10372
- newRoot(fs14) {
10373
- return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs14 });
10372
+ newRoot(fs13) {
10373
+ return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs13 });
10374
10374
  }
10375
10375
  /**
10376
10376
  * Return true if the provided path string is an absolute path
@@ -10398,8 +10398,8 @@ var init_esm5 = __esm({
10398
10398
  /**
10399
10399
  * @internal
10400
10400
  */
10401
- newRoot(fs14) {
10402
- return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs14 });
10401
+ newRoot(fs13) {
10402
+ return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs13 });
10403
10403
  }
10404
10404
  /**
10405
10405
  * Return true if the provided path string is an absolute path
@@ -10718,8 +10718,8 @@ var init_processor = __esm({
10718
10718
  }
10719
10719
  // match, absolute, ifdir
10720
10720
  entries() {
10721
- return [...this.store.entries()].map(([path14, n]) => [
10722
- path14,
10721
+ return [...this.store.entries()].map(([path13, n]) => [
10722
+ path13,
10723
10723
  !!(n & 2),
10724
10724
  !!(n & 1)
10725
10725
  ]);
@@ -10932,9 +10932,9 @@ var init_walker = __esm({
10932
10932
  signal;
10933
10933
  maxDepth;
10934
10934
  includeChildMatches;
10935
- constructor(patterns, path14, opts) {
10935
+ constructor(patterns, path13, opts) {
10936
10936
  this.patterns = patterns;
10937
- this.path = path14;
10937
+ this.path = path13;
10938
10938
  this.opts = opts;
10939
10939
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
10940
10940
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -10953,11 +10953,11 @@ var init_walker = __esm({
10953
10953
  });
10954
10954
  }
10955
10955
  }
10956
- #ignored(path14) {
10957
- return this.seen.has(path14) || !!this.#ignore?.ignored?.(path14);
10956
+ #ignored(path13) {
10957
+ return this.seen.has(path13) || !!this.#ignore?.ignored?.(path13);
10958
10958
  }
10959
- #childrenIgnored(path14) {
10960
- return !!this.#ignore?.childrenIgnored?.(path14);
10959
+ #childrenIgnored(path13) {
10960
+ return !!this.#ignore?.childrenIgnored?.(path13);
10961
10961
  }
10962
10962
  // backpressure mechanism
10963
10963
  pause() {
@@ -11172,8 +11172,8 @@ var init_walker = __esm({
11172
11172
  };
11173
11173
  GlobWalker = class extends GlobUtil {
11174
11174
  matches = /* @__PURE__ */ new Set();
11175
- constructor(patterns, path14, opts) {
11176
- super(patterns, path14, opts);
11175
+ constructor(patterns, path13, opts) {
11176
+ super(patterns, path13, opts);
11177
11177
  }
11178
11178
  matchEmit(e) {
11179
11179
  this.matches.add(e);
@@ -11210,8 +11210,8 @@ var init_walker = __esm({
11210
11210
  };
11211
11211
  GlobStream = class extends GlobUtil {
11212
11212
  results;
11213
- constructor(patterns, path14, opts) {
11214
- super(patterns, path14, opts);
11213
+ constructor(patterns, path13, opts) {
11214
+ super(patterns, path13, opts);
11215
11215
  this.results = new Minipass({
11216
11216
  signal: this.signal,
11217
11217
  objectMode: true
@@ -11540,10 +11540,7 @@ __export(scanner_exports, {
11540
11540
  scanFiles: () => scanFiles,
11541
11541
  scanText: () => scanText2
11542
11542
  });
11543
- function scanFiles(paths, ignore = []) {
11544
- return scanFilesImpl(paths, ignore);
11545
- }
11546
- async function scanFilesImpl(paths, ignore = []) {
11543
+ async function scanFiles(paths, ignore = []) {
11547
11544
  const allFiles = [];
11548
11545
  for (const p of paths) {
11549
11546
  if (fs10.existsSync(p) && fs10.statSync(p).isFile()) {
@@ -11661,7 +11658,7 @@ var import_chalk = __toESM(require_source());
11661
11658
  var import_open = __toESM(require_open());
11662
11659
  init_config();
11663
11660
  function request(url, options = {}) {
11664
- return new Promise((resolve6, reject) => {
11661
+ return new Promise((resolve5, reject) => {
11665
11662
  const urlObj = new URL(url);
11666
11663
  const isHttps = urlObj.protocol === "https:";
11667
11664
  const client = isHttps ? https : http;
@@ -11672,7 +11669,7 @@ function request(url, options = {}) {
11672
11669
  method: options.method || "GET",
11673
11670
  headers: {
11674
11671
  "Content-Type": "application/json",
11675
- "User-Agent": "hyv-cli/2.3.1",
11672
+ "User-Agent": "hyv-cli/2.4.3",
11676
11673
  ...options.headers
11677
11674
  },
11678
11675
  timeout: options.timeout || 3e4
@@ -11682,9 +11679,9 @@ function request(url, options = {}) {
11682
11679
  res.on("data", (chunk) => data += chunk);
11683
11680
  res.on("end", () => {
11684
11681
  try {
11685
- resolve6({ status: res.statusCode || 0, data: JSON.parse(data) });
11682
+ resolve5({ status: res.statusCode || 0, data: JSON.parse(data) });
11686
11683
  } catch {
11687
- resolve6({ status: res.statusCode || 0, data });
11684
+ resolve5({ status: res.statusCode || 0, data });
11688
11685
  }
11689
11686
  });
11690
11687
  });
@@ -11729,9 +11726,9 @@ async function authenticateWithLicense(licenseKey) {
11729
11726
  }
11730
11727
  async function authenticateWithBrowser() {
11731
11728
  const server = http.createServer();
11732
- const port = await new Promise((resolve6) => {
11733
- server.listen(0, "0.0.0.0", () => {
11734
- resolve6(server.address().port);
11729
+ const port = await new Promise((resolve5) => {
11730
+ server.listen(0, "127.0.0.1", () => {
11731
+ resolve5(server.address().port);
11735
11732
  });
11736
11733
  });
11737
11734
  const redirectUri = `http://127.0.0.1:${port}/callback`;
@@ -11746,7 +11743,7 @@ async function authenticateWithBrowser() {
11746
11743
  const { auth_url } = response.data;
11747
11744
  console.log(import_chalk.default.cyan("\nOpening browser for authentication..."));
11748
11745
  await (0, import_open.default)(auth_url);
11749
- const authData = await new Promise((resolve6, reject) => {
11746
+ const authData = await new Promise((resolve5, reject) => {
11750
11747
  const timeout = setTimeout(() => {
11751
11748
  server.close();
11752
11749
  reject(new Error("Authentication timeout. Please try again."));
@@ -11784,7 +11781,7 @@ async function authenticateWithBrowser() {
11784
11781
  `);
11785
11782
  clearTimeout(timeout);
11786
11783
  server.close();
11787
- resolve6(data);
11784
+ resolve5(data);
11788
11785
  } catch (error) {
11789
11786
  res.writeHead(500, { "Content-Type": "text/html" });
11790
11787
  res.end(`<h1>Authentication failed</h1><p>${error.message}</p>`);
@@ -12273,24 +12270,20 @@ function scanText(text) {
12273
12270
  const hits = [];
12274
12271
  const safeText = text || "";
12275
12272
  for (const rule of AI_PATTERN_RULES) {
12276
- const regex = new RegExp(rule.pattern.source, rule.pattern.flags.replace("g", "") + "g");
12277
- let match2;
12278
- let lastIndex = 0;
12279
- while ((match2 = regex.exec(safeText)) !== null) {
12280
- const snippet = match2[0].trim();
12281
- if (!snippet) {
12282
- if (match2.index === regex.lastIndex)
12283
- regex.lastIndex++;
12284
- continue;
12273
+ const matches = safeText.match(rule.pattern);
12274
+ if (matches) {
12275
+ for (const match2 of matches) {
12276
+ const snippet = match2.trim();
12277
+ if (!snippet)
12278
+ continue;
12279
+ const matchIndex = safeText.indexOf(match2);
12280
+ const lineNo = matchIndex >= 0 ? safeText.slice(0, matchIndex).split("\n").length : 1;
12281
+ hits.push({
12282
+ line: lineNo,
12283
+ rule: rule.id,
12284
+ phrase: snippet.slice(0, 160)
12285
+ });
12285
12286
  }
12286
- const lineNo = safeText.slice(0, match2.index).split("\n").length;
12287
- hits.push({
12288
- line: lineNo,
12289
- rule: rule.id,
12290
- phrase: snippet.slice(0, 160)
12291
- });
12292
- if (match2.index === regex.lastIndex)
12293
- regex.lastIndex++;
12294
12287
  }
12295
12288
  }
12296
12289
  const lines = safeText.split("\n");
@@ -12336,19 +12329,19 @@ function scanText(text) {
12336
12329
  return a.rule.localeCompare(b.rule);
12337
12330
  });
12338
12331
  }
12339
- function formatScanText(path14, hits) {
12332
+ function formatScanText(path13, hits) {
12340
12333
  if (!hits.length) {
12341
- return `${path14}: no deterministic AI-pattern issues found`;
12334
+ return `${path13}: no deterministic AI-pattern issues found`;
12342
12335
  }
12343
- const lines = [`${path14}: ${hits.length} issue(s)`];
12336
+ const lines = [`${path13}: ${hits.length} issue(s)`];
12344
12337
  for (const hit of hits) {
12345
12338
  lines.push(`- line ${hit.line}: ${hit.rule} - ${hit.phrase}`);
12346
12339
  }
12347
12340
  return lines.join("\n");
12348
12341
  }
12349
- function formatScanJson(path14, hits) {
12342
+ function formatScanJson(path13, hits) {
12350
12343
  return {
12351
- path: path14,
12344
+ path: path13,
12352
12345
  issue_count: hits.length,
12353
12346
  issues: hits
12354
12347
  };
@@ -12464,9 +12457,11 @@ function buildRewritePrompt(options) {
12464
12457
  }
12465
12458
 
12466
12459
  // src/commands/rewrite.ts
12460
+ init_api();
12467
12461
  function registerRewriteCommand(program3) {
12468
12462
  program3.command("rewrite").description("Generate rewrite prompt for LLM").argument("<file>", "File to rewrite (or - for stdin)").option("--profile <name>", "Voice profile to use").option("--format <type>", "Content format (linkedin, blog, email)").option("--constraints <text>", "Additional constraints").option("--no-scan", "Skip local scan").option("--output <file>", "Write prompt to file instead of stdout").action(async (file, options) => {
12469
12463
  try {
12464
+ await requireSubscription();
12470
12465
  let draftContent;
12471
12466
  let draftPath;
12472
12467
  if (file === "-") {
@@ -12989,8 +12984,27 @@ hyv import ${name} <file.md>
12989
12984
  Or paste the profile content and I'll save it.`;
12990
12985
  console.log(prompt);
12991
12986
  }
12987
+ function registerImportCommand(program3) {
12988
+ program3.command("import").description("Import a voice profile from file").argument("<name>", "Profile name").argument("<file>", "Profile markdown file").action(async (name, file) => {
12989
+ try {
12990
+ const filePath = path6.resolve(file);
12991
+ if (!fs6.existsSync(filePath)) {
12992
+ console.error(import_chalk7.default.red(`File not found: ${filePath}`));
12993
+ process.exit(1);
12994
+ }
12995
+ const content = fs6.readFileSync(filePath, "utf-8");
12996
+ ensureHyvDir();
12997
+ writeCachedProfile(name, content);
12998
+ console.log(import_chalk7.default.green(`
12999
+ \u2713 Profile imported: ${name}`));
13000
+ } catch (error) {
13001
+ console.error(import_chalk7.default.red(`Error: ${error.message}`));
13002
+ process.exit(1);
13003
+ }
13004
+ });
13005
+ }
12992
13006
  function askQuestion(question) {
12993
- return new Promise((resolve6) => {
13007
+ return new Promise((resolve5) => {
12994
13008
  const readline = require("readline");
12995
13009
  const rl = readline.createInterface({
12996
13010
  input: process.stdin,
@@ -12999,7 +13013,7 @@ function askQuestion(question) {
12999
13013
  rl.question(import_chalk7.default.cyan(` ${question}
13000
13014
  > `), (answer) => {
13001
13015
  rl.close();
13002
- resolve6(answer.trim());
13016
+ resolve5(answer.trim());
13003
13017
  });
13004
13018
  });
13005
13019
  }
@@ -13186,9 +13200,11 @@ async function downgradePlan() {
13186
13200
  var import_chalk9 = __toESM(require_source());
13187
13201
  var fs7 = __toESM(require("fs"));
13188
13202
  var path7 = __toESM(require("path"));
13203
+ init_api();
13189
13204
  function registerScanCommand(program3) {
13190
13205
  program3.command("scan").description("Scan text for voice issues").argument("<file>", "File to scan (or - for stdin)").option("--format <type>", "Output format (text or json)", "text").option("--fail-on-hit", "Exit with code 2 if issues found").option("--ignore <rules>", "Comma-separated rules to ignore").action(async (file, options) => {
13191
13206
  try {
13207
+ await requireSubscription();
13192
13208
  let text;
13193
13209
  let filePath;
13194
13210
  if (file === "-") {
@@ -13233,7 +13249,7 @@ function registerScanCommand(program3) {
13233
13249
  console.log(formatScanText(filePath, hits));
13234
13250
  }
13235
13251
  if (options.failOnHit && hits.length > 0) {
13236
- process.exit(1);
13252
+ process.exit(2);
13237
13253
  }
13238
13254
  } catch (error) {
13239
13255
  console.error(import_chalk9.default.red(`Error: ${error.message}`));
@@ -13332,22 +13348,14 @@ function registerDoctorCommand(program3) {
13332
13348
  { name: "cursor", file: path8.join(HOME, ".cursor", "rules", "hyv.md") },
13333
13349
  { name: "windsurf", file: path8.join(HOME, IS_WIN ? path8.join("AppData", "Roaming", "Windsurf") : ".windsurf", "rules", "hyv.md") },
13334
13350
  { name: "chatgpt", file: path8.join(HOME, ".chatgpt", "hyv-instructions.txt") },
13335
- { name: "codex (project)", file: path8.join(cwd, ".codex", "instructions.md"), check: path8.join(cwd, ".codex") },
13336
- { name: "codex (global)", file: path8.join(HOME, ".codex", "instructions.md"), check: path8.join(HOME, ".codex") },
13337
- { name: "command code", file: path8.join(HOME, ".commandcode", "skills", "hyv", "hyv.md"), check: path8.join(HOME, ".commandcode", "skills", "hyv") },
13338
- { name: "windsurf (app support)", file: path8.join(HOME, "Library", "Application Support", "Windsurf", "rules", "hyv.md"), check: path8.join(HOME, "Library", "Application Support", "Windsurf") }
13351
+ { name: "codex (project)", file: path8.join(cwd, "AGENTS.md") },
13352
+ { name: "command code", file: path8.join(HOME, ".commandcode", "skills", "hyv") }
13339
13353
  ];
13340
13354
  for (const agent of agents) {
13341
- const effectiveFile = agent.file;
13342
- const checkPath = agent.check || effectiveFile;
13343
- if (fs8.existsSync(checkPath)) {
13344
- if (fs8.existsSync(effectiveFile)) {
13345
- console.log(import_chalk10.default.green(` \u2713 ${agent.name}`));
13346
- } else {
13347
- console.log(import_chalk10.default.dim(` - ${agent.name} dir exists but no hyv config`));
13348
- }
13355
+ if (fs8.existsSync(agent.file)) {
13356
+ console.log(import_chalk10.default.green(` \u2713 ${agent.name}`));
13349
13357
  } else {
13350
- console.log(import_chalk10.default.dim(` - ${agent.name} not found`));
13358
+ console.log(import_chalk10.default.dim(` - ${agent.name} not configured`));
13351
13359
  }
13352
13360
  }
13353
13361
  console.log(import_chalk10.default.dim("checking mcp server..."));
@@ -13437,6 +13445,83 @@ error: ${error.message}
13437
13445
  }
13438
13446
  });
13439
13447
  }
13448
+ function registerSayCommand(program3) {
13449
+ program3.command("say").description('natural language commands (e.g., "rename my profile to X")').argument("<input>", "natural language command").action(async (input) => {
13450
+ const trimmed = input.trim();
13451
+ if (!trimmed) {
13452
+ console.log(import_chalk11.default.red("\nerror: no input provided\n"));
13453
+ console.log(import_chalk11.default.dim(' try: hyv say "rename my profile to <name>"\n'));
13454
+ process.exit(1);
13455
+ return;
13456
+ }
13457
+ const intent = parseNaturalLanguage(trimmed);
13458
+ switch (intent.action) {
13459
+ case "rename":
13460
+ if (intent.name) {
13461
+ const token = getToken();
13462
+ if (!token) {
13463
+ console.log(import_chalk11.default.red("\nerror: you're not signed in yet\n"));
13464
+ console.log(import_chalk11.default.dim(" run: hyv init\n"));
13465
+ process.exit(1);
13466
+ return;
13467
+ }
13468
+ const response = await authenticatedRequest(
13469
+ "https://holdyourvoice.com/cli/profiles/rename",
13470
+ {
13471
+ method: "POST",
13472
+ body: { slug_or_id: "default", new_name: intent.name }
13473
+ }
13474
+ );
13475
+ if (response.status === 200) {
13476
+ const data = response.data;
13477
+ console.log(import_chalk11.default.green(`
13478
+ \u2713 profile renamed to ${data.profile?.name || intent.name}
13479
+ `));
13480
+ } else {
13481
+ console.log(import_chalk11.default.red(`
13482
+ error: server returned ${response.status}
13483
+ `));
13484
+ }
13485
+ }
13486
+ break;
13487
+ case "unknown":
13488
+ default:
13489
+ console.log(import_chalk11.default.yellow("\n! i didn't catch that\n"));
13490
+ console.log(import_chalk11.default.dim(' try: hyv say "rename my profile to <name>"'));
13491
+ console.log(import_chalk11.default.dim(" or: hyv rename <new-name>\n"));
13492
+ process.exit(1);
13493
+ break;
13494
+ }
13495
+ });
13496
+ }
13497
+ function parseNaturalLanguage(input) {
13498
+ const raw = input.trim();
13499
+ const renamePatterns = [
13500
+ /rename\s+(?:my\s+)?(?:voice\s+)?profile\s+(?:to|as)\s+(.+)/i,
13501
+ /update\s+(?:my\s+)?(?:voice\s+)?profile\s+(?:name\s+)?(?:to|as)\s+(.+)/i,
13502
+ /change\s+(?:my\s+)?(?:voice\s+)?profile\s+(?:name\s+)?(?:to|as)\s+(.+)/i,
13503
+ /call\s+(?:my\s+)?(?:voice\s+)?profile\s+(.+)/i,
13504
+ /set\s+(?:my\s+)?(?:voice\s+)?profile\s+(?:name\s+)?(?:to|as)\s+(.+)/i,
13505
+ /name\s+(?:my\s+)?(?:voice\s+)?profile\s+(.+)/i,
13506
+ /(?:voice\s+)?profile\s+(?:rename|name)\s+(?:to|as)\s+(.+)/i,
13507
+ /rename\s+(?:to|as)\s+(.+)/i,
13508
+ /update\s+(?:voice\s+)?profile\s+(?:name\s+)?(?:to|as)\s+(.+)/i
13509
+ ];
13510
+ for (const pattern of renamePatterns) {
13511
+ const match2 = raw.match(pattern);
13512
+ if (match2 && match2[1]) {
13513
+ let name = match2[1].trim();
13514
+ if (name.startsWith('"') && name.endsWith('"') || name.startsWith("'") && name.endsWith("'")) {
13515
+ name = name.slice(1, -1);
13516
+ }
13517
+ name = name.replace(/[.!?]+$/, "").trim();
13518
+ if (name.length > 0 && name.length <= 100) {
13519
+ return { action: "rename", name, raw };
13520
+ }
13521
+ }
13522
+ }
13523
+ return { action: "unknown", raw };
13524
+ }
13440
13525
 
13441
13526
  // src/mcp.ts
13442
13527
  var fs11 = __toESM(require("fs"));
@@ -14143,7 +14228,7 @@ function buildMinimalProfile(slug, body) {
14143
14228
  }
14144
14229
  function getDefaultProfileSlug() {
14145
14230
  const config = readConfig();
14146
- return config.profile;
14231
+ return config.default_profile;
14147
14232
  }
14148
14233
 
14149
14234
  // src/mcp.ts
@@ -14296,7 +14381,6 @@ function buildRetryInstruction(issues, signals, profile) {
14296
14381
  }
14297
14382
 
14298
14383
  // src/mcp.ts
14299
- var pkg = { version: "2.3.1" };
14300
14384
  var VOICE_MD = path12.join(os4.homedir(), ".hyv", "voice.md");
14301
14385
  var PROFILES_DIR3 = path12.join(os4.homedir(), ".hyv", "profiles");
14302
14386
  function jsonRpcOk(id, result) {
@@ -14353,16 +14437,15 @@ async function toolScan(args) {
14353
14437
  return `Found ${issues2.length} issues:
14354
14438
  ${issues2.join("\n")}`;
14355
14439
  }
14356
- const { scanText: scanText4 } = await Promise.resolve().then(() => (init_scanner(), scanner_exports));
14357
- const findings = scanText4(text);
14440
+ const { scanText: scanText3 } = await Promise.resolve().then(() => (init_scanner(), scanner_exports));
14441
+ const findings = scanText3(text);
14358
14442
  if (findings.length === 0)
14359
14443
  return "No AI patterns found";
14360
14444
  const issues = findings.map((f) => `line ${f.line}: [${f.severity}] ${f.pattern} \u2014 ${f.excerpt}`);
14361
14445
  return `Found ${issues.length} issues:
14362
14446
  ${issues.join("\n")}`;
14363
14447
  } catch (err) {
14364
- const errorObj = err?.code ? err : { code: -32603, message: err?.message || "Unknown error", data: err?.data };
14365
- return JSON.stringify({ error: errorObj });
14448
+ return `Error: ${err.message}`;
14366
14449
  }
14367
14450
  }
14368
14451
  async function toolProfiles(_args) {
@@ -14380,8 +14463,7 @@ async function toolProfiles(_args) {
14380
14463
  if (msg.includes("session expired") || msg.includes("not signed in")) {
14381
14464
  return "Session expired. Run `hyv init` in your terminal to re-authenticate, then retry.";
14382
14465
  }
14383
- const errorObj = err?.code ? err : { code: -32603, message: err?.message || "Unknown error", data: { type: "profiles_fetch_failed" } };
14384
- return JSON.stringify({ error: errorObj });
14466
+ return `Error: ${err.message}`;
14385
14467
  }
14386
14468
  }
14387
14469
  async function toolValidate(args) {
@@ -14406,14 +14488,13 @@ async function toolValidate(args) {
14406
14488
  ${result.issues.map((i) => ` - ${i}`).join("\n")}`);
14407
14489
  return parts.join("\n");
14408
14490
  } catch (err) {
14409
- const errorObj = err?.code ? err : { code: -32603, message: err?.message || "Unknown error", data: { type: "validate_failed" } };
14410
- return JSON.stringify({ error: errorObj });
14491
+ return `Error: ${err.message}`;
14411
14492
  }
14412
14493
  }
14413
14494
  var TOOLS = [
14414
14495
  {
14415
14496
  name: "hyv_rewrite",
14416
- description: "Rewrite text to match the user's voice profile using Voice DNA rules (natural voice, short paragraphs, no jargon, no em-dashes, physical verbs, specificity over jokes) and Ogilvy principles (write like you talk, short words, clear action). Auto-fixes 80+ AI patterns including engagement bait, insider claims, antithesis negation, and dead transitions. ALWAYS use this tool when: the user asks to write, rewrite, edit, draft, or improve any text. Trigger on: make this better, fix the tone, clean this up, make it sound like me, rewrite in my voice, or any writing/editing request.",
14497
+ description: "Rewrite text to match the user's voice profile using Voice DNA rules (natural voice, short paragraphs, no jargon, no em-dashes, physical verbs, specificity over jokes) and Ogilvy principles (write like you talk, short words, clear action). Auto-fixes 80+ AI patterns including engagement bait, insider claims, antithesis negation, and dead transitions. ALWAYS use this tool when: the user asks to write, rewrite, edit, draft, or improve any text. Trigger on: make this better, fix the tone, clean this up, make it sound like me, rewrite in my voice, or any writing/editing request. Do NOT wait for the user to say hyv.",
14417
14498
  inputSchema: {
14418
14499
  type: "object",
14419
14500
  properties: {
@@ -14478,7 +14559,7 @@ async function handleRequest(line) {
14478
14559
  send(jsonRpcOk(id, {
14479
14560
  protocolVersion: "2024-11-05",
14480
14561
  capabilities: { tools: {}, prompts: {} },
14481
- serverInfo: { name: "hyv", version: pkg.version }
14562
+ serverInfo: { name: "hyv", version: "2.4.3" }
14482
14563
  }));
14483
14564
  break;
14484
14565
  case "notifications/initialized":
@@ -14711,18 +14792,8 @@ async function exportCommand(format, opts) {
14711
14792
  }
14712
14793
 
14713
14794
  // src/index.ts
14714
- var fs13 = __toESM(require("fs"));
14715
- var path13 = __toESM(require("path"));
14716
14795
  var program2 = new Command();
14717
- var pkgPath = path13.resolve(__dirname, "..", "package.json");
14718
- var pkgVersion = (() => {
14719
- try {
14720
- return JSON.parse(fs13.readFileSync(pkgPath, "utf-8")).version;
14721
- } catch {
14722
- return "2.3.1";
14723
- }
14724
- })();
14725
- program2.name("hyv").description("Hold Your Voice \u2014 CLI-first voice gate layer for AI workflows").version(pkgVersion);
14796
+ program2.name("hyv").description("Hold Your Voice \u2014 CLI-first voice gate layer for AI workflows").version("2.4.3");
14726
14797
  registerInitCommand(program2);
14727
14798
  registerStatusCommand(program2);
14728
14799
  registerSyncCommand(program2);
@@ -14733,6 +14804,8 @@ registerPlanCommand(program2);
14733
14804
  registerScanCommand(program2);
14734
14805
  registerDoctorCommand(program2);
14735
14806
  registerRenameCommand(program2);
14807
+ registerSayCommand(program2);
14808
+ registerImportCommand(program2);
14736
14809
  program2.command("mcp").description("Start MCP server (for Claude Desktop and other MCP hosts)").option("--setup-chatgpt", "Show ChatGPT connector setup instructions").action(async (opts) => {
14737
14810
  if (opts.setupChatgpt) {
14738
14811
  console.log(import_chalk13.default.bold("\nhold your voice \u2014 chatgpt setup\n"));
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@holdyourvoice/hyv",
3
- "version": "2.4.4",
4
- "description": "Hold Your Voice voice gate layer for AI workflows. make your ai agent sound exactly like you! includes 220+ AI pattern detection engine.",
3
+ "version": "2.4.5",
4
+ "description": "Hold Your Voice \u2014 voice gate layer for AI workflows. make your ai agent sound exactly like you! includes 220+ AI pattern detection engine.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "hyv": "dist/index.js",
8
- "hyvoice": "dist/index.js"
8
+ "hyvoice": "dist/index.js",
9
+ "hyv-voice": "scripts/hold_voice.py",
10
+ "hyv-sync": "scripts/hold_voice_sync.py"
9
11
  },
10
12
  "scripts": {
11
13
  "build": "esbuild src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --format=cjs --banner:js='#!/usr/bin/env node'",
12
14
  "dev": "npm run build && node dist/index.js",
13
15
  "prepublishOnly": "node scripts/check-no-duplicates.js && npm run build",
14
- "postinstall": "node scripts/postinstall.js",
15
- "test": "vitest run",
16
- "test:watch": "vitest"
16
+ "postinstall": "node scripts/postinstall.js"
17
17
  },
18
18
  "keywords": [
19
19
  "voice",
@@ -30,14 +30,13 @@
30
30
  "dependencies": {
31
31
  "chalk": "^4.1.2",
32
32
  "commander": "^12.1.0",
33
- "glob": "^11.0.0",
34
- "open": "^8.4.2"
33
+ "open": "^8.4.2",
34
+ "glob": "^11.0.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/node": "^20.19.42",
37
+ "@types/node": "^20.11.0",
38
38
  "esbuild": "^0.20.0",
39
- "typescript": "^5.3.3",
40
- "vitest": "^4.1.8"
39
+ "typescript": "^5.3.3"
41
40
  },
42
41
  "engines": {
43
42
  "node": ">=18"
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python3
2
- #!/usr/bin/env python3
3
2
  """Portable Hold Your Voice helpers.
4
3
 
5
4
  This script intentionally has no third-party dependencies. It is not the Hold
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python3
2
- #!/usr/bin/env python3
3
2
  """Push voice profile, meta, and voice.md to Cloudflare R2 for backup.
4
3
 
5
4
  Cost design: R2 has no egress fees. This script uses S3-compatible PUT only
@@ -77,24 +77,16 @@ try {
77
77
 
78
78
  // ── Windsurf (global rules) ───────────────────────────────────────────────
79
79
  try {
80
- const wsDirs = [
81
- isWin
82
- ? path.join(home, 'AppData', 'Roaming', 'Windsurf')
83
- : path.join(home, '.windsurf'),
84
- isWin
85
- ? null
86
- : path.join(home, 'Library', 'Application Support', 'Windsurf'),
87
- ].filter(Boolean);
88
- for (const wsDir of wsDirs) {
89
- if (fs.existsSync(wsDir)) {
90
- const rulesFile = path.join(wsDir, 'rules', 'hyv.md');
91
- fs.mkdirSync(path.dirname(rulesFile), { recursive: true });
92
- const src = path.join(pkgDir, 'agents', 'windsurf.md');
93
- if (fs.existsSync(src) && !fs.existsSync(rulesFile)) {
94
- fs.copyFileSync(src, rulesFile);
95
- configured.push('windsurf');
96
- break;
97
- }
80
+ const wsDir = isWin
81
+ ? path.join(home, 'AppData', 'Roaming', 'Windsurf')
82
+ : path.join(home, '.windsurf');
83
+ if (fs.existsSync(wsDir)) {
84
+ const rulesFile = path.join(wsDir, 'rules', 'hyv.md');
85
+ fs.mkdirSync(path.dirname(rulesFile), { recursive: true });
86
+ const src = path.join(pkgDir, 'agents', 'windsurf.md');
87
+ if (fs.existsSync(src) && !fs.existsSync(rulesFile)) {
88
+ fs.copyFileSync(src, rulesFile);
89
+ configured.push('windsurf');
98
90
  }
99
91
  }
100
92
  } catch {}
@@ -111,6 +103,33 @@ try {
111
103
  }
112
104
  } catch {}
113
105
 
106
+ // ── Codex (AGENTS.md in current project) ──────────────────────────────────
107
+ try {
108
+ const cwd = process.cwd();
109
+ const agentsFile = path.join(cwd, 'AGENTS.md');
110
+ if (!fs.existsSync(agentsFile)) {
111
+ const src = path.join(pkgDir, 'agents', 'codex.md');
112
+ if (fs.existsSync(src)) {
113
+ fs.copyFileSync(src, agentsFile);
114
+ configured.push('codex');
115
+ }
116
+ }
117
+ } catch {}
118
+
119
+ // ── Command Code (global skills) ──────────────────────────────────────────
120
+ try {
121
+ const ccDir = path.join(home, '.commandcode', 'skills', 'hyv');
122
+ if (fs.existsSync(path.dirname(ccDir))) {
123
+ fs.mkdirSync(ccDir, { recursive: true });
124
+ const skillFile = path.join(ccDir, 'SKILL.md');
125
+ const src = path.join(pkgDir, 'agents', 'generic.md');
126
+ if (fs.existsSync(src) && !fs.existsSync(skillFile)) {
127
+ fs.copyFileSync(src, skillFile);
128
+ configured.push('command code');
129
+ }
130
+ }
131
+ } catch {}
132
+
114
133
  // ── Summary ───────────────────────────────────────────────────────────────
115
134
  if (configured.length > 0) {
116
135
  console.log(' \u2713 auto-configured: ' + configured.join(', '));