editorbrain 0.8.0 → 0.10.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 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.0 help
8
+ npx editorbrain@0.10.0 help
9
9
  ```
10
10
 
11
11
  For a persistent installation:
12
12
 
13
13
  ```sh
14
- npm install -g editorbrain@0.8.0
14
+ npm install -g editorbrain@0.10.0
15
15
  editorbrain login --url https://api.editorbrain.com
16
16
  editorbrain status --url https://api.editorbrain.com
17
17
  editorbrain projects list
@@ -1,5 +1,35 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // packages/core/src/memory.ts
4
+ function memoryPath(scope, id) {
5
+ if (!["brand", "style", "project"].includes(scope) || !/^[a-z0-9][a-z0-9_-]{0,79}$/.test(id)) throw new Error("Invalid memory scope");
6
+ return scope === "project" ? `videos/${id}/preferences.json` : `.editorbrain/${scope === "brand" ? "brands" : "styles"}/${id}/preferences.json`;
7
+ }
8
+ function memoryScope(path) {
9
+ const m = path.match(/^\.editorbrain\/(brands|styles)\/([a-z0-9_-]+)\/preferences\.json$/), p = path.match(/^videos\/([a-z0-9_-]+)\/preferences\.json$/);
10
+ return m ? { scope: m[1] === "brands" ? "brand" : "style", scopeId: m[2] } : p ? { scope: "project", scopeId: p[1] } : null;
11
+ }
12
+ function memoryIssues(path, doc) {
13
+ const scope = memoryScope(path);
14
+ if (!scope) return [];
15
+ if (doc.scope !== scope.scope || doc.scopeId !== scope.scopeId || !Array.isArray(doc.entries) || doc.entries.length > 60) return ["Memory requires matching scope and at most 60 entries"];
16
+ const ids = /* @__PURE__ */ new Set();
17
+ const errors = [];
18
+ for (const e of doc.entries) {
19
+ if (!e || typeof e.id !== "string" || !/^[a-zA-Z0-9_-]{1,100}$/.test(e.id) || ids.has(e.id) || typeof e.text !== "string" || !e.text.trim() || e.text.length > 800 || typeof e.conditions !== "string" || e.conditions.length > 400 || !["suggested", "confirmed", "disabled"].includes(e.status) || typeof e.source !== "string" || e.source.length > 400 || !["agent_reported", "user_saved", "weekly_proposal"].includes(e.provenance) || typeof e.updatedAt !== "string" || !Number.isFinite(Date.parse(e.updatedAt))) errors.push("Invalid or duplicate memory entry");
20
+ ids.add(e?.id);
21
+ }
22
+ return errors;
23
+ }
24
+ function resolveMemory(files, p) {
25
+ const entries = [["style", p.style], ["brand", p.brand], ["project", p.id]].flatMap(([scope, id]) => {
26
+ const path = memoryPath(scope, id);
27
+ if (!files[path]) return [];
28
+ return JSON.parse(files[path]).entries.map((e) => ({ ...e, scope, scopeId: id, path }));
29
+ });
30
+ return { confirmed: entries.filter((e) => e.status === "confirmed"), pending: entries.filter((e) => e.status === "suggested").map(({ id, scope, scopeId }) => ({ id, scope, scopeId })), policy: "Apply only relevant confirmed preferences. Conditions and prose conflicts require agent judgment. Project-specific guidance precedes brand then style; required tokens still govern. Suggestions are not instructions. Provenance is a claim, not proof of human confirmation." };
31
+ }
32
+
3
33
  // packages/core/src/index.ts
4
34
  var SCHEMA_VERSION = 1;
5
35
  var MAX_DOCUMENT_BYTES = 128 * 1024;
@@ -80,6 +110,7 @@ function validateDocument(path, content) {
80
110
  return { valid: false, issues };
81
111
  }
82
112
  if (doc.schemaVersion !== SCHEMA_VERSION) add("schemaVersion must be 1");
113
+ for (const message of memoryIssues(canonicalDocumentPath(path), doc)) add(message);
83
114
  const parts = canonicalDocumentPath(path).split("/");
84
115
  const isBrand = parts[0] === ".editorbrain" && parts[1] === "brands" && parts.length === 4;
85
116
  const isStyle = parts[0] === ".editorbrain" && parts[1] === "styles" && parts.length === 4;
@@ -154,7 +185,7 @@ function projectSources(project) {
154
185
  ];
155
186
  }
