whatsapp-group-summary 1.0.0 → 1.0.1

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.
Files changed (3) hide show
  1. package/README.md +5 -5
  2. package/install.js +179 -30
  3. package/package.json +8 -2
package/README.md CHANGED
@@ -136,13 +136,13 @@
136
136
  ### Step 1: Install Skill
137
137
 
138
138
  ```bash
139
- # Via npx (recommended)
140
- npx github:mocasus/whatsapp-group-summary
139
+ # ⚔ npx (recommended)
140
+ npx whatsapp-group-summary
141
141
 
142
- # Atau via hermes skills install
143
- hermes skills install https://raw.githubusercontent.com/mocasus/whatsapp-group-summary/main/SKILL.md
142
+ # šŸŽÆ Via Hermes CLI
143
+ hermes skills install whatsapp-group-summary
144
144
 
145
- # Atau manual git clone
145
+ # šŸ“¦ Manual git clone
146
146
  git clone https://github.com/mocasus/whatsapp-group-summary.git ~/.hermes/skills/whatsapp-group-summary-bot
147
147
  ```
148
148
 
package/install.js CHANGED
@@ -1,59 +1,208 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * WhatsApp Group Summary Bot — Installer
3
+ * WhatsApp Group Summary Bot — One-Command Installer
4
4
  *
5
5
  * Usage: npx whatsapp-group-summary
6
6
  *
7
- * Copies the skill to ~/.hermes/skills/whatsapp-group-summary-bot
7
+ * Installs the skill, validates Hermes setup, and guides through configuration.
8
8
  */
9
9
 
10
10
  const fs = require('fs');
11
11
  const path = require('path');
12
+ const os = require('os');
12
13
  const { execSync } = require('child_process');
13
14
 
15
+ // ── Config ──────────────────────────────────────────────
14
16
  const SKILL_NAME = 'whatsapp-group-summary-bot';
15
- const HERMES_HOME = process.env.HERMES_HOME || path.join(require('os').homedir(), '.hermes');
16
- const TARGET_DIR = path.join(HERMES_HOME, 'skills', SKILL_NAME);
17
+ const HERMES_HOME = process.env.HERMES_HOME || path.join(os.homedir(), '.hermes');
18
+ const SKILLS_DIR = path.join(HERMES_HOME, 'skills');
19
+ const TARGET_DIR = path.join(SKILLS_DIR, SKILL_NAME);
20
+ const HERMES_SRC = path.join(HERMES_HOME, 'hermes-agent');
17
21
  const REPO_URL = 'https://github.com/mocasus/whatsapp-group-summary.git';
22
+ const NPM_URL = 'https://www.npmjs.com/package/whatsapp-group-summary';
18
23
 
19
- console.log('šŸ¤– WhatsApp Group Summary Bot — Installer');
20
- console.log(` Target: ${TARGET_DIR}\n`);
24
+ // Colors
25
+ const c = { r: '\x1b[0m', g: '\x1b[32m', y: '\x1b[33m', b: '\x1b[34m', m: '\x1b[35m', w: '\x1b[37m', dim: '\x1b[2m' };
26
+ const ok = s => `${c.g}āœ… ${s}${c.r}`;
27
+ const warn = s => `${c.y}āš ļø ${s}${c.r}`;
28
+ const info = s => `${c.b}ā„¹ļø ${s}${c.r}`;
29
+ const title = s => `${c.m}${s}${c.r}`;
30
+ const cmd = s => `${c.dim} $ ${s}${c.r}`;
21
31
 
