vipcare 0.3.18 → 0.3.20
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/CLAUDE.md +2 -2
- package/README.md +1 -1
- package/bin/vip.js +29 -10
- package/lib/config.js +1 -1
- package/lib/scheduler.js +2 -2
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -12,7 +12,7 @@ CLI tool that auto-builds VIP person profiles from Twitter, LinkedIn, and web se
|
|
|
12
12
|
```
|
|
13
13
|
bin/vip.js — CLI entry point, all command definitions
|
|
14
14
|
lib/
|
|
15
|
-
config.js — Config loading (~/.vip
|
|
15
|
+
config.js — Config loading (~/.vip/config.json), tool checks
|
|
16
16
|
profile.js — CRUD for profile Markdown files in profiles/
|
|
17
17
|
resolver.js — Parse input (name vs URL) into person object
|
|
18
18
|
fetchers/
|
|
@@ -43,7 +43,7 @@ Input flows through a pipeline: **resolver** parses the input (name or URL) into
|
|
|
43
43
|
- ESM modules (`"type": "module"` in package.json)
|
|
44
44
|
- Tests use node:test built-in runner with assert
|
|
45
45
|
- Profile data stored as Markdown files in profiles/
|
|
46
|
-
- Config at ~/.vip
|
|
46
|
+
- Config at ~/.vip/config.json
|
|
47
47
|
- AI backends: Claude CLI, Anthropic API, GitHub Copilot (auto-detected in that order)
|
|
48
48
|
|
|
49
49
|
## Adding a New Command
|
package/README.md
CHANGED
package/bin/vip.js
CHANGED
|
@@ -475,15 +475,20 @@ program.command('youtube-search')
|
|
|
475
475
|
// --- card ---
|
|
476
476
|
program.command('card')
|
|
477
477
|
.description('Generate and serve H5 baseball card page')
|
|
478
|
-
.option('-o, --output <path>', 'Output HTML file', '
|
|
478
|
+
.option('-o, --output <path>', 'Output HTML file', path.join(os.homedir(), '.vip', 'cards', 'index.html'))
|
|
479
479
|
.option('-p, --port <port>', 'Server port', '3000')
|
|
480
|
+
.option('-w, --watch', 'Watch profile files and auto-regenerate')
|
|
480
481
|
.option('--no-serve', 'Only generate, do not start server')
|
|
481
482
|
.action(async (opts) => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
483
|
+
function regenerate() {
|
|
484
|
+
const profiles = listProfiles();
|
|
485
|
+
if (!profiles.length) return null;
|
|
486
|
+
return generateCards(profiles, opts.output);
|
|
487
|
+
}
|
|
485
488
|
|
|
486
|
-
|
|
489
|
+
console.log(c.cyan('Generating baseball cards...'));
|
|
490
|
+
const outputPath = regenerate();
|
|
491
|
+
if (!outputPath) { console.log(c.dim('No profiles. Use "vip add" first.')); return; }
|
|
487
492
|
console.log(c.green(`Cards generated: ${outputPath}`));
|
|
488
493
|
|
|
489
494
|
if (opts.serve === false) {
|
|
@@ -508,8 +513,20 @@ program.command('card')
|
|
|
508
513
|
server.listen(port, () => {
|
|
509
514
|
const url = `http://localhost:${port}`;
|
|
510
515
|
console.log(c.green(`\nServer running at ${c.bold(url)}`));
|
|
516
|
+
|
|
517
|
+
// Watch profiles dir for changes
|
|
518
|
+
if (opts.watch) {
|
|
519
|
+
const profilesDir = getProfilesDir();
|
|
520
|
+
console.log(c.dim(`Watching ${profilesDir} for changes...`));
|
|
521
|
+
fs.watch(profilesDir, { recursive: false }, (event, filename) => {
|
|
522
|
+
if (!filename?.endsWith('.md')) return;
|
|
523
|
+
console.log(c.dim(` ${filename} changed, regenerating...`));
|
|
524
|
+
regenerate();
|
|
525
|
+
});
|
|
526
|
+
console.log(c.dim('Edit a .md profile file and the cards will auto-update.'));
|
|
527
|
+
}
|
|
528
|
+
|
|
511
529
|
console.log(c.dim('Press Ctrl+C to stop\n'));
|
|
512
|
-
// Auto-open in browser
|
|
513
530
|
try { execFileSync('open', [url], { stdio: 'ignore' }); } catch {}
|
|
514
531
|
});
|
|
515
532
|
});
|
|
@@ -799,7 +816,7 @@ program.command('reset')
|
|
|
799
816
|
}
|
|
800
817
|
|
|
801
818
|
// Delete generated web files
|
|
802
|
-
const webDir = path.join(
|
|
819
|
+
const webDir = path.join(CONFIG_DIR, 'cards');
|
|
803
820
|
if (fs.existsSync(webDir)) {
|
|
804
821
|
const webFiles = fs.readdirSync(webDir).filter(f => f.endsWith('.html'));
|
|
805
822
|
for (const f of webFiles) fs.unlinkSync(path.join(webDir, f));
|
|
@@ -867,9 +884,11 @@ program.command('init')
|
|
|
867
884
|
try {
|
|
868
885
|
console.log(c.bold(c.cyan('\nWelcome to VIPCare!\n')));
|
|
869
886
|
|
|
870
|
-
const
|
|
871
|
-
const
|
|
872
|
-
const
|
|
887
|
+
const defaultHome = path.join(os.homedir(), '.vip');
|
|
888
|
+
const homeAnswer = await rl.question(`VIPCare home directory (all data stored here):\n (default: ${defaultHome}) > `);
|
|
889
|
+
const homeDir = (homeAnswer.trim() || defaultHome).replace(/^~/, os.homedir());
|
|
890
|
+
|
|
891
|
+
const profilesDir = path.join(homeDir, 'profiles');
|
|
873
892
|
|
|
874
893
|
console.log(`\n${c.cyan('AI backend preference:')}`);
|
|
875
894
|
console.log(' 1. Claude CLI (recommended)');
|
package/lib/config.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import { execFileSync } from 'child_process';
|
|
5
5
|
|
|
6
|
-
const CONFIG_DIR = path.join(os.homedir(), '.vip
|
|
6
|
+
const CONFIG_DIR = path.join(os.homedir(), '.vip');
|
|
7
7
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
8
8
|
const CHANGELOG_FILE = path.join(CONFIG_DIR, 'changelog.jsonl');
|
|
9
9
|
|
package/lib/scheduler.js
CHANGED
|
@@ -4,7 +4,7 @@ import os from 'os';
|
|
|
4
4
|
import { execFileSync } from 'child_process';
|
|
5
5
|
import { loadConfig } from './config.js';
|
|
6
6
|
|
|
7
|
-
const PLIST_NAME = 'com.
|
|
7
|
+
const PLIST_NAME = 'com.vipcare.monitor';
|
|
8
8
|
const PLIST_PATH = path.join(os.homedir(), 'Library', 'LaunchAgents', `${PLIST_NAME}.plist`);
|
|
9
9
|
|
|
10
10
|
function getVipPath() {
|
|
@@ -31,7 +31,7 @@ export function createPlist(intervalHours) {
|
|
|
31
31
|
|
|
32
32
|
const vipPath = getVipPath();
|
|
33
33
|
const intervalSeconds = intervalHours * 3600;
|
|
34
|
-
const logDir = path.join(os.homedir(), '.vip
|
|
34
|
+
const logDir = path.join(os.homedir(), '.vip');
|
|
35
35
|
|
|
36
36
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
37
37
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|