@holdyourvoice/hyv 2.7.1 → 2.8.0
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 +37 -0
- package/README.md +35 -7
- package/agents/chatgpt.md +6 -7
- package/agents/claude-code.md +7 -7
- package/agents/codex.md +8 -7
- package/agents/cursor.md +19 -10
- package/agents/generic.md +17 -18
- package/agents/windsurf.md +8 -8
- package/assets/detection-rules.json +18 -0
- package/dist/index.js +2832 -1234
- package/package.json +14 -6
- package/scripts/postinstall.js +61 -40
- package/scripts/hold_voice.py +0 -2013
- package/scripts/hold_voice_sync.py +0 -194
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdyourvoice/hyv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
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.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,11 +9,17 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --format=cjs --banner:js='#!/usr/bin/env node'",
|
|
12
|
+
"build:debug": "esbuild src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --format=cjs --sourcemap --banner:js='#!/usr/bin/env node'",
|
|
12
13
|
"dev": "npm run build && node dist/index.js",
|
|
13
|
-
"
|
|
14
|
+
"validate:publish": "npm run build && node scripts/validate-publish.js",
|
|
15
|
+
"prepublishOnly": "npm run validate:publish",
|
|
14
16
|
"postinstall": "node scripts/postinstall.js",
|
|
15
17
|
"test": "vitest run",
|
|
16
|
-
"test:
|
|
18
|
+
"test:smoke": "npm run build && bash scripts/smoke-test.sh",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"release:patch": "npm version patch && npm publish --access public",
|
|
21
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
22
|
+
"release:major": "npm version major && npm publish --access public"
|
|
17
23
|
},
|
|
18
24
|
"keywords": [
|
|
19
25
|
"voice",
|
|
@@ -43,12 +49,14 @@
|
|
|
43
49
|
"node": ">=18"
|
|
44
50
|
},
|
|
45
51
|
"files": [
|
|
46
|
-
"dist",
|
|
47
|
-
"scripts/",
|
|
52
|
+
"dist/",
|
|
53
|
+
"scripts/postinstall.js",
|
|
54
|
+
"scripts/check-no-duplicates.js",
|
|
48
55
|
"assets/",
|
|
49
56
|
"skills/",
|
|
57
|
+
"agents/",
|
|
50
58
|
"README.md",
|
|
51
|
-
"
|
|
59
|
+
"CHANGELOG.md"
|
|
52
60
|
],
|
|
53
61
|
"repository": {
|
|
54
62
|
"type": "git",
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,28 +1,43 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* postinstall.js — auto-configure MCP + agent instructions after npm install.
|
|
4
|
-
*
|
|
5
|
-
* Configures: Claude Desktop, Claude Code, Cursor, Windsurf, ChatGPT
|
|
6
|
-
* Fails silently for apps that aren't installed.
|
|
7
4
|
*/
|
|
8
5
|
const fs = require('fs');
|
|
9
6
|
const path = require('path');
|
|
10
7
|
const os = require('os');
|
|
8
|
+
const readline = require('readline');
|
|
11
9
|
|
|
12
10
|
const home = os.homedir();
|
|
13
11
|
const isWin = process.platform === 'win32';
|
|
14
12
|
const pkgDir = path.resolve(__dirname, '..');
|
|
13
|
+
const quiet = process.env.HYV_POSTINSTALL_QUIET === '1' || process.argv.includes('--quiet');
|
|
14
|
+
const hyvDir = path.join(home, '.hyv');
|
|
15
|
+
const agentsMarker = path.join(hyvDir, 'agents-version.json');
|
|
16
|
+
const { readPkgVersion, copyAgent, writeAgentsMarker } = require('./postinstall-lib');
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
console.log(
|
|
25
|
-
|
|
18
|
+
const pkgVersion = readPkgVersion(pkgDir);
|
|
19
|
+
|
|
20
|
+
function installAgent(src, dest) {
|
|
21
|
+
const result = copyAgent(src, dest, agentsMarker, pkgVersion);
|
|
22
|
+
return result.copied;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function print(msg) {
|
|
26
|
+
if (!quiet) console.log(msg);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
print('');
|
|
30
|
+
print(' make your ai agent sound exactly like you!');
|
|
31
|
+
print(' ✓ Free local scan engine ready (works offline)');
|
|
32
|
+
print('');
|
|
33
|
+
print(' Try instantly:');
|
|
34
|
+
print(' hyv scan your-draft.md');
|
|
35
|
+
print(' hyv fix your-draft.md');
|
|
36
|
+
print(' hyv check "your text here"');
|
|
37
|
+
print(' npx @holdyourvoice/hyv welcome');
|
|
38
|
+
print('');
|
|
39
|
+
print(' Profiles + learning (paid power): hyv init');
|
|
40
|
+
print('');
|
|
26
41
|
|
|
27
42
|
const configured = [];
|
|
28
43
|
|
|
@@ -47,51 +62,40 @@ try {
|
|
|
47
62
|
}
|
|
48
63
|
} catch {}
|
|
49
64
|
|
|
50
|
-
// ── Claude Code
|
|
65
|
+
// ── Claude Code ──────────────────────────────────────────────────────────────
|
|
51
66
|
try {
|
|
52
67
|
const cmdDir = path.join(home, '.claude', 'commands');
|
|
53
68
|
if (fs.existsSync(path.dirname(cmdDir))) {
|
|
54
69
|
fs.mkdirSync(cmdDir, { recursive: true });
|
|
55
70
|
const cmdFile = path.join(cmdDir, 'hyv.md');
|
|
56
71
|
const src = path.join(pkgDir, 'agents', 'claude-code.md');
|
|
57
|
-
if (
|
|
58
|
-
fs.copyFileSync(src, cmdFile);
|
|
59
|
-
configured.push('claude code');
|
|
60
|
-
}
|
|
72
|
+
if (installAgent(src, cmdFile)) configured.push('claude code');
|
|
61
73
|
}
|
|
62
74
|
} catch {}
|
|
63
75
|
|
|
64
|
-
// ── Cursor
|
|
76
|
+
// ── Cursor ─────────────────────────────────────────────────────────────────
|
|
65
77
|
try {
|
|
66
78
|
const cursorDir = path.join(home, '.cursor');
|
|
67
79
|
if (fs.existsSync(cursorDir)) {
|
|
68
80
|
const rulesFile = path.join(cursorDir, 'rules', 'hyv.md');
|
|
69
81
|
fs.mkdirSync(path.dirname(rulesFile), { recursive: true });
|
|
70
82
|
const src = path.join(pkgDir, 'agents', 'cursor.md');
|
|
71
|
-
if (
|
|
72
|
-
fs.copyFileSync(src, rulesFile);
|
|
73
|
-
configured.push('cursor');
|
|
74
|
-
}
|
|
83
|
+
if (installAgent(src, rulesFile)) configured.push('cursor');
|
|
75
84
|
}
|
|
76
85
|
} catch {}
|
|
77
86
|
|
|
78
|
-
// ── Windsurf
|
|
87
|
+
// ── Windsurf ───────────────────────────────────────────────────────────────
|
|
79
88
|
try {
|
|
80
89
|
const wsDirs = [
|
|
81
|
-
isWin
|
|
82
|
-
|
|
83
|
-
: path.join(home, '.windsurf'),
|
|
84
|
-
isWin
|
|
85
|
-
? null
|
|
86
|
-
: path.join(home, 'Library', 'Application Support', 'Windsurf'),
|
|
90
|
+
isWin ? path.join(home, 'AppData', 'Roaming', 'Windsurf') : path.join(home, '.windsurf'),
|
|
91
|
+
isWin ? null : path.join(home, 'Library', 'Application Support', 'Windsurf'),
|
|
87
92
|
].filter(Boolean);
|
|
88
93
|
for (const wsDir of wsDirs) {
|
|
89
94
|
if (fs.existsSync(wsDir)) {
|
|
90
95
|
const rulesFile = path.join(wsDir, 'rules', 'hyv.md');
|
|
91
96
|
fs.mkdirSync(path.dirname(rulesFile), { recursive: true });
|
|
92
97
|
const src = path.join(pkgDir, 'agents', 'windsurf.md');
|
|
93
|
-
if (
|
|
94
|
-
fs.copyFileSync(src, rulesFile);
|
|
98
|
+
if (installAgent(src, rulesFile)) {
|
|
95
99
|
configured.push('windsurf');
|
|
96
100
|
break;
|
|
97
101
|
}
|
|
@@ -99,20 +103,37 @@ try {
|
|
|
99
103
|
}
|
|
100
104
|
} catch {}
|
|
101
105
|
|
|
102
|
-
// ── ChatGPT
|
|
106
|
+
// ── ChatGPT ──────────────────────────────────────────────────────────────────
|
|
103
107
|
try {
|
|
104
108
|
const chatgptDir = path.join(home, '.chatgpt');
|
|
105
109
|
if (!fs.existsSync(chatgptDir)) fs.mkdirSync(chatgptDir, { recursive: true });
|
|
106
110
|
const instrFile = path.join(chatgptDir, 'hyv-instructions.txt');
|
|
107
111
|
const src = path.join(pkgDir, 'agents', 'chatgpt.md');
|
|
108
|
-
if (
|
|
109
|
-
fs.copyFileSync(src, instrFile);
|
|
110
|
-
configured.push('chatgpt');
|
|
111
|
-
}
|
|
112
|
+
if (installAgent(src, instrFile)) configured.push('chatgpt');
|
|
112
113
|
} catch {}
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
writeAgentsMarker(hyvDir, pkgVersion);
|
|
116
|
+
|
|
115
117
|
if (configured.length > 0) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
print(' ✓ auto-configured: ' + configured.join(', '));
|
|
119
|
+
print('');
|
|
118
120
|
}
|
|
121
|
+
|
|
122
|
+
// Optional interactive demo (TTY only, non-quiet)
|
|
123
|
+
if (!quiet && process.stdin.isTTY) {
|
|
124
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
125
|
+
rl.question(' See quick free demo? (y/N) ', (answer) => {
|
|
126
|
+
rl.close();
|
|
127
|
+
if (answer.trim().toLowerCase() === 'y') {
|
|
128
|
+
try {
|
|
129
|
+
const { execSync } = require('child_process');
|
|
130
|
+
execSync('node "' + path.join(pkgDir, 'dist', 'index.js') + '" welcome', {
|
|
131
|
+
stdio: 'inherit',
|
|
132
|
+
env: process.env,
|
|
133
|
+
});
|
|
134
|
+
} catch {
|
|
135
|
+
print(' (run: hyv welcome)');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|