voicci 1.0.9 ā 1.0.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/package.json +1 -1
- package/scripts/postinstall.js +68 -76
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "voicci",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "AI-Powered Audiobook Generator for Claude Code, OpenCode & AI Code Editors. Convert books and PDFs to audiobooks using natural language.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cli/index.js",
|
package/scripts/postinstall.js
CHANGED
|
@@ -9,12 +9,13 @@ import { execFileSync } from 'child_process';
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = path.dirname(__filename);
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
// Skills use directory-based format: skills/<name>/SKILL.md
|
|
13
|
+
const SKILLS = [
|
|
14
|
+
{
|
|
15
|
+
dirName: 'voicci',
|
|
16
|
+
content: `---
|
|
17
|
+
name: voicci
|
|
18
|
+
description: "Voicci - AI audiobook generator. Use when the user wants to convert books, PDFs, or documents to audiobooks."
|
|
18
19
|
argument-hint: "COMMAND_OR_FILE"
|
|
19
20
|
---
|
|
20
21
|
|
|
@@ -33,10 +34,13 @@ Convert books, PDFs, and documents to audiobooks using AI text-to-speech.
|
|
|
33
34
|
#!/bin/bash
|
|
34
35
|
voicci $ARGUMENTS
|
|
35
36
|
\`\`\`
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
`
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
dirName: 'voicci-audiobook',
|
|
41
|
+
content: `---
|
|
42
|
+
name: voicci-audiobook
|
|
43
|
+
description: "Voicci - AI audiobook generator with full documentation. Use when the user needs detailed help with audiobook generation."
|
|
40
44
|
argument-hint: "COMMAND_OR_FILE"
|
|
41
45
|
---
|
|
42
46
|
|
|
@@ -101,7 +105,6 @@ voicci memory
|
|
|
101
105
|
|
|
102
106
|
\`\`\`!
|
|
103
107
|
#!/bin/bash
|
|
104
|
-
# Execute voicci with user-provided arguments
|
|
105
108
|
voicci $ARGUMENTS
|
|
106
109
|
\`\`\`
|
|
107
110
|
|
|
@@ -112,14 +115,9 @@ voicci $ARGUMENTS
|
|
|
112
115
|
- macOS: \`~/Library/Application Support/voicci/audiobooks/\`
|
|
113
116
|
- Linux: \`~/.local/share/voicci/audiobooks/\`
|
|
114
117
|
- Copyright warning will appear before first book search
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- \`/voicci-audiobook ~/Documents/book.pdf\` - Convert local file
|
|
119
|
-
- \`/voicci-audiobook -s\` - Check all job statuses
|
|
120
|
-
- \`/voicci-audiobook summary book.pdf\` - Generate summary only
|
|
121
|
-
- \`/voicci-audiobook --help\` - Show all options
|
|
122
|
-
`;
|
|
118
|
+
`
|
|
119
|
+
}
|
|
120
|
+
];
|
|
123
121
|
|
|
124
122
|
// Editor detection configurations
|
|
125
123
|
const EDITORS = {
|
|
@@ -127,7 +125,6 @@ const EDITORS = {
|
|
|
127
125
|
name: 'Claude Code',
|
|
128
126
|
detect: () => {
|
|
129
127
|
const homeDir = os.homedir();
|
|
130
|
-
// Check for claude command or .claude directory
|
|
131
128
|
if (fs.existsSync(path.join(homeDir, '.claude'))) return true;
|
|
132
129
|
try {
|
|
133
130
|
execFileSync('which', ['claude'], { stdio: 'ignore' });
|
|
@@ -136,11 +133,7 @@ const EDITORS = {
|
|
|
136
133
|
return false;
|
|
137
134
|
}
|
|
138
135
|
},
|
|
139
|
-
|
|
140
|
-
skillsDirs: () => [
|
|
141
|
-
path.join(os.homedir(), '.claude', 'commands'),
|
|
142
|
-
path.join(os.homedir(), '.claude', 'skills')
|
|
143
|
-
]
|
|
136
|
+
skillsDir: () => path.join(os.homedir(), '.claude', 'skills')
|
|
144
137
|
},
|
|
145
138
|
'OpenCode': {
|
|
146
139
|
name: 'OpenCode',
|
|
@@ -154,7 +147,7 @@ const EDITORS = {
|
|
|
154
147
|
return false;
|
|
155
148
|
}
|
|
156
149
|
},
|
|
157
|
-
|
|
150
|
+
skillsDir: () => path.join(os.homedir(), '.opencode', 'skills')
|
|
158
151
|
},
|
|
159
152
|
'Cursor': {
|
|
160
153
|
name: 'Cursor',
|
|
@@ -169,17 +162,16 @@ const EDITORS = {
|
|
|
169
162
|
return false;
|
|
170
163
|
}
|
|
171
164
|
},
|
|
172
|
-
|
|
165
|
+
skillsDir: () => {
|
|
173
166
|
const homeDir = os.homedir();
|
|
174
167
|
const locations = [
|
|
175
168
|
path.join(homeDir, '.cursor', 'skills'),
|
|
176
169
|
path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'skills')
|
|
177
170
|
];
|
|
178
171
|
for (const loc of locations) {
|
|
179
|
-
|
|
180
|
-
if (fs.existsSync(parent)) return [loc];
|
|
172
|
+
if (fs.existsSync(path.dirname(loc))) return loc;
|
|
181
173
|
}
|
|
182
|
-
return
|
|
174
|
+
return locations[0];
|
|
183
175
|
}
|
|
184
176
|
},
|
|
185
177
|
'Windsurf': {
|
|
@@ -194,64 +186,65 @@ const EDITORS = {
|
|
|
194
186
|
return false;
|
|
195
187
|
}
|
|
196
188
|
},
|
|
197
|
-
|
|
189
|
+
skillsDir: () => path.join(os.homedir(), '.windsurf', 'skills')
|
|
198
190
|
}
|
|
199
191
|
};
|
|
200
192
|
|
|
201
|
-
function
|
|
202
|
-
const
|
|
203
|
-
|
|
193
|
+
function installSkill(skillsDir, skill) {
|
|
194
|
+
const skillDir = path.join(skillsDir, skill.dirName);
|
|
195
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
196
|
+
|
|
204
197
|
// Check if already installed
|
|
205
198
|
if (fs.existsSync(skillFile)) {
|
|
206
199
|
const existingContent = fs.readFileSync(skillFile, 'utf8');
|
|
207
|
-
if (existingContent.includes('voicci
|
|
200
|
+
if (existingContent.includes('voicci')) {
|
|
208
201
|
return 'exists';
|
|
209
202
|
}
|
|
210
203
|
}
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
fs.
|
|
204
|
+
|
|
205
|
+
// Create skill directory and write SKILL.md
|
|
206
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
207
|
+
fs.writeFileSync(skillFile, skill.content, 'utf8');
|
|
208
|
+
|
|
209
|
+
// Clean up legacy flat file if it exists
|
|
210
|
+
const legacyFile = path.join(skillsDir, `${skill.dirName}.md`);
|
|
211
|
+
if (fs.existsSync(legacyFile)) {
|
|
212
|
+
fs.unlinkSync(legacyFile);
|
|
213
|
+
}
|
|
214
|
+
|
|
214
215
|
return 'new';
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
function detectAndInstall() {
|
|
218
|
-
const homeDir = os.homedir();
|
|
219
219
|
const installedEditors = [];
|
|
220
220
|
const failedEditors = [];
|
|
221
221
|
|
|
222
|
-
console.log('
|
|
222
|
+
console.log('Detecting AI code editors...\n');
|
|
223
223
|
|
|
224
|
-
// Detect and install for each editor
|
|
225
224
|
for (const [key, editor] of Object.entries(EDITORS)) {
|
|
226
225
|
try {
|
|
227
226
|
if (editor.detect()) {
|
|
228
|
-
console.log(
|
|
227
|
+
console.log(` Found ${editor.name}`);
|
|
229
228
|
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
let anyNew = false;
|
|
233
|
-
let allExist = true;
|
|
229
|
+
const skillsDir = editor.skillsDir();
|
|
234
230
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
231
|
+
// Create skills directory if needed
|
|
232
|
+
if (!fs.existsSync(skillsDir)) {
|
|
233
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
234
|
+
}
|
|
240
235
|
|
|
241
|
-
|
|
242
|
-
const simpleStatus = installSkillFile(skillsDir, SKILL_NAME_SIMPLE, SKILL_CONTENT_SIMPLE);
|
|
243
|
-
const detailedStatus = installSkillFile(skillsDir, SKILL_NAME_DETAILED, SKILL_CONTENT_DETAILED);
|
|
236
|
+
let anyNew = false;
|
|
244
237
|
|
|
245
|
-
|
|
238
|
+
for (const skill of SKILLS) {
|
|
239
|
+
const status = installSkill(skillsDir, skill);
|
|
240
|
+
if (status === 'new') {
|
|
246
241
|
anyNew = true;
|
|
247
|
-
|
|
248
|
-
if (simpleStatus === 'new') console.log(` ā³ Installed: ${path.join(skillsDir, SKILL_NAME_SIMPLE)}`);
|
|
249
|
-
if (detailedStatus === 'new') console.log(` ā³ Installed: ${path.join(skillsDir, SKILL_NAME_DETAILED)}`);
|
|
242
|
+
console.log(` Installed: ${path.join(skillsDir, skill.dirName, 'SKILL.md')}`);
|
|
250
243
|
}
|
|
251
244
|
}
|
|
252
245
|
|
|
253
246
|
if (!anyNew) {
|
|
254
|
-
console.log(`
|
|
247
|
+
console.log(` Skills already installed`);
|
|
255
248
|
installedEditors.push({ name: editor.name, status: 'exists' });
|
|
256
249
|
} else {
|
|
257
250
|
installedEditors.push({ name: editor.name, status: 'new' });
|
|
@@ -263,37 +256,36 @@ function detectAndInstall() {
|
|
|
263
256
|
}
|
|
264
257
|
|
|
265
258
|
// Summary
|
|
266
|
-
console.log('\n' + '
|
|
259
|
+
console.log('\n' + '='.repeat(60));
|
|
267
260
|
|
|
268
261
|
if (installedEditors.length > 0) {
|
|
269
|
-
console.log('\
|
|
270
|
-
console.log('\n
|
|
271
|
-
console.log('
|
|
272
|
-
console.log('\n
|
|
262
|
+
console.log('\nVoicci CLI installed successfully!');
|
|
263
|
+
console.log('\n Command-line tool: voicci');
|
|
264
|
+
console.log(' Skill commands: /voicci OR /voicci-audiobook');
|
|
265
|
+
console.log('\n Installed in:');
|
|
273
266
|
installedEditors.forEach(editor => {
|
|
274
267
|
const status = editor.status === 'new' ? '(new)' : '(already installed)';
|
|
275
|
-
console.log(`
|
|
268
|
+
console.log(` ${editor.name} ${status}`);
|
|
276
269
|
});
|
|
277
270
|
|
|
278
|
-
console.log('\n
|
|
279
|
-
console.log('
|
|
280
|
-
console.log('
|
|
281
|
-
console.log('
|
|
282
|
-
console.log(' 4. Or CLI: voicci "your search query"');
|
|
271
|
+
console.log('\n Usage:');
|
|
272
|
+
console.log(' 1. Restart your AI code editor');
|
|
273
|
+
console.log(' 2. Type: /voicci "search query"');
|
|
274
|
+
console.log(' 3. Or CLI: voicci "your search query"');
|
|
283
275
|
} else {
|
|
284
|
-
console.log('\n
|
|
285
|
-
console.log('\
|
|
286
|
-
console.log('\n
|
|
276
|
+
console.log('\n No supported AI code editors detected');
|
|
277
|
+
console.log('\n Supported editors: Claude Code, OpenCode, Cursor, Windsurf');
|
|
278
|
+
console.log('\n You can still use the CLI: voicci <command>');
|
|
287
279
|
}
|
|
288
280
|
|
|
289
281
|
if (failedEditors.length > 0) {
|
|
290
|
-
console.log('\n
|
|
282
|
+
console.log('\n Failed to install for:');
|
|
291
283
|
failedEditors.forEach(({ name, error }) => {
|
|
292
|
-
console.log(`
|
|
284
|
+
console.log(` ${name}: ${error}`);
|
|
293
285
|
});
|
|
294
286
|
}
|
|
295
287
|
|
|
296
|
-
console.log('\n' + '
|
|
288
|
+
console.log('\n' + '='.repeat(60));
|
|
297
289
|
console.log();
|
|
298
290
|
}
|
|
299
291
|
|