22
- if (fs.existsSync(TARGET_DIR)) {
23
- console.log('āš ļø Skill already exists. Updating...');
32
+ // ── Helpers ─────────────────────────────────────────────
33
+ function run(cmd, opts = {}) {
24
34
  try {
25
- execSync(`git -C "${TARGET_DIR}" pull`, { stdio: 'inherit' });
26
- console.log('āœ… Updated successfully!');
35
+ return execSync(cmd, { stdio: opts.silent ? 'pipe' : 'inherit', ...opts });
36
+ } catch { return null; }
37
+ }
38
+
39
+ function exists(p) { return fs.existsSync(p); }
40
+
41
+ // ── Banner ──────────────────────────────────────────────
42
+ console.log('');
43
+ console.log(title('šŸ¤– WhatsApp Group Summary Bot'));
44
+ console.log(title(' for Hermes Agent'));
45
+ console.log(c.dim + ` ${NPM_URL}` + c.r);
46
+ console.log('');
47
+
48
+ // ── Step 0: Check Hermes ────────────────────────────────
49
+ console.log(info('Checking Hermes installation...'));
50
+
51
+ const hermesBin = run('which hermes', { silent: true });
52
+ if (!hermesBin) {
53
+ console.log(warn('Hermes CLI not found. Install it first:'));
54
+ console.log(cmd('curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash'));
55
+ process.exit(1);
56
+ }
57
+ console.log(ok(`Hermes found at ${hermesBin.toString().trim()}`));
58
+
59
+ // Check if WhatsApp gateway is configured
60
+ const hermesHomeExists = exists(HERMES_HOME);
61
+ if (!hermesHomeExists) {
62
+ console.log(warn(`Hermes home not found at ${HERMES_HOME}`));
63
+ }
64
+
65
+ // ── Step 1: Install Skill ───────────────────────────────
66
+ console.log(`\n${info}Installing ${SKILL_NAME}...`);
67
+
68
+ fs.mkdirSync(SKILLS_DIR, { recursive: true });
69
+
70
+ if (exists(TARGET_DIR)) {
71
+ console.log(warn('Existing installation found. Updating...'));
72
+ try {
73
+ run(`git -C "${TARGET_DIR}" pull`, { silent: true });
74
+ console.log(ok('Updated to latest version'));
27
75
  } catch {
28
- console.log('āš ļø Git pull failed. Re-cloning...');
76
+ console.log(warn('Git pull failed. Reinstalling...'));
29
77
  fs.rmSync(TARGET_DIR, { recursive: true, force: true });
30
78
  }
31
79
  }
32
80
 
33
- if (!fs.existsSync(TARGET_DIR)) {
34
- console.log('šŸ“¦ Cloning skill...');
81
+ if (!exists(TARGET_DIR)) {
35
82
  try {
36
- execSync(`git clone "${REPO_URL}" "${TARGET_DIR}"`, { stdio: 'inherit' });
37
- console.log('āœ… Skill installed!');
38
- } catch (e) {
39
- console.error('āŒ Failed to clone. Trying manual copy...');
83
+ run(`git clone "${REPO_URL}" "${TARGET_DIR}"`, { silent: true });
84
+ console.log(ok('Cloned from GitHub'));
85
+ } catch {
86
+ // Fallback: copy from npm package
87
+ const srcDir = __dirname;
40
88
  fs.mkdirSync(TARGET_DIR, { recursive: true });
41
- const sourceDir = path.join(__dirname, '..');
42
- const files = fs.readdirSync(sourceDir);
89
+ const files = fs.readdirSync(srcDir);
43
90
  for (const file of files) {
44
- if (file === 'node_modules' || file === '.git' || file === 'package.json') continue;
45
- const src = path.join(sourceDir, file);
91
+ if (['node_modules', '.git', 'package.json', 'install.js'].includes(file)) continue;
92
+ const src = path.join(srcDir, file);
46
93
  const dest = path.join(TARGET_DIR, file);
47
- fs.cpSync(src, dest, { recursive: true });
94
+ if (fs.statSync(src).isDirectory()) {
95
+ fs.cpSync(src, dest, { recursive: true });
96
+ } else {
97
+ fs.copyFileSync(src, dest);
98
+ }
48
99
  }
49
- console.log('āœ… Skill installed (manual copy)!');
100
+ console.log(ok('Installed from package (offline mode)'));
101
+ }
102
+ }
103
+
104
+ // Remove .git to keep it clean
105
+ const gitDir = path.join(TARGET_DIR, '.git');
106
+ if (exists(gitDir)) fs.rmSync(gitDir, { recursive: true, force: true });
107
+
108
+ console.log(ok(`Skill installed at ${TARGET_DIR}`));
109
+
110
+ // ── Step 2: Check Patches ───────────────────────────────
111
+ console.log(`\n${info}Checking source patches...`);
112
+
113
+ const patches = {
114
+ bridge: {
115
+ file: path.join(HERMES_SRC, 'scripts', 'whatsapp-bridge', 'bridge.js'),
116
+ check: (content) => content.includes('!isGroup && WHATSAPP_DM_POLICY'),
117
+ desc: 'Bridge group allowlist bypass',
118
+ },
119
+ adapter: {
120
+ file: path.join(HERMES_SRC, 'gateway', 'platforms', 'whatsapp_common.py'),
121
+ check: (content) => content.includes('patched — allowlist check skipped for groups'),
122
+ desc: 'Adapter group allowlist bypass',
123
+ },
124
+ recorder: {
125
+ file: path.join(HERMES_SRC, 'plugins', 'platforms', 'whatsapp', 'adapter.py'),
126
+ check: (content) => content.includes('_record_group_message_sync'),
127
+ desc: 'Silent group message recorder',
128
+ },
129
+ };
130
+
131
+ let patchesOk = 0;
132
+ let patchesMissing = 0;
133
+
134
+ for (const [key, patch] of Object.entries(patches)) {
135
+ if (!exists(patch.file)) {
136
+ console.log(` ${warn('?')} ${patch.desc}: file not found (${path.relative(HERMES_HOME, patch.file)})`);
137
+ continue;
50
138
  }
139
+ const content = fs.readFileSync(patch.file, 'utf8');
140
+ if (patch.check(content)) {
141
+ patchesOk++;
142
+ console.log(` ${ok('āœ“')} ${patch.desc}`);
143
+ } else {
144
+ patchesMissing++;
145
+ console.log(` ${warn('āœ—')} ${patch.desc} — NEEDS PATCH`);
146
+ }
147
+ }
148
+
149
+ // ── Step 3: Check Env ───────────────────────────────────
150
+ console.log(`\n${info}Checking environment config...`);
151
+ const envFile = path.join(HERMES_HOME, '.env');
152
+ let mentionSet = false;
153
+ if (exists(envFile)) {
154
+ const envContent = fs.readFileSync(envFile, 'utf8');
155
+ mentionSet = /WHATSAPP_REQUIRE_MENTION\s*=\s*true/i.test(envContent);
156
+ }
157
+
158
+ if (mentionSet) {
159
+ console.log(ok('WHATSAPP_REQUIRE_MENTION=true'));
160
+ } else {
161
+ console.log(warn('WHATSAPP_REQUIRE_MENTION=true not set'));
162
+ }
163
+
164
+ // ── Summary & Next Steps ────────────────────────────────
165
+ console.log(`\n${'─'.repeat(50)}`);
166
+ console.log(title('šŸ“‹ Next Steps'));
167
+ console.log(`${'─'.repeat(50)}\n`);
168
+
169
+ const steps = [];
170
+
171
+ if (patchesMissing > 0) {
172
+ steps.push('1. Apply source patches:');
173
+ steps.push(' See README for detailed diff instructions');
174
+ steps.push(` ${cmd}cat ${path.join(TARGET_DIR, 'README.md')}`);
175
+ steps.push('');
176
+ }
177
+
178
+ if (!mentionSet) {
179
+ steps.push('2. Set environment variable:');
180
+ steps.push(' Add to Hermes env config:');
181
+ steps.push(` WHATSAPP_REQUIRE_MENTION=true`);
182
+ steps.push('');
51
183
  }
52
184
 
53
- console.log('\nšŸ“‹ Next steps:');
54
- console.log(' 1. Apply 3 source patches (see README)');
55
- console.log(' 2. Set WHATSAPP_REQUIRE_MENTION=true in Hermes env');
56
- console.log(' 3. Restart gateway: hermes gateway restart');
57
- console.log(' 4. Tag @Hermes in group: "apa id grup ini?"');
58
- console.log(' 5. Setup 2 cron jobs (morning 07:00 + evening 23:00 WIB)');
59
- console.log('\n Full guide: https://github.com/mocasus/whatsapp-group-summary');
185
+ steps.push(`${patchesMissing > 0 ? '3' : '1'}. Restart gateway:`);
186
+ steps.push(` ${cmd}hermes gateway restart`);
187
+ steps.push(' (Must run from separate SSH terminal)');
188
+ steps.push('');
189
+ steps.push(`${patchesMissing > 0 ? '4' : '2'}. Get group ID:`);
190
+ steps.push(' Tag @Hermes in your WhatsApp group: "apa id grup ini?"');
191
+ steps.push('');
192
+ steps.push(`${patchesMissing > 0 ? '5' : '3'}. Setup cron jobs:`);
193
+ steps.push(' Morning: 0 0 * * * (07:00 WIB)');
194
+ steps.push(' Evening: 0 16 * * * (23:00 WIB)');
195
+ steps.push(` Prompt: ${cmd}cat ${path.join(TARGET_DIR, 'SKILL.md')}`);
196
+ steps.push('');
197
+
198
+ for (const s of steps) console.log(` ${s}`);
199
+
200
+ console.log(title('šŸ“– Full Guide'));
201
+ console.log(` ${c.dim}https://github.com/mocasus/whatsapp-group-summary${c.r}`);
202
+ console.log('');
203
+
204
+ if (patchesMissing > 0) {
205
+ console.log(warn(`${patchesMissing} patch(es) need to be applied before recording works.`));
206
+ } else {
207
+ console.log(ok('All patches detected! Recording should work after restart.'));
208
+ }
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "whatsapp-group-summary",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "WhatsApp group chat summary bot for Hermes Agent — record all messages silently, auto-summarize 2x daily",
5
5
  "main": "install.js",
6
6
  "bin": {
7
7
  "whatsapp-group-summary": "./install.js"
8
8
  },
9
- "keywords": ["hermes-agent", "whatsapp", "summary", "group-chat", "bot"],
9
+ "keywords": [
10
+ "hermes-agent",
11
+ "whatsapp",
12
+ "summary",
13
+ "group-chat",
14
+ "bot"
15
+ ],
10
16
  "author": "mocasus",
11
17
  "license": "MIT",
12
18
  "repository": {