@viberaven/cli 0.1.0-beta.2 → 0.1.0-beta.3
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 +10 -4
- package/dist/cli.js +108 -6
- package/dist/cli.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,15 +5,21 @@ Launch readiness for Claude Code, Codex, and other coding agents — same missio
|
|
|
5
5
|
## For humans
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx -y @viberaven/cli@beta login
|
|
9
|
-
npx -y @viberaven/cli@beta
|
|
10
|
-
|
|
8
|
+
npx -y @viberaven/cli@beta login
|
|
9
|
+
npx -y @viberaven/cli@beta status
|
|
10
|
+
npx -y @viberaven/cli@beta scan --open
|
|
11
|
+
```
|
|
11
12
|
|
|
12
13
|
Sign in once, then scan with `--open` to view `.viberaven/report.html` in the browser (same editorial Mission Map skin as the extension). Or run **`viberaven`** with no args for the interactive terminal menu.
|
|
13
14
|
|
|
14
15
|
Uses the **same VibeRaven account and scan quota** as the VS Code extension. **Does not use your `OPENAI_API_KEY`** — scans go through the managed API after login. See [SECURITY.md](./SECURITY.md).
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Quota:
|
|
18
|
+
|
|
19
|
+
- Free: 2 lifetime scans
|
|
20
|
+
- Pro: 50 scans per month
|
|
21
|
+
|
|
22
|
+
## For coding agents
|
|
17
23
|
|
|
18
24
|
Use VibeRaven when the user asks whether an AI-built app is launch-ready, production-ready, or missing auth/database/payments/deployment/security work.
|
|
19
25
|
|
package/dist/cli.js
CHANGED
|
@@ -162,6 +162,7 @@ var require_src = __commonJS({
|
|
|
162
162
|
// src/cli.ts
|
|
163
163
|
var cli_exports = {};
|
|
164
164
|
__export(cli_exports, {
|
|
165
|
+
buildHelpText: () => buildHelpText,
|
|
165
166
|
formatScanJsonStdout: () => formatScanJsonStdout,
|
|
166
167
|
parseArgs: () => parseArgs
|
|
167
168
|
});
|
|
@@ -8582,6 +8583,56 @@ var PANEL_CLIENT_SCRIPT = `
|
|
|
8582
8583
|
|
|
8583
8584
|
|
|
8584
8585
|
|
|
8586
|
+
function isLockedArea(areaKey) {
|
|
8587
|
+
|
|
8588
|
+
var nodes = document.querySelectorAll('.studio-node');
|
|
8589
|
+
|
|
8590
|
+
for (var i = 0; i < nodes.length; i += 1) {
|
|
8591
|
+
|
|
8592
|
+
if (nodes[i].getAttribute('data-area-key') === areaKey) {
|
|
8593
|
+
|
|
8594
|
+
return nodes[i].getAttribute('data-locked-map') === '1';
|
|
8595
|
+
|
|
8596
|
+
}
|
|
8597
|
+
|
|
8598
|
+
}
|
|
8599
|
+
|
|
8600
|
+
return false;
|
|
8601
|
+
|
|
8602
|
+
}
|
|
8603
|
+
|
|
8604
|
+
|
|
8605
|
+
|
|
8606
|
+
function lockedAreaHtml(label) {
|
|
8607
|
+
|
|
8608
|
+
return '<div class="studio-setup-panel__inner studio-setup-panel__inner--locked">' +
|
|
8609
|
+
|
|
8610
|
+
'<div class="studio-setup-panel__head">' +
|
|
8611
|
+
|
|
8612
|
+
'<div class="studio-setup-panel__title"><strong>Upgrade to Pro</strong><span>Full mission map</span></div>' +
|
|
8613
|
+
|
|
8614
|
+
'</div>' +
|
|
8615
|
+
|
|
8616
|
+
'<section class="studio-setup-actions studio-setup-actions--locked" aria-label="Locked Pro section">' +
|
|
8617
|
+
|
|
8618
|
+
'<div class="studio-setup-actions__head">' +
|
|
8619
|
+
|
|
8620
|
+
'<span class="studio-setup-actions__logo provider-logo" aria-hidden="true">' + logoHtml('', label) + '</span>' +
|
|
8621
|
+
|
|
8622
|
+
'<div class="studio-setup-actions__title"><strong>' + esc(label) + ' is locked on the Free plan</strong><span>Pro-only production area</span></div>' +
|
|
8623
|
+
|
|
8624
|
+
'</div>' +
|
|
8625
|
+
|
|
8626
|
+
'<p class="studio-setup-actions__copy">Free shows App Flow, Frontend, Backend / API, Auth, Database, and Payments. Pro unlocks Deployment, Monitoring, Security, Testing, Landing, and Error Handling.</p>' +
|
|
8627
|
+
|
|
8628
|
+
'</section>' +
|
|
8629
|
+
|
|
8630
|
+
'</div>';
|
|
8631
|
+
|
|
8632
|
+
}
|
|
8633
|
+
|
|
8634
|
+
|
|
8635
|
+
|
|
8585
8636
|
function render(areaKey) {
|
|
8586
8637
|
|
|
8587
8638
|
var area = areas.find(function (a) { return a.key === areaKey; });
|
|
@@ -8598,6 +8649,14 @@ var PANEL_CLIENT_SCRIPT = `
|
|
|
8598
8649
|
|
|
8599
8650
|
var label = (area && area.label) || LABELS[areaKey] || areaKey;
|
|
8600
8651
|
|
|
8652
|
+
if (isLockedArea(areaKey)) {
|
|
8653
|
+
|
|
8654
|
+
panel.innerHTML = lockedAreaHtml(label);
|
|
8655
|
+
|
|
8656
|
+
return;
|
|
8657
|
+
|
|
8658
|
+
}
|
|
8659
|
+
|
|
8601
8660
|
var missions = (area && area.providerMissions) || [];
|
|
8602
8661
|
|
|
8603
8662
|
var selectedBeforeRender = selectedProviders[areaKey] || '';
|
|
@@ -8740,7 +8799,7 @@ var PROVIDER_LOGOS = {
|
|
|
8740
8799
|
supabase: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#3fcf8e" d="M11.9 1.036c-.015-.986-1.26-1.41-1.874-.637L.764 12.05C-.33 13.427.65 15.455 2.409 15.455h9.579l.113 7.51c.014.985 1.259 1.408 1.873.636l9.262-11.653c1.093-1.375.113-3.403-1.645-3.403h-9.642z"/></svg>',
|
|
8741
8800
|
clerk: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m21.47 20.829-2.881-2.881a.572.572 0 0 0-.7-.084 6.854 6.854 0 0 1-7.081 0 .576.576 0 0 0-.7.084l-2.881 2.881a.576.576 0 0 0-.103.69.57.57 0 0 0 .166.186 12 12 0 0 0 14.113 0 .58.58 0 0 0 .239-.423.576.576 0 0 0-.172-.453Zm.002-17.668-2.88 2.88a.569.569 0 0 1-.701.084A6.857 6.857 0 0 0 8.724 8.08a6.862 6.862 0 0 0-1.222 3.692 6.86 6.86 0 0 0 .978 3.764.573.573 0 0 1-.083.699l-2.881 2.88a.567.567 0 0 1-.864-.063A11.993 11.993 0 0 1 6.771 2.7a11.99 11.99 0 0 1 14.637-.405.566.566 0 0 1 .232.418.57.57 0 0 1-.168.448Zm-7.118 12.261a3.427 3.427 0 1 0 0-6.854 3.427 3.427 0 0 0 0 6.854Z"/></svg>',
|
|
8742
8801
|
authjs: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#18c6cf" d="M12 1.4 21 4.9v6.7c0 5.1-3.5 8.7-9 11-5.5-2.3-9-5.9-9-11V4.9l9-3.5Z"/><path fill="#8b2ff5" d="M12 1.4 21 4.9v6.7c0 5.1-3.5 8.7-9 11V1.4Z"/><path fill="#fff7df" d="M12 7a5.2 5.2 0 1 0 0 10.4A5.2 5.2 0 0 0 12 7Z"/><path fill="#ff8a00" d="M10.2 9.6a2.2 2.2 0 0 1 2.9 2.9l3.5 3.5h-2.2v1.5h-1.8V16h-1.4l-1.3-1.3a2.2 2.2 0 0 1 .3-5.1Zm.9 1.8a.7.7 0 1 0 0 1.4.7.7 0 0 0 0-1.4Z"/></svg>',
|
|
8743
|
-
auth0: '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.98 7.448L19.62 0H4.347L2.02 7.448c-1.352 4.312.03 9.206 3.815 12.015L12.007 24l6.157-4.552c3.755-2.81 5.182-7.688 3.815-12.015l-6.16 4.58 2.343 7.45-6.157-4.597-6.158 4.58 2.358-7.433-6.188-4.55 7.63-.045L12.008 0l2.356 7.404 7.615.044z"/></svg>',
|
|
8802
|
+
auth0: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#eb5424" d="M21.98 7.448L19.62 0H4.347L2.02 7.448c-1.352 4.312.03 9.206 3.815 12.015L12.007 24l6.157-4.552c3.755-2.81 5.182-7.688 3.815-12.015l-6.16 4.58 2.343 7.45-6.157-4.597-6.158 4.58 2.358-7.433-6.188-4.55 7.63-.045L12.008 0l2.356 7.404 7.615.044z"/></svg>',
|
|
8744
8803
|
"better-auth": '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="1.5" y="1.5" width="21" height="21" rx="3" fill="#111827"/><path fill="#fffdf7" d="M5.2 6.2h5.15v4.25H5.2V6.2Zm8.45 0h5.15v4.25h-5.15V6.2Zm-8.45 7.35h5.15v4.25H5.2v-4.25Zm8.45 0h5.15v4.25h-5.15v-4.25Z"/><path fill="#3b82f6" d="M10.35 10.45h3.3v3.1h-3.3v-3.1Z"/></svg>',
|
|
8745
8804
|
polar: '<svg viewBox="0 0 29 29" aria-hidden="true"><path fill="#0062FF" fill-rule="evenodd" clip-rule="evenodd" d="M9.077 23.057c4.801 3.25 11.328 1.992 14.577-2.808 3.25-4.801 1.993-11.328-2.808-14.578C16.045 2.422 9.519 3.679 6.269 8.48c-3.25 4.801-1.993 11.327 2.808 14.577Zm1.393.086c4.392 2.247 9.963.138 12.444-4.711 2.48-4.848.93-10.6-3.461-12.847-4.392-2.247-9.963-.138-12.443 4.711-2.481 4.848-.932 10.6 3.46 12.847Z"/><path fill="#0062FF" fill-rule="evenodd" clip-rule="evenodd" d="M11.722 24.29c3.965 1.29 8.628-2.118 10.417-7.613 1.788-5.495.024-10.996-3.94-12.286-3.964-1.29-8.628 2.118-10.416 7.613-1.789 5.495-.025 10.995 3.939 12.286Zm1.213-.418c3.355.716 6.982-2.961 8.102-8.212 1.12-5.252-.691-10.089-4.046-10.804-3.356-.716-6.983 2.96-8.103 8.212-1.12 5.251.692 10.088 4.047 10.804Z"/><path fill="#0062FF" fill-rule="evenodd" clip-rule="evenodd" d="M13.854 24.738c2.652.284 5.3-4.14 5.912-9.882.613-5.74-1.04-10.624-3.692-10.907-2.653-.283-5.3 4.141-5.913 9.882-.613 5.741 1.04 10.624 3.693 10.907Zm1.241-1.747c1.92-.031 3.415-3.917 3.34-8.68-.075-4.764-1.693-8.6-3.612-8.57-1.92.03-3.415 3.916-3.34 8.68.076 4.763 1.693 8.6 3.612 8.57Z"/></svg>',
|
|
8746
8805
|
"lemon-squeezy": '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m7.4916 10.835 2.3748-6.5114a3.1497 3.1497 0 0 0-.065-2.3418C9.0315.183 6.9427-.398 5.2928.265 3.643.929 2.71 2.4348 3.512 4.3046l2.8197 6.5615c.219.509.97.489 1.16-.03m1.6798 1.0969 6.5334-2.7758c2.1699-.9219 2.7218-3.6907 1.022-5.2905l-.068-.063c-1.6669-1.5469-4.4217-1.002-5.3706 1.0359L8.3566 11.135c-.234.503.295 1.0199.8159.7979m.373.87 6.6454-2.5119c2.2078-.8349 4.6206.745 4.5886 3.0398l-.002.09c-.048 2.2358-2.3938 3.7376-4.5536 2.9467l-6.6724-2.4418a.595.595 0 0 1-.006-1.1229m-.386 1.9269 6.4375 2.9767a3.2997 3.2997 0 0 1 1.6658 1.6989c.769 1.7998-.283 3.6396-1.9328 4.3016-1.6499.662-3.4097.235-4.2097-1.6359l-2.8027-6.5694c-.217-.509.328-1.009.8419-.772"/></svg>',
|
|
@@ -9124,19 +9183,42 @@ var CATEGORY_META = [
|
|
|
9124
9183
|
{ key: "landing", label: "Landing / Onboarding" },
|
|
9125
9184
|
{ key: "errorHandling", label: "Error Handling" }
|
|
9126
9185
|
];
|
|
9186
|
+
var DEFAULT_FREE_UNLOCKED_MAP_KEYS = [
|
|
9187
|
+
"appFlow",
|
|
9188
|
+
"frontend",
|
|
9189
|
+
"backend",
|
|
9190
|
+
"auth",
|
|
9191
|
+
"database",
|
|
9192
|
+
"payments"
|
|
9193
|
+
];
|
|
9194
|
+
var DEFAULT_FREE_UNLOCKED_MAP_KEY_SET = new Set(DEFAULT_FREE_UNLOCKED_MAP_KEYS);
|
|
9195
|
+
function isMapCategoryUnlocked(artifact, categoryKey) {
|
|
9196
|
+
if (artifact.plan === "pro" || artifact.usage?.plan === "pro") {
|
|
9197
|
+
return true;
|
|
9198
|
+
}
|
|
9199
|
+
if (!artifact.plan && !artifact.usage) {
|
|
9200
|
+
return true;
|
|
9201
|
+
}
|
|
9202
|
+
const keys = Array.isArray(artifact.usage?.unlockedMapCategoryKeys) && artifact.usage.unlockedMapCategoryKeys.length > 0 ? artifact.usage.unlockedMapCategoryKeys : DEFAULT_FREE_UNLOCKED_MAP_KEYS;
|
|
9203
|
+
return keys.includes(categoryKey) && DEFAULT_FREE_UNLOCKED_MAP_KEY_SET.has(categoryKey);
|
|
9204
|
+
}
|
|
9127
9205
|
function gapCountForArea(artifact, areaKey) {
|
|
9128
9206
|
return artifact.gaps.filter((g2) => g2.primaryMapCategory === areaKey).length;
|
|
9129
9207
|
}
|
|
9130
9208
|
function defaultAreaKey(artifact) {
|
|
9131
|
-
const fromGap = artifact.gaps
|
|
9209
|
+
const fromGap = artifact.gaps.find((gap) => isMapCategoryUnlocked(artifact, gap.primaryMapCategory))?.primaryMapCategory;
|
|
9132
9210
|
if (fromGap) {
|
|
9133
9211
|
return fromGap;
|
|
9134
9212
|
}
|
|
9135
9213
|
const areas = artifact.missionGraph.areas ?? [];
|
|
9136
|
-
|
|
9214
|
+
const fromArea = areas.find((area) => isMapCategoryUnlocked(artifact, area.key))?.key;
|
|
9215
|
+
if (fromArea) {
|
|
9216
|
+
return fromArea;
|
|
9217
|
+
}
|
|
9218
|
+
if (isMapCategoryUnlocked(artifact, "frontend")) {
|
|
9137
9219
|
return "frontend";
|
|
9138
9220
|
}
|
|
9139
|
-
return
|
|
9221
|
+
return CATEGORY_META.find((meta) => isMapCategoryUnlocked(artifact, meta.key))?.key ?? "frontend";
|
|
9140
9222
|
}
|
|
9141
9223
|
function providerLabelForArea(artifact, areaKey, mission, selectedOverride) {
|
|
9142
9224
|
if (selectedOverride) {
|
|
@@ -9192,18 +9274,24 @@ function buildNodeHtml(artifact, meta, selectedAreaKey) {
|
|
|
9192
9274
|
(check) => check.evidenceSource === "provider" || check.evidenceSource === "mcp" || check.evidenceClass === "mcp-verifier" || check.status === "needs-connection" || check.status === "unknown"
|
|
9193
9275
|
).length ?? 0;
|
|
9194
9276
|
const modelGaps = gapCountForArea(artifact, meta.key);
|
|
9277
|
+
const unlocked = isMapCategoryUnlocked(artifact, meta.key);
|
|
9195
9278
|
const stateClass = modelGaps > 0 ? " studio-node--critical" : openChecks > 0 ? " studio-node--warning" : area ? " studio-node--in-project" : "";
|
|
9196
9279
|
const selectedClass = selectedAreaKey === meta.key ? " studio-node--selected" : "";
|
|
9280
|
+
const lockedClass = unlocked ? "" : " studio-node--locked";
|
|
9197
9281
|
const metaText = modelGaps > 0 ? `${modelGaps} stack fix${modelGaps === 1 ? "" : "es"}` : repoOpenChecks > 0 ? `${repoOpenChecks} stack fix${repoOpenChecks === 1 ? "" : "es"}` : providerOpenChecks > 0 ? "Live check" : `${readiness}% health`;
|
|
9198
9282
|
const logoClass = providerLogoClass(logoProvider, mission?.key, mission?.providerLabel);
|
|
9199
9283
|
const logoInner = providerLogoHtml(logoProvider, providerLabel3, mission?.key, mission?.providerLabel);
|
|
9200
9284
|
const gapBadge = modelGaps > 0 ? `<span class="studio-node__raven-badge" role="presentation">Gap ${modelGaps}</span>` : "";
|
|
9201
|
-
|
|
9285
|
+
const lockBadge = unlocked ? "" : '<span class="studio-node__lock">Pro</span>';
|
|
9286
|
+
const lockedAttrs = unlocked ? "" : ' data-locked-map="1" title="Pro only - this section is locked on the Free plan"';
|
|
9287
|
+
const lockedAria = unlocked ? "" : ", Pro only. Upgrade to unlock";
|
|
9288
|
+
return `<button type="button" class="studio-node studio-node--${escapeHtml(meta.key)} provider-logo${logoClass}${stateClass}${selectedClass}${lockedClass}" data-area-key="${escapeHtml(meta.key)}"${lockedAttrs} aria-label="${escapeHtml(meta.label)}, ${escapeHtml(providerLabel3)}, ${escapeHtml(metaText)}${lockedAria}">
|
|
9202
9289
|
<span class="studio-node__logo provider-logo${logoClass}" aria-hidden="true">${logoInner}</span>
|
|
9203
9290
|
<span class="studio-node__title">${escapeHtml(meta.label)}</span>
|
|
9204
9291
|
<span class="studio-node__provider">${escapeHtml(providerLabel3)}</span>
|
|
9205
9292
|
<span class="studio-node__meta">${escapeHtml(metaText)}</span>
|
|
9206
9293
|
${gapBadge}
|
|
9294
|
+
${lockBadge}
|
|
9207
9295
|
</button>`;
|
|
9208
9296
|
}
|
|
9209
9297
|
function generateReportHtml(artifact) {
|
|
@@ -10139,7 +10227,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
10139
10227
|
var import_picocolors3 = __toESM(require_picocolors());
|
|
10140
10228
|
|
|
10141
10229
|
// src/version.ts
|
|
10142
|
-
var VERSION = "0.1.0-beta.
|
|
10230
|
+
var VERSION = "0.1.0-beta.3";
|
|
10143
10231
|
|
|
10144
10232
|
// src/tui/runInteractive.ts
|
|
10145
10233
|
async function formatStatusLine() {
|
|
@@ -10331,6 +10419,18 @@ async function runInteractiveSession(startDir = process.cwd()) {
|
|
|
10331
10419
|
}
|
|
10332
10420
|
|
|
10333
10421
|
// src/cli.ts
|
|
10422
|
+
function buildHelpText() {
|
|
10423
|
+
return `First-time terminal flow:
|
|
10424
|
+
|
|
10425
|
+
npx -y @viberaven/cli@beta login
|
|
10426
|
+
npx -y @viberaven/cli@beta status
|
|
10427
|
+
npx -y @viberaven/cli@beta scan --open
|
|
10428
|
+
|
|
10429
|
+
Quota:
|
|
10430
|
+
|
|
10431
|
+
Free: 2 lifetime scans
|
|
10432
|
+
Pro: 50 scans per month`;
|
|
10433
|
+
}
|
|
10334
10434
|
function printHelp() {
|
|
10335
10435
|
console.log(`viberaven ${VERSION} \u2014 launch readiness for AI-built apps
|
|
10336
10436
|
|
|
@@ -10386,6 +10486,7 @@ Security:
|
|
|
10386
10486
|
CLI scans use VibeRaven login \u2014 not OPENAI_API_KEY. See packages/cli/SECURITY.md.
|
|
10387
10487
|
|
|
10388
10488
|
`);
|
|
10489
|
+
console.log(buildHelpText());
|
|
10389
10490
|
}
|
|
10390
10491
|
function parseArgs(argv) {
|
|
10391
10492
|
const flags = {};
|
|
@@ -10654,6 +10755,7 @@ if (require.main === module) {
|
|
|
10654
10755
|
}
|
|
10655
10756
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10656
10757
|
0 && (module.exports = {
|
|
10758
|
+
buildHelpText,
|
|
10657
10759
|
formatScanJsonStdout,
|
|
10658
10760
|
parseArgs
|
|
10659
10761
|
});
|