@holdyourvoice/hyv 2.9.26 → 2.9.27

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 CHANGED
@@ -2,6 +2,11 @@
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.27] — 2026-07-15
6
+
7
+ ### Fixed
8
+ - **MCP scan hang** — `hyv_scan`, `hyv_fix`, `hyv_check`, `hyv_score`, `hyv_diff`, and `hyv_validate` no longer block on account profile sync; they use local `~/.hyv` cache immediately (matching `hyv scan` CLI) and hydrate profiles in the background
9
+
5
10
  ## [2.9.26] — 2026-07-09
6
11
 
7
12
  ### Improved
package/README.md CHANGED
@@ -96,7 +96,7 @@ hyv doctor --fix-agents
96
96
  | tool | description |
97
97
  |------|-------------|
98
98
  | `hyv_welcome` / `hyv_demo` | onboarding + live free scan demo |
99
- | `hyv_scan` | fast local scan (free, offline) |
99
+ | `hyv_scan` | fast local scan (free, offline; uses `~/.hyv` cache, no network wait) |
100
100
  | `hyv_analyze` | hybrid local + server analysis (paid when online) |
101
101
  | `hyv_clean` | scan → fix → validate → rewrite prompt |
102
102
  | `hyv_fix` / `hyv_check` / `hyv_score` / `hyv_diff` | local utilities |
