@officexapp/vidfarm-devcli 0.21.55 → 0.21.57

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@officexapp/vidfarm-devcli",
3
- "version": "0.21.55",
3
+ "version": "0.21.57",
4
4
  "description": "Local bridge for the Vidfarm Trackpad Editor. `vidfarm serve <template_id>` boots the FULL editor on localhost (disk-backed records/storage, free in-process render); edit composition.html on disk (Claude Code, Codex, etc.) and the browser live-morphs it.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "dist/src/devcli/captions.js",
17
17
  "dist/src/devcli/clip-store.js",
18
18
  "dist/src/devcli/clips.js",
19
+ "dist/src/devcli/clipper-run.js",
19
20
  "dist/src/devcli/composition-edit.js",
20
21
  "dist/src/devcli/consult.js",
21
22
  "dist/src/devcli/cost-mode.js",
@@ -45,6 +46,7 @@
45
46
  "dist/src/devcli/stills.js",
46
47
  "dist/src/devcli/storyboard.js",
47
48
  "dist/src/devcli/telemetry.js",
49
+ "dist/src/devcli/update-check.js",
48
50
  "dist/src/devcli/timeline-edit.js",
49
51
  "dist/src/devcli/transitions.js",
50
52
  "dist/src/hyperframes/composition.js",
@@ -111,6 +113,9 @@
111
113
  "test:clips": "node --import tsx --test test/clip-curation.test.ts",
112
114
  "test:social-download": "node --import tsx --test test/video-download-media.test.ts test/social-download-lookup.test.ts",
113
115
  "test:qa": "node --import tsx --test test/qa-check.test.ts",
116
+ "test:engine-globals": "node --import tsx --test test/engine-globals.test.ts",
117
+ "test:clipper-run": "node --import tsx --test test/clipper-run.test.ts",
118
+ "test:update-check": "node --import tsx --test test/update-check.test.ts",
114
119
  "test:studio-brand": "node --import tsx --test test/studio-brand.test.ts",
115
120
  "test:stickers": "node --import tsx --test test/sticker-pack.test.ts test/plate-key.test.ts",
116
121
  "test:social-recycle": "node --import tsx --test test/social-recycle.test.ts",
@@ -122,7 +127,7 @@
122
127
  "test:consult": "node --import tsx --test test/consult.test.ts",
123
128
  "test:agent-imagegen": "node --import tsx --test test/agent-imagegen.test.ts",
124
129
  "test:social-meta": "node --import tsx --test test/social-meta.test.ts",
125
- "check:skills": "node scripts/build-director-skill-rollup.mjs --check && node scripts/check-skill-routes.mjs && node scripts/check-skill-nav.mjs",
130
+ "check:skills": "node scripts/sync-skill-version.mjs --check && node scripts/build-director-skill-rollup.mjs --check && node scripts/check-skill-routes.mjs && node scripts/check-skill-nav.mjs",
126
131
  "benchmark:editor-chat": "node --import tsx scripts/benchmark-editor-chat-harness.mjs",
127
132
  "cdk:deploy:prod-serverless": "npm run build && dotenv -e .env.production -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-prod.js'",
128
133
  "cdk:synth:staging-serverless": "npm run build && dotenv -e .env.staging -- npx aws-cdk synth --app 'node dist/infra/cdk/bin/vidfarm-serverless-staging.js'",
@@ -348,6 +348,33 @@
348
348
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
349
349
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
350
350
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
351
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
352
+ visible (a missing note must read as a gap, not as nothing). */
353
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
354
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
355
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
356
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
357
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
358
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
359
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
360
+ /* the note popover (body-appended, plain colors for portability) */
361
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
362
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
363
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
364
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
365
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
366
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
367
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
368
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
369
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
370
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
371
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
372
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
373
+ .rk-dir-notestatus.is-err{color:#b4341f}
374
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
375
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
376
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
377
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
351
378
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
352
379
  portability onto any host page) */
353
380
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
@@ -363,6 +363,33 @@
363
363
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
364
364
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
365
365
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
366
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
367
+ visible (a missing note must read as a gap, not as nothing). */
368
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
369
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
370
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
371
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
372
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
373
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
374
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
375
+ /* the note popover (body-appended, plain colors for portability) */
376
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
377
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
378
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
379
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
380
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
381
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
382
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
383
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
384
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
385
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
386
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
387
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
388
+ .rk-dir-notestatus.is-err{color:#b4341f}
389
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
390
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
391
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
392
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
366
393
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
367
394
  portability onto any host page) */
