editorbrain 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/editorbrain.mjs +68 -4
- package/package.json +1 -1
- package/skill/editorbrain/AGENTS.md +2 -1
- package/skill/editorbrain/SKILL.md +13 -9
- package/skill/editorbrain/references/cli-mcp.md +16 -1
- package/skill/editorbrain/references/first-edit.md +27 -0
- package/skill/editorbrain/references/search-brief.md +44 -0
- package/skill/editorbrain/references/workspace-files.md +11 -0
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ Editorial references, brand context and portable video projects for Claude Code
|
|
|
5
5
|
Inspect the CLI without configuring your agent:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npx editorbrain@0.
|
|
8
|
+
npx editorbrain@0.9.0 help
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
For a persistent installation:
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
npm install -g editorbrain@0.
|
|
14
|
+
npm install -g editorbrain@0.9.0
|
|
15
15
|
editorbrain login --url https://api.editorbrain.com
|
|
16
16
|
editorbrain status --url https://api.editorbrain.com
|
|
17
17
|
editorbrain projects list
|
package/bin/editorbrain.mjs
CHANGED
|
@@ -103,6 +103,7 @@ function validateDocument(path, content) {
|
|
|
103
103
|
if (isProject) {
|
|
104
104
|
for (const key of ["id", "brand", "style", "outputProfile"]) if (typeof doc[key] !== "string" || !identifier.test(doc[key])) add(`${key} must be a valid identifier`);
|
|
105
105
|
if (!object(doc.intent) || !nonempty(doc.intent.topic) || !nonempty(doc.intent.goal)) add("intent requires topic and goal");
|
|
106
|
+
if (doc.reviewMode !== void 0 && !["direct", "directions", "sample"].includes(doc.reviewMode)) add("reviewMode must be direct, directions or sample");
|
|
106
107
|
if (doc.script !== void 0 && typeof doc.script !== "string") add("script must be text");
|
|
107
108
|
if (doc.overrides !== void 0) {
|
|
108
109
|
if (!object(doc.overrides)) add("overrides must be an object");
|
|
@@ -326,7 +327,7 @@ Describe identity, audience, non-negotiables and preferred visual/audio treatmen
|
|
|
326
327
|
".editorbrain/memory/preferences.json": json({ confirmed: [], note: "Only explicitly confirmed feedback becomes a reusable preference. Keep scope and evidence." }),
|
|
327
328
|
[`videos/${project}/project.json`]: json({ id: project, brand, style, outputProfile: "vertical", intent: { topic: options.topic ?? "Define the subject of this video", goal: options.goal ?? "Explain the subject clearly" }, script: "", overrides: {} }),
|
|
328
329
|
[`videos/${project}/brief.md`]: "# Brief\n\nDescribe the objective, audience, script or source video, constraints and available assets.\n",
|
|
329
|
-
[`videos/${project}/direction.md`]: "# Direction\n\nDIRECTION_PENDING\n\nRead the installed EditorBrain skill and its AGENTS.md.
|
|
330
|
+
[`videos/${project}/direction.md`]: "# Direction\n\nDIRECTION_PENDING\n\nRead the installed EditorBrain skill and its AGENTS.md. Analyze the actual script and media yourself, read brand constraints, and retrieve candidates with search_from_brief. Inspect selected evidence and judge fit yourself. Save the inspected source coverage and the current review preference/version. State the intended transfer: faithful preset, editorial family or inspiration. Connect each beat to its meaning, resource/action, composition, motion, real timing and verification. Distinguish observed evidence, inference and new design. Define layer treatments, justify source reuse, and review movement and SFX in the final render. Preserve reference hashes and project-scoped feedback. A plan is not an executed or verified edit.\n"
|
|
330
331
|
};
|
|
331
332
|
}
|
|
332
333
|
function canonicalDocumentPath(path) {
|
|
@@ -542,7 +543,7 @@ var Client = class {
|
|
|
542
543
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
543
544
|
let response;
|
|
544
545
|
try {
|
|
545
|
-
response = await this.fetcher(`${this.url}${path}`, { method, headers, body: options.body === void 0 ? void 0 : JSON.stringify(options.body), redirect: "error", signal: AbortSignal.timeout(2e4) });
|
|
546
|
+
response = await this.fetcher(`${this.url}${path}`, { method, headers, body: options.body === void 0 ? void 0 : JSON.stringify(options.body), redirect: "error", signal: AbortSignal.timeout(Math.min(18e4, Math.max(1e3, options.timeoutMs ?? 2e4))) });
|
|
546
547
|
} catch {
|
|
547
548
|
if (readOnly && attempt < 2) {
|
|
548
549
|
await this.runtime.sleep(250 * 2 ** attempt + this.runtime.random() * 100);
|
|
@@ -776,7 +777,7 @@ import { createHash } from "node:crypto";
|
|
|
776
777
|
import { constants as constants2 } from "node:fs";
|
|
777
778
|
import { lstat as lstat2, open as open2, readdir as readdir2, rename as rename2 } from "node:fs/promises";
|
|
778
779
|
import { fileURLToPath } from "node:url";
|
|
779
|
-
var previousSkillHashes = { "SKILL.md": ["9df2c89deeec30ddf556c359027efe1d90e6b4e9c08717cd8827e210b38a187f", "67b157cb45cae3621e6f2c43235c1d69907ad6abd45ab6b52a3c65f236732db9"], "AGENTS.md": ["4f3ef860ade3a31aa7c6a6aab5cf6ec2a700850bf19ea2320324c12c2e0fbf5b"], "references/cli-mcp.md": ["5d3a79343fbd76cdae5bdbe12fb9c944d5dff4f489ac6534fd96e0cb8630b988", "8e011c31368cef2117a28ee972b39aab9535eeb0f601a4a0f9d6fc019b22c1c2"], "references/production-and-review.md": ["055c6df9e0f167be148b0a5c0bba5b43e108eb1f58f478d88b3536c6589ac7b3"], "references/workspace-files.md": ["e72af2871f42cd776be1bfff8009ed5562780e7f8a65b12c27887f3880631f81", "00780c64bd0244c6afb18d786b7512b43e315c376e8f88c67d6ba53d91275ccf"] };
|
|
780
|
+
var previousSkillHashes = { "SKILL.md": ["9df2c89deeec30ddf556c359027efe1d90e6b4e9c08717cd8827e210b38a187f", "67b157cb45cae3621e6f2c43235c1d69907ad6abd45ab6b52a3c65f236732db9", "1e2fff65a1b303b18b2d65156bef6eb2439a19d77ba2a25b37bcb1819ff009e3"], "AGENTS.md": ["4f3ef860ade3a31aa7c6a6aab5cf6ec2a700850bf19ea2320324c12c2e0fbf5b", "1b07de01698a0040b47ea0eddb1b017f70a69e81acd0bf9710647ca5e02f5125", "b5ee3439ff974c668755816149fab76899d7ad9266f63978b30fbc9b7d2cd640"], "references/cli-mcp.md": ["5d3a79343fbd76cdae5bdbe12fb9c944d5dff4f489ac6534fd96e0cb8630b988", "8e011c31368cef2117a28ee972b39aab9535eeb0f601a4a0f9d6fc019b22c1c2", "666082653efc000f8a7cc5f1836c80bbdda5f0f57cdbbdcb393f2b84aeb93a01", "78b737796a8685b1135e0acb91b620c51845b62e31dba04eb51dd9dd38b41008"], "references/production-and-review.md": ["055c6df9e0f167be148b0a5c0bba5b43e108eb1f58f478d88b3536c6589ac7b3"], "references/workspace-files.md": ["e72af2871f42cd776be1bfff8009ed5562780e7f8a65b12c27887f3880631f81", "00780c64bd0244c6afb18d786b7512b43e315c376e8f88c67d6ba53d91275ccf", "97053b092e0ff36e3cfb764095fcb4a4fca94e722567e774b53bc118279f40e5"] };
|
|
780
781
|
var destinations = {
|
|
781
782
|
codex: { directory: ".agents/skills/editorbrain", entryPoint: "AGENTS.md" },
|
|
782
783
|
claude: { directory: ".claude/skills/editorbrain", entryPoint: "CLAUDE.md" }
|
|
@@ -1361,6 +1362,9 @@ editorbrain push [--dir folder] [--dry-run]
|
|
|
1361
1362
|
editorbrain projects list
|
|
1362
1363
|
editorbrain documents list [--prefix path]
|
|
1363
1364
|
editorbrain documents get <path>
|
|
1365
|
+
editorbrain workflow check [--project id] [--previous-version hash]
|
|
1366
|
+
editorbrain search brief --file <editorial-brief.json> [--project id] [--mode styles|events|both] [--review direct|directions|sample]
|
|
1367
|
+
editorbrain search edit [--script file | --video file | --asset sha256 | --project id] [--requirements text] [--assets tag,tag] [--mode styles|events|both] [--review direct|directions|sample]
|
|
1364
1368
|
editorbrain library search [query]
|
|
1365
1369
|
editorbrain library get <video-id> [--document relative-source-path] [--sha256 source-hash]
|
|
1366
1370
|
editorbrain library media <video-id> --sha256 media-hash --out file
|
|
@@ -1388,7 +1392,7 @@ function parseArgs(argv) {
|
|
|
1388
1392
|
const positional = [];
|
|
1389
1393
|
const flags = {};
|
|
1390
1394
|
const booleans = /* @__PURE__ */ new Set(["help", "version", "offline", "dry-run", "key-stdin", "invite-stdin", "no-browser", "skip-mcp", "all"]);
|
|
1391
|
-
const known = /* @__PURE__ */ new Set(["dir", "brand", "style", "project", "topic", "goal", "name", "adapter", "out", "url", "document", "mime", "label", "role", "limit", "cursor", "timeout", "assets", "capabilities", "duration", "agent", "workspace", "prefix", "sha256", "kind", "channel", "epistemic-status", "event-offset", "relation-offset", ...booleans]);
|
|
1395
|
+
const known = /* @__PURE__ */ new Set(["dir", "brand", "style", "project", "topic", "goal", "name", "adapter", "out", "url", "document", "mime", "label", "role", "limit", "cursor", "timeout", "assets", "capabilities", "duration", "agent", "workspace", "prefix", "sha256", "kind", "channel", "epistemic-status", "event-offset", "relation-offset", "script", "video", "asset", "requirements", "mode", "review", "previous-version", "file", ...booleans]);
|
|
1392
1396
|
for (let i = 0; i < argv.length; i++) {
|
|
1393
1397
|
const arg = argv[i];
|
|
1394
1398
|
if (!arg.startsWith("--")) {
|
|
@@ -1735,6 +1739,66 @@ async function main() {
|
|
|
1735
1739
|
}
|
|
1736
1740
|
throw new Error("Use narrative search [query] or narrative get <video-id>.");
|
|
1737
1741
|
}
|
|
1742
|
+
if (command === "workflow" && subcommand === "check") {
|
|
1743
|
+
const client = new Client(await config(args));
|
|
1744
|
+
output(await client.request("/v1/workflow/check", { method: "POST", body: { projectId: str(args, "project"), previousVersion: str(args, "previous-version") } }));
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
if (command === "search" && subcommand === "brief") {
|
|
1748
|
+
const path = str(args, "file");
|
|
1749
|
+
if (!path) throw new Error("Provide --file with the editorial brief JSON after inspecting the actual material.");
|
|
1750
|
+
const handle = await open4(resolve4(path), constants4.O_RDONLY | constants4.O_NOFOLLOW);
|
|
1751
|
+
let brief;
|
|
1752
|
+
try {
|
|
1753
|
+
const stat = await handle.stat();
|
|
1754
|
+
if (!stat.isFile() || stat.size < 1 || stat.size > 32e3) throw new Error("Brief must be a regular UTF-8 JSON file of at most 32000 bytes.");
|
|
1755
|
+
brief = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await handle.readFile()));
|
|
1756
|
+
} finally {
|
|
1757
|
+
await handle.close();
|
|
1758
|
+
}
|
|
1759
|
+
if (!brief || typeof brief !== "object" || Array.isArray(brief)) throw new Error("Brief must be a JSON object. See the installed search-brief reference.");
|
|
1760
|
+
const mode = str(args, "mode") ?? "both", reviewMode = str(args, "review");
|
|
1761
|
+
if (!["styles", "events", "both"].includes(mode)) throw new Error("--mode must be styles, events or both.");
|
|
1762
|
+
if (reviewMode && !["direct", "directions", "sample"].includes(reviewMode)) throw new Error("--review must be direct, directions or sample.");
|
|
1763
|
+
const client = new Client(await config(args));
|
|
1764
|
+
output(await client.request("/v1/search/brief", { method: "POST", timeoutMs: 9e4, body: { brief, projectId: str(args, "project"), mode, reviewMode } }));
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
if (command === "search" && subcommand === "edit") {
|
|
1768
|
+
const client = new Client(await config(args));
|
|
1769
|
+
const scriptPath = str(args, "script"), videoPath = str(args, "video");
|
|
1770
|
+
let script, assetId = str(args, "asset");
|
|
1771
|
+
const readInput = async (path, max) => {
|
|
1772
|
+
const handle = await open4(resolve4(path), constants4.O_RDONLY | constants4.O_NOFOLLOW);
|
|
1773
|
+
try {
|
|
1774
|
+
const stat = await handle.stat();
|
|
1775
|
+
if (!stat.isFile() || stat.size < 1 || stat.size > max) throw new Error(`Input must be a regular file of at most ${max} bytes.`);
|
|
1776
|
+
return await handle.readFile();
|
|
1777
|
+
} finally {
|
|
1778
|
+
await handle.close();
|
|
1779
|
+
}
|
|
1780
|
+
};
|
|
1781
|
+
if (videoPath && assetId) throw new Error("Use --video or --asset, not both.");
|
|
1782
|
+
if (scriptPath) {
|
|
1783
|
+
script = new TextDecoder("utf-8", { fatal: true }).decode(await readInput(scriptPath, 64e3));
|
|
1784
|
+
if (script.length > 16e3) throw new Error("Script must contain at most 16000 characters.");
|
|
1785
|
+
}
|
|
1786
|
+
const mode = str(args, "mode") ?? "both", reviewMode = str(args, "review");
|
|
1787
|
+
if (!["styles", "events", "both"].includes(mode)) throw new Error("--mode must be styles, events or both.");
|
|
1788
|
+
if (reviewMode && !["direct", "directions", "sample"].includes(reviewMode)) throw new Error("--review must be direct, directions or sample.");
|
|
1789
|
+
if (assetId && !/^[a-f0-9]{64}$/.test(assetId)) throw new Error("--asset requires an owned production asset SHA-256.");
|
|
1790
|
+
if (videoPath) {
|
|
1791
|
+
const bytes = await readInput(videoPath, 12 * 1024 * 1024);
|
|
1792
|
+
const mimeType = { ".mp4": "video/mp4", ".mov": "video/quicktime", ".webm": "video/webm" }[extname(videoPath).toLowerCase()];
|
|
1793
|
+
if (!mimeType) throw new Error("Use MP4, MOV or WebM.");
|
|
1794
|
+
assetId = await sha256(bytes);
|
|
1795
|
+
const uploaded = await client.media(`/v1/assets/${assetId}?name=${encodeURIComponent(basename(videoPath))}`, { content: bytes, mimeType });
|
|
1796
|
+
if ((await uploaded.json()).sha256 !== assetId) throw new Error("Upload hash mismatch.");
|
|
1797
|
+
}
|
|
1798
|
+
if (!script && !assetId && !str(args, "project")) throw new Error("Provide --script, --video, --asset or --project with a saved script.");
|
|
1799
|
+
output(await client.request("/v1/search/edit", { method: "POST", timeoutMs: 18e4, body: { script, assetId, projectId: str(args, "project"), requirements: str(args, "requirements") ?? "", availableAssets: (str(args, "assets") ?? "").split(",").filter(Boolean), mode, reviewMode } }));
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1738
1802
|
if (command === "library") {
|
|
1739
1803
|
const client = new Client(await config(args));
|
|
1740
1804
|
if (subcommand === "search") {
|
package/package.json
CHANGED
|
@@ -25,7 +25,8 @@ editing question. Existing proposals or other project documents can be discovere
|
|
|
25
25
|
Read [the workspace file map](references/workspace-files.md) for the full structure, required/optional files and token precedence. Start with `videos/<project-id>/project.json` to discover the selected brand, style and output profile. Read their actual files plus the brief and direction; do not assume that all documents under the workspace are included automatically by `resolve`.
|
|
26
26
|
|
|
27
27
|
- Consult style packs for methods and the reference library for their execution. Search by communicative function as well as topic: comparison, demonstration, reveal, cumulative typography, collage, atmosphere, callback.
|
|
28
|
-
-
|
|
28
|
+
- Analyze the actual source yourself, then call `search_from_brief` / `editorbrain search brief` with your editorial brief and project ID. See [search brief](references/search-brief.md). EditorBrain retrieves candidates; you judge fit and inspect visual evidence. A retrieval rank is not creative review. Do not automatically call the optional server-analysis path or upload source footage. Declared inspection and hashes are your record, not server verification.
|
|
29
|
+
- Read `check_workflow` at the start, before proposals, before paid resource generation, and before the full render. Precedence: current explicit user request > project reviewMode > workspace default. Direct means proceed and review; directions means offer 2–3 fitting options with labelled library evidence; sample means show a representative customer-material frame or short clip and obtain approval. Do not require a new approval when the relevant version is already approved. Use a moving sample when rhythm or sound is what needs review. Save the workflow version and any approval with the project direction. A receipt acknowledges reading, not actual compliance.
|
|
29
30
|
- Retrieve evidence to answer a concrete question. Use representative images for composition; intervals and source video for movement; the audio review and accessible audio for sound; narrative events and relations for hooks, development, payoff and CTA.
|
|
30
31
|
- Read source documents using paths actually returned by the reference manifest. Pin hashes where supported. A script summary is not word-level alignment, and a provider candidate is not a verified measurement.
|
|
31
32
|
- Check coverage, truncation and pagination. Retrieve the relevant remaining pages or source document before generalizing to an entire reference. Do not claim complete analysis from a partial tool response.
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: editorbrain
|
|
3
|
-
description:
|
|
3
|
+
description: Edit a user's video with EditorBrain's brand files, reusable styles and reference evidence through its CLI or MCP. Inspect the actual script/media, retrieve relevant examples, adapt them, implement with available editing tools and review the result. Also use when the user names EditorBrain or requests a saved editing style.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# EditorBrain
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
You are the editor. EditorBrain supplies the harness: persistent brand/style/project files, a searchable evidence library and a workflow for turning that evidence into a finished edit. You analyze the customer's material and judge the references; no second model needs to repeat your creative decisions.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Start here, including a first installation
|
|
11
11
|
|
|
12
|
-
1. Read the bundled [AGENTS.md](AGENTS.md)
|
|
13
|
-
2.
|
|
14
|
-
3. Read
|
|
15
|
-
4.
|
|
12
|
+
1. Read the bundled [AGENTS.md](AGENTS.md) once for the editorial contract. Do not assume the host loads this nested file automatically.
|
|
13
|
+
2. If no workspace is ready, use [first edit](references/first-edit.md). Verify connection, discover or create the active project, and prepare its context without overwriting existing files. Read [CLI and MCP](references/cli-mcp.md) only for the commands needed now.
|
|
14
|
+
3. Read the selected project's `project.json`, brief, direction and the brand/style files it names. Resolve effective tokens and inspect available editing tools. Use `check_workflow` (CLI `editorbrain workflow check`) for the current review preference. Do not load every project or library document.
|
|
15
|
+
4. Inspect the actual script/video yourself. Understand its argument, goal, audience, tone, rhythm, usable resources and brand restrictions. Declare what you could inspect: script, frames, motion, audio and coverage. If you cannot access a modality, keep the limitation explicit; never invent it from a filename.
|
|
16
|
+
5. Use `search_from_brief` (CLI `editorbrain search brief --file <brief.json>`) with your analysis and project ID. Read [search brief](references/search-brief.md) for its schema. Search editorial mechanisms as well as the subject. The server returns evidence candidates using embeddings; it does not analyze the source again or certify fit. `search_for_edit` is an optional older server-analysis path, only when explicitly requested; never silently fall back to it.
|
|
17
|
+
6. Compare the candidates yourself. View the relevant reference frames; inspect intervals and audio when movement or sound matters. Select what fits the actual material, explain adaptations and missing resources, and save the direction with source hashes. Similarity is not approval; reject weak matches instead of forcing them.
|
|
18
|
+
7. Follow the effective review mode: `direct` → implement and review; `directions` → propose suitable alternatives with labelled reference evidence; `sample` → show a frame/short clip made with customer material before the full edit. Respect existing approval. Check the preference version before proposals, costly generation and full rendering; a web update cannot interrupt an active tool.
|
|
19
|
+
8. Implement with available editing/rendering tools, then inspect the final artifact and save scoped feedback. An editing request needs the edit, not only a plan. Read [production and review](references/production-and-review.md) for complex motion, audio or transfer QA. Report any dimension you could not verify.
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
Use [workspace files](references/workspace-files.md) when changing branding/styles or saving feedback. Keep `design.md`, `effects.md` and `music.md` editable at their own scopes; they guide coherent choices, not identical edits for every topic. Preserve customized instructions and previous versions. Fetch further evidence only to answer a concrete editing question.
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
Public web: https://editorbrain.com. CLI/package/skill: `editorbrain`. MCP: https://api.editorbrain.com/mcp. Source analysis by you, library retrieval by EditorBrain, selection and execution by you. A retrieved reference, export or model opinion does not certify render quality.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI and MCP: read, retrieve, save
|
|
2
2
|
|
|
3
|
-
Use the connected MCP schema and `editorbrain help` to confirm the installed contract. Examples below describe the 0.
|
|
3
|
+
Use the connected MCP schema and `editorbrain help` to confirm the installed contract. Examples below describe the 0.9.0 customer workflow; older installations may lack the skill installer or reference-media tool. Do not invent commands from historical architecture documents.
|
|
4
4
|
|
|
5
5
|
API/MCP: `https://api.editorbrain.com/mcp`. The host must connect this server separately; installing a skill does not register or authorize MCP.
|
|
6
6
|
|
|
@@ -132,3 +132,18 @@ Codex can use `codex mcp login editorbrain`; Claude Code completes OAuth from `/
|
|
|
132
132
|
`editorbrain narrative search [query] --kind hook --channel visual` finds candidates. `narrative get <video-id> --sha256 <document-hash> --event-offset 0 --relation-offset 0 --limit 50` pages through one pinned narrative document; follow returned offsets. Missing narrative coverage stays explicit.
|
|
133
133
|
|
|
134
134
|
`editorbrain library media <video-id> --sha256 <media-hash> --out <new-file>` downloads an authorized frame/audio/video and verifies its hash (90 MiB maximum). It will not overwrite an existing file. Downloading is not reviewing: inspect it with available visual/audio tools and record the intervals actually checked. Neither CLI nor MCP ingest customer references.
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Agent-led search and web preferences (0.9+)
|
|
138
|
+
|
|
139
|
+
Inspect the actual source yourself, then read [search brief](search-brief.md) for the request schema.
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
editorbrain workflow check --project my-video
|
|
143
|
+
editorbrain search brief --file ./videos/my-video/plans/search-brief.json --project my-video
|
|
144
|
+
editorbrain workflow check --project my-video --previous-version <returned-hash>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
MCP equivalents: `check_workflow` and `search_from_brief`. Search returns candidate evidence; you inspect it, compare applicability, choose and implement. It does not upload or re-analyze your source video. Older `search_for_edit` / `search edit` remains compatible as an explicitly chosen server-analysis option; it is not the default and must not be an automatic fallback.
|
|
148
|
+
|
|
149
|
+
Web preferences are pulled at checkpoints, not pushed into arbitrary agent chats. A receipt acknowledges reading; it cannot stop a running tool. Reconcile relevant changes before the next step. Respect existing scoped approval. Server timing/token telemetry excludes the host agent's own work.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# First edit: from an empty folder to reviewed output
|
|
2
|
+
|
|
3
|
+
Use this only when the user's environment or project is not ready. Do not re-onboard an existing project.
|
|
4
|
+
|
|
5
|
+
## Establish a working workspace
|
|
6
|
+
|
|
7
|
+
- Discover the installed CLI (`editorbrain version`, `editorbrain help`) and MCP tools. If absent, follow the official app's installation prompt; do not invent a package or install a rendering engine without need.
|
|
8
|
+
- For an existing account, authenticate if necessary, discover projects and use `editorbrain setup --dir <folder> --agent codex|claude|both --project <id>`. Confirm MCP `workspace_info` and CLI `status` name the same workspace. Browser consent needs the user; configuration alone is not authentication.
|
|
9
|
+
- If no project exists, `editorbrain init --dir <new-folder> --brand <brand-id> --style <style-id> --project <project-id>` creates context and installs the harness. Authenticate before synchronization. Validate, inspect `push --dry-run`, then push that intended context. Never use init to reset a pulled project. Do not confuse an empty local draft with a remotely saved project.
|
|
10
|
+
- Existing root AGENTS.md/CLAUDE.md and customized skills are preserved. Read install results and any conflict; use the returned skill path explicitly if needed. Installation is not proof the host has read it.
|
|
11
|
+
|
|
12
|
+
## Make defaults meaningful
|
|
13
|
+
|
|
14
|
+
Inspect the current request and material first. Populate the existing brief and `project.json.script` from the user's actual content, not placeholder copy. Establish goal, audience and destination from context; ask only for consequential missing choices. Keep unspecified brand colors/fonts unset rather than inheriting reference colors or the developer's personal brand. Any provisional visual choice belongs in the project direction until the user makes it reusable.
|
|
15
|
+
|
|
16
|
+
Use the selected brand's `brand.md`, `design.md`, `tokens.json`; the style's `style.md`, `effects.md`, `music.md`; and the project's `brief.md` and `direction.md`. The generated output profile is editable: 9:16/30fps is a starter, not a requirement for every video. Discover the user's actual target and available tools before rendering. Read the workspace file map when editing schemas or selecting another style.
|
|
17
|
+
|
|
18
|
+
## Keep a resumable editing record
|
|
19
|
+
|
|
20
|
+
Save only what helps the next session:
|
|
21
|
+
|
|
22
|
+
- `videos/<id>/plans/search-brief.json`: your current inspected-source brief for retrieval, including source hashes when available. This is local working data, not automatically synced context.
|
|
23
|
+
- `videos/<id>/direction.md`: selected reference IDs/document hashes, rejected conflicts if useful, adaptations, per-beat decisions, required assets, review preference/version and scoped approval. This portable document is synchronized explicitly.
|
|
24
|
+
- `assets/`, `plans/`, `renders/`, `reviews/`: local production files. Create them when needed. Local paths are not cloud uploads; never persist temporary media URLs or credentials.
|
|
25
|
+
- A final review identifies the actual file/hash and what was checked: story, visual composition/motion, text, audio and technical delivery. Record unchecked modalities. Promote feedback to a shared brand/style only at its intended scope.
|
|
26
|
+
|
|
27
|
+
The first edit follows the same quality contract as later edits: actual source inspection → brief → evidence → adaptation → implementation → final review. These are responsibilities, not a mandatory number of scenes or effects. A small revision may reuse current evidence; a materially changed source or brief needs refreshed reasoning and relevant retrieval.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Search from your own analysis (0.9+)
|
|
2
|
+
|
|
3
|
+
Inspect the actual source before filling this brief. CLI reads the brief object from a UTF-8 JSON file (up to 32,000 bytes). MCP takes `{brief, projectId?, mode?, reviewMode?}`. The server validates shape, not whether you truly inspected the source; never present that validation as verification.
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"source": {
|
|
8
|
+
"kind": "script",
|
|
9
|
+
"summary": "A creator compares two ways to organize a desk, then demonstrates the chosen layout.",
|
|
10
|
+
"inspected": ["script"],
|
|
11
|
+
"coverage": "Full supplied script read; no footage or audio supplied.",
|
|
12
|
+
"sha256": [],
|
|
13
|
+
"excerpt": "Optional short passage preserving the actual argument, not a rewritten claim."
|
|
14
|
+
},
|
|
15
|
+
"goal": "Make the difference between the two layouts understandable",
|
|
16
|
+
"audience": "People working from a small home office",
|
|
17
|
+
"tone": "Practical and calm",
|
|
18
|
+
"pacing": "Hold comparisons long enough to read; accelerate simple setup steps",
|
|
19
|
+
"availableAssets": ["User-supplied script"],
|
|
20
|
+
"missingAssets": ["Footage demonstrating both layouts"],
|
|
21
|
+
"hardConstraints": ["Preserve the user's required brand tokens; do not invent product claims"],
|
|
22
|
+
"uncertainty": ["Cannot verify camera angles or sound before receiving footage"],
|
|
23
|
+
"styleQuery": "Clear paired comparison, restrained labels, practical demonstration and visual payoff",
|
|
24
|
+
"eventQueries": ["Before-after comparison with aligned framing", "Reveal the final arrangement after setup"]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Replace this example with observations for the real project. Required fields are shown; `source.excerpt` and `source.sha256` are optional. `kind` is `script`, `video` or `mixed`; `inspected` contains only actually inspected modalities from `script`, `frames`, `motion`, `audio`. A silent video can have inspected frames/motion with no audio. State sampled intervals and omitted coverage. Hashes identify local source files, do not grant access to any remote file and are not server-verified.
|
|
29
|
+
|
|
30
|
+
Bounds: summary/styleQuery/excerpt up to 1,800 characters each; coverage 800; goal 600; audience 500; tone/pacing 400. Asset, constraint and uncertainty arrays have up to 12 entries of 400 characters each; use `[]` when empty. Up to two event queries of 1,000 characters each. These limits keep retrieval focused; preserve full production notes locally.
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
editorbrain search brief --file videos/my-video/plans/search-brief.json --project my-video --mode both
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`mode` is `styles`, `events` or `both` (default). Include projectId whenever the project is saved remotely; validate/push intended local context first. Inspect returned context and source hashes to catch stale local assumptions. Without projectId, constraints are only your declarations; do not claim the server resolved the customer's brand. Omit `reviewMode` to inherit the current preference; set it only to carry an explicit user instruction.
|
|
37
|
+
|
|
38
|
+
Search uses a mechanism query plus source meaning/constraints for styles, and specific event queries for details. It returns up to eight styles and six candidates per event query, with pinned source documents and retrieval ranks. These are candidates, not eight recommendations to show the user. Embeddings may still use a provider; no source video upload or generative model analysis/review occurs in this path. Only the text needed for embeddings is sent to the embedding provider. Telemetry measures server calls, not your host agent's token consumption.
|
|
39
|
+
|
|
40
|
+
Inspect the best few using `get_reference` / `library get`, then `view_example` for actual returned image hashes. Use `get_reference_media` for relevant motion/audio intervals. The search response supplies metadata/instructions; it does not automatically show images in the host. Keep evidence source hashes. Never fabricate media hashes, links or timestamps from a ranking.
|
|
41
|
+
|
|
42
|
+
Choose based on narrative function, required brand rules, available resources, readability, tone and continuity. Record what you retain, adapt and omit. If there is no fit, say so and refine one mechanism query while keeping constraints; avoid endless searches or claiming the top score proves quality. Broaden beyond the subject when transferable techniques exist in other niches.
|
|
43
|
+
|
|
44
|
+
If this tool is absent, report the installed version limitation, inspect sources yourself and use explicit library lookup if useful. Do not silently upload material to the older server-analysis method. A video your host cannot inspect requires accessible media tools or a disclosed limited plan, not invented observations.
|
|
@@ -34,6 +34,7 @@ videos/<project-id>/
|
|
|
34
34
|
media.json Production asset metadata (optional)
|
|
35
35
|
assets/ Local production media
|
|
36
36
|
plans/ Local plans and implementation notes
|
|
37
|
+
search-brief.json Agent analysis for retrieval (local, not auto-synced)
|
|
37
38
|
renders/ Rendered files
|
|
38
39
|
reviews/ Reviews tied to a particular delivered version
|
|
39
40
|
```
|
|
@@ -79,3 +80,13 @@ Save reusable feedback at its stated scope: project-only changes in the project,
|
|
|
79
80
|
Updating the global CLI does not replace skills already copied into a project. Run `editorbrain skill install --dir <workspace> --agent both` and inspect `conflicts`, `preserved`, `warnings` and `readInstructions`.
|
|
80
81
|
|
|
81
82
|
If skill files differ, the installer keeps them. Prepare the new version in a separate temporary directory, compare it with the project's installed copy, and merge changes while preserving custom instructions. Do not assume a successful exit means all guidance was upgraded. Root `AGENTS.md`/`CLAUDE.md` remain user-owned: if already present, use the returned skill path explicitly, or add a narrowly scoped pointer when the user asks to integrate it. There is no automatic global installation for every future project.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
## Review preference
|
|
86
|
+
|
|
87
|
+
`videos/<id>/project.json` optionally stores `reviewMode`: `direct`, `directions`, or
|
|
88
|
+
`sample`. Omit it to inherit the workspace default saved in the web app. The current
|
|
89
|
+
explicit user instruction takes precedence. Read the effective value with
|
|
90
|
+
`check_workflow` / `editorbrain workflow check`; local files alone cannot reveal a
|
|
91
|
+
new web preference. Store received versions and scoped approvals in `direction.md`.
|
|
92
|
+
Brand colors/fonts and editing effects/music remain in their existing files.
|