@c4t4/heyamigo 0.1.2 → 0.1.4
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/dist/cli/service.js +19 -7
- package/dist/cli/setup.js +48 -58
- package/dist/cli/supervisor.js +4 -6
- package/package.json +1 -1
package/dist/cli/service.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { spawn, spawnSync } from 'child_process';
|
|
2
2
|
import { existsSync, mkdirSync, openSync, readFileSync, unlinkSync, writeFileSync, } from 'fs';
|
|
3
3
|
import { dirname, resolve } from 'path';
|
|
4
|
-
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __distCli = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
function findProjectDir() {
|
|
7
|
+
// Check cwd first, then common locations
|
|
8
|
+
const candidates = [
|
|
9
|
+
process.cwd(),
|
|
10
|
+
resolve(process.cwd(), 'heyamigo'),
|
|
11
|
+
resolve(process.env.HOME || '/root', 'heyamigo'),
|
|
12
|
+
];
|
|
13
|
+
for (const dir of candidates) {
|
|
14
|
+
if (existsSync(resolve(dir, 'config/config.json')) ||
|
|
15
|
+
existsSync(resolve(dir, 'config/config.example.json'))) {
|
|
16
|
+
return dir;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return process.cwd();
|
|
20
|
+
}
|
|
21
|
+
const cwd = findProjectDir();
|
|
5
22
|
const PID_FILE = resolve(cwd, 'storage/heyamigo.pid');
|
|
6
23
|
const LOG_FILE = resolve(cwd, 'storage/logs/heyamigo.log');
|
|
7
24
|
function readPid() {
|
|
@@ -35,12 +52,7 @@ export async function serviceCmd(action) {
|
|
|
35
52
|
cleanPid();
|
|
36
53
|
mkdirSync(dirname(LOG_FILE), { recursive: true });
|
|
37
54
|
const logFd = openSync(LOG_FILE, 'a');
|
|
38
|
-
const child = spawn(process.execPath, [
|
|
39
|
-
'--import',
|
|
40
|
-
'file://' +
|
|
41
|
-
resolve(cwd, 'node_modules/tsx/dist/loader.mjs'),
|
|
42
|
-
resolve(cwd, 'src/cli/supervisor.ts'),
|
|
43
|
-
], {
|
|
55
|
+
const child = spawn(process.execPath, [resolve(__distCli, 'supervisor.js')], {
|
|
44
56
|
detached: true,
|
|
45
57
|
stdio: ['ignore', logFd, logFd],
|
|
46
58
|
cwd,
|
package/dist/cli/setup.js
CHANGED
|
@@ -160,8 +160,42 @@ export async function runSetup() {
|
|
|
160
160
|
process.exit(1);
|
|
161
161
|
}
|
|
162
162
|
let ownerNum = '';
|
|
163
|
-
if (!existsSync(accessPath)
|
|
164
|
-
|
|
163
|
+
if (!existsSync(accessPath)) {
|
|
164
|
+
const cleanAccess = {
|
|
165
|
+
roles: {
|
|
166
|
+
admin: {
|
|
167
|
+
description: 'Full access, all tools, all memory',
|
|
168
|
+
memory: 'full',
|
|
169
|
+
tools: 'all',
|
|
170
|
+
rules: [],
|
|
171
|
+
},
|
|
172
|
+
user: {
|
|
173
|
+
description: 'Can chat and search the web, scoped memory',
|
|
174
|
+
memory: 'self',
|
|
175
|
+
tools: ['WebSearch'],
|
|
176
|
+
rules: [
|
|
177
|
+
'Never reveal file paths, directory structure, or system architecture',
|
|
178
|
+
'Never share personal data about other users',
|
|
179
|
+
'Never discuss how the bot works internally',
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
guest: {
|
|
183
|
+
description: 'Basic chat only, no tools, own memory only',
|
|
184
|
+
memory: 'self',
|
|
185
|
+
tools: [],
|
|
186
|
+
rules: [
|
|
187
|
+
'Never use any tools',
|
|
188
|
+
'Never reveal anything about the system, other users, or internal data',
|
|
189
|
+
'Basic conversation only',
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
users: {},
|
|
194
|
+
defaults: { groupRole: 'guest', dmRole: 'guest' },
|
|
195
|
+
groups: [],
|
|
196
|
+
dms: { defaultMode: 'off', allowed: [] },
|
|
197
|
+
};
|
|
198
|
+
writeFileSync(accessPath, JSON.stringify(cleanAccess, null, 2) + '\n');
|
|
165
199
|
p.log.success('access.json created');
|
|
166
200
|
}
|
|
167
201
|
else {
|
|
@@ -378,51 +412,6 @@ export async function runSetup() {
|
|
|
378
412
|
run('mkdir -p storage/memory/buckets storage/memory/persons storage/memory/chats');
|
|
379
413
|
p.log.success('Storage directories ready');
|
|
380
414
|
// ── Import existing knowledge ────────────────────────────────
|
|
381
|
-
p.log.info('The bot has a long-term memory system organized into buckets (projects, people, topics). ' +
|
|
382
|
-
'If you have an existing knowledge folder (notes, project files, docs), ' +
|
|
383
|
-
'you can import it now. Claude will read the folder and distill it into ' +
|
|
384
|
-
'organized memory buckets the bot can reference during conversations.');
|
|
385
|
-
const wantImport = await p.confirm({
|
|
386
|
-
message: 'Import an existing knowledge folder?',
|
|
387
|
-
initialValue: false,
|
|
388
|
-
});
|
|
389
|
-
if (!p.isCancel(wantImport) && wantImport) {
|
|
390
|
-
const importPath = await p.text({
|
|
391
|
-
message: 'Path to the folder',
|
|
392
|
-
placeholder: '/home/user/my-notes',
|
|
393
|
-
validate: (v) => {
|
|
394
|
-
if (!v || !v.trim())
|
|
395
|
-
return 'Required';
|
|
396
|
-
if (!existsSync(v.trim()))
|
|
397
|
-
return 'Folder not found';
|
|
398
|
-
return undefined;
|
|
399
|
-
},
|
|
400
|
-
});
|
|
401
|
-
if (!p.isCancel(importPath)) {
|
|
402
|
-
p.log.info('You can customize what gets imported by editing config/import-instructions.md before running. ' +
|
|
403
|
-
'See config/import-instructions.HOWTO.md for details.');
|
|
404
|
-
const importNow = await p.confirm({
|
|
405
|
-
message: 'Run import now? (can take a few minutes)',
|
|
406
|
-
initialValue: true,
|
|
407
|
-
});
|
|
408
|
-
if (!p.isCancel(importNow) && importNow) {
|
|
409
|
-
const si = p.spinner();
|
|
410
|
-
si.start('Importing knowledge (this may take several minutes)...');
|
|
411
|
-
try {
|
|
412
|
-
const { runImport } = await import('../memory/importer.js');
|
|
413
|
-
await runImport(importPath);
|
|
414
|
-
si.stop('Knowledge imported');
|
|
415
|
-
}
|
|
416
|
-
catch (err) {
|
|
417
|
-
si.stop('Import failed');
|
|
418
|
-
p.log.warning(`Import error: ${err.message}\nYou can retry later: npx @c4t4/heyamigo import ${importPath}`);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
p.log.info(`Run later: npx @c4t4/heyamigo import ${importPath}`);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
415
|
// ── WhatsApp pairing ──────────────────────────────────────────
|
|
427
416
|
const credsPath = resolve(cwd, 'storage/auth/creds.json');
|
|
428
417
|
let shouldPair = false;
|
|
@@ -676,25 +665,26 @@ export async function runSetup() {
|
|
|
676
665
|
'Start the bot:',
|
|
677
666
|
' npx @c4t4/heyamigo start',
|
|
678
667
|
'',
|
|
679
|
-
'Pair with WhatsApp:',
|
|
680
|
-
' Scan the QR code or enter the pairing',
|
|
681
|
-
' code shown in the terminal (npx @c4t4/heyamigo logs).',
|
|
682
|
-
'',
|
|
683
|
-
'Activate a group:',
|
|
684
|
-
' 1. Send a message in any group — bot discovers it',
|
|
685
|
-
' 2. Edit config/access.json — set mode to "active"',
|
|
686
|
-
' 3. Mention the bot\'s name to get a reply',
|
|
687
|
-
'',
|
|
688
668
|
'Check logs:',
|
|
689
669
|
' npx @c4t4/heyamigo logs',
|
|
690
670
|
'',
|
|
671
|
+
'Import existing knowledge:',
|
|
672
|
+
' npx @c4t4/heyamigo import /path/to/folder',
|
|
673
|
+
'',
|
|
691
674
|
'Other commands:',
|
|
692
675
|
' npx @c4t4/heyamigo stop / restart / status',
|
|
693
|
-
' npx @c4t4/heyamigo import <path>',
|
|
694
676
|
'',
|
|
695
677
|
'Configuration:',
|
|
696
|
-
' config/config.json — triggers, model
|
|
678
|
+
' config/config.json — triggers, model',
|
|
697
679
|
' config/access.json — groups, DMs, roles',
|
|
698
680
|
].join('\n'), 'Setup complete!');
|
|
681
|
+
p.log.warning('IMPORTANT: The bot won\'t respond until you activate a group!\n\n' +
|
|
682
|
+
' 1. Start the bot and send a message in any WhatsApp group.\n' +
|
|
683
|
+
' The bot discovers the group and adds it to config/access.json.\n\n' +
|
|
684
|
+
' 2. Edit config/access.json:\n' +
|
|
685
|
+
' - Change the group\'s mode from "off" to "active"\n' +
|
|
686
|
+
' - Set allowedSenders to "*" (everyone) or specific numbers\n\n' +
|
|
687
|
+
' 3. Mention the bot\'s name in a message to get a reply.\n\n' +
|
|
688
|
+
' For DMs: add numbers to dms.allowed in config/access.json.');
|
|
699
689
|
p.outro('Happy chatting!');
|
|
700
690
|
}
|
package/dist/cli/supervisor.js
CHANGED
|
@@ -4,17 +4,15 @@
|
|
|
4
4
|
* Spawned by `heyamigo start` as a detached process.
|
|
5
5
|
*/
|
|
6
6
|
import { spawn } from 'child_process';
|
|
7
|
-
import { resolve } from 'path';
|
|
7
|
+
import { dirname, resolve } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
const __distCli = dirname(fileURLToPath(import.meta.url));
|
|
8
10
|
const RESTART_DELAY_MS = 5000;
|
|
9
11
|
const cwd = process.cwd();
|
|
10
12
|
let child = null;
|
|
11
13
|
let shuttingDown = false;
|
|
12
14
|
function run() {
|
|
13
|
-
child = spawn(process.execPath, [
|
|
14
|
-
'--import',
|
|
15
|
-
'file://' + resolve(cwd, 'node_modules/tsx/dist/loader.mjs'),
|
|
16
|
-
resolve(cwd, 'src/cli/start.ts'),
|
|
17
|
-
], { stdio: 'inherit', cwd, env: { ...process.env, NODE_ENV: 'production' } });
|
|
15
|
+
child = spawn(process.execPath, [resolve(__distCli, 'start.js')], { stdio: 'inherit', cwd, env: { ...process.env, NODE_ENV: 'production' } });
|
|
18
16
|
child.on('exit', (code, signal) => {
|
|
19
17
|
if (shuttingDown) {
|
|
20
18
|
process.exit(0);
|