@officexapp/vidfarm-devcli 0.21.62 → 0.21.63
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/.agents/skills/dollarplatoon-skill/SKILL.md +163 -1174
- package/.agents/skills/dollarplatoon-skill/SOURCE.md +62 -0
- package/.agents/skills/dollarplatoon-skill/skill/clients.md +234 -0
- package/.agents/skills/dollarplatoon-skill/skill/feeds.md +326 -0
- package/.agents/skills/dollarplatoon-skill/skill/gigs.md +395 -0
- package/.agents/skills/dollarplatoon-skill/skill/gigworkers.md +324 -0
- package/.agents/skills/dollarplatoon-skill/skill/orders.md +573 -0
- package/.agents/skills/dollarplatoon-skill/skill/payouts.md +234 -0
- package/.agents/skills/dollarplatoon-skill/skill/platform.md +174 -0
- package/.agents/skills/dollarplatoon-skill/skill/prices.md +75 -0
- package/.agents/skills/dollarplatoon-skill/skill/pricing-and-tags.md +255 -0
- package/.agents/skills/dollarplatoon-skill/skill/proofs.md +555 -0
- package/.agents/skills/dollarplatoon-skill/skill/queue.md +404 -0
- package/.agents/skills/dollarplatoon-skill/skill/quickstart.md +191 -0
- package/.agents/skills/dollarplatoon-skill/skill/staging.md +178 -0
- package/.agents/skills/dollarplatoon-skill/skill/tasks.md +588 -0
- package/.agents/skills/dollarplatoon-skill/skill/web-pages.md +586 -0
- package/.agents/skills/vidfarm/SKILL.md +3 -3
- package/.agents/skills/vidfarm/references/core-workflows.md +39 -0
- package/SKILL.director.md +42 -3
- package/SKILL.md +3 -1
- package/clipper.md +20 -0
- package/dist/src/cli.js +50 -6
- package/dist/src/devcli/delivery-seal.js +119 -0
- package/dist/src/devcli/marketplace-console.js +1253 -0
- package/dist/src/devcli/marketplace-gigs.js +162 -16
- package/marketplace.md +275 -1
- package/package.json +24 -3
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
// api key, read the feed to find clients, join a machine, claim a task, and
|
|
9
9
|
// submit your proof.
|
|
10
10
|
//
|
|
11
|
+
// Those two sides are a VIDFARM distinction — paid plan versus none. Dollar
|
|
12
|
+
// Platoon itself has no personas: one account, and per machine you are its
|
|
13
|
+
// Owner or a Participant. Its web pages live under `/gigs*` only.
|
|
14
|
+
//
|
|
11
15
|
// Everything here talks to Dollar Platoon's own API. The key is resolved in
|
|
12
16
|
// this order:
|
|
13
17
|
// 1. --dp-key <key>
|
|
@@ -21,6 +25,7 @@ import { parseArgs } from "node:util";
|
|
|
21
25
|
import { readFileSync } from "node:fs";
|
|
22
26
|
import { readStoredAuth } from "./auth-store.js";
|
|
23
27
|
import { verifyProof } from "./proof-verify.js";
|
|
28
|
+
import { buildSealedDeliverable, sealDeliverable, describeSealedDeliverable } from "./delivery-seal.js";
|
|
24
29
|
const BOLD = "\x1b[1m";
|
|
25
30
|
const DIM = "\x1b[2m";
|
|
26
31
|
const GREEN = "\x1b[32m";
|
|
@@ -116,6 +121,17 @@ GIGWORKER — "help me earn on vidfarm" (free — bring your own key: export DOL
|
|
|
116
121
|
--private-note "<text>" Anything else that follows the master (ProRes, project
|
|
117
122
|
files, music licence id). 8000 chars, and on a SUBMITTED
|
|
118
123
|
proof it cannot be changed — withdraw it first, or draft it.
|
|
124
|
+
Delivering to a VIDFARM order (a vending-machine shop on vidfarm.cc/marketplace):
|
|
125
|
+
--project <url> The composition folder — composition.html + composition.json
|
|
126
|
+
— so the buyer can FORK your build, not just download it.
|
|
127
|
+
--delivery-url <url> The pack this settles: https://vidfarm.cc/delivery/del_…
|
|
128
|
+
Minted by the shop console when you fulfil the order.
|
|
129
|
+
--preview-note "<text>" What the WATERMARKED cut is (aspect, length, fps). It
|
|
130
|
+
describes the half they can already see.
|
|
131
|
+
--sealed Force the vidfarm json note even with none of the above.
|
|
132
|
+
Any of the three flags turns it on by itself. The note is
|
|
133
|
+
then json WHOLE — your prose moves into --private-note,
|
|
134
|
+
which vidfarm renders as your message on the pack.
|
|
119
135
|
--mailbox <id> --tags a,b --note "<text>" (--note is the PUBLIC feedback field)
|
|
120
136
|
--ask <usd> Quote your own price (machines with price offers on). An
|
|
121
137
|
ask is a QUOTE — the buyer must approve at that number.
|
|
@@ -129,6 +145,8 @@ GIGWORKER — "help me earn on vidfarm" (free — bring your own key: export DOL
|
|
|
129
145
|
gigs drafts <gig-id> Your unsent drafts on that machine
|
|
130
146
|
gigs edit-draft <gig-id> <proof-id> [--proof <url>…] [--private-note "<t>"] [--ask <usd>]
|
|
131
147
|
Change an unsent draft. --private-note "" clears it.
|
|
148
|
+
Takes --clean-master and the vidfarm delivery flags too, so
|
|
149
|
+
a missing master or a lost delivery note is repaired here.
|
|
132
150
|
gigs send <gig-id> <proof-id> Send a draft. The price is snapshotted NOW, not when you
|
|
133
151
|
saved it, and the review clock starts here.
|
|
134
152
|
gigs withdraw <gig-id> <proof-id> THE UNDO. Pulls a pending proof back to draft, stops the
|
|
@@ -139,6 +157,10 @@ GIGWORKER — "help me earn on vidfarm" (free — bring your own key: export DOL
|
|
|
139
157
|
inside a rollup or already paid is final.
|
|
140
158
|
gigs discard <gig-id> <proof-id> Delete a draft and free its task. Drafts only — a
|
|
141
159
|
submitted proof stays on the record. (alias: delete-draft)
|
|
160
|
+
gigs seal --clean-master-url <url> [--project <url>] [--delivery-url <url>]
|
|
161
|
+
Print the vidfarm delivery note as json and stop. No key
|
|
162
|
+
needed. Use it to check what submit would send, or to build
|
|
163
|
+
the note for a curl you write yourself. Never hand-roll it.
|
|
142
164
|
gigs proof <gig-id> <proof-id> Read your own proof back: paid_out_at + the private note
|
|
143
165
|
gigs earnings Your rollups + totals. (aliases: rollups, paid)
|
|
144
166
|
gigs mine Your mailboxes across every gig
|
|
@@ -191,7 +213,7 @@ async function resolveAuth(values) {
|
|
|
191
213
|
throw new GigsAuthMissingError([
|
|
192
214
|
"No Dollar Platoon key found.",
|
|
193
215
|
" Any plan: run `vidfarm login` — every vidfarm account (free included) holds a key.",
|
|
194
|
-
" Gigworker: export DOLLARPLATOON_API_KEY=… from https://dollarplatoon.com/
|
|
216
|
+
" Gigworker: export DOLLARPLATOON_API_KEY=… from https://dollarplatoon.com/settings",
|
|
195
217
|
" Or pass it directly: --dp-key <key>"
|
|
196
218
|
].join("\n"));
|
|
197
219
|
}
|
|
@@ -412,8 +434,10 @@ const MACHINE_ALIASES = {
|
|
|
412
434
|
};
|
|
413
435
|
/** Both machines, found by their stable `vidfarm_vm_<slug>` tag. */
|
|
414
436
|
async function listMachines(auth) {
|
|
415
|
-
|
|
416
|
-
|
|
437
|
+
// Paged. `?tag=` is matched INSIDE a page, so a buyer with a few order gigs
|
|
438
|
+
// can have a machine sitting behind the cursor — and a machine we cannot see
|
|
439
|
+
// is one `resolveGigId` reports as missing.
|
|
440
|
+
const { rows: gigs } = await pageAll(auth, "/gigs/mine", (body) => body.gigs ?? body.items ?? body.data ?? [], { tag: "vidfarm_vm_" });
|
|
417
441
|
return gigs.map((gig) => {
|
|
418
442
|
const tag = (gig.tags ?? []).find((t) => typeof t === "string" && t.startsWith("vidfarm_vm_")) ?? "";
|
|
419
443
|
return {
|
|
@@ -453,8 +477,11 @@ async function resolveInviteUrl(auth, gigId) {
|
|
|
453
477
|
return `https://dollarplatoon.com/gig/${encodeURIComponent(gigId)}/join?invite=${encodeURIComponent(String(invite.token))}`;
|
|
454
478
|
return "";
|
|
455
479
|
};
|
|
456
|
-
|
|
457
|
-
|
|
480
|
+
// Paged: not finding the durable `default` invite MINTS ANOTHER, so stopping
|
|
481
|
+
// at page one is how a machine collects dead links it will never redeem.
|
|
482
|
+
const invites = await pageAll(auth, `/gigs/${gigId}/invites`, (body) => body.invites ?? [])
|
|
483
|
+
.then((r) => r.rows)
|
|
484
|
+
.catch(() => []);
|
|
458
485
|
const reusable = invites.filter((i) => !i.revoked && !i.exhausted && !i.email && (i.max_uses === null || i.max_uses === undefined));
|
|
459
486
|
const chosen = reusable.find((i) => i.label === "default") ?? reusable[0];
|
|
460
487
|
if (chosen && pick(chosen))
|
|
@@ -1314,6 +1341,64 @@ export async function cmdVerifyProof(values) {
|
|
|
1314
1341
|
if (blocked)
|
|
1315
1342
|
process.exitCode = 2;
|
|
1316
1343
|
}
|
|
1344
|
+
// ── the vidfarm delivery note ────────────────────────────────────────────────
|
|
1345
|
+
/**
|
|
1346
|
+
* Build the sealed note from submit's own flags — or return null, meaning this
|
|
1347
|
+
* proof is a plain-text delivery on somebody else's gig and must stay one.
|
|
1348
|
+
*
|
|
1349
|
+
* The trigger is any VIDFARM-ONLY flag. A worker on a stranger's machine never
|
|
1350
|
+
* passes one, so they never get a json blob where the buyer expected a sentence.
|
|
1351
|
+
*
|
|
1352
|
+
* ONE item, on purpose. A `gigs submit` call carries one task and one cut, and
|
|
1353
|
+
* the multi-item deliveries are made in the shop console, which builds the same
|
|
1354
|
+
* shape from its own form. A vendor who really is delivering a batch from the
|
|
1355
|
+
* terminal builds it with `gigs seal` and passes the json through.
|
|
1356
|
+
*/
|
|
1357
|
+
function sealedFrom(values, proofs, masterUrl) {
|
|
1358
|
+
const project = values.project ? String(values.project) : "";
|
|
1359
|
+
const deliveryUrl = values["delivery-url"] ? String(values["delivery-url"]) : "";
|
|
1360
|
+
const previewNote = values["preview-note"] ? String(values["preview-note"]) : "";
|
|
1361
|
+
if (!values.sealed && !project && !deliveryUrl && !previewNote)
|
|
1362
|
+
return null;
|
|
1363
|
+
return buildSealedDeliverable({
|
|
1364
|
+
deliveryUrl,
|
|
1365
|
+
// In prose the private note is everything-after-the-master. In the sealed
|
|
1366
|
+
// shape it is the VENDOR'S MESSAGE, which is where vidfarm renders it on the
|
|
1367
|
+
// pack — so it moves here rather than being lost or duplicated per item.
|
|
1368
|
+
vendorNote: values["private-note"] ? String(values["private-note"]) : "",
|
|
1369
|
+
items: [{
|
|
1370
|
+
masterUrls: masterUrl ? [masterUrl] : [],
|
|
1371
|
+
previewUrls: proofs,
|
|
1372
|
+
previewNote,
|
|
1373
|
+
projectUrl: project,
|
|
1374
|
+
notes: values["master-note"] ? String(values["master-note"]) : ""
|
|
1375
|
+
}]
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* `vidfarm gigs seal` — print the note and stop. Needs NO key.
|
|
1380
|
+
*
|
|
1381
|
+
* The whole point of shipping this is that nobody hand-rolls `JSON.stringify`:
|
|
1382
|
+
* a note with the right fields spelled slightly wrong parses fine, opens to
|
|
1383
|
+
* nothing on the buyer's pack, and cannot be patched once the proof is sent.
|
|
1384
|
+
*/
|
|
1385
|
+
function cmdSeal(values) {
|
|
1386
|
+
const proofs = [].concat(values.proof ?? []);
|
|
1387
|
+
const masterUrl = values["clean-master-url"] ? String(values["clean-master-url"]) : "";
|
|
1388
|
+
if (!masterUrl && !values.project) {
|
|
1389
|
+
throw new Error("gigs seal needs at least --clean-master-url <url> (upload it first: vidfarm gigs upload ./final-clean.mp4) or --project <url>.");
|
|
1390
|
+
}
|
|
1391
|
+
// Forced on: `seal` IS the sealed format, so it never asks for --sealed too.
|
|
1392
|
+
const sealed = sealedFrom({ ...values, sealed: true }, proofs, masterUrl);
|
|
1393
|
+
if (values.json) {
|
|
1394
|
+
console.log(sealDeliverable(sealed));
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
for (const line of describeSealedDeliverable(sealed))
|
|
1398
|
+
console.log(`${DIM}${line}${RESET}`);
|
|
1399
|
+
console.log("");
|
|
1400
|
+
console.log(sealDeliverable(sealed));
|
|
1401
|
+
}
|
|
1317
1402
|
async function cmdSubmit(auth, values, positionals) {
|
|
1318
1403
|
const gigId = positionals[0];
|
|
1319
1404
|
if (!gigId)
|
|
@@ -1382,14 +1467,35 @@ async function cmdSubmit(auth, values, positionals) {
|
|
|
1382
1467
|
// --clean-master uploads the file to DollarPlatoon's own s3 first, because the
|
|
1383
1468
|
// note presigns that url at read time off a random key; a link you host is
|
|
1384
1469
|
// reachable the moment anyone guesses it.
|
|
1385
|
-
const
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1470
|
+
const masterUrl = values["clean-master"]
|
|
1471
|
+
? await uploadToDollarPlatoon(auth, String(values["clean-master"]))
|
|
1472
|
+
: (values["clean-master-url"] ? String(values["clean-master-url"]) : "");
|
|
1473
|
+
// TWO NOTE FORMATS, and the difference is who reads it.
|
|
1474
|
+
//
|
|
1475
|
+
// A stranger's own vending machine reads the note as prose, so prose is the
|
|
1476
|
+
// default and nothing about that changed. A VIDFARM order reads it as json —
|
|
1477
|
+
// it is how the buyer's pack finds the master, the composition folder and
|
|
1478
|
+
// your message — and json must be the WHOLE string, so the two cannot be
|
|
1479
|
+
// mixed. Deciding by whether a vidfarm-only flag was passed means a worker on
|
|
1480
|
+
// someone else's gig never accidentally sends a buyer a blob to read.
|
|
1481
|
+
const sealedNote = sealedFrom(values, proofs, masterUrl);
|
|
1482
|
+
let privateNote;
|
|
1483
|
+
if (sealedNote) {
|
|
1484
|
+
privateNote = sealDeliverable(sealedNote);
|
|
1485
|
+
if (!values.json) {
|
|
1486
|
+
console.log(`${DIM}Sealing a vidfarm delivery note:${RESET}`);
|
|
1487
|
+
for (const line of describeSealedDeliverable(sealedNote))
|
|
1488
|
+
console.log(` ${DIM}${line}${RESET}`);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
else {
|
|
1492
|
+
const noteParts = [];
|
|
1493
|
+
if (masterUrl)
|
|
1494
|
+
noteParts.push(`Clean master, no watermark: ${masterUrl}`);
|
|
1495
|
+
if (values["private-note"])
|
|
1496
|
+
noteParts.push(String(values["private-note"]));
|
|
1497
|
+
privateNote = noteParts.join("\n");
|
|
1389
1498
|
}
|
|
1390
|
-
if (values["private-note"])
|
|
1391
|
-
noteParts.push(String(values["private-note"]));
|
|
1392
|
-
const privateNote = noteParts.join("\n");
|
|
1393
1499
|
const result = await dp(auth, `/gigs/${encodeURIComponent(gigId)}/proofs`, {
|
|
1394
1500
|
method: "POST",
|
|
1395
1501
|
body: {
|
|
@@ -1482,10 +1588,37 @@ async function cmdEditDraft(auth, values, positionals) {
|
|
|
1482
1588
|
const body = {};
|
|
1483
1589
|
if (proofs.length)
|
|
1484
1590
|
body.proofs = proofs;
|
|
1485
|
-
//
|
|
1486
|
-
//
|
|
1487
|
-
|
|
1591
|
+
// Repair a VIDFARM delivery note the same way submit writes it. Without this
|
|
1592
|
+
// the obvious repair — `edit-draft --private-note "…"` — would replace a
|
|
1593
|
+
// sealed json note with prose, and the buyer's pack would open to nothing.
|
|
1594
|
+
// The trigger is the same: any vidfarm-only flag.
|
|
1595
|
+
// A missing master is the other half of the same repair, so --clean-master
|
|
1596
|
+
// uploads here too rather than sending the vendor back to `gigs upload`.
|
|
1597
|
+
const masterUrl = values["clean-master"]
|
|
1598
|
+
? await uploadToDollarPlatoon(auth, String(values["clean-master"]))
|
|
1599
|
+
: (values["clean-master-url"] ? String(values["clean-master-url"]) : "");
|
|
1600
|
+
const sealedNote = sealedFrom(values, proofs, masterUrl);
|
|
1601
|
+
if (sealedNote) {
|
|
1602
|
+
body.private_note = sealDeliverable(sealedNote);
|
|
1603
|
+
if (!values.json) {
|
|
1604
|
+
console.log(`${DIM}Resealing the vidfarm delivery note:${RESET}`);
|
|
1605
|
+
for (const line of describeSealedDeliverable(sealedNote))
|
|
1606
|
+
console.log(` ${DIM}${line}${RESET}`);
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
else if (masterUrl) {
|
|
1610
|
+
// Prose, in the same layout `gigs submit` writes, so a draft repaired here
|
|
1611
|
+
// reads identically to one that never needed repairing.
|
|
1612
|
+
const noteParts = [`Clean master, no watermark: ${masterUrl}`];
|
|
1613
|
+
if (values["private-note"])
|
|
1614
|
+
noteParts.push(String(values["private-note"]));
|
|
1615
|
+
body.private_note = noteParts.join("\n");
|
|
1616
|
+
}
|
|
1617
|
+
else if (values["private-note"] !== undefined) {
|
|
1618
|
+
// An empty string is the documented way to CLEAR either field, so the test
|
|
1619
|
+
// is "was the flag present", never "is the value truthy".
|
|
1488
1620
|
body.private_note = String(values["private-note"]) || null;
|
|
1621
|
+
}
|
|
1489
1622
|
if (values.ask !== undefined)
|
|
1490
1623
|
body.asking_price = String(values.ask) === "" ? null : Number(values.ask);
|
|
1491
1624
|
if (!Object.keys(body).length) {
|
|
@@ -1641,7 +1774,9 @@ function options() {
|
|
|
1641
1774
|
tag: { type: "string" },
|
|
1642
1775
|
title: { type: "string" },
|
|
1643
1776
|
subtext: { type: "string" },
|
|
1644
|
-
// Bid auction (request-bids / bids / award).
|
|
1777
|
+
// Bid auction (request-bids / bids / award) — a PRIVATE bid thread. On
|
|
1778
|
+
// `gigs submit` the same flag means the sealed vidfarm delivery note. They
|
|
1779
|
+
// never meet: one is a buyer command, the other a worker command.
|
|
1645
1780
|
sealed: { type: "boolean" },
|
|
1646
1781
|
bell: { type: "boolean" },
|
|
1647
1782
|
opening: { type: "string" },
|
|
@@ -1660,6 +1795,13 @@ function options() {
|
|
|
1660
1795
|
"private-note": { type: "string" },
|
|
1661
1796
|
"clean-master": { type: "string" },
|
|
1662
1797
|
"clean-in-proof": { type: "boolean" },
|
|
1798
|
+
// The vidfarm delivery note. Any ONE of project / delivery-url /
|
|
1799
|
+
// preview-note switches the private note from prose to the sealed json.
|
|
1800
|
+
project: { type: "string" },
|
|
1801
|
+
"delivery-url": { type: "string" },
|
|
1802
|
+
"preview-note": { type: "string" },
|
|
1803
|
+
"master-note": { type: "string" },
|
|
1804
|
+
"clean-master-url": { type: "string" },
|
|
1663
1805
|
draft: { type: "boolean" },
|
|
1664
1806
|
ask: { type: "string" },
|
|
1665
1807
|
"skip-verify": { type: "boolean" },
|
|
@@ -1682,6 +1824,10 @@ export async function runGigsCommand(argv) {
|
|
|
1682
1824
|
// share-link worker with no account can still check a proof before sending it.
|
|
1683
1825
|
if (["verify-proof", "check-proof", "preflight", "verify"].includes(sub))
|
|
1684
1826
|
return cmdVerifyProof(values);
|
|
1827
|
+
// Same reason: `seal` only formats a string. A share-link worker with no
|
|
1828
|
+
// account must be able to build the note they are about to paste into a curl.
|
|
1829
|
+
if (["seal", "delivery-note"].includes(sub))
|
|
1830
|
+
return cmdSeal(values);
|
|
1685
1831
|
const auth = await resolveAuth(values);
|
|
1686
1832
|
switch (sub) {
|
|
1687
1833
|
case "machines":
|
package/marketplace.md
CHANGED
|
@@ -14,13 +14,44 @@ trying to fund machines it does not own. Decide once, out loud, before anything
|
|
|
14
14
|
| Your human… | You are | Load this harness and follow it |
|
|
15
15
|
|---|---|---|
|
|
16
16
|
| wants videos **made for them** — they have a product, a budget, a brand | the **buyer** | **`https://vidfarm.cc/marketplace-buyer.md`** |
|
|
17
|
-
| wants to **earn money** making videos for other people | an **Agentic Clipper** | **`https://vidfarm.cc/agentic-clipper.md`** |
|
|
17
|
+
| wants to **earn money** making videos for other people | an **Agentic Clipper**, a.k.a. a **vendor** | **`https://vidfarm.cc/agentic-clipper.md`** |
|
|
18
|
+
|
|
19
|
+
**"Clipper" and "vendor" are the same person, and both words are correct.** *Clipper* is the role —
|
|
20
|
+
someone earning by making videos. *Vendor* is what that person is called once they open a **shop** on
|
|
21
|
+
`https://vidfarm.cc/marketplace` and put **vending machines** on the shelf for buyers to order packs
|
|
22
|
+
from. Nothing changes between the two: the same key, the same proofs, the same payouts. A vendor just
|
|
23
|
+
has a storefront and therefore an extra way to deliver — see § *delivering to a vidfarm order*.
|
|
18
24
|
|
|
19
25
|
**"Agentic Clipper" means one specific thing on vidfarm: the earning mode in
|
|
20
26
|
`agentic-clipper.md`** — one orchestrator agent running a long-horizon mission to earn money from
|
|
21
27
|
this marketplace, spawning one subagent per task. When a human says *"run in agentic clipper mode"*,
|
|
22
28
|
that file is what they are asking for. It is not a synonym for "a person who edits clips."
|
|
23
29
|
|
|
30
|
+
### three verbs, and the difference between them
|
|
31
|
+
|
|
32
|
+
The shop half of this marketplace was a set of web pages until 2026-08-29 — an agent could read the
|
|
33
|
+
shelf and touch nothing on it. It is now a REST surface under `/api/v1/marketplace/`, and the devcli
|
|
34
|
+
wraps it. **Reach for the right verb first; they do not overlap.**
|
|
35
|
+
|
|
36
|
+
| Verb | What it drives | Use it when |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `vidfarm shop` | **your storefront** — pack cards, orders, deliveries, reviews, payouts | you are the vendor and a buyer ordered from *your shop* |
|
|
39
|
+
| `vidfarm purchases` | **your orders as a buyer** — the shelf, buying, ruling on a pack, accepting | you are spending money to get videos made |
|
|
40
|
+
| `vidfarm gigs` | **Dollar Platoon underneath** — mailboxes, task queues, proofs, rollups | you are working someone else's gig, with or without a shop |
|
|
41
|
+
|
|
42
|
+
`gigs` knows nothing about shops or pack cards; `shop` and `purchases` know nothing about mailboxes.
|
|
43
|
+
A clipper with no storefront lives entirely in `gigs` and that is a complete, paid way to work — a
|
|
44
|
+
shop is how buyers come to *you* instead of you going to the queue.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
vidfarm shop help # the vendor surface, in full
|
|
48
|
+
vidfarm purchases help # the buyer surface, in full
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Both take `--json` on every subcommand, and both authenticate on the ordinary vidfarm key
|
|
52
|
+
(`vidfarm login`, `VIDFARM_API_KEY`, or `--api-key`). The marketplace is paid-only, so a free key
|
|
53
|
+
reaches the routes and is refused with `402`.
|
|
54
|
+
|
|
24
55
|
**This document is the shared reference underneath both harnesses** — the keys, the REST surface,
|
|
25
56
|
the machines, the proof rules, the payout rules. The harness tells you *what loop to run*; this file
|
|
26
57
|
tells you *what each call does*. Read the harness for your side first, then use this as the manual.
|
|
@@ -161,6 +192,82 @@ export DOLLARPLATOON_API_KEY=$(curl -s -H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
|
161
192
|
|
|
162
193
|
Then read `https://dollarplatoon.com/skill.md`. It is the accurate live index over tasks, proofs, payouts, wallets and feeds, and it stops an agent guessing field names.
|
|
163
194
|
|
|
195
|
+
## How you get told — the bell, and the two emails
|
|
196
|
+
|
|
197
|
+
Both sides of the marketplace share one inbox: **`https://vidfarm.cc/notifications`**. Buyer rows and
|
|
198
|
+
vendor rows sit in the same list, because one person is a buyer on one order and a vendor on the next,
|
|
199
|
+
and splitting the list would make them check two pages to learn one thing.
|
|
200
|
+
|
|
201
|
+
The bell that opens it sits on `/marketplace`, `/marketplace/shop` and `/shop/:slug`, and the gold
|
|
202
|
+
**Marketplace** / **Vendor** button in the sidebar wears a green dot while anything is unseen.
|
|
203
|
+
|
|
204
|
+
| you are | you are told about |
|
|
205
|
+
|---|---|
|
|
206
|
+
| **vendor** | a new order · a new review · a payout · the buyer asked for changes · a new comment · the buyer withdrew · a wallet withdrawal |
|
|
207
|
+
| **buyer** | your order was fulfilled · a new comment · the vendor refunded and closed it |
|
|
208
|
+
|
|
209
|
+
### three words that look alike and are not
|
|
210
|
+
|
|
211
|
+
This is the one thing to get right before acting on a row.
|
|
212
|
+
|
|
213
|
+
| the row says | it actually means | what the deposit did |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| **vendor:** *Order rejected* | the BUYER asked for **changes** | nothing moved. still in escrow. **re-upload** |
|
|
216
|
+
| **vendor:** *Order withdrawn* | the buyer refunded | returned to the buyer. the order is dead |
|
|
217
|
+
| **buyer:** *Order rejected* | the VENDOR refunded and closed it | returned to you |
|
|
218
|
+
|
|
219
|
+
The first one is the trap. `request-changes` never reaches Dollar Platoon — their verdict is final in
|
|
220
|
+
both directions, so a wrong caption cannot be routed through their `reject` (see
|
|
221
|
+
*an order ends three ways*). A vendor who reads "rejected" and stops working has abandoned a fully
|
|
222
|
+
funded order.
|
|
223
|
+
|
|
224
|
+
### the page
|
|
225
|
+
|
|
226
|
+
Not paid-gated — a free account can fulfil work, so it can be owed a payout. Every control is a form
|
|
227
|
+
post and works with JavaScript off.
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
GET /notifications?q=<search>&filter=all|unseen&page=<n> newest first, 25 a page
|
|
231
|
+
POST /notifications/:notificationId/seen form: seen=1|0, q, filter, page
|
|
232
|
+
POST /notifications/mark-all-seen form: q, filter
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
A row carries **two separate controls**: *Mark seen / Mark unseen*, and *Open ↗* — a plain link that
|
|
236
|
+
opens the order in a new tab, so middle-click and cmd-click behave. Clicking the row itself does
|
|
237
|
+
nothing, on purpose. There is a search box, an All / Unseen filter, *Mark all seen*, and paging.
|
|
238
|
+
|
|
239
|
+
The unseen **count** is not in the page HTML — `/marketplace` is shared-cached for anonymous visitors,
|
|
240
|
+
so a number baked in would be one buyer's badge served to whoever came through the cache next. It
|
|
241
|
+
rides the session's own access probe, which an agent can read directly:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
curl -s -b cookies.txt "https://vidfarm.cc/api/v1/user/me/marketplace-access"
|
|
245
|
+
# { "ok": true, "marketplace": true, "vendor": true, "shop_slug": "acme", "notifications_unseen": 3 }
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### the two emails
|
|
249
|
+
|
|
250
|
+
`marketplace@vidfarm.cc` sends exactly two things. Nothing else ever comes from that address, which is
|
|
251
|
+
what makes a single on/off switch an honest offer.
|
|
252
|
+
|
|
253
|
+
| to | when | the button |
|
|
254
|
+
|---|---|---|
|
|
255
|
+
| the **vendor** | a buyer placed an order in their shop | *Open the order →* |
|
|
256
|
+
| the **buyer** | a vendor delivered — the pack is sealed and waiting | *Tear your pack →* |
|
|
257
|
+
|
|
258
|
+
**Default ON**, and on by *absence* of a preference rather than by a backfill, so every existing
|
|
259
|
+
account already gets them. The switch is **Settings → Marketplace → Marketplace email**
|
|
260
|
+
(`POST /settings/marketplace/email-prefs`).
|
|
261
|
+
|
|
262
|
+
Turning it off changes nothing about how orders work — the same events are still on `/notifications`.
|
|
263
|
+
**Do not suggest turning it off as a fix for anything.** Those two mails are how the other party
|
|
264
|
+
learns money moved, and a vendor who never sees an order ages past their delivery estimate and earns
|
|
265
|
+
a bad review for a shop that never knew.
|
|
266
|
+
|
|
267
|
+
> **Notifications are for the HUMAN. They are not a work queue.** An agent still polls
|
|
268
|
+
> `GET /work/available` and `POST /gigs/$GIG/queue/poll` — see *Gigworker Instructions*. The bell tells
|
|
269
|
+
> a person something happened; it does not claim tasks, and nothing here changes the polling loop.
|
|
270
|
+
|
|
164
271
|
## Client Instructions
|
|
165
272
|
|
|
166
273
|
> **The operating harness for this side is `https://vidfarm.cc/marketplace-buyer.md`.** It is the
|
|
@@ -1574,6 +1681,173 @@ that `GET` returns the proof **flat** — read `.paid_out_at`, not `.proof.paid_
|
|
|
1574
1681
|
|
|
1575
1682
|
**never put the clean master in the task's `upload_link` folder.** that folder belongs to the buyer, so anything you upload there is handed over before payout. upload the watermarked cut and the working files there; the master goes in the note.
|
|
1576
1683
|
|
|
1684
|
+
### delivering to a vidfarm ORDER — the vending machine shops on /marketplace
|
|
1685
|
+
|
|
1686
|
+
everything above is the general case: a proof on somebody's gig, and a note the buyer reads as
|
|
1687
|
+
prose. **a vidfarm order is different, and it is the one case where the note has a required shape.**
|
|
1688
|
+
|
|
1689
|
+
**"clipper" and "vendor" are the same person.** a clipper who opens a **shop** on
|
|
1690
|
+
`https://vidfarm.cc/marketplace` is a vendor. the shop holds **vending machines** — a machine is one
|
|
1691
|
+
product on the shelf, with a lot size, a price per lot and its own examples — and a buyer buys a
|
|
1692
|
+
**pack** from a machine. underneath, every machine is a dollar platoon gig and **every order is a
|
|
1693
|
+
dollar platoon task**, which is why the order page and the task thread are the same conversation.
|
|
1694
|
+
|
|
1695
|
+
| vidfarm | dollar platoon |
|
|
1696
|
+
|---|---|
|
|
1697
|
+
| vending machine (in your shop) | gig, distribution `inbound_order` |
|
|
1698
|
+
| a buyer orders a pack | task, funded on publish |
|
|
1699
|
+
| you deliver | proof — watermarked evidence + **sealed note** |
|
|
1700
|
+
| the buyer's pack | `https://vidfarm.cc/delivery/<id>` |
|
|
1701
|
+
|
|
1702
|
+
#### the delivery url — vidfarm mints it, you never invent it
|
|
1703
|
+
|
|
1704
|
+
**you do not construct a `/delivery/` url.** it is minted when you fulfil the order, and it is the
|
|
1705
|
+
buyer's own pack: private to their account, `noindex`, never shared-cached.
|
|
1706
|
+
|
|
1707
|
+
**from the terminal — this is the path for an agent:**
|
|
1708
|
+
|
|
1709
|
+
```bash
|
|
1710
|
+
vidfarm shop orders # your queue: who is waiting on you
|
|
1711
|
+
vidfarm shop order ord_… # the brief, their links, the thread
|
|
1712
|
+
|
|
1713
|
+
vidfarm shop deliver ord_… \
|
|
1714
|
+
--item "https://…/watermarked-1.mp4::https://…/clean-1.mp4::hook lands at 0:02" \
|
|
1715
|
+
--item "https://…/watermarked-2.mp4::https://…/clean-2.mp4"
|
|
1716
|
+
# → Sent 2 items to the buyer.
|
|
1717
|
+
# Pack: https://vidfarm.cc/delivery/del_…
|
|
1718
|
+
```
|
|
1719
|
+
|
|
1720
|
+
one `--item` per video. the halves are `preview::master::note`, and either url half may be a
|
|
1721
|
+
`|`-separated list to make that item a **slideshow**. `vidfarm shop deliver` again to **revise** —
|
|
1722
|
+
what you send replaces the pack.
|
|
1723
|
+
|
|
1724
|
+
the web form at `https://vidfarm.cc/marketplace/shop/orders` does exactly the same thing, one url per
|
|
1725
|
+
line. both go through one call, and vidfarm does three things in it:
|
|
1726
|
+
|
|
1727
|
+
1. creates the delivery and returns `https://vidfarm.cc/delivery/del_…`
|
|
1728
|
+
2. attaches it to the order
|
|
1729
|
+
3. submits the dollar platoon proof for you, with the note already sealed
|
|
1730
|
+
|
|
1731
|
+
**and it tells the buyer.** fulfilling puts an *Order fulfilled* row on their
|
|
1732
|
+
`https://vidfarm.cc/notifications` and mails them *"your pack is ready to tear"* from
|
|
1733
|
+
`marketplace@vidfarm.cc`. a revision does the same, worded as a revision. **so do not also chase them
|
|
1734
|
+
in the thread** — they have been told, twice, and the order page is where they rule on it. (the same
|
|
1735
|
+
machinery told YOU about the order in the first place; see *How you get told* above.)
|
|
1736
|
+
|
|
1737
|
+
so **when you deliver through `vidfarm shop deliver` or the console there is nothing to hand-roll.**
|
|
1738
|
+
the flags below are for the third route only: a task where you want the sealed note built before you
|
|
1739
|
+
paste it into your own `curl`, or a clipper with no shop delivering straight to a gig.
|
|
1740
|
+
|
|
1741
|
+
a delivery link is a **signpost**, not a page. whoever opens it is sent to their own side — the buyer
|
|
1742
|
+
to `/marketplace/orders/:orderId#delivery`, you to `/marketplace/shop/orders/:orderId`, anyone else
|
|
1743
|
+
to a 404 that does not confirm the id exists. so it is safe to put in the note, and it is the one
|
|
1744
|
+
link that survives being forwarded.
|
|
1745
|
+
|
|
1746
|
+
**a clipper with no shop has no delivery url, and that is fine.** send `deliveryUrl: ""` — an empty
|
|
1747
|
+
string is the honest answer. inventing one gives the buyer's console a link that 404s.
|
|
1748
|
+
|
|
1749
|
+
#### attach the proof to the TASK, not to the order
|
|
1750
|
+
|
|
1751
|
+
`task_identifier` is the **dollar platoon task id on that order** — the same id the order thread
|
|
1752
|
+
hangs off. it is what claims the work to you and what joins your proof to the money. never send the
|
|
1753
|
+
order id, never send the subject line. subjects collide and cause duplicate `409`s.
|
|
1754
|
+
|
|
1755
|
+
#### the note is JSON, and there is a supplied function — do not hand-roll it
|
|
1756
|
+
|
|
1757
|
+
vidfarm parses the **whole** `private_note` as json. nothing may be written before or after it: one
|
|
1758
|
+
sentence of greeting around the blob and the buyer's pack opens to nothing, and **a submitted proof's
|
|
1759
|
+
note cannot be patched.** your prose goes *inside*, in `vendorNote`.
|
|
1760
|
+
|
|
1761
|
+
**`vidfarm gigs seal` builds it.** it needs no api key, it prints the note in words before it prints
|
|
1762
|
+
the json, and it is the same builder the shop console uses — so the two can never drift:
|
|
1763
|
+
|
|
1764
|
+
```bash
|
|
1765
|
+
vidfarm gigs upload ./final-clean.mp4 # → a durable dollarplatoon s3 url
|
|
1766
|
+
|
|
1767
|
+
vidfarm gigs seal \
|
|
1768
|
+
--clean-master-url "https://…/clean.mp4" \
|
|
1769
|
+
--proof "https://…/watermarked.mp4" \
|
|
1770
|
+
--project "https://vidfarm.cc/directory/preview/dsh_…/files/acme-01" \
|
|
1771
|
+
--delivery-url "https://vidfarm.cc/delivery/del_…" \
|
|
1772
|
+
--preview-note "watermarked, 1080x1920, 27s, 30fps" \
|
|
1773
|
+
--private-note "Second hook tested better. Fork the folder to swap the CTA." \
|
|
1774
|
+
--master-note "ProRes + 1:1 alt in the same folder. Music: Epidemic #1234."
|
|
1775
|
+
```
|
|
1776
|
+
|
|
1777
|
+
`gigs submit` takes the same flags and seals the note itself. **any one of `--project`,
|
|
1778
|
+
`--delivery-url` or `--preview-note` switches it on**; with none of them the note stays prose, which
|
|
1779
|
+
is what a stranger's own vending machine wants:
|
|
1780
|
+
|
|
1781
|
+
```bash
|
|
1782
|
+
vidfarm gigs submit $GIG --task $TASK \
|
|
1783
|
+
--proof https://…/watermarked.mp4 \
|
|
1784
|
+
--clean-master ./final-clean.mp4 \
|
|
1785
|
+
--project https://vidfarm.cc/directory/preview/dsh_…/files/acme-01 \
|
|
1786
|
+
--delivery-url https://vidfarm.cc/delivery/del_… \
|
|
1787
|
+
--preview-note "watermarked, 1080x1920, 27s, 30fps" \
|
|
1788
|
+
--private-note "Second hook tested better. Fork the folder to swap the CTA."
|
|
1789
|
+
```
|
|
1790
|
+
|
|
1791
|
+
this is the shape it writes. it is versioned because the note is read back after the payout, weeks
|
|
1792
|
+
later, by code that has moved on — **v2 is additive, and every v1 note still opens**:
|
|
1793
|
+
|
|
1794
|
+
```json
|
|
1795
|
+
{
|
|
1796
|
+
"v": 2,
|
|
1797
|
+
"deliveryUrl": "https://vidfarm.cc/delivery/del_…",
|
|
1798
|
+
"vendorNote": "Second hook tested better. Fork the folder to swap the CTA.",
|
|
1799
|
+
"items": [
|
|
1800
|
+
{
|
|
1801
|
+
"itemId": "item_1",
|
|
1802
|
+
"kind": "video",
|
|
1803
|
+
"urls": ["https://…/clean.mp4"],
|
|
1804
|
+
"previewUrls": ["https://…/watermarked.mp4"],
|
|
1805
|
+
"previewNote": "watermarked, 1080x1920, 27s, 30fps",
|
|
1806
|
+
"projectUrl": "https://vidfarm.cc/directory/preview/dsh_…/files/acme-01",
|
|
1807
|
+
"notes": "ProRes + 1:1 alt in the same folder. Music: Epidemic #1234."
|
|
1808
|
+
}
|
|
1809
|
+
]
|
|
1810
|
+
}
|
|
1811
|
+
```
|
|
1812
|
+
|
|
1813
|
+
| field | what belongs in it |
|
|
1814
|
+
|---|---|
|
|
1815
|
+
| `deliveryUrl` | the pack this settles. `""` if you have no shop. |
|
|
1816
|
+
| `vendorNote` | **your own message about the delivery** — what you changed, what to look at first, what you would do next. this is where prose lives now. |
|
|
1817
|
+
| `itemId` | the join. a verdict is recorded against it, and it is what matches a preview to the master that replaces it. **never the array index** — that moves the moment you re-upload. |
|
|
1818
|
+
| `kind` | `video` or `slideshow`. derived from how many urls you gave, never declared, so it cannot disagree with the content. |
|
|
1819
|
+
| `urls` | the **clean master**. the sealed half. empty means nothing unseals when they pay. |
|
|
1820
|
+
| `previewUrls` | the **watermarked** cut they already saw. repeating it here is what tells the note which master replaces which card. |
|
|
1821
|
+
| `previewNote` | what the PREVIEW is — aspect, length, fps. it describes the half they are judging. |
|
|
1822
|
+
| `projectUrl` | the **composition folder** — `composition.html` + `composition.json`. |
|
|
1823
|
+
| `notes` | what follows the MASTER: ProRes, alternate aspects, fonts, the music licence id. |
|
|
1824
|
+
|
|
1825
|
+
#### ship the composition folder, not just a file
|
|
1826
|
+
|
|
1827
|
+
**`projectUrl` is the field vendors forget, and it is the one that gets you rebooked.** a buyer with
|
|
1828
|
+
an mp4 has to come back and pay again for "make the CTA green". a buyer with the composition folder
|
|
1829
|
+
**forks it** — `composition.html` plus `composition.json` open in the vidfarm editor, they change the
|
|
1830
|
+
line themselves, and they re-render. that is the difference between selling a file and selling
|
|
1831
|
+
something they can keep.
|
|
1832
|
+
|
|
1833
|
+
put the folder in your own vidfarm file directory and share it. **do not put it in the task's
|
|
1834
|
+
`upload_link` folder** — that folder belongs to the buyer and everything in it is handed over
|
|
1835
|
+
*before* payout, which is exactly what the sealed note exists to prevent. the folder link goes in the
|
|
1836
|
+
note with the master, and it unseals with it.
|
|
1837
|
+
|
|
1838
|
+
#### so the four things a vendor sends, and where each one goes
|
|
1839
|
+
|
|
1840
|
+
| what | where |
|
|
1841
|
+
|---|---|
|
|
1842
|
+
| the **watermarked preview** | `proofs[]` — public, playable, what they rule on |
|
|
1843
|
+
| what that preview IS | `previewNote` |
|
|
1844
|
+
| the **clean unwatermarked HD master** | `urls` — sealed until `paid_out_at` |
|
|
1845
|
+
| the **composition.html / .json folder** to fork | `projectUrl` — sealed with it |
|
|
1846
|
+
| **your own notes** | `vendorNote` for the delivery, `notes` for one item |
|
|
1847
|
+
|
|
1848
|
+
the release condition is unchanged and it is not yours to trigger: the note opens on `paid_out_at`,
|
|
1849
|
+
not on approval, and the platform does it.
|
|
1850
|
+
|
|
1577
1851
|
### drafts, and the undo — a submitted proof is not one-way
|
|
1578
1852
|
|
|
1579
1853
|
a proof has two halves, and for a long time this document only described the second one. the first
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@officexapp/vidfarm-devcli",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.63",
|
|
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": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"dist/src/devcli/consult.js",
|
|
23
23
|
"dist/src/devcli/cost-mode.js",
|
|
24
24
|
"dist/src/devcli/dedupe-local.js",
|
|
25
|
+
"dist/src/devcli/delivery-seal.js",
|
|
25
26
|
"dist/src/devcli/doctor.js",
|
|
26
27
|
"dist/src/devcli/experiments.js",
|
|
27
28
|
"dist/src/devcli/handoff.js",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"dist/src/devcli/interaction-mode.js",
|
|
31
32
|
"dist/src/devcli/local-backend.js",
|
|
32
33
|
"dist/src/devcli/marketplace-gigs.js",
|
|
34
|
+
"dist/src/devcli/marketplace-console.js",
|
|
33
35
|
"dist/src/devcli/local-frontend-server.js",
|
|
34
36
|
"dist/src/devcli/local-render.js",
|
|
35
37
|
"dist/src/devcli/plate-key.js",
|
|
@@ -106,6 +108,10 @@
|
|
|
106
108
|
"fonts:specimens": "node scripts/render-font-specimens.mjs",
|
|
107
109
|
"operator:template-artifact": "node scripts/platform-operator-template-artifact.mjs",
|
|
108
110
|
"bootstrap:staging-templates": "tsx scripts/bootstrap-staging-template-releases.ts",
|
|
111
|
+
"seed:staging-shops": "dotenv -e .env.staging -- env -u AWS_PROFILE tsx scripts/seed-marketplace-shops.ts",
|
|
112
|
+
"seed:povs": "dotenv -e .env.staging -- env -u AWS_PROFILE tsx scripts/seed-shop-povs.ts",
|
|
113
|
+
"seed:reviews": "dotenv -e .env.staging -- env -u AWS_PROFILE tsx scripts/seed-shop-reviews.ts",
|
|
114
|
+
"reset:marketplace": "dotenv -e .env.staging -- env -u AWS_PROFILE tsx scripts/reset-marketplace-staging.ts",
|
|
109
115
|
"migrate:sqlite-to-dynamodb": "tsx scripts/migrate-sqlite-to-dynamodb.ts",
|
|
110
116
|
"onboard": "node scripts/onboard-customer.mjs",
|
|
111
117
|
"deploy:prod": "bash scripts/deploy-prod.sh",
|
|
@@ -133,7 +139,7 @@
|
|
|
133
139
|
"test:consult": "node --import tsx --test test/consult.test.ts",
|
|
134
140
|
"test:agent-imagegen": "node --import tsx --test test/agent-imagegen.test.ts",
|
|
135
141
|
"test:social-meta": "node --import tsx --test test/social-meta.test.ts",
|
|
136
|
-
"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",
|
|
142
|
+
"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 && node scripts/relock-dollarplatoon-skill.mjs --check",
|
|
137
143
|
"benchmark:editor-chat": "node --import tsx scripts/benchmark-editor-chat-harness.mjs",
|
|
138
144
|
"cdk:deploy:prod-serverless": "npm run build && dotenv -e .env.production -- npx aws-cdk deploy --app 'node dist/infra/cdk/bin/vidfarm-prod.js'",
|
|
139
145
|
"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'",
|
|
@@ -147,7 +153,21 @@
|
|
|
147
153
|
"test:render-routing": "node --import tsx --test test/render-routing.test.ts",
|
|
148
154
|
"test:onboarding": "node --import tsx --test test/onboarding.test.ts",
|
|
149
155
|
"test:dp-invites": "node --import tsx --test test/dollarplatoon-invites.test.ts",
|
|
150
|
-
"test:shared-folder": "node --import tsx --test test/shared-folder.test.ts"
|
|
156
|
+
"test:shared-folder": "node --import tsx --test test/shared-folder.test.ts",
|
|
157
|
+
"test:gatcha": "node --import tsx --test test/gatcha-packs.test.ts",
|
|
158
|
+
"test:shop": "node --import tsx --test test/marketplace-shop.test.ts",
|
|
159
|
+
"test:order": "node --import tsx --test test/order-page.test.ts",
|
|
160
|
+
"test:vendor-order": "node --import tsx --test test/vendor-order-page.test.ts",
|
|
161
|
+
"test:order-decision": "node --import tsx --test test/order-decision.test.ts",
|
|
162
|
+
"test:reviews": "node --import tsx --test test/shop-reviews.test.ts",
|
|
163
|
+
"test:marketplace-api": "node --import tsx --test test/marketplace-api.test.ts",
|
|
164
|
+
"test:notifications": "node --import tsx --test test/marketplace-notifications.test.ts",
|
|
165
|
+
"test:delivery": "node --import tsx --test test/delivery-items.test.ts",
|
|
166
|
+
"test:dporders": "node --import tsx --test test/dp-order-fee.test.ts",
|
|
167
|
+
"test:dp-orders-live": "node --import tsx --test test/dp-orders-are-live.test.ts",
|
|
168
|
+
"test:dp-base-url": "node --import tsx --test test/dp-api-base-url.test.ts",
|
|
169
|
+
"test:lambda-env": "node --import tsx --test test/lambda-env-budget.test.ts",
|
|
170
|
+
"test:stage-table": "node --import tsx --test test/deployment-stage-table.test.ts"
|
|
151
171
|
},
|
|
152
172
|
"dependencies": {
|
|
153
173
|
"@ai-sdk/google": "^3.0.79",
|
|
@@ -184,6 +204,7 @@
|
|
|
184
204
|
"hyperframes": "0.8.2",
|
|
185
205
|
"linkedom": "^0.18.12",
|
|
186
206
|
"puppeteer": "25.8.0",
|
|
207
|
+
"qrcode-generator": "^1.4.4",
|
|
187
208
|
"react": "^18.3.1",
|
|
188
209
|
"react-dom": "^18.3.1",
|
|
189
210
|
"sharp": "^0.34.5",
|