@officexapp/vidfarm-devcli 0.21.54 → 0.21.56
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/vidfarm/SKILL.md +65 -0
- package/.agents/skills/vidfarm/harnesses/README.md +26 -0
- package/.agents/skills/vidfarm/recipes/bulk-scripting-with-a-harness.md +2 -1
- package/.agents/skills/vidfarm/references/automation-and-local-dev.md +2 -2
- package/SKILL.director.md +69 -3
- package/SKILL.md +76 -4
- package/clipper.md +40 -6
- package/dist/src/cli.js +104 -11
- package/dist/src/devcli/clipper-run.js +941 -0
- package/dist/src/devcli/doctor.js +23 -1
- package/dist/src/devcli/harness.js +60 -15
- package/dist/src/devcli/marketplace-gigs.js +545 -39
- package/dist/src/devcli/skill-docs.js +2 -1
- package/dist/src/devcli/update-check.js +340 -0
- package/experimental/animated-sticker-story.md +2252 -0
- package/experimental/flash-harness.md +549 -0
- package/experimental/google-news-to-video.md +9 -0
- package/experimental/unique-product-explainers.md +8 -0
- package/marketplace.md +549 -14
- package/package.json +6 -2
- package/public/serve-shells/editor.html +27 -0
- package/public/serve-shells/library-files.html +28 -1
- package/public/serve-shells/library-raws.html +27 -0
- package/public/serve-shells/tools-clipper.html +27 -0
- package/public/serve-shells/tools-image.html +27 -0
- package/public/serve-shells/tools-video.html +27 -0
- package/update.md +12 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// else prints as ⚠/✗ but does not fail the command, so agents can run doctor
|
|
8
8
|
// unconditionally at session start.
|
|
9
9
|
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
10
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import net from "node:net";
|
|
13
13
|
import { homedir } from "node:os";
|
|
@@ -143,6 +143,28 @@ export async function runDoctorCommand(argv) {
|
|
|
143
143
|
const killOrphans = Boolean(parsed.values["kill-orphans"]);
|
|
144
144
|
const checks = [];
|
|
145
145
|
const add = (name, level, detail) => checks.push({ name, level, detail });
|
|
146
|
+
// 0. Are the two halves current, and are they the SAME version? The skill and
|
|
147
|
+
// the devcli ship on one semver, and a gap between them is the usual cause of
|
|
148
|
+
// "that command doesn't exist" — so it belongs in the health check, not only
|
|
149
|
+
// in the update runbook. Never fails the doctor: offline is not a defect, and
|
|
150
|
+
// a pending update is information, not breakage.
|
|
151
|
+
try {
|
|
152
|
+
const { installedDevcliVersion, installedSkillPath, readSkillVersion, compareSemver, readUpdateState, hoursSinceLastCheck } = await import("./update-check.js");
|
|
153
|
+
const devcli = installedDevcliVersion();
|
|
154
|
+
const skillPath = installedSkillPath();
|
|
155
|
+
const skill = skillPath ? readSkillVersion(readFileSync(skillPath, "utf8")) : null;
|
|
156
|
+
const since = hoursSinceLastCheck(readUpdateState());
|
|
157
|
+
const staleNote = since === null ? " · never checked for updates" : since >= 24 ? ` · last update check ${Math.round(since / 24)}d ago` : "";
|
|
158
|
+
if (devcli && skill && compareSemver(devcli, skill) !== 0) {
|
|
159
|
+
add("versions", "warn", `devcli ${devcli} vs skill ${skill} — MISMATCHED. They ship together; run: vidfarm update-check`);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
add("versions", since !== null && since < 24 ? "ok" : "warn", `devcli ${devcli ?? "?"} · skill ${skill ?? "not installed"}${staleNote}${staleNote ? " — vidfarm update-check" : ""}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// A version probe must never take the doctor down with it.
|
|
167
|
+
}
|
|
146
168
|
// 1. Node version.
|
|
147
169
|
const nodeMajor = Number(process.versions.node.split(".")[0]);
|
|
148
170
|
add("node", nodeMajor >= 22 ? "ok" : "fail", `v${process.versions.node}${nodeMajor >= 22 ? "" : " — vidfarm-devcli needs Node >= 22"}`);
|
|
@@ -59,10 +59,10 @@ const DISCOVERY_NAMES = ["HARNESS.md", "harness.md", "QA_REGIME.md", "qa_regime.
|
|
|
59
59
|
// They ship inside the skill pack (.agents/skills/vidfarm/harnesses/) rather
|
|
60
60
|
// than as TS string constants, so a director can read, diff, and copy them as
|
|
61
61
|
// normal files — the file IS the documentation.
|
|
62
|
-
function
|
|
62
|
+
function packDir(...segments) {
|
|
63
63
|
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
64
64
|
for (let i = 0; i < 6; i += 1) {
|
|
65
|
-
const candidate = path.join(dir,
|
|
65
|
+
const candidate = path.join(dir, ...segments);
|
|
66
66
|
if (existsSync(candidate))
|
|
67
67
|
return candidate;
|
|
68
68
|
const parent = path.dirname(dir);
|
|
@@ -72,32 +72,77 @@ function builtinDir() {
|
|
|
72
72
|
}
|
|
73
73
|
return null;
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
function builtinDir() {
|
|
76
|
+
return packDir(".agents", "skills", "vidfarm", "harnesses");
|
|
77
|
+
}
|
|
78
|
+
// The EXPERIMENTAL harnesses — full format contracts under live testing, served
|
|
79
|
+
// at https://vidfarm.cc/experimental/<slug>.md. They ship inside the npm package
|
|
80
|
+
// too (`experimental/**/*.md` in package.json `files`), so an agent that already
|
|
81
|
+
// has the CLI reaches them by NAME, offline, with no fetch: `vidfarm harness show
|
|
82
|
+
// meme-recaption`, `vidfarm qa ./work --harness wall-text-pov-ugc`. The web index
|
|
83
|
+
// stays the source of truth for what exists; this is the same shelf, local.
|
|
84
|
+
function experimentalDir() {
|
|
85
|
+
return packDir("experimental");
|
|
86
|
+
}
|
|
87
|
+
function readEntry(full, name, origin) {
|
|
88
|
+
const parsed = parseHarness(readFileSync(full, "utf8"), full);
|
|
89
|
+
return {
|
|
90
|
+
name,
|
|
91
|
+
path: full,
|
|
92
|
+
video_type: parsed.video_type,
|
|
93
|
+
summary: parsed.summary,
|
|
94
|
+
origin,
|
|
95
|
+
...(origin === "experimental" ? { url: `https://vidfarm.cc/experimental/${name}.md` } : {})
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export function listExperimentalHarnesses() {
|
|
99
|
+
const dir = experimentalDir();
|
|
77
100
|
if (!dir)
|
|
78
101
|
return [];
|
|
79
102
|
return readdirSync(dir)
|
|
80
|
-
.filter((file) => file.endsWith(
|
|
103
|
+
.filter((file) => file.endsWith(".md"))
|
|
81
104
|
.sort()
|
|
82
|
-
.map((file) =>
|
|
83
|
-
const full = path.join(dir, file);
|
|
84
|
-
const parsed = parseHarness(readFileSync(full, "utf8"), full);
|
|
85
|
-
return { name: file.slice(0, -BUILTIN_SUFFIX.length), path: full, video_type: parsed.video_type, summary: parsed.summary };
|
|
86
|
-
});
|
|
105
|
+
.map((file) => readEntry(path.join(dir, file), file.slice(0, -".md".length), "experimental"));
|
|
87
106
|
}
|
|
88
|
-
/**
|
|
107
|
+
/** Both shelves, built-ins first. `vidfarm harness list` prints exactly this. */
|
|
108
|
+
export function listBuiltinHarnesses() {
|
|
109
|
+
const dir = builtinDir();
|
|
110
|
+
const builtins = !dir
|
|
111
|
+
? []
|
|
112
|
+
: readdirSync(dir)
|
|
113
|
+
.filter((file) => file.endsWith(BUILTIN_SUFFIX))
|
|
114
|
+
.sort()
|
|
115
|
+
.map((file) => readEntry(path.join(dir, file), file.slice(0, -BUILTIN_SUFFIX.length), "builtin"));
|
|
116
|
+
return [...builtins, ...listExperimentalHarnesses()];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve `hooks` (built-in), `meme-recaption` (experimental), or
|
|
120
|
+
* `./my/HARNESS.md` (a path) to a file. Underscore spellings resolve too, so the
|
|
121
|
+
* URL slug and the CLI name never disagree — the same near-miss the web route
|
|
122
|
+
* forgives with its aliases.
|
|
123
|
+
*/
|
|
89
124
|
export function resolveHarnessPath(ref) {
|
|
90
125
|
const direct = path.resolve(ref);
|
|
91
126
|
if (existsSync(direct) && !direct.endsWith(path.sep))
|
|
92
127
|
return direct;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
const slug = ref.trim().toLowerCase().replace(/\.md$/, "").replace(/_/g, "-");
|
|
129
|
+
const builtins = builtinDir();
|
|
130
|
+
if (builtins) {
|
|
131
|
+
for (const name of [ref, slug]) {
|
|
132
|
+
const candidate = path.join(builtins, `${name}${BUILTIN_SUFFIX}`);
|
|
133
|
+
if (existsSync(candidate))
|
|
134
|
+
return candidate;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const experimental = experimentalDir();
|
|
138
|
+
if (experimental) {
|
|
139
|
+
const candidate = path.join(experimental, `${slug}.md`);
|
|
96
140
|
if (existsSync(candidate))
|
|
97
141
|
return candidate;
|
|
98
142
|
}
|
|
99
143
|
const names = listBuiltinHarnesses().map((entry) => entry.name);
|
|
100
|
-
throw new Error(`No harness "${ref}". Pass a file path, or one of the
|
|
144
|
+
throw new Error(`No harness "${ref}". Pass a file path, or one of the bundled names: ${names.join(", ") || "(none bundled)"}. ` +
|
|
145
|
+
`The live index is https://vidfarm.cc/experimental. ` +
|
|
101
146
|
`Scaffold your own with \`vidfarm harness init <name> --out ./work/HARNESS.md\`, ` +
|
|
102
147
|
`or derive one from a decomposed template with \`vidfarm harness derive <forkId>\`.`);
|
|
103
148
|
}
|