@@ -209,6 +209,10 @@ HYV_API_URL=https://staging.holdyourvoice.com hyv init
209
209
  - [blog](https://holdyourvoice.com/blog)
210
210
  - [community](https://holdyourvoice.com/community)
211
211
 
212
+ ## documentation ownership
213
+
214
+ Changes under `cli/` update this README, the more-specific owner README when applicable, and the root repository README. Package-relative paths, bin names, published files, and postinstall behavior are contracts; validate them with `npm run validate:publish` before merging.
215
+
212
216
  ## license
213
217
 
214
218
  UNLICENSED — [holdyourvoice.com](https://holdyourvoice.com)
@@ -0,0 +1,20 @@
1
+ # `cli/agents/`
2
+
3
+ ## Purpose
4
+
5
+ `cli/agents/` contains agent resources included in the published CLI package.
6
+
7
+ ## Contracts
8
+
9
+ The directory is included by the `files` list in `cli/package.json`. Changes must preserve package inclusion and postinstall discovery behavior.
10
+
11
+ ## Validation
12
+
13
+ ```bash
14
+ cd cli
15
+ npm run validate:publish
16
+ ```
17
+
18
+ ## Documentation ownership
19
+
20
+ Changes update this README, `cli/README.md`, and the root `README.md`.
@@ -0,0 +1,20 @@
1
+ # `cli/assets/`
2
+
3
+ ## Purpose
4
+
5
+ `cli/assets/` contains assets included in the published CLI package.
6
+
7
+ ## Contracts
8
+
9
+ The directory is included by the `files` list in `cli/package.json`. Keep package paths and postinstall consumers intact.
10
+
11
+ ## Validation
12
+
13
+ ```bash
14
+ cd cli
15
+ npm run validate:publish
16
+ ```
17
+
18
+ ## Documentation ownership
19
+
20
+ Changes update this README, `cli/README.md`, and the root `README.md`.
package/dist/index.js CHANGED
@@ -16662,7 +16662,9 @@ function buildRewritePrompt(options) {
16662
16662
  const template = loadPromptTemplate();
16663
16663
  const prompt = template.replace("{profile_block}", profileBlock).replace("{constraints_block}", constraints || "(none)").replace("{tier_one_lines}", tierOneLines).replace("{other_lines}", otherLines).replace("{draft_name}", draftPath).replace("{numbered_draft}", numberedDraft);
16664
16664
  return {
16665
- prompt,
16665
+ prompt: skipScan ? `${prompt}
16666
+
16667
+ none found by deterministic scan` : prompt,
16666
16668
  profileUsed,
16667
16669
  issuesFound: issues.length
16668
16670
  };
@@ -17938,6 +17940,7 @@ var MCP_SERVER_ARGS = ["mcp", "--stdio"];
17938
17940
  // src/lib/cli-entry.ts
17939
17941
  function resolveCliEntry() {
17940
17942
  const candidates = [
17943
+ typeof __filename !== "undefined" ? path17.resolve(__filename) : "",
17941
17944
  path17.resolve(process.argv[1] || ""),
17942
17945
  path17.resolve(__dirname, "index.js"),
17943
17946
  path17.resolve(__dirname, "..", "dist", "index.js")
@@ -17949,7 +17952,7 @@ function mcpServerCommand() {
17949
17952
  if (entry) {
17950
17953
  return { command: process.execPath, args: [entry, ...MCP_SERVER_ARGS] };
17951
17954
  }
17952
- return { command: "hyv", args: [...MCP_SERVER_ARGS] };
17955
+ throw new Error("could not resolve hyv CLI entry \u2014 reinstall @holdyourvoice/hyv or run via node dist/index.js");
17953
17956
  }
17954
17957
  function mcpServerSnippet() {
17955
17958
  const { command, args: args2 } = mcpServerCommand();
@@ -19827,6 +19830,10 @@ async function resolveProfile(slug) {
19827
19830
  }
19828
19831
  return profile;
19829
19832
  }
19833
+ async function loadLocalProfileForTool(slug) {
19834
+ void ensureMcpProfilesHydrated();
19835
+ return loadProfileForCommand(slug);
19836
+ }
19830
19837
  function jsonRpcOk(id, result) {
19831
19838
  return JSON.stringify({ jsonrpc: "2.0", id, result });
19832
19839
  }
@@ -19884,7 +19891,7 @@ async function toolScan(args2) {
19884
19891
  return "Error: no text or file provided";
19885
19892
  try {
19886
19893
  let scanText2 = text;
19887
- const profile = await resolveProfile(args2.profile);
19894
+ const profile = await loadLocalProfileForTool(args2.profile);
19888
19895
  if (filePath) {
19889
19896
  try {
19890
19897
  scanText2 = readScanFile(filePath);
@@ -19932,7 +19939,7 @@ async function toolValidate(args2) {
19932
19939
  if (!text.trim())
19933
19940
  return "Error: no text provided";
19934
19941
  try {
19935
- const profile = await resolveProfile(profileSlug);
19942
+ const profile = await loadLocalProfileForTool(profileSlug);
19936
19943
  if (!profile)
19937
19944
  return "Error: no voice profile available. Run hyv init or use hyv scan for free generic checks.";
19938
19945
  const result = validateRewrite(text, text, profile);
@@ -19955,7 +19962,7 @@ async function toolFix(args2) {
19955
19962
  if (!text.trim())
19956
19963
  return "Error: no text provided";
19957
19964
  try {
19958
- const profile = await resolveProfile(args2.profile);
19965
+ const profile = await loadLocalProfileForTool(args2.profile);
19959
19966
  const result = runPipeline(text, profile, true);
19960
19967
  if (result.changes.length === 0)
19961
19968
  return "No auto-fixable issues found.";
@@ -19974,7 +19981,7 @@ async function toolCheck(args2) {
19974
19981
  if (!text.trim())
19975
19982
  return "Error: no text provided";
19976
19983
  try {
19977
- const profile = await resolveProfile(args2.profile);
19984
+ const profile = await loadLocalProfileForTool(args2.profile);
19978
19985
  const result = runPipeline(text, profile, false);
19979
19986
  if (result.stats.totalSignals === 0)
19980
19987
  return `Clean \u2014 score: ${result.score}/100. No AI patterns found.`;
@@ -19992,7 +19999,7 @@ async function toolScore(args2) {
19992
19999
  if (!text.trim())
19993
20000
  return "Error: no text provided";
19994
20001
  try {
19995
- const profile = await resolveProfile(args2.profile);
20002
+ const profile = await loadLocalProfileForTool(args2.profile);
19996
20003
  const result = runPipeline(text, profile, false);
19997
20004
  return result.score.toString();
19998
20005
  } catch (err) {
@@ -20004,7 +20011,7 @@ async function toolDiff(args2) {
20004
20011
  if (!text.trim())
20005
20012
  return "Error: no text provided";
20006
20013
  try {
20007
- const profile = await resolveProfile(args2.profile);
20014
+ const profile = await loadLocalProfileForTool(args2.profile);
20008
20015
  const result = runPipeline(text, profile, true);
20009
20016
  if (result.changes.length === 0)
20010
20017
  return "No auto-fixable changes available.";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holdyourvoice/hyv",
3
- "version": "2.9.26",
3
+ "version": "2.9.27",
4
4
  "description": "Free local AI writing scan for cursor & claude. MCP server, 220+ pattern detection, voice profiles. npx @holdyourvoice/hyv welcome",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -0,0 +1,21 @@
1
+ # `cli/scripts/`
2
+
3
+ ## Purpose
4
+
5
+ `cli/scripts/` contains package install, publish validation, smoke-test, and supporting CLI scripts.
6
+
7
+ ## Contracts
8
+
9
+ Scripts are referenced by `cli/package.json` and the npm package `files` list. Package-relative paths must remain valid when the package is published.
10
+
11
+ ## Validation
12
+
13
+ ```bash
14
+ cd cli
15
+ npm run validate:publish
16
+ npm run test:smoke
17
+ ```
18
+
19
+ ## Documentation ownership
20
+
21
+ Changes under this folder update this README, `cli/README.md`, and the root `README.md`.
@@ -0,0 +1,20 @@
1
+ # `cli/skills/`
2
+
3
+ ## Purpose
4
+
5
+ `cli/skills/` contains skills included in the published CLI package.
6
+
7
+ ## Contracts
8
+
9
+ The directory is included by the `files` list in `cli/package.json`. Changes must preserve package inclusion and any postinstall or agent configuration paths that reference these files.
10
+
11
+ ## Validation
12
+
13
+ ```bash
14
+ cd cli
15
+ npm run validate:publish
16
+ ```
17
+
18
+ ## Documentation ownership
19
+
20
+ Changes update this README, `cli/README.md`, and the root `README.md`.