368
395
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
@@ -1523,7 +1550,7 @@ button.rk-clips-thumb{appearance:none;-webkit-appearance:none;border:0;margin:0;
1523
1550
  </div>
1524
1551
 
1525
1552
  <div class="rk-files-explorer">
1526
- <div data-rk-directory data-mode="standalone" data-show-upload="true" data-upload-placement="toolbar" data-show-multiselect="true" data-primary-click="preview" data-enable-shares="true"></div>
1553
+ <div data-rk-directory data-mode="standalone" data-show-upload="true" data-upload-placement="toolbar" data-show-multiselect="true" data-primary-click="preview" data-enable-shares="true" data-url-base="/library" data-url-root="/library/files"></div>
1527
1554
  </div>
1528
1555
  </main>
1529
1556
 
@@ -363,6 +363,33 @@
363
363
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
364
364
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
365
365
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
366
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
367
+ visible (a missing note must read as a gap, not as nothing). */
368
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
369
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
370
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
371
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
372
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
373
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
374
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
375
+ /* the note popover (body-appended, plain colors for portability) */
376
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
377
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
378
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
379
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
380
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
381
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
382
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
383
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
384
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
385
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
386
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
387
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
388
+ .rk-dir-notestatus.is-err{color:#b4341f}
389
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
390
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
391
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
392
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
366
393
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
367
394
  portability onto any host page) */
368
395
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
@@ -363,6 +363,33 @@
363
363
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
364
364
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
365
365
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
366
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
367
+ visible (a missing note must read as a gap, not as nothing). */
368
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
369
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
370
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
371
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
372
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
373
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
374
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
375
+ /* the note popover (body-appended, plain colors for portability) */
376
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
377
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
378
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
379
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
380
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
381
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
382
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
383
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
384
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
385
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
386
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
387
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
388
+ .rk-dir-notestatus.is-err{color:#b4341f}
389
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
390
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
391
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
392
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
366
393
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
367
394
  portability onto any host page) */
368
395
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
@@ -363,6 +363,33 @@
363
363
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
364
364
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
365
365
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
366
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
367
+ visible (a missing note must read as a gap, not as nothing). */
368
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
369
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
370
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
371
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
372
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
373
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
374
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
375
+ /* the note popover (body-appended, plain colors for portability) */
376
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
377
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
378
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
379
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
380
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
381
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
382
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
383
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
384
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
385
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
386
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
387
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
388
+ .rk-dir-notestatus.is-err{color:#b4341f}
389
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
390
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
391
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
392
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
366
393
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
367
394
  portability onto any host page) */
368
395
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
@@ -363,6 +363,33 @@
363
363
  transition:opacity var(--rk-dur) var(--rk-ease),background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease)}
364
364
  .rk-aichat-frow:hover .rk-dir-kebab,.rk-dir-kebab:focus-visible{opacity:1}
365
365
  .rk-dir-kebab:hover{background:var(--rk-n-100);color:var(--rk-ink);border-color:var(--rk-border)}
