@gentbajko/slopify 3.18.0 → 3.18.2

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.
@@ -0,0 +1,11 @@
1
+ # Slopify 3.18.1
2
+
3
+ Released 11 October 2026.
4
+
5
+ - **Your images are kept with your video.** Every image the video shows now sits in the project's `Upload/Images/` folder, in order, and each short's images sit beside that short in `Upload/Shorts/<n> - <title>/`. An older version's images go to `Upload/Images/Earlier/<date>/` instead of `History/`. They used to be under `Working/` and `History/`.
6
+ - **Cleanup no longer deletes images.** **Keep outputs only**, **Free space**, **Delete old versions** and **Clean up everything** keep every image the video and shorts used, from every version. Before, they deleted them as working files, and making them again never gives the same pictures.
7
+
8
+ ## Upgrading from 3.18.0
9
+
10
+ - On the first start, finished projects move their images from `Working/` and `History/` into `Upload/` by themselves. Nothing is copied, so this takes no extra space.
11
+ - Images an earlier cleanup already deleted can't be brought back by this update. A backup made before the cleanup still has them; otherwise remaking the images makes new ones.
@@ -0,0 +1,10 @@
1
+ # Slopify 3.18.2
2
+
3
+ Released 11 October 2026.
4
+
5
+ - **Each image is named by its scene.** In a project's Images, every image is titled by its own scene, for example "Explorers scramble along a rock shelf above a fossil sea…", instead of the prompt's opening, which was the same on every image.
6
+ - **The full-size view says the prompt once.** The scene is on the top bar and the whole prompt is under the picture, instead of the whole prompt in both places.
7
+
8
+ ## Upgrading from 3.18.1
9
+
10
+ - Nothing becomes outdated; existing images get their titles at once.
@@ -1,4 +1,16 @@
1
1
  [
2
+ {
3
+ "id": "3.18.2",
4
+ "title": "Slopify 3.18.2",
5
+ "version": "3.18.2",
6
+ "date": "2026-10-11"
7
+ },
8
+ {
9
+ "id": "3.18.1",
10
+ "title": "Slopify 3.18.1",
11
+ "version": "3.18.1",
12
+ "date": "2026-10-11"
13
+ },
2
14
  {
3
15
  "id": "3.18.0",
4
16
  "title": "Slopify 3.18.0",
@@ -5,7 +5,13 @@ import { backupsFolderName, projectDir, renderCacheFolder } from "./layout.js";
5
5
  // The file in each project folder that says which project it is, for when the database and
6
6
  // the folders disagree (a restored database, a folder renamed by hand). Reconcile keeps it.
7
7
  export const projectMarker = ".slopify-project";
8
- // What makes a project's arrangement current: its title, head version and files. A project
8
+ // The pictures a video or short shows. Every version's stay in Upload, an older version's under
9
+ // Images/Earlier/<date>/, never in History: making them again never gives the same ones.
10
+ const imageRoles = new Set(["image", "animated_image", "short_image"]);
11
+ // Raised when a role's place changes, so every project arranged by the older places is moved
12
+ // once: 2 put every version's images the video and shorts show into Upload (3.18.1).
13
+ const layoutVersion = 2;
14
+ // What makes a project's arrangement current: the layout, its title, head version and files. A project
9
15
  // whose key is unchanged since it was last arranged is left alone.
10
16
  export function arrangeKeys(db) {
11
17
  const keys = new Map();
@@ -16,7 +22,10 @@ export function arrangeKeys(db) {
16
22
  (SELECT count(*)||':'||COALESCE(max(r.id),'') FROM revision_outputs r WHERE r.project_id=p.id AND r.selected=1 AND r.revision_id=h.revision_id) AS current
17
23
  FROM projects p LEFT JOIN project_heads h ON h.project_id=p.id`)
18
24
  .all())
19
- keys.set(String(row.id), [row.title, row.revision_id, row.assets, row.legacy, row.current].map(String).join("|"));
25
+ keys.set(String(row.id), [
26
+ `layout ${layoutVersion}`,
27
+ ...[row.title, row.revision_id, row.assets, row.legacy, row.current].map(String),
28
+ ].join("|"));
20
29
  return keys;
21
30
  }
22
31
  // Whether anything of the project runs or may start: its files stay where they are until then.
@@ -241,7 +250,9 @@ export function desiredPlaces(db, projectId) {
241
250
  const place = placeFor(reference, order, titles);
242
251
  out.set(reference.path, reference.current
243
252
  ? place
244
- : `History/${day(reference.createdAt)}/${place.replace(/^Upload\//u, "")}`);
253
+ : imageRoles.has(reference.role)
254
+ ? `Upload/Images/Earlier/${day(reference.createdAt)}/${place.replace(/^Upload\/(?:Images\/)?/u, "")}`
255
+ : `History/${day(reference.createdAt)}/${place.replace(/^Upload\//u, "")}`);
245
256
  }
246
257
  return out;
247
258
  }
@@ -286,14 +297,16 @@ function placeFor(reference, order, titles) {
286
297
  const key = /^image:(.+)$/u.exec(slot)?.[1];
287
298
  const at = key === undefined ? undefined : order.get(key);
288
299
  return at === undefined
289
- ? `Working/Images/${file}`
290
- : `Working/Images/${pad(at + 1)}${extension}`;
300
+ ? `Upload/Images/${file}`
301
+ : `Upload/Images/${pad(at + 1)}${extension}`;
291
302
  }
292
303
  case "short_image": {
293
304
  const match = /^shorts:([0-9]+):image:([0-9]+)$/u.exec(slot);
294
- return match === null
295
- ? `Working/Shorts/${file}`
296
- : `Working/Shorts/Short ${match[1]}/image ${match[2]}${extension}`;
305
+ if (match === null)
306
+ return `Upload/Shorts/Images/${file}`;
307
+ // Beside the short's video, in a folder named like it: Shorts/3 - Title/image 1.png.
308
+ const title = titles.get(Number(match[1]));
309
+ return `Upload/Shorts/${match[1]}${title === undefined || title === "" ? "" : ` - ${clean(title)}`}/image ${match[2]}${extension}`;
297
310
  }
298
311
  case "figure_card":
299
312
  return `Working/Cards/${file}`;
@@ -5,8 +5,9 @@ import { liveProject, projectExists, projectPaused, stagesOf } from "../admissio
5
5
  import { projectSettled } from "./arrange.js";
6
6
  import { backupsFolderName, outputPath, projectDir } from "./layout.js";
7
7
  import { pieceFile } from "./reconcile.js";
8
- // Keep outputs only: a finished project drops the working files it was made from (images,
9
- // narration parts, subtitle timing, render settings) and keeps what gets published. Two
8
+ // Keep outputs only: a finished project drops the working files it was made from (narration
9
+ // parts, subtitle timing, render settings) and keeps what gets published, the images the
10
+ // video and shorts show included: making them again costs money and never gives the same ones. Two
10
11
  // rules keep it safe. A file the user supplied is never removed, because nothing could make
11
12
  // it again. And only files a project record names are removed: anything else in the folder
12
13
  // is reconcile's business (`reconcile.ts`), which leaves the Backups folder alone.
@@ -28,6 +29,9 @@ export const outputRoles = [
28
29
  "audio_export",
29
30
  "subtitles_srt",
30
31
  "subtitles_vtt",
32
+ "image",
33
+ "animated_image",
34
+ "short_image",
31
35
  ];
32
36
  export function projectStorage(deps, projectId) {
33
37
  const files = filesOf(deps.paths, projectId);
@@ -197,7 +197,7 @@ Only generated steps can have a checkpoint. Pausing the project still applies on
197
197
 
198
198
  ## Free space
199
199
 
200
- A finished project can drop the working files it was made from (images, narration parts, subtitle timing, render settings) and keep what gets published: the video, shorts, thumbnail, article, description, document and anything you uploaded. In the right rail, **Free space** shows the size of both, for example "Outputs 1.4 GB · working files 1.2 GB", with the button **Free 1.2 GB: keep the outputs, drop the working files**.
200
+ A finished project can drop the working files it was made from (narration parts, subtitle timing, render settings) and keep what gets published: the video, shorts, the images they show, thumbnail, article, description, document and anything you uploaded. In the right rail, **Free space** shows the size of both, for example "Outputs 1.4 GB · working files 1.2 GB", with the button **Free 1.2 GB: keep the outputs, drop the working files**.
201
201
 
202
202
  1. Press the button.
203
203
  2. Read what goes, then confirm with **Free 1.2 GB**, or press **Keep the working files**.
@@ -198,7 +198,7 @@ After importing, enter your keys again in Settings → Providers. You can also r
198
198
  |---|---|
199
199
  | **Disk space** | What Slopify stores: the total, project files, staged uploads, and deleted projects still in the trash (freed when the trash removes them after 30 days, or with **Delete now**). |
200
200
  | Storage by project | Each project's size, split into outputs and working files, largest first. A finished project's page offers the same on its own (**Free space**, see [Project Page](Project-Page#free-space)). |
201
- | **Keep outputs only** | On a finished project, deletes the working files (images, narration parts, subtitle timing, render settings) and keeps the video, shorts, thumbnail, article, description, document and your uploads. You confirm first. Changing the project later makes those files again, which takes time and provider credits. |
201
+ | **Keep outputs only** | On a finished project, deletes the working files (narration parts, subtitle timing, render settings) and keeps the video, shorts, the images they show, thumbnail, article, description, document and your uploads. You confirm first. Changing the project later makes those files again, which takes time and provider credits. |
202
202
 
203
203
  ### Sample projects
204
204
 
@@ -31,8 +31,8 @@ Each project has one folder in `Projects/`, named after its title (`Lolth | D&D
31
31
 
32
32
  | Folder | What is in it | Safe to delete? |
33
33
  | --- | --- | --- |
34
- | `Upload/` | The current version, ready to publish: `video.mp4`, `thumbnail.png` (and `thumbnail 2.png`…), `subtitles.srt` and `.vtt`, `description.txt`, `tags.txt`, `titles.txt`, `pinned comment.txt`, `document.pdf`, `article.md`, and `Shorts/1 - <title>.mp4`… | No: it is what you upload. |
35
- | `Working/` | What the current version was made from: `Images/`, `Narration/` (each chunk, the joined and levelled narration), `Research/`, `Article/`, `Subtitles/`, `Render/`, `Shorts/` (each short's images). | Only to free space on a finished video: changing that project later makes these again, which takes time and provider credits. **Keep outputs only** does it for you. |
34
+ | `Upload/` | The current version, ready to publish: `video.mp4`, `thumbnail.png` (and `thumbnail 2.png`…), `subtitles.srt` and `.vtt`, `description.txt`, `tags.txt`, `titles.txt`, `pinned comment.txt`, `document.pdf`, `article.md`, `Images/` (every image the video shows, in order; an older version's images in `Images/Earlier/<date>/`), and `Shorts/1 - <title>.mp4`… with each short's images beside it in `Shorts/1 - <title>/`. No cleanup ever deletes these images. | No: it is what you upload. |
35
+ | `Working/` | What the current version was made from: `Narration/` (each chunk, the joined and levelled narration), `Research/`, `Article/`, `Subtitles/`, `Render/`. | Only to free space on a finished video: changing that project later makes these again, which takes time and provider credits. **Keep outputs only** does it for you. |
36
36
  | `History/<date>/` | Files of older versions, by the day they were made (an earlier render, the narration before a voice change). | Yes. Delete a day's folder, or all of `History/`, to free its space. Going back to that version in History makes its files again. |
37
37
 
38
38
  A hidden `.slopify-project` file tells Slopify which project the folder holds and where its files went. Leave it there.
@@ -132,7 +132,7 @@ Deleted projects free their space when the trash removes them after 30 days, or
132
132
 
133
133
  ### Keep outputs only
134
134
 
135
- On a finished project, **Keep outputs only** deletes the working files it was made from (images, narration parts, subtitle timing, render settings) and keeps the video, shorts, thumbnail, article, description, document and your uploads.
135
+ On a finished project, **Keep outputs only** deletes the working files it was made from (narration parts, subtitle timing, render settings) and keeps the video, shorts, the images they show, thumbnail, article, description, document and your uploads.
136
136
 
137
137
  1. Find the project in the **Disk space** list. The button says how much it frees.
138
138
  2. Press **Keep outputs only**.