@conversionpros/aiva 1.0.0
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/README.md +148 -0
- package/auto-deploy.js +190 -0
- package/bin/aiva.js +81 -0
- package/cli-sync.js +126 -0
- package/d2a-prompt-template.txt +106 -0
- package/diagnostics-api.js +304 -0
- package/docs/ara-dedup-fix-scope.md +112 -0
- package/docs/ara-fix-round2-scope.md +61 -0
- package/docs/ara-greeting-fix-scope.md +70 -0
- package/docs/calendar-date-fix-scope.md +28 -0
- package/docs/getting-started.md +115 -0
- package/docs/network-architecture-rollout-scope.md +43 -0
- package/docs/scope-google-oauth-integration.md +351 -0
- package/docs/settings-page-scope.md +50 -0
- package/docs/xai-imagine-scope.md +116 -0
- package/docs/xai-voice-integration-scope.md +115 -0
- package/docs/xai-voice-tools-scope.md +165 -0
- package/email-router.js +512 -0
- package/follow-up-handler.js +606 -0
- package/gateway-monitor.js +158 -0
- package/google-email.js +379 -0
- package/google-oauth.js +310 -0
- package/grok-imagine.js +97 -0
- package/health-reporter.js +287 -0
- package/invisible-prefix-base.txt +206 -0
- package/invisible-prefix-owner.txt +26 -0
- package/invisible-prefix-slim.txt +10 -0
- package/invisible-prefix.txt +43 -0
- package/knowledge-base.js +472 -0
- package/lib/cli.js +19 -0
- package/lib/config.js +124 -0
- package/lib/health.js +57 -0
- package/lib/process.js +207 -0
- package/lib/server.js +42 -0
- package/lib/setup.js +472 -0
- package/meta-capi.js +206 -0
- package/meta-leads.js +411 -0
- package/notion-oauth.js +323 -0
- package/package.json +61 -0
- package/public/agent-config.html +241 -0
- package/public/aiva-avatar-anime.png +0 -0
- package/public/css/docs.css.bak +688 -0
- package/public/css/onboarding.css +543 -0
- package/public/diagrams/claude-subscription-pool.html +329 -0
- package/public/diagrams/claude-subscription-pool.png +0 -0
- package/public/docs-icon.png +0 -0
- package/public/escalation.html +237 -0
- package/public/group-config.html +300 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/icons/agents.svg +1 -0
- package/public/icons/attach.svg +1 -0
- package/public/icons/characters.svg +1 -0
- package/public/icons/chat.svg +1 -0
- package/public/icons/docs.svg +1 -0
- package/public/icons/heartbeat.svg +1 -0
- package/public/icons/messages.svg +1 -0
- package/public/icons/mic.svg +1 -0
- package/public/icons/notes.svg +1 -0
- package/public/icons/settings.svg +1 -0
- package/public/icons/tasks.svg +1 -0
- package/public/images/onboarding/p0-communication-layer.png +0 -0
- package/public/images/onboarding/p0-infinite-surface.png +0 -0
- package/public/images/onboarding/p0-learning-model.png +0 -0
- package/public/images/onboarding/p0-meet-aiva.png +0 -0
- package/public/images/onboarding/p4-contact-intelligence.png +0 -0
- package/public/images/onboarding/p4-context-compounds.png +0 -0
- package/public/images/onboarding/p4-message-router.png +0 -0
- package/public/images/onboarding/p4-per-contact-rules.png +0 -0
- package/public/images/onboarding/p4-send-messages.png +0 -0
- package/public/images/onboarding/p6-be-precise.png +0 -0
- package/public/images/onboarding/p6-review-escalations.png +0 -0
- package/public/images/onboarding/p6-voice-input.png +0 -0
- package/public/images/onboarding/p7-completion.png +0 -0
- package/public/index.html +11594 -0
- package/public/js/onboarding.js +699 -0
- package/public/manifest.json +24 -0
- package/public/messages-v2.html +2824 -0
- package/public/permission-approve.html.bak +107 -0
- package/public/permissions.html +150 -0
- package/public/styles/design-system.css +68 -0
- package/router-db.js +604 -0
- package/router-utils.js +28 -0
- package/router-v2/adapters/imessage.js +191 -0
- package/router-v2/adapters/quo.js +82 -0
- package/router-v2/adapters/whatsapp.js +192 -0
- package/router-v2/contact-manager.js +234 -0
- package/router-v2/conversation-engine.js +498 -0
- package/router-v2/data/knowledge-base.json +176 -0
- package/router-v2/data/router-v2.db +0 -0
- package/router-v2/data/router-v2.db-shm +0 -0
- package/router-v2/data/router-v2.db-wal +0 -0
- package/router-v2/data/router.db +0 -0
- package/router-v2/db.js +457 -0
- package/router-v2/escalation-bridge.js +540 -0
- package/router-v2/follow-up-engine.js +347 -0
- package/router-v2/index.js +441 -0
- package/router-v2/ingestion.js +213 -0
- package/router-v2/knowledge-base.js +231 -0
- package/router-v2/lead-qualifier.js +152 -0
- package/router-v2/learning-loop.js +202 -0
- package/router-v2/outbound-sender.js +160 -0
- package/router-v2/package.json +13 -0
- package/router-v2/permission-gate.js +86 -0
- package/router-v2/playbook.js +177 -0
- package/router-v2/prompts/base.js +52 -0
- package/router-v2/prompts/first-contact.js +38 -0
- package/router-v2/prompts/lead-qualification.js +37 -0
- package/router-v2/prompts/scheduling.js +72 -0
- package/router-v2/prompts/style-overrides.js +22 -0
- package/router-v2/scheduler.js +301 -0
- package/router-v2/scripts/migrate-v1-to-v2.js +215 -0
- package/router-v2/scripts/seed-faq.js +67 -0
- package/router-v2/seed-knowledge-base.js +39 -0
- package/router-v2/utils/ai.js +129 -0
- package/router-v2/utils/phone.js +52 -0
- package/router-v2/utils/response-validator.js +98 -0
- package/router-v2/utils/sanitize.js +222 -0
- package/router.js +5005 -0
- package/routes/google-calendar.js +186 -0
- package/scripts/deploy.sh +62 -0
- package/scripts/macos-calendar.sh +232 -0
- package/scripts/onboard-device.sh +466 -0
- package/server.js +5131 -0
- package/start.sh +24 -0
- package/templates/AGENTS.md +548 -0
- package/templates/IDENTITY.md +15 -0
- package/templates/docs-agents.html +132 -0
- package/templates/docs-app.html +130 -0
- package/templates/docs-home.html +83 -0
- package/templates/docs-imessage.html +121 -0
- package/templates/docs-tasks.html +123 -0
- package/templates/docs-tips.html +175 -0
- package/templates/getting-started.html +809 -0
- package/templates/invisible-prefix-base.txt +171 -0
- package/templates/invisible-prefix-owner.txt +282 -0
- package/templates/invisible-prefix.txt +338 -0
- package/templates/manifest.json +61 -0
- package/templates/memory-org/clients.md +7 -0
- package/templates/memory-org/credentials.md +9 -0
- package/templates/memory-org/devices.md +7 -0
- package/templates/updates.html +464 -0
- package/templates/workspace/AGENTS.md.tmpl +161 -0
- package/templates/workspace/HEARTBEAT.md.tmpl +17 -0
- package/templates/workspace/IDENTITY.md.tmpl +15 -0
- package/templates/workspace/MEMORY.md.tmpl +16 -0
- package/templates/workspace/SOUL.md.tmpl +51 -0
- package/templates/workspace/USER.md.tmpl +25 -0
- package/tts-proxy.js +96 -0
- package/voice-call-local.js +731 -0
- package/voice-call.js +732 -0
- package/wa-listener.js +354 -0
package/lib/process.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { execSync, spawn } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const pc = require('picocolors');
|
|
7
|
+
const { loadConfig, getLogsDir, getAivaHome, getDataDir, getUploadsDir } = require('./config');
|
|
8
|
+
const { checkHealth, checkGateway } = require('./health');
|
|
9
|
+
|
|
10
|
+
function getEcosystemPath() {
|
|
11
|
+
return path.join(getAivaHome(), 'ecosystem.config.js');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function writeEcosystem() {
|
|
15
|
+
const config = loadConfig();
|
|
16
|
+
const serverPath = path.join(__dirname, 'server.js');
|
|
17
|
+
const ecosystemPath = getEcosystemPath();
|
|
18
|
+
|
|
19
|
+
const content = `module.exports = {
|
|
20
|
+
apps: [{
|
|
21
|
+
name: 'aiva-app',
|
|
22
|
+
script: '${serverPath}',
|
|
23
|
+
cwd: '${getAivaHome()}',
|
|
24
|
+
env: {
|
|
25
|
+
PORT: '${config.port || 3847}',
|
|
26
|
+
AIVA_CONFIG_PATH: '${path.join(getAivaHome(), 'config.json')}',
|
|
27
|
+
AIVA_DATA_DIR: '${getDataDir()}',
|
|
28
|
+
AIVA_UPLOADS_DIR: '${getUploadsDir()}',
|
|
29
|
+
AIVA_LOGS_DIR: '${getLogsDir()}',
|
|
30
|
+
AIVA_HOME: '${getAivaHome()}',
|
|
31
|
+
NODE_ENV: 'production'
|
|
32
|
+
},
|
|
33
|
+
watch: false,
|
|
34
|
+
max_restarts: 10,
|
|
35
|
+
restart_delay: 3000,
|
|
36
|
+
log_file: '${path.join(getLogsDir(), 'aiva.log')}',
|
|
37
|
+
out_file: '${path.join(getLogsDir(), 'aiva-out.log')}',
|
|
38
|
+
error_file: '${path.join(getLogsDir(), 'aiva-error.log')}',
|
|
39
|
+
merge_logs: true,
|
|
40
|
+
time: true
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
`;
|
|
44
|
+
fs.writeFileSync(ecosystemPath, content);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function ensurePm2() {
|
|
48
|
+
try {
|
|
49
|
+
execSync('which pm2', { stdio: 'pipe' });
|
|
50
|
+
} catch {
|
|
51
|
+
console.log(pc.yellow('PM2 not found. Installing globally...'));
|
|
52
|
+
try {
|
|
53
|
+
execSync('npm install -g pm2', { stdio: 'inherit' });
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.error(pc.red('Failed to install PM2. Please run: npm install -g pm2'));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function startServer(opts = {}) {
|
|
62
|
+
const config = loadConfig();
|
|
63
|
+
const port = config.port || 3847;
|
|
64
|
+
|
|
65
|
+
if (opts.foreground) {
|
|
66
|
+
console.log(pc.cyan(`Starting AIVA in foreground on port ${port}...`));
|
|
67
|
+
const serverPath = path.join(__dirname, 'server.js');
|
|
68
|
+
const child = spawn('node', [serverPath], {
|
|
69
|
+
stdio: 'inherit',
|
|
70
|
+
env: {
|
|
71
|
+
...process.env,
|
|
72
|
+
PORT: String(port),
|
|
73
|
+
AIVA_CONFIG_PATH: path.join(getAivaHome(), 'config.json'),
|
|
74
|
+
AIVA_DATA_DIR: getDataDir(),
|
|
75
|
+
AIVA_UPLOADS_DIR: getUploadsDir(),
|
|
76
|
+
AIVA_LOGS_DIR: getLogsDir(),
|
|
77
|
+
AIVA_HOME: getAivaHome()
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
child.on('exit', (code) => process.exit(code));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
ensurePm2();
|
|
85
|
+
writeEcosystem();
|
|
86
|
+
|
|
87
|
+
console.log(pc.cyan(`Starting AIVA on port ${port}...`));
|
|
88
|
+
try {
|
|
89
|
+
execSync(`pm2 start ${getEcosystemPath()}`, { stdio: 'pipe' });
|
|
90
|
+
// Wait briefly for startup
|
|
91
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
92
|
+
const health = await checkHealth(port);
|
|
93
|
+
if (health.ok) {
|
|
94
|
+
console.log(pc.green(`AIVA is running at http://localhost:${port}`));
|
|
95
|
+
} else {
|
|
96
|
+
console.log(pc.yellow(`AIVA process started but health check pending. Check: aiva logs`));
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error(pc.red('Failed to start AIVA:'), e.message);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function stopServer() {
|
|
104
|
+
ensurePm2();
|
|
105
|
+
console.log(pc.cyan('Stopping AIVA...'));
|
|
106
|
+
try {
|
|
107
|
+
execSync('pm2 stop aiva-app', { stdio: 'pipe' });
|
|
108
|
+
console.log(pc.green('AIVA stopped.'));
|
|
109
|
+
} catch {
|
|
110
|
+
console.log(pc.yellow('AIVA is not running.'));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function restartServer() {
|
|
115
|
+
ensurePm2();
|
|
116
|
+
writeEcosystem();
|
|
117
|
+
console.log(pc.cyan('Restarting AIVA...'));
|
|
118
|
+
try {
|
|
119
|
+
execSync('pm2 restart aiva-app', { stdio: 'pipe' });
|
|
120
|
+
console.log(pc.green('AIVA restarted.'));
|
|
121
|
+
} catch {
|
|
122
|
+
console.log(pc.yellow('AIVA not running. Starting...'));
|
|
123
|
+
startServer();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function getStatus() {
|
|
128
|
+
const config = loadConfig();
|
|
129
|
+
const port = config.port || 3847;
|
|
130
|
+
const pkg = require('../package.json');
|
|
131
|
+
|
|
132
|
+
console.log(pc.bold(`\n${config.name || 'AIVA'} Status`));
|
|
133
|
+
console.log(pc.dim('─'.repeat(40)));
|
|
134
|
+
console.log(` Version: ${pc.cyan(pkg.version)}`);
|
|
135
|
+
console.log(` Port: ${port}`);
|
|
136
|
+
|
|
137
|
+
// PM2 status
|
|
138
|
+
let pm2Status = 'unknown';
|
|
139
|
+
let uptime = '-';
|
|
140
|
+
let memory = '-';
|
|
141
|
+
try {
|
|
142
|
+
const raw = execSync('pm2 jlist', { stdio: 'pipe' }).toString();
|
|
143
|
+
const procs = JSON.parse(raw);
|
|
144
|
+
const aiva = procs.find(p => p.name === 'aiva-app');
|
|
145
|
+
if (aiva) {
|
|
146
|
+
pm2Status = aiva.pm2_env?.status || 'unknown';
|
|
147
|
+
if (aiva.pm2_env?.pm_uptime) {
|
|
148
|
+
const ms = Date.now() - aiva.pm2_env.pm_uptime;
|
|
149
|
+
const hours = Math.floor(ms / 3600000);
|
|
150
|
+
const mins = Math.floor((ms % 3600000) / 60000);
|
|
151
|
+
uptime = hours > 0 ? `${hours}h ${mins}m` : `${mins}m`;
|
|
152
|
+
}
|
|
153
|
+
if (aiva.monit?.memory) {
|
|
154
|
+
memory = `${Math.round(aiva.monit.memory / 1024 / 1024)}MB`;
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
pm2Status = 'not registered';
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
pm2Status = 'pm2 not available';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const statusColor = pm2Status === 'online' ? pc.green : pm2Status === 'stopped' ? pc.red : pc.yellow;
|
|
164
|
+
console.log(` Status: ${statusColor(pm2Status)}`);
|
|
165
|
+
console.log(` Uptime: ${uptime}`);
|
|
166
|
+
console.log(` Memory: ${memory}`);
|
|
167
|
+
|
|
168
|
+
// Health check
|
|
169
|
+
const health = await checkHealth(port);
|
|
170
|
+
console.log(` Health: ${health.ok ? pc.green('Healthy') : pc.red('Unhealthy')}`);
|
|
171
|
+
|
|
172
|
+
// Gateway
|
|
173
|
+
if (config.gateway?.url) {
|
|
174
|
+
const gw = await checkGateway(config.gateway.url);
|
|
175
|
+
console.log(` Gateway: ${gw.ok ? pc.green('Connected') : pc.red('Unreachable')}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Data dir size
|
|
179
|
+
try {
|
|
180
|
+
const size = execSync(`du -sh "${getDataDir()}" 2>/dev/null | cut -f1`, { stdio: 'pipe' }).toString().trim();
|
|
181
|
+
console.log(` Data size: ${size || '-'}`);
|
|
182
|
+
} catch {
|
|
183
|
+
console.log(` Data size: -`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
console.log(pc.dim('─'.repeat(40)));
|
|
187
|
+
console.log();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function getLogs(lines = 50) {
|
|
191
|
+
ensurePm2();
|
|
192
|
+
try {
|
|
193
|
+
execSync(`pm2 logs aiva-app --lines ${lines} --nostream`, { stdio: 'inherit' });
|
|
194
|
+
} catch {
|
|
195
|
+
// Try reading log files directly
|
|
196
|
+
const logFile = path.join(getLogsDir(), 'aiva.log');
|
|
197
|
+
if (fs.existsSync(logFile)) {
|
|
198
|
+
const content = fs.readFileSync(logFile, 'utf8');
|
|
199
|
+
const logLines = content.split('\n');
|
|
200
|
+
console.log(logLines.slice(-lines).join('\n'));
|
|
201
|
+
} else {
|
|
202
|
+
console.log(pc.yellow('No logs found.'));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
module.exports = { startServer, stopServer, restartServer, getStatus, getLogs, writeEcosystem, ensurePm2 };
|
package/lib/server.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// AIVA Server - CLI adapter
|
|
4
|
+
// This wraps the main server.js, setting up environment variables
|
|
5
|
+
// so that it resolves paths from ~/.aiva/ instead of hardcoded locations.
|
|
6
|
+
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
// Determine AIVA home - either from env or default ~/.aiva/
|
|
11
|
+
const AIVA_HOME = process.env.AIVA_HOME || path.join(require('os').homedir(), '.aiva');
|
|
12
|
+
const configPath = process.env.AIVA_CONFIG_PATH || path.join(AIVA_HOME, 'config.json');
|
|
13
|
+
|
|
14
|
+
// Load config
|
|
15
|
+
let config = {};
|
|
16
|
+
try {
|
|
17
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.warn('[aiva] No config found at', configPath, '- using defaults');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Set environment variables that the server reads
|
|
23
|
+
process.env.PORT = process.env.PORT || String(config.port || 3847);
|
|
24
|
+
process.env.AIVA_HOME = AIVA_HOME;
|
|
25
|
+
process.env.AIVA_DATA_DIR = process.env.AIVA_DATA_DIR || path.join(AIVA_HOME, 'data');
|
|
26
|
+
process.env.AIVA_UPLOADS_DIR = process.env.AIVA_UPLOADS_DIR || path.join(AIVA_HOME, 'uploads');
|
|
27
|
+
process.env.AIVA_LOGS_DIR = process.env.AIVA_LOGS_DIR || path.join(AIVA_HOME, 'logs');
|
|
28
|
+
|
|
29
|
+
// Ensure data directories exist
|
|
30
|
+
[process.env.AIVA_DATA_DIR, process.env.AIVA_UPLOADS_DIR, process.env.AIVA_LOGS_DIR].forEach(dir => {
|
|
31
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Load .env from AIVA_HOME if it exists (user-specific environment)
|
|
35
|
+
const envPath = path.join(AIVA_HOME, '.env');
|
|
36
|
+
if (fs.existsSync(envPath)) {
|
|
37
|
+
require('dotenv').config({ path: envPath });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Now load the actual server - it lives alongside this file in the package
|
|
41
|
+
const serverPath = path.join(__dirname, '..', 'server.js');
|
|
42
|
+
require(serverPath);
|