@arcadialdev/arcality 2.4.25 → 2.4.27
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/.agents/skills/security-qa/SKILL.md +253 -253
- package/README.md +2 -2
- package/package.json +7 -4
- package/scripts/gen-and-run.mjs +932 -932
- package/scripts/setup.mjs +166 -166
- package/src/arcalityClient.mjs +266 -266
- package/tests/_helpers/ArcalityReporter.js +706 -706
- package/tests/_helpers/agentic-runner.bundle.spec.js +83 -2806
- package/src/KnowledgeService.ts +0 -256
- package/src/consoleBanner.ts +0 -32
- package/src/envSetup.ts +0 -205
- package/src/index.ts +0 -25
- package/src/projectInspector.ts +0 -42
- package/src/services/collectiveMemoryService.ts +0 -178
- package/src/services/securityScanner.ts +0 -128
- package/src/testRunner.ts +0 -201
- package/tests/_helpers/ArcalityReporter.ts +0 -733
- package/tests/_helpers/agentic-runner.spec.ts +0 -783
- package/tests/_helpers/ai-agent-helper.ts +0 -1660
- package/tests/_helpers/discover-view.spec.ts +0 -238
- package/tests/_helpers/extract-view.spec.ts +0 -118
- package/tests/_helpers/qa-security-tools.ts +0 -265
- package/tests/_helpers/qa-tools.ts +0 -333
- package/tests/_helpers/smart-action.spec.ts +0 -1458
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
|
+
});
|