366
+ /* vector-note badge — the "does this thing say what it is?" signal. Always
367
+ visible (a missing note must read as a gap, not as nothing). */
368
+ .rk-dir-note{flex:none;font-family:inherit;font-size:11px;font-weight:800;line-height:1;cursor:pointer;
369
+ padding:5px 8px;border-radius:999px;white-space:nowrap;max-width:120px;overflow:hidden;text-overflow:ellipsis;
370
+ transition:background var(--rk-dur) var(--rk-ease),border-color var(--rk-dur) var(--rk-ease),color var(--rk-dur) var(--rk-ease)}
371
+ .rk-dir-note.is-empty{border:1px dashed var(--rk-border-strong,#d9d2c6);background:transparent;color:var(--rk-n-500,#8b8377)}
372
+ .rk-dir-note.is-empty:hover{border-color:var(--rk-gold-600,#d99e00);color:var(--rk-gold-700,#a16207);background:var(--rk-gold-tint,#fff7e0)}
373
+ .rk-dir-note.is-set{border:1px solid transparent;background:var(--rk-gold-tint,#fff7e0);color:var(--rk-gold-700,#a16207)}
374
+ .rk-dir-note.is-set:hover{border-color:var(--rk-gold-600,#d99e00)}
375
+ /* the note popover (body-appended, plain colors for portability) */
376
+ .rk-dir-notepanel{position:fixed;z-index:2147483000;width:min(360px,calc(100vw - 24px));background:#fff;
377
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-lg,12px);
378
+ box-shadow:var(--rk-shadow-md,0 10px 30px rgba(40,30,10,.16));padding:12px;display:grid;gap:8px}
379
+ .rk-dir-notehead{font-size:12.5px;font-weight:800;color:var(--rk-ink,#2b2620);overflow-wrap:anywhere}
380
+ .rk-dir-notehint{font-size:11.5px;line-height:1.45;color:var(--rk-text-muted,#78716c)}
381
+ .rk-dir-notearea{font-family:inherit;font-size:12.5px;line-height:1.5;color:var(--rk-ink,#2b2620);width:100%;
382
+ border:1px solid var(--rk-border,#e6e1d8);border-radius:var(--rk-r-md,8px);padding:8px 9px;resize:vertical;background:#fff}
383
+ .rk-dir-notearea:focus{outline:none;border-color:var(--rk-gold-600,#d99e00)}
384
+ .rk-dir-notearea[readonly]{background:var(--rk-n-100,#f2efe9);color:var(--rk-text-muted,#78716c)}
385
+ .rk-dir-notefoot{display:flex;align-items:center;gap:8px}
386
+ .rk-dir-notestatus{flex:1;font-size:11px;font-weight:700;color:var(--rk-text-muted,#78716c);overflow-wrap:anywhere}
387
+ .rk-dir-notestatus.is-ok{color:#2f7d32}
388
+ .rk-dir-notestatus.is-err{color:#b4341f}
389
+ .rk-dir-notebtn{font-family:inherit;font-size:12px;font-weight:800;cursor:pointer;border-radius:999px;padding:7px 13px;
390
+ border:1px solid transparent;background:var(--rk-gold-500,#fcb900);color:var(--rk-ink,#2b2620)}
391
+ .rk-dir-notebtn:disabled{opacity:.6;cursor:default}
392
+ .rk-dir-notebtn.is-ghost{background:transparent;border-color:var(--rk-border,#e6e1d8);color:var(--rk-text-muted,#78716c)}
366
393
  /* kebab popup + copy toast (appended to <body>, so plain colors not tokens for
367
394
  portability onto any host page) */
368
395
  .rk-dir-menu{position:fixed;z-index:2147483000;min-width:150px;background:#fff;border:1px solid var(--rk-border,#e6e1d8);
package/update.md CHANGED
@@ -28,11 +28,21 @@ have yet. **Always update both together.**
28
28
  Worth ten seconds, because it tells you which breaking-change notes below actually apply:
29
29
 
30
30
  ```bash
31
- vidfarm --version # devcli version
32
- npm view @officexapp/vidfarm-devcli version # latest published
31
+ vidfarm update-check # BOTH halves, installed vs published, with a verdict
32
+ vidfarm --version # devcli version + the installed skill version
33
33
  cat skills-lock.json # which skill packs are installed, and from where
34
34
  ```
35
35
 
36
+ `vidfarm update-check` is the one to reach for — it reads the installed devcli, the installed
37
+ skill's `skill_version`, the npm registry and the published `vidfarm.cc/SKILL.md`, and tells you
38
+ which half is behind. It reports **offline as offline**, never as outdated.
39
+
40
+ **Agents: check on a cadence, not on every command.** `vidfarm update-check --if-stale --quiet` is a
41
+ no-op unless the last check is over 24 hours old, and prints nothing at all when you are current, so
42
+ it is safe to leave at the top of every session. When it does report an update, tell the user and
43
+ offer it — never update silently. If they decline, record it with `vidfarm update-check --skip`:
44
+ that version stays quiet and a newer one asks again. **Honour the skip.** `--unskip` undoes it.
45
+
36
46
  ### 2. Remove the old skill
37
47
 
38
48
  There is no `skills remove` command — a skill is just a directory plus a lock entry, so delete both.
@@ -93,6 +103,21 @@ latest. If nothing here mentions their version, a plain update is safe.
93
103
 
94
104
  **Current published devcli: `0.21.23`.**
95
105
 
106
+ - **0.21.57 — a local render can now FAIL on a video that renders fine.** Two new gates close the
107
+ frozen-render hole (a composition that assigns `window.__player` or `window.__hf` destroys frame
108
+ capture; the renderer then exits 0 and writes a correct-length MP4 in which nothing moves):
109
+
110
+ 1. `vidfarm render --target local` **refuses to start** when the composition assigns an
111
+ engine-owned global (`__player`, `__hf`, `__playerReady`, `__renderReady`, `__hyperframes`).
112
+ `vidfarm lint` and `vidfarm qa` report the same thing as an **error**.
113
+ 2. Every local render ends with an automatic motion check and **exits 1** if the finished file
114
+ never moves. Pass `--allow-static` for a card that is meant to hold still.
115
+
116
+ A scripted batch that renders deliberately static cards needs `--allow-static` added, or it will
117
+ start failing. Everything else that was already correct is unaffected. New command:
118
+ `vidfarm motion-check <video.mp4>` — run it on cloud renders and watermarked masters too, which
119
+ have no gate of their own.
120
+
96
121
  - **0.21.x — the package moved scopes.** The devcli is `@officexapp/vidfarm-devcli`. The old
97
122
  `@mevdragon/vidfarm-devcli` is not maintained. If `npm ls -g` shows the `@mevdragon` package,
98
123
  uninstall it explicitly, or two `vidfarm` binaries will fight over the same name on `PATH`: