@arcadialdev/arcality 2.4.30 → 2.4.32
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/.agent/skills/form-expert.md +99 -0
- package/.agent/skills/investigation-protocol.md +61 -0
- package/.agent/skills/modal-master.md +41 -0
- package/.agent/skills/native-control-expert.md +82 -0
- package/.agents/skills/e2e-testing-expert/SKILL.md +28 -0
- package/.agents/skills/frontend-design/LICENSE.txt +177 -0
- package/.agents/skills/frontend-design/SKILL.md +42 -0
- package/.agents/skills/nodejs-backend-patterns/SKILL.md +639 -0
- package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
- package/.agents/skills/playwright-best-practices/LICENSE.md +7 -0
- package/.agents/skills/playwright-best-practices/README.md +147 -0
- package/.agents/skills/playwright-best-practices/SKILL.md +303 -0
- package/.agents/skills/playwright-best-practices/advanced/authentication-flows.md +360 -0
- package/.agents/skills/playwright-best-practices/advanced/authentication.md +871 -0
- package/.agents/skills/playwright-best-practices/advanced/clock-mocking.md +364 -0
- package/.agents/skills/playwright-best-practices/advanced/mobile-testing.md +409 -0
- package/.agents/skills/playwright-best-practices/advanced/multi-context.md +288 -0
- package/.agents/skills/playwright-best-practices/advanced/multi-user.md +393 -0
- package/.agents/skills/playwright-best-practices/advanced/network-advanced.md +452 -0
- package/.agents/skills/playwright-best-practices/advanced/third-party.md +464 -0
- package/.agents/skills/playwright-best-practices/architecture/pom-vs-fixtures.md +363 -0
- package/.agents/skills/playwright-best-practices/architecture/test-architecture.md +369 -0
- package/.agents/skills/playwright-best-practices/architecture/when-to-mock.md +383 -0
- package/.agents/skills/playwright-best-practices/browser-apis/browser-apis.md +391 -0
- package/.agents/skills/playwright-best-practices/browser-apis/iframes.md +403 -0
- package/.agents/skills/playwright-best-practices/browser-apis/service-workers.md +504 -0
- package/.agents/skills/playwright-best-practices/browser-apis/websockets.md +403 -0
- package/.agents/skills/playwright-best-practices/core/annotations.md +424 -0
- package/.agents/skills/playwright-best-practices/core/assertions-waiting.md +361 -0
- package/.agents/skills/playwright-best-practices/core/configuration.md +452 -0
- package/.agents/skills/playwright-best-practices/core/fixtures-hooks.md +417 -0
- package/.agents/skills/playwright-best-practices/core/global-setup.md +434 -0
- package/.agents/skills/playwright-best-practices/core/locators.md +242 -0
- package/.agents/skills/playwright-best-practices/core/page-object-model.md +315 -0
- package/.agents/skills/playwright-best-practices/core/projects-dependencies.md +453 -0
- package/.agents/skills/playwright-best-practices/core/test-data.md +492 -0
- package/.agents/skills/playwright-best-practices/core/test-suite-structure.md +361 -0
- package/.agents/skills/playwright-best-practices/core/test-tags.md +298 -0
- package/.agents/skills/playwright-best-practices/debugging/console-errors.md +420 -0
- package/.agents/skills/playwright-best-practices/debugging/debugging.md +504 -0
- package/.agents/skills/playwright-best-practices/debugging/error-testing.md +360 -0
- package/.agents/skills/playwright-best-practices/debugging/flaky-tests.md +496 -0
- package/.agents/skills/playwright-best-practices/frameworks/angular.md +530 -0
- package/.agents/skills/playwright-best-practices/frameworks/nextjs.md +469 -0
- package/.agents/skills/playwright-best-practices/frameworks/react.md +531 -0
- package/.agents/skills/playwright-best-practices/frameworks/vue.md +574 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +468 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/docker.md +283 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/github-actions.md +546 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/gitlab.md +397 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/other-providers.md +521 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +371 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/performance.md +453 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/reporting.md +424 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +497 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/accessibility.md +359 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/api-testing.md +719 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/browser-extensions.md +506 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/canvas-webgl.md +493 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/component-testing.md +500 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/drag-drop.md +576 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/electron.md +509 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/file-operations.md +377 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/file-upload-download.md +562 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/forms-validation.md +561 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/graphql-testing.md +331 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/i18n.md +508 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/performance-testing.md +476 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/security-testing.md +430 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/visual-regression.md +634 -0
- package/.agents/skills/security-qa/SKILL.md +254 -0
- package/package.json +3 -1
- package/scripts/gen-and-run.mjs +33 -5
- package/scripts/init.mjs +2 -2
- package/scripts/setup.mjs +2 -2
- package/src/arcalityClient.mjs +4 -3
- package/tests/_helpers/agentic-runner.bundle.spec.js +161 -50
- package/scripts/cleanup-qmsdev.mjs +0 -63
- package/scripts/discover-view.mjs +0 -52
- package/scripts/extract-view.mjs +0 -64
- package/scripts/migrate-to-central-out.mjs +0 -157
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# SKILL: Security QA Analyst
|
|
2
|
+
|
|
3
|
+
You are a Security QA Analyst. Your goal is to identify, validate, classify, and report security findings in the web application under test with precision and low ambiguity.
|
|
4
|
+
|
|
5
|
+
Adopt a hacker mindset, but do not overstate risk. Distinguish clearly between:
|
|
6
|
+
- confirmed vulnerabilities
|
|
7
|
+
- security misconfigurations
|
|
8
|
+
- potential issues
|
|
9
|
+
- informational findings
|
|
10
|
+
|
|
11
|
+
Your reports must help developers and security reviewers understand:
|
|
12
|
+
1. what was detected,
|
|
13
|
+
2. how certain the finding is,
|
|
14
|
+
3. whether exploitation was confirmed,
|
|
15
|
+
4. what evidence supports it,
|
|
16
|
+
5. how to remediate it.
|
|
17
|
+
|
|
18
|
+
## Core Objectives
|
|
19
|
+
|
|
20
|
+
1. Identify security weaknesses in the application.
|
|
21
|
+
2. Validate findings whenever possible before escalating severity.
|
|
22
|
+
3. Classify each finding correctly.
|
|
23
|
+
4. Report findings using a structured JSON attachment.
|
|
24
|
+
5. Avoid false positives and avoid presenting unverified issues as confirmed vulnerabilities.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Classification Rules
|
|
29
|
+
|
|
30
|
+
Every finding MUST be classified as one of the following:
|
|
31
|
+
|
|
32
|
+
### 1. confirmed_vulnerability
|
|
33
|
+
Use this only when there is direct evidence of exploitable behavior or unauthorized access.
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
- XSS payload executed
|
|
37
|
+
- SQL injection altered behavior or response
|
|
38
|
+
- IDOR allowed access to another user's resource
|
|
39
|
+
- Auth bypass allowed access to a protected page
|
|
40
|
+
- Open redirect successfully redirected to an external untrusted domain
|
|
41
|
+
- CSRF was successfully executed or clearly lacks protection in a state-changing action
|
|
42
|
+
|
|
43
|
+
### 2. security_misconfiguration
|
|
44
|
+
Use this when a security control is missing, weak, or improperly configured, but exploitation was not directly demonstrated.
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
- Missing Content-Security-Policy
|
|
48
|
+
- Missing Strict-Transport-Security
|
|
49
|
+
- Missing X-Frame-Options or missing frame-ancestors CSP directive
|
|
50
|
+
- Cookies missing Secure, HttpOnly, or SameSite
|
|
51
|
+
- Overly permissive CORS
|
|
52
|
+
- Sensitive pages cached improperly
|
|
53
|
+
|
|
54
|
+
### 3. potential_issue
|
|
55
|
+
Use this when there is a suspicious condition, but the issue is not fully validated.
|
|
56
|
+
|
|
57
|
+
Examples:
|
|
58
|
+
- Input appears suspicious for XSS but payload execution not confirmed
|
|
59
|
+
- Parameter suggests open redirect but redirect not confirmed
|
|
60
|
+
- Sequential resource IDs suggest possible IDOR but unauthorized access not confirmed
|
|
61
|
+
- Error messages may leak internal info but impact is limited or unclear
|
|
62
|
+
|
|
63
|
+
### 4. informational
|
|
64
|
+
Use this for low-impact observations that are useful but not actionable as vulnerabilities by themselves.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
- Server technology disclosure
|
|
68
|
+
- Minor header omissions with low direct impact
|
|
69
|
+
- Non-sensitive debug indicators
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Confidence Levels
|
|
74
|
+
|
|
75
|
+
Each finding MUST include a confidence field:
|
|
76
|
+
|
|
77
|
+
- high: direct evidence clearly supports the finding
|
|
78
|
+
- medium: evidence is strong but not fully conclusive
|
|
79
|
+
- low: weak signal or heuristic suspicion only
|
|
80
|
+
|
|
81
|
+
Never assign high confidence to a finding with speculative evidence.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Exploitability Status
|
|
86
|
+
|
|
87
|
+
Each finding MUST include exploitability:
|
|
88
|
+
|
|
89
|
+
- confirmed
|
|
90
|
+
- likely
|
|
91
|
+
- unknown
|
|
92
|
+
- not_confirmed
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
- Missing CSP => not_confirmed
|
|
96
|
+
- XSS payload executed => confirmed
|
|
97
|
+
- IDOR suspected from URL pattern only => unknown
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Severity Guidance
|
|
102
|
+
|
|
103
|
+
Severity must reflect actual impact and proof, not just category.
|
|
104
|
+
|
|
105
|
+
### High
|
|
106
|
+
Use for:
|
|
107
|
+
- confirmed unauthorized access
|
|
108
|
+
- confirmed code/script execution
|
|
109
|
+
- sensitive data exposure with real impact
|
|
110
|
+
- auth bypass
|
|
111
|
+
- exploitable SQLi
|
|
112
|
+
- exploitable IDOR
|
|
113
|
+
- confirmed stored/reflected/DOM XSS with meaningful execution
|
|
114
|
+
|
|
115
|
+
### Medium
|
|
116
|
+
Use for:
|
|
117
|
+
- meaningful security misconfigurations
|
|
118
|
+
- missing defense-in-depth controls
|
|
119
|
+
- insecure cookie attributes
|
|
120
|
+
- CSP missing
|
|
121
|
+
- weak CSRF protections not fully exploited
|
|
122
|
+
- permissive CORS with realistic risk
|
|
123
|
+
|
|
124
|
+
### Low
|
|
125
|
+
Use for:
|
|
126
|
+
- low-impact disclosures
|
|
127
|
+
- minor hardening gaps
|
|
128
|
+
- findings with limited impact
|
|
129
|
+
|
|
130
|
+
### Info
|
|
131
|
+
Use for:
|
|
132
|
+
- observations without direct security impact
|
|
133
|
+
|
|
134
|
+
Do not automatically mark missing security headers as High.
|
|
135
|
+
Missing CSP is usually security_misconfiguration and commonly Medium unless stronger contextual evidence justifies otherwise.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Vulnerability Checklist
|
|
140
|
+
|
|
141
|
+
As you navigate and test the application, actively assess the following areas.
|
|
142
|
+
|
|
143
|
+
### Input Fields & Forms
|
|
144
|
+
Check for:
|
|
145
|
+
- reflected XSS
|
|
146
|
+
- stored XSS
|
|
147
|
+
- DOM XSS
|
|
148
|
+
- SQL injection
|
|
149
|
+
- weak input handling
|
|
150
|
+
- insecure file upload behavior
|
|
151
|
+
|
|
152
|
+
When a field looks suspicious for script injection, test carefully.
|
|
153
|
+
Use available XSS testing tooling where applicable.
|
|
154
|
+
|
|
155
|
+
### Navigation & URLs
|
|
156
|
+
Check for:
|
|
157
|
+
- open redirect
|
|
158
|
+
- IDOR
|
|
159
|
+
- auth bypass
|
|
160
|
+
- parameter tampering
|
|
161
|
+
- direct access to protected routes
|
|
162
|
+
|
|
163
|
+
### Data Exposure
|
|
164
|
+
Check for:
|
|
165
|
+
- sensitive data in API responses
|
|
166
|
+
- excessive data exposure
|
|
167
|
+
- tokens or secrets in localStorage/sessionStorage
|
|
168
|
+
- verbose errors
|
|
169
|
+
- stack traces
|
|
170
|
+
- internal paths or implementation details
|
|
171
|
+
- source maps or debug artifacts in production when visible
|
|
172
|
+
|
|
173
|
+
### Authentication & Session Management
|
|
174
|
+
Check for:
|
|
175
|
+
- CSRF protections on state-changing requests
|
|
176
|
+
- weak password policy
|
|
177
|
+
- session fixation
|
|
178
|
+
- insecure session cookies
|
|
179
|
+
- missing cookie flags
|
|
180
|
+
- session not rotated after login
|
|
181
|
+
- user enumeration signals
|
|
182
|
+
|
|
183
|
+
### Security Headers & Browser Protections
|
|
184
|
+
Check for:
|
|
185
|
+
- Content-Security-Policy
|
|
186
|
+
- Strict-Transport-Security
|
|
187
|
+
- X-Frame-Options
|
|
188
|
+
- X-Content-Type-Options
|
|
189
|
+
- Referrer-Policy
|
|
190
|
+
- Permissions-Policy
|
|
191
|
+
- frame-ancestors via CSP where relevant
|
|
192
|
+
|
|
193
|
+
Remember:
|
|
194
|
+
Missing headers usually indicate misconfiguration, not automatically an exploitable vulnerability.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Evidence Standards
|
|
199
|
+
|
|
200
|
+
Every reported finding MUST include evidence appropriate to the type of finding.
|
|
201
|
+
|
|
202
|
+
Evidence should include as many of these as possible:
|
|
203
|
+
- url
|
|
204
|
+
- method
|
|
205
|
+
- selector
|
|
206
|
+
- parameter
|
|
207
|
+
- payload
|
|
208
|
+
- request summary
|
|
209
|
+
- response summary
|
|
210
|
+
- observed behavior
|
|
211
|
+
- storage key
|
|
212
|
+
- cookie attributes
|
|
213
|
+
- screenshot reference if available
|
|
214
|
+
- reproduction steps
|
|
215
|
+
|
|
216
|
+
If exploitation was not confirmed, explicitly state that in the finding.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Required Attachment Format
|
|
221
|
+
|
|
222
|
+
Whenever you identify a finding, you MUST attach it as JSON with the name `security_finding`.
|
|
223
|
+
|
|
224
|
+
Use this exact shape:
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
test.info().attach('security_finding', {
|
|
228
|
+
body: JSON.stringify({
|
|
229
|
+
type: 'security_misconfiguration',
|
|
230
|
+
category: 'Missing Security Header',
|
|
231
|
+
subcategory: 'Content-Security-Policy',
|
|
232
|
+
severity: 'Medium',
|
|
233
|
+
confidence: 'High',
|
|
234
|
+
exploitability: 'not_confirmed',
|
|
235
|
+
status: 'detected',
|
|
236
|
+
description: 'The response does not include a Content-Security-Policy header, reducing defense-in-depth against XSS and malicious script/resource injection.',
|
|
237
|
+
impact: 'If an injection issue exists elsewhere in the application, the lack of CSP may increase exploitability and impact.',
|
|
238
|
+
evidence: {
|
|
239
|
+
url: page.url(),
|
|
240
|
+
missingHeader: 'Content-Security-Policy'
|
|
241
|
+
},
|
|
242
|
+
reproductionSteps: [
|
|
243
|
+
'Navigate to the target page.',
|
|
244
|
+
'Inspect the response headers.',
|
|
245
|
+
'Verify that Content-Security-Policy is absent.'
|
|
246
|
+
],
|
|
247
|
+
remediation: 'Implement a restrictive Content-Security-Policy and avoid unsafe-inline and unsafe-eval where possible.',
|
|
248
|
+
classification: {
|
|
249
|
+
owaspTop10: 'A05:2021 Security Misconfiguration',
|
|
250
|
+
cwe: 'CWE-16'
|
|
251
|
+
}
|
|
252
|
+
}),
|
|
253
|
+
contentType: 'application/json'
|
|
254
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcadialdev/arcality",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.32",
|
|
4
4
|
"description": "AI-powered QA testing tool — Autonomous web testing agent by Arcadial",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"bin/",
|
|
19
19
|
"scripts/",
|
|
20
20
|
"src/",
|
|
21
|
+
".agent/",
|
|
22
|
+
".agents/",
|
|
21
23
|
"tests/_helpers/agentic-runner.bundle.spec.js",
|
|
22
24
|
"tests/_helpers/ArcalityReporter.js",
|
|
23
25
|
"playwright.config.js",
|
package/scripts/gen-and-run.mjs
CHANGED
|
@@ -194,7 +194,7 @@ function showBanner() {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
const ARCALITY_BRAIN_URL = "https://api.anthropic.com/v1/messages";
|
|
197
|
-
const ARCALITY_MODEL = process.env.CLAUDE_MODEL || "claude-
|
|
197
|
+
const ARCALITY_MODEL = process.env.CLAUDE_MODEL || "claude-4-5-sonnet-latest";
|
|
198
198
|
const OUT_DIR = path.join(PROJECT_ROOT, "tests");
|
|
199
199
|
const LOGS_DIR = path.join(PROJECT_ROOT, "logs");
|
|
200
200
|
|
|
@@ -586,7 +586,7 @@ async function main() {
|
|
|
586
586
|
|
|
587
587
|
if (!discoverPath) {
|
|
588
588
|
const knownBaseUrl = projectConfig?.project?.baseUrl || process.env.BASE_URL;
|
|
589
|
-
const promptMsg = knownBaseUrl
|
|
589
|
+
const promptMsg = knownBaseUrl
|
|
590
590
|
? `🌐 Initial navigation path (relative to ${knownBaseUrl}):`
|
|
591
591
|
: '🌐 Full Navigation URL (e.g., http://localhost:3000/):';
|
|
592
592
|
|
|
@@ -623,7 +623,7 @@ async function main() {
|
|
|
623
623
|
if (!validation.valid) {
|
|
624
624
|
const errorMessages = {
|
|
625
625
|
'no_api_key': '🔑 API Key not found.\n Configure it via `arcality init` or in .env (ARCALITY_API_KEY)',
|
|
626
|
-
'invalid_format': '🔑 Invalid API Key. It must start with "
|
|
626
|
+
'invalid_format': '🔑 Invalid API Key. It must start with "arc_"',
|
|
627
627
|
'invalid_api_key': '🔑 API Key not recognized by the server',
|
|
628
628
|
'plan_expired': '💳 Your plan has expired'
|
|
629
629
|
};
|
|
@@ -807,7 +807,22 @@ async function main() {
|
|
|
807
807
|
|
|
808
808
|
// ── End Mission ──
|
|
809
809
|
const { endMission } = await import('../src/arcalityClient.mjs');
|
|
810
|
-
|
|
810
|
+
|
|
811
|
+
let finalUsage = undefined;
|
|
812
|
+
try {
|
|
813
|
+
const ctxDir = process.env.CONTEXT_DIR;
|
|
814
|
+
if (fs.existsSync(ctxDir)) {
|
|
815
|
+
const files = fs.readdirSync(ctxDir);
|
|
816
|
+
const logFiles = files.filter(f => f.startsWith('agent-log-') && f.endsWith('.json')).sort();
|
|
817
|
+
if (logFiles.length > 0) {
|
|
818
|
+
const lastLog = path.join(ctxDir, logFiles[logFiles.length - 1]);
|
|
819
|
+
const logData = JSON.parse(fs.readFileSync(lastLog, 'utf8'));
|
|
820
|
+
finalUsage = logData.usage;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
} catch(e) {}
|
|
824
|
+
|
|
825
|
+
await endMission(mission.mission_id, 'success', finalUsage);
|
|
811
826
|
|
|
812
827
|
// ── Ping Project ──
|
|
813
828
|
await pingProject(finalProjectId, process.env.ARCALITY_API_KEY);
|
|
@@ -866,7 +881,20 @@ async function main() {
|
|
|
866
881
|
// End mission with failure
|
|
867
882
|
try {
|
|
868
883
|
const { endMission } = await import('../src/arcalityClient.mjs');
|
|
869
|
-
|
|
884
|
+
let finalUsage = undefined;
|
|
885
|
+
try {
|
|
886
|
+
const ctxDir = process.env.CONTEXT_DIR;
|
|
887
|
+
if (fs.existsSync(ctxDir)) {
|
|
888
|
+
const files = fs.readdirSync(ctxDir);
|
|
889
|
+
const logFiles = files.filter(f => f.startsWith('agent-log-') && f.endsWith('.json')).sort();
|
|
890
|
+
if (logFiles.length > 0) {
|
|
891
|
+
const lastLog = path.join(ctxDir, logFiles[logFiles.length - 1]);
|
|
892
|
+
const logData = JSON.parse(fs.readFileSync(lastLog, 'utf8'));
|
|
893
|
+
finalUsage = logData.usage;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
} catch(e) {}
|
|
897
|
+
await endMission(mission.mission_id, 'failed', finalUsage);
|
|
870
898
|
} catch { }
|
|
871
899
|
} finally {
|
|
872
900
|
const sRep = spinner();
|
package/scripts/init.mjs
CHANGED
|
@@ -109,10 +109,10 @@ async function main() {
|
|
|
109
109
|
// ── Step 1: API Key ──
|
|
110
110
|
const apiKey = await text({
|
|
111
111
|
message: chalk.cyan('🔑 Enter your Arcality API Key:'),
|
|
112
|
-
placeholder: '
|
|
112
|
+
placeholder: 'arc_live_xxxxx',
|
|
113
113
|
validate: (v) => {
|
|
114
114
|
if (!v || !v.trim()) return 'API Key is required.';
|
|
115
|
-
if (!v.startsWith('
|
|
115
|
+
if (!v.startsWith('arc_')) return 'API Key must start with "arc_"';
|
|
116
116
|
},
|
|
117
117
|
});
|
|
118
118
|
|
package/scripts/setup.mjs
CHANGED
|
@@ -71,8 +71,8 @@ async function main() {
|
|
|
71
71
|
|
|
72
72
|
const newKey = await question(' 👉 Ingresa Arcality API Key (Enter p. mantener): ');
|
|
73
73
|
if (newKey) {
|
|
74
|
-
if (!newKey.startsWith('
|
|
75
|
-
console.log(' ❌ La API Key debe iniciar con "
|
|
74
|
+
if (!newKey.startsWith('arc_')) {
|
|
75
|
+
console.log(' ❌ La API Key debe iniciar con "arc_"');
|
|
76
76
|
process.exit(1);
|
|
77
77
|
}
|
|
78
78
|
config.api_key = newKey;
|
package/src/arcalityClient.mjs
CHANGED
|
@@ -119,7 +119,7 @@ export async function validateApiKey() {
|
|
|
119
119
|
return { valid: false, error: 'no_api_key', mode: 'mock' };
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
if (!key.startsWith('
|
|
122
|
+
if (!key.startsWith('arc_')) {
|
|
123
123
|
return { valid: false, error: 'invalid_format', mode: 'mock' };
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -234,8 +234,9 @@ export async function startMission(prompt, targetUrl) {
|
|
|
234
234
|
* Marks a mission as completed.
|
|
235
235
|
* @param {string} missionId
|
|
236
236
|
* @param {'success'|'failed'|'cancelled'} result
|
|
237
|
+
* @param {object} usage - Optional usage statistics directly from the AI
|
|
237
238
|
*/
|
|
238
|
-
export async function endMission(missionId, result) {
|
|
239
|
+
export async function endMission(missionId, result, usage = null) {
|
|
239
240
|
const apiBase = getEffectiveApiBase();
|
|
240
241
|
if (!apiBase || !missionId) return { ok: true };
|
|
241
242
|
|
|
@@ -247,7 +248,7 @@ export async function endMission(missionId, result) {
|
|
|
247
248
|
'Content-Type': 'application/json',
|
|
248
249
|
'x-api-key': key
|
|
249
250
|
},
|
|
250
|
-
body: JSON.stringify({ result })
|
|
251
|
+
body: JSON.stringify({ result, usage })
|
|
251
252
|
});
|
|
252
253
|
} catch { }
|
|
253
254
|
return { ok: true };
|