@mevdragon/vidfarm-devcli 0.18.0 → 0.19.0

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.
Files changed (68) hide show
  1. package/.agents/skills/editor-capabilities/SKILL.md +166 -0
  2. package/.agents/skills/editor-capabilities/references/re-theme-walkthrough.md +58 -0
  3. package/.agents/skills/vidfarm-media/SKILL.md +43 -4
  4. package/SKILL.director.md +190 -18
  5. package/SKILL.platform.md +8 -4
  6. package/demo/dist/app.css +1 -1
  7. package/demo/dist/app.js +77 -75
  8. package/demo/dist/favicon.ico +0 -0
  9. package/dist/src/app.js +3031 -300
  10. package/dist/src/cli.js +1549 -69
  11. package/dist/src/config.js +7 -0
  12. package/dist/src/devcli/clip-store.js +29 -2
  13. package/dist/src/devcli/clips.js +55 -9
  14. package/dist/src/devcli/composition-edit.js +658 -8
  15. package/dist/src/devcli/local-backend.js +123 -0
  16. package/dist/src/devcli/migrate-local.js +140 -0
  17. package/dist/src/devcli/sync.js +311 -0
  18. package/dist/src/devcli/timeline-edit.js +490 -0
  19. package/dist/src/editor-chat.js +56 -17
  20. package/dist/src/frontend/discover-client.js +130 -0
  21. package/dist/src/frontend/discover-store.js +23 -0
  22. package/dist/src/frontend/file-directory.js +995 -0
  23. package/dist/src/frontend/homepage-view.js +3 -3
  24. package/dist/src/frontend/template-editor-chat.js +28 -22
  25. package/dist/src/landing-page.js +24 -7
  26. package/dist/src/page-shell.js +26 -2
  27. package/dist/src/primitive-registry.js +409 -4
  28. package/dist/src/reskin/agency-page.js +1 -1
  29. package/dist/src/reskin/calendar-page.js +2 -1
  30. package/dist/src/reskin/chat-page.js +420 -85
  31. package/dist/src/reskin/discover-page.js +731 -39
  32. package/dist/src/reskin/document.js +1311 -387
  33. package/dist/src/reskin/help-page.js +1 -0
  34. package/dist/src/reskin/inpaint-clipper-page.js +649 -0
  35. package/dist/src/reskin/inpaint-page.js +2459 -446
  36. package/dist/src/reskin/inpaint-video-page.js +1339 -0
  37. package/dist/src/reskin/library-page.js +1168 -228
  38. package/dist/src/reskin/login-page.js +6 -6
  39. package/dist/src/reskin/pricing-page.js +2 -0
  40. package/dist/src/reskin/settings-page.js +55 -10
  41. package/dist/src/reskin/theme.js +365 -20
  42. package/dist/src/services/billing.js +4 -0
  43. package/dist/src/services/clip-curation/gemini.js +5 -0
  44. package/dist/src/services/clip-curation/hunt.js +81 -1
  45. package/dist/src/services/clip-curation/index.js +2 -1
  46. package/dist/src/services/clip-curation/local-agent.js +4 -3
  47. package/dist/src/services/clip-curation/media-select.js +85 -0
  48. package/dist/src/services/clip-curation/query.js +5 -1
  49. package/dist/src/services/clip-curation/refine.js +50 -20
  50. package/dist/src/services/clip-curation/scan.js +10 -3
  51. package/dist/src/services/clip-curation/taxonomy.js +3 -1
  52. package/dist/src/services/clip-curation/taxonomy.v1.json +13 -1
  53. package/dist/src/services/clip-records.js +42 -1
  54. package/dist/src/services/clip-search.js +43 -13
  55. package/dist/src/services/file-directory.js +117 -0
  56. package/dist/src/services/hyperframes.js +283 -3
  57. package/dist/src/services/serverless-records.js +43 -0
  58. package/dist/src/services/storage.js +47 -2
  59. package/dist/src/services/upstream.js +5 -5
  60. package/dist/src/template-editor-shell.js +16 -2
  61. package/package.json +1 -1
  62. package/public/assets/discover-client-app.js +1 -0
  63. package/public/assets/file-directory-app.js +2 -0
  64. package/public/assets/homepage-client-app.js +12 -12
  65. package/public/assets/page-runtime-client-app.js +24 -24
  66. package/public/assets/placeholders/scene-placeholder.png +0 -0
  67. package/src/assets/favicon.ico +0 -0
  68. package/src/assets/logo-vidfarm.png +0 -0
