@viberaven/cli 1.6.0 → 1.6.1

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/dist/cli.js CHANGED
@@ -14690,7 +14690,7 @@ var VERSION;
14690
14690
  var init_version = __esm({
14691
14691
  "src/version.ts"() {
14692
14692
  "use strict";
14693
- VERSION = "1.6.0";
14693
+ VERSION = "1.6.1";
14694
14694
  }
14695
14695
  });
14696
14696
 
@@ -17417,6 +17417,17 @@ var init_initGithub = __esm({
17417
17417
  }
17418
17418
  });
17419
17419
 
17420
+ // src/local-ui/stack/setupLink.ts
17421
+ function setupFragment(ids) {
17422
+ const safe2 = [...new Set(ids.filter((id) => /^[a-z][a-z0-9-]{0,39}$/.test(id)))].slice(0, 30);
17423
+ return `#${new URLSearchParams({ stack: safe2.join(",") })}`;
17424
+ }
17425
+ var init_setupLink = __esm({
17426
+ "src/local-ui/stack/setupLink.ts"() {
17427
+ "use strict";
17428
+ }
17429
+ });
17430
+
17420
17431
  // src/commands/doctorAgents.ts
17421
17432
  function managedBlocks(content) {
17422
17433
  const blocks = content.match(/<!-- (?:VIBERAVEN:START|viberaven:agent-rules:start) -->[\s\S]*?<!-- (?:VIBERAVEN:END|viberaven:agent-rules:end) -->/g);
@@ -24762,7 +24773,8 @@ __export(cli_exports, {
24762
24773
  parseArgs: () => parseArgs,
24763
24774
  printHelp: () => printHelp,
24764
24775
  resolveDefaultEntrypointMode: () => resolveDefaultEntrypointMode,
24765
- runScanCommand: () => runScanCommand
24776
+ runScanCommand: () => runScanCommand,
24777
+ stackInitialPath: () => stackInitialPath
24766
24778
  });
24767
24779
  module.exports = __toCommonJS(cli_exports);
24768
24780
  function printHelp() {
@@ -24777,6 +24789,7 @@ Usage:
24777
24789
  viberaven tui Interactive terminal menu
24778
24790
 
24779
24791
  viberaven check [--json] [--quiet] [path]
24792
+ viberaven --stack supabase,vercel,stripe Open the Studio with these services already picked
24780
24793
  viberaven check --base <ref> [--markdown] What this change introduced and fixed, compared with <ref>
24781
24794
  viberaven init --github [--dry-run] Check every pull request in GitHub Actions
24782
24795
  Local production check: one line per finding, exit 1 on blockers
@@ -24937,6 +24950,11 @@ function isBooleanFlag(command, key) {
24937
24950
  if (key === "agents" && command === "doctor") return true;
24938
24951
  return false;
24939
24952
  }
24953
+ function stackInitialPath(flags) {
24954
+ if (typeof flags.stack !== "string") return void 0;
24955
+ const ids = flags.stack.split(",").map((id) => id.trim().toLowerCase()).filter(Boolean);
24956
+ return ids.length ? `/${setupFragment(ids)}` : void 0;
24957
+ }
24940
24958
  function hasFlag(flags, key) {
24941
24959
  return flags[key] === true || typeof flags[key] === "string";
24942
24960
  }
@@ -25220,7 +25238,7 @@ async function main() {
25220
25238
  });
25221
25239
  if (mode === "local-ui") {
25222
25240
  const cwd = positional[0] ? (0, import_node_path42.resolve)(process.cwd(), positional[0]) : process.cwd();
25223
- const handle = await startLocalUiServer({ cwd });
25241
+ const handle = await startLocalUiServer({ cwd, initialPath: stackInitialPath(flags) });
25224
25242
  console.log(`VibeRaven local UI: ${handle.url}`);
25225
25243
  await waitForServerShutdown();
25226
25244
  await handle.close();
@@ -25241,7 +25259,7 @@ async function main() {
25241
25259
  case "ui": {
25242
25260
  const cwd = positional[0] ? (0, import_node_path42.resolve)(process.cwd(), positional[0]) : process.cwd();
25243
25261
  const envPort = Number(process.env.PORT);
25244
- const handle = await startLocalUiServer({ cwd, port: Number.isFinite(envPort) && envPort > 0 ? envPort : void 0 });
25262
+ const handle = await startLocalUiServer({ cwd, port: Number.isFinite(envPort) && envPort > 0 ? envPort : void 0, initialPath: stackInitialPath(flags) });
25245
25263
  console.log(`VibeRaven local UI: ${handle.url}`);
25246
25264
  await waitForServerShutdown();
25247
25265
  await handle.close();
@@ -25421,6 +25439,7 @@ var init_cli = __esm({
25421
25439
  init_commands();
25422
25440
  init_runInit();
25423
25441
  init_initGithub();
25442
+ init_setupLink();
25424
25443
  init_runDoctor();
25425
25444
  init_runValidateNpmPackage();
25426
25445
  init_runAudit();
@@ -25458,5 +25477,6 @@ init_cli();
25458
25477
  parseArgs,
25459
25478
  printHelp,
25460
25479
  resolveDefaultEntrypointMode,
25461
- runScanCommand
25480
+ runScanCommand,
25481
+ stackInitialPath
25462
25482
  });
package/dist/stack/app.js CHANGED
@@ -16,4 +16,4 @@ ${l.map((d,h)=>`${h+1}. ${d.title}`).join(`
16
16
  `)}
17
17
  After each, note the files touched. Do not claim production-ready; I will re-check.`},`Fix all ${l.length} repo blockers`,{label:"Re-check to update the score",action:"recheck"})},focusBlockers(r){if(!S(e.get()).available.findings)return;e.set(d=>({section:"findings",drawer:null,contextProviderId:r,setup:{...d.setup,open:!1},flow:{...d.flow,step:"findings"}}));let l=Array.from(document.querySelectorAll(".finding")).find(d=>d.dataset.provider===r)??document.getElementById("stage-heading");l?.focus({preventScroll:!0}),l?.scrollIntoView?.({behavior:"smooth",block:"center"})},async compare(r,l){if(!r.trim()||!l.trim()){e.set({compare:{...e.get().compare,error:"Both refs are required."}});return}e.set({busy:{...e.get().busy,compare:!0},compare:{...e.get().compare,from:r,to:l,error:null}});try{let d=await k.compare(r.trim(),l.trim());e.set({compare:{from:r,to:l,result:d,error:null}})}catch(d){e.set({compare:{from:r,to:l,result:null,error:C(d)}})}finally{e.set({busy:{...e.get().busy,compare:!1}})}},async explainDiff(r,l){e.get().setup.running||await c({...o(),taskKind:"diff",release:{id:`${r.trim()}..${l.trim()}`,label:`${r.trim()} \u2192 ${l.trim()}`},prompt:`Explain what changed between ${r.trim()} and ${l.trim()} in this repo, in plain words. Call out anything risky for production: auth, database writes, webhooks, env, payments.`},`Explain ${r.trim()} \u2192 ${l.trim()}`)},goToStep(r){let l=S(e.get());l.available[r]&&(r==="fix"&&!l.current&&e.flow({fixId:l.fixable[0]?.id??null,handoff:null}),e.flow({step:r}),u())},async checkMyApp(){let r=e.get();if(!(r.busy.scan||r.setup.running)){e.set({busy:{...r.busy,scan:!0}});try{await k.scan(),await a();let l=S(e.get());e.flow({step:ie(l),fixId:null,handoff:null,recheck:null}),u()}catch(l){e.toast(`The check did not finish: ${C(l)}`,"err")}finally{e.set({busy:{...e.get().busy,scan:!1}})}}},fixFinding(r){let l=S(e.get()),d=r?l.fixable.find(h=>h.id===r):l.fixable[0];d&&(e.flow({step:"fix",fixId:d.id,handoff:e.get().flow.handoff?.findingId===d.id?e.get().flow.handoff:null}),u())},async sendFix(){let r=e.get(),l=S(r).current;if(!l||r.busy.chat||r.setup.running||!r.probes[r.cliId]?.ready&&(await p.testConnection(r.cliId),!e.get().probes[r.cliId]?.ready))return;let d=e.get().cliId,h=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;e.set({busy:{...e.get().busy,chat:!0},workingSince:Date.now(),runId:h}),e.flow({handoff:{findingId:l.id,cliId:d,status:"running",output:""}}),e.push({role:"me",text:`Fix: ${l.title}`});try{let g=(await k.chat({...o(),runId:h,taskKind:"fix",prompt:l.prompt,displayPrompt:`Fix: ${l.title}`,provider:l.service?{id:l.service.id,name:l.service.name,area:""}:void 0})).agentRun,m=/Stopped by user/.test(g.stderr??""),M=g.timedOut||m||g.exitCode!==null&&g.exitCode!==0||!g.output?.trim(),w=g.output?.trim()||(m?"Stopped.":g.timedOut?`${d} did not finish in time and was stopped.`:`${d} exited with code ${g.exitCode??"unknown"} and no answer.
18
18
 
19
- ${Ge(g.stderr,1200)}`);e.flow({handoff:{findingId:l.id,cliId:d,status:M?"failed":"done",output:w}}),e.push({role:M?"error":"agent",text:w,cliId:d})}catch(y){e.flow({handoff:{findingId:l.id,cliId:d,status:"failed",output:C(y)}})}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}},async copyFix(){let r=S(e.get()).current;if(r)try{await navigator.clipboard.writeText(r.prompt),e.toast("Prompt copied. Paste it into your coding agent.")}catch{e.toast("Could not copy. Select the prompt and copy it by hand.","err")}},async checkAgain(){let r=e.get(),l=S(r).current;if(!l||r.busy.scan)return;let d=r.project.gate?.score;e.flow({step:"recheck",recheck:{findingId:l.id,title:l.title,status:"running",scoreBefore:d}}),e.set({busy:{...e.get().busy,scan:!0}}),u();try{await k.scan(),await a();let h=S(e.get()),y=h.findings.find(M=>M.id===l.id),g=e.get().project.gate?.score;if(y){e.flow({recheck:{findingId:l.id,title:l.title,status:"open",message:y.summary,scoreBefore:d,scoreAfter:g}});return}let m=h.fixable[0]??null;e.flow({recheck:{findingId:l.id,title:l.title,status:"fixed",nextId:m?.id??null,scoreBefore:d,scoreAfter:g}}),window.setTimeout(()=>{let M=e.get().flow;if(M.step!=="recheck"||M.recheck?.findingId!==l.id||M.recheck.status!=="fixed")return;let w=S(e.get());m&&w.fixable.some(D=>D.id===m.id)?e.flow({step:"fix",fixId:m.id,handoff:null}):e.flow({step:"ready",fixId:null,handoff:null}),u()},1600)}catch(h){e.flow({recheck:{findingId:l.id,title:l.title,status:"error",message:C(h),scoreBefore:d}})}finally{e.set({busy:{...e.get().busy,scan:!1}})}},toggleChecklistItem(r){let l={...e.get().flow.checklist,[r]:!e.get().flow.checklist[r]};e.flow({checklist:l})},togglePrChecks(r){let l=r??!e.get().prChecks.open;e.set(d=>({prChecks:{...d.prChecks,open:l,error:null}})),l?queueMicrotask(()=>document.getElementById("pr-checks-action")?.focus({preventScroll:!0})):document.getElementById("pr-checks-button")?.focus({preventScroll:!0})},async addPrChecks(){if(!e.get().prChecks.busy){e.set(r=>({prChecks:{...r.prChecks,busy:!0,error:null}}));try{let r=await k.addGithubWorkflow();e.set(l=>({prChecks:{...l.prChecks,status:r.status,written:r.written,busy:!1}})),queueMicrotask(()=>document.getElementById("pr-checks-copy")?.focus({preventScroll:!0}))}catch(r){e.set(l=>({prChecks:{...l.prChecks,busy:!1,error:C(r)}}))}}},async copyPrCommit(){let r=e.get().prChecks.status?.path??".github/workflows/viberaven.yml";try{await navigator.clipboard.writeText(`git add ${r} && git commit -m "Check pull requests with VibeRaven"`),e.toast("Copied. Run it, then push.")}catch{e.toast("Could not copy. Select the command and copy it by hand.","err")}},toggleMore(r){let l=r??!e.get().moreOpen;e.set({moreOpen:l}),l?queueMicrotask(()=>document.querySelector('#more-menu [role="menuitem"]')?.focus({preventScroll:!0})):document.getElementById("open-more")?.focus({preventScroll:!0})},openMore(r){if(e.set({moreOpen:!1}),r==="chat"){s();return}if(r==="services"){e.set({drawer:"services",agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}));return}e.set({drawer:r,agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}))}};return p}function Kt(){let e=document.getElementById("app");if(!e)return;let i=be(Wt()),n=qt(i),s=()=>He(e,i,n);i.subscribe(s),s(),document.addEventListener("keydown",u=>{let o=i.get().fullCheck.step;if(u.key==="Escape"&&o!=="closed"){o!=="running"&&n.closeFullCheck();return}if(u.key==="Escape"&&i.get().moreOpen){n.toggleMore(!1);return}if(u.key==="Escape"&&i.get().prChecks.open){n.togglePrChecks(!1);return}if(u.key==="Escape"&&i.get().agentOpen){n.toggleAgent();return}u.key==="Escape"&&i.get().drawer&&n.toggleDrawer(null)}),document.addEventListener("pointerdown",u=>{!i.get().moreOpen||u.target?.closest("#more-menu, #open-more")||i.set({moreOpen:!1})});let a=()=>{let u=i.get();if(!u.catalog.length||u.setup.running||u.busy.chat)return;let o=Qe(window.location.hash,u.catalog.map(p=>p.id));o!==null&&(i.set({section:"stack",agentOpen:!0,setup:{...u.setup,open:!0,initialized:!0,selected:o,progress:[],error:null}}),history.replaceState(null,"",window.location.pathname+window.location.search),document.getElementById("stack-setup-heading")?.focus())};window.addEventListener("hashchange",a),k.catalog().then(u=>{i.set(o=>({catalog:u.providers,setup:o.setup.open&&!o.setup.initialized?{...o.setup,initialized:!0,selected:pe(u.providers)}:o.setup})),a()}).catch(()=>{}),k.verified().then(u=>i.set({verified:u.verified})).catch(()=>{}),k.githubWorkflow().then(u=>i.set(o=>({prChecks:{...o.prChecks,status:u}}))).catch(()=>{}),k.agents().then(u=>{i.set({agents:u.agents.filter(p=>p.id==="codex"||p.id==="claude"||p.id==="gemini")});let o=u.agents.find(p=>p.id===i.get().cliId);if(o&&!o.installed){let p=u.agents.find(r=>r.installed);p&&i.set({cliId:p.id})}n.testConnection(i.get().cliId,{silent:!0})}).catch(()=>{});let c=async()=>{try{let u=await k.scanStatus();if(i.set({scan:u}),u.state==="running")window.setTimeout(c,1500);else if(u.state==="done"&&i.get().project.empty){let o=await k.project();i.set({project:o}),i.get().flow.step==="app"&&i.flow({step:ie(S(i.get()))})}}catch{}};c(),window.setInterval(()=>{Ye(document,i.get().workingSince)},1e3)}Kt();})();
19
+ ${Ge(g.stderr,1200)}`);e.flow({handoff:{findingId:l.id,cliId:d,status:M?"failed":"done",output:w}}),e.push({role:M?"error":"agent",text:w,cliId:d})}catch(y){e.flow({handoff:{findingId:l.id,cliId:d,status:"failed",output:C(y)}})}finally{e.set({busy:{...e.get().busy,chat:!1},workingSince:null,runId:null})}},async copyFix(){let r=S(e.get()).current;if(r)try{await navigator.clipboard.writeText(r.prompt),e.toast("Prompt copied. Paste it into your coding agent.")}catch{e.toast("Could not copy. Select the prompt and copy it by hand.","err")}},async checkAgain(){let r=e.get(),l=S(r).current;if(!l||r.busy.scan)return;let d=r.project.gate?.score;e.flow({step:"recheck",recheck:{findingId:l.id,title:l.title,status:"running",scoreBefore:d}}),e.set({busy:{...e.get().busy,scan:!0}}),u();try{await k.scan(),await a();let h=S(e.get()),y=h.findings.find(M=>M.id===l.id),g=e.get().project.gate?.score;if(y){e.flow({recheck:{findingId:l.id,title:l.title,status:"open",message:y.summary,scoreBefore:d,scoreAfter:g}});return}let m=h.fixable[0]??null;e.flow({recheck:{findingId:l.id,title:l.title,status:"fixed",nextId:m?.id??null,scoreBefore:d,scoreAfter:g}}),window.setTimeout(()=>{let M=e.get().flow;if(M.step!=="recheck"||M.recheck?.findingId!==l.id||M.recheck.status!=="fixed")return;let w=S(e.get());m&&w.fixable.some(D=>D.id===m.id)?e.flow({step:"fix",fixId:m.id,handoff:null}):e.flow({step:"ready",fixId:null,handoff:null}),u()},1600)}catch(h){e.flow({recheck:{findingId:l.id,title:l.title,status:"error",message:C(h),scoreBefore:d}})}finally{e.set({busy:{...e.get().busy,scan:!1}})}},toggleChecklistItem(r){let l={...e.get().flow.checklist,[r]:!e.get().flow.checklist[r]};e.flow({checklist:l})},togglePrChecks(r){let l=r??!e.get().prChecks.open;e.set(d=>({prChecks:{...d.prChecks,open:l,error:null}})),l?queueMicrotask(()=>document.getElementById("pr-checks-action")?.focus({preventScroll:!0})):document.getElementById("pr-checks-button")?.focus({preventScroll:!0})},async addPrChecks(){if(!e.get().prChecks.busy){e.set(r=>({prChecks:{...r.prChecks,busy:!0,error:null}}));try{let r=await k.addGithubWorkflow();e.set(l=>({prChecks:{...l.prChecks,status:r.status,written:r.written,busy:!1}})),queueMicrotask(()=>document.getElementById("pr-checks-copy")?.focus({preventScroll:!0}))}catch(r){e.set(l=>({prChecks:{...l.prChecks,busy:!1,error:C(r)}}))}}},async copyPrCommit(){let r=e.get().prChecks.status?.path??".github/workflows/viberaven.yml";try{await navigator.clipboard.writeText(`git add ${r} && git commit -m "Check pull requests with VibeRaven"`),e.toast("Copied. Run it, then push.")}catch{e.toast("Could not copy. Select the command and copy it by hand.","err")}},toggleMore(r){let l=r??!e.get().moreOpen;e.set({moreOpen:l}),l?queueMicrotask(()=>document.querySelector('#more-menu [role="menuitem"]')?.focus({preventScroll:!0})):document.getElementById("open-more")?.focus({preventScroll:!0})},openMore(r){if(e.set({moreOpen:!1}),r==="chat"){s();return}if(r==="services"){e.set({drawer:"services",agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}));return}e.set({drawer:r,agentOpen:!1}),queueMicrotask(()=>document.getElementById("drawer-close")?.focus({preventScroll:!0}))}};return p}function Kt(){let e=document.getElementById("app");if(!e)return;let i=be(Wt()),n=qt(i),s=()=>He(e,i,n);i.subscribe(s),s(),document.addEventListener("keydown",u=>{let o=i.get().fullCheck.step;if(u.key==="Escape"&&o!=="closed"){o!=="running"&&n.closeFullCheck();return}if(u.key==="Escape"&&i.get().moreOpen){n.toggleMore(!1);return}if(u.key==="Escape"&&i.get().prChecks.open){n.togglePrChecks(!1);return}if(u.key==="Escape"&&i.get().agentOpen){n.toggleAgent();return}u.key==="Escape"&&i.get().drawer&&n.toggleDrawer(null)}),document.addEventListener("pointerdown",u=>{!i.get().moreOpen||u.target?.closest("#more-menu, #open-more")||i.set({moreOpen:!1})});let a=()=>{let u=i.get();if(!u.catalog.length||u.setup.running||u.busy.chat)return;let o=Qe(window.location.hash,u.catalog.map(p=>p.id));o!==null&&(i.set({section:"stack",drawer:"services",agentOpen:!1,moreOpen:!1,setup:{...u.setup,open:!0,initialized:!0,selected:o,progress:[],error:null}}),history.replaceState(null,"",window.location.pathname+window.location.search),document.getElementById("stack-setup-heading")?.focus())};window.addEventListener("hashchange",a),k.catalog().then(u=>{i.set(o=>({catalog:u.providers,setup:o.setup.open&&!o.setup.initialized?{...o.setup,initialized:!0,selected:pe(u.providers)}:o.setup})),a()}).catch(()=>{}),k.verified().then(u=>i.set({verified:u.verified})).catch(()=>{}),k.githubWorkflow().then(u=>i.set(o=>({prChecks:{...o.prChecks,status:u}}))).catch(()=>{}),k.agents().then(u=>{i.set({agents:u.agents.filter(p=>p.id==="codex"||p.id==="claude"||p.id==="gemini")});let o=u.agents.find(p=>p.id===i.get().cliId);if(o&&!o.installed){let p=u.agents.find(r=>r.installed);p&&i.set({cliId:p.id})}n.testConnection(i.get().cliId,{silent:!0})}).catch(()=>{});let c=async()=>{try{let u=await k.scanStatus();if(i.set({scan:u}),u.state==="running")window.setTimeout(c,1500);else if(u.state==="done"&&i.get().project.empty){let o=await k.project();i.set({project:o}),i.get().flow.step==="app"&&i.flow({step:ie(S(i.get()))})}}catch{}};c(),window.setInterval(()=>{Ye(document,i.get().workingSince)},1e3)}Kt();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viberaven/cli",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Local Studio cockpit for AI-built apps: agentic chat, provider context, release review, diffs, and approval-controlled repo work.",
5
5
  "license": "MIT",
6
6
  "author": "VibeRaven",