@holdyourvoice/hyv 2.4.0 → 2.4.2

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.
@@ -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
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ /**
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
+ */
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+
12
+ const home = os.homedir();
13
+ const isWin = process.platform === 'win32';
14
+ const pkgDir = path.resolve(__dirname, '..');
15
+
16
+ // Print branded message
17
+ console.log('');
18
+ console.log(' make your ai agent sound exactly like you!');
19
+ console.log('');
20
+ console.log(' to get started:');
21
+ console.log(' hyv init \u2192 sign in');
22
+ console.log(' hyv new my-voice \u2192 create your voice profile');
23
+ console.log('');
24
+ console.log(' first month is just $1.');
25
+ console.log('');
26
+
27
+ const configured = [];
28
+
29
+ // ── Claude Desktop ─────────────────────────────────────────────────────────
30
+ try {
31
+ const claudeDir = isWin
32
+ ? path.join(home, 'AppData', 'Roaming', 'Claude')
33
+ : path.join(home, 'Library', 'Application Support', 'Claude');
34
+ const configFile = path.join(claudeDir, 'claude_desktop_config.json');
35
+
36
+ if (fs.existsSync(claudeDir)) {
37
+ let config = {};
38
+ if (fs.existsSync(configFile)) {
39
+ try { config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); } catch {}
40
+ }
41
+ if (!config.mcpServers) config.mcpServers = {};
42
+ if (!config.mcpServers.hyv) {
43
+ config.mcpServers.hyv = { command: 'hyv', args: ['mcp'] };
44
+ fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
45
+ configured.push('claude desktop');
46
+ }
47
+ }
48
+ } catch {}
49
+
50
+ // ── Claude Code (global commands) ──────────────────────────────────────────
51
+ try {
52
+ const cmdDir = path.join(home, '.claude', 'commands');
53
+ if (fs.existsSync(path.dirname(cmdDir))) {
54
+ fs.mkdirSync(cmdDir, { recursive: true });
55
+ const cmdFile = path.join(cmdDir, 'hyv.md');
56
+ const src = path.join(pkgDir, 'agents', 'claude-code.md');
57
+ if (fs.existsSync(src) && !fs.existsSync(cmdFile)) {
58
+ fs.copyFileSync(src, cmdFile);
59
+ configured.push('claude code');
60
+ }
61
+ }
62
+ } catch {}
63
+
64
+ // ── Cursor (global rules) ─────────────────────────────────────────────────
65
+ try {
66
+ const cursorDir = path.join(home, '.cursor');
67
+ if (fs.existsSync(cursorDir)) {
68
+ const rulesFile = path.join(cursorDir, 'rules', 'hyv.md');
69
+ fs.mkdirSync(path.dirname(rulesFile), { recursive: true });
70
+ const src = path.join(pkgDir, 'agents', 'cursor.md');
71
+ if (fs.existsSync(src) && !fs.existsSync(rulesFile)) {
72
+ fs.copyFileSync(src, rulesFile);
73
+ configured.push('cursor');
74
+ }
75
+ }
76
+ } catch {}
77
+
78
+ // ── Windsurf (global rules) ───────────────────────────────────────────────
79
+ try {
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');
90
+ }
91
+ }
92
+ } catch {}
93
+
94
+ // ── ChatGPT (custom instructions file) ────────────────────────────────────
95
+ try {
96
+ const chatgptDir = path.join(home, '.chatgpt');
97
+ if (!fs.existsSync(chatgptDir)) fs.mkdirSync(chatgptDir, { recursive: true });
98
+ const instrFile = path.join(chatgptDir, 'hyv-instructions.txt');
99
+ const src = path.join(pkgDir, 'agents', 'chatgpt.md');
100
+ if (fs.existsSync(src) && !fs.existsSync(instrFile)) {
101
+ fs.copyFileSync(src, instrFile);
102
+ configured.push('chatgpt');
103
+ }
104
+ } catch {}
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
+
133
+ // ── Summary ───────────────────────────────────────────────────────────────
134
+ if (configured.length > 0) {
135
+ console.log(' \u2713 auto-configured: ' + configured.join(', '));
136
+ console.log('');
137
+ }