156
187
  function optionalProjectSources(project) {
157
- return [`.editorbrain/brands/${project.brand}/design.md`, `.editorbrain/styles/${project.style}/effects.md`, `.editorbrain/styles/${project.style}/music.md`, `videos/${project.id}/media.json`];
188
+ return [`.editorbrain/brands/${project.brand}/design.md`, `.editorbrain/styles/${project.style}/effects.md`, `.editorbrain/styles/${project.style}/music.md`, `videos/${project.id}/media.json`, memoryPath("brand", project.brand), memoryPath("style", project.style), memoryPath("project", project.id)];
158
189
  }
159
190
  function validateWorkspace(files) {
160
191
  files = canonicalFiles(files);
@@ -233,6 +264,7 @@ async function resolveProject(files, projectId) {
233
264
  brandAssets: JSON.parse(files[assetsPath]),
234
265
  examples: JSON.parse(files[examplesPath]),
235
266
  ...own(files, optionalPaths[3]) ? { media: JSON.parse(files[optionalPaths[3]]) } : {},
267
+ memory: resolveMemory(files, project),
236
268
  evidence: style.references ?? [],
237
269
  warnings,
238
270
  lock: { schemaVersion: 1, projectId, sourceHashes, overrides: project.overrides ?? {}, adapters: Object.fromEntries(["neutral", "hyperframes", "remotion"].map((key) => [key, { version: "0.2.1", kind: "editorial_handoff", rendered: false }])) }
@@ -327,7 +359,7 @@ Describe identity, audience, non-negotiables and preferred visual/audio treatmen
327
359
  ".editorbrain/memory/preferences.json": json({ confirmed: [], note: "Only explicitly confirmed feedback becomes a reusable preference. Keep scope and evidence." }),
328
360
  [`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: {} }),
329
361
  [`videos/${project}/brief.md`]: "# Brief\n\nDescribe the objective, audience, script or source video, constraints and available assets.\n",
330
- [`videos/${project}/direction.md`]: "# Direction\n\nDIRECTION_PENDING\n\nRead the installed EditorBrain skill and its AGENTS.md. Inspect the actual script, media, brand and selected evidence. 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"
362
+ [`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"
331
363
  };
332
364
  }
333
365
  function canonicalDocumentPath(path) {
@@ -777,7 +809,7 @@ import { createHash } from "node:crypto";
777
809
  import { constants as constants2 } from "node:fs";
778
810
  import { lstat as lstat2, open as open2, readdir as readdir2, rename as rename2 } from "node:fs/promises";
779
811
  import { fileURLToPath } from "node:url";
780
- var previousSkillHashes = { "SKILL.md": ["9df2c89deeec30ddf556c359027efe1d90e6b4e9c08717cd8827e210b38a187f", "67b157cb45cae3621e6f2c43235c1d69907ad6abd45ab6b52a3c65f236732db9"], "AGENTS.md": ["4f3ef860ade3a31aa7c6a6aab5cf6ec2a700850bf19ea2320324c12c2e0fbf5b", "1b07de01698a0040b47ea0eddb1b017f70a69e81acd0bf9710647ca5e02f5125"], "references/cli-mcp.md": ["5d3a79343fbd76cdae5bdbe12fb9c944d5dff4f489ac6534fd96e0cb8630b988", "8e011c31368cef2117a28ee972b39aab9535eeb0f601a4a0f9d6fc019b22c1c2", "666082653efc000f8a7cc5f1836c80bbdda5f0f57cdbbdcb393f2b84aeb93a01"], "references/production-and-review.md": ["055c6df9e0f167be148b0a5c0bba5b43e108eb1f58f478d88b3536c6589ac7b3"], "references/workspace-files.md": ["e72af2871f42cd776be1bfff8009ed5562780e7f8a65b12c27887f3880631f81", "00780c64bd0244c6afb18d786b7512b43e315c376e8f88c67d6ba53d91275ccf"] };
812
+ var previousSkillHashes = { "SKILL.md": ["9df2c89deeec30ddf556c359027efe1d90e6b4e9c08717cd8827e210b38a187f", "67b157cb45cae3621e6f2c43235c1d69907ad6abd45ab6b52a3c65f236732db9", "1e2fff65a1b303b18b2d65156bef6eb2439a19d77ba2a25b37bcb1819ff009e3", "dacce1c4127f4281df6f7e1681e243444bb6f8a8e74b829e52ee0108c6672348"], "AGENTS.md": ["4f3ef860ade3a31aa7c6a6aab5cf6ec2a700850bf19ea2320324c12c2e0fbf5b", "1b07de01698a0040b47ea0eddb1b017f70a69e81acd0bf9710647ca5e02f5125", "b5ee3439ff974c668755816149fab76899d7ad9266f63978b30fbc9b7d2cd640", "bacedb7bdedab5abe75c9601717cfdb05a96208fa2e2a42af878e2dfd2ae4251"], "references/cli-mcp.md": ["5d3a79343fbd76cdae5bdbe12fb9c944d5dff4f489ac6534fd96e0cb8630b988", "8e011c31368cef2117a28ee972b39aab9535eeb0f601a4a0f9d6fc019b22c1c2", "666082653efc000f8a7cc5f1836c80bbdda5f0f57cdbbdcb393f2b84aeb93a01", "78b737796a8685b1135e0acb91b620c51845b62e31dba04eb51dd9dd38b41008", "8b2e01bfd937237919f5ade794eed01dc6e32b556ede9de3a0ccc28cbdd988d1"], "references/production-and-review.md": ["055c6df9e0f167be148b0a5c0bba5b43e108eb1f58f478d88b3536c6589ac7b3"], "references/workspace-files.md": ["e72af2871f42cd776be1bfff8009ed5562780e7f8a65b12c27887f3880631f81", "00780c64bd0244c6afb18d786b7512b43e315c376e8f88c67d6ba53d91275ccf", "97053b092e0ff36e3cfb764095fcb4a4fca94e722567e774b53bc118279f40e5", "70fc660e7ed3d70c16c33c62c8e0399b99c3251808f093ef3d4ea5e8d39e4c8a"] };
781
813
  var destinations = {
782
814
  codex: { directory: ".agents/skills/editorbrain", entryPoint: "AGENTS.md" },
783
815
  claude: { directory: ".claude/skills/editorbrain", entryPoint: "CLAUDE.md" }
@@ -1361,8 +1393,20 @@ editorbrain pull [--project id | --all] [--dir folder] [--dry-run]
1361
1393
  editorbrain push [--dir folder] [--dry-run]
1362
1394
  editorbrain projects list
1363
1395
  editorbrain documents list [--prefix path]
1364
- editorbrain documents get <path>
1396
+ editorbrain documents get <path> [--revision N]
1397
+ editorbrain documents history <path> [--before N]
1398
+ editorbrain documents restore <path> --revision N --expected-revision N
1399
+ editorbrain memory list --scope brand|style|project --id ID
1400
+ editorbrain memory add --scope brand|style|project --id ID --text TEXT --status suggested|confirmed --expected-revision N
1401
+ editorbrain memory confirm|disable ENTRY --scope brand|style|project --id ID --expected-revision N
1402
+ editorbrain feedback add --project ID --text TEXT
1403
+ editorbrain improvements list --brand ID
1404
+ editorbrain improvements accept RUN --index N --expected-revision N
1405
+ editorbrain review list --project ID
1406
+ editorbrain review create --project ID --asset SHA --title TEXT --kind sample|render --days 7 --share-authorized
1407
+ editorbrain review revoke ID
1365
1408
  editorbrain workflow check [--project id] [--previous-version hash]
1409
+ editorbrain search brief --file <editorial-brief.json> [--project id] [--mode styles|events|both] [--review direct|directions|sample]
1366
1410
  editorbrain search edit [--script file | --video file | --asset sha256 | --project id] [--requirements text] [--assets tag,tag] [--mode styles|events|both] [--review direct|directions|sample]
1367
1411
  editorbrain library search [query]
1368
1412
  editorbrain library get <video-id> [--document relative-source-path] [--sha256 source-hash]
@@ -1390,8 +1434,8 @@ Output is JSON except help; login progress/code goes to stderr. --url overrides
1390
1434
  function parseArgs(argv) {
1391
1435
  const positional = [];
1392
1436
  const flags = {};
1393
- const booleans = /* @__PURE__ */ new Set(["help", "version", "offline", "dry-run", "key-stdin", "invite-stdin", "no-browser", "skip-mcp", "all"]);
1394
- 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", ...booleans]);
1437
+ const booleans = /* @__PURE__ */ new Set(["help", "version", "offline", "dry-run", "key-stdin", "invite-stdin", "no-browser", "skip-mcp", "all", "share-authorized"]);
1438
+ 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", "revision", "expected-revision", "before", "scope", "id", "text", "conditions", "status", "index", "title", "days", ...booleans]);
1395
1439
  for (let i = 0; i < argv.length; i++) {
1396
1440
  const arg = argv[i];
1397
1441
  if (!arg.startsWith("--")) {
@@ -1666,12 +1710,57 @@ async function main() {
1666
1710
  return;
1667
1711
  }
1668
1712
  if (subcommand === "get" && argument) {
1669
- const doc = await client.get(argument);
1713
+ const doc = await client.request(`/v1/documents/${argument.split("/").map(encodeURIComponent).join("/")}${str(args, "revision") ? "?revision=" + encodeURIComponent(str(args, "revision")) : ""}`);
1670
1714
  if (await sha256(doc.content) !== doc.sha256) throw new Error("Document integrity failed");
1671
1715
  output(doc);
1672
1716
  return;
1673
1717
  }
1674
- throw new Error("Use documents list --prefix path or documents get <path>.");
1718
+ if (subcommand === "history" && argument) {
1719
+ output(await client.request("/v1/history?" + new URLSearchParams({ path: argument, ...str(args, "before") ? { before: str(args, "before") } : {} })));
1720
+ return;
1721
+ }
1722
+ if (subcommand === "restore" && argument) {
1723
+ output(await client.request("/v1/history/restore", { method: "POST", body: { path: argument, revision: Number(str(args, "revision")), expectedRevision: Number(str(args, "expected-revision")) } }));
1724
+ return;
1725
+ }
1726
+ throw new Error("Use documents list/get/history/restore. Restore requires --revision and --expected-revision.");
1727
+ }
1728
+ if (command === "memory" || command === "feedback" || command === "review" || command === "improvements") {
1729
+ const client = new Client(await config(args));
1730
+ if (command === "memory" && subcommand === "list") {
1731
+ output(await client.request("/v1/memory?" + new URLSearchParams({ scope: str(args, "scope") ?? "brand", scopeId: str(args, "id") ?? "" })));
1732
+ return;
1733
+ }
1734
+ if (command === "memory" && ["add", "confirm", "disable"].includes(subcommand ?? "")) {
1735
+ output(await client.request("/v1/memory", { method: "POST", body: { scope: str(args, "scope") ?? "brand", scopeId: str(args, "id"), action: subcommand, entryId: argument, expectedRevision: Number(str(args, "expected-revision")), text: str(args, "text"), conditions: str(args, "conditions") ?? "", status: str(args, "status") ?? "suggested" } }));
1736
+ return;
1737
+ }
1738
+ if (command === "feedback" && subcommand === "add") {
1739
+ output(await client.request("/v1/feedback", { method: "POST", body: { projectId: str(args, "project"), text: str(args, "text") } }));
1740
+ return;
1741
+ }
1742
+ if (command === "improvements" && subcommand === "list") {
1743
+ output(await client.request("/v1/improvements?" + new URLSearchParams({ brandId: str(args, "brand") ?? "" })));
1744
+ return;
1745
+ }
1746
+ if (command === "improvements" && subcommand === "accept") {
1747
+ output(await client.request("/v1/improvements/accept", { method: "POST", body: { runId: argument, index: Number(str(args, "index")), expectedRevision: Number(str(args, "expected-revision")) } }));
1748
+ return;
1749
+ }
1750
+ if (command === "review" && subcommand === "list") {
1751
+ output(await client.request("/v1/reviews?" + new URLSearchParams({ projectId: str(args, "project") ?? "" })));
1752
+ return;
1753
+ }
1754
+ if (command === "review" && subcommand === "revoke" && argument) {
1755
+ output(await client.request("/v1/reviews/" + encodeURIComponent(argument), { method: "DELETE" }));
1756
+ return;
1757
+ }
1758
+ if (command === "review" && subcommand === "create") {
1759
+ if (!args.flags["share-authorized"]) throw new Error("Sharing requires explicit user authorization and --share-authorized. Anyone with the link can view.");
1760
+ output(await client.request("/v1/reviews", { method: "POST", body: { projectId: str(args, "project"), assetId: str(args, "asset"), title: str(args, "title"), kind: str(args, "kind") ?? "sample", days: Number(str(args, "days") ?? 7), shareAuthorized: true } }));
1761
+ return;
1762
+ }
1763
+ throw new Error("Use memory list/add/confirm/disable, feedback add, improvements list/accept, review list/create/revoke. See help for flags.");
1675
1764
  }
1676
1765
  if (command === "assets") {
1677
1766
  const client = new Client(await config(args));
@@ -1743,6 +1832,26 @@ async function main() {
1743
1832
  output(await client.request("/v1/workflow/check", { method: "POST", body: { projectId: str(args, "project"), previousVersion: str(args, "previous-version") } }));
1744
1833
  return;
1745
1834
  }
1835
+ if (command === "search" && subcommand === "brief") {
1836
+ const path = str(args, "file");
1837
+ if (!path) throw new Error("Provide --file with the editorial brief JSON after inspecting the actual material.");
1838
+ const handle = await open4(resolve4(path), constants4.O_RDONLY | constants4.O_NOFOLLOW);
1839
+ let brief;
1840
+ try {
1841
+ const stat = await handle.stat();
1842
+ 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.");
1843
+ brief = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await handle.readFile()));
1844
+ } finally {
1845
+ await handle.close();
1846
+ }
1847
+ if (!brief || typeof brief !== "object" || Array.isArray(brief)) throw new Error("Brief must be a JSON object. See the installed search-brief reference.");
1848
+ const mode = str(args, "mode") ?? "both", reviewMode = str(args, "review");
1849
+ if (!["styles", "events", "both"].includes(mode)) throw new Error("--mode must be styles, events or both.");
1850
+ if (reviewMode && !["direct", "directions", "sample"].includes(reviewMode)) throw new Error("--review must be direct, directions or sample.");
1851
+ const client = new Client(await config(args));
1852
+ output(await client.request("/v1/search/brief", { method: "POST", timeoutMs: 9e4, body: { brief, projectId: str(args, "project"), mode, reviewMode } }));
1853
+ return;
1854
+ }
1746
1855
  if (command === "search" && subcommand === "edit") {
1747
1856
  const client = new Client(await config(args));
1748
1857
  const scriptPath = str(args, "script"), videoPath = str(args, "video");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "editorbrain",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "EditorBrain editorial knowledge, portable workspaces and skills for AI video agents",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -25,7 +25,7 @@ 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
- - Start with `search_for_edit` / `editorbrain search edit`, supplying the actual script or owned video and the project ID for brand constraints. It analyzes new material before semantic retrieval and candidate review; inspect its uncertainty, source hashes, coverage and missing assets. Its model reading is not human verification. Legacy literal search and rule-based recommendations remain lookup tools, not equivalents to this content-first flow.
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
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.
30
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.
31
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.
@@ -73,6 +73,8 @@ Separate these levels:
73
73
  2. **Conditional technique requirements:** a matte follows its subject if used; synchronized text aligns if chosen; a functional UI has meaningful states if depicted.
74
74
  3. **Project/preset preferences:** particular colors, click patterns, monochrome treatment, density or source choices.
75
75
 
76
+ At workflow checkpoints, read `context.memory.confirmed` and its conditions; compare `context.contextVersion` before costly work. Refresh changed source documents without overwriting local changes. Suggestions are not applied preferences; prose memory never bypasses required tokens. Read [memory and review](references/memory-and-review.md) when saving feedback, accepting proposals, restoring history or sharing a specific artifact.
77
+
76
78
  Do not convert a single video's feedback into a global ban, fixed source quota or mandatory sound. Record feedback at its stated scope; ask only when that scope materially changes other work. Approval of one production does not prove transfer quality in every niche.
77
79
 
78
80
  Preserve previous versions and save the references used, adaptations, source plan, effective parameters, review results and user feedback with their project/version. Reuse existing formats; optional production notes may live under `videos/<project-id>/`. Do not invent mandatory files that the CLI cannot validate.
@@ -1,21 +1,25 @@
1
1
  ---
2
2
  name: editorbrain
3
- description: Use EditorBrain to edit a user's video, adapt an editorial style, find reference evidence, or manage brand and video project context through its CLI or MCP. Connect the project's actual footage, script and brand to editing decisions, then implement and review the result with the available editing tools. Also use when the user names EditorBrain, requests its library or asks to follow a saved preset.
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
- The public product is EditorBrain. The npm package is `editorbrain`; `editorbrain` is the CLI command. Skill name and portable folder paths use `editorbrain`. Web: https://editorbrain.com. API/MCP: https://api.editorbrain.com/mcp.
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
- Convert reference evidence into an appropriate edit for this project. Reading the library starts the work; quality is demonstrated in the delivered video.
10
+ ## Start here, including a first installation
11
11
 
12
- Before selecting a style, use `check_workflow` (CLI: `editorbrain workflow check`) and `search_for_edit` (CLI: `editorbrain search edit`) with the actual script or owned production video and project ID. Respect the returned review mode: direct editing, a choice of directions, or approval of a customer-material sample. Check the preference version again before costly generation and full rendering; a web change cannot interrupt a running tool. Honor current explicit user instructions and existing approval. If these tools are unavailable, report the version limitation and inspect material and evidence explicitly; literal search is not an equivalent quality ranking.
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 and confirmed scoped memory. Compare `contextVersion` at later checkpoints; fetch changed files before acting. 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.
13
20
 
14
- 1. Read the bundled [AGENTS.md](AGENTS.md) before using the workflow. It is this skill's editorial contract; do not assume your host auto-loads it.
15
- 2. Read [CLI and MCP](references/cli-mcp.md) when connecting, locating documents, retrieving reference media or saving work. Discover the installed CLI help and connected MCP tool schemas; they take precedence over examples for version-specific arguments.
16
- 3. Read [Workspace files](references/workspace-files.md) when configuring a brand/style, creating projects, resolving preferences, saving feedback or upgrading an installed skill.
17
- 4. Read [Production and review](references/production-and-review.md) when translating a style into scenes, generating assets, implementing motion/audio, or evaluating an edit.
21
+ For feedback, accepted memory, weekly proposals, document restore or explicitly requested sharing, read [memory and review](references/memory-and-review.md). Weekly suggestions never become instructions until accepted.
18
22
 
19
- Honor the user's requested scope. A consultation needs a supported answer; a direction request needs a usable plan; an editing request needs implementation and review, not just an exported JSON. Continue authorized work without requiring approval at every stage. If a needed tool or asset is unavailable, state the exact limitation and complete independent work.
23
+ 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.
20
24
 
21
- EditorBrain supplies brand context, styles and a curated evidence library. The agent uses the project's available editing/rendering tools to produce video. Neither a recommendation nor an export certifies a finished edit.
25
+ 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.7.0 customer workflow; older installations may lack the skill installer or reference-media tool. Do not invent commands from historical architecture documents.
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
 
@@ -134,35 +134,20 @@ Codex can use `codex mcp login editorbrain`; Claude Code completes OAuth from `/
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
135
 
136
136
 
137
- ## Content-first search and web preferences (0.8+)
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.
138
140
 
139
141
  ```sh
140
142
  editorbrain workflow check --project my-video
141
- editorbrain search edit --script ./script.txt --project my-video --mode both
142
- editorbrain search edit --video ./analysis-proxy.mp4 --project my-video
143
+ editorbrain search brief --file ./videos/my-video/plans/search-brief.json --project my-video
143
144
  editorbrain workflow check --project my-video --previous-version <returned-hash>
144
145
  ```
145
146
 
146
- MCP equivalents: `check_workflow` and `search_for_edit`. Use their current schemas.
147
- A topic alone is insufficient. A project may supply its saved script; passing a video
148
- uploads that selected production asset to the workspace, then sends it to the configured
149
- analysis provider. This is customer material, not a new library reference. No automatic
150
- scraping, FFmpeg installation, asset generation or rendering occurs.
151
-
152
- Video inputs currently accept MP4/MOV/WebM up to 12 MiB and 24,000 analysis input tokens.
153
- For a larger source, prepare a complete analysis proxy with the available media tools;
154
- keep the original and record duration/coverage. If using excerpts, disclose omitted
155
- content. Never treat coarse model timing as frame-accurate or inferred sound as verified.
156
- Scripts accept up to 16,000 characters. Search may take longer than a literal lookup.
157
-
158
- Results include source hashes, observed/inferred limitations, applicable evidence,
159
- missing resources, current workflow version and per-stage elapsed time/token usage.
160
- A null token count means the provider did not report it, not zero. Follow pinned
161
- source paths and retrieve needed example media; do not enumerate the entire library.
162
- If no fit exists, disclose the gap rather than fabricate a matching style. Source,
163
- reference access or preference changes during a search invalidate that result.
164
-
165
- Web preferences are pulled at checkpoints, not pushed into arbitrary agent chats.
166
- `check_workflow` records a receipt; it cannot stop a tool already running. After a
167
- version change, reconcile the next step and relevant approval with the current user
168
- instruction. Do not repeat approval just because an unrelated preference changed.
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.
150
+
151
+ ## Memory, history and review links (0.10+)
152
+
153
+ Read [memory and review](memory-and-review.md) when needed. CLI commands `memory`, `feedback`, `improvements`, `documents history/restore` and `review` map to the corresponding scoped MCP tools. Memory/restore mutations require current revisions. Sharing requires explicit authorization and a project-linked own asset.
@@ -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,91 @@
1
+ # Editorial memory, history and reviews
2
+
3
+ ## Read only the selected context
4
+
5
+ `check_workflow` / `editorbrain workflow check --project ID` returns `context.memory`,
6
+ `context.sourceHashes`, and `context.contextVersion`. The version is distinct from
7
+ workflow preference `version`. Compare both at the start and before proposals, paid
8
+ generation and final render. A changed context requires rereading affected documents;
9
+ it does not justify overwriting local work. Offline edits cannot see new web changes.
10
+ `resolve` and `search_from_brief` also include scoped memory.
11
+
12
+ Optional portable memory paths:
13
+ - Brand: `.editorbrain/brands/<id>/preferences.json`
14
+ - Style: `.editorbrain/styles/<id>/preferences.json`
15
+ - Project: `videos/<id>/preferences.json`
16
+
17
+ Each contains `schemaVersion:1`, matching `scope` (`brand`, `style`, `project`),
18
+ `scopeId` and up to 60 `entries`. Each entry has `id`, `text`, `conditions`, `status`
19
+ (`suggested`, `confirmed`, `disabled`), `source`, `provenance` and `updatedAt`.
20
+ The API validates these and provides IDs and timestamps. Prefer its memory tools.
21
+ Confirmed entries guide choices only when their conditions fit. Project guidance
22
+ precedes brand then style; exact required tokens still govern. Resolve prose conflicts
23
+ using the actual user request. `provenance` records a claim, not proof of human approval.
24
+ Suggestions and disabled entries are not editing instructions.
25
+
26
+ Legacy `.editorbrain/memory/preferences.json` is preserved and not resolved. If relevant,
27
+ inspect it and migrate only clearly scoped, confirmed preferences with the user's intent;
28
+ do not silently apply old unscoped notes to all brands.
29
+
30
+ ## Save feedback without inventing approval
31
+
32
+ `save_editorial_feedback({projectId,text})` / `editorbrain feedback add --project ID --text TEXT`
33
+ saves an observation, not a reusable rule. The server derives the brand from the project.
34
+ Identical notes for one project/day are deduplicated. Maximum 500 notes/workspace/7 days.
35
+ Keep actual customer feedback distinct from your own QA and identify it in the text.
36
+ Do not manufacture feedback to activate a weekly analysis.
37
+
38
+ Read `get_editorial_memory({scope,scopeId})` / `editorbrain memory list --scope brand --id ID`
39
+ for the current document revision. `save_editorial_memory` supports:
40
+ - `action:add`, `text`, optional `conditions`, explicit `status:suggested|confirmed`.
41
+ - `action:confirm|disable`, `entryId`.
42
+ All changes require `scope`, `scopeId`, `expectedRevision` (0 creates).
43
+ CLI equivalents: `memory add --text TEXT --conditions TEXT --status suggested --expected-revision N`
44
+ or `memory confirm|disable ENTRY --expected-revision N`, plus scope/id.
45
+ Use confirmed only for a preference supported by the user's instruction. If uncertain
46
+ about cross-project scope, save a suggestion rather than generalizing one correction.
47
+
48
+ ## Weekly proposals
49
+
50
+ The owner enables analysis per brand in the web app, with explicit consent to send
51
+ saved feedback and confirmed brand preferences to Google Gemini. Videos are not sent.
52
+ The analysis considers at most 50 notes from the last seven days; reports expose coverage,
53
+ supporting feedback and usage. No fine-tuning, cross-customer learning or automatic editing.
54
+ Manual review is limited to once per day; scheduled reviews run weekly. Fewer than two
55
+ notes returns insufficient data. Two notes are not proof a preference generalizes.
56
+
57
+ Use `get_improvement_reviews({brandId})` / `improvements list --brand ID` only when relevant.
58
+ `accept_improvement({runId,index,expectedRevision})` / `improvements accept RUN --index N --expected-revision N`
59
+ requires user acceptance of that suggestion. Changed brand memory invalidates an old
60
+ review; do not bypass that conflict or silently apply it elsewhere. Acceptance changes
61
+ future context, not already rendered videos. Disabling weekly analysis stops future calls,
62
+ not a provider request already in flight. It does not erase past proposals.
63
+
64
+ ## Document history
65
+
66
+ `list_document_versions({path,before?})` / `documents history PATH [--before N]` returns
67
+ 50 revisions and a cursor. Read an old version with `read_document({path,revision})` /
68
+ `documents get PATH --revision N`. Compare it with current content before restoring.
69
+ `restore_document_version({path,revision,expectedRevision})` / `documents restore PATH --revision N --expected-revision N`
70
+ creates a NEW revision containing that historical content; nothing is deleted.
71
+ After restoring remotely, refresh local files with conflict-aware pull.
72
+ History covers synced documents, not arbitrary local files or complete video timelines.
73
+
74
+ ## Share only a specifically authorized artifact
75
+
76
+ Use own uploaded production media already linked in `videos/<project>/media.json`.
77
+ Do not republish library reference footage. PNG/JPEG/WebP and MP4/WebM are supported.
78
+ `create_review_link({projectId,assetId,title,kind:'sample'|'render',days:1..30,shareAuthorized:true,context?})`
79
+ creates a bearer link: anyone possessing it can view the exact asset. CLI:
80
+ `review create --project ID --asset SHA --title TEXT --kind sample --days 7 --share-authorized`.
81
+ Creation does not email or message anyone. Ask only if authorization to share is missing.
82
+ Do not store the secret URL in portable files, logs or source control. Return it only
83
+ to the user requesting it. It is returned once; list endpoints never reveal tokens.
84
+
85
+ Optional `context` maps document paths to `{revision,sha256}` verified by the server.
86
+ These pins are an agent declaration, not proof that the render used that configuration.
87
+ Without pins, the server labels context not recorded. The asset hash always fixes the file.
88
+ Up to 100 active links per workspace. Read with `list_review_links({projectId})` /
89
+ `review list --project ID`; revoke with `revoke_review_link({id})` / `review revoke ID`.
90
+ Expiry/revocation prevents subsequent access; it cannot recall an already downloaded copy.
91
+ The viewer does not certify quality or provide timestamp comments/approval in this version.
@@ -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.
@@ -18,29 +18,33 @@ CLAUDE.md Claude Code entry point (existing instructions
18
18
  tokens.json Exact color/font/other named values and strengths
19
19
  language.json Language, glossary, pronunciations
20
20
  assets.json Brand asset declarations
21
+ preferences.json Optional scoped editorial memory
21
22
  styles/<style-id>/
22
23
  style.md Editorial method and intended effect
23
24
  style.json Style tokens, reference IDs, component status
24
25
  effects.md Motion and effect guidance (optional)
25
26
  music.md Music, voice and sound guidance (optional)
26
27
  examples.json Saved reference examples
28
+ preferences.json Optional scoped editorial memory
27
29
  output-profiles/<profile-id>.json Dimensions, fps, captions, safe areas
28
30
  library/index.json Local reference index, not the entire remote library
29
- memory/preferences.json Confirmed feedback with its intended scope
31
+ memory/preferences.json Legacy notes, preserved; not auto-applied
30
32
  videos/<project-id>/
31
33
  project.json Brand/style/profile IDs, intent, script, overrides
32
34
  brief.md Goal, audience, constraints, material
33
35
  direction.md Decisions for this specific edit
34
36
  media.json Production asset metadata (optional)
37
+ preferences.json Optional project-specific memory
35
38
  assets/ Local production media
36
39
  plans/ Local plans and implementation notes
40
+ search-brief.json Agent analysis for retrieval (local, not auto-synced)
37
41
  renders/ Rendered files
38
42
  reviews/ Reviews tied to a particular delivered version
39
43
  ```
40
44
 
41
45
  The native skill folders are local instructions, not portable documents synchronized by `push`. Local media/render folders are not media uploads. `.editorbrain/.sync.json` is CLI-managed sync state; do not edit it to bypass conflicts. An older valid workspace may omit the optional files and local production directories.
42
46
 
43
- The resolver requires the selected brand's `brand.md`, `tokens.json`, `language.json`, `assets.json`; the selected style's `style.md`, `style.json`, `examples.json`; the selected output profile; and the project's `project.json`, `brief.md`, `direction.md`. Preserve them even when a declaration is empty. Additional guidance such as `adaptation-rules.json`, library indexes or memory may be present: read it explicitly when relevant. It is not automatically included in `resolve` merely because it exists.
47
+ The resolver requires the selected brand's `brand.md`, `tokens.json`, `language.json`, `assets.json`; the selected style's `style.md`, `style.json`, `examples.json`; the selected output profile; and the project's `project.json`, `brief.md`, `direction.md`. Preserve them even when a declaration is empty. Scoped `preferences.json` files are optional resolver inputs with pinned hashes; only confirmed entries are returned as active memory. Additional guidance such as `adaptation-rules.json`, library indexes or legacy memory may be present: read it explicitly when relevant. It is not automatically included in `resolve` merely because it exists.
44
48
 
45
49
  ## Brand, style and project exceptions
46
50
 
@@ -89,3 +93,5 @@ explicit user instruction takes precedence. Read the effective value with
89
93
  `check_workflow` / `editorbrain workflow check`; local files alone cannot reveal a
90
94
  new web preference. Store received versions and scoped approvals in `direction.md`.
91
95
  Brand colors/fonts and editing effects/music remain in their existing files.
96
+
97
+ See [memory and review](memory-and-review.md) for memory schemas, version restoration, saved feedback and sharing. Legacy unscoped notes are preserved but are not silently assigned to every brand.