scenri 0.3.2 → 0.3.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.4](https://github.com/tonygorb/Scenri/compare/v0.3.3...v0.3.4) (2026-08-20)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * presenter references are identity, not wardrobe ([dc372fd](https://github.com/tonygorb/Scenri/commit/dc372fd40d7e15d7d8dc72b5ec8f41993e078ae9))
9
+ * presenter references are identity, not wardrobe ([c8bca43](https://github.com/tonygorb/Scenri/commit/c8bca431730a2d4c41d2783fb6eba2c564af5141))
10
+ * stop custom presenter and scene pages freezing the whole app ([fcf88dd](https://github.com/tonygorb/Scenri/commit/fcf88ddbcd57d01354c833cf9f8456fa1b0b0434))
11
+ * stop custom presenter and scene pages freezing the whole app ([8595078](https://github.com/tonygorb/Scenri/commit/859507893892cb23a7ff2f132f273db4dbd0a0f9))
12
+
13
+ ## [0.3.3](https://github.com/tonygorb/Scenri/compare/v0.3.2...v0.3.3) (2026-08-20)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * absolute README links so they survive the npm package page ([c8b2cd0](https://github.com/tonygorb/Scenri/commit/c8b2cd04e6f4a2e6be9e7470b970c2d5033d60d4))
19
+ * absolute README links so they survive the npm package page ([16219cf](https://github.com/tonygorb/Scenri/commit/16219cf848279f58ab2d1e0db46e5f3efffeb388))
20
+
3
21
  ## [0.3.2](https://github.com/tonygorb/scenri/compare/v0.3.1...v0.3.2) (2026-08-20)
4
22
 
5
23
 
package/README.md CHANGED
@@ -11,7 +11,7 @@ Define a client's brand once. Then generate, branch, and art-direct on-brand ima
11
11
 
12
12
  [![CI](https://github.com/tonygorb/scenri/actions/workflows/ci.yml/badge.svg)](https://github.com/tonygorb/scenri/actions/workflows/ci.yml)
13
13
  [![npm](https://img.shields.io/npm/v/scenri)](https://www.npmjs.com/package/scenri)
14
- [![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)
14
+ [![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-blue)](https://github.com/tonygorb/scenri/blob/main/LICENSE)
15
15
 
16
16
  **Get started:** one command, no account.
17
17
 
@@ -19,7 +19,7 @@ Define a client's brand once. Then generate, branch, and art-direct on-brand ima
19
19
  npx scenri
20
20
  ```
21
21
 
22
- <sub>Needs [Node.js](https://nodejs.org) 22 or newer. New to any of this? The [install guide](docs/INSTALL.md) walks through every step.</sub>
22
+ <sub>Needs [Node.js](https://nodejs.org) 22 or newer. New to any of this? The [install guide](https://github.com/tonygorb/scenri/blob/main/docs/INSTALL.md) walks through every step.</sub>
23
23
 
24
24
  <img src="https://raw.githubusercontent.com/tonygorb/scenri/main/docs/media/demo.gif" alt="The Scenri composer: a dollar sign opens a product picker and Selvedge Trucker is chosen, an at sign picks the presenter Maren, a slash picks the Editorial Walk scene, a line of written direction is typed after the three chips, the shot renders as a card in the wall, and it opens to show the picture beside the brief that made it" width="820">
25
25
 
@@ -57,7 +57,7 @@ The brand kit sits one gesture away in Settings and is the part that keeps outpu
57
57
 
58
58
  ## Run it
59
59
 
60
- Scenri runs on [Node.js](https://nodejs.org), version 22 or newer. If you are not sure you have it, or terminals are not part of your day, the **[install guide](docs/INSTALL.md)** covers every step for macOS, Windows and Linux. With Node in place:
60
+ Scenri runs on [Node.js](https://nodejs.org), version 22 or newer. If you are not sure you have it, or terminals are not part of your day, the **[install guide](https://github.com/tonygorb/scenri/blob/main/docs/INSTALL.md)** covers every step for macOS, Windows and Linux. With Node in place:
61
61
 
62
62
  ```bash
63
63
  npx scenri
@@ -67,7 +67,7 @@ That is the whole install. npm asks once whether to proceed, downloads the curre
67
67
 
68
68
  Generation runs on **Codex CLI**, an official helper from OpenAI that draws on your own ChatGPT plan. No API key to paste, and Scenri never charges you. Each image draws on your plan's Codex usage. You do not have to set it up by hand: if it is missing, Scenri offers to install it and to sign you in, both from the app. No ChatGPT plan? Add your own key from an image provider in Settings instead, see [Engines](#engines).
69
69
 
70
- Two dependencies (`better-sqlite3` and `sharp`) ship native binaries, so on recent npm you may be asked to approve their install scripts once. Something not starting? See [troubleshooting](docs/INSTALL.md#troubleshooting).
70
+ Two dependencies (`better-sqlite3` and `sharp`) ship native binaries, so on recent npm you may be asked to approve their install scripts once. Something not starting? See [troubleshooting](https://github.com/tonygorb/scenri/blob/main/docs/INSTALL.md#troubleshooting).
71
71
 
72
72
  <details>
73
73
  <summary>Run from source</summary>
@@ -95,7 +95,7 @@ pnpm dev # starts the server on 127.0.0.1:4747
95
95
  - **Iteration is the product.** A version tree, not a prompt box. Branch, compare, keep the winners.
96
96
  - **Your brands are files, not hostages.** `.brand` is an open, documented format under a permissive license. Email one to a client. Any tool can adopt it.
97
97
  - **Your AI, your cost.** Bring your own Codex CLI session or an API key. Experiments cost raw API price, or nothing at all on a local session. No credits that burn on a miss.
98
- - **Local first, and it means it.** No account, no telemetry, no upload. The server binds to your machine only. Scenri makes exactly two requests on its own behalf: a daily version-number check against npm so updates can announce themselves, and a one-time download of the library imagery archive, cached locally forever after. Nothing about you or your work is ever sent, and both turn off: in Settings or `SCENRI_NO_UPDATE_CHECK=1` for the first, `SCENRI_NO_CONTENT_FETCH=1` for the second ([how updates work](docs/updates.md)).
98
+ - **Local first, and it means it.** No account, no telemetry, no upload. The server binds to your machine only. Scenri makes exactly two requests on its own behalf: a daily version-number check against npm so updates can announce themselves, and a one-time download of the library imagery archive, cached locally forever after. Nothing about you or your work is ever sent, and both turn off: in Settings or `SCENRI_NO_UPDATE_CHECK=1` for the first, `SCENRI_NO_CONTENT_FETCH=1` for the second ([how updates work](https://github.com/tonygorb/scenri/blob/main/docs/updates.md)).
99
99
 
100
100
  ## Engines
101
101
 
@@ -148,23 +148,23 @@ One package publishes to npm: **`scenri`**, the CLI, which bundles everything el
148
148
 
149
149
  ## Contributing
150
150
 
151
- Start with [CONTRIBUTING.md](CONTRIBUTING.md). Engine adapters are the friendliest surface: one file, one interface, well covered by tests.
151
+ Start with [CONTRIBUTING.md](https://github.com/tonygorb/scenri/blob/main/CONTRIBUTING.md). Engine adapters are the friendliest surface: one file, one interface, well covered by tests.
152
152
 
153
- Accessibility is tracked in [docs/A11Y-BACKLOG.md](docs/A11Y-BACKLOG.md). Every Biome a11y rule runs at `error`, so the backlog is currently empty and a new defect fails CI rather than joining a list.
153
+ Accessibility is tracked in [docs/A11Y-BACKLOG.md](https://github.com/tonygorb/scenri/blob/main/docs/A11Y-BACKLOG.md). Every Biome a11y rule runs at `error`, so the backlog is currently empty and a new defect fails CI rather than joining a list.
154
154
 
155
- Found a security problem? Please report it privately. See [SECURITY.md](SECURITY.md).
155
+ Found a security problem? Please report it privately. See [SECURITY.md](https://github.com/tonygorb/scenri/blob/main/SECURITY.md).
156
156
 
157
157
  ## Status
158
158
 
159
- Early. The version is `0.x` and interfaces can still move. Everything documented above works today. [ROADMAP.md](ROADMAP.md) says what is next.
159
+ Early. The version is `0.x` and interfaces can still move. Everything documented above works today. [ROADMAP.md](https://github.com/tonygorb/scenri/blob/main/ROADMAP.md) says what is next.
160
160
 
161
161
  ## License
162
162
 
163
- The application is [AGPL-3.0-only](LICENSE). The `.brand` format, its schema, and its validator live in [packages/brand-spec](https://github.com/tonygorb/scenri/tree/main/packages/brand-spec) under Apache-2.0, so any tool may implement or reuse them without taking on copyleft; the npm package carries that license text as `LICENSE-APACHE-2.0-brand-spec`. Contributions require a [CLA](CLA.md).
163
+ The application is [AGPL-3.0-only](https://github.com/tonygorb/scenri/blob/main/LICENSE). The `.brand` format, its schema, and its validator live in [packages/brand-spec](https://github.com/tonygorb/scenri/tree/main/packages/brand-spec) under Apache-2.0, so any tool may implement or reuse them without taking on copyleft; the npm package carries that license text as `LICENSE-APACHE-2.0-brand-spec`. Contributions require a [CLA](https://github.com/tonygorb/scenri/blob/main/CLA.md).
164
164
 
165
- The bundled imagery and curated content are licensed separately under [ASSETS-LICENSE.md](docs/ASSETS-LICENSE.md): free to use within Scenri, commercial work included; no redistribution or rebundling. The npm package's `license` field describes the code; the starter imagery inside it stays under those asset terms.
165
+ The bundled imagery and curated content are licensed separately under [ASSETS-LICENSE.md](https://github.com/tonygorb/scenri/blob/main/docs/ASSETS-LICENSE.md): free to use within Scenri, commercial work included; no redistribution or rebundling. The npm package's `license` field describes the code; the starter imagery inside it stays under those asset terms.
166
166
 
167
- The name and the mark are not part of the code license: [TRADEMARKS.md](TRADEMARKS.md) says what a fork may and may not call itself. What the app does and does not send anywhere is written down in [PRIVACY.md](PRIVACY.md).
167
+ The name and the mark are not part of the code license: [TRADEMARKS.md](https://github.com/tonygorb/scenri/blob/main/TRADEMARKS.md) says what a fork may and may not call itself. What the app does and does not send anywhere is written down in [PRIVACY.md](https://github.com/tonygorb/scenri/blob/main/PRIVACY.md).
168
168
 
169
169
  ---
170
170
 
package/dist/serve.js CHANGED
@@ -1271,7 +1271,7 @@ function createCatalogStore(db) {
1271
1271
  // ../core/src/engine.ts
1272
1272
  var REFERENCE_ROLE_DIRECTIVE = {
1273
1273
  product: "the exact product \u2014 preserve its label, shape, colors and design faithfully; do not redesign it",
1274
- character: "the exact person \u2014 preserve their face, hair and build faithfully; do not restyle them",
1274
+ character: "the exact person \u2014 match their face, facial structure, skin, hair and build exactly; their clothing, pose and background are capture context, not styling to reproduce",
1275
1275
  brand: "the brand's own mark \u2014 if the direction calls for the mark to appear, reproduce it exactly as drawn, same colours, letterforms and proportions; otherwise take only its colour and treatment, and never its subject, geometry or composition",
1276
1276
  scene: "a reference for the environment and light only \u2014 take no subject, product or person from it",
1277
1277
  composition: "a reference for framing, camera angle and pose only \u2014 take no subject, color, material or branding from it",
@@ -1280,7 +1280,7 @@ var REFERENCE_ROLE_DIRECTIVE = {
1280
1280
  };
1281
1281
  var EDIT_REFERENCE_ROLE_DIRECTIVE = {
1282
1282
  product: "the exact product: keep or restore its label, shape and design faithfully",
1283
- character: "the exact person: keep their face, hair and build faithfully",
1283
+ character: "the exact person: keep their face, facial structure, skin, hair and build faithfully; take no clothing, pose or background from this reference, and keep the source image's existing outfit unless the instruction changes it",
1284
1284
  brand: "the brand's own mark: reproduce it exactly as drawn wherever it appears, never redrawn or re-lettered",
1285
1285
  scene: "a reference for environment and light only",
1286
1286
  composition: "a reference for framing and pose only",
@@ -1944,6 +1944,9 @@ function createRunner(opts = {}) {
1944
1944
  });
1945
1945
  }
1946
1946
  async function probe() {
1947
+ if (process.env.SCENRI_NO_CODEX === "1") {
1948
+ return { ok: false, reason: NOT_INSTALLED_REASON, code: "not-installed" };
1949
+ }
1947
1950
  if (!await exitedZero(["--version"])) {
1948
1951
  return { ok: false, reason: NOT_INSTALLED_REASON, code: "not-installed" };
1949
1952
  }
@@ -2487,7 +2490,14 @@ async function resolvePresenterImages(core, templatesRoot, presenter) {
2487
2490
  const hash = core.images.save(png);
2488
2491
  shots.push({ file: `asset:${hash}`, angle, locked: true });
2489
2492
  }
2490
- return shots.length ? { id: presenter.id, name: presenter.name, shots } : null;
2493
+ if (!shots.length) return null;
2494
+ return {
2495
+ id: presenter.id,
2496
+ name: presenter.name,
2497
+ ...presenter.identityNotes ? { identityNotes: presenter.identityNotes } : {},
2498
+ ...presenter.negativeConstraints?.length ? { negativeConstraints: presenter.negativeConstraints } : {},
2499
+ shots
2500
+ };
2491
2501
  }
2492
2502
  async function brandJsonWithResolvedPresenters(core, templatesRoot, presenters, brandJson, tokens) {
2493
2503
  const existing = brandJson?.characters ?? [];
@@ -2793,7 +2803,7 @@ function compileBrief(brief, ctx) {
2793
2803
  attachments.push({ role: "character", id: c.id, label: c.name, hash: chash, essential: i === 0 });
2794
2804
  });
2795
2805
  personDirectives.push(
2796
- "The attached person reference is the same person every time: hold their face, hair and build, and do not restyle them."
2806
+ "The attached person reference is the same person every time: match their face, facial structure, skin, hair and build exactly. Their outfit, pose, background and lighting are neutral studio capture conditions, not styling direction: dress and style them for this shot, to a commercial standard, following any wardrobe the direction itself specifies."
2797
2807
  );
2798
2808
  if (c.identityNotes) personDirectives.push(String(c.identityNotes));
2799
2809
  if (c.negativeConstraints?.length)
@@ -2891,10 +2901,14 @@ function compileBrief(brief, ctx) {
2891
2901
  const sceneCamera = inlineTemplates[0]?.camera?.trim() || ctx.template?.camera?.trim() || "";
2892
2902
  const cameraDirectives = sceneCamera && !shotSpecifiesCamera(sentence) ? [`Camera for this shot: ${sceneCamera}`] : [];
2893
2903
  const guard = scene ? sceneGuardDirectives({ hasProduct: !!productId, hasPerson }) : [];
2904
+ const pairDirectives = productId && hasPerson ? [
2905
+ "If the attached product is something a person wears, the presenter wears that exact product, with the rest of the outfit styled around it; otherwise the presenter presents or uses the product naturally."
2906
+ ] : [];
2894
2907
  const brandLines = brandRuleDirectives(ctx.brand);
2895
2908
  const allDirectives = [
2896
2909
  ...productDirectives,
2897
2910
  ...personDirectives,
2911
+ ...pairDirectives,
2898
2912
  ...otherDirectives,
2899
2913
  ...cameraDirectives,
2900
2914
  ...brandLines,
@@ -6524,6 +6538,27 @@ function registerImageRoutes(app, deps) {
6524
6538
 
6525
6539
  // src/release/notes.data.ts
6526
6540
  var RELEASES = [
6541
+ {
6542
+ version: "0.3.4",
6543
+ date: "2026-08-21",
6544
+ sections: [
6545
+ {
6546
+ heading: "Presenters",
6547
+ body: "A presenter's reference photos now define who they are, not what they wear. The neutral studio outfit from their reference set no longer follows them into finished shots; wardrobe comes from the shot, the product and the scene instead, and refining an image keeps the outfit it already has."
6548
+ },
6549
+ {
6550
+ heading: "Fixes",
6551
+ body: "Opening a presenter or scene you built yourself no longer freezes the app."
6552
+ }
6553
+ ]
6554
+ },
6555
+ {
6556
+ version: "0.3.3",
6557
+ date: "2026-08-20",
6558
+ // Documentation only: the links on the npm package page were resolving
6559
+ // against the package folder and 404ing. Nothing inside the app changed.
6560
+ sections: []
6561
+ },
6527
6562
  {
6528
6563
  version: "0.3.2",
6529
6564
  date: "2026-08-20",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scenri",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "author": "Tony Gorb <hello@scenri.co>",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",