@viberaven/cli 1.1.3 → 1.1.5
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/SECURITY.md +53 -53
- package/assets/report/assets/provider-authjs.svg +5 -5
- package/assets/report/assets/provider-aws.svg +5 -5
- package/assets/report/assets/provider-logrocket.svg +4 -4
- package/assets/report/station.css +9 -146
- package/assets/report/station.js +24 -108
- package/dist/cli.js +811 -1927
- package/dist/cli.js.map +4 -4
- package/dist/report/assets/provider-authjs.svg +5 -5
- package/dist/report/assets/provider-aws.svg +5 -5
- package/dist/report/assets/provider-logrocket.svg +4 -4
- package/dist/report/station.css +9 -146
- package/dist/report/station.js +24 -108
- package/package.json +1 -2
- package/fixtures/demo-saas/.env.example +0 -3
- package/fixtures/demo-saas/app/api/stripe/webhook/route.ts +0 -12
- package/fixtures/demo-saas/package.json +0 -11
- package/fixtures/demo-saas/supabase/migrations/0001_init.sql +0 -6
package/SECURITY.md
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
# Security - `@viberaven/cli`
|
|
2
|
-
|
|
3
|
-
## Managed Scan Boundary
|
|
4
|
-
|
|
5
|
-
The npm CLI does not read `OPENAI_API_KEY` and does not accept a bring-your-own-key scan path. Scans use the VibeRaven managed API after device login, same as the signed-in VS Code extension.
|
|
6
|
-
|
|
7
|
-
- API keys for model calls live on the server, not in the published npm package.
|
|
8
|
-
- Local credentials store only a VibeRaven access token in `%APPDATA%\viberaven\credentials.json` or `~/.config/viberaven/`.
|
|
9
|
-
- Never commit `credentials.json` or paste tokens into chat.
|
|
10
|
-
|
|
11
|
-
## Safe Commands
|
|
12
|
-
|
|
13
|
-
Human terminal:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npx -y viberaven
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Agent or CI gate:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npx -y viberaven --agent-mode
|
|
23
|
-
npx -y viberaven --verify
|
|
24
|
-
npx -y viberaven --strict
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
VibeRaven is the Agent Context + Production Gate. Agents should read `.viberaven/agent-tasklist.md`, `.viberaven/gate-result.json`, and `.viberaven/context-map.json` before claiming an app is safe to deploy.
|
|
28
|
-
|
|
29
|
-
## Written Artifacts
|
|
30
|
-
|
|
31
|
-
After a scan, the CLI may create:
|
|
32
|
-
|
|
33
|
-
| Path | Contents |
|
|
34
|
-
|------|----------|
|
|
35
|
-
| `.viberaven/last-scan.json` | Full scan payload |
|
|
36
|
-
| `.viberaven/agent-tasklist.md` | Agent tasklist |
|
|
37
|
-
| `.viberaven/gate-result.json` | Machine gate verdict |
|
|
38
|
-
| `.viberaven/context-map.json` | Compact agent context |
|
|
39
|
-
| `.viberaven/gaps/<gapId>.json` | Per-gap evidence |
|
|
40
|
-
| `.viberaven/agent-summary.md` | Human/agent summary |
|
|
41
|
-
| `.viberaven/launch-playbook.md` | Launch checklist |
|
|
42
|
-
| `.viberaven/report.html` | Local HTML report |
|
|
43
|
-
|
|
44
|
-
Repo scanners redact common key patterns in evidence strings; the CLI runs an extra redaction pass before writing files.
|
|
45
|
-
|
|
46
|
-
## Provider Boundaries
|
|
47
|
-
|
|
48
|
-
Provider dashboard checks are not cleared by repo-code edits. Billing/product configuration, DNS, webhooks, credentials, quotas, and live provider verification must be completed or verified in the provider dashboard or through read-only provider evidence.
|
|
49
|
-
|
|
50
|
-
## Reporting Issues
|
|
51
|
-
|
|
52
|
-
If you believe a scan artifact leaked a secret, rotate the key immediately and open an issue at https://github.com/ohad6k/VibeRaven/issues with the redacted file path only.
|
|
53
|
-
|
|
1
|
+
# Security - `@viberaven/cli`
|
|
2
|
+
|
|
3
|
+
## Managed Scan Boundary
|
|
4
|
+
|
|
5
|
+
The npm CLI does not read `OPENAI_API_KEY` and does not accept a bring-your-own-key scan path. Scans use the VibeRaven managed API after device login, same as the signed-in VS Code extension.
|
|
6
|
+
|
|
7
|
+
- API keys for model calls live on the server, not in the published npm package.
|
|
8
|
+
- Local credentials store only a VibeRaven access token in `%APPDATA%\viberaven\credentials.json` or `~/.config/viberaven/`.
|
|
9
|
+
- Never commit `credentials.json` or paste tokens into chat.
|
|
10
|
+
|
|
11
|
+
## Safe Commands
|
|
12
|
+
|
|
13
|
+
Human terminal:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx -y viberaven
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Agent or CI gate:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y viberaven --agent-mode
|
|
23
|
+
npx -y viberaven --verify
|
|
24
|
+
npx -y viberaven --strict
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
VibeRaven is the Agent Context + Production Gate. Agents should read `.viberaven/agent-tasklist.md`, `.viberaven/gate-result.json`, and `.viberaven/context-map.json` before claiming an app is safe to deploy.
|
|
28
|
+
|
|
29
|
+
## Written Artifacts
|
|
30
|
+
|
|
31
|
+
After a scan, the CLI may create:
|
|
32
|
+
|
|
33
|
+
| Path | Contents |
|
|
34
|
+
|------|----------|
|
|
35
|
+
| `.viberaven/last-scan.json` | Full scan payload |
|
|
36
|
+
| `.viberaven/agent-tasklist.md` | Agent tasklist |
|
|
37
|
+
| `.viberaven/gate-result.json` | Machine gate verdict |
|
|
38
|
+
| `.viberaven/context-map.json` | Compact agent context |
|
|
39
|
+
| `.viberaven/gaps/<gapId>.json` | Per-gap evidence |
|
|
40
|
+
| `.viberaven/agent-summary.md` | Human/agent summary |
|
|
41
|
+
| `.viberaven/launch-playbook.md` | Launch checklist |
|
|
42
|
+
| `.viberaven/report.html` | Local HTML report |
|
|
43
|
+
|
|
44
|
+
Repo scanners redact common key patterns in evidence strings; the CLI runs an extra redaction pass before writing files.
|
|
45
|
+
|
|
46
|
+
## Provider Boundaries
|
|
47
|
+
|
|
48
|
+
Provider dashboard checks are not cleared by repo-code edits. Billing/product configuration, DNS, webhooks, credentials, quotas, and live provider verification must be completed or verified in the provider dashboard or through read-only provider evidence.
|
|
49
|
+
|
|
50
|
+
## Reporting Issues
|
|
51
|
+
|
|
52
|
+
If you believe a scan artifact leaked a secret, rotate the key immediately and open an issue at https://github.com/ohad6k/VibeRaven/issues with the redacted file path only.
|
|
53
|
+
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
|
|
2
|
-
<path fill="#412991" d="M32 5 11 16.8v13.7c0 12.2 8.9 23.3 21 27 12.1-3.7 21-14.8 21-27V16.8L32 5Z"/>
|
|
3
|
-
<path fill="#EB5424" d="M32 5v48.7c-3.1-1.1-6.1-2.7-8.7-4.7L32 5Z"/>
|
|
4
|
-
<path fill="#FBC22C" d="m32 5 8.7 44c-2.6 2-5.6 3.6-8.7 4.7V5Z"/>
|
|
5
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
|
|
2
|
+
<path fill="#412991" d="M32 5 11 16.8v13.7c0 12.2 8.9 23.3 21 27 12.1-3.7 21-14.8 21-27V16.8L32 5Z"/>
|
|
3
|
+
<path fill="#EB5424" d="M32 5v48.7c-3.1-1.1-6.1-2.7-8.7-4.7L32 5Z"/>
|
|
4
|
+
<path fill="#FBC22C" d="m32 5 8.7 44c-2.6 2-5.6 3.6-8.7 4.7V5Z"/>
|
|
5
|
+
</svg>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 64" aria-hidden="true">
|
|
2
|
-
<text x="48" y="31" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="21" font-weight="800" letter-spacing="-1.4" fill="#111827">AWS</text>
|
|
3
|
-
<path fill="#FF9900" d="M23.6 42.4c13.9 7.5 31.5 7.5 45.1-.1 1.1-.6 2.2.8 1.3 1.7-12.3 12.5-34.3 12.6-47.2.8-.9-.8-.3-2.9.8-2.4Z"/>
|
|
4
|
-
<path fill="#FF9900" d="M66.8 39.8c2.4-.3 7.8-.8 8.8 1 .9 1.6-1 5.8-2.5 8.2-.5.8-1.7.4-1.5-.6.5-2.1 1.3-4.8.5-5.8-.8-1-3.8-.8-5.4-.6-1 .1-1.2-2-.1-2.2h.2Z"/>
|
|
5
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 64" aria-hidden="true">
|
|
2
|
+
<text x="48" y="31" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="21" font-weight="800" letter-spacing="-1.4" fill="#111827">AWS</text>
|
|
3
|
+
<path fill="#FF9900" d="M23.6 42.4c13.9 7.5 31.5 7.5 45.1-.1 1.1-.6 2.2.8 1.3 1.7-12.3 12.5-34.3 12.6-47.2.8-.9-.8-.3-2.9.8-2.4Z"/>
|
|
4
|
+
<path fill="#FF9900" d="M66.8 39.8c2.4-.3 7.8-.8 8.8 1 .9 1.6-1 5.8-2.5 8.2-.5.8-1.7.4-1.5-.6.5-2.1 1.3-4.8.5-5.8-.8-1-3.8-.8-5.4-.6-1 .1-1.2-2-.1-2.2h.2Z"/>
|
|
5
|
+
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
|
|
2
|
-
<path fill="#764ABC" fill-rule="evenodd" clip-rule="evenodd" d="M26.8 12.9A20.8 20.8 0 0 1 32.3 7a20.5 20.5 0 0 1 5.5 5.8 29.3 29.3 0 0 1 5.1 17.1c1.1.9 2.3 1.8 3.4 2.7a6.2 6.2 0 0 1 2 5.7c-.5 2.6-1.1 5.2-1.6 7.8a2.2 2.2 0 0 1-3.3 1.1c-1.8-1.5-3.6-3-5.4-4.5a8.4 8.4 0 0 1-5.2 2.3 8.5 8.5 0 0 1-6.1-2.2c-1.3 1-2.5 2.1-3.8 3.2-.6.6-1.2 1-1.9 1.4a2.2 2.2 0 0 1-2.9-1.4c-.6-2.5-1.2-5.1-1.8-7.6a6.3 6.3 0 0 1 2.1-6c1-.8 2-1.6 3-2.3.3-.2.1-.5.2-.7a29.3 29.3 0 0 1 5.2-16.5Zm2.2 8.2a4.3 4.3 0 0 0 .4 5.8 4.8 4.8 0 0 0 6.5.1 4.3 4.3 0 0 0 1.1-4.8 4.4 4.4 0 0 0-3.9-2.9 4.5 4.5 0 0 0-4.1 1.8Zm3.3 4.9a2.1 2.1 0 1 0 0-4.2 2.1 2.1 0 0 0 0 4.2Z"/>
|
|
3
|
-
<path fill="#764ABC" d="M26.4 48.1a1.1 1.1 0 0 1 1.6-.9 10.4 10.4 0 0 0 9 0 1.1 1.1 0 0 1 1.6.8v4.8a1.1 1.1 0 0 1-1.7.8c-.5-.4-.9-.9-1.4-1.3-.7 1.4-1.4 2.8-2.1 4.1a1.1 1.1 0 0 1-1.8 0c-.8-1.4-1.4-2.8-2.2-4.1-.4.4-.9.9-1.3 1.3a1.1 1.1 0 0 1-1.7-.8v-4.7Z"/>
|
|
4
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
|
|
2
|
+
<path fill="#764ABC" fill-rule="evenodd" clip-rule="evenodd" d="M26.8 12.9A20.8 20.8 0 0 1 32.3 7a20.5 20.5 0 0 1 5.5 5.8 29.3 29.3 0 0 1 5.1 17.1c1.1.9 2.3 1.8 3.4 2.7a6.2 6.2 0 0 1 2 5.7c-.5 2.6-1.1 5.2-1.6 7.8a2.2 2.2 0 0 1-3.3 1.1c-1.8-1.5-3.6-3-5.4-4.5a8.4 8.4 0 0 1-5.2 2.3 8.5 8.5 0 0 1-6.1-2.2c-1.3 1-2.5 2.1-3.8 3.2-.6.6-1.2 1-1.9 1.4a2.2 2.2 0 0 1-2.9-1.4c-.6-2.5-1.2-5.1-1.8-7.6a6.3 6.3 0 0 1 2.1-6c1-.8 2-1.6 3-2.3.3-.2.1-.5.2-.7a29.3 29.3 0 0 1 5.2-16.5Zm2.2 8.2a4.3 4.3 0 0 0 .4 5.8 4.8 4.8 0 0 0 6.5.1 4.3 4.3 0 0 0 1.1-4.8 4.4 4.4 0 0 0-3.9-2.9 4.5 4.5 0 0 0-4.1 1.8Zm3.3 4.9a2.1 2.1 0 1 0 0-4.2 2.1 2.1 0 0 0 0 4.2Z"/>
|
|
3
|
+
<path fill="#764ABC" d="M26.4 48.1a1.1 1.1 0 0 1 1.6-.9 10.4 10.4 0 0 0 9 0 1.1 1.1 0 0 1 1.6.8v4.8a1.1 1.1 0 0 1-1.7.8c-.5-.4-.9-.9-1.4-1.3-.7 1.4-1.4 2.8-2.1 4.1a1.1 1.1 0 0 1-1.8 0c-.8-1.4-1.4-2.8-2.2-4.1-.4.4-.9.9-1.3 1.3a1.1 1.1 0 0 1-1.7-.8v-4.7Z"/>
|
|
4
|
+
</svg>
|
|
@@ -5402,152 +5402,15 @@ body.station-results-active .studio-node__logo:not(.provider-logo--brand) svg pa
|
|
|
5402
5402
|
background: rgba(3, 8, 13, 0.94);
|
|
5403
5403
|
}
|
|
5404
5404
|
|
|
5405
|
-
.studio-top-rail__build,
|
|
5406
|
-
.studio-top-rail__brand {
|
|
5407
|
-
color: rgba(63, 224, 244, 0.9);
|
|
5408
|
-
}
|
|
5409
|
-
|
|
5410
|
-
.studio-
|
|
5411
|
-
|
|
5412
|
-
grid-template-columns: minmax(0, 1fr)
|
|
5413
|
-
|
|
5414
|
-
align-items: stretch;
|
|
5415
|
-
padding: 12px 14px;
|
|
5416
|
-
border-bottom: 1px solid rgba(32, 214, 237, 0.16);
|
|
5417
|
-
background:
|
|
5418
|
-
radial-gradient(circle at 8% 20%, rgba(63, 224, 244, 0.15), transparent 34%),
|
|
5419
|
-
linear-gradient(135deg, rgba(5, 18, 28, 0.96), rgba(2, 8, 13, 0.98));
|
|
5420
|
-
}
|
|
5421
|
-
|
|
5422
|
-
.studio-launch-hero__main,
|
|
5423
|
-
.studio-launch-hero__next {
|
|
5424
|
-
display: grid;
|
|
5425
|
-
min-width: 0;
|
|
5426
|
-
align-content: center;
|
|
5427
|
-
}
|
|
5428
|
-
|
|
5429
|
-
.studio-launch-hero__main {
|
|
5430
|
-
gap: 8px;
|
|
5431
|
-
}
|
|
5432
|
-
|
|
5433
|
-
.studio-launch-hero__next {
|
|
5434
|
-
gap: 7px;
|
|
5435
|
-
padding: 10px 11px;
|
|
5436
|
-
border: 1px solid rgba(63, 224, 244, 0.16);
|
|
5437
|
-
border-radius: 8px;
|
|
5438
|
-
background: rgba(1, 6, 10, 0.62);
|
|
5439
|
-
}
|
|
5440
|
-
|
|
5441
|
-
.studio-launch-hero__wordmark {
|
|
5442
|
-
margin: 0;
|
|
5443
|
-
color: rgba(232, 250, 255, 0.92);
|
|
5444
|
-
font-size: 11px;
|
|
5445
|
-
font-weight: 900;
|
|
5446
|
-
letter-spacing: 0.14em;
|
|
5447
|
-
text-transform: uppercase;
|
|
5448
|
-
}
|
|
5449
|
-
|
|
5450
|
-
.studio-launch-hero__decision {
|
|
5451
|
-
display: inline-flex;
|
|
5452
|
-
align-items: center;
|
|
5453
|
-
width: max-content;
|
|
5454
|
-
max-width: 100%;
|
|
5455
|
-
min-height: 30px;
|
|
5456
|
-
padding: 6px 11px;
|
|
5457
|
-
border: 1px solid rgba(239, 68, 68, 0.35);
|
|
5458
|
-
border-radius: 999px;
|
|
5459
|
-
background: rgba(40, 12, 12, 0.46);
|
|
5460
|
-
color: #fecaca;
|
|
5461
|
-
font-size: 12px;
|
|
5462
|
-
font-weight: 900;
|
|
5463
|
-
letter-spacing: 0.08em;
|
|
5464
|
-
line-height: 1;
|
|
5465
|
-
text-transform: uppercase;
|
|
5466
|
-
overflow-wrap: anywhere;
|
|
5467
|
-
}
|
|
5468
|
-
|
|
5469
|
-
.studio-launch-hero__decision--warning {
|
|
5470
|
-
border-color: rgba(245, 158, 11, 0.42);
|
|
5471
|
-
background: rgba(40, 28, 8, 0.5);
|
|
5472
|
-
color: #fde68a;
|
|
5473
|
-
}
|
|
5474
|
-
|
|
5475
|
-
.studio-launch-hero__decision--clear {
|
|
5476
|
-
border-color: rgba(74, 222, 128, 0.38);
|
|
5477
|
-
background: rgba(8, 32, 18, 0.52);
|
|
5478
|
-
color: #bbf7d0;
|
|
5479
|
-
}
|
|
5480
|
-
|
|
5481
|
-
.studio-launch-hero__gauge {
|
|
5482
|
-
height: 8px;
|
|
5483
|
-
overflow: hidden;
|
|
5484
|
-
border-radius: 999px;
|
|
5485
|
-
background: rgba(255, 255, 255, 0.08);
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5488
|
-
.studio-launch-hero__gauge-fill {
|
|
5489
|
-
display: block;
|
|
5490
|
-
height: 100%;
|
|
5491
|
-
border-radius: inherit;
|
|
5492
|
-
background: #ef4444;
|
|
5493
|
-
transition: width 0.35s var(--vr-ease-out);
|
|
5494
|
-
}
|
|
5495
|
-
|
|
5496
|
-
.studio-launch-hero__gauge-fill--warning {
|
|
5497
|
-
background: #f59e0b;
|
|
5498
|
-
}
|
|
5499
|
-
|
|
5500
|
-
.studio-launch-hero__gauge-fill--clear {
|
|
5501
|
-
background: #4ade80;
|
|
5502
|
-
}
|
|
5503
|
-
|
|
5504
|
-
.studio-launch-hero__next-label {
|
|
5505
|
-
color: rgba(232, 250, 255, 0.58);
|
|
5506
|
-
font-size: 9px;
|
|
5507
|
-
font-weight: 900;
|
|
5508
|
-
letter-spacing: 0.12em;
|
|
5509
|
-
line-height: 1;
|
|
5510
|
-
text-transform: uppercase;
|
|
5511
|
-
}
|
|
5512
|
-
|
|
5513
|
-
.studio-launch-hero__next strong {
|
|
5514
|
-
min-width: 0;
|
|
5515
|
-
color: rgba(248, 252, 255, 0.95);
|
|
5516
|
-
font-size: 12px;
|
|
5517
|
-
font-weight: 850;
|
|
5518
|
-
line-height: 1.25;
|
|
5519
|
-
overflow-wrap: anywhere;
|
|
5520
|
-
}
|
|
5521
|
-
|
|
5522
|
-
.studio-launch-hero__verify {
|
|
5523
|
-
justify-self: start;
|
|
5524
|
-
min-height: 30px;
|
|
5525
|
-
padding: 0 10px;
|
|
5526
|
-
border: 1px solid rgba(63, 224, 244, 0.32);
|
|
5527
|
-
border-radius: 7px;
|
|
5528
|
-
background: rgba(63, 224, 244, 0.1);
|
|
5529
|
-
color: rgba(232, 250, 255, 0.92);
|
|
5530
|
-
font: 800 10px/1 var(--font-ui);
|
|
5531
|
-
letter-spacing: 0.07em;
|
|
5532
|
-
text-transform: uppercase;
|
|
5533
|
-
}
|
|
5534
|
-
|
|
5535
|
-
.studio-launch-hero__verify:hover,
|
|
5536
|
-
.studio-launch-hero__verify:focus-visible {
|
|
5537
|
-
border-color: rgba(63, 224, 244, 0.52);
|
|
5538
|
-
background: rgba(63, 224, 244, 0.16);
|
|
5539
|
-
}
|
|
5540
|
-
|
|
5541
|
-
@media (max-width: 620px) {
|
|
5542
|
-
.studio-launch-hero {
|
|
5543
|
-
grid-template-columns: minmax(0, 1fr);
|
|
5544
|
-
}
|
|
5545
|
-
}
|
|
5546
|
-
|
|
5547
|
-
.studio-workspace {
|
|
5548
|
-
position: relative;
|
|
5549
|
-
grid-template-columns: 52px minmax(0, 1fr);
|
|
5550
|
-
}
|
|
5405
|
+
.studio-top-rail__build,
|
|
5406
|
+
.studio-top-rail__brand {
|
|
5407
|
+
color: rgba(63, 224, 244, 0.9);
|
|
5408
|
+
}
|
|
5409
|
+
|
|
5410
|
+
.studio-workspace {
|
|
5411
|
+
position: relative;
|
|
5412
|
+
grid-template-columns: 52px minmax(0, 1fr);
|
|
5413
|
+
}
|
|
5551
5414
|
|
|
5552
5415
|
.studio-nav-rail {
|
|
5553
5416
|
border-right-color: rgba(32, 214, 237, 0.14);
|
package/assets/report/station.js
CHANGED
|
@@ -6670,99 +6670,18 @@ function applyScanStage(stage) {
|
|
|
6670
6670
|
}
|
|
6671
6671
|
}
|
|
6672
6672
|
|
|
6673
|
-
function setTextById(id, text) {
|
|
6674
|
-
const element = document.getElementById(id);
|
|
6675
|
-
if (element) {
|
|
6676
|
-
element.textContent = String(text || '');
|
|
6677
|
-
}
|
|
6678
|
-
}
|
|
6679
|
-
|
|
6680
|
-
function
|
|
6681
|
-
const
|
|
6682
|
-
if (
|
|
6683
|
-
return
|
|
6684
|
-
}
|
|
6685
|
-
if (raw === 'warning' || raw === 'warn') {
|
|
6686
|
-
return 'WARNING';
|
|
6687
|
-
}
|
|
6688
|
-
if (raw === 'blocked' || raw === 'block' || raw === 'not_clear' || raw === 'needs_work' || raw === 'fail' || raw === 'failed') {
|
|
6689
|
-
return 'BLOCKED';
|
|
6690
|
-
}
|
|
6691
|
-
return '';
|
|
6692
|
-
}
|
|
6693
|
-
|
|
6694
|
-
function resolveLaunchHeroDecision(payload, score, gaps) {
|
|
6695
|
-
const explicitDecision = isRecord(payload)
|
|
6696
|
-
? normalizeLaunchHeroDecision(payload.decision) ||
|
|
6697
|
-
normalizeLaunchHeroDecision(payload.gateStatus) ||
|
|
6698
|
-
normalizeLaunchHeroDecision(payload.status) ||
|
|
6699
|
-
(isRecord(payload.productionGate) ? normalizeLaunchHeroDecision(payload.productionGate.status) : '') ||
|
|
6700
|
-
(isRecord(payload.gateResult)
|
|
6701
|
-
? normalizeLaunchHeroDecision(payload.gateResult.status) ||
|
|
6702
|
-
(isRecord(payload.gateResult.gate) ? normalizeLaunchHeroDecision(payload.gateResult.gate.status) : '')
|
|
6703
|
-
: '')
|
|
6704
|
-
: '';
|
|
6705
|
-
if (explicitDecision) {
|
|
6706
|
-
return explicitDecision;
|
|
6707
|
-
}
|
|
6708
|
-
|
|
6709
|
-
const gapCount = Array.isArray(gaps) ? gaps.length : 0;
|
|
6710
|
-
if (Array.isArray(gaps) && gaps.some(function (gap) { return isRecord(gap) && readString(gap.severity).toLowerCase() === 'critical'; })) {
|
|
6711
|
-
return 'BLOCKED';
|
|
6712
|
-
}
|
|
6713
|
-
if (gapCount > 0) {
|
|
6714
|
-
return 'WARNING';
|
|
6715
|
-
}
|
|
6716
|
-
if (score >= 90 && gapCount === 0) {
|
|
6717
|
-
return 'CLEAR';
|
|
6718
|
-
}
|
|
6719
|
-
if (score >= 70) {
|
|
6720
|
-
return 'WARNING';
|
|
6721
|
-
}
|
|
6722
|
-
return 'BLOCKED';
|
|
6723
|
-
}
|
|
6724
|
-
|
|
6725
|
-
function resolveLaunchHeroNextAction(decision, gaps) {
|
|
6726
|
-
const firstGap = Array.isArray(gaps) && isRecord(gaps[0]) ? gaps[0] : null;
|
|
6727
|
-
const firstTitle = firstGap ? readString(firstGap.title) : '';
|
|
6728
|
-
if (firstTitle) {
|
|
6729
|
-
return firstTitle;
|
|
6730
|
-
}
|
|
6731
|
-
if (decision === 'CLEAR') {
|
|
6732
|
-
return 'Share the VibeRaven proof card.';
|
|
6733
|
-
}
|
|
6734
|
-
if (decision === 'WARNING') {
|
|
6735
|
-
return 'Run verify after applying the remaining fixes.';
|
|
6736
|
-
}
|
|
6737
|
-
return 'Run a scan to map production gaps.';
|
|
6738
|
-
}
|
|
6739
|
-
|
|
6740
|
-
function updateLaunchHero(decision, score, nextAction) {
|
|
6741
|
-
const normalizedDecision = decision === 'CLEAR' || decision === 'WARNING' ? decision : 'BLOCKED';
|
|
6742
|
-
const normalizedScore = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
6743
|
-
const toneClass = normalizedDecision === 'CLEAR'
|
|
6744
|
-
? 'clear'
|
|
6745
|
-
: normalizedDecision === 'WARNING'
|
|
6746
|
-
? 'warning'
|
|
6747
|
-
: 'blocked';
|
|
6748
|
-
const decisionEl = document.getElementById('studio-launch-decision');
|
|
6749
|
-
if (decisionEl) {
|
|
6750
|
-
decisionEl.className = 'studio-launch-hero__decision studio-launch-hero__decision--' + toneClass;
|
|
6751
|
-
decisionEl.textContent = (normalizedDecision === 'CLEAR' ? '\u25c6 ' : '\u25c7 ') + normalizedDecision;
|
|
6752
|
-
}
|
|
6753
|
-
const gaugeFill = document.getElementById('studio-launch-gauge-fill');
|
|
6754
|
-
if (gaugeFill) {
|
|
6755
|
-
gaugeFill.className = 'studio-launch-hero__gauge-fill studio-launch-hero__gauge-fill--' + toneClass;
|
|
6756
|
-
gaugeFill.style.width = normalizedScore + '%';
|
|
6757
|
-
}
|
|
6758
|
-
setTextById('studio-launch-next-action', nextAction || resolveLaunchHeroNextAction(normalizedDecision, []));
|
|
6759
|
-
}
|
|
6760
|
-
|
|
6761
|
-
function setResultsBar(score) {
|
|
6762
|
-
const bar = document.getElementById('mc-results-bar');
|
|
6763
|
-
if (!bar) {
|
|
6764
|
-
return;
|
|
6765
|
-
}
|
|
6673
|
+
function setTextById(id, text) {
|
|
6674
|
+
const element = document.getElementById(id);
|
|
6675
|
+
if (element) {
|
|
6676
|
+
element.textContent = String(text || '');
|
|
6677
|
+
}
|
|
6678
|
+
}
|
|
6679
|
+
|
|
6680
|
+
function setResultsBar(score) {
|
|
6681
|
+
const bar = document.getElementById('mc-results-bar');
|
|
6682
|
+
if (!bar) {
|
|
6683
|
+
return;
|
|
6684
|
+
}
|
|
6766
6685
|
bar.style.width = score + '%';
|
|
6767
6686
|
bar.setAttribute('aria-valuenow', String(score));
|
|
6768
6687
|
bar.classList.remove('mc-bar-fill--amber', 'mc-bar-fill--green');
|
|
@@ -6828,14 +6747,13 @@ function renderMissionControl(payload, options) {
|
|
|
6828
6747
|
}
|
|
6829
6748
|
clearProductionChrome();
|
|
6830
6749
|
setSection('spec-update', null);
|
|
6831
|
-
if (specNotes instanceof HTMLElement) {
|
|
6832
|
-
specNotes.hidden = true;
|
|
6833
|
-
}
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
}
|
|
6750
|
+
if (specNotes instanceof HTMLElement) {
|
|
6751
|
+
specNotes.hidden = true;
|
|
6752
|
+
}
|
|
6753
|
+
announceMissionControlReadout(payload, 0, true);
|
|
6754
|
+
showMcState('results');
|
|
6755
|
+
return;
|
|
6756
|
+
}
|
|
6839
6757
|
|
|
6840
6758
|
// Success path — new schema
|
|
6841
6759
|
if (mcResults instanceof HTMLElement) {
|
|
@@ -6858,11 +6776,9 @@ function renderMissionControl(payload, options) {
|
|
|
6858
6776
|
mainBar.setAttribute('aria-valuenow', String(score));
|
|
6859
6777
|
mainBar.classList.remove('mc-bar-fill--amber', 'mc-bar-fill--green');
|
|
6860
6778
|
}
|
|
6861
|
-
|
|
6862
|
-
const gaps = Array.isArray(payload.gaps) ? payload.gaps : [];
|
|
6863
|
-
const
|
|
6864
|
-
updateLaunchHero(launchDecision, score, resolveLaunchHeroNextAction(launchDecision, gaps));
|
|
6865
|
-
const fullSummary = typeof payload.summary === 'string' ? payload.summary.replace(/\s+/g, ' ').trim() : '';
|
|
6779
|
+
|
|
6780
|
+
const gaps = Array.isArray(payload.gaps) ? payload.gaps : [];
|
|
6781
|
+
const fullSummary = typeof payload.summary === 'string' ? payload.summary.replace(/\s+/g, ' ').trim() : '';
|
|
6866
6782
|
/* Cap only for pathological payload size; normal summaries show in full in the panel. */
|
|
6867
6783
|
const maxSummary = 4000;
|
|
6868
6784
|
const summary = fullSummary.length > maxSummary ? fullSummary.slice(0, maxSummary - 1).replace(/\s+\S*$/, '') + '\u2026' : fullSummary;
|
|
@@ -7358,9 +7274,9 @@ function buildAgentPromptText(payload, nextMove, missing, files) {
|
|
|
7358
7274
|
|
|
7359
7275
|
function buildChecklistText(payload, nextMove, missing, files) {
|
|
7360
7276
|
const lines = [
|
|
7361
|
-
'# VibeRaven production checklist',
|
|
7277
|
+
'# VibeRaven production checklist',
|
|
7362
7278
|
'',
|
|
7363
|
-
'Generated from the latest VibeRaven run.',
|
|
7279
|
+
'Generated from the latest VibeRaven run.',
|
|
7364
7280
|
'',
|
|
7365
7281
|
'## Next move',
|
|
7366
7282
|
'',
|