@viberaven/cli 1.0.1 → 1.0.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/AGENTS.md +71 -6
- package/README.md +10 -10
- package/SECURITY.md +4 -4
- package/dist/cli.js +343 -40
- package/dist/cli.js.map +4 -4
- package/package.json +1 -1
- package/templates/AGENTS.snippet.md +10 -10
- package/templates/CLAUDE.snippet.md +5 -5
- package/templates/CURSOR.snippet.md +5 -5
package/dist/cli.js
CHANGED
|
@@ -170,8 +170,8 @@ __export(cli_exports, {
|
|
|
170
170
|
runScanCommand: () => runScanCommand
|
|
171
171
|
});
|
|
172
172
|
module.exports = __toCommonJS(cli_exports);
|
|
173
|
-
var
|
|
174
|
-
var
|
|
173
|
+
var import_promises17 = require("node:fs/promises");
|
|
174
|
+
var import_node_path22 = require("node:path");
|
|
175
175
|
|
|
176
176
|
// src/config.ts
|
|
177
177
|
var import_node_os = require("node:os");
|
|
@@ -585,14 +585,18 @@ function formatUsageLine(usage) {
|
|
|
585
585
|
const periodLabel = usage.period === "monthly" ? "this month" : "lifetime";
|
|
586
586
|
return `Scans: ${usage.used}/${usage.limit} (${periodLabel}, ${usage.plan}) \xB7 ${usage.remainingPrompts} remaining`;
|
|
587
587
|
}
|
|
588
|
+
function normalizeUpgradeUrl(url) {
|
|
589
|
+
return url.replace("https://viberice.com/account", "https://viberaven.dev/account");
|
|
590
|
+
}
|
|
588
591
|
function formatScanLimitMessage(upgradeUrl) {
|
|
592
|
+
const safeUpgradeUrl = normalizeUpgradeUrl(upgradeUrl);
|
|
589
593
|
return [
|
|
590
594
|
"",
|
|
591
595
|
formatAgentStatus(UPGRADE_REQUIRED, "Free scan limit reached. Upgrade to Pro to continue."),
|
|
592
596
|
"Your last scan artifacts are unchanged if you already ran a scan in this repo.",
|
|
593
597
|
"Do not keep retrying this scan until the user upgrades or quota resets.",
|
|
594
598
|
"",
|
|
595
|
-
`Upgrade & account: ${
|
|
599
|
+
`Upgrade & account: ${safeUpgradeUrl}`,
|
|
596
600
|
""
|
|
597
601
|
].join("\n");
|
|
598
602
|
}
|
|
@@ -641,7 +645,7 @@ async function openUrlInBrowser(url) {
|
|
|
641
645
|
}
|
|
642
646
|
|
|
643
647
|
// src/contracts/commands.ts
|
|
644
|
-
var PUBLIC_PACKAGE = "
|
|
648
|
+
var PUBLIC_PACKAGE = "viberaven";
|
|
645
649
|
var PUBLIC_COMMAND = `npx -y ${PUBLIC_PACKAGE}`;
|
|
646
650
|
var PUBLIC_AGENT_MODE_COMMAND = `${PUBLIC_COMMAND} --agent-mode`;
|
|
647
651
|
var PUBLIC_VERIFY_COMMAND = `${PUBLIC_COMMAND} --verify`;
|
|
@@ -11224,7 +11228,7 @@ function buildAgentFixPrompt(artifact, gap) {
|
|
|
11224
11228
|
}
|
|
11225
11229
|
|
|
11226
11230
|
// src/version.ts
|
|
11227
|
-
var VERSION = "1.0.
|
|
11231
|
+
var VERSION = "1.0.3";
|
|
11228
11232
|
|
|
11229
11233
|
// src/commands/guide.ts
|
|
11230
11234
|
var import_picocolors3 = __toESM(require_picocolors());
|
|
@@ -11491,12 +11495,35 @@ var import_promises8 = require("node:fs/promises");
|
|
|
11491
11495
|
var import_node_path11 = require("node:path");
|
|
11492
11496
|
|
|
11493
11497
|
// src/commands/agentRulesBlock.ts
|
|
11494
|
-
var
|
|
11495
|
-
var
|
|
11498
|
+
var VIBERAVEN_BLOCK_START = "<!-- VIBERAVEN:START -->";
|
|
11499
|
+
var VIBERAVEN_BLOCK_END = "<!-- VIBERAVEN:END -->";
|
|
11500
|
+
var VIBERAVEN_LEGACY_BLOCK_START = "<!-- viberaven:agent-rules:start -->";
|
|
11501
|
+
var VIBERAVEN_LEGACY_BLOCK_END = "<!-- viberaven:agent-rules:end -->";
|
|
11496
11502
|
var HEAL_PLAN_GAP_COMMAND = healPlanGapCommand("<id>");
|
|
11497
11503
|
var PROMPT_GAP_COMMAND = promptGapCommand("<id>");
|
|
11498
11504
|
var HEAL_APPLY_GAP_COMMAND = `${PUBLIC_COMMAND} --heal --apply --gap <id> --yes`;
|
|
11499
|
-
var
|
|
11505
|
+
var AGENT_RULES_PREAMBLE = `VibeRaven provides production readiness for AI-built apps.
|
|
11506
|
+
|
|
11507
|
+
Canonical command: \`${PUBLIC_AGENT_MODE_COMMAND}\`
|
|
11508
|
+
|
|
11509
|
+
Use VibeRaven before launch, deployment, real users, auth, billing, database, RLS, env vars, webhooks, monitoring, or tests.
|
|
11510
|
+
|
|
11511
|
+
Agent loop: run VibeRaven, read Mission Map (\`.viberaven/mission-map.md\`), fix one launch gap, re-run VibeRaven.`;
|
|
11512
|
+
var AGENT_NEGATIVE_CONSTRAINTS = `## Event-Triggered Production Verification
|
|
11513
|
+
|
|
11514
|
+
Trigger: modifications to \`package.json\`, \`vercel.json\`, \`supabase/migrations/**/*\`, \`.env.example\`, auth/billing/webhook paths, or deploy workflow files.
|
|
11515
|
+
|
|
11516
|
+
1. Do NOT claim "production ready" or close a deploy checklist until \`gate.status === "clear"\` in \`.viberaven/gate-result.json\`.
|
|
11517
|
+
2. Do NOT run verify after every file patch. Batch heals, then \`${PUBLIC_VERIFY_COMMAND}\` once per loop.
|
|
11518
|
+
3. Do NOT \`git push\` or deploy after auth, RLS, billing, or webhook changes without \`${PUBLIC_AGENT_MODE_COMMAND}\`.
|
|
11519
|
+
4. If anomalies appear, read \`.viberaven/agent-tasklist.md\` fully before writing new repo logic.
|
|
11520
|
+
|
|
11521
|
+
Prefer \`viberaven_check_readiness\` when MCP is configured; otherwise \`${PUBLIC_AGENT_MODE_COMMAND}\`.`;
|
|
11522
|
+
var AGENT_RULES_BODY = `${AGENT_RULES_PREAMBLE}
|
|
11523
|
+
|
|
11524
|
+
${AGENT_NEGATIVE_CONSTRAINTS}
|
|
11525
|
+
|
|
11526
|
+
## VibeRaven Production-Readiness Gate
|
|
11500
11527
|
|
|
11501
11528
|
- Before running build, compile, cleanup, deployment, vercel, or supabase commands, run \`${PUBLIC_AGENT_MODE_COMMAND}\` first from the project root.
|
|
11502
11529
|
- Treat VibeRaven as the Agent Context + Production Gate for AI-built apps, especially apps using Vercel, Supabase, auth, database, payments, webhooks, monitoring, rate limits, or environment variables.
|
|
@@ -11511,7 +11538,7 @@ var AGENT_RULES_BODY = `## VibeRaven Production-Readiness Gate
|
|
|
11511
11538
|
- Run \`${PUBLIC_STRICT_COMMAND}\` before deploy or CI pass.
|
|
11512
11539
|
- Use \`${HEAL_PLAN_GAP_COMMAND}\` before any heal apply.
|
|
11513
11540
|
- Only use \`${HEAL_APPLY_GAP_COMMAND}\` for supported low-risk repo-code recipes.
|
|
11514
|
-
- Preview local rule installation with \`${
|
|
11541
|
+
- Preview local rule installation with \`${PUBLIC_INIT_ALL_COMMAND} --dry-run\`.
|
|
11515
11542
|
- Cleanup is non-destructive: only run \`${PUBLIC_CLEAN_PLAN_COMMAND}\` to create a reviewable cleanup plan.
|
|
11516
11543
|
- 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 MCP evidence.
|
|
11517
11544
|
- Do not claim provider dashboard work is fixed by repo-code edits.
|
|
@@ -11539,17 +11566,63 @@ The loop is:
|
|
|
11539
11566
|
9. If \`fixType === 'upgrade-required'\`, provide upgradeUrl and move on.
|
|
11540
11567
|
|
|
11541
11568
|
Do not stop at "scan complete." The loop is not done until \`gate.status === 'clear'\`.`;
|
|
11569
|
+
var AGENT_CONTEXT_BODY = `${AGENT_RULES_PREAMBLE}
|
|
11570
|
+
|
|
11571
|
+
After \`--agent-mode\`, read these artifacts in order:
|
|
11572
|
+
|
|
11573
|
+
1. \`.viberaven/mission-map.md\`
|
|
11574
|
+
2. \`.viberaven/agent-tasklist.md\`
|
|
11575
|
+
3. \`.viberaven/gate-result.json\`
|
|
11576
|
+
4. \`.viberaven/context-map.json\``;
|
|
11577
|
+
var MISSION_MAP_BODY = `${AGENT_RULES_PREAMBLE}
|
|
11578
|
+
|
|
11579
|
+
## Mission Map loop
|
|
11580
|
+
|
|
11581
|
+
1. Run \`${PUBLIC_AGENT_MODE_COMMAND}\` from the project root.
|
|
11582
|
+
2. Read \`.viberaven/agent-tasklist.md\` and \`.viberaven/gate-result.json\`.
|
|
11583
|
+
3. Fix one launch gap.
|
|
11584
|
+
4. Re-run VibeRaven until \`gate.status === 'clear'\`.`;
|
|
11585
|
+
var BLOCK_MARKER_PAIRS = [
|
|
11586
|
+
[VIBERAVEN_BLOCK_START, VIBERAVEN_BLOCK_END],
|
|
11587
|
+
[VIBERAVEN_LEGACY_BLOCK_START, VIBERAVEN_LEGACY_BLOCK_END]
|
|
11588
|
+
];
|
|
11542
11589
|
function buildAgentRulesBlock() {
|
|
11543
|
-
return
|
|
11590
|
+
return wrapViberavenBlock(AGENT_RULES_BODY);
|
|
11591
|
+
}
|
|
11592
|
+
function buildAgentContextBlock() {
|
|
11593
|
+
return wrapViberavenBlock(AGENT_CONTEXT_BODY);
|
|
11594
|
+
}
|
|
11595
|
+
function buildMissionMapBlock() {
|
|
11596
|
+
return wrapViberavenBlock(MISSION_MAP_BODY);
|
|
11597
|
+
}
|
|
11598
|
+
function wrapViberavenBlock(body) {
|
|
11599
|
+
return [VIBERAVEN_BLOCK_START, body, VIBERAVEN_BLOCK_END].join("\n");
|
|
11600
|
+
}
|
|
11601
|
+
function stripLegacyFrontmatterBeforeViberavenBlock(content) {
|
|
11602
|
+
const blockStarts = [VIBERAVEN_BLOCK_START, VIBERAVEN_LEGACY_BLOCK_START];
|
|
11603
|
+
let blockIndex = -1;
|
|
11604
|
+
for (const start of blockStarts) {
|
|
11605
|
+
const index = content.indexOf(start);
|
|
11606
|
+
if (index !== -1 && (blockIndex === -1 || index < blockIndex)) {
|
|
11607
|
+
blockIndex = index;
|
|
11608
|
+
}
|
|
11609
|
+
}
|
|
11610
|
+
if (blockIndex <= 0) {
|
|
11611
|
+
return content;
|
|
11612
|
+
}
|
|
11613
|
+
const beforeBlock = content.slice(0, blockIndex);
|
|
11614
|
+
if (!beforeBlock.trimStart().startsWith("---")) {
|
|
11615
|
+
return content;
|
|
11616
|
+
}
|
|
11617
|
+
const strippedPrefix = beforeBlock.replace(/^---[\s\S]*?---\s*/m, "");
|
|
11618
|
+
return `${strippedPrefix}${content.slice(blockIndex)}`;
|
|
11544
11619
|
}
|
|
11545
11620
|
function injectAgentRulesBlock(existingContent, replacementBlock = buildAgentRulesBlock()) {
|
|
11546
|
-
const
|
|
11547
|
-
|
|
11548
|
-
);
|
|
11549
|
-
const existingMatch = boundedBlockPattern.exec(existingContent);
|
|
11621
|
+
const normalizedExisting = replacementBlock.trimStart().startsWith("---") ? stripLegacyFrontmatterBeforeViberavenBlock(existingContent) : existingContent;
|
|
11622
|
+
const existingMatch = findBoundedBlock(normalizedExisting);
|
|
11550
11623
|
if (existingMatch) {
|
|
11551
11624
|
const content = replaceExistingAgentRulesBlock({
|
|
11552
|
-
existingContent,
|
|
11625
|
+
existingContent: normalizedExisting,
|
|
11553
11626
|
existingMatch,
|
|
11554
11627
|
replacementBlock
|
|
11555
11628
|
});
|
|
@@ -11558,14 +11631,26 @@ function injectAgentRulesBlock(existingContent, replacementBlock = buildAgentRul
|
|
|
11558
11631
|
changed: content !== existingContent
|
|
11559
11632
|
};
|
|
11560
11633
|
}
|
|
11561
|
-
const separator =
|
|
11634
|
+
const separator = normalizedExisting.length > 0 ? "\n\n" : "";
|
|
11562
11635
|
return {
|
|
11563
|
-
content: `${replacementBlock}${separator}${
|
|
11636
|
+
content: `${replacementBlock}${separator}${normalizedExisting}`,
|
|
11564
11637
|
changed: true
|
|
11565
11638
|
};
|
|
11566
11639
|
}
|
|
11640
|
+
function findBoundedBlock(content) {
|
|
11641
|
+
for (const [start, end] of BLOCK_MARKER_PAIRS) {
|
|
11642
|
+
const boundedBlockPattern = new RegExp(
|
|
11643
|
+
`${escapeRegExp3(start)}[\\s\\S]*?${escapeRegExp3(end)}`
|
|
11644
|
+
);
|
|
11645
|
+
const match = boundedBlockPattern.exec(content);
|
|
11646
|
+
if (match) {
|
|
11647
|
+
return match;
|
|
11648
|
+
}
|
|
11649
|
+
}
|
|
11650
|
+
return null;
|
|
11651
|
+
}
|
|
11567
11652
|
function replaceExistingAgentRulesBlock(input) {
|
|
11568
|
-
const replacementMarkerIndex = input.replacementBlock
|
|
11653
|
+
const replacementMarkerIndex = findBlockStartIndex(input.replacementBlock);
|
|
11569
11654
|
const existingStart = input.existingMatch.index;
|
|
11570
11655
|
const existingEnd = existingStart + input.existingMatch[0].length;
|
|
11571
11656
|
if (replacementMarkerIndex === -1) {
|
|
@@ -11583,6 +11668,10 @@ function replaceExistingAgentRulesBlock(input) {
|
|
|
11583
11668
|
existingEnd
|
|
11584
11669
|
)}`;
|
|
11585
11670
|
}
|
|
11671
|
+
function findBlockStartIndex(block) {
|
|
11672
|
+
const indices = BLOCK_MARKER_PAIRS.map(([start]) => block.indexOf(start)).filter((index) => index !== -1);
|
|
11673
|
+
return indices.length > 0 ? Math.min(...indices) : -1;
|
|
11674
|
+
}
|
|
11586
11675
|
function findGeneratedPrefixStart(input) {
|
|
11587
11676
|
if (!input.replacementPrefix) {
|
|
11588
11677
|
return input.fallbackStart;
|
|
@@ -11627,6 +11716,8 @@ var AGENT_RULE_TARGETS = {
|
|
|
11627
11716
|
cursorLegacy: { file: ".cursorrules", aliases: ["cursor-legacy"] },
|
|
11628
11717
|
copilot: { file: ".github/copilot-instructions.md", aliases: ["github-copilot"] },
|
|
11629
11718
|
gemini: { file: "GEMINI.md" },
|
|
11719
|
+
agentContext: { file: ".viberaven/agent-context.md", aliases: ["agent-context"] },
|
|
11720
|
+
missionMap: { file: ".viberaven/mission-map.md", aliases: ["mission-map"] },
|
|
11630
11721
|
devin: { file: ".devin/rules/viberaven.md" },
|
|
11631
11722
|
windsurf: { file: ".windsurf/rules/viberaven.md" },
|
|
11632
11723
|
cline: { file: ".clinerules/viberaven.md" },
|
|
@@ -11634,13 +11725,17 @@ var AGENT_RULE_TARGETS = {
|
|
|
11634
11725
|
junie: { file: ".junie/guidelines.md" },
|
|
11635
11726
|
zed: { file: ".rules" }
|
|
11636
11727
|
};
|
|
11637
|
-
var
|
|
11728
|
+
var CORE_AGENT_INJECTION_TARGETS = [
|
|
11638
11729
|
"codex",
|
|
11639
11730
|
"claude",
|
|
11731
|
+
"gemini",
|
|
11640
11732
|
"cursor",
|
|
11641
|
-
"cursorLegacy",
|
|
11642
11733
|
"copilot",
|
|
11643
|
-
"
|
|
11734
|
+
"agentContext",
|
|
11735
|
+
"missionMap"
|
|
11736
|
+
];
|
|
11737
|
+
var EXTENDED_AGENT_RULE_TARGETS = [
|
|
11738
|
+
"cursorLegacy",
|
|
11644
11739
|
"devin",
|
|
11645
11740
|
"windsurf",
|
|
11646
11741
|
"cline",
|
|
@@ -11648,11 +11743,16 @@ var ALL_AGENT_RULE_TARGETS = [
|
|
|
11648
11743
|
"junie",
|
|
11649
11744
|
"zed"
|
|
11650
11745
|
];
|
|
11746
|
+
var ALL_AGENT_RULE_TARGETS = [
|
|
11747
|
+
...CORE_AGENT_INJECTION_TARGETS,
|
|
11748
|
+
...EXTENDED_AGENT_RULE_TARGETS
|
|
11749
|
+
];
|
|
11651
11750
|
var AGENT_RULE_TARGET_ALIAS_ENTRIES = ALL_AGENT_RULE_TARGETS.flatMap((target) => [
|
|
11652
11751
|
[target.toLowerCase(), target],
|
|
11653
11752
|
...(AGENT_RULE_TARGETS[target].aliases ?? []).map((alias) => [alias, target])
|
|
11654
11753
|
]);
|
|
11655
11754
|
var AGENT_RULE_TARGET_ALIASES = new Map(AGENT_RULE_TARGET_ALIAS_ENTRIES);
|
|
11755
|
+
var VALID_AGENT_RULES_TARGET_TEXT = "all, codex, claude, cursor, cursor-legacy, copilot, github-copilot, gemini, agent-context, mission-map, devin, windsurf, cline, roo, junie, zed";
|
|
11656
11756
|
function renderAgentRulesForTarget(target) {
|
|
11657
11757
|
if (target === "claude") {
|
|
11658
11758
|
return ["@AGENTS.md", "", buildAgentRulesBlock()].join("\n");
|
|
@@ -11660,20 +11760,52 @@ function renderAgentRulesForTarget(target) {
|
|
|
11660
11760
|
if (target === "cursor") {
|
|
11661
11761
|
return [
|
|
11662
11762
|
"---",
|
|
11663
|
-
"description:
|
|
11763
|
+
"description: Applied when verifying backend or infrastructure readiness before production deployment.",
|
|
11664
11764
|
"globs:",
|
|
11765
|
+
" - package.json",
|
|
11766
|
+
" - vercel.json",
|
|
11767
|
+
" - supabase/migrations/**",
|
|
11768
|
+
" - .env.example",
|
|
11769
|
+
" - .github/workflows/**",
|
|
11665
11770
|
"alwaysApply: true",
|
|
11666
11771
|
"---",
|
|
11667
11772
|
"",
|
|
11668
11773
|
buildAgentRulesBlock()
|
|
11669
11774
|
].join("\n");
|
|
11670
11775
|
}
|
|
11776
|
+
if (target === "agentContext") {
|
|
11777
|
+
return ["# VibeRaven Agent Context", "", buildAgentContextBlock()].join("\n");
|
|
11778
|
+
}
|
|
11779
|
+
if (target === "missionMap") {
|
|
11780
|
+
return ["# VibeRaven Mission Map", "", buildMissionMapBlock()].join("\n");
|
|
11781
|
+
}
|
|
11671
11782
|
return buildAgentRulesBlock();
|
|
11672
11783
|
}
|
|
11784
|
+
function validAgentRulesTargetText() {
|
|
11785
|
+
return VALID_AGENT_RULES_TARGET_TEXT;
|
|
11786
|
+
}
|
|
11787
|
+
function getAgentRulesTargets(value) {
|
|
11788
|
+
if (value === void 0 || value.trim() === "" || value.trim().toLowerCase() === "all") {
|
|
11789
|
+
return [...CORE_AGENT_INJECTION_TARGETS];
|
|
11790
|
+
}
|
|
11791
|
+
const requested = value.split(",").map((target) => target.trim().toLowerCase()).filter(Boolean);
|
|
11792
|
+
if (requested.length === 0 || requested.includes("all")) {
|
|
11793
|
+
return [...CORE_AGENT_INJECTION_TARGETS];
|
|
11794
|
+
}
|
|
11795
|
+
const resolved = requested.map((target) => {
|
|
11796
|
+
const canonicalTarget = AGENT_RULE_TARGET_ALIASES.get(target);
|
|
11797
|
+
if (!canonicalTarget) {
|
|
11798
|
+
throw new Error(`Unknown agent rules target "${target}". Valid targets: ${validAgentRulesTargetText()}.`);
|
|
11799
|
+
}
|
|
11800
|
+
return canonicalTarget;
|
|
11801
|
+
});
|
|
11802
|
+
const requestedTargets = new Set(resolved);
|
|
11803
|
+
return ALL_AGENT_RULE_TARGETS.filter((target) => requestedTargets.has(target));
|
|
11804
|
+
}
|
|
11673
11805
|
|
|
11674
11806
|
// src/commands/initRules.ts
|
|
11675
11807
|
async function initAgentRules(options) {
|
|
11676
|
-
const targets = options.targets ?? [...
|
|
11808
|
+
const targets = options.targets ?? [...CORE_AGENT_INJECTION_TARGETS];
|
|
11677
11809
|
const results = [];
|
|
11678
11810
|
for (const target of targets) {
|
|
11679
11811
|
const file = AGENT_RULE_TARGETS[target].file;
|
|
@@ -11689,6 +11821,46 @@ async function initAgentRules(options) {
|
|
|
11689
11821
|
}
|
|
11690
11822
|
return results;
|
|
11691
11823
|
}
|
|
11824
|
+
function renderAgentRulesDryRun(targets) {
|
|
11825
|
+
const files = targets.map((target) => `- ${target}: ${AGENT_RULE_TARGETS[target].file}`).join("\n");
|
|
11826
|
+
const previews = targets.flatMap((target) => [
|
|
11827
|
+
`Preview: ${target} (${AGENT_RULE_TARGETS[target].file})`,
|
|
11828
|
+
"",
|
|
11829
|
+
renderAgentRulesForTarget(target)
|
|
11830
|
+
]);
|
|
11831
|
+
return [`VibeRaven agent rules dry run`, "", `Target files:`, files, "", ...previews].join("\n");
|
|
11832
|
+
}
|
|
11833
|
+
function formatAgentRulesInitSummary(results) {
|
|
11834
|
+
const created = results.filter((result) => result.action === "created");
|
|
11835
|
+
const updated = results.filter((result) => result.action === "updated");
|
|
11836
|
+
const skipped = results.filter((result) => result.action === "unchanged");
|
|
11837
|
+
const lines = ["VibeRaven agent injection summary", ""];
|
|
11838
|
+
if (created.length > 0) {
|
|
11839
|
+
lines.push("Created:");
|
|
11840
|
+
for (const result of created) {
|
|
11841
|
+
lines.push(` + ${result.file}`);
|
|
11842
|
+
}
|
|
11843
|
+
lines.push("");
|
|
11844
|
+
}
|
|
11845
|
+
if (updated.length > 0) {
|
|
11846
|
+
lines.push("Updated:");
|
|
11847
|
+
for (const result of updated) {
|
|
11848
|
+
lines.push(` ~ ${result.file}`);
|
|
11849
|
+
}
|
|
11850
|
+
lines.push("");
|
|
11851
|
+
}
|
|
11852
|
+
if (skipped.length > 0) {
|
|
11853
|
+
lines.push("Skipped (unchanged):");
|
|
11854
|
+
for (const result of skipped) {
|
|
11855
|
+
lines.push(` = ${result.file}`);
|
|
11856
|
+
}
|
|
11857
|
+
lines.push("");
|
|
11858
|
+
}
|
|
11859
|
+
lines.push(
|
|
11860
|
+
`Done: ${created.length} created, ${updated.length} updated, ${skipped.length} skipped.`
|
|
11861
|
+
);
|
|
11862
|
+
return lines.join("\n");
|
|
11863
|
+
}
|
|
11692
11864
|
async function readExistingFile(path) {
|
|
11693
11865
|
try {
|
|
11694
11866
|
return { exists: true, content: await (0, import_promises8.readFile)(path, "utf-8") };
|
|
@@ -11911,7 +12083,7 @@ async function handleAuth() {
|
|
|
11911
12083
|
await runDeviceLogin(apiBaseUrl);
|
|
11912
12084
|
}
|
|
11913
12085
|
async function handleAgentRules(cwd) {
|
|
11914
|
-
const results = await initAgentRules({ cwd
|
|
12086
|
+
const results = await initAgentRules({ cwd });
|
|
11915
12087
|
for (const result of results) {
|
|
11916
12088
|
const color = result.action === "created" ? import_picocolors4.default.green : result.action === "updated" ? import_picocolors4.default.yellow : import_picocolors4.default.dim;
|
|
11917
12089
|
M2.message(color(`${result.action.toUpperCase()}: ${result.file}`));
|
|
@@ -12325,7 +12497,7 @@ function applyRlsRecipe(_source) {
|
|
|
12325
12497
|
dashboardUrl: "https://supabase.com/dashboard/project/{{PROJECT_REF}}/auth/policies",
|
|
12326
12498
|
exactStep: 'Enable Row Level Security (RLS) on each table under the "Table Editor" or "Auth > Policies" section.',
|
|
12327
12499
|
doneSignal: "RLS toggle is green for all public tables",
|
|
12328
|
-
verifyCommand: "npx -y
|
|
12500
|
+
verifyCommand: "npx -y viberaven audit --vercel-supabase --json"
|
|
12329
12501
|
}
|
|
12330
12502
|
};
|
|
12331
12503
|
}
|
|
@@ -12992,6 +13164,112 @@ async function recommendStack(cwd = process.cwd()) {
|
|
|
12992
13164
|
return rec;
|
|
12993
13165
|
}
|
|
12994
13166
|
|
|
13167
|
+
// src/commands/runInit.ts
|
|
13168
|
+
async function runInitCommand(options) {
|
|
13169
|
+
let targets;
|
|
13170
|
+
try {
|
|
13171
|
+
targets = getAgentRulesTargets(options.agents);
|
|
13172
|
+
} catch (error) {
|
|
13173
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
13174
|
+
return 1;
|
|
13175
|
+
}
|
|
13176
|
+
if (options.dryRun) {
|
|
13177
|
+
console.log(renderAgentRulesDryRun(targets));
|
|
13178
|
+
return 0;
|
|
13179
|
+
}
|
|
13180
|
+
const results = await initAgentRules({
|
|
13181
|
+
cwd: options.cwd,
|
|
13182
|
+
targets,
|
|
13183
|
+
dryRun: false
|
|
13184
|
+
});
|
|
13185
|
+
console.log(formatAgentRulesInitSummary(results));
|
|
13186
|
+
return 0;
|
|
13187
|
+
}
|
|
13188
|
+
|
|
13189
|
+
// src/commands/doctorAgents.ts
|
|
13190
|
+
var import_promises16 = require("node:fs/promises");
|
|
13191
|
+
var import_node_path20 = require("node:path");
|
|
13192
|
+
var REQUIRED_EXISTENCE_CHECKS = [
|
|
13193
|
+
{ id: "agents-md", file: "AGENTS.md" },
|
|
13194
|
+
{ id: "claude-md", file: "CLAUDE.md" },
|
|
13195
|
+
{ id: "cursor-rule", file: ".cursor/rules/viberaven.mdc" },
|
|
13196
|
+
{ id: "copilot-instructions", file: ".github/copilot-instructions.md" }
|
|
13197
|
+
];
|
|
13198
|
+
var STALE_PATTERNS = [
|
|
13199
|
+
{ id: "stale-beta-scan", pattern: "@beta scan" },
|
|
13200
|
+
{ id: "stale-viberaven-station", pattern: "viberaven-station" },
|
|
13201
|
+
{ id: "stale-viberice", pattern: "viberice" }
|
|
13202
|
+
];
|
|
13203
|
+
async function checkAgentInjection(cwd) {
|
|
13204
|
+
const checks = [];
|
|
13205
|
+
for (const item3 of REQUIRED_EXISTENCE_CHECKS) {
|
|
13206
|
+
const exists = await fileExists((0, import_node_path20.join)(cwd, item3.file));
|
|
13207
|
+
checks.push({
|
|
13208
|
+
id: item3.id,
|
|
13209
|
+
status: exists ? "pass" : "fail",
|
|
13210
|
+
message: exists ? `${item3.file} exists` : `Missing ${item3.file}`
|
|
13211
|
+
});
|
|
13212
|
+
}
|
|
13213
|
+
for (const target of CORE_AGENT_INJECTION_TARGETS) {
|
|
13214
|
+
const file = AGENT_RULE_TARGETS[target].file;
|
|
13215
|
+
const path = (0, import_node_path20.join)(cwd, file);
|
|
13216
|
+
const exists = await fileExists(path);
|
|
13217
|
+
if (!exists) {
|
|
13218
|
+
checks.push({
|
|
13219
|
+
id: `canonical-${target}`,
|
|
13220
|
+
status: "fail",
|
|
13221
|
+
message: `Cannot verify canonical command \u2014 missing ${file}`
|
|
13222
|
+
});
|
|
13223
|
+
continue;
|
|
13224
|
+
}
|
|
13225
|
+
const content = await (0, import_promises16.readFile)(path, "utf-8");
|
|
13226
|
+
const hasCommand = content.includes(PUBLIC_AGENT_MODE_COMMAND);
|
|
13227
|
+
checks.push({
|
|
13228
|
+
id: `canonical-${target}`,
|
|
13229
|
+
status: hasCommand ? "pass" : "fail",
|
|
13230
|
+
message: hasCommand ? `Canonical command found in ${file}` : `Missing canonical command in ${file}`
|
|
13231
|
+
});
|
|
13232
|
+
for (const stale of STALE_PATTERNS) {
|
|
13233
|
+
if (content.includes(stale.pattern)) {
|
|
13234
|
+
checks.push({
|
|
13235
|
+
id: `${stale.id}-${target}`,
|
|
13236
|
+
status: "fail",
|
|
13237
|
+
message: `Stale ${stale.pattern} reference in ${file}`
|
|
13238
|
+
});
|
|
13239
|
+
}
|
|
13240
|
+
}
|
|
13241
|
+
}
|
|
13242
|
+
return {
|
|
13243
|
+
ok: checks.every((check) => check.status === "pass"),
|
|
13244
|
+
checks
|
|
13245
|
+
};
|
|
13246
|
+
}
|
|
13247
|
+
function formatDoctorAgentsReport(report) {
|
|
13248
|
+
const lines = ["VibeRaven agent injection doctor", ""];
|
|
13249
|
+
for (const check of report.checks) {
|
|
13250
|
+
const icon = check.status === "pass" ? "\u2713" : "\u2717";
|
|
13251
|
+
lines.push(`${icon} ${check.message}`);
|
|
13252
|
+
}
|
|
13253
|
+
lines.push("");
|
|
13254
|
+
lines.push(report.ok ? "All agent injection checks passed." : "Agent injection checks failed.");
|
|
13255
|
+
return lines.join("\n");
|
|
13256
|
+
}
|
|
13257
|
+
async function fileExists(path) {
|
|
13258
|
+
try {
|
|
13259
|
+
await (0, import_promises16.access)(path);
|
|
13260
|
+
return true;
|
|
13261
|
+
} catch {
|
|
13262
|
+
return false;
|
|
13263
|
+
}
|
|
13264
|
+
}
|
|
13265
|
+
|
|
13266
|
+
// src/commands/runDoctor.ts
|
|
13267
|
+
async function runDoctorAgentsCommand(options) {
|
|
13268
|
+
const report = await checkAgentInjection(options.cwd);
|
|
13269
|
+
console.log(formatDoctorAgentsReport(report));
|
|
13270
|
+
return report.ok ? 0 : 1;
|
|
13271
|
+
}
|
|
13272
|
+
|
|
12995
13273
|
// src/output/nextActionBlock.ts
|
|
12996
13274
|
function buildNextActionBlock(tasks, loopState, plan) {
|
|
12997
13275
|
const batchSize = plan === "pro" ? 10 : 3;
|
|
@@ -13030,7 +13308,7 @@ function buildNextActionBlock(tasks, loopState, plan) {
|
|
|
13030
13308
|
title: repoCodeTask.title,
|
|
13031
13309
|
mcpTool: repoCodeTask.mcpTool,
|
|
13032
13310
|
mcpArgs: repoCodeTask.mcpArgs,
|
|
13033
|
-
fallbackCommand: repoCodeTask.mcpArgs ? `npx -y
|
|
13311
|
+
fallbackCommand: repoCodeTask.mcpArgs ? `npx -y viberaven --heal --apply --gap ${repoCodeTask.gapId} --yes` : void 0,
|
|
13034
13312
|
requiresUserAction: false
|
|
13035
13313
|
};
|
|
13036
13314
|
}
|
|
@@ -13113,17 +13391,17 @@ function printNextActionBlock(block) {
|
|
|
13113
13391
|
// src/providerMcpBridge.ts
|
|
13114
13392
|
var import_node_fs10 = require("node:fs");
|
|
13115
13393
|
var import_node_os2 = require("node:os");
|
|
13116
|
-
var
|
|
13394
|
+
var import_node_path21 = require("node:path");
|
|
13117
13395
|
var UPGRADE_URL4 = "https://viberaven.dev/pricing";
|
|
13118
|
-
var FALLBACK_COMMAND = "npx -y
|
|
13396
|
+
var FALLBACK_COMMAND = "npx -y viberaven audit --vercel-supabase --json";
|
|
13119
13397
|
var SUPPORTED_PROVIDERS = /* @__PURE__ */ new Set(["supabase", "vercel"]);
|
|
13120
13398
|
var configPathsOverride;
|
|
13121
13399
|
function defaultMcpConfigPaths() {
|
|
13122
13400
|
const home = (0, import_node_os2.homedir)();
|
|
13123
13401
|
return [
|
|
13124
|
-
(0,
|
|
13125
|
-
(0,
|
|
13126
|
-
(0,
|
|
13402
|
+
(0, import_node_path21.join)(home, ".config", "claude", "claude_desktop_config.json"),
|
|
13403
|
+
(0, import_node_path21.join)(home, ".cursor", "mcp.json"),
|
|
13404
|
+
(0, import_node_path21.join)(home, ".gemini", "antigravity", "mcp_config.json")
|
|
13127
13405
|
];
|
|
13128
13406
|
}
|
|
13129
13407
|
function resolveConfigPaths() {
|
|
@@ -13266,6 +13544,12 @@ Usage:
|
|
|
13266
13544
|
viberaven open [provider|url]
|
|
13267
13545
|
Open dashboard URL from next action or playbook
|
|
13268
13546
|
|
|
13547
|
+
viberaven init [--agents all|codex,claude,...] [--dry-run] [path]
|
|
13548
|
+
Install bounded VibeRaven agent rules (${PUBLIC_INIT_ALL_COMMAND})
|
|
13549
|
+
|
|
13550
|
+
viberaven doctor --agents [path]
|
|
13551
|
+
Verify agent instruction files and canonical commands
|
|
13552
|
+
|
|
13269
13553
|
|
|
13270
13554
|
|
|
13271
13555
|
Agent workflow (Claude Code / Codex):
|
|
@@ -13352,6 +13636,8 @@ function isBooleanFlag(command, key) {
|
|
|
13352
13636
|
if (key === "open" && (command === "" || command === "scan" || command === "report")) return true;
|
|
13353
13637
|
if (key === "verify" && command === "") return true;
|
|
13354
13638
|
if (key === "vercel-supabase" && command === "audit") return true;
|
|
13639
|
+
if (key === "dry-run" && command === "init") return true;
|
|
13640
|
+
if (key === "agents" && command === "doctor") return true;
|
|
13355
13641
|
return false;
|
|
13356
13642
|
}
|
|
13357
13643
|
function shouldConsumeLeadingHyphenValue(command, key, value) {
|
|
@@ -13368,7 +13654,7 @@ async function guardEarlyVerifyScan(input) {
|
|
|
13368
13654
|
if (!verifyLike) {
|
|
13369
13655
|
return void 0;
|
|
13370
13656
|
}
|
|
13371
|
-
const workspacePath = input.positional[0] ? (0,
|
|
13657
|
+
const workspacePath = input.positional[0] ? (0, import_node_path22.join)(process.cwd(), input.positional[0]) : await resolveWorkspaceRoot(process.cwd());
|
|
13372
13658
|
const loopState = await loadLoopState(workspacePath);
|
|
13373
13659
|
if (loopState.batchApplied <= 0) {
|
|
13374
13660
|
return void 0;
|
|
@@ -13394,7 +13680,7 @@ async function guardEarlyVerifyScan(input) {
|
|
|
13394
13680
|
const nextTask = remainingRepoCodeTasks[0];
|
|
13395
13681
|
console.error("SCAN_DEFERRED: Local heal batch is not full yet, so VibeRaven is protecting scan quota.");
|
|
13396
13682
|
console.error(`Batch progress: ${loopState.batchApplied}/${batchSize} local heals applied since the last scan.`);
|
|
13397
|
-
console.error(`Next local heal: npx -y
|
|
13683
|
+
console.error(`Next local heal: npx -y viberaven --heal --apply --gap ${nextTask.gapId} --yes`);
|
|
13398
13684
|
console.error("Run verify again after the batch is full, or add --force-scan if the user explicitly wants to spend a scan now.");
|
|
13399
13685
|
return 4;
|
|
13400
13686
|
}
|
|
@@ -13444,7 +13730,7 @@ async function cmdStatus(flags, positional) {
|
|
|
13444
13730
|
console.log("Not signed in. Run: viberaven login");
|
|
13445
13731
|
return 1;
|
|
13446
13732
|
}
|
|
13447
|
-
const startDir = positional[0] ? (0,
|
|
13733
|
+
const startDir = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd();
|
|
13448
13734
|
let artifact;
|
|
13449
13735
|
try {
|
|
13450
13736
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -13598,7 +13884,7 @@ async function cmdWatch(flags) {
|
|
|
13598
13884
|
}
|
|
13599
13885
|
}
|
|
13600
13886
|
async function runScanCommand(flags, positional, options) {
|
|
13601
|
-
const workspacePath = positional[0] ? (0,
|
|
13887
|
+
const workspacePath = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : await resolveWorkspaceRoot(process.cwd());
|
|
13602
13888
|
const apiBaseUrl = resolveApiBaseUrl(typeof flags["api-url"] === "string" ? flags["api-url"] : void 0);
|
|
13603
13889
|
let accessToken;
|
|
13604
13890
|
try {
|
|
@@ -13676,7 +13962,7 @@ async function runScanCommand(flags, positional, options) {
|
|
|
13676
13962
|
return { exitCode: 0, artifacts: paths };
|
|
13677
13963
|
}
|
|
13678
13964
|
async function cmdReport(flags, positional) {
|
|
13679
|
-
const startDir = positional[0] ? (0,
|
|
13965
|
+
const startDir = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd();
|
|
13680
13966
|
try {
|
|
13681
13967
|
const paths = await refreshReportFromDisk(startDir);
|
|
13682
13968
|
console.log(`Report refreshed: ${paths.reportPath}`);
|
|
@@ -13698,7 +13984,7 @@ async function cmdReport(flags, positional) {
|
|
|
13698
13984
|
}
|
|
13699
13985
|
}
|
|
13700
13986
|
async function cmdPrompt(flags, positional) {
|
|
13701
|
-
const startDir = positional[0] ? (0,
|
|
13987
|
+
const startDir = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd();
|
|
13702
13988
|
let artifact;
|
|
13703
13989
|
try {
|
|
13704
13990
|
artifact = await loadLastArtifact(startDir);
|
|
@@ -13796,7 +14082,7 @@ async function main() {
|
|
|
13796
14082
|
const wantsJsonl = hasFlag(flags, "jsonl");
|
|
13797
14083
|
const wantsStrict = hasFlag(flags, "strict");
|
|
13798
14084
|
if (flags.condense) {
|
|
13799
|
-
const cwd = positional[0] ? (0,
|
|
14085
|
+
const cwd = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd();
|
|
13800
14086
|
const result = await runCondenseCommand({ cwd });
|
|
13801
14087
|
console.log(`VibeRaven context map refreshed: ${result.contextMapPath}`);
|
|
13802
14088
|
return 0;
|
|
@@ -13825,7 +14111,7 @@ async function main() {
|
|
|
13825
14111
|
console.error("VibeRaven could not produce machine output because scan artifacts were not written.");
|
|
13826
14112
|
return 3;
|
|
13827
14113
|
}
|
|
13828
|
-
const gateResult = scanResult.artifacts && (wantsJson || wantsJsonl || wantsStrict) ? JSON.parse(await (0,
|
|
14114
|
+
const gateResult = scanResult.artifacts && (wantsJson || wantsJsonl || wantsStrict) ? JSON.parse(await (0, import_promises17.readFile)(scanResult.artifacts.gateResultPath, "utf8")) : void 0;
|
|
13829
14115
|
const strictExitCode = wantsStrict && gateResult ? exitCodeForStrictGate(gateResult, { failOnWarnings: flags.strict === "warning" }) : scanResult.exitCode;
|
|
13830
14116
|
if (wantsJson && gateResult) {
|
|
13831
14117
|
process.stdout.write(renderGateResultJson(gateResult));
|
|
@@ -13860,7 +14146,7 @@ async function main() {
|
|
|
13860
14146
|
case "next":
|
|
13861
14147
|
return runNextCommand({
|
|
13862
14148
|
json: Boolean(flags.json),
|
|
13863
|
-
cwd: positional[0] ? (0,
|
|
14149
|
+
cwd: positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd()
|
|
13864
14150
|
});
|
|
13865
14151
|
case "guide": {
|
|
13866
14152
|
const provider2 = positional[0];
|
|
@@ -13897,6 +14183,23 @@ async function main() {
|
|
|
13897
14183
|
return cmdStack(positional);
|
|
13898
14184
|
case "provider-verify":
|
|
13899
14185
|
return cmdProviderVerify(flags, positional);
|
|
14186
|
+
case "init": {
|
|
14187
|
+
const cwd = positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd();
|
|
14188
|
+
const agents = typeof flags.agents === "string" ? flags.agents : void 0;
|
|
14189
|
+
return runInitCommand({
|
|
14190
|
+
cwd,
|
|
14191
|
+
agents,
|
|
14192
|
+
dryRun: flags["dry-run"] === true
|
|
14193
|
+
});
|
|
14194
|
+
}
|
|
14195
|
+
case "doctor":
|
|
14196
|
+
if (flags.agents !== true) {
|
|
14197
|
+
console.error("Usage: viberaven doctor --agents [path]");
|
|
14198
|
+
return 1;
|
|
14199
|
+
}
|
|
14200
|
+
return runDoctorAgentsCommand({
|
|
14201
|
+
cwd: positional[0] ? (0, import_node_path22.join)(process.cwd(), positional[0]) : process.cwd()
|
|
14202
|
+
});
|
|
13900
14203
|
default:
|
|
13901
14204
|
console.error(`Unknown command: ${command}`);
|
|
13902
14205
|
printHelp();
|