@vibeflow-tools/cli 0.4.0 → 0.4.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/index.js +7 -5
- package/dist/index.js +7 -5
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -29334,12 +29334,14 @@ lucide-react/dist/esm/lucide-react.js:
|
|
|
29334
29334
|
*)
|
|
29335
29335
|
*/
|
|
29336
29336
|
`;function en(t){return`
|
|
29337
|
+
var _vfScriptSrc = document.currentScript && document.currentScript.src;
|
|
29338
|
+
var _vfOrigin = _vfScriptSrc ? new URL(_vfScriptSrc).origin : ('http://' + window.location.host);
|
|
29337
29339
|
var PROTO_CONFIG = {
|
|
29338
29340
|
port: ${t},
|
|
29339
|
-
wsUrl: 'ws
|
|
29340
|
-
apiUrl:
|
|
29341
|
-
pagesUrl:
|
|
29342
|
-
screenshotsUrl:
|
|
29341
|
+
wsUrl: _vfOrigin.replace(/^http/, 'ws'),
|
|
29342
|
+
apiUrl: _vfOrigin + '/api/tasks',
|
|
29343
|
+
pagesUrl: _vfOrigin + '/api/pages',
|
|
29344
|
+
screenshotsUrl: _vfOrigin + '/screenshots/'
|
|
29343
29345
|
};
|
|
29344
29346
|
`+Ze}function Tn(t){return`var PROTO_CONFIG = ${JSON.stringify({port:0,wsUrl:"",apiUrl:`${t}/api/overlay/tasks`,pagesUrl:"",screenshotsUrl:""})};
|
|
29345
29347
|
`+Ze}import{existsSync as jt,readFileSync as $t}from"fs";import{dirname as zt,join as tn}from"path";import{fileURLToPath as Bt}from"url";var _n=`*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
|
|
@@ -29411,7 +29413,7 @@ li{margin:8px 0}</style></head>
|
|
|
29411
29413
|
Push them to your board now? [Y/n]: `),async P=>{if(C.close(),P.trim().toLowerCase()==="n"){console.log(D.dim(" Skipped. You can push later with: vibeflow push")),u();return}let k=vt.createInterface({input:process.stdin,output:process.stdout});k.question(D.cyan(" Delete local task files after push? [y/N]: "),async w=>{k.close();let R=w.trim().toLowerCase()!=="y";try{let L=await fetch(`${t}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({boardId:r.id,tasks:c,keepLocalFiles:R})}),f={};try{f=await L.json()}catch{}L.ok?(console.log(D.green(` \u2713 Pushed ${f.imported??0} task${(f.imported??0)!==1?"s":""} to ${r.name}`)),(f.skipped??0)>0&&console.log(D.dim(` (${f.skipped} already existed and were skipped)`))):console.log(D.red(` Push failed: ${f.error??`HTTP ${L.status}`}`))}catch(L){console.log(D.red(` Push failed: ${L instanceof Error?L.message:"Network error"}`))}u()})})})}async function Ve(){let t=bt();console.log(D.cyan(" Initiating device login flow..."));let e=await fetch(`${t}/api/cli/auth/device-init`,{method:"POST",headers:{"Content-Type":"application/json"}});e.ok||(console.error(D.red(` Failed to initiate login: ${e.status} ${e.statusText}`)),process.exit(1));let{deviceCode:r,userCode:i,verificationUrl:s,expiresIn:o}=await e.json();console.log(),console.log(D.bold(" Open this URL in your browser to authorize:")),console.log(D.underline(` ${s}`)),console.log();try{await Dr(s),console.log(D.dim(" (Browser opened automatically)"))}catch{}let a=Date.now()+o*1e3,c=3e3;for(;Date.now()<a;){await Wr(c);let l=await fetch(`${t}/api/cli/auth/device-poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:r})});if(!l.ok){console.error(D.red(" Poll request failed. Retrying..."));continue}let u=await l.json();if("token"in u){await Vn(u.token),console.log(),console.log(D.green(" Logged in successfully. Now operating in SaaS mode.")),await Promise.all([$r(t,u.token),kt(t,u.token)]);let{readWorkspace:C}=await import("./workspace-KGOQ67YV.js"),P=await C();P&&await zr(t,u.token,P);return}"expired"in u&&(console.error(D.red(" Device code expired. Please try again.")),process.exit(1)),process.stdout.write(D.dim("."))}console.error(D.red(`
|
|
29412
29414
|
Login timed out. Please try again.`)),process.exit(1)}import Br from"chalk";async function xt(){await qn(),console.log(Br.green(" Logged out. Now operating in local mode."))}import B from"chalk";import{unlinkSync as Vr,readFileSync as qr,existsSync as Yr}from"fs";import{resolve as Kr,join as Qr}from"path";var Gr="http://localhost:3000";function Xr(){return process.env.SPOTA_API_URL??Gr}function Jr(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function Ct(t,e,r=24){let i=Math.round(t/e*r);return`[${"\u2588".repeat(i)+"\u2591".repeat(r-i)}]`}async function Zr(t,e,r,i){let s=[];for(let{localId:w,remoteId:R}of i){let L=ne(r,w);for(let f of L){let _=f.linkedPath??Qr(xn(r,w),f.name);Yr(_)&&s.push({remoteId:R,name:f.name,filePath:_,size:f.size})}}if(s.length===0)return{uploaded:0,failed:0,failedFiles:[]};let o=s.length,a=s.reduce((w,R)=>w+R.size,0);console.log(B.cyan(`
|
|
29413
29415
|
Uploading ${o} file(s) (${Jr(a)})...`));let c=0,l=0,u=0,C=Date.now(),P=[];for(let w of s){let R=Math.round(c/o*100),L=Ct(c,o),f=(Date.now()-C)/1e3,_=u/Math.max(f,.01),F=a-u,q=_>0?Math.ceil(F/_):0,M=q>60?`${Math.ceil(q/60)}m`:`${q}s`;process.stdout.write(`\r ${L} ${R}% ${w.name.slice(0,28)} ETA: ${M} `);try{let Y=qr(w.filePath),oe=await fetch(`${t}/api/tasks/${encodeURIComponent(w.remoteId)}/files`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/octet-stream","x-filename":encodeURIComponent(w.name)},body:Y});oe.ok?(c++,u+=w.size):(l++,P.push({name:w.name,reason:`HTTP ${oe.status}`}))}catch(Y){l++,P.push({name:w.name,reason:Y instanceof Error?Y.message:String(Y)})}}let k=Ct(o,o);return process.stdout.write(`\r ${k} 100% Done${" ".repeat(40)}
|
|
29414
|
-
`),{uploaded:c,failed:l,failedFiles:P}}async function St(t,e){let r=Kr(t),i=await Q();if(!i&&(console.log(B.yellow(" Not logged in. Starting login flow...")),await Ve(),i=await Q(),!i)){console.error(B.red(" Login failed. Please run `vibeflow login` and try again.")),process.exitCode=1;return}let s=ce(r);if(s.length===0){console.log(B.dim(" No local tasks found. Nothing to push."));return}console.log(B.cyan(` Found ${s.length} local task(s). Pushing to SaaS...`));let o=Xr(),a=e.workspace;if(!a){let f=await J();f&&(a=f.id,console.log(B.dim(` Using board: ${f.icon??""} ${f.name}`)))}let c={tasks:s};a&&(c.workspaceId=a);let l;try{let f=await fetch(`${o}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(c)});if(!f.ok){let _=await f.json().catch(()=>({}));console.error(B.red(` Import failed: ${f.status} ${_.error??f.statusText}`)),process.exitCode=1;return}l=await f.json()}catch(f){let _=f instanceof Error?f.message:String(f);console.error(B.red(` Network error: ${_}`)),process.exitCode=1;return}console.log(B.green(` \u2713 Pushed ${l.imported} task(s) to SaaS`)),l.skipped&&l.skipped>0&&console.log(B.dim(` Skipped ${l.skipped} already-imported task(s).`));let u=(await J())?.name??l.workspaceId;console.log(B.dim(` Board: ${u}`));let C=l.idMap??{},P=s.filter(f=>f.id&&C[f.id]).map(f=>({localId:f.id,remoteId:C[f.id]})),{uploaded:k,failed:w,failedFiles:R}=await Zr(o,i,r,P);if(k>0&&console.log(B.green(` \u2713 Uploaded ${k} file(s) to storage`)),w>0){console.log(B.yellow(` \u26A0 ${w} file(s) failed to upload`));for(let f of R)console.log(B.dim(` - ${f.name}: ${f.reason}`))}if(e.keepLocalFiles){console.log(B.dim(" Local task files kept (--keep-local-files)."));return}let L=0;for(let f of s)try{Vr(f.filePath),L++}catch{}console.log(B.dim(` Deleted ${L} local task file(s).`))}var eo="http://localhost:3000";function qe(){return process.env.SPOTA_API_URL??eo}var no={backlog:"backlog",todo:"todo","in-progress":"in_progress",review:"review",done:"done"},to={backlog:"backlog",todo:"todo",in_progress:"in-progress",review:"review",done:"done",cancelled:"done"};function de(t){return to[t]??"todo"}function ro(t){return no[t]??"todo"}async function Ye(){let t=await Q();return t?{Authorization:`Bearer ${t}`}:null}async function Se(t){let e=await Ye();if(!e)return null;let r=new URL(`${qe()}/api/cli/tasks`);t&&r.searchParams.set("boardId",t);try{let i=await fetch(r.toString(),{headers:e});return i.ok?i.json():null}catch{return null}}async function Et(t){let e=await Se();return e?e.tasks.find(r=>r.id===t)??null:null}async function mn(t,e){let r=await Ye();if(!r)return null;let i={};e.status!==void 0&&(i.status=ro(e.status)),e.title!==void 0&&(i.title=e.title),e.description!==void 0&&(i.description=e.description),e.priority!==void 0&&(i.priority=e.priority);try{let s=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}`,{method:"PATCH",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!s.ok)return null;let o=await s.json();return{task:o.task,warning:o.warning}}catch{return null}}async function Pt(t,e){let r=await Ye();if(!r)return null;try{let i=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}/comments`,{method:"POST",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify({body:e})});return i.ok?(await i.json()).comment:null}catch{return null}}async function It(t){let e=await Ye();if(!e)return null;try{let r=await fetch(`${qe()}/api/cli/tasks`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify(t)});return r.ok?(await r.json()).task:null}catch{return null}}import{readFileSync as hn,existsSync as vn,unlinkSync as yo}from"fs";import{resolve as V,join as At,basename as Ot}from"path";import n from"chalk";import{createHash as oo,randomUUID as ao}from"crypto";import{existsSync as io,readFileSync as so,writeFileSync as lo,mkdirSync as co}from"fs";import{join as Tt}from"path";import _t from"os";import{PostHog as uo}from"posthog-node";var po="phc_C9AUV3rnayLfVvxgHtvj6AXcwsd8FKWUfJ9262zWsCvM",fo="https://eu.i.posthog.com";function Rt(){return Tt(process.env.HOME??_t.homedir(),".vibeflow")}function Nt(){return Tt(Rt(),"config.json")}function Ke(){try{return JSON.parse(so(Nt(),"utf-8"))}catch{return{}}}function Lt(t){let e=Rt();io(e)||co(e,{recursive:!0});let r=Ke();lo(Nt(),JSON.stringify({...r,...t},null,2),"utf-8")}function Ft(){return process.env.VIBEFLOW_TELEMETRY==="0"?!1:Ke().disabled!==!0}function gn(t){Lt({disabled:!t})}function Dt(){let t=Ft(),e=Ke();return{enabled:t,anonymousId:e.anonymousId??null}}function mo(){let t=Ke();if(t.anonymousId)return t.anonymousId;let e=ao();return Lt({anonymousId:e}),e}function go(){let t=_t.userInfo().username;return oo("sha256").update(t).digest("hex").slice(0,16)}var Ne=null;function ho(){return Ft()?(Ne||(Ne=new uo(po,{host:fo,flushAt:1,flushInterval:0})),Ne):null}function ye(t,e){let r=ho();if(!r)return;let i=mo();r.capture({distinctId:i,event:t,properties:{...e,$user_id:go()}})}async function be(){if(Ne)try{await Ne.shutdown()}catch{}}function bo(t,e){let r=u=>u.replace(/[^0-9.]/g,"").split(".").map(Number),[i=0,s=0,o=0]=r(t),[a=0,c=0,l=0]=r(e);return i!==a?i>a:s!==c?s>c:o>l}function ko(){let t="0.4.0";if(!t)return;let e="@vibeflow-tools/cli";import("https").then(({default:r})=>{let i=r.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:5e3},s=>{let o="";s.on("data",a=>{o+=a.toString()}),s.on("end",()=>{try{let{version:a}=JSON.parse(o);a&&bo(a,t)&&(console.log(),console.log(n.bgYellow.black.bold(` \u2191 Update available: ${t} \u2192 ${a} `)),console.log(n.dim(" Run: ")+n.cyan(`npm install -g ${e}@${a}`)+n.dim(" to update")),console.log())}catch{}})});i.on("error",()=>{}),i.on("timeout",()=>{i.destroy()})}).catch(()=>{})}wt();var ke={backlog:n.gray,todo:n.yellow,"in-progress":n.blue,review:n.magenta,done:n.green},wo=new Set(["Task","Bug","Research"]);function xo(t){if(t){for(let e of wo)if(e.toLowerCase()===t.toLowerCase())return e}}function ge(t){let e=(t??"Medium").trim().toLowerCase();return e==="critical"?0:e==="high"?1:e==="low"?3:2}var Mt=["in-progress","review","todo","backlog","done"];function Qe(t){let e=Mt.indexOf(t);return e===-1?Mt.length:e}function Ht(t){try{return Ge("git",["push"],{cwd:t,stdio:"inherit"}),{ok:!0}}catch{try{let e=yn("git rev-parse --abbrev-ref HEAD",{cwd:t}).toString().trim();return Ge("git",["push","--set-upstream","origin",e],{cwd:t,stdio:"inherit"}),{ok:!0}}catch(e){return{ok:!1,error:(e instanceof Error?e.message:String(e)).slice(0,220)}}}}function Ee(t){let{autoCommit:e,autoPush:r,autoComment:i,createBranch:s}=t;if(console.log(n.bold("Agent instructions (concise):")),console.log(n.dim(" Discover: vibeflow tasks --status todo | vibeflow tasks --type Research | vibeflow tasks --user <email> | vibeflow tasks --tag <tag>")),console.log(n.dim(" Details: vibeflow tasks --get <id> (full task info with comments and files)")),console.log(n.dim(' Create: vibeflow tasks --add --title "..." --description "..."')),console.log(),console.log(n.dim(" Workflow:")),console.log(n.yellow(" \u26A0 IMMEDIATELY set in-progress BEFORE any implementation work:")),console.log(n.dim(" 1. vibeflow tasks --edit <id> --set-status in-progress \u2190 DO THIS FIRST")),console.log(n.dim(" 2. <implement the change>")),e){console.log(n.dim(" 3. git add <files> (stage your changes first)"));let o=["--set-status review"];e&&o.push('--commit-message "<one-line summary>"'),i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`)),console.log(n.dim(" CLI will commit staged changes and link the commit SHA automatically."))}else{console.log(n.dim(' 3. git add <files> && vibeflow tasks --commit --task <id> --message "<one-line summary>"'));let o=["--set-status review"];i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`))}i&&(console.log(n.dim("")),console.log(n.dim(" Comment format (--comment):")),console.log(n.dim(" \xB7 Plain text for concise one-liners.")),console.log(n.dim(" \xB7 Markdown for multi-section reports. Use **bold**, bullet lists, code fences.")),console.log(n.dim(" \xB7 Must cover: what changed, why, key decisions, anything future agents should know.")),console.log(n.dim(" \xB7 For long reports, attach a .md file and reference it in the comment."))),console.log(),e&&console.log(n.dim(" [setting] Auto-commit ON: provide --commit-message when setting status to review; CLI commits.")),r&&console.log(n.dim(" [setting] Auto-push ON: CLI pushes after the commit automatically.")),i&&console.log(n.dim(" [setting] Auto-comment ON: --comment is required when setting status to review.")),s&&(console.log(n.dim(" [setting] Create branch ON: after ALL tasks in this session are done, create and push a descriptive branch:")),console.log(n.dim(" git checkout -b <short-name> (e.g. fix/annotation-errors, feat/eye-toggle, chore/cleanup-extension)")),console.log(n.dim(" git push -u origin HEAD")),console.log(n.dim(" Branch name rules: lowercase, kebab-case, 2-5 words, prefix fix/feat/chore/docs.")),console.log(n.dim(" Describe the WORK done (not dates). Bad: agent/2026-04-16. Good: fix/bug-errors-visibility."))),t.hasResearchTasks&&(console.log(n.dim(" Research tasks: NEVER generate code \u2014 research only.")),console.log(n.dim(" Attach a .md report before marking Research tasks as review.")),console.log(n.dim(" CLI ENFORCES: cannot mark Research as review without an attached .md report.")),console.log(n.dim(" Use --report-file <path> to upload your .md report when marking as review:")),console.log(n.dim(' vibeflow tasks --edit <id> --set-status review --report-file ./report.md --comment "..."')),console.log(n.dim(" The file is uploaded to the task and deleted from the local filesystem automatically."))),t.hasBugTasks&&(console.log(n.dim(" Bug tasks: Include error logs / stack traces in the commit comment.")),console.log(n.dim(" Describe: the symptom, the console error, what triggered it, and how it was fixed."))),console.log(n.red(" CRITICAL: NEVER edit .vibeflow/ task files directly.")),console.log(n.dim(" All task operations (status, comments, commits) must go through CLI commands.")),console.log(n.red(" CRITICAL: Set in-progress BEFORE reading/planning. Other agents may pick the same task.")),console.log(n.dim(" The in-progress transition signals ownership. Skip it and another agent may duplicate your work.")),console.log(n.dim(" Sequence: discover tasks \u2192 pick one \u2192 set in-progress \u2192 THEN read details and implement.")),console.log(n.red(' CRITICAL: NEVER set a task status to "done".')),console.log(n.dim(' When your implementation is complete, set the status to "review" \u2014 not "done".')),console.log(n.dim(" Only humans can mark tasks as done after reviewing the work.")),console.log(n.dim(" The CLI will warn you and still allow the change \u2014 but agents must not use it.")),console.log()}var re=new vo;re.name("vibeflow").description("Vibeflow \u2014 CLI tool for frontend prototyping with LLM assistance").version("0.4.0");re.addHelpText("after",`
|
|
29416
|
+
`),{uploaded:c,failed:l,failedFiles:P}}async function St(t,e){let r=Kr(t),i=await Q();if(!i&&(console.log(B.yellow(" Not logged in. Starting login flow...")),await Ve(),i=await Q(),!i)){console.error(B.red(" Login failed. Please run `vibeflow login` and try again.")),process.exitCode=1;return}let s=ce(r);if(s.length===0){console.log(B.dim(" No local tasks found. Nothing to push."));return}console.log(B.cyan(` Found ${s.length} local task(s). Pushing to SaaS...`));let o=Xr(),a=e.workspace;if(!a){let f=await J();f&&(a=f.id,console.log(B.dim(` Using board: ${f.icon??""} ${f.name}`)))}let c={tasks:s};a&&(c.workspaceId=a);let l;try{let f=await fetch(`${o}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(c)});if(!f.ok){let _=await f.json().catch(()=>({}));console.error(B.red(` Import failed: ${f.status} ${_.error??f.statusText}`)),process.exitCode=1;return}l=await f.json()}catch(f){let _=f instanceof Error?f.message:String(f);console.error(B.red(` Network error: ${_}`)),process.exitCode=1;return}console.log(B.green(` \u2713 Pushed ${l.imported} task(s) to SaaS`)),l.skipped&&l.skipped>0&&console.log(B.dim(` Skipped ${l.skipped} already-imported task(s).`));let u=(await J())?.name??l.workspaceId;console.log(B.dim(` Board: ${u}`));let C=l.idMap??{},P=s.filter(f=>f.id&&C[f.id]).map(f=>({localId:f.id,remoteId:C[f.id]})),{uploaded:k,failed:w,failedFiles:R}=await Zr(o,i,r,P);if(k>0&&console.log(B.green(` \u2713 Uploaded ${k} file(s) to storage`)),w>0){console.log(B.yellow(` \u26A0 ${w} file(s) failed to upload`));for(let f of R)console.log(B.dim(` - ${f.name}: ${f.reason}`))}if(e.keepLocalFiles){console.log(B.dim(" Local task files kept (--keep-local-files)."));return}let L=0;for(let f of s)try{Vr(f.filePath),L++}catch{}console.log(B.dim(` Deleted ${L} local task file(s).`))}var eo="http://localhost:3000";function qe(){return process.env.SPOTA_API_URL??eo}var no={backlog:"backlog",todo:"todo","in-progress":"in_progress",review:"review",done:"done"},to={backlog:"backlog",todo:"todo",in_progress:"in-progress",review:"review",done:"done",cancelled:"done"};function de(t){return to[t]??"todo"}function ro(t){return no[t]??"todo"}async function Ye(){let t=await Q();return t?{Authorization:`Bearer ${t}`}:null}async function Se(t){let e=await Ye();if(!e)return null;let r=new URL(`${qe()}/api/cli/tasks`);t&&r.searchParams.set("boardId",t);try{let i=await fetch(r.toString(),{headers:e});return i.ok?i.json():null}catch{return null}}async function Et(t){let e=await Se();return e?e.tasks.find(r=>r.id===t)??null:null}async function mn(t,e){let r=await Ye();if(!r)return null;let i={};e.status!==void 0&&(i.status=ro(e.status)),e.title!==void 0&&(i.title=e.title),e.description!==void 0&&(i.description=e.description),e.priority!==void 0&&(i.priority=e.priority);try{let s=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}`,{method:"PATCH",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!s.ok)return null;let o=await s.json();return{task:o.task,warning:o.warning}}catch{return null}}async function Pt(t,e){let r=await Ye();if(!r)return null;try{let i=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}/comments`,{method:"POST",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify({body:e})});return i.ok?(await i.json()).comment:null}catch{return null}}async function It(t){let e=await Ye();if(!e)return null;try{let r=await fetch(`${qe()}/api/cli/tasks`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify(t)});return r.ok?(await r.json()).task:null}catch{return null}}import{readFileSync as hn,existsSync as vn,unlinkSync as yo}from"fs";import{resolve as V,join as At,basename as Ot}from"path";import n from"chalk";import{createHash as oo,randomUUID as ao}from"crypto";import{existsSync as io,readFileSync as so,writeFileSync as lo,mkdirSync as co}from"fs";import{join as Tt}from"path";import _t from"os";import{PostHog as uo}from"posthog-node";var po="phc_C9AUV3rnayLfVvxgHtvj6AXcwsd8FKWUfJ9262zWsCvM",fo="https://eu.i.posthog.com";function Rt(){return Tt(process.env.HOME??_t.homedir(),".vibeflow")}function Nt(){return Tt(Rt(),"config.json")}function Ke(){try{return JSON.parse(so(Nt(),"utf-8"))}catch{return{}}}function Lt(t){let e=Rt();io(e)||co(e,{recursive:!0});let r=Ke();lo(Nt(),JSON.stringify({...r,...t},null,2),"utf-8")}function Ft(){return process.env.VIBEFLOW_TELEMETRY==="0"?!1:Ke().disabled!==!0}function gn(t){Lt({disabled:!t})}function Dt(){let t=Ft(),e=Ke();return{enabled:t,anonymousId:e.anonymousId??null}}function mo(){let t=Ke();if(t.anonymousId)return t.anonymousId;let e=ao();return Lt({anonymousId:e}),e}function go(){let t=_t.userInfo().username;return oo("sha256").update(t).digest("hex").slice(0,16)}var Ne=null;function ho(){return Ft()?(Ne||(Ne=new uo(po,{host:fo,flushAt:1,flushInterval:0})),Ne):null}function ye(t,e){let r=ho();if(!r)return;let i=mo();r.capture({distinctId:i,event:t,properties:{...e,$user_id:go()}})}async function be(){if(Ne)try{await Ne.shutdown()}catch{}}function bo(t,e){let r=u=>u.replace(/[^0-9.]/g,"").split(".").map(Number),[i=0,s=0,o=0]=r(t),[a=0,c=0,l=0]=r(e);return i!==a?i>a:s!==c?s>c:o>l}function ko(){let t="0.4.1";if(!t)return;let e="@vibeflow-tools/cli";import("https").then(({default:r})=>{let i=r.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:5e3},s=>{let o="";s.on("data",a=>{o+=a.toString()}),s.on("end",()=>{try{let{version:a}=JSON.parse(o);a&&bo(a,t)&&(console.log(),console.log(n.bgYellow.black.bold(` \u2191 Update available: ${t} \u2192 ${a} `)),console.log(n.dim(" Run: ")+n.cyan(`npm install -g ${e}@${a}`)+n.dim(" to update")),console.log())}catch{}})});i.on("error",()=>{}),i.on("timeout",()=>{i.destroy()})}).catch(()=>{})}wt();var ke={backlog:n.gray,todo:n.yellow,"in-progress":n.blue,review:n.magenta,done:n.green},wo=new Set(["Task","Bug","Research"]);function xo(t){if(t){for(let e of wo)if(e.toLowerCase()===t.toLowerCase())return e}}function ge(t){let e=(t??"Medium").trim().toLowerCase();return e==="critical"?0:e==="high"?1:e==="low"?3:2}var Mt=["in-progress","review","todo","backlog","done"];function Qe(t){let e=Mt.indexOf(t);return e===-1?Mt.length:e}function Ht(t){try{return Ge("git",["push"],{cwd:t,stdio:"inherit"}),{ok:!0}}catch{try{let e=yn("git rev-parse --abbrev-ref HEAD",{cwd:t}).toString().trim();return Ge("git",["push","--set-upstream","origin",e],{cwd:t,stdio:"inherit"}),{ok:!0}}catch(e){return{ok:!1,error:(e instanceof Error?e.message:String(e)).slice(0,220)}}}}function Ee(t){let{autoCommit:e,autoPush:r,autoComment:i,createBranch:s}=t;if(console.log(n.bold("Agent instructions (concise):")),console.log(n.dim(" Discover: vibeflow tasks --status todo | vibeflow tasks --type Research | vibeflow tasks --user <email> | vibeflow tasks --tag <tag>")),console.log(n.dim(" Details: vibeflow tasks --get <id> (full task info with comments and files)")),console.log(n.dim(' Create: vibeflow tasks --add --title "..." --description "..."')),console.log(),console.log(n.dim(" Workflow:")),console.log(n.yellow(" \u26A0 IMMEDIATELY set in-progress BEFORE any implementation work:")),console.log(n.dim(" 1. vibeflow tasks --edit <id> --set-status in-progress \u2190 DO THIS FIRST")),console.log(n.dim(" 2. <implement the change>")),e){console.log(n.dim(" 3. git add <files> (stage your changes first)"));let o=["--set-status review"];e&&o.push('--commit-message "<one-line summary>"'),i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`)),console.log(n.dim(" CLI will commit staged changes and link the commit SHA automatically."))}else{console.log(n.dim(' 3. git add <files> && vibeflow tasks --commit --task <id> --message "<one-line summary>"'));let o=["--set-status review"];i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`))}i&&(console.log(n.dim("")),console.log(n.dim(" Comment format (--comment):")),console.log(n.dim(" \xB7 Plain text for concise one-liners.")),console.log(n.dim(" \xB7 Markdown for multi-section reports. Use **bold**, bullet lists, code fences.")),console.log(n.dim(" \xB7 Must cover: what changed, why, key decisions, anything future agents should know.")),console.log(n.dim(" \xB7 For long reports, attach a .md file and reference it in the comment."))),console.log(),e&&console.log(n.dim(" [setting] Auto-commit ON: provide --commit-message when setting status to review; CLI commits.")),r&&console.log(n.dim(" [setting] Auto-push ON: CLI pushes after the commit automatically.")),i&&console.log(n.dim(" [setting] Auto-comment ON: --comment is required when setting status to review.")),s&&(console.log(n.dim(" [setting] Create branch ON: after ALL tasks in this session are done, create and push a descriptive branch:")),console.log(n.dim(" git checkout -b <short-name> (e.g. fix/annotation-errors, feat/eye-toggle, chore/cleanup-extension)")),console.log(n.dim(" git push -u origin HEAD")),console.log(n.dim(" Branch name rules: lowercase, kebab-case, 2-5 words, prefix fix/feat/chore/docs.")),console.log(n.dim(" Describe the WORK done (not dates). Bad: agent/2026-04-16. Good: fix/bug-errors-visibility."))),t.hasResearchTasks&&(console.log(n.dim(" Research tasks: NEVER generate code \u2014 research only.")),console.log(n.dim(" Attach a .md report before marking Research tasks as review.")),console.log(n.dim(" CLI ENFORCES: cannot mark Research as review without an attached .md report.")),console.log(n.dim(" Use --report-file <path> to upload your .md report when marking as review:")),console.log(n.dim(' vibeflow tasks --edit <id> --set-status review --report-file ./report.md --comment "..."')),console.log(n.dim(" The file is uploaded to the task and deleted from the local filesystem automatically."))),t.hasBugTasks&&(console.log(n.dim(" Bug tasks: Include error logs / stack traces in the commit comment.")),console.log(n.dim(" Describe: the symptom, the console error, what triggered it, and how it was fixed."))),console.log(n.red(" CRITICAL: NEVER edit .vibeflow/ task files directly.")),console.log(n.dim(" All task operations (status, comments, commits) must go through CLI commands.")),console.log(n.red(" CRITICAL: Set in-progress BEFORE reading/planning. Other agents may pick the same task.")),console.log(n.dim(" The in-progress transition signals ownership. Skip it and another agent may duplicate your work.")),console.log(n.dim(" Sequence: discover tasks \u2192 pick one \u2192 set in-progress \u2192 THEN read details and implement.")),console.log(n.red(' CRITICAL: NEVER set a task status to "done".')),console.log(n.dim(' When your implementation is complete, set the status to "review" \u2014 not "done".')),console.log(n.dim(" Only humans can mark tasks as done after reviewing the work.")),console.log(n.dim(" The CLI will warn you and still allow the change \u2014 but agents must not use it.")),console.log()}var re=new vo;re.name("vibeflow").description("Vibeflow \u2014 CLI tool for frontend prototyping with LLM assistance").version("0.4.1");re.addHelpText("after",`
|
|
29415
29417
|
${"\u2500".repeat(60)}
|
|
29416
29418
|
For coding agents \u2014 quick reference:
|
|
29417
29419
|
|
package/dist/index.js
CHANGED
|
@@ -29334,12 +29334,14 @@ lucide-react/dist/esm/lucide-react.js:
|
|
|
29334
29334
|
*)
|
|
29335
29335
|
*/
|
|
29336
29336
|
`;function en(t){return`
|
|
29337
|
+
var _vfScriptSrc = document.currentScript && document.currentScript.src;
|
|
29338
|
+
var _vfOrigin = _vfScriptSrc ? new URL(_vfScriptSrc).origin : ('http://' + window.location.host);
|
|
29337
29339
|
var PROTO_CONFIG = {
|
|
29338
29340
|
port: ${t},
|
|
29339
|
-
wsUrl: 'ws
|
|
29340
|
-
apiUrl:
|
|
29341
|
-
pagesUrl:
|
|
29342
|
-
screenshotsUrl:
|
|
29341
|
+
wsUrl: _vfOrigin.replace(/^http/, 'ws'),
|
|
29342
|
+
apiUrl: _vfOrigin + '/api/tasks',
|
|
29343
|
+
pagesUrl: _vfOrigin + '/api/pages',
|
|
29344
|
+
screenshotsUrl: _vfOrigin + '/screenshots/'
|
|
29343
29345
|
};
|
|
29344
29346
|
`+Ze}function Tn(t){return`var PROTO_CONFIG = ${JSON.stringify({port:0,wsUrl:"",apiUrl:`${t}/api/overlay/tasks`,pagesUrl:"",screenshotsUrl:""})};
|
|
29345
29347
|
`+Ze}import{existsSync as jt,readFileSync as $t}from"fs";import{dirname as zt,join as tn}from"path";import{fileURLToPath as Bt}from"url";var _n=`*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
|
|
@@ -29411,7 +29413,7 @@ li{margin:8px 0}</style></head>
|
|
|
29411
29413
|
Push them to your board now? [Y/n]: `),async P=>{if(C.close(),P.trim().toLowerCase()==="n"){console.log(D.dim(" Skipped. You can push later with: vibeflow push")),u();return}let k=vt.createInterface({input:process.stdin,output:process.stdout});k.question(D.cyan(" Delete local task files after push? [y/N]: "),async w=>{k.close();let R=w.trim().toLowerCase()!=="y";try{let L=await fetch(`${t}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({boardId:r.id,tasks:c,keepLocalFiles:R})}),f={};try{f=await L.json()}catch{}L.ok?(console.log(D.green(` \u2713 Pushed ${f.imported??0} task${(f.imported??0)!==1?"s":""} to ${r.name}`)),(f.skipped??0)>0&&console.log(D.dim(` (${f.skipped} already existed and were skipped)`))):console.log(D.red(` Push failed: ${f.error??`HTTP ${L.status}`}`))}catch(L){console.log(D.red(` Push failed: ${L instanceof Error?L.message:"Network error"}`))}u()})})})}async function Ve(){let t=bt();console.log(D.cyan(" Initiating device login flow..."));let e=await fetch(`${t}/api/cli/auth/device-init`,{method:"POST",headers:{"Content-Type":"application/json"}});e.ok||(console.error(D.red(` Failed to initiate login: ${e.status} ${e.statusText}`)),process.exit(1));let{deviceCode:r,userCode:i,verificationUrl:s,expiresIn:o}=await e.json();console.log(),console.log(D.bold(" Open this URL in your browser to authorize:")),console.log(D.underline(` ${s}`)),console.log();try{await Dr(s),console.log(D.dim(" (Browser opened automatically)"))}catch{}let a=Date.now()+o*1e3,c=3e3;for(;Date.now()<a;){await Wr(c);let l=await fetch(`${t}/api/cli/auth/device-poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:r})});if(!l.ok){console.error(D.red(" Poll request failed. Retrying..."));continue}let u=await l.json();if("token"in u){await Vn(u.token),console.log(),console.log(D.green(" Logged in successfully. Now operating in SaaS mode.")),await Promise.all([$r(t,u.token),kt(t,u.token)]);let{readWorkspace:C}=await import("./workspace-KGOQ67YV.js"),P=await C();P&&await zr(t,u.token,P);return}"expired"in u&&(console.error(D.red(" Device code expired. Please try again.")),process.exit(1)),process.stdout.write(D.dim("."))}console.error(D.red(`
|
|
29412
29414
|
Login timed out. Please try again.`)),process.exit(1)}import Br from"chalk";async function xt(){await qn(),console.log(Br.green(" Logged out. Now operating in local mode."))}import B from"chalk";import{unlinkSync as Vr,readFileSync as qr,existsSync as Yr}from"fs";import{resolve as Kr,join as Qr}from"path";var Gr="http://localhost:3000";function Xr(){return process.env.SPOTA_API_URL??Gr}function Jr(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function Ct(t,e,r=24){let i=Math.round(t/e*r);return`[${"\u2588".repeat(i)+"\u2591".repeat(r-i)}]`}async function Zr(t,e,r,i){let s=[];for(let{localId:w,remoteId:R}of i){let L=ne(r,w);for(let f of L){let _=f.linkedPath??Qr(xn(r,w),f.name);Yr(_)&&s.push({remoteId:R,name:f.name,filePath:_,size:f.size})}}if(s.length===0)return{uploaded:0,failed:0,failedFiles:[]};let o=s.length,a=s.reduce((w,R)=>w+R.size,0);console.log(B.cyan(`
|
|
29413
29415
|
Uploading ${o} file(s) (${Jr(a)})...`));let c=0,l=0,u=0,C=Date.now(),P=[];for(let w of s){let R=Math.round(c/o*100),L=Ct(c,o),f=(Date.now()-C)/1e3,_=u/Math.max(f,.01),F=a-u,q=_>0?Math.ceil(F/_):0,M=q>60?`${Math.ceil(q/60)}m`:`${q}s`;process.stdout.write(`\r ${L} ${R}% ${w.name.slice(0,28)} ETA: ${M} `);try{let Y=qr(w.filePath),oe=await fetch(`${t}/api/tasks/${encodeURIComponent(w.remoteId)}/files`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/octet-stream","x-filename":encodeURIComponent(w.name)},body:Y});oe.ok?(c++,u+=w.size):(l++,P.push({name:w.name,reason:`HTTP ${oe.status}`}))}catch(Y){l++,P.push({name:w.name,reason:Y instanceof Error?Y.message:String(Y)})}}let k=Ct(o,o);return process.stdout.write(`\r ${k} 100% Done${" ".repeat(40)}
|
|
29414
|
-
`),{uploaded:c,failed:l,failedFiles:P}}async function St(t,e){let r=Kr(t),i=await Q();if(!i&&(console.log(B.yellow(" Not logged in. Starting login flow...")),await Ve(),i=await Q(),!i)){console.error(B.red(" Login failed. Please run `vibeflow login` and try again.")),process.exitCode=1;return}let s=ce(r);if(s.length===0){console.log(B.dim(" No local tasks found. Nothing to push."));return}console.log(B.cyan(` Found ${s.length} local task(s). Pushing to SaaS...`));let o=Xr(),a=e.workspace;if(!a){let f=await J();f&&(a=f.id,console.log(B.dim(` Using board: ${f.icon??""} ${f.name}`)))}let c={tasks:s};a&&(c.workspaceId=a);let l;try{let f=await fetch(`${o}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(c)});if(!f.ok){let _=await f.json().catch(()=>({}));console.error(B.red(` Import failed: ${f.status} ${_.error??f.statusText}`)),process.exitCode=1;return}l=await f.json()}catch(f){let _=f instanceof Error?f.message:String(f);console.error(B.red(` Network error: ${_}`)),process.exitCode=1;return}console.log(B.green(` \u2713 Pushed ${l.imported} task(s) to SaaS`)),l.skipped&&l.skipped>0&&console.log(B.dim(` Skipped ${l.skipped} already-imported task(s).`));let u=(await J())?.name??l.workspaceId;console.log(B.dim(` Board: ${u}`));let C=l.idMap??{},P=s.filter(f=>f.id&&C[f.id]).map(f=>({localId:f.id,remoteId:C[f.id]})),{uploaded:k,failed:w,failedFiles:R}=await Zr(o,i,r,P);if(k>0&&console.log(B.green(` \u2713 Uploaded ${k} file(s) to storage`)),w>0){console.log(B.yellow(` \u26A0 ${w} file(s) failed to upload`));for(let f of R)console.log(B.dim(` - ${f.name}: ${f.reason}`))}if(e.keepLocalFiles){console.log(B.dim(" Local task files kept (--keep-local-files)."));return}let L=0;for(let f of s)try{Vr(f.filePath),L++}catch{}console.log(B.dim(` Deleted ${L} local task file(s).`))}var eo="http://localhost:3000";function qe(){return process.env.SPOTA_API_URL??eo}var no={backlog:"backlog",todo:"todo","in-progress":"in_progress",review:"review",done:"done"},to={backlog:"backlog",todo:"todo",in_progress:"in-progress",review:"review",done:"done",cancelled:"done"};function de(t){return to[t]??"todo"}function ro(t){return no[t]??"todo"}async function Ye(){let t=await Q();return t?{Authorization:`Bearer ${t}`}:null}async function Se(t){let e=await Ye();if(!e)return null;let r=new URL(`${qe()}/api/cli/tasks`);t&&r.searchParams.set("boardId",t);try{let i=await fetch(r.toString(),{headers:e});return i.ok?i.json():null}catch{return null}}async function Et(t){let e=await Se();return e?e.tasks.find(r=>r.id===t)??null:null}async function mn(t,e){let r=await Ye();if(!r)return null;let i={};e.status!==void 0&&(i.status=ro(e.status)),e.title!==void 0&&(i.title=e.title),e.description!==void 0&&(i.description=e.description),e.priority!==void 0&&(i.priority=e.priority);try{let s=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}`,{method:"PATCH",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!s.ok)return null;let o=await s.json();return{task:o.task,warning:o.warning}}catch{return null}}async function Pt(t,e){let r=await Ye();if(!r)return null;try{let i=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}/comments`,{method:"POST",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify({body:e})});return i.ok?(await i.json()).comment:null}catch{return null}}async function It(t){let e=await Ye();if(!e)return null;try{let r=await fetch(`${qe()}/api/cli/tasks`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify(t)});return r.ok?(await r.json()).task:null}catch{return null}}import{readFileSync as hn,existsSync as vn,unlinkSync as yo}from"fs";import{resolve as V,join as At,basename as Ot}from"path";import n from"chalk";import{createHash as oo,randomUUID as ao}from"crypto";import{existsSync as io,readFileSync as so,writeFileSync as lo,mkdirSync as co}from"fs";import{join as Tt}from"path";import _t from"os";import{PostHog as uo}from"posthog-node";var po="phc_C9AUV3rnayLfVvxgHtvj6AXcwsd8FKWUfJ9262zWsCvM",fo="https://eu.i.posthog.com";function Rt(){return Tt(process.env.HOME??_t.homedir(),".vibeflow")}function Nt(){return Tt(Rt(),"config.json")}function Ke(){try{return JSON.parse(so(Nt(),"utf-8"))}catch{return{}}}function Lt(t){let e=Rt();io(e)||co(e,{recursive:!0});let r=Ke();lo(Nt(),JSON.stringify({...r,...t},null,2),"utf-8")}function Ft(){return process.env.VIBEFLOW_TELEMETRY==="0"?!1:Ke().disabled!==!0}function gn(t){Lt({disabled:!t})}function Dt(){let t=Ft(),e=Ke();return{enabled:t,anonymousId:e.anonymousId??null}}function mo(){let t=Ke();if(t.anonymousId)return t.anonymousId;let e=ao();return Lt({anonymousId:e}),e}function go(){let t=_t.userInfo().username;return oo("sha256").update(t).digest("hex").slice(0,16)}var Ne=null;function ho(){return Ft()?(Ne||(Ne=new uo(po,{host:fo,flushAt:1,flushInterval:0})),Ne):null}function ye(t,e){let r=ho();if(!r)return;let i=mo();r.capture({distinctId:i,event:t,properties:{...e,$user_id:go()}})}async function be(){if(Ne)try{await Ne.shutdown()}catch{}}function bo(t,e){let r=u=>u.replace(/[^0-9.]/g,"").split(".").map(Number),[i=0,s=0,o=0]=r(t),[a=0,c=0,l=0]=r(e);return i!==a?i>a:s!==c?s>c:o>l}function ko(){let t="0.4.0";if(!t)return;let e="@vibeflow-tools/cli";import("https").then(({default:r})=>{let i=r.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:5e3},s=>{let o="";s.on("data",a=>{o+=a.toString()}),s.on("end",()=>{try{let{version:a}=JSON.parse(o);a&&bo(a,t)&&(console.log(),console.log(n.bgYellow.black.bold(` \u2191 Update available: ${t} \u2192 ${a} `)),console.log(n.dim(" Run: ")+n.cyan(`npm install -g ${e}@${a}`)+n.dim(" to update")),console.log())}catch{}})});i.on("error",()=>{}),i.on("timeout",()=>{i.destroy()})}).catch(()=>{})}wt();var ke={backlog:n.gray,todo:n.yellow,"in-progress":n.blue,review:n.magenta,done:n.green},wo=new Set(["Task","Bug","Research"]);function xo(t){if(t){for(let e of wo)if(e.toLowerCase()===t.toLowerCase())return e}}function ge(t){let e=(t??"Medium").trim().toLowerCase();return e==="critical"?0:e==="high"?1:e==="low"?3:2}var Mt=["in-progress","review","todo","backlog","done"];function Qe(t){let e=Mt.indexOf(t);return e===-1?Mt.length:e}function Ht(t){try{return Ge("git",["push"],{cwd:t,stdio:"inherit"}),{ok:!0}}catch{try{let e=yn("git rev-parse --abbrev-ref HEAD",{cwd:t}).toString().trim();return Ge("git",["push","--set-upstream","origin",e],{cwd:t,stdio:"inherit"}),{ok:!0}}catch(e){return{ok:!1,error:(e instanceof Error?e.message:String(e)).slice(0,220)}}}}function Ee(t){let{autoCommit:e,autoPush:r,autoComment:i,createBranch:s}=t;if(console.log(n.bold("Agent instructions (concise):")),console.log(n.dim(" Discover: vibeflow tasks --status todo | vibeflow tasks --type Research | vibeflow tasks --user <email> | vibeflow tasks --tag <tag>")),console.log(n.dim(" Details: vibeflow tasks --get <id> (full task info with comments and files)")),console.log(n.dim(' Create: vibeflow tasks --add --title "..." --description "..."')),console.log(),console.log(n.dim(" Workflow:")),console.log(n.yellow(" \u26A0 IMMEDIATELY set in-progress BEFORE any implementation work:")),console.log(n.dim(" 1. vibeflow tasks --edit <id> --set-status in-progress \u2190 DO THIS FIRST")),console.log(n.dim(" 2. <implement the change>")),e){console.log(n.dim(" 3. git add <files> (stage your changes first)"));let o=["--set-status review"];e&&o.push('--commit-message "<one-line summary>"'),i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`)),console.log(n.dim(" CLI will commit staged changes and link the commit SHA automatically."))}else{console.log(n.dim(' 3. git add <files> && vibeflow tasks --commit --task <id> --message "<one-line summary>"'));let o=["--set-status review"];i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`))}i&&(console.log(n.dim("")),console.log(n.dim(" Comment format (--comment):")),console.log(n.dim(" \xB7 Plain text for concise one-liners.")),console.log(n.dim(" \xB7 Markdown for multi-section reports. Use **bold**, bullet lists, code fences.")),console.log(n.dim(" \xB7 Must cover: what changed, why, key decisions, anything future agents should know.")),console.log(n.dim(" \xB7 For long reports, attach a .md file and reference it in the comment."))),console.log(),e&&console.log(n.dim(" [setting] Auto-commit ON: provide --commit-message when setting status to review; CLI commits.")),r&&console.log(n.dim(" [setting] Auto-push ON: CLI pushes after the commit automatically.")),i&&console.log(n.dim(" [setting] Auto-comment ON: --comment is required when setting status to review.")),s&&(console.log(n.dim(" [setting] Create branch ON: after ALL tasks in this session are done, create and push a descriptive branch:")),console.log(n.dim(" git checkout -b <short-name> (e.g. fix/annotation-errors, feat/eye-toggle, chore/cleanup-extension)")),console.log(n.dim(" git push -u origin HEAD")),console.log(n.dim(" Branch name rules: lowercase, kebab-case, 2-5 words, prefix fix/feat/chore/docs.")),console.log(n.dim(" Describe the WORK done (not dates). Bad: agent/2026-04-16. Good: fix/bug-errors-visibility."))),t.hasResearchTasks&&(console.log(n.dim(" Research tasks: NEVER generate code \u2014 research only.")),console.log(n.dim(" Attach a .md report before marking Research tasks as review.")),console.log(n.dim(" CLI ENFORCES: cannot mark Research as review without an attached .md report.")),console.log(n.dim(" Use --report-file <path> to upload your .md report when marking as review:")),console.log(n.dim(' vibeflow tasks --edit <id> --set-status review --report-file ./report.md --comment "..."')),console.log(n.dim(" The file is uploaded to the task and deleted from the local filesystem automatically."))),t.hasBugTasks&&(console.log(n.dim(" Bug tasks: Include error logs / stack traces in the commit comment.")),console.log(n.dim(" Describe: the symptom, the console error, what triggered it, and how it was fixed."))),console.log(n.red(" CRITICAL: NEVER edit .vibeflow/ task files directly.")),console.log(n.dim(" All task operations (status, comments, commits) must go through CLI commands.")),console.log(n.red(" CRITICAL: Set in-progress BEFORE reading/planning. Other agents may pick the same task.")),console.log(n.dim(" The in-progress transition signals ownership. Skip it and another agent may duplicate your work.")),console.log(n.dim(" Sequence: discover tasks \u2192 pick one \u2192 set in-progress \u2192 THEN read details and implement.")),console.log(n.red(' CRITICAL: NEVER set a task status to "done".')),console.log(n.dim(' When your implementation is complete, set the status to "review" \u2014 not "done".')),console.log(n.dim(" Only humans can mark tasks as done after reviewing the work.")),console.log(n.dim(" The CLI will warn you and still allow the change \u2014 but agents must not use it.")),console.log()}var re=new vo;re.name("vibeflow").description("Vibeflow \u2014 CLI tool for frontend prototyping with LLM assistance").version("0.4.0");re.addHelpText("after",`
|
|
29416
|
+
`),{uploaded:c,failed:l,failedFiles:P}}async function St(t,e){let r=Kr(t),i=await Q();if(!i&&(console.log(B.yellow(" Not logged in. Starting login flow...")),await Ve(),i=await Q(),!i)){console.error(B.red(" Login failed. Please run `vibeflow login` and try again.")),process.exitCode=1;return}let s=ce(r);if(s.length===0){console.log(B.dim(" No local tasks found. Nothing to push."));return}console.log(B.cyan(` Found ${s.length} local task(s). Pushing to SaaS...`));let o=Xr(),a=e.workspace;if(!a){let f=await J();f&&(a=f.id,console.log(B.dim(` Using board: ${f.icon??""} ${f.name}`)))}let c={tasks:s};a&&(c.workspaceId=a);let l;try{let f=await fetch(`${o}/api/cli/import`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify(c)});if(!f.ok){let _=await f.json().catch(()=>({}));console.error(B.red(` Import failed: ${f.status} ${_.error??f.statusText}`)),process.exitCode=1;return}l=await f.json()}catch(f){let _=f instanceof Error?f.message:String(f);console.error(B.red(` Network error: ${_}`)),process.exitCode=1;return}console.log(B.green(` \u2713 Pushed ${l.imported} task(s) to SaaS`)),l.skipped&&l.skipped>0&&console.log(B.dim(` Skipped ${l.skipped} already-imported task(s).`));let u=(await J())?.name??l.workspaceId;console.log(B.dim(` Board: ${u}`));let C=l.idMap??{},P=s.filter(f=>f.id&&C[f.id]).map(f=>({localId:f.id,remoteId:C[f.id]})),{uploaded:k,failed:w,failedFiles:R}=await Zr(o,i,r,P);if(k>0&&console.log(B.green(` \u2713 Uploaded ${k} file(s) to storage`)),w>0){console.log(B.yellow(` \u26A0 ${w} file(s) failed to upload`));for(let f of R)console.log(B.dim(` - ${f.name}: ${f.reason}`))}if(e.keepLocalFiles){console.log(B.dim(" Local task files kept (--keep-local-files)."));return}let L=0;for(let f of s)try{Vr(f.filePath),L++}catch{}console.log(B.dim(` Deleted ${L} local task file(s).`))}var eo="http://localhost:3000";function qe(){return process.env.SPOTA_API_URL??eo}var no={backlog:"backlog",todo:"todo","in-progress":"in_progress",review:"review",done:"done"},to={backlog:"backlog",todo:"todo",in_progress:"in-progress",review:"review",done:"done",cancelled:"done"};function de(t){return to[t]??"todo"}function ro(t){return no[t]??"todo"}async function Ye(){let t=await Q();return t?{Authorization:`Bearer ${t}`}:null}async function Se(t){let e=await Ye();if(!e)return null;let r=new URL(`${qe()}/api/cli/tasks`);t&&r.searchParams.set("boardId",t);try{let i=await fetch(r.toString(),{headers:e});return i.ok?i.json():null}catch{return null}}async function Et(t){let e=await Se();return e?e.tasks.find(r=>r.id===t)??null:null}async function mn(t,e){let r=await Ye();if(!r)return null;let i={};e.status!==void 0&&(i.status=ro(e.status)),e.title!==void 0&&(i.title=e.title),e.description!==void 0&&(i.description=e.description),e.priority!==void 0&&(i.priority=e.priority);try{let s=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}`,{method:"PATCH",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!s.ok)return null;let o=await s.json();return{task:o.task,warning:o.warning}}catch{return null}}async function Pt(t,e){let r=await Ye();if(!r)return null;try{let i=await fetch(`${qe()}/api/cli/tasks/${encodeURIComponent(t)}/comments`,{method:"POST",headers:{...r,"Content-Type":"application/json"},body:JSON.stringify({body:e})});return i.ok?(await i.json()).comment:null}catch{return null}}async function It(t){let e=await Ye();if(!e)return null;try{let r=await fetch(`${qe()}/api/cli/tasks`,{method:"POST",headers:{...e,"Content-Type":"application/json"},body:JSON.stringify(t)});return r.ok?(await r.json()).task:null}catch{return null}}import{readFileSync as hn,existsSync as vn,unlinkSync as yo}from"fs";import{resolve as V,join as At,basename as Ot}from"path";import n from"chalk";import{createHash as oo,randomUUID as ao}from"crypto";import{existsSync as io,readFileSync as so,writeFileSync as lo,mkdirSync as co}from"fs";import{join as Tt}from"path";import _t from"os";import{PostHog as uo}from"posthog-node";var po="phc_C9AUV3rnayLfVvxgHtvj6AXcwsd8FKWUfJ9262zWsCvM",fo="https://eu.i.posthog.com";function Rt(){return Tt(process.env.HOME??_t.homedir(),".vibeflow")}function Nt(){return Tt(Rt(),"config.json")}function Ke(){try{return JSON.parse(so(Nt(),"utf-8"))}catch{return{}}}function Lt(t){let e=Rt();io(e)||co(e,{recursive:!0});let r=Ke();lo(Nt(),JSON.stringify({...r,...t},null,2),"utf-8")}function Ft(){return process.env.VIBEFLOW_TELEMETRY==="0"?!1:Ke().disabled!==!0}function gn(t){Lt({disabled:!t})}function Dt(){let t=Ft(),e=Ke();return{enabled:t,anonymousId:e.anonymousId??null}}function mo(){let t=Ke();if(t.anonymousId)return t.anonymousId;let e=ao();return Lt({anonymousId:e}),e}function go(){let t=_t.userInfo().username;return oo("sha256").update(t).digest("hex").slice(0,16)}var Ne=null;function ho(){return Ft()?(Ne||(Ne=new uo(po,{host:fo,flushAt:1,flushInterval:0})),Ne):null}function ye(t,e){let r=ho();if(!r)return;let i=mo();r.capture({distinctId:i,event:t,properties:{...e,$user_id:go()}})}async function be(){if(Ne)try{await Ne.shutdown()}catch{}}function bo(t,e){let r=u=>u.replace(/[^0-9.]/g,"").split(".").map(Number),[i=0,s=0,o=0]=r(t),[a=0,c=0,l=0]=r(e);return i!==a?i>a:s!==c?s>c:o>l}function ko(){let t="0.4.1";if(!t)return;let e="@vibeflow-tools/cli";import("https").then(({default:r})=>{let i=r.get(`https://registry.npmjs.org/${encodeURIComponent(e)}/latest`,{timeout:5e3},s=>{let o="";s.on("data",a=>{o+=a.toString()}),s.on("end",()=>{try{let{version:a}=JSON.parse(o);a&&bo(a,t)&&(console.log(),console.log(n.bgYellow.black.bold(` \u2191 Update available: ${t} \u2192 ${a} `)),console.log(n.dim(" Run: ")+n.cyan(`npm install -g ${e}@${a}`)+n.dim(" to update")),console.log())}catch{}})});i.on("error",()=>{}),i.on("timeout",()=>{i.destroy()})}).catch(()=>{})}wt();var ke={backlog:n.gray,todo:n.yellow,"in-progress":n.blue,review:n.magenta,done:n.green},wo=new Set(["Task","Bug","Research"]);function xo(t){if(t){for(let e of wo)if(e.toLowerCase()===t.toLowerCase())return e}}function ge(t){let e=(t??"Medium").trim().toLowerCase();return e==="critical"?0:e==="high"?1:e==="low"?3:2}var Mt=["in-progress","review","todo","backlog","done"];function Qe(t){let e=Mt.indexOf(t);return e===-1?Mt.length:e}function Ht(t){try{return Ge("git",["push"],{cwd:t,stdio:"inherit"}),{ok:!0}}catch{try{let e=yn("git rev-parse --abbrev-ref HEAD",{cwd:t}).toString().trim();return Ge("git",["push","--set-upstream","origin",e],{cwd:t,stdio:"inherit"}),{ok:!0}}catch(e){return{ok:!1,error:(e instanceof Error?e.message:String(e)).slice(0,220)}}}}function Ee(t){let{autoCommit:e,autoPush:r,autoComment:i,createBranch:s}=t;if(console.log(n.bold("Agent instructions (concise):")),console.log(n.dim(" Discover: vibeflow tasks --status todo | vibeflow tasks --type Research | vibeflow tasks --user <email> | vibeflow tasks --tag <tag>")),console.log(n.dim(" Details: vibeflow tasks --get <id> (full task info with comments and files)")),console.log(n.dim(' Create: vibeflow tasks --add --title "..." --description "..."')),console.log(),console.log(n.dim(" Workflow:")),console.log(n.yellow(" \u26A0 IMMEDIATELY set in-progress BEFORE any implementation work:")),console.log(n.dim(" 1. vibeflow tasks --edit <id> --set-status in-progress \u2190 DO THIS FIRST")),console.log(n.dim(" 2. <implement the change>")),e){console.log(n.dim(" 3. git add <files> (stage your changes first)"));let o=["--set-status review"];e&&o.push('--commit-message "<one-line summary>"'),i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`)),console.log(n.dim(" CLI will commit staged changes and link the commit SHA automatically."))}else{console.log(n.dim(' 3. git add <files> && vibeflow tasks --commit --task <id> --message "<one-line summary>"'));let o=["--set-status review"];i&&o.push('--comment "<report>"'),console.log(n.dim(` 4. vibeflow tasks --edit <id> ${o.join(" ")}`))}i&&(console.log(n.dim("")),console.log(n.dim(" Comment format (--comment):")),console.log(n.dim(" \xB7 Plain text for concise one-liners.")),console.log(n.dim(" \xB7 Markdown for multi-section reports. Use **bold**, bullet lists, code fences.")),console.log(n.dim(" \xB7 Must cover: what changed, why, key decisions, anything future agents should know.")),console.log(n.dim(" \xB7 For long reports, attach a .md file and reference it in the comment."))),console.log(),e&&console.log(n.dim(" [setting] Auto-commit ON: provide --commit-message when setting status to review; CLI commits.")),r&&console.log(n.dim(" [setting] Auto-push ON: CLI pushes after the commit automatically.")),i&&console.log(n.dim(" [setting] Auto-comment ON: --comment is required when setting status to review.")),s&&(console.log(n.dim(" [setting] Create branch ON: after ALL tasks in this session are done, create and push a descriptive branch:")),console.log(n.dim(" git checkout -b <short-name> (e.g. fix/annotation-errors, feat/eye-toggle, chore/cleanup-extension)")),console.log(n.dim(" git push -u origin HEAD")),console.log(n.dim(" Branch name rules: lowercase, kebab-case, 2-5 words, prefix fix/feat/chore/docs.")),console.log(n.dim(" Describe the WORK done (not dates). Bad: agent/2026-04-16. Good: fix/bug-errors-visibility."))),t.hasResearchTasks&&(console.log(n.dim(" Research tasks: NEVER generate code \u2014 research only.")),console.log(n.dim(" Attach a .md report before marking Research tasks as review.")),console.log(n.dim(" CLI ENFORCES: cannot mark Research as review without an attached .md report.")),console.log(n.dim(" Use --report-file <path> to upload your .md report when marking as review:")),console.log(n.dim(' vibeflow tasks --edit <id> --set-status review --report-file ./report.md --comment "..."')),console.log(n.dim(" The file is uploaded to the task and deleted from the local filesystem automatically."))),t.hasBugTasks&&(console.log(n.dim(" Bug tasks: Include error logs / stack traces in the commit comment.")),console.log(n.dim(" Describe: the symptom, the console error, what triggered it, and how it was fixed."))),console.log(n.red(" CRITICAL: NEVER edit .vibeflow/ task files directly.")),console.log(n.dim(" All task operations (status, comments, commits) must go through CLI commands.")),console.log(n.red(" CRITICAL: Set in-progress BEFORE reading/planning. Other agents may pick the same task.")),console.log(n.dim(" The in-progress transition signals ownership. Skip it and another agent may duplicate your work.")),console.log(n.dim(" Sequence: discover tasks \u2192 pick one \u2192 set in-progress \u2192 THEN read details and implement.")),console.log(n.red(' CRITICAL: NEVER set a task status to "done".')),console.log(n.dim(' When your implementation is complete, set the status to "review" \u2014 not "done".')),console.log(n.dim(" Only humans can mark tasks as done after reviewing the work.")),console.log(n.dim(" The CLI will warn you and still allow the change \u2014 but agents must not use it.")),console.log()}var re=new vo;re.name("vibeflow").description("Vibeflow \u2014 CLI tool for frontend prototyping with LLM assistance").version("0.4.1");re.addHelpText("after",`
|
|
29415
29417
|
${"\u2500".repeat(60)}
|
|
29416
29418
|
For coding agents \u2014 quick reference:
|
|
29417
29419
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeflow-tools/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Vibeflow CLI for frontend prototyping with LLM assistance — review, annotate, and iterate on HTML prototypes",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Tomislav Zorcec <zorcec@gmail.com>",
|