@officexapp/vidfarm-devcli 0.21.46 → 0.21.47

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.
@@ -313,8 +313,11 @@ vidfarm gigs approve PRF_01H… --feedback "Great hook, keeping it."
313
313
  vidfarm gigs reject PRF_01H… --tag not_selected # a pass — costs the worker NO reputation
314
314
 
315
315
  # GIGWORKER (free, no vidfarm account: export DOLLARPLATOON_API_KEY=…)
316
- vidfarm gigs join-feed && vidfarm gigs feed # who is asking for videos right now
316
+ vidfarm gigs join-feed && vidfarm gigs feed # join read-only, then see who wants videos right now
317
317
  vidfarm gigs join <invite-url> # or --registry to list every joinable machine
318
+ # BEFORE working it, check the machine is funded — see the warning below
319
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
320
+ "https://dollarplatoon.com/api/gigs/<gig-id>" | jq '{available_funds, reserved_funds}'
318
321
  vidfarm gigs work # work waiting across every machine you joined
319
322
  vidfarm gigs claim <gig-id> # claim off the FIFO queue — note the task id
320
323
  vidfarm gigs submit <gig-id> --task <task-id> --proof https://…/final.mp4
@@ -322,6 +325,18 @@ vidfarm gigs submit <gig-id> --task <task-id> --proof https://…/final.mp4
322
325
 
323
326
  Key resolution is `--dp-key` → `DOLLARPLATOON_API_KEY` → `GIGDESK_API_KEY` → the paid account's own key via `GET /api/v1/user/me/marketplace`. **Review promptly: silence is approval** — an unreviewed proof auto-approves after the gig's review timeout (default 48h) and you pay for it.
324
327
 
