@arcadialdev/arcality 2.4.24 → 2.4.25

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.
@@ -1,77 +1,77 @@
1
- #!/usr/bin/env node
2
- // scripts/postinstall.mjs — Post-install hook
3
- // Runs automatically after 'npm install @arcadialdev/arcality'
4
-
5
- import fs from 'node:fs';
6
- import path from 'node:path';
7
- import os from 'node:os';
8
-
9
- const CONFIG_DIR = path.join(os.homedir(), '.arcality');
10
- const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
11
-
12
- // Read version from package.json
13
- let version = 'unknown';
14
- try {
15
- const pkgPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', 'package.json');
16
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
17
- version = pkg.version || 'unknown';
18
- } catch { }
19
-
20
- // ── Create global config dir if missing ──
21
- if (!fs.existsSync(CONFIG_DIR)) {
22
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
23
- }
24
- if (!fs.existsSync(CONFIG_FILE)) {
25
- const defaultConfig = { api_key: '', version, installed_at: new Date().toISOString() };
26
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(defaultConfig, null, 2), 'utf8');
27
- } else {
28
- try {
29
- let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
30
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
31
- const config = JSON.parse(raw);
32
- config.version = version;
33
- config.updated_at = new Date().toISOString();
34
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
35
- } catch { }
36
- }
37
-
38
- // ── Inject `arcality` npm scripts into user's project package.json ──
39
- const userPkgPath = path.join(process.cwd(), 'package.json');
40
- let scriptsInjected = false;
41
-
42
- if (fs.existsSync(userPkgPath)) {
43
- try {
44
- let raw = fs.readFileSync(userPkgPath, 'utf8');
45
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
46
- const pkg = JSON.parse(raw);
47
-
48
- // Only inject if not already there
49
- if (!pkg.scripts?.['arcality'] && !pkg.scripts?.['arcality:run']) {
50
- pkg.scripts = pkg.scripts || {};
51
- pkg.scripts['arcality'] = 'arcality run';
52
- pkg.scripts['arcality:init'] = 'arcality init';
53
- pkg.scripts['arcality:run'] = 'arcality run';
54
- fs.writeFileSync(userPkgPath, JSON.stringify(pkg, null, 2), 'utf8');
55
- scriptsInjected = true;
56
- }
57
- } catch { /* silently skip if user's package.json is unreadable */ }
58
- }
59
-
60
- // ── Banner ──
61
- console.log('');
62
- console.log(' ╔══════════════════════════════════════════════╗');
63
- console.log(` ║ ARCALITY v${version.padEnd(10)} — Installed ✅ ║`);
64
- console.log(' ╚══════════════════════════════════════════════╝');
65
- console.log('');
66
-
67
- if (scriptsInjected) {
68
- console.log(' ⚡ Scripts added to your package.json automatically!');
69
- console.log('');
70
- }
71
-
72
- console.log(' 📌 How to use Arcality:');
73
- console.log('');
74
- console.log(' npm run arcality:init → Configure this project');
75
- console.log(' npm run arcality:run → Launch an autonomous test mission');
76
- console.log(' npm run arcality → Open the interactive menu');
77
- console.log('');
1
+ #!/usr/bin/env node
2
+ // scripts/postinstall.mjs — Post-install hook
3
+ // Runs automatically after 'npm install @arcadialdev/arcality'
4
+
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import os from 'node:os';
8
+
9
+ const CONFIG_DIR = path.join(os.homedir(), '.arcality');
10
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
11
+
12
+ // Read version from package.json
13
+ let version = 'unknown';
14
+ try {
15
+ const pkgPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', 'package.json');
16
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
17
+ version = pkg.version || 'unknown';
18
+ } catch { }
19
+
20
+ // ── Create global config dir if missing ──
21
+ if (!fs.existsSync(CONFIG_DIR)) {
22
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
23
+ }
24
+ if (!fs.existsSync(CONFIG_FILE)) {
25
+ const defaultConfig = { api_key: '', version, installed_at: new Date().toISOString() };
26
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(defaultConfig, null, 2), 'utf8');
27
+ } else {
28
+ try {
29
+ let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
30
+ if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
31
+ const config = JSON.parse(raw);
32
+ config.version = version;
33
+ config.updated_at = new Date().toISOString();
34
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
35
+ } catch { }
36
+ }
37
+
38
+ // ── Inject `arcality` npm scripts into user's project package.json ──
39
+ const userPkgPath = path.join(process.cwd(), 'package.json');
40
+ let scriptsInjected = false;
41
+
42
+ if (fs.existsSync(userPkgPath)) {
43
+ try {
44
+ let raw = fs.readFileSync(userPkgPath, 'utf8');
45
+ if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
46
+ const pkg = JSON.parse(raw);
47
+
48
+ // Only inject if not already there
49
+ if (!pkg.scripts?.['arcality'] && !pkg.scripts?.['arcality:run']) {
50
+ pkg.scripts = pkg.scripts || {};
51
+ pkg.scripts['arcality'] = 'arcality run';
52
+ pkg.scripts['arcality:init'] = 'arcality init';
53
+ pkg.scripts['arcality:run'] = 'arcality run';
54
+ fs.writeFileSync(userPkgPath, JSON.stringify(pkg, null, 2), 'utf8');
55
+ scriptsInjected = true;
56
+ }
57
+ } catch { /* silently skip if user's package.json is unreadable */ }
58
+ }
59
+
60
+ // ── Banner ──
61
+ console.log('');
62
+ console.log(' ╔══════════════════════════════════════════════╗');
63
+ console.log(` ║ ARCALITY v${version.padEnd(10)} — Installed ✅ ║`);
64
+ console.log(' ╚══════════════════════════════════════════════╝');
65
+ console.log('');
66
+
67
+ if (scriptsInjected) {
68
+ console.log(' ⚡ Scripts added to your package.json automatically!');
69
+ console.log('');
70
+ }
71
+
72
+ console.log(' 📌 How to use Arcality:');
73
+ console.log('');
74
+ console.log(' npm run arcality:init → Configure this project');
75
+ console.log(' npm run arcality:run → Launch an autonomous test mission');
76
+ console.log(' npm run arcality → Open the interactive menu');
77
+ console.log('');
package/scripts/setup.mjs CHANGED
@@ -1,166 +1,166 @@
1
- #!/usr/bin/env node
2
- // scripts/setup.mjs — Comando: arcality setup
3
- // Configura API Key + instala navegador Playwright (Chromium)
4
-
5
- import fs from 'node:fs';
6
- import path from 'node:path';
7
- import os from 'node:os';
8
- import { spawn } from 'node:child_process';
9
- import { createInterface } from 'node:readline';
10
-
11
- const CONFIG_DIR = path.join(os.homedir(), '.arcality');
12
- const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
13
- const PACKAGE_ROOT = process.env.ARCALITY_ROOT || path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
14
-
15
- function question(prompt) {
16
- const rl = createInterface({ input: process.stdin, output: process.stdout });
17
- return new Promise(resolve => {
18
- rl.question(prompt, answer => { rl.close(); resolve(answer.trim()); });
19
- });
20
- }
21
-
22
- function loadConfig() {
23
- try {
24
- if (fs.existsSync(CONFIG_FILE)) {
25
- let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
26
- if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
27
- return JSON.parse(raw);
28
- }
29
- } catch { }
30
- return {};
31
- }
32
-
33
- function saveConfig(config) {
34
- if (!fs.existsSync(CONFIG_DIR)) {
35
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
36
- }
37
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
38
- }
39
-
40
- async function main() {
41
- // Leer versión
42
- let version = 'unknown';
43
- try {
44
- const pkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'));
45
- version = pkg.version || 'unknown';
46
- } catch { }
47
-
48
- console.log('');
49
- console.log(' ╔══════════════════════════════════════════╗');
50
- console.log(` ║ ARCALITY — Setup v${version.padEnd(24)}║`);
51
- console.log(' ╚══════════════════════════════════════════╝');
52
- console.log('');
53
-
54
- const config = loadConfig();
55
-
56
- // ──────────────── Paso 1: API Key de Arcality ────────────────
57
- const currentKey = config.api_key || '';
58
- const currentAnthropic = config.anthropic_api_key || '';
59
-
60
- const maskedArc = currentKey
61
- ? `✅ ${currentKey.slice(0, 6)}****${currentKey.slice(-4)}`
62
- : '❌ (No configurada)';
63
-
64
- const maskedAnt = currentAnthropic
65
- ? `✅ ${currentAnthropic.slice(0, 6)}****${currentAnthropic.slice(-4)}`
66
- : '❌ (No configurada)';
67
-
68
- console.log(` 🔑 Arcality API Key (dummy/real): ${maskedArc}`);
69
- console.log(` 🧠 Anthropic API Key (corporativa): ${maskedAnt}`);
70
- console.log('');
71
-
72
- const newKey = await question(' 👉 Ingresa Arcality API Key (Enter p. mantener): ');
73
- if (newKey) {
74
- if (!newKey.startsWith('arc_k_')) {
75
- console.log(' ❌ La API Key debe iniciar con "arc_k_"');
76
- process.exit(1);
77
- }
78
- config.api_key = newKey;
79
- }
80
-
81
- // API URL is internal-only (loaded via dotenv), always available
82
- const hasSaaSBackend = !!process.env.ARCALITY_API_URL;
83
-
84
- if (hasSaaSBackend) {
85
- console.log(' 🧠 Anthropic API Key (omitida — se usará el Cerebro SaaS)');
86
- // Podemos limpiar la llave local por seguridad si queremos
87
- if (config.anthropic_api_key) delete config.anthropic_api_key;
88
- } else {
89
- const newAnt = await question(' 👉 Ingresa Anthropic API Key (Enter p. mantener): ');
90
- if (newAnt) {
91
- if (!newAnt.startsWith('sk-ant-')) {
92
- console.log(' ⚠️ Formato de llave Anthropic inusual. Verifica que inicie con "sk-ant-"');
93
- }
94
- config.anthropic_api_key = newAnt;
95
- }
96
- }
97
-
98
- // Configurar modelo por defecto
99
- config.model = config.model || 'claude-sonnet-4-5';
100
-
101
- // Guardar config
102
- config.version = version;
103
- config.setup_at = new Date().toISOString();
104
- saveConfig(config);
105
- console.log('');
106
- console.log(' ✅ Configuración guardada correctamente.');
107
-
108
- // ─── Paso 2: Instalar Chromium ───
109
- console.log('');
110
- console.log(' 🌐 Instalando navegador (Chromium para Playwright)...');
111
- console.log('');
112
-
113
- try {
114
- await new Promise((resolve, reject) => {
115
- const child = spawn('npx', ['playwright', 'install', 'chromium'], {
116
- stdio: 'inherit',
117
- shell: true,
118
- cwd: PACKAGE_ROOT
119
- });
120
- child.on('exit', code => code === 0 ? resolve() : reject(new Error(`Playwright install falló (exit code ${code})`)));
121
- child.on('error', reject);
122
- });
123
- console.log('');
124
- console.log(' ✅ Chromium instalado correctamente');
125
- } catch (err) {
126
- console.log('');
127
- console.log(` ⚠️ No se pudo instalar Chromium automáticamente: ${err.message}`);
128
- console.log(' Puedes instalarlo manualmente ejecutando:');
129
- console.log(' npx playwright install chromium');
130
- }
131
-
132
- // ─── Paso 3: Crear .env si no existe ───
133
- const envFile = path.join(PACKAGE_ROOT, '.env');
134
- const envExample = path.join(PACKAGE_ROOT, '.env.example');
135
-
136
- if (!fs.existsSync(envFile) && fs.existsSync(envExample)) {
137
- let content = fs.readFileSync(envExample, 'utf8');
138
-
139
- // Inyectar la API Key
140
- if (config.api_key) {
141
- content = content.replace('ARCALITY_API_KEY=', `ARCALITY_API_KEY=${config.api_key}`);
142
- }
143
-
144
- fs.writeFileSync(envFile, content, 'utf8');
145
- console.log(' ✅ .env creado desde .env.example');
146
- } else if (fs.existsSync(envFile)) {
147
- console.log(' ✅ .env existente (sin modificar)');
148
- }
149
-
150
- // ─── Resumen final ───
151
- console.log('');
152
- console.log(' ╔══════════════════════════════════════════╗');
153
- console.log(' ║ ✅ SETUP COMPLETADO ║');
154
- console.log(' ╚══════════════════════════════════════════╝');
155
- console.log('');
156
- console.log(' Para empezar, ejecuta:');
157
- console.log('');
158
- console.log(' arcality → Menú interactivo');
159
- console.log(' arcality --agent "tu misión" → Ejecución directa');
160
- console.log('');
161
- }
162
-
163
- main().catch(err => {
164
- console.error(' ❌ Error durante setup:', err.message);
165
- process.exit(1);
166
- });
1
+ #!/usr/bin/env node
2
+ // scripts/setup.mjs — Comando: arcality setup
3
+ // Configura API Key + instala navegador Playwright (Chromium)
4
+
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import os from 'node:os';
8
+ import { spawn } from 'node:child_process';
9
+ import { createInterface } from 'node:readline';
10
+
11
+ const CONFIG_DIR = path.join(os.homedir(), '.arcality');
12
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
13
+ const PACKAGE_ROOT = process.env.ARCALITY_ROOT || path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
14
+
15
+ function question(prompt) {
16
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
17
+ return new Promise(resolve => {
18
+ rl.question(prompt, answer => { rl.close(); resolve(answer.trim()); });
19
+ });
20
+ }
21
+
22
+ function loadConfig() {
23
+ try {
24
+ if (fs.existsSync(CONFIG_FILE)) {
25
+ let raw = fs.readFileSync(CONFIG_FILE, 'utf8');
26
+ if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
27
+ return JSON.parse(raw);
28
+ }
29
+ } catch { }
30
+ return {};
31
+ }
32
+
33
+ function saveConfig(config) {
34
+ if (!fs.existsSync(CONFIG_DIR)) {
35
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
36
+ }
37
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
38
+ }
39
+
40
+ async function main() {
41
+ // Leer versión
42
+ let version = 'unknown';
43
+ try {
44
+ const pkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'));
45
+ version = pkg.version || 'unknown';
46
+ } catch { }
47
+
48
+ console.log('');
49
+ console.log(' ╔══════════════════════════════════════════╗');
50
+ console.log(` ║ ARCALITY — Setup v${version.padEnd(24)}║`);
51
+ console.log(' ╚══════════════════════════════════════════╝');
52
+ console.log('');
53
+
54
+ const config = loadConfig();
55
+
56
+ // ──────────────── Paso 1: API Key de Arcality ────────────────
57
+ const currentKey = config.api_key || '';
58
+ const currentAnthropic = config.anthropic_api_key || '';
59
+
60
+ const maskedArc = currentKey
61
+ ? `✅ ${currentKey.slice(0, 6)}****${currentKey.slice(-4)}`
62
+ : '❌ (No configurada)';
63
+
64
+ const maskedAnt = currentAnthropic
65
+ ? `✅ ${currentAnthropic.slice(0, 6)}****${currentAnthropic.slice(-4)}`
66
+ : '❌ (No configurada)';
67
+
68
+ console.log(` 🔑 Arcality API Key (dummy/real): ${maskedArc}`);
69
+ console.log(` 🧠 Anthropic API Key (corporativa): ${maskedAnt}`);
70
+ console.log('');
71
+
72
+ const newKey = await question(' 👉 Ingresa Arcality API Key (Enter p. mantener): ');
73
+ if (newKey) {
74
+ if (!newKey.startsWith('arc_k_')) {
75
+ console.log(' ❌ La API Key debe iniciar con "arc_k_"');
76
+ process.exit(1);
77
+ }
78
+ config.api_key = newKey;
79
+ }
80
+
81
+ // API URL is internal-only (loaded via dotenv), always available
82
+ const hasSaaSBackend = !!process.env.ARCALITY_API_URL;
83
+
84
+ if (hasSaaSBackend) {
85
+ console.log(' 🧠 Anthropic API Key (omitida — se usará el Cerebro SaaS)');
86
+ // Podemos limpiar la llave local por seguridad si queremos
87
+ if (config.anthropic_api_key) delete config.anthropic_api_key;
88
+ } else {
89
+ const newAnt = await question(' 👉 Ingresa Anthropic API Key (Enter p. mantener): ');
90
+ if (newAnt) {
91
+ if (!newAnt.startsWith('sk-ant-')) {
92
+ console.log(' ⚠️ Formato de llave Anthropic inusual. Verifica que inicie con "sk-ant-"');
93
+ }
94
+ config.anthropic_api_key = newAnt;
95
+ }
96
+ }
97
+
98
+ // Configurar modelo por defecto
99
+ config.model = config.model || 'claude-sonnet-4-5';
100
+
101
+ // Guardar config
102
+ config.version = version;
103
+ config.setup_at = new Date().toISOString();
104
+ saveConfig(config);
105
+ console.log('');
106
+ console.log(' ✅ Configuración guardada correctamente.');
107
+
108
+ // ─── Paso 2: Instalar Chromium ───
109
+ console.log('');
110
+ console.log(' 🌐 Instalando navegador (Chromium para Playwright)...');
111
+ console.log('');
112
+
113
+ try {
114
+ await new Promise((resolve, reject) => {
115
+ const child = spawn('npx', ['playwright', 'install', 'chromium'], {
116
+ stdio: 'inherit',
117
+ shell: true,
118
+ cwd: PACKAGE_ROOT
119
+ });
120
+ child.on('exit', code => code === 0 ? resolve() : reject(new Error(`Playwright install falló (exit code ${code})`)));
121
+ child.on('error', reject);
122
+ });
123
+ console.log('');
124
+ console.log(' ✅ Chromium instalado correctamente');
125
+ } catch (err) {
126
+ console.log('');
127
+ console.log(` ⚠️ No se pudo instalar Chromium automáticamente: ${err.message}`);
128
+ console.log(' Puedes instalarlo manualmente ejecutando:');
129
+ console.log(' npx playwright install chromium');
130
+ }
131
+
132
+ // ─── Paso 3: Crear .env si no existe ───
133
+ const envFile = path.join(PACKAGE_ROOT, '.env');
134
+ const envExample = path.join(PACKAGE_ROOT, '.env.example');
135
+
136
+ if (!fs.existsSync(envFile) && fs.existsSync(envExample)) {
137
+ let content = fs.readFileSync(envExample, 'utf8');
138
+
139
+ // Inyectar la API Key
140
+ if (config.api_key) {
141
+ content = content.replace('ARCALITY_API_KEY=', `ARCALITY_API_KEY=${config.api_key}`);
142
+ }
143
+
144
+ fs.writeFileSync(envFile, content, 'utf8');
145
+ console.log(' ✅ .env creado desde .env.example');
146
+ } else if (fs.existsSync(envFile)) {
147
+ console.log(' ✅ .env existente (sin modificar)');
148
+ }
149
+
150
+ // ─── Resumen final ───
151
+ console.log('');
152
+ console.log(' ╔══════════════════════════════════════════╗');
153
+ console.log(' ║ ✅ SETUP COMPLETADO ║');
154
+ console.log(' ╚══════════════════════════════════════════╝');
155
+ console.log('');
156
+ console.log(' Para empezar, ejecuta:');
157
+ console.log('');
158
+ console.log(' arcality → Menú interactivo');
159
+ console.log(' arcality --agent "tu misión" → Ejecución directa');
160
+ console.log('');
161
+ }
162
+
163
+ main().catch(err => {
164
+ console.error(' ❌ Error durante setup:', err.message);
165
+ process.exit(1);
166
+ });