@@ -118,7 +118,7 @@ export function renderReskinLogin(input = {}) {
118
118
  <span class="rk-login-blob rk-login-blob-b"></span>
119
119
  <div class="rk-login-art-inner">
120
120
  <a class="rk-brand rk-login-brand" href="/">
121
- <span class="rk-brand-mark">V</span>vidfarm
121
+ <span class="rk-brand-mark">V</span>VidFarm
122
122
  </a>
123
123
  <div class="rk-login-art-copy">
124
124
  <h1 class="rk-login-hed">A week of content, made in an afternoon.</h1>
@@ -142,7 +142,7 @@ export function renderReskinLogin(input = {}) {
142
142
  <div class="rk-login-pane">
143
143
  <div class="rk-login-card">
144
144
  <a class="rk-brand rk-login-card-brand" href="/">
145
- <span class="rk-brand-mark">V</span>vidfarm
145
+ <span class="rk-brand-mark">V</span>VidFarm
146
146
  </a>
147
147
 
148
148
  <div class="rk-login-head">
@@ -159,13 +159,13 @@ export function renderReskinLogin(input = {}) {
159
159
  </div>
160
160
  </main>`;
161
161
  const pageCss = `
162
- .rk-login{min-height:100vh;display:grid;grid-template-columns:1.05fr .95fr;
162
+ .rk-login{min-height:100svh;display:grid;grid-template-columns:1.05fr .95fr;
163
163
  background:radial-gradient(120% 90% at 100% 0%,var(--rk-gold-tint) 0%,transparent 55%),var(--rk-bg)}
164
- @media(max-width:920px){.rk-login{grid-template-columns:1fr}}
164
+ @media(max-width:920px),(max-height:600px){.rk-login{grid-template-columns:1fr}}
165
165
 
166
166
  /* ── left: sunlit brand / marketing panel ── */
167
167
  .rk-login-art{position:relative;overflow:hidden;display:flex;padding:56px clamp(2rem,4vw,4rem)}
168
- @media(max-width:920px){.rk-login-art{display:none}}
168
+ @media(max-width:920px),(max-height:600px){.rk-login-art{display:none}}
169
169
  .rk-login-art-sky{position:absolute;inset:0;z-index:0;background:
170
170
  radial-gradient(72% 55% at 22% 12%,rgba(255,244,214,.96),transparent 62%),
171
171
  radial-gradient(60% 55% at 92% 96%,rgba(255,199,56,.42),transparent 60%),
@@ -203,7 +203,7 @@ export function renderReskinLogin(input = {}) {
203
203
  .rk-login-card{width:100%;max-width:412px;background:var(--rk-surface);border:1px solid var(--rk-border);
204
204
  border-radius:var(--rk-r-3xl);padding:clamp(28px,3vw,40px);box-shadow:var(--rk-shadow-xl);display:grid;gap:22px}
205
205
  .rk-login-card-brand{display:none;font-size:20px}
206
- @media(max-width:920px){.rk-login-card-brand{display:inline-flex;justify-self:center}}
206
+ @media(max-width:920px),(max-height:600px){.rk-login-card-brand{display:inline-flex;justify-self:center}}
207
207
  .rk-login-head{display:grid;gap:6px;text-align:center}
208
208
  .rk-login-title{font-size:var(--rk-text-3xl);letter-spacing:-.03em}
209
209
  .rk-login-flash{font-size:13px;padding:11px 14px}
@@ -329,6 +329,7 @@ export function renderReskinPricing(input) {
329
329
 
330
330
  /* credit strip */
331
331
  .rk-pricing-credits{padding:34px;background:linear-gradient(180deg,#fff 0%,var(--rk-n-50) 100%)}
332
+ @media(max-width:560px){.rk-pricing-credits{padding:22px 16px}}
332
333
  .rk-pricing-credits-head{max-width:680px;margin-bottom:26px;display:grid;gap:8px}
333
334
  .rk-pricing-credits-head h2{font-size:var(--rk-text-3xl);letter-spacing:-.02em}
334
335
  .rk-pricing-credits-head p{font-size:15px;line-height:1.55}
@@ -381,6 +382,7 @@ export function renderReskinPricing(input) {
381
382
  title: "vidfarm reskin — Pricing",
382
383
  description: "Reskinned vidfarm pricing — the $99/mo Pro plan, the $0.03/credit wallet, and real Stripe checkout.",
383
384
  activeSlug: "pricing",
385
+ account: { email: input.email },
384
386
  pageCss,
385
387
  body
386
388
  });
@@ -448,20 +448,55 @@ export function renderReskinSettings(input) {
448
448
  .rk-set-explorer{border:1px solid var(--rk-border);border-radius:var(--rk-r-2xl);background:var(--rk-n-50);overflow:hidden}
449
449
  .rk-set-fx-crumbs{padding:12px 14px 8px}
450
450
  .rk-set-fx-body{max-height:360px;min-height:120px;overflow-y:auto;padding:2px 10px 12px;display:grid;gap:2px;align-content:start}
451
+ /* a revealed API key lives in .rk-item-sub (nowrap+ellipsis), so it truncates to
452
+ a few chars + "…". When shown (data-rk-shown=1), let that row wrap in full. */
453
+ .rk-set-panel .rk-item-sub:has([data-rk-shown="1"]){white-space:normal;overflow:visible;overflow-wrap:anywhere}
454
+ /* phone portrait: the channel / key rows pack tile + status pill + Resend +
455
+ Remove into one non-wrapping flex row that overflows the padded card and
456
+ forces horizontal page scroll. Let the actions wrap under the title. */
457
+ @media(max-width:620px){
458
+ .rk-set-panel .rk-item{flex-wrap:wrap}
459
+ .rk-set-panel .rk-item .rk-item-main{flex:1 1 100%;order:-1}
460
+ }
461
+ /* very narrow: let the dialog footer buttons wrap instead of cramping */
462
+ @media(max-width:420px){
463
+ .rk-set-dialog-actions{flex-wrap:wrap;gap:8px}
464
+ .rk-set-dialog-actions .rk-btn:first-child{margin-right:0}
465
+ }
451
466
  `;
452
467
  const script = `
453
468
  (function(){
454
469
  var root=document;
455
- function show(tab){
470
+ // Each panel that has its own canonical URL (/settings/<tab>). "logout" is a
471
+ // client-only confirm panel, so it never rewrites the address bar.
472
+ var URL_TABS={profile:1,wallet:1,channels:1,developer:1};
473
+ function setUrl(tab){
474
+ if(!URL_TABS[tab]||!history.pushState)return;
475
+ try{
476
+ var u=new URL(window.location.href);
477
+ var m=u.pathname.match(/^(\\/u\\/[^/]+)\\/settings/); // preserve account scope
478
+ u.pathname=(m?m[1]:'')+'/settings/'+tab; u.hash='';
479
+ history.pushState(null,'',u.pathname+u.search);
480
+ }catch(e){ history.pushState(null,'','/settings/'+tab); }
481
+ }
482
+ function show(tab,opts){
456
483
  root.querySelectorAll('[data-rk-tab]').forEach(function(b){b.classList.toggle('is-active',b.getAttribute('data-rk-tab')===tab)});
457
484
  root.querySelectorAll('[data-rk-panel]').forEach(function(p){p.hidden=p.getAttribute('data-rk-panel')!==tab});
458
- if(history.replaceState)history.replaceState(null,'','#'+tab);
485
+ if(!opts||!opts.skipUrl)setUrl(tab);
459
486
  }
460
487
  root.querySelectorAll('[data-rk-tab]').forEach(function(btn){
461
488
  btn.addEventListener('click',function(){show(btn.getAttribute('data-rk-tab'));});
462
489
  });
463
- var hash=(location.hash||'').replace('#','');
464
- if(hash&&root.querySelector('[data-rk-tab="'+hash+'"]'))show(hash);
490
+ function tabFromLocation(){
491
+ var m=(location.pathname||'').match(/\\/settings\\/([a-z]+)/);
492
+ if(m&&URL_TABS[m[1]])return m[1];
493
+ var hash=(location.hash||'').replace('#','');
494
+ return (hash&&URL_TABS[hash])?hash:null;
495
+ }
496
+ var initial=tabFromLocation();
497
+ if(initial&&root.querySelector('[data-rk-tab="'+initial+'"]'))show(initial,{skipUrl:true});
498
+ // Back/forward between settings tabs — reflect the path without pushing again.
499
+ window.addEventListener('popstate',function(){ show(tabFromLocation()||'profile',{skipUrl:true}); });
465
500
  // reveal password inputs
466
501
  root.querySelectorAll('[data-rk-reveal]').forEach(function(btn){
467
502
  btn.addEventListener('click',function(){var el=root.getElementById(btn.getAttribute('data-rk-reveal'));if(el)el.type=el.type==='password'?'text':'password';});
@@ -501,16 +536,25 @@ export function renderReskinSettings(input) {
501
536
  var bodyEl=fx.querySelector('[data-rk-fx-body]');
502
537
  var ROOTS={
503
538
  my_files:{url:'/api/v1/user/me/attachments',key:'attachments',label:'My Files'},
504
- temp:{url:'/api/v1/user/me/temporary-files',key:'files',label:'Temp'}
539
+ temp:{url:'/api/v1/user/me/temporary-files',key:'files',label:'Temp'},
540
+ raws:{url:'/raws/feed',key:'clips',label:'Raws'}
505
541
  };
506
- var VROOTS=[{key:'my_files',label:'My Files'},{key:'temp',label:'Temp'}];
507
- var st={root:'',path:{my_files:'',temp:''},data:{my_files:null,temp:null},status:{my_files:'idle',temp:'idle'}};
542
+ var VROOTS=[{key:'my_files',label:'My Files'},{key:'temp',label:'Temp'},{key:'raws',label:'Raws'}];
543
+ var st={root:'',path:{},data:{},status:{}};
544
+ VROOTS.forEach(function(v){ st.path[v.key]=''; st.data[v.key]=null; st.status[v.key]='idle'; });
508
545
 
509
546
  function normFolder(v){ return String(v||'').split('/').map(function(s){return s.trim();}).filter(Boolean).join('/'); }
510
547
  function normItem(raw){
511
- var id=raw.id||raw.attachment_id||raw.file_id||''; var name=raw.fileName||raw.file_name||'';
512
- if(!id||!name) return null;
513
- return {id:id,name:name,contentType:raw.contentType||raw.content_type||'',viewUrl:raw.viewUrl||raw.view_url||'',
548
+ // Handles attachments, temp files, AND raws/clips (which use clip_id +
549
+ // source_filename/description and carry no content_type/folder).
550
+ var id=raw.id||raw.attachment_id||raw.file_id||raw.clip_id||'';
551
+ var name=raw.fileName||raw.file_name||raw.source_filename||raw.title||raw.description||'';
552
+ var viewUrl=raw.viewUrl||raw.view_url||'';
553
+ if(!id||(!name&&!viewUrl)) return null;
554
+ if(!name) name=id;
555
+ var ct=raw.contentType||raw.content_type||'';
556
+ if(!ct&&(raw.clip_id||raw.file_path)) ct='video/mp4';
557
+ return {id:id,name:name,contentType:ct,viewUrl:viewUrl,
514
558
  sizeBytes:typeof raw.sizeBytes==='number'?raw.sizeBytes:raw.size_bytes,folderPath:normFolder(raw.folderPath||raw.folder_path||'')};
515
559
  }
516
560
  function fmtBytes(b){ if(!b||b<=0) return ''; var u=['B','KB','MB','GB'],v=b,i=0; while(v>=1024&&i<u.length-1){v/=1024;i++;} return (v>=10||i===0?Math.round(v):v.toFixed(1))+' '+u[i]; }
@@ -679,6 +723,7 @@ export function renderReskinSettings(input) {
679
723
  title: "vidfarm reskin — Settings",
680
724
  description: "Vidfarm settings — profile, wallet, channels, developer.",
681
725
  activeSlug: "settings",
726
+ account: { name: input.name, email: input.email },
682
727
  pageCss,
683
728
  body,
684
729
  script