328
+ **Warn the gigworker off an empty machine.** A gig is a vending machine with its own on-chain balance, and `available_funds: 0` means it cannot pay, no matter how good the delivery is. Read `available_funds` on `GET /gigs/:id` before doing any work, and tell the worker plainly what it says:
329
+
330
+ - **`0`** — do not work it yet. The proof can be approved and still sit unpaid indefinitely; nothing obliges the client to top up.
331
+ - **less than the task price** — partial coverage only. The submit response carries `"warning": "Warning: gig available funds are less than the task price"` and still accepts the proof, so acceptance is not a promise of payment.
332
+ - **`reserved_funds`** is already committed to proofs ahead of this one. Judge payability on `available_funds` alone, never on the sum.
333
+ - Budget the **10% platform fee**: a $1.00 payout draws $1.10, so a $5.00 machine covers four $1.00 videos, not five.
334
+ - Compare the funds against the **task** price, not the gig's. The gig `price` is a default only; a task may carry its own, and `price: null` (`price_tbd`) means the client names the amount at approval.
335
+
336
+ Funds never move between gigs, so one funded machine says nothing about the client's other machines — check each one. Pair the funding check with the client's reputation score before committing a batch.
337
+
338
+ The upstream contract lives at **https://dollarplatoon.com/skill.md** (an index; the gigworker playbook is `skill/gigworkers.md`, funding and fees are `skill/payouts.md`). Read it rather than guessing a field name — `GET /gigs/:id` carries `price`, `terms`, `available_funds`, `reserved_funds`, `review_timeout` and `distribution`, and there is no `price_per_proof`.
339
+
325
340
  A link is a **bearer credential**: whoever holds it has that mode. Prefer `upload` over `edit` for crowdsourcing (nobody can delete a colleague's work), keep one link per campaign rather than one per worker, and disable it the day the batch closes. **Free tier fallback:** minting is paid, so a free user puts a Google Drive / Dropbox / WeTransfer folder URL into the same `assets_link` / `upload_link` fields — worker agents treat them as plain URLs. What is lost: vector search, the scoped subtree, and the one-command `vidfarm shared put`.
326
341
 
327
342
  Two things to know. **Search is included in `read`** — that is what makes a shared folder useful to a gigworker's AI agent: it finds footage by meaning instead of paging through folders. The query embedding is billed to the **folder's owner**, not the visitor. And **only `/files` and `/temp` accept direct uploads** — `/raws`, `/approved` and `/projects` have no plain-upload backend even for the owner (raws are scanned/imported, approved posts are published renders, projects are fork storage), so an `upload` link there only creates folders. To crowdsource footage, share a `/files` folder for `upload` and import the contributions into `/raws` yourself.
package/SKILL.director.md CHANGED
@@ -2349,8 +2349,11 @@ vidfarm gigs approve PRF_01H… --feedback "Great hook, keeping it."
2349
2349
  vidfarm gigs reject PRF_01H… --tag not_selected # a pass — costs the worker NO reputation
2350
2350
 
2351
2351
  # GIGWORKER (free, no vidfarm account: export DOLLARPLATOON_API_KEY=…)
2352
- vidfarm gigs join-feed && vidfarm gigs feed # who is asking for videos right now
2352
+ vidfarm gigs join-feed && vidfarm gigs feed # join read-only, then see who wants videos right now
2353
2353
  vidfarm gigs join <invite-url> # or --registry to list every joinable machine
2354
+ # BEFORE working it, check the machine is funded — see the warning below
2355
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
2356
+ "https://dollarplatoon.com/api/gigs/<gig-id>" | jq '{available_funds, reserved_funds}'
2354
2357
  vidfarm gigs work # work waiting across every machine you joined
2355
2358
  vidfarm gigs claim <gig-id> # claim off the FIFO queue — note the task id
2356
2359
  vidfarm gigs submit <gig-id> --task <task-id> --proof https://…/final.mp4
@@ -2358,6 +2361,18 @@ vidfarm gigs submit <gig-id> --task <task-id> --proof https://…/final.mp4
2358
2361
 
2359
2362
  Key resolution is `--dp-key` → `DOLLARPLATOON_API_KEY` → `GIGDESK_API_KEY` → the paid account's own key via `GET /api/v1/user/me/marketplace`. **Review promptly: silence is approval** — an unreviewed proof auto-approves after the gig's review timeout (default 48h) and you pay for it.
2360
2363
 
2364
+ **Warn the gigworker off an empty machine.** A gig is a vending machine with its own on-chain balance, and `available_funds: 0` means it cannot pay, no matter how good the delivery is. Read `available_funds` on `GET /gigs/:id` before doing any work, and tell the worker plainly what it says:
2365
+
2366
+ - **`0`** — do not work it yet. The proof can be approved and still sit unpaid indefinitely; nothing obliges the client to top up.
2367
+ - **less than the task price** — partial coverage only. The submit response carries `"warning": "Warning: gig available funds are less than the task price"` and still accepts the proof, so acceptance is not a promise of payment.
2368
+ - **`reserved_funds`** is already committed to proofs ahead of this one. Judge payability on `available_funds` alone, never on the sum.
2369
+ - Budget the **10% platform fee**: a $1.00 payout draws $1.10, so a $5.00 machine covers four $1.00 videos, not five.
2370
+ - Compare the funds against the **task** price, not the gig's. The gig `price` is a default only; a task may carry its own, and `price: null` (`price_tbd`) means the client names the amount at approval.
2371
+
2372
+ Funds never move between gigs, so one funded machine says nothing about the client's other machines — check each one. Pair the funding check with the client's reputation score before committing a batch.
2373
+
2374
+ The upstream contract lives at **https://dollarplatoon.com/skill.md** (an index; the gigworker playbook is `skill/gigworkers.md`, funding and fees are `skill/payouts.md`). Read it rather than guessing a field name — `GET /gigs/:id` carries `price`, `terms`, `available_funds`, `reserved_funds`, `review_timeout` and `distribution`, and there is no `price_per_proof`.
2375
+
2361
2376
  A link is a **bearer credential**: whoever holds it has that mode. Prefer `upload` over `edit` for crowdsourcing (nobody can delete a colleague's work), keep one link per campaign rather than one per worker, and disable it the day the batch closes. **Free tier fallback:** minting is paid, so a free user puts a Google Drive / Dropbox / WeTransfer folder URL into the same `assets_link` / `upload_link` fields — worker agents treat them as plain URLs. What is lost: vector search, the scoped subtree, and the one-command `vidfarm shared put`.
2362
2377
 
2363
2378
  Two things to know. **Search is included in `read`** — that is what makes a shared folder useful to a gigworker's AI agent: it finds footage by meaning instead of paging through folders. The query embedding is billed to the **folder's owner**, not the visitor. And **only `/files` and `/temp` accept direct uploads** — `/raws`, `/approved` and `/projects` have no plain-upload backend even for the owner (raws are scanned/imported, approved posts are published renders, projects are fork storage), so an `upload` link there only creates folders. To crowdsource footage, share a `/files` folder for `upload` and import the contributions into `/raws` yourself.
package/SKILL.md CHANGED
@@ -191,4 +191,4 @@ Otherwise fetch `https://vidfarm.cc/skill-pack/vidfarm/files/<path>`. Load one f
191
191
  | `recipes/*.md` | `find-and-fork-template` · `retheme-template` · `local-edit-render-approve` · `onboard-a-new-director` · `bulk-scripting-with-a-harness` · `cutout-graphics-for-explainers` |
192
192
  | `harnesses/README.md` | anything harness-shaped — start here. Bases: `short-form` · `hooks` · `ugc-testimonial` · `explainer` · `product-demo` · `product-explainer` |
193
193
 
194
- Also served at `vidfarm.cc`: `/experiments.md` (ad testing), `/crowdsourcing.md` (producing a batch with gigworkers), `/update.md` (upgrade runbook), `/experimental` (methods under live testing), `/skill/vidfarm-platform` (architecture), `/skill/hyperframes` (composition-authoring craft — route broad "make me a video" asks here first).
194
+ Also served at `vidfarm.cc`: `/experiments.md` (ad testing), `/marketplace.md` (producing a batch with gigworkers), `/update.md` (upgrade runbook), `/experimental` (methods under live testing), `/skill/vidfarm-platform` (architecture), `/skill/hyperframes` (composition-authoring craft — route broad "make me a video" asks here first).
package/dist/src/cli.js CHANGED
@@ -13046,7 +13046,10 @@ void main().catch(async (error) => {
13046
13046
  || error instanceof CostModeBlockedError
13047
13047
  // A missing OPTIONAL native module (better-sqlite3 with no C++ toolchain,
13048
13048
  // the common Windows case) is an environment fact, not a vidfarm bug.
13049
- || error instanceof NativeModuleUnavailableError) {
13049
+ || error instanceof NativeModuleUnavailableError
13050
+ // marketplace-gigs is imported lazily, so match its "no key yet" error by
13051
+ // name rather than pulling the module into the startup path just for this.
13052
+ || (error instanceof Error && error.name === "GigsAuthMissingError")) {
13050
13053
  console.error(error.message);
13051
13054
  process.exit(1);
13052
13055
  }
@@ -27,8 +27,13 @@ const YELLOW = "\x1b[33m";
27
27
  const RESET = "\x1b[0m";
28
28
  /** The shared vidfarm feed: the registry + notification stream every client's machines are listed in. */
29
29
  const VIDFARM_FEED_ID = "FEED_01M0BCTVTKSDFZQVEY1RXA4NJK";
30
- /** Standing reusable invite for that feed it is public by design. */
31
- const VIDFARM_FEED_INVITE = "MDFNMEQyRUVYMVdDNzQ2Qzha";
30
+ // Two standing invites exist for that feed. The read+register+publish one is
31
+ // PRIVATE signup applies it server-side (services/dollarplatoon.ts) for paid
32
+ // clients, who are the only ones allowed to list a machine. This module ships in
33
+ // the public npm package, so it may only ever carry the read-only invite: every
34
+ // `gigs join-feed` caller is a gigworker who just needs to see the work.
35
+ /** Standing reusable read-only invite for that feed — public by design. */
36
+ const VIDFARM_FEED_READ_INVITE = "MDFNMEJDVFZUWjVaUEFHNDlO";
32
37
  const DEFAULT_DP_API = "https://dollarplatoon.com/api";
33
38
  const GIGDESK_API = "https://gigdesk.cc/api";
34
39
  export const GIGS_HELP = `vidfarm gigs — your vending machines, both sides of them
@@ -58,7 +63,7 @@ GIGWORKER (free — bring your own key: export DOLLARPLATOON_API_KEY=…)
58
63
  gigs feed Who is asking for videos right now (notifications)
59
64
  --registry Every machine listed in the feed, joinable
60
65
  --limit <n>
61
- gigs join-feed [--name "<you>"] Join the shared vidfarm feed (needed to read it)
66
+ gigs join-feed [--name "<you>"] Join the shared vidfarm feed, read-only (needed to read it)
62
67
  gigs join <gig-id> [--invite <token>] [--name "<you>"] [--wallet 0x…]
63
68
  gigs claim <gig-id> [--count 2] Claim task(s) off a FIFO queue machine
64
69
  gigs submit <gig-id> --task <task-id> --proof <url> [--proof <url>…]
@@ -72,6 +77,17 @@ GIGWORKER (free — bring your own key: export DOLLARPLATOON_API_KEY=…)
72
77
  vidfarm gigs proofs --status pending
73
78
  vidfarm gigs approve PRF_01H… --feedback "Great hook, keeping it."
74
79
  DOLLARPLATOON_API_KEY=… vidfarm gigs work`;
80
+ /**
81
+ * "You have no key yet, here is how to get one" — the single most common first
82
+ * run for a gigworker, and a deliberate instruction rather than a bug. cli.ts
83
+ * prints these without a stack trace and files no crash report.
84
+ */
85
+ export class GigsAuthMissingError extends Error {
86
+ constructor(message) {
87
+ super(message);
88
+ this.name = "GigsAuthMissingError";
89
+ }
90
+ }
75
91
  async function resolveAuth(values) {
76
92
  const explicit = values["dp-key"]?.trim();
77
93
  if (explicit)
@@ -90,7 +106,7 @@ async function resolveAuth(values) {
90
106
  source: "your vidfarm account"
91
107
  };
92
108
  }
93
- throw new Error([
109
+ throw new GigsAuthMissingError([
94
110
  "No Dollar Platoon key found.",
95
111
  " Client: run `vidfarm login` (paid plan) — the key comes from your account.",
96
112
  " Gigworker: export DOLLARPLATOON_API_KEY=… from https://dollarplatoon.com/gigworker/settings",
@@ -118,8 +134,12 @@ async function loadVidfarmMarketplace(values) {
118
134
  const body = await response.json().catch(() => ({}));
119
135
  if (!response.ok) {
120
136
  // 402/409 are meaningful: not paid, or no key connected yet. Surface them
121
- // rather than falling through to a bare "no key found".
122
- if (body?.error)
137
+ // rather than falling through to a bare "no key found". Everything else —
138
+ // above all a 401 from a stale `vidfarm login` — must fall through: this
139
+ // lookup is the LAST resort in resolveAuth, and a gigworker who never had
140
+ // a vidfarm account needs its "here is how to get a key" message, not a
141
+ // bare "Unauthorized" from a client-side route they were never using.
142
+ if (body?.error && (response.status === 402 || response.status === 409))
123
143
  throw new Error(body.error);
124
144
  marketplaceCache = null;
125
145
  return null;
@@ -144,6 +164,11 @@ async function dp(auth, path, init = {}) {
144
164
  const response = await fetch(url, {
145
165
  method: init.method ?? "GET",
146
166
  headers: {
167
+ // DollarPlatoon authenticates ONLY on x-api-key — a Bearer token alone is
168
+ // rejected with "Missing x-api-key header" before the key is even read.
169
+ // GigDesk documents Bearer and accepts x-api-key too, so sending both is
170
+ // correct for either host and keeps this transport host-agnostic.
171
+ "x-api-key": auth.key,
147
172
  authorization: `Bearer ${auth.key}`,
148
173
  accept: "application/json",
149
174
  ...(init.body === undefined ? {} : { "content-type": "application/json" })
@@ -420,7 +445,10 @@ async function cmdFeed(auth, values) {
420
445
  const registry = Boolean(values.registry);
421
446
  const path = registry ? `/feeds/${VIDFARM_FEED_ID}/registry` : `/feeds/${VIDFARM_FEED_ID}/notifications`;
422
447
  const body = await dp(auth, path, { query: { limit: values.limit ?? "50" } }).catch((error) => {
423
- if (/40[13]/.test(error.message)) {
448
+ // A non-member gets 404 on EVERY feed route — never 403 — so a stranger cannot
449
+ // confirm a feed exists. 404 is therefore the code this actually fires on; the
450
+ // others are kept for a revoked key or a lost membership.
451
+ if (/40[134]/.test(error.message)) {
424
452
  throw new Error("You are not on the vidfarm feed yet — join it first: vidfarm gigs join-feed");
425
453
  }
426
454
  throw error;
@@ -446,7 +474,7 @@ async function cmdFeed(auth, values) {
446
474
  async function cmdJoinFeed(auth, values) {
447
475
  const result = await dp(auth, `/feeds/${VIDFARM_FEED_ID}/join`, {
448
476
  method: "POST",
449
- body: { invite: VIDFARM_FEED_INVITE, ...(values.name ? { display_name: String(values.name) } : {}) }
477
+ body: { invite: VIDFARM_FEED_READ_INVITE, ...(values.name ? { display_name: String(values.name) } : {}) }
450
478
  });
451
479
  out(Boolean(values.json), result, () => {
452
480
  console.log(`${GREEN}✓${RESET} On the vidfarm feed. Read it: ${BOLD}vidfarm gigs feed${RESET}`);
package/experiments.md CHANGED
@@ -129,7 +129,7 @@ That is the strong starting checkpoint. It is not arbitrary — it is the cheape
129
129
  Test **N videos regardless of their composition params.** Every video may differ in format, hook, angle, pacing, everything. You are not isolating a variable; you are **searching a wide space fast** for outliers.
130
130
 
131
131
  - **Best for:** new users, cold starts, any product with no performance history at all.
132
- - **Editing:** thrives with **distributed task forces** — other people's AI agents (gigworkers) doing the editing. Variance between editors is a *feature* here: it widens the search. Set up the loop from `https://vidfarm.cc/crowdsourcing.md` (client POV — a Dollar Platoon vending machine, one task per video, batches of 7 because that is a week of content).
132
+ - **Editing:** thrives with **distributed task forces** — other people's AI agents (gigworkers) doing the editing. Variance between editors is a *feature* here: it widens the search. Set up the loop from `https://vidfarm.cc/marketplace.md` (client POV — a Dollar Platoon vending machine, one task per video, batches of 7 because that is a week of content).
133
133
  - **Typical shape:** the user brings the selling angles; the gigworkers take creative liberty on everything else. You get diverse videos, and diversity gets you to an outlier fastest.
134
134
  - **What you learn:** *that* something works. Not yet why.
135
135
 
@@ -420,6 +420,6 @@ When you accumulate winners, you are building the real deliverable: **a library
420
420
  ## Where to go next
421
421
 
422
422
  - **Making the videos:** `https://vidfarm.cc/skill.md` (and the director skill it points to — hooks, harnesses, review, cost mode, interactive vs autonomous)
423
- - **Crowdsourcing the editing (Creative Mode, client POV):** `https://vidfarm.cc/crowdsourcing.md`
423
+ - **Crowdsourcing the editing (Creative Mode, client POV):** `https://vidfarm.cc/marketplace.md`
424
424
  - **The agentic clipper loop programme:** `https://vidfarm.cc/clipper.md`
425
425
  - **Scheduling and analytics:** the `flockposter` skill, or the Vidfarm email channel scheduling flow
@@ -1,8 +1,11 @@
1
- # Crowdsourcing.md
1
+ # Marketplace.md
2
2
 
3
- How to crowdsource videos from vidfarm.cc
3
+ How to crowdsource videos from the vidfarm.cc marketplace.
4
4
  Please redirect user based on whether they are a client or a gigworker, instructions below.
5
5
 
6
+ > Served at `https://vidfarm.cc/marketplace.md`. The older `https://vidfarm.cc/crowdsourcing.md`
7
+ > redirects here — same document, one canonical name.
8
+
6
9
  ## Client Instructions
7
10
 
8
11
  Please help setup agentic clipper loops for a client so they can get crowdsourced viral videos for their app.
@@ -321,6 +324,24 @@ record the newest notification `id` you have seen and stop paging when you reach
321
324
 
322
325
  ### Step 3 — join a machine and set your payout wallet
323
326
 
327
+ **first: check the machine has money in it.** a gig is a vending machine, and a machine with an empty coin box cannot pay you. read `available_funds` on the gig before you do any work:
328
+
329
+ ```bash
330
+ curl -s -H "x-api-key: $DOLLARPLATOON_API_KEY" \
331
+ "https://dollarplatoon.com/api/gigs/$GIG" \
332
+ | jq '{available_funds, reserved_funds, price, review_timeout, distribution}'
333
+ ```
334
+
335
+ what the numbers mean:
336
+
337
+ - **`available_funds` is `0`** — the machine is empty. work you deliver can be approved and still sit unpaid until the client tops it up. nothing forces them to. treat `0` as *do not work this gig yet*.
338
+ - **`available_funds` is less than the task price** — it can pay some deliveries, not all. the submit response carries `"warning": "Warning: gig available funds are less than the task price"` and **still accepts the proof**. do not read that acceptance as a promise of payment.
339
+ - **`reserved_funds`** is already promised to proofs ahead of you in the queue. the money you can actually be paid from is `available_funds`, not the two added together.
340
+ - budget the **10% platform fee**: a $1.00 payout draws $1.10 out of the machine. a gig holding $5.00 pays four $1.00 videos, not five.
341
+ - **compare the funds against the TASK price, not the gig `price`.** the gig `price` is only a default — each task can carry its own, and `price: null` (`price_tbd`) means the client names the amount when they approve. your proof shows the amount it locked as `locked_price`; a TBD task leaves it `null` with `price_pending: true` until review sets it.
342
+
343
+ funds are per gig and **cannot** move between gigs, so a client with one well-funded machine tells you nothing about their empty one. check each machine you join. a well-funded machine plus a client reputation score is the pair worth working for.
344
+
324
345
  take an `invite_url` from the registry (or a `destination_url` from a notification), pull the gig id and invite token out of it, and join. **set your Base L2 payout address in the same call** — this is the field that decides where your money lands:
325
346
 
326
347
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@officexapp/vidfarm-devcli",
3
- "version": "0.21.46",
3
+ "version": "0.21.47",
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": {
@@ -8,6 +8,77 @@
8
8
  "vidfarm-devcli": "dist/src/cli.js"
9
9
  },
10
10
  "//files": "PUBLISHED = CLOUD-ONLY CLI. Ships ONLY the CLI's static import closure (backend-free) + shared client utils + skills/docs + the curated local-frontend assets (public/serve-shells snapshots, public/assets + demo/dist prebuilt bundles) that `vidfarm serve` serves offline while proxying data to the cloud. The full backend (dist/src/app.js, editor-chat, serverless-*, reskin/, landing/homepage, services/hyperframes|providers|storage|ghostcut|upstream, infra) is INTENTIONALLY EXCLUDED so the server is never open-sourced — only the RENDERED HTML shells ship, never the source that produced them. `prepack` runs scripts/check-devcli-pack-safe.mjs which HARD-FAILS if any backend file leaks in or a needed CLI file is missing. Do not broaden these globs without re-running that guard.",
11
+ "files": [
12
+ "dist/src/cli.js",
13
+ "dist/src/devcli/auth-store.js",
14
+ "dist/src/devcli/agent-imagegen.js",
15
+ "dist/src/devcli/browser-harness.js",
16
+ "dist/src/devcli/captions.js",
17
+ "dist/src/devcli/clip-store.js",
18
+ "dist/src/devcli/clips.js",
19
+ "dist/src/devcli/composition-edit.js",
20
+ "dist/src/devcli/consult.js",
21
+ "dist/src/devcli/cost-mode.js",
22
+ "dist/src/devcli/dedupe-local.js",
23
+ "dist/src/devcli/doctor.js",
24
+ "dist/src/devcli/experiments.js",
25
+ "dist/src/devcli/handoff.js",
26
+ "dist/src/devcli/greenscreen-local.js",
27
+ "dist/src/devcli/hyperframes-cli.js",
28
+ "dist/src/devcli/interaction-mode.js",
29
+ "dist/src/devcli/local-backend.js",
30
+ "dist/src/devcli/marketplace-gigs.js",
31
+ "dist/src/devcli/local-frontend-server.js",
32
+ "dist/src/devcli/local-render.js",
33
+ "dist/src/devcli/plate-key.js",
34
+ "dist/src/devcli/port-utils.js",
35
+ "dist/src/devcli/process-scan.js",
36
+ "dist/src/devcli/qa-check.js",
37
+ "dist/src/devcli/harness.js",
38
+ "dist/src/devcli/sequence.js",
39
+ "dist/src/devcli/skill-docs.js",
40
+ "dist/src/devcli/skills.js",
41
+ "dist/src/devcli/shared-folder.js",
42
+ "dist/src/devcli/speech.js",
43
+ "dist/src/devcli/sticker-pack.js",
44
+ "dist/src/devcli/studio-brand.js",
45
+ "dist/src/devcli/stills.js",
46
+ "dist/src/devcli/storyboard.js",
47
+ "dist/src/devcli/telemetry.js",
48
+ "dist/src/devcli/timeline-edit.js",
49
+ "dist/src/devcli/transitions.js",
50
+ "dist/src/hyperframes/composition.js",
51
+ "dist/src/lib/**/*.js",
52
+ "dist/src/services/brainstorm-prompts.js",
53
+ "dist/src/services/captions.js",
54
+ "dist/src/services/composition-lint.js",
55
+ "dist/src/services/provider-errors.js",
56
+ "dist/src/services/sequence-prompts.js",
57
+ "dist/src/services/speech.js",
58
+ "dist/src/services/clip-curation/**/*.js",
59
+ "dist/src/services/clip-curation/**/*.json",
60
+ "public/serve-shells/**/*.html",
61
+ "public/assets/**/*.js",
62
+ "public/assets/**/*.css",
63
+ "public/assets/**/*.map",
64
+ "public/assets/**/*.ico",
65
+ "public/assets/**/*.png",
66
+ "public/assets/**/*.svg",
67
+ "demo/dist/**",
68
+ ".agents/skills/**",
69
+ "README.md",
70
+ "SKILL.md",
71
+ "SKILL.director.md",
72
+ "src/assets/SELLING_WITH_HOOKS.md",
73
+ "src/assets/SELLING_AWARENESS_STAGES.md",
74
+ "clipper.md",
75
+ "experiments.md",
76
+ "marketplace.md",
77
+ "update.md",
78
+ "experimental/**/*.md",
79
+ "!readme.secret.md",
80
+ "!**/*.secret.*"
81
+ ],
11
82
  "publishConfig": {
12
83
  "access": "public"
13
84
  },
@@ -18,19 +89,104 @@
18
89
  "engines": {
19
90
  "node": ">=22.0.0"
20
91
  },
92
+ "scripts": {
93
+ "prepare": "patch-package || true",
94
+ "dev": "tsx --import ./src/instrument.ts watch src/index.ts",
95
+ "dev:frontend": "node scripts/build-homepage-client.mjs --watch",
96
+ "dev:cli": "tsx src/cli.ts",
97
+ "build:frontend": "node scripts/build-homepage-client.mjs",
98
+ "build:hyperframes-editor": "cd demo && node scripts/build.mjs",
99
+ "build:serve-shells": "tsx scripts/build-serve-shells.ts",
100
+ "seo:refresh": "tsx scripts/generate-route-seo.ts",
101
+ "portfolio:share": "tsx scripts/render-portfolio-share.ts",
102
+ "operator:template-artifact": "node scripts/platform-operator-template-artifact.mjs",
103
+ "bootstrap:staging-templates": "tsx scripts/bootstrap-staging-template-releases.ts",
104
+ "migrate:sqlite-to-dynamodb": "tsx scripts/migrate-sqlite-to-dynamodb.ts",
105
+ "deploy:prod": "bash scripts/deploy-prod.sh",
106
+ "deploy:staging": "bash scripts/deploy-staging.sh",
107
+ "build": "npm run build:frontend && npm run build:hyperframes-editor && npm run build:serve-shells && node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json",
108
+ "start": "node --import ./dist/src/instrument.js --enable-source-maps dist/src/index.js",
109
+ "check": "tsc -p tsconfig.json --noEmit && npm run check:skills",
110
+ "test:clips": "node --import tsx --test test/clip-curation.test.ts",
111
+ "test:social-download": "node --import tsx --test test/video-download-media.test.ts test/social-download-lookup.test.ts",
112
+ "test:qa": "node --import tsx --test test/qa-check.test.ts",
113
+ "test:studio-brand": "node --import tsx --test test/studio-brand.test.ts",
114
+ "test:stickers": "node --import tsx --test test/sticker-pack.test.ts test/plate-key.test.ts",
115
+ "test:social-recycle": "node --import tsx --test test/social-recycle.test.ts",
116
+ "test:dedupe": "node --import tsx --test test/dedupe-recipe.test.ts",
117
+ "test:iconscout": "node --import tsx --test test/iconscout.test.ts",
118
+ "test:web-search": "node --import tsx --test test/web-search.test.ts",
119
+ "test:billing": "node --import tsx --test test/billing-wallet-cas.test.ts",
120
+ "test:skill-docs": "node --import tsx --test test/skill-docs.test.ts",
121
+ "test:consult": "node --import tsx --test test/consult.test.ts",
122
+ "test:agent-imagegen": "node --import tsx --test test/agent-imagegen.test.ts",
123
+ "test:social-meta": "node --import tsx --test test/social-meta.test.ts",
124
+ "check:skills": "node scripts/build-director-skill-rollup.mjs --check && node scripts/check-skill-routes.mjs && node scripts/check-skill-nav.mjs",
125
+ "benchmark:editor-chat": "node --import tsx scripts/benchmark-editor-chat-harness.mjs",
126
+ "cdk:deploy:prod-serverless": "npm run build && dotenv -e .env.production -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-prod.js'",
127
+ "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'",
128
+ "cdk:deploy:staging-serverless": "npm run build && dotenv -e .env.staging -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-serverless-staging.js'",
129
+ "cdk:deploy:staging-serverless:hotswap": "npm run build && dotenv -e .env.staging -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-serverless-staging.js' --hotswap-fallback --require-approval never",
130
+ "cdk:deploy:prod-serverless:hotswap": "npm run build && dotenv -e .env.production -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-prod.js' --hotswap-fallback --require-approval never",
131
+ "prepack": "npm run build && node scripts/check-devcli-pack-safe.mjs",
132
+ "check:pack-safe": "node scripts/check-devcli-pack-safe.mjs",
133
+ "pack:devcli": "npm run build && node scripts/check-devcli-pack-safe.mjs && node scripts/build-devcli-package.mjs",
134
+ "pack:devcli:fast": "node scripts/check-devcli-pack-safe.mjs && node scripts/build-devcli-package.mjs",
135
+ "test:render-routing": "node --import tsx --test test/render-routing.test.ts",
136
+ "test:shared-folder": "node --import tsx --test test/shared-folder.test.ts"
137
+ },
21
138
  "dependencies": {
22
139
  "@ai-sdk/google": "^3.0.79",
23
140
  "@ai-sdk/openai": "^3.0.65",
24
141
  "@ai-sdk/openai-compatible": "^2.0.48",
142
+ "@assistant-ui/react": "^0.14.8",
143
+ "@assistant-ui/react-data-stream": "^0.12.14",
144
+ "@aws-sdk/client-cloudformation": "^3.1076.0",
145
+ "@aws-sdk/client-dynamodb": "^3.1056.0",
146
+ "@aws-sdk/client-lambda": "^3.1087.0",
147
+ "@aws-sdk/client-s3": "^3.1064.0",
148
+ "@aws-sdk/client-sfn": "^3.1073.0",
149
+ "@aws-sdk/lib-dynamodb": "^3.1073.0",
150
+ "@aws-sdk/s3-request-presigner": "^3.787.0",
25
151
  "@ffprobe-installer/ffprobe": "^2.1.2",
152
+ "@fontsource/libre-baskerville": "^5.2.10",
153
+ "@fontsource/montserrat": "^5.2.8",
154
+ "@fontsource/source-code-pro": "^5.2.7",
155
+ "@fontsource/tiktok-sans": "^5.2.4",
156
+ "@hono/node-server": "^1.14.4",
157
+ "@hyperframes/aws-lambda": "0.8.2",
158
+ "@hyperframes/studio-server": "0.8.2",
159
+ "@sentry/aws-serverless": "^10.56.0",
160
+ "@sentry/hono": "^10.56.0",
26
161
  "@sentry/node": "^10.56.0",
162
+ "@sentry/react": "^10.56.0",
27
163
  "ai": "^6.0.191",
164
+ "dotenv": "^16.5.0",
165
+ "esbuild": "^0.28.1",
28
166
  "ffmpeg-static": "^5.3.0",
167
+ "fontkit": "^2.0.4",
168
+ "hono": "^4.8.3",
29
169
  "hyperframes": "0.8.2",
30
170
  "linkedom": "^0.18.12",
171
+ "react": "^18.3.1",
172
+ "react-dom": "^18.3.1",
31
173
  "sharp": "^0.34.5",
32
174
  "zod": "^3.25.28"
33
175
  },
176
+ "devDependencies": {
177
+ "@types/better-sqlite3": "^7.6.13",
178
+ "@types/node": "^24.0.1",
179
+ "@types/react": "^18.3.23",
180
+ "@types/react-dom": "^18.3.7",
181
+ "aws-cdk-lib": "^2.196.0",
182
+ "constructs": "^10.4.2",
183
+ "dotenv-cli": "^11.0.0",
184
+ "patch-package": "^8.0.1",
185
+ "react-grab": "^0.1.48",
186
+ "tsx": "^4.19.4",
187
+ "typescript": "^5.8.3",
188
+ "zustand": "^5.0.13"
189
+ },
34
190
  "main": "index.js",
35
191
  "keywords": [],
36
192
  "author": "",